'use client' import { useTranslations } from 'next-intl' import { Check, ChevronDown } from 'lucide-react' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Checkbox } from '@/components/ui/checkbox' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu' import { HOVER_REVEAL_CLASS, TD_CLASS, TH_CLASS } from '@/components/ui/dry-table' import type { PartyRole, RegisterRow } from '@/lib/parties/register' import { formatCurrency } from '@/lib/utils' import { AccountNub } from './AccountNub' import { isDuplicateCandidate, reasonText, rolesLabel } from './format' /** * The queue in front of Leverantörer and Kunder. Every row states why it is * here and what it becomes; only rows with a hard key arrive pre-ticked; * bulk confirm opens one dialog that says what happens. */ export function SuggestionQueue({ rows, selected, roles, canWrite, busy, onToggle, onSelectAll, onClear, onRoles, onConfirmSelected, onDismiss, onOpen, onFind, }: { rows: RegisterRow[] selected: Set roles: (row: RegisterRow) => PartyRole[] canWrite: boolean busy: boolean onToggle: (id: string) => void onSelectAll: () => void onClear: () => void onRoles: (id: string, roles: PartyRole[]) => void onConfirmSelected: () => void onDismiss: (row: RegisterRow) => void onOpen: (id: string) => void /** Open the SCB picker for a row without an org number; undefined hides the link. */ onFind?: (row: RegisterRow) => void }) { const t = useTranslations('parties') const count = selected.size const allSelected = rows.length > 0 && rows.every((r) => selected.has(r.id)) function toggleRole(row: RegisterRow, role: PartyRole) { const current = roles(row) const next = current.includes(role) ? current.filter((r) => r !== role) : [...current, role] if (next.length === 0) return onRoles(row.id, next) } return (
{t('selected_n', { count })} {t('selected_hint')}
{rows.map((row) => { const checked = selected.has(row.id) const current = roles(row) return ( ) })}
{t('th_name')} {t('th_why')} {t('th_becomes')} {t('th_account')} {t('th_revenue')} {t('th_expense')}
onToggle(row.id)} aria-label={row.displayName} disabled={!canWrite} /> {isDuplicateCandidate(row) ? ( {t('chip_duplicate')} ) : null} {reasonText(t, row.reason, row.stats?.rhythm ?? null, row.orgNumber)} {onFind && !row.orgNumber && row.kind !== 'person' ? ( <> {' · '} ) : null} {(['supplier', 'customer'] as const).map((role) => ( { e.preventDefault(); toggleRole(row, role) }} className="gap-2"> ))} {row.stats?.revenueSek ? formatCurrency(row.stats.revenueSek) : ''} {row.stats?.expenseSek ? formatCurrency(row.stats.expenseSek) : ''}
) }