import React, { useMemo } from 'react'; import AppLayout from '../../layouts/app-layout'; import { Container, Title, Group, Button, Badge, ActionIcon, Stack, Text, Tabs, } from '@mantine/core'; import { IconEye, IconRefresh } from '@tabler/icons-react'; import { MantineReactTable } from 'mantine-react-table'; import type { MRT_Row } from 'mantine-react-table'; import { Link, router } from '@inertiajs/react'; import { Client } from "@/types"; 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 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', }, { accessorKey: 'sql_acc_code', header: 'Customer Code', }, { accessorKey: 'name', header: 'Google Account Name', }, { accessorKey: 'status', header: 'Status', Cell: ({ cell }: any) => { const value = cell.getValue() as string; return {value}; }, }, { accessorKey: 'industry', header: 'Industry', }, { accessorKey: 'assigned_person', header: 'Assigned Person', Cell: ({ cell }: any) => cell.getValue() ?? '—', }, { accessorKey: 'sales_person', header: 'Sales Person', 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} ))} )} /> ); }