🚀 مُصادَق: تحديث برمجي جديد 2026-05-03 02:22
This commit is contained in:
131
public/shell.php
131
public/shell.php
@@ -56,6 +56,10 @@
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg>
|
||||
الفواتير المرفوعة
|
||||
</a>
|
||||
<a href="#" onclick="navigateTo('users')" id="nav-users" class="nav-link flex items-center gap-3 px-6 py-3 text-slate-400 hover:text-white transition-colors">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"></path></svg>
|
||||
المستخدمين
|
||||
</a>
|
||||
</nav>
|
||||
<div class="p-6 border-t border-white/10">
|
||||
<button onclick="logout()" class="flex items-center gap-3 text-red-400 hover:text-red-300 transition-colors w-full">
|
||||
@@ -160,6 +164,30 @@
|
||||
if (page === 'dashboard') await renderDashboard();
|
||||
else if (page === 'companies') await renderCompanies();
|
||||
else if (page === 'invoices') await renderInvoices();
|
||||
else if (page === 'users') await renderUsers();
|
||||
}
|
||||
|
||||
// ── Users View ───────────────────────────────────────────
|
||||
async function renderUsers() {
|
||||
document.getElementById('page-title').textContent = 'إدارة المستخدمين';
|
||||
try {
|
||||
// We'll build the API for this later, for now just show a placeholder
|
||||
contentDiv.innerHTML = `
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<p class="text-slate-400">لوحة تحكم السوبر يوزر لإدارة المحاسبين والمدراء وربطهم بالشركات.</p>
|
||||
<button class="bg-primary hover:bg-primary-dark text-white px-6 py-2 rounded-xl transition-all shadow-lg flex items-center gap-2 font-bold">
|
||||
+ إضافة مستخدم
|
||||
</button>
|
||||
</div>
|
||||
<div class="glass-panel p-12 rounded-3xl text-center">
|
||||
<svg class="w-16 h-16 text-slate-600 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"></path></svg>
|
||||
<h3 class="text-xl font-bold mb-2">قريباً...</h3>
|
||||
<p class="text-slate-500">جاري برمجة واجهات ربط المحاسبين بالشركات وتحديد الصلاحيات الخاصة بهم.</p>
|
||||
</div>
|
||||
`;
|
||||
} catch(err) {
|
||||
contentDiv.innerHTML = `<div class="text-red-400">خطأ في جلب المستخدمين</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Login View ───────────────────────────────────────────
|
||||
@@ -284,16 +312,16 @@
|
||||
html += `
|
||||
<div class="glass-panel p-6 rounded-3xl flex flex-col h-full border-t-4 border-t-primary">
|
||||
<h3 class="text-xl font-bold mb-1">${company.name}</h3>
|
||||
<p class="text-slate-400 text-sm font-mono mb-4">الرقم الضريبي: ${company.tax_number}</p>
|
||||
<p class="text-slate-400 text-sm font-mono mb-4">الرقم الضريبي: ${company.tax_identification_number || company.tax_number || 'غير متوفر'}</p>
|
||||
|
||||
<div class="mt-auto space-y-3">
|
||||
<div class="flex items-center justify-between text-sm p-3 bg-black/20 rounded-xl border border-white/5">
|
||||
<span class="text-slate-400">بوابة JoFotara</span>
|
||||
${company.jofotara_client_id
|
||||
${company.jofotara_client_id_encrypted
|
||||
? '<span class="text-primary font-bold">مربوط ✓</span>'
|
||||
: '<span class="text-yellow-400 font-bold">غير مربوط ⚠</span>'}
|
||||
</div>
|
||||
<button onclick="showJoFotaraModal(${company.id})" class="w-full py-2 bg-white/5 hover:bg-white/10 rounded-xl text-sm transition border border-white/10">إعدادات الربط</button>
|
||||
<button onclick="showJoFotaraModal('${company.id}')" class="w-full py-2 bg-white/5 hover:bg-white/10 rounded-xl text-sm transition border border-white/10">إعدادات الربط</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -450,50 +478,65 @@
|
||||
};
|
||||
}
|
||||
|
||||
function showUploadInvoiceModal() {
|
||||
const modals = document.getElementById('modals');
|
||||
modals.innerHTML = `
|
||||
<div class="fixed inset-0 bg-black/60 backdrop-blur-sm z-[100] flex items-center justify-center" id="invoice-modal">
|
||||
<div class="glass-panel p-8 rounded-3xl w-full max-w-md border border-white/10 shadow-2xl">
|
||||
<h3 class="text-2xl font-bold mb-6">رفع فاتورة للتدقيق</h3>
|
||||
<form id="upload-invoice-form" class="space-y-4" enctype="multipart/form-data">
|
||||
<input type="text" id="inv-comp-id" class="w-full bg-black/20 border border-white/10 rounded-xl px-4 py-3 text-white focus:border-primary outline-none" placeholder="معرف الشركة (Company ID)" required>
|
||||
<div class="p-4 border-2 border-dashed border-white/20 rounded-xl bg-black/10 text-center">
|
||||
<p class="text-sm text-slate-400 mb-2">اختر ملف الفاتورة (JSON/XML/PDF)</p>
|
||||
<input type="file" id="inv-file" class="text-sm w-full" required>
|
||||
</div>
|
||||
<div class="flex gap-3 mt-6">
|
||||
<button type="button" onclick="document.getElementById('invoice-modal').remove()" class="flex-1 py-3 bg-white/5 hover:bg-white/10 rounded-xl transition">إلغاء</button>
|
||||
<button type="submit" class="flex-1 py-3 bg-primary hover:bg-primary-dark text-white font-bold rounded-xl shadow-lg transition">تحقق ورفع</button>
|
||||
</div>
|
||||
</form>
|
||||
async function showUploadInvoiceModal() {
|
||||
try {
|
||||
// Fetch companies to populate the select dropdown
|
||||
const res = await API.get('/companies');
|
||||
const companies = res.data;
|
||||
|
||||
let optionsHtml = '<option value="" disabled selected>-- اختر الشركة --</option>';
|
||||
companies.forEach(c => {
|
||||
optionsHtml += \`<option value="\${c.id}">\${c.name} (\${c.tax_identification_number || ''})</option>\`;
|
||||
});
|
||||
|
||||
const modals = document.getElementById('modals');
|
||||
modals.innerHTML = \`
|
||||
<div class="fixed inset-0 bg-black/60 backdrop-blur-sm z-[100] flex items-center justify-center" id="invoice-modal">
|
||||
<div class="glass-panel p-8 rounded-3xl w-full max-w-md border border-white/10 shadow-2xl">
|
||||
<h3 class="text-2xl font-bold mb-6">رفع فاتورة للتدقيق</h3>
|
||||
<form id="upload-invoice-form" class="space-y-4" enctype="multipart/form-data">
|
||||
<select id="inv-comp-id" class="w-full bg-black/20 border border-white/10 rounded-xl px-4 py-3 text-white focus:border-primary outline-none" required>
|
||||
\${optionsHtml}
|
||||
</select>
|
||||
<div class="p-4 border-2 border-dashed border-white/20 rounded-xl bg-black/10 text-center">
|
||||
<p class="text-sm text-slate-400 mb-2">اختر ملف الفاتورة (JSON/XML/PDF)</p>
|
||||
<input type="file" id="inv-file" class="text-sm w-full" required>
|
||||
</div>
|
||||
<div class="flex gap-3 mt-6">
|
||||
<button type="button" onclick="document.getElementById('invoice-modal').remove()" class="flex-1 py-3 bg-white/5 hover:bg-white/10 rounded-xl transition">إلغاء</button>
|
||||
<button type="submit" class="flex-1 py-3 bg-primary hover:bg-primary-dark text-white font-bold rounded-xl shadow-lg transition">تحقق ورفع</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
\`;
|
||||
|
||||
document.getElementById('upload-invoice-form').onsubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
try {
|
||||
const companyId = document.getElementById('inv-comp-id').value;
|
||||
const fileInput = document.getElementById('inv-file');
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('company_id', companyId);
|
||||
formData.append('invoice', fileInput.files[0]);
|
||||
|
||||
const btn = e.target.querySelector('button[type="submit"]');
|
||||
btn.textContent = 'جاري التحقق...';
|
||||
btn.disabled = true;
|
||||
document.getElementById('upload-invoice-form').onsubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
try {
|
||||
const companyId = document.getElementById('inv-comp-id').value;
|
||||
const fileInput = document.getElementById('inv-file');
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('company_id', companyId);
|
||||
formData.append('invoice', fileInput.files[0]);
|
||||
|
||||
const btn = e.target.querySelector('button[type="submit"]');
|
||||
btn.textContent = 'جاري التحقق...';
|
||||
btn.disabled = true;
|
||||
|
||||
await API.upload('/invoices/upload', formData);
|
||||
document.getElementById('invoice-modal').remove();
|
||||
renderInvoices();
|
||||
} catch(err) {
|
||||
alert(err.error?.message_ar || 'صيغة البيانات غير صحيحة أو حدث خطأ ضريبي.');
|
||||
e.target.querySelector('button[type="submit"]').textContent = 'تحقق ورفع';
|
||||
e.target.querySelector('button[type="submit"]').disabled = false;
|
||||
}
|
||||
};
|
||||
await API.upload('/invoices/upload', formData);
|
||||
document.getElementById('invoice-modal').remove();
|
||||
renderInvoices();
|
||||
} catch(err) {
|
||||
alert(err.error?.message_ar || 'صيغة البيانات غير صحيحة أو حدث خطأ ضريبي.');
|
||||
e.target.querySelector('button[type="submit"]').textContent = 'تحقق ورفع';
|
||||
e.target.querySelector('button[type="submit"]').disabled = false;
|
||||
}
|
||||
};
|
||||
} catch(err) {
|
||||
alert('خطأ في جلب بيانات الشركات المربوطة بك.');
|
||||
}
|
||||
}
|
||||
|
||||
// ── Init Engine ──────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user