From f688307b3910de9e6f9dfd13e9251c0b5b664593 Mon Sep 17 00:00:00 2001 From: Christopher Sanden Date: Tue, 17 Mar 2026 16:06:47 +0100 Subject: [PATCH] updated navigation for login and signup --- FastNotes/app/login.tsx | 110 ++++++++++++---------- FastNotes/app/newNote.tsx | 2 +- FastNotes/app/signup.tsx | 126 +++++++++++++++----------- FastNotes/providers/auth-provider.tsx | 31 +++++++ FastNotes/src/styles/app-styles.ts | 42 ++++++++- 5 files changed, 205 insertions(+), 106 deletions(-) diff --git a/FastNotes/app/login.tsx b/FastNotes/app/login.tsx index b8c419d..833eb41 100644 --- a/FastNotes/app/login.tsx +++ b/FastNotes/app/login.tsx @@ -1,6 +1,6 @@ import { useState } from 'react' import { Link, Stack } from 'expo-router' -import { Pressable, Text, TextInput, View } from 'react-native' +import { Keyboard, KeyboardAvoidingView, Platform, Pressable, ScrollView, Text, TextInput, View } from 'react-native' import { supabase } from '@/libs/supabase' import { useAppTheme } from '@/src/theme/AppThemeProvider' import { loginScreenStyles as styles } from '@/src/styles/app-styles' @@ -36,55 +36,69 @@ export default function LoginScreen() { return ( <> - - Login - - E-mail - - - Password - - - {errorMessage ? ( - {errorMessage} - ) : null} - - [ - styles.loginButton, - pressed && !isSubmitting ? styles.loginButtonPressed : null, - isSubmitting ? styles.loginButtonDisabled : null, - ]} + + - - {isSubmitting ? 'Logging in...' : 'Log in'} - - + + + Login - - Create a new account - - + E-mail + + + Password + + + {errorMessage ? ( + {errorMessage} + ) : null} + + [ + styles.loginButton, + pressed && !isSubmitting ? styles.loginButtonPressed : null, + isSubmitting ? styles.loginButtonDisabled : null, + ]} + > + + {isSubmitting ? 'Logging in...' : 'Log in'} + + + + + Create a new account + + + + + ) } diff --git a/FastNotes/app/newNote.tsx b/FastNotes/app/newNote.tsx index a995bff..99c48e6 100644 --- a/FastNotes/app/newNote.tsx +++ b/FastNotes/app/newNote.tsx @@ -88,7 +88,7 @@ export default function NewNoteScreen() { return } - router.replace("/index") + router.replace("/") } } diff --git a/FastNotes/app/signup.tsx b/FastNotes/app/signup.tsx index e243dbc..afcf518 100644 --- a/FastNotes/app/signup.tsx +++ b/FastNotes/app/signup.tsx @@ -1,7 +1,7 @@ import { supabase } from "@/libs/supabase" -import { Link, Stack } from "expo-router" +import { Link, Stack, router } from "expo-router" import { useState } from "react" -import { Pressable, Text, TextInput, View } from 'react-native' +import { Keyboard, KeyboardAvoidingView, Platform, Pressable, ScrollView, Text, TextInput, View } from 'react-native' import { useAppTheme } from "@/src/theme/AppThemeProvider" import { signupScreenStyles as styles } from "@/src/styles/app-styles" @@ -59,60 +59,80 @@ export default function SignupScreen(){ return ( <> - - Sign up - - E-mail - - - Password - - - {errorMessage ? ( - {errorMessage} - ) : null} - - {successMessage ? ( - {successMessage} - ) : null} - - [ - styles.actionButton, - pressed && !isSubmitting ? styles.actionButtonPressed : null, - isSubmitting ? styles.actionButtonDisabled : null, - ]} + + - - {isSubmitting ? 'Creating account...' : 'Sign up'} - - + + + router.replace("/login")} + style={styles.backButton} + > + Back to login + - - Already have an account? Log in - + Sign up - + E-mail + + + Password + + + {errorMessage ? ( + {errorMessage} + ) : null} + + {successMessage ? ( + {successMessage} + ) : null} + + [ + styles.actionButton, + pressed && !isSubmitting ? styles.actionButtonPressed : null, + isSubmitting ? styles.actionButtonDisabled : null, + ]} + > + + {isSubmitting ? 'Creating account...' : 'Sign up'} + + + + + Already have an account? Log in + + + + + ) } diff --git a/FastNotes/providers/auth-provider.tsx b/FastNotes/providers/auth-provider.tsx index 3abc1a0..cccf199 100644 --- a/FastNotes/providers/auth-provider.tsx +++ b/FastNotes/providers/auth-provider.tsx @@ -10,12 +10,37 @@ const buildClaims = (user?: { id: string; email?: string | null } | null) => } : null +const isInvalidRefreshTokenError = (error: { message?: string; status?: number } | null) => { + if (!error) { + return false + } + + const message = error.message?.toLowerCase() ?? '' + + return error.status === 401 && ( + message.includes('invalid refresh token') || + message.includes('refresh token not found') + ) +} + export default function AuthProvider({ children }: PropsWithChildren) { const [claims, setClaims] = useState | undefined | null>() const [profile, setProfile] = useState() const [isLoading, setIsLoading] = useState(true) useEffect(() => { + const clearInvalidSession = async () => { + const { error } = await supabase.auth.signOut({ scope: 'local' }) + + if (error) { + console.error('Error clearing invalid local session:', error) + } + + setClaims(null) + setProfile(null) + setIsLoading(false) + } + const hydrateSession = async () => { const { data: { session }, @@ -23,6 +48,12 @@ export default function AuthProvider({ children }: PropsWithChildren) { } = await supabase.auth.getSession() if (error) { + if (isInvalidRefreshTokenError(error)) { + console.warn('Clearing expired auth session:', error.message) + await clearInvalidSession() + return + } + console.error('Error hydrating session:', error) } diff --git a/FastNotes/src/styles/app-styles.ts b/FastNotes/src/styles/app-styles.ts index 429271c..bd1a42a 100644 --- a/FastNotes/src/styles/app-styles.ts +++ b/FastNotes/src/styles/app-styles.ts @@ -72,10 +72,23 @@ export const themedTextStyles = StyleSheet.create({ }) export const loginScreenStyles = StyleSheet.create({ - container: { + keyboardAvoider: { + flex: 1, + }, + scrollView: { + flex: 1, + }, + scrollContent: { + flexGrow: 1, + justifyContent: "center", + paddingHorizontal: 24, + paddingVertical: 32, + }, + dismissArea: { flex: 1, justifyContent: "center", - padding: 24, + }, + form: { gap: 12, }, title: { @@ -125,12 +138,33 @@ export const loginScreenStyles = StyleSheet.create({ }) export const signupScreenStyles = StyleSheet.create({ - container: { + keyboardAvoider: { + flex: 1, + }, + scrollView: { + flex: 1, + }, + scrollContent: { + flexGrow: 1, + justifyContent: "center", + paddingHorizontal: 24, + paddingVertical: 32, + }, + dismissArea: { flex: 1, justifyContent: "center", - padding: 24, + }, + form: { gap: 12, }, + backButton: { + alignSelf: "flex-start", + paddingVertical: 8, + }, + backButtonText: { + fontSize: 16, + fontWeight: "600", + }, title: { fontSize: 28, fontWeight: "700",