From 6f8d70186c9b9b9926f2e8788bdc42e16d190f86 Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Tue, 10 Mar 2026 09:52:54 -0700 Subject: [PATCH] fix(mobile): honor auth failures and tighten selectors --- mobile/src/app/_layout.tsx | 12 ++++++------ mobile/src/app/auth.tsx | 25 +++++++++++++++++++++---- mobile/src/store/auth-store.ts | 10 +++++++--- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/mobile/src/app/_layout.tsx b/mobile/src/app/_layout.tsx index 005d48b..fb63234 100644 --- a/mobile/src/app/_layout.tsx +++ b/mobile/src/app/_layout.tsx @@ -1,14 +1,14 @@ import { useEffect } from 'react'; import { Stack } from 'expo-router'; import { StatusBar } from 'expo-status-bar'; -import { useAuthStore } from '../store/auth-store'; -import { useNotesStore } from '../store/notes-store'; -import { useWorkspaceStore } from '../store/workspace-store'; +import { useAuthStore, type AuthState } from '../store/auth-store'; +import { useNotesStore, type NotesState } from '../store/notes-store'; +import { useWorkspaceStore, type WorkspaceState } from '../store/workspace-store'; export default function RootLayout() { - const bootstrapAuth = useAuthStore((state) => state.bootstrap); - const hydrateNotes = useNotesStore((state) => state.hydrate); - const hydrateWorkspaces = useWorkspaceStore((state) => state.hydrate); + const bootstrapAuth = useAuthStore((state: AuthState) => state.bootstrap); + const hydrateNotes = useNotesStore((state: NotesState) => state.hydrate); + const hydrateWorkspaces = useWorkspaceStore((state: WorkspaceState) => state.hydrate); useEffect(() => { void bootstrapAuth(); diff --git a/mobile/src/app/auth.tsx b/mobile/src/app/auth.tsx index f05b2a4..10e8fb4 100644 --- a/mobile/src/app/auth.tsx +++ b/mobile/src/app/auth.tsx @@ -7,6 +7,7 @@ import { colors } from '../theme'; export default function AuthScreen() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); + const [errorMessage, setErrorMessage] = useState(null); const signIn = useAuthStore((state: AuthState) => state.signIn); const isLoading = useAuthStore((state: AuthState) => state.isLoading); @@ -17,24 +18,36 @@ export default function AuthScreen() { { + setErrorMessage(null); + setEmail(value); + }} placeholder="Email" placeholderTextColor={colors.textTertiary} style={styles.input} value={email} /> { + setErrorMessage(null); + setPassword(value); + }} placeholder="Password" placeholderTextColor={colors.textTertiary} secureTextEntry style={styles.input} value={password} /> + {errorMessage ? {errorMessage} : null} { - await signIn(email, password); - router.replace('/(tabs)'); + const didSignIn = await signIn(email, password); + if (didSignIn) { + router.replace('/(tabs)'); + return; + } + + setErrorMessage('Sign-in failed. Check your credentials or connection and try again.'); }} style={styles.button} > @@ -82,4 +95,8 @@ const styles = StyleSheet.create({ color: colors.textPrimary, fontWeight: '700', }, + errorText: { + color: colors.danger, + fontSize: 14, + }, }); diff --git a/mobile/src/store/auth-store.ts b/mobile/src/store/auth-store.ts index 1aa6410..2eba72f 100644 --- a/mobile/src/store/auth-store.ts +++ b/mobile/src/store/auth-store.ts @@ -6,7 +6,7 @@ export type AuthState = { isLoading: boolean; email: string | null; bootstrap: () => Promise; - signIn: (email: string, password: string) => Promise; + signIn: (email: string, password: string) => Promise; signOut: () => void; }; @@ -27,7 +27,8 @@ export const useAuthStore = create((set) => ({ const me = await client.getMe(); set({ isAuthenticated: true, email: me.email, isLoading: false }); } catch { - set({ isAuthenticated: true, email: 'demo@bytelyst.local', isLoading: false }); + client.clearTokens(); + set({ isAuthenticated: false, email: null, isLoading: false }); } }, async signIn(email: string, password: string) { @@ -36,8 +37,11 @@ export const useAuthStore = create((set) => ({ try { await getAuthClient().login(email, password); set({ isAuthenticated: true, email, isLoading: false }); + return true; } catch { - set({ isAuthenticated: true, email, isLoading: false }); + getAuthClient().clearTokens(); + set({ isAuthenticated: false, email: null, isLoading: false }); + return false; } }, signOut() {