2025-06-12 16:36:02 +02:00

165 lines
6.1 KiB
TypeScript

import {
Select,
SelectItem,
Table,
TableBody,
TableCell,
TableColumn,
TableHeader,
TableRow,
} from '@heroui/react';
import { useEffect, useState } from 'react';
interface ChunkerData {
terms: {
id: string;
name: string;
courses: {
id: string;
name: string;
chunks: {
id: string;
name: string;
tokens: number;
}[];
images: string[];
}[];
}[];
}
export default function ChunkerDataTable({
chunkerData,
}: {
chunkerData: ChunkerData;
}) {
if (!chunkerData || !chunkerData.terms || chunkerData.terms.length === 0) {
return (
<div className="p-6 rounded shadow-md">
<p className="text-lg text-default-500">No data</p>
</div>
);
}
// Initialize selected term to the first term in the program
const [selectedTerm, setSelectedTerm] = useState<ChunkedTerm | null>(
chunkerData.terms[0] || null
);
const [selectedCourse, setSelectedCourse] =
useState<ChunkedCourse | null>(null); // Initialize to null
const [flattenedChunks, setFlattenedChunks] = useState<FlattenedChunk[]>(
[]
);
const getFlattenedChunks = (course: ChunkedCourse | null) => {
return course?.chunks.map((chunk) => ({
id: chunk.id,
name: chunk.name,
tokens: chunk.tokens,
}));
};
useEffect(() => {
if (selectedTerm) {
setSelectedCourse(selectedTerm.courses[0] || null);
}
}, [selectedTerm]);
useEffect(() => {
if (selectedTerm && selectedCourse) {
setFlattenedChunks(getFlattenedChunks(selectedCourse));
}
}, [selectedCourse]);
return (
<div className="p-6 rounded shadow-md">
{/* Term Selector */}
<div className="flex flex-row gap-4">
<Select
className="mt-1 block w-full rounded-md shadow-sm focus:ring focus:ring-primary text-lg"
selectedKeys={selectedTerm ? [selectedTerm.id] : []}
label="Select Term"
labelPlacement="outside"
onSelectionChange={(keys) => {
const key = Array.from(keys)[0];
setSelectedTerm(
typeof key === 'string' ? key : String(key)
);
}}
>
{chunkerData.terms.map((term) => (
<SelectItem key={term.id} className="text-lg">
{term.name}
</SelectItem>
))}
</Select>
{/* Course Selector */}
<Select
className="mt-1 block w-full rounded-md shadow-sm focus:ring focus:ring-primary text-lg"
selectedKeys={selectedCourse ? [selectedCourse.id] : []}
label="Select Course"
labelPlacement="outside"
onSelectionChange={(keys) => {
const key = Array.from(keys)[0];
const courseId =
typeof key === 'string' ? key : String(key);
const courseToSet =
selectedTerm?.courses.find(
(c) => c.id === courseId
) || null;
setSelectedCourse(courseToSet);
}}
>
{(selectedTerm?.courses || []).map((course) => (
<SelectItem key={course.id} className="text-lg">
{course.name}
</SelectItem>
))}
</Select>
</div>
{/* Courses Table */}
{selectedTerm && selectedCourse && flattenedChunks && (
<div className="my-12 overflow-hidden rounded-xl">
<div className="overflow-auto max-h-[60dvh]">
<Table className="min-w-full">
<TableHeader className="bg-default-50 sticky top-0 z-10">
<TableColumn className="px-6 py-3 text-left text-xs font-medium text-default-500 uppercase">
Name
</TableColumn>
<TableColumn className="px-6 py-3 text-left text-xs font-medium text-default-500 uppercase">
Tokens
</TableColumn>
</TableHeader>
<TableBody className="bg-default divide-y divide-default-200 max-w-full">
{flattenedChunks.map((chunk, i) => {
return (
<TableRow
key={i}
className={`border-default-200`}
>
<TableCell
className={`px-6 whitespace-nowrap truncate max-w-xs text-lg font-semibold`}
>
{chunk.name}
</TableCell>
<TableCell
className={`px-6 whitespace-nowrap truncate max-w-xs`}
>
{chunk.tokens}
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</div>
</div>
)}
</div>
);
}