chahinebrini 5434254f74 feat(auth,mail): pw-reset OTP-flow + custom mail templates + account-switch cleanup
- 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()
2026-05-19 10:49:23 +02:00

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 {}
},
}));