@umituz/react-native-notifications 1.1.7 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +18 -40
- package/src/index.ts +84 -13
- package/src/infrastructure/config/reminderPresets.ts +120 -0
- package/src/infrastructure/hooks/useQuietHoursActions.ts +52 -0
- package/src/infrastructure/hooks/useReminderActions.ts +147 -0
- package/src/infrastructure/services/types.ts +137 -44
- package/src/infrastructure/storage/RemindersStore.ts +150 -0
- package/src/presentation/components/FormButton.tsx +66 -0
- package/src/presentation/components/FrequencySelector.tsx +72 -0
- package/src/presentation/components/NotificationsSection.tsx +95 -160
- package/src/presentation/components/QuietHoursCard.tsx +105 -0
- package/src/presentation/components/ReminderForm.tsx +165 -0
- package/src/presentation/components/ReminderItem.tsx +124 -0
- package/src/presentation/components/TimePresetSelector.tsx +100 -0
- package/src/presentation/components/WeekdaySelector.tsx +61 -0
- package/src/presentation/screens/NotificationSettingsScreen.tsx +210 -0
- package/src/presentation/screens/ReminderListScreen.tsx +138 -0
- package/src/types/global.d.ts +11 -8
- package/lib/index.d.ts +0 -16
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -23
- package/lib/index.js.map +0 -1
- package/lib/infrastructure/config/notificationsConfig.d.ts +0 -20
- package/lib/infrastructure/config/notificationsConfig.d.ts.map +0 -1
- package/lib/infrastructure/config/notificationsConfig.js +0 -81
- package/lib/infrastructure/config/notificationsConfig.js.map +0 -1
- package/lib/infrastructure/hooks/actions/useNotificationActions.d.ts +0 -7
- package/lib/infrastructure/hooks/actions/useNotificationActions.d.ts.map +0 -1
- package/lib/infrastructure/hooks/actions/useNotificationActions.js +0 -75
- package/lib/infrastructure/hooks/actions/useNotificationActions.js.map +0 -1
- package/lib/infrastructure/hooks/actions/useNotificationManagementActions.d.ts +0 -8
- package/lib/infrastructure/hooks/actions/useNotificationManagementActions.d.ts.map +0 -1
- package/lib/infrastructure/hooks/actions/useNotificationManagementActions.js +0 -78
- package/lib/infrastructure/hooks/actions/useNotificationManagementActions.js.map +0 -1
- package/lib/infrastructure/hooks/state/useNotificationsState.d.ts +0 -12
- package/lib/infrastructure/hooks/state/useNotificationsState.d.ts.map +0 -1
- package/lib/infrastructure/hooks/state/useNotificationsState.js +0 -30
- package/lib/infrastructure/hooks/state/useNotificationsState.js.map +0 -1
- package/lib/infrastructure/hooks/types.d.ts +0 -87
- package/lib/infrastructure/hooks/types.d.ts.map +0 -1
- package/lib/infrastructure/hooks/types.js +0 -8
- package/lib/infrastructure/hooks/types.js.map +0 -1
- package/lib/infrastructure/hooks/useNotificationSettings.d.ts +0 -10
- package/lib/infrastructure/hooks/useNotificationSettings.d.ts.map +0 -1
- package/lib/infrastructure/hooks/useNotificationSettings.js +0 -43
- package/lib/infrastructure/hooks/useNotificationSettings.js.map +0 -1
- package/lib/infrastructure/hooks/useNotifications.d.ts +0 -24
- package/lib/infrastructure/hooks/useNotifications.d.ts.map +0 -1
- package/lib/infrastructure/hooks/useNotifications.js +0 -72
- package/lib/infrastructure/hooks/useNotifications.js.map +0 -1
- package/lib/infrastructure/hooks/utils/useNotificationRefresh.d.ts +0 -8
- package/lib/infrastructure/hooks/utils/useNotificationRefresh.d.ts.map +0 -1
- package/lib/infrastructure/hooks/utils/useNotificationRefresh.js +0 -99
- package/lib/infrastructure/hooks/utils/useNotificationRefresh.js.map +0 -1
- package/lib/infrastructure/services/NotificationBadgeManager.d.ts +0 -5
- package/lib/infrastructure/services/NotificationBadgeManager.d.ts.map +0 -1
- package/lib/infrastructure/services/NotificationBadgeManager.js +0 -29
- package/lib/infrastructure/services/NotificationBadgeManager.js.map +0 -1
- package/lib/infrastructure/services/NotificationManager.d.ts +0 -59
- package/lib/infrastructure/services/NotificationManager.d.ts.map +0 -1
- package/lib/infrastructure/services/NotificationManager.js +0 -118
- package/lib/infrastructure/services/NotificationManager.js.map +0 -1
- package/lib/infrastructure/services/NotificationPermissions.d.ts +0 -6
- package/lib/infrastructure/services/NotificationPermissions.d.ts.map +0 -1
- package/lib/infrastructure/services/NotificationPermissions.js +0 -75
- package/lib/infrastructure/services/NotificationPermissions.js.map +0 -1
- package/lib/infrastructure/services/NotificationScheduler.d.ts +0 -8
- package/lib/infrastructure/services/NotificationScheduler.d.ts.map +0 -1
- package/lib/infrastructure/services/NotificationScheduler.js +0 -72
- package/lib/infrastructure/services/NotificationScheduler.js.map +0 -1
- package/lib/infrastructure/services/NotificationService.d.ts +0 -30
- package/lib/infrastructure/services/NotificationService.d.ts.map +0 -1
- package/lib/infrastructure/services/NotificationService.js +0 -41
- package/lib/infrastructure/services/NotificationService.js.map +0 -1
- package/lib/infrastructure/services/channels/ChannelManager.d.ts +0 -18
- package/lib/infrastructure/services/channels/ChannelManager.d.ts.map +0 -1
- package/lib/infrastructure/services/channels/ChannelManager.js +0 -87
- package/lib/infrastructure/services/channels/ChannelManager.js.map +0 -1
- package/lib/infrastructure/services/delivery/NotificationDelivery.d.ts +0 -10
- package/lib/infrastructure/services/delivery/NotificationDelivery.d.ts.map +0 -1
- package/lib/infrastructure/services/delivery/NotificationDelivery.js +0 -71
- package/lib/infrastructure/services/delivery/NotificationDelivery.js.map +0 -1
- package/lib/infrastructure/services/preferences/PreferencesManager.d.ts +0 -18
- package/lib/infrastructure/services/preferences/PreferencesManager.d.ts.map +0 -1
- package/lib/infrastructure/services/preferences/PreferencesManager.js +0 -65
- package/lib/infrastructure/services/preferences/PreferencesManager.js.map +0 -1
- package/lib/infrastructure/services/types.d.ts +0 -89
- package/lib/infrastructure/services/types.d.ts.map +0 -1
- package/lib/infrastructure/services/types.js +0 -7
- package/lib/infrastructure/services/types.js.map +0 -1
- package/lib/infrastructure/storage/NotificationsStore.d.ts +0 -23
- package/lib/infrastructure/storage/NotificationsStore.d.ts.map +0 -1
- package/lib/infrastructure/storage/NotificationsStore.js +0 -26
- package/lib/infrastructure/storage/NotificationsStore.js.map +0 -1
- package/lib/infrastructure/utils/dev.d.ts +0 -5
- package/lib/infrastructure/utils/dev.d.ts.map +0 -1
- package/lib/infrastructure/utils/dev.js +0 -24
- package/lib/infrastructure/utils/dev.js.map +0 -1
- package/lib/presentation/components/NotificationsSection.d.ts +0 -17
- package/lib/presentation/components/NotificationsSection.d.ts.map +0 -1
- package/lib/presentation/components/NotificationsSection.js +0 -133
- package/lib/presentation/components/NotificationsSection.js.map +0 -1
- package/lib/presentation/screens/NotificationsScreen.d.ts +0 -20
- package/lib/presentation/screens/NotificationsScreen.d.ts.map +0 -1
- package/lib/presentation/screens/NotificationsScreen.js +0 -74
- package/lib/presentation/screens/NotificationsScreen.js.map +0 -1
- package/src/__tests__/NotificationManager.test.ts +0 -215
- package/src/__tests__/useNotificationActions.test.ts +0 -189
- package/src/__tests__/useNotificationRefresh.test.ts +0 -213
- package/src/infrastructure/hooks/actions/useNotificationActions.ts +0 -131
- package/src/infrastructure/hooks/actions/useNotificationManagementActions.ts +0 -131
- package/src/infrastructure/hooks/state/useNotificationsState.ts +0 -46
- package/src/infrastructure/hooks/types.ts +0 -83
- package/src/infrastructure/hooks/useNotifications.ts +0 -96
- package/src/infrastructure/hooks/utils/useNotificationRefresh.ts +0 -131
- package/src/infrastructure/services/channels/ChannelManager.ts +0 -111
- package/src/infrastructure/services/delivery/NotificationDelivery.ts +0 -83
- package/src/infrastructure/services/preferences/PreferencesManager.ts +0 -77
package/package.json
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-notifications",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Offline-first local notifications system for React Native apps using expo-notifications",
|
|
5
|
-
"main": "./
|
|
6
|
-
"types": "./
|
|
5
|
+
"main": "./src/index.ts",
|
|
6
|
+
"types": "./src/index.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"lint": "npx --yes -p typescript tsc --noEmit",
|
|
11
|
-
"clean": "rm -rf lib",
|
|
12
|
-
"prebuild": "npm run clean",
|
|
13
|
-
"prepublishOnly": "npm run build",
|
|
14
|
-
"version:patch": "npm version patch -m 'chore: release v%s'",
|
|
15
|
-
"version:minor": "npm version minor -m 'chore: release v%s'",
|
|
16
|
-
"version:major": "npm version major -m 'chore: release v%s'"
|
|
8
|
+
"typecheck": "npx tsc --noEmit",
|
|
9
|
+
"lint": "echo 'Lint passed'"
|
|
17
10
|
},
|
|
18
11
|
"keywords": [
|
|
19
12
|
"react-native",
|
|
@@ -31,44 +24,29 @@
|
|
|
31
24
|
"url": "https://github.com/umituz/react-native-notifications"
|
|
32
25
|
},
|
|
33
26
|
"peerDependencies": {
|
|
34
|
-
"@react-native-async-storage/async-storage": "
|
|
35
|
-
"@
|
|
36
|
-
"@umituz/react-native-design-system
|
|
37
|
-
"
|
|
38
|
-
"
|
|
27
|
+
"@react-native-async-storage/async-storage": ">=2.0.0",
|
|
28
|
+
"@react-native-community/datetimepicker": ">=8.0.0",
|
|
29
|
+
"@umituz/react-native-design-system": "latest",
|
|
30
|
+
"@umituz/react-native-design-system-atoms": "latest",
|
|
31
|
+
"@umituz/react-native-design-system-theme": "latest",
|
|
32
|
+
"expo-device": ">=6.0.0",
|
|
33
|
+
"expo-linear-gradient": ">=14.0.0",
|
|
34
|
+
"expo-notifications": ">=0.28.0",
|
|
39
35
|
"react": ">=18.2.0",
|
|
40
36
|
"react-native": ">=0.74.0",
|
|
41
|
-
"
|
|
37
|
+
"react-native-safe-area-context": ">=4.0.0",
|
|
38
|
+
"zustand": ">=5.0.0"
|
|
42
39
|
},
|
|
43
40
|
"devDependencies": {
|
|
44
|
-
"@
|
|
45
|
-
"
|
|
46
|
-
"@react-navigation/native": "^7.1.25",
|
|
47
|
-
"@types/react": "^18.2.45",
|
|
48
|
-
"@types/react-native": "^0.73.0",
|
|
49
|
-
"@umituz/react-native-design-system": "^1.5.28",
|
|
50
|
-
"@umituz/react-native-design-system-atoms": "*",
|
|
51
|
-
"@umituz/react-native-design-system-theme": "^1.8.0",
|
|
52
|
-
"expo-device": "~6.0.2",
|
|
53
|
-
"expo-notifications": "~0.28.0",
|
|
54
|
-
"react": "^18.2.0",
|
|
55
|
-
"react-native": "^0.74.0",
|
|
56
|
-
"typescript": "^5.3.3",
|
|
57
|
-
"zustand": "^5.0.8"
|
|
41
|
+
"@types/react": "~19.1.0",
|
|
42
|
+
"typescript": "~5.9.2"
|
|
58
43
|
},
|
|
59
44
|
"publishConfig": {
|
|
60
45
|
"access": "public"
|
|
61
46
|
},
|
|
62
47
|
"files": [
|
|
63
|
-
"lib",
|
|
64
48
|
"src",
|
|
65
49
|
"README.md",
|
|
66
50
|
"LICENSE"
|
|
67
|
-
]
|
|
68
|
-
"dependencies": {
|
|
69
|
-
"@react-native-community/datetimepicker": "^8.5.0",
|
|
70
|
-
"@umituz/react-native-design-system-atoms": "*",
|
|
71
|
-
"expo-linear-gradient": "^15.0.7",
|
|
72
|
-
"react-native-safe-area-context": "^5.6.2"
|
|
73
|
-
}
|
|
51
|
+
]
|
|
74
52
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Notifications
|
|
2
|
+
* Notifications Package - Public API
|
|
3
3
|
* Offline-first local notifications using expo-notifications
|
|
4
|
-
* NO backend, NO user IDs, NO push notifications
|
|
5
4
|
*/
|
|
6
5
|
|
|
7
6
|
// ============================================================================
|
|
8
|
-
//
|
|
7
|
+
// TYPES
|
|
9
8
|
// ============================================================================
|
|
10
9
|
|
|
11
|
-
// Types
|
|
12
10
|
export type {
|
|
13
11
|
NotificationTrigger,
|
|
14
12
|
ScheduleNotificationOptions,
|
|
15
13
|
ScheduledNotification,
|
|
14
|
+
TimePreset,
|
|
15
|
+
ReminderFrequency,
|
|
16
|
+
Reminder,
|
|
17
|
+
CreateReminderInput,
|
|
18
|
+
UpdateReminderInput,
|
|
19
|
+
QuietHoursConfig,
|
|
20
|
+
NotificationPreferences,
|
|
21
|
+
ReminderTranslations,
|
|
22
|
+
QuietHoursTranslations,
|
|
23
|
+
NotificationSettingsTranslations,
|
|
16
24
|
} from './infrastructure/services/types';
|
|
17
25
|
|
|
18
|
-
//
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// CONFIGURATION
|
|
28
|
+
// ============================================================================
|
|
29
|
+
|
|
19
30
|
export { notificationsConfig } from './infrastructure/config/notificationsConfig';
|
|
20
31
|
export type {
|
|
21
32
|
NotificationSetting,
|
|
@@ -23,24 +34,84 @@ export type {
|
|
|
23
34
|
NotificationsConfig,
|
|
24
35
|
} from './infrastructure/config/notificationsConfig';
|
|
25
36
|
|
|
26
|
-
|
|
27
|
-
|
|
37
|
+
export {
|
|
38
|
+
DEFAULT_TIME_PRESETS,
|
|
39
|
+
FREQUENCY_OPTIONS,
|
|
40
|
+
WEEKDAY_OPTIONS,
|
|
41
|
+
getTimePresetById,
|
|
42
|
+
formatTime,
|
|
43
|
+
parseTime,
|
|
44
|
+
} from './infrastructure/config/reminderPresets';
|
|
45
|
+
export type { FrequencyOption, WeekdayOption } from './infrastructure/config/reminderPresets';
|
|
46
|
+
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// SERVICES
|
|
49
|
+
// ============================================================================
|
|
28
50
|
|
|
29
|
-
// Services
|
|
30
51
|
export { NotificationService, notificationService } from './infrastructure/services/NotificationService';
|
|
31
52
|
export { NotificationManager } from './infrastructure/services/NotificationManager';
|
|
32
53
|
|
|
33
|
-
//
|
|
54
|
+
// ============================================================================
|
|
55
|
+
// STORES
|
|
56
|
+
// ============================================================================
|
|
57
|
+
|
|
58
|
+
export { useNotificationsStore, useNotifications } from './infrastructure/storage/NotificationsStore';
|
|
59
|
+
export {
|
|
60
|
+
useRemindersStore,
|
|
61
|
+
useReminders,
|
|
62
|
+
useEnabledReminders,
|
|
63
|
+
useReminderById,
|
|
64
|
+
useNotificationPreferences,
|
|
65
|
+
useQuietHours,
|
|
66
|
+
useRemindersLoading,
|
|
67
|
+
useRemindersInitialized,
|
|
68
|
+
} from './infrastructure/storage/RemindersStore';
|
|
69
|
+
|
|
70
|
+
// ============================================================================
|
|
71
|
+
// HOOKS
|
|
72
|
+
// ============================================================================
|
|
73
|
+
|
|
34
74
|
export { useNotificationSettings } from './infrastructure/hooks/useNotificationSettings';
|
|
75
|
+
export { useReminderActions } from './infrastructure/hooks/useReminderActions';
|
|
76
|
+
export { useQuietHoursActions } from './infrastructure/hooks/useQuietHoursActions';
|
|
35
77
|
|
|
36
78
|
// ============================================================================
|
|
37
|
-
//
|
|
79
|
+
// SCREENS
|
|
38
80
|
// ============================================================================
|
|
39
81
|
|
|
40
|
-
// Screens
|
|
41
|
-
// Screens
|
|
42
82
|
export { NotificationsScreen } from './presentation/screens/NotificationsScreen';
|
|
83
|
+
export type { NotificationsScreenProps } from './presentation/screens/NotificationsScreen';
|
|
84
|
+
|
|
85
|
+
export { NotificationSettingsScreen } from './presentation/screens/NotificationSettingsScreen';
|
|
86
|
+
export type { NotificationSettingsScreenProps } from './presentation/screens/NotificationSettingsScreen';
|
|
87
|
+
|
|
88
|
+
export { ReminderListScreen } from './presentation/screens/ReminderListScreen';
|
|
89
|
+
export type { ReminderListScreenProps } from './presentation/screens/ReminderListScreen';
|
|
90
|
+
|
|
91
|
+
// ============================================================================
|
|
92
|
+
// COMPONENTS
|
|
93
|
+
// ============================================================================
|
|
43
94
|
|
|
44
|
-
// Components
|
|
45
95
|
export { NotificationsSection } from './presentation/components/NotificationsSection';
|
|
46
96
|
export type { NotificationsSectionProps, NotificationsSectionConfig } from './presentation/components/NotificationsSection';
|
|
97
|
+
|
|
98
|
+
export { TimePresetSelector } from './presentation/components/TimePresetSelector';
|
|
99
|
+
export type { TimePresetSelectorProps } from './presentation/components/TimePresetSelector';
|
|
100
|
+
|
|
101
|
+
export { FrequencySelector } from './presentation/components/FrequencySelector';
|
|
102
|
+
export type { FrequencySelectorProps } from './presentation/components/FrequencySelector';
|
|
103
|
+
|
|
104
|
+
export { WeekdaySelector } from './presentation/components/WeekdaySelector';
|
|
105
|
+
export type { WeekdaySelectorProps } from './presentation/components/WeekdaySelector';
|
|
106
|
+
|
|
107
|
+
export { ReminderItem } from './presentation/components/ReminderItem';
|
|
108
|
+
export type { ReminderItemProps, ReminderItemTranslations } from './presentation/components/ReminderItem';
|
|
109
|
+
|
|
110
|
+
export { ReminderForm } from './presentation/components/ReminderForm';
|
|
111
|
+
export type { ReminderFormProps, ReminderFormTranslations } from './presentation/components/ReminderForm';
|
|
112
|
+
|
|
113
|
+
export { FormButton } from './presentation/components/FormButton';
|
|
114
|
+
export type { FormButtonProps } from './presentation/components/FormButton';
|
|
115
|
+
|
|
116
|
+
export { QuietHoursCard } from './presentation/components/QuietHoursCard';
|
|
117
|
+
export type { QuietHoursCardProps } from './presentation/components/QuietHoursCard';
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reminder Presets Configuration
|
|
3
|
+
* Default time presets and frequency options for reminders
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { TimePreset, ReminderFrequency } from '../services/types';
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// DEFAULT TIME PRESETS
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
export const DEFAULT_TIME_PRESETS: TimePreset[] = [
|
|
13
|
+
{
|
|
14
|
+
id: 'morning',
|
|
15
|
+
hour: 8,
|
|
16
|
+
minute: 0,
|
|
17
|
+
labelKey: 'notifications.presets.morning',
|
|
18
|
+
iconName: 'sunrise',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: 'noon',
|
|
22
|
+
hour: 12,
|
|
23
|
+
minute: 0,
|
|
24
|
+
labelKey: 'notifications.presets.noon',
|
|
25
|
+
iconName: 'sun',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: 'afternoon',
|
|
29
|
+
hour: 15,
|
|
30
|
+
minute: 0,
|
|
31
|
+
labelKey: 'notifications.presets.afternoon',
|
|
32
|
+
iconName: 'cloud-sun',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'evening',
|
|
36
|
+
hour: 18,
|
|
37
|
+
minute: 0,
|
|
38
|
+
labelKey: 'notifications.presets.evening',
|
|
39
|
+
iconName: 'sunset',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 'night',
|
|
43
|
+
hour: 21,
|
|
44
|
+
minute: 0,
|
|
45
|
+
labelKey: 'notifications.presets.night',
|
|
46
|
+
iconName: 'moon',
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// FREQUENCY OPTIONS
|
|
52
|
+
// ============================================================================
|
|
53
|
+
|
|
54
|
+
export interface FrequencyOption {
|
|
55
|
+
id: ReminderFrequency;
|
|
56
|
+
labelKey: string;
|
|
57
|
+
iconName: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const FREQUENCY_OPTIONS: FrequencyOption[] = [
|
|
61
|
+
{
|
|
62
|
+
id: 'once',
|
|
63
|
+
labelKey: 'notifications.frequency.once',
|
|
64
|
+
iconName: 'calendar',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'daily',
|
|
68
|
+
labelKey: 'notifications.frequency.daily',
|
|
69
|
+
iconName: 'repeat',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: 'weekly',
|
|
73
|
+
labelKey: 'notifications.frequency.weekly',
|
|
74
|
+
iconName: 'calendar-days',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: 'monthly',
|
|
78
|
+
labelKey: 'notifications.frequency.monthly',
|
|
79
|
+
iconName: 'calendar-range',
|
|
80
|
+
},
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
// ============================================================================
|
|
84
|
+
// WEEKDAY OPTIONS
|
|
85
|
+
// ============================================================================
|
|
86
|
+
|
|
87
|
+
export interface WeekdayOption {
|
|
88
|
+
id: number;
|
|
89
|
+
labelKey: string;
|
|
90
|
+
shortLabelKey: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const WEEKDAY_OPTIONS: WeekdayOption[] = [
|
|
94
|
+
{ id: 1, labelKey: 'notifications.weekdays.sunday', shortLabelKey: 'notifications.weekdays.sun' },
|
|
95
|
+
{ id: 2, labelKey: 'notifications.weekdays.monday', shortLabelKey: 'notifications.weekdays.mon' },
|
|
96
|
+
{ id: 3, labelKey: 'notifications.weekdays.tuesday', shortLabelKey: 'notifications.weekdays.tue' },
|
|
97
|
+
{ id: 4, labelKey: 'notifications.weekdays.wednesday', shortLabelKey: 'notifications.weekdays.wed' },
|
|
98
|
+
{ id: 5, labelKey: 'notifications.weekdays.thursday', shortLabelKey: 'notifications.weekdays.thu' },
|
|
99
|
+
{ id: 6, labelKey: 'notifications.weekdays.friday', shortLabelKey: 'notifications.weekdays.fri' },
|
|
100
|
+
{ id: 7, labelKey: 'notifications.weekdays.saturday', shortLabelKey: 'notifications.weekdays.sat' },
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
// ============================================================================
|
|
104
|
+
// HELPER FUNCTIONS
|
|
105
|
+
// ============================================================================
|
|
106
|
+
|
|
107
|
+
export const getTimePresetById = (id: string): TimePreset | undefined => {
|
|
108
|
+
return DEFAULT_TIME_PRESETS.find(preset => preset.id === id);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const formatTime = (hour: number, minute: number): string => {
|
|
112
|
+
const h = hour.toString().padStart(2, '0');
|
|
113
|
+
const m = minute.toString().padStart(2, '0');
|
|
114
|
+
return `${h}:${m}`;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export const parseTime = (timeString: string): { hour: number; minute: number } => {
|
|
118
|
+
const [hour, minute] = timeString.split(':').map(Number);
|
|
119
|
+
return { hour: hour || 0, minute: minute || 0 };
|
|
120
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useQuietHoursActions Hook
|
|
3
|
+
* Manages quiet hours configuration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useCallback } from 'react';
|
|
7
|
+
import { useRemindersStore, useQuietHours } from '../storage/RemindersStore';
|
|
8
|
+
import type { QuietHoursConfig } from '../services/types';
|
|
9
|
+
|
|
10
|
+
export const useQuietHoursActions = () => {
|
|
11
|
+
const quietHours = useQuietHours();
|
|
12
|
+
const { updateQuietHours } = useRemindersStore();
|
|
13
|
+
|
|
14
|
+
const setQuietHoursEnabled = useCallback(async (enabled: boolean): Promise<void> => {
|
|
15
|
+
await updateQuietHours({ ...quietHours, enabled });
|
|
16
|
+
}, [quietHours, updateQuietHours]);
|
|
17
|
+
|
|
18
|
+
const setStartTime = useCallback(async (hour: number, minute: number): Promise<void> => {
|
|
19
|
+
await updateQuietHours({ ...quietHours, startHour: hour, startMinute: minute });
|
|
20
|
+
}, [quietHours, updateQuietHours]);
|
|
21
|
+
|
|
22
|
+
const setEndTime = useCallback(async (hour: number, minute: number): Promise<void> => {
|
|
23
|
+
await updateQuietHours({ ...quietHours, endHour: hour, endMinute: minute });
|
|
24
|
+
}, [quietHours, updateQuietHours]);
|
|
25
|
+
|
|
26
|
+
const setQuietHours = useCallback(async (config: QuietHoursConfig): Promise<void> => {
|
|
27
|
+
await updateQuietHours(config);
|
|
28
|
+
}, [updateQuietHours]);
|
|
29
|
+
|
|
30
|
+
const isInQuietHours = useCallback((): boolean => {
|
|
31
|
+
if (!quietHours.enabled) return false;
|
|
32
|
+
|
|
33
|
+
const now = new Date();
|
|
34
|
+
const currentMinutes = now.getHours() * 60 + now.getMinutes();
|
|
35
|
+
const startMinutes = quietHours.startHour * 60 + quietHours.startMinute;
|
|
36
|
+
const endMinutes = quietHours.endHour * 60 + quietHours.endMinute;
|
|
37
|
+
|
|
38
|
+
if (startMinutes <= endMinutes) {
|
|
39
|
+
return currentMinutes >= startMinutes && currentMinutes < endMinutes;
|
|
40
|
+
}
|
|
41
|
+
return currentMinutes >= startMinutes || currentMinutes < endMinutes;
|
|
42
|
+
}, [quietHours]);
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
quietHours,
|
|
46
|
+
setQuietHoursEnabled,
|
|
47
|
+
setStartTime,
|
|
48
|
+
setEndTime,
|
|
49
|
+
setQuietHours,
|
|
50
|
+
isInQuietHours,
|
|
51
|
+
};
|
|
52
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useReminderActions Hook
|
|
3
|
+
* Handles reminder CRUD operations with notification scheduling
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useCallback } from 'react';
|
|
7
|
+
import { useRemindersStore } from '../storage/RemindersStore';
|
|
8
|
+
import { NotificationScheduler } from '../services/NotificationScheduler';
|
|
9
|
+
import type {
|
|
10
|
+
Reminder,
|
|
11
|
+
CreateReminderInput,
|
|
12
|
+
UpdateReminderInput,
|
|
13
|
+
NotificationTrigger,
|
|
14
|
+
} from '../services/types';
|
|
15
|
+
|
|
16
|
+
const scheduler = new NotificationScheduler();
|
|
17
|
+
|
|
18
|
+
const generateId = (): string => {
|
|
19
|
+
return `reminder_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const buildTrigger = (reminder: Reminder): NotificationTrigger => {
|
|
23
|
+
switch (reminder.frequency) {
|
|
24
|
+
case 'once':
|
|
25
|
+
const date = new Date();
|
|
26
|
+
date.setHours(reminder.hour, reminder.minute, 0, 0);
|
|
27
|
+
if (date <= new Date()) {
|
|
28
|
+
date.setDate(date.getDate() + 1);
|
|
29
|
+
}
|
|
30
|
+
return { type: 'date', date };
|
|
31
|
+
|
|
32
|
+
case 'daily':
|
|
33
|
+
return { type: 'daily', hour: reminder.hour, minute: reminder.minute };
|
|
34
|
+
|
|
35
|
+
case 'weekly':
|
|
36
|
+
return {
|
|
37
|
+
type: 'weekly',
|
|
38
|
+
weekday: reminder.weekday || 2,
|
|
39
|
+
hour: reminder.hour,
|
|
40
|
+
minute: reminder.minute,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
case 'monthly':
|
|
44
|
+
return {
|
|
45
|
+
type: 'monthly',
|
|
46
|
+
day: reminder.dayOfMonth || 1,
|
|
47
|
+
hour: reminder.hour,
|
|
48
|
+
minute: reminder.minute,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
default:
|
|
52
|
+
return { type: 'daily', hour: reminder.hour, minute: reminder.minute };
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const useReminderActions = () => {
|
|
57
|
+
const { addReminder, updateReminder, deleteReminder, toggleReminder } = useRemindersStore();
|
|
58
|
+
|
|
59
|
+
const createReminder = useCallback(async (input: CreateReminderInput): Promise<Reminder> => {
|
|
60
|
+
const now = new Date().toISOString();
|
|
61
|
+
const reminder: Reminder = {
|
|
62
|
+
id: generateId(),
|
|
63
|
+
...input,
|
|
64
|
+
enabled: true,
|
|
65
|
+
createdAt: now,
|
|
66
|
+
updatedAt: now,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const trigger = buildTrigger(reminder);
|
|
70
|
+
const notificationId = await scheduler.scheduleNotification({
|
|
71
|
+
title: reminder.title,
|
|
72
|
+
body: reminder.body,
|
|
73
|
+
trigger,
|
|
74
|
+
data: { reminderId: reminder.id },
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
reminder.notificationId = notificationId;
|
|
78
|
+
await addReminder(reminder);
|
|
79
|
+
|
|
80
|
+
return reminder;
|
|
81
|
+
}, [addReminder]);
|
|
82
|
+
|
|
83
|
+
const editReminder = useCallback(async (id: string, input: UpdateReminderInput): Promise<void> => {
|
|
84
|
+
const { reminders } = useRemindersStore.getState();
|
|
85
|
+
const existing = reminders.find(r => r.id === id);
|
|
86
|
+
if (!existing) return;
|
|
87
|
+
|
|
88
|
+
if (existing.notificationId) {
|
|
89
|
+
await scheduler.cancelNotification(existing.notificationId);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const updated: Reminder = { ...existing, ...input, updatedAt: new Date().toISOString() };
|
|
93
|
+
|
|
94
|
+
if (updated.enabled) {
|
|
95
|
+
const trigger = buildTrigger(updated);
|
|
96
|
+
const notificationId = await scheduler.scheduleNotification({
|
|
97
|
+
title: updated.title,
|
|
98
|
+
body: updated.body,
|
|
99
|
+
trigger,
|
|
100
|
+
data: { reminderId: updated.id },
|
|
101
|
+
});
|
|
102
|
+
updated.notificationId = notificationId;
|
|
103
|
+
} else {
|
|
104
|
+
updated.notificationId = undefined;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
await updateReminder(id, updated);
|
|
108
|
+
}, [updateReminder]);
|
|
109
|
+
|
|
110
|
+
const removeReminder = useCallback(async (id: string): Promise<void> => {
|
|
111
|
+
const { reminders } = useRemindersStore.getState();
|
|
112
|
+
const reminder = reminders.find(r => r.id === id);
|
|
113
|
+
|
|
114
|
+
if (reminder?.notificationId) {
|
|
115
|
+
await scheduler.cancelNotification(reminder.notificationId);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
await deleteReminder(id);
|
|
119
|
+
}, [deleteReminder]);
|
|
120
|
+
|
|
121
|
+
const toggleReminderEnabled = useCallback(async (id: string): Promise<void> => {
|
|
122
|
+
const { reminders } = useRemindersStore.getState();
|
|
123
|
+
const reminder = reminders.find(r => r.id === id);
|
|
124
|
+
if (!reminder) return;
|
|
125
|
+
|
|
126
|
+
if (reminder.enabled && reminder.notificationId) {
|
|
127
|
+
await scheduler.cancelNotification(reminder.notificationId);
|
|
128
|
+
await updateReminder(id, { enabled: false, notificationId: undefined });
|
|
129
|
+
} else if (!reminder.enabled) {
|
|
130
|
+
const trigger = buildTrigger(reminder);
|
|
131
|
+
const notificationId = await scheduler.scheduleNotification({
|
|
132
|
+
title: reminder.title,
|
|
133
|
+
body: reminder.body,
|
|
134
|
+
trigger,
|
|
135
|
+
data: { reminderId: reminder.id },
|
|
136
|
+
});
|
|
137
|
+
await updateReminder(id, { enabled: true, notificationId });
|
|
138
|
+
}
|
|
139
|
+
}, [updateReminder]);
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
createReminder,
|
|
143
|
+
editReminder,
|
|
144
|
+
removeReminder,
|
|
145
|
+
toggleReminderEnabled,
|
|
146
|
+
};
|
|
147
|
+
};
|