feat: implement ClassList component to display classes; update UserList to show associated classes and handle empty states

This commit is contained in:
Rémi 2025-01-08 00:20:56 +01:00
parent 52274f204c
commit 0cc0d18558
5 changed files with 106 additions and 8 deletions

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --turbopack -p 4000",
"dev": "next dev -p 4000",
"build": "next build",
"build:docker": "docker build -t toogether/webapp .",
"start": "next start -p 4000",

View File

@ -1,3 +1,4 @@
import { ClassList } from "@/app/components/Class";
import { Metadata } from "next";
export const metadata: Metadata = {
@ -5,5 +6,5 @@ export const metadata: Metadata = {
};
export default async function Page() {
return <p>Hello world!</p>;
return <ClassList />;
}

View File

@ -0,0 +1,71 @@
"use client";
import { Class } from "@/app/interface/class";
import { classesService } from "@/app/services/classes.service";
import {
Card,
Skeleton,
Table,
TableBody,
TableCell,
TableColumn,
TableHeader,
TableRow,
} from "@nextui-org/react";
import { useEffect, useState } from "react";
export const ClassList = () => {
const [classes, setClasses] = useState<Class[]>();
useEffect(() => {
classesService.getAll().then((response) => {
setClasses(response.data);
});
}, []);
if (!classes) {
return (
<Card className="w-full space-y-5 p-4" radius="lg">
<Skeleton className="rounded-lg">
<div className="h-10 rounded-lg bg-default-300" />
</Skeleton>
<div className="space-y-3">
<Skeleton className="w-3/5 rounded-lg">
<div className="h-3 w-3/5 rounded-lg bg-default-200" />
</Skeleton>
<Skeleton className="w-4/5 rounded-lg">
<div className="h-3 w-4/5 rounded-lg bg-default-200" />
</Skeleton>
<Skeleton className="w-2/5 rounded-lg">
<div className="h-3 w-2/5 rounded-lg bg-default-300" />
</Skeleton>
</div>
</Card>
);
}
if (classes.length === 0) {
return (
<Card className="w-full p-4" radius="lg">
<p className="text-center text-lg text-gray-500 dark:text-gray-400">
No classes found
</p>
</Card>
);
}
return (
<Table aria-label="List of users" className="w-full">
<TableHeader>
<TableColumn>NAME</TableColumn>
</TableHeader>
<TableBody>
{classes.map((Class) => (
<TableRow key={Class.id.toString()}>
<TableCell>{Class.name}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
};

View File

@ -43,18 +43,38 @@ export const UserList = () => {
);
}
if (users.length === 0) {
return (
<Card className="w-full p-4" radius="lg">
<p className="text-center text-lg text-gray-500 dark:text-gray-400">
No users found
</p>
</Card>
);
}
return (
<Table aria-label="List of users" className="w-full">
<TableHeader>
<TableColumn>USERNAME</TableColumn>
<TableColumn>CLASS</TableColumn>
</TableHeader>
<TableBody>
{users &&
users.map((user) => (
<TableRow key={user.id.toString()}>
<TableCell>{user.username}</TableCell>
</TableRow>
))}
{users.map((user) => (
<TableRow key={user.id.toString()}>
<TableCell>{user.username}</TableCell>
<TableCell className="flex flex-wrap gap-1">
{user.Class.map((c) => (
<span
className="px-2 rounded-md bg-foreground-100"
key={c.id.toString()}
>
{c.name}
</span>
))}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);

View File

@ -1,4 +1,10 @@
export interface User {
id: string;
username: string;
Class: {
id: string;
name: string;
createdAt: string;
}[];
}