-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathadmin.html
More file actions
800 lines (741 loc) · 51 KB
/
Copy pathadmin.html
File metadata and controls
800 lines (741 loc) · 51 KB
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
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理系統 - 丫亮笑長練功坊預約助手</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-auth.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="js/config.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<link rel="icon" href="images/Alianglogo.png" type="image/png">
</head>
<body class="bg-gray-100 font-sans text-gray-800">
<div id="login-modal" class="fixed inset-0 bg-gray-900 bg-opacity-90 flex items-center justify-center z-50">
<div class="bg-white p-8 rounded-lg shadow-xl w-full max-w-md">
<h2 class="text-2xl font-bold mb-4 text-center">管理員登入</h2>
<form id="loginForm" class="space-y-4">
<input type="text" id="adminEmail" placeholder="帳號或 Email" class="w-full p-3 border rounded">
<input type="password" id="adminPass" placeholder="Password" class="w-full p-3 border rounded">
<button type="submit" class="w-full bg-blue-600 text-white py-3 rounded hover:bg-blue-700">登入</button>
</form>
<p class="text-xs text-gray-500 mt-4 text-center">首次使用請至 Firebase Console 建立使用者</p>
</div>
</div>
<div id="admin-dashboard" class="hidden min-h-screen flex flex-col">
<header class="bg-indigo-700 text-white p-4 shadow-md flex justify-between items-center">
<h1 class="font-bold text-xl"><i class="fa-solid fa-gear"></i> 丫亮笑長練功坊預約助手</h1>
<div class="flex items-center space-x-4">
<a href="index.html" class="hover:text-yellow-300 font-medium"><i class="fa-solid fa-house"></i> 回首頁</a>
<button onclick="switchTab('dashboard')" class="hover:text-yellow-300 font-medium"><i
class="fa-solid fa-chart-line"></i> 課程儀表板</button>
<button onclick="switchTab('bookings')" class="hover:text-yellow-300 font-medium"><i
class="fa-solid fa-calendar-days"></i> 課程管理</button>
<button onclick="switchTab('reports')" class="hover:text-yellow-300 font-medium"><i
class="fa-solid fa-chart-pie"></i> 報表中心</button>
<button onclick="switchTab('courses')" class="hover:text-yellow-300 font-medium"><i
class="fa-solid fa-book-open-reader"></i> 課程設定</button>
<button onclick="switchTab('portfolio')" class="hover:text-yellow-300 font-medium"><i
class="fa-solid fa-briefcase"></i> 作品集管理</button>
<button onclick="logout()" class="bg-indigo-800 px-3 py-1 rounded text-sm hover:bg-indigo-900"><i
class="fa-solid fa-right-from-bracket"></i> 登出</button>
</div>
</header>
<div class="flex-1 container mx-auto p-6">
<!-- Dashboard Tab -->
<div id="tab-dashboard">
<div class="mb-8">
<h2 class="text-2xl font-bold text-gray-800">歡迎回來,管理員!</h2>
<p class="text-gray-500">這裡是您的營運概況總覽</p>
</div>
<!-- Stats Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<!-- Income Card -->
<div onclick="showDashboardDetail('income')"
class="cursor-pointer hover:scale-105 transition transform bg-gradient-to-r from-emerald-500 to-teal-600 rounded-xl shadow-lg p-6 text-white">
<div class="flex justify-between items-start">
<div>
<p class="text-emerald-100 text-sm font-medium mb-1">本月預估收入</p>
<h3 class="text-3xl font-bold" id="dash-income">$0</h3>
</div>
<div class="bg-white bg-opacity-20 p-3 rounded-lg">
<i class="fa-solid fa-coins text-2xl"></i>
</div>
</div>
<p class="text-emerald-100 text-xs mt-4"><i class="fa-solid fa-calendar-day"></i> 統計範圍:本月</p>
</div>
<!-- Pending Card -->
<div onclick="showDashboardDetail('pending')"
class="cursor-pointer hover:scale-105 transition transform bg-gradient-to-r from-amber-400 to-orange-500 rounded-xl shadow-lg p-6 text-white">
<div class="flex justify-between items-start">
<div>
<p class="text-amber-100 text-sm font-medium mb-1">待確認邀約</p>
<h3 class="text-3xl font-bold" id="dash-pending">0</h3>
</div>
<div class="bg-white bg-opacity-20 p-3 rounded-lg">
<i class="fa-solid fa-bell text-2xl"></i>
</div>
</div>
<p class="text-amber-100 text-xs mt-4"><i class="fa-solid fa-circle-exclamation"></i> 請盡快審核回覆
</p>
</div>
<!-- Upcoming Card -->
<div onclick="showDashboardDetail('upcoming')"
class="cursor-pointer hover:scale-105 transition transform bg-gradient-to-r from-blue-500 to-indigo-600 rounded-xl shadow-lg p-6 text-white">
<div class="flex justify-between items-start">
<div>
<p class="text-blue-100 text-sm font-medium mb-1">即將來到課程</p>
<h3 class="text-3xl font-bold" id="dash-upcoming">0</h3>
</div>
<div class="bg-white bg-opacity-20 p-3 rounded-lg">
<i class="fa-regular fa-calendar-check text-2xl"></i>
</div>
</div>
<p class="text-blue-100 text-xs mt-4"><i class="fa-solid fa-clock"></i> 未來 30 天內</p>
</div>
<!-- Unpaid Card -->
<div onclick="showDashboardDetail('unpaid')"
class="cursor-pointer hover:scale-105 transition transform bg-gradient-to-r from-rose-500 to-pink-600 rounded-xl shadow-lg p-6 text-white">
<div class="flex justify-between items-start">
<div>
<p class="text-rose-100 text-sm font-medium mb-1">未入帳款項</p>
<h3 class="text-3xl font-bold" id="dash-unpaid">$0</h3>
</div>
<div class="bg-white bg-opacity-20 p-3 rounded-lg">
<i class="fa-solid fa-file-invoice-dollar text-2xl"></i>
</div>
</div>
<p class="text-rose-100 text-xs mt-4"><i class="fa-solid fa-triangle-exclamation"></i> 已確認但未收款
</p>
</div>
</div>
<!-- Main Content Grid -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Left Col: Pending List -->
<div class="lg:col-span-2 bg-white rounded-xl shadow-md border border-gray-100 overflow-hidden">
<div class="p-5 border-b border-gray-100 flex justify-between items-center bg-gray-50">
<h3 class="font-bold text-gray-800"><i
class="fa-solid fa-clipboard-list text-amber-500 mr-2"></i> 待確認邀約列表</h3>
<button onclick="showDashboardDetail('pending')"
class="text-sm text-blue-600 hover:text-blue-800">查看全部 <i
class="fa-solid fa-arrow-right"></i></button>
</div>
<div class="divide-y divide-gray-100" id="dash-pending-list">
<!-- JS populated -->
<div class="p-8 text-center text-gray-400">載入中...</div>
</div>
</div>
<!-- Right Col: Upcoming Schedule -->
<div class="bg-white rounded-xl shadow-md border border-gray-100 overflow-hidden">
<div class="p-5 border-b border-gray-100 bg-gray-50 flex justify-between items-center">
<h3 class="font-bold text-gray-800"><i class="fa-solid fa-timeline text-blue-500 mr-2"></i>
近期通告行程</h3>
<button onclick="showDashboardDetail('upcoming')"
class="text-sm text-blue-600 hover:text-blue-800">全部 <i
class="fa-solid fa-arrow-right"></i></button>
</div>
<div class="p-4" id="dash-schedule-list">
<!-- JS populated -->
<div class="text-center text-gray-400 py-4">載入中...</div>
</div>
</div>
</div>
</div>
<div id="tab-bookings" class="hidden">
<button onclick="switchTab('dashboard')"
class="mb-4 text-gray-500 hover:text-blue-600 flex items-center text-sm transition"><i
class="fa-solid fa-arrow-left mr-1"></i> 回儀表板</button>
<!-- Unified Toolbar -->
<div
class="bg-white p-4 rounded-xl shadow-sm border border-gray-100 flex flex-wrap gap-4 items-center justify-between mb-6">
<!-- Filters Group -->
<div class="flex flex-wrap gap-2 items-center">
<div class="text-gray-400 text-sm mr-1"><i class="fa-solid fa-filter"></i></div>
<select id="filter-month" onchange="renderBookings()"
class="p-2 border border-gray-300 rounded-lg text-sm bg-gray-50 focus:ring-2 focus:ring-blue-500 focus:bg-white transition hover:border-blue-400">
<option value="">全部月份</option>
</select>
<select id="filter-org" onchange="renderBookings()"
class="p-2 border border-gray-300 rounded-lg text-sm bg-gray-50 focus:ring-2 focus:ring-blue-500 focus:bg-white transition hover:border-blue-400 max-w-[150px]">
<option value="">全部單位</option>
</select>
<select id="filter-course" onchange="renderBookings()"
class="p-2 border border-gray-300 rounded-lg text-sm bg-gray-50 focus:ring-2 focus:ring-blue-500 focus:bg-white transition hover:border-blue-400 max-w-[150px]">
<option value="">全部課程</option>
</select>
<select id="filter-payment" onchange="renderBookings()"
class="p-2 border border-gray-300 rounded-lg text-sm bg-gray-50 focus:ring-2 focus:ring-blue-500 focus:bg-white transition hover:border-blue-400 font-bold text-gray-700">
<option value="">全部入帳狀態</option>
<option value="unpaid">🔴 未入帳</option>
<option value="paid">🟢 已入帳</option>
</select>
</div>
<!-- Search & Actions Group -->
<div class="flex flex-wrap gap-3 items-center flex-1 justify-end">
<div class="relative">
<input type="text" id="search-input" oninput="currentSearch=this.value; renderBookings()"
placeholder="搜尋關鍵字..."
class="pl-9 p-2 border border-gray-300 rounded-lg w-48 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition">
<i class="fa-solid fa-search absolute left-3 top-2.5 text-gray-400 text-xs"></i>
</div>
<div class="h-6 w-px bg-gray-300 mx-1 hidden md:block"></div>
<select id="sort-select" onchange="currentSort=this.value; renderBookings()"
class="p-2 border border-gray-300 rounded-lg text-sm bg-white focus:ring-2 focus:ring-blue-500">
<option value="date-desc">日期新→舊</option>
<option value="date-asc">日期舊→新</option>
<option value="status">狀態優先</option>
</select>
<button onclick="openBookingModal()"
class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 shadow-md transition transform active:scale-95 flex items-center text-sm font-bold">
<i class="fa-solid fa-plus mr-1"></i> 新增
</button>
</div>
</div>
<div class="bg-white rounded-lg shadow overflow-hidden">
<table class="w-full text-left border-collapse">
<thead class="bg-gray-50 border-b">
<tr>
<th class="p-4 font-semibold text-gray-600">日期/時間</th>
<th class="p-4 font-semibold text-gray-600">邀請單位/聯絡人</th>
<th class="p-4 font-semibold text-gray-600">地區/課程</th>
<th class="p-4 font-semibold text-gray-600">費用/狀態</th>
<th class="p-4 font-semibold text-gray-600 text-right">管理</th>
</tr>
</thead>
<tbody id="booking-table-body" class="divide-y divide-gray-100">
</tbody>
</table>
</div>
</div>
<div id="tab-reports" class="hidden">
<button onclick="switchTab('dashboard')"
class="mb-4 text-gray-500 hover:text-blue-600 flex items-center text-sm transition"><i
class="fa-solid fa-arrow-left mr-1"></i> 回儀表板</button>
<div
class="flex flex-wrap justify-between items-center mb-6 mt-2 bg-white p-4 rounded-xl shadow-sm border border-gray-100">
<div class="flex items-center gap-4 flex-wrap">
<h2 class="text-xl font-bold text-gray-800"><i
class="fa-solid fa-chart-pie mr-2 text-indigo-600"></i> 營運報表中心</h2>
<div class="h-6 w-px bg-gray-300 hidden md:block"></div>
<!-- Mode Selector -->
<select id="report-mode" onchange="toggleReportMode()"
class="border-gray-300 border rounded-md p-2 text-sm focus:ring-indigo-500 focus:border-indigo-500 font-bold text-indigo-700 bg-indigo-50">
<option value="year">📅 依年度檢視</option>
<option value="custom">🛠 自訂區間</option>
</select>
<!-- Year Mode UI -->
<span id="report-mode-year" class="flex items-center gap-2">
<select id="report-year" onchange="loadReports()"
class="border-gray-300 border rounded-md p-2 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<!-- JS populated years -->
</select>
</span>
<!-- Custom Range Mode UI -->
<span id="report-mode-custom" class="hidden flex items-center gap-2">
<input type="date" id="report-start" class="border p-2 rounded text-sm w-32">
<span class="text-gray-400">~</span>
<input type="date" id="report-end" class="border p-2 rounded text-sm w-32">
<button onclick="loadReports()"
class="bg-indigo-600 text-white px-3 py-2 rounded hover:bg-indigo-700 transition"><i
class="fa-solid fa-magnifying-glass"></i></button>
</span>
</div>
<button onclick="exportToCSV()"
class="mt-2 md:mt-0 bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700 shadow flex items-center text-sm font-bold transition">
<i class="fa-solid fa-file-excel mr-2"></i> 匯出 CSV 報表
</button>
</div>
<!-- Summary Cards -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="bg-white p-6 rounded-xl shadow-sm border border-gray-100">
<p class="text-gray-500 text-sm mb-1">年度總營收 (已確認)</p>
<h3 class="text-3xl font-bold text-gray-800" id="report-total-revenue">$0</h3>
</div>
<div class="bg-white p-6 rounded-xl shadow-sm border border-gray-100">
<p class="text-gray-500 text-sm mb-1">年度邀約場次</p>
<h3 class="text-3xl font-bold text-gray-800" id="report-total-count">0</h3>
</div>
<div class="bg-white p-6 rounded-xl shadow-sm border border-gray-100">
<p class="text-gray-500 text-sm mb-1">平均單場產值</p>
<h3 class="text-3xl font-bold text-gray-800" id="report-avg-revenue">$0</h3>
</div>
</div>
<!-- Charts -->
<div class="space-y-8">
<!-- Main Trend Chart -->
<div class="bg-white p-6 rounded-xl shadow-md border border-gray-100">
<h3 class="text-lg font-bold text-gray-700 mb-4 border-l-4 border-indigo-500 pl-3">月營收趨勢分析</h3>
<div class="relative h-80 w-full">
<canvas id="revenueChart"></canvas>
</div>
</div>
<!-- Secondary Charts -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<div class="bg-white p-6 rounded-xl shadow-md border border-gray-100">
<h3 class="text-lg font-bold text-gray-700 mb-4 border-l-4 border-pink-500 pl-3">課程類別分佈</h3>
<div class="relative h-64 w-full flex justify-center">
<canvas id="categoryChart"></canvas>
</div>
</div>
<div class="bg-white p-6 rounded-xl shadow-md border border-gray-100">
<h3 class="text-lg font-bold text-gray-700 mb-4 border-l-4 border-teal-500 pl-3">邀約縣市排行 (Top
10)</h3>
<div class="relative h-64 w-full">
<canvas id="cityChart"></canvas>
</div>
</div>
</div>
</div>
</div>
<div id="tab-courses" class="hidden">
<button onclick="switchTab('dashboard')"
class="mb-4 text-gray-500 hover:text-blue-600 flex items-center text-sm transition"><i
class="fa-solid fa-arrow-left mr-1"></i> 回儀表板</button>
<div class="flex justify-between items-center mb-6 mt-2">
<h2 class="text-xl font-bold">目前上架課程</h2>
<button onclick="openCourseModal()"
class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 shadow">
<i class="fa-solid fa-plus"></i> 新增課程
</button>
</div>
<div class="bg-white rounded-lg shadow overflow-hidden">
<table class="w-full text-left border-collapse">
<thead class="bg-gray-50 border-b">
<tr>
<th class="p-4 font-semibold text-gray-600 w-1/4">課程名稱</th>
<th class="p-4 font-semibold text-gray-600 w-1/3">簡介</th>
<th class="p-4 font-semibold text-gray-600">時數</th>
<th class="p-4 font-semibold text-gray-600">類別</th>
<th class="p-4 font-semibold text-gray-600 text-right">管理</th>
</tr>
</thead>
<tbody id="course-table-body" class="divide-y divide-gray-100">
<!-- Course rows will be populated here -->
</tbody>
</table>
</div>
</div>
<!-- Portfolio Tab -->
<div id="tab-portfolio" class="hidden">
<button onclick="switchTab('dashboard')"
class="mb-4 text-gray-500 hover:text-blue-600 flex items-center text-sm transition"><i
class="fa-solid fa-arrow-left mr-1"></i> 回儀表板</button>
<div class="flex justify-between items-center mb-6 mt-2">
<h2 class="text-xl font-bold">作品集列表</h2>
<div class="flex gap-2">
<button onclick="openPortfolioModal()"
class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 shadow">
<i class="fa-solid fa-plus"></i> 新增作品
</button>
</div>
</div>
<div class="bg-white rounded-lg shadow overflow-hidden">
<table class="w-full text-left border-collapse">
<thead class="bg-gray-50 border-b">
<tr>
<th class="p-4 font-semibold text-gray-600 w-1/4">作品名稱</th>
<th class="p-4 font-semibold text-gray-600 w-1/3">簡介</th>
<th class="p-4 font-semibold text-gray-600">外觀</th>
<th class="p-4 font-semibold text-gray-600">排序</th>
<th class="p-4 font-semibold text-gray-600 text-right">管理</th>
</tr>
</thead>
<tbody id="portfolio-table-body" class="divide-y divide-gray-100">
<!-- Portfolio rows will be populated here -->
</tbody>
</table>
</div>
</div>
</div>
</div>
<div id="booking-modal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
<div class="bg-white rounded-lg w-full max-w-2xl max-h-[90vh] overflow-y-auto">
<div class="p-4 bg-blue-600 text-white flex justify-between items-center sticky top-0">
<h3 class="font-bold" id="modal-title">新增/編輯課程邀約</h3>
<button onclick="closeBookingModal()" class="text-white hover:text-gray-200"><i
class="fa-solid fa-times"></i></button>
</div>
<div class="p-6">
<form id="adminBookingForm" class="space-y-4">
<input type="hidden" name="docId">
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-sm font-bold text-gray-700">日期</label>
<input type="date" name="date" required class="w-full border p-2 rounded">
</div>
<div>
<label class="block text-sm font-bold text-gray-700">時段</label>
<select name="timeSlot" class="w-full border p-2 rounded">
<option value="09:00-12:00">上午 (09:00-12:00)</option>
<option value="13:30-16:30">下午 (13:30-16:30)</option>
<option value="09:00-16:30">全日 (09:00-16:30)</option>
<option value="不指定時段">不指定時段 (計為1單位)</option>
</select>
</div>
</div>
<div>
<label class="block text-sm font-bold text-gray-700">工作性質</label>
<div class="flex gap-2">
<select name="type" id="workTypeSelect" class="w-full border p-2 rounded"
onchange="toggleCustomWorkType()">
<option value="邀請">邀請</option>
<option value="自辦">自辦</option>
<option value="合作">合作</option>
<option value="長期顧問">長期顧問</option>
<option value="固定直播">固定直播</option>
<option value="自訂">自訂</option>
</select>
<input type="text" id="customWorkType" class="w-full border p-2 rounded hidden"
placeholder="輸入自訂性質">
</div>
</div>
<div>
<label class="block text-sm font-bold text-gray-700">課程名稱/工作標題</label>
<select name="courseName" id="courseNameSelect" class="w-full border p-2 rounded">
<option value="">請選擇課程...</option>
<!-- Options will be populated by JS -->
</select>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-sm font-bold text-gray-700">邀請單位/服務對象</label>
<input type="text" name="orgName" class="w-full border p-2 rounded">
</div>
<div>
<label class="block text-sm font-bold text-gray-700">執行縣市/平台</label>
<select name="city" class="w-full border p-2 rounded">
<option value="">請選擇縣市/平台</option>
<option value="線上/直播">線上/直播</option>
<option value="基隆市">基隆市</option>
<option value="台北市">台北市</option>
<option value="新北市">新北市</option>
<option value="桃園市">桃園市</option>
<option value="新竹市">新竹市</option>
<option value="新竹縣">新竹縣</option>
<option value="苗栗縣">苗栗縣</option>
<option value="台中市">台中市</option>
<option value="彰化縣">彰化縣</option>
<option value="南投縣">南投縣</option>
<option value="雲林縣">雲林縣</option>
<option value="嘉義市">嘉義市</option>
<option value="嘉義縣">嘉義縣</option>
<option value="台南市">台南市</option>
<option value="高雄市">高雄市</option>
<option value="屏東縣">屏東縣</option>
<option value="宜蘭縣">宜蘭縣</option>
<option value="花蓮縣">花蓮縣</option>
<option value="台東縣">台東縣</option>
<option value="澎湖縣">澎湖縣</option>
<option value="金門縣">金門縣</option>
<option value="連江縣">連江縣</option>
</select>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-sm font-bold text-gray-700">聯絡人姓名 (邀請人)</label>
<input type="text" name="contactName" class="w-full border p-2 rounded">
</div>
<div>
<label class="block text-sm font-bold text-gray-700">聯絡電話</label>
<input type="text" name="contactPhone" class="w-full border p-2 rounded">
</div>
</div>
<div>
<label class="block text-sm font-bold text-gray-700">聯絡 Email</label>
<input type="email" name="contactEmail" class="w-full border p-2 rounded">
</div>
<div class="bg-blue-50 p-4 rounded border border-blue-100">
<h4 class="text-blue-800 font-bold mb-2"><i class="fa-solid fa-dollar-sign"></i> 財務與核銷</h4>
<div class="grid grid-cols-3 gap-4 mb-2">
<div>
<label class="text-xs">費用類別</label>
<select name="feeType" class="w-full border p-1 rounded bg-white">
<option>鐘點費</option>
<option>演講費</option>
<option>顧問費</option>
<option>車馬費</option>
</select>
</div>
<div>
<label class="text-xs">講師費用/hr (或單次)</label>
<input type="number" name="lecturerFee" class="w-full border p-1 rounded">
</div>
<div>
<label class="text-xs">付款單位</label>
<input type="text" name="payerName" class="w-full border p-1 rounded"
placeholder="預設同邀請單位">
</div>
</div>
<div class="flex items-center space-x-4 mt-2">
<label class="flex items-center text-sm"><input type="checkbox" name="receiptSent"
class="mr-1"> 領據已寄送/簽收</label>
<label class="flex items-center text-sm"><input type="checkbox" name="paymentReceived"
class="mr-1"> 款項已核對入帳</label>
</div>
</div>
<div class="mb-4">
<label class="block text-sm font-bold text-gray-700">預約狀態</label>
<select name="status" class="w-full border p-2 rounded bg-white">
<option value="pending">待確認 (Pending)</option>
<option value="confirmed">已確認 (Confirmed)</option>
<option value="completed">已完成 (Completed)</option>
<option value="cancelled">已取消 (Cancelled)</option>
</select>
</div>
<div>
<label class="block text-sm font-bold text-gray-700">備註</label>
<textarea name="notes" class="w-full border p-2 rounded" rows="2"></textarea>
</div>
<!-- Recurring Section (Only for New Bookings) -->
<div id="recurrence-section" class="bg-indigo-50 p-4 rounded border border-indigo-100 mt-2">
<h4 class="text-indigo-800 font-bold mb-2"><i class="fa-solid fa-repeat text-indigo-500"></i>
重複設定 (批次建立)</h4>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="text-xs font-bold text-indigo-700">重複頻率</label>
<select name="recurringType" id="recurringType" onchange="toggleRecurringDate()"
class="w-full border p-1 rounded bg-white">
<option value="none">不重複</option>
<option value="weekly">每週 (Weekly)</option>
<option value="biweekly">每隔週 (Bi-weekly)</option>
<option value="monthly">每月 (Monthly)</option>
</select>
</div>
<div id="recurringEndDateContainer" class="hidden">
<label class="text-xs font-bold text-indigo-700">結束日期</label>
<input type="date" name="recurringEndDate" id="recurringEndDate"
class="w-full border p-1 rounded">
</div>
</div>
<p class="text-[10px] text-indigo-400 mt-2">※ 系統將自動根據起始日期與頻率,產生多筆獨立的預約記錄。</p>
</div>
</form>
</div>
<div class="p-4 border-t flex justify-end space-x-2">
<button onclick="closeBookingModal()" class="px-4 py-2 border rounded hover:bg-gray-100">取消</button>
<button onclick="saveBooking()"
class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">儲存資料</button>
</div>
</div>
</div>
<div id="course-modal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
<div class="bg-white rounded-lg w-full max-w-lg">
<div class="p-4 bg-indigo-600 text-white font-bold">新增/編輯課程</div>
<div class="p-6 space-y-4">
<form id="courseForm" class="space-y-4">
<input type="hidden" name="courseId">
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">課程名稱 <span
class="text-xs text-gray-500 font-normal">(請輸入完整的課程標題)</span></label>
<input type="text" name="title"
class="w-full border p-2 rounded focus:ring-2 focus:ring-indigo-500 outline-none" required>
</div>
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">課程簡介 <span
class="text-xs text-gray-500 font-normal">(請簡述課程內容與目標)</span></label>
<textarea name="description"
class="w-full border p-2 rounded h-24 focus:ring-2 focus:ring-indigo-500 outline-none"
required></textarea>
</div>
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">備註說明 <span
class="text-xs text-gray-500 font-normal">(例如:上課地點、有無廣播設備、學員需要帶載具等等)</span></label>
<textarea name="requirements"
class="w-full border p-2 rounded h-20 focus:ring-2 focus:ring-indigo-500 outline-none"
placeholder="輸入此課程的特殊需求或注意事項..."></textarea>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">課程時數</label>
<select name="durationSelect" id="durationSelect" class="w-full border p-2 rounded bg-white"
onchange="toggleCustomDuration()">
<option value="3小時">3小時</option>
<option value="6小時">6小時</option>
<option value="自訂">自訂</option>
</select>
<input type="text" id="customDuration" name="customDuration" placeholder="輸入時數 (例: 2.5小時)"
class="w-full border p-2 rounded mt-2 hidden">
</div>
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">課程類別</label>
<select name="categorySelect" id="categorySelect" class="w-full border p-2 rounded bg-white"
onchange="toggleCustomCategory()">
<option value="初階">初階</option>
<option value="進階">進階</option>
<option value="自訂">自訂</option>
</select>
<input type="text" id="customCategory" name="customCategory" placeholder="輸入類別 (例: 工作坊)"
class="w-full border p-2 rounded mt-2 hidden">
</div>
</div>
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">課程標籤 <span
class="text-xs text-gray-500 font-normal">(選填,以逗號分隔,如:AI, 實作)</span></label>
<input type="text" name="tags" placeholder="例如:AI教學, 實作工作坊"
class="w-full border p-2 rounded focus:ring-2 focus:ring-indigo-500 outline-none">
</div>
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">課程封面圖片 <span
class="text-xs text-gray-500 font-normal">(支援 JPG, PNG 格式)</span></label>
<div
class="border-2 border-dashed border-gray-300 rounded p-4 text-center hover:bg-gray-50 transition cursor-pointer relative">
<input type="file" id="courseImageFile"
class="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
onchange="handleImageUpload(this)">
<div class="text-gray-500">
<i class="fa-solid fa-cloud-upload-alt text-2xl mb-2"></i>
<p class="text-sm">點擊上傳或拖曳圖片至此</p>
</div>
</div>
<input type="hidden" name="imageUrl" id="courseImageUrl">
<div id="imagePreview" class="hidden mt-4 relative group w-32 mx-auto">
<img src="" alt="Preview" class="w-32 h-32 object-cover rounded shadow-md">
<button type="button" onclick="clearImage()"
class="absolute -top-2 -right-2 bg-red-500 text-white rounded-full w-6 h-6 flex items-center justify-center shadow-sm hover:bg-red-600"><i
class="fa-solid fa-times text-xs"></i></button>
</div>
</div>
</form>
</div>
<div class="p-4 border-t flex justify-end gap-2">
<button onclick="document.getElementById('course-modal').classList.add('hidden')"
class="px-4 py-2 border rounded">取消</button>
<button onclick="saveCourse()" class="px-4 py-2 bg-indigo-600 text-white rounded">儲存</button>
</div>
</div>
</div>
<!-- Portfolio Modal -->
<div id="portfolio-modal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
<div class="bg-white rounded-lg w-full max-w-lg">
<div class="p-4 bg-indigo-600 text-white font-bold">新增/編輯作品集</div>
<div class="p-6 space-y-4">
<form id="portfolioForm" class="space-y-4">
<input type="hidden" name="portfolioId">
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">作品名稱</label>
<input type="text" name="title"
class="w-full border p-2 rounded focus:ring-2 focus:ring-indigo-500 outline-none" required>
</div>
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">簡介</label>
<textarea name="description"
class="w-full border p-2 rounded h-20 focus:ring-2 focus:ring-indigo-500 outline-none"
required></textarea>
</div>
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">連結網址 (URL)</label>
<input type="url" name="url" placeholder="https://..."
class="w-full border p-2 rounded focus:ring-2 focus:ring-indigo-500 outline-none" required>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">圖示類別 (FontAwesome)</label>
<!-- Icon Select with Preview -->
<div class="flex gap-2 mb-2">
<div id="iconPreviewContainer" class="w-10 h-10 border rounded flex items-center justify-center bg-gray-50 text-gray-600 flex-shrink-0">
<i id="iconPreview" class="fa-solid fa-link text-xl"></i>
</div>
<select id="iconSelect" class="flex-grow border p-2 rounded focus:ring-2 focus:ring-indigo-500 outline-none bg-white w-full max-w-[calc(100%-3rem)]" onchange="updateIconSelection()">
<optgroup label="教育與工作">
<option value="fa-solid fa-chalkboard">白板 (Chalkboard)</option>
<option value="fa-solid fa-chalkboard-user">教學 (Chalkboard User)</option>
<option value="fa-solid fa-book">書籍 (Book)</option>
<option value="fa-solid fa-laptop">筆電 (Laptop)</option>
<option value="fa-solid fa-graduation-cap">學位帽 (Graduation)</option>
<option value="fa-solid fa-pen">畫筆/寫作 (Pen)</option>
<option value="fa-solid fa-file-pdf">PDF 檔案 (PDF)</option>
<option value="fa-solid fa-chart-line">圖表/數據 (Chart)</option>
<option value="fa-solid fa-user-group">團隊/群組 (Group)</option>
</optgroup>
<optgroup label="工具與應用">
<option value="fa-solid fa-link">連結 (Link)</option>
<option value="fa-solid fa-ticket">票券/抽獎 (Ticket)</option>
<option value="fa-solid fa-circle-question">問答/題目 (Question)</option>
<option value="fa-solid fa-qrcode">QR Code</option>
<option value="fa-solid fa-stopwatch">碼表/倒數 (Stopwatch)</option>
<option value="fa-solid fa-magnifying-glass">搜尋 (Search)</option>
<option value="fa-solid fa-wand-magic-sparkles">魔法棒/AI生圖 (Magic)</option>
<option value="fa-solid fa-lightbulb">靈感/點子 (Lightbulb)</option>
<option value="fa-solid fa-screwdriver-wrench">工具/設定 (Wrench)</option>
</optgroup>
<optgroup label="媒體與社群">
<option value="fa-brands fa-youtube">YouTube影片 (YouTube)</option>
<option value="fa-solid fa-microphone">麥克風/廣播 (Mic)</option>
<option value="fa-solid fa-camera">相機/攝影 (Camera)</option>
<option value="fa-solid fa-bullhorn">大聲公/廣播 (Megaphone)</option>
<option value="fa-brands fa-facebook">Facebook</option>
<option value="fa-brands fa-line">LINE</option>
<option value="fa-brands fa-instagram">Instagram</option>
<option value="fa-solid fa-globe">地球/網站 (Globe)</option>
</optgroup>
<optgroup label="符號">
<option value="fa-solid fa-star">星星 (Star)</option>
<option value="fa-solid fa-heart">愛心 (Heart)</option>
<option value="fa-solid fa-gamepad">遊戲 (Gamepad)</option>
</optgroup>
<optgroup label="其他 (進階)">
<option value="custom">自訂輸入 (Custom)</option>
</optgroup>
</select>
</div>
<!-- Actual input sent to JS -->
<input type="text" id="customIconInput" name="iconClass" placeholder="例如: fa-solid fa-star"
class="w-full border p-2 rounded focus:ring-2 focus:ring-indigo-500 outline-none hidden" oninput="updateIconPreview()">
<p class="text-xs text-gray-500 mt-1">選擇自訂即可手動輸入 FontAwesome CSS</p>
</div>
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">主題顏色</label>
<select name="colorTheme" class="w-full border p-2 rounded bg-white">
<option value="teal">藍綠色 (Teal)</option>
<option value="blue">藍色 (Blue)</option>
<option value="yellow">黃色 (Yellow)</option>
<option value="red">紅色 (Red)</option>
<option value="green">綠色 (Green)</option>
<option value="purple">紫色 (Purple)</option>
<option value="indigo">靛色 (Indigo)</option>
<option value="pink">粉紅 (Pink)</option>
</select>
</div>
</div>
<div>
<label class="block text-sm font-bold text-gray-700 mb-1">排序順序 (數字越小越前面)</label>
<input type="number" name="order" class="w-full border p-2 rounded focus:ring-2 focus:ring-indigo-500 outline-none" placeholder="0">
</div>
</form>
</div>
<div class="p-4 border-t flex justify-end gap-2">
<button onclick="document.getElementById('portfolio-modal').classList.add('hidden')"
class="px-4 py-2 border rounded">取消</button>
<button onclick="savePortfolio()" class="px-4 py-2 bg-indigo-600 text-white rounded">儲存</button>
</div>
</div>
</div>
<!-- Detail Modal -->
<div id="detail-modal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
<div class="bg-white rounded-xl w-full max-w-4xl max-h-[85vh] flex flex-col shadow-2xl m-4">
<div id="detail-modal-header"
class="p-5 bg-gray-800 text-white rounded-t-xl flex justify-between items-center shrink-0">
<h3 class="text-xl font-bold" id="detail-modal-title">詳細資料</h3>
<button
onclick="document.getElementById('detail-modal').classList.add('hidden'); document.getElementById('detail-modal').classList.remove('flex')"
class="text-gray-400 hover:text-white transition">
<i class="fa-solid fa-times text-xl"></i>
</button>
</div>
<div class="p-6 overflow-y-auto flex-1 custom-scrollbar" id="detail-modal-content">
<!-- Content injected via JS -->
</div>
<div class="p-4 border-t bg-gray-50 rounded-b-xl flex justify-end shrink-0">
<button
onclick="document.getElementById('detail-modal').classList.add('hidden'); document.getElementById('detail-modal').classList.remove('flex')"
class="px-6 py-2 bg-gray-200 text-gray-700 rounded hover:bg-gray-300 font-medium">關閉</button>
</div>
</div>
</div>
<script src="js/admin.js?v=2"></script>
</body>
</html>