83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
'use client';
|
|
|
|
import { useMemo } from 'react';
|
|
import type { ColumnDef } from '@tanstack/react-table';
|
|
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
|
import type { Project } from '@/types';
|
|
|
|
function EmptyValue() {
|
|
return <span className="text-muted-foreground">-</span>;
|
|
}
|
|
|
|
function StateBadges({ value }: { value: string | null }) {
|
|
if (!value) {
|
|
return <EmptyValue />;
|
|
}
|
|
|
|
const states = value
|
|
.split(',')
|
|
.map((state) => state.trim())
|
|
.filter(Boolean);
|
|
|
|
if (!states.length) {
|
|
return <EmptyValue />;
|
|
}
|
|
|
|
const [firstState, ...remainingStates] = states;
|
|
|
|
return (
|
|
<div className="flex items-center gap-1.5">
|
|
<Badge variant="secondary">{firstState}</Badge>
|
|
{remainingStates.length > 0 ? (
|
|
<Popover>
|
|
<PopoverTrigger asChild>
|
|
<button
|
|
type="button"
|
|
className="flex items-center justify-center rounded-full border border-border/40 bg-muted/50 px-1.5 py-0.5 text-muted-foreground transition-colors hover:bg-muted"
|
|
>
|
|
+{remainingStates.length}
|
|
</button>
|
|
</PopoverTrigger>
|
|
<PopoverContent className="w-auto p-2" align="start">
|
|
<div className="flex flex-col gap-1.5">
|
|
<p className="mb-0.5 px-1 text-muted-foreground">
|
|
Other States
|
|
</p>
|
|
{remainingStates.map((state) => (
|
|
<Badge key={state} variant="secondary">
|
|
{state}
|
|
</Badge>
|
|
))}
|
|
</div>
|
|
</PopoverContent>
|
|
</Popover>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function useProjectColumns() {
|
|
return useMemo<ColumnDef<Project>[]>(
|
|
() => [
|
|
{
|
|
accessorKey: 'name',
|
|
header: 'Project Name',
|
|
cell: ({ row }) => <div>{row.original.name}</div>,
|
|
},
|
|
{
|
|
accessorKey: 'state',
|
|
header: 'State',
|
|
cell: ({ row }) => <StateBadges value={row.original.state} />,
|
|
},
|
|
{
|
|
accessorKey: 'corridor_name',
|
|
header: 'Corridor',
|
|
cell: ({ row }) => row.original.corridor_name || <EmptyValue />,
|
|
},
|
|
],
|
|
[],
|
|
);
|
|
}
|