import { Client } from '@/types'; import { dateDisplay } from '@/utils/datetime'; import { Link, router } from '@inertiajs/react'; import { ActionIcon, Badge, Button, Container, Group, Stack, Tabs, Text, Title, } from '@mantine/core'; import { IconEye, IconRefresh } from '@tabler/icons-react'; import type { MRT_Row } from 'mantine-react-table'; import { MantineReactTable } from 'mantine-react-table'; import React, { useMemo } from 'react'; import AppLayout from '../../layouts/app-layout'; interface Props { clients: Client[]; googleCompanySyncRunning: boolean; } const currencyFormatter = new Intl.NumberFormat('en-MY', { minimumFractionDigits: 2, maximumFractionDigits: 2, }); const parseAmount = (value?: number | string | null): number => { if (value === undefined || value === null) { return 0; } const normalized = typeof value === 'string' ? Number(value.replace(/,/g, '')) : Number(value); return Number.isNaN(normalized) ? 0 : normalized; }; const formatDate = (value?: string | null): string => value ? dateDisplay(value) : '—'; const statusOrder = ['ENABLED', 'PAUSED', 'REMOVED', 'ENDED', 'CANCELED']; const getStatusColor = (status: string) => { if (status === 'ENABLED') { return 'green'; } if (status === 'PAUSED') { return 'yellow'; } if (status === 'ENDED' || status === 'CANCELED' || status === 'REMOVED') { return 'red'; } return 'gray'; }; export default function TicketDetails({ clients, googleCompanySyncRunning, }: Props) { const [syncing, setSyncing] = React.useState(false); const [activeStatus, setActiveStatus] = React.useState( 'all', ); const campaignsData = clients ?? []; const statusTabs = useMemo(() => { const counts = campaignsData.reduce>( (acc, client) => { const status = client.status || 'UNKNOWN'; acc[status] = (acc[status] ?? 0) + 1; return acc; }, {}, ); return Object.entries(counts).sort(([a], [b]) => { const aIndex = statusOrder.indexOf(a); const bIndex = statusOrder.indexOf(b); if (aIndex !== -1 || bIndex !== -1) { return ( (aIndex === -1 ? Number.MAX_SAFE_INTEGER : aIndex) - (bIndex === -1 ? Number.MAX_SAFE_INTEGER : bIndex) ); } return a.localeCompare(b); }); }, [campaignsData]); const filteredClients = useMemo(() => { if (!activeStatus || activeStatus === 'all') { return campaignsData; } return campaignsData.filter( (client) => (client.status || 'UNKNOWN') === activeStatus, ); }, [activeStatus, campaignsData]); const columns = useMemo( () => [ { accessorKey: 'customer_id', header: 'Google ID', size: 150, }, { accessorKey: 'sql_acc_code', header: 'Customer Code', size: 170, }, { accessorKey: 'name', header: 'Google Account Name', size: 320, }, { accessorKey: 'status', header: 'Status', size: 130, Cell: ({ cell }: any) => { const value = cell.getValue() as string; return {value}; }, }, // { // accessorKey: 'latest_remaining_amount', // header: 'Remaining Amount', // size: 180, // Cell: ({ cell }: any) => { // const amount = parseAmount(cell.getValue()); // return ( // // {currencyFormatter.format(amount)} // // ); // }, // }, { accessorKey: 'latest_start_date', header: 'Latest Start Date', size: 180, Cell: ({ cell }: any) => formatDate(cell.getValue()), }, { accessorKey: 'latest_end_date', header: 'Latest End Date', size: 180, Cell: ({ cell }: any) => formatDate(cell.getValue()), }, { accessorKey: 'latest_remaining_days', header: 'Remaining Days', size: 160, Cell: ({ cell }: any) => cell.getValue() ?? '—', }, { accessorKey: 'industry', header: 'Industry', size: 180, }, { accessorKey: 'assigned_person', header: 'Assigned Person', size: 180, Cell: ({ cell }: any) => cell.getValue() ?? '—', }, { accessorKey: 'sales_person', header: 'Sales Person', size: 180, Cell: ({ cell }: any) => cell.getValue() ?? '—', }, ], [], ); const renderRowActions = ({ row }: { row: MRT_Row }) => { const client = row.original; return ( ); }; const syncGoogleRecords = () => { if (syncing || googleCompanySyncRunning) { return; } setSyncing(true); router.post( route('google-ads.accounts.sync-google-company-details'), {}, { preserveScroll: true, onFinish: () => setSyncing(false), }, ); }; return ( Clients Sync Google account records before linking pending invoices to new clients. ( All ({campaignsData.length}) {statusTabs.map(([status, count]) => ( {status} {count} ))} )} /> ); }