Download src/lib/notificationStore.ts from Esketch/CarboAny: direct link, hf CLI and curl.
- Browser
- Download file 2.68 kB
-
https://huggingface.co/spaces/Esketch/CarboAny/resolve/main/src/lib/notificationStore.ts
- Command line
-
hf download hf://spaces/Esketch/CarboAny/src/lib/notificationStore.ts
-
curl -L -o notificationStore.ts https://huggingface.co/spaces/Esketch/CarboAny/resolve/main/src/lib/notificationStore.ts
2.68 kB
| // Notification store (Supabase-backed) | |
| import { supabase } from './supabase'; | |
| export type NotificationType = 'approval_result' | 'new_request' | 'status_change' | 'system'; | |
| export interface Notification { | |
| id: string; | |
| userId: string; | |
| type: NotificationType; | |
| title: string; | |
| body: string; | |
| linkTo?: string; | |
| relatedApprovalId?: string; | |
| read: boolean; | |
| createdAt: string; | |
| } | |
| // --- Mapping helpers --- | |
| function dbToNotif(row: Record<string, unknown>): Notification { | |
| return { | |
| id: row.id as string, | |
| userId: row.user_id as string, | |
| type: row.type as NotificationType, | |
| title: row.title as string, | |
| body: row.body as string, | |
| linkTo: (row.link_to as string) ?? undefined, | |
| relatedApprovalId: (row.related_approval_id as string) ?? undefined, | |
| read: row.read as boolean, | |
| createdAt: row.created_at as string, | |
| }; | |
| } | |
| // --- CRUD --- | |
| export async function getNotifications(userId: string): Promise<Notification[]> { | |
| const { data, error } = await supabase | |
| .from('notifications') | |
| .select('*') | |
| .eq('user_id', userId) | |
| .order('created_at', { ascending: false }) | |
| .limit(50); | |
| if (error) { | |
| console.error('getNotifications error:', error); | |
| return []; | |
| } | |
| return (data ?? []).map(dbToNotif); | |
| } | |
| export async function getUnreadCount(userId: string): Promise<number> { | |
| const { count, error } = await supabase | |
| .from('notifications') | |
| .select('*', { count: 'exact', head: true }) | |
| .eq('user_id', userId) | |
| .eq('read', false); | |
| if (error) { | |
| console.error('getUnreadCount error:', error); | |
| return 0; | |
| } | |
| return count ?? 0; | |
| } | |
| export async function createNotification( | |
| n: Omit<Notification, 'id' | 'createdAt' | 'read'>, | |
| ): Promise<Notification | null> { | |
| const row = { | |
| user_id: n.userId, | |
| type: n.type, | |
| title: n.title, | |
| body: n.body, | |
| link_to: n.linkTo ?? null, | |
| related_approval_id: n.relatedApprovalId ?? null, | |
| read: false, | |
| }; | |
| const { data, error } = await supabase | |
| .from('notifications') | |
| .insert(row) | |
| .select() | |
| .single(); | |
| if (error) { | |
| console.error('createNotification error:', error); | |
| return null; | |
| } | |
| return dbToNotif(data); | |
| } | |
| export async function markAsRead(id: string): Promise<void> { | |
| const { error } = await supabase | |
| .from('notifications') | |
| .update({ read: true }) | |
| .eq('id', id); | |
| if (error) console.error('markAsRead error:', error); | |
| } | |
| export async function markAllAsRead(userId: string): Promise<void> { | |
| const { error } = await supabase | |
| .from('notifications') | |
| .update({ read: true }) | |
| .eq('user_id', userId) | |
| .eq('read', false); | |
| if (error) console.error('markAllAsRead error:', error); | |
| } | |