165 lines
6.1 KiB
TypeScript
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>
|
|
);
|
|
}
|