@umituz/react-native-settings 4.21.11 → 4.21.13

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.
Files changed (47) hide show
  1. package/package.json +11 -2
  2. package/src/domains/gamification/components/GamificationScreenWrapper.tsx +58 -85
  3. package/src/domains/gamification/components/index.ts +1 -0
  4. package/src/domains/gamification/index.ts +4 -11
  5. package/src/domains/gamification/types/index.ts +18 -0
  6. package/src/domains/notifications/index.ts +139 -0
  7. package/src/domains/notifications/infrastructure/config/notificationsConfig.ts +98 -0
  8. package/src/domains/notifications/infrastructure/hooks/useNotificationSettings.ts +37 -0
  9. package/src/domains/notifications/infrastructure/services/NotificationBadgeManager.ts +28 -0
  10. package/src/domains/notifications/infrastructure/services/NotificationManager.ts +138 -0
  11. package/src/domains/notifications/infrastructure/services/NotificationPermissions.ts +80 -0
  12. package/src/domains/notifications/infrastructure/services/NotificationScheduler.ts +77 -0
  13. package/src/domains/notifications/infrastructure/services/NotificationService.ts +50 -0
  14. package/src/domains/notifications/infrastructure/services/types.ts +176 -0
  15. package/src/domains/notifications/infrastructure/storage/NotificationsStore.ts +45 -0
  16. package/src/domains/notifications/infrastructure/utils/dev.ts +25 -0
  17. package/src/domains/notifications/infrastructure/utils/idGenerator.ts +14 -0
  18. package/src/domains/notifications/infrastructure/utils/triggerBuilder.ts +45 -0
  19. package/src/domains/notifications/presentation/components/NotificationsSection.tsx +84 -0
  20. package/src/domains/notifications/presentation/components/RemindersNavRow.styles.ts +38 -0
  21. package/src/domains/notifications/presentation/components/RemindersNavRow.tsx +51 -0
  22. package/src/domains/notifications/presentation/components/SettingRow.tsx +86 -0
  23. package/src/domains/notifications/presentation/hooks/useNotificationSettingsUI.ts +52 -0
  24. package/src/domains/notifications/presentation/hooks/useTimePicker.ts +71 -0
  25. package/src/domains/notifications/presentation/screens/NotificationSettingsScreen.styles.ts +30 -0
  26. package/src/domains/notifications/presentation/screens/NotificationSettingsScreen.tsx +131 -0
  27. package/src/domains/notifications/presentation/screens/NotificationsScreen.tsx +107 -0
  28. package/src/domains/notifications/quietHours/infrastructure/hooks/useQuietHoursActions.ts +52 -0
  29. package/src/domains/notifications/quietHours/presentation/components/QuietHoursCard.tsx +112 -0
  30. package/src/domains/notifications/reminders/infrastructure/config/reminderPresets.ts +120 -0
  31. package/src/domains/notifications/reminders/infrastructure/hooks/useReminderActions.ts +106 -0
  32. package/src/domains/notifications/reminders/infrastructure/storage/RemindersStore.ts +148 -0
  33. package/src/domains/notifications/reminders/presentation/components/FormButton.tsx +66 -0
  34. package/src/domains/notifications/reminders/presentation/components/FrequencySelector.tsx +72 -0
  35. package/src/domains/notifications/reminders/presentation/components/ReminderForm.tsx +169 -0
  36. package/src/domains/notifications/reminders/presentation/components/ReminderItem.tsx +130 -0
  37. package/src/domains/notifications/reminders/presentation/components/TimePresetSelector.tsx +100 -0
  38. package/src/domains/notifications/reminders/presentation/components/WeekdaySelector.tsx +61 -0
  39. package/src/domains/notifications/reminders/presentation/screens/ReminderListScreen.tsx +131 -0
  40. package/src/index.ts +3 -0
  41. package/src/presentation/navigation/SettingsStackNavigator.tsx +21 -11
  42. package/src/presentation/screens/components/sections/FeatureSettingsSection.tsx +1 -1
  43. package/src/domains/gamification/README.md +0 -343
  44. package/src/domains/gamification/components/GamificationSettingsItem.tsx +0 -33
  45. package/src/domains/gamification/examples/gamification.config.example.ts +0 -70
  46. package/src/domains/gamification/examples/localization.example.json +0 -71
  47. package/src/domains/gamification/types/settings.ts +0 -28
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-settings",
3
- "version": "4.21.11",
3
+ "version": "4.21.13",
4
4
  "description": "Complete settings hub for React Native apps - consolidated package with settings, about, legal, appearance, feedback, FAQs, rating, and gamification",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -38,7 +38,6 @@
