@open-mercato/core 0.7.1-develop.7122.1.421cefe668 → 0.7.1-develop.7130.1.fef2396fd8
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.
- package/.turbo/turbo-build.log +1 -1
- package/dist/modules/customers/api/deals/aggregate/route.js +85 -0
- package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js +5 -117
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +1 -3
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +33 -9
- package/dist/modules/customers/commands/deals.js.map +3 -3
- package/dist/modules/customers/components/AddressEditor.js +71 -1
- package/dist/modules/customers/components/AddressEditor.js.map +2 -2
- package/dist/modules/customers/utils/addressFormat.js +18 -2
- package/dist/modules/customers/utils/addressFormat.js.map +2 -2
- package/dist/modules/sales/components/documents/AddressesSection.js +17 -2
- package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentForm.js +7 -24
- package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
- package/dist/modules/sales/components/documents/normalizeAddressDraft.js +29 -0
- package/dist/modules/sales/components/documents/normalizeAddressDraft.js.map +7 -0
- package/package.json +7 -7
- package/src/modules/customers/api/deals/aggregate/route.ts +102 -0
- package/src/modules/customers/backend/customers/deals/[id]/hooks/types.ts +0 -23
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.ts +11 -172
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +1 -1
- package/src/modules/customers/commands/deals.ts +84 -9
- package/src/modules/customers/components/AddressEditor.tsx +116 -1
- package/src/modules/customers/i18n/de.json +6 -0
- package/src/modules/customers/i18n/en.json +6 -0
- package/src/modules/customers/i18n/es.json +6 -0
- package/src/modules/customers/i18n/ko.json +6 -0
- package/src/modules/customers/i18n/pl.json +6 -0
- package/src/modules/customers/utils/addressFormat.tsx +59 -1
- package/src/modules/sales/components/documents/AddressesSection.tsx +48 -5
- package/src/modules/sales/components/documents/SalesDocumentForm.tsx +5 -23
- package/src/modules/sales/components/documents/normalizeAddressDraft.ts +29 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/customers/components/AddressEditor.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { usePathname, useSearchParams } from 'next/navigation'\nimport { Plus, Settings } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@open-mercato/ui/primitives/dialog'\nimport { buildCountryOptions } from '@open-mercato/shared/lib/location/countries'\nimport { buildHrefWithReturnTo } from '@open-mercato/shared/lib/navigation/returnTo'\nimport type { AddressFormatStrategy } from '../utils/addressFormat'\nimport { useAddressTypes } from './detail/hooks/useAddressTypes'\n\ntype Translator = (key: string, fallback?: string, params?: Record<string, string | number>) => string\n\nexport type AddressEditorDraft = {\n name: string\n purpose: string\n companyName: string\n addressLine1: string\n addressLine2: string\n buildingNumber: string\n flatNumber: string\n city: string\n region: string\n postalCode: string\n country: string\n latitude?: string\n longitude?: string\n isPrimary: boolean\n}\n\nexport type AddressEditorField =\n | 'name'\n | 'purpose'\n | 'companyName'\n | 'addressLine1'\n | 'addressLine2'\n | 'buildingNumber'\n | 'flatNumber'\n | 'city'\n | 'region'\n | 'postalCode'\n | 'country'\n | 'latitude'\n | 'longitude'\n | 'isPrimary'\n\ntype AddressEditorProps = {\n value: AddressEditorDraft\n onChange: (next: AddressEditorDraft) => void\n format: AddressFormatStrategy\n t: Translator\n disabled?: boolean\n errors?: Partial<Record<AddressEditorField, string>>\n hidePrimaryToggle?: boolean\n showFormatHint?: boolean\n showCoordinateFields?: boolean\n}\n\nexport function AddressEditor({\n value,\n onChange,\n format,\n t,\n disabled = false,\n errors = {},\n hidePrimaryToggle = false,\n showFormatHint = true,\n showCoordinateFields = false,\n}: AddressEditorProps) {\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const { options: addressTypes, loading: addressTypesLoading, error: addressTypeError, createType } = useAddressTypes(t)\n const [typeDialogOpen, setTypeDialogOpen] = React.useState(false)\n const [typeValue, setTypeValue] = React.useState('')\n const [typeFormError, setTypeFormError] = React.useState<string | null>(null)\n const [countryDialogOpen, setCountryDialogOpen] = React.useState(false)\n const [countryQuery, setCountryQuery] = React.useState('')\n\n const countryOptions = React.useMemo(\n () =>\n buildCountryOptions({\n transformLabel: (code, fallback) => t(`customers.countries.${code.toLowerCase()}`, fallback ?? code),\n }),\n [t],\n )\n\n const current: AddressEditorDraft = {\n name: value.name ?? '',\n purpose: value.purpose ?? '',\n companyName: value.companyName ?? '',\n addressLine1: value.addressLine1 ?? '',\n addressLine2: value.addressLine2 ?? '',\n buildingNumber: value.buildingNumber ?? '',\n flatNumber: value.flatNumber ?? '',\n city: value.city ?? '',\n region: value.region ?? '',\n postalCode: value.postalCode ?? '',\n country: value.country ?? '',\n ...(showCoordinateFields\n ? { latitude: value.latitude ?? '', longitude: value.longitude ?? '' }\n : {}),\n isPrimary: value.isPrimary ?? false,\n }\n\n const update = React.useCallback(\n (key: keyof AddressEditorDraft, nextValue: string | boolean) => {\n onChange({ ...current, [key]: nextValue })\n },\n [current, onChange],\n )\n\n const filteredCountryOptions = React.useMemo(() => {\n const query = countryQuery.trim().toLowerCase()\n if (!query.length) return countryOptions\n return countryOptions.filter(\n (option) => option.label.toLowerCase().includes(query) || option.code.toLowerCase().includes(query),\n )\n }, [countryOptions, countryQuery])\n\n const selectedCountry = React.useMemo(() => {\n const code = (current.country ?? '').toUpperCase()\n if (!code.length) return null\n return countryOptions.find((option) => option.code === code) ?? null\n }, [countryOptions, current.country])\n const returnTo = React.useMemo(() => {\n const query = searchParams?.toString() ?? ''\n if (!pathname) return null\n return query.length ? `${pathname}?${query}` : pathname\n }, [pathname, searchParams])\n const manageAddressTypesHref = React.useMemo(\n () => buildHrefWithReturnTo('/backend/config/customers', returnTo),\n [returnTo],\n )\n\n const handleTypeSubmit = React.useCallback(\n async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n const trimmed = typeValue.trim()\n if (!trimmed.length) {\n setTypeFormError(t('customers.people.detail.addresses.types.emptyError', 'Please provide a value'))\n return\n }\n setTypeFormError(null)\n await createType(trimmed)\n setTypeDialogOpen(false)\n setTypeValue('')\n },\n [createType, t, typeValue],\n )\n\n const inputClass = (field: AddressEditorField) =>\n [\n 'w-full rounded-md border px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring',\n errors[field] ? 'border-status-error-border focus:ring-status-error-border' : 'border-input bg-background',\n ].join(' ')\n\n return (\n <div className=\"space-y-3\">\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <Input\n className={inputClass('name')}\n placeholder={t('customers.people.detail.addresses.fields.label', 'Label')}\n value={current.name}\n onChange={(evt) => update('name', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.name ? 'true' : undefined}\n />\n <div className=\"flex gap-2\">\n <Select\n value={current.purpose || undefined}\n onValueChange={(next) => update('purpose', next ?? '')}\n disabled={disabled}\n >\n <SelectTrigger\n className={errors.purpose ? 'border-destructive' : undefined}\n aria-invalid={errors.purpose ? 'true' : undefined}\n >\n <SelectValue\n placeholder={\n addressTypesLoading\n ? t('customers.people.detail.addresses.types.loading', 'Loading\u2026')\n : t('customers.people.detail.addresses.types.placeholder', 'Address type')\n }\n />\n </SelectTrigger>\n <SelectContent>\n {addressTypes.map((entry) => (\n <SelectItem key={entry.value} value={entry.value}>\n {entry.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Dialog open={typeDialogOpen} onOpenChange={setTypeDialogOpen}>\n <DialogTrigger asChild>\n <Button type=\"button\" variant=\"outline\" size=\"icon\" className=\"shrink-0\" disabled={disabled}>\n <Plus className=\"h-4 w-4\" />\n </Button>\n </DialogTrigger>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>{t('customers.people.detail.addresses.types.add', 'Add address type')}</DialogTitle>\n <DialogDescription>\n {t('customers.people.detail.addresses.types.addHint', 'Create a new address type for reuse.')}\n </DialogDescription>\n </DialogHeader>\n <form className=\"space-y-3\" onSubmit={handleTypeSubmit}>\n <Input\n autoFocus\n value={typeValue}\n onChange={(evt) => {\n setTypeValue(evt.target.value)\n if (typeFormError) setTypeFormError(null)\n }}\n placeholder={t('customers.people.detail.addresses.types.placeholder', 'Address type')}\n disabled={disabled}\n aria-invalid={typeFormError ? 'true' : undefined}\n />\n {typeFormError ? <p className=\"text-sm text-destructive\">{typeFormError}</p> : null}\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setTypeDialogOpen(false)} disabled={disabled}>\n {t('customers.people.detail.addresses.types.cancel', 'Cancel')}\n </Button>\n <Button type=\"submit\" disabled={disabled || !typeValue.trim()}>\n {t('customers.people.detail.addresses.types.save', 'Save')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n <Button\n asChild\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"shrink-0\"\n disabled={disabled}\n title={t('customers.people.detail.addresses.types.manage', 'Manage address types')}\n >\n <Link\n href={manageAddressTypesHref}\n aria-label={t('customers.people.detail.addresses.types.manage', 'Manage address types')}\n >\n <Settings className=\"h-4 w-4\" />\n </Link>\n </Button>\n </div>\n </div>\n {errors.purpose ? <p className=\"text-xs text-destructive\">{errors.purpose}</p> : null}\n {addressTypeError ? <p className=\"text-xs text-destructive\">{addressTypeError}</p> : null}\n <Input\n className={inputClass('companyName')}\n placeholder={t('customers.people.detail.addresses.fields.companyName', 'Company name')}\n value={current.companyName}\n onChange={(evt) => update('companyName', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.companyName ? 'true' : undefined}\n />\n {showFormatHint ? (\n <p className=\"text-xs text-muted-foreground\">\n {format === 'street_first'\n ? t('customers.people.detail.addresses.streetFormatHint', 'Street-first layout is active.')\n : t('customers.people.detail.addresses.lineFormatHint', 'Address-line layout is active.')}\n </p>\n ) : null}\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <Input\n className={inputClass('addressLine1')}\n placeholder={\n format === 'street_first'\n ? t('customers.people.detail.addresses.fields.street', 'Street')\n : t('customers.people.detail.addresses.fields.line1', 'Address line 1')\n }\n value={current.addressLine1}\n onChange={(evt) => update('addressLine1', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.addressLine1 ? 'true' : undefined}\n />\n {errors.addressLine1 ? <p className=\"text-xs text-destructive sm:col-span-2\">{errors.addressLine1}</p> : null}\n {format === 'street_first' ? (\n <>\n <Input\n className={inputClass('buildingNumber')}\n placeholder={t('customers.people.detail.addresses.fields.buildingNumber', 'Building number')}\n value={current.buildingNumber}\n onChange={(evt) => update('buildingNumber', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.buildingNumber ? 'true' : undefined}\n />\n <Input\n className={inputClass('flatNumber')}\n placeholder={t('customers.people.detail.addresses.fields.flatNumber', 'Flat number')}\n value={current.flatNumber}\n onChange={(evt) => update('flatNumber', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.flatNumber ? 'true' : undefined}\n />\n <Input\n className={inputClass('addressLine2')}\n placeholder={t('customers.people.detail.addresses.fields.streetExtra', 'Address line 2')}\n value={current.addressLine2}\n onChange={(evt) => update('addressLine2', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.addressLine2 ? 'true' : undefined}\n />\n {errors.addressLine2 ? <p className=\"text-xs text-destructive sm:col-span-2\">{errors.addressLine2}</p> : null}\n </>\n ) : (\n <>\n <Input\n className={inputClass('addressLine2')}\n placeholder={t('customers.people.detail.addresses.fields.line2', 'Address line 2')}\n value={current.addressLine2}\n onChange={(evt) => update('addressLine2', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.addressLine2 ? 'true' : undefined}\n />\n {errors.addressLine2 ? <p className=\"text-xs text-destructive sm:col-span-2\">{errors.addressLine2}</p> : null}\n </>\n )}\n <Input\n className={inputClass('city')}\n placeholder={t('customers.people.detail.addresses.fields.city', 'City')}\n value={current.city}\n onChange={(evt) => update('city', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.city ? 'true' : undefined}\n />\n {errors.city ? <p className=\"text-xs text-destructive\">{errors.city}</p> : null}\n <Input\n className={inputClass('region')}\n placeholder={t('customers.people.detail.addresses.fields.region', 'Region/state')}\n value={current.region}\n onChange={(evt) => update('region', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.region ? 'true' : undefined}\n />\n {errors.region ? <p className=\"text-xs text-destructive\">{errors.region}</p> : null}\n <Input\n className={inputClass('postalCode')}\n placeholder={t('customers.people.detail.addresses.fields.postalCode', 'Postal code')}\n value={current.postalCode}\n onChange={(evt) => update('postalCode', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.postalCode ? 'true' : undefined}\n />\n {errors.postalCode ? <p className=\"text-xs text-destructive\">{errors.postalCode}</p> : null}\n <Dialog\n open={countryDialogOpen}\n onOpenChange={(open) => {\n setCountryDialogOpen(open)\n if (!open) setCountryQuery('')\n }}\n >\n <DialogTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n className={`${inputClass('country')} h-10 w-full justify-between`}\n disabled={disabled}\n aria-invalid={errors.country ? 'true' : undefined}\n >\n <span className=\"truncate text-left\">\n {selectedCountry\n ? `${selectedCountry.label}`\n : t('customers.people.detail.addresses.countryPlaceholder', 'Select country')}\n </span>\n <span className=\"ml-2 text-xs text-muted-foreground\">\n {selectedCountry ? selectedCountry.code : null}\n </span>\n </Button>\n </DialogTrigger>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>{t('customers.people.detail.addresses.countryDialogTitle', 'Select country')}</DialogTitle>\n <DialogDescription>\n {t('customers.people.detail.addresses.countryDialogDescription', 'Search and choose an ISO country code.')}\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-3\">\n <Input\n placeholder={t('customers.people.detail.addresses.countrySearch', 'Search country')}\n value={countryQuery}\n onChange={(evt) => setCountryQuery(evt.target.value)}\n />\n <div className=\"max-h-64 overflow-y-auto rounded border divide-y\">\n {filteredCountryOptions.length === 0 ? (\n <p className=\"px-3 py-2 text-sm text-muted-foreground\">\n {t('customers.people.detail.addresses.countryEmpty', 'No matches found')}\n </p>\n ) : (\n filteredCountryOptions.map((option) => (\n <Button\n key={option.code}\n variant=\"ghost\"\n size=\"sm\"\n className=\"w-full justify-between rounded-none font-normal\"\n onClick={() => {\n update('country', option.code)\n setCountryDialogOpen(false)\n setCountryQuery('')\n }}\n >\n <span className=\"truncate\">{option.label}</span>\n <span className=\"text-xs text-muted-foreground\">{option.code}</span>\n </Button>\n ))\n )}\n </div>\n <div className=\"flex items-center justify-between gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => {\n update('country', '')\n setCountryDialogOpen(false)\n setCountryQuery('')\n }}\n disabled={disabled}\n >\n {t('customers.people.detail.addresses.countryClear', 'Clear')}\n </Button>\n <Button type=\"button\" onClick={() => setCountryDialogOpen(false)}>\n {t('customers.people.detail.addresses.countryClose', 'Done')}\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n {errors.country ? <p className=\"text-xs text-destructive\">{errors.country}</p> : null}\n {showCoordinateFields ? (\n <>\n <Input\n className={inputClass('latitude')}\n placeholder={t('customers.people.detail.addresses.fields.latitude', 'Latitude')}\n aria-label={t('customers.people.detail.addresses.fields.latitude', 'Latitude')}\n inputMode=\"decimal\"\n value={current.latitude ?? ''}\n onChange={(evt) => update('latitude', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.latitude ? 'true' : undefined}\n />\n {errors.latitude ? <p className=\"text-xs text-destructive\">{errors.latitude}</p> : null}\n <Input\n className={inputClass('longitude')}\n placeholder={t('customers.people.detail.addresses.fields.longitude', 'Longitude')}\n aria-label={t('customers.people.detail.addresses.fields.longitude', 'Longitude')}\n inputMode=\"decimal\"\n value={current.longitude ?? ''}\n onChange={(evt) => update('longitude', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.longitude ? 'true' : undefined}\n />\n {errors.longitude ? <p className=\"text-xs text-destructive\">{errors.longitude}</p> : null}\n </>\n ) : null}\n </div>\n {!hidePrimaryToggle ? (\n <label className=\"inline-flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={current.isPrimary}\n onChange={(evt) => update('isPrimary', evt.target.checked)}\n disabled={disabled}\n aria-invalid={errors.isPrimary ? 'true' : undefined}\n />\n <span>{t('customers.people.detail.addresses.fields.primary', 'Set as primary')}</span>\n </label>\n ) : null}\n {errors.isPrimary ? <p className=\"text-xs text-destructive\">{errors.isPrimary}</p> : null}\n </div>\n )\n}\n\nexport default AddressEditor\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { usePathname, useSearchParams } from 'next/navigation'\nimport { Plus, Settings } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@open-mercato/ui/primitives/dialog'\nimport { buildCountryOptions } from '@open-mercato/shared/lib/location/countries'\nimport { buildHrefWithReturnTo } from '@open-mercato/shared/lib/navigation/returnTo'\nimport { resolveTaxIdLabel, type AddressFormatStrategy } from '../utils/addressFormat'\nimport { useAddressTypes } from './detail/hooks/useAddressTypes'\n\ntype Translator = (key: string, fallback?: string, params?: Record<string, string | number>) => string\n\nexport type AddressEditorDraft = {\n name: string\n purpose: string\n companyName: string\n addressLine1: string\n addressLine2: string\n buildingNumber: string\n flatNumber: string\n city: string\n region: string\n postalCode: string\n country: string\n /**\n * Contact details that belong to the ADDRESS rather than to the customer: the tax identifier it was\n * invoiced under, and the phone a carrier calls about a delivery. Optional so every existing caller\n * keeps compiling; callers must opt in with the matching `show*Field` props before they render.\n */\n taxId?: string\n /**\n * Which scheme the identifier belongs to, in Stripe's `{country}_{kind}` vocabulary. Chosen, not\n * inferred: `PL1234567890` and `1234567890` are the same business written two ways, and a rule\n * that reads the form of the value is guessing \u2014 the more schemes the vocabulary carries, the more\n * often it guesses wrong, and a wrong type is worse than none because it names the number.\n */\n taxIdType?: string\n phone?: string\n latitude?: string\n longitude?: string\n isPrimary: boolean\n}\n\nexport type AddressEditorField =\n | 'name'\n | 'purpose'\n | 'companyName'\n | 'addressLine1'\n | 'addressLine2'\n | 'buildingNumber'\n | 'flatNumber'\n | 'city'\n | 'region'\n | 'postalCode'\n | 'country'\n | 'taxId'\n | 'taxIdType'\n | 'phone'\n | 'latitude'\n | 'longitude'\n | 'isPrimary'\n\ntype AddressEditorProps = {\n value: AddressEditorDraft\n onChange: (next: AddressEditorDraft) => void\n format: AddressFormatStrategy\n t: Translator\n disabled?: boolean\n errors?: Partial<Record<AddressEditorField, string>>\n hidePrimaryToggle?: boolean\n showFormatHint?: boolean\n showCoordinateFields?: boolean\n /**\n * Render the phone. Off by default, opt-in for the same reason `showCoordinateFields` is: only a\n * caller whose storage can hold a field should offer it.\n */\n showPhoneField?: boolean\n /**\n * Render the tax identifier and its scheme. Separate from the phone, and not for symmetry \u2014 a\n * phone is a contact detail and a tax identifier is not, and the two stop travelling together at\n * the next phase: `CustomerAddress` gains a `phone` column and no tax id, so the address book will\n * offer one and not the other.\n *\n * Both gate the CALLER, not the field. Inside a tile that opts in, the input renders whether or not\n * it carries a value and takes the same `disabled` as every neighbour.\n */\n showTaxIdField?: boolean\n}\n\n/**\n * The schemes offered in the picker, in the order a Polish deployment meets them. The vocabulary is\n * additive under the backward-compatibility contract, so a new scheme is a new entry here rather\n * than a new branch in a rule that has to guess.\n *\n * The labels are the ones `resolveTaxIdLabel` resolves, so the picker and the marker beside the\n * filled field always read the same.\n */\nconst TAX_ID_TYPES = ['pl_nip', 'eu_vat', 'other'] as const\n\nexport function AddressEditor({\n value,\n onChange,\n format,\n t,\n disabled = false,\n errors = {},\n hidePrimaryToggle = false,\n showFormatHint = true,\n showCoordinateFields = false,\n showPhoneField = false,\n showTaxIdField = false,\n}: AddressEditorProps) {\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const { options: addressTypes, loading: addressTypesLoading, error: addressTypeError, createType } = useAddressTypes(t)\n const [typeDialogOpen, setTypeDialogOpen] = React.useState(false)\n const [typeValue, setTypeValue] = React.useState('')\n const [typeFormError, setTypeFormError] = React.useState<string | null>(null)\n const [countryDialogOpen, setCountryDialogOpen] = React.useState(false)\n const [countryQuery, setCountryQuery] = React.useState('')\n\n const countryOptions = React.useMemo(\n () =>\n buildCountryOptions({\n transformLabel: (code, fallback) => t(`customers.countries.${code.toLowerCase()}`, fallback ?? code),\n }),\n [t],\n )\n\n const taxIdLabels = {\n plNip: t('customers.people.detail.addresses.fields.taxId.plNip', 'Tax ID'),\n euVat: t('customers.people.detail.addresses.fields.taxId.euVat', 'EU VAT'),\n other: t('customers.people.detail.addresses.fields.taxId.other', 'Tax number'),\n }\n const current: AddressEditorDraft = {\n name: value.name ?? '',\n purpose: value.purpose ?? '',\n companyName: value.companyName ?? '',\n addressLine1: value.addressLine1 ?? '',\n addressLine2: value.addressLine2 ?? '',\n buildingNumber: value.buildingNumber ?? '',\n flatNumber: value.flatNumber ?? '',\n city: value.city ?? '',\n region: value.region ?? '',\n postalCode: value.postalCode ?? '',\n country: value.country ?? '',\n taxId: value.taxId ?? '',\n taxIdType: value.taxIdType ?? '',\n phone: value.phone ?? '',\n ...(showCoordinateFields\n ? { latitude: value.latitude ?? '', longitude: value.longitude ?? '' }\n : {}),\n isPrimary: value.isPrimary ?? false,\n }\n\n const update = React.useCallback(\n (key: keyof AddressEditorDraft, nextValue: string | boolean) => {\n onChange({ ...current, [key]: nextValue })\n },\n [current, onChange],\n )\n\n const filteredCountryOptions = React.useMemo(() => {\n const query = countryQuery.trim().toLowerCase()\n if (!query.length) return countryOptions\n return countryOptions.filter(\n (option) => option.label.toLowerCase().includes(query) || option.code.toLowerCase().includes(query),\n )\n }, [countryOptions, countryQuery])\n\n const selectedCountry = React.useMemo(() => {\n const code = (current.country ?? '').toUpperCase()\n if (!code.length) return null\n return countryOptions.find((option) => option.code === code) ?? null\n }, [countryOptions, current.country])\n const returnTo = React.useMemo(() => {\n const query = searchParams?.toString() ?? ''\n if (!pathname) return null\n return query.length ? `${pathname}?${query}` : pathname\n }, [pathname, searchParams])\n const manageAddressTypesHref = React.useMemo(\n () => buildHrefWithReturnTo('/backend/config/customers', returnTo),\n [returnTo],\n )\n\n const handleTypeSubmit = React.useCallback(\n async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n const trimmed = typeValue.trim()\n if (!trimmed.length) {\n setTypeFormError(t('customers.people.detail.addresses.types.emptyError', 'Please provide a value'))\n return\n }\n setTypeFormError(null)\n await createType(trimmed)\n setTypeDialogOpen(false)\n setTypeValue('')\n },\n [createType, t, typeValue],\n )\n\n const inputClass = (field: AddressEditorField) =>\n [\n 'w-full rounded-md border px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring',\n errors[field] ? 'border-status-error-border focus:ring-status-error-border' : 'border-input bg-background',\n ].join(' ')\n\n return (\n <div className=\"space-y-3\">\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <Input\n className={inputClass('name')}\n placeholder={t('customers.people.detail.addresses.fields.label', 'Label')}\n value={current.name}\n onChange={(evt) => update('name', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.name ? 'true' : undefined}\n />\n <div className=\"flex gap-2\">\n <Select\n value={current.purpose || undefined}\n onValueChange={(next) => update('purpose', next ?? '')}\n disabled={disabled}\n >\n <SelectTrigger\n className={errors.purpose ? 'border-destructive' : undefined}\n aria-invalid={errors.purpose ? 'true' : undefined}\n >\n <SelectValue\n placeholder={\n addressTypesLoading\n ? t('customers.people.detail.addresses.types.loading', 'Loading\u2026')\n : t('customers.people.detail.addresses.types.placeholder', 'Address type')\n }\n />\n </SelectTrigger>\n <SelectContent>\n {addressTypes.map((entry) => (\n <SelectItem key={entry.value} value={entry.value}>\n {entry.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Dialog open={typeDialogOpen} onOpenChange={setTypeDialogOpen}>\n <DialogTrigger asChild>\n <Button type=\"button\" variant=\"outline\" size=\"icon\" className=\"shrink-0\" disabled={disabled}>\n <Plus className=\"h-4 w-4\" />\n </Button>\n </DialogTrigger>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>{t('customers.people.detail.addresses.types.add', 'Add address type')}</DialogTitle>\n <DialogDescription>\n {t('customers.people.detail.addresses.types.addHint', 'Create a new address type for reuse.')}\n </DialogDescription>\n </DialogHeader>\n <form className=\"space-y-3\" onSubmit={handleTypeSubmit}>\n <Input\n autoFocus\n value={typeValue}\n onChange={(evt) => {\n setTypeValue(evt.target.value)\n if (typeFormError) setTypeFormError(null)\n }}\n placeholder={t('customers.people.detail.addresses.types.placeholder', 'Address type')}\n disabled={disabled}\n aria-invalid={typeFormError ? 'true' : undefined}\n />\n {typeFormError ? <p className=\"text-sm text-destructive\">{typeFormError}</p> : null}\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setTypeDialogOpen(false)} disabled={disabled}>\n {t('customers.people.detail.addresses.types.cancel', 'Cancel')}\n </Button>\n <Button type=\"submit\" disabled={disabled || !typeValue.trim()}>\n {t('customers.people.detail.addresses.types.save', 'Save')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n <Button\n asChild\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"shrink-0\"\n disabled={disabled}\n title={t('customers.people.detail.addresses.types.manage', 'Manage address types')}\n >\n <Link\n href={manageAddressTypesHref}\n aria-label={t('customers.people.detail.addresses.types.manage', 'Manage address types')}\n >\n <Settings className=\"h-4 w-4\" />\n </Link>\n </Button>\n </div>\n </div>\n {errors.purpose ? <p className=\"text-xs text-destructive\">{errors.purpose}</p> : null}\n {addressTypeError ? <p className=\"text-xs text-destructive\">{addressTypeError}</p> : null}\n <Input\n className={inputClass('companyName')}\n placeholder={t('customers.people.detail.addresses.fields.companyName', 'Company name')}\n value={current.companyName}\n onChange={(evt) => update('companyName', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.companyName ? 'true' : undefined}\n />\n {showFormatHint ? (\n <p className=\"text-xs text-muted-foreground\">\n {format === 'street_first'\n ? t('customers.people.detail.addresses.streetFormatHint', 'Street-first layout is active.')\n : t('customers.people.detail.addresses.lineFormatHint', 'Address-line layout is active.')}\n </p>\n ) : null}\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <Input\n className={inputClass('addressLine1')}\n placeholder={\n format === 'street_first'\n ? t('customers.people.detail.addresses.fields.street', 'Street')\n : t('customers.people.detail.addresses.fields.line1', 'Address line 1')\n }\n value={current.addressLine1}\n onChange={(evt) => update('addressLine1', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.addressLine1 ? 'true' : undefined}\n />\n {errors.addressLine1 ? <p className=\"text-xs text-destructive sm:col-span-2\">{errors.addressLine1}</p> : null}\n {format === 'street_first' ? (\n <>\n <Input\n className={inputClass('buildingNumber')}\n placeholder={t('customers.people.detail.addresses.fields.buildingNumber', 'Building number')}\n value={current.buildingNumber}\n onChange={(evt) => update('buildingNumber', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.buildingNumber ? 'true' : undefined}\n />\n <Input\n className={inputClass('flatNumber')}\n placeholder={t('customers.people.detail.addresses.fields.flatNumber', 'Flat number')}\n value={current.flatNumber}\n onChange={(evt) => update('flatNumber', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.flatNumber ? 'true' : undefined}\n />\n <Input\n className={inputClass('addressLine2')}\n placeholder={t('customers.people.detail.addresses.fields.streetExtra', 'Address line 2')}\n value={current.addressLine2}\n onChange={(evt) => update('addressLine2', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.addressLine2 ? 'true' : undefined}\n />\n {errors.addressLine2 ? <p className=\"text-xs text-destructive sm:col-span-2\">{errors.addressLine2}</p> : null}\n </>\n ) : (\n <>\n <Input\n className={inputClass('addressLine2')}\n placeholder={t('customers.people.detail.addresses.fields.line2', 'Address line 2')}\n value={current.addressLine2}\n onChange={(evt) => update('addressLine2', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.addressLine2 ? 'true' : undefined}\n />\n {errors.addressLine2 ? <p className=\"text-xs text-destructive sm:col-span-2\">{errors.addressLine2}</p> : null}\n </>\n )}\n <Input\n className={inputClass('city')}\n placeholder={t('customers.people.detail.addresses.fields.city', 'City')}\n value={current.city}\n onChange={(evt) => update('city', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.city ? 'true' : undefined}\n />\n {errors.city ? <p className=\"text-xs text-destructive\">{errors.city}</p> : null}\n <Input\n className={inputClass('region')}\n placeholder={t('customers.people.detail.addresses.fields.region', 'Region/state')}\n value={current.region}\n onChange={(evt) => update('region', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.region ? 'true' : undefined}\n />\n {errors.region ? <p className=\"text-xs text-destructive\">{errors.region}</p> : null}\n <Input\n className={inputClass('postalCode')}\n placeholder={t('customers.people.detail.addresses.fields.postalCode', 'Postal code')}\n value={current.postalCode}\n onChange={(evt) => update('postalCode', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.postalCode ? 'true' : undefined}\n />\n {errors.postalCode ? <p className=\"text-xs text-destructive\">{errors.postalCode}</p> : null}\n <Dialog\n open={countryDialogOpen}\n onOpenChange={(open) => {\n setCountryDialogOpen(open)\n if (!open) setCountryQuery('')\n }}\n >\n <DialogTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n className={`${inputClass('country')} h-10 w-full justify-between`}\n disabled={disabled}\n aria-invalid={errors.country ? 'true' : undefined}\n >\n <span className=\"truncate text-left\">\n {selectedCountry\n ? `${selectedCountry.label}`\n : t('customers.people.detail.addresses.countryPlaceholder', 'Select country')}\n </span>\n <span className=\"ml-2 text-xs text-muted-foreground\">\n {selectedCountry ? selectedCountry.code : null}\n </span>\n </Button>\n </DialogTrigger>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>{t('customers.people.detail.addresses.countryDialogTitle', 'Select country')}</DialogTitle>\n <DialogDescription>\n {t('customers.people.detail.addresses.countryDialogDescription', 'Search and choose an ISO country code.')}\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-3\">\n <Input\n placeholder={t('customers.people.detail.addresses.countrySearch', 'Search country')}\n value={countryQuery}\n onChange={(evt) => setCountryQuery(evt.target.value)}\n />\n <div className=\"max-h-64 overflow-y-auto rounded border divide-y\">\n {filteredCountryOptions.length === 0 ? (\n <p className=\"px-3 py-2 text-sm text-muted-foreground\">\n {t('customers.people.detail.addresses.countryEmpty', 'No matches found')}\n </p>\n ) : (\n filteredCountryOptions.map((option) => (\n <Button\n key={option.code}\n variant=\"ghost\"\n size=\"sm\"\n className=\"w-full justify-between rounded-none font-normal\"\n onClick={() => {\n update('country', option.code)\n setCountryDialogOpen(false)\n setCountryQuery('')\n }}\n >\n <span className=\"truncate\">{option.label}</span>\n <span className=\"text-xs text-muted-foreground\">{option.code}</span>\n </Button>\n ))\n )}\n </div>\n <div className=\"flex items-center justify-between gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => {\n update('country', '')\n setCountryDialogOpen(false)\n setCountryQuery('')\n }}\n disabled={disabled}\n >\n {t('customers.people.detail.addresses.countryClear', 'Clear')}\n </Button>\n <Button type=\"button\" onClick={() => setCountryDialogOpen(false)}>\n {t('customers.people.detail.addresses.countryClose', 'Done')}\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n {errors.country ? <p className=\"text-xs text-destructive\">{errors.country}</p> : null}\n {showCoordinateFields ? (\n <>\n <Input\n className={inputClass('latitude')}\n placeholder={t('customers.people.detail.addresses.fields.latitude', 'Latitude')}\n aria-label={t('customers.people.detail.addresses.fields.latitude', 'Latitude')}\n inputMode=\"decimal\"\n value={current.latitude ?? ''}\n onChange={(evt) => update('latitude', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.latitude ? 'true' : undefined}\n />\n {errors.latitude ? <p className=\"text-xs text-destructive\">{errors.latitude}</p> : null}\n <Input\n className={inputClass('longitude')}\n placeholder={t('customers.people.detail.addresses.fields.longitude', 'Longitude')}\n aria-label={t('customers.people.detail.addresses.fields.longitude', 'Longitude')}\n inputMode=\"decimal\"\n value={current.longitude ?? ''}\n onChange={(evt) => update('longitude', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.longitude ? 'true' : undefined}\n />\n {errors.longitude ? <p className=\"text-xs text-destructive\">{errors.longitude}</p> : null}\n </>\n ) : null}\n {showTaxIdField ? (\n <>\n <Select\n value={current.taxIdType || undefined}\n onValueChange={(next) => update('taxIdType', next ?? '')}\n disabled={disabled}\n >\n <SelectTrigger\n className={errors.taxIdType ? 'border-destructive' : undefined}\n aria-label={t('customers.people.detail.addresses.fields.taxIdType', 'Tax id type')}\n aria-invalid={errors.taxIdType ? 'true' : undefined}\n >\n <SelectValue\n placeholder={t('customers.people.detail.addresses.fields.taxIdType', 'Tax id type')}\n />\n </SelectTrigger>\n <SelectContent>\n {TAX_ID_TYPES.map((type) => (\n <SelectItem key={type} value={type}>\n {resolveTaxIdLabel(taxIdLabels, type)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Input\n className={inputClass('taxId')}\n placeholder={t('customers.people.detail.addresses.fields.taxId', 'Tax number')}\n aria-label={t('customers.people.detail.addresses.fields.taxId', 'Tax number')}\n rightIcon={\n current.taxId ? (\n <span className=\"text-xs\">{resolveTaxIdLabel(taxIdLabels, current.taxIdType)}</span>\n ) : null\n }\n value={current.taxId ?? ''}\n onChange={(evt) => update('taxId', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.taxId ? 'true' : undefined}\n />\n {errors.taxId ? <p className=\"text-xs text-destructive\">{errors.taxId}</p> : null}\n </>\n ) : null}\n {showPhoneField ? (\n <>\n <Input\n className={inputClass('phone')}\n placeholder={t('customers.people.detail.addresses.fields.phone', 'Phone')}\n aria-label={t('customers.people.detail.addresses.fields.phone', 'Phone')}\n rightIcon={\n current.phone ? (\n <span className=\"text-xs\">\n {t('customers.people.detail.addresses.fields.phone', 'Phone')}\n </span>\n ) : null\n }\n inputMode=\"tel\"\n value={current.phone ?? ''}\n onChange={(evt) => update('phone', evt.target.value)}\n disabled={disabled}\n aria-invalid={errors.phone ? 'true' : undefined}\n />\n {errors.phone ? <p className=\"text-xs text-destructive\">{errors.phone}</p> : null}\n </>\n ) : null}\n </div>\n {!hidePrimaryToggle ? (\n <label className=\"inline-flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={current.isPrimary}\n onChange={(evt) => update('isPrimary', evt.target.checked)}\n disabled={disabled}\n aria-invalid={errors.isPrimary ? 'true' : undefined}\n />\n <span>{t('customers.people.detail.addresses.fields.primary', 'Set as primary')}</span>\n </label>\n ) : null}\n {errors.isPrimary ? <p className=\"text-xs text-destructive\">{errors.isPrimary}</p> : null}\n </div>\n )\n}\n\nexport default AddressEditor\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -63,7 +63,22 @@ function formatAddressLines(address, format) {
|
|
|
63
63
|
function formatAddressString(address, format, separator = ", ") {
|
|
64
64
|
return formatAddressLines(address, format).filter(Boolean).join(separator);
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
const TAX_ID_LABEL_KEY_BY_TYPE = {
|
|
67
|
+
pl_nip: "plNip",
|
|
68
|
+
eu_vat: "euVat"
|
|
69
|
+
};
|
|
70
|
+
function resolveTaxIdLabel(label, taxIdType) {
|
|
71
|
+
if (!label) return void 0;
|
|
72
|
+
if (typeof label === "string") return label;
|
|
73
|
+
const key = TAX_ID_LABEL_KEY_BY_TYPE[typeof taxIdType === "string" ? taxIdType : ""] ?? "other";
|
|
74
|
+
return label[key];
|
|
75
|
+
}
|
|
76
|
+
function AddressView({
|
|
77
|
+
address,
|
|
78
|
+
format,
|
|
79
|
+
className,
|
|
80
|
+
lineClassName
|
|
81
|
+
}) {
|
|
67
82
|
const lines = formatAddressLines(address, format);
|
|
68
83
|
if (!lines.length) return null;
|
|
69
84
|
return /* @__PURE__ */ jsx("div", { className, children: lines.map((line, index) => /* @__PURE__ */ jsx("div", { className: lineClassName, children: line }, `${index}-${line}`)) });
|
|
@@ -72,6 +87,7 @@ export {
|
|
|
72
87
|
AddressView,
|
|
73
88
|
formatAddressJson,
|
|
74
89
|
formatAddressLines,
|
|
75
|
-
formatAddressString
|
|
90
|
+
formatAddressString,
|
|
91
|
+
resolveTaxIdLabel
|
|
76
92
|
};
|
|
77
93
|
//# sourceMappingURL=addressFormat.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/customers/utils/addressFormat.tsx"],
|
|
4
|
-
"sourcesContent": ["import * as React from 'react'\nimport type { CustomerAddressFormat } from '../data/entities'\n\nexport type AddressFormatStrategy = CustomerAddressFormat\n\nexport type AddressValue = {\n addressLine1: string | null | undefined\n addressLine2?: string | null\n buildingNumber?: string | null\n flatNumber?: string | null\n city?: string | null\n region?: string | null\n postalCode?: string | null\n country?: string | null\n companyName?: string | null\n}\n\nexport type AddressJsonShape = {\n format: AddressFormatStrategy\n companyName: string | null\n addressLine1: string | null\n addressLine2: string | null\n buildingNumber: string | null\n flatNumber: string | null\n postalCode: string | null\n city: string | null\n region: string | null\n country: string | null\n}\n\nfunction normalize(value: string | null | undefined): string | null {\n if (typeof value !== 'string') return null\n const trimmed = value.trim()\n return trimmed.length ? trimmed : null\n}\n\nfunction mergeStreetLine(address: AddressValue): string | null {\n const street = normalize(address.addressLine1)\n const building = normalize(address.buildingNumber)\n const flat = normalize(address.flatNumber)\n if (!street && !building && !flat) return null\n let line = street ?? ''\n if (building) line = line ? `${line} ${building}` : building\n if (flat) line = line ? `${line}/${flat}` : flat\n return line.length ? line : null\n}\n\nexport function formatAddressJson(address: AddressValue, format: AddressFormatStrategy): AddressJsonShape {\n return {\n format,\n companyName: normalize(address.companyName),\n addressLine1: normalize(address.addressLine1),\n addressLine2: normalize(address.addressLine2),\n buildingNumber: normalize(address.buildingNumber),\n flatNumber: normalize(address.flatNumber),\n postalCode: normalize(address.postalCode),\n city: normalize(address.city),\n region: normalize(address.region),\n country: normalize(address.country),\n }\n}\n\nexport function formatAddressLines(address: AddressValue, format: AddressFormatStrategy): string[] {\n const json = formatAddressJson(address, format)\n const lines: string[] = []\n\n if (json.companyName) lines.push(json.companyName)\n\n if (format === 'street_first') {\n const streetLine = mergeStreetLine(address)\n if (streetLine) lines.push(streetLine)\n const supplemental = normalize(address.addressLine2)\n if (supplemental) lines.push(supplemental)\n const postalCity = [json.postalCode, json.city].filter(Boolean).join(' ')\n if (postalCity.length) lines.push(postalCity)\n if (json.region) lines.push(json.region)\n if (json.country) lines.push(json.country)\n } else {\n if (json.addressLine1) {\n const baseLine1 = json.addressLine1\n const appended = mergeStreetLine(address)\n if (!json.buildingNumber && !json.flatNumber) {\n lines.push(baseLine1)\n } else {\n const composite = appended ?? baseLine1\n lines.push(composite)\n }\n }\n if (json.addressLine2) lines.push(json.addressLine2)\n const postalCity = [json.postalCode, json.city].filter(Boolean).join(' ')\n if (postalCity.length) lines.push(postalCity)\n if (json.region) lines.push(json.region)\n if (json.country) lines.push(json.country)\n }\n\n return lines\n}\n\nexport function formatAddressString(address: AddressValue, format: AddressFormatStrategy, separator = ', '): string {\n return formatAddressLines(address, format).filter(Boolean).join(separator)\n}\n\ntype AddressViewProps = {\n address: AddressValue\n format: AddressFormatStrategy\n className?: string\n lineClassName?: string\n}\n\nexport function AddressView({
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import * as React from 'react'\nimport type { CustomerAddressFormat } from '../data/entities'\n\nexport type AddressFormatStrategy = CustomerAddressFormat\n\nexport type AddressValue = {\n addressLine1: string | null | undefined\n addressLine2?: string | null\n buildingNumber?: string | null\n flatNumber?: string | null\n city?: string | null\n region?: string | null\n postalCode?: string | null\n country?: string | null\n companyName?: string | null\n /**\n * Contact details that belong to the ADDRESS rather than to the customer: who to call about this\n * delivery, and the tax identifier this invoice address was billed under. They remain available to\n * address editors and snapshot payloads, but are deliberately excluded from `formatAddressLines`\n * and `AddressView`, whose existing contract remains postal-only.\n *\n * `taxIdType` interprets the value in Stripe's `{country}_{kind}` vocabulary (`pl_nip`, `eu_vat`,\n * `other`, widened additively): `1234567890` and `PL1234567890` are the same business, and only the\n * type tells a domestic identifier from an EU VAT number. It is metadata about `taxId`, never a\n * displayed field of its own.\n */\n phone?: string | null\n taxId?: string | null\n taxIdType?: string | null\n}\n\n/**\n * Tax-id labels keyed by `taxIdType`, for a caller that wants the identifier named correctly rather\n * than generically.\n *\n * The stored scheme is chosen explicitly rather than inferred from the identifier. `other` also\n * covers an address written before `taxIdType` existed. An unrecognised type takes the `other` route\n * instead of guessing a domestic scheme.\n */\nexport type TaxIdLabelByType = {\n plNip: string\n euVat: string\n other: string\n}\n\nexport type AddressJsonShape = {\n format: AddressFormatStrategy\n companyName: string | null\n addressLine1: string | null\n addressLine2: string | null\n buildingNumber: string | null\n flatNumber: string | null\n postalCode: string | null\n city: string | null\n region: string | null\n country: string | null\n}\n\nfunction normalize(value: string | null | undefined): string | null {\n if (typeof value !== 'string') return null\n const trimmed = value.trim()\n return trimmed.length ? trimmed : null\n}\n\nfunction mergeStreetLine(address: AddressValue): string | null {\n const street = normalize(address.addressLine1)\n const building = normalize(address.buildingNumber)\n const flat = normalize(address.flatNumber)\n if (!street && !building && !flat) return null\n let line = street ?? ''\n if (building) line = line ? `${line} ${building}` : building\n if (flat) line = line ? `${line}/${flat}` : flat\n return line.length ? line : null\n}\n\nexport function formatAddressJson(address: AddressValue, format: AddressFormatStrategy): AddressJsonShape {\n return {\n format,\n companyName: normalize(address.companyName),\n addressLine1: normalize(address.addressLine1),\n addressLine2: normalize(address.addressLine2),\n buildingNumber: normalize(address.buildingNumber),\n flatNumber: normalize(address.flatNumber),\n postalCode: normalize(address.postalCode),\n city: normalize(address.city),\n region: normalize(address.region),\n country: normalize(address.country),\n }\n}\n\nexport function formatAddressLines(address: AddressValue, format: AddressFormatStrategy): string[] {\n const json = formatAddressJson(address, format)\n const lines: string[] = []\n\n if (json.companyName) lines.push(json.companyName)\n\n if (format === 'street_first') {\n const streetLine = mergeStreetLine(address)\n if (streetLine) lines.push(streetLine)\n const supplemental = normalize(address.addressLine2)\n if (supplemental) lines.push(supplemental)\n const postalCity = [json.postalCode, json.city].filter(Boolean).join(' ')\n if (postalCity.length) lines.push(postalCity)\n if (json.region) lines.push(json.region)\n if (json.country) lines.push(json.country)\n } else {\n if (json.addressLine1) {\n const baseLine1 = json.addressLine1\n const appended = mergeStreetLine(address)\n if (!json.buildingNumber && !json.flatNumber) {\n lines.push(baseLine1)\n } else {\n const composite = appended ?? baseLine1\n lines.push(composite)\n }\n }\n if (json.addressLine2) lines.push(json.addressLine2)\n const postalCity = [json.postalCode, json.city].filter(Boolean).join(' ')\n if (postalCity.length) lines.push(postalCity)\n if (json.region) lines.push(json.region)\n if (json.country) lines.push(json.country)\n }\n\n return lines\n}\n\nexport function formatAddressString(address: AddressValue, format: AddressFormatStrategy, separator = ', '): string {\n return formatAddressLines(address, format).filter(Boolean).join(separator)\n}\n\n/**\n * Which member of a label map names which scheme. Private, and deliberately not exhaustive: an\n * unrecognised type resolves to `other`, so the vocabulary can widen without every caller being\n * updated in the same release.\n */\nconst TAX_ID_LABEL_KEY_BY_TYPE: Record<string, keyof TaxIdLabelByType> = {\n pl_nip: 'plNip',\n eu_vat: 'euVat',\n}\n\n/**\n * The label a tax identifier should carry, given its type. Exported because the editor renders the\n * same identifier as an input and must name it the same way this formatter does \u2014 two copies of the\n * mapping is exactly how a foreign number ends up under a domestic scheme's name.\n */\nexport function resolveTaxIdLabel(\n label: string | TaxIdLabelByType | undefined,\n taxIdType: string | null | undefined,\n): string | undefined {\n if (!label) return undefined\n if (typeof label === 'string') return label\n const key = TAX_ID_LABEL_KEY_BY_TYPE[typeof taxIdType === 'string' ? taxIdType : ''] ?? 'other'\n return label[key]\n}\n\ntype AddressViewProps = {\n address: AddressValue\n format: AddressFormatStrategy\n className?: string\n lineClassName?: string\n}\n\nexport function AddressView({\n address,\n format,\n className,\n lineClassName,\n}: AddressViewProps): React.ReactElement | null {\n const lines = formatAddressLines(address, format)\n if (!lines.length) return null\n return (\n <div className={className}>\n {lines.map((line, index) => (\n <div key={`${index}-${line}`} className={lineClassName}>\n {line}\n </div>\n ))}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -38,6 +38,9 @@ const emptyDraft = {
|
|
|
38
38
|
region: "",
|
|
39
39
|
postalCode: "",
|
|
40
40
|
country: "",
|
|
41
|
+
taxId: "",
|
|
42
|
+
taxIdType: "",
|
|
43
|
+
phone: "",
|
|
41
44
|
isPrimary: false
|
|
42
45
|
};
|
|
43
46
|
const EDITABLE_SNAPSHOT_KEYS = new Set(Object.keys(emptyDraft));
|
|
@@ -64,6 +67,9 @@ function normalizeAddressDraft(draft, previous) {
|
|
|
64
67
|
assign("region", "region");
|
|
65
68
|
assign("postalCode", "postalCode");
|
|
66
69
|
assign("country", "country");
|
|
70
|
+
assign("taxId", "taxId");
|
|
71
|
+
assign("taxIdType", "taxIdType");
|
|
72
|
+
assign("phone", "phone");
|
|
67
73
|
assign("isPrimary", "isPrimary");
|
|
68
74
|
if (!hasEditableContent) return null;
|
|
69
75
|
if (previous) {
|
|
@@ -89,6 +95,9 @@ function draftFromSnapshot(snapshot) {
|
|
|
89
95
|
region: typeof record.region === "string" ? record.region : "",
|
|
90
96
|
postalCode: typeof record.postalCode === "string" ? record.postalCode : "",
|
|
91
97
|
country: typeof record.country === "string" ? record.country : "",
|
|
98
|
+
taxId: typeof record.taxId === "string" ? record.taxId : "",
|
|
99
|
+
taxIdType: typeof record.taxIdType === "string" ? record.taxIdType : "",
|
|
100
|
+
phone: typeof record.phone === "string" ? record.phone : "",
|
|
92
101
|
isPrimary: record.isPrimary === true
|
|
93
102
|
};
|
|
94
103
|
}
|
|
@@ -921,9 +930,12 @@ function SalesDocumentAddressesSection({
|
|
|
921
930
|
{
|
|
922
931
|
value: shippingDraft,
|
|
923
932
|
format: addressFormat,
|
|
933
|
+
showPhoneField: true,
|
|
934
|
+
showTaxIdField: true,
|
|
924
935
|
t,
|
|
925
936
|
onChange: (next) => setShippingDraft(next),
|
|
926
|
-
hidePrimaryToggle: true
|
|
937
|
+
hidePrimaryToggle: true,
|
|
938
|
+
disabled: locked
|
|
927
939
|
}
|
|
928
940
|
),
|
|
929
941
|
/* @__PURE__ */ jsx(
|
|
@@ -988,9 +1000,12 @@ function SalesDocumentAddressesSection({
|
|
|
988
1000
|
{
|
|
989
1001
|
value: billingDraft,
|
|
990
1002
|
format: addressFormat,
|
|
1003
|
+
showPhoneField: true,
|
|
1004
|
+
showTaxIdField: true,
|
|
991
1005
|
t,
|
|
992
1006
|
onChange: (next) => setBillingDraft(next),
|
|
993
|
-
hidePrimaryToggle: true
|
|
1007
|
+
hidePrimaryToggle: true,
|
|
1008
|
+
disabled: locked
|
|
994
1009
|
}
|
|
995
1010
|
),
|
|
996
1011
|
/* @__PURE__ */ jsx(
|