- Phase 3 PW-Reset: 3 screens (forgot-password → reset-otp → new-password),
verifyOtp({type:'recovery'}), new updatePassword() action
- Custom Brevo-Mail templates (backend/public/templates/) — 5 HTMLs with
go-template i18n (de/en/fr/ar incl. RTL for AR), OTP-only (no link),
ReBreak branding
- signUp metadata.data.locale aus i18n.language → templates resolven Sprache
- Account-Switch-Bug fix: signOut() resettet alle 10 user-spezifischen stores
+ invalidateMe()
72 lines
2.4 KiB
TypeScript
72 lines
2.4 KiB
TypeScript
import { create } from 'zustand';
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
import * as Notifications from 'expo-notifications';
|
|
|
|
const STORAGE_KEY = '@rebreak/notifications-prefs';
|
|
|
|
type NotificationPrefsState = {
|
|
pushEnabled: boolean;
|
|
streakReminderEnabled: boolean;
|
|
streakReminderTime: { hour: number; minute: number };
|
|
|
|
init: () => Promise<void>;
|
|
setPushEnabled: (value: boolean) => Promise<void>;
|
|
setStreakReminderEnabled: (value: boolean) => Promise<void>;
|
|
setStreakReminderTime: (hour: number, minute: number) => Promise<void>;
|
|
reset: () => Promise<void>;
|
|
};
|
|
|
|
async function persist(patch: Partial<Pick<NotificationPrefsState, 'pushEnabled' | 'streakReminderEnabled' | 'streakReminderTime'>>) {
|
|
const existing = await AsyncStorage.getItem(STORAGE_KEY);
|
|
const current = existing ? JSON.parse(existing) : {};
|
|
await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify({ ...current, ...patch }));
|
|
}
|
|
|
|
export const useNotificationPrefsStore = create<NotificationPrefsState>((set, get) => ({
|
|
pushEnabled: false,
|
|
streakReminderEnabled: false,
|
|
streakReminderTime: { hour: 9, minute: 0 },
|
|
|
|
init: async () => {
|
|
const stored = await AsyncStorage.getItem(STORAGE_KEY);
|
|
if (!stored) return;
|
|
const parsed = JSON.parse(stored);
|
|
set({
|
|
pushEnabled: parsed.pushEnabled ?? false,
|
|
streakReminderEnabled: parsed.streakReminderEnabled ?? false,
|
|
streakReminderTime: parsed.streakReminderTime ?? { hour: 9, minute: 0 },
|
|
});
|
|
},
|
|
|
|
// TODO: wire up expo-notifications requestPermissionsAsync + scheduleNotificationAsync
|
|
// once the streak reminder backend endpoint exists. Currently persists user intent only.
|
|
setPushEnabled: async (value) => {
|
|
if (value) {
|
|
const { status } = await Notifications.requestPermissionsAsync();
|
|
if (status !== 'granted') {
|
|
return;
|
|
}
|
|
}
|
|
set({ pushEnabled: value });
|
|
await persist({ pushEnabled: value });
|
|
},
|
|
|
|
setStreakReminderEnabled: async (value) => {
|
|
set({ streakReminderEnabled: value });
|
|
await persist({ streakReminderEnabled: value });
|
|
},
|
|
|
|
setStreakReminderTime: async (hour, minute) => {
|
|
const streakReminderTime = { hour, minute };
|
|
set({ streakReminderTime });
|
|
await persist({ streakReminderTime });
|
|
},
|
|
|
|
reset: async () => {
|
|
set({ pushEnabled: false, streakReminderEnabled: false, streakReminderTime: { hour: 9, minute: 0 } });
|
|
try {
|
|
await AsyncStorage.removeItem(STORAGE_KEY);
|
|
} catch {}
|
|
},
|
|
}));
|