mobileapp / src /store /useAppStore.ts
Antaram Dev Bot
feat: complete ANTARAM.ORG ride-sharing app frontend
5c876be
/**
* Global app preferences & UI state store.
*
* Manages cross-cutting concerns like the user's current role,
* online status, and theme preference. These are persisted
* separately from auth because they survive logouts.
*/
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import type { UserRole } from '../types/user';
// ─── State Shape ─────────────────────────────────────────────────────────────
interface AppState {
/** The role the user is currently acting as (rider or passenger) */
currentRole: UserRole;
/** Whether the user is visible to others as online */
isOnline: boolean;
/** Whether dark mode is active */
isDarkMode: boolean;
/** Whether push notifications are enabled */
notificationsEnabled: boolean;
}
// ─── Actions ─────────────────────────────────────────────────────────────────
interface AppActions {
/** Switch between rider and passenger mode */
setRole: (role: UserRole) => void;
/** Toggle online/offline visibility */
setOnline: (value: boolean) => void;
/** Toggle dark mode */
setDarkMode: (value: boolean) => void;
/** Toggle notifications */
setNotificationsEnabled: (value: boolean) => void;
}
// ─── Persisted Store ─────────────────────────────────────────────────────────
export const useAppStore = create<AppState & AppActions>()(
persist(
(set) => ({
// Initial / default state
currentRole: 'rider' as UserRole,
isOnline: true,
isDarkMode: false,
notificationsEnabled: true,
// Actions
setRole: (role) =>
set({ currentRole: role }),
setOnline: (value) =>
set({ isOnline: value }),
setDarkMode: (value) =>
set({ isDarkMode: value }),
setNotificationsEnabled: (value) =>
set({ notificationsEnabled: value }),
}),
{
name: 'antaram-app-storage',
storage: createJSONStorage(() => {
// AsyncStorage will be used in React Native by default when available
// This also falls back to localStorage in web / Expo web
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const { AsyncStorage } = require('@react-native-async-storage/async-storage');
return AsyncStorage;
} catch {
// Web fallback
return localStorage;
}
}),
// Only persist these specific keys
partialize: (state) => ({
currentRole: state.currentRole,
isOnline: state.isOnline,
isDarkMode: state.isDarkMode,
notificationsEnabled: state.notificationsEnabled,
}),
},
),
);
// ─── Selectors ───────────────────────────────────────────────────────────────
export const selectIsRider = (state: AppState) => state.currentRole === 'rider';
export const selectIsPassenger = (state: AppState) => state.currentRole === 'passenger';