Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
305 lines (281 loc) · 20.8 KB
/
Copy pathindex.html
File metadata and controls
305 lines (281 loc) · 20.8 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
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://cdn.tailwindcss.com https://cdn.jsdelivr.net https://cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; font-src 'self' https://cdnjs.cloudflare.com data:; img-src 'self' https: data:; connect-src 'self' https://enodcxbwqqigqfwnjlwc.supabase.co wss://enodcxbwqqigqfwnjlwc.supabase.co https://*.supabase.co wss://*.supabase.co; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; form-action 'self';">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>UniSync - 校園公告即時推播助手</title>
<!-- 引入外部 CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
<!-- ✨ 引入自定義 CSS -->
<link rel="stylesheet" href="css/style.css?v=20260614-visual-3">
</head>
<body class="app-base-text bg-slate-50 font-sans text-slate-800">
<div class="relative flex h-screen overflow-hidden">
<!-- Sidebar -->
<aside id="sidebar" class="app-sidebar w-96 max-w-[90vw] border-r flex flex-col h-full z-20 absolute lg:relative -translate-x-full lg:translate-x-0 transition-transform duration-300 ease-in-out">
<div class="p-6 border-b border-slate-100 flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="app-logo p-2 text-white">
<i class="fas fa-sync-alt fa-lg"></i>
</div>
<div>
<h1 class="text-xl font-bold text-slate-900 tracking-tight leading-none">UniSync</h1>
<span class="text-xs text-slate-500 font-bold">公告同步設定</span>
</div>
</div>
<button id="close-sidebar-btn" class="lg:hidden text-slate-400 hover:text-slate-600">
<i class="fas fa-times fa-lg"></i>
</button>
</div>
<div id="menu-toolbar-container" class="bg-white"></div>
<!-- ✨ 動態選單容器 (由 main.js 生成) -->
<div class="flex-1 overflow-y-auto p-4 custom-scrollbar bg-white" id="menu-container">
<p class="text-sm text-slate-400 p-4">初始化選單中...</p>
</div>
<div class="p-4 bg-white border-t border-slate-200">
<button id="update-sub-btn" class="app-primary-button w-full py-3 font-bold active:scale-95">更新訂閱偏好</button>
</div>
</aside>
<div id="overlay" class="fixed inset-0 bg-black/50 z-10 hidden lg:hidden"></div>
<main class="flex-1 overflow-y-auto p-4 md:p-8 custom-scrollbar">
<div class="max-w-6xl mx-auto">
<header class="app-page-header mb-6">
<div class="flex items-start gap-4">
<button id="menu-btn" class="lg:hidden text-slate-500 hover:text-blue-600 p-2 -ml-2"><i class="fas fa-bars fa-lg"></i></button>
<div>
<h2 class="app-page-title">公告通知設定</h2>
<p class="app-page-subtitle">設定接收管道、訂閱來源與全域關鍵字;之後由通知主動送達。</p>
<div class="mt-3 flex flex-wrap items-center gap-2">
<span id="monitoring-status" class="app-status-pill">
<span class="w-2 h-2 bg-slate-400 rounded-full"></span> 未連線
</span>
<span class="app-status-pill app-status-pill-muted hidden sm:inline-flex">監控師大公告來源</span>
</div>
</div>
</div>
<div class="app-header-actions">
<div class="app-metrics-strip">
<div class="app-stat-pill">
<span class="app-stat-label">訂閱類別</span>
<span id="active-subscriptions-count" class="app-stat-value text-blue-600">--</span>
</div>
<div class="app-stat-pill">
<span class="app-stat-label">雷達命中</span>
<span id="global-keyword-matches-count" class="app-stat-value text-rose-500">--</span>
</div>
<div class="app-stat-pill">
<span class="app-stat-label">關鍵字</span>
<span id="global-keywords-count" class="app-stat-value text-emerald-600">--</span>
</div>
</div>
<!-- Auth Section -->
<div id="auth-section">
<button id="login-btn" class="app-auth-button">
<i class="fab fa-google text-red-500"></i><span>Google 登入</span>
</button>
<div id="user-info" class="app-user-card hidden flex items-center gap-3">
<img id="user-avatar" class="w-8 h-8 rounded-full" src="" alt="avatar">
<span id="user-name" class="text-base font-bold text-slate-700"></span>
<button id="logout-btn" class="ml-2 text-slate-400 hover:text-rose-500"><i class="fas fa-sign-out-alt"></i></button>
</div>
</div>
</div>
</header>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
<section class="app-card p-5 sm:p-6 flex flex-col justify-between">
<div>
<div class="mb-5 flex items-start justify-between gap-4">
<div>
<h3 class="text-sm font-black text-slate-900 flex items-center gap-2">
<i class="fas fa-paper-plane text-blue-500"></i>
通知接收方式
</h3>
<p class="mt-1 text-xs font-medium text-slate-500">設定完成後,新公告會透過啟用的管道通知你。</p>
</div>
<span class="app-chip app-chip-success shrink-0 px-2.5 py-1 text-[11px]">Discord / Telegram 已支援</span>
</div>
<div class="space-y-3">
<label class="block">
<span class="mb-1.5 flex items-center justify-between text-xs font-bold text-slate-600">
<span class="inline-flex items-center gap-2"><i class="fab fa-discord text-[#5865F2]"></i> Discord Webhook</span>
<span class="app-chip app-chip-success px-2 py-0.5 text-[10px]">可使用</span>
</span>
<input id="discord-input" type="text" placeholder="貼上 Discord Webhook URL" class="w-full rounded-xl border border-slate-200 bg-slate-50 px-3 py-2.5 text-sm font-mono outline-none transition-all focus:border-blue-500 focus:bg-white focus:ring-4 focus:ring-blue-500/10">
</label>
<div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
<div class="rounded-xl border border-slate-200 bg-slate-50 px-3 py-3 text-sm text-slate-500">
<div class="mb-2 flex items-center justify-between gap-2">
<span class="font-bold text-slate-700"><i class="fab fa-telegram mr-2 text-[#26A5E4]"></i>Telegram</span>
<span class="app-chip app-chip-success px-2 py-0.5 text-[10px]">可使用</span>
</div>
<div class="space-y-2">
<input id="telegram-bot-token-input" type="password" placeholder="Bot Token" autocomplete="off" class="w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-xs font-mono outline-none transition-all focus:border-blue-500 focus:ring-4 focus:ring-blue-500/10">
<input id="telegram-chat-id-input" type="text" placeholder="Chat ID 或 @channel" class="w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-xs font-mono outline-none transition-all focus:border-blue-500 focus:ring-4 focus:ring-blue-500/10">
</div>
<p class="mt-2 text-[11px] font-medium leading-relaxed text-slate-500">先與 Bot 對話或把 Bot 加入頻道,再填入接收目標。</p>
</div>
<div class="rounded-xl border border-slate-200 bg-slate-50 px-3 py-3 text-sm text-slate-500">
<div class="flex items-center justify-between gap-2">
<span class="font-bold text-slate-700"><i class="fas fa-envelope mr-2 text-rose-400"></i>Email</span>
<span class="rounded-full bg-slate-200 px-2 py-0.5 text-[10px] font-black text-slate-600">即將支援</span>
</div>
</div>
</div>
</div>
</div>
<div class="mt-6 flex justify-end">
<button id="save-profile-btn" class="app-primary-button px-5 py-2.5 text-sm font-bold active:bg-blue-800">儲存通知設定</button>
</div>
</section>
<section class="app-card p-5 sm:p-6 flex flex-col justify-between">
<div>
<div class="mb-5 flex items-start justify-between gap-4">
<div>
<h3 class="text-sm font-black text-slate-900 flex items-center gap-2">
<i class="fas fa-crosshairs text-blue-500"></i>
全域關鍵字
</h3>
<p class="mt-1 text-xs font-medium text-slate-500">符合關鍵字的新公告會觸發通知,不限已訂閱分類。</p>
</div>
<span class="app-chip shrink-0 px-2.5 py-1 text-[11px]">全站比對</span>
</div>
<div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<div class="text-xs leading-relaxed text-slate-500">
先預覽目前資料庫命中;即使目前沒有結果,也可以加入等待未來公告。
</div>
<button
id="open-radar-modal-btn"
class="app-soft-button inline-flex shrink-0 items-center justify-center gap-2 px-4 py-2.5 text-sm font-bold"
>
<i class="fas fa-plus-circle"></i>
<span>新增關鍵字</span>
</button>
</div>
<div class="mt-5 rounded-xl border border-slate-200 bg-slate-50 p-3">
<div id="global-radar-tags" class="flex min-h-[32px] flex-wrap items-center gap-2"></div>
</div>
</div>
</section>
</div>
<section class="app-card overflow-hidden">
<div class="border-b border-slate-100 p-4 sm:p-5">
<div class="flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between">
<div>
<h3 class="flex items-center gap-2 text-sm font-black text-slate-900">
<i class="fas fa-list-check text-blue-500"></i>
最近命中
</h3>
<p class="mt-1 text-xs font-medium text-slate-500">用來確認你的分類訂閱與全域關鍵字是否有抓到資料。</p>
</div>
<div class="text-xs font-bold text-slate-400">近 90 天,最多 50 筆</div>
</div>
</div>
<div id="live-feed-status" class="border-b border-slate-100 px-4 py-3 text-sm text-slate-500 sm:px-5">
請先登入以載入最近命中。
</div>
<div class="overflow-x-auto hidden md:block">
<table class="w-full text-left border-collapse">
<thead>
<tr class="border-b border-slate-100 bg-slate-50/80 text-xs font-black text-slate-500">
<th class="px-6 py-4">時間</th>
<th class="px-6 py-4 w-36 whitespace-nowrap">觸發類型</th>
<th class="px-6 py-4 w-48 whitespace-nowrap">來源單位</th>
<th class="px-6 py-4">公告標題</th>
<th class="px-6 py-4 text-right">連結</th>
</tr>
</thead>
<tbody id="live-feed-table-body" class="divide-y divide-slate-50">
</tbody>
</table>
</div>
<div id="live-feed-mobile" class="md:hidden divide-y divide-slate-100">
</div>
<div class="flex justify-center border-t border-slate-100 px-4 py-4 sm:px-5">
<button id="live-feed-load-more" class="hidden rounded-lg bg-slate-100 px-4 py-2 text-sm font-bold text-slate-700 transition-colors hover:bg-slate-200">
載入更多
</button>
</div>
</section>
</div>
</main>
</div>
<!-- ✨ 核心腳本引入順序 -->
<script src="js/menu-data.js?v=20260614-ui"></script> <!-- 1. 先載入資料 -->
<script src="js/auth.js?v=20260614-ui"></script> <!-- 2. 初始化 Supabase -->
<script src="js/keywords.js?v=20260614-ui"></script> <!-- 3. 關鍵字管理 -->
<script src="js/main.js?v=20260615-mobile-sidebar"></script> <!-- 4. 執行 UI 與 事件處理 -->
<!-- 📋 預覽 Modal -->
<div id="preview-modal" class="fixed inset-0 bg-black/50 z-50 hidden flex items-center justify-center p-4">
<div class="bg-white rounded-2xl shadow-2xl max-w-2xl w-full max-h-[80vh] flex flex-col">
<div class="p-6 border-b border-slate-200 flex items-center justify-between">
<h3 id="preview-title" class="text-lg font-bold text-slate-900">預覽</h3>
<button id="close-preview-modal-btn" class="text-slate-400 hover:text-slate-600">
<i class="fas fa-times fa-lg"></i>
</button>
</div>
<div id="preview-content" class="flex-1 overflow-y-auto p-6 custom-scrollbar">
<p class="text-sm text-slate-500">載入中...</p>
</div>
<div class="p-4 border-t border-slate-100 flex justify-end">
<button id="close-preview-modal-footer-btn" class="px-4 py-2 bg-slate-100 text-slate-700 rounded-lg hover:bg-slate-200 font-medium">關閉</button>
</div>
</div>
</div>
<div id="keyword-action-modal" class="fixed inset-0 z-50 hidden items-center justify-center bg-slate-950/60 p-4">
<div class="relative flex max-h-[88vh] w-full max-w-3xl flex-col overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-xl shadow-slate-950/20">
<div class="flex items-start justify-between border-b border-slate-200 bg-white px-5 py-4 sm:px-6">
<div>
<h3 class="text-lg font-black tracking-tight text-slate-900 sm:text-xl">新增全域關鍵字</h3>
<p class="mt-1 text-sm text-slate-500">預覽目前資料庫命中後,加入未來公告通知條件。</p>
</div>
<button id="close-keyword-modal-btn" type="button" class="inline-flex h-9 w-9 items-center justify-center rounded-lg border border-slate-200 text-slate-400 transition-colors hover:bg-slate-100 hover:text-slate-700 focus:outline-none focus:ring-4 focus:ring-blue-500/10">
<i class="fas fa-times"></i>
</button>
</div>
<div class="flex-1 overflow-y-auto bg-slate-50 px-5 py-5 sm:px-6 custom-scrollbar">
<div class="rounded-xl border border-slate-200 bg-white p-4">
<div class="mb-3 flex items-center gap-2 text-xs font-black text-slate-600">
<span class="inline-flex h-6 w-6 items-center justify-center rounded-full bg-blue-50 text-blue-700">1</span>
輸入關鍵字
</div>
<div class="flex flex-col gap-3 sm:flex-row sm:items-center">
<div class="relative flex-1">
<i class="fas fa-magnifying-glass absolute left-4 top-1/2 -translate-y-1/2 text-slate-400"></i>
<input id="modal-radar-input" type="text" placeholder="例如:資安、獎學金、交換學生" class="w-full rounded-xl border border-slate-200 bg-slate-50 py-2.5 pl-11 pr-4 text-sm text-slate-800 outline-none transition-all placeholder:text-slate-400 focus:border-blue-500 focus:bg-white focus:ring-4 focus:ring-blue-500/10" />
</div>
<button id="modal-preview-btn" class="inline-flex items-center justify-center gap-2 rounded-xl bg-blue-600 px-4 py-2.5 text-sm font-bold text-white transition-colors hover:bg-blue-700 active:bg-blue-800 focus:outline-none focus:ring-4 focus:ring-blue-500/10">
<i class="fas fa-eye"></i>
<span>預覽</span>
</button>
</div>
</div>
<div class="mt-4 rounded-xl border border-slate-200 bg-white p-4 text-slate-800">
<div class="flex items-center justify-between border-b border-slate-200 pb-3">
<div class="flex items-center gap-2 text-xs font-black text-slate-600">
<span class="inline-flex h-6 w-6 items-center justify-center rounded-full bg-blue-50 text-blue-700">2</span>
目前命中公告
</div>
<span class="text-[11px] font-bold text-slate-400">最多顯示 10 筆</span>
</div>
<ul id="modal-preview-list" class="mt-3 max-h-[42vh] space-y-2.5 overflow-y-auto pr-1 custom-scrollbar text-xs"></ul>
</div>
</div>
<div id="modal-action-footer" class="hidden border-t border-slate-200 bg-white px-5 py-4 sm:px-6">
<div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<div class="flex items-center gap-2 text-xs font-black text-slate-600">
<span class="inline-flex h-6 w-6 items-center justify-center rounded-full bg-emerald-50 text-emerald-700">3</span>
加入通知條件
</div>
<button id="confirm-modal-add-keyword-btn" class="inline-flex w-full items-center justify-center gap-2 rounded-xl bg-emerald-600 px-4 py-2.5 text-sm font-bold text-white transition-colors hover:bg-emerald-700 active:bg-emerald-800 focus:outline-none focus:ring-4 focus:ring-emerald-500/10 sm:w-auto">
<i class="fas fa-circle-plus"></i>
<span>確認新增至雷達</span>
</button>
</div>
</div>
</div>
</div>
</body>
</html>