@aglyn/plugins-commerce 1.0.0-beta.289 → 1.0.0-beta.291

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 (140) hide show
  1. package/README.md +4 -2
  2. package/package.json +13 -13
  3. package/src/lib/components/commerce-console-page.js +2 -1
  4. package/src/lib/components/commerce-console-page.js.map +1 -1
  5. package/src/lib/components/console/commerce-pdf-download.d.ts +30 -0
  6. package/src/lib/components/console/commerce-pdf-download.js +53 -0
  7. package/src/lib/components/console/commerce-pdf-download.js.map +1 -0
  8. package/src/lib/components/console/host-orders-card.component.d.ts +6 -0
  9. package/src/lib/components/console/host-orders-card.component.js +3 -2
  10. package/src/lib/components/console/host-orders-card.component.js.map +1 -1
  11. package/src/lib/components/console/host-quotes-card.component.js +20 -4
  12. package/src/lib/components/console/host-quotes-card.component.js.map +1 -1
  13. package/src/lib/components/console/invoice-send.component.d.ts +44 -0
  14. package/src/lib/components/console/invoice-send.component.js +237 -0
  15. package/src/lib/components/console/invoice-send.component.js.map +1 -0
  16. package/src/lib/components/console/order-detail-dialog.component.d.ts +5 -0
  17. package/src/lib/components/console/order-detail-dialog.component.js +9 -2
  18. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
  19. package/src/lib/components/console/order-invoice.component.d.ts +15 -4
  20. package/src/lib/components/console/order-invoice.component.js +93 -12
  21. package/src/lib/components/console/order-invoice.component.js.map +1 -1
  22. package/src/lib/components/console/quote-editor-dialog.component.d.ts +29 -0
  23. package/src/lib/components/console/quote-editor-dialog.component.js +154 -5
  24. package/src/lib/components/console/quote-editor-dialog.component.js.map +1 -1
  25. package/src/lib/components/console/quote-proofs.component.d.ts +48 -0
  26. package/src/lib/components/console/quote-proofs.component.js +694 -0
  27. package/src/lib/components/console/quote-proofs.component.js.map +1 -0
  28. package/src/lib/components/console/quote-send.component.d.ts +42 -0
  29. package/src/lib/components/console/quote-send.component.js +307 -0
  30. package/src/lib/components/console/quote-send.component.js.map +1 -0
  31. package/src/lib/components/console/quote-start.component.d.ts +45 -0
  32. package/src/lib/components/console/quote-start.component.js +182 -0
  33. package/src/lib/components/console/quote-start.component.js.map +1 -0
  34. package/src/lib/components/product-options-field-body.d.ts +44 -0
  35. package/src/lib/components/product-options-field-body.js +260 -0
  36. package/src/lib/components/product-options-field-body.js.map +1 -0
  37. package/src/lib/components/product-options-field.d.ts +32 -0
  38. package/src/lib/components/product-options-field.js +128 -0
  39. package/src/lib/components/product-options-field.js.map +1 -0
  40. package/src/lib/components/quote-page-body.js +67 -20
  41. package/src/lib/components/quote-page-body.js.map +1 -1
  42. package/src/lib/components/quote-proof-panel.d.ts +42 -0
  43. package/src/lib/components/quote-proof-panel.js +436 -0
  44. package/src/lib/components/quote-proof-panel.js.map +1 -0
  45. package/src/lib/model/commerce-invoices.d.ts +132 -0
  46. package/src/lib/model/commerce-invoices.js +332 -0
  47. package/src/lib/model/commerce-invoices.js.map +1 -0
  48. package/src/lib/model/commerce-orders.d.ts +29 -2
  49. package/src/lib/model/commerce-orders.js.map +1 -1
  50. package/src/lib/model/commerce-product-field.d.ts +23 -0
  51. package/src/lib/model/commerce-product-field.js +26 -0
  52. package/src/lib/model/commerce-product-field.js.map +1 -0
  53. package/src/lib/model/commerce-quote-email.d.ts +67 -0
  54. package/src/lib/model/commerce-quote-email.js +154 -0
  55. package/src/lib/model/commerce-quote-email.js.map +1 -0
  56. package/src/lib/model/commerce-quote-pay.d.ts +76 -6
  57. package/src/lib/model/commerce-quote-pay.js +105 -39
  58. package/src/lib/model/commerce-quote-pay.js.map +1 -1
  59. package/src/lib/model/commerce-quote-proofs.d.ts +159 -0
  60. package/src/lib/model/commerce-quote-proofs.js +348 -0
  61. package/src/lib/model/commerce-quote-proofs.js.map +1 -0
  62. package/src/lib/model/commerce-quote-request.d.ts +93 -0
  63. package/src/lib/model/commerce-quote-request.js +207 -0
  64. package/src/lib/model/commerce-quote-request.js.map +1 -0
  65. package/src/lib/model/commerce-quotes.d.ts +140 -3
  66. package/src/lib/model/commerce-quotes.js.map +1 -1
  67. package/src/lib/model/index.d.ts +4 -0
  68. package/src/lib/model/index.js +4 -0
  69. package/src/lib/model/index.js.map +1 -1
  70. package/src/lib/plugin.js +19 -0
  71. package/src/lib/plugin.js.map +1 -1
  72. package/src/lib/server/billing-webhook.js +115 -70
  73. package/src/lib/server/billing-webhook.js.map +1 -1
  74. package/src/lib/server/commerce-pdf.d.ts +104 -0
  75. package/src/lib/server/commerce-pdf.js +310 -0
  76. package/src/lib/server/commerce-pdf.js.map +1 -0
  77. package/src/lib/server/draft-order.js +23 -3
  78. package/src/lib/server/draft-order.js.map +1 -1
  79. package/src/lib/server/invoice-email.d.ts +76 -0
  80. package/src/lib/server/invoice-email.js +183 -0
  81. package/src/lib/server/invoice-email.js.map +1 -0
  82. package/src/lib/server/order-invoice-send.d.ts +43 -0
  83. package/src/lib/server/order-invoice-send.js +218 -0
  84. package/src/lib/server/order-invoice-send.js.map +1 -0
  85. package/src/lib/server/order-print.d.ts +6 -0
  86. package/src/lib/server/order-print.js +22 -5
  87. package/src/lib/server/order-print.js.map +1 -1
  88. package/src/lib/server/order-status.d.ts +11 -0
  89. package/src/lib/server/order-status.js +44 -8
  90. package/src/lib/server/order-status.js.map +1 -1
  91. package/src/lib/server/pdf-response.d.ts +31 -0
  92. package/src/lib/server/pdf-response.js +30 -0
  93. package/src/lib/server/pdf-response.js.map +1 -0
  94. package/src/lib/server/person-eraser.d.ts +3 -2
  95. package/src/lib/server/person-eraser.js +25 -6
  96. package/src/lib/server/person-eraser.js.map +1 -1
  97. package/src/lib/server/pos-reader-splash.d.ts +2 -18
  98. package/src/lib/server/pos-reader-splash.js +8 -93
  99. package/src/lib/server/pos-reader-splash.js.map +1 -1
  100. package/src/lib/server/quote-email.d.ts +85 -0
  101. package/src/lib/server/quote-email.js +211 -0
  102. package/src/lib/server/quote-email.js.map +1 -0
  103. package/src/lib/server/quote-link-token.d.ts +11 -0
  104. package/src/lib/server/quote-link-token.js +21 -0
  105. package/src/lib/server/quote-link-token.js.map +1 -1
  106. package/src/lib/server/quote-pay.d.ts +38 -6
  107. package/src/lib/server/quote-pay.js +115 -53
  108. package/src/lib/server/quote-pay.js.map +1 -1
  109. package/src/lib/server/quote-proofs.d.ts +51 -0
  110. package/src/lib/server/quote-proofs.js +500 -0
  111. package/src/lib/server/quote-proofs.js.map +1 -0
  112. package/src/lib/server/quote-uploads.d.ts +33 -0
  113. package/src/lib/server/quote-uploads.js +29 -0
  114. package/src/lib/server/quote-uploads.js.map +1 -0
  115. package/src/lib/server/quote.d.ts +25 -0
  116. package/src/lib/server/quote.js +638 -8
  117. package/src/lib/server/quote.js.map +1 -1
  118. package/src/lib/server/site-image-source.d.ts +38 -0
  119. package/src/lib/server/site-image-source.js +130 -0
  120. package/src/lib/server/site-image-source.js.map +1 -0
  121. package/src/lib/server/site-page-resolver.js +2 -1
  122. package/src/lib/server/site-page-resolver.js.map +1 -1
  123. package/src/lib/server.js +24 -1
  124. package/src/lib/server.js.map +1 -1
  125. package/src/lib/site.js +8 -0
  126. package/src/lib/site.js.map +1 -1
  127. package/src/lib/tenant-emails.js +243 -0
  128. package/src/lib/tenant-emails.js.map +1 -1
  129. package/src/lib/utils/commerce-document-pdf.d.ts +82 -0
  130. package/src/lib/utils/commerce-document-pdf.js +613 -0
  131. package/src/lib/utils/commerce-document-pdf.js.map +1 -0
  132. package/src/lib/utils/invoice-email-content.d.ts +45 -0
  133. package/src/lib/utils/invoice-email-content.js +126 -0
  134. package/src/lib/utils/invoice-email-content.js.map +1 -0
  135. package/src/lib/utils/order-invoice.d.ts +52 -3
  136. package/src/lib/utils/order-invoice.js +124 -64
  137. package/src/lib/utils/order-invoice.js.map +1 -1
  138. package/src/lib/utils/quote-email-content.d.ts +62 -0
  139. package/src/lib/utils/quote-email-content.js +154 -0
  140. package/src/lib/utils/quote-email-content.js.map +1 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/quote-editor-dialog.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport * as CommerceModel from '../../model'\nimport { posMoney } from '../../model/commerce-pos-ops'\nimport { commerceSitePermissionRefusal } from '../../model/plugin-permissions'\nimport { BlockedControl } from '@aglyn/shared-ui-jsx/components/blocked-control.component'\nimport { PrerequisiteNotice } from '@aglyn/shared-ui-jsx/components/prerequisite-notice.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport {\n useFirestore,\n useFirestoreDoc,\n useStoreSettingsHref,\n useUser,\n} from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Box,\n Button,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogContentText,\n DialogTitle,\n Divider,\n FormControlLabel,\n List,\n ListItemButton,\n ListItemText,\n MenuItem,\n Paper,\n Stack,\n Switch,\n TextField,\n Typography,\n type Theme,\n} from '@mui/material'\nimport { doc } from 'firebase/firestore'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { QuotePayLinkSection } from './quote-pay-link.component'\n\n/** A quote as the list reads it: the order document and its id. */\nexport type QuoteRow = CommerceModel.HostOrder & { $id: string }\n\nexport interface QuoteEditorDialogProps {\n hostId: string\n /** The quote to edit, or `null` for a new one. */\n quote: QuoteRow | null\n /** The store's products, for the product picker. */\n products: readonly Record<string, any>[]\n /** Holds \"Create and edit quotes\" (`commerce.quotes`). */\n canEdit: boolean\n /** Holds \"Send quotes and invoices to customers\" (`commerce.quotes.send`). */\n canSend: boolean\n onClose: () => void\n}\n\nconst REFUSAL = commerceSitePermissionRefusal('commerce.quotes')\nconst SEARCH_DEBOUNCE_MS = 250\n\nconst money = (cents: number): string => posMoney(cents)\n\n/** Field widths on a wide screen, from the theme's spacing; full width on a phone. */\nconst narrowField = (theme: Theme) => ({ maxWidth: { sm: theme.spacing(16) } })\nconst mediumField = (theme: Theme) => ({ minWidth: { sm: theme.spacing(20) }, maxWidth: { sm: theme.spacing(24) } })\n\n/** Dollars typed into a field, as whole cents, or `null` when it is not an amount. */\nfunction centsOf(text: string): number | null {\n const trimmed = text.trim()\n if (!trimmed) return 0\n if (!/^\\d+(\\.\\d{0,2})?$/.test(trimmed)) return null\n return Math.round(Number(trimmed) * 100)\n}\n\nconst dollarsOf = (cents: number | undefined): string =>\n cents ? (cents / 100).toFixed(2).replace(/\\.00$/, '') : ''\n\ntype AddressForm = Record<'name' | 'line1' | 'line2' | 'city' | 'state' | 'postalCode' | 'country', string>\n\nfunction addressForm(address: CommerceModel.OrderAddress | null | undefined): AddressForm {\n return {\n name: address?.name ?? '',\n line1: address?.line1 ?? '',\n line2: address?.line2 ?? '',\n city: address?.city ?? '',\n state: address?.state ?? '',\n postalCode: address?.postalCode ?? '',\n country: address?.country ?? '',\n }\n}\n\ntype LineForm =\n | {\n key: string\n kind: 'catalog'\n productId: string\n variantId: string\n quantity: string\n modifiers: CommerceModel.ModifierSelection[]\n description: string\n included: boolean\n }\n | {\n key: string\n kind: 'custom'\n name: string\n description: string\n sku: string\n price: string\n quantity: string\n ships: boolean\n included: boolean\n }\n\ninterface QuoteForm {\n lines: LineForm[]\n customer: { record: { kind: string; id: string } | null; name: string; company: string; email: string; phone: string }\n shipTo: AddressForm\n billTo: AddressForm\n discountKind: 'none' | 'amount' | 'percent'\n discountValue: string\n shipping: string\n notes: string\n terms: string\n requireProofApproval: boolean\n}\n\nlet lineSequence = 0\nconst nextLineKey = () => `line-${++lineSequence}`\n\nfunction formFromQuote(quote: QuoteRow | null, requireProofApproval: boolean): QuoteForm {\n const section = quote?.quote\n const discount = section?.discount ?? null\n return {\n lines: (quote?.lineItems ?? []).map((line): LineForm => {\n const request = CommerceModel.quoteLineRequestFromLine(line)\n return request.kind === 'custom'\n ? {\n key: nextLineKey(),\n kind: 'custom',\n name: request.name,\n description: request.description ?? '',\n sku: request.sku ?? '',\n price: dollarsOf(request.unitAmountCents),\n quantity: String(request.quantity),\n ships: request.ships !== false,\n included: request.included === true,\n }\n : {\n key: nextLineKey(),\n kind: 'catalog',\n productId: request.productId,\n variantId: request.variantId ?? '',\n quantity: String(request.quantity),\n modifiers: request.modifiers ?? [],\n description: request.description ?? '',\n included: request.included === true,\n }\n }),\n customer: {\n record: section?.customer?.record ?? null,\n name: section?.customer?.name ?? '',\n company: section?.customer?.company ?? '',\n email: section?.customer?.email ?? '',\n phone: section?.customer?.phone ?? '',\n },\n shipTo: addressForm(section?.shipTo),\n billTo: addressForm(section?.billTo),\n discountKind: discount?.kind ?? 'none',\n discountValue:\n discount?.kind === 'amount' ? dollarsOf(discount.amountCents) : discount?.kind === 'percent' ? String(discount.pct) : '',\n shipping: dollarsOf(section?.shipping?.amountCents),\n notes: section?.notes ?? '',\n terms: section?.terms ?? '',\n requireProofApproval: section ? section.requireProofApproval === true : requireProofApproval,\n }\n}\n\nfunction lineRequest(line: LineForm): CommerceModel.QuoteLineRequest {\n const quantity = Number(line.quantity)\n if (line.kind === 'catalog') {\n return {\n kind: 'catalog',\n productId: line.productId,\n ...(line.variantId ? { variantId: line.variantId } : {}),\n quantity,\n ...(line.modifiers.length ? { modifiers: line.modifiers } : {}),\n ...(line.included ? { included: true } : {}),\n ...(line.description.trim() ? { description: line.description.trim() } : {}),\n }\n }\n return {\n kind: 'custom',\n name: line.name.trim(),\n ...(line.description.trim() ? { description: line.description.trim() } : {}),\n ...(line.sku.trim() ? { sku: line.sku.trim() } : {}),\n unitAmountCents: line.included ? 0 : (centsOf(line.price) ?? Number.NaN),\n quantity,\n ships: line.ships,\n ...(line.included ? { included: true } : {}),\n }\n}\n\nfunction addressBody(address: AddressForm): Partial<AddressForm> | null {\n const entries = Object.entries(address).filter(([, value]) => value.trim())\n return entries.length ? Object.fromEntries(entries.map(([key, value]) => [key, value.trim()])) : null\n}\n\n/** What the server is sent: choices, never what a product costs. */\nfunction quoteBody(form: QuoteForm): Record<string, unknown> {\n const discountCents = centsOf(form.discountValue)\n return {\n lines: form.lines.map(lineRequest),\n customer: {\n ...(form.customer.record ? { record: form.customer.record } : {}),\n name: form.customer.name,\n company: form.customer.company,\n email: form.customer.email,\n phone: form.customer.phone,\n },\n shipTo: addressBody(form.shipTo),\n billTo: addressBody(form.billTo),\n discount:\n form.discountKind === 'amount'\n ? { kind: 'amount', amountCents: discountCents ?? Number.NaN }\n : form.discountKind === 'percent'\n ? { kind: 'percent', pct: Number(form.discountValue || 0) }\n : null,\n shipping: form.shipping.trim() ? { amountCents: centsOf(form.shipping) ?? Number.NaN } : null,\n notes: form.notes,\n terms: form.terms,\n requireProofApproval: form.requireProofApproval,\n }\n}\n\ninterface FoundCustomer {\n record: { kind: string; id: string }\n name: string\n company: string\n email: string | null\n phone: string | null\n}\n\n/**\n * The quote editor (AGL-4093): who it is for, its lines (products with their\n * options and add-ons, typed items, things included at no charge), discount,\n * shipping, notes and terms, with the totals worked out as it is edited. The\n * server prices and saves it; the totals here are the same function's answer\n * over the same inputs, and a connected tax service's figure arrives on save.\n */\nexport function QuoteEditorDialog(props: QuoteEditorDialogProps) {\n const { hostId, quote, products, canEdit, canSend, onClose } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const taxesHref = useStoreSettingsHref(hostId, 'taxes')\n const { data: store } = useFirestoreDoc<any>(\n () => doc(firestore, 'hosts', hostId, 'settings', 'store'),\n [firestore, hostId],\n )\n const storeDefault = CommerceModel.quoteRequiresProofApprovalByDefault(store?.quotes)\n const [form, setForm] = useState<QuoteForm>(() => formFromQuote(quote, storeDefault))\n // The version this form was opened on. A change saved elsewhere while it is\n // open arrives on `quote`; the save still names this one, so the server\n // refuses rather than overwrite that change.\n const [baseUpdatedAtMs] = useState(() => quote?.quote?.updatedAtMs)\n const [busy, setBusy] = useState(false)\n const [confirmingDelete, setConfirmingDelete] = useState(false)\n /** Whether anything has been changed since the dialog opened. */\n const [edited, setEdited] = useState(false)\n /** Whether the proof-approval switch was set by hand. */\n const [approvalSet, setApprovalSet] = useState(false)\n // A new quote starts with the store's default, which may arrive after the\n // dialog opens; a switch set by hand keeps its setting.\n const requireProofApproval = quote || approvalSet ? form.requireProofApproval : storeDefault\n\n const update = useCallback((patch: Partial<QuoteForm>) => {\n setEdited(true)\n if ('requireProofApproval' in patch) setApprovalSet(true)\n setForm((prev) => ({ ...prev, ...patch }))\n }, [])\n const updateLine = useCallback((key: string, patch: Partial<LineForm>) => {\n setEdited(true)\n setForm((prev) => ({\n ...prev,\n lines: prev.lines.map((line) => (line.key === key ? ({ ...line, ...patch } as LineForm) : line)),\n }))\n }, [])\n\n /*\n * One attempt per change (AGL-1697's rule): a retried Save presents the same\n * key and is answered from the first, an edited quote is a new attempt.\n */\n const attemptKey = useRef('')\n useEffect(() => {\n attemptKey.current = ''\n }, [form])\n\n const productsById = useMemo(\n () => new Map(products.map((product) => [String(product.$id), product])),\n [products],\n )\n\n /** Each line priced as the server will price it, or why it cannot be. */\n const priced = useMemo(\n () =>\n form.lines.map((line) => {\n const request = lineRequest(line)\n if (request.kind === 'custom') {\n if (!request.name) return { error: 'Name the item.' }\n if (!Number.isInteger(request.unitAmountCents)) return { error: 'Enter a price.' }\n if (!(request.quantity >= 1)) return { error: 'Enter a quantity.' }\n return { line: CommerceModel.priceQuoteCustomLine(request) }\n }\n if (!request.productId) return { error: 'Choose a product.' }\n if (!(request.quantity >= 1)) return { error: 'Enter a quantity.' }\n const answer = CommerceModel.priceQuoteCatalogLine(productsById.get(request.productId) as never, request)\n return 'error' in answer ? { error: answer.error } : { line: answer.line }\n }),\n [form.lines, productsById],\n )\n\n const discountCents = centsOf(form.discountValue)\n const discount: CommerceModel.QuoteDiscount | null =\n form.discountKind === 'amount' && discountCents\n ? { kind: 'amount', amountCents: discountCents }\n : form.discountKind === 'percent' && Number(form.discountValue) > 0\n ? { kind: 'percent', pct: Math.min(100, Number(form.discountValue)) }\n : null\n const shippingCents = centsOf(form.shipping) ?? 0\n const taxBasis = CommerceModel.quoteTaxBasisFromSettings(store?.tax, {\n country: form.shipTo.country.trim().toUpperCase(),\n state: form.shipTo.state.trim(),\n })\n const pricedLines = priced.flatMap((entry) => ('line' in entry && entry.line ? [entry.line] : []))\n const totals = CommerceModel.computeQuoteTotals({ lines: pricedLines, discount, shippingCents, tax: taxBasis })\n const problems = priced.some((entry) => 'error' in entry)\n const savedService = quote?.quote?.tax?.kind === 'service' ? quote.quote.tax : null\n\n const save = useCallback(async () => {\n setBusy(true)\n try {\n if (!attemptKey.current) {\n attemptKey.current = globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`\n }\n const response = await authorizedFetch(user, '/api/commerce/quote', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Idempotency-Key': attemptKey.current },\n body: JSON.stringify({\n action: quote ? 'update' : 'create',\n hostId,\n ...(quote ? { quoteId: quote.$id, baseUpdatedAtMs } : {}),\n quote: quoteBody({ ...form, requireProofApproval }),\n }),\n })\n const payload = await response.json().catch(() => ({}))\n if (!response.ok) {\n return void enqueueSnackbar(payload?.error ?? 'The quote could not be saved', { variant: 'error', allowDuplicate: true })\n }\n enqueueSnackbar(`${CommerceModel.formatQuoteNumber({ number: payload.number ?? undefined }, payload.quoteId)} saved`, {\n variant: 'success',\n persist: false,\n })\n onClose()\n } finally {\n setBusy(false)\n }\n }, [user, quote, hostId, baseUpdatedAtMs, form, requireProofApproval, enqueueSnackbar, onClose])\n\n const remove = useCallback(async () => {\n if (!quote) return\n setBusy(true)\n try {\n const response = await authorizedFetch(user, '/api/commerce/quote', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ action: 'delete', hostId, quoteId: quote.$id }),\n })\n const payload = await response.json().catch(() => ({}))\n if (!response.ok) {\n return void enqueueSnackbar(payload?.error ?? 'The quote could not be deleted', { variant: 'error', allowDuplicate: true })\n }\n enqueueSnackbar(`${CommerceModel.formatQuoteNumber(quote, quote.$id)} deleted`, { variant: 'success', persist: false })\n setConfirmingDelete(false)\n onClose()\n } finally {\n setBusy(false)\n }\n }, [user, quote, hostId, enqueueSnackbar, onClose])\n\n const readOnly = !canEdit || busy\n const paid = quote ? !CommerceModel.isUnpaidQuote(quote) : false\n const title = quote ? CommerceModel.formatQuoteNumber(quote, quote.$id) : 'New quote'\n const status = quote ? CommerceModel.quoteDisplayStatus(quote) : null\n const deletable = Boolean(quote) && !paid && (quote?.quote?.stage ?? 'draft') === 'draft'\n\n return (\n <Dialog open onClose={busy ? undefined : onClose} maxWidth=\"md\" fullWidth scroll=\"paper\" aria-labelledby=\"quote-editor-title\">\n <DialogTitle id=\"quote-editor-title\">\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <span>{title}</span>\n {status ? (\n <Chip size=\"small\" variant=\"outlined\" label={status.label} color={CommerceModel.QUOTE_STATUS_COLOR[status.key]} />\n ) : null}\n </Stack>\n </DialogTitle>\n <DialogContent dividers>\n <Stack spacing={3}>\n {paid ? (\n <Alert severity=\"success\">\n {quote?.quote?.paidAtMs\n ? `Paid ${new Date(quote.quote.paidAtMs).toLocaleDateString()}. It is an order now and can no longer be changed.`\n : 'This quote has been paid, so it is an order now and can no longer be changed.'}\n </Alert>\n ) : null}\n {quote ? (\n <QuotePayLinkSection hostId={hostId} quoteId={quote.$id} quote={quote} canSend={canSend} edited={edited} />\n ) : null}\n {taxBasis.kind === 'none' && taxBasis.reason === 'undecided' ? (\n <PrerequisiteNotice href={taxesHref ?? undefined} actionLabel=\"Open Taxes\">\n {'This store has not chosen how it handles sales tax, so this quote shows no tax. Choose it in Taxes.'}\n </PrerequisiteNotice>\n ) : null}\n\n <QuoteCustomerSection\n hostId={hostId}\n form={form}\n disabled={readOnly || paid}\n onChange={(customer) => update({ customer })}\n />\n\n <Stack spacing={1.5}>\n <Typography variant=\"subtitle2\">{'Items'}</Typography>\n {form.lines.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Add products from your catalog, or type an item that is made to order.'}\n </Typography>\n ) : null}\n {form.lines.map((line, index) => (\n <QuoteLineEditor\n key={line.key}\n line={line}\n priced={priced[index]}\n products={products}\n disabled={readOnly || paid}\n onChange={(patch) => updateLine(line.key, patch)}\n onRemove={() => update({ lines: form.lines.filter((entry) => entry.key !== line.key) })}\n />\n ))}\n <Stack direction=\"row\" spacing={1} useFlexGap sx={{ flexWrap: 'wrap' }}>\n <Button\n size=\"small\"\n disabled={readOnly || paid || products.length === 0}\n onClick={() =>\n update({\n lines: [\n ...form.lines,\n { key: nextLineKey(), kind: 'catalog', productId: '', variantId: '', quantity: '1', modifiers: [], description: '', included: false },\n ],\n })\n }\n >\n {'Add product'}\n </Button>\n <Button\n size=\"small\"\n disabled={readOnly || paid}\n onClick={() =>\n update({\n lines: [\n ...form.lines,\n { key: nextLineKey(), kind: 'custom', name: '', description: '', sku: '', price: '', quantity: '1', ships: true, included: false },\n ],\n })\n }\n >\n {'Add custom item'}\n </Button>\n </Stack>\n </Stack>\n\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <TextField\n label=\"Discount\"\n select\n size=\"small\"\n value={form.discountKind}\n disabled={readOnly || paid}\n onChange={(event) => update({ discountKind: event.target.value as QuoteForm['discountKind'] })}\n sx={mediumField}\n >\n <MenuItem value=\"none\">{'None'}</MenuItem>\n <MenuItem value=\"amount\">{'Amount off'}</MenuItem>\n <MenuItem value=\"percent\">{'Percent off'}</MenuItem>\n </TextField>\n {form.discountKind !== 'none' ? (\n <TextField\n label={form.discountKind === 'amount' ? 'Amount ($)' : 'Percent (%)'}\n size=\"small\"\n value={form.discountValue}\n disabled={readOnly || paid}\n onChange={(event) => update({ discountValue: event.target.value })}\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n error={form.discountKind === 'amount' ? centsOf(form.discountValue) === null : !(Number(form.discountValue) >= 0 && Number(form.discountValue) <= 100)}\n />\n ) : null}\n <TextField\n label=\"Shipping ($)\"\n size=\"small\"\n value={form.shipping}\n disabled={readOnly || paid}\n onChange={(event) => update({ shipping: event.target.value })}\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n error={centsOf(form.shipping) === null}\n helperText=\"Leave empty when nothing ships.\"\n />\n </Stack>\n\n <QuoteAddressFields\n label=\"Ship to\"\n value={form.shipTo}\n disabled={readOnly || paid}\n helperText=\"Where the order goes. Store tax rates use its state and country.\"\n onChange={(shipTo) => update({ shipTo })}\n />\n <QuoteAddressFields\n label=\"Bill to\"\n value={form.billTo}\n disabled={readOnly || paid}\n onChange={(billTo) => update({ billTo })}\n />\n\n <Stack spacing={2}>\n <TextField\n label=\"Notes for the customer\"\n multiline\n minRows={2}\n value={form.notes}\n disabled={readOnly || paid}\n onChange={(event) => update({ notes: event.target.value })}\n />\n <TextField\n label=\"Terms\"\n multiline\n minRows={2}\n value={form.terms}\n disabled={readOnly || paid}\n onChange={(event) => update({ terms: event.target.value })}\n />\n <FormControlLabel\n control={\n <Switch\n checked={requireProofApproval}\n disabled={readOnly || paid}\n onChange={(event) => update({ requireProofApproval: event.target.checked })}\n />\n }\n label=\"Customers approve the proof before they can pay\"\n />\n </Stack>\n\n <Divider />\n <QuoteTotalsSummary\n totals={totals}\n tax={taxBasis}\n savedService={edited ? null : savedService}\n savedTotals={edited ? null : (quote?.totals ?? null)}\n />\n </Stack>\n </DialogContent>\n <DialogActions sx={{ flexWrap: 'wrap', rowGap: 1 }}>\n {deletable ? (\n <BlockedControl blocked={!canEdit} reason={REFUSAL}>\n <Button color=\"error\" disabled={busy} onClick={() => setConfirmingDelete(true)} sx={{ mr: 'auto' }}>\n {'Delete'}\n </Button>\n </BlockedControl>\n ) : null}\n <Button onClick={onClose} disabled={busy}>\n {paid || !canEdit ? 'Close' : 'Cancel'}\n </Button>\n {paid ? null : (\n <BlockedControl blocked={!canEdit} reason={REFUSAL}>\n <Button\n variant=\"contained\"\n disabled={busy || form.lines.length === 0 || problems}\n onClick={() => void save()}\n >\n {quote ? 'Save' : 'Create quote'}\n </Button>\n </BlockedControl>\n )}\n </DialogActions>\n <Dialog open={confirmingDelete} onClose={() => setConfirmingDelete(false)} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{`Delete ${title}?`}</DialogTitle>\n <DialogContent>\n <DialogContentText>{'The quote and everything on it is removed. This can’t be undone.'}</DialogContentText>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setConfirmingDelete(false)} disabled={busy}>\n {'Cancel'}\n </Button>\n <Button color=\"error\" variant=\"contained\" disabled={busy} onClick={() => void remove()}>\n {'Delete'}\n </Button>\n </DialogActions>\n </Dialog>\n </Dialog>\n )\n}\nQuoteEditorDialog.displayName = 'QuoteEditorDialog'\n\n/** Who the quote is for: a person the workspace keeps, or details typed here. */\nfunction QuoteCustomerSection(props: {\n hostId: string\n form: QuoteForm\n disabled: boolean\n onChange: (customer: QuoteForm['customer']) => void\n}) {\n const { hostId, form, disabled, onChange } = props\n const { data: user } = useUser()\n const [text, setText] = useState('')\n const [found, setFound] = useState<FoundCustomer[]>([])\n const [available, setAvailable] = useState(true)\n const ticket = useRef(0)\n const customer = form.customer\n\n useEffect(() => {\n const typed = text.trim()\n if (typed.length < 2 || !user) {\n // Only when something is listed, so an effect that re-runs settles.\n setFound((prev) => (prev.length ? [] : prev))\n return\n }\n const mine = ++ticket.current\n const timer = window.setTimeout(() => {\n void authorizedFetch(user, '/api/commerce/quote', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ action: 'search-customers', hostId, text: typed }),\n })\n .then((response) => response.json().catch(() => ({})))\n .then((payload) => {\n if (mine !== ticket.current) return\n setAvailable(payload?.available !== false)\n setFound(Array.isArray(payload?.customers) ? payload.customers : [])\n })\n .catch(() => undefined)\n }, SEARCH_DEBOUNCE_MS)\n return () => window.clearTimeout(timer)\n }, [text, user, hostId])\n\n const pick = (person: FoundCustomer) => {\n onChange({\n record: person.record,\n name: person.name,\n company: person.company,\n email: person.email ?? '',\n phone: person.phone ?? '',\n })\n setText('')\n setFound([])\n }\n\n return (\n <Stack spacing={1.5}>\n <Typography variant=\"subtitle2\">{'Customer'}</Typography>\n {customer.record ? (\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Chip\n color=\"primary\"\n variant=\"outlined\"\n label={customer.name || customer.email || 'Contact'}\n onDelete={disabled ? undefined : () => onChange({ ...customer, record: null })}\n />\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'From your contacts'}\n </Typography>\n </Stack>\n ) : available ? (\n <Box>\n <TextField\n size=\"small\"\n fullWidth\n label=\"Find a contact\"\n placeholder=\"Name, email or phone\"\n value={text}\n disabled={disabled}\n onChange={(event) => setText(event.target.value)}\n />\n {found.length ? (\n <Paper variant=\"outlined\" sx={{ mt: 0.5 }}>\n <List dense disablePadding>\n {found.map((person) => (\n <ListItemButton key={`${person.record.kind}:${person.record.id}`} onClick={() => pick(person)}>\n <ListItemText\n primary={person.name || person.email || 'Contact'}\n secondary={[person.company, person.email, person.phone].filter(Boolean).join(' · ')}\n />\n </ListItemButton>\n ))}\n </List>\n </Paper>\n ) : null}\n </Box>\n ) : null}\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <TextField size=\"small\" fullWidth label=\"Name\" value={customer.name} disabled={disabled} onChange={(event) => onChange({ ...customer, name: event.target.value })} />\n <TextField size=\"small\" fullWidth label=\"Company\" value={customer.company} disabled={disabled} onChange={(event) => onChange({ ...customer, company: event.target.value })} />\n </Stack>\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <TextField size=\"small\" fullWidth label=\"Email\" type=\"email\" value={customer.email} disabled={disabled} onChange={(event) => onChange({ ...customer, email: event.target.value })} />\n <TextField size=\"small\" fullWidth label=\"Phone\" value={customer.phone} disabled={disabled} onChange={(event) => onChange({ ...customer, phone: event.target.value })} />\n </Stack>\n </Stack>\n )\n}\n\n/** One address on the quote. */\nfunction QuoteAddressFields(props: {\n label: string\n value: AddressForm\n disabled: boolean\n helperText?: string\n onChange: (value: AddressForm) => void\n}) {\n const { label, value, disabled, helperText, onChange } = props\n const field = (key: keyof AddressForm, fieldLabel: string, extra: Record<string, unknown> = {}) => (\n <TextField\n size=\"small\"\n fullWidth\n label={fieldLabel}\n value={value[key]}\n disabled={disabled}\n onChange={(event) => onChange({ ...value, [key]: event.target.value })}\n {...extra}\n />\n )\n return (\n <Stack spacing={1.5}>\n <Typography variant=\"subtitle2\">{label}</Typography>\n {helperText ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {helperText}\n </Typography>\n ) : null}\n {field('name', 'Name')}\n {field('line1', 'Address')}\n {field('line2', 'Apartment, suite, unit')}\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n {field('city', 'City')}\n {field('state', 'State or region')}\n {field('postalCode', 'Postal code')}\n {field('country', 'Country code', { placeholder: 'US', slotProps: { htmlInput: { maxLength: 2 } } })}\n </Stack>\n </Stack>\n )\n}\n\n/** One line of the quote: a product with its options and add-ons, or a typed item. */\nfunction QuoteLineEditor(props: {\n line: LineForm\n priced: { line?: CommerceModel.PricedQuoteLine; error?: string } | undefined\n products: readonly Record<string, any>[]\n disabled: boolean\n onChange: (patch: Partial<LineForm>) => void\n onRemove: () => void\n}) {\n const { line, priced, products, disabled, onChange, onRemove } = props\n const product = line.kind === 'catalog' ? products.find((entry) => String(entry.$id) === line.productId) : undefined\n const lifted = product ? CommerceModel.liftLegacyProduct(product) : null\n const groups = lifted ? CommerceModel.productModifierGroups(lifted) : []\n const lineCents = priced?.line ? CommerceModel.quoteLineCents(priced.line) : 0\n\n return (\n <Paper variant=\"outlined\" sx={{ p: 2 }}>\n <Stack spacing={1.5}>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'flex-start' }}>\n <Stack spacing={1.5} sx={{ flex: 1, minWidth: 0 }}>\n {line.kind === 'catalog' ? (\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <TextField\n label=\"Product\"\n select\n size=\"small\"\n fullWidth\n value={line.productId}\n disabled={disabled}\n onChange={(event) => onChange({ productId: event.target.value, variantId: '', modifiers: [] })}\n >\n {products.map((entry) => (\n <MenuItem key={String(entry.$id)} value={String(entry.$id)}>\n {String(entry.name ?? entry.$id)}\n </MenuItem>\n ))}\n </TextField>\n {lifted && lifted.variants.length > 1 ? (\n <TextField\n label=\"Option\"\n select\n size=\"small\"\n fullWidth\n value={line.variantId || lifted.variants[0]?.id || ''}\n disabled={disabled}\n onChange={(event) => onChange({ variantId: event.target.value })}\n >\n {lifted.variants.map((variant) => (\n <MenuItem key={variant.id} value={variant.id}>\n {Object.values(variant.options ?? {}).join(' / ') || 'Default'}\n </MenuItem>\n ))}\n </TextField>\n ) : null}\n </Stack>\n ) : (\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <TextField\n label=\"Item\"\n size=\"small\"\n fullWidth\n value={line.name}\n disabled={disabled}\n onChange={(event) => onChange({ name: event.target.value })}\n />\n <TextField\n label=\"SKU (optional)\"\n size=\"small\"\n value={line.sku}\n disabled={disabled}\n onChange={(event) => onChange({ sku: event.target.value })}\n />\n </Stack>\n )}\n {groups.map((group) => {\n const chosen = line.kind === 'catalog' ? line.modifiers.filter((pick) => pick.groupId === group.id).map((pick) => pick.optionId) : []\n return (\n <TextField\n key={group.id}\n label={CommerceModel.modifierGroupRequired(group) ? group.name : `${group.name} (optional)`}\n select\n size=\"small\"\n fullWidth\n value={group.max > 1 ? chosen : (chosen[0] ?? '')}\n disabled={disabled}\n slotProps={{ select: { multiple: group.max > 1 } }}\n onChange={(event) => {\n const raw = event.target.value as unknown\n const picked = (Array.isArray(raw) ? raw : raw ? [raw] : []).map(String)\n if (line.kind !== 'catalog') return\n onChange({\n modifiers: [\n ...line.modifiers.filter((pick) => pick.groupId !== group.id),\n ...picked.map((optionId) => ({ groupId: group.id, optionId })),\n ],\n })\n }}\n >\n {group.max > 1 ? null : <MenuItem value=\"\">{'None'}</MenuItem>}\n {group.options.map((option) => (\n <MenuItem key={option.id} value={option.id}>\n {option.priceCents ? `${option.name} (+${money(option.priceCents)})` : option.name}\n </MenuItem>\n ))}\n </TextField>\n )\n })}\n <TextField\n label=\"Description (optional)\"\n size=\"small\"\n fullWidth\n multiline\n value={line.description}\n disabled={disabled}\n onChange={(event) => onChange({ description: event.target.value })}\n />\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'center' } }}>\n <TextField\n label=\"Quantity\"\n size=\"small\"\n value={line.quantity}\n disabled={disabled}\n onChange={(event) => onChange({ quantity: event.target.value.replace(/[^0-9]/g, '') })}\n slotProps={{ htmlInput: { inputMode: 'numeric' } }}\n sx={narrowField}\n />\n {line.kind === 'custom' ? (\n <TextField\n label=\"Unit price ($)\"\n size=\"small\"\n value={line.included ? '' : line.price}\n disabled={disabled || line.included}\n onChange={(event) => onChange({ price: event.target.value })}\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n error={!line.included && centsOf(line.price) === null}\n sx={mediumField}\n />\n ) : null}\n {line.kind === 'custom' ? (\n <FormControlLabel\n control={<Switch checked={line.ships} disabled={disabled} onChange={(event) => onChange({ ships: event.target.checked })} />}\n label=\"Ships\"\n />\n ) : null}\n <FormControlLabel\n control={\n <Switch checked={line.included} disabled={disabled} onChange={(event) => onChange({ included: event.target.checked })} />\n }\n label=\"Included at no charge\"\n />\n </Stack>\n </Stack>\n <Stack sx={{ alignItems: 'flex-end', flexShrink: 0 }}>\n <Button size=\"small\" color=\"inherit\" disabled={disabled} onClick={onRemove}>\n {'Remove'}\n </Button>\n <Typography variant=\"body2\" sx={{ fontWeight: 'fontWeightMedium' }}>\n {line.included ? 'Included' : money(lineCents)}\n </Typography>\n {priced?.line && !line.included && priced.line.quantity > 1 ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`${money(priced.line.unitAmountCents)} each`}\n </Typography>\n ) : null}\n </Stack>\n </Stack>\n {priced?.error ? (\n <Typography variant=\"caption\" color=\"error\">\n {priced.error}\n </Typography>\n ) : null}\n </Stack>\n </Paper>\n )\n}\n\n/** The quote's totals, as the customer will read them. */\nfunction QuoteTotalsSummary(props: {\n totals: CommerceModel.QuoteTotals\n tax: CommerceModel.QuoteTaxBasis\n /** A saved quote's tax service answer, shown until the quote is edited. */\n savedService: CommerceModel.QuoteTaxBasis | null\n savedTotals: CommerceModel.OrderTotals | null\n}) {\n const { totals, tax, savedService, savedTotals } = props\n const shown = savedService && savedTotals ? { ...totals, ...savedTotals } : totals\n const taxLabel = CommerceModel.describeQuoteTax(savedService ?? tax)\n const row = (label: string, value: string, strong = false) => (\n <Stack direction=\"row\" sx={{ justifyContent: 'space-between' }}>\n <Typography variant={strong ? 'subtitle1' : 'body2'} color={strong ? 'text.primary' : 'text.secondary'}>\n {label}\n </Typography>\n <Typography variant={strong ? 'subtitle1' : 'body2'}>{value}</Typography>\n </Stack>\n )\n return (\n <Stack spacing={0.5} sx={(theme) => ({ alignSelf: { sm: 'flex-end' }, minWidth: { sm: theme.spacing(40) } })}>\n {row('Items', money(shown.itemsCents))}\n {shown.discountCents ? row('Discount', `−${money(shown.discountCents)}`) : null}\n {shown.shippingCents ? row('Shipping', money(shown.shippingCents)) : null}\n {tax.kind === 'at-payment' && !savedService ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {taxLabel}\n </Typography>\n ) : (\n row(taxLabel, money(shown.taxCents))\n )}\n {row(totals.taxAtPayment && !savedService ? 'Total before tax' : 'Total', money(shown.totalCents), true)}\n </Stack>\n )\n}\n\nexport default QuoteEditorDialog\n"],"names":["CommerceModel","posMoney","commerceSitePermissionRefusal","BlockedControl","PrerequisiteNotice","useSnackbar","authorizedFetch","useFirestore","useFirestoreDoc","useStoreSettingsHref","useUser","Alert","Box","Button","Chip","Dialog","DialogActions","DialogContent","DialogContentText","DialogTitle","Divider","FormControlLabel","List","ListItemButton","ListItemText","MenuItem","Paper","Stack","Switch","TextField","Typography","doc","useCallback","useEffect","useMemo","useRef","useState","QuotePayLinkSection","REFUSAL","SEARCH_DEBOUNCE_MS","money","cents","narrowField","theme","maxWidth","sm","spacing","mediumField","minWidth","centsOf","text","trimmed","trim","test","Math","round","Number","dollarsOf","toFixed","replace","addressForm","address","name","line1","line2","city","state","postalCode","country","lineSequence","nextLineKey","formFromQuote","quote","requireProofApproval","section","discount","lines","lineItems","map","line","request","quoteLineRequestFromLine","kind","key","description","sku","price","unitAmountCents","quantity","String","ships","included","productId","variantId","modifiers","customer","record","company","email","phone","shipTo","billTo","discountKind","discountValue","amountCents","pct","shipping","notes","terms","lineRequest","length","NaN","addressBody","entries","Object","filter","value","fromEntries","quoteBody","form","discountCents","QuoteEditorDialog","props","hostId","products","canEdit","canSend","onClose","firestore","data","user","enqueueSnackbar","taxesHref","store","storeDefault","quoteRequiresProofApprovalByDefault","quotes","setForm","baseUpdatedAtMs","updatedAtMs","busy","setBusy","confirmingDelete","setConfirmingDelete","edited","setEdited","approvalSet","setApprovalSet","update","patch","prev","updateLine","attemptKey","current","productsById","Map","product","$id","priced","error","isInteger","priceQuoteCustomLine","answer","priceQuoteCatalogLine","get","min","shippingCents","taxBasis","quoteTaxBasisFromSettings","tax","toUpperCase","pricedLines","flatMap","entry","totals","computeQuoteTotals","problems","some","savedService","save","payload","globalThis","crypto","randomUUID","Date","now","random","toString","slice","response","method","headers","body","JSON","stringify","action","quoteId","json","catch","ok","variant","allowDuplicate","formatQuoteNumber","number","undefined","persist","remove","readOnly","paid","isUnpaidQuote","title","status","quoteDisplayStatus","deletable","Boolean","stage","open","fullWidth","scroll","aria-labelledby","id","direction","sx","alignItems","span","size","label","color","QUOTE_STATUS_COLOR","dividers","severity","paidAtMs","toLocaleDateString","reason","href","actionLabel","QuoteCustomerSection","disabled","onChange","index","QuoteLineEditor","onRemove","useFlexGap","flexWrap","onClick","xs","select","event","target","slotProps","htmlInput","inputMode","helperText","QuoteAddressFields","multiline","minRows","control","checked","QuoteTotalsSummary","savedTotals","rowGap","blocked","mr","displayName","setText","found","setFound","available","setAvailable","ticket","typed","mine","timer","window","setTimeout","then","Array","isArray","customers","clearTimeout","pick","person","onDelete","placeholder","mt","dense","disablePadding","primary","secondary","join","type","field","fieldLabel","extra","maxLength","lifted","find","liftLegacyProduct","groups","productModifierGroups","lineCents","quoteLineCents","p","flex","variants","values","options","group","chosen","groupId","optionId","modifierGroupRequired","max","multiple","raw","picked","option","priceCents","flexShrink","fontWeight","shown","taxLabel","describeQuoteTax","row","strong","justifyContent","alignSelf","itemsCents","taxCents","taxAtPayment","totalCents"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/quote-editor-dialog.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport * as CommerceModel from '../../model'\nimport { posMoney } from '../../model/commerce-pos-ops'\nimport { commerceSitePermissionRefusal } from '../../model/plugin-permissions'\nimport { BlockedControl } from '@aglyn/shared-ui-jsx/components/blocked-control.component'\nimport { PrerequisiteNotice } from '@aglyn/shared-ui-jsx/components/prerequisite-notice.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport {\n useFirestore,\n useFirestoreDoc,\n useStoreSettingsHref,\n useUser,\n} from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Box,\n Button,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogContentText,\n DialogTitle,\n Divider,\n FormControlLabel,\n List,\n ListItemButton,\n ListItemText,\n MenuItem,\n Paper,\n Stack,\n Switch,\n TextField,\n Typography,\n type Theme,\n} from '@mui/material'\nimport { doc } from 'firebase/firestore'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { downloadCommercePdf } from './commerce-pdf-download'\nimport { QuotePayLinkSection } from './quote-pay-link.component'\nimport { QuoteProofsSection, QuoteRequestFilesSection } from './quote-proofs.component'\nimport { QuoteSendSection } from './quote-send.component'\n\n/** A quote as the list reads it: the order document and its id. */\nexport type QuoteRow = CommerceModel.HostOrder & { $id: string }\n\nexport interface QuoteEditorDialogProps {\n hostId: string\n /** The quote to edit, or `null` for a new one. */\n quote: QuoteRow | null\n /** The store's products, for the product picker. */\n products: readonly Record<string, any>[]\n /** Holds \"Create and edit quotes\" (`commerce.quotes`). */\n canEdit: boolean\n /** Holds \"Send quotes and invoices to customers\" (`commerce.quotes.send`). */\n canSend: boolean\n /**\n * What a NEW quote opens with when it is started from a request or a\n * contact (AGL-4098). The editable fields are filled in; a request's own\n * parts (which request, its files, its conversation) are stamped by the\n * server from `from` when the quote is created, never from here.\n */\n start?: QuoteEditorStart | null\n onClose: () => void\n}\n\n/** A new quote's start: from a request (with what it carried) or from a contact. */\nexport interface QuoteEditorStart {\n /** The request it is started from, which the server reads again on create; null for a contact. */\n from: { kind: 'submission'; id: string } | null\n prefill: CommerceModel.QuoteStartPrefill\n /** The request, as the editor says where the quote came from. */\n request?: { formName: string; receivedAtMs: number | null } | null\n files?: ReadonlyArray<{ id: string; name: string; contentType: string; size: number }>\n /** Whether the request started an email conversation the quote's first email will reply into. */\n threaded?: boolean\n}\n\nconst REFUSAL = commerceSitePermissionRefusal('commerce.quotes')\nconst SEARCH_DEBOUNCE_MS = 250\n\nconst money = (cents: number): string => posMoney(cents)\n\n/** Field widths on a wide screen, from the theme's spacing; full width on a phone. */\nconst narrowField = (theme: Theme) => ({ maxWidth: { sm: theme.spacing(16) } })\nconst mediumField = (theme: Theme) => ({ minWidth: { sm: theme.spacing(20) }, maxWidth: { sm: theme.spacing(24) } })\n\n/** Dollars typed into a field, as whole cents, or `null` when it is not an amount. */\nfunction centsOf(text: string): number | null {\n const trimmed = text.trim()\n if (!trimmed) return 0\n if (!/^\\d+(\\.\\d{0,2})?$/.test(trimmed)) return null\n return Math.round(Number(trimmed) * 100)\n}\n\nconst dollarsOf = (cents: number | undefined): string =>\n cents ? (cents / 100).toFixed(2).replace(/\\.00$/, '') : ''\n\ntype AddressForm = Record<'name' | 'line1' | 'line2' | 'city' | 'state' | 'postalCode' | 'country', string>\n\nfunction addressForm(address: CommerceModel.OrderAddress | null | undefined): AddressForm {\n return {\n name: address?.name ?? '',\n line1: address?.line1 ?? '',\n line2: address?.line2 ?? '',\n city: address?.city ?? '',\n state: address?.state ?? '',\n postalCode: address?.postalCode ?? '',\n country: address?.country ?? '',\n }\n}\n\ntype LineForm =\n | {\n key: string\n kind: 'catalog'\n productId: string\n variantId: string\n quantity: string\n modifiers: CommerceModel.ModifierSelection[]\n description: string\n included: boolean\n }\n | {\n key: string\n kind: 'custom'\n name: string\n description: string\n sku: string\n price: string\n quantity: string\n ships: boolean\n included: boolean\n }\n\ninterface QuoteForm {\n lines: LineForm[]\n customer: { record: { kind: string; id: string } | null; name: string; company: string; email: string; phone: string }\n shipTo: AddressForm\n billTo: AddressForm\n discountKind: 'none' | 'amount' | 'percent'\n discountValue: string\n shipping: string\n notes: string\n terms: string\n requireProofApproval: boolean\n}\n\nlet lineSequence = 0\nconst nextLineKey = () => `line-${++lineSequence}`\n\nfunction formFromQuote(quote: QuoteRow | null, requireProofApproval: boolean): QuoteForm {\n const section = quote?.quote\n const discount = section?.discount ?? null\n return {\n lines: (quote?.lineItems ?? []).map((line): LineForm => {\n const request = CommerceModel.quoteLineRequestFromLine(line)\n return request.kind === 'custom'\n ? {\n key: nextLineKey(),\n kind: 'custom',\n name: request.name,\n description: request.description ?? '',\n sku: request.sku ?? '',\n price: dollarsOf(request.unitAmountCents),\n quantity: String(request.quantity),\n ships: request.ships !== false,\n included: request.included === true,\n }\n : {\n key: nextLineKey(),\n kind: 'catalog',\n productId: request.productId,\n variantId: request.variantId ?? '',\n quantity: String(request.quantity),\n modifiers: request.modifiers ?? [],\n description: request.description ?? '',\n included: request.included === true,\n }\n }),\n customer: {\n record: section?.customer?.record ?? null,\n name: section?.customer?.name ?? '',\n company: section?.customer?.company ?? '',\n email: section?.customer?.email ?? '',\n phone: section?.customer?.phone ?? '',\n },\n shipTo: addressForm(section?.shipTo),\n billTo: addressForm(section?.billTo),\n discountKind: discount?.kind ?? 'none',\n discountValue:\n discount?.kind === 'amount' ? dollarsOf(discount.amountCents) : discount?.kind === 'percent' ? String(discount.pct) : '',\n shipping: dollarsOf(section?.shipping?.amountCents),\n notes: section?.notes ?? '',\n terms: section?.terms ?? '',\n requireProofApproval: section ? section.requireProofApproval === true : requireProofApproval,\n }\n}\n\n/** A new quote's form, filled in from where it was started (AGL-4098). */\nfunction formFromStart(start: QuoteEditorStart, requireProofApproval: boolean): QuoteForm {\n const blank = formFromQuote(null, requireProofApproval)\n const { customer, lines, notes } = start.prefill\n return {\n ...blank,\n customer: {\n record: customer.record ?? null,\n name: customer.name ?? '',\n company: customer.company ?? '',\n email: customer.email ?? '',\n phone: customer.phone ?? '',\n },\n lines: lines.map(\n (line): LineForm => ({\n key: nextLineKey(),\n kind: 'catalog',\n productId: line.productId,\n variantId: line.variantId ?? '',\n quantity: String(line.quantity || 1),\n modifiers: line.modifiers ?? [],\n description: line.description ?? '',\n included: line.included === true,\n }),\n ),\n notes: notes ?? '',\n }\n}\n\nfunction lineRequest(line: LineForm): CommerceModel.QuoteLineRequest {\n const quantity = Number(line.quantity)\n if (line.kind === 'catalog') {\n return {\n kind: 'catalog',\n productId: line.productId,\n ...(line.variantId ? { variantId: line.variantId } : {}),\n quantity,\n ...(line.modifiers.length ? { modifiers: line.modifiers } : {}),\n ...(line.included ? { included: true } : {}),\n ...(line.description.trim() ? { description: line.description.trim() } : {}),\n }\n }\n return {\n kind: 'custom',\n name: line.name.trim(),\n ...(line.description.trim() ? { description: line.description.trim() } : {}),\n ...(line.sku.trim() ? { sku: line.sku.trim() } : {}),\n unitAmountCents: line.included ? 0 : (centsOf(line.price) ?? Number.NaN),\n quantity,\n ships: line.ships,\n ...(line.included ? { included: true } : {}),\n }\n}\n\nfunction addressBody(address: AddressForm): Partial<AddressForm> | null {\n const entries = Object.entries(address).filter(([, value]) => value.trim())\n return entries.length ? Object.fromEntries(entries.map(([key, value]) => [key, value.trim()])) : null\n}\n\n/** What the server is sent: choices, never what a product costs. */\nfunction quoteBody(form: QuoteForm): Record<string, unknown> {\n const discountCents = centsOf(form.discountValue)\n return {\n lines: form.lines.map(lineRequest),\n customer: {\n ...(form.customer.record ? { record: form.customer.record } : {}),\n name: form.customer.name,\n company: form.customer.company,\n email: form.customer.email,\n phone: form.customer.phone,\n },\n shipTo: addressBody(form.shipTo),\n billTo: addressBody(form.billTo),\n discount:\n form.discountKind === 'amount'\n ? { kind: 'amount', amountCents: discountCents ?? Number.NaN }\n : form.discountKind === 'percent'\n ? { kind: 'percent', pct: Number(form.discountValue || 0) }\n : null,\n shipping: form.shipping.trim() ? { amountCents: centsOf(form.shipping) ?? Number.NaN } : null,\n notes: form.notes,\n terms: form.terms,\n requireProofApproval: form.requireProofApproval,\n }\n}\n\ninterface FoundCustomer {\n record: { kind: string; id: string }\n name: string\n company: string\n email: string | null\n phone: string | null\n}\n\n/**\n * The quote editor (AGL-4093): who it is for, its lines (products with their\n * options and add-ons, typed items, things included at no charge), discount,\n * shipping, notes and terms, with the totals worked out as it is edited. The\n * server prices and saves it; the totals here are the same function's answer\n * over the same inputs, and a connected tax service's figure arrives on save.\n */\nexport function QuoteEditorDialog(props: QuoteEditorDialogProps) {\n const { hostId, quote, products, canEdit, canSend, onClose } = props\n const start = quote ? null : (props.start ?? null)\n const firestore = useFirestore()\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const taxesHref = useStoreSettingsHref(hostId, 'taxes')\n const { data: store } = useFirestoreDoc<any>(\n () => doc(firestore, 'hosts', hostId, 'settings', 'store'),\n [firestore, hostId],\n )\n const storeDefault = CommerceModel.quoteRequiresProofApprovalByDefault(store?.quotes)\n const [form, setForm] = useState<QuoteForm>(() =>\n start ? formFromStart(start, storeDefault) : formFromQuote(quote, storeDefault),\n )\n // The version this form was opened on. A change saved elsewhere while it is\n // open arrives on `quote`; the save still names this one, so the server\n // refuses rather than overwrite that change. A proof added or a revision\n // started here (AGL-4096) moves it, and the save names the new one.\n const [baseUpdatedAtMs, setBaseUpdatedAtMs] = useState(() => quote?.quote?.updatedAtMs)\n const [busy, setBusy] = useState(false)\n const [confirmingDelete, setConfirmingDelete] = useState(false)\n /** Whether anything has been changed since the dialog opened. */\n const [edited, setEdited] = useState(false)\n /** Whether the proof-approval switch was set by hand. */\n const [approvalSet, setApprovalSet] = useState(false)\n // A new quote starts with the store's default, which may arrive after the\n // dialog opens; a switch set by hand keeps its setting.\n const requireProofApproval = quote || approvalSet ? form.requireProofApproval : storeDefault\n\n const update = useCallback((patch: Partial<QuoteForm>) => {\n setEdited(true)\n if ('requireProofApproval' in patch) setApprovalSet(true)\n setForm((prev) => ({ ...prev, ...patch }))\n }, [])\n const updateLine = useCallback((key: string, patch: Partial<LineForm>) => {\n setEdited(true)\n setForm((prev) => ({\n ...prev,\n lines: prev.lines.map((line) => (line.key === key ? ({ ...line, ...patch } as LineForm) : line)),\n }))\n }, [])\n\n /*\n * One attempt per change (AGL-1697's rule): a retried Save presents the same\n * key and is answered from the first, an edited quote is a new attempt.\n */\n const attemptKey = useRef('')\n useEffect(() => {\n attemptKey.current = ''\n }, [form])\n\n const productsById = useMemo(\n () => new Map(products.map((product) => [String(product.$id), product])),\n [products],\n )\n\n /** Each line priced as the server will price it, or why it cannot be. */\n const priced = useMemo(\n () =>\n form.lines.map((line) => {\n const request = lineRequest(line)\n if (request.kind === 'custom') {\n if (!request.name) return { error: 'Name the item.' }\n if (!Number.isInteger(request.unitAmountCents)) return { error: 'Enter a price.' }\n if (!(request.quantity >= 1)) return { error: 'Enter a quantity.' }\n return { line: CommerceModel.priceQuoteCustomLine(request) }\n }\n if (!request.productId) return { error: 'Choose a product.' }\n if (!(request.quantity >= 1)) return { error: 'Enter a quantity.' }\n const answer = CommerceModel.priceQuoteCatalogLine(productsById.get(request.productId) as never, request)\n return 'error' in answer ? { error: answer.error } : { line: answer.line }\n }),\n [form.lines, productsById],\n )\n\n const discountCents = centsOf(form.discountValue)\n const discount: CommerceModel.QuoteDiscount | null =\n form.discountKind === 'amount' && discountCents\n ? { kind: 'amount', amountCents: discountCents }\n : form.discountKind === 'percent' && Number(form.discountValue) > 0\n ? { kind: 'percent', pct: Math.min(100, Number(form.discountValue)) }\n : null\n const shippingCents = centsOf(form.shipping) ?? 0\n const taxBasis = CommerceModel.quoteTaxBasisFromSettings(store?.tax, {\n country: form.shipTo.country.trim().toUpperCase(),\n state: form.shipTo.state.trim(),\n })\n const pricedLines = priced.flatMap((entry) => ('line' in entry && entry.line ? [entry.line] : []))\n const totals = CommerceModel.computeQuoteTotals({ lines: pricedLines, discount, shippingCents, tax: taxBasis })\n const problems = priced.some((entry) => 'error' in entry)\n const savedService = quote?.quote?.tax?.kind === 'service' ? quote.quote.tax : null\n\n const save = useCallback(async () => {\n setBusy(true)\n try {\n if (!attemptKey.current) {\n attemptKey.current = globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`\n }\n const response = await authorizedFetch(user, '/api/commerce/quote', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Idempotency-Key': attemptKey.current },\n body: JSON.stringify({\n action: quote ? 'update' : 'create',\n hostId,\n ...(quote ? { quoteId: quote.$id, baseUpdatedAtMs } : {}),\n // A request's parts are read again by the server from here (AGL-4098).\n ...(!quote && start?.from ? { from: start.from } : {}),\n quote: quoteBody({ ...form, requireProofApproval }),\n }),\n })\n const payload = await response.json().catch(() => ({}))\n if (!response.ok) {\n return void enqueueSnackbar(payload?.error ?? 'The quote could not be saved', { variant: 'error', allowDuplicate: true })\n }\n enqueueSnackbar(`${CommerceModel.formatQuoteNumber({ number: payload.number ?? undefined }, payload.quoteId)} saved`, {\n variant: 'success',\n persist: false,\n })\n onClose()\n } finally {\n setBusy(false)\n }\n }, [user, quote, hostId, baseUpdatedAtMs, start, form, requireProofApproval, enqueueSnackbar, onClose])\n\n const remove = useCallback(async () => {\n if (!quote) return\n setBusy(true)\n try {\n const response = await authorizedFetch(user, '/api/commerce/quote', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ action: 'delete', hostId, quoteId: quote.$id }),\n })\n const payload = await response.json().catch(() => ({}))\n if (!response.ok) {\n return void enqueueSnackbar(payload?.error ?? 'The quote could not be deleted', { variant: 'error', allowDuplicate: true })\n }\n enqueueSnackbar(`${CommerceModel.formatQuoteNumber(quote, quote.$id)} deleted`, { variant: 'success', persist: false })\n setConfirmingDelete(false)\n onClose()\n } finally {\n setBusy(false)\n }\n }, [user, quote, hostId, enqueueSnackbar, onClose])\n\n const [downloading, setDownloading] = useState(false)\n const downloadPdf = useCallback(async () => {\n if (!quote) return\n setDownloading(true)\n try {\n const refused = await downloadCommercePdf(\n user,\n '/api/commerce/quote',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ action: 'pdf', hostId, quoteId: quote.$id }),\n },\n `quote-${quote.number ?? quote.$id.slice(-6)}.pdf`,\n )\n if (refused) enqueueSnackbar(refused, { variant: 'error', allowDuplicate: true })\n } finally {\n setDownloading(false)\n }\n }, [user, quote, hostId, enqueueSnackbar])\n\n const readOnly = !canEdit || busy\n const paid = quote ? !CommerceModel.isUnpaidQuote(quote) : false\n const title = quote ? CommerceModel.formatQuoteNumber(quote, quote.$id) : 'New quote'\n const status = quote ? CommerceModel.quoteDisplayStatus(quote) : null\n const deletable = Boolean(quote) && !paid && (quote?.quote?.stage ?? 'draft') === 'draft'\n\n return (\n <Dialog open onClose={busy ? undefined : onClose} maxWidth=\"md\" fullWidth scroll=\"paper\" aria-labelledby=\"quote-editor-title\">\n <DialogTitle id=\"quote-editor-title\">\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <span>{title}</span>\n {status ? (\n <Chip size=\"small\" variant=\"outlined\" label={status.label} color={CommerceModel.QUOTE_STATUS_COLOR[status.key]} />\n ) : null}\n </Stack>\n </DialogTitle>\n <DialogContent dividers>\n <Stack spacing={3}>\n {paid ? (\n <Alert severity=\"success\">\n {quote?.quote?.paidAtMs\n ? `Paid ${new Date(quote.quote.paidAtMs).toLocaleDateString()}. It is an order now and can no longer be changed.`\n : 'This quote has been paid, so it is an order now and can no longer be changed.'}\n </Alert>\n ) : null}\n {quote ? (\n <QuoteSendSection hostId={hostId} quoteId={quote.$id} quote={quote} canSend={canSend} edited={edited} />\n ) : null}\n {quote ? (\n <QuotePayLinkSection hostId={hostId} quoteId={quote.$id} quote={quote} canSend={canSend} edited={edited} />\n ) : null}\n {quote ? (\n <QuoteProofsSection\n hostId={hostId}\n quoteId={quote.$id}\n quote={quote}\n canEdit={canEdit}\n onEdited={(updatedAtMs) => {\n if (updatedAtMs) setBaseUpdatedAtMs(updatedAtMs)\n }}\n />\n ) : null}\n {/* Where it came from (AGL-4098): the request, its files and its conversation. */}\n {start?.request ? (\n <QuoteStartedFromRequest\n formName={start.request.formName}\n receivedAtMs={start.request.receivedAtMs}\n files={start.files ?? []}\n threaded={start.threaded === true}\n />\n ) : null}\n {quote?.quote?.request ? (\n <QuoteRequestFilesSection hostId={hostId} quoteId={quote.$id} quote={quote} />\n ) : null}\n {taxBasis.kind === 'none' && taxBasis.reason === 'undecided' ? (\n <PrerequisiteNotice href={taxesHref ?? undefined} actionLabel=\"Open Taxes\">\n {'This store has not chosen how it handles sales tax, so this quote shows no tax. Choose it in Taxes.'}\n </PrerequisiteNotice>\n ) : null}\n\n <QuoteCustomerSection\n hostId={hostId}\n form={form}\n disabled={readOnly || paid}\n onChange={(customer) => update({ customer })}\n />\n\n <Stack spacing={1.5}>\n <Typography variant=\"subtitle2\">{'Items'}</Typography>\n {form.lines.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Add products from your catalog, or type an item that is made to order.'}\n </Typography>\n ) : null}\n {form.lines.map((line, index) => (\n <QuoteLineEditor\n key={line.key}\n line={line}\n priced={priced[index]}\n products={products}\n disabled={readOnly || paid}\n onChange={(patch) => updateLine(line.key, patch)}\n onRemove={() => update({ lines: form.lines.filter((entry) => entry.key !== line.key) })}\n />\n ))}\n <Stack direction=\"row\" spacing={1} useFlexGap sx={{ flexWrap: 'wrap' }}>\n <Button\n size=\"small\"\n disabled={readOnly || paid || products.length === 0}\n onClick={() =>\n update({\n lines: [\n ...form.lines,\n { key: nextLineKey(), kind: 'catalog', productId: '', variantId: '', quantity: '1', modifiers: [], description: '', included: false },\n ],\n })\n }\n >\n {'Add product'}\n </Button>\n <Button\n size=\"small\"\n disabled={readOnly || paid}\n onClick={() =>\n update({\n lines: [\n ...form.lines,\n { key: nextLineKey(), kind: 'custom', name: '', description: '', sku: '', price: '', quantity: '1', ships: true, included: false },\n ],\n })\n }\n >\n {'Add custom item'}\n </Button>\n </Stack>\n </Stack>\n\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <TextField\n label=\"Discount\"\n select\n size=\"small\"\n value={form.discountKind}\n disabled={readOnly || paid}\n onChange={(event) => update({ discountKind: event.target.value as QuoteForm['discountKind'] })}\n sx={mediumField}\n >\n <MenuItem value=\"none\">{'None'}</MenuItem>\n <MenuItem value=\"amount\">{'Amount off'}</MenuItem>\n <MenuItem value=\"percent\">{'Percent off'}</MenuItem>\n </TextField>\n {form.discountKind !== 'none' ? (\n <TextField\n label={form.discountKind === 'amount' ? 'Amount ($)' : 'Percent (%)'}\n size=\"small\"\n value={form.discountValue}\n disabled={readOnly || paid}\n onChange={(event) => update({ discountValue: event.target.value })}\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n error={form.discountKind === 'amount' ? centsOf(form.discountValue) === null : !(Number(form.discountValue) >= 0 && Number(form.discountValue) <= 100)}\n />\n ) : null}\n <TextField\n label=\"Shipping ($)\"\n size=\"small\"\n value={form.shipping}\n disabled={readOnly || paid}\n onChange={(event) => update({ shipping: event.target.value })}\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n error={centsOf(form.shipping) === null}\n helperText=\"Leave empty when nothing ships.\"\n />\n </Stack>\n\n <QuoteAddressFields\n label=\"Ship to\"\n value={form.shipTo}\n disabled={readOnly || paid}\n helperText=\"Where the order goes. Store tax rates use its state and country.\"\n onChange={(shipTo) => update({ shipTo })}\n />\n <QuoteAddressFields\n label=\"Bill to\"\n value={form.billTo}\n disabled={readOnly || paid}\n onChange={(billTo) => update({ billTo })}\n />\n\n <Stack spacing={2}>\n <TextField\n label=\"Notes for the customer\"\n multiline\n minRows={2}\n value={form.notes}\n disabled={readOnly || paid}\n onChange={(event) => update({ notes: event.target.value })}\n />\n <TextField\n label=\"Terms\"\n multiline\n minRows={2}\n value={form.terms}\n disabled={readOnly || paid}\n onChange={(event) => update({ terms: event.target.value })}\n />\n <FormControlLabel\n control={\n <Switch\n checked={requireProofApproval}\n disabled={readOnly || paid}\n onChange={(event) => update({ requireProofApproval: event.target.checked })}\n />\n }\n label=\"Customers approve the proof before they can pay\"\n />\n </Stack>\n\n <Divider />\n <QuoteTotalsSummary\n totals={totals}\n tax={taxBasis}\n savedService={edited ? null : savedService}\n savedTotals={edited ? null : (quote?.totals ?? null)}\n />\n </Stack>\n </DialogContent>\n <DialogActions sx={{ flexWrap: 'wrap', rowGap: 1 }}>\n {deletable ? (\n <BlockedControl blocked={!canEdit} reason={REFUSAL}>\n <Button color=\"error\" disabled={busy} onClick={() => setConfirmingDelete(true)} sx={{ mr: 'auto' }}>\n {'Delete'}\n </Button>\n </BlockedControl>\n ) : null}\n {quote ? (\n <BlockedControl\n blocked={!canEdit || edited}\n reason={edited ? 'Save your changes first: the PDF shows the quote as it was last saved.' : REFUSAL}\n >\n <Button disabled={busy || downloading} onClick={() => void downloadPdf()}>\n {downloading ? 'Making PDF…' : 'Download PDF'}\n </Button>\n </BlockedControl>\n ) : null}\n <Button onClick={onClose} disabled={busy}>\n {paid || !canEdit ? 'Close' : 'Cancel'}\n </Button>\n {paid ? null : (\n <BlockedControl blocked={!canEdit} reason={REFUSAL}>\n <Button\n variant=\"contained\"\n disabled={busy || form.lines.length === 0 || problems}\n onClick={() => void save()}\n >\n {quote ? 'Save' : 'Create quote'}\n </Button>\n </BlockedControl>\n )}\n </DialogActions>\n <Dialog open={confirmingDelete} onClose={() => setConfirmingDelete(false)} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{`Delete ${title}?`}</DialogTitle>\n <DialogContent>\n <DialogContentText>{'The quote and everything on it is removed. This can’t be undone.'}</DialogContentText>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setConfirmingDelete(false)} disabled={busy}>\n {'Cancel'}\n </Button>\n <Button color=\"error\" variant=\"contained\" disabled={busy} onClick={() => void remove()}>\n {'Delete'}\n </Button>\n </DialogActions>\n </Dialog>\n </Dialog>\n )\n}\nQuoteEditorDialog.displayName = 'QuoteEditorDialog'\n\n/** A new quote's request (AGL-4098): which form sent it and when, its files by name, and its conversation. */\nfunction QuoteStartedFromRequest(props: {\n formName: string\n receivedAtMs: number | null\n files: ReadonlyArray<{ id: string; name: string; size: number }>\n threaded: boolean\n}) {\n const { formName, receivedAtMs, files, threaded } = props\n const when = receivedAtMs\n ? ` on ${new Date(receivedAtMs).toLocaleString(undefined, { dateStyle: 'medium', timeStyle: 'short' })}`\n : ''\n return (\n <Alert severity=\"info\">\n <Stack spacing={1}>\n <Typography variant=\"body2\">{`From a request sent through “${formName}”${when}.`}</Typography>\n {files.length ? (\n <Stack spacing={0.5}>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Their files, kept on the quote as the customer’s:'}\n </Typography>\n <Stack direction=\"row\" spacing={1} useFlexGap sx={{ flexWrap: 'wrap' }}>\n {files.map((file) => (\n <Chip key={file.id} size=\"small\" variant=\"outlined\" label={file.name} />\n ))}\n </Stack>\n </Stack>\n ) : null}\n <Typography variant=\"caption\" color=\"text.secondary\">\n {threaded\n ? 'When you email the quote, it replies to the confirmation they were sent, in the same conversation.'\n : 'They weren’t sent a confirmation, so the quote’s email starts the conversation.'}\n </Typography>\n </Stack>\n </Alert>\n )\n}\n\n/** Who the quote is for: a person the workspace keeps, or details typed here. */\nfunction QuoteCustomerSection(props: {\n hostId: string\n form: QuoteForm\n disabled: boolean\n onChange: (customer: QuoteForm['customer']) => void\n}) {\n const { hostId, form, disabled, onChange } = props\n const { data: user } = useUser()\n const [text, setText] = useState('')\n const [found, setFound] = useState<FoundCustomer[]>([])\n const [available, setAvailable] = useState(true)\n const ticket = useRef(0)\n const customer = form.customer\n\n useEffect(() => {\n const typed = text.trim()\n if (typed.length < 2 || !user) {\n // Only when something is listed, so an effect that re-runs settles.\n setFound((prev) => (prev.length ? [] : prev))\n return\n }\n const mine = ++ticket.current\n const timer = window.setTimeout(() => {\n void authorizedFetch(user, '/api/commerce/quote', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ action: 'search-customers', hostId, text: typed }),\n })\n .then((response) => response.json().catch(() => ({})))\n .then((payload) => {\n if (mine !== ticket.current) return\n setAvailable(payload?.available !== false)\n setFound(Array.isArray(payload?.customers) ? payload.customers : [])\n })\n .catch(() => undefined)\n }, SEARCH_DEBOUNCE_MS)\n return () => window.clearTimeout(timer)\n }, [text, user, hostId])\n\n const pick = (person: FoundCustomer) => {\n onChange({\n record: person.record,\n name: person.name,\n company: person.company,\n email: person.email ?? '',\n phone: person.phone ?? '',\n })\n setText('')\n setFound([])\n }\n\n return (\n <Stack spacing={1.5}>\n <Typography variant=\"subtitle2\">{'Customer'}</Typography>\n {customer.record ? (\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Chip\n color=\"primary\"\n variant=\"outlined\"\n label={customer.name || customer.email || 'Contact'}\n onDelete={disabled ? undefined : () => onChange({ ...customer, record: null })}\n />\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'From your contacts'}\n </Typography>\n </Stack>\n ) : available ? (\n <Box>\n <TextField\n size=\"small\"\n fullWidth\n label=\"Find a contact\"\n placeholder=\"Name, email or phone\"\n value={text}\n disabled={disabled}\n onChange={(event) => setText(event.target.value)}\n />\n {found.length ? (\n <Paper variant=\"outlined\" sx={{ mt: 0.5 }}>\n <List dense disablePadding>\n {found.map((person) => (\n <ListItemButton key={`${person.record.kind}:${person.record.id}`} onClick={() => pick(person)}>\n <ListItemText\n primary={person.name || person.email || 'Contact'}\n secondary={[person.company, person.email, person.phone].filter(Boolean).join(' · ')}\n />\n </ListItemButton>\n ))}\n </List>\n </Paper>\n ) : null}\n </Box>\n ) : null}\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <TextField size=\"small\" fullWidth label=\"Name\" value={customer.name} disabled={disabled} onChange={(event) => onChange({ ...customer, name: event.target.value })} />\n <TextField size=\"small\" fullWidth label=\"Company\" value={customer.company} disabled={disabled} onChange={(event) => onChange({ ...customer, company: event.target.value })} />\n </Stack>\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <TextField size=\"small\" fullWidth label=\"Email\" type=\"email\" value={customer.email} disabled={disabled} onChange={(event) => onChange({ ...customer, email: event.target.value })} />\n <TextField size=\"small\" fullWidth label=\"Phone\" value={customer.phone} disabled={disabled} onChange={(event) => onChange({ ...customer, phone: event.target.value })} />\n </Stack>\n </Stack>\n )\n}\n\n/** One address on the quote. */\nfunction QuoteAddressFields(props: {\n label: string\n value: AddressForm\n disabled: boolean\n helperText?: string\n onChange: (value: AddressForm) => void\n}) {\n const { label, value, disabled, helperText, onChange } = props\n const field = (key: keyof AddressForm, fieldLabel: string, extra: Record<string, unknown> = {}) => (\n <TextField\n size=\"small\"\n fullWidth\n label={fieldLabel}\n value={value[key]}\n disabled={disabled}\n onChange={(event) => onChange({ ...value, [key]: event.target.value })}\n {...extra}\n />\n )\n return (\n <Stack spacing={1.5}>\n <Typography variant=\"subtitle2\">{label}</Typography>\n {helperText ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {helperText}\n </Typography>\n ) : null}\n {field('name', 'Name')}\n {field('line1', 'Address')}\n {field('line2', 'Apartment, suite, unit')}\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n {field('city', 'City')}\n {field('state', 'State or region')}\n {field('postalCode', 'Postal code')}\n {field('country', 'Country code', { placeholder: 'US', slotProps: { htmlInput: { maxLength: 2 } } })}\n </Stack>\n </Stack>\n )\n}\n\n/** One line of the quote: a product with its options and add-ons, or a typed item. */\nfunction QuoteLineEditor(props: {\n line: LineForm\n priced: { line?: CommerceModel.PricedQuoteLine; error?: string } | undefined\n products: readonly Record<string, any>[]\n disabled: boolean\n onChange: (patch: Partial<LineForm>) => void\n onRemove: () => void\n}) {\n const { line, priced, products, disabled, onChange, onRemove } = props\n const product = line.kind === 'catalog' ? products.find((entry) => String(entry.$id) === line.productId) : undefined\n const lifted = product ? CommerceModel.liftLegacyProduct(product) : null\n const groups = lifted ? CommerceModel.productModifierGroups(lifted) : []\n const lineCents = priced?.line ? CommerceModel.quoteLineCents(priced.line) : 0\n\n return (\n <Paper variant=\"outlined\" sx={{ p: 2 }}>\n <Stack spacing={1.5}>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'flex-start' }}>\n <Stack spacing={1.5} sx={{ flex: 1, minWidth: 0 }}>\n {line.kind === 'catalog' ? (\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <TextField\n label=\"Product\"\n select\n size=\"small\"\n fullWidth\n value={line.productId}\n disabled={disabled}\n onChange={(event) => onChange({ productId: event.target.value, variantId: '', modifiers: [] })}\n >\n {products.map((entry) => (\n <MenuItem key={String(entry.$id)} value={String(entry.$id)}>\n {String(entry.name ?? entry.$id)}\n </MenuItem>\n ))}\n </TextField>\n {lifted && lifted.variants.length > 1 ? (\n <TextField\n label=\"Option\"\n select\n size=\"small\"\n fullWidth\n value={line.variantId || lifted.variants[0]?.id || ''}\n disabled={disabled}\n onChange={(event) => onChange({ variantId: event.target.value })}\n >\n {lifted.variants.map((variant) => (\n <MenuItem key={variant.id} value={variant.id}>\n {Object.values(variant.options ?? {}).join(' / ') || 'Default'}\n </MenuItem>\n ))}\n </TextField>\n ) : null}\n </Stack>\n ) : (\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <TextField\n label=\"Item\"\n size=\"small\"\n fullWidth\n value={line.name}\n disabled={disabled}\n onChange={(event) => onChange({ name: event.target.value })}\n />\n <TextField\n label=\"SKU (optional)\"\n size=\"small\"\n value={line.sku}\n disabled={disabled}\n onChange={(event) => onChange({ sku: event.target.value })}\n />\n </Stack>\n )}\n {groups.map((group) => {\n const chosen = line.kind === 'catalog' ? line.modifiers.filter((pick) => pick.groupId === group.id).map((pick) => pick.optionId) : []\n return (\n <TextField\n key={group.id}\n label={CommerceModel.modifierGroupRequired(group) ? group.name : `${group.name} (optional)`}\n select\n size=\"small\"\n fullWidth\n value={group.max > 1 ? chosen : (chosen[0] ?? '')}\n disabled={disabled}\n slotProps={{ select: { multiple: group.max > 1 } }}\n onChange={(event) => {\n const raw = event.target.value as unknown\n const picked = (Array.isArray(raw) ? raw : raw ? [raw] : []).map(String)\n if (line.kind !== 'catalog') return\n onChange({\n modifiers: [\n ...line.modifiers.filter((pick) => pick.groupId !== group.id),\n ...picked.map((optionId) => ({ groupId: group.id, optionId })),\n ],\n })\n }}\n >\n {group.max > 1 ? null : <MenuItem value=\"\">{'None'}</MenuItem>}\n {group.options.map((option) => (\n <MenuItem key={option.id} value={option.id}>\n {option.priceCents ? `${option.name} (+${money(option.priceCents)})` : option.name}\n </MenuItem>\n ))}\n </TextField>\n )\n })}\n <TextField\n label=\"Description (optional)\"\n size=\"small\"\n fullWidth\n multiline\n value={line.description}\n disabled={disabled}\n onChange={(event) => onChange({ description: event.target.value })}\n />\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'center' } }}>\n <TextField\n label=\"Quantity\"\n size=\"small\"\n value={line.quantity}\n disabled={disabled}\n onChange={(event) => onChange({ quantity: event.target.value.replace(/[^0-9]/g, '') })}\n slotProps={{ htmlInput: { inputMode: 'numeric' } }}\n sx={narrowField}\n />\n {line.kind === 'custom' ? (\n <TextField\n label=\"Unit price ($)\"\n size=\"small\"\n value={line.included ? '' : line.price}\n disabled={disabled || line.included}\n onChange={(event) => onChange({ price: event.target.value })}\n slotProps={{ htmlInput: { inputMode: 'decimal' } }}\n error={!line.included && centsOf(line.price) === null}\n sx={mediumField}\n />\n ) : null}\n {line.kind === 'custom' ? (\n <FormControlLabel\n control={<Switch checked={line.ships} disabled={disabled} onChange={(event) => onChange({ ships: event.target.checked })} />}\n label=\"Ships\"\n />\n ) : null}\n <FormControlLabel\n control={\n <Switch checked={line.included} disabled={disabled} onChange={(event) => onChange({ included: event.target.checked })} />\n }\n label=\"Included at no charge\"\n />\n </Stack>\n </Stack>\n <Stack sx={{ alignItems: 'flex-end', flexShrink: 0 }}>\n <Button size=\"small\" color=\"inherit\" disabled={disabled} onClick={onRemove}>\n {'Remove'}\n </Button>\n <Typography variant=\"body2\" sx={{ fontWeight: 'fontWeightMedium' }}>\n {line.included ? 'Included' : money(lineCents)}\n </Typography>\n {priced?.line && !line.included && priced.line.quantity > 1 ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`${money(priced.line.unitAmountCents)} each`}\n </Typography>\n ) : null}\n </Stack>\n </Stack>\n {priced?.error ? (\n <Typography variant=\"caption\" color=\"error\">\n {priced.error}\n </Typography>\n ) : null}\n </Stack>\n </Paper>\n )\n}\n\n/** The quote's totals, as the customer will read them. */\nfunction QuoteTotalsSummary(props: {\n totals: CommerceModel.QuoteTotals\n tax: CommerceModel.QuoteTaxBasis\n /** A saved quote's tax service answer, shown until the quote is edited. */\n savedService: CommerceModel.QuoteTaxBasis | null\n savedTotals: CommerceModel.OrderTotals | null\n}) {\n const { totals, tax, savedService, savedTotals } = props\n const shown = savedService && savedTotals ? { ...totals, ...savedTotals } : totals\n const taxLabel = CommerceModel.describeQuoteTax(savedService ?? tax)\n const row = (label: string, value: string, strong = false) => (\n <Stack direction=\"row\" sx={{ justifyContent: 'space-between' }}>\n <Typography variant={strong ? 'subtitle1' : 'body2'} color={strong ? 'text.primary' : 'text.secondary'}>\n {label}\n </Typography>\n <Typography variant={strong ? 'subtitle1' : 'body2'}>{value}</Typography>\n </Stack>\n )\n return (\n <Stack spacing={0.5} sx={(theme) => ({ alignSelf: { sm: 'flex-end' }, minWidth: { sm: theme.spacing(40) } })}>\n {row('Items', money(shown.itemsCents))}\n {shown.discountCents ? row('Discount', `−${money(shown.discountCents)}`) : null}\n {shown.shippingCents ? row('Shipping', money(shown.shippingCents)) : null}\n {tax.kind === 'at-payment' && !savedService ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {taxLabel}\n </Typography>\n ) : (\n row(taxLabel, money(shown.taxCents))\n )}\n {row(totals.taxAtPayment && !savedService ? 'Total before tax' : 'Total', money(shown.totalCents), true)}\n </Stack>\n )\n}\n\nexport default QuoteEditorDialog\n"],"names":["CommerceModel","posMoney","commerceSitePermissionRefusal","BlockedControl","PrerequisiteNotice","useSnackbar","authorizedFetch","useFirestore","useFirestoreDoc","useStoreSettingsHref","useUser","Alert","Box","Button","Chip","Dialog","DialogActions","DialogContent","DialogContentText","DialogTitle","Divider","FormControlLabel","List","ListItemButton","ListItemText","MenuItem","Paper","Stack","Switch","TextField","Typography","doc","useCallback","useEffect","useMemo","useRef","useState","downloadCommercePdf","QuotePayLinkSection","QuoteProofsSection","QuoteRequestFilesSection","QuoteSendSection","REFUSAL","SEARCH_DEBOUNCE_MS","money","cents","narrowField","theme","maxWidth","sm","spacing","mediumField","minWidth","centsOf","text","trimmed","trim","test","Math","round","Number","dollarsOf","toFixed","replace","addressForm","address","name","line1","line2","city","state","postalCode","country","lineSequence","nextLineKey","formFromQuote","quote","requireProofApproval","section","discount","lines","lineItems","map","line","request","quoteLineRequestFromLine","kind","key","description","sku","price","unitAmountCents","quantity","String","ships","included","productId","variantId","modifiers","customer","record","company","email","phone","shipTo","billTo","discountKind","discountValue","amountCents","pct","shipping","notes","terms","formFromStart","start","blank","prefill","lineRequest","length","NaN","addressBody","entries","Object","filter","value","fromEntries","quoteBody","form","discountCents","QuoteEditorDialog","props","hostId","products","canEdit","canSend","onClose","firestore","data","user","enqueueSnackbar","taxesHref","store","storeDefault","quoteRequiresProofApprovalByDefault","quotes","setForm","baseUpdatedAtMs","setBaseUpdatedAtMs","updatedAtMs","busy","setBusy","confirmingDelete","setConfirmingDelete","edited","setEdited","approvalSet","setApprovalSet","update","patch","prev","updateLine","attemptKey","current","productsById","Map","product","$id","priced","error","isInteger","priceQuoteCustomLine","answer","priceQuoteCatalogLine","get","min","shippingCents","taxBasis","quoteTaxBasisFromSettings","tax","toUpperCase","pricedLines","flatMap","entry","totals","computeQuoteTotals","problems","some","savedService","save","payload","globalThis","crypto","randomUUID","Date","now","random","toString","slice","response","method","headers","body","JSON","stringify","action","quoteId","from","json","catch","ok","variant","allowDuplicate","formatQuoteNumber","number","undefined","persist","remove","downloading","setDownloading","downloadPdf","refused","readOnly","paid","isUnpaidQuote","title","status","quoteDisplayStatus","deletable","Boolean","stage","open","fullWidth","scroll","aria-labelledby","id","direction","sx","alignItems","span","size","label","color","QUOTE_STATUS_COLOR","dividers","severity","paidAtMs","toLocaleDateString","onEdited","QuoteStartedFromRequest","formName","receivedAtMs","files","threaded","reason","href","actionLabel","QuoteCustomerSection","disabled","onChange","index","QuoteLineEditor","onRemove","useFlexGap","flexWrap","onClick","xs","select","event","target","slotProps","htmlInput","inputMode","helperText","QuoteAddressFields","multiline","minRows","control","checked","QuoteTotalsSummary","savedTotals","rowGap","blocked","mr","displayName","when","toLocaleString","dateStyle","timeStyle","file","setText","found","setFound","available","setAvailable","ticket","typed","mine","timer","window","setTimeout","then","Array","isArray","customers","clearTimeout","pick","person","onDelete","placeholder","mt","dense","disablePadding","primary","secondary","join","type","field","fieldLabel","extra","maxLength","lifted","find","liftLegacyProduct","groups","productModifierGroups","lineCents","quoteLineCents","p","flex","variants","values","options","group","chosen","groupId","optionId","modifierGroupRequired","max","multiple","raw","picked","option","priceCents","flexShrink","fontWeight","shown","taxLabel","describeQuoteTax","row","strong","justifyContent","alignSelf","itemsCents","taxCents","taxAtPayment","totalCents"],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import * as CommerceModel from '../../model';
18
+ export interface QuoteProofsSectionProps {
19
+ hostId: string;
20
+ quoteId: string;
21
+ quote: CommerceModel.HostOrder;
22
+ /** Holds "Create and edit quotes" (`commerce.quotes`). */
23
+ canEdit: boolean;
24
+ /** A change here moved the quote's edit stamp; the editor saves against the new one. */
25
+ onEdited: (updatedAtMs: number) => void;
26
+ }
27
+ /**
28
+ * A quote's proofs and revisions (AGL-4096), in its editor: the current
29
+ * revision's proofs (a picture for an image, a chip for a PDF or a design
30
+ * file), Add proof, what the customer last said with any files they sent,
31
+ * "Start revision N+1", and every earlier revision as it was kept.
32
+ */
33
+ export declare function QuoteProofsSection(props: QuoteProofsSectionProps): import("react").JSX.Element;
34
+ export declare namespace QuoteProofsSection {
35
+ var displayName: string;
36
+ }
37
+ export default QuoteProofsSection;
38
+ /**
39
+ * The files a quote's request came with (AGL-4098), as the customer's files:
40
+ * a picture for an image, a chip naming anything else, each downloaded
41
+ * through the quote's own route. They stay where the request keeps them, so a
42
+ * request deleted from the Inbox takes them with it.
43
+ */
44
+ export declare function QuoteRequestFilesSection(props: {
45
+ hostId: string;
46
+ quoteId: string;
47
+ quote: CommerceModel.HostOrder;
48
+ }): import("react").JSX.Element;