main
html 318 lines 10.3 KB
Raw
1 <html>
2
3 <head>
4 <title>Notifications</title>
5 <script type="module">
6 import { store } from "/components/notifications/notification-store.js";
7 </script>
8 </head>
9
10 <body>
11 <div x-data>
12 <template x-if="$store.notificationStore">
13 <div>
14 <!-- Modal Header Actions -->
15 <div class="modal-subheader">
16 <div class="notification-header-actions">
17 <button class="notification-action" @click="$store.notificationStore?.clearAll()"
18 :disabled="!$store.notificationStore || $store.notificationStore.getDisplayNotifications().length === 0"
19 title="Clear All">
20 <x-icon name="delete"></x-icon> Clear All
21 </button>
22 </div>
23 </div>
24
25 <!-- Notifications List -->
26 <div class="notification-list"
27 x-show="$store.notificationStore && $store.notificationStore.getDisplayNotifications().length > 0">
28 <template x-for="notification in ($store.notificationStore?.getDisplayNotifications() || [])"
29 :key="notification.id">
30 <div class="notification-item" x-data="{ expanded: false }"
31 :class="$store.notificationStore?.getNotificationItemClass(notification) || 'notification-item'"
32 @click="$store.notificationStore?.markAsRead(notification.id)">
33
34 <div class="notification-icon"
35 x-html="$store.notificationStore?.getNotificationIcon(notification.type) || ''">
36 </div>
37
38 <div class="notification-content">
39 <div class="notification-title" x-show="notification.title" x-text="notification.title">
40 </div>
41 <div class="notification-message" x-html="notification.message">
42 </div>
43 <div class="notification-timestamp"
44 x-text="$store.notificationStore?.formatTimestamp(notification.timestamp) || notification.timestamp">
45 </div>
46
47 <!-- Expand Toggle Button (as last row element) -->
48 <button class="notification-expand-toggle" x-show="notification.detail"
49 @click.stop="expanded = !expanded"
50 :title="expanded ? 'Collapse Details' : 'Expand Details'">
51 <span x-show="!expanded">▶ Show Details</span>
52 <span x-show="expanded">▼ Hide Details</span>
53 </button>
54
55 <!-- Expandable Detail Content -->
56 <div class="notification-detail" x-show="expanded && notification.detail"
57 x-transition:enter="transition ease-out duration-200"
58 x-transition:enter-start="opacity-0 max-h-0"
59 x-transition:enter-end="opacity-100 max-h-96"
60 x-transition:leave="transition ease-in duration-200"
61 x-transition:leave-start="opacity-100 max-h-96"
62 x-transition:leave-end="opacity-0 max-h-0">
63 <div class="notification-detail-content" x-html="notification.detail"></div>
64 </div>
65 </div>
66 </div>
67 </template>
68 </div>
69
70 <!-- Empty State -->
71 <div class="notification-empty"
72 x-show="!$store.notificationStore || $store.notificationStore.getDisplayNotifications().length === 0">
73 <div class="notification-empty-icon">
74 <x-icon name="notifications"></x-icon>
75 </div>
76 <p>No notifications to display</p>
77 </div>
78 </div>
79 </template>
80 </div>
81
82 <style>
83 /* Modal-specific styles that override the standard modal */
84 .modal-container.notification-modal {
85 width: 90%;
86 max-width: 600px;
87 max-height: 80vh;
88 }
89
90 .notification-header-actions {
91 display: flex;
92 gap: 0.5rem;
93 align-items: center;
94 justify-content: flex-end;
95 width: 100%;
96 }
97
98 .notification-action {
99 padding: 0.5rem 0.75rem;
100 background: rgba(255, 255, 255, 0.1);
101 border: 1px solid rgba(255, 255, 255, 0.2);
102 border-radius: 4px;
103 color: var(--color-text);
104 cursor: pointer;
105 transition: all 0.2s ease;
106 font-size: 0.85rem;
107 display: flex;
108 align-items: center;
109 gap: 0.25rem;
110 }
111
112 .notification-action:hover {
113 background: rgba(255, 255, 255, 0.15);
114 border-color: rgba(255, 255, 255, 0.3);
115 }
116
117 .notification-action:disabled {
118 opacity: 0.4;
119 cursor: not-allowed;
120 }
121
122 .notification-action:disabled:hover {
123 background: rgba(255, 255, 255, 0.1);
124 border-color: rgba(255, 255, 255, 0.2);
125 }
126
127 /* Notification List */
128 .notification-list {
129 max-height: 60vh;
130 overflow-y: auto;
131 padding: 0.5rem 0;
132 }
133
134 .notification-list::-webkit-scrollbar {
135 width: 6px;
136 }
137
138 .notification-list::-webkit-scrollbar-track {
139 background: transparent;
140 }
141
142 .notification-list::-webkit-scrollbar-thumb {
143 background-color: rgba(155, 155, 155, 0.5);
144 border-radius: 6px;
145 transition: background-color 0.2s ease;
146 }
147
148 .notification-list::-webkit-scrollbar-thumb:hover {
149 background-color: rgba(155, 155, 155, 0.7);
150 }
151
152 /* Include all the notification item styles from the CSS file */
153 .notification-item {
154 display: flex;
155 align-items: flex-start;
156 gap: 0.75rem;
157 padding: 1rem;
158 margin-bottom: 0.5rem;
159 background: rgba(0, 0, 0, 0.1);
160 border: 1px solid rgba(255, 255, 255, 0.1);
161 border-radius: 8px;
162 cursor: pointer;
163 transition: all 0.2s ease;
164 position: relative;
165 }
166
167 .notification-item:hover {
168 background: rgba(0, 0, 0, 0.15);
169 border-color: rgba(255, 255, 255, 0.2);
170 }
171
172 .notification-item:last-child {
173 margin-bottom: 0;
174 }
175
176 .notification-item.unread {
177 border-left: 4px solid var(--color-primary);
178 background: var(--color-panel);
179 }
180
181 .notification-item.read {
182 opacity: 0.85;
183 background: var(--color-panel);
184 }
185
186 .notification-item.read .notification-title {
187 color: var(--color-text-muted);
188 }
189
190 .notification-item.read .notification-message {
191 color: var(--color-text-muted);
192 }
193
194 /* Notification Icon */
195 .notification-icon {
196 font-size: 1.1rem;
197 line-height: 1;
198 opacity: 0.8;
199 min-width: 20px;
200 text-align: center;
201 margin-top: 0.1rem;
202 }
203
204 .notification-info .notification-icon {
205 color: #2196F3;
206 }
207
208 .notification-success .notification-icon {
209 color: #4CAF50;
210 }
211
212 .notification-warning .notification-icon {
213 color: #FF9800;
214 }
215
216 .notification-error .notification-icon {
217 color: #F44336;
218 }
219
220 .notification-progress .notification-icon {
221 color: #9C27B0;
222 animation: spin 2s linear infinite;
223 }
224
225 /* Notification Content */
226 .notification-content {
227 flex: 1;
228 min-width: 0;
229 }
230
231 .notification-title {
232 font-weight: 600;
233 font-size: 0.9rem;
234 color: var(--color-primary);
235 margin-bottom: 0.25rem;
236 line-height: 1.3;
237 }
238
239 .notification-message {
240 font-size: 0.85rem;
241 color: var(--color-text);
242 line-height: 1.4;
243 margin-bottom: 0.5rem;
244 }
245
246 .notification-expand-toggle {
247 background: transparent;
248 border: none;
249 color: var(--color-text);
250 cursor: pointer;
251 padding: 0.25rem;
252 border-radius: 4px;
253 transition: all 0.2s ease;
254 font-size: 0.8rem;
255 opacity: 0.7;
256 display: flex;
257 align-items: center;
258 gap: 0.25rem;
259 }
260
261 .notification-expand-toggle:hover {
262 opacity: 1;
263 background: rgba(255, 255, 255, 0.1);
264 }
265
266 .notification-timestamp {
267 font-size: 0.75rem;
268 color: var(--color-text);
269 opacity: 0.6;
270 margin-top: 0.5rem;
271 }
272
273 /* Notification Detail */
274 .notification-detail {
275 margin-top: 0.75rem;
276 padding: 0.75rem;
277 background: rgba(0, 0, 0, 0.1);
278 border-radius: 6px;
279 border-left: 3px solid rgba(255, 255, 255, 0.2);
280 overflow: hidden;
281 transition: all 0.2s ease;
282 }
283
284 .notification-detail-content {
285 font-size: 0.85rem;
286 line-height: 1.4;
287 color: var(--color-text);
288 }
289
290 /* Empty State */
291 .notification-empty {
292 text-align: center;
293 padding: 3rem 1rem;
294 color: var(--color-text);
295 opacity: 0.6;
296 }
297
298 .notification-empty-icon {
299 font-size: 3rem;
300 margin-bottom: 1rem;
301 opacity: 0.5;
302 }
303
304 /* Animations */
305 @keyframes spin {
306 from {
307 transform: rotate(0deg);
308 }
309
310 to {
311 transform: rotate(360deg);
312 }
313 }
314 </style>
315
316 </body>
317
318 </html>