diff --git a/app/(tabs)/subjects.tsx b/app/(tabs)/subjects.tsx index 86564b8..f3cd33c 100644 --- a/app/(tabs)/subjects.tsx +++ b/app/(tabs)/subjects.tsx @@ -4,13 +4,14 @@ import { Subject } from '@/lib/types'; import { Session } from '@supabase/supabase-js'; import { router, Stack, useFocusEffect } from 'expo-router'; import { useCallback, useEffect, useState } from 'react'; -import { Alert, Pressable, ScrollView, Text, View } from 'react-native'; +import { ActivityIndicator, Alert, Pressable, ScrollView, Text, View } from 'react-native'; import type { SubjectColor } from '@/lib/subjectColors'; export default function Subjects() { const [subjects, SetSubjects] = useState([]); const [session, SetSession] = useState(null); + const [isLoading, SetIsLoading] = useState(true); useEffect(() => { supabase.auth.getSession().then(({ data }) => { @@ -27,7 +28,12 @@ export default function Subjects() { }, []); const GetSubjects = async () => { - if (!session?.user.id) return; + if (!session?.user.id) { + SetIsLoading(false); + return; + } + + SetIsLoading(true); const { data, error } = await supabase .from('subjects') @@ -37,10 +43,12 @@ export default function Subjects() { if (error) { Alert.alert('Subjects could not be fetched, please try again'); + SetIsLoading(false); return; } SetSubjects((data as Subject[]) ?? []); + SetIsLoading(false); }; useFocusEffect( @@ -85,7 +93,14 @@ export default function Subjects() { - {subjects.length === 0 ? ( + {isLoading ? ( + + + + Loading subjects... + + + ) : subjects.length === 0 ? ( No subjects yet @@ -178,4 +193,4 @@ export default function Subjects() { ); -} \ No newline at end of file +} diff --git a/app/subject/viewDetailsSubject.tsx b/app/subject/viewDetailsSubject.tsx index 7b5480f..030937d 100644 --- a/app/subject/viewDetailsSubject.tsx +++ b/app/subject/viewDetailsSubject.tsx @@ -6,7 +6,7 @@ import type { Assignment } from '@/lib/types'; import { Session } from '@supabase/supabase-js'; import { router, Stack, useFocusEffect, useLocalSearchParams } from 'expo-router'; import { useCallback, useEffect, useState } from 'react'; -import { Alert, Pressable, SectionList, Text, View } from 'react-native'; +import { ActivityIndicator, Alert, Pressable, SectionList, Text, View } from 'react-native'; export type Subject = { sId: string; @@ -23,6 +23,7 @@ export default function ViewDetailsSubject() { const [subject, SetSubject] = useState(null); const [assignments, SetAssignments] = useState([]); const [session, SetSession] = useState(null); + const [isLoading, SetIsLoading] = useState(true); const assignmentSections = [ { @@ -79,10 +80,16 @@ export default function ViewDetailsSubject() { useFocusEffect( useCallback(() => { - if (session && sId) { - GetSubject(sId); - GetAssignments(sId); + if (!session || !sId) { + return; } + + SetIsLoading(true); + SetSubject(null); + + Promise.all([GetSubject(sId), GetAssignments(sId)]).finally(() => { + SetIsLoading(false); + }); }, [session, sId]) ); @@ -181,6 +188,25 @@ export default function ViewDetailsSubject() { ? 0 : Math.round((completedAssignments / totalAssignments) * 100); + if (isLoading) { + return ( + + + + + + + Loading subject... + + + + ); + } + if (!subject) { return ( @@ -474,4 +500,4 @@ export default function ViewDetailsSubject() { /> ); -} \ No newline at end of file +}