a a vibe-coded abomination experiment of a fragrance review platform built on the atmosphere.
drydown.social
1/**
2 * Client-side notification preference management
3 * Stores user's per-review notification opt-in choices in localStorage
4 */
5
6interface NotificationPreferences {
7 [reviewUri: string]: {
8 stage2?: boolean
9 stage3?: boolean
10 }
11}
12
13const STORAGE_KEY = 'drydown:notification-prefs'
14
15export class NotificationService {
16 /**
17 * Get notification preferences for a specific review
18 */
19 static getPreferences(reviewUri: string): { stage2: boolean; stage3: boolean } {
20 const prefs = this.getAllPreferences()
21 const reviewPrefs = prefs[reviewUri] || {}
22 return {
23 stage2: reviewPrefs.stage2 || false,
24 stage3: reviewPrefs.stage3 || false
25 }
26 }
27
28 /**
29 * Set notification preference for a specific review stage
30 */
31 static setPreference(reviewUri: string, stage: 'stage2' | 'stage3', enabled: boolean): void {
32 const prefs = this.getAllPreferences()
33
34 if (!prefs[reviewUri]) {
35 prefs[reviewUri] = {}
36 }
37
38 prefs[reviewUri][stage] = enabled
39
40 localStorage.setItem(STORAGE_KEY, JSON.stringify(prefs))
41 }
42
43 /**
44 * Check if user should be notified for a specific review + stage
45 */
46 static shouldNotify(reviewUri: string, stage: 'stage2' | 'stage3'): boolean {
47 const prefs = this.getPreferences(reviewUri)
48 return prefs[stage] || false
49 }
50
51 /**
52 * Request browser notification permission if needed
53 * Returns true if permission is granted or was already granted
54 */
55 static async requestPermission(): Promise<boolean> {
56 if (!('Notification' in window)) {
57 return false
58 }
59
60 if (Notification.permission === 'granted') {
61 return true
62 }
63
64 if (Notification.permission === 'default') {
65 const result = await Notification.requestPermission()
66 return result === 'granted'
67 }
68
69 return false
70 }
71
72 /**
73 * Get all stored notification preferences
74 */
75 private static getAllPreferences(): NotificationPreferences {
76 try {
77 const stored = localStorage.getItem(STORAGE_KEY)
78 return stored ? JSON.parse(stored) : {}
79 } catch (e) {
80 console.error('Failed to parse notification preferences', e)
81 return {}
82 }
83 }
84
85 /**
86 * Clear all notification preferences (for testing/debugging)
87 */
88 static clearAll(): void {
89 localStorage.removeItem(STORAGE_KEY)
90 }
91}