Files
HarborForge.Frontend/src/pages/NotificationsPage.tsx

70 lines
2.4 KiB
TypeScript

import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import api from '@/services/api'
import type { Notification } from '@/types'
import dayjs from 'dayjs'
export default function NotificationsPage() {
const [notifications, setNotifications] = useState<Notification[]>([])
const [unreadOnly, setUnreadOnly] = useState(false)
const [unreadCount, setUnreadCount] = useState(0)
const navigate = useNavigate()
const fetchNotifications = () => {
const params = new URLSearchParams()
if (unreadOnly) params.set('unread_only', 'true')
api.get<Notification[]>(`/notifications?${params}`).then(({ data }) => setNotifications(data))
api.get<{ count: number }>('/notifications/count').then(({ data }) => setUnreadCount(data.count)).catch(() => {})
}
useEffect(() => { fetchNotifications() }, [unreadOnly])
const markRead = async (id: number) => {
await api.post(`/notifications/${id}/read`)
fetchNotifications()
}
const markAllRead = async () => {
await api.post('/notifications/read-all')
fetchNotifications()
}
return (
<div className="notifications-page">
<div className="page-header">
<h2>🔔 Notifications {unreadCount > 0 && <span className="badge" style={{ background: 'var(--danger)' }}>{unreadCount}</span>}</h2>
{unreadCount > 0 && (
<button className="btn-primary" onClick={markAllRead}>Mark all read</button>
)}
</div>
<div className="filters">
<label className="filter-check">
<input type="checkbox" checked={unreadOnly} onChange={(e) => setUnreadOnly(e.target.checked)} />
Show unread only
</label>
</div>
<div className="notification-list">
{notifications.map((n) => (
<div
key={n.id}
className={`notification-item ${n.is_read ? 'read' : 'unread'}`}
onClick={() => {
if (!n.is_read) markRead(n.id)
if (n.task_code) navigate(`/tasks/${n.task_code}`)
}}
>
<div className="notification-dot">{n.is_read ? '' : '●'}</div>
<div className="notification-body">
<p>{n.message}</p>
<span className="text-dim">{dayjs(n.created_at).format('MM-DD HH:mm')}</span>
</div>
</div>
))}
{notifications.length === 0 && <p className="empty">No notifications</p>}
</div>
</div>
)
}