mediahub-fe/src/components/features/project/team-table.tsx

291 lines
7.7 KiB
TypeScript
Raw Normal View History

2025-05-27 00:19:52 +00:00
"use client";
2024-11-26 03:09:48 +00:00
2025-05-27 00:19:52 +00:00
import * as React from "react";
2024-11-26 03:09:48 +00:00
import {
ColumnDef,
ColumnFiltersState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
2025-05-27 00:19:52 +00:00
PaginationState,
SortingState,
2024-11-26 03:09:48 +00:00
useReactTable,
2025-05-27 00:19:52 +00:00
VisibilityState,
} from "@tanstack/react-table";
import { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react";
import Chart from "react-apexcharts";
2024-11-26 03:09:48 +00:00
2025-05-27 00:19:52 +00:00
import { colors } from "@/lib/colors";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
2024-11-26 03:09:48 +00:00
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
2025-05-27 00:19:52 +00:00
} from "@/components/ui/table";
2024-11-26 03:09:48 +00:00
export type TeamTableProps = {
customer: {
name: string;
image: string;
deg: string;
2025-05-27 00:19:52 +00:00
};
2024-11-26 03:09:48 +00:00
status: "progress" | "complete";
time: string;
chart: null;
2025-05-27 00:19:52 +00:00
action: null;
};
2024-11-26 03:09:48 +00:00
const series = [
{
data: [800, 600, 1000, 800, 600, 1000, 800, 900],
2025-05-27 00:19:52 +00:00
},
2024-11-26 03:09:48 +00:00
];
const options: any = {
chart: {
toolbar: {
autoSelected: "pan",
show: false,
},
offsetX: 0,
offsetY: 0,
zoom: {
enabled: false,
},
sparkline: {
enabled: true,
},
},
dataLabels: {
enabled: false,
},
stroke: {
curve: "smooth",
width: 2,
},
colors: [colors.primary],
tooltip: {
theme: "dark",
},
grid: {
show: false,
padding: {
left: 0,
right: 0,
},
},
yaxis: {
show: false,
},
fill: {
type: "solid",
opacity: [0.1],
},
legend: {
theme: "dark",
show: false,
},
xaxis: {
low: 0,
offsetX: 0,
offsetY: 0,
show: false,
labels: {
low: 0,
offsetX: 0,
show: false,
},
axisBorder: {
low: 0,
offsetX: 0,
show: false,
},
},
};
export const columns: ColumnDef<TeamTableProps>[] = [
{
accessorKey: "customer",
header: "ASSIGNEE",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-none">
<div className="w-8 h-8">
<Avatar>
<AvatarImage src={row.original.customer.image}></AvatarImage>
<AvatarFallback>SC</AvatarFallback>
</Avatar>
</div>
</div>
<div className="flex-1 text-start text-default-600 capitalize whitespace-nowrap">
{row.original.customer.name}
</div>
</div>
),
},
{
accessorKey: "status",
header: "status",
enableSorting: false,
cell: ({ row }) => {
return (
<div className="min-w-[140px] text-start">
<div className="text-center mx-auto py-1">
{row.getValue("status") === "progress" && (
<span className="flex items-center gap-3">
<span className="h-1.5 w-1.5 bg-destructive rounded-full inline-block ring-4 ring-opacity-30 ring-destructive/50"></span>
<span>In progress</span>
</span>
)}
{row.getValue("status") === "complete" && (
<span className="flex items-center gap-3">
<span className="h-1.5 w-1.5 bg-success rounded-full inline-block ring-4 ring-opacity-30 ring-success/50"></span>
<span>Complete</span>
</span>
)}
</div>
</div>
2025-05-27 00:19:52 +00:00
);
},
2024-11-26 03:09:48 +00:00
},
{
accessorKey: "time",
header: "Time",
2025-05-27 00:19:52 +00:00
cell: ({ row }) => <span className="whitespace-nowrap">{row.getValue("time")}</span>,
2024-11-26 03:09:48 +00:00
},
{
accessorKey: "chart",
header: "Chart",
cell: ({ row }) => (
<div>
<Chart options={options} series={series} type="area" width="100%" height={48} />
</div>
2025-05-27 00:19:52 +00:00
),
2024-11-26 03:09:48 +00:00
},
{
id: "actions",
accessorKey: "action",
header: "Actions",
enableHiding: false,
cell: ({ row }) => {
return (
<div className="flex justify-end">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
2025-05-27 00:19:52 +00:00
className="w-8 h-8 text-default-700 bg-transparent hover:bg-transparent ring-offset-transparent hover:ring-transparent"
2024-11-26 03:09:48 +00:00
>
<span className="sr-only">Open menu</span>
<MoreVertical className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<SquarePen className="w-4 h-4 me-1.5" />
2025-05-27 00:19:52 +00:00
Edit
</DropdownMenuItem>
2024-11-26 03:09:48 +00:00
<DropdownMenuItem className="p-2 border-b bg-destructive/30 text-destructive group focus:bg-destructive focus:text-destructive-foreground rounded-none">
<Trash2 className="w-4 h-4 me-1.5" />
2025-05-27 00:19:52 +00:00
Delete
</DropdownMenuItem>
2024-11-26 03:09:48 +00:00
</DropdownMenuContent>
</DropdownMenu>
</div>
2025-05-27 00:19:52 +00:00
);
},
},
];
2024-11-26 03:09:48 +00:00
const TeamTable = ({ data }: any) => {
2025-05-27 00:19:52 +00:00
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([]);
const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
2024-11-26 03:09:48 +00:00
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 6,
2025-05-27 00:19:52 +00:00
});
2024-11-26 03:09:48 +00:00
const table = useReactTable({
data,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
onPaginationChange: setPagination,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
2025-05-27 00:19:52 +00:00
pagination,
2024-11-26 03:09:48 +00:00
},
2025-05-27 00:19:52 +00:00
});
2024-11-26 03:09:48 +00:00
return (
<div className="w-full overflow-x-auto">
<Table className="overflow-hidden">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-default-200">
{headerGroup.headers.map((header) => (
<TableHead key={header.id} className="last:text-end">
2025-05-27 00:19:52 +00:00
{header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())}
2024-11-26 03:09:48 +00:00
</TableHead>
))}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
className="h-[75px]"
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
2025-05-27 00:19:52 +00:00
{flexRender(cell.column.columnDef.cell, cell.getContext())}
2024-11-26 03:09:48 +00:00
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
2025-05-27 00:19:52 +00:00
<TableCell colSpan={columns.length} className="h-24 text-center">
2024-11-26 03:09:48 +00:00
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
2025-05-27 00:19:52 +00:00
);
};
2024-11-26 03:09:48 +00:00
export default TeamTable;