@open-mercato/core 0.4.6-develop-ce2a0728a5 → 0.4.6-develop-77fa3b7ed8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/AGENTS.md +22 -0
  2. package/dist/modules/customers/backend/customers/companies/page.js +3 -3
  3. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  4. package/dist/modules/customers/backend/customers/deals/page.js +3 -3
  5. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  6. package/dist/modules/customers/backend/customers/people/page.js +3 -3
  7. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  8. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +3 -3
  9. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  10. package/dist/modules/resources/backend/resources/resource-types/page.js +2 -2
  11. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  12. package/dist/modules/resources/backend/resources/resources/page.js +3 -3
  13. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  14. package/dist/modules/sales/backend/sales/channels/page.js +3 -3
  15. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  16. package/dist/modules/sales/components/channels/offerTableUtils.js +3 -2
  17. package/dist/modules/sales/components/channels/offerTableUtils.js.map +2 -2
  18. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +3 -3
  19. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  20. package/dist/modules/staff/backend/staff/leave-requests/page.js +3 -3
  21. package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
  22. package/dist/modules/staff/backend/staff/my-leave-requests/page.js +3 -3
  23. package/dist/modules/staff/backend/staff/my-leave-requests/page.js.map +2 -2
  24. package/dist/modules/staff/backend/staff/team-members/page.js +3 -3
  25. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  26. package/dist/modules/staff/backend/staff/team-roles/page.js +2 -2
  27. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  28. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +3 -3
  29. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  30. package/dist/modules/staff/backend/staff/teams/page.js +2 -2
  31. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  32. package/package.json +2 -2
  33. package/src/modules/customers/backend/customers/companies/page.tsx +3 -3
  34. package/src/modules/customers/backend/customers/deals/page.tsx +3 -3
  35. package/src/modules/customers/backend/customers/people/page.tsx +3 -3
  36. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +3 -4
  37. package/src/modules/resources/backend/resources/resource-types/page.tsx +2 -3
  38. package/src/modules/resources/backend/resources/resources/page.tsx +3 -3
  39. package/src/modules/sales/backend/sales/channels/page.tsx +3 -3
  40. package/src/modules/sales/components/channels/offerTableUtils.tsx +3 -2
  41. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +3 -3
  42. package/src/modules/staff/backend/staff/leave-requests/page.tsx +3 -3
  43. package/src/modules/staff/backend/staff/my-leave-requests/page.tsx +3 -3
  44. package/src/modules/staff/backend/staff/team-members/page.tsx +3 -3
  45. package/src/modules/staff/backend/staff/team-roles/page.tsx +2 -2
  46. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +3 -4
  47. package/src/modules/staff/backend/staff/teams/page.tsx +2 -3
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/customers/backend/customers/deals/page.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation'\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { E } from '#generated/entities.ids.generated'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport {\n DictionaryValue,\n type CustomerDictionaryKind,\n type CustomerDictionaryMap,\n} from '../../../lib/dictionaries'\nimport {\n ensureCustomerDictionary,\n invalidateCustomerDictionary,\n} from '../../../components/detail/hooks/useCustomerDictionary'\nimport {\n useCustomFieldDefs,\n filterCustomFieldDefs,\n} from '@open-mercato/ui/backend/utils/customFieldDefs'\n\ntype DealRow = {\n id: string\n title: string\n status?: string | null\n pipelineStage?: string | null\n pipelineStageId?: string | null\n pipelineId?: string | null\n valueAmount?: number | null\n valueCurrency?: string | null\n probability?: number | null\n expectedCloseAt?: string | null\n updatedAt?: string | null\n companies: { id: string; label: string }[]\n people: { id: string; label: string }[]\n} & Record<string, unknown>\n\ntype DealsResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\ntype FilterOption = { value: string; label: string }\n\ntype DictionaryKey = Extract<CustomerDictionaryKind, 'deal-statuses' | 'pipeline-stages'>\n\ntype PersonLookupRecord = {\n id: string\n name: string | null\n email: string | null\n phone: string | null\n}\n\ntype CompanyLookupRecord = {\n id: string\n name: string | null\n domain: string | null\n email: string | null\n}\n\nfunction parsePersonLookupRecord(item: unknown): PersonLookupRecord | null {\n if (typeof item !== 'object' || item === null) return null\n const record = item as Record<string, unknown>\n const id = typeof record.id === 'string' ? record.id : null\n if (!id || !isUuid(id)) return null\n const name = typeof record.display_name === 'string' ? record.display_name : null\n const email = typeof record.primary_email === 'string' ? record.primary_email : null\n const phone = typeof record.primary_phone === 'string' ? record.primary_phone : null\n return { id, name, email, phone }\n}\n\nfunction parseCompanyLookupRecord(item: unknown): CompanyLookupRecord | null {\n if (typeof item !== 'object' || item === null) return null\n const record = item as Record<string, unknown>\n const id = typeof record.id === 'string' ? record.id : null\n if (!id || !isUuid(id)) return null\n const name = typeof record.display_name === 'string' ? record.display_name : null\n const domain = typeof record.primary_domain === 'string' ? record.primary_domain : null\n const email = typeof record.primary_email === 'string' ? record.primary_email : null\n return { id, name, domain, email }\n}\n\ntype OptionsState = {\n options: FilterOption[]\n idToLabel: Record<string, string>\n labelToId: Record<string, string>\n}\n\nconst EMPTY_OPTIONS_STATE: OptionsState = {\n options: [],\n idToLabel: {},\n labelToId: {},\n}\n\nconst PAGE_SIZE = 20\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n\nfunction isUuid(value: string | null | undefined): value is string {\n if (!value) return false\n return UUID_REGEX.test(value.trim())\n}\n\nfunction normalizeIdCandidates(raw: Array<string>): string[] {\n const set = new Set<string>()\n raw.forEach((candidate) => {\n candidate\n .split(',')\n .map((part) => part.trim())\n .filter((part) => part.length > 0)\n .forEach((part) => {\n if (isUuid(part)) set.add(part)\n })\n })\n return Array.from(set)\n}\n\nfunction extractIdsFromParams(params: URLSearchParams | null | undefined, key: string): string[] {\n if (!params) return []\n const values = params.getAll(key)\n return normalizeIdCandidates(values)\n}\n\nfunction ensureUniqueLabel(base: string, occupied: Set<string>): string {\n const trimmed = base.trim() || 'Unnamed'\n if (!occupied.has(trimmed)) {\n occupied.add(trimmed)\n return trimmed\n }\n let counter = 2\n let candidate = `${trimmed} \u2022 ${counter}`\n while (occupied.has(candidate)) {\n counter += 1\n candidate = `${trimmed} \u2022 ${counter}`\n }\n occupied.add(candidate)\n return candidate\n}\n\nasync function fetchPeopleLookup(query?: string): Promise<PersonLookupRecord[]> {\n const search = new URLSearchParams()\n search.set('page', '1')\n search.set('pageSize', '20')\n if (query && query.trim().length) search.set('search', query.trim())\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/people?${search.toString()}`)\n if (!call.ok) return []\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n return items\n .map((item) => parsePersonLookupRecord(item))\n .filter((record): record is PersonLookupRecord => record !== null)\n } catch {\n return []\n }\n}\n\nasync function fetchPeopleLookupByIds(ids: string[]): Promise<PersonLookupRecord[]> {\n const unique = Array.from(new Set(ids.filter((id) => isUuid(id))))\n if (!unique.length) return []\n const results = await Promise.all(\n unique.map(async (id) => {\n const search = new URLSearchParams()\n search.set('id', id)\n search.set('page', '1')\n search.set('pageSize', '1')\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/people?${search.toString()}`)\n if (!call.ok) return null\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const match = items\n .map((item) => parsePersonLookupRecord(item))\n .find((record) => record?.id === id)\n return match ?? null\n } catch {\n return null\n }\n }),\n )\n return results.filter((record): record is PersonLookupRecord => !!record)\n}\n\nasync function fetchCompaniesLookup(query?: string): Promise<CompanyLookupRecord[]> {\n const search = new URLSearchParams()\n search.set('page', '1')\n search.set('pageSize', '20')\n if (query && query.trim().length) search.set('search', query.trim())\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/companies?${search.toString()}`)\n if (!call.ok) return []\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n return items\n .map((item) => parseCompanyLookupRecord(item))\n .filter((record): record is CompanyLookupRecord => record !== null)\n } catch {\n return []\n }\n}\n\nasync function fetchCompaniesLookupByIds(ids: string[]): Promise<CompanyLookupRecord[]> {\n const unique = Array.from(new Set(ids.filter((id) => isUuid(id))))\n if (!unique.length) return []\n const results = await Promise.all(\n unique.map(async (id) => {\n const search = new URLSearchParams()\n search.set('id', id)\n search.set('page', '1')\n search.set('pageSize', '1')\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/companies?${search.toString()}`)\n if (!call.ok) return null\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const match = items\n .map((item) => parseCompanyLookupRecord(item))\n .find((record) => record?.id === id)\n return match ?? null\n } catch {\n return null\n }\n }),\n )\n return results.filter((record): record is CompanyLookupRecord => !!record)\n}\n\nfunction formatCurrency(amount: number | null | undefined, currency: string | null | undefined, fallback: string): string {\n if (typeof amount !== 'number' || Number.isNaN(amount)) return fallback\n try {\n if (currency && currency.trim().length) {\n const formatter = new Intl.NumberFormat(undefined, { style: 'currency', currency })\n return formatter.format(amount)\n }\n const formatter = new Intl.NumberFormat(undefined, { style: 'decimal', maximumFractionDigits: 2 })\n return formatter.format(amount)\n } catch {\n return currency ? `${amount} ${currency}` : String(amount)\n }\n}\n\nfunction formatDateValue(value: string | null | undefined, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString()\n}\n\nfunction arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) return false\n }\n return true\n}\n\nexport default function CustomersDealsPage() {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const router = useRouter()\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const scopeVersion = useOrganizationScopeVersion()\n const queryClient = useQueryClient()\n\n const [rows, setRows] = React.useState<DealRow[]>([])\n const [page, setPage] = React.useState(() => {\n const raw = Number(searchParams?.get('page') ?? '1')\n return Number.isFinite(raw) && raw > 0 ? raw : 1\n })\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState(() => searchParams?.get('search')?.trim() ?? '')\n const [isLoading, setIsLoading] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [pendingDeleteId, setPendingDeleteId] = React.useState<string | null>(null)\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n\n const initialPersonIds = React.useMemo(\n () => extractIdsFromParams(searchParams, 'personId'),\n [searchParams],\n )\n const initialCompanyIds = React.useMemo(\n () => extractIdsFromParams(searchParams, 'companyId'),\n [searchParams],\n )\n\n const [selectedPersonIds, setSelectedPersonIds] = React.useState<string[]>(initialPersonIds)\n const [selectedCompanyIds, setSelectedCompanyIds] = React.useState<string[]>(initialCompanyIds)\n\n const [peopleState, setPeopleState] = React.useState<OptionsState>(EMPTY_OPTIONS_STATE)\n const [companiesState, setCompaniesState] = React.useState<OptionsState>(EMPTY_OPTIONS_STATE)\n const peopleCacheRef = React.useRef<Map<string, FilterOption[]>>(new Map())\n const companiesCacheRef = React.useRef<Map<string, FilterOption[]>>(new Map())\n\n const buildPersonLabel = React.useCallback((record: PersonLookupRecord): string => {\n const parts: string[] = []\n const name = record.name?.trim()\n if (name) parts.push(name)\n const email = record.email?.trim()\n if (email && !parts.includes(email)) parts.push(email)\n const phone = record.phone?.trim()\n if (!parts.length && phone) parts.push(phone)\n if (!parts.length) parts.push(t('customers.deals.list.unnamedPerson', 'Unnamed person'))\n return parts.join(' \u2022 ')\n }, [t])\n\n const buildCompanyLabel = React.useCallback((record: CompanyLookupRecord): string => {\n const parts: string[] = []\n const name = record.name?.trim()\n if (name) parts.push(name)\n const domain = record.domain?.trim()\n if (domain && !parts.includes(domain)) parts.push(domain)\n const email = record.email?.trim()\n if (!parts.length && email) parts.push(email)\n if (!parts.length) parts.push(t('customers.deals.list.unnamedCompany', 'Unnamed company'))\n return parts.join(' \u2022 ')\n }, [t])\n\n const ingestPeopleRecords = React.useCallback((records: PersonLookupRecord[]) => {\n if (!records.length) return [] as FilterOption[]\n const queryMap = new Map<string, FilterOption>()\n setPeopleState((prev) => {\n const idToLabel = { ...prev.idToLabel }\n const labelToId: Record<string, string> = {}\n const merged = new Map(prev.options.map((opt) => [opt.value, opt]))\n const occupied = new Set<string>()\n Object.entries(prev.labelToId).forEach(([label, id]) => {\n occupied.add(label)\n labelToId[label] = id\n })\n records.forEach((record) => {\n if (!isUuid(record.id)) return\n const base = buildPersonLabel(record)\n let previousLabel = idToLabel[record.id]\n if (previousLabel) {\n // remove previous label before reassigning\n delete labelToId[previousLabel]\n occupied.delete(previousLabel)\n }\n const label = ensureUniqueLabel(base, occupied)\n idToLabel[record.id] = label\n labelToId[label] = record.id\n const option = { value: record.id, label }\n merged.set(record.id, option)\n queryMap.set(record.id, option)\n })\n const nextOptions = Array.from(merged.values()).sort((a, b) => a.label.localeCompare(b.label))\n return { options: nextOptions, idToLabel, labelToId }\n })\n return Array.from(queryMap.values()).sort((a, b) => a.label.localeCompare(b.label))\n }, [buildPersonLabel])\n\n const ingestCompanyRecords = React.useCallback((records: CompanyLookupRecord[]) => {\n if (!records.length) return [] as FilterOption[]\n const queryMap = new Map<string, FilterOption>()\n setCompaniesState((prev) => {\n const idToLabel = { ...prev.idToLabel }\n const labelToId: Record<string, string> = {}\n const merged = new Map(prev.options.map((opt) => [opt.value, opt]))\n const occupied = new Set<string>()\n Object.entries(prev.labelToId).forEach(([label, id]) => {\n occupied.add(label)\n labelToId[label] = id\n })\n records.forEach((record) => {\n if (!isUuid(record.id)) return\n const base = buildCompanyLabel(record)\n let previousLabel = idToLabel[record.id]\n if (previousLabel) {\n delete labelToId[previousLabel]\n occupied.delete(previousLabel)\n }\n const label = ensureUniqueLabel(base, occupied)\n idToLabel[record.id] = label\n labelToId[label] = record.id\n const option = { value: record.id, label }\n merged.set(record.id, option)\n queryMap.set(record.id, option)\n })\n const nextOptions = Array.from(merged.values()).sort((a, b) => a.label.localeCompare(b.label))\n return { options: nextOptions, idToLabel, labelToId }\n })\n return Array.from(queryMap.values()).sort((a, b) => a.label.localeCompare(b.label))\n }, [buildCompanyLabel])\n\n const loadPeopleOptions = React.useCallback(async (query?: string) => {\n const normalizedQuery = (query || '').trim().toLowerCase()\n const cacheKey = `${scopeVersion}|${normalizedQuery}`\n const cached = peopleCacheRef.current.get(cacheKey)\n if (cached) return cached\n const records = await fetchPeopleLookup(query)\n const options = ingestPeopleRecords(records)\n peopleCacheRef.current.set(cacheKey, options)\n return options\n }, [scopeVersion, ingestPeopleRecords])\n\n const loadCompanyOptions = React.useCallback(async (query?: string) => {\n const normalizedQuery = (query || '').trim().toLowerCase()\n const cacheKey = `${scopeVersion}|${normalizedQuery}`\n const cached = companiesCacheRef.current.get(cacheKey)\n if (cached) return cached\n const records = await fetchCompaniesLookup(query)\n const options = ingestCompanyRecords(records)\n companiesCacheRef.current.set(cacheKey, options)\n return options\n }, [scopeVersion, ingestCompanyRecords])\n\n React.useEffect(() => {\n let cancelled = false\n if (!selectedPersonIds.length) return\n const missing = selectedPersonIds.filter((id) => !peopleState.idToLabel[id])\n if (!missing.length) return\n fetchPeopleLookupByIds(missing).then((records) => {\n if (cancelled) return\n ingestPeopleRecords(records)\n })\n return () => { cancelled = true }\n }, [selectedPersonIds, peopleState.idToLabel, ingestPeopleRecords])\n\n React.useEffect(() => {\n let cancelled = false\n if (!selectedCompanyIds.length) return\n const missing = selectedCompanyIds.filter((id) => !companiesState.idToLabel[id])\n if (!missing.length) return\n fetchCompaniesLookupByIds(missing).then((records) => {\n if (cancelled) return\n ingestCompanyRecords(records)\n })\n return () => { cancelled = true }\n }, [selectedCompanyIds, companiesState.idToLabel, ingestCompanyRecords])\n\n const [dictionaryMaps, setDictionaryMaps] = React.useState<Record<DictionaryKey, CustomerDictionaryMap>>({\n 'deal-statuses': {},\n 'pipeline-stages': {},\n })\n\n const [pipelineNames, setPipelineNames] = React.useState<Record<string, string>>({})\n\n const fetchDictionaryEntries = React.useCallback(\n async (kind: DictionaryKey) => {\n try {\n const data = await ensureCustomerDictionary(queryClient, kind, scopeVersion)\n setDictionaryMaps((prev) => ({ ...prev, [kind]: data.map }))\n } catch {\n setDictionaryMaps((prev) => ({ ...prev, [kind]: {} }))\n }\n },\n [queryClient, scopeVersion],\n )\n\n React.useEffect(() => {\n let cancelled = false\n async function loadDictionaries() {\n if (cancelled) return\n await Promise.all([fetchDictionaryEntries('deal-statuses'), fetchDictionaryEntries('pipeline-stages')])\n }\n loadDictionaries().catch(() => {})\n return () => { cancelled = true }\n }, [fetchDictionaryEntries, reloadToken])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadPipelines() {\n try {\n const call = await apiCall<{ items?: Array<{ id: string; name: string }> }>('/api/customers/pipelines')\n if (cancelled || !call.ok) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const map: Record<string, string> = {}\n items.forEach((p) => { if (p.id && p.name) map[p.id] = p.name })\n setPipelineNames(map)\n } catch {}\n }\n loadPipelines().catch(() => {})\n return () => { cancelled = true }\n }, [reloadToken, scopeVersion])\n\n React.useEffect(() => {\n peopleCacheRef.current.clear()\n companiesCacheRef.current.clear()\n setPeopleState((prev) => {\n if (!prev.options.length && !Object.keys(prev.idToLabel).length) return prev\n return { ...EMPTY_OPTIONS_STATE }\n })\n setCompaniesState((prev) => {\n if (!prev.options.length && !Object.keys(prev.idToLabel).length) return prev\n return { ...EMPTY_OPTIONS_STATE }\n })\n }, [scopeVersion, reloadToken])\n\n const syncFilterLabels = React.useCallback((\n key: 'people' | 'companies',\n ids: string[],\n idToLabel: Record<string, string>,\n ) => {\n setFilterValues((prev) => {\n const current = Array.isArray(prev[key]) ? (prev[key] as string[]) : []\n if (!ids.length) {\n if (!current.length) return prev\n const next = { ...prev }\n delete next[key]\n return next\n }\n const labels: string[] = []\n ids.forEach((id) => {\n const label = idToLabel[id]\n if (label && !labels.includes(label)) labels.push(label)\n })\n if (labels.length < ids.length) return prev\n if (arraysEqual(current, labels)) return prev\n return { ...prev, [key]: labels }\n })\n }, [])\n\n React.useEffect(() => {\n syncFilterLabels('people', selectedPersonIds, peopleState.idToLabel)\n }, [selectedPersonIds, peopleState.idToLabel, syncFilterLabels])\n\n React.useEffect(() => {\n syncFilterLabels('companies', selectedCompanyIds, companiesState.idToLabel)\n }, [selectedCompanyIds, companiesState.idToLabel, syncFilterLabels])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value.trim())\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = { ...values }\n const rawPeople = Array.isArray(values.people) ? (values.people as string[]) : []\n const nextPersonIds: string[] = []\n rawPeople.forEach((value) => {\n const trimmed = typeof value === 'string' ? value.trim() : ''\n if (!trimmed) return\n const mapped = peopleState.labelToId[trimmed]\n if (mapped && !nextPersonIds.includes(mapped)) nextPersonIds.push(mapped)\n })\n setSelectedPersonIds(nextPersonIds)\n if (nextPersonIds.length) {\n next.people = Array.from(new Set(rawPeople.map((value) => (typeof value === 'string' ? value.trim() : '')).filter((value) => value.length > 0)))\n } else {\n delete next.people\n }\n\n const rawCompanies = Array.isArray(values.companies) ? (values.companies as string[]) : []\n const nextCompanyIds: string[] = []\n rawCompanies.forEach((value) => {\n const trimmed = typeof value === 'string' ? value.trim() : ''\n if (!trimmed) return\n const mapped = companiesState.labelToId[trimmed]\n if (mapped && !nextCompanyIds.includes(mapped)) nextCompanyIds.push(mapped)\n })\n setSelectedCompanyIds(nextCompanyIds)\n if (nextCompanyIds.length) {\n next.companies = Array.from(new Set(rawCompanies.map((value) => (typeof value === 'string' ? value.trim() : '')).filter((value) => value.length > 0)))\n } else {\n delete next.companies\n }\n\n setFilterValues(next)\n setPage(1)\n }, [peopleState.labelToId, companiesState.labelToId])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setSelectedPersonIds([])\n setSelectedCompanyIds([])\n setPage(1)\n }, [])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(PAGE_SIZE))\n if (search.trim().length) params.set('search', search.trim())\n if (selectedPersonIds.length) params.set('personId', selectedPersonIds.join(','))\n if (selectedCompanyIds.length) params.set('companyId', selectedCompanyIds.join(','))\n Object.entries(filterValues).forEach(([key, value]) => {\n if (key === 'people' || key === 'companies') return\n if (value == null) return\n if (Array.isArray(value)) {\n const normalized = value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item.trim()\n return String(item).trim()\n })\n .filter((item) => item.length > 0)\n if (normalized.length) params.set(key, normalized.join(','))\n } else if (typeof value === 'object') {\n const obj = value as Record<string, unknown>\n const from = typeof obj.from === 'string' ? obj.from.trim() : ''\n const to = typeof obj.to === 'string' ? obj.to.trim() : ''\n if (from) params.set(`${key}[from]`, from)\n if (to) params.set(`${key}[to]`, to)\n } else {\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (stringValue) params.set(key, stringValue)\n }\n })\n return params.toString()\n }, [filterValues, page, search, selectedCompanyIds, selectedPersonIds])\n\n const currentParams = React.useMemo(\n () => Object.fromEntries(new URLSearchParams(queryParams)),\n [queryParams],\n )\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/deals', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/deals', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const fallback: DealsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<DealsResponse>(`/api/customers/deals?${queryParams}`, undefined, { fallback })\n if (!call.ok) {\n const message =\n typeof (call.result as { error?: string } | undefined)?.error === 'string'\n ? (call.result as { error?: string }).error!\n : t('customers.deals.list.error.load')\n flash(message, 'error')\n if (!cancelled) setCacheStatus(null)\n return\n }\n const payload = call.result ?? fallback\n if (cancelled) return\n setCacheStatus(call.cacheStatus ?? null)\n const items = Array.isArray(payload.items) ? payload.items : []\n const mapped = items\n .map((item) => mapDeal(item as Record<string, unknown>))\n .filter((row): row is DealRow => !!row)\n setRows(mapped)\n setTotal(typeof payload.total === 'number' ? payload.total : mapped.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n } catch (err) {\n if (!cancelled) {\n setCacheStatus(null)\n const message = err instanceof Error ? err.message : t('customers.deals.list.error.load')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n React.useEffect(() => {\n if (totalPages > 0 && page > totalPages) {\n setPage(totalPages)\n }\n }, [page, totalPages])\n\n const queryRef = React.useRef(searchParams?.toString() ?? '')\n React.useEffect(() => {\n if (!pathname) return\n const params = new URLSearchParams()\n if (search.trim().length) params.set('search', search.trim())\n if (selectedPersonIds.length) selectedPersonIds.forEach((id) => params.append('personId', id))\n if (selectedCompanyIds.length) selectedCompanyIds.forEach((id) => params.append('companyId', id))\n if (page > 1) params.set('page', String(page))\n const next = params.toString()\n if (queryRef.current === next) return\n queryRef.current = next\n router.replace(next ? `${pathname}?${next}` : pathname, { scroll: false })\n }, [pathname, router, page, search, selectedPersonIds, selectedCompanyIds])\n\n const handleRefresh = React.useCallback(() => {\n peopleCacheRef.current.clear()\n companiesCacheRef.current.clear()\n void Promise.all([\n invalidateCustomerDictionary(queryClient, 'deal-statuses'),\n invalidateCustomerDictionary(queryClient, 'pipeline-stages'),\n ])\n setReloadToken((token) => token + 1)\n }, [queryClient])\n\n const handleDeleteDeal = React.useCallback(\n async (dealId: string) => {\n if (pendingDeleteId) return\n const confirmed = await confirm({\n title: t(\n 'customers.deals.list.deleteConfirm',\n 'Delete this deal? This action cannot be undone.',\n ),\n variant: 'destructive',\n })\n if (!confirmed) return\n setPendingDeleteId(dealId)\n try {\n await deleteCrud('customers/deals', {\n body: { id: dealId },\n errorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),\n })\n flash(t('customers.deals.list.deleteSuccess', 'Deal deleted.'), 'success')\n setRows((prev) => prev.filter((row) => row.id !== dealId))\n setTotal((prev) => Math.max(0, prev - 1))\n handleRefresh()\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.list.deleteError', 'Failed to delete deal.')\n flash(message, 'error')\n } finally {\n setPendingDeleteId(null)\n }\n },\n [confirm, handleRefresh, pendingDeleteId, t],\n )\n\n const personOptions = peopleState.options\n const companyOptions = companiesState.options\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'people',\n label: t('customers.deals.list.filters.people'),\n type: 'tags',\n options: personOptions,\n loadOptions: loadPeopleOptions,\n placeholder: t('customers.deals.list.filters.peoplePlaceholder'),\n },\n {\n id: 'companies',\n label: t('customers.deals.list.filters.companies'),\n type: 'tags',\n options: companyOptions,\n loadOptions: loadCompanyOptions,\n placeholder: t('customers.deals.list.filters.companiesPlaceholder'),\n },\n ], [companyOptions, loadCompanyOptions, loadPeopleOptions, personOptions, t])\n\n const { data: customFieldDefs = [] } = useCustomFieldDefs([E.customers.customer_deal], {\n keyExtras: [scopeVersion, reloadToken],\n })\n\n const columns = React.useMemo<ColumnDef<DealRow>[]>(() => {\n const noValue = <span className=\"text-muted-foreground text-sm\">{t('customers.deals.list.noValue')}</span>\n const renderDictionaryCell = (kind: DictionaryKey, value: string | null | undefined) => (\n <DictionaryValue\n value={value}\n map={dictionaryMaps[kind]}\n fallback={value ? <span className=\"text-sm\">{value}</span> : noValue}\n className=\"text-sm\"\n iconWrapperClassName=\"inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\"\n iconClassName=\"h-4 w-4\"\n colorClassName=\"h-3 w-3 rounded-full\"\n />\n )\n const renderAssociationList = (\n items: { id: string; label: string }[],\n fallbackLabel: string,\n ) => {\n if (!items.length) return noValue\n return (\n <ul className=\"flex flex-wrap gap-1 text-sm\">\n {items.map((entry) => (\n <li key={entry.id} className=\"rounded border px-2 py-0.5 text-xs bg-muted\">\n {entry.label && entry.label.trim().length ? entry.label : fallbackLabel}\n </li>\n ))}\n </ul>\n )\n }\n\n const customColumns = filterCustomFieldDefs(customFieldDefs, 'list').map<ColumnDef<DealRow>>((def) => ({\n accessorKey: `cf_${def.key}`,\n header: def.label || def.key,\n cell: ({ getValue }) => {\n const value = getValue()\n if (value == null) return noValue\n if (Array.isArray(value)) {\n const normalized = value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item.trim()\n return String(item).trim()\n })\n .filter((item) => item.length > 0)\n if (!normalized.length) return noValue\n return <span className=\"text-sm\">{normalized.join(', ')}</span>\n }\n if (typeof value === 'boolean') {\n return (\n <span className=\"text-sm\">\n {value\n ? t('customers.deals.list.booleanYes', 'Yes')\n : t('customers.deals.list.booleanNo', 'No')}\n </span>\n )\n }\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (!stringValue) return noValue\n return <span className=\"text-sm\">{stringValue}</span>\n },\n }))\n\n return [\n {\n accessorKey: 'title',\n header: t('customers.deals.list.columns.title'),\n cell: ({ row }) => <span className=\"font-medium text-sm\">{row.original.title}</span>,\n },\n {\n accessorKey: 'status',\n header: t('customers.deals.list.columns.status'),\n cell: ({ row }) => renderDictionaryCell('deal-statuses', row.original.status),\n },\n {\n accessorKey: 'pipelineStage',\n header: t('customers.deals.list.columns.pipelineStage'),\n cell: ({ row }) => renderDictionaryCell('pipeline-stages', row.original.pipelineStage),\n },\n {\n accessorKey: 'pipelineId',\n header: t('customers.deals.list.columns.pipeline', 'Pipeline'),\n cell: ({ row }) => {\n const name = row.original.pipelineId ? pipelineNames[row.original.pipelineId] : null\n return name ? <span className=\"text-sm\">{name}</span> : noValue\n },\n },\n {\n accessorKey: 'valueAmount',\n header: t('customers.deals.list.columns.value'),\n cell: ({ row }) => (\n <span className=\"text-sm font-medium\">\n {formatCurrency(row.original.valueAmount ?? null, row.original.valueCurrency ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n {\n accessorKey: 'probability',\n header: t('customers.deals.list.columns.probability'),\n cell: ({ row }) => {\n const value = row.original.probability\n if (typeof value === 'number' && Number.isFinite(value)) {\n return <span className=\"text-sm\">{`${Math.min(Math.max(value, 0), 100)}%`}</span>\n }\n return noValue\n },\n },\n {\n accessorKey: 'expectedCloseAt',\n header: t('customers.deals.list.columns.expectedClose'),\n cell: ({ row }) => (\n <span className=\"text-sm\">\n {formatDateValue(row.original.expectedCloseAt ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n {\n accessorKey: 'companies',\n header: t('customers.deals.list.columns.companies'),\n cell: ({ row }) => renderAssociationList(row.original.companies, t('customers.deals.list.unnamedCompany')),\n },\n {\n accessorKey: 'people',\n header: t('customers.deals.list.columns.people'),\n cell: ({ row }) => renderAssociationList(row.original.people, t('customers.deals.list.unnamedPerson')),\n },\n {\n accessorKey: 'updatedAt',\n header: t('customers.deals.list.columns.updatedAt'),\n cell: ({ row }) => (\n <span className=\"text-sm\">\n {formatDateValue(row.original.updatedAt ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n ...customColumns,\n ]\n }, [customFieldDefs, dictionaryMaps, pipelineNames, t])\n\n return (\n <Page>\n <PageBody>\n <DataTable<DealRow>\n title={t('customers.deals.list.title')}\n actions={(\n <Button asChild>\n <Link href=\"/backend/customers/deals/create\">\n {t('customers.deals.list.actions.new', 'New deal')}\n </Link>\n </Button>\n )}\n columns={columns}\n data={rows}\n onRowClick={(row) => {\n router.push(`/backend/customers/deals/${row.id}`)\n }}\n rowActions={(row) => {\n const isDeleting = pendingDeleteId === row.id\n return (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('customers.deals.list.actions.edit', 'Edit'),\n onSelect: () => { router.push(`/backend/customers/deals/${row.id}`) },\n },\n {\n id: 'open-new-tab',\n label: t('customers.deals.list.actions.openInNewTab', 'Open in new tab'),\n onSelect: () => {\n if (typeof window !== 'undefined') {\n window.open(`/backend/customers/deals/${row.id}`, '_blank', 'noopener')\n }\n },\n },\n {\n id: 'delete',\n label: isDeleting\n ? t('customers.deals.list.actions.deleting', 'Deleting\u2026')\n : t('customers.deals.list.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => handleDeleteDeal(row.id),\n },\n ]}\n />\n )\n }}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('customers.deals.list.searchPlaceholder')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: (nextPage) => setPage(nextPage),\n cacheStatus,\n }}\n isLoading={isLoading}\n refreshButton={{\n label: t('customers.deals.list.refresh'),\n onRefresh: handleRefresh,\n }}\n exporter={exportConfig}\n entityId={E.customers.customer_deal}\n perspective={{ tableId: 'customers.deals.list' }}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n\nfunction mapDeal(item: Record<string, unknown>): DealRow | null {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const title = typeof item.title === 'string' ? item.title : ''\n const status = typeof item.status === 'string' ? item.status : null\n const pipelineStage = typeof item.pipeline_stage === 'string' ? item.pipeline_stage : null\n const pipelineStageId = typeof item.pipeline_stage_id === 'string' ? item.pipeline_stage_id : null\n const pipelineId = typeof item.pipeline_id === 'string' ? item.pipeline_id : null\n const valueAmountRaw = item.value_amount\n const valueAmount =\n typeof valueAmountRaw === 'number'\n ? valueAmountRaw\n : typeof valueAmountRaw === 'string' && valueAmountRaw.trim()\n ? Number(valueAmountRaw)\n : null\n const valueCurrency =\n typeof item.value_currency === 'string' && item.value_currency.trim().length\n ? item.value_currency.trim().toUpperCase()\n : null\n const probabilityRaw = item.probability\n const probability =\n typeof probabilityRaw === 'number'\n ? probabilityRaw\n : typeof probabilityRaw === 'string' && probabilityRaw.trim().length\n ? Number(probabilityRaw)\n : null\n const expectedCloseAt = typeof item.expected_close_at === 'string' ? item.expected_close_at : null\n const updatedAt = typeof item.updated_at === 'string' ? item.updated_at : null\n const peopleRaw = Array.isArray(item.people) ? item.people : []\n const companiesRaw = Array.isArray(item.companies) ? item.companies : []\n const people = peopleRaw\n .map((entry) => {\n if (!entry || typeof entry !== 'object') return null\n const data = entry as Record<string, unknown>\n const pid = typeof data.id === 'string' ? data.id : null\n if (!pid) return null\n const label = typeof data.label === 'string' ? data.label : ''\n return { id: pid, label }\n })\n .filter((entry): entry is { id: string; label: string } => !!entry)\n const companies = companiesRaw\n .map((entry) => {\n if (!entry || typeof entry !== 'object') return null\n const data = entry as Record<string, unknown>\n const cid = typeof data.id === 'string' ? data.id : null\n if (!cid) return null\n const label = typeof data.label === 'string' ? data.label : ''\n return { id: cid, label }\n })\n .filter((entry): entry is { id: string; label: string } => !!entry)\n const customFields: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(item)) {\n if (key.startsWith('cf_')) customFields[key] = value\n }\n return {\n id,\n title,\n status,\n pipelineStage,\n pipelineStageId,\n pipelineId,\n valueAmount,\n valueCurrency,\n probability,\n expectedCloseAt,\n updatedAt,\n people,\n companies,\n ...customFields,\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation'\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type DataTableExportFormat, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { E } from '#generated/entities.ids.generated'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport {\n DictionaryValue,\n type CustomerDictionaryKind,\n type CustomerDictionaryMap,\n} from '../../../lib/dictionaries'\nimport {\n ensureCustomerDictionary,\n invalidateCustomerDictionary,\n} from '../../../components/detail/hooks/useCustomerDictionary'\nimport {\n useCustomFieldDefs,\n filterCustomFieldDefs,\n} from '@open-mercato/ui/backend/utils/customFieldDefs'\n\ntype DealRow = {\n id: string\n title: string\n status?: string | null\n pipelineStage?: string | null\n pipelineStageId?: string | null\n pipelineId?: string | null\n valueAmount?: number | null\n valueCurrency?: string | null\n probability?: number | null\n expectedCloseAt?: string | null\n updatedAt?: string | null\n companies: { id: string; label: string }[]\n people: { id: string; label: string }[]\n} & Record<string, unknown>\n\ntype DealsResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\ntype FilterOption = { value: string; label: string }\n\ntype DictionaryKey = Extract<CustomerDictionaryKind, 'deal-statuses' | 'pipeline-stages'>\n\ntype PersonLookupRecord = {\n id: string\n name: string | null\n email: string | null\n phone: string | null\n}\n\ntype CompanyLookupRecord = {\n id: string\n name: string | null\n domain: string | null\n email: string | null\n}\n\nfunction parsePersonLookupRecord(item: unknown): PersonLookupRecord | null {\n if (typeof item !== 'object' || item === null) return null\n const record = item as Record<string, unknown>\n const id = typeof record.id === 'string' ? record.id : null\n if (!id || !isUuid(id)) return null\n const name = typeof record.display_name === 'string' ? record.display_name : null\n const email = typeof record.primary_email === 'string' ? record.primary_email : null\n const phone = typeof record.primary_phone === 'string' ? record.primary_phone : null\n return { id, name, email, phone }\n}\n\nfunction parseCompanyLookupRecord(item: unknown): CompanyLookupRecord | null {\n if (typeof item !== 'object' || item === null) return null\n const record = item as Record<string, unknown>\n const id = typeof record.id === 'string' ? record.id : null\n if (!id || !isUuid(id)) return null\n const name = typeof record.display_name === 'string' ? record.display_name : null\n const domain = typeof record.primary_domain === 'string' ? record.primary_domain : null\n const email = typeof record.primary_email === 'string' ? record.primary_email : null\n return { id, name, domain, email }\n}\n\ntype OptionsState = {\n options: FilterOption[]\n idToLabel: Record<string, string>\n labelToId: Record<string, string>\n}\n\nconst EMPTY_OPTIONS_STATE: OptionsState = {\n options: [],\n idToLabel: {},\n labelToId: {},\n}\n\nconst PAGE_SIZE = 20\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n\nfunction isUuid(value: string | null | undefined): value is string {\n if (!value) return false\n return UUID_REGEX.test(value.trim())\n}\n\nfunction normalizeIdCandidates(raw: Array<string>): string[] {\n const set = new Set<string>()\n raw.forEach((candidate) => {\n candidate\n .split(',')\n .map((part) => part.trim())\n .filter((part) => part.length > 0)\n .forEach((part) => {\n if (isUuid(part)) set.add(part)\n })\n })\n return Array.from(set)\n}\n\nfunction extractIdsFromParams(params: URLSearchParams | null | undefined, key: string): string[] {\n if (!params) return []\n const values = params.getAll(key)\n return normalizeIdCandidates(values)\n}\n\nfunction ensureUniqueLabel(base: string, occupied: Set<string>): string {\n const trimmed = base.trim() || 'Unnamed'\n if (!occupied.has(trimmed)) {\n occupied.add(trimmed)\n return trimmed\n }\n let counter = 2\n let candidate = `${trimmed} \u2022 ${counter}`\n while (occupied.has(candidate)) {\n counter += 1\n candidate = `${trimmed} \u2022 ${counter}`\n }\n occupied.add(candidate)\n return candidate\n}\n\nasync function fetchPeopleLookup(query?: string): Promise<PersonLookupRecord[]> {\n const search = new URLSearchParams()\n search.set('page', '1')\n search.set('pageSize', '20')\n if (query && query.trim().length) search.set('search', query.trim())\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/people?${search.toString()}`)\n if (!call.ok) return []\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n return items\n .map((item) => parsePersonLookupRecord(item))\n .filter((record): record is PersonLookupRecord => record !== null)\n } catch {\n return []\n }\n}\n\nasync function fetchPeopleLookupByIds(ids: string[]): Promise<PersonLookupRecord[]> {\n const unique = Array.from(new Set(ids.filter((id) => isUuid(id))))\n if (!unique.length) return []\n const results = await Promise.all(\n unique.map(async (id) => {\n const search = new URLSearchParams()\n search.set('id', id)\n search.set('page', '1')\n search.set('pageSize', '1')\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/people?${search.toString()}`)\n if (!call.ok) return null\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const match = items\n .map((item) => parsePersonLookupRecord(item))\n .find((record) => record?.id === id)\n return match ?? null\n } catch {\n return null\n }\n }),\n )\n return results.filter((record): record is PersonLookupRecord => !!record)\n}\n\nasync function fetchCompaniesLookup(query?: string): Promise<CompanyLookupRecord[]> {\n const search = new URLSearchParams()\n search.set('page', '1')\n search.set('pageSize', '20')\n if (query && query.trim().length) search.set('search', query.trim())\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/companies?${search.toString()}`)\n if (!call.ok) return []\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n return items\n .map((item) => parseCompanyLookupRecord(item))\n .filter((record): record is CompanyLookupRecord => record !== null)\n } catch {\n return []\n }\n}\n\nasync function fetchCompaniesLookupByIds(ids: string[]): Promise<CompanyLookupRecord[]> {\n const unique = Array.from(new Set(ids.filter((id) => isUuid(id))))\n if (!unique.length) return []\n const results = await Promise.all(\n unique.map(async (id) => {\n const search = new URLSearchParams()\n search.set('id', id)\n search.set('page', '1')\n search.set('pageSize', '1')\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/companies?${search.toString()}`)\n if (!call.ok) return null\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const match = items\n .map((item) => parseCompanyLookupRecord(item))\n .find((record) => record?.id === id)\n return match ?? null\n } catch {\n return null\n }\n }),\n )\n return results.filter((record): record is CompanyLookupRecord => !!record)\n}\n\nfunction formatCurrency(amount: number | null | undefined, currency: string | null | undefined, fallback: string): string {\n if (typeof amount !== 'number' || Number.isNaN(amount)) return fallback\n try {\n if (currency && currency.trim().length) {\n const formatter = new Intl.NumberFormat(undefined, { style: 'currency', currency })\n return formatter.format(amount)\n }\n const formatter = new Intl.NumberFormat(undefined, { style: 'decimal', maximumFractionDigits: 2 })\n return formatter.format(amount)\n } catch {\n return currency ? `${amount} ${currency}` : String(amount)\n }\n}\n\nfunction formatDateValue(value: string | null | undefined, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString()\n}\n\nfunction arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) return false\n }\n return true\n}\n\nexport default function CustomersDealsPage() {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const router = useRouter()\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const scopeVersion = useOrganizationScopeVersion()\n const queryClient = useQueryClient()\n\n const [rows, setRows] = React.useState<DealRow[]>([])\n const [page, setPage] = React.useState(() => {\n const raw = Number(searchParams?.get('page') ?? '1')\n return Number.isFinite(raw) && raw > 0 ? raw : 1\n })\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState(() => searchParams?.get('search')?.trim() ?? '')\n const [isLoading, setIsLoading] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [pendingDeleteId, setPendingDeleteId] = React.useState<string | null>(null)\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n\n const initialPersonIds = React.useMemo(\n () => extractIdsFromParams(searchParams, 'personId'),\n [searchParams],\n )\n const initialCompanyIds = React.useMemo(\n () => extractIdsFromParams(searchParams, 'companyId'),\n [searchParams],\n )\n\n const [selectedPersonIds, setSelectedPersonIds] = React.useState<string[]>(initialPersonIds)\n const [selectedCompanyIds, setSelectedCompanyIds] = React.useState<string[]>(initialCompanyIds)\n\n const [peopleState, setPeopleState] = React.useState<OptionsState>(EMPTY_OPTIONS_STATE)\n const [companiesState, setCompaniesState] = React.useState<OptionsState>(EMPTY_OPTIONS_STATE)\n const peopleCacheRef = React.useRef<Map<string, FilterOption[]>>(new Map())\n const companiesCacheRef = React.useRef<Map<string, FilterOption[]>>(new Map())\n\n const buildPersonLabel = React.useCallback((record: PersonLookupRecord): string => {\n const parts: string[] = []\n const name = record.name?.trim()\n if (name) parts.push(name)\n const email = record.email?.trim()\n if (email && !parts.includes(email)) parts.push(email)\n const phone = record.phone?.trim()\n if (!parts.length && phone) parts.push(phone)\n if (!parts.length) parts.push(t('customers.deals.list.unnamedPerson', 'Unnamed person'))\n return parts.join(' \u2022 ')\n }, [t])\n\n const buildCompanyLabel = React.useCallback((record: CompanyLookupRecord): string => {\n const parts: string[] = []\n const name = record.name?.trim()\n if (name) parts.push(name)\n const domain = record.domain?.trim()\n if (domain && !parts.includes(domain)) parts.push(domain)\n const email = record.email?.trim()\n if (!parts.length && email) parts.push(email)\n if (!parts.length) parts.push(t('customers.deals.list.unnamedCompany', 'Unnamed company'))\n return parts.join(' \u2022 ')\n }, [t])\n\n const ingestPeopleRecords = React.useCallback((records: PersonLookupRecord[]) => {\n if (!records.length) return [] as FilterOption[]\n const queryMap = new Map<string, FilterOption>()\n setPeopleState((prev) => {\n const idToLabel = { ...prev.idToLabel }\n const labelToId: Record<string, string> = {}\n const merged = new Map(prev.options.map((opt) => [opt.value, opt]))\n const occupied = new Set<string>()\n Object.entries(prev.labelToId).forEach(([label, id]) => {\n occupied.add(label)\n labelToId[label] = id\n })\n records.forEach((record) => {\n if (!isUuid(record.id)) return\n const base = buildPersonLabel(record)\n let previousLabel = idToLabel[record.id]\n if (previousLabel) {\n // remove previous label before reassigning\n delete labelToId[previousLabel]\n occupied.delete(previousLabel)\n }\n const label = ensureUniqueLabel(base, occupied)\n idToLabel[record.id] = label\n labelToId[label] = record.id\n const option = { value: record.id, label }\n merged.set(record.id, option)\n queryMap.set(record.id, option)\n })\n const nextOptions = Array.from(merged.values()).sort((a, b) => a.label.localeCompare(b.label))\n return { options: nextOptions, idToLabel, labelToId }\n })\n return Array.from(queryMap.values()).sort((a, b) => a.label.localeCompare(b.label))\n }, [buildPersonLabel])\n\n const ingestCompanyRecords = React.useCallback((records: CompanyLookupRecord[]) => {\n if (!records.length) return [] as FilterOption[]\n const queryMap = new Map<string, FilterOption>()\n setCompaniesState((prev) => {\n const idToLabel = { ...prev.idToLabel }\n const labelToId: Record<string, string> = {}\n const merged = new Map(prev.options.map((opt) => [opt.value, opt]))\n const occupied = new Set<string>()\n Object.entries(prev.labelToId).forEach(([label, id]) => {\n occupied.add(label)\n labelToId[label] = id\n })\n records.forEach((record) => {\n if (!isUuid(record.id)) return\n const base = buildCompanyLabel(record)\n let previousLabel = idToLabel[record.id]\n if (previousLabel) {\n delete labelToId[previousLabel]\n occupied.delete(previousLabel)\n }\n const label = ensureUniqueLabel(base, occupied)\n idToLabel[record.id] = label\n labelToId[label] = record.id\n const option = { value: record.id, label }\n merged.set(record.id, option)\n queryMap.set(record.id, option)\n })\n const nextOptions = Array.from(merged.values()).sort((a, b) => a.label.localeCompare(b.label))\n return { options: nextOptions, idToLabel, labelToId }\n })\n return Array.from(queryMap.values()).sort((a, b) => a.label.localeCompare(b.label))\n }, [buildCompanyLabel])\n\n const loadPeopleOptions = React.useCallback(async (query?: string) => {\n const normalizedQuery = (query || '').trim().toLowerCase()\n const cacheKey = `${scopeVersion}|${normalizedQuery}`\n const cached = peopleCacheRef.current.get(cacheKey)\n if (cached) return cached\n const records = await fetchPeopleLookup(query)\n const options = ingestPeopleRecords(records)\n peopleCacheRef.current.set(cacheKey, options)\n return options\n }, [scopeVersion, ingestPeopleRecords])\n\n const loadCompanyOptions = React.useCallback(async (query?: string) => {\n const normalizedQuery = (query || '').trim().toLowerCase()\n const cacheKey = `${scopeVersion}|${normalizedQuery}`\n const cached = companiesCacheRef.current.get(cacheKey)\n if (cached) return cached\n const records = await fetchCompaniesLookup(query)\n const options = ingestCompanyRecords(records)\n companiesCacheRef.current.set(cacheKey, options)\n return options\n }, [scopeVersion, ingestCompanyRecords])\n\n React.useEffect(() => {\n let cancelled = false\n if (!selectedPersonIds.length) return\n const missing = selectedPersonIds.filter((id) => !peopleState.idToLabel[id])\n if (!missing.length) return\n fetchPeopleLookupByIds(missing).then((records) => {\n if (cancelled) return\n ingestPeopleRecords(records)\n })\n return () => { cancelled = true }\n }, [selectedPersonIds, peopleState.idToLabel, ingestPeopleRecords])\n\n React.useEffect(() => {\n let cancelled = false\n if (!selectedCompanyIds.length) return\n const missing = selectedCompanyIds.filter((id) => !companiesState.idToLabel[id])\n if (!missing.length) return\n fetchCompaniesLookupByIds(missing).then((records) => {\n if (cancelled) return\n ingestCompanyRecords(records)\n })\n return () => { cancelled = true }\n }, [selectedCompanyIds, companiesState.idToLabel, ingestCompanyRecords])\n\n const [dictionaryMaps, setDictionaryMaps] = React.useState<Record<DictionaryKey, CustomerDictionaryMap>>({\n 'deal-statuses': {},\n 'pipeline-stages': {},\n })\n\n const [pipelineNames, setPipelineNames] = React.useState<Record<string, string>>({})\n\n const fetchDictionaryEntries = React.useCallback(\n async (kind: DictionaryKey) => {\n try {\n const data = await ensureCustomerDictionary(queryClient, kind, scopeVersion)\n setDictionaryMaps((prev) => ({ ...prev, [kind]: data.map }))\n } catch {\n setDictionaryMaps((prev) => ({ ...prev, [kind]: {} }))\n }\n },\n [queryClient, scopeVersion],\n )\n\n React.useEffect(() => {\n let cancelled = false\n async function loadDictionaries() {\n if (cancelled) return\n await Promise.all([fetchDictionaryEntries('deal-statuses'), fetchDictionaryEntries('pipeline-stages')])\n }\n loadDictionaries().catch(() => {})\n return () => { cancelled = true }\n }, [fetchDictionaryEntries, reloadToken])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadPipelines() {\n try {\n const call = await apiCall<{ items?: Array<{ id: string; name: string }> }>('/api/customers/pipelines')\n if (cancelled || !call.ok) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const map: Record<string, string> = {}\n items.forEach((p) => { if (p.id && p.name) map[p.id] = p.name })\n setPipelineNames(map)\n } catch {}\n }\n loadPipelines().catch(() => {})\n return () => { cancelled = true }\n }, [reloadToken, scopeVersion])\n\n React.useEffect(() => {\n peopleCacheRef.current.clear()\n companiesCacheRef.current.clear()\n setPeopleState((prev) => {\n if (!prev.options.length && !Object.keys(prev.idToLabel).length) return prev\n return { ...EMPTY_OPTIONS_STATE }\n })\n setCompaniesState((prev) => {\n if (!prev.options.length && !Object.keys(prev.idToLabel).length) return prev\n return { ...EMPTY_OPTIONS_STATE }\n })\n }, [scopeVersion, reloadToken])\n\n const syncFilterLabels = React.useCallback((\n key: 'people' | 'companies',\n ids: string[],\n idToLabel: Record<string, string>,\n ) => {\n setFilterValues((prev) => {\n const current = Array.isArray(prev[key]) ? (prev[key] as string[]) : []\n if (!ids.length) {\n if (!current.length) return prev\n const next = { ...prev }\n delete next[key]\n return next\n }\n const labels: string[] = []\n ids.forEach((id) => {\n const label = idToLabel[id]\n if (label && !labels.includes(label)) labels.push(label)\n })\n if (labels.length < ids.length) return prev\n if (arraysEqual(current, labels)) return prev\n return { ...prev, [key]: labels }\n })\n }, [])\n\n React.useEffect(() => {\n syncFilterLabels('people', selectedPersonIds, peopleState.idToLabel)\n }, [selectedPersonIds, peopleState.idToLabel, syncFilterLabels])\n\n React.useEffect(() => {\n syncFilterLabels('companies', selectedCompanyIds, companiesState.idToLabel)\n }, [selectedCompanyIds, companiesState.idToLabel, syncFilterLabels])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value.trim())\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = { ...values }\n const rawPeople = Array.isArray(values.people) ? (values.people as string[]) : []\n const nextPersonIds: string[] = []\n rawPeople.forEach((value) => {\n const trimmed = typeof value === 'string' ? value.trim() : ''\n if (!trimmed) return\n const mapped = peopleState.labelToId[trimmed]\n if (mapped && !nextPersonIds.includes(mapped)) nextPersonIds.push(mapped)\n })\n setSelectedPersonIds(nextPersonIds)\n if (nextPersonIds.length) {\n next.people = Array.from(new Set(rawPeople.map((value) => (typeof value === 'string' ? value.trim() : '')).filter((value) => value.length > 0)))\n } else {\n delete next.people\n }\n\n const rawCompanies = Array.isArray(values.companies) ? (values.companies as string[]) : []\n const nextCompanyIds: string[] = []\n rawCompanies.forEach((value) => {\n const trimmed = typeof value === 'string' ? value.trim() : ''\n if (!trimmed) return\n const mapped = companiesState.labelToId[trimmed]\n if (mapped && !nextCompanyIds.includes(mapped)) nextCompanyIds.push(mapped)\n })\n setSelectedCompanyIds(nextCompanyIds)\n if (nextCompanyIds.length) {\n next.companies = Array.from(new Set(rawCompanies.map((value) => (typeof value === 'string' ? value.trim() : '')).filter((value) => value.length > 0)))\n } else {\n delete next.companies\n }\n\n setFilterValues(next)\n setPage(1)\n }, [peopleState.labelToId, companiesState.labelToId])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setSelectedPersonIds([])\n setSelectedCompanyIds([])\n setPage(1)\n }, [])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(PAGE_SIZE))\n if (search.trim().length) params.set('search', search.trim())\n if (selectedPersonIds.length) params.set('personId', selectedPersonIds.join(','))\n if (selectedCompanyIds.length) params.set('companyId', selectedCompanyIds.join(','))\n Object.entries(filterValues).forEach(([key, value]) => {\n if (key === 'people' || key === 'companies') return\n if (value == null) return\n if (Array.isArray(value)) {\n const normalized = value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item.trim()\n return String(item).trim()\n })\n .filter((item) => item.length > 0)\n if (normalized.length) params.set(key, normalized.join(','))\n } else if (typeof value === 'object') {\n const obj = value as Record<string, unknown>\n const from = typeof obj.from === 'string' ? obj.from.trim() : ''\n const to = typeof obj.to === 'string' ? obj.to.trim() : ''\n if (from) params.set(`${key}[from]`, from)\n if (to) params.set(`${key}[to]`, to)\n } else {\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (stringValue) params.set(key, stringValue)\n }\n })\n return params.toString()\n }, [filterValues, page, search, selectedCompanyIds, selectedPersonIds])\n\n const currentParams = React.useMemo(\n () => Object.fromEntries(new URLSearchParams(queryParams)),\n [queryParams],\n )\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/deals', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/deals', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const fallback: DealsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<DealsResponse>(`/api/customers/deals?${queryParams}`, undefined, { fallback })\n if (!call.ok) {\n const message =\n typeof (call.result as { error?: string } | undefined)?.error === 'string'\n ? (call.result as { error?: string }).error!\n : t('customers.deals.list.error.load')\n flash(message, 'error')\n if (!cancelled) setCacheStatus(null)\n return\n }\n const payload = call.result ?? fallback\n if (cancelled) return\n setCacheStatus(call.cacheStatus ?? null)\n const items = Array.isArray(payload.items) ? payload.items : []\n const mapped = items\n .map((item) => mapDeal(item as Record<string, unknown>))\n .filter((row): row is DealRow => !!row)\n setRows(mapped)\n setTotal(typeof payload.total === 'number' ? payload.total : mapped.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n } catch (err) {\n if (!cancelled) {\n setCacheStatus(null)\n const message = err instanceof Error ? err.message : t('customers.deals.list.error.load')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n React.useEffect(() => {\n if (totalPages > 0 && page > totalPages) {\n setPage(totalPages)\n }\n }, [page, totalPages])\n\n const queryRef = React.useRef(searchParams?.toString() ?? '')\n React.useEffect(() => {\n if (!pathname) return\n const params = new URLSearchParams()\n if (search.trim().length) params.set('search', search.trim())\n if (selectedPersonIds.length) selectedPersonIds.forEach((id) => params.append('personId', id))\n if (selectedCompanyIds.length) selectedCompanyIds.forEach((id) => params.append('companyId', id))\n if (page > 1) params.set('page', String(page))\n const next = params.toString()\n if (queryRef.current === next) return\n queryRef.current = next\n router.replace(next ? `${pathname}?${next}` : pathname, { scroll: false })\n }, [pathname, router, page, search, selectedPersonIds, selectedCompanyIds])\n\n const handleRefresh = React.useCallback(() => {\n peopleCacheRef.current.clear()\n companiesCacheRef.current.clear()\n void Promise.all([\n invalidateCustomerDictionary(queryClient, 'deal-statuses'),\n invalidateCustomerDictionary(queryClient, 'pipeline-stages'),\n ])\n setReloadToken((token) => token + 1)\n }, [queryClient])\n\n const handleDeleteDeal = React.useCallback(\n async (dealId: string) => {\n if (pendingDeleteId) return\n const confirmed = await confirm({\n title: t(\n 'customers.deals.list.deleteConfirm',\n 'Delete this deal? This action cannot be undone.',\n ),\n variant: 'destructive',\n })\n if (!confirmed) return\n setPendingDeleteId(dealId)\n try {\n await deleteCrud('customers/deals', {\n body: { id: dealId },\n errorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),\n })\n flash(t('customers.deals.list.deleteSuccess', 'Deal deleted.'), 'success')\n setRows((prev) => prev.filter((row) => row.id !== dealId))\n setTotal((prev) => Math.max(0, prev - 1))\n handleRefresh()\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.list.deleteError', 'Failed to delete deal.')\n flash(message, 'error')\n } finally {\n setPendingDeleteId(null)\n }\n },\n [confirm, handleRefresh, pendingDeleteId, t],\n )\n\n const personOptions = peopleState.options\n const companyOptions = companiesState.options\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'people',\n label: t('customers.deals.list.filters.people'),\n type: 'tags',\n options: personOptions,\n loadOptions: loadPeopleOptions,\n placeholder: t('customers.deals.list.filters.peoplePlaceholder'),\n },\n {\n id: 'companies',\n label: t('customers.deals.list.filters.companies'),\n type: 'tags',\n options: companyOptions,\n loadOptions: loadCompanyOptions,\n placeholder: t('customers.deals.list.filters.companiesPlaceholder'),\n },\n ], [companyOptions, loadCompanyOptions, loadPeopleOptions, personOptions, t])\n\n const { data: customFieldDefs = [] } = useCustomFieldDefs([E.customers.customer_deal], {\n keyExtras: [scopeVersion, reloadToken],\n })\n\n const columns = React.useMemo<ColumnDef<DealRow>[]>(() => {\n const noValue = <span className=\"text-muted-foreground text-sm\">{t('customers.deals.list.noValue')}</span>\n const renderDictionaryCell = (kind: DictionaryKey, value: string | null | undefined) => (\n <DictionaryValue\n value={value}\n map={dictionaryMaps[kind]}\n fallback={value ? <span className=\"text-sm\">{value}</span> : noValue}\n className=\"text-sm\"\n iconWrapperClassName=\"inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\"\n iconClassName=\"h-4 w-4\"\n colorClassName=\"h-3 w-3 rounded-full\"\n />\n )\n const renderAssociationList = (\n items: { id: string; label: string }[],\n fallbackLabel: string,\n ) => {\n if (!items.length) return noValue\n return (\n <ul className=\"flex flex-wrap gap-1 text-sm\">\n {items.map((entry) => (\n <li key={entry.id} className=\"rounded border px-2 py-0.5 text-xs bg-muted\">\n {entry.label && entry.label.trim().length ? entry.label : fallbackLabel}\n </li>\n ))}\n </ul>\n )\n }\n\n const customColumns = filterCustomFieldDefs(customFieldDefs, 'list').map<ColumnDef<DealRow>>((def) => ({\n accessorKey: `cf_${def.key}`,\n header: def.label || def.key,\n cell: ({ getValue }) => {\n const value = getValue()\n if (value == null) return noValue\n if (Array.isArray(value)) {\n const normalized = value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item.trim()\n return String(item).trim()\n })\n .filter((item) => item.length > 0)\n if (!normalized.length) return noValue\n return <span className=\"text-sm\">{normalized.join(', ')}</span>\n }\n if (typeof value === 'boolean') {\n return (\n <span className=\"text-sm\">\n {value\n ? t('customers.deals.list.booleanYes', 'Yes')\n : t('customers.deals.list.booleanNo', 'No')}\n </span>\n )\n }\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (!stringValue) return noValue\n return <span className=\"text-sm\">{stringValue}</span>\n },\n }))\n\n return [\n {\n accessorKey: 'title',\n header: t('customers.deals.list.columns.title'),\n cell: ({ row }) => <span className=\"font-medium text-sm\">{row.original.title}</span>,\n },\n {\n accessorKey: 'status',\n header: t('customers.deals.list.columns.status'),\n cell: ({ row }) => renderDictionaryCell('deal-statuses', row.original.status),\n },\n {\n accessorKey: 'pipelineStage',\n header: t('customers.deals.list.columns.pipelineStage'),\n cell: ({ row }) => renderDictionaryCell('pipeline-stages', row.original.pipelineStage),\n },\n {\n accessorKey: 'pipelineId',\n header: t('customers.deals.list.columns.pipeline', 'Pipeline'),\n cell: ({ row }) => {\n const name = row.original.pipelineId ? pipelineNames[row.original.pipelineId] : null\n return name ? <span className=\"text-sm\">{name}</span> : noValue\n },\n },\n {\n accessorKey: 'valueAmount',\n header: t('customers.deals.list.columns.value'),\n cell: ({ row }) => (\n <span className=\"text-sm font-medium\">\n {formatCurrency(row.original.valueAmount ?? null, row.original.valueCurrency ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n {\n accessorKey: 'probability',\n header: t('customers.deals.list.columns.probability'),\n cell: ({ row }) => {\n const value = row.original.probability\n if (typeof value === 'number' && Number.isFinite(value)) {\n return <span className=\"text-sm\">{`${Math.min(Math.max(value, 0), 100)}%`}</span>\n }\n return noValue\n },\n },\n {\n accessorKey: 'expectedCloseAt',\n header: t('customers.deals.list.columns.expectedClose'),\n cell: ({ row }) => (\n <span className=\"text-sm\">\n {formatDateValue(row.original.expectedCloseAt ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n {\n accessorKey: 'companies',\n header: t('customers.deals.list.columns.companies'),\n cell: ({ row }) => renderAssociationList(row.original.companies, t('customers.deals.list.unnamedCompany')),\n },\n {\n accessorKey: 'people',\n header: t('customers.deals.list.columns.people'),\n cell: ({ row }) => renderAssociationList(row.original.people, t('customers.deals.list.unnamedPerson')),\n },\n {\n accessorKey: 'updatedAt',\n header: t('customers.deals.list.columns.updatedAt'),\n cell: ({ row }) => (\n <span className=\"text-sm\">\n {formatDateValue(row.original.updatedAt ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n ...customColumns,\n ]\n }, [customFieldDefs, dictionaryMaps, pipelineNames, t])\n\n return (\n <Page>\n <PageBody>\n <DataTable<DealRow>\n title={t('customers.deals.list.title')}\n actions={(\n <Button asChild>\n <Link href=\"/backend/customers/deals/create\">\n {t('customers.deals.list.actions.new', 'New deal')}\n </Link>\n </Button>\n )}\n columns={columns}\n data={rows}\n onRowClick={(row) => {\n router.push(`/backend/customers/deals/${row.id}`)\n }}\n rowActions={(row) => {\n const isDeleting = pendingDeleteId === row.id\n return (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('customers.deals.list.actions.edit', 'Edit'),\n onSelect: () => { router.push(`/backend/customers/deals/${row.id}`) },\n },\n {\n id: 'open-new-tab',\n label: t('customers.deals.list.actions.openInNewTab', 'Open in new tab'),\n onSelect: () => {\n if (typeof window !== 'undefined') {\n window.open(`/backend/customers/deals/${row.id}`, '_blank', 'noopener')\n }\n },\n },\n {\n id: 'delete',\n label: isDeleting\n ? t('customers.deals.list.actions.deleting', 'Deleting\u2026')\n : t('customers.deals.list.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => handleDeleteDeal(row.id),\n },\n ]}\n />\n )\n }}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('customers.deals.list.searchPlaceholder')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: (nextPage) => setPage(nextPage),\n cacheStatus,\n }}\n isLoading={isLoading}\n refreshButton={{\n label: t('customers.deals.list.refresh'),\n onRefresh: handleRefresh,\n }}\n exporter={exportConfig}\n entityId={E.customers.customer_deal}\n perspective={{ tableId: 'customers.deals.list' }}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n\nfunction mapDeal(item: Record<string, unknown>): DealRow | null {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const title = typeof item.title === 'string' ? item.title : ''\n const status = typeof item.status === 'string' ? item.status : null\n const pipelineStage = typeof item.pipeline_stage === 'string' ? item.pipeline_stage : null\n const pipelineStageId = typeof item.pipeline_stage_id === 'string' ? item.pipeline_stage_id : null\n const pipelineId = typeof item.pipeline_id === 'string' ? item.pipeline_id : null\n const valueAmountRaw = item.value_amount\n const valueAmount =\n typeof valueAmountRaw === 'number'\n ? valueAmountRaw\n : typeof valueAmountRaw === 'string' && valueAmountRaw.trim()\n ? Number(valueAmountRaw)\n : null\n const valueCurrency =\n typeof item.value_currency === 'string' && item.value_currency.trim().length\n ? item.value_currency.trim().toUpperCase()\n : null\n const probabilityRaw = item.probability\n const probability =\n typeof probabilityRaw === 'number'\n ? probabilityRaw\n : typeof probabilityRaw === 'string' && probabilityRaw.trim().length\n ? Number(probabilityRaw)\n : null\n const expectedCloseAt = typeof item.expected_close_at === 'string' ? item.expected_close_at : null\n const updatedAt = typeof item.updated_at === 'string' ? item.updated_at : null\n const peopleRaw = Array.isArray(item.people) ? item.people : []\n const companiesRaw = Array.isArray(item.companies) ? item.companies : []\n const people = peopleRaw\n .map((entry) => {\n if (!entry || typeof entry !== 'object') return null\n const data = entry as Record<string, unknown>\n const pid = typeof data.id === 'string' ? data.id : null\n if (!pid) return null\n const label = typeof data.label === 'string' ? data.label : ''\n return { id: pid, label }\n })\n .filter((entry): entry is { id: string; label: string } => !!entry)\n const companies = companiesRaw\n .map((entry) => {\n if (!entry || typeof entry !== 'object') return null\n const data = entry as Record<string, unknown>\n const cid = typeof data.id === 'string' ? data.id : null\n if (!cid) return null\n const label = typeof data.label === 'string' ? data.label : ''\n return { id: cid, label }\n })\n .filter((entry): entry is { id: string; label: string } => !!entry)\n const customFields: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(item)) {\n if (key.startsWith('cf_')) customFields[key] = value\n }\n return withDataTableNamespaces({\n id,\n title,\n status,\n pipelineStage,\n pipelineStageId,\n pipelineId,\n valueAmount,\n valueCurrency,\n probability,\n expectedCloseAt,\n updatedAt,\n people,\n companies,\n ...customFields,\n }, item)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["formatter"]
7
7
  }
