Update: 2026-05-04 00:23:45
This commit is contained in:
@@ -48,8 +48,19 @@ try {
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
");
|
||||
|
||||
// Determine tenant_id: Super Admin chooses, Admin uses own
|
||||
$tenantId = null;
|
||||
if ($decoded['role'] === 'super_admin') {
|
||||
if (empty($data['tenant_id'])) {
|
||||
json_error('يجب اختيار المكتب المحاسبي', 422);
|
||||
}
|
||||
$tenantId = $data['tenant_id'];
|
||||
} else {
|
||||
$tenantId = $decoded['tenant_id'];
|
||||
}
|
||||
|
||||
$stmt->execute([
|
||||
$decoded['tenant_id'], // Correctly using tenant_id from JWT
|
||||
$tenantId,
|
||||
$encryptedName,
|
||||
$encryptedNameEn,
|
||||
$data['tax_identification_number'],
|
||||
|
||||
264
public/shell.php
264
public/shell.php
@@ -4,12 +4,9 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>مُصادَق | لوحة التحكم</title>
|
||||
|
||||
<!-- Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans+Arabic:wght@300;400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--emerald: #10b981;
|
||||
@@ -19,9 +16,19 @@
|
||||
--text-primary: #f0f6fc;
|
||||
}
|
||||
body { font-family: 'IBM Plex Sans Arabic', sans-serif; background-color: var(--bg-base); color: var(--text-primary); }
|
||||
[x-cloak] { display: none !important; }
|
||||
</style>
|
||||
</head>
|
||||
<body x-data="app" x-init="init()">
|
||||
|
||||
<!-- Global Error Toast -->
|
||||
<div x-show="globalError" x-cloak
|
||||
class="fixed top-4 left-1/2 -translate-x-1/2 z-[100] bg-red-900/90 border border-red-500 text-white px-6 py-3 rounded-lg shadow-2xl max-w-lg text-center"
|
||||
x-text="globalError"
|
||||
x-transition
|
||||
@click="globalError = ''">
|
||||
</div>
|
||||
|
||||
<div class="flex h-screen overflow-hidden">
|
||||
<!-- Sidebar -->
|
||||
<aside class="w-64 bg-surface border-l border-gray-800 flex flex-col">
|
||||
@@ -31,7 +38,7 @@
|
||||
<nav class="flex-1 px-4 space-y-2">
|
||||
<a href="#" @click="page='dashboard'" class="block p-3 rounded hover:bg-gray-800" :class="page==='dashboard'?'bg-emerald-900/20 text-emerald-500':''">📊 لوحة التحكم</a>
|
||||
<a x-show="user?.role === 'super_admin'" href="#" @click="page='tenants'" class="block p-3 rounded hover:bg-gray-800" :class="page==='tenants'?'bg-emerald-900/20 text-emerald-500':''">🏢 المكاتب</a>
|
||||
<a x-show="user?.role !== 'accountant' && user?.role !== 'employee'" href="#" @click="page='companies'" class="block p-3 rounded hover:bg-gray-800" :class="page==='companies'?'bg-emerald-900/20 text-emerald-500':''">🏢 الشركات</a>
|
||||
<a x-show="user?.role !== 'accountant' && user?.role !== 'employee'" href="#" @click="page='companies'" class="block p-3 rounded hover:bg-gray-800" :class="page==='companies'?'bg-emerald-900/20 text-emerald-500':''">🏭 الشركات</a>
|
||||
<a x-show="user?.role === 'super_admin' || user?.role === 'admin'" href="#" @click="page='users'" class="block p-3 rounded hover:bg-gray-800" :class="page==='users'?'bg-emerald-900/20 text-emerald-500':''">👥 المستخدمون</a>
|
||||
</nav>
|
||||
<div class="p-6 border-t border-gray-800">
|
||||
@@ -54,38 +61,50 @@
|
||||
<div id="content">
|
||||
<!-- Dashboard -->
|
||||
<div x-show="page === 'dashboard'">
|
||||
<template x-if="user?.role === 'super_admin'">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div class="p-6 bg-surface border border-gray-800 rounded">
|
||||
<p class="text-gray-500 text-sm">إجمالي فواتير المنصة</p>
|
||||
<p class="text-3xl font-bold mt-2" x-text="stats.total_invoices"></p>
|
||||
</div>
|
||||
<div class="p-6 bg-surface border border-gray-800 rounded">
|
||||
<p class="text-gray-500 text-sm">المكاتب النشطة</p>
|
||||
<p class="text-3xl font-bold mt-2 text-emerald-500" x-text="stats.active_tenants"></p>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div class="p-6 bg-surface border border-gray-800 rounded">
|
||||
<p class="text-gray-500 text-sm">إجمالي الفواتير</p>
|
||||
<p class="text-3xl font-bold mt-2" x-text="stats.total || 0"></p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template x-if="user?.role !== 'super_admin'">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div class="p-6 bg-surface border border-gray-800 rounded">
|
||||
<p class="text-gray-500 text-sm">إجمالي الفواتير</p>
|
||||
<p class="text-3xl font-bold mt-2" x-text="stats.total"></p>
|
||||
</div>
|
||||
<div class="p-6 bg-surface border border-gray-800 rounded">
|
||||
<p class="text-gray-500 text-sm">قيد المعالجة</p>
|
||||
<p class="text-3xl font-bold mt-2 text-yellow-500" x-text="stats.pending"></p>
|
||||
</div>
|
||||
<div class="p-6 bg-surface border border-gray-800 rounded">
|
||||
<p class="text-gray-500 text-sm">تم الاعتماد</p>
|
||||
<p class="text-3xl font-bold mt-2 text-emerald-500" x-text="stats.approved"></p>
|
||||
</div>
|
||||
<div class="p-6 bg-surface border border-gray-800 rounded">
|
||||
<p class="text-gray-500 text-sm">قيد المعالجة</p>
|
||||
<p class="text-3xl font-bold mt-2 text-yellow-500" x-text="stats.pending || 0"></p>
|
||||
</div>
|
||||
</template>
|
||||
<div class="p-6 bg-surface border border-gray-800 rounded">
|
||||
<p class="text-gray-500 text-sm">تم الاعتماد</p>
|
||||
<p class="text-3xl font-bold mt-2 text-emerald-500" x-text="stats.approved || 0"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Companies -->
|
||||
<!-- Tenants List -->
|
||||
<div x-show="page === 'tenants'">
|
||||
<div class="bg-surface border border-gray-800 rounded overflow-hidden">
|
||||
<table class="w-full text-right">
|
||||
<thead class="bg-gray-900/50">
|
||||
<tr>
|
||||
<th class="p-4">اسم المكتب</th>
|
||||
<th class="p-4">البريد الإلكتروني</th>
|
||||
<th class="p-4">الهاتف</th>
|
||||
<th class="p-4">الحالة</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr x-show="tenants.length === 0"><td colspan="4" class="p-8 text-center text-gray-600">لا توجد مكاتب بعد</td></tr>
|
||||
<template x-for="t in tenants" :key="t.id">
|
||||
<tr class="border-t border-gray-800">
|
||||
<td class="p-4 font-bold text-emerald-500" x-text="t.name"></td>
|
||||
<td class="p-4" x-text="t.email"></td>
|
||||
<td class="p-4" x-text="t.phone || '-'"></td>
|
||||
<td class="p-4"><span class="px-2 py-1 bg-emerald-900/30 text-emerald-400 rounded text-xs" x-text="t.status"></span></td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Companies List -->
|
||||
<div x-show="page === 'companies'">
|
||||
<div class="bg-surface border border-gray-800 rounded overflow-hidden">
|
||||
<table class="w-full text-right">
|
||||
@@ -98,11 +117,12 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr x-show="companies.length === 0"><td colspan="4" class="p-8 text-center text-gray-600">لا توجد شركات بعد</td></tr>
|
||||
<template x-for="c in companies" :key="c.id">
|
||||
<tr class="border-t border-gray-800">
|
||||
<td class="p-4 font-bold text-emerald-500" x-text="c.name"></td>
|
||||
<td class="p-4" x-text="c.tax_number"></td>
|
||||
<td class="p-4" x-text="c.registration_number"></td>
|
||||
<td class="p-4" x-text="c.tax_identification_number"></td>
|
||||
<td class="p-4" x-text="c.commercial_registration_number"></td>
|
||||
<td class="p-4 text-xs text-gray-500" x-text="c.created_at"></td>
|
||||
</tr>
|
||||
</template>
|
||||
@@ -111,7 +131,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Users -->
|
||||
<!-- Users List -->
|
||||
<div x-show="page === 'users'">
|
||||
<div class="bg-surface border border-gray-800 rounded overflow-hidden">
|
||||
<table class="w-full text-right">
|
||||
@@ -120,20 +140,17 @@
|
||||
<th class="p-4">الاسم</th>
|
||||
<th class="p-4">البريد الإلكتروني</th>
|
||||
<th class="p-4">المكتب</th>
|
||||
<th class="p-4">الشركة المعينة</th>
|
||||
<th class="p-4">الدور</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr x-show="users.length === 0"><td colspan="4" class="p-8 text-center text-gray-600">لا يوجد مستخدمون بعد</td></tr>
|
||||
<template x-for="u in users" :key="u.id">
|
||||
<tr class="border-t border-gray-800">
|
||||
<td class="p-4" x-text="u.name"></td>
|
||||
<td class="p-4" x-text="u.email"></td>
|
||||
<td class="p-4 text-xs text-gray-400" x-text="u.tenant_name || '-'"></td>
|
||||
<td class="p-4 text-xs text-gray-400" x-text="u.company_name || 'كامل المكتب'"></td>
|
||||
<td class="p-4 text-xs uppercase text-gray-500">
|
||||
<span class="px-2 py-1 bg-gray-800 rounded" x-text="u.role"></span>
|
||||
</td>
|
||||
<td class="p-4"><span class="px-2 py-1 bg-gray-800 rounded text-xs" x-text="u.role"></span></td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
@@ -144,7 +161,7 @@
|
||||
</main>
|
||||
|
||||
<!-- Add User Modal -->
|
||||
<div x-show="showAddModal" class="fixed inset-0 bg-black/80 backdrop-blur-sm flex items-center justify-center p-4 z-50" x-cloak>
|
||||
<div x-show="showAddModal" x-cloak class="fixed inset-0 bg-black/80 backdrop-blur-sm flex items-center justify-center p-4 z-50">
|
||||
<div class="bg-surface border border-gray-800 w-full max-w-md p-8 rounded-lg shadow-2xl" @click.away="showAddModal = false">
|
||||
<h3 class="text-xl font-bold mb-6">إضافة مستخدم جديد 👤</h3>
|
||||
<form @submit.prevent="createUser" class="space-y-4">
|
||||
@@ -165,11 +182,11 @@
|
||||
<select x-model="newUser.role" class="w-full bg-gray-950 border border-gray-800 p-3 rounded outline-none focus:border-emerald-500">
|
||||
<option value="employee">موظف</option>
|
||||
<option value="accountant">محاسب</option>
|
||||
<option value="admin">مدير نظام</option>
|
||||
<option value="admin">مدير مكتب</option>
|
||||
</select>
|
||||
</div>
|
||||
<div x-show="user?.role === 'super_admin'">
|
||||
<label class="block text-xs text-gray-500 uppercase mb-1">تعيين لمكتب (للسوبر أدمن فقط)</label>
|
||||
<label class="block text-xs text-gray-500 uppercase mb-1">تعيين لمكتب</label>
|
||||
<select x-model="newUser.tenant_id" class="w-full bg-gray-950 border border-gray-800 p-3 rounded outline-none focus:border-emerald-500">
|
||||
<option value="">-- اختر المكتب --</option>
|
||||
<template x-for="t in tenants" :key="t.id">
|
||||
@@ -186,16 +203,16 @@
|
||||
</div>
|
||||
|
||||
<!-- Add Tenant Modal -->
|
||||
<div x-show="showAddTenantModal" class="fixed inset-0 bg-black/80 flex items-center justify-center p-4 z-50" style="display: none;">
|
||||
<div class="bg-gray-900 border border-gray-800 rounded-lg p-6 w-full max-w-md shadow-2xl" @click.outside="showAddTenantModal = false">
|
||||
<h3 class="text-xl font-bold mb-6 text-emerald-500">مكتب جديد</h3>
|
||||
<div x-show="showAddTenantModal" x-cloak class="fixed inset-0 bg-black/80 backdrop-blur-sm flex items-center justify-center p-4 z-50">
|
||||
<div class="bg-surface border border-gray-800 rounded-lg p-6 w-full max-w-md shadow-2xl" @click.away="showAddTenantModal = false">
|
||||
<h3 class="text-xl font-bold mb-6 text-emerald-500">مكتب جديد + مدير</h3>
|
||||
<form @submit.prevent="createTenant" class="space-y-4">
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 uppercase mb-1">اسم المكتب</label>
|
||||
<input type="text" x-model="newTenant.name" required class="w-full bg-gray-950 border border-gray-800 p-3 rounded outline-none focus:border-emerald-500">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 uppercase mb-1">البريد الإلكتروني</label>
|
||||
<label class="block text-xs text-gray-500 uppercase mb-1">بريد المكتب</label>
|
||||
<input type="email" x-model="newTenant.email" required class="w-full bg-gray-950 border border-gray-800 p-3 rounded outline-none focus:border-emerald-500">
|
||||
</div>
|
||||
<div>
|
||||
@@ -225,10 +242,19 @@
|
||||
</div>
|
||||
|
||||
<!-- Add Company Modal -->
|
||||
<div x-show="showAddCompanyModal" class="fixed inset-0 bg-black/80 backdrop-blur-sm flex items-center justify-center p-4 z-50" x-cloak>
|
||||
<div x-show="showAddCompanyModal" x-cloak class="fixed inset-0 bg-black/80 backdrop-blur-sm flex items-center justify-center p-4 z-50">
|
||||
<div class="bg-surface border border-gray-800 w-full max-w-md p-8 rounded-lg shadow-2xl" @click.away="showAddCompanyModal = false">
|
||||
<h3 class="text-xl font-bold mb-6">إنشاء شركة جديدة 🏢</h3>
|
||||
<h3 class="text-xl font-bold mb-6">إنشاء شركة جديدة 🏭</h3>
|
||||
<form @submit.prevent="createCompany" class="space-y-4">
|
||||
<div x-show="user?.role === 'super_admin'">
|
||||
<label class="block text-xs text-gray-500 uppercase mb-1">المكتب المحاسبي</label>
|
||||
<select x-model="newCompany.tenant_id" class="w-full bg-gray-950 border border-gray-800 p-3 rounded outline-none focus:border-emerald-500">
|
||||
<option value="">-- اختر المكتب --</option>
|
||||
<template x-for="t in tenants" :key="t.id">
|
||||
<option :value="t.id" x-text="t.name"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 uppercase mb-1">اسم الشركة</label>
|
||||
<input type="text" x-model="newCompany.name" class="w-full bg-gray-950 border border-gray-800 p-3 rounded outline-none focus:border-emerald-500" required>
|
||||
@@ -266,114 +292,128 @@
|
||||
showAddModal: false,
|
||||
showAddCompanyModal: false,
|
||||
showAddTenantModal: false,
|
||||
globalError: '',
|
||||
newUser: { name: '', email: '', password: '', role: 'employee', tenant_id: '' },
|
||||
newCompany: { name: '', tax_identification_number: '', commercial_registration_number: '', address: '' },
|
||||
newCompany: { name: '', tax_identification_number: '', commercial_registration_number: '', address: '', tenant_id: '' },
|
||||
newTenant: { name: '', email: '', phone: '', manager_name: '', manager_email: '', manager_password: '' },
|
||||
|
||||
|
||||
init() {
|
||||
if (!this.user) window.location.href = '/login.php';
|
||||
this.loadUsers();
|
||||
if (!this.user) { window.location.href = '/login.php'; return; }
|
||||
this.loadStats();
|
||||
this.loadCompanies();
|
||||
if (this.user.role === 'super_admin' || this.user.role === 'admin') {
|
||||
this.loadUsers();
|
||||
}
|
||||
if (this.user.role === 'super_admin') {
|
||||
this.loadTenants();
|
||||
}
|
||||
},
|
||||
|
||||
title() {
|
||||
return { dashboard: 'لوحة التحكم', users: 'المستخدمون', companies: 'الشركات' }[this.page];
|
||||
return { dashboard: 'نظرة عامة', users: 'المستخدمون', companies: 'الشركات', tenants: 'المكاتب المحاسبية' }[this.page] || '';
|
||||
},
|
||||
|
||||
showError(msg) {
|
||||
this.globalError = msg;
|
||||
console.error('[مُصادَق Error]', msg);
|
||||
setTimeout(() => this.globalError = '', 6000);
|
||||
},
|
||||
|
||||
token() {
|
||||
return localStorage.getItem('access_token');
|
||||
},
|
||||
|
||||
async apiGet(route) {
|
||||
try {
|
||||
const res = await fetch('/index.php?route=' + route, {
|
||||
headers: { 'Authorization': 'Bearer ' + this.token() }
|
||||
});
|
||||
if (res.status === 401) { this.logout(); return null; }
|
||||
const json = await res.json();
|
||||
console.log('[API GET]', route, json);
|
||||
if (!json.success) {
|
||||
this.showError(json.message || 'خطأ في جلب البيانات');
|
||||
return null;
|
||||
}
|
||||
return json.data;
|
||||
} catch (e) {
|
||||
this.showError('خطأ في الاتصال: ' + route + ' — ' + e.message);
|
||||
console.error('[API ERROR]', route, e);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
async apiPost(route, body) {
|
||||
try {
|
||||
const res = await fetch('/index.php?route=' + route, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer ' + this.token()
|
||||
},
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
const json = await res.json();
|
||||
console.log('[API POST]', route, json);
|
||||
if (!json.success) {
|
||||
this.showError(json.message || 'خطأ في حفظ البيانات');
|
||||
}
|
||||
return json;
|
||||
} catch (e) {
|
||||
this.showError('خطأ في الاتصال: ' + route + ' — ' + e.message);
|
||||
console.error('[API ERROR]', route, e);
|
||||
return { success: false };
|
||||
}
|
||||
},
|
||||
|
||||
async loadUsers() {
|
||||
const res = await fetch('/api/v1/users', {
|
||||
headers: { 'Authorization': 'Bearer ' + localStorage.getItem('access_token') }
|
||||
});
|
||||
if (res.status === 401) this.logout();
|
||||
const json = await res.json();
|
||||
if (json.success) this.users = json.data;
|
||||
const data = await this.apiGet('v1/users');
|
||||
if (data) this.users = data;
|
||||
},
|
||||
|
||||
async loadCompanies() {
|
||||
const res = await fetch('/api/v1/companies', {
|
||||
headers: { 'Authorization': 'Bearer ' + localStorage.getItem('access_token') }
|
||||
});
|
||||
const json = await res.json();
|
||||
if (json.success) this.companies = json.data;
|
||||
const data = await this.apiGet('v1/companies');
|
||||
if (data) this.companies = data;
|
||||
},
|
||||
|
||||
async loadStats() {
|
||||
const res = await fetch('/api/v1/dashboard/stats', {
|
||||
headers: { 'Authorization': 'Bearer ' + localStorage.getItem('access_token') }
|
||||
});
|
||||
const json = await res.json();
|
||||
if (json.success) this.stats = json.data;
|
||||
const data = await this.apiGet('v1/dashboard/stats');
|
||||
if (data) this.stats = data;
|
||||
},
|
||||
|
||||
async loadTenants() {
|
||||
const data = await this.apiGet('v1/tenants');
|
||||
if (data) this.tenants = data;
|
||||
},
|
||||
|
||||
async createUser() {
|
||||
const res = await fetch('/api/v1/users/create', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer ' + localStorage.getItem('access_token')
|
||||
},
|
||||
body: JSON.stringify(this.newUser)
|
||||
});
|
||||
const json = await res.json();
|
||||
const json = await this.apiPost('v1/users/create', this.newUser);
|
||||
if (json.success) {
|
||||
this.showAddModal = false;
|
||||
this.newUser = { name: '', email: '', password: '', role: 'employee', tenant_id: '' };
|
||||
this.loadUsers();
|
||||
alert('تم إضافة المستخدم بنجاح');
|
||||
} else {
|
||||
alert(json.message);
|
||||
}
|
||||
},
|
||||
|
||||
async createCompany() {
|
||||
const res = await fetch('/api/v1/companies/create', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer ' + localStorage.getItem('access_token')
|
||||
},
|
||||
body: JSON.stringify(this.newCompany)
|
||||
});
|
||||
const json = await res.json();
|
||||
const json = await this.apiPost('v1/companies/create', this.newCompany);
|
||||
if (json.success) {
|
||||
this.showAddCompanyModal = false;
|
||||
this.newCompany = { name: '', tax_identification_number: '', commercial_registration_number: '', address: '' };
|
||||
this.newCompany = { name: '', tax_identification_number: '', commercial_registration_number: '', address: '', tenant_id: '' };
|
||||
this.loadCompanies();
|
||||
alert('تم إنشاء الشركة بنجاح');
|
||||
} else {
|
||||
alert(json.message);
|
||||
}
|
||||
},
|
||||
|
||||
async loadTenants() {
|
||||
const res = await fetch('/api/v1/tenants', {
|
||||
headers: { 'Authorization': 'Bearer ' + localStorage.getItem('access_token') }
|
||||
});
|
||||
const json = await res.json();
|
||||
if (json.success) this.tenants = json.data;
|
||||
},
|
||||
|
||||
async createTenant() {
|
||||
const res = await fetch('/api/v1/tenants/create', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer ' + localStorage.getItem('access_token')
|
||||
},
|
||||
body: JSON.stringify(this.newTenant)
|
||||
});
|
||||
const json = await res.json();
|
||||
const json = await this.apiPost('v1/tenants/create', this.newTenant);
|
||||
if (json.success) {
|
||||
this.showAddTenantModal = false;
|
||||
this.newTenant = { name: '', email: '', phone: '', manager_name: '', manager_email: '', manager_password: '' };
|
||||
this.loadTenants();
|
||||
this.loadUsers();
|
||||
alert('تم إنشاء المكتب وتعيين المدير بنجاح!');
|
||||
} else {
|
||||
alert(json.message);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user