Skip to content
This repository was archived by the owner on Jun 12, 2025. It is now read-only.

Commit 1cb8634

Browse files
authored
Merge pull request #13 from EVOGD-Project:dev
Dev
2 parents 986f4c9 + 4d7e59e commit 1cb8634

3 files changed

Lines changed: 80 additions & 51 deletions

File tree

src/api/api.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { API_URL } from '@/constants/constants';
22
import type { IActivity } from '@/types/IActivity';
33
import type { IClassroom } from '@/types/IClassroomCard';
4+
import type { IUser } from '@/types/IUser';
45

56
const getAuthHeaders = (): Record<string, string> => {
67
const token = typeof window !== 'undefined' ? localStorage.getItem('token') : null;
@@ -31,6 +32,18 @@ export const api = {
3132
return res.json();
3233
},
3334

35+
getMembers: async (id: string): Promise<IUser[]> => {
36+
const res = await fetch(`${API_URL}/classrooms/${encodeURIComponent(id)}/members`, {
37+
headers: {
38+
...getAuthHeaders()
39+
}
40+
});
41+
42+
if (!res.ok) throw new Error('Failed to fetch classroom');
43+
return res.json();
44+
},
45+
46+
3447
create: async (data: {
3548
name: string;
3649
description: string;

src/components/modals/JoinClassModal.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export default function JoinClassModal({ isOpen, onClose, onClassroomJoined }: R
5151

5252
setIsLoading(true);
5353
try {
54+
await api.classroom.join(code);
5455
const updatedClassrooms = await api.classroom.getAll();
5556
onClassroomJoined?.(updatedClassrooms);
5657

src/components/screens/ClassScreen.tsx

Lines changed: 66 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,15 @@ import { useEffect, useState } from 'react';
3131
import { FiCode, FiFileText, FiPlus, FiUsers } from 'react-icons/fi';
3232
import ActivityCard from '../general/ActivityCard';
3333
import CreateActivityModal from '../modals/CreateActivityModal';
34+
import type { IUser } from '@/types/IUser';
3435

3536
export default function ClassScreen({ id }: Readonly<{ id: string }>) {
3637
const [classroom, setClassroom] = useState<IClassroom | null>(null);
3738
const [isLoading, setIsLoading] = useState(true);
3839
const router = useRouter();
3940
const [classActivities, setClassActivities] = useState<IActivity[]>([]);
41+
const [classMembers, setClassMembers] = useState<IUser[]>([]);
42+
const [isMembersLoading, setIsMembersLoading] = useState(false);
4043
const { isOpen, onOpen, onClose } = useDisclosure();
4144
const toast = useToast();
4245

@@ -72,6 +75,28 @@ export default function ClassScreen({ id }: Readonly<{ id: string }>) {
7275
setClassActivities((prev) => [...prev, activity]);
7376
};
7477

78+
const handleTabChange = async (index: number) => {
79+
// Index 1 is the "Estudiantes" tab
80+
if (index === 1 && classMembers.length === 0) {
81+
setIsMembersLoading(true);
82+
try {
83+
const members = await api.classroom.getMembers(id);
84+
setClassMembers(members);
85+
} catch (error) {
86+
toast({
87+
title: 'Error',
88+
description: 'No se pudo cargar la lista de estudiantes',
89+
status: 'error',
90+
position: 'top-right',
91+
duration: 3000,
92+
isClosable: true
93+
});
94+
} finally {
95+
setIsMembersLoading(false);
96+
}
97+
}
98+
};
99+
75100
if (isLoading) {
76101
return (
77102
<Flex h='100%' align='center' justify='center'>
@@ -125,7 +150,7 @@ export default function ClassScreen({ id }: Readonly<{ id: string }>) {
125150
<Flex gap={6} color='gray.400'>
126151
<Flex align='center' gap={2}>
127152
<Icon as={FiUsers} />
128-
<Text>24 estudiantes</Text>
153+
<Text>{classMembers.length || '...'} estudiantes</Text>
129154
</Flex>
130155
<Flex align='center' gap={2}>
131156
<Icon as={FiCode} />
@@ -148,7 +173,7 @@ export default function ClassScreen({ id }: Readonly<{ id: string }>) {
148173

149174
<Box>
150175
<Container maxW='container.xl'>
151-
<Tabs variant='unstyled'>
176+
<Tabs variant='unstyled' onChange={handleTabChange}>
152177
<Box borderBottom='1px solid' borderColor='brand.dark.800'>
153178
<TabList gap={4}>
154179
<Tab
@@ -243,57 +268,47 @@ export default function ClassScreen({ id }: Readonly<{ id: string }>) {
243268
<Heading size='lg' mb={6}>
244269
Estudiantes
245270
</Heading>
246-
<Grid
247-
templateColumns={{
248-
base: '1fr',
249-
sm: 'repeat(2, 1fr)',
250-
md: 'repeat(3, 1fr)'
251-
}}
252-
gap={4}
253-
>
254-
<Flex
255-
p={4}
271+
{isMembersLoading ? (
272+
<Flex justify='center' py={8}>
273+
<Spinner size='xl' />
274+
</Flex>
275+
) : (
276+
<Grid
277+
templateColumns={{
278+
base: '1fr',
279+
sm: 'repeat(2, 1fr)',
280+
md: 'repeat(3, 1fr)'
281+
}}
256282
gap={4}
257-
align='center'
258-
bg='brand.dark.900'
259-
borderRadius='xl'
260-
border='1px solid'
261-
borderColor='brand.dark.800'
262283
>
263-
<Avatar
264-
size='md'
265-
name='Ángel'
266-
src='https://avatars.githubusercontent.com/u/57068341?v=4'
267-
/>
268-
<Box>
269-
<Text fontWeight='bold'>Ángel</Text>
270-
<Text fontSize='sm' color='brand.primary.400'>
271-
Profesor
272-
</Text>
273-
</Box>
274-
</Flex>
275-
276-
{Array.from({ length: 5 }).map((_, i) => (
277-
<Flex
278-
key={i}
279-
p={4}
280-
gap={4}
281-
align='center'
282-
bg='brand.dark.900'
283-
borderRadius='xl'
284-
border='1px solid'
285-
borderColor='brand.dark.800'
286-
>
287-
<Avatar size='md' name={`Estudiante ${i + 1}`} />
288-
<Box>
289-
<Text fontWeight='bold'>Estudiante {i + 1}</Text>
290-
<Text fontSize='sm' color='gray.400'>
291-
Estudiante
292-
</Text>
293-
</Box>
294-
</Flex>
295-
))}
296-
</Grid>
284+
{classMembers.map((member) => (
285+
<Flex
286+
key={member.id}
287+
p={4}
288+
gap={4}
289+
align='center'
290+
bg='brand.dark.900'
291+
borderRadius='xl'
292+
border='1px solid'
293+
borderColor='brand.dark.800'
294+
>
295+
<Avatar size='md' name={member.username} />
296+
<Box>
297+
<Text fontWeight='bold'>{member.username}</Text>
298+
{member.id === classroom.owner ? (
299+
<Text fontSize='sm' color='brand.primary.400'>
300+
Profesor
301+
</Text>
302+
) : (
303+
<Text fontSize='sm' color='gray.400'>
304+
Estudiante
305+
</Text>
306+
)}
307+
</Box>
308+
</Flex>
309+
))}
310+
</Grid>
311+
)}
297312
</Box>
298313
</VStack>
299314
</TabPanel>

0 commit comments

Comments
 (0)