File size: 34,097 Bytes
e56588a
 
 
 
0a95766
61ed5e2
 
e56588a
06521f9
 
 
 
 
 
 
 
 
 
 
 
b1559b7
06521f9
b1559b7
96d9294
06521f9
b1559b7
06521f9
 
 
96d9294
06521f9
 
 
 
 
96d9294
06521f9
 
 
 
 
96d9294
 
06521f9
96d9294
 
06521f9
 
 
96d9294
 
06521f9
96d9294
2106380
96d9294
06521f9
 
96d9294
 
06521f9
96d9294
06521f9
326e719
96d9294
 
 
326e719
96d9294
326e719
96d9294
 
 
06521f9
96d9294
 
06521f9
 
 
96d9294
 
 
 
06521f9
96d9294
2106380
96d9294
 
06521f9
 
96d9294
 
06521f9
96d9294
 
 
 
06521f9
96d9294
06521f9
 
 
96d9294
06521f9
 
326e719
 
 
b1559b7
326e719
96d9294
326e719
 
 
96d9294
 
 
326e719
 
 
 
96d9294
326e719
 
96d9294
 
 
 
 
 
 
 
 
 
 
 
 
326e719
 
 
96d9294
326e719
 
96d9294
326e719
 
96d9294
326e719
96d9294
 
326e719
 
 
 
 
e56588a
 
 
 
afa2e2f
2106380
0a95766
2106380
 
61ed5e2
 
 
 
 
0a95766
 
2106380
e56588a
61ed5e2
0a95766
61ed5e2
 
 
 
 
 
 
0a95766
61ed5e2
 
0a95766
e56588a
61ed5e2
 
 
 
 
 
 
 
 
 
 
 
0a95766
 
 
 
 
 
 
61ed5e2
 
 
 
0a95766
 
 
 
 
 
 
61ed5e2
 
 
 
06521f9
0a95766
61ed5e2
 
0a95766
afa2e2f
 
96d9294
326e719
 
 
96d9294
326e719
 
 
 
61ed5e2
 
e56588a
61ed5e2
 
 
 
 
 
d8ccd98
61ed5e2
d8ccd98
61ed5e2
 
 
2106380
61ed5e2
96d9294
 
 
 
 
 
 
 
61ed5e2
 
 
 
 
0a95766
61ed5e2
 
 
 
2106380
e56588a
61ed5e2
 
 
d8ccd98
61ed5e2
 
 
 
 
 
0a95766
 
 
61ed5e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50e4a1d
61ed5e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50e4a1d
61ed5e2
 
 
 
 
 
 
 
 
 
 
 
50c11e2
61ed5e2
 
 
50c11e2
61ed5e2
 
50e4a1d
 
61ed5e2
 
50c11e2
61ed5e2
06521f9
61ed5e2
 
 
06521f9
61ed5e2
 
 
 
 
 
 
50c11e2
 
 
 
 
 
 
 
 
61ed5e2
0a95766
 
 
 
 
 
 
 
 
d8ccd98
0a95766
 
 
 
 
61ed5e2
 
2106380
 
50e4a1d
 
 
2106380
66558c3
2106380
61ed5e2
66558c3
e56588a
0a95766
66558c3
 
9fbfe7b
50e4a1d
e56588a
06521f9
 
e56588a
 
 
 
 
66558c3
2106380
61ed5e2
 
e56588a
 
0a95766
 
61ed5e2
0a95766
 
 
 
 
 
50e4a1d
0a95766
06521f9
 
0a95766
 
 
 
 
 
 
61ed5e2
 
0a95766
 
 
61ed5e2
 
 
 
0a95766
326e719
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50e4a1d
326e719
9fbfe7b
326e719
61ed5e2
 
06521f9
326e719
 
 
 
 
 
96d9294
326e719
 
 
 
 
 
 
0a95766
96d9294
0a95766
 
61ed5e2
 
 
 
 
 
 
 
 
 
 
 
41ccfab
 
61ed5e2
 
 
41ccfab
 
 
0a95766
 
 
96d9294
61ed5e2
0a95766
 
