Student page ui changes + modal

This commit is contained in:
Anushlinux
2025-07-05 01:01:41 +05:30
parent 0ac4865e47
commit 9aa7e61d34
8 changed files with 822 additions and 98 deletions

View File

@@ -1,5 +1,6 @@
'use client';
import { useState } from 'react';
import {
ColumnDef,
flexRender,
@@ -16,13 +17,18 @@ import {
TableHeader,
TableRow,
} from '@workspace/ui/components/table';
import { Student } from './columns';
import { StudentDetailsModal } from './student-details-modal.tsx';
import { columns } from './columns';
interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[];
data: TData[];
interface DataTableProps {
data: Student[];
}
export function DataTable<TData, TValue>({ columns, data }: DataTableProps<TData, TValue>) {
export function DataTable({ data }: DataTableProps) {
const [selectedStudent, setSelectedStudent] = useState<Student | null>(null);
const [isModalOpen, setIsModalOpen] = useState(false);
const table = useReactTable({
data,
columns,
@@ -30,44 +36,94 @@ export function DataTable<TData, TValue>({ columns, data }: DataTableProps<TData
getPaginationRowModel: getPaginationRowModel(),
});
const handleRowClick = (student: Student) => {
setSelectedStudent(student);
setIsModalOpen(true);
};
const handleCloseModal = () => {
setIsModalOpen(false);
setSelectedStudent(null);
};
return (
<div className="rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())}
</TableHead>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
<>
<div className="rounded-md border bg-white">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-gray-50">
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id} className="font-semibold text-gray-700">
{header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())}
</TableHead>
);
})}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center">
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && 'selected'}
className="cursor-pointer hover:bg-gray-50 transition-colors duration-150"
onClick={() => handleRowClick(row.original as Student)}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id} className="py-4">
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center text-gray-500">
No students found.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
{/* Pagination */}
<div className="flex items-center justify-between space-x-2 py-4">
<div className="flex-1 text-sm text-gray-700">
Showing {table.getFilteredRowModel().rows.length} of{' '}
{table.getFilteredRowModel().rows.length} results
</div>
<div className="space-x-2">
<button
className="px-3 py-1 text-sm border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
Previous
</button>
<button
className="px-3 py-1 text-sm border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
Next
</button>
</div>
</div>
{/* Student Details Modal */}
{selectedStudent && (
<StudentDetailsModal
student={selectedStudent}
isOpen={isModalOpen}
onClose={handleCloseModal}
/>
)}
</>
);
}