@@ -4,7 +4,7 @@ import * as React from "react";
4
4
  import Link from "next/link";
5
5
  import { useRouter } from "next/navigation";
6
6
  import { Page, PageBody } from "@open-mercato/ui/backend/Page";
7
- import { DataTable } from "@open-mercato/ui/backend/DataTable";
7
+ import { DataTable, withDataTableNamespaces } from "@open-mercato/ui/backend/DataTable";
8
8
  import { Button } from "@open-mercato/ui/primitives/button";
9
9
  import { RowActions } from "@open-mercato/ui/backend/RowActions";
10
10
  import { apiCall, apiCallOrThrow, readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
@@ -66,7 +66,7 @@ function mapApiItem(item) {
66
66
  customFields[key] = value;
67
67
  }
68
68
  }
69
- return {
69
+ return withDataTableNamespaces({
70
70
  id,
71
71
  name,
72
72
  description,
@@ -81,7 +81,7 @@ function mapApiItem(item) {
81
81
  organizationId,
82
82
  source,
83
83
  ...customFields
84
- };
84
+ }, item);
85
85
  }
86
86
  function CustomersPeoplePage() {
87
87
  const { confirm, ConfirmDialogElement } = useConfirmDialog();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/customers/backend/customers/people/page.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall, apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildCrudExportUrl } from '@open-mercato/ui/backend/utils/crud'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { E } from '#generated/entities.ids.generated'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { FilterOption } from '@open-mercato/ui/backend/FilterOverlay'\nimport {\n DictionaryValue,\n renderDictionaryColor,\n renderDictionaryIcon,\n type CustomerDictionaryKind,\n type CustomerDictionaryMap,\n} from '../../../lib/dictionaries'\nimport {\n useCustomFieldDefs,\n filterCustomFieldDefs,\n} from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { ensureCustomerDictionary } from '../../../components/detail/hooks/useCustomerDictionary'\n\ntype PersonRow = {\n id: string\n name: string\n description?: string | null\n email?: string | null\n phone?: string | null\n status?: string | null\n lifecycleStage?: string | null\n nextInteractionAt?: string | null\n nextInteractionName?: string | null\n nextInteractionIcon?: string | null\n nextInteractionColor?: string | null\n organizationId?: string | null\n source?: string | null\n} & Record<string, unknown>\n\ntype PeopleResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n page?: number\n totalPages?: number\n}\n\ntype DictionaryKindKey = CustomerDictionaryKind\ntype DictionaryMap = CustomerDictionaryMap\n\nconst NO_MATCH_TAG_SENTINEL = '__no_match__'\n\nfunction createEmptyDictionaryMaps(): Record<DictionaryKindKey, DictionaryMap> {\n return {\n statuses: {},\n sources: {},\n 'lifecycle-stages': {},\n 'address-types': {},\n 'activity-types': {},\n 'deal-statuses': {},\n 'pipeline-stages': {},\n 'job-titles': {},\n industries: {},\n }\n}\n\nfunction formatDate(value: string | null | undefined, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString()\n}\n\nfunction mapApiItem(item: Record<string, unknown>): PersonRow | null {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const name = typeof item.display_name === 'string' ? item.display_name : ''\n const description = typeof item.description === 'string' ? item.description : null\n const email = typeof item.primary_email === 'string' ? item.primary_email : null\n const phone = typeof item.primary_phone === 'string' ? item.primary_phone : null\n const status = typeof item.status === 'string' ? item.status : null\n const lifecycleStage = typeof item.lifecycle_stage === 'string' ? item.lifecycle_stage : null\n const nextInteractionAt = typeof item.next_interaction_at === 'string' ? item.next_interaction_at : null\n const nextInteractionName = typeof item.next_interaction_name === 'string' ? item.next_interaction_name : null\n const nextInteractionIcon = typeof item.next_interaction_icon === 'string' ? item.next_interaction_icon : null\n const nextInteractionColor = typeof item.next_interaction_color === 'string' ? item.next_interaction_color : null\n const organizationId = typeof item.organization_id === 'string' ? item.organization_id : null\n const source = typeof item.source === 'string' ? item.source : null\n const customFields: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(item)) {\n if (key.startsWith('cf_')) {\n customFields[key] = value\n }\n }\n return {\n id,\n name,\n description,\n email,\n phone,\n status,\n lifecycleStage,\n nextInteractionAt,\n nextInteractionName,\n nextInteractionIcon,\n nextInteractionColor,\n organizationId,\n source,\n ...customFields,\n }\n}\n\nexport default function CustomersPeoplePage() {\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [rows, setRows] = React.useState<PersonRow[]>([])\n const [page, setPage] = React.useState(1)\n const [pageSize] = React.useState(20)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setIsLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n const [dictionaryMaps, setDictionaryMaps] = React.useState<Record<DictionaryKindKey, DictionaryMap>>(createEmptyDictionaryMaps())\n const [tagIdToLabel, setTagIdToLabel] = React.useState<Record<string, string>>({})\n const scopeVersion = useOrganizationScopeVersion()\n const queryClient = useQueryClient()\n const t = useT()\n const router = useRouter()\n const fetchDictionaryEntries = React.useCallback(async (kind: DictionaryKindKey) => {\n try {\n const data = await ensureCustomerDictionary(queryClient, kind, scopeVersion)\n setDictionaryMaps((prev) => ({\n ...prev,\n [kind]: data.map,\n }))\n return data.entries\n } catch {\n return []\n }\n }, [queryClient, scopeVersion])\n const loadDictionaryOptions = React.useCallback(async (kind: 'statuses' | 'sources' | 'lifecycle-stages') => {\n const entries = await fetchDictionaryEntries(kind)\n return entries.map((entry) => ({ value: entry.value, label: entry.label }))\n }, [fetchDictionaryEntries])\n\n const dictionaryOptions = React.useMemo(() => {\n const toOptions = (map?: DictionaryMap | null): FilterOption[] =>\n Object.values(map ?? {})\n .map((entry) => ({ value: entry.value, label: entry.label }))\n .sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }))\n return {\n statuses: toOptions(dictionaryMaps.statuses),\n sources: toOptions(dictionaryMaps.sources),\n lifecycleStages: toOptions(dictionaryMaps['lifecycle-stages']),\n }\n }, [dictionaryMaps])\n\n const loadTagOptions = React.useCallback(async (query?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100' })\n const trimmedQuery = typeof query === 'string' ? query.trim() : ''\n if (trimmedQuery) params.set('search', trimmedQuery)\n const payload = await readApiResultOrThrow<{ items?: unknown[] }>(\n `/api/customers/tags?${params.toString()}`,\n undefined,\n { errorMessage: t('customers.people.detail.tags.loadError', 'Failed to load tags.') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options: FilterOption[] = []\n for (const item of items) {\n if (!item || typeof item !== 'object') continue\n const raw = item as { id?: unknown; tagId?: unknown; label?: unknown; slug?: unknown }\n const rawId = typeof raw.id === 'string'\n ? raw.id\n : typeof raw.tagId === 'string'\n ? raw.tagId\n : null\n if (!rawId) continue\n const label = typeof raw.label === 'string' && raw.label.trim().length\n ? raw.label.trim()\n : typeof raw.slug === 'string' && raw.slug.trim().length\n ? raw.slug.trim()\n : rawId\n options.push({ value: rawId, label })\n }\n if (options.length) {\n setTagIdToLabel((prev) => {\n let changed = false\n const next = { ...prev }\n for (const option of options) {\n if (next[option.value] !== option.label) {\n next[option.value] = option.label\n changed = true\n }\n }\n return changed ? next : prev\n })\n }\n return options\n } catch (err) {\n console.error('customers.people.list.loadTagOptions', err)\n return []\n }\n }, [setTagIdToLabel, t])\n\n const tagLabelToId = React.useMemo(() => {\n const map: Record<string, string> = {}\n for (const [id, label] of Object.entries(tagIdToLabel)) {\n if (!label) continue\n map[label] = id\n }\n return map\n }, [tagIdToLabel])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadAll() {\n if (cancelled) return\n setDictionaryMaps(createEmptyDictionaryMaps())\n await Promise.all([\n fetchDictionaryEntries('statuses'),\n fetchDictionaryEntries('sources'),\n fetchDictionaryEntries('lifecycle-stages'),\n ])\n }\n loadAll().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [fetchDictionaryEntries, scopeVersion, reloadToken])\n\n const { data: customFieldDefs = [] } = useCustomFieldDefs(\n [E.customers.customer_entity, E.customers.customer_person_profile],\n { keyExtras: [scopeVersion, reloadToken] },\n )\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'status',\n label: t('customers.people.list.filters.status'),\n type: 'select',\n options: dictionaryOptions.statuses,\n loadOptions: () => loadDictionaryOptions('statuses'),\n },\n {\n id: 'source',\n label: t('customers.people.list.filters.source'),\n type: 'select',\n options: dictionaryOptions.sources,\n loadOptions: () => loadDictionaryOptions('sources'),\n },\n {\n id: 'lifecycleStage',\n label: t('customers.people.list.filters.lifecycleStage'),\n type: 'select',\n options: dictionaryOptions.lifecycleStages,\n loadOptions: () => loadDictionaryOptions('lifecycle-stages'),\n },\n {\n id: 'tagIds',\n label: t('customers.people.list.filters.tags'),\n type: 'tags',\n loadOptions: loadTagOptions,\n },\n {\n id: 'createdAt',\n label: t('customers.people.list.filters.createdAt'),\n type: 'dateRange',\n },\n {\n id: 'emailContains',\n label: t('customers.people.list.filters.emailContains'),\n type: 'text',\n placeholder: t('customers.people.list.filters.emailContainsPlaceholder'),\n },\n {\n id: 'hasEmail',\n label: t('customers.people.list.filters.hasEmail'),\n type: 'checkbox',\n },\n {\n id: 'hasPhone',\n label: t('customers.people.list.filters.hasPhone'),\n type: 'checkbox',\n },\n {\n id: 'hasNextInteraction',\n label: t('customers.people.list.filters.hasNextInteraction'),\n type: 'checkbox',\n },\n ], [dictionaryOptions.lifecycleStages, dictionaryOptions.sources, dictionaryOptions.statuses, loadDictionaryOptions, loadTagOptions, t])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(pageSize))\n if (search.trim()) params.set('search', search.trim())\n const status = filterValues.status\n if (typeof status === 'string' && status.trim()) params.set('status', status)\n const source = filterValues.source\n if (typeof source === 'string' && source.trim()) params.set('source', source)\n const lifecycleStage = filterValues.lifecycleStage\n if (typeof lifecycleStage === 'string' && lifecycleStage.trim()) params.set('lifecycleStage', lifecycleStage)\n const createdAt = filterValues.createdAt\n if (createdAt && typeof createdAt === 'object') {\n if (createdAt.from) params.set('createdFrom', createdAt.from)\n if (createdAt.to) params.set('createdTo', createdAt.to)\n }\n const emailContains = filterValues.emailContains\n if (typeof emailContains === 'string' && emailContains.trim()) {\n params.set('emailContains', emailContains.trim())\n }\n const booleanFilters: Array<['hasEmail' | 'hasPhone' | 'hasNextInteraction', string]> = [\n ['hasEmail', 'hasEmail'],\n ['hasPhone', 'hasPhone'],\n ['hasNextInteraction', 'hasNextInteraction'],\n ]\n for (const [key, queryKey] of booleanFilters) {\n const value = filterValues[key]\n if (value === true) params.set(queryKey, 'true')\n if (value === false) params.set(queryKey, 'false')\n }\n const tagLabels = Array.isArray(filterValues.tagIds)\n ? filterValues.tagIds\n .map((value) => (typeof value === 'string' ? value.trim() : String(value || '').trim()))\n .filter((value) => value.length > 0)\n : []\n if (tagLabels.length > 0) {\n const normalizedTagIds = tagLabels\n .map((label) => tagLabelToId[label])\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n if (normalizedTagIds.length === tagLabels.length && normalizedTagIds.length > 0) {\n params.set('tagIds', normalizedTagIds.join(','))\n } else {\n params.set('tagIdsEmpty', 'true')\n }\n }\n Object.entries(filterValues).forEach(([key, value]) => {\n if (!key.startsWith('cf_') || value == null) return\n if (Array.isArray(value)) {\n const normalized = value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item.trim()\n return String(item).trim()\n })\n .filter((item) => item.length > 0)\n if (normalized.length) params.set(key, normalized.join(','))\n } else if (typeof value === 'object') {\n return\n } else if (value !== '') {\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (stringValue) params.set(key, stringValue)\n }\n })\n return params.toString()\n }, [filterValues, page, pageSize, search, tagLabelToId])\n\n const currentParams = React.useMemo(() => Object.fromEntries(new URLSearchParams(queryParams)), [queryParams])\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/people', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/people', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const fallback: PeopleResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<PeopleResponse>(`/api/customers/people?${queryParams}`, undefined, { fallback })\n if (!call.ok) {\n const errorPayload = call.result as { error?: string } | undefined\n const message = typeof errorPayload?.error === 'string' ? errorPayload.error : t('customers.people.list.error.load')\n flash(message, 'error')\n if (!cancelled) setCacheStatus(null)\n return\n }\n const payload = call.result ?? fallback\n if (cancelled) return\n setCacheStatus(call.cacheStatus ?? null)\n const items = Array.isArray(payload.items) ? payload.items : []\n setRows(items.map((item) => mapApiItem(item as Record<string, unknown>)).filter((row): row is PersonRow => !!row))\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n } catch (err) {\n if (!cancelled) {\n setCacheStatus(null)\n const message = err instanceof Error ? err.message : t('customers.people.list.error.load')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (person: PersonRow) => {\n if (!person?.id) return\n const name = person.name || t('customers.people.list.deleteFallbackName')\n const confirmed = await confirm({\n title: t('customers.people.list.deleteConfirm', undefined, { name }),\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n await apiCallOrThrow(\n `/api/customers/people?id=${encodeURIComponent(person.id)}`,\n {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n },\n { errorMessage: t('customers.people.list.deleteError') },\n )\n setRows((prev) => prev.filter((row) => row.id !== person.id))\n setTotal((prev) => Math.max(prev - 1, 0))\n handleRefresh()\n flash(t('customers.people.list.deleteSuccess'), 'success')\n } catch (err) {\n const message = err instanceof Error ? err.message : t('customers.people.list.deleteError')\n flash(message, 'error')\n }\n }, [confirm, handleRefresh, t])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = {}\n Object.entries(values).forEach(([key, value]) => {\n if (value !== undefined) {\n next[key] = value\n }\n })\n const rawTags = Array.isArray(values.tagIds) ? (values.tagIds as string[]) : []\n const sanitizedTags = rawTags\n .map((tag) => (typeof tag === 'string' ? tag.trim() : ''))\n .filter((tag) => tag.length > 0)\n if (sanitizedTags.length) next.tagIds = sanitizedTags\n else delete next.tagIds\n setFilterValues(next)\n setPage(1)\n }, [setFilterValues, setPage])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [setFilterValues, setPage])\n\n const columns = React.useMemo<ColumnDef<PersonRow>[]>(() => {\n const noValue = <span className=\"text-muted-foreground text-sm\">{t('customers.people.list.noValue')}</span>\n const renderDictionaryCell = (kind: DictionaryKindKey, rawValue: string | null | undefined) => (\n <DictionaryValue\n value={rawValue}\n map={dictionaryMaps[kind]}\n fallback={rawValue ? <span>{rawValue}</span> : noValue}\n className=\"text-sm\"\n iconWrapperClassName=\"inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\"\n iconClassName=\"h-4 w-4\"\n colorClassName=\"h-3 w-3 rounded-full\"\n />\n )\n\n const renderCustomFieldCell = (value: unknown) => {\n if (value == null) return noValue\n if (Array.isArray(value)) {\n if (!value.length) return noValue\n const normalized = value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item.trim()\n return String(item).trim()\n })\n .filter((item) => item.length > 0)\n if (!normalized.length) return noValue\n return <span className=\"text-sm\">{normalized.join(', ')}</span>\n }\n if (typeof value === 'boolean') {\n return (\n <span className=\"text-sm\">\n {value\n ? t('customers.people.list.booleanYes', 'Yes')\n : t('customers.people.list.booleanNo', 'No')}\n </span>\n )\n }\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (!stringValue) return noValue\n return <span className=\"text-sm\">{stringValue}</span>\n }\n\n const baseColumns: ColumnDef<PersonRow>[] = [\n {\n accessorKey: 'name',\n header: t('customers.people.list.columns.name'),\n cell: ({ row }) => (\n <Link href={`/backend/customers/people/${row.original.id}`} className=\"font-medium hover:underline\">\n {row.original.name}\n </Link>\n ),\n },\n {\n accessorKey: 'email',\n header: t('customers.people.list.columns.email'),\n cell: ({ row }) => row.original.email || <span className=\"text-muted-foreground text-sm\">{t('customers.people.list.noValue')}</span>,\n },\n {\n accessorKey: 'status',\n header: t('customers.people.list.columns.status'),\n cell: ({ row }) => renderDictionaryCell('statuses', row.original.status),\n },\n {\n accessorKey: 'lifecycleStage',\n header: t('customers.people.list.columns.lifecycleStage'),\n cell: ({ row }) => renderDictionaryCell('lifecycle-stages', row.original.lifecycleStage),\n },\n {\n accessorKey: 'nextInteractionAt',\n header: t('customers.people.list.columns.nextInteraction'),\n meta: {\n tooltipContent: (row: PersonRow) => {\n if (!row.nextInteractionAt) return undefined\n const date = formatDate(row.nextInteractionAt, '')\n const name = row.nextInteractionName || ''\n return [date, name].filter(Boolean).join(' - ')\n },\n },\n cell: ({ row }) =>\n row.original.nextInteractionAt\n ? (\n <div className=\"flex items-start gap-2 text-sm\">\n {row.original.nextInteractionIcon ? (\n <span className=\"mt-0.5 inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\">\n {renderDictionaryIcon(row.original.nextInteractionIcon, 'h-4 w-4')}\n </span>\n ) : null}\n <div className=\"flex flex-col\">\n <span>{formatDate(row.original.nextInteractionAt, t('customers.people.list.noValue'))}</span>\n {row.original.nextInteractionName ? (\n <span className=\"text-xs text-muted-foreground\">{row.original.nextInteractionName}</span>\n ) : null}\n </div>\n {row.original.nextInteractionColor ? (\n <span className=\"mt-1\">\n {renderDictionaryColor(row.original.nextInteractionColor, 'h-3 w-3 rounded-full border border-border')}\n </span>\n ) : null}\n </div>\n )\n : <span className=\"text-muted-foreground text-sm\">{t('customers.people.list.noValue')}</span>,\n },\n {\n accessorKey: 'source',\n header: t('customers.people.list.columns.source'),\n cell: ({ row }) => renderDictionaryCell('sources', row.original.source),\n },\n ]\n\n const customColumns = filterCustomFieldDefs(customFieldDefs, 'list').map<ColumnDef<PersonRow>>((def) => ({\n accessorKey: `cf_${def.key}`,\n header: def.label || def.key,\n cell: ({ getValue }) => renderCustomFieldCell(getValue()),\n }))\n\n return [...baseColumns, ...customColumns]\n }, [customFieldDefs, dictionaryMaps, t])\n\n return (\n <Page>\n <PageBody>\n <DataTable<PersonRow>\n title={t('customers.people.list.title')}\n refreshButton={{\n label: t('customers.people.list.actions.refresh'),\n onRefresh: () => { setSearch(''); setPage(1); handleRefresh() },\n }}\n actions={(\n <Button asChild>\n <Link href=\"/backend/customers/people/create\">\n {t('customers.people.list.actions.new')}\n </Link>\n </Button>\n )}\n columns={columns}\n data={rows}\n exporter={exportConfig}\n searchValue={search}\n onSearchChange={(value) => { setSearch(value); setPage(1) }}\n searchPlaceholder={t('customers.people.list.searchPlaceholder')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n entityIds={[E.customers.customer_entity, E.customers.customer_person_profile]}\n perspective={{ tableId: 'customers.people.list' }}\n onRowClick={(row) => router.push(`/backend/customers/people/${row.id}`)}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'view',\n label: t('customers.people.list.actions.view'),\n onSelect: () => { router.push(`/backend/customers/people/${row.id}`) },\n },\n {\n id: 'open-new-tab',\n label: t('customers.people.list.actions.openInNewTab'),\n onSelect: () => window.open(`/backend/customers/people/${row.id}`, '_blank', 'noopener'),\n },\n {\n id: 'delete',\n label: t('customers.people.list.actions.delete'),\n destructive: true,\n onSelect: () => handleDelete(row),\n },\n ]}\n />\n )}\n pagination={{ page, pageSize, total, totalPages, onPageChange: setPage, cacheStatus }}\n isLoading={isLoading}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type DataTableExportFormat, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall, apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildCrudExportUrl } from '@open-mercato/ui/backend/utils/crud'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { E } from '#generated/entities.ids.generated'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { FilterOption } from '@open-mercato/ui/backend/FilterOverlay'\nimport {\n DictionaryValue,\n renderDictionaryColor,\n renderDictionaryIcon,\n type CustomerDictionaryKind,\n type CustomerDictionaryMap,\n} from '../../../lib/dictionaries'\nimport {\n useCustomFieldDefs,\n filterCustomFieldDefs,\n} from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { ensureCustomerDictionary } from '../../../components/detail/hooks/useCustomerDictionary'\n\ntype PersonRow = {\n id: string\n name: string\n description?: string | null\n email?: string | null\n phone?: string | null\n status?: string | null\n lifecycleStage?: string | null\n nextInteractionAt?: string | null\n nextInteractionName?: string | null\n nextInteractionIcon?: string | null\n nextInteractionColor?: string | null\n organizationId?: string | null\n source?: string | null\n} & Record<string, unknown>\n\ntype PeopleResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n page?: number\n totalPages?: number\n}\n\ntype DictionaryKindKey = CustomerDictionaryKind\ntype DictionaryMap = CustomerDictionaryMap\n\nconst NO_MATCH_TAG_SENTINEL = '__no_match__'\n\nfunction createEmptyDictionaryMaps(): Record<DictionaryKindKey, DictionaryMap> {\n return {\n statuses: {},\n sources: {},\n 'lifecycle-stages': {},\n 'address-types': {},\n 'activity-types': {},\n 'deal-statuses': {},\n 'pipeline-stages': {},\n 'job-titles': {},\n industries: {},\n }\n}\n\nfunction formatDate(value: string | null | undefined, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString()\n}\n\nfunction mapApiItem(item: Record<string, unknown>): PersonRow | null {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const name = typeof item.display_name === 'string' ? item.display_name : ''\n const description = typeof item.description === 'string' ? item.description : null\n const email = typeof item.primary_email === 'string' ? item.primary_email : null\n const phone = typeof item.primary_phone === 'string' ? item.primary_phone : null\n const status = typeof item.status === 'string' ? item.status : null\n const lifecycleStage = typeof item.lifecycle_stage === 'string' ? item.lifecycle_stage : null\n const nextInteractionAt = typeof item.next_interaction_at === 'string' ? item.next_interaction_at : null\n const nextInteractionName = typeof item.next_interaction_name === 'string' ? item.next_interaction_name : null\n const nextInteractionIcon = typeof item.next_interaction_icon === 'string' ? item.next_interaction_icon : null\n const nextInteractionColor = typeof item.next_interaction_color === 'string' ? item.next_interaction_color : null\n const organizationId = typeof item.organization_id === 'string' ? item.organization_id : null\n const source = typeof item.source === 'string' ? item.source : null\n const customFields: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(item)) {\n if (key.startsWith('cf_')) {\n customFields[key] = value\n }\n }\n return withDataTableNamespaces({\n id,\n name,\n description,\n email,\n phone,\n status,\n lifecycleStage,\n nextInteractionAt,\n nextInteractionName,\n nextInteractionIcon,\n nextInteractionColor,\n organizationId,\n source,\n ...customFields,\n }, item)\n}\n\nexport default function CustomersPeoplePage() {\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [rows, setRows] = React.useState<PersonRow[]>([])\n const [page, setPage] = React.useState(1)\n const [pageSize] = React.useState(20)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setIsLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n const [dictionaryMaps, setDictionaryMaps] = React.useState<Record<DictionaryKindKey, DictionaryMap>>(createEmptyDictionaryMaps())\n const [tagIdToLabel, setTagIdToLabel] = React.useState<Record<string, string>>({})\n const scopeVersion = useOrganizationScopeVersion()\n const queryClient = useQueryClient()\n const t = useT()\n const router = useRouter()\n const fetchDictionaryEntries = React.useCallback(async (kind: DictionaryKindKey) => {\n try {\n const data = await ensureCustomerDictionary(queryClient, kind, scopeVersion)\n setDictionaryMaps((prev) => ({\n ...prev,\n [kind]: data.map,\n }))\n return data.entries\n } catch {\n return []\n }\n }, [queryClient, scopeVersion])\n const loadDictionaryOptions = React.useCallback(async (kind: 'statuses' | 'sources' | 'lifecycle-stages') => {\n const entries = await fetchDictionaryEntries(kind)\n return entries.map((entry) => ({ value: entry.value, label: entry.label }))\n }, [fetchDictionaryEntries])\n\n const dictionaryOptions = React.useMemo(() => {\n const toOptions = (map?: DictionaryMap | null): FilterOption[] =>\n Object.values(map ?? {})\n .map((entry) => ({ value: entry.value, label: entry.label }))\n .sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }))\n return {\n statuses: toOptions(dictionaryMaps.statuses),\n sources: toOptions(dictionaryMaps.sources),\n lifecycleStages: toOptions(dictionaryMaps['lifecycle-stages']),\n }\n }, [dictionaryMaps])\n\n const loadTagOptions = React.useCallback(async (query?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100' })\n const trimmedQuery = typeof query === 'string' ? query.trim() : ''\n if (trimmedQuery) params.set('search', trimmedQuery)\n const payload = await readApiResultOrThrow<{ items?: unknown[] }>(\n `/api/customers/tags?${params.toString()}`,\n undefined,\n { errorMessage: t('customers.people.detail.tags.loadError', 'Failed to load tags.') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options: FilterOption[] = []\n for (const item of items) {\n if (!item || typeof item !== 'object') continue\n const raw = item as { id?: unknown; tagId?: unknown; label?: unknown; slug?: unknown }\n const rawId = typeof raw.id === 'string'\n ? raw.id\n : typeof raw.tagId === 'string'\n ? raw.tagId\n : null\n if (!rawId) continue\n const label = typeof raw.label === 'string' && raw.label.trim().length\n ? raw.label.trim()\n : typeof raw.slug === 'string' && raw.slug.trim().length\n ? raw.slug.trim()\n : rawId\n options.push({ value: rawId, label })\n }\n if (options.length) {\n setTagIdToLabel((prev) => {\n let changed = false\n const next = { ...prev }\n for (const option of options) {\n if (next[option.value] !== option.label) {\n next[option.value] = option.label\n changed = true\n }\n }\n return changed ? next : prev\n })\n }\n return options\n } catch (err) {\n console.error('customers.people.list.loadTagOptions', err)\n return []\n }\n }, [setTagIdToLabel, t])\n\n const tagLabelToId = React.useMemo(() => {\n const map: Record<string, string> = {}\n for (const [id, label] of Object.entries(tagIdToLabel)) {\n if (!label) continue\n map[label] = id\n }\n return map\n }, [tagIdToLabel])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadAll() {\n if (cancelled) return\n setDictionaryMaps(createEmptyDictionaryMaps())\n await Promise.all([\n fetchDictionaryEntries('statuses'),\n fetchDictionaryEntries('sources'),\n fetchDictionaryEntries('lifecycle-stages'),\n ])\n }\n loadAll().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [fetchDictionaryEntries, scopeVersion, reloadToken])\n\n const { data: customFieldDefs = [] } = useCustomFieldDefs(\n [E.customers.customer_entity, E.customers.customer_person_profile],\n { keyExtras: [scopeVersion, reloadToken] },\n )\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'status',\n label: t('customers.people.list.filters.status'),\n type: 'select',\n options: dictionaryOptions.statuses,\n loadOptions: () => loadDictionaryOptions('statuses'),\n },\n {\n id: 'source',\n label: t('customers.people.list.filters.source'),\n type: 'select',\n options: dictionaryOptions.sources,\n loadOptions: () => loadDictionaryOptions('sources'),\n },\n {\n id: 'lifecycleStage',\n label: t('customers.people.list.filters.lifecycleStage'),\n type: 'select',\n options: dictionaryOptions.lifecycleStages,\n loadOptions: () => loadDictionaryOptions('lifecycle-stages'),\n },\n {\n id: 'tagIds',\n label: t('customers.people.list.filters.tags'),\n type: 'tags',\n loadOptions: loadTagOptions,\n },\n {\n id: 'createdAt',\n label: t('customers.people.list.filters.createdAt'),\n type: 'dateRange',\n },\n {\n id: 'emailContains',\n label: t('customers.people.list.filters.emailContains'),\n type: 'text',\n placeholder: t('customers.people.list.filters.emailContainsPlaceholder'),\n },\n {\n id: 'hasEmail',\n label: t('customers.people.list.filters.hasEmail'),\n type: 'checkbox',\n },\n {\n id: 'hasPhone',\n label: t('customers.people.list.filters.hasPhone'),\n type: 'checkbox',\n },\n {\n id: 'hasNextInteraction',\n label: t('customers.people.list.filters.hasNextInteraction'),\n type: 'checkbox',\n },\n ], [dictionaryOptions.lifecycleStages, dictionaryOptions.sources, dictionaryOptions.statuses, loadDictionaryOptions, loadTagOptions, t])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(pageSize))\n if (search.trim()) params.set('search', search.trim())\n const status = filterValues.status\n if (typeof status === 'string' && status.trim()) params.set('status', status)\n const source = filterValues.source\n if (typeof source === 'string' && source.trim()) params.set('source', source)\n const lifecycleStage = filterValues.lifecycleStage\n if (typeof lifecycleStage === 'string' && lifecycleStage.trim()) params.set('lifecycleStage', lifecycleStage)\n const createdAt = filterValues.createdAt\n if (createdAt && typeof createdAt === 'object') {\n if (createdAt.from) params.set('createdFrom', createdAt.from)\n if (createdAt.to) params.set('createdTo', createdAt.to)\n }\n const emailContains = filterValues.emailContains\n if (typeof emailContains === 'string' && emailContains.trim()) {\n params.set('emailContains', emailContains.trim())\n }\n const booleanFilters: Array<['hasEmail' | 'hasPhone' | 'hasNextInteraction', string]> = [\n ['hasEmail', 'hasEmail'],\n ['hasPhone', 'hasPhone'],\n ['hasNextInteraction', 'hasNextInteraction'],\n ]\n for (const [key, queryKey] of booleanFilters) {\n const value = filterValues[key]\n if (value === true) params.set(queryKey, 'true')\n if (value === false) params.set(queryKey, 'false')\n }\n const tagLabels = Array.isArray(filterValues.tagIds)\n ? filterValues.tagIds\n .map((value) => (typeof value === 'string' ? value.trim() : String(value || '').trim()))\n .filter((value) => value.length > 0)\n : []\n if (tagLabels.length > 0) {\n const normalizedTagIds = tagLabels\n .map((label) => tagLabelToId[label])\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n if (normalizedTagIds.length === tagLabels.length && normalizedTagIds.length > 0) {\n params.set('tagIds', normalizedTagIds.join(','))\n } else {\n params.set('tagIdsEmpty', 'true')\n }\n }\n Object.entries(filterValues).forEach(([key, value]) => {\n if (!key.startsWith('cf_') || value == null) return\n if (Array.isArray(value)) {\n const normalized = value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item.trim()\n return String(item).trim()\n })\n .filter((item) => item.length > 0)\n if (normalized.length) params.set(key, normalized.join(','))\n } else if (typeof value === 'object') {\n return\n } else if (value !== '') {\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (stringValue) params.set(key, stringValue)\n }\n })\n return params.toString()\n }, [filterValues, page, pageSize, search, tagLabelToId])\n\n const currentParams = React.useMemo(() => Object.fromEntries(new URLSearchParams(queryParams)), [queryParams])\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/people', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/people', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const fallback: PeopleResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<PeopleResponse>(`/api/customers/people?${queryParams}`, undefined, { fallback })\n if (!call.ok) {\n const errorPayload = call.result as { error?: string } | undefined\n const message = typeof errorPayload?.error === 'string' ? errorPayload.error : t('customers.people.list.error.load')\n flash(message, 'error')\n if (!cancelled) setCacheStatus(null)\n return\n }\n const payload = call.result ?? fallback\n if (cancelled) return\n setCacheStatus(call.cacheStatus ?? null)\n const items = Array.isArray(payload.items) ? payload.items : []\n setRows(items.map((item) => mapApiItem(item as Record<string, unknown>)).filter((row): row is PersonRow => !!row))\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n } catch (err) {\n if (!cancelled) {\n setCacheStatus(null)\n const message = err instanceof Error ? err.message : t('customers.people.list.error.load')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (person: PersonRow) => {\n if (!person?.id) return\n const name = person.name || t('customers.people.list.deleteFallbackName')\n const confirmed = await confirm({\n title: t('customers.people.list.deleteConfirm', undefined, { name }),\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n await apiCallOrThrow(\n `/api/customers/people?id=${encodeURIComponent(person.id)}`,\n {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n },\n { errorMessage: t('customers.people.list.deleteError') },\n )\n setRows((prev) => prev.filter((row) => row.id !== person.id))\n setTotal((prev) => Math.max(prev - 1, 0))\n handleRefresh()\n flash(t('customers.people.list.deleteSuccess'), 'success')\n } catch (err) {\n const message = err instanceof Error ? err.message : t('customers.people.list.deleteError')\n flash(message, 'error')\n }\n }, [confirm, handleRefresh, t])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = {}\n Object.entries(values).forEach(([key, value]) => {\n if (value !== undefined) {\n next[key] = value\n }\n })\n const rawTags = Array.isArray(values.tagIds) ? (values.tagIds as string[]) : []\n const sanitizedTags = rawTags\n .map((tag) => (typeof tag === 'string' ? tag.trim() : ''))\n .filter((tag) => tag.length > 0)\n if (sanitizedTags.length) next.tagIds = sanitizedTags\n else delete next.tagIds\n setFilterValues(next)\n setPage(1)\n }, [setFilterValues, setPage])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [setFilterValues, setPage])\n\n const columns = React.useMemo<ColumnDef<PersonRow>[]>(() => {\n const noValue = <span className=\"text-muted-foreground text-sm\">{t('customers.people.list.noValue')}</span>\n const renderDictionaryCell = (kind: DictionaryKindKey, rawValue: string | null | undefined) => (\n <DictionaryValue\n value={rawValue}\n map={dictionaryMaps[kind]}\n fallback={rawValue ? <span>{rawValue}</span> : noValue}\n className=\"text-sm\"\n iconWrapperClassName=\"inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\"\n iconClassName=\"h-4 w-4\"\n colorClassName=\"h-3 w-3 rounded-full\"\n />\n )\n\n const renderCustomFieldCell = (value: unknown) => {\n if (value == null) return noValue\n if (Array.isArray(value)) {\n if (!value.length) return noValue\n const normalized = value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item.trim()\n return String(item).trim()\n })\n .filter((item) => item.length > 0)\n if (!normalized.length) return noValue\n return <span className=\"text-sm\">{normalized.join(', ')}</span>\n }\n if (typeof value === 'boolean') {\n return (\n <span className=\"text-sm\">\n {value\n ? t('customers.people.list.booleanYes', 'Yes')\n : t('customers.people.list.booleanNo', 'No')}\n </span>\n )\n }\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (!stringValue) return noValue\n return <span className=\"text-sm\">{stringValue}</span>\n }\n\n const baseColumns: ColumnDef<PersonRow>[] = [\n {\n accessorKey: 'name',\n header: t('customers.people.list.columns.name'),\n cell: ({ row }) => (\n <Link href={`/backend/customers/people/${row.original.id}`} className=\"font-medium hover:underline\">\n {row.original.name}\n </Link>\n ),\n },\n {\n accessorKey: 'email',\n header: t('customers.people.list.columns.email'),\n cell: ({ row }) => row.original.email || <span className=\"text-muted-foreground text-sm\">{t('customers.people.list.noValue')}</span>,\n },\n {\n accessorKey: 'status',\n header: t('customers.people.list.columns.status'),\n cell: ({ row }) => renderDictionaryCell('statuses', row.original.status),\n },\n {\n accessorKey: 'lifecycleStage',\n header: t('customers.people.list.columns.lifecycleStage'),\n cell: ({ row }) => renderDictionaryCell('lifecycle-stages', row.original.lifecycleStage),\n },\n {\n accessorKey: 'nextInteractionAt',\n header: t('customers.people.list.columns.nextInteraction'),\n meta: {\n tooltipContent: (row: PersonRow) => {\n if (!row.nextInteractionAt) return undefined\n const date = formatDate(row.nextInteractionAt, '')\n const name = row.nextInteractionName || ''\n return [date, name].filter(Boolean).join(' - ')\n },\n },\n cell: ({ row }) =>\n row.original.nextInteractionAt\n ? (\n <div className=\"flex items-start gap-2 text-sm\">\n {row.original.nextInteractionIcon ? (\n <span className=\"mt-0.5 inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\">\n {renderDictionaryIcon(row.original.nextInteractionIcon, 'h-4 w-4')}\n </span>\n ) : null}\n <div className=\"flex flex-col\">\n <span>{formatDate(row.original.nextInteractionAt, t('customers.people.list.noValue'))}</span>\n {row.original.nextInteractionName ? (\n <span className=\"text-xs text-muted-foreground\">{row.original.nextInteractionName}</span>\n ) : null}\n </div>\n {row.original.nextInteractionColor ? (\n <span className=\"mt-1\">\n {renderDictionaryColor(row.original.nextInteractionColor, 'h-3 w-3 rounded-full border border-border')}\n </span>\n ) : null}\n </div>\n )\n : <span className=\"text-muted-foreground text-sm\">{t('customers.people.list.noValue')}</span>,\n },\n {\n accessorKey: 'source',\n header: t('customers.people.list.columns.source'),\n cell: ({ row }) => renderDictionaryCell('sources', row.original.source),\n },\n ]\n\n const customColumns = filterCustomFieldDefs(customFieldDefs, 'list').map<ColumnDef<PersonRow>>((def) => ({\n accessorKey: `cf_${def.key}`,\n header: def.label || def.key,\n cell: ({ getValue }) => renderCustomFieldCell(getValue()),\n }))\n\n return [...baseColumns, ...customColumns]\n }, [customFieldDefs, dictionaryMaps, t])\n\n return (\n <Page>\n <PageBody>\n <DataTable<PersonRow>\n title={t('customers.people.list.title')}\n refreshButton={{\n label: t('customers.people.list.actions.refresh'),\n onRefresh: () => { setSearch(''); setPage(1); handleRefresh() },\n }}\n actions={(\n <Button asChild>\n <Link href=\"/backend/customers/people/create\">\n {t('customers.people.list.actions.new')}\n </Link>\n </Button>\n )}\n columns={columns}\n data={rows}\n exporter={exportConfig}\n searchValue={search}\n onSearchChange={(value) => { setSearch(value); setPage(1) }}\n searchPlaceholder={t('customers.people.list.searchPlaceholder')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n entityIds={[E.customers.customer_entity, E.customers.customer_person_profile]}\n perspective={{ tableId: 'customers.people.list' }}\n onRowClick={(row) => router.push(`/backend/customers/people/${row.id}`)}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'view',\n label: t('customers.people.list.actions.view'),\n onSelect: () => { router.push(`/backend/customers/people/${row.id}`) },\n },\n {\n id: 'open-new-tab',\n label: t('customers.people.list.actions.openInNewTab'),\n onSelect: () => window.open(`/backend/customers/people/${row.id}`, '_blank', 'noopener'),\n },\n {\n id: 'delete',\n label: t('customers.people.list.actions.delete'),\n destructive: true,\n onSelect: () => handleDelete(row),\n },\n ]}\n />\n )}\n pagination={{ page, pageSize, total, totalPages, onPageChange: setPage, cacheStatus }}\n isLoading={isLoading}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
5
+ "mappings": ";AAudoB,cAsFJ,YAtFI;AArdpB,YAAY,WAAW;AACvB,OAAO,UAAU;AACjB,SAAS,iBAAiB;AAC1B,SAAS,MAAM,gBAAgB;AAC/B,SAAS,WAAuC,+BAA+B;AAE/E,SAAS,cAAc;AACvB,SAAS,kBAAkB;AAC3B,SAAS,SAAS,gBAAgB,4BAA4B;AAC9D,SAAS,0BAA0B;AACnC,SAAS,aAAa;AACtB,SAAS,SAAS;AAClB,SAAS,mCAAmC;AAC5C,SAAS,YAAY;AACrB,SAAS,wBAAwB;AAGjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAC/B,SAAS,gCAAgC;AA4BzC,MAAM,wBAAwB;AAE9B,SAAS,4BAAsE;AAC7E,SAAO;AAAA,IACL,UAAU,CAAC;AAAA,IACX,SAAS,CAAC;AAAA,IACV,oBAAoB,CAAC;AAAA,IACrB,iBAAiB,CAAC;AAAA,IAClB,kBAAkB,CAAC;AAAA,IACnB,iBAAiB,CAAC;AAAA,IAClB,mBAAmB,CAAC;AAAA,IACpB,cAAc,CAAC;AAAA,IACf,YAAY,CAAC;AAAA,EACf;AACF;AAEA,SAAS,WAAW,OAAkC,UAA0B;AAC9E,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAG,QAAO;AACzC,SAAO,KAAK,mBAAmB;AACjC;AAEA,SAAS,WAAW,MAAiD;AACnE,QAAM,KAAK,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AACnD,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,OAAO,OAAO,KAAK,iBAAiB,WAAW,KAAK,eAAe;AACzE,QAAM,cAAc,OAAO,KAAK,gBAAgB,WAAW,KAAK,cAAc;AAC9E,QAAM,QAAQ,OAAO,KAAK,kBAAkB,WAAW,KAAK,gBAAgB;AAC5E,QAAM,QAAQ,OAAO,KAAK,kBAAkB,WAAW,KAAK,gBAAgB;AAC5E,QAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAC/D,QAAM,iBAAiB,OAAO,KAAK,oBAAoB,WAAW,KAAK,kBAAkB;AACzF,QAAM,oBAAoB,OAAO,KAAK,wBAAwB,WAAW,KAAK,sBAAsB;AACpG,QAAM,sBAAsB,OAAO,KAAK,0BAA0B,WAAW,KAAK,wBAAwB;AAC1G,QAAM,sBAAsB,OAAO,KAAK,0BAA0B,WAAW,KAAK,wBAAwB;AAC1G,QAAM,uBAAuB,OAAO,KAAK,2BAA2B,WAAW,KAAK,yBAAyB;AAC7G,QAAM,iBAAiB,OAAO,KAAK,oBAAoB,WAAW,KAAK,kBAAkB;AACzF,QAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAC/D,QAAM,eAAwC,CAAC;AAC/C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,IAAI,WAAW,KAAK,GAAG;AACzB,mBAAa,GAAG,IAAI;AAAA,IACtB;AAAA,EACF;AACA,SAAO,wBAAwB;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GAAG,IAAI;AACT;AAEe,SAAR,sBAAuC;AAC5C,QAAM,EAAE,SAAS,qBAAqB,IAAI,iBAAiB;AAC3D,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAsB,CAAC,CAAC;AACtD,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAS,CAAC;AACxC,QAAM,CAAC,QAAQ,IAAI,MAAM,SAAS,EAAE;AACpC,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAS,CAAC;AAC1C,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,CAAC;AACpD,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,EAAE;AAC7C,QAAM,CAAC,cAAc,eAAe,IAAI,MAAM,SAAuB,CAAC,CAAC;AACvE,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAS,IAAI;AACrD,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAS,CAAC;AACtD,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAgC,IAAI;AAChF,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,MAAM,SAAmD,0BAA0B,CAAC;AAChI,QAAM,CAAC,cAAc,eAAe,IAAI,MAAM,SAAiC,CAAC,CAAC;AACjF,QAAM,eAAe,4BAA4B;AACjD,QAAM,cAAc,eAAe;AACnC,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,UAAU;AACzB,QAAM,yBAAyB,MAAM,YAAY,OAAO,SAA4B;AAClF,QAAI;AACF,YAAM,OAAO,MAAM,yBAAyB,aAAa,MAAM,YAAY;AAC3E,wBAAkB,CAAC,UAAU;AAAA,QAC3B,GAAG;AAAA,QACH,CAAC,IAAI,GAAG,KAAK;AAAA,MACf,EAAE;AACF,aAAO,KAAK;AAAA,IACd,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF,GAAG,CAAC,aAAa,YAAY,CAAC;AAC9B,QAAM,wBAAwB,MAAM,YAAY,OAAO,SAAsD;AAC3G,UAAM,UAAU,MAAM,uBAAuB,IAAI;AACjD,WAAO,QAAQ,IAAI,CAAC,WAAW,EAAE,OAAO,MAAM,OAAO,OAAO,MAAM,MAAM,EAAE;AAAA,EAC5E,GAAG,CAAC,sBAAsB,CAAC;AAE3B,QAAM,oBAAoB,MAAM,QAAQ,MAAM;AAC5C,UAAM,YAAY,CAAC,QACjB,OAAO,OAAO,OAAO,CAAC,CAAC,EACpB,IAAI,CAAC,WAAW,EAAE,OAAO,MAAM,OAAO,OAAO,MAAM,MAAM,EAAE,EAC3D,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,cAAc,EAAE,OAAO,QAAW,EAAE,aAAa,OAAO,CAAC,CAAC;AACtF,WAAO;AAAA,MACL,UAAU,UAAU,eAAe,QAAQ;AAAA,MAC3C,SAAS,UAAU,eAAe,OAAO;AAAA,MACzC,iBAAiB,UAAU,eAAe,kBAAkB,CAAC;AAAA,IAC/D;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,iBAAiB,MAAM,YAAY,OAAO,UAA4C;AAC1F,QAAI;AACF,YAAM,SAAS,IAAI,gBAAgB,EAAE,UAAU,MAAM,CAAC;AACtD,YAAM,eAAe,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI;AAChE,UAAI,aAAc,QAAO,IAAI,UAAU,YAAY;AACnD,YAAM,UAAU,MAAM;AAAA,QACpB,uBAAuB,OAAO,SAAS,CAAC;AAAA,QACxC;AAAA,QACA,EAAE,cAAc,EAAE,0CAA0C,sBAAsB,EAAE;AAAA,MACtF;AACA,YAAM,QAAQ,MAAM,QAAQ,SAAS,KAAK,IAAI,QAAQ,QAAQ,CAAC;AAC/D,YAAM,UAA0B,CAAC;AACjC,iBAAW,QAAQ,OAAO;AACxB,YAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AACvC,cAAM,MAAM;AACZ,cAAM,QAAQ,OAAO,IAAI,OAAO,WAC5B,IAAI,KACJ,OAAO,IAAI,UAAU,WACnB,IAAI,QACJ;AACN,YAAI,CAAC,MAAO;AACZ,cAAM,QAAQ,OAAO,IAAI,UAAU,YAAY,IAAI,MAAM,KAAK,EAAE,SAC5D,IAAI,MAAM,KAAK,IACf,OAAO,IAAI,SAAS,YAAY,IAAI,KAAK,KAAK,EAAE,SAC9C,IAAI,KAAK,KAAK,IACd;AACN,gBAAQ,KAAK,EAAE,OAAO,OAAO,MAAM,CAAC;AAAA,MACtC;AACA,UAAI,QAAQ,QAAQ;AAClB,wBAAgB,CAAC,SAAS;AACxB,cAAI,UAAU;AACd,gBAAM,OAAO,EAAE,GAAG,KAAK;AACvB,qBAAW,UAAU,SAAS;AAC5B,gBAAI,KAAK,OAAO,KAAK,MAAM,OAAO,OAAO;AACvC,mBAAK,OAAO,KAAK,IAAI,OAAO;AAC5B,wBAAU;AAAA,YACZ;AAAA,UACF;AACA,iBAAO,UAAU,OAAO;AAAA,QAC1B,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,MAAM,wCAAwC,GAAG;AACzD,aAAO,CAAC;AAAA,IACV;AAAA,EACF,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAEvB,QAAM,eAAe,MAAM,QAAQ,MAAM;AACvC,UAAM,MAA8B,CAAC;AACrC,eAAW,CAAC,IAAI,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AACtD,UAAI,CAAC,MAAO;AACZ,UAAI,KAAK,IAAI;AAAA,IACf;AACA,WAAO;AAAA,EACT,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,UAAU,MAAM;AACpB,QAAI,YAAY;AAChB,mBAAe,UAAU;AACvB,UAAI,UAAW;AACf,wBAAkB,0BAA0B,CAAC;AAC7C,YAAM,QAAQ,IAAI;AAAA,QAChB,uBAAuB,UAAU;AAAA,QACjC,uBAAuB,SAAS;AAAA,QAChC,uBAAuB,kBAAkB;AAAA,MAC3C,CAAC;AAAA,IACH;AACA,YAAQ,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AACxB,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,wBAAwB,cAAc,WAAW,CAAC;AAEtD,QAAM,EAAE,MAAM,kBAAkB,CAAC,EAAE,IAAI;AAAA,IACrC,CAAC,EAAE,UAAU,iBAAiB,EAAE,UAAU,uBAAuB;AAAA,IACjE,EAAE,WAAW,CAAC,cAAc,WAAW,EAAE;AAAA,EAC3C;AAEA,QAAM,UAAU,MAAM,QAAqB,MAAM;AAAA,IAC/C;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,sCAAsC;AAAA,MAC/C,MAAM;AAAA,MACN,SAAS,kBAAkB;AAAA,MAC3B,aAAa,MAAM,sBAAsB,UAAU;AAAA,IACrD;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,sCAAsC;AAAA,MAC/C,MAAM;AAAA,MACN,SAAS,kBAAkB;AAAA,MAC3B,aAAa,MAAM,sBAAsB,SAAS;AAAA,IACpD;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,8CAA8C;AAAA,MACvD,MAAM;AAAA,MACN,SAAS,kBAAkB;AAAA,MAC3B,aAAa,MAAM,sBAAsB,kBAAkB;AAAA,IAC7D;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,oCAAoC;AAAA,MAC7C,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,yCAAyC;AAAA,MAClD,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,6CAA6C;AAAA,MACtD,MAAM;AAAA,MACN,aAAa,EAAE,wDAAwD;AAAA,IACzE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,wCAAwC;AAAA,MACjD,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,wCAAwC;AAAA,MACjD,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,kDAAkD;AAAA,MAC3D,MAAM;AAAA,IACR;AAAA,EACF,GAAG,CAAC,kBAAkB,iBAAiB,kBAAkB,SAAS,kBAAkB,UAAU,uBAAuB,gBAAgB,CAAC,CAAC;AAEvI,QAAM,cAAc,MAAM,QAAQ,MAAM;AACtC,UAAM,SAAS,IAAI,gBAAgB;AACnC,WAAO,IAAI,QAAQ,OAAO,IAAI,CAAC;AAC/B,WAAO,IAAI,YAAY,OAAO,QAAQ,CAAC;AACvC,QAAI,OAAO,KAAK,EAAG,QAAO,IAAI,UAAU,OAAO,KAAK,CAAC;AACrD,UAAM,SAAS,aAAa;AAC5B,QAAI,OAAO,WAAW,YAAY,OAAO,KAAK,EAAG,QAAO,IAAI,UAAU,MAAM;AAC5E,UAAM,SAAS,aAAa;AAC5B,QAAI,OAAO,WAAW,YAAY,OAAO,KAAK,EAAG,QAAO,IAAI,UAAU,MAAM;AAC5E,UAAM,iBAAiB,aAAa;AACpC,QAAI,OAAO,mBAAmB,YAAY,eAAe,KAAK,EAAG,QAAO,IAAI,kBAAkB,cAAc;AAC5G,UAAM,YAAY,aAAa;AAC/B,QAAI,aAAa,OAAO,cAAc,UAAU;AAC9C,UAAI,UAAU,KAAM,QAAO,IAAI,eAAe,UAAU,IAAI;AAC5D,UAAI,UAAU,GAAI,QAAO,IAAI,aAAa,UAAU,EAAE;AAAA,IACxD;AACA,UAAM,gBAAgB,aAAa;AACnC,QAAI,OAAO,kBAAkB,YAAY,cAAc,KAAK,GAAG;AAC7D,aAAO,IAAI,iBAAiB,cAAc,KAAK,CAAC;AAAA,IAClD;AACA,UAAM,iBAAkF;AAAA,MACtF,CAAC,YAAY,UAAU;AAAA,MACvB,CAAC,YAAY,UAAU;AAAA,MACvB,CAAC,sBAAsB,oBAAoB;AAAA,IAC7C;AACA,eAAW,CAAC,KAAK,QAAQ,KAAK,gBAAgB;AAC5C,YAAM,QAAQ,aAAa,GAAG;AAC9B,UAAI,UAAU,KAAM,QAAO,IAAI,UAAU,MAAM;AAC/C,UAAI,UAAU,MAAO,QAAO,IAAI,UAAU,OAAO;AAAA,IACnD;AACA,UAAM,YAAY,MAAM,QAAQ,aAAa,MAAM,IAC/C,aAAa,OACV,IAAI,CAAC,UAAW,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI,OAAO,SAAS,EAAE,EAAE,KAAK,CAAE,EACtF,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC,IACrC,CAAC;AACL,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,mBAAmB,UACtB,IAAI,CAAC,UAAU,aAAa,KAAK,CAAC,EAClC,OAAO,CAAC,OAAqB,OAAO,OAAO,YAAY,GAAG,SAAS,CAAC;AACvE,UAAI,iBAAiB,WAAW,UAAU,UAAU,iBAAiB,SAAS,GAAG;AAC/E,eAAO,IAAI,UAAU,iBAAiB,KAAK,GAAG,CAAC;AAAA,MACjD,OAAO;AACL,eAAO,IAAI,eAAe,MAAM;AAAA,MAClC;AAAA,IACF;AACA,WAAO,QAAQ,YAAY,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACrD,UAAI,CAAC,IAAI,WAAW,KAAK,KAAK,SAAS,KAAM;AAC7C,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,cAAM,aAAa,MAChB,IAAI,CAAC,SAAS;AACb,cAAI,QAAQ,KAAM,QAAO;AACzB,cAAI,OAAO,SAAS,SAAU,QAAO,KAAK,KAAK;AAC/C,iBAAO,OAAO,IAAI,EAAE,KAAK;AAAA,QAC3B,CAAC,EACA,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AACnC,YAAI,WAAW,OAAQ,QAAO,IAAI,KAAK,WAAW,KAAK,GAAG,CAAC;AAAA,MAC7D,WAAW,OAAO,UAAU,UAAU;AACpC;AAAA,MACF,WAAW,UAAU,IAAI;AACvB,cAAM,cAAc,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI,OAAO,KAAK;AAC3E,YAAI,YAAa,QAAO,IAAI,KAAK,WAAW;AAAA,MAC9C;AAAA,IACF,CAAC;AACD,WAAO,OAAO,SAAS;AAAA,EACzB,GAAG,CAAC,cAAc,MAAM,UAAU,QAAQ,YAAY,CAAC;AAEvD,QAAM,gBAAgB,MAAM,QAAQ,MAAM,OAAO,YAAY,IAAI,gBAAgB,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC;AAC7G,QAAM,eAAe,MAAM,QAAQ,OAAO;AAAA,IACxC,MAAM;AAAA,MACJ,QAAQ,CAAC,WACP,mBAAmB,oBAAoB,EAAE,GAAG,eAAe,aAAa,OAAO,GAAG,MAAM;AAAA,IAC5F;AAAA,IACA,MAAM;AAAA,MACJ,QAAQ,CAAC,WACP,mBAAmB,oBAAoB,EAAE,GAAG,eAAe,aAAa,QAAQ,KAAK,OAAO,GAAG,MAAM;AAAA,IACzG;AAAA,EACF,IAAI,CAAC,aAAa,CAAC;AAEnB,QAAM,UAAU,MAAM;AACpB,QAAI,YAAY;AAChB,mBAAe,OAAO;AACpB,mBAAa,IAAI;AACjB,qBAAe,IAAI;AACnB,UAAI;AACF,cAAM,WAA2B,EAAE,OAAO,CAAC,GAAG,OAAO,GAAG,YAAY,EAAE;AACtE,cAAM,OAAO,MAAM,QAAwB,yBAAyB,WAAW,IAAI,QAAW,EAAE,SAAS,CAAC;AAC1G,YAAI,CAAC,KAAK,IAAI;AACZ,gBAAM,eAAe,KAAK;AAC1B,gBAAM,UAAU,OAAO,cAAc,UAAU,WAAW,aAAa,QAAQ,EAAE,kCAAkC;AACnH,gBAAM,SAAS,OAAO;AACtB,cAAI,CAAC,UAAW,gBAAe,IAAI;AACnC;AAAA,QACF;AACA,cAAM,UAAU,KAAK,UAAU;AAC/B,YAAI,UAAW;AACf,uBAAe,KAAK,eAAe,IAAI;AACvC,cAAM,QAAQ,MAAM,QAAQ,QAAQ,KAAK,IAAI,QAAQ,QAAQ,CAAC;AAC9D,gBAAQ,MAAM,IAAI,CAAC,SAAS,WAAW,IAA+B,CAAC,EAAE,OAAO,CAAC,QAA0B,CAAC,CAAC,GAAG,CAAC;AACjH,iBAAS,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,MAAM,MAAM;AACzE,sBAAc,OAAO,QAAQ,eAAe,WAAW,QAAQ,aAAa,CAAC;AAAA,MAC/E,SAAS,KAAK;AACZ,YAAI,CAAC,WAAW;AACd,yBAAe,IAAI;AACnB,gBAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,EAAE,kCAAkC;AACzF,gBAAM,SAAS,OAAO;AAAA,QACxB;AAAA,MACF,UAAE;AACA,YAAI,CAAC,UAAW,cAAa,KAAK;AAAA,MACpC;AAAA,IACF;AACA,SAAK;AACL,WAAO,MAAM;AAAE,kBAAY;AAAA,IAAK;AAAA,EAClC,GAAG,CAAC,aAAa,aAAa,cAAc,CAAC,CAAC;AAE9C,QAAM,gBAAgB,MAAM,YAAY,MAAM;AAC5C,mBAAe,CAAC,UAAU,QAAQ,CAAC;AAAA,EACrC,GAAG,CAAC,CAAC;AAEL,QAAM,eAAe,MAAM,YAAY,OAAO,WAAsB;AAClE,QAAI,CAAC,QAAQ,GAAI;AACjB,UAAM,OAAO,OAAO,QAAQ,EAAE,0CAA0C;AACxE,UAAM,YAAY,MAAM,QAAQ;AAAA,MAC9B,OAAO,EAAE,uCAAuC,QAAW,EAAE,KAAK,CAAC;AAAA,MACnE,SAAS;AAAA,IACX,CAAC;AACD,QAAI,CAAC,UAAW;AAChB,QAAI;AACF,YAAM;AAAA,QACJ,4BAA4B,mBAAmB,OAAO,EAAE,CAAC;AAAA,QACzD;AAAA,UACE,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAChD;AAAA,QACA,EAAE,cAAc,EAAE,mCAAmC,EAAE;AAAA,MACzD;AACA,cAAQ,CAAC,SAAS,KAAK,OAAO,CAAC,QAAQ,IAAI,OAAO,OAAO,EAAE,CAAC;AAC5D,eAAS,CAAC,SAAS,KAAK,IAAI,OAAO,GAAG,CAAC,CAAC;AACxC,oBAAc;AACd,YAAM,EAAE,qCAAqC,GAAG,SAAS;AAAA,IAC3D,SAAS,KAAK;AACZ,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,EAAE,mCAAmC;AAC1F,YAAM,SAAS,OAAO;AAAA,IACxB;AAAA,EACF,GAAG,CAAC,SAAS,eAAe,CAAC,CAAC;AAE9B,QAAM,qBAAqB,MAAM,YAAY,CAAC,WAAyB;AACrE,UAAM,OAAqB,CAAC;AAC5B,WAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAC/C,UAAI,UAAU,QAAW;AACvB,aAAK,GAAG,IAAI;AAAA,MACd;AAAA,IACF,CAAC;AACD,UAAM,UAAU,MAAM,QAAQ,OAAO,MAAM,IAAK,OAAO,SAAsB,CAAC;AAC9E,UAAM,gBAAgB,QACnB,IAAI,CAAC,QAAS,OAAO,QAAQ,WAAW,IAAI,KAAK,IAAI,EAAG,EACxD,OAAO,CAAC,QAAQ,IAAI,SAAS,CAAC;AACjC,QAAI,cAAc,OAAQ,MAAK,SAAS;AAAA,QACnC,QAAO,KAAK;AACjB,oBAAgB,IAAI;AACpB,YAAQ,CAAC;AAAA,EACX,GAAG,CAAC,iBAAiB,OAAO,CAAC;AAE7B,QAAM,qBAAqB,MAAM,YAAY,MAAM;AACjD,oBAAgB,CAAC,CAAC;AAClB,YAAQ,CAAC;AAAA,EACX,GAAG,CAAC,iBAAiB,OAAO,CAAC;AAE7B,QAAM,UAAU,MAAM,QAAgC,MAAM;AAC1D,UAAM,UAAU,oBAAC,UAAK,WAAU,iCAAiC,YAAE,+BAA+B,GAAE;AACpG,UAAM,uBAAuB,CAAC,MAAyB,aACrD;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,KAAK,eAAe,IAAI;AAAA,QACxB,UAAU,WAAW,oBAAC,UAAM,oBAAS,IAAU;AAAA,QAC/C,WAAU;AAAA,QACV,sBAAqB;AAAA,QACrB,eAAc;AAAA,QACd,gBAAe;AAAA;AAAA,IACjB;AAGF,UAAM,wBAAwB,CAAC,UAAmB;AAChD,UAAI,SAAS,KAAM,QAAO;AAC1B,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,cAAM,aAAa,MAChB,IAAI,CAAC,SAAS;AACb,cAAI,QAAQ,KAAM,QAAO;AACzB,cAAI,OAAO,SAAS,SAAU,QAAO,KAAK,KAAK;AAC/C,iBAAO,OAAO,IAAI,EAAE,KAAK;AAAA,QAC3B,CAAC,EACA,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AACnC,YAAI,CAAC,WAAW,OAAQ,QAAO;AAC/B,eAAO,oBAAC,UAAK,WAAU,WAAW,qBAAW,KAAK,IAAI,GAAE;AAAA,MAC1D;AACA,UAAI,OAAO,UAAU,WAAW;AAC9B,eACE,oBAAC,UAAK,WAAU,WACb,kBACG,EAAE,oCAAoC,KAAK,IAC3C,EAAE,mCAAmC,IAAI,GAC/C;AAAA,MAEJ;AACA,YAAM,cAAc,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI,OAAO,KAAK;AAC3E,UAAI,CAAC,YAAa,QAAO;AACzB,aAAO,oBAAC,UAAK,WAAU,WAAW,uBAAY;AAAA,IAChD;AAEA,UAAM,cAAsC;AAAA,MAC1C;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,oCAAoC;AAAA,QAC9C,MAAM,CAAC,EAAE,IAAI,MACX,oBAAC,QAAK,MAAM,6BAA6B,IAAI,SAAS,EAAE,IAAI,WAAU,+BACnE,cAAI,SAAS,MAChB;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,qCAAqC;AAAA,QAC/C,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,SAAS,oBAAC,UAAK,WAAU,iCAAiC,YAAE,+BAA+B,GAAE;AAAA,MAC/H;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,sCAAsC;AAAA,QAChD,MAAM,CAAC,EAAE,IAAI,MAAM,qBAAqB,YAAY,IAAI,SAAS,MAAM;AAAA,MACzE;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,8CAA8C;AAAA,QACxD,MAAM,CAAC,EAAE,IAAI,MAAM,qBAAqB,oBAAoB,IAAI,SAAS,cAAc;AAAA,MACzF;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,+CAA+C;AAAA,QACzD,MAAM;AAAA,UACJ,gBAAgB,CAAC,QAAmB;AAClC,gBAAI,CAAC,IAAI,kBAAmB,QAAO;AACnC,kBAAM,OAAO,WAAW,IAAI,mBAAmB,EAAE;AACjD,kBAAM,OAAO,IAAI,uBAAuB;AACxC,mBAAO,CAAC,MAAM,IAAI,EAAE,OAAO,OAAO,EAAE,KAAK,KAAK;AAAA,UAChD;AAAA,QACF;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MACX,IAAI,SAAS,oBAET,qBAAC,SAAI,WAAU,kCACZ;AAAA,cAAI,SAAS,sBACZ,oBAAC,UAAK,WAAU,+FACb,+BAAqB,IAAI,SAAS,qBAAqB,SAAS,GACnE,IACE;AAAA,UACJ,qBAAC,SAAI,WAAU,iBACb;AAAA,gCAAC,UAAM,qBAAW,IAAI,SAAS,mBAAmB,EAAE,+BAA+B,CAAC,GAAE;AAAA,YACrF,IAAI,SAAS,sBACZ,oBAAC,UAAK,WAAU,iCAAiC,cAAI,SAAS,qBAAoB,IAChF;AAAA,aACN;AAAA,UACC,IAAI,SAAS,uBACZ,oBAAC,UAAK,WAAU,QACb,gCAAsB,IAAI,SAAS,sBAAsB,2CAA2C,GACvG,IACE;AAAA,WACN,IAEA,oBAAC,UAAK,WAAU,iCAAiC,YAAE,+BAA+B,GAAE;AAAA,MAC5F;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,sCAAsC;AAAA,QAChD,MAAM,CAAC,EAAE,IAAI,MAAM,qBAAqB,WAAW,IAAI,SAAS,MAAM;AAAA,MACxE;AAAA,IACF;AAEA,UAAM,gBAAgB,sBAAsB,iBAAiB,MAAM,EAAE,IAA0B,CAAC,SAAS;AAAA,MACvG,aAAa,MAAM,IAAI,GAAG;AAAA,MAC1B,QAAQ,IAAI,SAAS,IAAI;AAAA,MACzB,MAAM,CAAC,EAAE,SAAS,MAAM,sBAAsB,SAAS,CAAC;AAAA,IAC1D,EAAE;AAEF,WAAO,CAAC,GAAG,aAAa,GAAG,aAAa;AAAA,EAC1C,GAAG,CAAC,iBAAiB,gBAAgB,CAAC,CAAC;AAEvC,SACE,qBAAC,QACC;AAAA,wBAAC,YACC;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,6BAA6B;AAAA,QACtC,eAAe;AAAA,UACb,OAAO,EAAE,uCAAuC;AAAA,UAChD,WAAW,MAAM;AAAE,sBAAU,EAAE;AAAG,oBAAQ,CAAC;AAAG,0BAAc;AAAA,UAAE;AAAA,QAChE;AAAA,QACA,SACE,oBAAC,UAAO,SAAO,MACb,8BAAC,QAAK,MAAK,oCACR,YAAE,mCAAmC,GACxC,GACF;AAAA,QAEF;AAAA,QACA,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,QACb,gBAAgB,CAAC,UAAU;AAAE,oBAAU,KAAK;AAAG,kBAAQ,CAAC;AAAA,QAAE;AAAA,QAC1D,mBAAmB,EAAE,yCAAyC;AAAA,QAC9D;AAAA,QACA;AAAA,QACA,gBAAgB;AAAA,QAChB,gBAAgB;AAAA,QAChB,WAAW,CAAC,EAAE,UAAU,iBAAiB,EAAE,UAAU,uBAAuB;AAAA,QAC5E,aAAa,EAAE,SAAS,wBAAwB;AAAA,QAChD,YAAY,CAAC,QAAQ,OAAO,KAAK,6BAA6B,IAAI,EAAE,EAAE;AAAA,QACtE,YAAY,CAAC,QACX;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL;AAAA,gBACE,IAAI;AAAA,gBACJ,OAAO,EAAE,oCAAoC;AAAA,gBAC7C,UAAU,MAAM;AAAE,yBAAO,KAAK,6BAA6B,IAAI,EAAE,EAAE;AAAA,gBAAE;AAAA,cACvE;AAAA,cACA;AAAA,gBACE,IAAI;AAAA,gBACJ,OAAO,EAAE,4CAA4C;AAAA,gBACrD,UAAU,MAAM,OAAO,KAAK,6BAA6B,IAAI,EAAE,IAAI,UAAU,UAAU;AAAA,cACzF;AAAA,cACA;AAAA,gBACE,IAAI;AAAA,gBACJ,OAAO,EAAE,sCAAsC;AAAA,gBAC/C,aAAa;AAAA,gBACb,UAAU,MAAM,aAAa,GAAG;AAAA,cAClC;AAAA,YACF;AAAA;AAAA,QACF;AAAA,QAEF,YAAY,EAAE,MAAM,UAAU,OAAO,YAAY,cAAc,SAAS,YAAY;AAAA,QACpF;AAAA;AAAA,IACF,GACF;AAAA,IACC;AAAA,KACH;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -6,7 +6,7 @@ import { useRouter } from "next/navigation";
6
6
  import ReactMarkdown from "react-markdown";
7
7
  import remarkGfm from "remark-gfm";
8
8
  import { Page, PageBody } from "@open-mercato/ui/backend/Page";
9
- import { DataTable } from "@open-mercato/ui/backend/DataTable";
9
+ import { DataTable, withDataTableNamespaces } from "@open-mercato/ui/backend/DataTable";
10
10
  import { RowActions } from "@open-mercato/ui/backend/RowActions";
11
11
  import { Button } from "@open-mercato/ui/primitives/button";
12
12
  import { readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
@@ -188,13 +188,13 @@ function mapRuleSet(item) {
188
188
  const description = typeof item.description === "string" ? item.description : null;
189
189
  const timezone = typeof item.timezone === "string" ? item.timezone : "UTC";
190
190
  const updatedAt = typeof item.updatedAt === "string" ? item.updatedAt : typeof item.updated_at === "string" ? item.updated_at : null;
191
- return {
191
+ return withDataTableNamespaces({
192
192
  id,
193
193
  name,
194
194
  description,
195
195
  timezone,
196
196
  updatedAt
197
- };
197
+ }, item);
198
198
  }
199
199
  export {
200
200
  PlannerAvailabilityRuleSetsPage as default