38
38
  "@umituz/react-native-auth": "latest",
39
39
  "@umituz/react-native-design-system": "latest",
40
40
  "@umituz/react-native-localization": "latest",
41
- "@umituz/react-native-notifications": "latest",
42
41
  "@umituz/react-native-storage": "latest",
43
42
  "@umituz/react-native-tanstack": "latest",
44
43
  "firebase": "^12.7.0"
@@ -48,6 +47,11 @@
48
47
  "@react-navigation/native": ">=6.0.0",
49
48
  "@react-navigation/stack": ">=6.0.0",
50
49
  "@tanstack/react-query": ">=5.0.0",
50
+ "expo-notifications": ">=0.28.0",
51
+ "expo-device": ">=6.0.0",
52
+ "expo-haptics": ">=15.0.0",
53
+ "@react-native-community/datetimepicker": ">=8.0.0",
54
+ "@umituz/react-native-haptics": "latest",
51
55
  "react": ">=19.0.0",
52
56
  "react-native": ">=0.81.0",
53
57
  "react-native-safe-area-context": ">=4.0.0"
@@ -58,6 +62,11 @@
58
62
  "@react-navigation/stack": "^7.6.13",
59
63
  "@tanstack/react-query": "^5.0.0",
60
64
  "@types/react": "~19.1.10",
65
+ "expo-notifications": "~0.27.6",
66
+ "expo-device": "~7.0.0",
67
+ "expo-haptics": "~14.0.0",
68
+ "@react-native-community/datetimepicker": "^8.2.0",
69
+ "@umituz/react-native-haptics": "latest",
61
70
  "@typescript-eslint/eslint-plugin": "^7.18.0",
62
71
  "@typescript-eslint/parser": "^7.18.0",
63
72
  "eslint": "^8.57.0",
@@ -1,91 +1,64 @@
1
- /**
2
- * Gamification Screen Component
3
- * Wrapper for gamification screen
4
- */
1
+ import React from 'react';
2
+ import { useGamification } from '../hooks/useGamification';
3
+ import { GamificationScreen } from './GamificationScreen';
4
+ import type { GamificationConfig } from '../types';
5
+ import type { AchievementItemProps } from '../components';
5
6
 
