Update: 2026-05-09 21:27:35
This commit is contained in:
136
public/shell.php
136
public/shell.php
@@ -1647,7 +1647,76 @@
|
||||
<span>📊</span> استيراد Excel (Bulk)
|
||||
</button>
|
||||
</div>
|
||||
<table class="data-table">
|
||||
|
||||
<!-- Invoice Filters & Tabs -->
|
||||
<div class="px-6 py-4 border-b border-gray-100 bg-gray-50/50">
|
||||
<div class="flex flex-wrap items-center justify-between gap-4">
|
||||
<!-- Tabs -->
|
||||
<div class="flex flex-wrap bg-white p-1 rounded-xl border border-gray-200 shadow-sm gap-1">
|
||||
<button @click="activeInvoiceTab = 'all'"
|
||||
:class="activeInvoiceTab === 'all' ? 'bg-indigo-600 text-white shadow-md' : 'text-gray-600 hover:bg-gray-100'"
|
||||
class="px-4 py-2 rounded-lg text-xs font-bold transition-all duration-200">
|
||||
الكل
|
||||
</button>
|
||||
<button @click="activeInvoiceTab = 'companies'"
|
||||
:class="activeInvoiceTab === 'companies' ? 'bg-indigo-600 text-white shadow-md' : 'text-gray-600 hover:bg-gray-100'"
|
||||
class="px-4 py-2 rounded-lg text-xs font-bold transition-all duration-200">
|
||||
حسب الشركات
|
||||
</button>
|
||||
<button @click="activeInvoiceTab = 'approved'"
|
||||
:class="activeInvoiceTab === 'approved' ? 'bg-indigo-600 text-white shadow-md' : 'text-gray-600 hover:bg-gray-100'"
|
||||
class="px-4 py-2 rounded-lg text-xs font-bold transition-all duration-200">
|
||||
المعتمدة
|
||||
</button>
|
||||
<button @click="activeInvoiceTab = 'pending'"
|
||||
:class="activeInvoiceTab === 'pending' ? 'bg-indigo-600 text-white shadow-md' : 'text-gray-600 hover:bg-gray-100'"
|
||||
class="px-4 py-2 rounded-lg text-xs font-bold transition-all duration-200">
|
||||
المعلقة
|
||||
</button>
|
||||
<button @click="activeInvoiceTab = 'rejected'"
|
||||
:class="activeInvoiceTab === 'rejected' ? 'bg-indigo-600 text-white shadow-md' : 'text-gray-600 hover:bg-gray-100'"
|
||||
class="px-4 py-2 rounded-lg text-xs font-bold transition-all duration-200">
|
||||
المرفوضة
|
||||
</button>
|
||||
<button @click="activeInvoiceTab = 'jofotara'"
|
||||
:class="activeInvoiceTab === 'jofotara' ? 'bg-indigo-600 text-white shadow-md' : 'text-gray-600 hover:bg-gray-100'"
|
||||
class="px-4 py-2 rounded-lg text-xs font-bold transition-all duration-200">
|
||||
جوفوترا
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Company Filter -->
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-xs font-bold text-gray-500">تصفية حسب الشركة:</span>
|
||||
<select x-model="invoiceCompanyFilter" class="text-xs font-bold border border-gray-200 rounded-lg px-3 py-2 bg-white outline-none focus:border-indigo-500 transition-colors">
|
||||
<option value="">جميع الشركات</option>
|
||||
<template x-for="c in companies" :key="c.id">
|
||||
<option :value="c.id" x-text="c.name"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Companies Selection View -->
|
||||
<div x-show="activeInvoiceTab === 'companies'" class="p-6 bg-gray-50 border-b border-gray-100">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<template x-for="c in companies" :key="c.id">
|
||||
<div @click="invoiceCompanyFilter = c.id; activeInvoiceTab = 'all'"
|
||||
class="bg-white p-4 rounded-xl border border-gray-200 shadow-sm cursor-pointer hover:border-indigo-500 hover:shadow-md transition-all group">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-lg bg-indigo-50 text-indigo-600 flex items-center justify-center font-bold group-hover:bg-indigo-600 group-hover:text-white transition-colors" x-text="c.name[0]"></div>
|
||||
<div>
|
||||
<div class="font-bold text-gray-800" x-text="c.name"></div>
|
||||
<div class="text-xs text-gray-500 num-font" x-text="c.tax_identification_number"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="data-table" x-show="activeInvoiceTab !== 'companies'">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>الشركة / المورد</th>
|
||||
@@ -1658,15 +1727,15 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr x-show="invoices.length === 0">
|
||||
<tr x-show="filteredInvoices.length === 0">
|
||||
<td colspan="5">
|
||||
<div class="empty-row">
|
||||
<span class="empty-icon">📄</span>
|
||||
<p class="empty-msg">لا توجد فواتير مرفوعة بعد</p>
|
||||
<p class="empty-msg">لا توجد فواتير تطابق التصفية لهذا الشهر</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<template x-for="inv in invoices" :key="inv.id">
|
||||
<template x-for="inv in filteredInvoices" :key="inv.id">
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight:700; color:var(--violet-mid); font-size:14px;"
|
||||
@@ -1682,8 +1751,8 @@
|
||||
x-text="parseFloat(inv.grand_total).toLocaleString() + ' JOD'"></td>
|
||||
<td style="text-align:center;">
|
||||
<span class="badge"
|
||||
:class="inv.status==='extracted' ? 'badge-blue' : (inv.status==='approved' ? 'badge-teal' : 'badge-gray')"
|
||||
x-text="inv.status === 'approved' ? '✓ مدققة' : (inv.status === 'extracted' ? 'جاهزة للتدقيق' : inv.status)">
|
||||
:class="inv.status==='extracted' ? 'badge-blue' : (inv.status==='approved' ? 'badge-teal' : (inv.status==='rejected'||inv.status==='failed'?'badge-red':'badge-gray'))"
|
||||
x-text="inv.status === 'approved' ? '✓ مدققة' : (inv.status === 'extracted' ? 'جاهزة للتدقيق' : (inv.status === 'rejected' ? 'مرفوضة' : inv.status))">
|
||||
</span>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
@@ -1790,18 +1859,18 @@
|
||||
<span style="font-weight:700; color:var(--text-1); font-size:14px;">📄 الفواتير
|
||||
الشهرية</span>
|
||||
<span class="num-font" style="font-weight:700; color:var(--green-mid);"
|
||||
x-text="(subscription?.invoices?.used || 0) + ' / ' + (subscription?.invoices?.limit || 0)"></span>
|
||||
x-text="(subscription?.invoices?.used || 0) + ' من ' + (subscription?.invoices?.limit || 0)"></span>
|
||||
</div>
|
||||
<div class="usage-bar-bg">
|
||||
<div class="usage-bar-fill"
|
||||
style="background:linear-gradient(to left, var(--green-bright), var(--green-mid));"
|
||||
:style="'width:' + (subscription?.invoices?.percent || 0) + '%'"></div>
|
||||
style="background:linear-gradient(to left, var(--green-bright), var(--green-mid)); min-width: 2px;"
|
||||
:style="'width:' + Math.min(100, (subscription?.invoices?.percent || 0)) + '%'"></div>
|
||||
</div>
|
||||
<div
|
||||
style="display:flex; justify-content:space-between; font-size:12px; color:var(--text-3);">
|
||||
<span
|
||||
x-text="'يتم التصفير في: ' + (subscription?.period_end?.split(' ')[0] || '—')"></span>
|
||||
<span class="num-font" x-text="(subscription?.invoices?.percent || 0) + '%'"></span>
|
||||
<span class="num-font font-bold" x-text="(subscription?.invoices?.percent || 0) + '%'"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1811,14 +1880,17 @@
|
||||
<span style="font-weight:700; color:var(--text-1); font-size:14px;">🏭 الشركات
|
||||
المدارة</span>
|
||||
<span class="num-font" style="font-weight:700; color:var(--violet-mid);"
|
||||
x-text="(subscription?.companies?.used || 0) + ' / ' + (subscription?.companies?.limit || 0)"></span>
|
||||
x-text="(subscription?.companies?.used || 0) + ' من ' + (subscription?.companies?.limit || 0)"></span>
|
||||
</div>
|
||||
<div class="usage-bar-bg">
|
||||
<div class="usage-bar-fill"
|
||||
style="background:linear-gradient(to left, var(--sb-accent), var(--violet-mid));"
|
||||
:style="'width:' + (subscription?.companies?.percent || 0) + '%'"></div>
|
||||
style="background:linear-gradient(to left, var(--sb-accent), var(--violet-mid)); min-width: 2px;"
|
||||
:style="'width:' + Math.min(100, (subscription?.companies?.percent || 0)) + '%'"></div>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:space-between; font-size:12px; color:var(--text-3);">
|
||||
<span>إجمالي الشركات المسموح بها</span>
|
||||
<span class="num-font font-bold" x-text="(subscription?.companies?.percent || 0) + '%'"></span>
|
||||
</div>
|
||||
<div style="font-size:12px; color:var(--text-3);">إجمالي الشركات المسموح بها</div>
|
||||
</div>
|
||||
|
||||
<!-- Team -->
|
||||
@@ -1826,14 +1898,17 @@
|
||||
<div style="display:flex; justify-content:space-between; margin-bottom:6px;">
|
||||
<span style="font-weight:700; color:var(--text-1); font-size:14px;">👥 فريق العمل</span>
|
||||
<span class="num-font" style="font-weight:700; color:var(--amber-mid);"
|
||||
x-text="(subscription?.users?.used || 0) + ' / ' + (subscription?.users?.limit || 0)"></span>
|
||||
x-text="(subscription?.users?.used || 0) + ' من ' + (subscription?.users?.limit || 0)"></span>
|
||||
</div>
|
||||
<div class="usage-bar-bg">
|
||||
<div class="usage-bar-fill"
|
||||
style="background:linear-gradient(to left, var(--amber-bright), var(--amber-mid));"
|
||||
:style="'width:' + (subscription?.users?.percent || 0) + '%'"></div>
|
||||
style="background:linear-gradient(to left, var(--amber-bright), var(--amber-mid)); min-width: 2px;"
|
||||
:style="'width:' + Math.min(100, (subscription?.users?.percent || 0)) + '%'"></div>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:space-between; font-size:12px; color:var(--text-3);">
|
||||
<span>مستخدمين نشطين في النظام</span>
|
||||
<span class="num-font font-bold" x-text="(subscription?.users?.percent || 0) + '%'"></span>
|
||||
</div>
|
||||
<div style="font-size:12px; color:var(--text-3);">مستخدمين نشطين في النظام</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2746,6 +2821,8 @@
|
||||
user: JSON.parse(localStorage.getItem('user')),
|
||||
page: 'dashboard',
|
||||
users: [], companies: [], invoices: [], tenants: [], subscription: null, plans: [],
|
||||
activeInvoiceTab: 'all', // all, approved, pending, rejected, jofotara
|
||||
invoiceCompanyFilter: '',
|
||||
showPaymentModal: false,
|
||||
paymentData: { cliq_alias: '', amount: 0, plan_name: '', reference: '', payment_id: '' },
|
||||
stats: { total: 0, pending: 0, approved: 0 },
|
||||
@@ -2773,6 +2850,29 @@
|
||||
setPage(p) { this.page = p; this.loadAll(); },
|
||||
title() { return { dashboard: 'الرئيسية', users: 'فريق العمل', companies: 'الشركات', invoices: 'إدارة الفواتير', tenants: 'المكاتب المحاسبية', subscription: 'إدارة الاشتراك' }[this.page] || ''; },
|
||||
subtitle() { return { dashboard: 'نظرة شاملة على نشاط النظام', users: 'إدارة المستخدمين والصلاحيات', companies: 'إدارة الشركات والربط بالفوترة الحكومية', invoices: 'رفع ومعالجة الفواتير الضريبية', tenants: 'إدارة المكاتب المحاسبية المشتركة', subscription: 'تفاصيل باقتك الحالية واستهلاك الموارد' }[this.page] || ''; },
|
||||
|
||||
get filteredInvoices() {
|
||||
const now = new Date();
|
||||
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
|
||||
|
||||
return this.invoices.filter(inv => {
|
||||
// 1. Time Filter (Current Month)
|
||||
const invDate = new Date(inv.invoice_date || inv.created_at);
|
||||
if (invDate < startOfMonth) return false;
|
||||
|
||||
// 2. Company Filter
|
||||
if (this.invoiceCompanyFilter && inv.company_id != this.invoiceCompanyFilter) return false;
|
||||
|
||||
// 3. Tab Filter
|
||||
if (this.activeInvoiceTab === 'approved' && inv.status !== 'approved') return false;
|
||||
if (this.activeInvoiceTab === 'pending' && inv.status !== 'extracted' && inv.status !== 'pending') return false;
|
||||
if (this.activeInvoiceTab === 'rejected' && inv.status !== 'rejected' && inv.status !== 'failed') return false;
|
||||
if (this.activeInvoiceTab === 'jofotara' && !inv.jofotara_uuid && !inv.jofotara) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
},
|
||||
|
||||
token() { return localStorage.getItem('access_token'); },
|
||||
showError(msg) { this.globalError = msg; setTimeout(() => this.globalError = '', 8000); },
|
||||
|
||||
|
||||
Reference in New Issue
Block a user