61 lines
1.9 KiB
TypeScript
61 lines
1.9 KiB
TypeScript
// A party's contact points. Part of a page's view (F10): it holds no state, and every string is passed in.
|
|
|
|
import { PageSection, type ResourceColumn, ResourceList } from "@conusai-kit/ui/patterns"
|
|
import type { ReactElement } from "react"
|
|
import type { ContactView } from "../contract/index.js"
|
|
|
|
export interface ContactsLabels {
|
|
readonly title: string
|
|
/** How many contact points, already filled with the plural form. */
|
|
readonly count: string
|
|
readonly caption: string
|
|
readonly empty: string
|
|
readonly kind: string
|
|
readonly value: string
|
|
readonly purposes: string
|
|
readonly primary: string
|
|
readonly erased: string
|
|
readonly yes: string
|
|
readonly no: string
|
|
readonly kinds: Readonly<Record<ContactView["kind"], string>>
|
|
readonly purposeNames: Readonly<Record<ContactView["purposes"][number], string>>
|
|
}
|
|
|
|
export function Contacts({
|
|
contacts,
|
|
labels,
|
|
}: {
|
|
contacts: readonly ContactView[]
|
|
labels: ContactsLabels
|
|
}): ReactElement {
|
|
const columns: ResourceColumn<ContactView>[] = [
|
|
{ id: "kind", header: labels.kind, cell: (contact) => labels.kinds[contact.kind] },
|
|
{
|
|
id: "value",
|
|
header: labels.value,
|
|
wrap: true,
|
|
cell: (contact) => (contact.erased ? labels.erased : contact.value),
|
|
},
|
|
{
|
|
id: "purposes",
|
|
header: labels.purposes,
|
|
wrap: true,
|
|
cell: (contact) => contact.purposes.map((purpose) => labels.purposeNames[purpose]).join(", "),
|
|
},
|
|
{ id: "isPrimary", header: labels.primary, cell: (contact) => (contact.isPrimary ? labels.yes : labels.no) },
|
|
]
|
|
return (
|
|
<PageSection title={labels.title}>
|
|
<ResourceList
|
|
label={labels.caption}
|
|
columns={columns}
|
|
data={contacts}
|
|
rowId={(contact) => contact.contactId}
|
|
count={contacts.length === 0 ? undefined : labels.count}
|
|
rowLabel={(contact) => labels.kinds[contact.kind]}
|
|
empty={{ title: labels.empty }}
|
|
/>
|
|
</PageSection>
|
|
)
|
|
}
|