6
- import React, { useMemo } from "react";
7
- import { GamificationScreen as BaseGamificationScreen } from "./GamificationScreen";
8
- import { useGamification } from "../hooks/useGamification";
9
- import { useLocalization } from "@umituz/react-native-localization";
10
- import type { GamificationSettingsConfig } from "../types/settings";
11
-
12
- export interface GamificationScreenWrapperProps {
13
- config: GamificationSettingsConfig;
7
+ interface GamificationScreenWrapperProps {
8
+ config: GamificationConfig;
14
9
  }
15
10
 
16
- /**
17
- * Gamification Screen for Settings
18
- * Displays achievements, levels, streaks, and stats
19
- */
20
- export const GamificationScreenWrapper: React.FC<GamificationScreenWrapperProps> = ({
21
- config,
22
- }) => {
23
- const { t } = useLocalization();
24
- const gamification = useGamification(config.config);
25
-
26
- const screenProps = useMemo(() => {
27
- // Map achievements to screen format
28
- const achievements = gamification.achievements.map((achievement) => ({
29
- id: achievement.id,
30
- title: t(`gamification.achievements.${achievement.id}.title`),
31
- description: t(`gamification.achievements.${achievement.id}.description`),
32
- icon: "trophy",
33
- isUnlocked: achievement.isUnlocked,
34
- progress: achievement.progress,
35
- threshold: achievement.threshold,
36
- }));
37
-
38
- // Map stats
39
- const stats = [
40
- {
41
- icon: "star",
42
- value: gamification.points,
43
- label: t("gamification.stats.totalPoints"),
44
- },
45
- {
46
- icon: "check-circle",
47
- value: gamification.totalTasksCompleted,
48
- label: t("gamification.stats.tasksCompleted"),
49
- },
50
- {
51
- icon: "award",
52
- value: gamification.achievements.filter((a) => a.isUnlocked).length,
53
- label: t("gamification.stats.achievementsUnlocked"),
54
- },
55
- ];
56
-
57
- // Level props
58
- const levelProps = {
59
- level: gamification.level.currentLevel,
60
- points: gamification.level.currentPoints,
61
- levelTitle: t("gamification.level.title", {
62
- level: gamification.level.currentLevel,
63
- }),
64
- pointsToNext: gamification.level.pointsToNext,
65
- progress: gamification.level.progress,
66
- showPoints: true,
67
- };
68
-
69
- // Streak props
70
- const streakProps = gamification.streak.current > 0
71
- ? {
72
- current: gamification.streak.current,
73
- longest: gamification.streak.longest,
74
- currentLabel: t("gamification.streak.current"),
75
- bestLabel: t("gamification.streak.best"),
76
- daysLabel: t("gamification.streak.days"),
77
- }
78
- : undefined;
11
+ export const GamificationScreenWrapper: React.FC<GamificationScreenWrapperProps> = ({ config }) => {
12
+ const {
13
+ points,
14
+ totalTasksCompleted,
15
+ level,
16
+ streak,
17
+ achievements,
18
+ } = useGamification(config);
79
19
 
80
- return {
81
- ...config.screenProps,
82
- levelProps,
83
- stats,
84
- achievements,
85
- streakProps,
86
- emptyAchievementsText: t("gamification.achievements.empty"),
87
- };
88
- }, [gamification, config.screenProps, t]);
20
+ // Transform store achievements to UI props
21
+ const achievementItems: any[] = achievements.map(a => ({
22
+ ...a,
23
+ title: a.title,
24
+ description: a.description,
25
+ icon: a.icon,
26
+ isUnlocked: a.isUnlocked,
27
+ progress: a.progress,
28
+ threshold: a.threshold,
29
+ id: a.id,
30
+ type: a.type
31
+ }));
89
32
 
90
- return <BaseGamificationScreen {...screenProps} />;
33
+ return (
34
+ <GamificationScreen
35
+ title={config.translations.title}
36
+ statsTitle={config.translations.statsTitle}
37
+ achievementsTitle={config.translations.achievementsTitle}
38
+ streakTitle={config.translations.streakTitle}
39
+ levelProps={{
40
+ level: level.currentLevel,
41
+ points: level.currentPoints,
42
+ pointsToNext: level.pointsToNext,
43
+ progress: level.progress,
44
+ levelTitle: config.translations.levelTitle,
45
+ showPoints: true,
46
+ }}
47
+ streakProps={{
48
+ current: streak.current,
49
+ longest: streak.longest,
50
+ // streakLabel: config.translations.streakTitle, // Omitted by GamificationScreen types apparently
51
+ bestLabel: config.translations.bestStreak,
52
+ }}
53
+ stats={[
54
+ {
55
+ label: config.translations.statsTitle,
56
+ value: points, // Pass number directly
57
+ icon: "star",
58
+ },
59
+ ]}
60
+ achievements={achievementItems}
61
+ emptyAchievementsText={config.translations.emptyAchievements}
62
+ />
63
+ );
91
64
  };
@@ -11,3 +11,4 @@ export { StreakDisplay, type StreakDisplayProps } from "./StreakDisplay";
11
11
  export { StatsCard, type StatsCardProps } from "./StatsCard";
12
12
  export { AchievementItem, type AchievementItemProps } from "./AchievementItem";
13
13
  export { GamificationScreen, type GamificationScreenProps } from "./GamificationScreen/index";
14
+ export { GamificationScreenWrapper } from "./GamificationScreenWrapper";
@@ -1,5 +1,6 @@
1
1
  /**
2
- * @umituz/react-native-gamification
2
+ * Gamification Domain
3
+ * Part of @umituz/react-native-settings
3
4
  *
4
5
  * Generic gamification system for React Native apps
5
6
  * All text via props - NO hardcoded strings
@@ -14,17 +15,12 @@ export type {
14
15
  LevelState,
15
16
  StreakState,
16
17
  GamificationConfig,
18
+ GamificationSettingsConfig,
17
19
  GamificationState,
18
20
  GamificationActions,
19
21
  GamificationStore,
20
22
  } from "./types";
21
23
 
22
- // Settings Integration Types
23
- export type {
24
- GamificationSettingsConfig,
25
- GamificationMenuConfig,
26
- } from "./types/settings";
27
-
28
24
  // Store
29
25
  export { useGamificationStore } from "./store/gamificationStore";
30
26
 
@@ -58,8 +54,5 @@ export {
58
54
  type AchievementItemProps,
59
55
  GamificationScreen,
60
56
  type GamificationScreenProps,
57
+ GamificationScreenWrapper,
61
58
  } from "./components";
62
-
63
- // Settings Integration Components
64
- export { GamificationScreenWrapper } from "./components/GamificationScreenWrapper";
65
- export { GamificationSettingsItem } from "./components/GamificationSettingsItem";
@@ -8,6 +8,9 @@ export interface AchievementDefinition {
8
8
  id: string;
9
9
  threshold: number;
10
10
  type: "count" | "streak" | "milestone";
11
+ title: string;
12
+ description: string;
13
+ icon: string;
11
14
  }
12
15
 
13
16
  // Achievement State (internal)
@@ -39,6 +42,17 @@ export interface StreakState {
39
42
  lastActivityDate: string | null;
40
43
  }
41
44
 
45
+ // Gamification Translations
46
+ export interface GamificationTranslations {
47
+ title: string;
48
+ statsTitle: string;
49
+ achievementsTitle: string;
50
+ streakTitle: string;
51
+ bestStreak: string;
52
+ levelTitle: string;
53
+ emptyAchievements: string;
54
+ }
55
+
42
56
  // Gamification Config (provided by app via props)
43
57
  export interface GamificationConfig {
44
58
  storageKey: string;
@@ -46,8 +60,12 @@ export interface GamificationConfig {
46
60
  levels: LevelDefinition[];
47
61
  pointsPerAction?: number;
48
62
  streakBonusMultiplier?: number;
63
+ enabled?: boolean;
64
+ translations: GamificationTranslations;
49
65
  }
50
66
 
67
+ export type GamificationSettingsConfig = GamificationConfig;
68
+
51
69
  // Store State
52
70
  export interface GamificationState {
53
71
  points: number;
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Notifications Package - Public API
3
+ * Offline-first local notifications using expo-notifications
4
+ */
5
+
6
+ // ============================================================================
7
+ // TYPES
8
+ // ============================================================================
9
+
10
+ export type {
11
+ NotificationTrigger,
12
+ ScheduleNotificationOptions,
13
+ ScheduledNotification,
14
+ TimePreset,
15
+ ReminderFrequency,
16
+ Reminder,
17
+ CreateReminderInput,
18
+ UpdateReminderInput,
19
+ QuietHoursConfig,
20
+ NotificationPreferences,
21
+ ReminderTranslations,
22
+ QuietHoursTranslations,
23
+ NotificationSettingsTranslations,
24
+ } from './infrastructure/services/types';
25
+
26
+ // ============================================================================
27
+ // CONFIGURATION
28
+ // ============================================================================
29
+
30
+ export { notificationsConfig } from './infrastructure/config/notificationsConfig';
31
+ export type {
32
+ NotificationSetting,
33
+ NotificationSection,
34
+ NotificationsConfig,
35
+ } from './infrastructure/config/notificationsConfig';
36
+
37
+ export {
38
+ DEFAULT_TIME_PRESETS,
39
+ FREQUENCY_OPTIONS,
40
+ WEEKDAY_OPTIONS,
41
+ getTimePresetById,
42
+ formatTime,
43
+ parseTime,
44
+ } from './reminders/infrastructure/config/reminderPresets';
45
+ export type { FrequencyOption, WeekdayOption } from './reminders/infrastructure/config/reminderPresets';
46
+
47
+ // ============================================================================
48
+ // SERVICES
49
+ // ============================================================================
50
+
51
+ export { NotificationService, notificationService } from './infrastructure/services/NotificationService';
52
+ export { NotificationManager } from './infrastructure/services/NotificationManager';
53
+
54
+ // ============================================================================
55
+ // STORES
56
+ // ============================================================================
57
+
58
+ export { useNotificationsStore, useNotifications } from './infrastructure/storage/NotificationsStore';
59
+ export {
60
+ useRemindersStore,
61
+ usePreferencesStore,
62
+ useReminders,
63
+ useEnabledReminders,
64
+ useReminderById,
65
+ useNotificationPreferences,
66
+ useQuietHours,
67
+ useRemindersLoading,
68
+ useRemindersInitialized,
69
+ } from './reminders/infrastructure/storage/RemindersStore';
70
+
71
+ // ============================================================================
72
+ // HOOKS
73
+ // ============================================================================
74
+
75
+ export { useNotificationSettings } from './infrastructure/hooks/useNotificationSettings';
76
+ export { useReminderActions } from './reminders/infrastructure/hooks/useReminderActions';
77
+ export { useQuietHoursActions } from './quietHours/infrastructure/hooks/useQuietHoursActions';
78
+ export { useNotificationSettingsUI } from './presentation/hooks/useNotificationSettingsUI';
79
+
80
+ // ============================================================================
81
+ // SCREENS
82
+ // ============================================================================
83
+
84
+ export { NotificationsScreen } from './presentation/screens/NotificationsScreen';
85
+ export type { NotificationsScreenProps } from './presentation/screens/NotificationsScreen';
86
+
87
+ export { NotificationSettingsScreen } from './presentation/screens/NotificationSettingsScreen';
88
+ export type { NotificationSettingsScreenProps } from './presentation/screens/NotificationSettingsScreen';
89
+
90
+ export { ReminderListScreen } from './reminders/presentation/screens/ReminderListScreen';
91
+ export type { ReminderListScreenProps } from './reminders/presentation/screens/ReminderListScreen';
92
+
93
+ // ============================================================================
94
+ // COMPONENTS
95
+ // ============================================================================
96
+
97
+ export { NotificationsSection } from './presentation/components/NotificationsSection';
98
+ export type { NotificationsSectionProps, NotificationsSectionConfig } from './presentation/components/NotificationsSection';
99
+
100
+ export { TimePresetSelector } from './reminders/presentation/components/TimePresetSelector';
101
+ export type { TimePresetSelectorProps } from './reminders/presentation/components/TimePresetSelector';
102
+
103
+ export { FrequencySelector } from './reminders/presentation/components/FrequencySelector';
104
+ export type { FrequencySelectorProps } from './reminders/presentation/components/FrequencySelector';
105
+
106
+ export { WeekdaySelector } from './reminders/presentation/components/WeekdaySelector';
107
+ export type { WeekdaySelectorProps } from './reminders/presentation/components/WeekdaySelector';
108
+
109
+ export { ReminderItem } from './reminders/presentation/components/ReminderItem';
110
+ export type { ReminderItemProps, ReminderItemTranslations } from './reminders/presentation/components/ReminderItem';
111
+
112
+ export { ReminderForm } from './reminders/presentation/components/ReminderForm';
113
+ export type { ReminderFormProps, ReminderFormTranslations } from './reminders/presentation/components/ReminderForm';
114
+
115
+ export { FormButton } from './reminders/presentation/components/FormButton';
116
+ export type { FormButtonProps } from './reminders/presentation/components/FormButton';
117
+
118
+ export { QuietHoursCard } from './quietHours/presentation/components/QuietHoursCard';
119
+ export type { QuietHoursCardProps } from './quietHours/presentation/components/QuietHoursCard';
120
+
121
+ export { RemindersNavRow } from './presentation/components/RemindersNavRow';
122
+ export type { RemindersNavRowProps } from './presentation/components/RemindersNavRow';
123
+
124
+ export { SettingRow } from './presentation/components/SettingRow';
125
+ export type { SettingRowProps } from './presentation/components/SettingRow';
126
+
127
+ // ============================================================================
128
+ // UTILS
129
+ // ============================================================================
130
+
131
+ export { generateId, generateReminderId } from './infrastructure/utils/idGenerator';
132
+ export { buildTrigger } from './infrastructure/utils/triggerBuilder';
133
+
134
+ // ============================================================================
135
+ // HOOKS - UTILS
136
+ // ============================================================================
137
+
138
+ export { useTimePicker } from './presentation/hooks/useTimePicker';
139
+ export type { PickerMode, UseTimePickerParams, TimePickerHandlers } from './presentation/hooks/useTimePicker';
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Notifications Configuration
3
+ * Defines notification settings structure
4
+ */
5
+
6
+ export interface NotificationSetting {
7
+ id: string;
8
+ titleKey: string;
9
+ descKey: string;
10
+ icon: string;
11
+ }
12
+
13
+ export interface NotificationSection {
14
+ id: string;
15
+ titleKey: string;
16
+ settings: NotificationSetting[];
17
+ }
18
+
19
+ export interface NotificationsConfig {
20
+ sections: NotificationSection[];
21
+ }
22
+
23
+ export const notificationsConfig: NotificationsConfig = {
24
+ sections: [
25
+ {
26
+ id: 'channels',
27
+ titleKey: 'notifications.channels',
28
+ settings: [
29
+ {
30
+ id: 'pushNotifications',
31
+ titleKey: 'notifications.push',
32
+ descKey: 'notifications.pushDesc',
33
+ icon: 'notifications',
34
+ },
35
+ {
36
+ id: 'emailNotifications',
37
+ titleKey: 'notifications.email',
38
+ descKey: 'notifications.emailDesc',
39
+ icon: 'email',
40
+ },
41
+ {
42
+ id: 'smsNotifications',
43
+ titleKey: 'notifications.sms',
44
+ descKey: 'notifications.smsDesc',
45
+ icon: 'message',
46
+ },
47
+ ],
48
+ },
49
+ {
50
+ id: 'content',
51
+ titleKey: 'notifications.content',
52
+ settings: [
53
+ {
54
+ id: 'appUpdates',
55
+ titleKey: 'notifications.updates',
56
+ descKey: 'notifications.updatesDesc',
57
+ icon: 'update',
58
+ },
59
+ {
60
+ id: 'features',
61
+ titleKey: 'notifications.features',
62
+ descKey: 'notifications.featuresDesc',
63
+ icon: 'new-releases',
64
+ },
65
+ {
66
+ id: 'tips',
67
+ titleKey: 'notifications.tips',
68
+ descKey: 'notifications.tipsDesc',
69
+ icon: 'tips-and-updates',
70
+ },
71
+ ],
72
+ },
73
+ {
74
+ id: 'activity',
75
+ titleKey: 'notifications.activity',
76
+ settings: [
77
+ {
78
+ id: 'reminders',
79
+ titleKey: 'notifications.reminders',
80
+ descKey: 'notifications.remindersDesc',
81
+ icon: 'alarm',
82
+ },
83
+ {
84
+ id: 'achievements',
85
+ titleKey: 'notifications.achievements',
86
+ descKey: 'notifications.achievementsDesc',
87
+ icon: 'emoji-events',
88
+ },
89
+ {
90
+ id: 'social',
91
+ titleKey: 'notifications.social',
92
+ descKey: 'notifications.socialDesc',
93
+ icon: 'people',
94
+ },
95
+ ],
96
+ },
97
+ ],
98
+ };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Simple notification settings hook
3
+ */
4
+
5
+ import { createStore } from '@umituz/react-native-storage';
6
+
7
+ interface NotificationSettingsState {
8
+ notificationsEnabled: boolean;
9
+ isLoading: boolean;
10
+ }
11
+
12
+ interface NotificationSettingsActions {
13
+ setNotificationsEnabled: (value: boolean) => void;
14
+ }
15
+
16
+ const useNotificationSettingsStore = createStore<NotificationSettingsState, NotificationSettingsActions>({
17
+ name: 'notification-settings-store',
18
+ initialState: {
19
+ notificationsEnabled: true,
20
+ isLoading: true,
21
+ },
22
+ persist: true,
23
+ actions: (set) => ({
24
+ setNotificationsEnabled: (value: boolean) => set({ notificationsEnabled: value }),
25
+ }),
26
+ });
27
+
28
+ export const useNotificationSettings = () => {
29
+ const store = useNotificationSettingsStore();
30
+ const { notificationsEnabled, isLoading, setNotificationsEnabled } = store;
31
+
32
+ return {
33
+ notificationsEnabled,
34
+ setNotificationsEnabled,
35
+ isLoading,
36
+ };
37
+ };
@@ -0,0 +1,28 @@
1
+ import * as Notifications from 'expo-notifications';
2
+ import { Platform } from 'react-native';
3
+ import { devError } from '../utils/dev';
4
+
5
+ export class NotificationBadgeManager {
6
+ async getBadgeCount(): Promise<number> {
7
+ try {
8
+ if (Platform.OS === 'ios') {
9
+ return await Notifications.getBadgeCountAsync();
10
+ }
11
+ return 0;
12
+ } catch (error) {
13
+ devError('[NotificationBadgeManager] Get badge count failed:', error);
14
+ return 0;
15
+ }
16
+ }
17
+
18
+ async setBadgeCount(count: number): Promise<void> {
19
+ try {
20
+ if (Platform.OS === 'ios') {
21
+ await Notifications.setBadgeCountAsync(count);
22
+ }
23
+ } catch (error) {
24
+ devError('[NotificationBadgeManager] Set badge count failed:', error);
25
+ throw error;
26
+ }
27
+ }
28
+ }