Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/app/hooks/useStudyGroups.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ function uid(prefix = 'id'): string {
}

export type UseStudyGroupsApi = {
loading: boolean;
groups: StudyGroup[];
messages: GroupMessage[];
resources: GroupResource[];
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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],
);
Expand Down Expand Up @@ -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,
Expand All @@ -609,4 +617,4 @@ export function useStudyGroups(currentUser?: { id: string; name: string }): UseS
groupChallenges,
challengeLeaderboard,
};
}
}
15 changes: 12 additions & 3 deletions src/app/pages/StudyGroups.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<string | null>(null);
const [searchQuery, setSearchQuery] = useState('');
const [showCreateForm, setShowCreateForm] = useState(false);
Expand Down Expand Up @@ -107,7 +107,16 @@ export default function StudyGroupsPage() {
Groups ({filteredGroups.length})
</h2>
</div>
{filteredGroups.length === 0 ? (
{loading ? (
<div className="space-y-3">
{[1, 2, 3].map((i) => (
<div
key={i}
className="h-24 bg-gray-200 dark:bg-gray-700 rounded-lg animate-pulse"
/>
))}
</div>
) : filteredGroups.length === 0 ? (
<div className="text-center py-8 text-gray-500 dark:text-gray-400 border border-dashed border-gray-300 dark:border-gray-600 rounded-lg">
<Users size={48} className="mx-auto mb-2 text-gray-300 dark:text-gray-600" />
<p className="text-sm">
Expand Down Expand Up @@ -323,4 +332,4 @@ function CreateGroupForm({
</div>
</div>
);
}
}
27 changes: 23 additions & 4 deletions src/app/study-groups/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
import { ServerlessPageSkeleton } from '@/components/ui/ServerlessSkeleton';

export default function StudyGroupsLoading() {
return <ServerlessPageSkeleton variant="generic" label="Loading study groups" />;
}
return (
<div className="min-h-screen bg-gray-50 dark:bg-gray-900">
<div className="container mx-auto px-4 py-8">
<div className="animate-pulse">
<div className="h-8 bg-gray-200 dark:bg-gray-700 rounded w-1/3 mb-2" />
<div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/2 mb-6" />
<div className="h-12 bg-gray-200 dark:bg-gray-700 rounded mb-6" />
<div className="h-10 bg-gray-200 dark:bg-gray-700 rounded w-40 mb-6" />
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div className="space-y-3">
<div className="h-6 bg-gray-200 dark:bg-gray-700 rounded w-1/4 mb-2" />
<div className="h-32 bg-gray-200 dark:bg-gray-700 rounded" />
<div className="h-32 bg-gray-200 dark:bg-gray-700 rounded" />
</div>
<div className="lg:col-span-2">
<div className="h-64 bg-gray-200 dark:bg-gray-700 rounded" />
</div>
</div>
</div>
</div>
</div>
);
}
Loading