Update: 2026-05-04 21:21:14
This commit is contained in:
@@ -223,13 +223,14 @@
|
|||||||
<td class="p-6">
|
<td class="p-6">
|
||||||
<p class="font-bold text-emerald-500" x-text="inv.company_name"></p>
|
<p class="font-bold text-emerald-500" x-text="inv.company_name"></p>
|
||||||
<p class="text-sm font-medium text-gray-200 mt-1" x-text="inv.supplier_name"></p>
|
<p class="text-sm font-medium text-gray-200 mt-1" x-text="inv.supplier_name"></p>
|
||||||
|
<p class="text-[10px] text-gray-500 mt-0.5" x-text="inv.supplier_tin"></p>
|
||||||
</td>
|
</td>
|
||||||
<td class="p-6 text-sm text-gray-400 font-mono" x-text="inv.invoice_date || '-'"></td>
|
<td class="p-6 text-sm text-gray-400 font-mono" x-text="inv.invoice_date || '-'"></td>
|
||||||
<td class="p-6 font-mono font-bold" x-text="parseFloat(inv.grand_total).toLocaleString() + ' JOD'"></td>
|
<td class="p-6 font-mono font-bold" x-text="parseFloat(inv.grand_total).toLocaleString() + ' JOD'"></td>
|
||||||
<td class="p-6">
|
<td class="p-6">
|
||||||
<span class="px-3 py-1.5 rounded-full text-[10px] font-bold uppercase tracking-wider"
|
<span class="px-3 py-1.5 rounded-full text-[10px] font-bold uppercase tracking-wider"
|
||||||
:class="inv.status==='extracted'?'bg-blue-900/40 text-blue-400':(inv.status==='approved'?'bg-emerald-900/40 text-emerald-400':'bg-gray-800 text-gray-400')"
|
:class="inv.status==='extracted'?'bg-blue-900/40 text-blue-400':(inv.status==='approved'?'bg-emerald-900/40 text-emerald-400':'bg-gray-800 text-gray-400')"
|
||||||
x-text="inv.status"></span>
|
x-text="inv.status === 'approved' ? 'مدققة' : inv.status"></span>
|
||||||
</td>
|
</td>
|
||||||
<td class="p-6">
|
<td class="p-6">
|
||||||
<button @click="viewInvoice(inv.id)" class="text-gray-500 hover:text-emerald-400 p-3 rounded-2xl hover:bg-emerald-400/10 transition-all">👁️ عرض</button>
|
<button @click="viewInvoice(inv.id)" class="text-gray-500 hover:text-emerald-400 p-3 rounded-2xl hover:bg-emerald-400/10 transition-all">👁️ عرض</button>
|
||||||
@@ -240,6 +241,46 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Tenants Table (Super Admin Only) -->
|
||||||
|
<div x-show="page === 'tenants' && user?.role === 'super_admin'">
|
||||||
|
<div class="bg-surface border border-gray-800 rounded-3xl overflow-hidden shadow-2xl glass">
|
||||||
|
<table class="w-full text-right divide-y divide-gray-800">
|
||||||
|
<thead class="bg-gray-950/50">
|
||||||
|
<tr>
|
||||||
|
<th class="p-6 text-xs font-bold text-gray-500 uppercase">المكتب المحاسبي</th>
|
||||||
|
<th class="p-6 text-xs font-bold text-gray-500 uppercase">التواصل</th>
|
||||||
|
<th class="p-6 text-xs font-bold text-gray-500 uppercase">الحالة</th>
|
||||||
|
<th class="p-6 text-xs font-bold text-gray-500 uppercase">تاريخ الانضمام</th>
|
||||||
|
<th class="p-6 text-xs font-bold text-gray-500 uppercase">إجراءات</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-800/50">
|
||||||
|
<tr x-show="tenants.length === 0"><td colspan="5" class="p-20 text-center text-gray-600 text-lg">لا توجد مكاتب مسجلة</td></tr>
|
||||||
|
<template x-for="t in tenants" :key="t.id">
|
||||||
|
<tr class="hover:bg-white/[0.02] transition-colors">
|
||||||
|
<td class="p-6">
|
||||||
|
<p class="font-bold text-emerald-500" x-text="t.name"></p>
|
||||||
|
</td>
|
||||||
|
<td class="p-6 text-sm">
|
||||||
|
<p class="text-gray-200" x-text="t.email"></p>
|
||||||
|
<p class="text-gray-500 font-mono" x-text="t.phone || '-'"></p>
|
||||||
|
</td>
|
||||||
|
<td class="p-6">
|
||||||
|
<span class="px-3 py-1 rounded-full text-[10px] font-bold uppercase tracking-wide"
|
||||||
|
:class="t.status==='active'?'bg-emerald-900/40 text-emerald-400':'bg-yellow-900/40 text-yellow-400'"
|
||||||
|
x-text="t.status"></span>
|
||||||
|
</td>
|
||||||
|
<td class="p-6 text-xs text-gray-500 font-mono" x-text="t.created_at"></td>
|
||||||
|
<td class="p-6">
|
||||||
|
<button class="text-gray-500 hover:text-emerald-400 p-2 transition">⚙️</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
@@ -447,20 +488,20 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- QR Code -->
|
<!-- QR Code -->
|
||||||
<div x-show="currentInvoice?.jofotara?.qr_image_uri || currentInvoice?.qr_code" class="mt-6 p-4 bg-white rounded-2xl flex justify-center items-center">
|
<div x-show="currentInvoice?.jofotara?.qr_image_uri || currentInvoice?.qr_code" class="mt-6 p-4 bg-white rounded-2xl flex justify-center items-center shadow-inner">
|
||||||
<img :src="currentInvoice?.jofotara?.qr_image_uri || currentInvoice?.qr_code" class="w-40 h-40 object-contain" alt="QR Code">
|
<img :src="getQrSrc(currentInvoice)" class="w-40 h-40 object-contain" alt="QR Code">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Actions -->
|
<!-- Actions -->
|
||||||
<div class="mt-6 pt-6 border-t border-gray-800 space-y-3">
|
<div class="mt-6 pt-6 border-t border-gray-800 space-y-3">
|
||||||
<button x-show="currentInvoice?.status === 'extracted'" @click="approveInvoice" class="w-full bg-emerald-600 hover:bg-emerald-500 py-4 rounded-2xl font-bold shadow-lg shadow-emerald-900/50 transition-all active:scale-95 btn-glow" :disabled="isBusy">
|
<button x-show="currentInvoice?.status === 'extracted'" @click="approveInvoice" class="w-full bg-emerald-600 hover:bg-emerald-500 py-4 rounded-2xl font-bold shadow-lg shadow-emerald-900/50 transition-all active:scale-95 btn-glow" :disabled="isBusy">
|
||||||
<span x-show="!isBusy">✔️ اعتماد وإرسال للفوترة</span>
|
<span x-show="!isBusy">✔️ تدقيق واعتماد محلي</span>
|
||||||
<span x-show="isBusy">⏳ جاري الاعتماد...</span>
|
<span x-show="isBusy">⏳ جاري التدقيق...</span>
|
||||||
</button>
|
</button>
|
||||||
<button x-show="currentInvoice?.status === 'extracted'" class="w-full bg-red-900/30 text-red-400 hover:bg-red-900/50 py-3 rounded-2xl font-bold transition-all">❌ رفض</button>
|
<button x-show="currentInvoice?.status === 'extracted'" class="w-full bg-red-900/30 text-red-400 hover:bg-red-900/50 py-3 rounded-2xl font-bold transition-all">❌ رفض</button>
|
||||||
<div x-show="currentInvoice?.status === 'approved'" class="w-full bg-emerald-900/30 text-emerald-400 py-3 rounded-2xl font-bold text-center border border-emerald-900/50">
|
<div x-show="currentInvoice?.status === 'approved'" class="w-full bg-emerald-900/30 text-emerald-400 py-3 rounded-2xl font-bold text-center border border-emerald-900/50">
|
||||||
✅ معتمدة مسبقاً
|
✅ مدققة وموثقة محلياً
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -515,6 +556,26 @@
|
|||||||
this.companies = await this.apiRequest('v1/companies') || [];
|
this.companies = await this.apiRequest('v1/companies') || [];
|
||||||
if (this.page === 'users') this.users = await this.apiRequest('v1/users') || [];
|
if (this.page === 'users') this.users = await this.apiRequest('v1/users') || [];
|
||||||
if (this.page === 'invoices') this.invoices = await this.apiRequest('v1/invoices') || [];
|
if (this.page === 'invoices') this.invoices = await this.apiRequest('v1/invoices') || [];
|
||||||
|
if (this.page === 'tenants' && this.user.role === 'super_admin') this.tenants = await this.apiRequest('v1/tenants') || [];
|
||||||
|
},
|
||||||
|
|
||||||
|
getQrSrc(inv) {
|
||||||
|
if (!inv) return '';
|
||||||
|
if (inv.jofotara?.qr_image_uri) return inv.jofotara.qr_image_uri;
|
||||||
|
if (inv.qr_code) {
|
||||||
|
// Check if it's already a data URI
|
||||||
|
if (inv.qr_code.startsWith('data:')) return inv.qr_code;
|
||||||
|
|
||||||
|
// Otherwise, it's raw TLV, generate it using QRious
|
||||||
|
try {
|
||||||
|
const qr = new QRious({
|
||||||
|
value: inv.qr_code,
|
||||||
|
size: 250
|
||||||
|
});
|
||||||
|
return qr.toDataURL();
|
||||||
|
} catch (e) { return ''; }
|
||||||
|
}
|
||||||
|
return '';
|
||||||
},
|
},
|
||||||
|
|
||||||
async createUser() {
|
async createUser() {
|
||||||
|
|||||||
Reference in New Issue
Block a user