source: chapterx-frontend/src/pages/NotificationsPage.tsx@ 7fbb91c

main
Last change on this file since 7fbb91c was b62cefc, checked in by kikisrbinoska <srbinoskakristina07@…>, 4 months ago

Added frontend and imporoved AI Suggestions service

  • Property mode set to 100644
File size: 4.1 KB
Line 
1import React from 'react'
2import { useNavigate } from 'react-router-dom'
3import { Bell, Heart, MessageCircle, Users, Settings, Check, ExternalLink } from 'lucide-react'
4import { useNotificationStore } from '../store/notificationStore'
5import { useAuthStore } from '../store/authStore'
6import { Button } from '../components/ui/Button'
7import { NotificationType } from '../types'
8
9const typeIcon = (type: NotificationType) => {
10 switch (type) {
11 case 'like': return <Heart size={16} className="text-rose-400" />
12 case 'comment': return <MessageCircle size={16} className="text-blue-400" />
13 case 'collaboration': return <Users size={16} className="text-violet-400" />
14 case 'system': return <Settings size={16} className="text-slate-400" />
15 default: return <Bell size={16} className="text-slate-400" />
16 }
17}
18
19function formatDate(str: string) {
20 return new Date(str).toLocaleDateString('en-US', {
21 month: 'short', day: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit',
22 })
23}
24
25export const NotificationsPage: React.FC = () => {
26 const navigate = useNavigate()
27 const { currentUser } = useAuthStore()
28 const { notifications, markAllRead, markRead } = useNotificationStore()
29
30 if (!currentUser) {
31 return (
32 <div className="max-w-2xl mx-auto px-4 py-20 text-center">
33 <Bell size={48} className="mx-auto mb-4 text-slate-600" />
34 <h2 className="text-2xl text-white mb-4">Sign in to view notifications</h2>
35 <Button onClick={() => navigate('/login')}>Sign In</Button>
36 </div>
37 )
38 }
39
40 const userNotifications = notifications
41 const unread = userNotifications.filter(n => !n.is_read)
42
43 return (
44 <div className="max-w-2xl mx-auto px-4 py-8">
45 <div className="flex items-center justify-between mb-8">
46 <div>
47 <h1 className="font-serif text-2xl font-bold text-white">Notifications</h1>
48 {unread.length > 0 && (
49 <p className="text-slate-400 text-sm mt-1">{unread.length} unread</p>
50 )}
51 </div>
52 {unread.length > 0 && (
53 <Button variant="ghost" size="sm" onClick={markAllRead}>
54 <Check size={14} />
55 Mark all read
56 </Button>
57 )}
58 </div>
59
60 {userNotifications.length === 0 ? (
61 <div className="text-center py-16 text-slate-500">
62 <Bell size={48} className="mx-auto mb-4 opacity-40" />
63 <p className="text-lg font-medium">No notifications yet</p>
64 <p className="text-sm mt-1">You'll see activity here when readers interact with your content.</p>
65 </div>
66 ) : (
67 <div className="space-y-2">
68 {userNotifications.map(n => (
69 <div
70 key={n.notification_id}
71 className={`flex gap-4 p-4 rounded-2xl border transition-colors cursor-pointer ${
72 !n.is_read
73 ? 'bg-indigo-500/5 border-indigo-500/20 hover:bg-indigo-500/10'
74 : 'bg-slate-800 border-slate-700 hover:bg-slate-700/50'
75 }`}
76 onClick={() => {
77 markRead(n.notification_id)
78 if (n.link) navigate(n.link)
79 }}
80 >
81 <div className="w-10 h-10 rounded-full bg-slate-700 flex items-center justify-center flex-shrink-0">
82 {typeIcon(n.type)}
83 </div>
84 <div className="flex-1 min-w-0">
85 <div className="flex items-start justify-between gap-2">
86 <p className="text-white text-sm font-medium">{n.title}</p>
87 <div className="flex items-center gap-2 flex-shrink-0">
88 {!n.is_read && (
89 <div className="w-2 h-2 rounded-full bg-indigo-400" />
90 )}
91 {n.link && (
92 <ExternalLink size={12} className="text-slate-600" />
93 )}
94 </div>
95 </div>
96 <p className="text-slate-400 text-sm mt-0.5 leading-relaxed">{n.message}</p>
97 <p className="text-slate-600 text-xs mt-2">{formatDate(n.created_at)}</p>
98 </div>
99 </div>
100 ))}
101 </div>
102 )}
103 </div>
104 )
105}
Note: See TracBrowser for help on using the repository browser.