From a9014dfeabf182f856ddf127a6724a95a1cbd093 Mon Sep 17 00:00:00 2001 From: Richard Chibuike Date: Thu, 30 Jul 2026 12:45:22 +0100 Subject: [PATCH] fix: add loading boundary and distinguish empty vs loading on Study Groups page --- src/app/hooks/useStudyGroups.tsx | 16 ++++++++++++---- src/app/pages/StudyGroups.tsx | 15 ++++++++++++--- src/app/study-groups/loading.tsx | 27 +++++++++++++++++++++++---- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/app/hooks/useStudyGroups.tsx b/src/app/hooks/useStudyGroups.tsx index 318b5410..1b1851d9 100644 --- a/src/app/hooks/useStudyGroups.tsx +++ b/src/app/hooks/useStudyGroups.tsx @@ -142,6 +142,7 @@ function uid(prefix = 'id'): string { } export type UseStudyGroupsApi = { + loading: boolean; groups: StudyGroup[]; messages: GroupMessage[]; resources: GroupResource[]; @@ -208,6 +209,12 @@ export function useStudyGroups(currentUser?: { id: string; name: string }): UseS load(STORAGE_KEYS.certificates, [] as ForumCertificate[]), ); + const [loading, setLoading] = useState(true); + + useEffect(() => { + setLoading(false); + }, []); + const me = currentUser ?? { id: 'current-user', name: 'You' }; const persistAll = useCallback( @@ -265,11 +272,11 @@ export function useStudyGroups(currentUser?: { id: string; name: string }): UseS const { addNotification } = useNotificationStore.getState(); addNotification({ type: 'success', - message: `Created group “${group.name}”`, + message: `Created group “${group.name}”`, meta: { groupId: group.id }, }); } catch {} - toast.success(`Created group “${group.name}”`); + toast.success(`Created group “${group.name}”`); return group; }, [me.id, me.name, triggerSync], @@ -326,7 +333,7 @@ export function useStudyGroups(currentUser?: { id: string; name: string }): UseS meta: { groupId }, }); } catch {} - toast('Left group', { icon: '👋' }); + toast('Left group', { icon: '👋' }); }, [me.id, triggerSync], ); @@ -588,6 +595,7 @@ export function useStudyGroups(currentUser?: { id: string; name: string }): UseS useMemo(() => persistAll(), [groups, messages, resources, challenges, certificates, persistAll]); return { + loading, groups, messages, resources, @@ -609,4 +617,4 @@ export function useStudyGroups(currentUser?: { id: string; name: string }): UseS groupChallenges, challengeLeaderboard, }; -} +} \ No newline at end of file diff --git a/src/app/pages/StudyGroups.tsx b/src/app/pages/StudyGroups.tsx index b6c6bf95..5fd183de 100644 --- a/src/app/pages/StudyGroups.tsx +++ b/src/app/pages/StudyGroups.tsx @@ -13,7 +13,7 @@ import { useStudyGroups } from '@/app/hooks/useStudyGroups'; import NotificationBell from '@/app/components/notifications/NotificationBell'; export default function StudyGroupsPage() { - const sg = useStudyGroups(); + const { loading, ...sg } = useStudyGroups(); const [selectedGroupId, setSelectedGroupId] = useState(null); const [searchQuery, setSearchQuery] = useState(''); const [showCreateForm, setShowCreateForm] = useState(false); @@ -107,7 +107,16 @@ export default function StudyGroupsPage() { Groups ({filteredGroups.length}) - {filteredGroups.length === 0 ? ( + {loading ? ( +
+ {[1, 2, 3].map((i) => ( +
+ ))} +
+ ) : filteredGroups.length === 0 ? (

@@ -323,4 +332,4 @@ function CreateGroupForm({

); -} +} \ No newline at end of file diff --git a/src/app/study-groups/loading.tsx b/src/app/study-groups/loading.tsx index 911833a5..982e5f03 100644 --- a/src/app/study-groups/loading.tsx +++ b/src/app/study-groups/loading.tsx @@ -1,5 +1,24 @@ -import { ServerlessPageSkeleton } from '@/components/ui/ServerlessSkeleton'; - export default function StudyGroupsLoading() { - return ; -} + return ( +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ); +} \ No newline at end of file