task-d.5.4

This commit is contained in:
phaichayon
2026-06-25 08:06:53 +07:00
parent 0c28735c90
commit 6093003b70
22 changed files with 1930 additions and 207 deletions

View File

@@ -0,0 +1,164 @@
'use client';
import Link from 'next/link';
import type { Column, ColumnDef } from '@tanstack/react-table';
import { Icons } from '@/components/icons';
import { Badge } from '@/components/ui/badge';
import { DataTableColumnHeader } from '@/components/ui/table/data-table-column-header';
import type { LeadReferenceData, LeadSummary } from '../api/types';
import { LeadCellAction } from './lead-cell-action';
export function getLeadColumns({
referenceData,
canUpdate,
canDelete,
canAssign
}: {
referenceData: LeadReferenceData;
canUpdate: boolean;
canDelete: boolean;
canAssign: boolean;
}): ColumnDef<LeadSummary>[] {
return [
{
id: 'code',
accessorKey: 'code',
header: ({ column }: { column: Column<LeadSummary, unknown> }) => (
<DataTableColumnHeader column={column} title='Lead Code' />
),
cell: ({ row }) => (
<div className='flex flex-col'>
<Link href={`/dashboard/crm/leads/${row.original.id}`} className='font-medium hover:underline'>
{row.original.code}
</Link>
<span className='text-muted-foreground text-xs'>{row.original.customerName ?? '-'}</span>
</div>
),
meta: {
label: 'Lead Code',
placeholder: 'Search leads...',
variant: 'text' as const,
icon: Icons.search
},
enableColumnFilter: true
},
{
id: 'status',
accessorFn: (row) => row.status,
header: ({ column }: { column: Column<LeadSummary, unknown> }) => (
<DataTableColumnHeader column={column} title='Status' />
),
cell: ({ row }) => <Badge variant='outline'>{row.original.statusLabel ?? row.original.status}</Badge>,
meta: {
label: 'Status',
variant: 'select' as const,
options: referenceData.statuses.map((item) => ({
label: item.label,
value: item.id
}))
},
enableColumnFilter: true
},
{
id: 'branchId',
accessorFn: (row) => row.branchId ?? '',
header: ({ column }: { column: Column<LeadSummary, unknown> }) => (
<DataTableColumnHeader column={column} title='Branch' />
),
cell: ({ row }) => {
const branch = referenceData.branches.find((item) => item.id === row.original.branchId);
return <span>{branch?.name ?? '-'}</span>;
},
meta: {
label: 'Branch',
variant: 'select' as const,
options: referenceData.branches.map((item) => ({
label: item.name,
value: item.id
}))
},
enableColumnFilter: true
},
{
id: 'customerId',
accessorFn: (row) => row.customerId ?? '',
header: ({ column }: { column: Column<LeadSummary, unknown> }) => (
<DataTableColumnHeader column={column} title='Customer' />
),
cell: ({ row }) => <span>{row.original.customerName ?? '-'}</span>,
meta: {
label: 'Customer',
variant: 'select' as const,
options: referenceData.customers.map((item) => ({
label: `${item.name} (${item.code})`,
value: item.id
}))
},
enableColumnFilter: true
},
{
id: 'projectName',
accessorKey: 'projectName',
header: ({ column }: { column: Column<LeadSummary, unknown> }) => (
<DataTableColumnHeader column={column} title='Project' />
),
cell: ({ row }) => <span>{row.original.projectName ?? '-'}</span>
},
{
id: 'priority',
accessorFn: (row) => row.priority ?? '',
header: ({ column }: { column: Column<LeadSummary, unknown> }) => (
<DataTableColumnHeader column={column} title='Priority' />
),
cell: ({ row }) => <span>{row.original.priority ?? '-'}</span>
},
{
id: 'suggestedSalesOwner',
accessorFn: (row) => row.suggestedSalesOwnerId ?? '',
header: ({ column }: { column: Column<LeadSummary, unknown> }) => (
<DataTableColumnHeader column={column} title='Suggested Owner' />
),
cell: ({ row }) => <span>{row.original.suggestedSalesOwnerName ?? '-'}</span>
},
{
id: 'assignedSalesOwner',
accessorFn: (row) => row.assignedSalesOwnerId ?? '',
header: ({ column }: { column: Column<LeadSummary, unknown> }) => (
<DataTableColumnHeader column={column} title='Assigned Owner' />
),
cell: ({ row }) => <span>{row.original.assignedSalesOwnerName ?? '-'}</span>
},
{
id: 'estimatedValue',
accessorKey: 'estimatedValue',
header: ({ column }: { column: Column<LeadSummary, unknown> }) => (
<DataTableColumnHeader column={column} title='Estimated Value' />
),
cell: ({ row }) => (
<span>
{row.original.estimatedValue !== null ? row.original.estimatedValue.toLocaleString() : '-'}
</span>
)
},
{
id: 'createdAt',
accessorKey: 'createdAt',
header: ({ column }: { column: Column<LeadSummary, unknown> }) => (
<DataTableColumnHeader column={column} title='Created' />
),
cell: ({ row }) => <span>{new Date(row.original.createdAt).toLocaleDateString()}</span>
},
{
id: 'actions',
cell: ({ row }) => (
<LeadCellAction
data={row.original}
referenceData={referenceData}
canUpdate={canUpdate}
canDelete={canDelete}
canAssign={canAssign}
/>
)
}
];
}