d8ccd98
e56588a
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<link rel="icon" href="favicon.svg" type="image/svg+xml">
<title>أدمن — نيّة</title>
<meta name="robots" content="noindex, nofollow">
<style>
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@400;600;700;800&family=IBM+Plex+Sans+Arabic:wght@300;400;500;600&display=swap');
:root{
  --bg:#FFFFFF; --ink:#0A0A0A;
  --line: rgba(10,10,10,0.12); --line-strong: rgba(10,10,10,0.22);
  --muted: rgba(10,10,10,0.55); --muted-soft: rgba(10,10,10,0.4);
  --surface: rgba(10,10,10,0.03); --surface-hover: rgba(10,10,10,0.05);
  --radius:14px; --radius-sm:10px; --ease: cubic-bezier(.22,1,.36,1);
  --shadow-sm: 0 1px 3px rgba(10,10,10,0.05), 0 1px 2px rgba(10,10,10,0.04);
  --shadow-md: 0 6px 20px rgba(10,10,10,0.07), 0 2px 6px rgba(10,10,10,0.04);
  --good:#1E8E3E; --good-bg:#EAF7EE; --danger:#C00000; --danger-bg:#FDECEC;
}
*{ box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
html{ overflow-x:hidden; scroll-behavior:smooth; height:100%; }
body{
  font-family:'IBM Plex Sans Arabic', sans-serif; margin:0; padding:0; min-height:100vh;
  background: var(--bg, #FFFFFF); color: var(--ink, #0A0A0A); overflow-x:hidden; -webkit-font-smoothing:antialiased;
}
.page-wrap{ max-width:1180px; margin:0 auto; padding:22px; animation: fadeIn .35s var(--ease, cubic-bezier(.22,1,.36,1)) both; }
h1,h2,h3,button{ font-family:'Cairo', sans-serif; }
@keyframes fadeIn{ from{opacity:0; transform:translateY(8px);} to{opacity:1; transform:none;} }
@keyframes rowIn{ from{opacity:0; transform:translateY(4px);} to{opacity:1; transform:none;} }
tr{ animation: rowIn .3s var(--ease, cubic-bezier(.22,1,.36,1)) both; }
img,video{ max-width:100%; height:auto; }
*{ word-wrap:break-word; overflow-wrap:break-word; }

.topbar{
  display:flex; justify-content:space-between; align-items:center; gap:14px; flex-wrap:wrap;
  margin-bottom:22px; padding-bottom:18px; border-bottom:1px solid var(--line, rgba(10,10,10,0.12));
}
.topbar h1{ font-size:22px; font-weight:800; margin:0; }

.stats{ display:flex; gap:12px; flex-wrap:wrap; margin-bottom:22px; }
.stat{
  background:var(--bg, #FFFFFF); border:1.5px solid var(--line, rgba(10,10,10,0.12)); border-radius: var(--radius-sm, 10px);
  padding:14px 18px; font-size:13px; color:var(--muted, rgba(10,10,10,0.55)); transition: transform .2s var(--ease, cubic-bezier(.22,1,.36,1)), box-shadow .2s var(--ease, cubic-bezier(.22,1,.36,1)), border-color .2s var(--ease, cubic-bezier(.22,1,.36,1));
}
.stat:hover{ transform: translateY(-2px); box-shadow: var(--shadow-sm, 0 1px 3px rgba(10,10,10,0.05), 0 1px 2px rgba(10,10,10,0.04)); border-color: var(--line-strong, rgba(10,10,10,0.22)); }
.stat b{ font-size:19px; display:block; font-family:'Cairo',sans-serif; font-weight:800; color:var(--ink, #0A0A0A); margin-top:2px; }

.filters{ display:flex; gap:8px; margin-bottom:18px; flex-wrap:wrap; }
.filters button{
  padding:8px 18px; border-radius:999px; border:1.5px solid var(--line-strong, rgba(10,10,10,0.22)); background:var(--bg, #FFFFFF);
  color:var(--ink, #0A0A0A); cursor:pointer; font-size:13px; font-weight:600; transition: all .18s var(--ease, cubic-bezier(.22,1,.36,1));
}
.filters button:hover{ background: var(--surface, rgba(10,10,10,0.03)); }
.filters button:active{ transform: scale(.95); }
.filters button.active{ background:var(--ink, #0A0A0A); color:var(--bg, #FFFFFF); border-color:var(--ink, #0A0A0A); }

input#search{
  padding:9px 14px; border-radius: var(--radius-sm, 10px); border:1.5px solid var(--line, rgba(10,10,10,0.12)); font-size:13.5px;
  min-width:220px; font-family:inherit; transition: border-color .18s var(--ease, cubic-bezier(.22,1,.36,1)), box-shadow .18s var(--ease, cubic-bezier(.22,1,.36,1));
}
input#search:focus{ outline:none; border-color:var(--ink, #0A0A0A); box-shadow:0 0 0 3.5px rgba(10,10,10,0.07); }

select, input{
  font-family:inherit; border-radius: var(--radius-sm, 10px); border:1.5px solid var(--line, rgba(10,10,10,0.12));
  padding:6px 10px; font-size:13px; transition: border-color .18s var(--ease, cubic-bezier(.22,1,.36,1)), box-shadow .18s var(--ease, cubic-bezier(.22,1,.36,1));
  background:var(--bg, #FFFFFF); color:var(--ink, #0A0A0A);
}
select:focus, input:focus{ outline:none; border-color:var(--ink, #0A0A0A); box-shadow:0 0 0 3.5px rgba(10,10,10,0.07); }

table{ border-collapse:separate; border-spacing:0; width:100%; background:var(--bg, #FFFFFF); border:1px solid var(--line, rgba(10,10,10,0.12)); border-radius: var(--radius, 14px); overflow:hidden; }
td, th{ border-bottom:1px solid var(--line, rgba(10,10,10,0.12)); padding:12px 14px; text-align:right; font-size:13.5px; }
th{ background: var(--surface, rgba(10,10,10,0.03)); font-weight:700; font-size:12.5px; color:var(--muted, rgba(10,10,10,0.55)); }
tr:last-child td{ border-bottom:none; }
tr:hover td{ background: var(--surface, rgba(10,10,10,0.03)); }
img{ max-width:180px; max-height:130px; border-radius: var(--radius-sm, 10px); cursor:pointer; transition: transform .2s var(--ease, cubic-bezier(.22,1,.36,1)); }
img:hover{ transform: scale(1.03); }

button.act{
  margin:2px; padding:7px 14px; cursor:pointer; border-radius:8px; border:1.5px solid var(--line-strong, rgba(10,10,10,0.22));
  background:var(--bg, #FFFFFF); color:var(--ink, #0A0A0A); font-size:12.5px; font-weight:600; font-family:inherit;
  transition: all .18s var(--ease, cubic-bezier(.22,1,.36,1));
  display:inline-flex; align-items:center; gap:4px; white-space:nowrap; line-height:1.3;
}
button.act:hover{ background: var(--surface, rgba(10,10,10,0.03)); }
button.act:active{ transform: scale(.94); }
button.act.approve{ background:var(--good, #1E8E3E); color:#ffffff; border-color:var(--good, #1E8E3E); }
button.act.reject{ background:var(--danger, #C00000); color:#ffffff; border-color:var(--danger, #C00000); }

.status-pending, .status-open{ color:#B15C00; font-weight:700; }
.status-approved, .status-resolved, .status-active{ color:var(--good, #1E8E3E); font-weight:700; }
.status-rejected, .status-dismissed, .status-closed{ color:var(--danger, #C00000); font-weight:700; }

.empty{ text-align:center; padding:50px 20px; color:var(--muted-soft, rgba(10,10,10,0.4)); font-size:14px; }
.badge{ display:inline-block; font-size:11px; font-weight:600; padding:3px 10px; border-radius:999px; background:var(--surface, rgba(10,10,10,0.03)); color:var(--muted, rgba(10,10,10,0.55)); margin-inline-start:4px; }
.badge.danger{ background:var(--danger-bg, #FDECEC); color:var(--danger, #C00000); }
.badge.good{ background:var(--good-bg, #EAF7EE); color:var(--good, #1E8E3E); }

::selection{ background:var(--ink, #0A0A0A); color:#fff; }
@media (max-width:720px){
  body{ padding:14px; }
  .topbar{ margin-bottom:16px; padding-bottom:14px; }
  table{ display:block; overflow-x:auto; -webkit-overflow-scrolling:touch; border-radius: var(--radius-sm, 10px); }
  button.act{ min-height:38px; }
}

/* ---------- user detail modal ---------- */
.u-overlay{
  display:none; position:fixed; inset:0; width:100vw; height:100vh; background:rgba(10,10,10,.5);
  align-items:center; justify-content:center; z-index:99; padding:20px;
  backdrop-filter: blur(2px); animation: fadeIn .18s var(--ease, cubic-bezier(.22,1,.36,1)) both;
}
.u-overlay.show{ display:flex; }
.u-modal{
  background:var(--bg, #FFFFFF); border-radius: var(--radius, 14px); width:100%; max-width:540px;
  max-height:85vh; display:flex; flex-direction:column; box-shadow: var(--shadow-md, 0 6px 20px rgba(10,10,10,0.07), 0 2px 6px rgba(10,10,10,0.04));
  animation: popIn .22s var(--ease, cubic-bezier(.22,1,.36,1)) both; overflow:hidden;
}
@keyframes popIn{ from{ opacity:0; transform:scale(.96) translateY(8px);} to{ opacity:1; transform:none; } }
.u-modal-head{
  display:flex; align-items:center; justify-content:space-between; padding:16px 20px;
  border-bottom:1px solid var(--line, rgba(10,10,10,0.12)); font-weight:700; font-size:14.5px; flex-shrink:0;
}
.u-close{
  border:none; background:var(--surface, rgba(10,10,10,0.03)); width:30px; height:30px; border-radius:999px;
  display:flex; align-items:center; justify-content:center; cursor:pointer; transition: background .18s var(--ease, cubic-bezier(.22,1,.36,1));
}
.u-close svg{ width:15px; height:15px; stroke:var(--ink, #0A0A0A); fill:none; stroke-width:2; }
.u-close:hover{ background:var(--line, rgba(10,10,10,0.12)); }
.u-modal-body{ padding:18px 20px 22px; overflow-y:auto; scrollbar-width:thin; scrollbar-color: var(--line-strong, rgba(10,10,10,0.22)) transparent; }
.u-modal-body::-webkit-scrollbar{ width:7px; }
.u-modal-body::-webkit-scrollbar-track{ background:transparent; }
.u-modal-body::-webkit-scrollbar-thumb{ background: var(--line-strong, rgba(10,10,10,0.22)); border-radius:999px; }
html{ scrollbar-width:thin; scrollbar-color: var(--line-strong, rgba(10,10,10,0.22)) transparent; }
html::-webkit-scrollbar{ width:8px; }
html::-webkit-scrollbar-track{ background:transparent; }
html::-webkit-scrollbar-thumb{ background: var(--line-strong, rgba(10,10,10,0.22)); border-radius:999px; }
.u-name{ margin:0 0 14px; font-size:17px; font-weight:800; }
.u-row{
  display:flex; align-items:center; flex-wrap:wrap; gap:6px 10px; padding:8px 0;
  border-bottom:1px solid var(--line, rgba(10,10,10,0.12)); font-size:13.5px;
}
.u-row:last-of-type{ border-bottom:none; }
.u-lbl{ font-weight:700; color:var(--muted, rgba(10,10,10,0.55)); min-width:110px; flex-shrink:0; }
.u-inline{ display:flex; align-items:center; flex-wrap:wrap; gap:8px; }
.u-inline select{ padding:5px 8px; }
.u-idcard{ display:block; max-width:100%; max-height:220px; border-radius: var(--radius-sm, 10px); margin:10px 0; cursor:pointer; }
.u-actions{ display:flex; flex-wrap:wrap; gap:8px; margin:12px 0; }
.u-hr{ border:none; border-top:1px solid var(--line, rgba(10,10,10,0.12)); margin:16px 0; }
.u-block-lbl{ font-weight:700; color:var(--muted, rgba(10,10,10,0.55)); font-size:13px; margin-bottom:6px; }
.u-list{ margin:0 0 4px; padding-inline-start:20px; font-size:13px; }
.u-list li{ margin-bottom:5px; }
@media (max-width:480px){
  .u-lbl{ min-width:100%; }
}
</style>
</head>
<body>

<div class="page-wrap">
<div class="topbar">
  <h2 style="margin:0;">لوحة الأدمن</h2>
</div>

<div class="filters" id="main-tabs">
  <button data-t="overview" class="active" onclick="setTab('overview')">نظرة عامة</button>
  <button data-t="users" onclick="setTab('users')">كل المستخدمين</button>
  <button data-t="projects" onclick="setTab('projects')">كل المشاريع</button>
  <button data-t="verif" onclick="setTab('verif')">توثيق الهوية</button>
  <button data-t="reports" onclick="setTab('reports')">البلاغات <span id="reports-badge"></span></button>
  <button data-t="backups" onclick="setTab('backups')">النسخ الاحتياطية</button>
</div>

<div id="tab-overview"><div class="stats" id="overview-stats"></div></div>

<div id="tab-users" style="display:none">
  <div class="filters">
    <input type="text" id="search" placeholder="دوّر بالاسم أو الإيميل..." oninput="renderUsers()">
    <button data-rf="all" class="active" onclick="setRoleFilter('all')">الكل</button>
    <button data-rf="owner" onclick="setRoleFilter('owner')">أصحاب مشاريع</button>
    <button data-rf="investor" onclick="setRoleFilter('investor')">مستثمرين</button>
    <button data-rf="suspended" onclick="setRoleFilter('suspended')">موقوفين</button>
  </div>
  <table><thead><tr><th>الاسم</th><th>الإيميل / الهاتف</th><th>الدور</th><th>التوثيق</th><th>مشاريعه</th><th>بلاغات ضده</th><th>الحالة</th><th>تاريخ التسجيل</th></tr></thead>
  <tbody id="users-rows"></tbody></table>
</div>

<div id="tab-projects" style="display:none">
  <div class="filters">
    <button data-pf="all" class="active" onclick="setProjFilter('all')">الكل</button>
    <button data-pf="active" onclick="setProjFilter('active')">شغالة</button>
    <button data-pf="closed" onclick="setProjFilter('closed')">مقفولة</button>
    <button data-pf="featured" onclick="setProjFilter('featured')">مميّزة</button>
  </div>
  <table><thead><tr><th>المشروع</th><th>صاحبه</th><th>القطاع</th><th>الهدف</th><th>النوايا</th><th>الحالة</th><th>إجراءات</th></tr></thead>
  <tbody id="projects-rows"></tbody></table>
</div>

<div id="tab-verif" style="display:none">
  <div class="filters" id="filters">
    <button data-f="pending" class="active" onclick="setFilter('pending')">قيد الانتظار</button>
    <button data-f="approved" onclick="setFilter('approved')">موثّقين</button>
    <button data-f="rejected" onclick="setFilter('rejected')">مرفوضين</button>
    <button data-f="all" onclick="setFilter('all')">الكل</button>
  </div>
  <table><thead><tr><th>الاسم</th><th>الإيميل</th><th>الدور</th><th>البطاقة</th><th>الحالة</th><th>إجراء</th></tr></thead>
  <tbody id="rows"></tbody></table>
</div>

<div id="tab-reports" style="display:none">
  <div class="filters" id="report-filters">
    <button data-f="open" class="active" onclick="setReportFilter('open')">مفتوحة</button>
    <button data-f="resolved" onclick="setReportFilter('resolved')">اتحلّت</button>
    <button data-f="dismissed" onclick="setReportFilter('dismissed')">اتجاهلت</button>
    <button data-f="all" onclick="setReportFilter('all')">الكل</button>
  </div>
  <table><thead><tr><th>المُبلَّغ عنه</th><th>السبب</th><th>التفاصيل</th><th>المُبلِّغ</th><th>الحالة</th><th>إجراء</th></tr></thead>
  <tbody id="report-rows"></tbody></table>
</div>

<div id="tab-backups" style="display:none">
  <button onclick="runBackup()" style="margin-bottom:12px; padding:8px 16px; cursor:pointer; border-radius:6px; border:1px solid #999;"><svg viewBox="0 0 24 24" style="width:14px;height:14px;vertical-align:-2px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-inline-end:3px"><path d="M3 7l9-4 9 4-9 4-9-4z"/><path d="M3 7v10l9 4 9-4V7"/><path d="M12 11v10"/></svg> اعمل نسخة دلوقتي</button>
  <table><thead><tr><th>الملف</th><th>الحجم</th><th>التاريخ</th><th>تحميل</th></tr></thead>
  <tbody id="backup-rows"></tbody></table>
</div>

</div>

<div id="user-overlay" class="u-overlay" onclick="if(event.target===this) hideUserOverlay();">
  <div class="u-modal">
    <div class="u-modal-head">
      <span>تفاصيل المستخدم</span>
      <button class="u-close" onclick="hideUserOverlay()" aria-label="إغلاق">
        <svg viewBox="0 0 24 24"><path d="M6 6l12 12M18 6L6 18"/></svg>
      </button>
    </div>
    <div class="u-modal-body" id="user-detail"></div>
  </div>
</div>

<script>
let allRows = [], allReports = [], allUsers = [], allProjects = [];
let filter = 'pending', reportFilter = 'open', roleFilter = 'all', projFilter = 'all';
async function api(path, opts={}){
  let res;
  try{
    res = await fetch(path, opts);
  }catch(e){
    throw new Error('فشل الاتصال بالسيرفر');
  }
  if(!res.ok) throw new Error('فشل: ' + path);
  return res.json();
}

function showUserOverlay(){
  document.getElementById('user-overlay').classList.add('show');
  document.body.style.overflow = 'hidden';
}
function hideUserOverlay(){
  document.getElementById('user-overlay').classList.remove('show');
  document.body.style.overflow = '';
}
function setTab(t){
  document.querySelectorAll('#main-tabs button[data-t]').forEach(b=>b.classList.toggle('active', b.dataset.t===t));
  ['overview','users','projects','verif','reports','backups'].forEach(id=>{
    document.getElementById('tab-'+id).style.display = (id===t) ? 'block' : 'none';
  });
}
function setFilter(f){ filter=f; document.querySelectorAll('#filters button').forEach(b=>b.classList.toggle('active', b.dataset.f===f)); renderRows(); }
function setReportFilter(f){ reportFilter=f; document.querySelectorAll('#report-filters button').forEach(b=>b.classList.toggle('active', b.dataset.f===f)); renderReports(); }
function setRoleFilter(f){ roleFilter=f; document.querySelectorAll('#tab-users button[data-rf]').forEach(b=>b.classList.toggle('active', b.dataset.rf===f)); renderUsers(); }
function setProjFilter(f){ projFilter=f; document.querySelectorAll('#tab-projects button[data-pf]').forEach(b=>b.classList.toggle('active', b.dataset.pf===f)); renderProjects(); }

async function load(){
  let ov;
  try{
    ov = await api('/api/admin/overview');
  }catch(e){ alert(e.message || 'خطأ في التحميل'); return; }
  renderOverview(ov);
  try{ allUsers = await api('/api/admin/users'); renderUsers(); }catch(e){}
  try{ allProjects = await api('/api/admin/projects'); renderProjects(); }catch(e){}
  try{ allRows = await api('/api/admin/id-verifications'); renderRows(); }catch(e){}
  try{
    allReports = await api('/api/admin/reports');
    const openCount = allReports.filter(r=>r.status==='open').length;
    document.getElementById('reports-badge').textContent = openCount ? `(${openCount})` : '';
    renderReports();
  }catch(e){}
  try{ renderBackups(await api('/api/admin/backups')); }catch(e){}
}

function renderOverview(ov){
  document.getElementById('overview-stats').innerHTML = `
    <div class="stat"><b>${ov.usersTotal}</b>إجمالي المستخدمين</div>
    <div class="stat"><b>${ov.usersVerified}</b>موثّقين</div>
    <div class="stat"><b>${ov.usersSuspended}</b>موقوفين</div>
    <div class="stat"><b>${ov.usersByRole.owner||0}</b>أصحاب مشاريع</div>
    <div class="stat"><b>${ov.usersByRole.investor||0}</b>مستثمرين</div>
    <div class="stat"><b>${ov.signups7d}</b>تسجيل جديد (٧ أيام)</div>
    <div class="stat"><b>${ov.projectsTotal}</b>إجمالي المشاريع</div>
    <div class="stat"><b>${ov.projectsActive}</b>مشاريع شغالة</div>
    <div class="stat"><b>${ov.projectsClosed}</b>مشاريع مقفولة</div>
    <div class="stat"><b>${ov.interestsTotal}</b>تسجيل نية</div>
    <div class="stat"><b><bdi dir="ltr">${Math.round(ov.interestsAmount).toLocaleString('ar-EG')}</bdi></b>إجمالي النوايا (جنيه)</div>
    <div class="stat"><b>${ov.appointmentsTotal}</b>مواعيد محجوزة</div>
    <div class="stat"><b>${ov.pendingIdReviews}</b>توثيق قيد الانتظار</div>
    <div class="stat"><b>${ov.reportsOpen}</b>بلاغات مفتوحة</div>
  `;
}

function renderUsers(){
  const q = (document.getElementById('search').value||'').trim().toLowerCase();
  let rows = allUsers;
  if(roleFilter==='suspended') rows = rows.filter(u=>!u.active);
  else if(roleFilter!=='all') rows = rows.filter(u=>u.role===roleFilter || u.role==='both');
  if(q) rows = rows.filter(u => (u.name||'').toLowerCase().includes(q) || (u.email||'').toLowerCase().includes(q));
  const roleLabel = { owner:'صاحب مشروع', investor:'مستثمر', both:'الاتنين', broker:'وسيط' };
  if(!rows.length){ document.getElementById('users-rows').innerHTML = `<tr><td colspan="8" class="empty">مفيش نتائج</td></tr>`; return; }
  document.getElementById('users-rows').innerHTML = rows.map(u => `
    <tr>
      <td><a href="#" onclick="openUser('${u.id}');return false;">${u.name}</a></td>
      <td>${u.email}<br><small>${u.phone||''}</small></td>
      <td>${roleLabel[u.role]||u.role}</td>
      <td>${u.id_verified ? '<span class="badge good">موثّق</span>' : `<span class="badge">${idStatusLabel[u.id_status]||u.id_status}</span>`}</td>
      <td>${u.projects_count}</td>
      <td>${u.reports_count ? `<span class="badge danger">${u.reports_count}</span>` : '0'}</td>
      <td>${u.active ? 'نشط' : '<span class="badge danger">موقوف</span>'}</td>
      <td>${new Date(u.created_at*1000).toLocaleDateString('ar-EG')}</td>
    </tr>
  `).join('');
}

function renderProjects(){
  let rows = allProjects;
  if(projFilter==='active') rows = rows.filter(p=>p.status==='active');
  else if(projFilter==='closed') rows = rows.filter(p=>p.status==='closed');
  else if(projFilter==='featured') rows = rows.filter(p=>p.featuredActive);
  if(!rows.length){ document.getElementById('projects-rows').innerHTML = `<tr><td colspan="7" class="empty">مفيش مشاريع</td></tr>`; return; }
  document.getElementById('projects-rows').innerHTML = rows.map(p => `
    <tr>
      <td><a href="project.html?id=${p.id}" target="_blank">${p.name}</a> ${p.featuredActive?`<span class="badge good">مميّز${p.featured_until ? ' — باقيله ' + Math.max(0, Math.ceil((p.featured_until - Date.now()/1000)/86400)) + ' يوم' : ''}</span>`:''}</td>
      <td><a href="#" onclick="openUser('${p.owner_id}');return false;">${p.owner_name}</a></td>
      <td>${p.sector}</td>
      <td><bdi dir="ltr">${Math.round(p.target).toLocaleString('ar-EG')} ج</bdi></td>
      <td>${p.interests_count} (<bdi dir="ltr">${Math.round(p.interests_amount).toLocaleString('ar-EG')} ج</bdi>)</td>
      <td class="status-${p.status}">${p.status==='closed'?'مقفول':'شغال'}</td>
      <td>
        ${p.featuredActive
          ? `<button class="act" onclick="projAct('${p.id}','unfeature')">إلغاء التمييز</button>`
          : `<button class="act approve" onclick="projAct('${p.id}','feature')">تمييز <svg viewBox="0 0 24 24" style="width:14px;height:14px;vertical-align:-2px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-inline-end:3px"><path d="M12 3l2.6 5.7 6.2.6-4.7 4.2 1.4 6.2L12 16.9 6.5 19.7l1.4-6.2L3.2 9.3l6.2-.6z"/></svg></button>`}
        ${p.status==='closed'
          ? `<button class="act" onclick="projAct('${p.id}','reopen')">فتح تاني</button>`
          : `<button class="act" onclick="projAct('${p.id}','close')">قفل</button>`}
        <button class="act reject" onclick="projAct('${p.id}','delete')">حذف نهائي <svg viewBox="0 0 24 24" style="width:14px;height:14px;vertical-align:-2px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-inline-end:3px"><path d="M5 7h14M9 7V4h6v3"/><path d="M7 7l1 13h8l1-13"/></svg>️</button>
      </td>
    </tr>
  `).join('');
}

async function projAct(id, action){
  if(action==='delete' && !confirm('حذف نهائي للمشروع وكل بياناته (النوايا والمواعيد والرسائل)، الإجراء ده مايترجعش. متأكد؟')) return;
  let query = '';
  if(action === 'feature'){
    const input = prompt('تمييز المشروع لمدة كام يوم؟ (1-90)', '14');
    if(input === null) return; // المستخدم عمل إلغاء
    const days = Number(input);
    if(!days || days < 1 || days > 90){ alert('لازم رقم بين 1 و90'); return; }
    query = `?days=${days}`;
  }
  try{ await api(`/api/admin/projects/${id}/${action}${query}`, { method:'POST' }); allProjects = await api('/api/admin/projects'); renderProjects(); }
  catch(e){ alert('فشل الإجراء'); }
}

function renderBackups(files){
  if(!files.length){ document.getElementById('backup-rows').innerHTML = `<tr><td colspan="4" class="empty">لسه مفيش نسخ احتياطية</td></tr>`; return; }
  document.getElementById('backup-rows').innerHTML = files.map(f => `
    <tr>
      <td>${f.name}</td>
      <td>${(f.size/1024).toFixed(1)} KB</td>
      <td>${new Date(f.created_at*1000).toLocaleString('ar-EG')}</td>
      <td><a href="/api/admin/backups/${f.name}">تحميل</a></td>
    </tr>
  `).join('');
}

async function runBackup(){
  try{ await api('/api/admin/backups/run', { method:'POST' }); renderBackups(await api('/api/admin/backups')); }
  catch(e){ alert('فشل عمل النسخة'); }
}

const idStatusLabel = { pending:'قيد الانتظار', approved:'موثّق', rejected:'مرفوض', none:'لسه ملقدمش' };
const reportStatusLabel = { open:'مفتوحة', resolved:'اتحلّت', dismissed:'اتجاهلت' };

function renderRows(){
  const roleLabel = { owner:'صاحب مشروع', investor:'مستثمر', both:'الاتنين' };
  const rows = filter === 'all' ? allRows : allRows.filter(r => r.id_status === filter);
  if(!rows.length){ document.getElementById('rows').innerHTML = `<tr><td colspan="6" class="empty">مفيش طلبات في القسم ده</td></tr>`; return; }
  document.getElementById('rows').innerHTML = rows.map(r => `
    <tr>
      <td><a href="#" onclick="openUser('${r.id}');return false;">${r.name}</a></td>
      <td>${r.email}<br><small>${r.phone||''}</small></td>
      <td>${roleLabel[r.role]||r.role}</td>
      <td>${(r.id_card && r.id_card !== 'none') ? `<img src="/api/admin/id-card/${r.id_card}" onclick="window.open(this.src)" onerror="this.style.display='none'; this.insertAdjacentHTML('afterend','—');">` : '—'}</td>
      <td class="status-${r.id_status}">${idStatusLabel[r.id_status]||r.id_status}</td>
      <td>
        <button class="act approve" ${r.id_status==='approved'?'disabled':''} onclick="act('${r.id}','approve')">توثيق <svg viewBox="0 0 24 24" style="width:14px;height:14px;vertical-align:-2px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-inline-end:3px"><path d="M5 13l4 4L19 7"/></svg></button>
        <button class="act reject" ${r.id_status==='rejected'?'disabled':''} onclick="act('${r.id}','reject')">رفض <svg viewBox="0 0 24 24" style="width:14px;height:14px;vertical-align:-2px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-inline-end:3px"><path d="M6 6l12 12M18 6L6 18"/></svg></button>
      </td>
    </tr>
  `).join('');
}

async function act(userId, action){
  if(action==='reject' && !confirm('متأكد إنك عايز ترفض التوثيق ده؟')) return;
  try{ await api(`/api/admin/id-verifications/${userId}/${action}`, { method:'POST' }); load(); }
  catch(e){ alert('فشل الإجراء'); }
}

function renderReports(){
  const rows = reportFilter === 'all' ? allReports : allReports.filter(r => r.status === reportFilter);
  if(!rows.length){ document.getElementById('report-rows').innerHTML = `<tr><td colspan="6" class="empty">مفيش بلاغات في القسم ده</td></tr>`; return; }
  document.getElementById('report-rows').innerHTML = rows.map(r => `
    <tr>
      <td>${r.target_user_id ? `<a href="#" onclick="openUser('${r.target_user_id}');return false;">${r.target_name||r.target_user_id}</a>${r.target_active===0?' <small style="color:#c00;">(موقوف)</small>':''}` : (r.project_name || '—')}</td>
      <td>${r.reason}</td>
      <td>${r.details||'—'}</td>
      <td>${r.reporter_name||'زائر'}${r.reporter_email?`<br><small>${r.reporter_email}</small>`:''}</td>
      <td class="status-${r.status}">${reportStatusLabel[r.status]||r.status}</td>
      <td>
        ${r.status!=='resolved'?`<button class="act approve" onclick="reportAct('${r.id}','resolve')">اتحل <svg viewBox="0 0 24 24" style="width:14px;height:14px;vertical-align:-2px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-inline-end:3px"><path d="M5 13l4 4L19 7"/></svg></button>`:''}
        ${r.status!=='dismissed'?`<button class="act reject" onclick="reportAct('${r.id}','dismiss')">تجاهل <svg viewBox="0 0 24 24" style="width:14px;height:14px;vertical-align:-2px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-inline-end:3px"><path d="M6 6l12 12M18 6L6 18"/></svg></button>`:''}
        ${r.status!=='open'?`<button class="act" onclick="reportAct('${r.id}','reopen')">فتح تاني</button>`:''}
      </td>
    </tr>
  `).join('');
}

async function reportAct(reportId, action){
  try{ await api(`/api/admin/reports/${reportId}/${action}`, { method:'POST' }); load(); }
  catch(e){ alert('فشل الإجراء'); }
}

async function openUser(userId){
  let u;
  try{ u = await api(`/api/admin/users/${userId}`); }
  catch(e){ alert('تعذر تحميل بيانات المستخدم'); return; }
  const roleLabel = { owner:'صاحب مشروع', investor:'مستثمر', both:'الاتنين', broker:'وسيط' };
  document.getElementById('user-detail').innerHTML = `
    <h3 class="u-name">${u.name} ${u.active?'':'<span class="badge danger">موقوف</span>'}</h3>
    <div class="u-row"><span class="u-lbl">الإيميل</span><span>${u.email}</span></div>
    <div class="u-row"><span class="u-lbl">الهاتف</span><span>${u.phone||'—'}</span></div>
    <div class="u-row">
      <span class="u-lbl">الدور</span>
      <span class="u-inline">
        ${roleLabel[u.role]||u.role}
        <select id="role-select">
          ${['owner','investor','both','broker'].map(r=>`<option value="${r}" ${r===u.role?'selected':''}>${roleLabel[r]}</option>`).join('')}
        </select>
        <button class="act" onclick="changeRole('${u.id}')">تغيير</button>
      </span>
    </div>
    <div class="u-row">
      <span class="u-lbl">توثيق الهوية</span>
      <span class="u-inline">${idStatusLabel[u.id_status]||u.id_status} ${u.id_verified?'<span class="badge good">موثّق <svg viewBox="0 0 24 24" style="width:14px;height:14px;vertical-align:-2px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-inline-end:3px"><path d="M5 13l4 4L19 7"/></svg></span>':''}</span>
    </div>
    ${(u.id_card && u.id_card !== 'none')?`<img class="u-idcard" src="/api/admin/id-card/${u.id_card}" onclick="window.open(this.src)" onerror="this.remove();">`:''}
    <div class="u-actions">
      ${u.id_verified
        ? `<button class="act reject" onclick="manualVerify('${u.id}', false)">إلغاء التوثيق</button>`
        : `<button class="act approve" onclick="manualVerify('${u.id}', true)">توثيق يدوي (من غير بطاقة) <svg viewBox="0 0 24 24" style="width:14px;height:14px;vertical-align:-2px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-inline-end:3px"><path d="M5 13l4 4L19 7"/></svg></button>`}
    </div>
    <div class="u-row"><span class="u-lbl">البايو</span><span>${u.bio||'—'}</span></div>
    <div class="u-row"><span class="u-lbl">تاريخ التسجيل</span><span>${new Date(u.created_at*1000).toLocaleDateString('ar-EG')}</span></div>
    <hr class="u-hr">
    <div class="u-row"><span class="u-lbl">مشاريعه (${u.projects.length})</span><span>${u.projects.map(p=>p.name).join('، ')||'—'}</span></div>
    <div class="u-block-lbl">بلاغات ضده (${u.reportsAgainst.length})</div>
    <ul class="u-list">${u.reportsAgainst.map(r=>`<li>${r.reason}${reportStatusLabel[r.status]||r.status}${r.details?` (${r.details})`:''}</li>`).join('')||'<li>لا يوجد</li>'}</ul>
    <hr class="u-hr">
    <div class="u-actions">
      ${u.active
        ? `<button class="act reject" onclick="toggleUser('${u.id}','suspend')"><svg viewBox="0 0 24 24" style="width:14px;height:14px;vertical-align:-2px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-inline-end:3px"><circle cx="12" cy="12" r="9"/><path d="M6 6l12 12"/></svg> إيقاف الحساب</button>`
        : `<button class="act approve" onclick="toggleUser('${u.id}','unsuspend')"><svg viewBox="0 0 24 24" style="width:14px;height:14px;vertical-align:-2px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-inline-end:3px"><path d="M5 13l4 4L19 7"/></svg> إعادة تفعيل الحساب</button>`}
      <button class="act" onclick="resetUserPassword('${u.id}')"><svg viewBox="0 0 24 24" style="width:14px;height:14px;vertical-align:-2px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-inline-end:3px"><circle cx="8" cy="15" r="4"/><path d="M11 12l9-9M17 6l3 3M14 9l2 2"/></svg> عمل كلمة مرور جديدة</button>
    </div>
  `;
  showUserOverlay();
}

async function changeRole(userId){
  const role = document.getElementById('role-select').value;
  try{ await api(`/api/admin/users/${userId}/set-role`, { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({role}) }); openUser(userId); allUsers = await api('/api/admin/users'); renderUsers(); }
  catch(e){ alert('فشل تغيير الدور'); }
}

async function manualVerify(userId, verified){
  if(!confirm(verified ? 'توثيق يدوي من غير مراجعة بطاقة — استخدمه بس لو اتأكدت من هوية الشخص بطريقة تانية. متأكد؟' : 'إلغاء التوثيق؟')) return;
  try{ await api(`/api/admin/users/${userId}/verify-manual`, { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({verified}) }); openUser(userId); load(); }
  catch(e){ alert('فشل الإجراء'); }
}

async function resetUserPassword(userId){
  if(!confirm('ده إجراء استثنائي — استخدمه بس بعد ما تتأكد من هوية صاحب الحساب يدويًا (واتساب/إيميل). متأكد؟')) return;
  let d;
  try{ d = await api(`/api/admin/users/${userId}/reset-password`, { method:'POST' }); }
  catch(e){ alert('فشل الإجراء'); return; }
  alert(`كلمة المرور المؤقتة: ${d.tempPassword}\nكود الاسترجاع الجديد: ${d.recoveryCode}\n\nابعتهم لصاحب الحساب على طول (واتساب/إيميل) — مش هيتعرضوا تاني.`);
}

async function toggleUser(userId, action){
  const msg = action==='suspend' ? 'متأكد إنك عايز توقف الحساب ده؟ هيتقفل خروجه فورًا.' : 'تفعيل الحساب تاني؟';
  if(!confirm(msg)) return;
  try{ await api(`/api/admin/users/${userId}/${action}`, { method:'POST' }); hideUserOverlay(); load(); }
  catch(e){ alert('فشل الإجراء'); }
}

load();
</script>
</body>
</html>