···
1
1
/* src/components/Admin/AdminPanel.css */
2
2
.admin-panel {
3
3
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
3
3
+
font-family: "articulat-cf", sans-serif;
4
4
max-width: 1200px;
5
5
margin: 0 auto;
6
6
padding: 20px;
7
7
-
color: #333;
7
7
+
color: var(--text);
8
8
+
background-color: var(--background);
9
9
+
transition: color 0.3s ease, background-color 0.3s ease;
8
10
}
9
11
10
12
/* Header */
···
14
16
align-items: center;
15
17
margin-bottom: 20px;
16
18
padding-bottom: 10px;
17
17
-
border-bottom: 1px solid #eee;
19
19
+
margin-top: 20px;
18
20
}
19
21
20
22
.admin-header h1 {
21
23
margin: 0;
22
22
-
color: #333;
23
23
-
font-size: 24px;
24
24
+
color: var(--button-bg);
25
25
+
font-size: 2.1em;
26
26
+
font-weight: 800;
24
27
}
25
28
26
29
/* Container layout */
···
33
36
34
37
/* Resources sidebar */
35
38
.resources-sidebar {
36
36
-
background-color: #f8f9fa;
39
39
+
background-color: var(--navbar-bg);
37
40
border-radius: 8px;
41
41
+
border: 1px solid var(--card-border);
38
42
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
39
39
-
overflow: hidden;
40
43
display: flex;
41
44
flex-direction: column;
42
42
-
height: 100%;
45
45
+
height: 93.8%;
46
46
+
overflow: hidden;
47
47
+
padding: 10px;
48
48
+
transition: background-color 0.3s ease, border-color 0.3s ease;
43
49
}
44
50
45
51
.sidebar-header {
···
47
53
justify-content: space-between;
48
54
align-items: center;
49
55
padding: 15px;
50
50
-
background-color: #f0f2f5;
51
51
-
border-bottom: 1px solid #ddd;
56
56
+
background-color: var(--navbar-bg);
57
57
+
border-bottom: 1px solid var(--card-border);
58
58
+
transition: background-color 0.3s ease, border-color 0.3s ease;
52
59
}
53
60
54
61
.sidebar-header h2 {
55
62
margin: 0;
56
63
font-size: 18px;
64
64
+
color: var(--text);
57
65
}
58
66
59
67
.sidebar-filters {
60
68
padding: 10px 15px;
61
61
-
border-bottom: 1px solid #ddd;
62
62
-
background-color: #f8f9fa;
69
69
+
border-bottom: 1px solid var(--card-border);
70
70
+
background-color: var(--navbar-bg);
71
71
+
transition: background-color 0.3s ease, border-color 0.3s ease;
63
72
}
64
73
65
74
.filter-group {
···
69
78
.search-input {
70
79
width: 100%;
71
80
padding: 8px;
72
72
-
border: 1px solid #ddd;
81
81
+
border: 1px solid var(--card-border);
73
82
border-radius: 4px;
74
83
font-size: 14px;
75
84
margin-bottom: 8px;
85
85
+
background-color: var(--navbar-bg);
86
86
+
color: var(--text);
87
87
+
transition: all 0.3s ease;
88
88
+
}
89
89
+
90
90
+
.search-input:hover,
91
91
+
.search-input:focus {
92
92
+
border-color: var(--button-bg);
93
93
+
background-color: var(--background);
76
94
}
77
95
78
96
.status-filter,
79
97
.completeness-filter {
80
98
width: 49%;
81
99
padding: 6px;
82
82
-
border: 1px solid #ddd;
100
100
+
border: 1px solid var(--card-border);
83
101
border-radius: 4px;
84
102
font-size: 13px;
85
103
margin-right: 2%;
104
104
+
background-color: var(--navbar-bg);
105
105
+
color: var(--text);
106
106
+
transition: all 0.3s ease;
107
107
+
}
108
108
+
109
109
+
.status-filter:hover,
110
110
+
.completeness-filter:hover,
111
111
+
.status-filter:focus,
112
112
+
.completeness-filter:focus {
113
113
+
border-color: var(--button-bg);
114
114
+
background-color: var(--background);
86
115
}
87
116
88
117
.completeness-filter {
···
98
127
display: flex;
99
128
flex-direction: column;
100
129
padding: 0;
101
101
-
border-bottom: 1px solid #eee;
130
130
+
border-bottom: 1px solid var(--card-border);
102
131
cursor: pointer;
103
132
transition: background-color 0.2s;
104
133
position: relative;
134
134
+
color: var(--text);
105
135
}
106
136
107
137
.resource-completeness-indicator {
108
138
height: 3px;
109
139
width: 100%;
110
110
-
background-color: #f0f0f0;
140
140
+
background-color: var(--card-border);
111
141
}
112
142
113
143
.completeness-bar {
···
123
153
}
124
154
125
155
.resource-item:hover {
126
126
-
background-color: #f0f2f5;
156
156
+
background-color: var(--background);
127
157
}
128
158
129
159
.resource-item.selected {
130
130
-
background-color: #e6f7ff;
131
131
-
border-left: 3px solid #1890ff;
160
160
+
background-color: rgba(59, 154, 248, 0.1);
161
161
+
border-left: 3px solid var(--button-bg);
132
162
}
133
163
134
164
.resource-item.status-draft .completeness-bar {
···
166
196
}
167
197
168
198
.status-badge.status-draft {
169
169
-
background-color: #fff7e6;
199
199
+
background-color: rgba(250, 173, 20, 0.2);
170
200
color: #faad14;
171
201
border: 1px solid #faad14;
172
202
}
173
203
174
204
.status-badge.status-review {
175
175
-
background-color: #e6f7ff;
205
205
+
background-color: rgba(24, 144, 255, 0.2);
176
206
color: #1890ff;
177
207
border: 1px solid #1890ff;
178
208
}
179
209
180
210
.status-badge.status-published {
181
181
-
background-color: #f6ffed;
211
211
+
background-color: rgba(82, 196, 26, 0.2);
182
212
color: #52c41a;
183
213
border: 1px solid #52c41a;
184
214
}
185
215
186
216
.featured-badge {
187
187
-
background-color: #f9f0ff;
217
217
+
background-color: rgba(114, 46, 209, 0.2);
188
218
color: #722ed1;
189
219
border: 1px solid #722ed1;
190
220
padding: 2px 6px;
···
206
236
207
237
/* Resource editor */
208
238
.resource-editor {
209
209
-
background-color: #fff;
239
239
+
background-color: var(--navbar-bg);
210
240
border-radius: 8px;
241
241
+
border: 1px solid var(--card-border);
211
242
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
212
243
padding: 20px;
244
244
+
height: 92%;
213
245
overflow-y: auto;
214
214
-
height: 100%;
246
246
+
transition: background-color 0.3s ease, border-color 0.3s ease;
247
247
+
color: var(--text);
215
248
}
216
249
217
250
.editor-header {
251
251
+
margin-bottom: 20px;
218
252
display: flex;
219
253
justify-content: space-between;
220
254
align-items: center;
221
221
-
margin-bottom: 20px;
222
222
-
padding-bottom: 15px;
223
223
-
border-bottom: 1px solid #eee;
255
255
+
}
256
256
+
257
257
+
.resource-editor input {
258
258
+
margin: 0px;
224
259
}
225
260
226
261
.editor-header h2 {
227
262
margin: 0;
228
228
-
color: #333;
263
263
+
color: var(--text);
229
264
}
230
265
231
266
.floating-actions {
···
235
270
}
236
271
237
272
.floating-save-button {
238
238
-
background-color: #52c41a;
239
239
-
color: white;
273
273
+
background-color: var(--button-bg);
274
274
+
color: var(--button-text);
240
275
padding: 8px 16px;
241
276
border-radius: 4px;
242
242
-
font-weight: 500;
277
277
+
font-weight: 700;
278
278
+
font-size: 0.9em;
279
279
+
transition: background-color 0.3s ease;
243
280
}
244
281
245
282
.floating-save-button:hover {
246
246
-
background-color: #73d13d;
283
283
+
background-color: #004F84;
247
284
}
248
285
249
286
.status-selector {
···
254
291
255
292
.status-selector span {
256
293
font-weight: 500;
257
257
-
color: #555;
294
294
+
color: var(--text);
258
295
}
259
296
260
297
.status-buttons {
261
298
display: flex;
262
262
-
border: 1px solid #ddd;
299
299
+
border: 1px solid var(--card-border);
263
300
border-radius: 4px;
264
301
overflow: hidden;
265
302
}
266
303
267
304
.status-button {
268
305
padding: 6px 10px;
269
269
-
background-color: #f5f5f5;
306
306
+
background-color: var(--navbar-bg);
270
307
border: none;
271
271
-
border-right: 1px solid #ddd;
308
308
+
border-right: 1px solid var(--card-border);
272
309
cursor: pointer;
273
310
font-size: 13px;
311
311
+
color: var(--text);
312
312
+
transition: all 0.3s ease;
274
313
}
275
314
276
315
.status-button:last-child {
···
278
317
}
279
318
280
319
.status-button.active {
281
281
-
background-color: #1890ff;
282
282
-
color: white;
320
320
+
background-color: var(--button-bg);
321
321
+
color: var(--button-text);
322
322
+
}
323
323
+
324
324
+
.status-button:hover:not(.active) {
325
325
+
background-color: var(--background);
283
326
}
284
327
285
328
.resource-editor h2 {
286
329
margin-top: 0;
287
330
margin-bottom: 20px;
288
288
-
color: #333;
331
331
+
color: var(--text);
289
332
}
290
333
291
334
/* Form styling */
···
304
347
display: block;
305
348
margin-bottom: 5px;
306
349
font-weight: 500;
307
307
-
color: #555;
350
350
+
color: var(--text);
308
351
}
309
352
310
353
.form-group input[type="text"],
···
312
355
.form-group input[type="number"],
313
356
.form-group textarea {
314
357
width: 100%;
315
315
-
padding: 10px;
316
316
-
border: 1px solid #ddd;
358
358
+
border: 1px solid var(--card-border);
317
359
border-radius: 4px;
318
360
font-size: 14px;
361
361
+
background-color: var(--navbar-bg);
362
362
+
color: var(--text);
363
363
+
padding: 8px;
364
364
+
transition: all 0.3s ease;
365
365
+
}
366
366
+
367
367
+
.form-group input[type="text"]:hover,
368
368
+
.form-group input[type="url"]:hover,
369
369
+
.form-group input[type="number"]:hover,
370
370
+
.form-group textarea:hover,
371
371
+
.form-group input[type="text"]:focus,
372
372
+
.form-group input[type="url"]:focus,
373
373
+
.form-group input[type="number"]:focus,
374
374
+
.form-group textarea:focus {
375
375
+
border-color: var(--button-bg);
376
376
+
background-color: var(--background);
319
377
}
320
378
321
379
.form-group textarea {
···
340
398
/* Categories and Tags sections */
341
399
.categories-section,
342
400
.tags-section {
343
343
-
background-color: #f8f9fa;
401
401
+
background-color: var(--background);
344
402
border-radius: 6px;
345
403
padding: 15px;
346
346
-
border: 1px solid #eee;
404
404
+
border: 1px solid var(--card-border);
405
405
+
transition: background-color 0.3s ease, border-color 0.3s ease;
347
406
}
348
407
349
408
.section-header {
···
356
415
.section-header label {
357
416
font-weight: 600;
358
417
margin-bottom: 0;
418
418
+
color: var(--text);
359
419
}
360
420
361
421
.checkbox-list {
···
373
433
.checkbox-item label {
374
434
margin-bottom: 0;
375
435
font-weight: normal;
436
436
+
color: var(--text);
376
437
}
377
438
378
439
/* Form actions */
···
393
454
}
394
455
395
456
.add-new-button {
396
396
-
background-color: #1890ff;
397
397
-
color: white;
457
457
+
background-color: var(--button-bg);
458
458
+
color: var(--button-text);
398
459
padding: 6px 12px;
399
460
font-size: 13px;
461
461
+
font-weight: 700;
400
462
}
401
463
402
464
.add-new-button:hover {
403
403
-
background-color: #40a9ff;
465
465
+
background-color: #004F84;
404
466
}
405
467
406
468
.delete-button {
···
412
474
413
475
.delete-button:hover {
414
476
opacity: 1;
415
415
-
background-color: #ffebee;
477
477
+
background-color: rgba(244, 67, 54, 0.1);
416
478
}
417
479
418
480
.add-item-button {
419
419
-
background-color: #f5f5f5;
420
420
-
color: #333;
481
481
+
background-color: var(--navbar-bg);
482
482
+
color: var(--text);
421
483
padding: 4px 8px;
422
484
font-size: 12px;
423
423
-
border: 1px solid #ddd;
485
485
+
border: 1px solid var(--card-border);
486
486
+
transition: all 0.3s ease;
424
487
}
425
488
426
489
.add-item-button:hover {
427
427
-
background-color: #e0e0e0;
490
490
+
background-color: var(--background);
491
491
+
border-color: var(--button-bg);
428
492
}
429
493
430
494
.save-button {
431
431
-
background-color: #52c41a;
432
432
-
color: white;
495
495
+
background-color: var(--button-bg);
496
496
+
color: var(--button-text);
433
497
padding: 10px 20px;
498
498
+
font-weight: 700;
434
499
}
435
500
436
501
.save-button:hover {
437
437
-
background-color: #73d13d;
502
502
+
background-color: #004F84;
438
503
}
439
504
440
505
.cancel-button {
441
441
-
background-color: #f5f5f5;
442
442
-
color: #333;
506
506
+
background-color: var(--navbar-bg);
507
507
+
color: var(--text);
443
508
padding: 10px 20px;
444
444
-
border: 1px solid #d9d9d9;
509
509
+
border: 1px solid var(--card-border);
510
510
+
transition: all 0.3s ease;
445
511
}
446
512
447
513
.cancel-button:hover {
448
448
-
background-color: #e6e6e6;
514
514
+
background-color: var(--background);
515
515
+
border-color: var(--button-bg);
449
516
}
450
517
451
518
.logout-button {
452
452
-
background-color: #f5f5f5;
453
453
-
color: #333;
519
519
+
background-color: var(--navbar-bg);
520
520
+
color: var(--text);
454
521
padding: 8px 16px;
455
455
-
border: 1px solid #d9d9d9;
522
522
+
border: 1px solid var(--card-border);
523
523
+
transition: all 0.3s ease;
456
524
}
457
525
458
526
.logout-button:hover {
459
459
-
background-color: #e6e6e6;
527
527
+
background-color: var(--background);
528
528
+
border-color: var(--button-bg);
460
529
}
461
530
462
531
/* Alert messages */
···
468
537
}
469
538
470
539
.alert.success {
471
471
-
background-color: #f6ffed;
472
472
-
border: 1px solid #b7eb8f;
540
540
+
background-color: rgba(82, 196, 26, 0.1);
541
541
+
border: 1px solid #52c41a;
473
542
color: #52c41a;
474
543
}
475
544
476
545
.alert.error {
477
477
-
background-color: #fff2f0;
478
478
-
border: 1px solid #ffccc7;
546
546
+
background-color: rgba(245, 34, 45, 0.1);
547
547
+
border: 1px solid #f5222d;
479
548
color: #f5222d;
480
549
}
481
550
···
486
555
align-items: center;
487
556
justify-content: center;
488
557
height: 100vh;
558
558
+
color: var(--text);
559
559
+
background-color: var(--background);
489
560
}
490
561
491
562
.loading-spinner {
492
492
-
border: 4px solid #f3f3f3;
493
493
-
border-top: 4px solid #1890ff;
563
563
+
border: 4px solid var(--card-border);
564
564
+
border-top: 4px solid var(--button-bg);
494
565
border-radius: 50%;
495
566
width: 40px;
496
567
height: 40px;
···
509
580
justify-content: center;
510
581
align-items: center;
511
582
height: 100vh;
512
512
-
background-color: #f0f2f5;
583
583
+
background-color: var(--background);
584
584
+
transition: background-color 0.3s ease;
513
585
}
514
586
515
587
.admin-login-card {
516
516
-
background-color: white;
588
588
+
background-color: var(--navbar-bg);
517
589
border-radius: 8px;
590
590
+
border: 1px solid var(--card-border);
518
591
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
519
592
padding: 30px;
520
593
width: 100%;
521
594
max-width: 400px;
595
595
+
transition: background-color 0.3s ease, border-color 0.3s ease;
522
596
}
523
597
524
598
.admin-login-card h2 {
525
599
margin-top: 0;
526
600
margin-bottom: 20px;
527
601
text-align: center;
528
528
-
color: #333;
602
602
+
color: var(--text);
529
603
}
530
604
531
605
.login-button {
532
532
-
background-color: #1890ff;
533
533
-
color: white;
606
606
+
background-color: var(--button-bg);
607
607
+
color: var(--button-text);
534
608
padding: 10px 0;
535
609
width: 100%;
536
610
font-size: 16px;
537
611
margin-top: 10px;
612
612
+
font-weight: 700;
538
613
}
539
614
540
615
.login-button:hover {
541
541
-
background-color: #40a9ff;
616
616
+
background-color: #004F84;
542
617
}
543
618
544
619
.auth-error {
545
545
-
background-color: #fff2f0;
546
546
-
border: 1px solid #ffccc7;
620
620
+
background-color: rgba(245, 34, 45, 0.1);
621
621
+
border: 1px solid #f5222d;
547
622
color: #f5222d;
548
623
padding: 10px;
549
624
border-radius: 4px;
···
15
15
const [statusFilter, setStatusFilter] = useState('all');
16
16
const [searchQuery, setSearchQuery] = useState('');
17
17
const [completenessFilter, setCompletenessFilter] = useState(0);
18
18
+
const [darkMode, setDarkMode] = useState(false);
18
19
19
20
// Login state
20
21
const [email, setEmail] = useState('');
···
35
36
36
37
// Alert state
37
38
const [alert, setAlert] = useState({ show: false, message: '', type: '' });
39
39
+
40
40
+
// Check for dark mode preference on component mount
41
41
+
useEffect(() => {
42
42
+
// Check if dark mode is stored in localStorage
43
43
+
const storedDarkMode = localStorage.getItem('darkMode');
44
44
+
if (storedDarkMode) {
45
45
+
setDarkMode(storedDarkMode === 'true');
46
46
+
} else {
47
47
+
// Check system preference
48
48
+
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
49
49
+
setDarkMode(prefersDarkMode);
50
50
+
}
51
51
+
}, []);
52
52
+
53
53
+
// Apply dark mode class when darkMode state changes
54
54
+
useEffect(() => {
55
55
+
if (darkMode) {
56
56
+
document.body.classList.add('dark-mode');
57
57
+
} else {
58
58
+
document.body.classList.remove('dark-mode');
59
59
+
}
60
60
+
}, [darkMode]);
61
61
+
62
62
+
// Toggle dark mode
63
63
+
const toggleDarkMode = () => {
64
64
+
const newDarkMode = !darkMode;
65
65
+
setDarkMode(newDarkMode);
66
66
+
localStorage.setItem('darkMode', newDarkMode.toString());
67
67
+
};
38
68
39
69
// Fetch all required data from Supabase
40
70
const fetchAllData = useCallback(async () => {
···
524
554
// Render loading spinner
525
555
if (isLoading) {
526
556
return (
527
527
-
<div className="admin-loading">
557
557
+
<div className={`admin-loading ${darkMode ? 'dark-mode' : ''}`}>
528
558
<div className="loading-spinner"></div>
529
559
<p>Loading...</p>
530
560
</div>
···
534
564
// Render login form if not authenticated
535
565
if (!isAuthenticated) {
536
566
return (
537
537
-
<div className="admin-login-container">
567
567
+
<div className={`admin-login-container ${darkMode ? 'dark-mode' : ''}`}>
538
568
<div className="admin-login-card">
539
569
<h2>Admin Login</h2>
540
570
{authError && <div className="auth-error">{authError}</div>}
···
561
591
</div>
562
592
<button type="submit" className="login-button">Login</button>
563
593
</form>
594
594
+
<div style={{ marginTop: '20px', textAlign: 'center' }}>
595
595
+
<button
596
596
+
onClick={toggleDarkMode}
597
597
+
style={{
598
598
+
background: 'none',
599
599
+
border: 'none',
600
600
+
cursor: 'pointer',
601
601
+
fontSize: '1em',
602
602
+
color: 'var(--text)'
603
603
+
}}
604
604
+
>
605
605
+
{darkMode ? '☀️ Light Mode' : '🌙 Dark Mode'}
606
606
+
</button>
607
607
+
</div>
564
608
</div>
565
609
</div>
566
610
);
···
568
612
569
613
// Main admin panel UI
570
614
return (
571
571
-
<div className="admin-panel">
615
615
+
<div className={`admin-panel ${darkMode ? 'dark-mode' : ''}`}>
572
616
{/* Header */}
573
617
<header className="admin-header">
574
618
<h1>Resources Admin Panel</h1>
575
575
-
<button onClick={handleLogout} className="logout-button">Logout</button>
619
619
+
<div style={{ display: 'flex', gap: '10px', alignItems: 'center' }}>
620
620
+
<button
621
621
+
onClick={toggleDarkMode}
622
622
+
style={{
623
623
+
background: 'none',
624
624
+
border: '1px solid var(--card-border)',
625
625
+
borderRadius: '6px',
626
626
+
padding: '8px 12px',
627
627
+
cursor: 'pointer',
628
628
+
fontSize: '0.9em',
629
629
+
color: 'var(--text)',
630
630
+
display: 'flex',
631
631
+
alignItems: 'center',
632
632
+
gap: '5px'
633
633
+
}}
634
634
+
>
635
635
+
{darkMode ? '☀️ Light' : '🌙 Dark'}
636
636
+
</button>
637
637
+
<button onClick={handleLogout} className="logout-button">Logout</button>
638
638
+
</div>
576
639
</header>
577
640
578
641
{/* Alert message */}
···
626
689
</div>
627
690
</div>
628
691
<div className="resources-list">
629
629
-
{filteredResources.map(resource => (
630
630
-
<div
631
631
-
key={resource.id}
632
632
-
className={`resource-item ${selectedResource && selectedResource.id === resource.id ? 'selected' : ''} status-${resource.status}`}
633
633
-
onClick={() => handleSelectResource(resource)}
634
634
-
>
635
635
-
<div className="resource-completeness-indicator">
636
636
-
<div
637
637
-
className="completeness-bar"
638
638
-
style={{ width: `${resource.completeness}%` }}
639
639
-
title={`${resource.completeness}% complete`}
640
640
-
></div>
641
641
-
</div>
642
642
-
<div className="resource-item-content">
643
643
-
<div className="resource-item-name">{resource.name}</div>
644
644
-
<div className="resource-item-meta">
645
645
-
<span className={`status-badge status-${resource.status}`}>
646
646
-
{resource.status}
647
647
-
</span>
648
648
-
{resource.featured && <span className="featured-badge">Featured</span>}
692
692
+
{filteredResources.length > 0 ? (
693
693
+
filteredResources.map(resource => (
694
694
+
<div
695
695
+
key={resource.id}
696
696
+
className={`resource-item ${selectedResource && selectedResource.id === resource.id ? 'selected' : ''} status-${resource.status}`}
697
697
+
onClick={() => handleSelectResource(resource)}
698
698
+
>
699
699
+
<div className="resource-completeness-indicator">
700
700
+
<div
701
701
+
className="completeness-bar"
702
702
+
style={{ width: `${resource.completeness}%` }}
703
703
+
title={`${resource.completeness}% complete`}
704
704
+
></div>
705
705
+
</div>
706
706
+
<div className="resource-item-content">
707
707
+
<div className="resource-item-name">{resource.name}</div>
708
708
+
<div className="resource-item-meta">
709
709
+
<span className={`status-badge status-${resource.status}`}>
710
710
+
{resource.status}
711
711
+
</span>
712
712
+
{resource.featured && <span className="featured-badge">Featured</span>}
713
713
+
</div>
714
714
+
</div>
715
715
+
<div className="resource-item-actions">
716
716
+
<button
717
717
+
onClick={(e) => {
718
718
+
e.stopPropagation();
719
719
+
handleDeleteResource(resource.id, resource.name);
720
720
+
}}
721
721
+
className="delete-button"
722
722
+
title="Delete resource"
723
723
+
>
724
724
+
🗑️
725
725
+
</button>
649
726
</div>
650
727
</div>
651
651
-
<div className="resource-item-actions">
652
652
-
<button
653
653
-
onClick={(e) => {
654
654
-
e.stopPropagation();
655
655
-
handleDeleteResource(resource.id, resource.name);
656
656
-
}}
657
657
-
className="delete-button"
658
658
-
title="Delete resource"
659
659
-
>
660
660
-
🗑️
661
661
-
</button>
662
662
-
</div>
728
728
+
))
729
729
+
) : (
730
730
+
<div style={{ padding: '20px', textAlign: 'center', color: 'var(--text)', opacity: 0.7 }}>
731
731
+
No resources match your filters
663
732
</div>
664
664
-
))}
733
733
+
)}
665
734
</div>
666
735
</div>
667
736
···
792
861
</button>
793
862
</div>
794
863
<div className="checkbox-list">
795
795
-
{categories.map(category => (
796
796
-
<div key={category.id} className="checkbox-item">
797
797
-
<input
798
798
-
type="checkbox"
799
799
-
id={`category-${category.id}`}
800
800
-
checked={formData.selectedCategories.includes(category.id)}
801
801
-
onChange={() => handleCategoryChange(category.id)}
802
802
-
/>
803
803
-
<label htmlFor={`category-${category.id}`}>
804
804
-
{category.emoji} {category.name}
805
805
-
</label>
864
864
+
{categories.length > 0 ? (
865
865
+
categories.map(category => (
866
866
+
<div key={category.id} className="checkbox-item">
867
867
+
<input
868
868
+
type="checkbox"
869
869
+
id={`category-${category.id}`}
870
870
+
checked={formData.selectedCategories.includes(category.id)}
871
871
+
onChange={() => handleCategoryChange(category.id)}
872
872
+
/>
873
873
+
<label htmlFor={`category-${category.id}`}>
874
874
+
{category.emoji} {category.name}
875
875
+
</label>
876
876
+
</div>
877
877
+
))
878
878
+
) : (
879
879
+
<div style={{ padding: '10px', color: 'var(--text)', opacity: 0.7 }}>
880
880
+
No categories available
806
881
</div>
807
807
-
))}
882
882
+
)}
808
883
</div>
809
884
</div>
810
885
···
821
896
</button>
822
897
</div>
823
898
<div className="checkbox-list">
824
824
-
{tags.map(tag => (
825
825
-
<div key={tag.id} className="checkbox-item">
826
826
-
<input
827
827
-
type="checkbox"
828
828
-
id={`tag-${tag.id}`}
829
829
-
checked={formData.selectedTags.includes(tag.id)}
830
830
-
onChange={() => handleTagChange(tag.id)}
831
831
-
/>
832
832
-
<label htmlFor={`tag-${tag.id}`}>
833
833
-
#{tag.name}
834
834
-
</label>
899
899
+
{tags.length > 0 ? (
900
900
+
tags.map(tag => (
901
901
+
<div key={tag.id} className="checkbox-item">
902
902
+
<input
903
903
+
type="checkbox"
904
904
+
id={`tag-${tag.id}`}
905
905
+
checked={formData.selectedTags.includes(tag.id)}
906
906
+
onChange={() => handleTagChange(tag.id)}
907
907
+
/>
908
908
+
<label htmlFor={`tag-${tag.id}`}>
909
909
+
#{tag.name}
910
910
+
</label>
911
911
+
</div>
912
912
+
))
913
913
+
) : (
914
914
+
<div style={{ padding: '10px', color: 'var(--text)', opacity: 0.7 }}>
915
915
+
No tags available
835
916
</div>
836
836
-
))}
917
917
+
)}
837
918
</div>
838
919
</div>
839
920
</div>