@develemit/commerce-admin 0.4.0 → 0.7.0
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/CHANGELOG.md +87 -0
- package/README.md +85 -9
- package/dist/client/admin-client.d.ts +3 -2
- package/dist/client/errors.d.ts +8 -0
- package/dist/client/index.js +1 -1
- package/dist/client/transport.d.ts +3 -1
- package/dist/client-DCL5DSHP.js +184 -0
- package/dist/client-DCL5DSHP.js.map +1 -0
- package/dist/components/admin-layout/admin-layout.d.ts +5 -6
- package/dist/components/admin-layout/nav-icons.d.ts +9 -0
- package/dist/components/admin-layout/nav-items.d.ts +36 -0
- package/dist/components/admin-layout/use-more-sheet.d.ts +5 -0
- package/dist/components/empty-state/empty-state.d.ts +10 -0
- package/dist/components/notice/notice.d.ts +5 -1
- package/dist/components/page-header/admin-page-header.d.ts +8 -0
- package/dist/components/setup-checklist/setup-checklist.d.ts +15 -0
- package/dist/components/switch/switch.d.ts +7 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +3325 -1211
- package/dist/index.js.map +1 -1
- package/dist/lib/admin-labels.d.ts +2 -0
- package/dist/lib/discount-labels.d.ts +1 -0
- package/dist/lib/fill-alts.d.ts +3 -0
- package/dist/lib/order-labels.d.ts +1 -0
- package/dist/lib/product-draft.d.ts +11 -0
- package/dist/lib/product-flow-labels.d.ts +54 -0
- package/dist/lib/product-labels.d.ts +53 -0
- package/dist/lib/product-missing.d.ts +4 -0
- package/dist/lib/product-sheet-actions.d.ts +13 -0
- package/dist/lib/shipping-labels.d.ts +2 -0
- package/dist/lib/stock-labels.d.ts +41 -0
- package/dist/lib/use-batch-upload.d.ts +38 -0
- package/dist/lib/use-focus-trap.d.ts +2 -0
- package/dist/lib/use-image-upload.d.ts +3 -2
- package/dist/lib/use-order-pages.d.ts +2 -0
- package/dist/lib/use-paged-list.d.ts +15 -0
- package/dist/lib/use-product-autosave.d.ts +95 -0
- package/dist/lib/use-product-pages.d.ts +2 -2
- package/dist/styles.css +1300 -55
- package/dist/views/products/add-several/admin-add-several.d.ts +5 -0
- package/dist/views/products/add-several/photo-picker.d.ts +7 -0
- package/dist/views/products/admin-product-editor.d.ts +3 -1
- package/dist/views/products/admin-product-list.d.ts +13 -1
- package/dist/views/products/finish-drafts/admin-finish-drafts.d.ts +7 -0
- package/dist/views/products/finish-drafts/piece-card.d.ts +10 -0
- package/dist/views/products/finish-drafts/piece-fields.d.ts +7 -0
- package/dist/views/products/finish-drafts/piece-summary.d.ts +10 -0
- package/dist/views/products/finish-drafts/use-publish-pieces.d.ts +52 -0
- package/dist/views/products/product-card.d.ts +6 -0
- package/dist/views/products/product-flow/admin-product-flow.d.ts +15 -0
- package/dist/views/products/product-flow/basics-section.d.ts +6 -0
- package/dist/views/products/product-flow/flow-actions.d.ts +10 -0
- package/dist/views/products/product-flow/flow-frame.d.ts +28 -0
- package/dist/views/products/product-flow/flow-images.d.ts +7 -0
- package/dist/views/products/product-flow/flow-section-props.d.ts +5 -0
- package/dist/views/products/product-flow/flow-success.d.ts +8 -0
- package/dist/views/products/product-flow/flow-test-helpers.d.ts +12 -0
- package/dist/views/products/product-flow/photos-section.d.ts +9 -0
- package/dist/views/products/product-flow/preview-section.d.ts +10 -0
- package/dist/views/products/product-flow/story-section.d.ts +8 -0
- package/dist/views/products/product-flow/use-product-flow.d.ts +138 -0
- package/dist/views/products/product-sheet/admin-product-sheet.d.ts +8 -0
- package/dist/views/products/product-sheet/sheet-carousel.d.ts +4 -0
- package/dist/views/products/product-sheet/sheet-edit-link.d.ts +14 -0
- package/dist/views/products/product-sheet/use-product-change.d.ts +16 -0
- package/dist/views/products/product-toolbar.d.ts +10 -0
- package/dist/views/products/product-welcome.d.ts +8 -0
- package/dist/views/shipping/admin-shipping-rates.d.ts +6 -1
- package/package.json +11 -3
- package/dist/client--_j5r8ag.js +0 -168
- package/dist/client--_j5r8ag.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_Fragment","_Fragment","TABS","_Fragment","_Fragment","_Fragment","_Fragment","AdminUnauthorizedError","ImageTooLargeError","InvalidOrderStateError","RefundExceedsBalanceError","InsufficientStockError","RefundOutcomeUnknownError","DiscountCodeTakenError","RefundGatewayError","AdminInvalidInputError","DiscountInUseError","InvalidImageError","defaultOrderLabels","defaultShippingLabels","defaultDiscountLabels","defaultProductLabels","defaultAdminLabels","mergeOrderLabels","base","overrides","mergeProductLabels","mergeDiscountLabels","mergeAdminLabels","labels","defaults","priority","id","AdminContext","createContext","AdminProvider","value","hrefs","useAdmin","useContext","useAdminClient","client","useAdminQuery","fnRef","useRef","fn","reloadCount","setReloadCount","useState","settled","setSettled","request","key","controller","prev","reload","useCallback","n","current","useAdminMutation","pending","setPending","error","setError","args","err","AdminLayout","kit","items","extraNav","i","header","renderLink","item","footer","AdminTable","rows","caption","columns","c","row","rowKey","StatusBadge","status","Money","text","locale","cents","FOCUSABLE","ConfirmDialog","panelRef","useEffect","open","trigger","event","onCancel","focusable","first","last","title","children","destructive","onConfirm","confirmLabel","Notice","toast","onDismiss","timer","duration","role","variant","className","KEYED","AdminNotFoundError","errorKey","type","ErrorMessage","isSold","product","displayStatus","serverStatus","filter","serverStock","useDebounced","debounced","setDebounced","delayMs","useProductPages","query","appended","setAppended","more","page","extra","nextCursor","FILTERS","AdminProductList","copy","setFilter","search","setSearch","q","stock","pages","updated","setUpdated","apply","kind","confirm","result","p","emptyText","MONEY","parseMoneyInput","raw","match","whole","fraction","formatMoneyInput","FIELD_ORDER","emptyForm","formFromProduct","fieldFor","head","path","mapped","mapServerIssues","errors","issue","issues","field","message","firstInvalidField","blankToNull","trimmed","validateForm","priceCents","form","quantity","parsed","adminProductInputSchema","currency","PATCH_KEYS","buildPatch","patch","input","original","ACCEPTED_TYPES","fill","template","values","imageFileProblem","file","useImageUpload","entries","setEntries","nextId","chain","onUploadedRef","onUploaded","entry","change","drop","send","productId","alt","added","files","reason","ImageAltEditor","draft","setDraft","saving","setSaving","failure","setFailure","close","name","onSave","imageId","ImageTile","image","index","move","direction","onMove","busy","renderImage","total","onSaveAlt","onRemove","UploadPicker","pick","onFiles","byPosition","images","a","b","AdminProductImages","initial","setImages","busyId","setBusyId","reordering","setReordering","setAlt","reorderFailed","setReorderFailed","removing","setRemoving","focusTarget","listRef","target","find","other","to","previous","next","confirmRemove","saveAlt","nextAlt","upload","Fragment","dismiss","FieldShell","described","help","label","CATEGORY_LIST_ID","DetailsFields","suggestCategories","categories","props","onChange","category","STATUSES","SalesFields","statusLabels","AdminProductEditor","ExistingProductEditor","ProductFormView","setBase","setForm","fieldErrors","setFieldErrors","saved","setSaved","showErrors","found","formEl","save","onSubmit","onSaved","imagesSlot","group","useOrderPages","TABS$1","tabQuery","tab","AdminOrderList","setTab","date","o","pendingRefundCents","order","r","sum","remainingRefundCents","hasPendingRefund","canRestock","amountCents","canShip","canRefund","RefundDialog","keyRef","remaining","amount","setAmount","setReason","restock","setRestock","invalid","setInvalid","refund","amountValid","restockOffered","retryable","onDone","onClose","ResolveButton","resolve","submit","stockError","names","isHttpUrl","protocol","ShipForm","carrier","setCarrier","trackingNumber","setTrackingNumber","trackingUrl","setTrackingUrl","urlError","setUrlError","ship","reship","url","OrderActions","refunding","setRefunding","setMessage","done","OrderFulfillment","f","OrderItems","OrderRefunds","addressLines","region","l","AdminOrderDetail","orderId","lines","actions","counter","newKey","toDrafts","rates","rate","blankDraft","snapshot","drafts","_key","rest","parseDays","checkDrafts","rowErrors","seen","min","max","shippingRatesInputSchema","noActive","SERVER_FIELDS","serverRowErrors","at","segment","ShippingRateRow","fieldId","disabled","AdminShippingRates","setDrafts","baseline","setBaseline","loaded","setLoaded","setRowErrors","blocked","setBlocked","removedAny","setRemovedAny","lastDirty","dirty","onDirtyChange","edit","d","_cleared","add","check","mixedCurrency","serverErrors","displayDiscountStatus","discount","now","fillTemplate","useDiscountPages","DiscountValue","TABS","AdminDiscountList","used","emptyDiscountForm","pad","isoToLocalInput","iso","localInputToIso","formFromDiscount","isDiscountUsed","positiveInt","validateDiscountForm","v","code","percentOff","amountOffCents","minText","minSubtotalCents","limitText","maxRedemptions","usedCount","startsAt","endsAt","VALUE_KEYS","LIMIT_KEYS","buildDiscountPatch","differs","locked","mapDiscountIssues","Shell","TYPES","DiscountFields","lockedHelp","AdminDiscountEditor","discountId","ExistingDiscountEditor","DiscountFormView","confirming","setConfirming","toggleActive","adopt","setActive","active"],"sources":["../src/lib/order-action-labels.ts","../src/lib/order-labels.ts","../src/lib/shipping-labels.ts","../src/lib/discount-labels.ts","../src/lib/image-labels.ts","../src/lib/product-labels.ts","../src/lib/admin-labels.ts","../src/lib/merge-labels.ts","../src/lib/provider.tsx","../src/lib/use-admin-query.ts","../src/lib/use-admin-mutation.ts","../src/components/admin-layout/admin-layout.tsx","../src/components/admin-table/admin-table.tsx","../src/components/status-badge/status-badge.tsx","../src/components/money/money.tsx","../src/components/confirm-dialog/confirm-dialog.tsx","../src/components/notice/notice.tsx","../src/components/error-message/error-message.tsx","../src/lib/product-filter.ts","../src/lib/use-debounced.ts","../src/lib/use-product-pages.ts","../src/views/products/admin-product-list.tsx","../src/lib/money-input.ts","../src/lib/product-form.ts","../src/lib/image-rules.ts","../src/lib/use-image-upload.ts","../src/views/products/image-alt-editor.tsx","../src/views/products/image-tile.tsx","../src/views/products/upload-picker.tsx","../src/views/products/admin-product-images.tsx","../src/views/products/product-fields.tsx","../src/views/products/admin-product-editor.tsx","../src/lib/use-order-pages.ts","../src/views/orders/admin-order-list.tsx","../src/lib/refund-rules.ts","../src/views/orders/refund-dialog.tsx","../src/views/orders/resolve-button.tsx","../src/views/orders/ship-form.tsx","../src/views/orders/order-actions.tsx","../src/views/orders/order-fulfillment.tsx","../src/views/orders/order-items.tsx","../src/views/orders/order-refunds.tsx","../src/views/orders/admin-order-detail.tsx","../src/lib/shipping-rates.ts","../src/views/shipping/shipping-rate-row.tsx","../src/views/shipping/admin-shipping-rates.tsx","../src/lib/discount-status.ts","../src/lib/use-discount-pages.ts","../src/views/discounts/discount-value.tsx","../src/views/discounts/admin-discount-list.tsx","../src/lib/discount-form.ts","../src/views/discounts/discount-fields.tsx","../src/views/discounts/admin-discount-editor.tsx"],"sourcesContent":["export interface OrderActionLabels {\n ship: string;\n reship: string;\n shipHeading: string;\n carrier: string;\n trackingNumber: string;\n trackingUrl: string;\n trackingUrlInvalid: string;\n shipped: string;\n refund: string;\n refundTitle: string;\n refundAmount: string;\n refundAmountInvalid: string;\n refundReason: string;\n refundSubmit: string;\n refundRetry: string;\n restock: string;\n restockWarning: string;\n refundPending: string;\n refundUnknown: string;\n refundGateway: string;\n refundDone: string;\n resolve: string;\n resolveHelp: string;\n resolved: string;\n restockThenResolve: string;\n}\n\nexport const defaultOrderActionLabels: OrderActionLabels = {\n ship: 'Mark as shipped',\n reship: 'Update tracking',\n shipHeading: 'Shipping',\n carrier: 'Carrier',\n trackingNumber: 'Tracking number',\n trackingUrl: 'Tracking URL',\n trackingUrlInvalid: 'Enter a full link starting with http:// or https://.',\n shipped: 'Shipping details saved.',\n refund: 'Refund…',\n refundTitle: 'Refund order',\n refundAmount: 'Amount',\n refundAmountInvalid:\n 'Enter an amount above zero and no more than the balance.',\n refundReason: 'Reason',\n refundSubmit: 'Refund',\n refundRetry: 'Retry refund',\n restock: 'Restock items',\n restockWarning: 'Only restock if the item came back.',\n refundPending:\n 'A refund is already pending on this order. Wait for it to finish or refresh before refunding again.',\n refundUnknown:\n 'We could not confirm whether this refund went through; it may have succeeded. Retrying is safe, it will not refund twice.',\n refundGateway:\n 'The payment provider rejected the refund. Retrying is safe, it will not refund twice.',\n refundDone: 'Refund sent.',\n resolve: 'Resolve order',\n resolveHelp:\n 'This order was paid but its stock ran out. Restock the items and resolve it, or refund it.',\n resolved: 'Order resolved.',\n restockThenResolve: 'Restock, then resolve',\n};\n","import type { OrderActionLabels } from './order-action-labels';\nimport { defaultOrderActionLabels } from './order-action-labels';\n\nexport type OrderTab =\n 'paid' | 'shipped' | 'needs_attention' | 'pending_refund' | 'all';\n\nexport interface OrderLabels {\n title: string;\n searchLabel: string;\n searchPlaceholder: string;\n tabs: Record<OrderTab, string>;\n empty: Record<OrderTab, string>;\n noMatches: string;\n loadMore: string;\n columns: {\n order: string;\n status: string;\n email: string;\n items: string;\n total: string;\n date: string;\n };\n noEmail: string;\n detailTitle: string;\n back: string;\n placed: string;\n buyer: string;\n itemsHeading: string;\n itemColumns: { name: string; price: string; quantity: string; line: string };\n subtotal: string;\n shipping: string;\n total: string;\n shippingAddress: string;\n noAddress: string;\n fulfillment: string;\n notShipped: string;\n shippedOn: string;\n carrier: string;\n tracking: string;\n trackShipment: string;\n refunds: string;\n noRefunds: string;\n refundColumns: {\n amount: string;\n reason: string;\n source: string;\n status: string;\n restocked: string;\n date: string;\n };\n refundSources: { admin: string; gateway: string };\n refundStatuses: { pending: string; succeeded: string };\n yes: string;\n no: string;\n refunded: string;\n remaining: string;\n actions: OrderActionLabels;\n}\n\nexport const defaultOrderLabels: OrderLabels = {\n title: 'Orders',\n searchLabel: 'Search orders',\n searchPlaceholder: 'Search by email or order id',\n tabs: {\n paid: 'To ship',\n shipped: 'Shipped',\n needs_attention: 'Needs attention',\n pending_refund: 'Pending refund',\n all: 'All',\n },\n empty: {\n paid: 'Nothing waiting to ship.',\n shipped: 'No shipped orders yet.',\n needs_attention: 'No orders need attention.',\n pending_refund: 'No refunds are pending.',\n all: 'No orders yet.',\n },\n noMatches: 'No orders match that search.',\n loadMore: 'Load more',\n columns: {\n order: 'Order',\n status: 'Status',\n email: 'Buyer',\n items: 'Items',\n total: 'Total',\n date: 'Placed',\n },\n noEmail: 'No email',\n detailTitle: 'Order',\n back: 'Back to orders',\n placed: 'Placed',\n buyer: 'Buyer',\n itemsHeading: 'Items',\n itemColumns: {\n name: 'Item',\n price: 'Price',\n quantity: 'Qty',\n line: 'Subtotal',\n },\n subtotal: 'Subtotal',\n shipping: 'Shipping',\n total: 'Total',\n shippingAddress: 'Shipping address',\n noAddress: 'No shipping address.',\n fulfillment: 'Fulfillment',\n notShipped: 'Not shipped',\n shippedOn: 'Shipped',\n carrier: 'Carrier',\n tracking: 'Tracking',\n trackShipment: 'Track shipment',\n refunds: 'Refunds',\n noRefunds: 'No refunds.',\n refundColumns: {\n amount: 'Amount',\n reason: 'Reason',\n source: 'Source',\n status: 'Status',\n restocked: 'Restocked',\n date: 'Date',\n },\n refundSources: { admin: 'Admin', gateway: 'Payment provider' },\n refundStatuses: { pending: 'Pending', succeeded: 'Refunded' },\n yes: 'Yes',\n no: 'No',\n refunded: 'Refunded',\n remaining: 'Remaining balance',\n actions: defaultOrderActionLabels,\n};\n","export interface ShippingLabels {\n title: string;\n loading: string;\n empty: string;\n add: string;\n save: string;\n saved: string;\n label: string;\n amount: string;\n currency: string;\n mixedCurrency: string;\n minDays: string;\n maxDays: string;\n active: string;\n rowName: string;\n moveEarlier: string;\n moveLater: string;\n remove: string;\n removeTitle: string;\n removeBody: string;\n newRateLabel: string;\n removalWarning: string;\n unsaved: string;\n noActive: string;\n labelRequired: string;\n labelDuplicate: string;\n amountInvalid: string;\n currencyInvalid: string;\n daysInvalid: string;\n daysOrder: string;\n rowInvalid: string;\n}\n\nexport const defaultShippingLabels: ShippingLabels = {\n title: 'Shipping rates',\n loading: 'Loading shipping rates…',\n empty: 'No shipping rates yet. Add one so customers can check out.',\n add: 'Add a rate',\n save: 'Save changes',\n saved: 'Shipping rates saved.',\n label: 'Name',\n amount: 'Price',\n currency: 'Currency',\n mixedCurrency:\n 'These rates use more than one currency. Checkout needs them to match your shop currency ({currency}).',\n minDays: 'Fastest (days)',\n maxDays: 'Slowest (days)',\n active: 'Offered at checkout',\n rowName: 'Rate {n}',\n moveEarlier: 'Move earlier',\n moveLater: 'Move later',\n remove: 'Remove',\n removeTitle: 'Remove this rate?',\n removeBody:\n 'It disappears from checkout once you save. Past orders are not affected.',\n newRateLabel: 'New rate',\n removalWarning:\n 'Saving replaces all rates. Rates you removed will no longer appear at checkout.',\n unsaved: 'You have unsaved changes.',\n noActive:\n 'Keep at least one rate offered at checkout, or customers cannot pay.',\n labelRequired: 'Give this rate a name.',\n labelDuplicate: 'Another rate already has this name.',\n amountInvalid: 'Enter a price like 5.00.',\n currencyInvalid: 'Use a 3-letter currency code like USD.',\n daysInvalid: 'Use a whole number of days, or leave blank.',\n daysOrder: 'Fastest cannot be more than slowest.',\n rowInvalid: 'These details are not valid.',\n};\n","export type DiscountTab = 'active' | 'scheduled' | 'expired' | 'inactive';\n\nexport interface DiscountLabels {\n title: string;\n newDiscount: string;\n searchLabel: string;\n searchPlaceholder: string;\n tabs: Record<DiscountTab, string>;\n empty: Record<DiscountTab, string>;\n noMatches: string;\n loadMore: string;\n columns: {\n code: string;\n value: string;\n status: string;\n usage: string;\n };\n usage: string;\n usageUnlimited: string;\n createTitle: string;\n editTitle: string;\n saved: string;\n fields: {\n code: string;\n type: string;\n percentOff: string;\n amountOff: string;\n minSubtotal: string;\n startsAt: string;\n endsAt: string;\n maxRedemptions: string;\n };\n types: { percent: string; fixed: string };\n optionalHelp: string;\n lockedHelp: string;\n deactivate: string;\n deactivateTitle: string;\n deactivateBody: string;\n reactivate: string;\n validation: {\n code: string;\n percentOff: string;\n amountOff: string;\n minSubtotal: string;\n maxRedemptions: string;\n maxRedemptionsBelowUsage: string;\n endsBeforeStart: string;\n date: string;\n codeTaken: string;\n invalid: string;\n };\n orderRow: string;\n}\n\nexport const defaultDiscountLabels: DiscountLabels = {\n title: 'Discounts',\n newDiscount: 'New discount',\n searchLabel: 'Search discounts',\n searchPlaceholder: 'Search by code',\n tabs: {\n active: 'Active',\n scheduled: 'Scheduled',\n expired: 'Expired',\n inactive: 'Inactive',\n },\n empty: {\n active: 'No active discounts.',\n scheduled: 'No scheduled discounts.',\n expired: 'No expired discounts.',\n inactive: 'No inactive discounts.',\n },\n noMatches: 'No discounts match your search.',\n loadMore: 'Load more',\n columns: {\n code: 'Code',\n value: 'Discount',\n status: 'Status',\n usage: 'Used',\n },\n usage: '{used} / {max} used',\n usageUnlimited: '{used} used',\n createTitle: 'New discount',\n editTitle: 'Edit discount',\n saved: 'Discount saved.',\n fields: {\n code: 'Code',\n type: 'Type',\n percentOff: 'Percent off',\n amountOff: 'Amount off',\n minSubtotal: 'Minimum subtotal',\n startsAt: 'Starts',\n endsAt: 'Ends',\n maxRedemptions: 'Usage limit',\n },\n types: { percent: 'Percent', fixed: 'Fixed amount' },\n optionalHelp: 'Optional',\n lockedHelp: 'Used on {count} orders; create a new code instead.',\n deactivate: 'Deactivate',\n deactivateTitle: 'Deactivate this discount?',\n deactivateBody:\n 'Buyers can no longer use this code. Past orders keep it. You can reactivate it later.',\n reactivate: 'Reactivate',\n validation: {\n code: 'Use letters, numbers, dashes or underscores (up to 40).',\n percentOff: 'Enter a whole number from 1 to 100.',\n amountOff: 'Enter an amount greater than zero, like 5.00.',\n minSubtotal: 'Enter an amount greater than zero, like 25.00.',\n maxRedemptions: 'Enter a whole number greater than zero.',\n maxRedemptionsBelowUsage: 'The limit cannot be lower than the times used.',\n endsBeforeStart: 'The end must be after the start.',\n date: 'Enter a valid date and time.',\n codeTaken: 'That code is already in use.',\n invalid: 'This value is not valid.',\n },\n orderRow: 'Discount',\n};\n","export interface ImageLabels {\n title: string;\n empty: string;\n add: string;\n takePhoto: string;\n dropHint: string;\n altLabel: string;\n altHelp: string;\n altWarning: string;\n cover: string;\n photoName: string;\n editAlt: string;\n saveAlt: string;\n cancelAlt: string;\n moveEarlier: string;\n moveLater: string;\n remove: string;\n removeTitle: string;\n removeBody: string;\n uploading: string;\n working: string;\n tooLarge: string;\n wrongType: string;\n reorderFailed: string;\n dismiss: string;\n}\n\nexport const defaultImageLabels: ImageLabels = {\n title: 'Photos',\n empty: 'Add a photo so this can go live.',\n add: 'Add photos',\n takePhoto: 'Take photo',\n dropHint: 'Drop photos here, or use the buttons.',\n altLabel: 'Photo description',\n altHelp: 'Describe what the photo shows, for people who cannot see it.',\n altWarning: 'No description yet. Add one so everyone can enjoy this photo.',\n cover: 'Cover',\n photoName: 'Photo {n}',\n editAlt: 'Edit description',\n saveAlt: 'Save',\n cancelAlt: 'Cancel',\n moveEarlier: 'Move earlier',\n moveLater: 'Move later',\n remove: 'Remove',\n removeTitle: 'Remove this photo?',\n removeBody: 'It will be deleted from this product.',\n uploading: 'Uploading…',\n working: 'Working…',\n tooLarge: '{name} is larger than 8 MB.',\n wrongType: '{name} must be a JPEG, PNG, WebP or HEIC image.',\n reorderFailed: 'The photos could not be reordered. The old order is back.',\n dismiss: 'Dismiss',\n};\n","import { defaultImageLabels, type ImageLabels } from './image-labels';\n\nexport type ProductFilter = 'all' | 'live' | 'sold' | 'draft' | 'archived';\n\nexport interface ProductLabels {\n title: string;\n newProduct: string;\n searchLabel: string;\n searchPlaceholder: string;\n filters: Record<ProductFilter, string>;\n empty: Record<ProductFilter, string>;\n noMatches: string;\n loadMore: string;\n columns: {\n image: string;\n name: string;\n price: string;\n status: string;\n quantity: string;\n actions: string;\n };\n noImage: string;\n viewInShop: string;\n markSold: string;\n archive: string;\n markSoldTitle: string;\n markSoldBody: string;\n archiveTitle: string;\n archiveBody: string;\n updated: string;\n createTitle: string;\n editTitle: string;\n saved: string;\n fields: {\n name: string;\n category: string;\n description: string;\n materials: string;\n dimensions: string;\n price: string;\n quantity: string;\n status: string;\n featured: string;\n };\n images: ImageLabels;\n statusHelp: string;\n priceHelp: string;\n validation: {\n required: string;\n price: string;\n quantity: string;\n };\n}\n\nexport const defaultProductLabels: ProductLabels = {\n title: 'Products',\n newProduct: 'New product',\n searchLabel: 'Search products',\n searchPlaceholder: 'Search by name',\n filters: {\n all: 'All',\n live: 'Live',\n sold: 'Sold',\n draft: 'Drafts',\n archived: 'Archived',\n },\n empty: {\n all: 'No products yet. Add your first piece.',\n live: 'Nothing is live in the shop right now.',\n sold: 'Nothing has sold out yet.',\n draft: 'No drafts.',\n archived: 'No archived products.',\n },\n noMatches: 'No products match that search.',\n loadMore: 'Load more',\n columns: {\n image: 'Image',\n name: 'Name',\n price: 'Price',\n status: 'Status',\n quantity: 'In stock',\n actions: 'Actions',\n },\n noImage: 'No image',\n viewInShop: 'View in shop',\n markSold: 'Mark sold',\n archive: 'Archive',\n markSoldTitle: 'Mark as sold?',\n markSoldBody: 'This sets the stock to zero. Customers will see it as sold.',\n archiveTitle: 'Archive this product?',\n archiveBody: 'It will disappear from the shop. You can restore it later.',\n updated: 'Product updated.',\n createTitle: 'New product',\n editTitle: 'Edit product',\n saved: 'Saved.',\n fields: {\n name: 'Name',\n category: 'Category',\n description: 'Description',\n materials: 'Materials',\n dimensions: 'Dimensions',\n price: 'Price',\n quantity: 'Quantity',\n status: 'Status',\n featured: 'Feature this product on the home page',\n },\n images: defaultImageLabels,\n statusHelp:\n 'Draft is hidden. Active is live in the shop. Archived is hidden and kept. Mark a piece sold from the product list.',\n priceHelp: 'In dollars, for example 48.00.',\n validation: {\n required: 'This field is required.',\n price: 'Enter a price like 48 or 48.50.',\n quantity: 'Enter a whole number, zero or more.',\n },\n};\n","import { defaultOrderLabels, type OrderLabels } from './order-labels';\nimport { defaultShippingLabels, type ShippingLabels } from './shipping-labels';\nimport { defaultDiscountLabels, type DiscountLabels } from './discount-labels';\nimport { defaultProductLabels, type ProductLabels } from './product-labels';\n\nexport type AdminErrorKey =\n | 'unauthorized'\n | 'notFound'\n | 'invalidInput'\n | 'invalidOrderState'\n | 'insufficientStock'\n | 'refundExceedsBalance'\n | 'refundGateway'\n | 'refundOutcomeUnknown'\n | 'discountCodeTaken'\n | 'discountInUse'\n | 'imageInvalid'\n | 'imageTooLarge'\n | 'generic';\n\nexport interface AdminLabels {\n loading: string;\n empty: string;\n save: string;\n cancel: string;\n confirm: string;\n dismiss: string;\n navLabel: string;\n nav: { products: string; orders: string; shippingRates: string };\n statuses: Record<string, string>;\n errors: Record<AdminErrorKey, string>;\n products: ProductLabels;\n orders: OrderLabels;\n shipping: ShippingLabels;\n discounts: DiscountLabels;\n}\n\nexport const defaultAdminLabels: AdminLabels = {\n loading: 'Loading…',\n empty: 'Nothing here yet.',\n save: 'Save',\n cancel: 'Cancel',\n confirm: 'Confirm',\n dismiss: 'Dismiss',\n navLabel: 'Admin',\n nav: {\n products: 'Products',\n orders: 'Orders',\n shippingRates: 'Shipping rates',\n },\n statuses: {\n draft: 'Draft',\n active: 'Active',\n archived: 'Archived',\n pending: 'Pending',\n paid: 'Paid',\n shipped: 'Shipped',\n cancelled: 'Cancelled',\n expired: 'Expired',\n needs_attention: 'Needs attention',\n refunded: 'Refunded',\n sold: 'Sold',\n scheduled: 'Scheduled',\n inactive: 'Inactive',\n },\n errors: {\n unauthorized: 'You are not signed in or not allowed to do this.',\n notFound: 'We could not find that.',\n invalidInput:\n 'Some of the details are not valid. Check them and try again.',\n invalidOrderState:\n 'This order cannot be changed that way in its current state.',\n insufficientStock: 'Not enough stock is available.',\n refundExceedsBalance: 'The refund is more than the remaining balance.',\n refundGateway:\n 'The payment provider rejected the refund. Try again shortly.',\n refundOutcomeUnknown:\n 'Refund outcome unknown — retry with the same request.',\n discountCodeTaken: 'That discount code is already in use.',\n discountInUse:\n 'This code has been used, so that detail can no longer change. Create a new code instead.',\n imageInvalid: 'That image could not be used. Try a different file.',\n imageTooLarge: 'That image is too large. Choose a smaller one.',\n generic: 'Something went wrong. Try again.',\n },\n products: defaultProductLabels,\n orders: defaultOrderLabels,\n shipping: defaultShippingLabels,\n discounts: defaultDiscountLabels,\n};\n","import { defaultAdminLabels, type AdminLabels } from './admin-labels';\nimport { defaultOrderLabels, type OrderLabels } from './order-labels';\nimport { defaultShippingLabels, type ShippingLabels } from './shipping-labels';\nimport { defaultDiscountLabels, type DiscountLabels } from './discount-labels';\nimport { defaultProductLabels, type ProductLabels } from './product-labels';\n\ntype DeepPartial<T> = {\n [K in keyof T]?: T[K] extends object ? Partial<T[K]> : T[K];\n};\n\nexport type AdminLabelOverrides = Partial<\n Omit<\n AdminLabels,\n | 'nav'\n | 'statuses'\n | 'errors'\n | 'products'\n | 'orders'\n | 'shipping'\n | 'discounts'\n > & {\n nav: Partial<AdminLabels['nav']>;\n statuses: Partial<AdminLabels['statuses']>;\n errors: Partial<AdminLabels['errors']>;\n products: DeepPartial<ProductLabels>;\n orders: DeepPartial<OrderLabels>;\n shipping: Partial<ShippingLabels>;\n discounts: DeepPartial<DiscountLabels>;\n }\n>;\n\nfunction mergeOrderLabels(\n overrides: DeepPartial<OrderLabels> | undefined,\n): OrderLabels {\n const base = defaultOrderLabels;\n return {\n ...base,\n ...overrides,\n tabs: { ...base.tabs, ...overrides?.tabs },\n empty: { ...base.empty, ...overrides?.empty },\n columns: { ...base.columns, ...overrides?.columns },\n itemColumns: { ...base.itemColumns, ...overrides?.itemColumns },\n refundColumns: { ...base.refundColumns, ...overrides?.refundColumns },\n refundSources: { ...base.refundSources, ...overrides?.refundSources },\n refundStatuses: { ...base.refundStatuses, ...overrides?.refundStatuses },\n actions: { ...base.actions, ...overrides?.actions },\n } as OrderLabels;\n}\n\nfunction mergeProductLabels(\n overrides: DeepPartial<ProductLabels> | undefined,\n): ProductLabels {\n const base = defaultProductLabels;\n return {\n ...base,\n ...overrides,\n filters: { ...base.filters, ...overrides?.filters },\n empty: { ...base.empty, ...overrides?.empty },\n columns: { ...base.columns, ...overrides?.columns },\n fields: { ...base.fields, ...overrides?.fields },\n validation: { ...base.validation, ...overrides?.validation },\n images: { ...base.images, ...overrides?.images },\n } as ProductLabels;\n}\n\nfunction mergeDiscountLabels(\n overrides: DeepPartial<DiscountLabels> | undefined,\n): DiscountLabels {\n const base = defaultDiscountLabels;\n return {\n ...base,\n ...overrides,\n tabs: { ...base.tabs, ...overrides?.tabs },\n empty: { ...base.empty, ...overrides?.empty },\n columns: { ...base.columns, ...overrides?.columns },\n fields: { ...base.fields, ...overrides?.fields },\n types: { ...base.types, ...overrides?.types },\n validation: { ...base.validation, ...overrides?.validation },\n } as DiscountLabels;\n}\n\nexport function mergeAdminLabels(\n labels: AdminLabelOverrides | undefined,\n): AdminLabels {\n const base = defaultAdminLabels;\n return {\n ...base,\n ...labels,\n nav: { ...base.nav, ...labels?.nav },\n statuses: { ...base.statuses, ...labels?.statuses } as Record<\n string,\n string\n >,\n errors: { ...base.errors, ...labels?.errors } as AdminLabels['errors'],\n products: mergeProductLabels(labels?.products),\n orders: mergeOrderLabels(labels?.orders),\n shipping: { ...defaultShippingLabels, ...labels?.shipping },\n discounts: mergeDiscountLabels(labels?.discounts),\n };\n}\n","import type { AdminClient } from '../client';\nimport { createContext, useContext, type ReactNode } from 'react';\nimport { defaultAdminLabels, type AdminLabels } from './admin-labels';\nimport { mergeAdminLabels, type AdminLabelOverrides } from './merge-labels';\n\nexport type { AdminErrorKey, AdminLabels } from './admin-labels';\n\nexport interface LinkProps {\n href: string;\n children: ReactNode;\n className?: string;\n}\n\nexport interface AdminImageProps {\n src: string;\n alt: string;\n sizes?: string;\n className?: string;\n priority?: boolean;\n}\n\nexport interface AdminConfig {\n renderLink: (props: LinkProps) => ReactNode;\n renderImage: (props: AdminImageProps) => ReactNode;\n locale: string;\n currency: string;\n hrefs: {\n products: string;\n product: (id: string) => string;\n newProduct: string;\n orders: string;\n order: (id: string) => string;\n shippingRates: string;\n discounts: string;\n discount: (id: string) => string;\n newDiscount: string;\n storefrontProduct?: (slug: string) => string;\n };\n client: AdminClient | null;\n labels: AdminLabels;\n}\n\nconst defaults: AdminConfig = {\n renderLink: ({ href, children, className }) => (\n <a href={href} className={className}>\n {children}\n </a>\n ),\n renderImage: ({ src, alt, sizes, className, priority }) => (\n <img\n src={src}\n alt={alt}\n sizes={sizes}\n className={className}\n loading={priority ? 'eager' : 'lazy'}\n decoding=\"async\"\n fetchPriority={priority ? 'high' : undefined}\n />\n ),\n locale: 'en-US',\n currency: 'USD',\n hrefs: {\n products: '/admin/products',\n product: (id) => `/admin/products/${id}`,\n newProduct: '/admin/products/new',\n orders: '/admin/orders',\n order: (id) => `/admin/orders/${id}`,\n shippingRates: '/admin/shipping-rates',\n discounts: '/admin/discounts',\n discount: (id) => `/admin/discounts/${id}`,\n newDiscount: '/admin/discounts/new',\n },\n client: null,\n labels: defaultAdminLabels,\n};\n\nconst AdminContext = createContext<AdminConfig>(defaults);\n\nexport interface AdminProviderProps extends Partial<\n Omit<AdminConfig, 'hrefs' | 'labels'>\n> {\n hrefs?: Partial<AdminConfig['hrefs']>;\n labels?: AdminLabelOverrides;\n children: ReactNode;\n}\n\nexport function AdminProvider({\n children,\n hrefs,\n labels,\n ...overrides\n}: AdminProviderProps) {\n const value: AdminConfig = {\n ...defaults,\n ...overrides,\n hrefs: { ...defaults.hrefs, ...hrefs },\n labels: mergeAdminLabels(labels),\n };\n return (\n <AdminContext.Provider value={value}>{children}</AdminContext.Provider>\n );\n}\n\nexport function useAdmin(): AdminConfig {\n return useContext(AdminContext);\n}\n\nexport function useAdminClient(): AdminClient {\n const { client } = useAdmin();\n if (!client) {\n throw new Error('AdminProvider needs a `client` to render this view.');\n }\n return client;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface AdminQuery<T> {\n data: T | undefined;\n error: unknown;\n loading: boolean;\n reload: () => void;\n}\n\ninterface Settled<T> {\n request: string;\n data: T | undefined;\n error: unknown;\n}\n\nexport function useAdminQuery<T>(\n key: readonly unknown[],\n fn: (signal: AbortSignal) => Promise<T>,\n): AdminQuery<T> {\n const fnRef = useRef(fn);\n useEffect(() => {\n fnRef.current = fn;\n });\n const [reloadCount, setReloadCount] = useState(0);\n const [settled, setSettled] = useState<Settled<T>>({\n request: '',\n data: undefined,\n error: undefined,\n });\n const request = `${JSON.stringify(key)}#${reloadCount}`;\n\n useEffect(() => {\n const controller = new AbortController();\n fnRef\n .current(controller.signal)\n .then((data) => {\n if (!controller.signal.aborted)\n setSettled({ request, data, error: undefined });\n })\n .catch((error: unknown) => {\n if (!controller.signal.aborted)\n setSettled((prev) => ({ request, data: prev.data, error }));\n });\n return () => controller.abort();\n }, [request]);\n\n const reload = useCallback(() => setReloadCount((n) => n + 1), []);\n const current = settled.request === request;\n return {\n data: settled.data,\n error: current ? settled.error : undefined,\n loading: !current,\n reload,\n };\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface AdminMutation<A extends unknown[], R> {\n run: (...args: A) => Promise<R | undefined>;\n pending: boolean;\n error: unknown;\n reset: () => void;\n}\n\nexport function useAdminMutation<A extends unknown[], R>(\n fn: (...args: A) => Promise<R>,\n): AdminMutation<A, R> {\n const fnRef = useRef(fn);\n useEffect(() => {\n fnRef.current = fn;\n });\n const [pending, setPending] = useState(false);\n const [error, setError] = useState<unknown>(undefined);\n\n const run = useCallback(async (...args: A) => {\n setPending(true);\n setError(undefined);\n try {\n return await fnRef.current(...args);\n } catch (err) {\n setError(err);\n return undefined;\n } finally {\n setPending(false);\n }\n }, []);\n\n const reset = useCallback(() => setError(undefined), []);\n return { run, pending, error, reset };\n}\n","import type { ReactNode } from 'react';\nimport { useAdmin } from '../../lib/provider';\n\nexport interface ExtraNavItem {\n href: string;\n label: string;\n position?: 'start' | 'end';\n}\n\nexport interface AdminLayoutProps {\n children: ReactNode;\n extraNav?: ExtraNavItem[];\n header?: ReactNode;\n footer?: ReactNode;\n}\n\nexport function AdminLayout({\n children,\n extraNav = [],\n header,\n footer,\n}: AdminLayoutProps) {\n const { hrefs, labels, renderLink } = useAdmin();\n const kit: ExtraNavItem[] = [\n { href: hrefs.products, label: labels.nav.products },\n { href: hrefs.orders, label: labels.nav.orders },\n { href: hrefs.shippingRates, label: labels.nav.shippingRates },\n ];\n const items = [\n ...extraNav.filter((i) => i.position === 'start'),\n ...kit,\n ...extraNav.filter((i) => i.position !== 'start'),\n ];\n return (\n <div className=\"sfa-root sfa-layout\">\n {header ? <header className=\"sfa-layout__header\">{header}</header> : null}\n <nav className=\"sfa-nav\" aria-label={labels.navLabel}>\n <ul>\n {items.map((item) => (\n <li key={item.href}>\n {renderLink({\n href: item.href,\n className: 'sfa-nav__link',\n children: item.label,\n })}\n </li>\n ))}\n </ul>\n </nav>\n <main className=\"sfa-layout__content\">{children}</main>\n {footer ? <footer className=\"sfa-layout__footer\">{footer}</footer> : null}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport { useAdmin } from '../../lib/provider';\n\nexport interface AdminColumn<T> {\n key: string;\n header: string;\n render: (row: T) => ReactNode;\n}\n\nexport interface AdminTableProps<T> {\n columns: AdminColumn<T>[];\n rows: T[];\n rowKey: (row: T) => string;\n caption?: string;\n}\n\nexport function AdminTable<T>({\n columns,\n rows,\n rowKey,\n caption,\n}: AdminTableProps<T>) {\n const { labels } = useAdmin();\n if (rows.length === 0) return <p className=\"sfa-empty\">{labels.empty}</p>;\n return (\n <table className=\"sfa-table sfa-table--stacked\">\n {caption ? <caption>{caption}</caption> : null}\n <thead>\n <tr>\n {columns.map((c) => (\n <th key={c.key} scope=\"col\">\n {c.header}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((row) => (\n <tr key={rowKey(row)}>\n {columns.map((c) => (\n <td key={c.key} data-label={c.header}>\n {c.render(row)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n );\n}\n","import { useAdmin } from '../../lib/provider';\n\nexport function StatusBadge({ status }: { status: string }) {\n const { labels } = useAdmin();\n return (\n <span className={`sfa-badge sfa-badge--${status.replace(/_/g, '-')}`}>\n {labels.statuses[status] ?? status}\n </span>\n );\n}\n","import { useAdmin } from '../../lib/provider';\n\nexport interface MoneyProps {\n cents: number;\n currency: string;\n}\n\nexport function Money({ cents, currency }: MoneyProps) {\n const { locale } = useAdmin();\n const text = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n }).format(cents / 100);\n return <span className=\"sfa-money\">{text}</span>;\n}\n","import { useEffect, useRef, type KeyboardEvent, type ReactNode } from 'react';\nimport { useAdmin } from '../../lib/provider';\n\nconst FOCUSABLE =\n 'button:not([disabled]), [href], input:not([disabled]), select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n\nexport interface ConfirmDialogProps {\n open: boolean;\n title: string;\n children?: ReactNode;\n confirmLabel?: string;\n destructive?: boolean;\n pending?: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n}\n\nexport function ConfirmDialog({\n open,\n title,\n children,\n confirmLabel,\n destructive = false,\n pending = false,\n onConfirm,\n onCancel,\n}: ConfirmDialogProps) {\n const { labels } = useAdmin();\n const panelRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const trigger = document.activeElement as HTMLElement | null;\n panelRef.current?.querySelector<HTMLElement>(FOCUSABLE)?.focus();\n return () => trigger?.focus();\n }, [open]);\n\n if (!open) return null;\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n onCancel();\n return;\n }\n if (event.key !== 'Tab') return;\n const focusable = Array.from(\n panelRef.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? [],\n );\n if (focusable.length === 0) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n };\n\n return (\n <div className=\"sfa-dialog-backdrop\" onKeyDown={onKeyDown}>\n <div\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n className=\"sfa-dialog\"\n >\n <h2 className=\"sfa-dialog__title\">{title}</h2>\n {children}\n <div className=\"sfa-dialog__actions\">\n <button type=\"button\" className=\"sfa-btn\" onClick={onCancel}>\n {labels.cancel}\n </button>\n <button\n type=\"button\"\n className={`sfa-btn ${destructive ? 'sfa-btn--danger' : 'sfa-btn--primary'}`}\n disabled={pending}\n onClick={onConfirm}\n >\n {confirmLabel ?? labels.confirm}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import { useEffect, type ReactNode } from 'react';\nimport { useAdmin } from '../../lib/provider';\n\nexport interface NoticeProps {\n variant: 'success' | 'error' | 'warning';\n children: ReactNode;\n toast?: boolean;\n duration?: number;\n onDismiss?: () => void;\n}\n\nexport function Notice({\n variant,\n children,\n toast = false,\n duration = 4000,\n onDismiss,\n}: NoticeProps) {\n const { labels } = useAdmin();\n\n useEffect(() => {\n if (!toast || !onDismiss) return;\n const timer = setTimeout(onDismiss, duration);\n return () => clearTimeout(timer);\n }, [toast, duration, onDismiss]);\n\n const role = variant === 'error' ? 'alert' : 'status';\n const className = `sfa-notice sfa-notice--${variant}${toast ? ' sfa-notice--toast' : ''}`;\n return (\n <div role={role} className={className}>\n <span className=\"sfa-notice__body\">{children}</span>\n {onDismiss && !toast ? (\n <button type=\"button\" className=\"sfa-btn\" onClick={onDismiss}>\n {labels.dismiss}\n </button>\n ) : null}\n </div>\n );\n}\n","import {\n AdminInvalidInputError,\n AdminNotFoundError,\n AdminUnauthorizedError,\n DiscountCodeTakenError,\n DiscountInUseError,\n ImageTooLargeError,\n InsufficientStockError,\n InvalidImageError,\n InvalidOrderStateError,\n RefundExceedsBalanceError,\n RefundGatewayError,\n RefundOutcomeUnknownError,\n} from '../../client';\nimport { useAdmin, type AdminErrorKey } from '../../lib/provider';\nimport { Notice } from '../notice/notice';\n\nconst KEYED: Array<[new (...args: never[]) => Error, AdminErrorKey]> = [\n [AdminUnauthorizedError, 'unauthorized'],\n [AdminNotFoundError, 'notFound'],\n [AdminInvalidInputError, 'invalidInput'],\n [InvalidOrderStateError, 'invalidOrderState'],\n [InsufficientStockError, 'insufficientStock'],\n [RefundExceedsBalanceError, 'refundExceedsBalance'],\n [RefundGatewayError, 'refundGateway'],\n [RefundOutcomeUnknownError, 'refundOutcomeUnknown'],\n [DiscountCodeTakenError, 'discountCodeTaken'],\n [DiscountInUseError, 'discountInUse'],\n [ImageTooLargeError, 'imageTooLarge'],\n [InvalidImageError, 'imageInvalid'],\n];\n\nexport function errorKey(error: unknown): AdminErrorKey {\n return KEYED.find(([type]) => error instanceof type)?.[1] ?? 'generic';\n}\n\nexport function ErrorMessage({ error }: { error: unknown }) {\n const { labels } = useAdmin();\n if (!error) return null;\n return <Notice variant=\"error\">{labels.errors[errorKey(error)]}</Notice>;\n}\n","import type {\n AdminProduct,\n ProductStatus,\n} from '@develemit/commerce-contracts';\nimport type { ProductFilter } from './product-labels';\n\nexport function isSold(product: AdminProduct): boolean {\n return product.status === 'active' && product.quantity === 0;\n}\n\nexport function displayStatus(product: AdminProduct): string {\n return isSold(product) ? 'sold' : product.status;\n}\n\nexport function serverStatus(filter: ProductFilter): ProductStatus | undefined {\n switch (filter) {\n case 'live':\n case 'sold':\n return 'active';\n case 'draft':\n case 'archived':\n return filter;\n case 'all':\n return undefined;\n }\n}\n\nexport function serverStock(filter: ProductFilter): 'in' | 'sold' | undefined {\n if (filter === 'live') return 'in';\n if (filter === 'sold') return 'sold';\n return undefined;\n}\n","import { useEffect, useState } from 'react';\n\nexport function useDebounced<T>(value: T, delayMs: number): T {\n const [debounced, setDebounced] = useState(value);\n useEffect(() => {\n const timer = setTimeout(() => setDebounced(value), delayMs);\n return () => clearTimeout(timer);\n }, [value, delayMs]);\n return debounced;\n}\n","import { useState } from 'react';\nimport type {\n AdminProduct,\n AdminProductPage,\n} from '@develemit/commerce-contracts';\nimport type { AdminProductQuery } from '../client/admin-client';\nimport { useAdminClient } from './provider';\nimport { useAdminMutation } from './use-admin-mutation';\nimport { useAdminQuery } from './use-admin-query';\n\ninterface Appended {\n base: AdminProductPage;\n items: AdminProduct[];\n nextCursor: string | null;\n}\n\nexport function useProductPages(query: Omit<AdminProductQuery, 'cursor'>) {\n const client = useAdminClient();\n const first = useAdminQuery(['admin-products', query], () =>\n client.listProducts(query),\n );\n const [appended, setAppended] = useState<Appended | null>(null);\n const more = useAdminMutation(\n async (cursor: string, base: AdminProductPage) => {\n const page = await client.listProducts({ ...query, cursor });\n setAppended((prev) => ({\n base,\n items: [...(prev?.base === base ? prev.items : []), ...page.items],\n nextCursor: page.nextCursor,\n }));\n },\n );\n\n const base = first.data;\n const extra = appended && appended.base === base ? appended : null;\n const nextCursor = extra ? extra.nextCursor : (base?.nextCursor ?? null);\n return {\n items: [...(base?.items ?? []), ...(extra?.items ?? [])],\n loaded: base !== undefined,\n loading: first.loading,\n error: first.error ?? more.error,\n hasMore: !first.loading && nextCursor !== null,\n loadingMore: more.pending,\n reload: first.reload,\n loadMore: () => {\n if (base && nextCursor) void more.run(nextCursor, base);\n },\n };\n}\n","import { useState } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport {\n AdminTable,\n type AdminColumn,\n} from '../../components/admin-table/admin-table';\nimport { ConfirmDialog } from '../../components/confirm-dialog/confirm-dialog';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Money } from '../../components/money/money';\nimport { Notice } from '../../components/notice/notice';\nimport { StatusBadge } from '../../components/status-badge/status-badge';\nimport {\n displayStatus,\n serverStatus,\n serverStock,\n} from '../../lib/product-filter';\nimport type { ProductFilter } from '../../lib/product-labels';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useAdminMutation } from '../../lib/use-admin-mutation';\nimport { useDebounced } from '../../lib/use-debounced';\nimport { useProductPages } from '../../lib/use-product-pages';\n\nconst FILTERS: ProductFilter[] = ['all', 'live', 'sold', 'draft', 'archived'];\n\ntype RowAction = { kind: 'sold' | 'archive'; product: AdminProduct };\n\nexport function AdminProductList() {\n const client = useAdminClient();\n const { labels, hrefs, renderLink } = useAdmin();\n const copy = labels.products;\n const [filter, setFilter] = useState<ProductFilter>('all');\n const [search, setSearch] = useState('');\n const q = useDebounced(search.trim(), 300);\n const status = serverStatus(filter);\n const stock = serverStock(filter);\n const pages = useProductPages({\n ...(status ? { status } : {}),\n ...(stock ? { stock } : {}),\n ...(q ? { q } : {}),\n });\n const [pending, setPending] = useState<RowAction | null>(null);\n const [updated, setUpdated] = useState(false);\n\n const apply = useAdminMutation(({ kind, product }: RowAction) =>\n client.updateProduct(\n product.id,\n kind === 'sold' ? { sold: true } : { status: 'archived' },\n ),\n );\n\n const confirm = async () => {\n if (!pending) return;\n const result = await apply.run(pending);\n setPending(null);\n if (!result) return;\n setUpdated(true);\n pages.reload();\n };\n\n const columns: AdminColumn<AdminProduct>[] = [\n {\n key: 'image',\n header: copy.columns.image,\n render: (p) =>\n p.images[0] ? (\n <img\n className=\"sfa-thumb\"\n src={p.images[0].url}\n alt={p.images[0].alt}\n width={48}\n height={48}\n />\n ) : (\n <span className=\"sfa-thumb sfa-thumb--empty\">{copy.noImage}</span>\n ),\n },\n {\n key: 'name',\n header: copy.columns.name,\n render: (p) =>\n renderLink({\n href: hrefs.product(p.id),\n children: p.name,\n className: 'sfa-link--tap',\n }),\n },\n {\n key: 'price',\n header: copy.columns.price,\n render: (p) => <Money cents={p.priceCents} currency={p.currency} />,\n },\n {\n key: 'status',\n header: copy.columns.status,\n render: (p) => <StatusBadge status={displayStatus(p)} />,\n },\n {\n key: 'quantity',\n header: copy.columns.quantity,\n render: (p) => p.quantity,\n },\n {\n key: 'actions',\n header: copy.columns.actions,\n render: (p) => (\n <div className=\"sfa-row-actions\">\n {p.status === 'active' && hrefs.storefrontProduct\n ? renderLink({\n href: hrefs.storefrontProduct(p.slug),\n children: copy.viewInShop,\n className: 'sfa-btn',\n })\n : null}\n {p.status !== 'archived' && p.quantity > 0 ? (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n onClick={() => setPending({ kind: 'sold', product: p })}\n >\n {copy.markSold}\n </button>\n ) : null}\n {p.status !== 'archived' ? (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n onClick={() => setPending({ kind: 'archive', product: p })}\n >\n {copy.archive}\n </button>\n ) : null}\n </div>\n ),\n },\n ];\n\n const rows = pages.items;\n const emptyText = q ? copy.noMatches : copy.empty[filter];\n\n return (\n <section className=\"sfa-products\">\n <header className=\"sfa-products__header\">\n <h1>{copy.title}</h1>\n {renderLink({\n href: hrefs.newProduct,\n children: copy.newProduct,\n className: 'sfa-btn sfa-btn--primary',\n })}\n </header>\n <div className=\"sfa-products__toolbar\">\n <div\n role=\"group\"\n aria-label={copy.columns.status}\n className=\"sfa-filter-group\"\n >\n {FILTERS.map((value) => (\n <button\n key={value}\n type=\"button\"\n className=\"sfa-btn sfa-filter\"\n aria-pressed={filter === value}\n onClick={() => setFilter(value)}\n >\n {copy.filters[value]}\n </button>\n ))}\n </div>\n <input\n type=\"search\"\n aria-label={copy.searchLabel}\n placeholder={copy.searchPlaceholder}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n <ErrorMessage error={pages.error ?? apply.error} />\n {pages.loading && !pages.loaded ? (\n <p>{labels.loading}</p>\n ) : rows.length === 0 ? (\n <p className=\"sfa-empty\">{emptyText}</p>\n ) : (\n <AdminTable columns={columns} rows={rows} rowKey={(p) => p.id} />\n )}\n {pages.hasMore ? (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-products__more\"\n disabled={pages.loadingMore}\n onClick={pages.loadMore}\n >\n {copy.loadMore}\n </button>\n ) : null}\n <ConfirmDialog\n open={pending !== null}\n title={\n pending?.kind === 'archive' ? copy.archiveTitle : copy.markSoldTitle\n }\n confirmLabel={\n pending?.kind === 'archive' ? copy.archive : copy.markSold\n }\n pending={apply.pending}\n onConfirm={confirm}\n onCancel={() => setPending(null)}\n >\n <p>\n {pending?.product.name}\n {' — '}\n {pending?.kind === 'archive' ? copy.archiveBody : copy.markSoldBody}\n </p>\n </ConfirmDialog>\n {updated ? (\n <Notice variant=\"success\" toast onDismiss={() => setUpdated(false)}>\n {copy.updated}\n </Notice>\n ) : null}\n </section>\n );\n}\n","const MONEY = /^\\$?\\s*(\\d+|\\d{1,3}(?:,\\d{3})+)?(?:\\.(\\d{1,2}))?$/;\n\nexport function parseMoneyInput(raw: string): number | null {\n const text = raw.trim();\n const match = MONEY.exec(text);\n if (!match || (!match[1] && !match[2])) return null;\n const whole = Number((match[1] ?? '0').replace(/,/g, ''));\n const fraction = Number((match[2] ?? '').padEnd(2, '0'));\n const cents = whole * 100 + fraction;\n return Number.isSafeInteger(cents) ? cents : null;\n}\n\nexport function formatMoneyInput(cents: number): string {\n const whole = Math.floor(cents / 100);\n const fraction = String(cents % 100).padStart(2, '0');\n return `${whole}.${fraction}`;\n}\n","import {\n adminProductInputSchema,\n type AdminProduct,\n type AdminProductInput,\n type AdminProductPatch,\n type ProductStatus,\n} from '@develemit/commerce-contracts';\nimport { formatMoneyInput, parseMoneyInput } from './money-input';\nimport type { ProductLabels } from './product-labels';\n\nexport const FIELD_ORDER = [\n 'name',\n 'category',\n 'description',\n 'materials',\n 'dimensions',\n 'price',\n 'quantity',\n 'status',\n 'featured',\n] as const;\n\nexport type FieldName = (typeof FIELD_ORDER)[number];\nexport type FieldErrors = Partial<Record<FieldName, string>>;\n\nexport interface ProductForm {\n name: string;\n category: string;\n description: string;\n materials: string;\n dimensions: string;\n price: string;\n quantity: string;\n status: ProductStatus;\n featured: boolean;\n}\n\nexport const emptyForm: ProductForm = {\n name: '',\n category: '',\n description: '',\n materials: '',\n dimensions: '',\n price: '',\n quantity: '1',\n status: 'draft',\n featured: false,\n};\n\nexport function formFromProduct(product: AdminProduct): ProductForm {\n return {\n name: product.name,\n category: product.category,\n description: product.description,\n materials: product.materials ?? '',\n dimensions: product.dimensions ?? '',\n price: formatMoneyInput(product.priceCents),\n quantity: String(product.quantity),\n status: product.status,\n featured: product.featured,\n };\n}\n\nfunction fieldFor(path: unknown): FieldName | undefined {\n const head = Array.isArray(path) ? String(path[0] ?? '') : String(path ?? '');\n const mapped = head === 'priceCents' ? 'price' : head;\n return (FIELD_ORDER as readonly string[]).includes(mapped)\n ? (mapped as FieldName)\n : undefined;\n}\n\nexport function mapServerIssues(issues: unknown[]): FieldErrors {\n const errors: FieldErrors = {};\n for (const issue of issues) {\n const { path, message } = (issue ?? {}) as {\n path?: unknown;\n message?: unknown;\n };\n const field = fieldFor(path);\n if (field && !errors[field]) {\n errors[field] = typeof message === 'string' ? message : 'Invalid value.';\n }\n }\n return errors;\n}\n\nexport function firstInvalidField(errors: FieldErrors): FieldName | undefined {\n return FIELD_ORDER.find((field) => errors[field]);\n}\n\nexport type ValidationResult =\n { ok: true; input: AdminProductInput } | { ok: false; errors: FieldErrors };\n\nfunction blankToNull(value: string): string | null {\n const trimmed = value.trim();\n return trimmed === '' ? null : trimmed;\n}\n\nexport function validateForm(\n form: ProductForm,\n labels: ProductLabels,\n currency?: string,\n): ValidationResult {\n const errors: FieldErrors = {};\n const priceCents = parseMoneyInput(form.price);\n if (priceCents === null) errors.price = labels.validation.price;\n const quantity = /^\\d+$/.test(form.quantity.trim())\n ? Number(form.quantity.trim())\n : null;\n if (quantity === null) errors.quantity = labels.validation.quantity;\n\n const parsed = adminProductInputSchema.safeParse({\n name: form.name,\n description: form.description,\n materials: blankToNull(form.materials),\n dimensions: blankToNull(form.dimensions),\n priceCents: priceCents ?? 0,\n ...(currency ? { currency } : {}),\n category: form.category,\n quantity: quantity ?? 0,\n status: form.status,\n featured: form.featured,\n });\n if (!parsed.success) {\n for (const issue of parsed.error.issues) {\n const field = fieldFor(issue.path);\n if (field && !errors[field]) errors[field] = labels.validation.required;\n }\n }\n if (!parsed.success || Object.keys(errors).length > 0) {\n return { ok: false, errors };\n }\n return { ok: true, input: parsed.data };\n}\n\nconst PATCH_KEYS = [\n 'name',\n 'description',\n 'materials',\n 'dimensions',\n 'priceCents',\n 'category',\n 'quantity',\n 'status',\n 'featured',\n] as const;\n\nexport function buildPatch(\n original: AdminProduct,\n input: AdminProductInput,\n): AdminProductPatch {\n const patch: Record<string, unknown> = {};\n for (const key of PATCH_KEYS) {\n const next = input[key] ?? null;\n if (next !== original[key]) patch[key] = input[key];\n }\n return patch as AdminProductPatch;\n}\n","import type { ImageLabels } from './image-labels';\n\nexport const MAX_IMAGE_BYTES = 8 * 1024 * 1024;\n\nconst ACCEPTED_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/heic'];\n\nexport function fill(template: string, values: Record<string, string>) {\n return template.replace(/\\{(\\w+)\\}/g, (_, key: string) => values[key] ?? '');\n}\n\nexport function imageFileProblem(\n file: File,\n labels: ImageLabels,\n): string | null {\n if (!ACCEPTED_TYPES.includes(file.type)) {\n return fill(labels.wrongType, { name: file.name });\n }\n if (file.size > MAX_IMAGE_BYTES) {\n return fill(labels.tooLarge, { name: file.name });\n }\n return null;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { imageFileProblem } from './image-rules';\nimport { useAdmin, useAdminClient } from './provider';\n\nexport interface UploadEntry {\n id: number;\n name: string;\n status: 'queued' | 'uploading' | 'error';\n reason?: string;\n error?: unknown;\n}\n\ninterface Options {\n productId: string;\n onUploaded: (product: AdminProduct) => void;\n}\n\nexport function useImageUpload({ productId, onUploaded }: Options) {\n const client = useAdminClient();\n const { labels } = useAdmin();\n const [entries, setEntries] = useState<UploadEntry[]>([]);\n const nextId = useRef(0);\n const chain = useRef<Promise<void>>(Promise.resolve());\n const onUploadedRef = useRef(onUploaded);\n useEffect(() => {\n onUploadedRef.current = onUploaded;\n });\n\n const patch = (id: number, change: Partial<UploadEntry>) =>\n setEntries((prev) =>\n prev.map((entry) => (entry.id === id ? { ...entry, ...change } : entry)),\n );\n const drop = (id: number) =>\n setEntries((prev) => prev.filter((entry) => entry.id !== id));\n\n const send = async (id: number, file: File, alt: string) => {\n patch(id, { status: 'uploading' });\n try {\n const product = await client.uploadProductImage(productId, file, alt);\n onUploadedRef.current(product);\n drop(id);\n } catch (error) {\n patch(id, { status: 'error', error });\n }\n };\n\n const upload = useCallback(\n (files: File[], alt: string) => {\n const added = files.map((file) => ({\n id: nextId.current++,\n file,\n reason: imageFileProblem(file, labels.products.images),\n }));\n setEntries((prev) => [\n ...prev,\n ...added.map(({ id, file, reason }): UploadEntry => ({\n id,\n name: file.name,\n status: reason ? 'error' : 'queued',\n reason: reason ?? undefined,\n })),\n ]);\n for (const { id, file, reason } of added) {\n if (reason) continue;\n chain.current = chain.current.then(() => send(id, file, alt.trim()));\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [client, productId, labels],\n );\n\n return { entries, upload, dismiss: drop };\n}\n","import { useState, type FormEvent } from 'react';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport type { ImageLabels } from '../../lib/image-labels';\n\nexport interface ImageAltEditorProps {\n imageId: string;\n alt: string;\n name: string;\n labels: ImageLabels;\n onSave: (alt: string) => Promise<void>;\n}\n\nexport function ImageAltEditor({\n imageId,\n alt,\n name,\n labels,\n onSave,\n}: ImageAltEditorProps) {\n const [draft, setDraft] = useState<string | null>(null);\n const [saving, setSaving] = useState(false);\n const [failure, setFailure] = useState<unknown>(undefined);\n\n const close = () => {\n setDraft(null);\n setFailure(undefined);\n };\n\n const submit = async (event: FormEvent) => {\n event.preventDefault();\n if (draft === null) return;\n setSaving(true);\n setFailure(undefined);\n try {\n await onSave(draft);\n setDraft(null);\n } catch (error) {\n setFailure(error);\n } finally {\n setSaving(false);\n }\n };\n\n if (draft === null) {\n return (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n aria-label={`${labels.editAlt}: ${name}`}\n onClick={() => setDraft(alt)}\n >\n {labels.editAlt}\n </button>\n );\n }\n return (\n <form className=\"sfa-image-tile__alt\" onSubmit={submit}>\n <input\n aria-label={`${labels.altLabel}: ${name}`}\n value={draft}\n disabled={saving}\n autoFocus\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Escape') close();\n }}\n />\n <ErrorMessage error={failure} />\n <button\n type=\"submit\"\n className=\"sfa-btn\"\n data-image-id={imageId}\n disabled={saving}\n >\n {labels.saveAlt}\n </button>\n <button\n type=\"button\"\n className=\"sfa-btn\"\n disabled={saving}\n onClick={close}\n >\n {labels.cancelAlt}\n </button>\n </form>\n );\n}\n","import type { AdminProduct } from '@develemit/commerce-contracts';\nimport { fill } from '../../lib/image-rules';\nimport type { ImageLabels } from '../../lib/image-labels';\nimport { useAdmin } from '../../lib/provider';\nimport { ImageAltEditor } from './image-alt-editor';\n\nexport type AdminProductImage = AdminProduct['images'][number];\nexport type MoveDirection = 'earlier' | 'later';\n\nexport interface ImageTileProps {\n image: AdminProductImage;\n index: number;\n total: number;\n busy: boolean;\n labels: ImageLabels;\n onMove: (direction: MoveDirection) => void;\n onRemove: () => void;\n onSaveAlt: (alt: string) => Promise<void>;\n}\n\nexport function ImageTile({\n image,\n index,\n total,\n busy,\n labels,\n onMove,\n onRemove,\n onSaveAlt,\n}: ImageTileProps) {\n const { renderImage } = useAdmin();\n const name = image.alt || fill(labels.photoName, { n: String(index + 1) });\n const move = (direction: MoveDirection, text: string, disabled: boolean) => (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n data-image-id={image.id}\n data-move={direction}\n aria-label={`${text}: ${name}`}\n disabled={disabled}\n onClick={() => onMove(direction)}\n >\n {text}\n </button>\n );\n return (\n <li className=\"sfa-image-tile\" aria-busy={busy} data-image-id={image.id}>\n {renderImage({\n src: image.url,\n alt: image.alt,\n sizes: '160px',\n className: 'sfa-image-tile__img',\n })}\n {index === 0 ? (\n <span className=\"sfa-image-tile__cover\">{labels.cover}</span>\n ) : null}\n {busy ? (\n <span className=\"sfa-spinner\" role=\"status\">\n {labels.working}\n </span>\n ) : null}\n <div className=\"sfa-image-tile__actions\">\n {move('earlier', labels.moveEarlier, index === 0)}\n {move('later', labels.moveLater, index === total - 1)}\n <ImageAltEditor\n imageId={image.id}\n alt={image.alt}\n name={name}\n labels={labels}\n onSave={onSaveAlt}\n />\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--danger\"\n aria-label={`${labels.remove}: ${name}`}\n onClick={onRemove}\n >\n {labels.remove}\n </button>\n </div>\n </li>\n );\n}\n","import type { ChangeEvent } from 'react';\nimport type { ImageLabels } from '../../lib/image-labels';\n\ninterface UploadPickerProps {\n labels: ImageLabels;\n onFiles: (files: File[]) => void;\n}\n\nexport function UploadPicker({ labels, onFiles }: UploadPickerProps) {\n const pick = (event: ChangeEvent<HTMLInputElement>) => {\n onFiles(Array.from(event.target.files ?? []));\n event.target.value = '';\n };\n return (\n <div className=\"sfa-image-picker\">\n <label className=\"sfa-btn sfa-image-picker__btn\">\n {labels.add}\n <input\n type=\"file\"\n accept=\"image/*\"\n multiple\n className=\"sfa-sr-only\"\n onChange={pick}\n />\n </label>\n <label className=\"sfa-btn sfa-image-picker__btn\">\n {labels.takePhoto}\n <input\n type=\"file\"\n accept=\"image/*\"\n capture=\"environment\"\n className=\"sfa-sr-only\"\n onChange={pick}\n />\n </label>\n </div>\n );\n}\n","import { useEffect, useRef, useState, type DragEvent } from 'react';\nimport { ConfirmDialog } from '../../components/confirm-dialog/confirm-dialog';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Notice } from '../../components/notice/notice';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useImageUpload } from '../../lib/use-image-upload';\nimport {\n ImageTile,\n type AdminProductImage,\n type MoveDirection,\n} from './image-tile';\nimport { UploadPicker } from './upload-picker';\n\nexport interface AdminProductImagesProps {\n productId: string;\n images: AdminProductImage[];\n}\n\nconst byPosition = (images: AdminProductImage[]) =>\n [...images].sort((a, b) => a.position - b.position);\n\nexport function AdminProductImages({\n productId,\n images: initial,\n}: AdminProductImagesProps) {\n const client = useAdminClient();\n const { labels } = useAdmin();\n const copy = labels.products.images;\n const [images, setImages] = useState(() => byPosition(initial));\n const [busyId, setBusyId] = useState<string | null>(null);\n const [reordering, setReordering] = useState(false);\n const [alt, setAlt] = useState('');\n const [failure, setFailure] = useState<unknown>(undefined);\n const [reorderFailed, setReorderFailed] = useState(false);\n const [removing, setRemoving] = useState<AdminProductImage | null>(null);\n const focusTarget = useRef<{ id: string; direction: MoveDirection } | null>(\n null,\n );\n const listRef = useRef<HTMLUListElement>(null);\n\n const { entries, upload, dismiss } = useImageUpload({\n productId,\n onUploaded: (product) => setImages(byPosition(product.images)),\n });\n\n useEffect(() => {\n const target = focusTarget.current;\n if (!target) return;\n focusTarget.current = null;\n const find = (direction: MoveDirection) =>\n listRef.current?.querySelector<HTMLButtonElement>(\n `[data-image-id=\"${target.id}\"][data-move=\"${direction}\"]:not(:disabled)`,\n );\n const other = target.direction === 'earlier' ? 'later' : 'earlier';\n (find(target.direction) ?? find(other))?.focus();\n }, [images]);\n\n const move = async (index: number, direction: MoveDirection) => {\n const to = direction === 'earlier' ? index - 1 : index + 1;\n if (reordering || to < 0 || to >= images.length) return;\n const previous = images;\n const next = [...images];\n [next[index], next[to]] = [next[to], next[index]];\n focusTarget.current = { id: images[index].id, direction };\n setImages(next);\n setReordering(true);\n setBusyId(images[index].id);\n setFailure(undefined);\n setReorderFailed(false);\n try {\n const product = await client.reorderProductImages(\n productId,\n next.map((image) => image.id),\n );\n setImages(byPosition(product.images));\n } catch (error) {\n focusTarget.current = { id: images[index].id, direction };\n setImages(previous);\n setFailure(error);\n setReorderFailed(true);\n } finally {\n setReordering(false);\n setBusyId(null);\n }\n };\n\n const confirmRemove = async () => {\n if (!removing) return;\n const target = removing;\n setRemoving(null);\n setBusyId(target.id);\n setFailure(undefined);\n setReorderFailed(false);\n try {\n const product = await client.deleteProductImage(productId, target.id);\n setImages(byPosition(product.images));\n } catch (error) {\n setFailure(error);\n } finally {\n setBusyId(null);\n }\n };\n\n const saveAlt = async (imageId: string, nextAlt: string) => {\n const product = await client.updateProductImage(productId, imageId, {\n alt: nextAlt,\n });\n setImages(byPosition(product.images));\n };\n\n const onDrop = (event: DragEvent) => {\n event.preventDefault();\n upload(Array.from(event.dataTransfer.files), alt);\n };\n\n return (\n <div\n className=\"sfa-images\"\n onDragOver={(event) => event.preventDefault()}\n onDrop={onDrop}\n >\n <h2>{copy.title}</h2>\n {reorderFailed ? (\n <Notice variant=\"error\" onDismiss={() => setReorderFailed(false)}>\n {copy.reorderFailed}\n </Notice>\n ) : (\n <ErrorMessage error={failure} />\n )}\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor={`${productId}-image-alt`}>\n {copy.altLabel}\n </label>\n <input\n id={`${productId}-image-alt`}\n value={alt}\n onChange={(event) => setAlt(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') event.preventDefault();\n }}\n />\n <p className=\"sfa-field__help\">{copy.altHelp}</p>\n {alt.trim() === '' ? (\n <p className=\"sfa-field__error\">{copy.altWarning}</p>\n ) : null}\n </div>\n <UploadPicker labels={copy} onFiles={(files) => upload(files, alt)} />\n <p className=\"sfa-field__help\">{copy.dropHint}</p>\n {images.length === 0 && entries.length === 0 ? <p>{copy.empty}</p> : null}\n <ul ref={listRef} className=\"sfa-image-grid\">\n {images.map((image, index) => (\n <ImageTile\n key={image.id}\n image={image}\n index={index}\n total={images.length}\n busy={busyId === image.id}\n labels={copy}\n onMove={(direction) => move(index, direction)}\n onRemove={() => setRemoving(image)}\n onSaveAlt={(next) => saveAlt(image.id, next)}\n />\n ))}\n {entries.map((entry) => (\n <li\n key={entry.id}\n className=\"sfa-image-tile\"\n aria-busy={entry.status !== 'error'}\n >\n <span>{entry.name}</span>\n {entry.status === 'error' ? (\n <>\n {entry.reason ? (\n <Notice variant=\"error\">{entry.reason}</Notice>\n ) : (\n <ErrorMessage error={entry.error} />\n )}\n <button\n type=\"button\"\n className=\"sfa-btn\"\n onClick={() => dismiss(entry.id)}\n >\n {copy.dismiss}\n </button>\n </>\n ) : (\n <span className=\"sfa-spinner\" role=\"status\">\n {entry.status === 'uploading' ? copy.uploading : copy.working}\n </span>\n )}\n </li>\n ))}\n </ul>\n <ConfirmDialog\n open={removing !== null}\n title={copy.removeTitle}\n destructive\n confirmLabel={copy.remove}\n onConfirm={confirmRemove}\n onCancel={() => setRemoving(null)}\n >\n <p>{copy.removeBody}</p>\n </ConfirmDialog>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport type { ProductStatus } from '@develemit/commerce-contracts';\nimport type {\n FieldErrors,\n FieldName,\n ProductForm,\n} from '../../lib/product-form';\nimport type { ProductLabels } from '../../lib/product-labels';\n\ninterface ControlProps {\n id: string;\n name: FieldName;\n 'aria-invalid': boolean;\n 'aria-describedby'?: string;\n}\n\ninterface FieldShellProps {\n name: FieldName;\n label: string;\n error?: string;\n help?: string;\n children: (props: ControlProps) => ReactNode;\n}\n\nfunction FieldShell({ name, label, error, help, children }: FieldShellProps) {\n const id = `sfa-field-${name}`;\n const described = [help ? `${id}-help` : '', error ? `${id}-error` : '']\n .filter(Boolean)\n .join(' ');\n return (\n <div className=\"sfa-field\">\n <label htmlFor={id} className=\"sfa-field__label\">\n {label}\n </label>\n {children({\n id,\n name,\n 'aria-invalid': Boolean(error),\n 'aria-describedby': described || undefined,\n })}\n {help ? (\n <p id={`${id}-help`} className=\"sfa-field__help\">\n {help}\n </p>\n ) : null}\n {error ? (\n <p id={`${id}-error`} className=\"sfa-field__error\">\n {error}\n </p>\n ) : null}\n </div>\n );\n}\n\nexport interface FieldGroupProps {\n form: ProductForm;\n errors: FieldErrors;\n labels: ProductLabels;\n statusLabels: Record<string, string>;\n categories?: string[];\n onChange: <K extends keyof ProductForm>(\n field: K,\n value: ProductForm[K],\n ) => void;\n}\n\nconst CATEGORY_LIST_ID = 'sfa-field-category-options';\n\nexport function DetailsFields({\n form,\n errors,\n labels,\n categories,\n onChange,\n}: FieldGroupProps) {\n const suggestCategories = Boolean(categories?.length);\n const text = (name: 'name' | 'category' | 'materials' | 'dimensions') => (\n <FieldShell name={name} label={labels.fields[name]} error={errors[name]}>\n {(props) => (\n <input\n {...props}\n type=\"text\"\n list={\n name === 'category' && suggestCategories\n ? CATEGORY_LIST_ID\n : undefined\n }\n value={form[name]}\n onChange={(e) => onChange(name, e.target.value)}\n />\n )}\n </FieldShell>\n );\n return (\n <>\n {text('name')}\n {text('category')}\n {suggestCategories ? (\n <datalist id={CATEGORY_LIST_ID}>\n {categories?.map((category) => (\n <option key={category} value={category} />\n ))}\n </datalist>\n ) : null}\n <FieldShell\n name=\"description\"\n label={labels.fields.description}\n error={errors.description}\n >\n {(props) => (\n <textarea\n {...props}\n rows={5}\n value={form.description}\n onChange={(e) => onChange('description', e.target.value)}\n />\n )}\n </FieldShell>\n {text('materials')}\n {text('dimensions')}\n </>\n );\n}\n\nconst STATUSES: ProductStatus[] = ['draft', 'active', 'archived'];\n\nexport function SalesFields({\n form,\n errors,\n labels,\n statusLabels,\n onChange,\n}: FieldGroupProps) {\n return (\n <>\n <FieldShell\n name=\"price\"\n label={labels.fields.price}\n error={errors.price}\n help={labels.priceHelp}\n >\n {(props) => (\n <input\n {...props}\n type=\"text\"\n inputMode=\"decimal\"\n value={form.price}\n onChange={(e) => onChange('price', e.target.value)}\n />\n )}\n </FieldShell>\n <FieldShell\n name=\"quantity\"\n label={labels.fields.quantity}\n error={errors.quantity}\n >\n {(props) => (\n <input\n {...props}\n type=\"text\"\n inputMode=\"numeric\"\n value={form.quantity}\n onChange={(e) => onChange('quantity', e.target.value)}\n />\n )}\n </FieldShell>\n <FieldShell\n name=\"status\"\n label={labels.fields.status}\n error={errors.status}\n help={labels.statusHelp}\n >\n {(props) => (\n <select\n {...props}\n value={form.status}\n onChange={(e) =>\n onChange('status', e.target.value as ProductStatus)\n }\n >\n {STATUSES.map((status) => (\n <option key={status} value={status}>\n {statusLabels[status] ?? status}\n </option>\n ))}\n </select>\n )}\n </FieldShell>\n <div className=\"sfa-field\">\n <label className=\"sfa-check\" htmlFor=\"sfa-field-featured\">\n <input\n id=\"sfa-field-featured\"\n name=\"featured\"\n type=\"checkbox\"\n checked={form.featured}\n onChange={(e) => onChange('featured', e.target.checked)}\n />\n <span>{labels.fields.featured}</span>\n </label>\n </div>\n </>\n );\n}\n","import { useState, type FormEvent, type ReactNode } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { AdminInvalidInputError } from '../../client';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Notice } from '../../components/notice/notice';\nimport {\n buildPatch,\n emptyForm,\n firstInvalidField,\n formFromProduct,\n mapServerIssues,\n validateForm,\n type FieldErrors,\n type ProductForm,\n} from '../../lib/product-form';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useAdminMutation } from '../../lib/use-admin-mutation';\nimport { useAdminQuery } from '../../lib/use-admin-query';\nimport { AdminProductImages } from './admin-product-images';\nimport { DetailsFields, SalesFields } from './product-fields';\n\nexport interface AdminProductEditorProps {\n productId?: string;\n onSaved?: (product: AdminProduct) => void;\n imagesSlot?: ReactNode;\n categories?: string[];\n}\n\nexport function AdminProductEditor({\n productId,\n onSaved,\n imagesSlot,\n categories,\n}: AdminProductEditorProps) {\n if (!productId) {\n return (\n <ProductFormView\n product={undefined}\n onSaved={onSaved}\n imagesSlot={null}\n categories={categories}\n />\n );\n }\n return (\n <ExistingProductEditor\n productId={productId}\n onSaved={onSaved}\n imagesSlot={imagesSlot}\n categories={categories}\n />\n );\n}\n\nfunction ExistingProductEditor({\n productId,\n onSaved,\n imagesSlot,\n categories,\n}: AdminProductEditorProps & { productId: string }) {\n const client = useAdminClient();\n const { labels } = useAdmin();\n const query = useAdminQuery(['admin-product', productId], () =>\n client.getProduct(productId),\n );\n if (query.error) return <ErrorMessage error={query.error} />;\n if (!query.data) return <p>{labels.loading}</p>;\n return (\n <ProductFormView\n key={query.data.id}\n product={query.data}\n onSaved={onSaved}\n imagesSlot={imagesSlot}\n categories={categories}\n />\n );\n}\n\ninterface ProductFormViewProps {\n product: AdminProduct | undefined;\n onSaved?: (product: AdminProduct) => void;\n imagesSlot: ReactNode;\n categories?: string[];\n}\n\nfunction ProductFormView({\n product,\n onSaved,\n imagesSlot,\n categories,\n}: ProductFormViewProps) {\n const client = useAdminClient();\n const { labels } = useAdmin();\n const copy = labels.products;\n const [base, setBase] = useState(product);\n const [form, setForm] = useState<ProductForm>(\n product ? formFromProduct(product) : emptyForm,\n );\n const [fieldErrors, setFieldErrors] = useState<FieldErrors>({});\n const [saved, setSaved] = useState(false);\n\n const showErrors = (formEl: HTMLFormElement, found: FieldErrors) => {\n setFieldErrors(found);\n const name = firstInvalidField(found);\n if (name) (formEl.elements.namedItem(name) as HTMLElement | null)?.focus();\n };\n\n const save = useAdminMutation(\n async (formEl: HTMLFormElement): Promise<AdminProduct | undefined> => {\n const result = validateForm(form, copy, base?.currency);\n if (!result.ok) {\n showErrors(formEl, result.errors);\n return undefined;\n }\n try {\n if (!base) return await client.createProduct(result.input);\n const patch = buildPatch(base, result.input);\n return Object.keys(patch).length === 0\n ? base\n : await client.updateProduct(base.id, patch);\n } catch (error) {\n if (!(error instanceof AdminInvalidInputError)) throw error;\n showErrors(formEl, mapServerIssues(error.issues));\n return undefined;\n }\n },\n );\n\n const onChange: Parameters<typeof DetailsFields>[0]['onChange'] = (\n field,\n value,\n ) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n setFieldErrors((prev) => ({\n ...prev,\n [field]: undefined,\n }));\n };\n\n const onSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setSaved(false);\n setFieldErrors({});\n save.reset();\n const result = await save.run(event.currentTarget);\n if (!result) return;\n setBase(result);\n setForm(formFromProduct(result));\n setSaved(true);\n onSaved?.(result);\n };\n\n const images = product\n ? (imagesSlot ?? (\n <AdminProductImages productId={product.id} images={product.images} />\n ))\n : null;\n const group = {\n form,\n errors: fieldErrors,\n labels: copy,\n statusLabels: labels.statuses,\n categories,\n onChange,\n };\n return (\n <form noValidate className=\"sfa-form\" onSubmit={onSubmit}>\n <h1>{product ? copy.editTitle : copy.createTitle}</h1>\n <ErrorMessage error={save.error} />\n <DetailsFields {...group} />\n <SalesFields {...group} />\n {images ? (\n <section data-slot=\"images\" className=\"sfa-form__images\">\n {images}\n </section>\n ) : null}\n <button\n type=\"submit\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={save.pending}\n >\n {labels.save}\n </button>\n {saved ? (\n <Notice variant=\"success\" toast onDismiss={() => setSaved(false)}>\n {copy.saved}\n </Notice>\n ) : null}\n </form>\n );\n}\n","import { useState } from 'react';\nimport type {\n AdminOrderListItem,\n AdminOrderPage,\n} from '@develemit/commerce-contracts';\nimport type { AdminOrderQuery } from '../client/admin-client';\nimport { useAdminClient } from './provider';\nimport { useAdminMutation } from './use-admin-mutation';\nimport { useAdminQuery } from './use-admin-query';\n\ninterface Appended {\n base: AdminOrderPage;\n items: AdminOrderListItem[];\n nextCursor: string | null;\n}\n\nexport function useOrderPages(query: Omit<AdminOrderQuery, 'cursor'>) {\n const client = useAdminClient();\n const first = useAdminQuery(['admin-orders', query], () =>\n client.listOrders(query),\n );\n const [appended, setAppended] = useState<Appended | null>(null);\n const more = useAdminMutation(\n async (cursor: string, base: AdminOrderPage) => {\n const page = await client.listOrders({ ...query, cursor });\n setAppended((prev) => ({\n base,\n items: [...(prev?.base === base ? prev.items : []), ...page.items],\n nextCursor: page.nextCursor,\n }));\n },\n );\n\n const base = first.data;\n const extra = appended && appended.base === base ? appended : null;\n const nextCursor = extra ? extra.nextCursor : (base?.nextCursor ?? null);\n return {\n items: [...(base?.items ?? []), ...(extra?.items ?? [])],\n loading: first.loading,\n error: first.error ?? more.error,\n hasMore: !first.loading && nextCursor !== null,\n loadingMore: more.pending,\n loadMore: () => {\n if (base && nextCursor) void more.run(nextCursor, base);\n },\n };\n}\n","import { useState } from 'react';\nimport type { AdminOrderListItem } from '@develemit/commerce-contracts';\nimport type { AdminOrderQuery } from '../../client/admin-client';\nimport {\n AdminTable,\n type AdminColumn,\n} from '../../components/admin-table/admin-table';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Money } from '../../components/money/money';\nimport { StatusBadge } from '../../components/status-badge/status-badge';\nimport type { OrderTab } from '../../lib/order-labels';\nimport { useAdmin } from '../../lib/provider';\nimport { useDebounced } from '../../lib/use-debounced';\nimport { useOrderPages } from '../../lib/use-order-pages';\n\nconst TABS: OrderTab[] = [\n 'paid',\n 'shipped',\n 'needs_attention',\n 'pending_refund',\n 'all',\n];\n\nfunction tabQuery(tab: OrderTab): AdminOrderQuery {\n if (tab === 'pending_refund') return { hasPendingRefund: true };\n if (tab === 'all') return {};\n return { status: tab };\n}\n\nexport function AdminOrderList() {\n const { labels, locale, hrefs, renderLink } = useAdmin();\n const copy = labels.orders;\n const [tab, setTab] = useState<OrderTab>('paid');\n const [search, setSearch] = useState('');\n const q = useDebounced(search.trim(), 300);\n const pages = useOrderPages({ ...tabQuery(tab), ...(q ? { q } : {}) });\n const date = new Intl.DateTimeFormat(locale);\n\n const columns: AdminColumn<AdminOrderListItem>[] = [\n {\n key: 'order',\n header: copy.columns.order,\n render: (o) =>\n renderLink({\n href: hrefs.order(o.id),\n children: o.id,\n className: 'sfa-link--tap',\n }),\n },\n {\n key: 'status',\n header: copy.columns.status,\n render: (o) => <StatusBadge status={o.status} />,\n },\n {\n key: 'email',\n header: copy.columns.email,\n render: (o) => o.email ?? copy.noEmail,\n },\n { key: 'items', header: copy.columns.items, render: (o) => o.itemCount },\n {\n key: 'total',\n header: copy.columns.total,\n render: (o) => <Money cents={o.totalCents} currency={o.currency} />,\n },\n {\n key: 'date',\n header: copy.columns.date,\n render: (o) => date.format(new Date(o.createdAt)),\n },\n ];\n\n return (\n <section className=\"sfa-orders\">\n <h1>{copy.title}</h1>\n <div className=\"sfa-orders__toolbar\">\n <div\n role=\"group\"\n aria-label={copy.columns.status}\n className=\"sfa-filter-group\"\n >\n {TABS.map((value) => (\n <button\n key={value}\n type=\"button\"\n className=\"sfa-btn sfa-filter\"\n aria-pressed={tab === value}\n onClick={() => setTab(value)}\n >\n {copy.tabs[value]}\n </button>\n ))}\n </div>\n <input\n type=\"search\"\n aria-label={copy.searchLabel}\n placeholder={copy.searchPlaceholder}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n <ErrorMessage error={pages.error} />\n {pages.loading ? (\n <p>{labels.loading}</p>\n ) : pages.items.length === 0 ? (\n <p className=\"sfa-empty\">{q ? copy.noMatches : copy.empty[tab]}</p>\n ) : (\n <AdminTable columns={columns} rows={pages.items} rowKey={(o) => o.id} />\n )}\n {pages.hasMore ? (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-orders__more\"\n disabled={pages.loadingMore}\n onClick={pages.loadMore}\n >\n {copy.loadMore}\n </button>\n ) : null}\n </section>\n );\n}\n","import type { AdminOrderDetail } from '@develemit/commerce-contracts';\n\nexport function pendingRefundCents(order: AdminOrderDetail): number {\n return order.refunds\n .filter((r) => r.status === 'pending')\n .reduce((sum, r) => sum + r.amountCents, 0);\n}\n\nexport function remainingRefundCents(order: AdminOrderDetail): number {\n return order.totalCents - order.refundedCents - pendingRefundCents(order);\n}\n\nexport function hasPendingRefund(order: AdminOrderDetail): boolean {\n return order.refunds.some((r) => r.status === 'pending');\n}\n\nexport function canRestock(\n order: AdminOrderDetail,\n amountCents: number | null,\n): boolean {\n return (\n order.status !== 'needs_attention' &&\n amountCents !== null &&\n amountCents === remainingRefundCents(order)\n );\n}\n\nexport function canShip(order: AdminOrderDetail): boolean {\n return order.status === 'paid' || order.status === 'shipped';\n}\n\nexport function canRefund(order: AdminOrderDetail): boolean {\n return (\n (canShip(order) || order.status === 'needs_attention') &&\n remainingRefundCents(order) > 0\n );\n}\n","import { useRef, useState } from 'react';\nimport type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport { RefundGatewayError, RefundOutcomeUnknownError } from '../../client';\nimport { ConfirmDialog } from '../../components/confirm-dialog/confirm-dialog';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Notice } from '../../components/notice/notice';\nimport { formatMoneyInput, parseMoneyInput } from '../../lib/money-input';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport {\n canRestock,\n hasPendingRefund,\n remainingRefundCents,\n} from '../../lib/refund-rules';\nimport { useAdminMutation } from '../../lib/use-admin-mutation';\n\ninterface RefundDialogProps {\n order: AdminOrderDetail;\n onClose: () => void;\n onDone: (message: string) => void;\n}\n\nexport function RefundDialog({ order, onClose, onDone }: RefundDialogProps) {\n const client = useAdminClient();\n const copy = useAdmin().labels.orders.actions;\n const keyRef = useRef(crypto.randomUUID());\n const remaining = remainingRefundCents(order);\n const [amount, setAmount] = useState(formatMoneyInput(remaining));\n const [reason, setReason] = useState('');\n const [restock, setRestock] = useState(false);\n const [invalid, setInvalid] = useState(false);\n const refund = useAdminMutation(client.refundOrder);\n\n const cents = parseMoneyInput(amount);\n const amountValid = cents !== null && cents > 0 && cents <= remaining;\n const restockOffered = canRestock(order, cents);\n const retryable =\n refund.error instanceof RefundGatewayError ||\n refund.error instanceof RefundOutcomeUnknownError;\n\n const submit = async () => {\n if (!amountValid) {\n setInvalid(true);\n return;\n }\n setInvalid(false);\n const result = await refund.run(\n order.id,\n {\n amountCents: cents,\n reason: reason.trim() || undefined,\n restock: restock && restockOffered,\n },\n { idempotencyKey: keyRef.current },\n );\n if (result) onDone(copy.refundDone);\n };\n\n return (\n <ConfirmDialog\n open\n title={copy.refundTitle}\n confirmLabel={retryable ? copy.refundRetry : copy.refundSubmit}\n destructive\n pending={refund.pending}\n onConfirm={submit}\n onCancel={onClose}\n >\n {hasPendingRefund(order) ? (\n <Notice variant=\"warning\">{copy.refundPending}</Notice>\n ) : null}\n <div className=\"sfa-field\">\n <label htmlFor=\"sfa-refund-amount\" className=\"sfa-field__label\">\n {copy.refundAmount}\n </label>\n <input\n id=\"sfa-refund-amount\"\n inputMode=\"decimal\"\n value={amount}\n disabled={retryable}\n aria-invalid={invalid && !amountValid}\n onChange={(e) => setAmount(e.target.value)}\n />\n {invalid && !amountValid ? (\n <p className=\"sfa-field__error\">{copy.refundAmountInvalid}</p>\n ) : null}\n </div>\n <div className=\"sfa-field\">\n <label htmlFor=\"sfa-refund-reason\" className=\"sfa-field__label\">\n {copy.refundReason}\n </label>\n <textarea\n id=\"sfa-refund-reason\"\n maxLength={500}\n value={reason}\n disabled={retryable}\n onChange={(e) => setReason(e.target.value)}\n />\n </div>\n {restockOffered ? (\n <div className=\"sfa-field\">\n <label>\n <input\n type=\"checkbox\"\n checked={restock}\n disabled={retryable}\n onChange={(e) => setRestock(e.target.checked)}\n />{' '}\n {copy.restock}\n </label>\n <p className=\"sfa-field__help\">{copy.restockWarning}</p>\n </div>\n ) : null}\n {refund.error instanceof RefundOutcomeUnknownError ? (\n <Notice variant=\"warning\">{copy.refundUnknown}</Notice>\n ) : refund.error instanceof RefundGatewayError ? (\n <Notice variant=\"warning\">{copy.refundGateway}</Notice>\n ) : (\n <ErrorMessage error={refund.error} />\n )}\n </ConfirmDialog>\n );\n}\n","import type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport { InsufficientStockError } from '../../client';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Notice } from '../../components/notice/notice';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useAdminMutation } from '../../lib/use-admin-mutation';\n\ninterface ResolveButtonProps {\n order: AdminOrderDetail;\n onDone: (message: string) => void;\n}\n\nexport function ResolveButton({ order, onDone }: ResolveButtonProps) {\n const client = useAdminClient();\n const { labels, hrefs, renderLink } = useAdmin();\n const copy = labels.orders.actions;\n const resolve = useAdminMutation(client.resolveOrder);\n\n const submit = async () => {\n const result = await resolve.run(order.id);\n if (result) onDone(copy.resolved);\n };\n\n const stockError =\n resolve.error instanceof InsufficientStockError ? resolve.error : null;\n const names = new Map(order.items.map((i) => [i.productId, i.name]));\n\n return (\n <div className=\"sfa-order__action\">\n <p>{copy.resolveHelp}</p>\n {stockError ? (\n <Notice variant=\"error\">\n {labels.errors.insufficientStock}\n <ul>\n {stockError.productIds.map((id) => (\n <li key={id}>\n {renderLink({\n href: hrefs.product(id),\n children: `${copy.restockThenResolve}: ${names.get(id) ?? id}`,\n className: 'sfa-link--tap',\n })}\n </li>\n ))}\n </ul>\n </Notice>\n ) : (\n <ErrorMessage error={resolve.error} />\n )}\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={resolve.pending}\n onClick={submit}\n >\n {copy.resolve}\n </button>\n </div>\n );\n}\n","import { useState, type FormEvent } from 'react';\nimport type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useAdminMutation } from '../../lib/use-admin-mutation';\n\nfunction isHttpUrl(value: string): boolean {\n try {\n const { protocol } = new URL(value);\n return protocol === 'http:' || protocol === 'https:';\n } catch {\n return false;\n }\n}\n\ninterface ShipFormProps {\n order: AdminOrderDetail;\n onDone: (message: string) => void;\n}\n\nexport function ShipForm({ order, onDone }: ShipFormProps) {\n const client = useAdminClient();\n const copy = useAdmin().labels.orders.actions;\n const current = order.fulfillment;\n const [carrier, setCarrier] = useState(current?.carrier ?? '');\n const [trackingNumber, setTrackingNumber] = useState(\n current?.trackingNumber ?? '',\n );\n const [trackingUrl, setTrackingUrl] = useState(current?.trackingUrl ?? '');\n const [urlError, setUrlError] = useState(false);\n const ship = useAdminMutation(client.shipOrder);\n const reship = order.status === 'shipped';\n\n const submit = async (event: FormEvent) => {\n event.preventDefault();\n const url = trackingUrl.trim();\n if (url && !isHttpUrl(url)) {\n setUrlError(true);\n return;\n }\n setUrlError(false);\n const result = await ship.run(order.id, {\n carrier: carrier.trim() || undefined,\n trackingNumber: trackingNumber.trim() || undefined,\n trackingUrl: url || undefined,\n });\n if (result) onDone(copy.shipped);\n };\n\n return (\n <form className=\"sfa-order__action\" onSubmit={submit}>\n <h3>{copy.shipHeading}</h3>\n <div className=\"sfa-field\">\n <label htmlFor=\"sfa-ship-carrier\" className=\"sfa-field__label\">\n {copy.carrier}\n </label>\n <input\n id=\"sfa-ship-carrier\"\n value={carrier}\n onChange={(e) => setCarrier(e.target.value)}\n />\n </div>\n <div className=\"sfa-field\">\n <label htmlFor=\"sfa-ship-number\" className=\"sfa-field__label\">\n {copy.trackingNumber}\n </label>\n <input\n id=\"sfa-ship-number\"\n value={trackingNumber}\n onChange={(e) => setTrackingNumber(e.target.value)}\n />\n </div>\n <div className=\"sfa-field\">\n <label htmlFor=\"sfa-ship-url\" className=\"sfa-field__label\">\n {copy.trackingUrl}\n </label>\n <input\n id=\"sfa-ship-url\"\n value={trackingUrl}\n aria-invalid={urlError}\n aria-describedby={urlError ? 'sfa-ship-url-error' : undefined}\n onChange={(e) => setTrackingUrl(e.target.value)}\n />\n {urlError ? (\n <p id=\"sfa-ship-url-error\" className=\"sfa-field__error\">\n {copy.trackingUrlInvalid}\n </p>\n ) : null}\n </div>\n <ErrorMessage error={ship.error} />\n <button\n type=\"submit\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={ship.pending}\n >\n {reship ? copy.reship : copy.ship}\n </button>\n </form>\n );\n}\n","import { useState } from 'react';\nimport type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport { Notice } from '../../components/notice/notice';\nimport { useAdmin } from '../../lib/provider';\nimport { canRefund, canShip } from '../../lib/refund-rules';\nimport { RefundDialog } from './refund-dialog';\nimport { ResolveButton } from './resolve-button';\nimport { ShipForm } from './ship-form';\n\ninterface OrderActionsProps {\n order: AdminOrderDetail;\n reload: () => void;\n}\n\nexport function OrderActions({ order, reload }: OrderActionsProps) {\n const copy = useAdmin().labels.orders.actions;\n const [refunding, setRefunding] = useState(false);\n const [message, setMessage] = useState<string | null>(null);\n\n const done = (text: string) => {\n setRefunding(false);\n setMessage(text);\n reload();\n };\n const closeRefund = () => {\n setRefunding(false);\n reload();\n };\n\n return (\n <div className=\"sfa-order__actions\">\n {message ? (\n <Notice variant=\"success\" onDismiss={() => setMessage(null)}>\n {message}\n </Notice>\n ) : null}\n {canShip(order) ? <ShipForm order={order} onDone={done} /> : null}\n {order.status === 'needs_attention' ? (\n <ResolveButton order={order} onDone={done} />\n ) : null}\n {canRefund(order) ? (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--danger\"\n onClick={() => setRefunding(true)}\n >\n {copy.refund}\n </button>\n ) : null}\n {refunding ? (\n <RefundDialog order={order} onClose={closeRefund} onDone={done} />\n ) : null}\n </div>\n );\n}\n","import type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport { useAdmin } from '../../lib/provider';\n\nexport function OrderFulfillment({ order }: { order: AdminOrderDetail }) {\n const { labels, locale, renderLink } = useAdmin();\n const copy = labels.orders;\n const f = order.fulfillment;\n return (\n <section className=\"sfa-order__section\">\n <h2>{copy.fulfillment}</h2>\n {f ? (\n <dl>\n <dt>{copy.shippedOn}</dt>\n <dd>\n {new Intl.DateTimeFormat(locale).format(new Date(f.shippedAt))}\n </dd>\n {f.carrier ? (\n <>\n <dt>{copy.carrier}</dt>\n <dd>{f.carrier}</dd>\n </>\n ) : null}\n {f.trackingNumber ? (\n <>\n <dt>{copy.tracking}</dt>\n <dd>{f.trackingNumber}</dd>\n </>\n ) : null}\n {f.trackingUrl ? (\n <dd>\n {renderLink({\n href: f.trackingUrl,\n children: copy.trackShipment,\n className: 'sfa-link--tap',\n })}\n </dd>\n ) : null}\n </dl>\n ) : (\n <p>{copy.notShipped}</p>\n )}\n </section>\n );\n}\n","import type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport {\n AdminTable,\n type AdminColumn,\n} from '../../components/admin-table/admin-table';\nimport { Money } from '../../components/money/money';\nimport { useAdmin } from '../../lib/provider';\n\ntype Item = AdminOrderDetail['items'][number];\n\nexport function OrderItems({ order }: { order: AdminOrderDetail }) {\n const { labels } = useAdmin();\n const copy = labels.orders;\n const { currency } = order;\n const columns: AdminColumn<Item>[] = [\n { key: 'name', header: copy.itemColumns.name, render: (i) => i.name },\n {\n key: 'price',\n header: copy.itemColumns.price,\n render: (i) => <Money cents={i.priceCents} currency={currency} />,\n },\n {\n key: 'quantity',\n header: copy.itemColumns.quantity,\n render: (i) => i.quantity,\n },\n {\n key: 'line',\n header: copy.itemColumns.line,\n render: (i) => (\n <Money cents={i.priceCents * i.quantity} currency={currency} />\n ),\n },\n ];\n return (\n <section className=\"sfa-order__section\">\n <h2>{copy.itemsHeading}</h2>\n <AdminTable\n columns={columns}\n rows={order.items}\n rowKey={(i) => i.productId}\n />\n <dl className=\"sfa-order__totals\">\n <dt>{copy.subtotal}</dt>\n <dd>\n <Money cents={order.subtotalCents} currency={currency} />\n </dd>\n {order.discountCents > 0 ? (\n <>\n <dt>\n {labels.discounts.orderRow}\n {order.discountCode ? ` (${order.discountCode})` : ''}\n </dt>\n <dd>\n −<Money cents={order.discountCents} currency={currency} />\n </dd>\n </>\n ) : null}\n <dt>{order.shippingLabel ?? copy.shipping}</dt>\n <dd>\n <Money cents={order.shippingCents} currency={currency} />\n </dd>\n <dt>{copy.total}</dt>\n <dd>\n <Money cents={order.totalCents} currency={currency} />\n </dd>\n </dl>\n </section>\n );\n}\n","import type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport {\n AdminTable,\n type AdminColumn,\n} from '../../components/admin-table/admin-table';\nimport { Money } from '../../components/money/money';\nimport { useAdmin } from '../../lib/provider';\n\ntype Refund = AdminOrderDetail['refunds'][number];\n\nexport function OrderRefunds({ order }: { order: AdminOrderDetail }) {\n const { labels, locale } = useAdmin();\n const copy = labels.orders;\n const { currency } = order;\n const date = new Intl.DateTimeFormat(locale);\n const columns: AdminColumn<Refund>[] = [\n {\n key: 'amount',\n header: copy.refundColumns.amount,\n render: (r) => <Money cents={r.amountCents} currency={currency} />,\n },\n {\n key: 'reason',\n header: copy.refundColumns.reason,\n render: (r) => r.reason ?? '—',\n },\n {\n key: 'source',\n header: copy.refundColumns.source,\n render: (r) => copy.refundSources[r.source],\n },\n {\n key: 'status',\n header: copy.refundColumns.status,\n render: (r) => (\n <span\n className={`sfa-badge sfa-badge--refund-${r.status}`}\n data-refund-status={r.status}\n >\n {copy.refundStatuses[r.status]}\n </span>\n ),\n },\n {\n key: 'restocked',\n header: copy.refundColumns.restocked,\n render: (r) => (r.restocked ? copy.yes : copy.no),\n },\n {\n key: 'date',\n header: copy.refundColumns.date,\n render: (r) => date.format(new Date(r.createdAt)),\n },\n ];\n const remaining = order.totalCents - order.refundedCents;\n return (\n <section className=\"sfa-order__section\">\n <h2>{copy.refunds}</h2>\n {order.refunds.length === 0 ? (\n <p>{copy.noRefunds}</p>\n ) : (\n <>\n <AdminTable\n columns={columns}\n rows={order.refunds}\n rowKey={(r) => r.id}\n />\n <dl className=\"sfa-order__totals\">\n <dt>{copy.refunded}</dt>\n <dd>\n <Money cents={order.refundedCents} currency={currency} />\n </dd>\n <dt>{copy.remaining}</dt>\n <dd>\n <Money cents={remaining} currency={currency} />\n </dd>\n </dl>\n </>\n )}\n </section>\n );\n}\n","import type { ReactNode } from 'react';\nimport type { AdminOrderDetail as OrderDetail } from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Money } from '../../components/money/money';\nimport { StatusBadge } from '../../components/status-badge/status-badge';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useAdminQuery } from '../../lib/use-admin-query';\nimport { OrderActions } from './order-actions';\nimport { OrderFulfillment } from './order-fulfillment';\nimport { OrderItems } from './order-items';\nimport { OrderRefunds } from './order-refunds';\n\nexport interface AdminOrderDetailProps {\n orderId: string;\n actions?: (ctx: { order: OrderDetail; reload: () => void }) => ReactNode;\n}\n\nfunction addressLines(order: OrderDetail): string[] {\n const a = order.shippingAddress;\n if (!a) return [];\n const region = [a.city, a.state, a.postalCode].filter(Boolean).join(' ');\n return [a.name, a.line1, a.line2, region, a.country].filter(\n (l): l is string => Boolean(l),\n );\n}\n\nexport function AdminOrderDetail({ orderId, actions }: AdminOrderDetailProps) {\n const client = useAdminClient();\n const { labels, locale, hrefs, renderLink } = useAdmin();\n const copy = labels.orders;\n const query = useAdminQuery(['admin-order', orderId], () =>\n client.getOrder(orderId),\n );\n if (query.error) return <ErrorMessage error={query.error} />;\n const order = query.data;\n if (!order) return <p>{labels.loading}</p>;\n const lines = addressLines(order);\n\n return (\n <article className=\"sfa-order\">\n {renderLink({\n href: hrefs.orders,\n children: copy.back,\n className: 'sfa-link--tap',\n })}\n <header className=\"sfa-order__header\">\n <h1>\n {copy.detailTitle} {order.id}\n </h1>\n <StatusBadge status={order.status} />\n <span>\n {copy.placed}{' '}\n {new Intl.DateTimeFormat(locale).format(new Date(order.createdAt))}\n </span>\n <Money cents={order.totalCents} currency={order.currency} />\n </header>\n <section className=\"sfa-order__section\">\n <h2>{copy.buyer}</h2>\n <p>{order.email ?? labels.orders.noEmail}</p>\n </section>\n <OrderItems order={order} />\n <section className=\"sfa-order__section\">\n <h2>{copy.shippingAddress}</h2>\n {lines.length === 0 ? (\n <p>{copy.noAddress}</p>\n ) : (\n <address className=\"sfa-order__address\">\n {lines.map((l) => (\n <div key={l}>{l}</div>\n ))}\n </address>\n )}\n </section>\n <OrderFulfillment order={order} />\n <OrderRefunds order={order} />\n <section className=\"sfa-order__section\">\n {actions ? (\n actions({ order, reload: query.reload })\n ) : (\n <OrderActions order={order} reload={query.reload} />\n )}\n </section>\n </article>\n );\n}\n","import {\n shippingRatesInputSchema,\n type ShippingRate,\n type ShippingRateInput,\n} from '@develemit/commerce-contracts';\nimport { formatMoneyInput, parseMoneyInput } from './money-input';\nimport type { ShippingLabels } from './shipping-labels';\n\nexport interface RateDraft {\n key: string;\n label: string;\n amount: string;\n currency: string;\n minDays: string;\n maxDays: string;\n active: boolean;\n}\n\nexport interface RateErrors {\n label?: string;\n amount?: string;\n minDays?: string;\n maxDays?: string;\n currency?: string;\n row?: string;\n}\n\nexport interface DraftCheck {\n rates: ShippingRateInput[];\n rowErrors: Record<string, RateErrors>;\n noActive: boolean;\n valid: boolean;\n}\n\nlet counter = 0;\nexport const newKey = () => `rate-${++counter}`;\n\nexport function toDrafts(rates: ShippingRate[]): RateDraft[] {\n return [...rates]\n .sort((a, b) => a.sort - b.sort)\n .map((rate) => ({\n key: newKey(),\n label: rate.label,\n amount: formatMoneyInput(rate.amountCents),\n currency: rate.currency,\n minDays: rate.minDays == null ? '' : String(rate.minDays),\n maxDays: rate.maxDays == null ? '' : String(rate.maxDays),\n active: rate.active,\n }));\n}\n\nexport function blankDraft(currency: string, label: string): RateDraft {\n return {\n key: newKey(),\n label,\n amount: '',\n currency,\n minDays: '',\n maxDays: '',\n active: true,\n };\n}\n\nexport const snapshot = (drafts: RateDraft[]) =>\n JSON.stringify(drafts.map(({ key: _key, ...rest }) => rest));\n\nfunction parseDays(raw: string): number | null | undefined {\n const text = raw.trim();\n if (text === '') return null;\n return /^\\d+$/.test(text) ? Number(text) : undefined;\n}\n\nexport function checkDrafts(\n drafts: RateDraft[],\n copy: ShippingLabels,\n): DraftCheck {\n const rowErrors: Record<string, RateErrors> = {};\n const rates: ShippingRateInput[] = [];\n const seen = new Map<string, number>();\n drafts.forEach((draft) => {\n const name = draft.label.trim();\n seen.set(name, (seen.get(name) ?? 0) + 1);\n });\n\n drafts.forEach((draft, index) => {\n const errors: RateErrors = {};\n const label = draft.label.trim();\n const cents = parseMoneyInput(draft.amount);\n const min = parseDays(draft.minDays);\n const max = parseDays(draft.maxDays);\n if (label === '') errors.label = copy.labelRequired;\n else if ((seen.get(label) ?? 0) > 1) errors.label = copy.labelDuplicate;\n if (!/^[A-Z]{3}$/.test(draft.currency))\n errors.currency = copy.currencyInvalid;\n if (cents === null) errors.amount = copy.amountInvalid;\n if (min === undefined) errors.minDays = copy.daysInvalid;\n if (max === undefined) errors.maxDays = copy.daysInvalid;\n if (typeof min === 'number' && typeof max === 'number' && min > max) {\n errors.minDays = copy.daysOrder;\n }\n if (Object.keys(errors).length > 0) rowErrors[draft.key] = errors;\n rates.push({\n label,\n amountCents: cents ?? 0,\n currency: draft.currency,\n minDays: min ?? null,\n maxDays: max ?? null,\n active: draft.active,\n sort: index,\n });\n });\n\n if (Object.keys(rowErrors).length === 0) {\n const parsed = shippingRatesInputSchema.safeParse(rates);\n if (!parsed.success) {\n for (const issue of parsed.error.issues) {\n const key =\n typeof issue.path[0] === 'number'\n ? drafts[issue.path[0]]?.key\n : undefined;\n if (key) rowErrors[key] = { row: copy.rowInvalid };\n }\n }\n }\n\n const noActive = !drafts.some((draft) => draft.active);\n return {\n rates,\n rowErrors,\n noActive,\n valid: Object.keys(rowErrors).length === 0 && !noActive,\n };\n}\n\nconst SERVER_FIELDS: Record<string, keyof RateErrors> = {\n label: 'label',\n amountCents: 'amount',\n currency: 'currency',\n minDays: 'minDays',\n maxDays: 'maxDays',\n};\n\nexport function serverRowErrors(\n issues: unknown[],\n drafts: RateDraft[],\n copy: ShippingLabels,\n): Record<string, RateErrors> {\n const result: Record<string, RateErrors> = {};\n for (const issue of issues) {\n const path = (issue as { path?: unknown[] } | null)?.path ?? [];\n const at = path.findIndex((segment) => typeof segment === 'number');\n const key = at >= 0 ? drafts[path[at] as number]?.key : undefined;\n if (!key) continue;\n const last = path[path.length - 1];\n const field =\n path.length - 1 > at && typeof last === 'string'\n ? SERVER_FIELDS[last]\n : undefined;\n result[key] = { ...result[key], [field ?? 'row']: copy.rowInvalid };\n }\n return result;\n}\n","import { fill } from '../../lib/image-rules';\nimport type { RateDraft, RateErrors } from '../../lib/shipping-rates';\nimport type { ShippingLabels } from '../../lib/shipping-labels';\n\nexport type RateMove = 'earlier' | 'later';\n\nexport interface ShippingRateRowProps {\n draft: RateDraft;\n index: number;\n total: number;\n errors: RateErrors;\n disabled: boolean;\n labels: ShippingLabels;\n onChange: (patch: Partial<RateDraft>) => void;\n onMove: (direction: RateMove) => void;\n onRemove: () => void;\n}\n\nexport function ShippingRateRow({\n draft,\n index,\n total,\n errors,\n disabled,\n labels,\n onChange,\n onMove,\n onRemove,\n}: ShippingRateRowProps) {\n const name =\n draft.label.trim() || fill(labels.rowName, { n: String(index + 1) });\n const field = (\n id: string,\n text: string,\n value: string,\n key: 'label' | 'amount' | 'minDays' | 'maxDays',\n inputMode?: 'decimal' | 'numeric',\n ) => {\n const error = errors[key];\n const fieldId = `${draft.key}-${id}`;\n return (\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor={fieldId}>\n {text}\n </label>\n <input\n id={fieldId}\n value={value}\n inputMode={inputMode}\n disabled={disabled}\n aria-invalid={Boolean(error)}\n aria-describedby={error ? `${fieldId}-error` : undefined}\n onChange={(event) => onChange({ [key]: event.target.value })}\n />\n {error ? (\n <p id={`${fieldId}-error`} className=\"sfa-field__error\">\n {error}\n </p>\n ) : null}\n </div>\n );\n };\n\n return (\n <li className=\"sfa-rate\" data-rate-key={draft.key}>\n {field('label', labels.label, draft.label, 'label')}\n {field('amount', labels.amount, draft.amount, 'amount', 'decimal')}\n <div className=\"sfa-field\">\n <span className=\"sfa-field__label\">{labels.currency}</span>\n <span\n className=\"sfa-rate__currency\"\n aria-invalid={Boolean(errors.currency)}\n >\n {draft.currency}\n </span>\n {errors.currency ? (\n <p className=\"sfa-field__error\">{errors.currency}</p>\n ) : null}\n </div>\n {field('min', labels.minDays, draft.minDays, 'minDays', 'numeric')}\n {field('max', labels.maxDays, draft.maxDays, 'maxDays', 'numeric')}\n <label className=\"sfa-rate__active\">\n <input\n type=\"checkbox\"\n checked={draft.active}\n disabled={disabled}\n onChange={(event) => onChange({ active: event.target.checked })}\n />\n {labels.active}\n </label>\n {errors.row ? <p className=\"sfa-field__error\">{errors.row}</p> : null}\n <div className=\"sfa-rate__actions\">\n <button\n type=\"button\"\n className=\"sfa-btn\"\n aria-label={`${labels.moveEarlier}: ${name}`}\n disabled={disabled || index === 0}\n onClick={() => onMove('earlier')}\n >\n {labels.moveEarlier}\n </button>\n <button\n type=\"button\"\n className=\"sfa-btn\"\n aria-label={`${labels.moveLater}: ${name}`}\n disabled={disabled || index === total - 1}\n onClick={() => onMove('later')}\n >\n {labels.moveLater}\n </button>\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--danger\"\n aria-label={`${labels.remove}: ${name}`}\n disabled={disabled}\n onClick={onRemove}\n >\n {labels.remove}\n </button>\n </div>\n </li>\n );\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { AdminInvalidInputError } from '../../client';\nimport { ConfirmDialog } from '../../components/confirm-dialog/confirm-dialog';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Notice } from '../../components/notice/notice';\nimport { fill } from '../../lib/image-rules';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport {\n blankDraft,\n checkDrafts,\n serverRowErrors,\n snapshot,\n toDrafts,\n type RateDraft,\n type RateErrors,\n} from '../../lib/shipping-rates';\nimport { useAdminMutation } from '../../lib/use-admin-mutation';\nimport { useAdminQuery } from '../../lib/use-admin-query';\nimport { ShippingRateRow, type RateMove } from './shipping-rate-row';\n\nexport interface AdminShippingRatesProps {\n onDirtyChange?: (dirty: boolean) => void;\n}\n\nexport function AdminShippingRates({ onDirtyChange }: AdminShippingRatesProps) {\n const client = useAdminClient();\n const { labels, currency } = useAdmin();\n const copy = labels.shipping;\n const query = useAdminQuery(['shipping-rates'], () =>\n client.listShippingRates(),\n );\n const [drafts, setDrafts] = useState<RateDraft[]>([]);\n const [baseline, setBaseline] = useState('[]');\n const [loaded, setLoaded] = useState<unknown>(undefined);\n const [removing, setRemoving] = useState<RateDraft | null>(null);\n const [rowErrors, setRowErrors] = useState<Record<string, RateErrors>>({});\n const [blocked, setBlocked] = useState(false);\n const [saved, setSaved] = useState(false);\n const [removedAny, setRemovedAny] = useState(false);\n const save = useAdminMutation(\n (rates: Parameters<typeof client.replaceShippingRates>[0]) =>\n client.replaceShippingRates(rates),\n );\n const lastDirty = useRef<boolean | undefined>(undefined);\n\n if (query.data && query.data !== loaded) {\n const next = toDrafts(query.data);\n setLoaded(query.data);\n setDrafts(next);\n setBaseline(snapshot(next));\n }\n\n const dirty = loaded !== undefined && snapshot(drafts) !== baseline;\n useEffect(() => {\n if (lastDirty.current === dirty) return;\n lastDirty.current = dirty;\n onDirtyChange?.(dirty);\n }, [dirty, onDirtyChange]);\n\n const edit = (next: RateDraft[]) => {\n setDrafts(next);\n setSaved(false);\n setBlocked(false);\n };\n\n const patch = (key: string, change: Partial<RateDraft>) => {\n edit(drafts.map((d) => (d.key === key ? { ...d, ...change } : d)));\n setRowErrors(({ [key]: _cleared, ...rest }) => rest);\n };\n\n const move = (index: number, direction: RateMove) => {\n const to = direction === 'earlier' ? index - 1 : index + 1;\n if (to < 0 || to >= drafts.length) return;\n const next = [...drafts];\n [next[index], next[to]] = [next[to], next[index]];\n edit(next);\n };\n\n const add = () => edit([...drafts, blankDraft(currency, copy.newRateLabel)]);\n\n const confirmRemove = () => {\n if (!removing) return;\n edit(drafts.filter((d) => d.key !== removing.key));\n setRemovedAny(true);\n setRemoving(null);\n };\n\n const submit = async () => {\n const check = checkDrafts(drafts, copy);\n setRowErrors(check.rowErrors);\n setBlocked(check.noActive);\n if (!check.valid) return;\n const result = await save.run(check.rates);\n if (!result) return;\n const next = toDrafts(result);\n setDrafts(next);\n setBaseline(snapshot(next));\n setRowErrors({});\n setRemovedAny(false);\n setSaved(true);\n };\n\n const mixedCurrency = drafts.some((d) => d.currency !== currency);\n\n const serverErrors =\n save.error instanceof AdminInvalidInputError\n ? serverRowErrors(save.error.issues, drafts, copy)\n : {};\n\n if (query.loading && !query.data) return <p role=\"status\">{copy.loading}</p>;\n if (!query.data) return <ErrorMessage error={query.error} />;\n\n return (\n <div className=\"sfa-shipping\">\n <h2>{copy.title}</h2>\n {removedAny ? (\n <Notice variant=\"warning\">{copy.removalWarning}</Notice>\n ) : null}\n {mixedCurrency ? (\n <Notice variant=\"warning\">\n {fill(copy.mixedCurrency, { currency })}\n </Notice>\n ) : null}\n {blocked ? <Notice variant=\"error\">{copy.noActive}</Notice> : null}\n <ErrorMessage error={save.error} />\n {saved ? <Notice variant=\"success\">{copy.saved}</Notice> : null}\n {dirty ? <p className=\"sfa-field__help\">{copy.unsaved}</p> : null}\n {drafts.length === 0 ? <p>{copy.empty}</p> : null}\n <ul className=\"sfa-rates\">\n {drafts.map((draft, index) => (\n <ShippingRateRow\n key={draft.key}\n draft={draft}\n index={index}\n total={drafts.length}\n errors={{ ...serverErrors[draft.key], ...rowErrors[draft.key] }}\n disabled={save.pending}\n labels={copy}\n onChange={(change) => patch(draft.key, change)}\n onMove={(direction) => move(index, direction)}\n onRemove={() => setRemoving(draft)}\n />\n ))}\n </ul>\n <div className=\"sfa-shipping__actions\">\n <button type=\"button\" className=\"sfa-btn\" onClick={add}>\n {copy.add}\n </button>\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={save.pending}\n onClick={submit}\n >\n {copy.save}\n </button>\n </div>\n <ConfirmDialog\n open={removing !== null}\n title={copy.removeTitle}\n destructive\n confirmLabel={copy.remove}\n onConfirm={confirmRemove}\n onCancel={() => setRemoving(null)}\n >\n <p>{copy.removeBody}</p>\n </ConfirmDialog>\n </div>\n );\n}\n","import type { Discount, DiscountStatus } from '@develemit/commerce-contracts';\n\ntype StatusFields = Pick<Discount, 'active' | 'startsAt' | 'endsAt'>;\n\nexport function displayDiscountStatus(\n discount: StatusFields,\n now: Date = new Date(),\n): DiscountStatus {\n if (!discount.active) return 'inactive';\n if (discount.startsAt && new Date(discount.startsAt) > now) {\n return 'scheduled';\n }\n if (discount.endsAt && new Date(discount.endsAt) <= now) return 'expired';\n return 'active';\n}\n\nexport function fillTemplate(\n template: string,\n values: Record<string, string | number>,\n): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, key: string) =>\n key in values ? String(values[key]) : match,\n );\n}\n","import { useState } from 'react';\nimport type {\n AdminDiscountPage,\n Discount,\n} from '@develemit/commerce-contracts';\nimport type { AdminDiscountQuery } from '../client/admin-client';\nimport { useAdminClient } from './provider';\nimport { useAdminMutation } from './use-admin-mutation';\nimport { useAdminQuery } from './use-admin-query';\n\ninterface Appended {\n base: AdminDiscountPage;\n items: Discount[];\n nextCursor: string | null;\n}\n\nexport function useDiscountPages(query: Omit<AdminDiscountQuery, 'cursor'>) {\n const client = useAdminClient();\n const first = useAdminQuery(['admin-discounts', query], () =>\n client.listDiscounts(query),\n );\n const [appended, setAppended] = useState<Appended | null>(null);\n const more = useAdminMutation(\n async (cursor: string, base: AdminDiscountPage) => {\n const page = await client.listDiscounts({ ...query, cursor });\n setAppended((prev) => ({\n base,\n items: [...(prev?.base === base ? prev.items : []), ...page.items],\n nextCursor: page.nextCursor,\n }));\n },\n );\n\n const base = first.data;\n const extra = appended && appended.base === base ? appended : null;\n const nextCursor = extra ? extra.nextCursor : (base?.nextCursor ?? null);\n return {\n items: [...(base?.items ?? []), ...(extra?.items ?? [])],\n loaded: base !== undefined,\n loading: first.loading,\n error: first.error ?? more.error,\n hasMore: !first.loading && nextCursor !== null,\n loadingMore: more.pending,\n reload: first.reload,\n loadMore: () => {\n if (base && nextCursor) void more.run(nextCursor, base);\n },\n };\n}\n","import type { Discount } from '@develemit/commerce-contracts';\nimport { Money } from '../../components/money/money';\n\nexport function DiscountValue({ discount }: { discount: Discount }) {\n if (discount.type === 'percent') return <span>{discount.percentOff}%</span>;\n return (\n <Money\n cents={discount.amountOffCents ?? 0}\n currency={discount.currency ?? 'USD'}\n />\n );\n}\n","import { useState } from 'react';\nimport type { Discount } from '@develemit/commerce-contracts';\nimport {\n AdminTable,\n type AdminColumn,\n} from '../../components/admin-table/admin-table';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { StatusBadge } from '../../components/status-badge/status-badge';\nimport type { DiscountTab } from '../../lib/discount-labels';\nimport { displayDiscountStatus, fillTemplate } from '../../lib/discount-status';\nimport { useAdmin } from '../../lib/provider';\nimport { useDebounced } from '../../lib/use-debounced';\nimport { useDiscountPages } from '../../lib/use-discount-pages';\nimport { DiscountValue } from './discount-value';\n\nconst TABS: DiscountTab[] = ['active', 'scheduled', 'expired', 'inactive'];\n\nexport function AdminDiscountList() {\n const { labels, hrefs, renderLink } = useAdmin();\n const copy = labels.discounts;\n const [tab, setTab] = useState<DiscountTab>('active');\n const [search, setSearch] = useState('');\n const q = useDebounced(search.trim(), 300);\n const pages = useDiscountPages({ status: tab, ...(q ? { q } : {}) });\n\n const usage = (d: Discount) => {\n const used = d.redeemedCount + d.reservedCount;\n return d.maxRedemptions\n ? fillTemplate(copy.usage, { used, max: d.maxRedemptions })\n : fillTemplate(copy.usageUnlimited, { used });\n };\n\n const columns: AdminColumn<Discount>[] = [\n {\n key: 'code',\n header: copy.columns.code,\n render: (d) =>\n renderLink({\n href: hrefs.discount(d.id),\n children: d.code,\n className: 'sfa-link--tap',\n }),\n },\n {\n key: 'value',\n header: copy.columns.value,\n render: (d) => <DiscountValue discount={d} />,\n },\n {\n key: 'status',\n header: copy.columns.status,\n render: (d) => <StatusBadge status={displayDiscountStatus(d)} />,\n },\n { key: 'usage', header: copy.columns.usage, render: usage },\n ];\n\n return (\n <section className=\"sfa-products\">\n <header className=\"sfa-products__header\">\n <h1>{copy.title}</h1>\n {renderLink({\n href: hrefs.newDiscount,\n children: copy.newDiscount,\n className: 'sfa-btn sfa-btn--primary',\n })}\n </header>\n <div className=\"sfa-products__toolbar\">\n <div\n role=\"group\"\n aria-label={copy.columns.status}\n className=\"sfa-filter-group\"\n >\n {TABS.map((value) => (\n <button\n key={value}\n type=\"button\"\n className=\"sfa-btn sfa-filter\"\n aria-pressed={tab === value}\n onClick={() => setTab(value)}\n >\n {copy.tabs[value]}\n </button>\n ))}\n </div>\n <input\n type=\"search\"\n aria-label={copy.searchLabel}\n placeholder={copy.searchPlaceholder}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n <ErrorMessage error={pages.error} />\n {pages.loading && !pages.loaded ? (\n <p>{labels.loading}</p>\n ) : pages.items.length === 0 ? (\n <p className=\"sfa-empty\">{q ? copy.noMatches : copy.empty[tab]}</p>\n ) : (\n <AdminTable columns={columns} rows={pages.items} rowKey={(d) => d.id} />\n )}\n {pages.hasMore ? (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-products__more\"\n disabled={pages.loadingMore}\n onClick={pages.loadMore}\n >\n {copy.loadMore}\n </button>\n ) : null}\n </section>\n );\n}\n","import type {\n Discount,\n DiscountInput,\n DiscountPatch,\n DiscountType,\n} from '@develemit/commerce-contracts';\nimport type { DiscountLabels } from './discount-labels';\nimport { formatMoneyInput, parseMoneyInput } from './money-input';\n\nexport interface DiscountForm {\n code: string;\n type: DiscountType;\n percentOff: string;\n amountOff: string;\n minSubtotal: string;\n startsAt: string;\n endsAt: string;\n maxRedemptions: string;\n}\n\nexport type DiscountFieldName = keyof DiscountForm;\nexport type DiscountFieldErrors = Partial<Record<DiscountFieldName, string>>;\n\nexport const emptyDiscountForm: DiscountForm = {\n code: '',\n type: 'percent',\n percentOff: '',\n amountOff: '',\n minSubtotal: '',\n startsAt: '',\n endsAt: '',\n maxRedemptions: '',\n};\n\nconst pad = (n: number) => String(n).padStart(2, '0');\n\nexport function isoToLocalInput(iso: string | null | undefined): string {\n if (!iso) return '';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n\nfunction localInputToIso(value: string): string | null {\n if (value.trim() === '') return null;\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d.toISOString();\n}\n\nexport function formFromDiscount(discount: Discount): DiscountForm {\n return {\n code: discount.code,\n type: discount.type,\n percentOff: discount.percentOff ? String(discount.percentOff) : '',\n amountOff: discount.amountOffCents\n ? formatMoneyInput(discount.amountOffCents)\n : '',\n minSubtotal: discount.minSubtotalCents\n ? formatMoneyInput(discount.minSubtotalCents)\n : '',\n startsAt: isoToLocalInput(discount.startsAt),\n endsAt: isoToLocalInput(discount.endsAt),\n maxRedemptions: discount.maxRedemptions\n ? String(discount.maxRedemptions)\n : '',\n };\n}\n\nexport function isDiscountUsed(discount: Discount | undefined): boolean {\n return Boolean(\n discount && discount.redeemedCount + discount.reservedCount > 0,\n );\n}\n\nexport type DiscountValidation =\n | { ok: true; input: DiscountInput }\n | { ok: false; errors: DiscountFieldErrors };\n\nconst positiveInt = (text: string): number | null =>\n /^\\d+$/.test(text.trim()) && Number(text) > 0 ? Number(text) : null;\n\nexport function validateDiscountForm(\n form: DiscountForm,\n labels: DiscountLabels,\n currency: string,\n usedCount = 0,\n): DiscountValidation {\n const v = labels.validation;\n const errors: DiscountFieldErrors = {};\n const code = form.code.trim().toUpperCase();\n if (!/^[A-Z0-9_-]{1,40}$/.test(code)) errors.code = v.code;\n\n const percentOff = positiveInt(form.percentOff);\n const amountOffCents = parseMoneyInput(form.amountOff);\n if (form.type === 'percent' && (percentOff === null || percentOff > 100)) {\n errors.percentOff = v.percentOff;\n }\n if (form.type === 'fixed' && !amountOffCents) errors.amountOff = v.amountOff;\n\n const minText = form.minSubtotal.trim();\n const minSubtotalCents = minText === '' ? null : parseMoneyInput(minText);\n if (minText !== '' && !minSubtotalCents) errors.minSubtotal = v.minSubtotal;\n\n const limitText = form.maxRedemptions.trim();\n const maxRedemptions = limitText === '' ? null : positiveInt(limitText);\n if (limitText !== '' && maxRedemptions === null) {\n errors.maxRedemptions = v.maxRedemptions;\n } else if (maxRedemptions !== null && maxRedemptions < usedCount) {\n errors.maxRedemptions = v.maxRedemptionsBelowUsage;\n }\n\n const startsAt = localInputToIso(form.startsAt);\n const endsAt = localInputToIso(form.endsAt);\n if (form.startsAt.trim() !== '' && !startsAt) errors.startsAt = v.date;\n if (form.endsAt.trim() !== '' && !endsAt) errors.endsAt = v.date;\n if (startsAt && endsAt && new Date(endsAt) <= new Date(startsAt)) {\n errors.endsAt = v.endsBeforeStart;\n }\n\n if (Object.keys(errors).length > 0) return { ok: false, errors };\n return {\n ok: true,\n input: {\n code,\n type: form.type,\n percentOff: form.type === 'percent' ? percentOff : null,\n amountOffCents: form.type === 'fixed' ? amountOffCents : null,\n currency: form.type === 'fixed' ? currency : null,\n minSubtotalCents,\n startsAt,\n endsAt,\n maxRedemptions,\n active: true,\n },\n };\n}\n\nconst VALUE_KEYS = [\n 'type',\n 'percentOff',\n 'amountOffCents',\n 'currency',\n] as const;\nconst LIMIT_KEYS = [\n 'minSubtotalCents',\n 'startsAt',\n 'endsAt',\n 'maxRedemptions',\n] as const;\n\nexport function buildDiscountPatch(\n original: Discount,\n input: DiscountInput,\n locked: boolean,\n): DiscountPatch {\n const patch: Record<string, unknown> = {};\n const next = input as Record<string, unknown>;\n const prev = original as unknown as Record<string, unknown>;\n const differs = (key: string) => (next[key] ?? null) !== (prev[key] ?? null);\n for (const key of LIMIT_KEYS) if (differs(key)) patch[key] = next[key];\n if (locked) return patch as DiscountPatch;\n if (differs('code')) patch.code = input.code;\n if (VALUE_KEYS.some(differs)) {\n for (const key of VALUE_KEYS) patch[key] = next[key];\n }\n return patch as DiscountPatch;\n}\n\nexport function mapDiscountIssues(\n issues: unknown[],\n message: string,\n): DiscountFieldErrors {\n const names: Record<string, DiscountFieldName> = {\n code: 'code',\n percentOff: 'percentOff',\n amountOffCents: 'amountOff',\n minSubtotalCents: 'minSubtotal',\n startsAt: 'startsAt',\n endsAt: 'endsAt',\n maxRedemptions: 'maxRedemptions',\n };\n const errors: DiscountFieldErrors = {};\n for (const issue of issues) {\n const head = (issue as { path?: unknown[] } | null)?.path?.[0];\n const field = typeof head === 'string' ? names[head] : undefined;\n if (field && !errors[field]) errors[field] = message;\n }\n return errors;\n}\n","import type { ReactNode } from 'react';\nimport type { DiscountType } from '@develemit/commerce-contracts';\nimport type {\n DiscountFieldErrors,\n DiscountFieldName,\n DiscountForm,\n} from '../../lib/discount-form';\nimport type { DiscountLabels } from '../../lib/discount-labels';\nimport { fillTemplate } from '../../lib/discount-status';\n\ninterface ControlProps {\n id: string;\n name: DiscountFieldName;\n disabled: boolean;\n 'aria-invalid': boolean;\n 'aria-describedby'?: string;\n}\n\ninterface ShellProps {\n name: DiscountFieldName;\n label: string;\n error?: string;\n help?: string;\n disabled?: boolean;\n children: (props: ControlProps) => ReactNode;\n}\n\nfunction Shell({ name, label, error, help, disabled, children }: ShellProps) {\n const id = `sfa-field-${name}`;\n const described = [help ? `${id}-help` : '', error ? `${id}-error` : '']\n .filter(Boolean)\n .join(' ');\n return (\n <div className=\"sfa-field\">\n <label htmlFor={id} className=\"sfa-field__label\">\n {label}\n </label>\n {children({\n id,\n name,\n disabled: Boolean(disabled),\n 'aria-invalid': Boolean(error),\n 'aria-describedby': described || undefined,\n })}\n {help ? (\n <p id={`${id}-help`} className=\"sfa-field__help\">\n {help}\n </p>\n ) : null}\n {error ? (\n <p id={`${id}-error`} className=\"sfa-field__error\">\n {error}\n </p>\n ) : null}\n </div>\n );\n}\n\nexport interface DiscountFieldsProps {\n form: DiscountForm;\n errors: DiscountFieldErrors;\n labels: DiscountLabels;\n usedCount: number;\n onChange: <K extends keyof DiscountForm>(\n field: K,\n value: DiscountForm[K],\n ) => void;\n}\n\nconst TYPES: DiscountType[] = ['percent', 'fixed'];\n\nexport function DiscountFields({\n form,\n errors,\n labels,\n usedCount,\n onChange,\n}: DiscountFieldsProps) {\n const locked = usedCount > 0;\n const lockedHelp = locked\n ? fillTemplate(labels.lockedHelp, { count: usedCount })\n : undefined;\n const text = (\n name: DiscountFieldName,\n label: string,\n extra: {\n help?: string;\n locked?: boolean;\n inputMode?: 'decimal' | 'numeric';\n } = {},\n ) => (\n <Shell\n name={name}\n label={label}\n error={errors[name]}\n help={extra.help}\n disabled={extra.locked}\n >\n {(props) => (\n <input\n {...props}\n type=\"text\"\n inputMode={extra.inputMode}\n value={form[name]}\n onChange={(e) => onChange(name, e.target.value)}\n />\n )}\n </Shell>\n );\n const date = (name: 'startsAt' | 'endsAt') => (\n <Shell\n name={name}\n label={labels.fields[name]}\n error={errors[name]}\n help={labels.optionalHelp}\n >\n {(props) => (\n <input\n {...props}\n type=\"datetime-local\"\n value={form[name]}\n onChange={(e) => onChange(name, e.target.value)}\n />\n )}\n </Shell>\n );\n return (\n <>\n {text('code', labels.fields.code, { help: lockedHelp, locked })}\n <Shell name=\"type\" label={labels.fields.type} disabled={locked}>\n {(props) => (\n <select\n {...props}\n value={form.type}\n onChange={(e) => onChange('type', e.target.value as DiscountType)}\n >\n {TYPES.map((type) => (\n <option key={type} value={type}>\n {labels.types[type]}\n </option>\n ))}\n </select>\n )}\n </Shell>\n {form.type === 'percent'\n ? text('percentOff', labels.fields.percentOff, {\n locked,\n inputMode: 'numeric',\n })\n : text('amountOff', labels.fields.amountOff, {\n locked,\n inputMode: 'decimal',\n })}\n {text('minSubtotal', labels.fields.minSubtotal, {\n help: labels.optionalHelp,\n inputMode: 'decimal',\n })}\n {date('startsAt')}\n {date('endsAt')}\n {text('maxRedemptions', labels.fields.maxRedemptions, {\n help: labels.optionalHelp,\n inputMode: 'numeric',\n })}\n </>\n );\n}\n","import { useState, type FormEvent } from 'react';\nimport type { Discount } from '@develemit/commerce-contracts';\nimport { AdminInvalidInputError, DiscountCodeTakenError } from '../../client';\nimport { ConfirmDialog } from '../../components/confirm-dialog/confirm-dialog';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Notice } from '../../components/notice/notice';\nimport {\n buildDiscountPatch,\n emptyDiscountForm,\n formFromDiscount,\n isDiscountUsed,\n mapDiscountIssues,\n validateDiscountForm,\n type DiscountFieldErrors,\n type DiscountForm,\n} from '../../lib/discount-form';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useAdminMutation } from '../../lib/use-admin-mutation';\nimport { useAdminQuery } from '../../lib/use-admin-query';\nimport { DiscountFields } from './discount-fields';\n\nexport interface AdminDiscountEditorProps {\n discountId?: string;\n onSaved?: (discount: Discount) => void;\n}\n\nexport function AdminDiscountEditor({\n discountId,\n onSaved,\n}: AdminDiscountEditorProps) {\n if (!discountId)\n return <DiscountFormView discount={undefined} onSaved={onSaved} />;\n return <ExistingDiscountEditor discountId={discountId} onSaved={onSaved} />;\n}\n\nfunction ExistingDiscountEditor({\n discountId,\n onSaved,\n}: AdminDiscountEditorProps & { discountId: string }) {\n const client = useAdminClient();\n const { labels } = useAdmin();\n const query = useAdminQuery(['admin-discount', discountId], () =>\n client.getDiscount(discountId),\n );\n if (query.error) return <ErrorMessage error={query.error} />;\n if (!query.data) return <p>{labels.loading}</p>;\n return (\n <DiscountFormView\n key={query.data.id}\n discount={query.data}\n onSaved={onSaved}\n />\n );\n}\n\ninterface FormViewProps {\n discount: Discount | undefined;\n onSaved?: (discount: Discount) => void;\n}\n\nfunction DiscountFormView({ discount, onSaved }: FormViewProps) {\n const client = useAdminClient();\n const { labels, currency } = useAdmin();\n const copy = labels.discounts;\n const [base, setBase] = useState(discount);\n const [form, setForm] = useState<DiscountForm>(\n discount ? formFromDiscount(discount) : emptyDiscountForm,\n );\n const [fieldErrors, setFieldErrors] = useState<DiscountFieldErrors>({});\n const [saved, setSaved] = useState(false);\n const [confirming, setConfirming] = useState(false);\n const usedCount = base ? base.redeemedCount + base.reservedCount : 0;\n const locked = isDiscountUsed(base);\n\n const showErrors = (formEl: HTMLFormElement, found: DiscountFieldErrors) => {\n setFieldErrors(found);\n const name = Object.keys(found)[0];\n if (name) (formEl.elements.namedItem(name) as HTMLElement | null)?.focus();\n };\n\n const save = useAdminMutation(\n async (formEl: HTMLFormElement): Promise<Discount | undefined> => {\n const result = validateDiscountForm(\n form,\n copy,\n base?.currency ?? currency,\n usedCount,\n );\n if (!result.ok) {\n showErrors(formEl, result.errors);\n return undefined;\n }\n try {\n if (!base) return await client.createDiscount(result.input);\n const patch = buildDiscountPatch(base, result.input, locked);\n return Object.keys(patch).length === 0\n ? base\n : await client.updateDiscount(base.id, patch);\n } catch (error) {\n if (error instanceof DiscountCodeTakenError) {\n showErrors(formEl, { code: copy.validation.codeTaken });\n return undefined;\n }\n if (!(error instanceof AdminInvalidInputError)) throw error;\n showErrors(\n formEl,\n mapDiscountIssues(error.issues, copy.validation.invalid),\n );\n return undefined;\n }\n },\n );\n\n const toggleActive = useAdminMutation((active: boolean) => {\n if (!base) throw new Error('Discount has not been created yet.');\n return client.updateDiscount(base.id, { active });\n });\n\n const adopt = (result: Discount) => {\n setBase(result);\n setForm(formFromDiscount(result));\n setSaved(true);\n onSaved?.(result);\n };\n\n const onChange: Parameters<typeof DiscountFields>[0]['onChange'] = (\n field,\n value,\n ) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n setFieldErrors((prev) => ({ ...prev, [field]: undefined }));\n };\n\n const onSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setSaved(false);\n setFieldErrors({});\n save.reset();\n const result = await save.run(event.currentTarget);\n if (result) adopt(result);\n };\n\n const setActive = async (active: boolean) => {\n setConfirming(false);\n setSaved(false);\n const result = await toggleActive.run(active);\n if (result) adopt(result);\n };\n\n return (\n <form noValidate className=\"sfa-form\" onSubmit={onSubmit}>\n <h1>{base ? copy.editTitle : copy.createTitle}</h1>\n <ErrorMessage error={save.error ?? toggleActive.error} />\n <DiscountFields\n form={form}\n errors={fieldErrors}\n labels={copy}\n usedCount={usedCount}\n onChange={onChange}\n />\n <div className=\"sfa-row-actions\">\n <button\n type=\"submit\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={save.pending}\n >\n {labels.save}\n </button>\n {base?.active ? (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n onClick={() => setConfirming(true)}\n >\n {copy.deactivate}\n </button>\n ) : null}\n {base && !base.active ? (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n disabled={toggleActive.pending}\n onClick={() => setActive(true)}\n >\n {copy.reactivate}\n </button>\n ) : null}\n </div>\n <ConfirmDialog\n open={confirming}\n title={copy.deactivateTitle}\n confirmLabel={copy.deactivate}\n destructive\n pending={toggleActive.pending}\n onConfirm={() => setActive(false)}\n onCancel={() => setConfirming(false)}\n >\n <p>{copy.deactivateBody}</p>\n </ConfirmDialog>\n {saved ? (\n <Notice variant=\"success\" toast onDismiss={() => setSaved(false)}>\n {copy.saved}\n </Notice>\n ) : null}\n </form>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","_Fragment","_Fragment","_Fragment","_Fragment","_Fragment","_Fragment","_Fragment","_Fragment","_Fragment","_Fragment","_Fragment","_Fragment","TABS","_Fragment","_Fragment","_Fragment","_Fragment","AdminUnauthorizedError","ImageTooLargeError","InvalidOrderStateError","MaxRedemptionsBelowUsageError","RefundOutcomeUnknownError","RefundGatewayError","AdminNotFoundError","InsufficientStockError","RefundExceedsBalanceError","DiscountCodeTakenError","ProductIncompleteError","AdminInvalidInputError","DiscountInUseError","InvalidImageError","defaultOrderLabels","defaultShippingLabels","defaultDiscountLabels","defaultStockLabels","defaultImageLabels","PRODUCT_FLOW_STEPS","defaultProductLabels","defaultAdminLabels","mergeOrderLabels","base","overrides","mergeProductLabels","mergeDiscountLabels","mergeAdminLabels","labels","defaults","priority","id","AdminContext","createContext","AdminProvider","value","hrefs","useAdmin","useContext","useAdminClient","client","useAdminQuery","fnRef","useRef","fn","reloadCount","setReloadCount","useState","settled","setSettled","request","key","controller","prev","reload","useCallback","n","current","useAdminMutation","pending","setPending","error","setError","args","err","icon","path","adminNavIcons","Fragment","hasBadge","badge","buildNavItems","kit","badges","extra","item","extraNav","i","splitForTabBar","items","useMoreSheet","open","setOpen","close","toggle","o","useEffect","onKey","event","AdminLayout","sheetId","useId","more","navBadges","link","renderLink","header","footer","bar","overflow","AdminPageHeader","title","actions","floatingAction","children","AdminTable","rows","caption","columns","c","row","rowKey","StatusBadge","status","Money","text","locale","cents","FOCUSABLE","useFocusTrap","active","trigger","ref","onDocumentKey","onEscape","focusable","first","last","ConfirmDialog","panelRef","onKeyDown","onCancel","destructive","onConfirm","confirmLabel","Notice","toast","onDismiss","timer","duration","role","variant","className","action","KEYED","errorKey","type","ErrorMessage","missingDetail","product","copy","fillCount","template","values","StepBody","detail","step","Step","actionable","content","AdminSetupChecklist","done","steps","s","progress","showList","compact","v","isSold","displayStatus","serverStatus","filter","serverStock","useDebounced","debounced","setDebounced","delayMs","usePagedList","fetchPage","appended","setAppended","page","cursor","nextCursor","useProductPages","query","isDraftComplete","primaryKind","primaryChange","kind","hideChange","archiveChange","featureChange","canFeature","SheetCarousel","index","setIndex","total","image","by","renderImage","useProductChange","notice","setNotice","mutation","patch","apply","next","change","setProduct","onChanged","undo","missing","hrefWithStep","href","finishStep","SheetEditLink","onEdit","AdminProductSheet","productId","override","setOverride","SheetFrame","SheetBody","LoadingBody","onClose","change0","edit","copyLink","f","ProductCard","cover","nameLink","onOpen","face","FILTERS","chipCount","counts","ProductToolbar","onFilter","search","onSearch","DefaultArt","ProductWelcome","art","onAddMany","AdminProductList","setFilter","setSearch","q","stock","pages","openId","setOpenId","refresh","totals","shopEmpty","waiting","emptyText","drafts","addButton","welcome","setup","onFinishDrafts","p","onOpenProduct","onEditProduct","Switch","label","onChange","MONEY","parseMoneyInput","raw","match","whole","fraction","formatMoneyInput","blankToNull","trimmed","wholeNumber","savableFields","name","form","category","priceCents","quantity","hasDraftContent","draftInput","currency","draftPatch","basicsReady","splitMaterials","part","toggleMaterial","list","material","appendPrompt","description","prompt","currencySymbol","fillText","categoryChoices","categories","BasicsSection","fields","choices","custom","setCustom","oneOfAKind","setOneOfAKind","update","choice","checked","nextStep","previousStep","FinishActions","flow","StepActions","goNext","hasPhotos","FlowHead","canGoBack","onBack","StepBar","allOpen","onStep","SaveNote","state","onRetry","isNew","FlowSectionFrame","sortedImages","a","b","FlowSuccessView","success","onAddAnother","onDone","ACCEPTED_TYPES","fill","imageFileProblem","file","useImageUpload","entries","setEntries","nextId","chain","onUploadedRef","onUploaded","target","currentId","resolve","entry","drop","send","alt","added","files","reason","PhotosSection","failure","setFailure","busy","setBusy","images","ensureProduct","imagesSlot","pick","upload","work","makeCover","imageId","UploadTile","dismiss","PreviewSection","missingCopy","StorySection","prompts","picked","materialSuggestions","AltField","setValue","emptyForm","formFromProduct","useProductAutosave","setProductState","initial","setState","productRef","formRef","initialForm","write","force","queue","flush","useProductFlow","setForm","setStep","initialStep","autosave","setMissing","setSuccess","closing","setClosing","field","fillBlankAlts","sorted","run","finish","saved","saveDraft","publish","wasDraft","live","isFirstProduct","AdminProductFlow","session","setSession","props","addAnother","ExistingProductFlow","FlowView","defaultCurrency","section","rootRef","firstRender","scroll","back","previous","stepFromUrl","noSubscription","AdminProductEditor","urlStep","useSyncExternalStore","onSaved","ImageAltEditor","draft","setDraft","saving","setSaving","onSave","ImageTile","move","direction","onMove","onSaveAlt","onRemove","UploadPicker","onFiles","byPosition","AdminProductImages","setImages","busyId","setBusyId","reordering","setReordering","setAlt","reorderFailed","setReorderFailed","removing","setRemoving","focusTarget","listRef","find","other","to","confirmRemove","saveAlt","nextAlt","PATHS","EmptyState","body","useOrderPages","TABS$1","tabQuery","tab","AdminOrderList","setTab","date","pendingRefundCents","order","r","sum","remainingRefundCents","hasPendingRefund","canRestock","amountCents","canShip","canRefund","RefundDialog","keyRef","remaining","amount","setAmount","setReason","restock","setRestock","invalid","setInvalid","refund","amountValid","restockOffered","retryable","ResolveButton","submit","stockError","names","isHttpUrl","protocol","ShipForm","carrier","setCarrier","trackingNumber","setTrackingNumber","trackingUrl","setTrackingUrl","urlError","setUrlError","ship","reship","url","OrderActions","refunding","setRefunding","message","setMessage","OrderFulfillment","OrderItems","OrderRefunds","addressLines","region","l","AdminOrderDetail","orderId","lines","counter","newKey","toDrafts","rates","rate","blankDraft","snapshot","_key","rest","parseDays","checkDrafts","rowErrors","seen","errors","min","max","parsed","shippingRatesInputSchema","issue","noActive","SERVER_FIELDS","serverRowErrors","result","issues","at","segment","ShippingRateRow","fieldId","disabled","AdminShippingRates","setDrafts","baseline","setBaseline","loaded","setLoaded","setRowErrors","blocked","setBlocked","setSaved","removedAny","setRemovedAny","save","lastDirty","dirty","onDirtyChange","d","_cleared","add","addSuggested","check","mixedCurrency","serverErrors","suggestedRates","displayDiscountStatus","discount","now","fillTemplate","useDiscountPages","DiscountValue","TABS","AdminDiscountList","used","emptyDiscountForm","pad","isoToLocalInput","iso","localInputToIso","formFromDiscount","isDiscountUsed","positiveInt","validateDiscountForm","code","percentOff","amountOffCents","minText","minSubtotalCents","limitText","maxRedemptions","usedCount","startsAt","endsAt","VALUE_KEYS","LIMIT_KEYS","buildDiscountPatch","input","original","differs","locked","mapDiscountIssues","head","Shell","described","help","TYPES","DiscountFields","lockedHelp","AdminDiscountEditor","discountId","ExistingDiscountEditor","DiscountFormView","setBase","fieldErrors","setFieldErrors","confirming","setConfirming","showErrors","found","formEl","toggleActive","adopt","onSubmit","setActive","useBatchUpload","setItems","sendOne","drain","retry","failed","PhotoPicker","primary","FailedList","AdminAddSeveral","batch","finished","PieceFields","PieceCard","advance","onAdvance","isReady","piece","PieceSummary","ready","pieces","onKeepDrafts","onPublish","usePublishPieces","outcome","setOutcome","published","Queue","setPieces","publisher","AdminFinishDrafts","productIds"],"sources":["../src/lib/order-action-labels.ts","../src/lib/order-labels.ts","../src/lib/shipping-labels.ts","../src/lib/discount-labels.ts","../src/lib/stock-labels.ts","../src/lib/image-labels.ts","../src/lib/product-flow-labels.ts","../src/lib/product-labels.ts","../src/lib/admin-labels.ts","../src/lib/merge-labels.ts","../src/lib/provider.tsx","../src/lib/use-admin-query.ts","../src/lib/use-admin-mutation.ts","../src/components/admin-layout/nav-icons.tsx","../src/components/admin-layout/nav-items.ts","../src/components/admin-layout/use-more-sheet.ts","../src/components/admin-layout/admin-layout.tsx","../src/components/page-header/admin-page-header.tsx","../src/components/admin-table/admin-table.tsx","../src/components/status-badge/status-badge.tsx","../src/components/money/money.tsx","../src/lib/use-focus-trap.ts","../src/components/confirm-dialog/confirm-dialog.tsx","../src/components/notice/notice.tsx","../src/components/error-message/error-message.tsx","../src/lib/product-missing.ts","../src/components/setup-checklist/setup-checklist.tsx","../src/lib/product-filter.ts","../src/lib/use-debounced.ts","../src/lib/use-paged-list.ts","../src/lib/use-product-pages.ts","../src/lib/product-sheet-actions.ts","../src/views/products/product-sheet/sheet-carousel.tsx","../src/views/products/product-sheet/use-product-change.ts","../src/views/products/product-sheet/sheet-edit-link.tsx","../src/views/products/product-sheet/admin-product-sheet.tsx","../src/views/products/product-card.tsx","../src/views/products/product-toolbar.tsx","../src/views/products/product-welcome.tsx","../src/views/products/admin-product-list.tsx","../src/components/switch/switch.tsx","../src/lib/money-input.ts","../src/lib/product-draft.ts","../src/views/products/product-flow/basics-section.tsx","../src/views/products/product-flow/flow-actions.tsx","../src/views/products/product-flow/flow-frame.tsx","../src/views/products/product-flow/flow-images.ts","../src/views/products/product-flow/flow-success.tsx","../src/lib/image-rules.ts","../src/lib/use-image-upload.ts","../src/views/products/product-flow/photos-section.tsx","../src/views/products/product-flow/preview-section.tsx","../src/views/products/product-flow/story-section.tsx","../src/lib/product-form.ts","../src/lib/use-product-autosave.ts","../src/views/products/product-flow/use-product-flow.ts","../src/views/products/product-flow/admin-product-flow.tsx","../src/views/products/admin-product-editor.tsx","../src/views/products/image-alt-editor.tsx","../src/views/products/image-tile.tsx","../src/views/products/upload-picker.tsx","../src/views/products/admin-product-images.tsx","../src/components/empty-state/empty-state.tsx","../src/lib/use-order-pages.ts","../src/views/orders/admin-order-list.tsx","../src/lib/refund-rules.ts","../src/views/orders/refund-dialog.tsx","../src/views/orders/resolve-button.tsx","../src/views/orders/ship-form.tsx","../src/views/orders/order-actions.tsx","../src/views/orders/order-fulfillment.tsx","../src/views/orders/order-items.tsx","../src/views/orders/order-refunds.tsx","../src/views/orders/admin-order-detail.tsx","../src/lib/shipping-rates.ts","../src/views/shipping/shipping-rate-row.tsx","../src/views/shipping/admin-shipping-rates.tsx","../src/lib/discount-status.ts","../src/lib/use-discount-pages.ts","../src/views/discounts/discount-value.tsx","../src/views/discounts/admin-discount-list.tsx","../src/lib/discount-form.ts","../src/views/discounts/discount-fields.tsx","../src/views/discounts/admin-discount-editor.tsx","../src/lib/use-batch-upload.ts","../src/views/products/add-several/photo-picker.tsx","../src/views/products/add-several/admin-add-several.tsx","../src/views/products/finish-drafts/piece-fields.tsx","../src/views/products/finish-drafts/piece-card.tsx","../src/views/products/finish-drafts/piece-summary.tsx","../src/lib/fill-alts.ts","../src/views/products/finish-drafts/use-publish-pieces.ts","../src/views/products/finish-drafts/admin-finish-drafts.tsx"],"sourcesContent":["export interface OrderActionLabels {\n ship: string;\n reship: string;\n shipHeading: string;\n carrier: string;\n trackingNumber: string;\n trackingUrl: string;\n trackingUrlInvalid: string;\n shipped: string;\n refund: string;\n refundTitle: string;\n refundAmount: string;\n refundAmountInvalid: string;\n refundReason: string;\n refundSubmit: string;\n refundRetry: string;\n restock: string;\n restockWarning: string;\n refundPending: string;\n refundUnknown: string;\n refundGateway: string;\n refundDone: string;\n resolve: string;\n resolveHelp: string;\n resolved: string;\n restockThenResolve: string;\n}\n\nexport const defaultOrderActionLabels: OrderActionLabels = {\n ship: 'Mark as shipped',\n reship: 'Update tracking',\n shipHeading: 'Shipping',\n carrier: 'Carrier',\n trackingNumber: 'Tracking number',\n trackingUrl: 'Tracking URL',\n trackingUrlInvalid: 'Enter a full link starting with http:// or https://.',\n shipped: 'Shipping details saved.',\n refund: 'Refund…',\n refundTitle: 'Refund order',\n refundAmount: 'Amount',\n refundAmountInvalid:\n 'Enter an amount above zero and no more than the balance.',\n refundReason: 'Reason',\n refundSubmit: 'Refund',\n refundRetry: 'Retry refund',\n restock: 'Restock items',\n restockWarning: 'Only restock if the item came back.',\n refundPending:\n 'A refund is already pending on this order. Wait for it to finish or refresh before refunding again.',\n refundUnknown:\n 'We could not confirm whether this refund went through; it may have succeeded. Retrying is safe, it will not refund twice.',\n refundGateway:\n 'The payment provider rejected the refund. Retrying is safe, it will not refund twice.',\n refundDone: 'Refund sent.',\n resolve: 'Resolve order',\n resolveHelp:\n 'This order was paid but its stock ran out. Restock the items and resolve it, or refund it.',\n resolved: 'Order resolved.',\n restockThenResolve: 'Restock, then resolve',\n};\n","import type { OrderActionLabels } from './order-action-labels';\nimport { defaultOrderActionLabels } from './order-action-labels';\n\nexport type OrderTab =\n 'paid' | 'shipped' | 'needs_attention' | 'pending_refund' | 'all';\n\nexport interface OrderLabels {\n title: string;\n searchLabel: string;\n searchPlaceholder: string;\n tabs: Record<OrderTab, string>;\n empty: Record<OrderTab, string>;\n noMatches: string;\n emptyHint: string;\n loadMore: string;\n columns: {\n order: string;\n status: string;\n email: string;\n items: string;\n total: string;\n date: string;\n };\n noEmail: string;\n detailTitle: string;\n back: string;\n placed: string;\n buyer: string;\n itemsHeading: string;\n itemColumns: { name: string; price: string; quantity: string; line: string };\n subtotal: string;\n shipping: string;\n total: string;\n shippingAddress: string;\n noAddress: string;\n fulfillment: string;\n notShipped: string;\n shippedOn: string;\n carrier: string;\n tracking: string;\n trackShipment: string;\n refunds: string;\n noRefunds: string;\n refundColumns: {\n amount: string;\n reason: string;\n source: string;\n status: string;\n restocked: string;\n date: string;\n };\n refundSources: { admin: string; gateway: string };\n refundStatuses: { pending: string; succeeded: string };\n yes: string;\n no: string;\n refunded: string;\n remaining: string;\n actions: OrderActionLabels;\n}\n\nexport const defaultOrderLabels: OrderLabels = {\n title: 'Orders',\n searchLabel: 'Search orders',\n searchPlaceholder: 'Search by email or order id',\n tabs: {\n paid: 'To ship',\n shipped: 'Shipped',\n needs_attention: 'Needs attention',\n pending_refund: 'Pending refund',\n all: 'All',\n },\n empty: {\n paid: 'Nothing waiting to ship.',\n shipped: 'No shipped orders yet.',\n needs_attention: 'No orders need attention.',\n pending_refund: 'No refunds are pending.',\n all: 'No orders yet.',\n },\n noMatches: 'No orders match that search.',\n emptyHint: 'Orders appear here as soon as a customer checks out.',\n loadMore: 'Load more',\n columns: {\n order: 'Order',\n status: 'Status',\n email: 'Buyer',\n items: 'Items',\n total: 'Total',\n date: 'Placed',\n },\n noEmail: 'No email',\n detailTitle: 'Order',\n back: 'Back to orders',\n placed: 'Placed',\n buyer: 'Buyer',\n itemsHeading: 'Items',\n itemColumns: {\n name: 'Item',\n price: 'Price',\n quantity: 'Qty',\n line: 'Subtotal',\n },\n subtotal: 'Subtotal',\n shipping: 'Shipping',\n total: 'Total',\n shippingAddress: 'Shipping address',\n noAddress: 'No shipping address.',\n fulfillment: 'Fulfillment',\n notShipped: 'Not shipped',\n shippedOn: 'Shipped',\n carrier: 'Carrier',\n tracking: 'Tracking',\n trackShipment: 'Track shipment',\n refunds: 'Refunds',\n noRefunds: 'No refunds.',\n refundColumns: {\n amount: 'Amount',\n reason: 'Reason',\n source: 'Source',\n status: 'Status',\n restocked: 'Restocked',\n date: 'Date',\n },\n refundSources: { admin: 'Admin', gateway: 'Payment provider' },\n refundStatuses: { pending: 'Pending', succeeded: 'Refunded' },\n yes: 'Yes',\n no: 'No',\n refunded: 'Refunded',\n remaining: 'Remaining balance',\n actions: defaultOrderActionLabels,\n};\n","export interface ShippingLabels {\n title: string;\n loading: string;\n emptyTitle: string;\n empty: string;\n addOption: string;\n add: string;\n save: string;\n saved: string;\n label: string;\n amount: string;\n currency: string;\n mixedCurrency: string;\n minDays: string;\n maxDays: string;\n active: string;\n rowName: string;\n moveEarlier: string;\n moveLater: string;\n remove: string;\n removeTitle: string;\n removeBody: string;\n newRateLabel: string;\n removalWarning: string;\n unsaved: string;\n noActive: string;\n labelRequired: string;\n labelDuplicate: string;\n amountInvalid: string;\n currencyInvalid: string;\n daysInvalid: string;\n daysOrder: string;\n rowInvalid: string;\n}\n\nexport const defaultShippingLabels: ShippingLabels = {\n title: 'Shipping rates',\n loading: 'Loading shipping rates…',\n emptyTitle: 'No shipping options yet',\n empty: 'Add one so customers can check out.',\n addOption: 'Add an option',\n add: 'Add a rate',\n save: 'Save changes',\n saved: 'Shipping rates saved.',\n label: 'Name',\n amount: 'Price',\n currency: 'Currency',\n mixedCurrency:\n 'These rates use more than one currency. Checkout needs them to match your shop currency ({currency}).',\n minDays: 'Fastest (days)',\n maxDays: 'Slowest (days)',\n active: 'Offered at checkout',\n rowName: 'Rate {n}',\n moveEarlier: 'Move earlier',\n moveLater: 'Move later',\n remove: 'Remove',\n removeTitle: 'Remove this rate?',\n removeBody:\n 'It disappears from checkout once you save. Past orders are not affected.',\n newRateLabel: 'New rate',\n removalWarning:\n 'Saving replaces all rates. Rates you removed will no longer appear at checkout.',\n unsaved: 'You have unsaved changes.',\n noActive:\n 'Keep at least one rate offered at checkout, or customers cannot pay.',\n labelRequired: 'Give this rate a name.',\n labelDuplicate: 'Another rate already has this name.',\n amountInvalid: 'Enter a price like 5.00.',\n currencyInvalid: 'Use a 3-letter currency code like USD.',\n daysInvalid: 'Use a whole number of days, or leave blank.',\n daysOrder: 'Fastest cannot be more than slowest.',\n rowInvalid: 'These details are not valid.',\n};\n","export type DiscountTab = 'active' | 'scheduled' | 'expired' | 'inactive';\n\nexport interface DiscountLabels {\n title: string;\n newDiscount: string;\n searchLabel: string;\n searchPlaceholder: string;\n tabs: Record<DiscountTab, string>;\n empty: Record<DiscountTab, string>;\n noMatches: string;\n emptyHint: string;\n loadMore: string;\n columns: {\n code: string;\n value: string;\n status: string;\n usage: string;\n };\n usage: string;\n usageUnlimited: string;\n createTitle: string;\n editTitle: string;\n saved: string;\n fields: {\n code: string;\n type: string;\n percentOff: string;\n amountOff: string;\n minSubtotal: string;\n startsAt: string;\n endsAt: string;\n maxRedemptions: string;\n };\n types: { percent: string; fixed: string };\n optionalHelp: string;\n lockedHelp: string;\n deactivate: string;\n deactivateTitle: string;\n deactivateBody: string;\n reactivate: string;\n validation: {\n code: string;\n percentOff: string;\n amountOff: string;\n minSubtotal: string;\n maxRedemptions: string;\n maxRedemptionsBelowUsage: string;\n endsBeforeStart: string;\n date: string;\n codeTaken: string;\n invalid: string;\n };\n orderRow: string;\n}\n\nexport const defaultDiscountLabels: DiscountLabels = {\n title: 'Discounts',\n newDiscount: 'New discount',\n searchLabel: 'Search discounts',\n searchPlaceholder: 'Search by code',\n tabs: {\n active: 'Active',\n scheduled: 'Scheduled',\n expired: 'Expired',\n inactive: 'Inactive',\n },\n empty: {\n active: 'No active discounts.',\n scheduled: 'No scheduled discounts.',\n expired: 'No expired discounts.',\n inactive: 'No inactive discounts.',\n },\n noMatches: 'No discounts match your search.',\n emptyHint: 'A discount code takes a percentage or an amount off an order.',\n loadMore: 'Load more',\n columns: {\n code: 'Code',\n value: 'Discount',\n status: 'Status',\n usage: 'Used',\n },\n usage: '{used} / {max} used',\n usageUnlimited: '{used} used',\n createTitle: 'New discount',\n editTitle: 'Edit discount',\n saved: 'Discount saved.',\n fields: {\n code: 'Code',\n type: 'Type',\n percentOff: 'Percent off',\n amountOff: 'Amount off',\n minSubtotal: 'Minimum subtotal',\n startsAt: 'Starts',\n endsAt: 'Ends',\n maxRedemptions: 'Usage limit',\n },\n types: { percent: 'Percent', fixed: 'Fixed amount' },\n optionalHelp: 'Optional',\n lockedHelp: 'Used on {count} orders; create a new code instead.',\n deactivate: 'Deactivate',\n deactivateTitle: 'Deactivate this discount?',\n deactivateBody:\n 'Buyers can no longer use this code. Past orders keep it. You can reactivate it later.',\n reactivate: 'Reactivate',\n validation: {\n code: 'Use letters, numbers, dashes or underscores (up to 40).',\n percentOff: 'Enter a whole number from 1 to 100.',\n amountOff: 'Enter an amount greater than zero, like 5.00.',\n minSubtotal: 'Enter an amount greater than zero, like 25.00.',\n maxRedemptions: 'Enter a whole number greater than zero.',\n maxRedemptionsBelowUsage: 'The limit cannot be lower than the times used.',\n endsBeforeStart: 'The end must be after the start.',\n date: 'Enter a valid date and time.',\n codeTaken: 'That code is already in use.',\n invalid: 'This value is not valid.',\n },\n orderRow: 'Discount',\n};\n","export interface StockLabels {\n addSeveral: {\n title: string;\n introTitle: string;\n introBody: string;\n choose: string;\n progress: string;\n failedTitle: string;\n retry: string;\n continueWithout: string;\n doneTitle: string;\n doneBody: string;\n next: string;\n };\n queue: {\n title: string;\n pieceOf: string;\n addPhoto: string;\n coverAlt: string;\n skip: string;\n next: string;\n review: string;\n back: string;\n loading: string;\n nothingToFinish: string;\n done: string;\n };\n summary: {\n title: string;\n lede: string;\n needsDetails: string;\n untitled: string;\n publish: string;\n keepDrafts: string;\n stillIncomplete: string;\n publishedTitle: string;\n publishedBody: string;\n allSkipped: string;\n };\n}\n\nexport const defaultStockLabels: StockLabels = {\n addSeveral: {\n title: 'Add several pieces',\n introTitle: 'One photo, one piece',\n introBody:\n 'Choose a stack of photos from your camera roll. Each one becomes a draft, and you name and price them one at a time next.',\n choose: 'Choose photos',\n progress: 'Adding {done} of {total}…',\n failedTitle: '{count} did not upload',\n retry: 'Try again',\n continueWithout: 'Continue without them',\n doneTitle: 'All {count} photos are in',\n doneBody: 'Next, give each piece a name and a price.',\n next: 'Name and price them',\n },\n queue: {\n title: 'Finish your pieces',\n pieceOf: 'Piece {n} of {m}',\n addPhoto: 'Add a photo',\n coverAlt: 'Photo of piece {n}',\n skip: 'Skip for now',\n next: 'Next piece',\n review: 'Review',\n back: 'Back',\n loading: 'Loading your pieces…',\n nothingToFinish: 'Nothing needs finishing. Every draft has its details.',\n done: 'Done',\n },\n summary: {\n title: 'Ready for the shop?',\n lede: 'Pieces with their details can go in the shop now. The rest stay as drafts.',\n needsDetails: 'Needs details',\n untitled: 'Untitled piece',\n publish: 'Put {count} in the shop',\n keepDrafts: 'Keep as drafts',\n stillIncomplete: '{count} could not be published and stay as drafts.',\n publishedTitle: '{count} in the shop',\n publishedBody: 'Customers can see them now.',\n allSkipped: 'None of these are ready yet.',\n },\n};\n","export interface ImageLabels {\n title: string;\n empty: string;\n add: string;\n takePhoto: string;\n dropHint: string;\n altLabel: string;\n altHelp: string;\n altWarning: string;\n cover: string;\n photoName: string;\n editAlt: string;\n saveAlt: string;\n cancelAlt: string;\n moveEarlier: string;\n moveLater: string;\n remove: string;\n removeTitle: string;\n removeBody: string;\n uploading: string;\n working: string;\n tooLarge: string;\n wrongType: string;\n reorderFailed: string;\n dismiss: string;\n}\n\nexport const defaultImageLabels: ImageLabels = {\n title: 'Photos',\n empty: 'Add a photo so this can go live.',\n add: 'Add photos',\n takePhoto: 'Take photo',\n dropHint: 'Drop photos here, or use the buttons.',\n altLabel: 'Photo description',\n altHelp: 'Describe what the photo shows, for people who cannot see it.',\n altWarning: 'No description yet. Add one so everyone can enjoy this photo.',\n cover: 'Cover',\n photoName: 'Photo {n}',\n editAlt: 'Edit description',\n saveAlt: 'Save',\n cancelAlt: 'Cancel',\n moveEarlier: 'Move earlier',\n moveLater: 'Move later',\n remove: 'Remove',\n removeTitle: 'Remove this photo?',\n removeBody: 'It will be deleted from this product.',\n uploading: 'Uploading…',\n working: 'Working…',\n tooLarge: '{name} is larger than 8 MB.',\n wrongType: '{name} must be a JPEG, PNG, WebP or HEIC image.',\n reorderFailed: 'The photos could not be reordered. The old order is back.',\n dismiss: 'Dismiss',\n};\n","export type ProductFlowStep = 'photos' | 'basics' | 'story' | 'preview';\n\nexport const PRODUCT_FLOW_STEPS: ProductFlowStep[] = [\n 'photos',\n 'basics',\n 'story',\n 'preview',\n];\n\nexport interface ProductFlowLabels {\n newTitle: string;\n editTitle: string;\n back: string;\n close: string;\n stepsLabel: string;\n steps: Record<ProductFlowStep, string>;\n headings: Record<ProductFlowStep, string>;\n ledes: Record<ProductFlowStep, string>;\n addPhotos: string;\n addMorePhotos: string;\n photoHint: string;\n photoTip: string;\n photoN: string;\n cover: string;\n makeCover: string;\n removePhoto: string;\n uploading: string;\n pricePlaceholder: string;\n otherCategory: string;\n newCategory: string;\n oneOfAKind: string;\n howMany: string;\n descriptionPrompts: string[];\n materialsOther: string;\n size: string;\n altTitle: string;\n altHelp: string;\n altFallback: string;\n inTheShop: string;\n untitled: string;\n noPhoto: string;\n needs: string;\n featured: string;\n continue: string;\n photosLater: string;\n skip: string;\n saveDraft: string;\n publish: string;\n done: string;\n saving: string;\n savedNew: string;\n savedEdit: string;\n saveFailed: string;\n retry: string;\n savedAsDraft: string;\n success: string;\n successFirst: string;\n addAnother: string;\n backToList: string;\n}\n\nexport const defaultProductFlowLabels: ProductFlowLabels = {\n newTitle: 'New product',\n editTitle: 'Edit product',\n back: 'Back',\n close: 'Close',\n stepsLabel: 'Steps',\n steps: {\n photos: 'Photos',\n basics: 'Basics',\n story: 'Story',\n preview: 'Preview',\n },\n headings: {\n photos: 'Start with photos',\n basics: 'The basics',\n story: 'Tell its story',\n preview: 'Ready for the shop?',\n },\n ledes: {\n photos:\n 'The first photo is the one customers see in the shop. Tap any photo to make it the cover.',\n basics: 'That is all a product needs to go in the shop.',\n story: 'Optional, but it helps it sell. You can add this later.',\n preview: 'This is how customers will see it.',\n },\n addPhotos: 'Take or choose photos',\n addMorePhotos: 'Add more photos',\n photoHint: 'Your camera or your library.',\n photoTip:\n 'Natural light and a plain background make products look their best.',\n photoN: 'Photo {n}',\n cover: 'Cover',\n makeCover: 'Make photo {n} the cover',\n removePhoto: 'Remove photo {n}',\n uploading: 'Uploading {name}…',\n pricePlaceholder: '0.00',\n otherCategory: 'Other…',\n newCategory: 'New category',\n oneOfAKind: 'One of a kind',\n howMany: 'How many do you have?',\n descriptionPrompts: [],\n materialsOther: 'Or type your own',\n size: 'Size',\n altTitle: 'Describe each photo',\n altHelp:\n 'Read aloud for customers who use screen readers. Left blank, it uses the name.',\n altFallback: '{name}, photo {n}',\n inTheShop: 'In the shop',\n untitled: 'Untitled product',\n noPhoto: 'No photo yet',\n needs: 'Before it can go in the shop, it needs:',\n featured: 'Feature on the home page',\n continue: 'Continue',\n photosLater: 'Add photos later',\n skip: 'Skip',\n saveDraft: 'Save as draft',\n publish: 'Put it in the shop',\n done: 'Done',\n saving: 'Saving…',\n savedNew: 'Saved as a draft as you go',\n savedEdit: 'Saved',\n saveFailed: 'Your changes have not been saved yet.',\n retry: 'Try again',\n savedAsDraft: 'Saved as a draft',\n success: 'It’s in the shop!',\n successFirst: 'Your first product is in the shop!',\n addAnother: 'Add another',\n backToList: 'Back to products',\n};\n","import { defaultStockLabels, type StockLabels } from './stock-labels';\nimport { defaultImageLabels, type ImageLabels } from './image-labels';\nimport {\n defaultProductFlowLabels,\n type ProductFlowLabels,\n} from './product-flow-labels';\n\nexport type ProductFilter = 'all' | 'live' | 'sold' | 'draft' | 'archived';\n\nexport interface ProductLabels {\n title: string;\n newProduct: string;\n searchLabel: string;\n searchPlaceholder: string;\n filters: Record<ProductFilter, string>;\n empty: Record<ProductFilter, string>;\n noMatches: string;\n loadMore: string;\n welcome: {\n title: string;\n body: string;\n addFirst: string;\n addMany: string;\n };\n card: {\n needsPrice: string;\n needsCategory: string;\n needsPhoto: string;\n featured: string;\n noPhoto: string;\n };\n draftsBanner: { one: string; many: string; finish: string };\n sheet: {\n close: string;\n photoOf: string;\n previousPhoto: string;\n nextPhoto: string;\n noPhoto: string;\n category: string;\n noCategory: string;\n primary: Record<\n 'finish' | 'publish' | 'sold' | 'restock' | 'restore',\n string\n >;\n edit: string;\n photos: string;\n featureOn: string;\n featureOff: string;\n hide: string;\n copyLink: string;\n linkCopied: string;\n archive: string;\n undo: string;\n missingTitle: string;\n missing: Record<string, string>;\n done: Record<\n | 'publish'\n | 'sold'\n | 'restock'\n | 'restore'\n | 'hide'\n | 'archive'\n | 'feature',\n string\n >;\n };\n openSearch: string;\n closeSearch: string;\n setup: {\n title: string;\n progress: string;\n show: string;\n hide: string;\n locked: string;\n };\n columns: {\n image: string;\n name: string;\n price: string;\n status: string;\n quantity: string;\n actions: string;\n };\n noImage: string;\n viewInShop: string;\n markSold: string;\n archive: string;\n markSoldTitle: string;\n markSoldBody: string;\n archiveTitle: string;\n archiveBody: string;\n updated: string;\n createTitle: string;\n editTitle: string;\n saved: string;\n fields: {\n name: string;\n category: string;\n description: string;\n materials: string;\n dimensions: string;\n price: string;\n quantity: string;\n status: string;\n featured: string;\n };\n images: ImageLabels;\n flow: ProductFlowLabels;\n stock: StockLabels;\n statusHelp: string;\n priceHelp: string;\n validation: {\n required: string;\n price: string;\n quantity: string;\n };\n}\n\nexport const defaultProductLabels: ProductLabels = {\n title: 'Products',\n newProduct: 'New product',\n searchLabel: 'Search products',\n searchPlaceholder: 'Search by name',\n filters: {\n all: 'All',\n live: 'Live',\n sold: 'Sold',\n draft: 'Drafts',\n archived: 'Archived',\n },\n empty: {\n all: 'No products yet. Add your first piece.',\n live: 'Nothing is live in the shop right now.',\n sold: 'Nothing has sold out yet.',\n draft: 'No drafts.',\n archived: 'No archived products.',\n },\n noMatches: 'No products match that search.',\n loadMore: 'Load more',\n welcome: {\n title: 'Your shop is ready for its first piece',\n body: 'Add a photo and a few details to put something on the shelf.',\n addFirst: 'Add your first piece',\n addMany: 'Add several at once',\n },\n card: {\n needsPrice: 'Needs a price',\n needsCategory: 'Needs a category',\n needsPhoto: 'Needs a photo',\n featured: 'Featured',\n noPhoto: 'No photo',\n },\n draftsBanner: {\n one: '1 draft needs a few details',\n many: '{count} drafts need a few details',\n finish: 'Finish',\n },\n sheet: {\n close: 'Close',\n photoOf: 'Photo {current} of {total}',\n previousPhoto: 'Previous photo',\n nextPhoto: 'Next photo',\n noPhoto: 'No photo yet',\n category: 'Category',\n noCategory: 'No category',\n primary: {\n finish: 'Add the missing details',\n publish: 'Put it in the shop',\n sold: 'Mark as sold',\n restock: 'Back in stock',\n restore: 'Restore as a draft',\n },\n edit: 'Edit details',\n photos: 'Photos ({count})',\n featureOn: 'Feature on home',\n featureOff: 'Remove from home',\n hide: 'Hide from shop',\n copyLink: 'Copy shop link',\n linkCopied: 'Link copied.',\n archive: 'Archive',\n undo: 'Undo',\n missingTitle: 'Before it can go in the shop, it needs:',\n missing: {\n name: 'a name',\n priceCents: 'a price',\n category: 'a category',\n images: 'a photo',\n },\n done: {\n publish: 'Now in the shop.',\n sold: 'Marked as sold.',\n restock: 'Back in stock.',\n restore: 'Restored as a draft.',\n hide: 'Hidden from the shop.',\n archive: 'Archived.',\n feature: 'Home page updated.',\n },\n },\n openSearch: 'Search',\n closeSearch: 'Close search',\n setup: {\n title: 'Get your shop ready',\n progress: '{done} of {total}',\n show: 'Show setup steps',\n hide: 'Hide setup steps',\n locked: 'Not available yet',\n },\n columns: {\n image: 'Image',\n name: 'Name',\n price: 'Price',\n status: 'Status',\n quantity: 'In stock',\n actions: 'Actions',\n },\n noImage: 'No image',\n viewInShop: 'View in shop',\n markSold: 'Mark sold',\n archive: 'Archive',\n markSoldTitle: 'Mark as sold?',\n markSoldBody: 'This sets the stock to zero. Customers will see it as sold.',\n archiveTitle: 'Archive this product?',\n archiveBody: 'It will disappear from the shop. You can restore it later.',\n updated: 'Product updated.',\n createTitle: 'New product',\n editTitle: 'Edit product',\n saved: 'Saved.',\n fields: {\n name: 'Name',\n category: 'Category',\n description: 'Description',\n materials: 'Materials',\n dimensions: 'Dimensions',\n price: 'Price',\n quantity: 'Quantity',\n status: 'Status',\n featured: 'Feature this product on the home page',\n },\n images: defaultImageLabels,\n flow: defaultProductFlowLabels,\n stock: defaultStockLabels,\n statusHelp:\n 'Draft is hidden. Active is live in the shop. Archived is hidden and kept. Mark a piece sold from the product list.',\n priceHelp: 'In dollars, for example 48.00.',\n validation: {\n required: 'This field is required.',\n price: 'Enter a price like 48 or 48.50.',\n quantity: 'Enter a whole number, zero or more.',\n },\n};\n","import { defaultOrderLabels, type OrderLabels } from './order-labels';\nimport { defaultShippingLabels, type ShippingLabels } from './shipping-labels';\nimport { defaultDiscountLabels, type DiscountLabels } from './discount-labels';\nimport { defaultProductLabels, type ProductLabels } from './product-labels';\n\nexport type AdminErrorKey =\n | 'unauthorized'\n | 'notFound'\n | 'invalidInput'\n | 'invalidOrderState'\n | 'insufficientStock'\n | 'refundExceedsBalance'\n | 'refundGateway'\n | 'refundOutcomeUnknown'\n | 'discountCodeTaken'\n | 'discountInUse'\n | 'imageInvalid'\n | 'imageTooLarge'\n | 'generic';\n\nexport interface AdminLabels {\n loading: string;\n empty: string;\n save: string;\n cancel: string;\n confirm: string;\n dismiss: string;\n navLabel: string;\n nav: {\n products: string;\n orders: string;\n shippingRates: string;\n more: string;\n closeMore: string;\n };\n statuses: Record<string, string>;\n errors: Record<AdminErrorKey, string>;\n products: ProductLabels;\n orders: OrderLabels;\n shipping: ShippingLabels;\n discounts: DiscountLabels;\n}\n\nexport const defaultAdminLabels: AdminLabels = {\n loading: 'Loading…',\n empty: 'Nothing here yet.',\n save: 'Save',\n cancel: 'Cancel',\n confirm: 'Confirm',\n dismiss: 'Dismiss',\n navLabel: 'Admin',\n nav: {\n products: 'Products',\n orders: 'Orders',\n shippingRates: 'Shipping rates',\n more: 'More',\n closeMore: 'Close menu',\n },\n statuses: {\n draft: 'Draft',\n active: 'Active',\n archived: 'Archived',\n pending: 'Pending',\n paid: 'Paid',\n shipped: 'Shipped',\n cancelled: 'Cancelled',\n expired: 'Expired',\n needs_attention: 'Needs attention',\n refunded: 'Refunded',\n sold: 'Sold',\n scheduled: 'Scheduled',\n inactive: 'Inactive',\n },\n errors: {\n unauthorized: 'You are not signed in or not allowed to do this.',\n notFound: 'We could not find that.',\n invalidInput:\n 'Some of the details are not valid. Check them and try again.',\n invalidOrderState:\n 'This order cannot be changed that way in its current state.',\n insufficientStock: 'Not enough stock is available.',\n refundExceedsBalance: 'The refund is more than the remaining balance.',\n refundGateway:\n 'The payment provider rejected the refund. Try again shortly.',\n refundOutcomeUnknown:\n 'Refund outcome unknown — retry with the same request.',\n discountCodeTaken: 'That discount code is already in use.',\n discountInUse:\n 'This code has been used, so that detail can no longer change. Create a new code instead.',\n imageInvalid: 'That image could not be used. Try a different file.',\n imageTooLarge: 'That image is too large. Choose a smaller one.',\n generic: 'Something went wrong. Try again.',\n },\n products: defaultProductLabels,\n orders: defaultOrderLabels,\n shipping: defaultShippingLabels,\n discounts: defaultDiscountLabels,\n};\n","import { defaultAdminLabels, type AdminLabels } from './admin-labels';\nimport { defaultOrderLabels, type OrderLabels } from './order-labels';\nimport { defaultShippingLabels, type ShippingLabels } from './shipping-labels';\nimport { defaultDiscountLabels, type DiscountLabels } from './discount-labels';\nimport { defaultProductLabels, type ProductLabels } from './product-labels';\n\ntype DeepPartial<T> = {\n [K in keyof T]?: T[K] extends object ? Partial<T[K]> : T[K];\n};\n\nexport type AdminLabelOverrides = Partial<\n Omit<\n AdminLabels,\n | 'nav'\n | 'statuses'\n | 'errors'\n | 'products'\n | 'orders'\n | 'shipping'\n | 'discounts'\n > & {\n nav: Partial<AdminLabels['nav']>;\n statuses: Partial<AdminLabels['statuses']>;\n errors: Partial<AdminLabels['errors']>;\n products: DeepPartial<ProductLabels>;\n orders: DeepPartial<OrderLabels>;\n shipping: Partial<ShippingLabels>;\n discounts: DeepPartial<DiscountLabels>;\n }\n>;\n\nfunction mergeOrderLabels(\n overrides: DeepPartial<OrderLabels> | undefined,\n): OrderLabels {\n const base = defaultOrderLabels;\n return {\n ...base,\n ...overrides,\n tabs: { ...base.tabs, ...overrides?.tabs },\n empty: { ...base.empty, ...overrides?.empty },\n columns: { ...base.columns, ...overrides?.columns },\n itemColumns: { ...base.itemColumns, ...overrides?.itemColumns },\n refundColumns: { ...base.refundColumns, ...overrides?.refundColumns },\n refundSources: { ...base.refundSources, ...overrides?.refundSources },\n refundStatuses: { ...base.refundStatuses, ...overrides?.refundStatuses },\n actions: { ...base.actions, ...overrides?.actions },\n } as OrderLabels;\n}\n\nfunction mergeProductLabels(\n overrides: DeepPartial<ProductLabels> | undefined,\n): ProductLabels {\n const base = defaultProductLabels;\n return {\n ...base,\n ...overrides,\n filters: { ...base.filters, ...overrides?.filters },\n empty: { ...base.empty, ...overrides?.empty },\n columns: { ...base.columns, ...overrides?.columns },\n fields: { ...base.fields, ...overrides?.fields },\n welcome: { ...base.welcome, ...overrides?.welcome },\n card: { ...base.card, ...overrides?.card },\n draftsBanner: { ...base.draftsBanner, ...overrides?.draftsBanner },\n sheet: {\n ...base.sheet,\n ...overrides?.sheet,\n primary: { ...base.sheet.primary, ...overrides?.sheet?.primary },\n missing: { ...base.sheet.missing, ...overrides?.sheet?.missing },\n done: { ...base.sheet.done, ...overrides?.sheet?.done },\n },\n setup: { ...base.setup, ...overrides?.setup },\n validation: { ...base.validation, ...overrides?.validation },\n images: { ...base.images, ...overrides?.images },\n flow: {\n ...base.flow,\n ...overrides?.flow,\n steps: { ...base.flow.steps, ...overrides?.flow?.steps },\n headings: { ...base.flow.headings, ...overrides?.flow?.headings },\n ledes: { ...base.flow.ledes, ...overrides?.flow?.ledes },\n },\n stock: {\n addSeveral: {\n ...base.stock.addSeveral,\n ...overrides?.stock?.addSeveral,\n },\n queue: { ...base.stock.queue, ...overrides?.stock?.queue },\n summary: { ...base.stock.summary, ...overrides?.stock?.summary },\n },\n } as ProductLabels;\n}\n\nfunction mergeDiscountLabels(\n overrides: DeepPartial<DiscountLabels> | undefined,\n): DiscountLabels {\n const base = defaultDiscountLabels;\n return {\n ...base,\n ...overrides,\n tabs: { ...base.tabs, ...overrides?.tabs },\n empty: { ...base.empty, ...overrides?.empty },\n columns: { ...base.columns, ...overrides?.columns },\n fields: { ...base.fields, ...overrides?.fields },\n types: { ...base.types, ...overrides?.types },\n validation: { ...base.validation, ...overrides?.validation },\n } as DiscountLabels;\n}\n\nexport function mergeAdminLabels(\n labels: AdminLabelOverrides | undefined,\n): AdminLabels {\n const base = defaultAdminLabels;\n return {\n ...base,\n ...labels,\n nav: { ...base.nav, ...labels?.nav },\n statuses: { ...base.statuses, ...labels?.statuses } as Record<\n string,\n string\n >,\n errors: { ...base.errors, ...labels?.errors } as AdminLabels['errors'],\n products: mergeProductLabels(labels?.products),\n orders: mergeOrderLabels(labels?.orders),\n shipping: { ...defaultShippingLabels, ...labels?.shipping },\n discounts: mergeDiscountLabels(labels?.discounts),\n };\n}\n","import type { AdminClient } from '../client';\nimport { createContext, useContext, type ReactNode } from 'react';\nimport { defaultAdminLabels, type AdminLabels } from './admin-labels';\nimport { mergeAdminLabels, type AdminLabelOverrides } from './merge-labels';\n\nexport type { AdminErrorKey, AdminLabels } from './admin-labels';\n\nexport interface LinkProps {\n href: string;\n children: ReactNode;\n className?: string;\n}\n\nexport interface AdminImageProps {\n src: string;\n alt: string;\n sizes?: string;\n className?: string;\n priority?: boolean;\n}\n\nexport interface AdminConfig {\n renderLink: (props: LinkProps) => ReactNode;\n renderImage: (props: AdminImageProps) => ReactNode;\n locale: string;\n currency: string;\n hrefs: {\n products: string;\n product: (id: string) => string;\n newProduct: string;\n orders: string;\n order: (id: string) => string;\n shippingRates: string;\n discounts: string;\n discount: (id: string) => string;\n newDiscount: string;\n storefrontProduct?: (slug: string) => string;\n };\n client: AdminClient | null;\n labels: AdminLabels;\n}\n\nconst defaults: AdminConfig = {\n renderLink: ({ href, children, className }) => (\n <a href={href} className={className}>\n {children}\n </a>\n ),\n renderImage: ({ src, alt, sizes, className, priority }) => (\n <img\n src={src}\n alt={alt}\n sizes={sizes}\n className={className}\n loading={priority ? 'eager' : 'lazy'}\n decoding=\"async\"\n fetchPriority={priority ? 'high' : undefined}\n />\n ),\n locale: 'en-US',\n currency: 'USD',\n hrefs: {\n products: '/admin/products',\n product: (id) => `/admin/products/${id}`,\n newProduct: '/admin/products/new',\n orders: '/admin/orders',\n order: (id) => `/admin/orders/${id}`,\n shippingRates: '/admin/shipping-rates',\n discounts: '/admin/discounts',\n discount: (id) => `/admin/discounts/${id}`,\n newDiscount: '/admin/discounts/new',\n },\n client: null,\n labels: defaultAdminLabels,\n};\n\nconst AdminContext = createContext<AdminConfig>(defaults);\n\nexport interface AdminProviderProps extends Partial<\n Omit<AdminConfig, 'hrefs' | 'labels'>\n> {\n hrefs?: Partial<AdminConfig['hrefs']>;\n labels?: AdminLabelOverrides;\n children: ReactNode;\n}\n\nexport function AdminProvider({\n children,\n hrefs,\n labels,\n ...overrides\n}: AdminProviderProps) {\n const value: AdminConfig = {\n ...defaults,\n ...overrides,\n hrefs: { ...defaults.hrefs, ...hrefs },\n labels: mergeAdminLabels(labels),\n };\n return (\n <AdminContext.Provider value={value}>{children}</AdminContext.Provider>\n );\n}\n\nexport function useAdmin(): AdminConfig {\n return useContext(AdminContext);\n}\n\nexport function useAdminClient(): AdminClient {\n const { client } = useAdmin();\n if (!client) {\n throw new Error('AdminProvider needs a `client` to render this view.');\n }\n return client;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface AdminQuery<T> {\n data: T | undefined;\n error: unknown;\n loading: boolean;\n reload: () => void;\n}\n\ninterface Settled<T> {\n request: string;\n data: T | undefined;\n error: unknown;\n}\n\nexport function useAdminQuery<T>(\n key: readonly unknown[],\n fn: (signal: AbortSignal) => Promise<T>,\n): AdminQuery<T> {\n const fnRef = useRef(fn);\n useEffect(() => {\n fnRef.current = fn;\n });\n const [reloadCount, setReloadCount] = useState(0);\n const [settled, setSettled] = useState<Settled<T>>({\n request: '',\n data: undefined,\n error: undefined,\n });\n const request = `${JSON.stringify(key)}#${reloadCount}`;\n\n useEffect(() => {\n const controller = new AbortController();\n fnRef\n .current(controller.signal)\n .then((data) => {\n if (!controller.signal.aborted)\n setSettled({ request, data, error: undefined });\n })\n .catch((error: unknown) => {\n if (!controller.signal.aborted)\n setSettled((prev) => ({ request, data: prev.data, error }));\n });\n return () => controller.abort();\n }, [request]);\n\n const reload = useCallback(() => setReloadCount((n) => n + 1), []);\n const current = settled.request === request;\n return {\n data: settled.data,\n error: current ? settled.error : undefined,\n loading: !current,\n reload,\n };\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface AdminMutation<A extends unknown[], R> {\n run: (...args: A) => Promise<R | undefined>;\n pending: boolean;\n error: unknown;\n reset: () => void;\n}\n\nexport function useAdminMutation<A extends unknown[], R>(\n fn: (...args: A) => Promise<R>,\n): AdminMutation<A, R> {\n const fnRef = useRef(fn);\n useEffect(() => {\n fnRef.current = fn;\n });\n const [pending, setPending] = useState(false);\n const [error, setError] = useState<unknown>(undefined);\n\n const run = useCallback(async (...args: A) => {\n setPending(true);\n setError(undefined);\n try {\n return await fnRef.current(...args);\n } catch (err) {\n setError(err);\n return undefined;\n } finally {\n setPending(false);\n }\n }, []);\n\n const reset = useCallback(() => setError(undefined), []);\n return { run, pending, error, reset };\n}\n","import type { ReactNode } from 'react';\n\nfunction icon(path: ReactNode): ReactNode {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"24\"\n height=\"24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n {path}\n </svg>\n );\n}\n\nexport const adminNavIcons = {\n products: icon(\n <>\n <path d=\"M4 8l8-4 8 4-8 4-8-4z\" />\n <path d=\"M4 8v8l8 4 8-4V8\" />\n <path d=\"M12 12v8\" />\n </>,\n ),\n orders: icon(\n <>\n <path d=\"M6 3h12v18l-3-2-3 2-3-2-3 2V3z\" />\n <path d=\"M9 8h6M9 12h6\" />\n </>,\n ),\n shipping: icon(\n <>\n <path d=\"M3 6h11v10H3zM14 10h4l3 3v3h-7\" />\n <circle cx=\"7\" cy=\"18\" r=\"1.6\" />\n <circle cx=\"17\" cy=\"18\" r=\"1.6\" />\n </>,\n ),\n discounts: icon(\n <>\n <path d=\"M4 12l8-8h8v8l-8 8-8-8z\" />\n <circle cx=\"15.5\" cy=\"8.5\" r=\"1.2\" />\n </>,\n ),\n more: icon(\n <>\n <circle cx=\"5\" cy=\"12\" r=\"1.4\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.4\" />\n <circle cx=\"19\" cy=\"12\" r=\"1.4\" />\n </>,\n ),\n dot: icon(<circle cx=\"12\" cy=\"12\" r=\"3\" />),\n};\n","import type { ReactNode } from 'react';\nimport { adminNavIcons } from './nav-icons';\n\nexport interface ExtraNavItem {\n href: string;\n label: string;\n position?: 'start' | 'end';\n icon?: ReactNode;\n badge?: number | string;\n}\n\nexport interface NavBadges {\n products?: number | string;\n orders?: number | string;\n shippingRates?: number | string;\n}\n\nexport interface NavItem {\n href: string;\n label: string;\n icon: ReactNode;\n badge?: number | string;\n}\n\nexport const TAB_BAR_SLOTS = 5;\n\ninterface KitHrefs {\n products: string;\n orders: string;\n shippingRates: string;\n}\n\ninterface KitLabels {\n products: string;\n orders: string;\n shippingRates: string;\n}\n\nfunction hasBadge(badge: number | string | undefined) {\n return badge !== undefined && badge !== '' && badge !== 0;\n}\n\nexport function buildNavItems(\n hrefs: KitHrefs,\n labels: KitLabels,\n extraNav: ExtraNavItem[],\n badges: NavBadges,\n): NavItem[] {\n const kit: NavItem[] = [\n {\n href: hrefs.products,\n label: labels.products,\n icon: adminNavIcons.products,\n badge: badges.products,\n },\n {\n href: hrefs.orders,\n label: labels.orders,\n icon: adminNavIcons.orders,\n badge: badges.orders,\n },\n {\n href: hrefs.shippingRates,\n label: labels.shippingRates,\n icon: adminNavIcons.shipping,\n badge: badges.shippingRates,\n },\n ];\n const extra = (item: ExtraNavItem): NavItem => ({\n href: item.href,\n label: item.label,\n icon: item.icon ?? adminNavIcons.dot,\n badge: item.badge,\n });\n return [\n ...extraNav.filter((i) => i.position === 'start').map(extra),\n ...kit,\n ...extraNav.filter((i) => i.position !== 'start').map(extra),\n ].map((item) => ({\n ...item,\n badge: hasBadge(item.badge) ? item.badge : undefined,\n }));\n}\n\nexport function splitForTabBar(items: NavItem[]) {\n if (items.length <= TAB_BAR_SLOTS) return { bar: items, overflow: [] };\n return {\n bar: items.slice(0, TAB_BAR_SLOTS - 1),\n overflow: items.slice(TAB_BAR_SLOTS - 1),\n };\n}\n","import { useCallback, useEffect, useState } from 'react';\n\nexport function useMoreSheet() {\n const [open, setOpen] = useState(false);\n const close = useCallback(() => setOpen(false), []);\n const toggle = useCallback(() => setOpen((o) => !o), []);\n\n useEffect(() => {\n if (!open) return;\n const onKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setOpen(false);\n };\n document.addEventListener('keydown', onKey);\n return () => document.removeEventListener('keydown', onKey);\n }, [open]);\n\n return { open, close, toggle };\n}\n","import { useId, type ReactNode } from 'react';\nimport { useAdmin } from '../../lib/provider';\nimport { adminNavIcons } from './nav-icons';\nimport {\n buildNavItems,\n splitForTabBar,\n type ExtraNavItem,\n type NavBadges,\n type NavItem,\n} from './nav-items';\nimport { useMoreSheet } from './use-more-sheet';\n\nexport type { ExtraNavItem, NavBadges } from './nav-items';\nexport { adminNavIcons } from './nav-icons';\n\nexport interface AdminLayoutProps {\n children: ReactNode;\n extraNav?: ExtraNavItem[];\n navBadges?: NavBadges;\n header?: ReactNode;\n footer?: ReactNode;\n}\n\nexport function AdminLayout({\n children,\n extraNav = [],\n navBadges = {},\n header,\n footer,\n}: AdminLayoutProps) {\n const { hrefs, labels, renderLink } = useAdmin();\n const sheetId = useId();\n const more = useMoreSheet();\n const items = buildNavItems(hrefs, labels.nav, extraNav, navBadges);\n const { bar, overflow } = splitForTabBar(items);\n\n const link = (item: NavItem, className: string) =>\n renderLink({\n href: item.href,\n className,\n children: (\n <>\n <span className=\"sfa-nav__icon\">{item.icon}</span>\n <span className=\"sfa-nav__label\">{item.label}</span>\n {item.badge !== undefined ? (\n <span className=\"sfa-nav__badge\">{item.badge}</span>\n ) : null}\n </>\n ),\n });\n\n return (\n <div className=\"sfa-root sfa-layout\">\n <aside className=\"sfa-sidebar\">\n {header ? <div className=\"sfa-layout__header\">{header}</div> : null}\n <nav className=\"sfa-nav\" aria-label={labels.navLabel}>\n <ul>\n {items.map((item) => (\n <li key={item.href}>{link(item, 'sfa-nav__link')}</li>\n ))}\n </ul>\n </nav>\n {footer ? <div className=\"sfa-layout__footer\">{footer}</div> : null}\n </aside>\n <main className=\"sfa-layout__content\">{children}</main>\n <nav className=\"sfa-tabbar\" aria-label={labels.navLabel}>\n <ul>\n {bar.map((item) => (\n <li key={item.href}>{link(item, 'sfa-tabbar__item')}</li>\n ))}\n {overflow.length > 0 || header || footer ? (\n <li>\n <button\n type=\"button\"\n className=\"sfa-tabbar__item\"\n aria-expanded={more.open}\n aria-controls={sheetId}\n onClick={more.toggle}\n >\n <span className=\"sfa-nav__icon\">{adminNavIcons.more}</span>\n <span className=\"sfa-nav__label\">{labels.nav.more}</span>\n {overflow.some((i) => i.badge !== undefined) ? (\n <span className=\"sfa-nav__badge sfa-nav__badge--dot\" />\n ) : null}\n </button>\n </li>\n ) : null}\n </ul>\n </nav>\n {more.open ? (\n <button\n type=\"button\"\n className=\"sfa-more__backdrop\"\n aria-label={labels.nav.closeMore}\n onClick={more.close}\n />\n ) : null}\n <div\n id={sheetId}\n className=\"sfa-more\"\n hidden={!more.open}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest('a')) more.close();\n }}\n >\n {header ? <div className=\"sfa-layout__header\">{header}</div> : null}\n {overflow.length > 0 ? (\n <ul className=\"sfa-more__list\">\n {overflow.map((item) => (\n <li key={item.href}>{link(item, 'sfa-nav__link')}</li>\n ))}\n </ul>\n ) : null}\n {footer ? <div className=\"sfa-layout__footer\">{footer}</div> : null}\n </div>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\n\nexport interface AdminPageHeaderProps {\n title: ReactNode;\n actions?: ReactNode;\n floatingAction?: ReactNode;\n children?: ReactNode;\n}\n\nexport function AdminPageHeader({\n title,\n actions,\n floatingAction,\n children,\n}: AdminPageHeaderProps) {\n return (\n <header className=\"sfa-page-header\">\n <div className=\"sfa-page-header__row\">\n <h1 className=\"sfa-page-header__title\">{title}</h1>\n {actions || floatingAction ? (\n <div className=\"sfa-page-header__actions\">\n {actions}\n {floatingAction ? (\n <span className=\"sfa-fab\">{floatingAction}</span>\n ) : null}\n </div>\n ) : null}\n </div>\n {children}\n </header>\n );\n}\n","import type { ReactNode } from 'react';\nimport { useAdmin } from '../../lib/provider';\n\nexport interface AdminColumn<T> {\n key: string;\n header: string;\n render: (row: T) => ReactNode;\n}\n\nexport interface AdminTableProps<T> {\n columns: AdminColumn<T>[];\n rows: T[];\n rowKey: (row: T) => string;\n caption?: string;\n}\n\nexport function AdminTable<T>({\n columns,\n rows,\n rowKey,\n caption,\n}: AdminTableProps<T>) {\n const { labels } = useAdmin();\n if (rows.length === 0) return <p className=\"sfa-empty\">{labels.empty}</p>;\n return (\n <table className=\"sfa-table sfa-table--stacked\">\n {caption ? <caption>{caption}</caption> : null}\n <thead>\n <tr>\n {columns.map((c) => (\n <th key={c.key} scope=\"col\">\n {c.header}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((row) => (\n <tr key={rowKey(row)}>\n {columns.map((c) => (\n <td key={c.key} data-label={c.header}>\n {c.render(row)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n );\n}\n","import { useAdmin } from '../../lib/provider';\n\nexport function StatusBadge({ status }: { status: string }) {\n const { labels } = useAdmin();\n return (\n <span className={`sfa-badge sfa-badge--${status.replace(/_/g, '-')}`}>\n {labels.statuses[status] ?? status}\n </span>\n );\n}\n","import { useAdmin } from '../../lib/provider';\n\nexport interface MoneyProps {\n cents: number;\n currency: string;\n}\n\nexport function Money({ cents, currency }: MoneyProps) {\n const { locale } = useAdmin();\n const text = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n }).format(cents / 100);\n return <span className=\"sfa-money\">{text}</span>;\n}\n","import { useEffect, type KeyboardEvent, type RefObject } from 'react';\n\nconst FOCUSABLE =\n 'button:not([disabled]), [href], input:not([disabled]), select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n\nexport function useFocusTrap(\n ref: RefObject<HTMLElement | null>,\n active: boolean,\n onEscape: () => void,\n) {\n useEffect(() => {\n if (!active) return;\n const trigger = document.activeElement as HTMLElement | null;\n ref.current?.querySelector<HTMLElement>(FOCUSABLE)?.focus();\n return () => trigger?.focus();\n }, [active, ref]);\n\n useEffect(() => {\n if (!active) return;\n const onDocumentKey = (event: globalThis.KeyboardEvent) => {\n if (event.key === 'Escape') onEscape();\n };\n document.addEventListener('keydown', onDocumentKey);\n return () => document.removeEventListener('keydown', onDocumentKey);\n }, [active, onEscape]);\n\n return (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n onEscape();\n return;\n }\n if (event.key !== 'Tab') return;\n const focusable = Array.from(\n ref.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? [],\n );\n if (focusable.length === 0) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n };\n}\n","import { useRef, type ReactNode } from 'react';\nimport { useFocusTrap } from '../../lib/use-focus-trap';\nimport { useAdmin } from '../../lib/provider';\n\nexport interface ConfirmDialogProps {\n open: boolean;\n title: string;\n children?: ReactNode;\n confirmLabel?: string;\n destructive?: boolean;\n pending?: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n}\n\nexport function ConfirmDialog({\n open,\n title,\n children,\n confirmLabel,\n destructive = false,\n pending = false,\n onConfirm,\n onCancel,\n}: ConfirmDialogProps) {\n const { labels } = useAdmin();\n const panelRef = useRef<HTMLDivElement>(null);\n\n const onKeyDown = useFocusTrap(panelRef, open, onCancel);\n\n if (!open) return null;\n\n return (\n <div className=\"sfa-dialog-backdrop\" onKeyDown={onKeyDown}>\n <div\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n className=\"sfa-dialog\"\n >\n <h2 className=\"sfa-dialog__title\">{title}</h2>\n {children}\n <div className=\"sfa-dialog__actions\">\n <button type=\"button\" className=\"sfa-btn\" onClick={onCancel}>\n {labels.cancel}\n </button>\n <button\n type=\"button\"\n className={`sfa-btn ${destructive ? 'sfa-btn--danger' : 'sfa-btn--primary'}`}\n disabled={pending}\n onClick={onConfirm}\n >\n {confirmLabel ?? labels.confirm}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import { useEffect, type ReactNode } from 'react';\nimport { useAdmin } from '../../lib/provider';\n\nexport interface NoticeProps {\n variant: 'success' | 'error' | 'warning';\n children: ReactNode;\n toast?: boolean;\n duration?: number;\n onDismiss?: () => void;\n action?: { label: string; onAction: () => void };\n}\n\nexport function Notice({\n variant,\n children,\n toast = false,\n duration = 4000,\n onDismiss,\n action,\n}: NoticeProps) {\n const { labels } = useAdmin();\n\n useEffect(() => {\n if (!toast || !onDismiss) return;\n const timer = setTimeout(onDismiss, duration);\n return () => clearTimeout(timer);\n }, [toast, duration, onDismiss]);\n\n const role = variant === 'error' ? 'alert' : 'status';\n const className = `sfa-notice sfa-notice--${variant}${toast ? ' sfa-notice--toast' : ''}`;\n return (\n <div role={role} className={className}>\n <span className=\"sfa-notice__body\">{children}</span>\n {action ? (\n <button type=\"button\" className=\"sfa-btn\" onClick={action.onAction}>\n {action.label}\n </button>\n ) : null}\n {onDismiss && !toast ? (\n <button type=\"button\" className=\"sfa-btn\" onClick={onDismiss}>\n {labels.dismiss}\n </button>\n ) : null}\n </div>\n );\n}\n","import {\n AdminInvalidInputError,\n AdminNotFoundError,\n AdminUnauthorizedError,\n DiscountCodeTakenError,\n DiscountInUseError,\n ImageTooLargeError,\n InsufficientStockError,\n InvalidImageError,\n InvalidOrderStateError,\n RefundExceedsBalanceError,\n RefundGatewayError,\n RefundOutcomeUnknownError,\n} from '../../client';\nimport { useAdmin, type AdminErrorKey } from '../../lib/provider';\nimport { Notice } from '../notice/notice';\n\nconst KEYED: Array<[new (...args: never[]) => Error, AdminErrorKey]> = [\n [AdminUnauthorizedError, 'unauthorized'],\n [AdminNotFoundError, 'notFound'],\n [AdminInvalidInputError, 'invalidInput'],\n [InvalidOrderStateError, 'invalidOrderState'],\n [InsufficientStockError, 'insufficientStock'],\n [RefundExceedsBalanceError, 'refundExceedsBalance'],\n [RefundGatewayError, 'refundGateway'],\n [RefundOutcomeUnknownError, 'refundOutcomeUnknown'],\n [DiscountCodeTakenError, 'discountCodeTaken'],\n [DiscountInUseError, 'discountInUse'],\n [ImageTooLargeError, 'imageTooLarge'],\n [InvalidImageError, 'imageInvalid'],\n];\n\nexport function errorKey(error: unknown): AdminErrorKey {\n return KEYED.find(([type]) => error instanceof type)?.[1] ?? 'generic';\n}\n\nexport function ErrorMessage({ error }: { error: unknown }) {\n const { labels } = useAdmin();\n if (!error) return null;\n return <Notice variant=\"error\">{labels.errors[errorKey(error)]}</Notice>;\n}\n","import type { AdminProduct } from '@develemit/commerce-contracts';\nimport type { ProductLabels } from './product-labels';\n\nexport function missingDetail(\n product: AdminProduct,\n copy: ProductLabels['card'],\n): string | null {\n if (product.status !== 'draft') return null;\n if (product.priceCents === null) return copy.needsPrice;\n if (!product.category) return copy.needsCategory;\n if (product.images.length === 0) return copy.needsPhoto;\n return null;\n}\n\nexport function fillCount(template: string, values: Record<string, number>) {\n return template.replace(/\\{(\\w+)\\}/g, (_, key: string) =>\n String(values[key] ?? ''),\n );\n}\n","import { useState, type ReactNode } from 'react';\nimport { useAdmin } from '../../lib/provider';\nimport { fillCount } from '../../lib/product-missing';\n\nexport interface SetupStep {\n id: string;\n title: string;\n detail?: string;\n done: boolean;\n href?: string;\n onSelect?: () => void;\n locked?: boolean;\n lockedDetail?: string;\n}\n\nexport interface AdminSetupChecklistProps {\n steps: SetupStep[];\n compact?: boolean;\n}\n\nfunction StepBody({ step }: { step: SetupStep }): ReactNode {\n const detail = step.locked ? step.lockedDetail : step.detail;\n return (\n <>\n <span className=\"sfa-setup__mark\" aria-hidden=\"true\">\n {step.done ? '✓' : ''}\n </span>\n <span className=\"sfa-setup__text\">\n <span className=\"sfa-setup__name\">{step.title}</span>\n {detail ? <span className=\"sfa-setup__detail\">{detail}</span> : null}\n </span>\n </>\n );\n}\n\nfunction Step({ step }: { step: SetupStep }) {\n const { renderLink } = useAdmin();\n const className = `sfa-setup__step${step.done ? ' is-done' : ''}${step.locked ? ' is-locked' : ''}`;\n const actionable = !step.done && !step.locked;\n let content: ReactNode;\n if (actionable && step.href) {\n content = renderLink({\n href: step.href,\n children: <StepBody step={step} />,\n className: 'sfa-setup__action',\n });\n } else if (actionable && step.onSelect) {\n content = (\n <button\n type=\"button\"\n className=\"sfa-setup__action\"\n onClick={step.onSelect}\n >\n <StepBody step={step} />\n </button>\n );\n } else {\n content = (\n <span className=\"sfa-setup__action\">\n <StepBody step={step} />\n </span>\n );\n }\n return (\n <li className={className} data-step={step.id}>\n {content}\n </li>\n );\n}\n\nexport function AdminSetupChecklist({\n steps,\n compact = false,\n}: AdminSetupChecklistProps) {\n const { labels } = useAdmin();\n const copy = labels.products.setup;\n const [open, setOpen] = useState(false);\n const done = steps.filter((s) => s.done).length;\n if (steps.length === 0 || done === steps.length) return null;\n const progress = fillCount(copy.progress, { done, total: steps.length });\n const showList = !compact || open;\n\n return (\n <section className=\"sfa-setup\" aria-label={copy.title}>\n {compact ? (\n <button\n type=\"button\"\n className=\"sfa-setup__pill\"\n aria-expanded={open}\n aria-label={`${open ? copy.hide : copy.show}: ${progress}`}\n onClick={() => setOpen((v) => !v)}\n >\n <span>{copy.title}</span>\n <span className=\"sfa-setup__count\">{progress}</span>\n </button>\n ) : (\n <div className=\"sfa-setup__head\">\n <h2 className=\"sfa-setup__title\">{copy.title}</h2>\n <span className=\"sfa-setup__count\">{progress}</span>\n </div>\n )}\n <div\n className=\"sfa-setup__bar\"\n role=\"progressbar\"\n aria-label={copy.title}\n aria-valuemin={0}\n aria-valuemax={steps.length}\n aria-valuenow={done}\n >\n <span style={{ width: `${(done / steps.length) * 100}%` }} />\n </div>\n {showList ? (\n <ul className=\"sfa-setup__list\">\n {steps.map((step) => (\n <Step key={step.id} step={step} />\n ))}\n </ul>\n ) : null}\n </section>\n );\n}\n","import type {\n AdminProduct,\n ProductStatus,\n} from '@develemit/commerce-contracts';\nimport type { ProductFilter } from './product-labels';\n\nexport function isSold(product: AdminProduct): boolean {\n return product.status === 'active' && product.quantity === 0;\n}\n\nexport function displayStatus(product: AdminProduct): string {\n return isSold(product) ? 'sold' : product.status;\n}\n\nexport function serverStatus(filter: ProductFilter): ProductStatus | undefined {\n switch (filter) {\n case 'live':\n case 'sold':\n return 'active';\n case 'draft':\n case 'archived':\n return filter;\n case 'all':\n return undefined;\n }\n}\n\nexport function serverStock(filter: ProductFilter): 'in' | 'sold' | undefined {\n if (filter === 'live') return 'in';\n if (filter === 'sold') return 'sold';\n return undefined;\n}\n","import { useEffect, useState } from 'react';\n\nexport function useDebounced<T>(value: T, delayMs: number): T {\n const [debounced, setDebounced] = useState(value);\n useEffect(() => {\n const timer = setTimeout(() => setDebounced(value), delayMs);\n return () => clearTimeout(timer);\n }, [value, delayMs]);\n return debounced;\n}\n","import { useState } from 'react';\nimport { useAdminMutation } from './use-admin-mutation';\nimport { useAdminQuery } from './use-admin-query';\n\ninterface CursorPage<Item> {\n items: Item[];\n nextCursor: string | null;\n}\n\ninterface Appended<Page, Item> {\n base: Page;\n items: Item[];\n nextCursor: string | null;\n}\n\nexport function usePagedList<Item, Page extends CursorPage<Item>>(\n key: readonly unknown[],\n fetchPage: (cursor?: string) => Promise<Page>,\n) {\n const first = useAdminQuery(key, () => fetchPage());\n const [appended, setAppended] = useState<Appended<Page, Item> | null>(null);\n const more = useAdminMutation(async (cursor: string, base: Page) => {\n const page = await fetchPage(cursor);\n setAppended((prev) => ({\n base,\n items: [...(prev?.base === base ? prev.items : []), ...page.items],\n nextCursor: page.nextCursor,\n }));\n });\n\n const base = first.data;\n const extra = appended && appended.base === base ? appended : null;\n const nextCursor = extra ? extra.nextCursor : (base?.nextCursor ?? null);\n return {\n items: [...(base?.items ?? []), ...(extra?.items ?? [])],\n loaded: base !== undefined,\n loading: first.loading,\n error: first.error ?? more.error,\n hasMore: !first.loading && nextCursor !== null,\n loadingMore: more.pending,\n reload: first.reload,\n loadMore: () => {\n if (base && nextCursor) void more.run(nextCursor, base);\n },\n };\n}\n","import type {\n AdminProduct,\n AdminProductPage,\n} from '@develemit/commerce-contracts';\nimport type { AdminProductQuery } from '../client/admin-client';\nimport { useAdminClient } from './provider';\nimport { usePagedList } from './use-paged-list';\n\nexport function useProductPages(query: Omit<AdminProductQuery, 'cursor'>) {\n const client = useAdminClient();\n return usePagedList<AdminProduct, AdminProductPage>(\n ['admin-products', query],\n (cursor) => client.listProducts(cursor ? { ...query, cursor } : query),\n );\n}\n","import type {\n AdminProduct,\n AdminProductPatch,\n} from '@develemit/commerce-contracts';\n\nexport type PrimaryKind = 'finish' | 'publish' | 'sold' | 'restock' | 'restore';\n\nexport interface ProductChange {\n patch: AdminProductPatch;\n undo: AdminProductPatch;\n}\n\nexport function isDraftComplete(product: AdminProduct): boolean {\n return (\n product.name.trim() !== '' &&\n product.priceCents !== null &&\n !!product.category &&\n product.images.length > 0\n );\n}\n\nexport function primaryKind(product: AdminProduct): PrimaryKind {\n if (product.status === 'draft') {\n return isDraftComplete(product) ? 'publish' : 'finish';\n }\n if (product.status === 'archived') return 'restore';\n return product.quantity > 0 ? 'sold' : 'restock';\n}\n\nexport function primaryChange(\n product: AdminProduct,\n kind: PrimaryKind,\n): ProductChange | null {\n switch (kind) {\n case 'publish':\n return { patch: { status: 'active' }, undo: { status: 'draft' } };\n case 'sold':\n return {\n patch: { sold: true },\n undo: { quantity: product.quantity },\n };\n case 'restock':\n return { patch: { quantity: 1 }, undo: { quantity: 0 } };\n case 'restore':\n return { patch: { status: 'draft' }, undo: { status: 'archived' } };\n case 'finish':\n return null;\n }\n}\n\nexport const hideChange: ProductChange = {\n patch: { status: 'draft' },\n undo: { status: 'active' },\n};\n\nexport function archiveChange(product: AdminProduct): ProductChange {\n return {\n patch: { status: 'archived' },\n undo: { status: product.status },\n };\n}\n\nexport function featureChange(product: AdminProduct): ProductChange {\n return {\n patch: { featured: !product.featured },\n undo: { featured: product.featured },\n };\n}\n\nexport const canFeature = (product: AdminProduct) =>\n product.status === 'active';\n","import { useState } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { fillCount } from '../../../lib/product-missing';\nimport { useAdmin } from '../../../lib/provider';\n\nexport function SheetCarousel({ product }: { product: AdminProduct }) {\n const { labels, renderImage } = useAdmin();\n const copy = labels.products.sheet;\n const [index, setIndex] = useState(0);\n const total = product.images.length;\n const image = product.images[Math.min(index, Math.max(total - 1, 0))];\n\n if (!image) {\n return <div className=\"sfa-sheet__photo\">{copy.noPhoto}</div>;\n }\n const step = (by: number) => setIndex((i) => (i + by + total) % total);\n return (\n <div\n className=\"sfa-sheet__photo\"\n role=\"group\"\n aria-label={fillCount(copy.photoOf, { current: index + 1, total })}\n >\n {renderImage({ src: image.url, alt: image.alt, sizes: '420px' })}\n {total > 1 ? (\n <>\n <button\n type=\"button\"\n className=\"sfa-sheet__step sfa-sheet__step--prev\"\n aria-label={copy.previousPhoto}\n onClick={() => step(-1)}\n >\n ‹\n </button>\n <button\n type=\"button\"\n className=\"sfa-sheet__step sfa-sheet__step--next\"\n aria-label={copy.nextPhoto}\n onClick={() => step(1)}\n >\n ›\n </button>\n </>\n ) : null}\n </div>\n );\n}\n","import { useState } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { ProductIncompleteError } from '../../../client';\nimport type { ProductChange } from '../../../lib/product-sheet-actions';\nimport { useAdminClient } from '../../../lib/provider';\nimport { useAdminMutation } from '../../../lib/use-admin-mutation';\n\nexport interface SheetNotice {\n text: string;\n undo?: ProductChange['undo'];\n}\n\nexport function useProductChange(\n product: AdminProduct,\n setProduct: (next: AdminProduct) => void,\n onChanged: () => void,\n) {\n const client = useAdminClient();\n const [notice, setNotice] = useState<SheetNotice | null>(null);\n const mutation = useAdminMutation((patch: ProductChange['patch']) =>\n client.updateProduct(product.id, patch),\n );\n\n const apply = async (change: ProductChange, text: string) => {\n setNotice(null);\n const next = await mutation.run(change.patch);\n if (!next) return;\n setProduct(next);\n setNotice({ text, undo: change.undo });\n onChanged();\n };\n\n const undo = async () => {\n if (!notice?.undo) return;\n const next = await mutation.run(notice.undo);\n setNotice(null);\n if (!next) return;\n setProduct(next);\n onChanged();\n };\n\n const missing =\n mutation.error instanceof ProductIncompleteError\n ? mutation.error.missing\n : null;\n\n return {\n apply,\n undo,\n notice,\n dismiss: () => setNotice(null),\n announce: (text: string) => setNotice({ text }),\n pending: mutation.pending,\n missing,\n error: missing ? null : mutation.error,\n };\n}\n","import type { ReactNode } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport type { ProductFlowStep } from '../../../lib/product-flow-labels';\nimport { useAdmin } from '../../../lib/provider';\n\nexport type EditProduct = (\n product: AdminProduct,\n step?: ProductFlowStep,\n) => void;\n\nexport function hrefWithStep(href: string, step: ProductFlowStep): string {\n return `${href}${href.includes('?') ? '&' : '?'}step=${step}`;\n}\n\nexport function finishStep(product: AdminProduct): ProductFlowStep {\n const basicsMissing =\n !product.name || product.priceCents === null || !product.category;\n return basicsMissing || product.images.length > 0 ? 'basics' : 'photos';\n}\n\nexport interface SheetEditLinkProps {\n product: AdminProduct;\n step: ProductFlowStep;\n onEdit?: EditProduct;\n className: string;\n children: ReactNode;\n}\n\nexport function SheetEditLink({\n product,\n step,\n onEdit,\n className,\n children,\n}: SheetEditLinkProps) {\n const { hrefs, renderLink } = useAdmin();\n if (onEdit) {\n return (\n <button\n type=\"button\"\n className={className}\n onClick={() => onEdit(product, step)}\n >\n {children}\n </button>\n );\n }\n return renderLink({\n href: hrefWithStep(hrefs.product(product.id), step),\n children,\n className,\n });\n}\n","import { useRef, useState, type ReactNode } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../../components/error-message/error-message';\nimport { Money } from '../../../components/money/money';\nimport { Notice } from '../../../components/notice/notice';\nimport { StatusBadge } from '../../../components/status-badge/status-badge';\nimport { displayStatus } from '../../../lib/product-filter';\nimport { fillCount } from '../../../lib/product-missing';\nimport {\n archiveChange,\n canFeature,\n featureChange,\n hideChange,\n primaryChange,\n primaryKind,\n} from '../../../lib/product-sheet-actions';\nimport { useAdmin, useAdminClient } from '../../../lib/provider';\nimport { useAdminQuery } from '../../../lib/use-admin-query';\nimport { useFocusTrap } from '../../../lib/use-focus-trap';\nimport { SheetCarousel } from './sheet-carousel';\nimport { useProductChange } from './use-product-change';\nimport { finishStep, SheetEditLink, type EditProduct } from './sheet-edit-link';\n\nexport interface AdminProductSheetProps {\n productId: string;\n onClose: () => void;\n onEdit?: EditProduct;\n onChanged?: () => void;\n}\n\nexport function AdminProductSheet({\n productId,\n onClose,\n onEdit,\n onChanged,\n}: AdminProductSheetProps) {\n const client = useAdminClient();\n const query = useAdminQuery(['admin-product', productId], () =>\n client.getProduct(productId),\n );\n const [override, setOverride] = useState<AdminProduct | null>(null);\n const product = override && override.id === productId ? override : query.data;\n\n return (\n <SheetFrame onClose={onClose}>\n {product ? (\n <SheetBody\n product={product}\n setProduct={setOverride}\n onEdit={onEdit}\n onChanged={onChanged ?? (() => undefined)}\n />\n ) : (\n <LoadingBody error={query.error} />\n )}\n </SheetFrame>\n );\n}\n\nfunction LoadingBody({ error }: { error: unknown }) {\n const { labels } = useAdmin();\n return error ? <ErrorMessage error={error} /> : <p>{labels.loading}</p>;\n}\n\nfunction SheetFrame({\n onClose,\n children,\n}: {\n onClose: () => void;\n children: ReactNode;\n}) {\n const { labels } = useAdmin();\n const ref = useRef<HTMLDivElement>(null);\n const onKeyDown = useFocusTrap(ref, true, onClose);\n return (\n <div className=\"sfa-sheet-layer\" onKeyDown={onKeyDown}>\n <div className=\"sfa-sheet__scrim\" onClick={onClose} aria-hidden=\"true\" />\n <div\n ref={ref}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={labels.products.title}\n className=\"sfa-sheet\"\n >\n <span className=\"sfa-sheet__grip\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n className=\"sfa-sheet__close sfa-btn\"\n aria-label={labels.products.sheet.close}\n onClick={onClose}\n >\n ✕\n </button>\n {children}\n </div>\n </div>\n );\n}\n\ninterface BodyProps {\n product: AdminProduct;\n setProduct: (next: AdminProduct) => void;\n onEdit?: EditProduct;\n onChanged: () => void;\n}\n\nfunction SheetBody({ product, setProduct, onEdit, onChanged }: BodyProps) {\n const { labels, hrefs } = useAdmin();\n const copy = labels.products.sheet;\n const change = useProductChange(product, setProduct, onChanged);\n const kind = primaryKind(product);\n const change0 = primaryChange(product, kind);\n const link = hrefs.storefrontProduct?.(product.slug);\n\n const edit = { product, onEdit };\n\n const copyLink = async () => {\n if (!link) return;\n await navigator.clipboard.writeText(\n new URL(link, window.location.href).href,\n );\n change.announce(copy.linkCopied);\n };\n\n return (\n <div className=\"sfa-sheet__body\">\n <SheetCarousel product={product} />\n <h2 className=\"sfa-sheet__name\">{product.name}</h2>\n <p className=\"sfa-sheet__meta\">\n <StatusBadge status={displayStatus(product)} />\n <span>\n {product.priceCents === null ? (\n '—'\n ) : (\n <Money cents={product.priceCents} currency={product.currency} />\n )}\n </span>\n <span>{product.category ?? copy.noCategory}</span>\n </p>\n {change.missing ? (\n <Notice variant=\"warning\">\n {copy.missingTitle}{' '}\n {change.missing.map((f) => copy.missing[f] ?? f).join(', ')}\n </Notice>\n ) : null}\n <ErrorMessage error={change.error} />\n {change0 ? (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary sfa-sheet__primary\"\n disabled={change.pending}\n onClick={() =>\n change.apply(change0, copy.done[kind as keyof typeof copy.done])\n }\n >\n {copy.primary[kind]}\n </button>\n ) : (\n <span className=\"sfa-sheet__primary\">\n <SheetEditLink\n {...edit}\n step={finishStep(product)}\n className=\"sfa-btn sfa-btn--primary\"\n >\n {copy.primary.finish}\n </SheetEditLink>\n </span>\n )}\n <div className=\"sfa-sheet__actions\">\n <SheetEditLink {...edit} step=\"basics\" className=\"sfa-btn\">\n {copy.edit}\n </SheetEditLink>\n <SheetEditLink {...edit} step=\"photos\" className=\"sfa-btn\">\n {fillCount(copy.photos, { count: product.images.length })}\n </SheetEditLink>\n {canFeature(product) ? (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n disabled={change.pending}\n onClick={() =>\n change.apply(featureChange(product), copy.done.feature)\n }\n >\n {product.featured ? copy.featureOff : copy.featureOn}\n </button>\n ) : null}\n {product.status === 'active' ? (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n disabled={change.pending}\n onClick={() => change.apply(hideChange, copy.done.hide)}\n >\n {copy.hide}\n </button>\n ) : null}\n {link ? (\n <button type=\"button\" className=\"sfa-btn\" onClick={copyLink}>\n {copy.copyLink}\n </button>\n ) : null}\n {product.status !== 'archived' ? (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n disabled={change.pending}\n onClick={() =>\n change.apply(archiveChange(product), copy.done.archive)\n }\n >\n {copy.archive}\n </button>\n ) : null}\n </div>\n {change.notice ? (\n <Notice\n variant=\"success\"\n toast\n duration={8000}\n onDismiss={change.dismiss}\n action={\n change.notice.undo\n ? { label: copy.undo, onAction: change.undo }\n : undefined\n }\n >\n {change.notice.text}\n </Notice>\n ) : null}\n </div>\n );\n}\n","import type { AdminProduct } from '@develemit/commerce-contracts';\nimport { Money } from '../../components/money/money';\nimport { StatusBadge } from '../../components/status-badge/status-badge';\nimport { displayStatus } from '../../lib/product-filter';\nimport { missingDetail } from '../../lib/product-missing';\nimport { useAdmin } from '../../lib/provider';\n\nexport interface ProductCardProps {\n product: AdminProduct;\n onOpen: () => void;\n}\n\nexport function ProductCard({ product, onOpen }: ProductCardProps) {\n const { labels, renderImage } = useAdmin();\n const copy = labels.products;\n const status = displayStatus(product);\n const missing = missingDetail(product, copy.card);\n const cover = product.images[0];\n const nameLink = (\n <button\n type=\"button\"\n className=\"sfa-card__name sfa-link--tap\"\n onClick={onOpen}\n >\n {product.name}\n </button>\n );\n const face = (\n <div className=\"sfa-card__face\">\n <span className=\"sfa-card__photo\">\n {cover ? (\n renderImage({\n src: cover.url,\n alt: cover.alt,\n sizes: '(min-width: 900px) 20vw, 50vw',\n })\n ) : (\n <span className=\"sfa-card__nophoto\">{copy.card.noPhoto}</span>\n )}\n <span className=\"sfa-card__pill\">\n <StatusBadge status={status} />\n </span>\n {product.featured ? (\n <span\n className=\"sfa-card__star\"\n role=\"img\"\n aria-label={copy.card.featured}\n >\n ★\n </span>\n ) : null}\n </span>\n {nameLink}\n <span className={`sfa-card__price${missing ? ' is-missing' : ''}`}>\n {missing ??\n (product.priceCents === null ? (\n '—'\n ) : (\n <Money cents={product.priceCents} currency={product.currency} />\n ))}\n </span>\n </div>\n );\n return (\n <li className=\"sfa-card\" data-status={status}>\n {face}\n </li>\n );\n}\n","import { useState } from 'react';\nimport type { AdminProductCounts } from '@develemit/commerce-contracts';\nimport type { ProductFilter } from '../../lib/product-labels';\nimport { useAdmin } from '../../lib/provider';\n\nconst FILTERS: ProductFilter[] = ['all', 'live', 'sold', 'draft', 'archived'];\n\nexport interface ProductToolbarProps {\n filter: ProductFilter;\n onFilter: (filter: ProductFilter) => void;\n search: string;\n onSearch: (value: string) => void;\n counts: AdminProductCounts | undefined;\n}\n\nfunction chipCount(counts: AdminProductCounts, filter: ProductFilter) {\n if (filter === 'all') return counts.all;\n return counts[filter];\n}\n\nexport function ProductToolbar({\n filter,\n onFilter,\n search,\n onSearch,\n counts,\n}: ProductToolbarProps) {\n const { labels } = useAdmin();\n const copy = labels.products;\n const [open, setOpen] = useState(false);\n return (\n <div className=\"sfa-products__toolbar\">\n <div\n role=\"group\"\n aria-label={copy.columns.status}\n className=\"sfa-filter-group\"\n >\n {FILTERS.map((value) => (\n <button\n key={value}\n type=\"button\"\n className=\"sfa-chip\"\n aria-pressed={filter === value}\n onClick={() => onFilter(value)}\n >\n {copy.filters[value]}\n {counts ? (\n <span className=\"sfa-chip__count\">\n {chipCount(counts, value)}\n </span>\n ) : null}\n </button>\n ))}\n </div>\n <button\n type=\"button\"\n className=\"sfa-btn sfa-search-toggle\"\n aria-expanded={open}\n onClick={() => setOpen((v) => !v)}\n >\n {open ? copy.closeSearch : copy.openSearch}\n </button>\n <input\n type=\"search\"\n className={`sfa-search${open ? ' is-open' : ''}`}\n aria-label={copy.searchLabel}\n placeholder={copy.searchPlaceholder}\n value={search}\n onChange={(e) => onSearch(e.target.value)}\n />\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport {\n AdminSetupChecklist,\n type SetupStep,\n} from '../../components/setup-checklist/setup-checklist';\nimport { useAdmin } from '../../lib/provider';\n\nexport interface ProductWelcomeProps {\n art?: ReactNode;\n steps?: SetupStep[];\n onAddMany?: () => void;\n}\n\nfunction DefaultArt() {\n return (\n <svg\n className=\"sfa-welcome__art\"\n viewBox=\"0 0 120 120\"\n width=\"120\"\n height=\"120\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <rect\n x=\"18\"\n y=\"30\"\n width=\"84\"\n height=\"64\"\n rx=\"10\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n />\n <circle\n cx=\"45\"\n cy=\"55\"\n r=\"8\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n />\n <path\n d=\"M22 88l26-24 18 16 14-12 20 18\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nexport function ProductWelcome({ art, steps, onAddMany }: ProductWelcomeProps) {\n const { labels, hrefs, renderLink } = useAdmin();\n const copy = labels.products.welcome;\n return (\n <div className=\"sfa-welcome\">\n <div className=\"sfa-welcome__hero\">\n {art ?? <DefaultArt />}\n <h2 className=\"sfa-welcome__title\">{copy.title}</h2>\n <p className=\"sfa-welcome__body\">{copy.body}</p>\n <div className=\"sfa-welcome__actions\">\n {renderLink({\n href: hrefs.newProduct,\n children: copy.addFirst,\n className: 'sfa-btn sfa-btn--primary',\n })}\n {onAddMany ? (\n <button type=\"button\" className=\"sfa-btn\" onClick={onAddMany}>\n {copy.addMany}\n </button>\n ) : null}\n </div>\n </div>\n {steps ? <AdminSetupChecklist steps={steps} /> : null}\n </div>\n );\n}\n","import { useState, type ReactNode } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { AdminPageHeader } from '../../components/page-header/admin-page-header';\nimport {\n AdminSetupChecklist,\n type SetupStep,\n} from '../../components/setup-checklist/setup-checklist';\nimport { serverStatus, serverStock } from '../../lib/product-filter';\nimport type { ProductFilter } from '../../lib/product-labels';\nimport { fillCount } from '../../lib/product-missing';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useAdminQuery } from '../../lib/use-admin-query';\nimport { useDebounced } from '../../lib/use-debounced';\nimport { useProductPages } from '../../lib/use-product-pages';\nimport { AdminProductSheet } from './product-sheet/admin-product-sheet';\nimport type { EditProduct } from './product-sheet/sheet-edit-link';\nimport { ProductCard } from './product-card';\nimport { ProductToolbar } from './product-toolbar';\nimport { ProductWelcome } from './product-welcome';\n\nexport interface AdminProductListProps {\n welcome?: ReactNode;\n setup?: SetupStep[];\n onAddMany?: () => void;\n onFinishDrafts?: () => void;\n onOpenProduct?: (product: AdminProduct) => void;\n onEditProduct?: EditProduct;\n}\n\nexport function AdminProductList({\n welcome,\n setup,\n onAddMany,\n onFinishDrafts,\n onOpenProduct,\n onEditProduct,\n}: AdminProductListProps = {}) {\n const client = useAdminClient();\n const { labels, hrefs, renderLink } = useAdmin();\n const copy = labels.products;\n const [filter, setFilter] = useState<ProductFilter>('all');\n const [search, setSearch] = useState('');\n const q = useDebounced(search.trim(), 300);\n const status = serverStatus(filter);\n const stock = serverStock(filter);\n const pages = useProductPages({\n ...(status ? { status } : {}),\n ...(filter === 'all' ? { excludeArchived: 'true' as const } : {}),\n ...(stock ? { stock } : {}),\n ...(q ? { q } : {}),\n });\n const counts = useAdminQuery(['admin-product-counts'], () =>\n client.getProductCounts(),\n );\n const [openId, setOpenId] = useState<string | null>(null);\n\n const refresh = () => {\n pages.reload();\n counts.reload();\n };\n\n const totals = counts.data;\n const shopEmpty = totals ? totals.all + totals.archived === 0 : false;\n const waiting = !totals && !counts.error;\n const rows = pages.items;\n const emptyText = q ? copy.noMatches : copy.empty[filter];\n const drafts = totals?.incompleteDrafts ?? 0;\n\n const addButton = renderLink({\n href: hrefs.newProduct,\n children: copy.newProduct,\n className: 'sfa-btn sfa-btn--primary',\n });\n\n const body = () => {\n if (waiting || (pages.loading && !pages.loaded && !shopEmpty)) {\n return <p>{labels.loading}</p>;\n }\n if (shopEmpty) {\n return (\n <ProductWelcome art={welcome} steps={setup} onAddMany={onAddMany} />\n );\n }\n return (\n <>\n {setup ? <AdminSetupChecklist steps={setup} compact /> : null}\n {drafts > 0 ? (\n <div className=\"sfa-banner\" role=\"status\">\n <span>\n {fillCount(\n drafts === 1 ? copy.draftsBanner.one : copy.draftsBanner.many,\n {\n count: drafts,\n },\n )}\n </span>\n {onFinishDrafts ? (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n onClick={onFinishDrafts}\n >\n {copy.draftsBanner.finish}\n </button>\n ) : null}\n </div>\n ) : null}\n <ProductToolbar\n filter={filter}\n onFilter={setFilter}\n search={search}\n onSearch={setSearch}\n counts={totals}\n />\n {rows.length === 0 ? (\n <p className=\"sfa-empty\">{emptyText}</p>\n ) : (\n <ul className=\"sfa-grid\">\n {rows.map((p) => (\n <ProductCard\n key={p.id}\n product={p}\n onOpen={() =>\n onOpenProduct ? onOpenProduct(p) : setOpenId(p.id)\n }\n />\n ))}\n </ul>\n )}\n {pages.hasMore ? (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-products__more\"\n disabled={pages.loadingMore}\n onClick={pages.loadMore}\n >\n {copy.loadMore}\n </button>\n ) : null}\n </>\n );\n };\n\n return (\n <section className=\"sfa-products\">\n <AdminPageHeader\n title={copy.title}\n floatingAction={shopEmpty ? undefined : addButton}\n />\n <ErrorMessage error={pages.error ?? counts.error} />\n {body()}\n {openId ? (\n <AdminProductSheet\n productId={openId}\n onClose={() => setOpenId(null)}\n onEdit={onEditProduct}\n onChanged={refresh}\n />\n ) : null}\n </section>\n );\n}\n","export interface SwitchProps {\n id: string;\n label: string;\n checked: boolean;\n onChange: (checked: boolean) => void;\n}\n\nexport function Switch({ id, label, checked, onChange }: SwitchProps) {\n return (\n <label className=\"sfa-switch\" htmlFor={id}>\n <span>{label}</span>\n <input\n id={id}\n type=\"checkbox\"\n role=\"switch\"\n checked={checked}\n onChange={(event) => onChange(event.target.checked)}\n />\n </label>\n );\n}\n","const MONEY = /^\\$?\\s*(\\d+|\\d{1,3}(?:,\\d{3})+)?(?:\\.(\\d{1,2}))?$/;\n\nexport function parseMoneyInput(raw: string): number | null {\n const text = raw.trim();\n const match = MONEY.exec(text);\n if (!match || (!match[1] && !match[2])) return null;\n const whole = Number((match[1] ?? '0').replace(/,/g, ''));\n const fraction = Number((match[2] ?? '').padEnd(2, '0'));\n const cents = whole * 100 + fraction;\n return Number.isSafeInteger(cents) ? cents : null;\n}\n\nexport function formatMoneyInput(cents: number): string {\n const whole = Math.floor(cents / 100);\n const fraction = String(cents % 100).padStart(2, '0');\n return `${whole}.${fraction}`;\n}\n","import type {\n AdminProduct,\n AdminProductInput,\n AdminProductPatch,\n} from '@develemit/commerce-contracts';\nimport { parseMoneyInput } from './money-input';\nimport type { ProductForm } from './product-form';\n\nfunction blankToNull(value: string): string | null {\n const trimmed = value.trim();\n return trimmed === '' ? null : trimmed;\n}\n\nfunction wholeNumber(value: string): number | null {\n return /^\\d+$/.test(value.trim()) ? Number(value.trim()) : null;\n}\n\nfunction savableFields(form: ProductForm) {\n const name = form.name.trim();\n const category = form.category.trim();\n const priceCents = parseMoneyInput(form.price);\n const quantity = wholeNumber(form.quantity);\n return {\n ...(name ? { name } : {}),\n ...(category ? { category } : {}),\n ...(priceCents === null ? {} : { priceCents }),\n ...(quantity === null ? {} : { quantity }),\n description: form.description,\n materials: blankToNull(form.materials),\n dimensions: blankToNull(form.dimensions),\n featured: form.featured,\n };\n}\n\nexport function hasDraftContent(form: ProductForm): boolean {\n return form.name.trim() !== '';\n}\n\nexport function draftInput(\n form: ProductForm,\n currency?: string,\n): AdminProductInput {\n return {\n ...savableFields(form),\n ...(currency ? { currency } : {}),\n status: 'draft',\n };\n}\n\nexport function draftPatch(\n base: AdminProduct,\n form: ProductForm,\n): AdminProductPatch {\n const patch: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(savableFields(form))) {\n if (value !== base[key as keyof AdminProduct]) patch[key] = value;\n }\n return patch as AdminProductPatch;\n}\n\nexport function basicsReady(form: ProductForm): boolean {\n return (\n form.name.trim() !== '' &&\n form.category.trim() !== '' &&\n parseMoneyInput(form.price) !== null\n );\n}\n\nexport function splitMaterials(value: string): string[] {\n return value\n .split(',')\n .map((part) => part.trim())\n .filter(Boolean);\n}\n\nexport function toggleMaterial(value: string, material: string): string {\n const list = splitMaterials(value);\n const next = list.includes(material)\n ? list.filter((item) => item !== material)\n : [...list, material];\n return next.join(', ');\n}\n\nexport function appendPrompt(description: string, prompt: string): string {\n const trimmed = description.trimEnd();\n return trimmed ? `${trimmed}\\n${prompt}` : prompt;\n}\n\nexport function currencySymbol(locale: string, currency: string): string {\n const parts = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n }).formatToParts(0);\n return parts.find((part) => part.type === 'currency')?.value ?? currency;\n}\n\nexport function fillText(template: string, values: Record<string, string>) {\n return template.replace(/\\{(\\w+)\\}/g, (_, key: string) => values[key] ?? '');\n}\n","import { useState } from 'react';\nimport { Switch } from '../../../components/switch/switch';\nimport { currencySymbol } from '../../../lib/product-draft';\nimport { useAdmin } from '../../../lib/provider';\nimport type { FlowSectionProps } from './flow-section-props';\n\nexport interface BasicsSectionProps extends FlowSectionProps {\n categories?: string[];\n currency: string;\n}\n\nfunction categoryChoices(categories: string[] | undefined, current: string) {\n const list = [...(categories ?? [])];\n const trimmed = current.trim();\n if (trimmed && !list.includes(trimmed)) list.push(trimmed);\n return list;\n}\n\nexport function BasicsSection({\n form,\n update,\n categories,\n currency,\n}: BasicsSectionProps) {\n const { labels, locale } = useAdmin();\n const copy = labels.products.flow;\n const fields = labels.products.fields;\n const choices = categoryChoices(categories, form.category);\n const [custom, setCustom] = useState(false);\n const [oneOfAKind, setOneOfAKind] = useState(form.quantity.trim() === '1');\n\n const toggleOneOfAKind = (checked: boolean) => {\n setOneOfAKind(checked);\n if (checked) update('quantity', '1');\n else if (form.quantity.trim() === '1') update('quantity', '2');\n };\n\n return (\n <>\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor=\"sfa-flow-name\">\n {fields.name}\n </label>\n <input\n id=\"sfa-flow-name\"\n type=\"text\"\n autoComplete=\"off\"\n value={form.name}\n onChange={(e) => update('name', e.target.value)}\n />\n </div>\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor=\"sfa-flow-price\">\n {fields.price}\n </label>\n <span className=\"sfa-flow__price\">\n <span aria-hidden=\"true\">{currencySymbol(locale, currency)}</span>\n <input\n id=\"sfa-flow-price\"\n type=\"text\"\n inputMode=\"decimal\"\n placeholder={copy.pricePlaceholder}\n value={form.price}\n onChange={(e) => update('price', e.target.value)}\n />\n </span>\n </div>\n {choices.length ? (\n <div\n className=\"sfa-field\"\n role=\"group\"\n aria-labelledby=\"sfa-flow-category-label\"\n >\n <span id=\"sfa-flow-category-label\" className=\"sfa-field__label\">\n {fields.category}\n </span>\n <div className=\"sfa-flow__chips\">\n {choices.map((choice) => (\n <button\n key={choice}\n type=\"button\"\n className=\"sfa-chip\"\n aria-pressed={!custom && form.category.trim() === choice}\n onClick={() => {\n setCustom(false);\n update('category', choice);\n }}\n >\n {choice}\n </button>\n ))}\n <button\n type=\"button\"\n className=\"sfa-chip\"\n aria-pressed={custom}\n onClick={() => {\n setCustom(true);\n update('category', '');\n }}\n >\n {copy.otherCategory}\n </button>\n </div>\n {custom ? (\n <input\n type=\"text\"\n aria-label={copy.newCategory}\n value={form.category}\n onChange={(e) => update('category', e.target.value)}\n />\n ) : null}\n </div>\n ) : (\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor=\"sfa-flow-category\">\n {fields.category}\n </label>\n <input\n id=\"sfa-flow-category\"\n type=\"text\"\n value={form.category}\n onChange={(e) => update('category', e.target.value)}\n />\n </div>\n )}\n <Switch\n id=\"sfa-flow-one-of-a-kind\"\n label={copy.oneOfAKind}\n checked={oneOfAKind}\n onChange={toggleOneOfAKind}\n />\n {oneOfAKind ? null : (\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor=\"sfa-flow-quantity\">\n {copy.howMany}\n </label>\n <input\n id=\"sfa-flow-quantity\"\n type=\"text\"\n inputMode=\"numeric\"\n value={form.quantity}\n onChange={(e) => update('quantity', e.target.value)}\n />\n </div>\n )}\n </>\n );\n}\n","import type { ProductFlowStep } from '../../../lib/product-flow-labels';\nimport { PRODUCT_FLOW_STEPS } from '../../../lib/product-flow-labels';\nimport { basicsReady } from '../../../lib/product-draft';\nimport { useAdmin } from '../../../lib/provider';\nimport type { ProductFlowState } from './use-product-flow';\n\nexport function nextStep(step: ProductFlowStep): ProductFlowStep {\n const index = PRODUCT_FLOW_STEPS.indexOf(step);\n return PRODUCT_FLOW_STEPS[Math.min(index + 1, PRODUCT_FLOW_STEPS.length - 1)];\n}\n\nexport function previousStep(step: ProductFlowStep): ProductFlowStep | null {\n const index = PRODUCT_FLOW_STEPS.indexOf(step);\n return index > 0 ? PRODUCT_FLOW_STEPS[index - 1] : null;\n}\n\nexport function FinishActions({ flow }: { flow: ProductFlowState }) {\n const { labels } = useAdmin();\n const copy = labels.products.flow;\n const draft = (flow.product?.status ?? 'draft') === 'draft';\n if (!draft) {\n return (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={flow.pending}\n onClick={flow.saveDraft}\n >\n {copy.done}\n </button>\n );\n }\n return (\n <>\n <button\n type=\"button\"\n className=\"sfa-btn\"\n disabled={flow.pending}\n onClick={flow.saveDraft}\n >\n {copy.saveDraft}\n </button>\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={flow.pending}\n onClick={flow.publish}\n >\n {copy.publish}\n </button>\n </>\n );\n}\n\nexport function StepActions({ flow }: { flow: ProductFlowState }) {\n const { labels } = useAdmin();\n const copy = labels.products.flow;\n const goNext = () => flow.goTo(nextStep(flow.step));\n\n if (flow.step === 'photos') {\n const hasPhotos = (flow.product?.images.length ?? 0) > 0;\n return (\n <button\n type=\"button\"\n className={`sfa-btn ${hasPhotos ? 'sfa-btn--primary' : 'sfa-btn--ghost'}`}\n onClick={goNext}\n >\n {hasPhotos ? copy.continue : copy.photosLater}\n </button>\n );\n }\n if (flow.step === 'basics') {\n return (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={!basicsReady(flow.form)}\n onClick={goNext}\n >\n {copy.continue}\n </button>\n );\n }\n if (flow.step === 'story') {\n return (\n <>\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--ghost\"\n onClick={goNext}\n >\n {copy.skip}\n </button>\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n onClick={goNext}\n >\n {copy.continue}\n </button>\n </>\n );\n }\n return <FinishActions flow={flow} />;\n}\n","import type { ReactNode } from 'react';\nimport {\n PRODUCT_FLOW_STEPS,\n type ProductFlowStep,\n} from '../../../lib/product-flow-labels';\nimport { useAdmin } from '../../../lib/provider';\nimport type { AutosaveState } from '../../../lib/use-product-autosave';\n\nexport interface FlowHeadProps {\n title: string;\n onBack: () => void;\n canGoBack: boolean;\n close: ReactNode;\n}\n\nexport function FlowHead({ title, onBack, canGoBack, close }: FlowHeadProps) {\n const { labels } = useAdmin();\n return (\n <div className=\"sfa-flow__head\">\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--ghost sfa-flow__back\"\n aria-label={labels.products.flow.back}\n disabled={!canGoBack}\n onClick={onBack}\n >\n ‹\n </button>\n <h1 className=\"sfa-flow__title\">{title}</h1>\n {close}\n </div>\n );\n}\n\nexport interface StepBarProps {\n step: ProductFlowStep;\n allOpen: boolean;\n onStep: (step: ProductFlowStep) => void;\n}\n\nexport function StepBar({ step, allOpen, onStep }: StepBarProps) {\n const { labels } = useAdmin();\n const copy = labels.products.flow;\n const current = PRODUCT_FLOW_STEPS.indexOf(step);\n return (\n <nav className=\"sfa-flow__steps\" aria-label={copy.stepsLabel}>\n <ol>\n {PRODUCT_FLOW_STEPS.map((item, index) => (\n <li key={item}>\n <button\n type=\"button\"\n aria-current={index === current ? 'step' : undefined}\n data-state={index < current ? 'done' : undefined}\n disabled={!allOpen && index > current}\n onClick={() => onStep(item)}\n >\n {copy.steps[item]}\n </button>\n </li>\n ))}\n </ol>\n </nav>\n );\n}\n\nexport interface SaveNoteProps {\n state: AutosaveState;\n isNew: boolean;\n onRetry: () => void;\n}\n\nexport function SaveNote({ state, isNew, onRetry }: SaveNoteProps) {\n const { labels } = useAdmin();\n const copy = labels.products.flow;\n if (state === 'idle') return null;\n if (state === 'error') {\n return (\n <div className=\"sfa-flow__saved is-error\" role=\"alert\">\n <span>{copy.saveFailed}</span>\n <button type=\"button\" className=\"sfa-btn\" onClick={onRetry}>\n {copy.retry}\n </button>\n </div>\n );\n }\n return (\n <p className=\"sfa-flow__saved\" role=\"status\">\n {state === 'saving'\n ? copy.saving\n : isNew\n ? copy.savedNew\n : copy.savedEdit}\n </p>\n );\n}\n\nexport interface FlowSectionFrameProps {\n step: ProductFlowStep;\n active: boolean;\n children: ReactNode;\n}\n\nexport function FlowSectionFrame({\n step,\n active,\n children,\n}: FlowSectionFrameProps) {\n const { labels } = useAdmin();\n const copy = labels.products.flow;\n return (\n <section\n id={`sfa-flow-${step}`}\n className={`sfa-flow__section sfa-flow__section--${step}`}\n data-active={active}\n aria-labelledby={`sfa-flow-${step}-title`}\n >\n <h2 id={`sfa-flow-${step}-title`}>{copy.headings[step]}</h2>\n <p className=\"sfa-flow__lede\">{copy.ledes[step]}</p>\n {children}\n </section>\n );\n}\n","import type { AdminProduct } from '@develemit/commerce-contracts';\n\nexport function sortedImages(product: AdminProduct | null) {\n return [...(product?.images ?? [])].sort((a, b) => a.position - b.position);\n}\n","import type { AdminProduct } from '@develemit/commerce-contracts';\nimport { Money } from '../../../components/money/money';\nimport { useAdmin } from '../../../lib/provider';\nimport { sortedImages } from './flow-images';\nimport type { FlowSuccess } from './use-product-flow';\n\nexport interface FlowSuccessViewProps {\n success: FlowSuccess;\n onAddAnother: () => void;\n onDone?: (product: AdminProduct) => void;\n}\n\nexport function FlowSuccessView({\n success,\n onAddAnother,\n onDone,\n}: FlowSuccessViewProps) {\n const { labels, hrefs, renderImage, renderLink } = useAdmin();\n const copy = labels.products.flow;\n const { product, first } = success;\n const cover = sortedImages(product)[0];\n return (\n <section className=\"sfa-flow-success\" aria-labelledby=\"sfa-flow-success\">\n <span className=\"sfa-flow-success__photo\">\n {cover\n ? renderImage({ src: cover.url, alt: cover.alt, sizes: '170px' })\n : null}\n </span>\n <h2 id=\"sfa-flow-success\" tabIndex={-1}>\n {first ? copy.successFirst : copy.success}\n </h2>\n <p>\n {product.name}\n {product.priceCents === null ? null : (\n <>\n {' · '}\n <Money cents={product.priceCents} currency={product.currency} />\n </>\n )}\n </p>\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n onClick={onAddAnother}\n >\n {copy.addAnother}\n </button>\n {onDone ? (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n onClick={() => onDone(product)}\n >\n {copy.backToList}\n </button>\n ) : (\n renderLink({\n href: hrefs.products,\n children: copy.backToList,\n className: 'sfa-btn',\n })\n )}\n </section>\n );\n}\n","import type { ImageLabels } from './image-labels';\n\nexport const MAX_IMAGE_BYTES = 8 * 1024 * 1024;\n\nconst ACCEPTED_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/heic'];\n\nexport function fill(template: string, values: Record<string, string>) {\n return template.replace(/\\{(\\w+)\\}/g, (_, key: string) => values[key] ?? '');\n}\n\nexport function imageFileProblem(\n file: File,\n labels: ImageLabels,\n): string | null {\n if (!ACCEPTED_TYPES.includes(file.type)) {\n return fill(labels.wrongType, { name: file.name });\n }\n if (file.size > MAX_IMAGE_BYTES) {\n return fill(labels.tooLarge, { name: file.name });\n }\n return null;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { imageFileProblem } from './image-rules';\nimport { useAdmin, useAdminClient } from './provider';\n\nexport interface UploadEntry {\n id: number;\n name: string;\n status: 'queued' | 'uploading' | 'error';\n reason?: string;\n error?: unknown;\n}\n\ninterface Options {\n productId?: string;\n resolveProductId?: () => Promise<string>;\n onUploaded: (product: AdminProduct) => void;\n}\n\nexport function useImageUpload({\n productId,\n resolveProductId,\n onUploaded,\n}: Options) {\n const client = useAdminClient();\n const { labels } = useAdmin();\n const [entries, setEntries] = useState<UploadEntry[]>([]);\n const nextId = useRef(0);\n const chain = useRef<Promise<void>>(Promise.resolve());\n const onUploadedRef = useRef(onUploaded);\n const target = useRef({ productId, resolveProductId });\n useEffect(() => {\n onUploadedRef.current = onUploaded;\n target.current = { productId, resolveProductId };\n });\n\n const currentId = async () => {\n const { productId: id, resolveProductId: resolve } = target.current;\n if (id) return id;\n if (!resolve) throw new Error('useImageUpload needs a productId.');\n return resolve();\n };\n\n const patch = (id: number, change: Partial<UploadEntry>) =>\n setEntries((prev) =>\n prev.map((entry) => (entry.id === id ? { ...entry, ...change } : entry)),\n );\n const drop = (id: number) =>\n setEntries((prev) => prev.filter((entry) => entry.id !== id));\n\n const send = async (id: number, file: File, alt: string) => {\n patch(id, { status: 'uploading' });\n try {\n const product = await client.uploadProductImage(\n await currentId(),\n file,\n alt,\n );\n onUploadedRef.current(product);\n drop(id);\n } catch (error) {\n patch(id, { status: 'error', error });\n }\n };\n\n const upload = useCallback(\n (files: File[], alt: string) => {\n const added = files.map((file) => ({\n id: nextId.current++,\n file,\n reason: imageFileProblem(file, labels.products.images),\n }));\n setEntries((prev) => [\n ...prev,\n ...added.map(({ id, file, reason }): UploadEntry => ({\n id,\n name: file.name,\n status: reason ? 'error' : 'queued',\n reason: reason ?? undefined,\n })),\n ]);\n for (const { id, file, reason } of added) {\n if (reason) continue;\n chain.current = chain.current.then(() => send(id, file, alt.trim()));\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [client, labels],\n );\n\n return { entries, upload, dismiss: drop };\n}\n","import { useState, type ChangeEvent, type ReactNode } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../../components/error-message/error-message';\nimport { Notice } from '../../../components/notice/notice';\nimport { fillText } from '../../../lib/product-draft';\nimport { useAdmin, useAdminClient } from '../../../lib/provider';\nimport {\n useImageUpload,\n type UploadEntry,\n} from '../../../lib/use-image-upload';\nimport { sortedImages } from './flow-images';\n\nexport interface PhotosSectionProps {\n product: AdminProduct | null;\n ensureProduct: () => Promise<AdminProduct>;\n setProduct: (next: AdminProduct) => void;\n imagesSlot?: ReactNode;\n}\n\nexport function PhotosSection({\n product,\n ensureProduct,\n setProduct,\n imagesSlot,\n}: PhotosSectionProps) {\n const client = useAdminClient();\n const { labels, renderImage } = useAdmin();\n const copy = labels.products.flow;\n const [failure, setFailure] = useState<unknown>(undefined);\n const [busy, setBusy] = useState(false);\n const images = sortedImages(product);\n const { entries, upload, dismiss } = useImageUpload({\n productId: product?.id,\n resolveProductId: async () => (await ensureProduct()).id,\n onUploaded: setProduct,\n });\n\n if (imagesSlot) return imagesSlot;\n\n const pick = (event: ChangeEvent<HTMLInputElement>) => {\n upload(Array.from(event.target.files ?? []), '');\n event.target.value = '';\n };\n\n const change = async (work: (id: string) => Promise<AdminProduct>) => {\n if (!product || busy) return;\n setBusy(true);\n setFailure(undefined);\n try {\n setProduct(await work(product.id));\n } catch (error) {\n setFailure(error);\n } finally {\n setBusy(false);\n }\n };\n\n const makeCover = (imageId: string) =>\n change((id) =>\n client.reorderProductImages(id, [\n imageId,\n ...images.filter((image) => image.id !== imageId).map((i) => i.id),\n ]),\n );\n\n return (\n <>\n <label className=\"sfa-flow__dropzone\">\n <span className=\"sfa-flow__dropzone-icon\" aria-hidden=\"true\">\n +\n </span>\n <strong>{images.length ? copy.addMorePhotos : copy.addPhotos}</strong>\n <small>{copy.photoHint}</small>\n <input\n type=\"file\"\n accept=\"image/*\"\n multiple\n className=\"sfa-sr-only\"\n onChange={pick}\n />\n </label>\n <ErrorMessage error={failure} />\n {images.length || entries.length ? (\n <ul className=\"sfa-flow__thumbs\">\n {images.map((image, index) => {\n const n = String(index + 1);\n return (\n <li\n key={image.id}\n className={`sfa-flow__thumb${index === 0 ? ' is-cover' : ''}`}\n >\n <button\n type=\"button\"\n className=\"sfa-flow__thumb-pick\"\n aria-label={\n index === 0\n ? `${fillText(copy.photoN, { n })}, ${copy.cover}`\n : fillText(copy.makeCover, { n })\n }\n aria-pressed={index === 0}\n disabled={busy}\n onClick={() =>\n index === 0 ? undefined : makeCover(image.id)\n }\n >\n {renderImage({ src: image.url, alt: '', sizes: '120px' })}\n {index === 0 ? (\n <span className=\"sfa-flow__badge\">{copy.cover}</span>\n ) : null}\n </button>\n <button\n type=\"button\"\n className=\"sfa-flow__thumb-remove\"\n aria-label={fillText(copy.removePhoto, { n })}\n disabled={busy}\n onClick={() =>\n change((id) => client.deleteProductImage(id, image.id))\n }\n >\n ✕\n </button>\n </li>\n );\n })}\n {entries.map((entry) => (\n <UploadTile key={entry.id} entry={entry} onDismiss={dismiss} />\n ))}\n </ul>\n ) : null}\n <p className=\"sfa-flow__tip\">{copy.photoTip}</p>\n </>\n );\n}\n\nfunction UploadTile({\n entry,\n onDismiss,\n}: {\n entry: UploadEntry;\n onDismiss: (id: number) => void;\n}) {\n const { labels } = useAdmin();\n if (entry.status !== 'error') {\n return (\n <li className=\"sfa-flow__thumb is-uploading\" aria-busy=\"true\">\n <span className=\"sfa-spinner\" role=\"status\">\n {fillText(labels.products.flow.uploading, { name: entry.name })}\n </span>\n </li>\n );\n }\n return (\n <li className=\"sfa-flow__thumb is-failed\">\n {entry.reason ? (\n <Notice variant=\"error\">{entry.reason}</Notice>\n ) : (\n <ErrorMessage error={entry.error} />\n )}\n <button\n type=\"button\"\n className=\"sfa-btn\"\n onClick={() => onDismiss(entry.id)}\n >\n {labels.products.images.dismiss}\n </button>\n </li>\n );\n}\n","import type { ReactNode } from 'react';\nimport type {\n AdminProduct,\n ProductIncompleteField,\n} from '@develemit/commerce-contracts';\nimport { Money } from '../../../components/money/money';\nimport { Notice } from '../../../components/notice/notice';\nimport { Switch } from '../../../components/switch/switch';\nimport { parseMoneyInput } from '../../../lib/money-input';\nimport { useAdmin } from '../../../lib/provider';\nimport { sortedImages } from './flow-images';\nimport type { FlowSectionProps } from './flow-section-props';\n\nexport interface PreviewSectionProps extends FlowSectionProps {\n product: AdminProduct | null;\n currency: string;\n missing: ProductIncompleteField[] | null;\n actions: ReactNode;\n}\n\nexport function PreviewSection({\n form,\n update,\n product,\n currency,\n missing,\n actions,\n}: PreviewSectionProps) {\n const { labels, renderImage } = useAdmin();\n const copy = labels.products.flow;\n const missingCopy = labels.products.sheet.missing;\n const cover = sortedImages(product)[0];\n const priceCents = parseMoneyInput(form.price);\n\n return (\n <>\n <div className=\"sfa-flow__preview\">\n <p className=\"sfa-flow__preview-label\">{copy.inTheShop}</p>\n <div className=\"sfa-flow__card\">\n <span className=\"sfa-flow__card-photo\">\n {cover ? (\n renderImage({\n src: cover.url,\n alt: cover.alt,\n sizes: '(min-width: 900px) 240px, 60vw',\n })\n ) : (\n <span className=\"sfa-flow__card-empty\">{copy.noPhoto}</span>\n )}\n </span>\n <p className=\"sfa-flow__card-name\">\n {form.name.trim() || copy.untitled}\n </p>\n <p className=\"sfa-flow__card-price\">\n {priceCents === null ? (\n '—'\n ) : (\n <Money cents={priceCents} currency={currency} />\n )}\n </p>\n </div>\n {form.description.trim() ? (\n <p className=\"sfa-flow__preview-desc\">{form.description}</p>\n ) : null}\n </div>\n <Switch\n id=\"sfa-flow-featured\"\n label={copy.featured}\n checked={form.featured}\n onChange={(checked) => update('featured', checked)}\n />\n {missing ? (\n <Notice variant=\"warning\">\n {copy.needs} {missing.map((f) => missingCopy[f] ?? f).join(', ')}\n </Notice>\n ) : null}\n <div className=\"sfa-flow__desk-actions\">{actions}</div>\n </>\n );\n}\n","import { useState } from 'react';\nimport type {\n AdminProduct,\n AdminProductImage,\n} from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../../components/error-message/error-message';\nimport {\n appendPrompt,\n fillText,\n splitMaterials,\n toggleMaterial,\n} from '../../../lib/product-draft';\nimport { useAdmin, useAdminClient } from '../../../lib/provider';\nimport { sortedImages } from './flow-images';\nimport type { FlowSectionProps } from './flow-section-props';\n\nexport interface StorySectionProps extends FlowSectionProps {\n product: AdminProduct | null;\n setProduct: (next: AdminProduct) => void;\n materialSuggestions?: string[];\n}\n\nexport function StorySection({\n form,\n update,\n product,\n setProduct,\n materialSuggestions,\n}: StorySectionProps) {\n const { labels } = useAdmin();\n const copy = labels.products.flow;\n const fields = labels.products.fields;\n const prompts = copy.descriptionPrompts;\n const picked = splitMaterials(form.materials);\n const images = sortedImages(product);\n\n return (\n <>\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor=\"sfa-flow-description\">\n {fields.description}\n </label>\n <textarea\n id=\"sfa-flow-description\"\n rows={5}\n value={form.description}\n onChange={(e) => update('description', e.target.value)}\n />\n {prompts.length ? (\n <div className=\"sfa-flow__chips\">\n {prompts.map((prompt) => (\n <button\n key={prompt}\n type=\"button\"\n className=\"sfa-chip\"\n onClick={() =>\n update('description', appendPrompt(form.description, prompt))\n }\n >\n + {prompt}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor=\"sfa-flow-materials\">\n {fields.materials}\n </label>\n {materialSuggestions?.length ? (\n <div className=\"sfa-flow__chips\">\n {materialSuggestions.map((material) => (\n <button\n key={material}\n type=\"button\"\n className=\"sfa-chip\"\n aria-pressed={picked.includes(material)}\n onClick={() =>\n update('materials', toggleMaterial(form.materials, material))\n }\n >\n {material}\n </button>\n ))}\n </div>\n ) : null}\n <input\n id=\"sfa-flow-materials\"\n type=\"text\"\n placeholder={materialSuggestions?.length ? copy.materialsOther : ''}\n value={form.materials}\n onChange={(e) => update('materials', e.target.value)}\n />\n </div>\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor=\"sfa-flow-size\">\n {copy.size}\n </label>\n <input\n id=\"sfa-flow-size\"\n type=\"text\"\n value={form.dimensions}\n onChange={(e) => update('dimensions', e.target.value)}\n />\n </div>\n {product && images.length ? (\n <fieldset className=\"sfa-flow__alts\">\n <legend className=\"sfa-field__label\">{copy.altTitle}</legend>\n <p className=\"sfa-field__help\">{copy.altHelp}</p>\n {images.map((image, index) => (\n <AltField\n key={image.id}\n productId={product.id}\n image={image}\n label={fillText(copy.photoN, { n: String(index + 1) })}\n placeholder={fillText(copy.altFallback, {\n name: form.name.trim() || copy.untitled,\n n: String(index + 1),\n })}\n onSaved={setProduct}\n />\n ))}\n </fieldset>\n ) : null}\n </>\n );\n}\n\ninterface AltFieldProps {\n productId: string;\n image: AdminProductImage;\n label: string;\n placeholder: string;\n onSaved: (product: AdminProduct) => void;\n}\n\nfunction AltField({\n productId,\n image,\n label,\n placeholder,\n onSaved,\n}: AltFieldProps) {\n const client = useAdminClient();\n const [value, setValue] = useState(image.alt);\n const [failure, setFailure] = useState<unknown>(undefined);\n const id = `sfa-flow-alt-${image.id}`;\n\n const save = async () => {\n if (value.trim() === image.alt) return;\n setFailure(undefined);\n try {\n onSaved(\n await client.updateProductImage(productId, image.id, {\n alt: value.trim(),\n }),\n );\n } catch (error) {\n setFailure(error);\n }\n };\n\n return (\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor={id}>\n {label}\n </label>\n <input\n id={id}\n type=\"text\"\n placeholder={placeholder}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onBlur={save}\n />\n <ErrorMessage error={failure} />\n </div>\n );\n}\n","import {\n adminProductInputSchema,\n type AdminProduct,\n type AdminProductInput,\n type AdminProductPatch,\n type ProductStatus,\n} from '@develemit/commerce-contracts';\nimport { formatMoneyInput, parseMoneyInput } from './money-input';\nimport type { ProductLabels } from './product-labels';\n\nexport const FIELD_ORDER = [\n 'name',\n 'category',\n 'description',\n 'materials',\n 'dimensions',\n 'price',\n 'quantity',\n 'status',\n 'featured',\n] as const;\n\nexport type FieldName = (typeof FIELD_ORDER)[number];\nexport type FieldErrors = Partial<Record<FieldName, string>>;\n\nexport interface ProductForm {\n name: string;\n category: string;\n description: string;\n materials: string;\n dimensions: string;\n price: string;\n quantity: string;\n status: ProductStatus;\n featured: boolean;\n}\n\nexport const emptyForm: ProductForm = {\n name: '',\n category: '',\n description: '',\n materials: '',\n dimensions: '',\n price: '',\n quantity: '1',\n status: 'draft',\n featured: false,\n};\n\nexport function formFromProduct(product: AdminProduct): ProductForm {\n return {\n name: product.name,\n category: product.category ?? '',\n description: product.description,\n materials: product.materials ?? '',\n dimensions: product.dimensions ?? '',\n price:\n product.priceCents === null ? '' : formatMoneyInput(product.priceCents),\n quantity: String(product.quantity),\n status: product.status,\n featured: product.featured,\n };\n}\n\nfunction fieldFor(path: unknown): FieldName | undefined {\n const head = Array.isArray(path) ? String(path[0] ?? '') : String(path ?? '');\n const mapped = head === 'priceCents' ? 'price' : head;\n return (FIELD_ORDER as readonly string[]).includes(mapped)\n ? (mapped as FieldName)\n : undefined;\n}\n\nexport function mapServerIssues(issues: unknown[]): FieldErrors {\n const errors: FieldErrors = {};\n for (const issue of issues) {\n const { path, message } = (issue ?? {}) as {\n path?: unknown;\n message?: unknown;\n };\n const field = fieldFor(path);\n if (field && !errors[field]) {\n errors[field] = typeof message === 'string' ? message : 'Invalid value.';\n }\n }\n return errors;\n}\n\nexport function firstInvalidField(errors: FieldErrors): FieldName | undefined {\n return FIELD_ORDER.find((field) => errors[field]);\n}\n\nexport type ValidationResult =\n { ok: true; input: AdminProductInput } | { ok: false; errors: FieldErrors };\n\nfunction blankToNull(value: string): string | null {\n const trimmed = value.trim();\n return trimmed === '' ? null : trimmed;\n}\n\nexport function validateForm(\n form: ProductForm,\n labels: ProductLabels,\n currency?: string,\n): ValidationResult {\n const errors: FieldErrors = {};\n const priceCents = parseMoneyInput(form.price);\n if (priceCents === null) errors.price = labels.validation.price;\n const quantity = /^\\d+$/.test(form.quantity.trim())\n ? Number(form.quantity.trim())\n : null;\n if (quantity === null) errors.quantity = labels.validation.quantity;\n if (!form.name.trim()) errors.name = labels.validation.required;\n if (!form.category.trim()) errors.category = labels.validation.required;\n\n const parsed = adminProductInputSchema.safeParse({\n name: form.name,\n description: form.description,\n materials: blankToNull(form.materials),\n dimensions: blankToNull(form.dimensions),\n priceCents: priceCents ?? 0,\n ...(currency ? { currency } : {}),\n category: form.category,\n quantity: quantity ?? 0,\n status: form.status,\n featured: form.featured,\n });\n if (!parsed.success) {\n for (const issue of parsed.error.issues) {\n const field = fieldFor(issue.path);\n if (field && !errors[field]) errors[field] = labels.validation.required;\n }\n }\n if (!parsed.success || Object.keys(errors).length > 0) {\n return { ok: false, errors };\n }\n return { ok: true, input: parsed.data };\n}\n\nconst PATCH_KEYS = [\n 'name',\n 'description',\n 'materials',\n 'dimensions',\n 'priceCents',\n 'category',\n 'quantity',\n 'status',\n 'featured',\n] as const;\n\nexport function buildPatch(\n original: AdminProduct,\n input: AdminProductInput,\n): AdminProductPatch {\n const patch: Record<string, unknown> = {};\n for (const key of PATCH_KEYS) {\n const next = input[key] ?? null;\n if (next !== original[key]) patch[key] = input[key];\n }\n return patch as AdminProductPatch;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { draftInput, draftPatch, hasDraftContent } from './product-draft';\nimport type { ProductForm } from './product-form';\nimport { useAdminClient } from './provider';\n\nexport type AutosaveState = 'idle' | 'saving' | 'saved' | 'error';\n\ninterface Options {\n initial: AdminProduct | null;\n form: ProductForm;\n currency?: string;\n delayMs?: number;\n}\n\nexport function useProductAutosave({\n initial,\n form,\n currency,\n delayMs = 600,\n}: Options) {\n const client = useAdminClient();\n const [product, setProductState] = useState(initial);\n const [state, setState] = useState<AutosaveState>(initial ? 'saved' : 'idle');\n const [error, setError] = useState<unknown>(undefined);\n const productRef = useRef(initial);\n const formRef = useRef(form);\n const initialForm = useRef(form);\n const chain = useRef<Promise<unknown>>(Promise.resolve());\n\n const setProduct = useCallback((next: AdminProduct) => {\n productRef.current = next;\n setProductState(next);\n }, []);\n\n const write = useCallback(\n async (force: boolean): Promise<AdminProduct | null> => {\n const base = productRef.current;\n const current = formRef.current;\n if (!base && !force && !hasDraftContent(current)) return null;\n const patch = base ? draftPatch(base, current) : null;\n if (base && patch && Object.keys(patch).length === 0) return base;\n setState('saving');\n try {\n const next = base\n ? await client.updateProduct(base.id, patch!)\n : await client.createProduct(draftInput(current, currency));\n setProduct(next);\n setError(undefined);\n setState('saved');\n return next;\n } catch (failure) {\n setError(failure);\n setState('error');\n return null;\n }\n },\n [client, currency, setProduct],\n );\n\n const queue = useCallback(\n (force: boolean) => {\n const next = chain.current.then(() => write(force));\n chain.current = next;\n return next;\n },\n [write],\n );\n\n const flush = useCallback(() => queue(false), [queue]);\n\n const ensureProduct = useCallback(async () => {\n const next = await queue(true);\n if (!next) throw new Error('Could not save the draft.');\n return next;\n }, [queue]);\n\n useEffect(() => {\n formRef.current = form;\n if (form === initialForm.current) return;\n const timer = setTimeout(() => void queue(false), delayMs);\n return () => clearTimeout(timer);\n }, [form, delayMs, queue]);\n\n return {\n product,\n setProduct,\n state,\n error,\n flush,\n ensureProduct,\n retry: flush,\n };\n}\n","import { useState } from 'react';\nimport type {\n AdminProduct,\n ProductIncompleteField,\n} from '@develemit/commerce-contracts';\nimport { ProductIncompleteError } from '../../../client';\nimport { fillText, hasDraftContent } from '../../../lib/product-draft';\nimport {\n emptyForm,\n formFromProduct,\n type ProductForm,\n} from '../../../lib/product-form';\nimport type { ProductFlowStep } from '../../../lib/product-flow-labels';\nimport { useAdmin, useAdminClient } from '../../../lib/provider';\nimport { useProductAutosave } from '../../../lib/use-product-autosave';\n\nexport interface FlowOptions {\n initial: AdminProduct | null;\n initialStep?: ProductFlowStep;\n isFirstProduct?: boolean;\n onDone?: (product: AdminProduct) => void;\n onClose?: (product: AdminProduct | null) => void;\n}\n\nexport interface FlowSuccess {\n product: AdminProduct;\n first: boolean;\n}\n\nexport function useProductFlow({\n initial,\n initialStep,\n isFirstProduct,\n onDone,\n onClose,\n}: FlowOptions) {\n const client = useAdminClient();\n const { labels } = useAdmin();\n const copy = labels.products.flow;\n const [form, setForm] = useState<ProductForm>(\n initial ? formFromProduct(initial) : emptyForm,\n );\n const [step, setStep] = useState<ProductFlowStep>(initialStep ?? 'photos');\n const autosave = useProductAutosave({ initial, form });\n const [missing, setMissing] = useState<ProductIncompleteField[] | null>(null);\n const [failure, setFailure] = useState<unknown>(undefined);\n const [pending, setPending] = useState(false);\n const [success, setSuccess] = useState<FlowSuccess | null>(null);\n const [notice, setNotice] = useState<string | null>(null);\n const [closing, setClosing] = useState(false);\n const product = autosave.product;\n const isNew = initial === null;\n\n const update = <K extends keyof ProductForm>(\n field: K,\n value: ProductForm[K],\n ) => {\n setMissing(null);\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const fillBlankAlts = async (target: AdminProduct) => {\n const name = form.name.trim();\n if (!name) return target;\n let next = target;\n const sorted = [...target.images].sort((a, b) => a.position - b.position);\n for (const [index, image] of sorted.entries()) {\n if (image.alt.trim()) continue;\n const alt = fillText(copy.altFallback, { name, n: String(index + 1) });\n next = await client.updateProductImage(target.id, image.id, { alt });\n }\n if (next !== target) autosave.setProduct(next);\n return next;\n };\n\n const run = async (work: () => Promise<void>) => {\n setPending(true);\n setFailure(undefined);\n setMissing(null);\n try {\n await work();\n } catch (error) {\n if (error instanceof ProductIncompleteError) setMissing(error.missing);\n else setFailure(error);\n } finally {\n setPending(false);\n }\n };\n\n const finish = (saved: AdminProduct) => {\n if (onDone) onDone(saved);\n else setNotice(labels.products.saved);\n };\n\n const saveDraft = () =>\n run(async () => {\n const saved = await autosave.flush();\n if (!saved) {\n if (!hasDraftContent(form)) await close();\n return;\n }\n finish(await fillBlankAlts(saved));\n });\n\n const publish = () =>\n run(async () => {\n const wasDraft = (product?.status ?? 'draft') === 'draft';\n const saved = await fillBlankAlts(await autosave.ensureProduct());\n const live =\n saved.status === 'active'\n ? saved\n : await client.updateProduct(saved.id, { status: 'active' });\n autosave.setProduct(live);\n if (!wasDraft) return finish(live);\n const first =\n isFirstProduct ?? (await client.getProductCounts()).live === 1;\n setSuccess({ product: live, first });\n });\n\n const close = async () => {\n const saved = (await autosave.flush()) ?? autosave.product;\n if (isNew && saved && saved.status === 'draft' && !success) {\n setClosing(true);\n return;\n }\n onClose?.(saved);\n };\n\n const finishClosing = () => {\n setClosing(false);\n onClose?.(autosave.product);\n };\n\n return {\n form,\n update,\n step,\n goTo: setStep,\n product,\n isNew,\n autosave,\n missing,\n failure,\n pending,\n success,\n notice,\n dismissNotice: () => setNotice(null),\n closing,\n finishClosing,\n saveDraft,\n publish,\n close,\n };\n}\n\nexport type ProductFlowState = ReturnType<typeof useProductFlow>;\n","import { useEffect, useRef, useState, type ReactNode } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../../components/error-message/error-message';\nimport { Notice } from '../../../components/notice/notice';\nimport type { ProductFlowStep } from '../../../lib/product-flow-labels';\nimport { useAdmin, useAdminClient } from '../../../lib/provider';\nimport { useAdminQuery } from '../../../lib/use-admin-query';\nimport { BasicsSection } from './basics-section';\nimport { FinishActions, StepActions, previousStep } from './flow-actions';\nimport { FlowHead, FlowSectionFrame, SaveNote, StepBar } from './flow-frame';\nimport { FlowSuccessView } from './flow-success';\nimport { PhotosSection } from './photos-section';\nimport { PreviewSection } from './preview-section';\nimport { StorySection } from './story-section';\nimport { useProductFlow } from './use-product-flow';\n\nexport type { ProductFlowStep } from '../../../lib/product-flow-labels';\n\nexport interface AdminProductFlowProps {\n productId?: string;\n initialStep?: ProductFlowStep;\n onDone?: (product: AdminProduct) => void;\n onClose?: (product: AdminProduct | null) => void;\n categories?: string[];\n materialSuggestions?: string[];\n isFirstProduct?: boolean;\n imagesSlot?: ReactNode;\n}\n\nexport function AdminProductFlow(props: AdminProductFlowProps) {\n const [session, setSession] = useState({\n key: 0,\n productId: props.productId,\n });\n const addAnother = () =>\n setSession((prev) => ({ key: prev.key + 1, productId: undefined }));\n if (!session.productId) {\n return (\n <FlowView\n key={session.key}\n {...props}\n initial={null}\n initialStep={undefined}\n imagesSlot={undefined}\n onAddAnother={addAnother}\n />\n );\n }\n return (\n <ExistingProductFlow\n key={session.key}\n {...props}\n productId={session.productId}\n onAddAnother={addAnother}\n />\n );\n}\n\ntype ViewProps = Omit<AdminProductFlowProps, 'productId'> & {\n onAddAnother: () => void;\n};\n\nfunction ExistingProductFlow({\n productId,\n ...props\n}: ViewProps & { productId: string }) {\n const client = useAdminClient();\n const { labels } = useAdmin();\n const query = useAdminQuery(['admin-product', productId], () =>\n client.getProduct(productId),\n );\n if (query.error) return <ErrorMessage error={query.error} />;\n if (!query.data) return <p>{labels.loading}</p>;\n return <FlowView key={query.data.id} {...props} initial={query.data} />;\n}\n\nfunction FlowView({\n initial,\n initialStep,\n onDone,\n onClose,\n categories,\n materialSuggestions,\n isFirstProduct,\n imagesSlot,\n onAddAnother,\n}: ViewProps & { initial: AdminProduct | null }) {\n const { labels, hrefs, renderLink, currency: defaultCurrency } = useAdmin();\n const copy = labels.products.flow;\n const flow = useProductFlow({\n initial,\n initialStep,\n isFirstProduct,\n onDone,\n onClose,\n });\n const currency = flow.product?.currency ?? defaultCurrency;\n const section = { form: flow.form, update: flow.update };\n const rootRef = useRef<HTMLDivElement>(null);\n const firstRender = useRef(true);\n\n useEffect(() => {\n const scroll = !firstRender.current || initialStep !== undefined;\n firstRender.current = false;\n if (!scroll) return;\n rootRef.current\n ?.querySelector(`#sfa-flow-${flow.step}`)\n ?.scrollIntoView?.({ block: 'start' });\n }, [flow.step, initialStep]);\n\n if (flow.success) {\n return (\n <div className=\"sfa-flow sfa-flow--done\">\n <FlowSuccessView\n success={flow.success}\n onAddAnother={onAddAnother}\n onDone={onDone}\n />\n </div>\n );\n }\n\n const back = () => {\n const previous = previousStep(flow.step);\n if (previous) flow.goTo(previous);\n else if (onClose) void flow.close();\n };\n const close = onClose ? (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--ghost\"\n aria-label={copy.close}\n onClick={() => void flow.close()}\n >\n ✕\n </button>\n ) : (\n renderLink({\n href: hrefs.products,\n className: 'sfa-btn sfa-btn--ghost',\n children: (\n <>\n <span aria-hidden=\"true\">✕</span>\n <span className=\"sfa-sr-only\">{copy.close}</span>\n </>\n ),\n })\n );\n const active = (step: ProductFlowStep) => flow.step === step;\n\n return (\n <div ref={rootRef} className=\"sfa-flow\" data-step={flow.step}>\n <FlowHead\n title={flow.isNew ? copy.newTitle : copy.editTitle}\n onBack={back}\n canGoBack={Boolean(onClose) || flow.step !== 'photos'}\n close={close}\n />\n <StepBar step={flow.step} allOpen={!flow.isNew} onStep={flow.goTo} />\n <div className=\"sfa-flow__body\">\n <div className=\"sfa-flow__main\">\n <FlowSectionFrame step=\"photos\" active={active('photos')}>\n <PhotosSection\n product={flow.product}\n ensureProduct={flow.autosave.ensureProduct}\n setProduct={flow.autosave.setProduct}\n imagesSlot={imagesSlot}\n />\n </FlowSectionFrame>\n <FlowSectionFrame step=\"basics\" active={active('basics')}>\n <BasicsSection\n {...section}\n categories={categories}\n currency={currency}\n />\n </FlowSectionFrame>\n <FlowSectionFrame step=\"story\" active={active('story')}>\n <StorySection\n {...section}\n product={flow.product}\n setProduct={flow.autosave.setProduct}\n materialSuggestions={materialSuggestions}\n />\n </FlowSectionFrame>\n </div>\n <aside className=\"sfa-flow__aside\">\n <FlowSectionFrame step=\"preview\" active={active('preview')}>\n <PreviewSection\n {...section}\n product={flow.product}\n currency={currency}\n missing={flow.missing}\n actions={<FinishActions flow={flow} />}\n />\n </FlowSectionFrame>\n <ErrorMessage error={flow.failure} />\n <SaveNote\n state={flow.autosave.state}\n isNew={flow.isNew}\n onRetry={() => void flow.autosave.retry()}\n />\n </aside>\n </div>\n <div className=\"sfa-flow__foot\">\n <StepActions flow={flow} />\n </div>\n {flow.notice ? (\n <Notice variant=\"success\" toast onDismiss={flow.dismissNotice}>\n {flow.notice}\n </Notice>\n ) : null}\n {flow.closing ? (\n <Notice\n variant=\"success\"\n toast\n duration={1500}\n onDismiss={flow.finishClosing}\n >\n {copy.savedAsDraft}\n </Notice>\n ) : null}\n </div>\n );\n}\n","import { useSyncExternalStore, type ReactNode } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport {\n PRODUCT_FLOW_STEPS,\n type ProductFlowStep,\n} from '../../lib/product-flow-labels';\nimport { AdminProductFlow } from './product-flow/admin-product-flow';\n\nexport interface AdminProductEditorProps {\n productId?: string;\n onSaved?: (product: AdminProduct) => void;\n imagesSlot?: ReactNode;\n categories?: string[];\n initialStep?: ProductFlowStep;\n}\n\nfunction stepFromUrl(): ProductFlowStep | undefined {\n const step = new URLSearchParams(window.location.search).get('step');\n return PRODUCT_FLOW_STEPS.find((item) => item === step);\n}\n\nconst noSubscription = () => () => undefined;\n\nexport function AdminProductEditor({\n productId,\n onSaved,\n imagesSlot,\n categories,\n initialStep,\n}: AdminProductEditorProps) {\n const urlStep = useSyncExternalStore(\n noSubscription,\n stepFromUrl,\n () => undefined,\n );\n return (\n <AdminProductFlow\n productId={productId}\n initialStep={initialStep ?? urlStep}\n onDone={onSaved}\n imagesSlot={imagesSlot}\n categories={categories}\n />\n );\n}\n","import { useState, type FormEvent } from 'react';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport type { ImageLabels } from '../../lib/image-labels';\n\nexport interface ImageAltEditorProps {\n imageId: string;\n alt: string;\n name: string;\n labels: ImageLabels;\n onSave: (alt: string) => Promise<void>;\n}\n\nexport function ImageAltEditor({\n imageId,\n alt,\n name,\n labels,\n onSave,\n}: ImageAltEditorProps) {\n const [draft, setDraft] = useState<string | null>(null);\n const [saving, setSaving] = useState(false);\n const [failure, setFailure] = useState<unknown>(undefined);\n\n const close = () => {\n setDraft(null);\n setFailure(undefined);\n };\n\n const submit = async (event: FormEvent) => {\n event.preventDefault();\n if (draft === null) return;\n setSaving(true);\n setFailure(undefined);\n try {\n await onSave(draft);\n setDraft(null);\n } catch (error) {\n setFailure(error);\n } finally {\n setSaving(false);\n }\n };\n\n if (draft === null) {\n return (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n aria-label={`${labels.editAlt}: ${name}`}\n onClick={() => setDraft(alt)}\n >\n {labels.editAlt}\n </button>\n );\n }\n return (\n <form className=\"sfa-image-tile__alt\" onSubmit={submit}>\n <input\n aria-label={`${labels.altLabel}: ${name}`}\n value={draft}\n disabled={saving}\n autoFocus\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Escape') close();\n }}\n />\n <ErrorMessage error={failure} />\n <button\n type=\"submit\"\n className=\"sfa-btn\"\n data-image-id={imageId}\n disabled={saving}\n >\n {labels.saveAlt}\n </button>\n <button\n type=\"button\"\n className=\"sfa-btn\"\n disabled={saving}\n onClick={close}\n >\n {labels.cancelAlt}\n </button>\n </form>\n );\n}\n","import type { AdminProduct } from '@develemit/commerce-contracts';\nimport { fill } from '../../lib/image-rules';\nimport type { ImageLabels } from '../../lib/image-labels';\nimport { useAdmin } from '../../lib/provider';\nimport { ImageAltEditor } from './image-alt-editor';\n\nexport type AdminProductImage = AdminProduct['images'][number];\nexport type MoveDirection = 'earlier' | 'later';\n\nexport interface ImageTileProps {\n image: AdminProductImage;\n index: number;\n total: number;\n busy: boolean;\n labels: ImageLabels;\n onMove: (direction: MoveDirection) => void;\n onRemove: () => void;\n onSaveAlt: (alt: string) => Promise<void>;\n}\n\nexport function ImageTile({\n image,\n index,\n total,\n busy,\n labels,\n onMove,\n onRemove,\n onSaveAlt,\n}: ImageTileProps) {\n const { renderImage } = useAdmin();\n const name = image.alt || fill(labels.photoName, { n: String(index + 1) });\n const move = (direction: MoveDirection, text: string, disabled: boolean) => (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n data-image-id={image.id}\n data-move={direction}\n aria-label={`${text}: ${name}`}\n disabled={disabled}\n onClick={() => onMove(direction)}\n >\n {text}\n </button>\n );\n return (\n <li className=\"sfa-image-tile\" aria-busy={busy} data-image-id={image.id}>\n {renderImage({\n src: image.url,\n alt: image.alt,\n sizes: '160px',\n className: 'sfa-image-tile__img',\n })}\n {index === 0 ? (\n <span className=\"sfa-image-tile__cover\">{labels.cover}</span>\n ) : null}\n {busy ? (\n <span className=\"sfa-spinner\" role=\"status\">\n {labels.working}\n </span>\n ) : null}\n <div className=\"sfa-image-tile__actions\">\n {move('earlier', labels.moveEarlier, index === 0)}\n {move('later', labels.moveLater, index === total - 1)}\n <ImageAltEditor\n imageId={image.id}\n alt={image.alt}\n name={name}\n labels={labels}\n onSave={onSaveAlt}\n />\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--danger\"\n aria-label={`${labels.remove}: ${name}`}\n onClick={onRemove}\n >\n {labels.remove}\n </button>\n </div>\n </li>\n );\n}\n","import type { ChangeEvent } from 'react';\nimport type { ImageLabels } from '../../lib/image-labels';\n\ninterface UploadPickerProps {\n labels: ImageLabels;\n onFiles: (files: File[]) => void;\n}\n\nexport function UploadPicker({ labels, onFiles }: UploadPickerProps) {\n const pick = (event: ChangeEvent<HTMLInputElement>) => {\n onFiles(Array.from(event.target.files ?? []));\n event.target.value = '';\n };\n return (\n <div className=\"sfa-image-picker\">\n <label className=\"sfa-btn sfa-image-picker__btn\">\n {labels.add}\n <input\n type=\"file\"\n accept=\"image/*\"\n multiple\n className=\"sfa-sr-only\"\n onChange={pick}\n />\n </label>\n <label className=\"sfa-btn sfa-image-picker__btn\">\n {labels.takePhoto}\n <input\n type=\"file\"\n accept=\"image/*\"\n capture=\"environment\"\n className=\"sfa-sr-only\"\n onChange={pick}\n />\n </label>\n </div>\n );\n}\n","import { useEffect, useRef, useState, type DragEvent } from 'react';\nimport { ConfirmDialog } from '../../components/confirm-dialog/confirm-dialog';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Notice } from '../../components/notice/notice';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useImageUpload } from '../../lib/use-image-upload';\nimport {\n ImageTile,\n type AdminProductImage,\n type MoveDirection,\n} from './image-tile';\nimport { UploadPicker } from './upload-picker';\n\nexport interface AdminProductImagesProps {\n productId: string;\n images: AdminProductImage[];\n}\n\nconst byPosition = (images: AdminProductImage[]) =>\n [...images].sort((a, b) => a.position - b.position);\n\nexport function AdminProductImages({\n productId,\n images: initial,\n}: AdminProductImagesProps) {\n const client = useAdminClient();\n const { labels } = useAdmin();\n const copy = labels.products.images;\n const [images, setImages] = useState(() => byPosition(initial));\n const [busyId, setBusyId] = useState<string | null>(null);\n const [reordering, setReordering] = useState(false);\n const [alt, setAlt] = useState('');\n const [failure, setFailure] = useState<unknown>(undefined);\n const [reorderFailed, setReorderFailed] = useState(false);\n const [removing, setRemoving] = useState<AdminProductImage | null>(null);\n const focusTarget = useRef<{ id: string; direction: MoveDirection } | null>(\n null,\n );\n const listRef = useRef<HTMLUListElement>(null);\n\n const { entries, upload, dismiss } = useImageUpload({\n productId,\n onUploaded: (product) => setImages(byPosition(product.images)),\n });\n\n useEffect(() => {\n const target = focusTarget.current;\n if (!target) return;\n focusTarget.current = null;\n const find = (direction: MoveDirection) =>\n listRef.current?.querySelector<HTMLButtonElement>(\n `[data-image-id=\"${target.id}\"][data-move=\"${direction}\"]:not(:disabled)`,\n );\n const other = target.direction === 'earlier' ? 'later' : 'earlier';\n (find(target.direction) ?? find(other))?.focus();\n }, [images]);\n\n const move = async (index: number, direction: MoveDirection) => {\n const to = direction === 'earlier' ? index - 1 : index + 1;\n if (reordering || to < 0 || to >= images.length) return;\n const previous = images;\n const next = [...images];\n [next[index], next[to]] = [next[to], next[index]];\n focusTarget.current = { id: images[index].id, direction };\n setImages(next);\n setReordering(true);\n setBusyId(images[index].id);\n setFailure(undefined);\n setReorderFailed(false);\n try {\n const product = await client.reorderProductImages(\n productId,\n next.map((image) => image.id),\n );\n setImages(byPosition(product.images));\n } catch (error) {\n focusTarget.current = { id: images[index].id, direction };\n setImages(previous);\n setFailure(error);\n setReorderFailed(true);\n } finally {\n setReordering(false);\n setBusyId(null);\n }\n };\n\n const confirmRemove = async () => {\n if (!removing) return;\n const target = removing;\n setRemoving(null);\n setBusyId(target.id);\n setFailure(undefined);\n setReorderFailed(false);\n try {\n const product = await client.deleteProductImage(productId, target.id);\n setImages(byPosition(product.images));\n } catch (error) {\n setFailure(error);\n } finally {\n setBusyId(null);\n }\n };\n\n const saveAlt = async (imageId: string, nextAlt: string) => {\n const product = await client.updateProductImage(productId, imageId, {\n alt: nextAlt,\n });\n setImages(byPosition(product.images));\n };\n\n const onDrop = (event: DragEvent) => {\n event.preventDefault();\n upload(Array.from(event.dataTransfer.files), alt);\n };\n\n return (\n <div\n className=\"sfa-images\"\n onDragOver={(event) => event.preventDefault()}\n onDrop={onDrop}\n >\n <h2>{copy.title}</h2>\n {reorderFailed ? (\n <Notice variant=\"error\" onDismiss={() => setReorderFailed(false)}>\n {copy.reorderFailed}\n </Notice>\n ) : (\n <ErrorMessage error={failure} />\n )}\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor={`${productId}-image-alt`}>\n {copy.altLabel}\n </label>\n <input\n id={`${productId}-image-alt`}\n value={alt}\n onChange={(event) => setAlt(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') event.preventDefault();\n }}\n />\n <p className=\"sfa-field__help\">{copy.altHelp}</p>\n {alt.trim() === '' ? (\n <p className=\"sfa-field__error\">{copy.altWarning}</p>\n ) : null}\n </div>\n <UploadPicker labels={copy} onFiles={(files) => upload(files, alt)} />\n <p className=\"sfa-field__help\">{copy.dropHint}</p>\n {images.length === 0 && entries.length === 0 ? <p>{copy.empty}</p> : null}\n <ul ref={listRef} className=\"sfa-image-grid\">\n {images.map((image, index) => (\n <ImageTile\n key={image.id}\n image={image}\n index={index}\n total={images.length}\n busy={busyId === image.id}\n labels={copy}\n onMove={(direction) => move(index, direction)}\n onRemove={() => setRemoving(image)}\n onSaveAlt={(next) => saveAlt(image.id, next)}\n />\n ))}\n {entries.map((entry) => (\n <li\n key={entry.id}\n className=\"sfa-image-tile\"\n aria-busy={entry.status !== 'error'}\n >\n <span>{entry.name}</span>\n {entry.status === 'error' ? (\n <>\n {entry.reason ? (\n <Notice variant=\"error\">{entry.reason}</Notice>\n ) : (\n <ErrorMessage error={entry.error} />\n )}\n <button\n type=\"button\"\n className=\"sfa-btn\"\n onClick={() => dismiss(entry.id)}\n >\n {copy.dismiss}\n </button>\n </>\n ) : (\n <span className=\"sfa-spinner\" role=\"status\">\n {entry.status === 'uploading' ? copy.uploading : copy.working}\n </span>\n )}\n </li>\n ))}\n </ul>\n <ConfirmDialog\n open={removing !== null}\n title={copy.removeTitle}\n destructive\n confirmLabel={copy.remove}\n onConfirm={confirmRemove}\n onCancel={() => setRemoving(null)}\n >\n <p>{copy.removeBody}</p>\n </ConfirmDialog>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\n\nexport type EmptyStateIcon = 'orders' | 'discounts' | 'shipping' | 'search';\n\nexport interface EmptyStateProps {\n icon: EmptyStateIcon;\n title: ReactNode;\n body?: ReactNode;\n action?: ReactNode;\n children?: ReactNode;\n}\n\nconst PATHS: Record<EmptyStateIcon, string> = {\n orders: 'M4 8l8-4 8 4v8l-8 4-8-4V8zm0 0l8 4m0 0l8-4m-8 4v8',\n discounts: 'M3 12V4h8l10 10-8 8L3 12zm5-5h.01',\n shipping: 'M2 6h11v9H2V6zm11 3h4l3 3v3h-7V9zM6 18.5h.01M17 18.5h.01',\n search: 'M11 4a7 7 0 100 14 7 7 0 000-14zm9 16l-4-4',\n};\n\nexport function EmptyState({\n icon,\n title,\n body,\n action,\n children,\n}: EmptyStateProps) {\n return (\n <div className=\"sfa-empty-state\">\n <svg\n className=\"sfa-empty-state__icon\"\n viewBox=\"0 0 24 24\"\n width=\"48\"\n height=\"48\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d={PATHS[icon]} />\n </svg>\n <h2 className=\"sfa-empty-state__title\">{title}</h2>\n {body ? <p className=\"sfa-empty-state__body\">{body}</p> : null}\n {children}\n {action ? <div className=\"sfa-empty-state__action\">{action}</div> : null}\n </div>\n );\n}\n","import type {\n AdminOrderListItem,\n AdminOrderPage,\n} from '@develemit/commerce-contracts';\nimport type { AdminOrderQuery } from '../client/admin-client';\nimport { useAdminClient } from './provider';\nimport { usePagedList } from './use-paged-list';\n\nexport function useOrderPages(query: Omit<AdminOrderQuery, 'cursor'>) {\n const client = useAdminClient();\n return usePagedList<AdminOrderListItem, AdminOrderPage>(\n ['admin-orders', query],\n (cursor) => client.listOrders(cursor ? { ...query, cursor } : query),\n );\n}\n","import { useState } from 'react';\nimport type { AdminOrderListItem } from '@develemit/commerce-contracts';\nimport type { AdminOrderQuery } from '../../client/admin-client';\nimport {\n AdminTable,\n type AdminColumn,\n} from '../../components/admin-table/admin-table';\nimport { EmptyState } from '../../components/empty-state/empty-state';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Money } from '../../components/money/money';\nimport { StatusBadge } from '../../components/status-badge/status-badge';\nimport type { OrderTab } from '../../lib/order-labels';\nimport { useAdmin } from '../../lib/provider';\nimport { useDebounced } from '../../lib/use-debounced';\nimport { useOrderPages } from '../../lib/use-order-pages';\nimport { AdminPageHeader } from '../../components/page-header/admin-page-header';\n\nconst TABS: OrderTab[] = [\n 'paid',\n 'shipped',\n 'needs_attention',\n 'pending_refund',\n 'all',\n];\n\nfunction tabQuery(tab: OrderTab): AdminOrderQuery {\n if (tab === 'pending_refund') return { hasPendingRefund: true };\n if (tab === 'all') return {};\n return { status: tab };\n}\n\nexport function AdminOrderList() {\n const { labels, locale, hrefs, renderLink } = useAdmin();\n const copy = labels.orders;\n const [tab, setTab] = useState<OrderTab>('paid');\n const [search, setSearch] = useState('');\n const q = useDebounced(search.trim(), 300);\n const pages = useOrderPages({ ...tabQuery(tab), ...(q ? { q } : {}) });\n const date = new Intl.DateTimeFormat(locale);\n\n const columns: AdminColumn<AdminOrderListItem>[] = [\n {\n key: 'order',\n header: copy.columns.order,\n render: (o) =>\n renderLink({\n href: hrefs.order(o.id),\n children: o.id,\n className: 'sfa-link--tap',\n }),\n },\n {\n key: 'status',\n header: copy.columns.status,\n render: (o) => <StatusBadge status={o.status} />,\n },\n {\n key: 'email',\n header: copy.columns.email,\n render: (o) => o.email ?? copy.noEmail,\n },\n { key: 'items', header: copy.columns.items, render: (o) => o.itemCount },\n {\n key: 'total',\n header: copy.columns.total,\n render: (o) => <Money cents={o.totalCents} currency={o.currency} />,\n },\n {\n key: 'date',\n header: copy.columns.date,\n render: (o) => date.format(new Date(o.createdAt)),\n },\n ];\n\n return (\n <section className=\"sfa-orders\">\n <AdminPageHeader title={copy.title} />\n <div className=\"sfa-orders__toolbar\">\n <div\n role=\"group\"\n aria-label={copy.columns.status}\n className=\"sfa-filter-group\"\n >\n {TABS.map((value) => (\n <button\n key={value}\n type=\"button\"\n className=\"sfa-chip\"\n aria-pressed={tab === value}\n onClick={() => setTab(value)}\n >\n {copy.tabs[value]}\n </button>\n ))}\n </div>\n <input\n type=\"search\"\n aria-label={copy.searchLabel}\n placeholder={copy.searchPlaceholder}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n <ErrorMessage error={pages.error} />\n {pages.loading ? (\n <p>{labels.loading}</p>\n ) : pages.items.length === 0 ? (\n <EmptyState\n icon={q ? 'search' : 'orders'}\n title={q ? copy.noMatches : copy.empty[tab]}\n body={q ? undefined : copy.emptyHint}\n />\n ) : (\n <AdminTable columns={columns} rows={pages.items} rowKey={(o) => o.id} />\n )}\n {pages.hasMore ? (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-orders__more\"\n disabled={pages.loadingMore}\n onClick={pages.loadMore}\n >\n {copy.loadMore}\n </button>\n ) : null}\n </section>\n );\n}\n","import type { AdminOrderDetail } from '@develemit/commerce-contracts';\n\nexport function pendingRefundCents(order: AdminOrderDetail): number {\n return order.refunds\n .filter((r) => r.status === 'pending')\n .reduce((sum, r) => sum + r.amountCents, 0);\n}\n\nexport function remainingRefundCents(order: AdminOrderDetail): number {\n return order.totalCents - order.refundedCents - pendingRefundCents(order);\n}\n\nexport function hasPendingRefund(order: AdminOrderDetail): boolean {\n return order.refunds.some((r) => r.status === 'pending');\n}\n\nexport function canRestock(\n order: AdminOrderDetail,\n amountCents: number | null,\n): boolean {\n return (\n order.status !== 'needs_attention' &&\n amountCents !== null &&\n amountCents === remainingRefundCents(order)\n );\n}\n\nexport function canShip(order: AdminOrderDetail): boolean {\n return order.status === 'paid' || order.status === 'shipped';\n}\n\nexport function canRefund(order: AdminOrderDetail): boolean {\n return (\n (canShip(order) || order.status === 'needs_attention') &&\n remainingRefundCents(order) > 0\n );\n}\n","import { useRef, useState } from 'react';\nimport type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport { RefundGatewayError, RefundOutcomeUnknownError } from '../../client';\nimport { ConfirmDialog } from '../../components/confirm-dialog/confirm-dialog';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Notice } from '../../components/notice/notice';\nimport { formatMoneyInput, parseMoneyInput } from '../../lib/money-input';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport {\n canRestock,\n hasPendingRefund,\n remainingRefundCents,\n} from '../../lib/refund-rules';\nimport { useAdminMutation } from '../../lib/use-admin-mutation';\n\ninterface RefundDialogProps {\n order: AdminOrderDetail;\n onClose: () => void;\n onDone: (message: string) => void;\n}\n\nexport function RefundDialog({ order, onClose, onDone }: RefundDialogProps) {\n const client = useAdminClient();\n const copy = useAdmin().labels.orders.actions;\n const keyRef = useRef(crypto.randomUUID());\n const remaining = remainingRefundCents(order);\n const [amount, setAmount] = useState(formatMoneyInput(remaining));\n const [reason, setReason] = useState('');\n const [restock, setRestock] = useState(false);\n const [invalid, setInvalid] = useState(false);\n const refund = useAdminMutation(client.refundOrder);\n\n const cents = parseMoneyInput(amount);\n const amountValid = cents !== null && cents > 0 && cents <= remaining;\n const restockOffered = canRestock(order, cents);\n const retryable =\n refund.error instanceof RefundGatewayError ||\n refund.error instanceof RefundOutcomeUnknownError;\n\n const submit = async () => {\n if (!amountValid) {\n setInvalid(true);\n return;\n }\n setInvalid(false);\n const result = await refund.run(\n order.id,\n {\n amountCents: cents,\n reason: reason.trim() || undefined,\n restock: restock && restockOffered,\n },\n { idempotencyKey: keyRef.current },\n );\n if (result) onDone(copy.refundDone);\n };\n\n return (\n <ConfirmDialog\n open\n title={copy.refundTitle}\n confirmLabel={retryable ? copy.refundRetry : copy.refundSubmit}\n destructive\n pending={refund.pending}\n onConfirm={submit}\n onCancel={onClose}\n >\n {hasPendingRefund(order) ? (\n <Notice variant=\"warning\">{copy.refundPending}</Notice>\n ) : null}\n <div className=\"sfa-field\">\n <label htmlFor=\"sfa-refund-amount\" className=\"sfa-field__label\">\n {copy.refundAmount}\n </label>\n <input\n id=\"sfa-refund-amount\"\n inputMode=\"decimal\"\n value={amount}\n disabled={retryable}\n aria-invalid={invalid && !amountValid}\n onChange={(e) => setAmount(e.target.value)}\n />\n {invalid && !amountValid ? (\n <p className=\"sfa-field__error\">{copy.refundAmountInvalid}</p>\n ) : null}\n </div>\n <div className=\"sfa-field\">\n <label htmlFor=\"sfa-refund-reason\" className=\"sfa-field__label\">\n {copy.refundReason}\n </label>\n <textarea\n id=\"sfa-refund-reason\"\n maxLength={500}\n value={reason}\n disabled={retryable}\n onChange={(e) => setReason(e.target.value)}\n />\n </div>\n {restockOffered ? (\n <div className=\"sfa-field\">\n <label>\n <input\n type=\"checkbox\"\n checked={restock}\n disabled={retryable}\n onChange={(e) => setRestock(e.target.checked)}\n />{' '}\n {copy.restock}\n </label>\n <p className=\"sfa-field__help\">{copy.restockWarning}</p>\n </div>\n ) : null}\n {refund.error instanceof RefundOutcomeUnknownError ? (\n <Notice variant=\"warning\">{copy.refundUnknown}</Notice>\n ) : refund.error instanceof RefundGatewayError ? (\n <Notice variant=\"warning\">{copy.refundGateway}</Notice>\n ) : (\n <ErrorMessage error={refund.error} />\n )}\n </ConfirmDialog>\n );\n}\n","import type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport { InsufficientStockError } from '../../client';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Notice } from '../../components/notice/notice';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useAdminMutation } from '../../lib/use-admin-mutation';\n\ninterface ResolveButtonProps {\n order: AdminOrderDetail;\n onDone: (message: string) => void;\n}\n\nexport function ResolveButton({ order, onDone }: ResolveButtonProps) {\n const client = useAdminClient();\n const { labels, hrefs, renderLink } = useAdmin();\n const copy = labels.orders.actions;\n const resolve = useAdminMutation(client.resolveOrder);\n\n const submit = async () => {\n const result = await resolve.run(order.id);\n if (result) onDone(copy.resolved);\n };\n\n const stockError =\n resolve.error instanceof InsufficientStockError ? resolve.error : null;\n const names = new Map(order.items.map((i) => [i.productId, i.name]));\n\n return (\n <div className=\"sfa-order__action\">\n <p>{copy.resolveHelp}</p>\n {stockError ? (\n <Notice variant=\"error\">\n {labels.errors.insufficientStock}\n <ul>\n {stockError.productIds.map((id) => (\n <li key={id}>\n {renderLink({\n href: hrefs.product(id),\n children: `${copy.restockThenResolve}: ${names.get(id) ?? id}`,\n className: 'sfa-link--tap',\n })}\n </li>\n ))}\n </ul>\n </Notice>\n ) : (\n <ErrorMessage error={resolve.error} />\n )}\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={resolve.pending}\n onClick={submit}\n >\n {copy.resolve}\n </button>\n </div>\n );\n}\n","import { useState, type FormEvent } from 'react';\nimport type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useAdminMutation } from '../../lib/use-admin-mutation';\n\nfunction isHttpUrl(value: string): boolean {\n try {\n const { protocol } = new URL(value);\n return protocol === 'http:' || protocol === 'https:';\n } catch {\n return false;\n }\n}\n\ninterface ShipFormProps {\n order: AdminOrderDetail;\n onDone: (message: string) => void;\n}\n\nexport function ShipForm({ order, onDone }: ShipFormProps) {\n const client = useAdminClient();\n const copy = useAdmin().labels.orders.actions;\n const current = order.fulfillment;\n const [carrier, setCarrier] = useState(current?.carrier ?? '');\n const [trackingNumber, setTrackingNumber] = useState(\n current?.trackingNumber ?? '',\n );\n const [trackingUrl, setTrackingUrl] = useState(current?.trackingUrl ?? '');\n const [urlError, setUrlError] = useState(false);\n const ship = useAdminMutation(client.shipOrder);\n const reship = order.status === 'shipped';\n\n const submit = async (event: FormEvent) => {\n event.preventDefault();\n const url = trackingUrl.trim();\n if (url && !isHttpUrl(url)) {\n setUrlError(true);\n return;\n }\n setUrlError(false);\n const result = await ship.run(order.id, {\n carrier: carrier.trim() || undefined,\n trackingNumber: trackingNumber.trim() || undefined,\n trackingUrl: url || undefined,\n });\n if (result) onDone(copy.shipped);\n };\n\n return (\n <form className=\"sfa-order__action\" onSubmit={submit}>\n <h3>{copy.shipHeading}</h3>\n <div className=\"sfa-field\">\n <label htmlFor=\"sfa-ship-carrier\" className=\"sfa-field__label\">\n {copy.carrier}\n </label>\n <input\n id=\"sfa-ship-carrier\"\n value={carrier}\n onChange={(e) => setCarrier(e.target.value)}\n />\n </div>\n <div className=\"sfa-field\">\n <label htmlFor=\"sfa-ship-number\" className=\"sfa-field__label\">\n {copy.trackingNumber}\n </label>\n <input\n id=\"sfa-ship-number\"\n value={trackingNumber}\n onChange={(e) => setTrackingNumber(e.target.value)}\n />\n </div>\n <div className=\"sfa-field\">\n <label htmlFor=\"sfa-ship-url\" className=\"sfa-field__label\">\n {copy.trackingUrl}\n </label>\n <input\n id=\"sfa-ship-url\"\n value={trackingUrl}\n aria-invalid={urlError}\n aria-describedby={urlError ? 'sfa-ship-url-error' : undefined}\n onChange={(e) => setTrackingUrl(e.target.value)}\n />\n {urlError ? (\n <p id=\"sfa-ship-url-error\" className=\"sfa-field__error\">\n {copy.trackingUrlInvalid}\n </p>\n ) : null}\n </div>\n <ErrorMessage error={ship.error} />\n <button\n type=\"submit\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={ship.pending}\n >\n {reship ? copy.reship : copy.ship}\n </button>\n </form>\n );\n}\n","import { useState } from 'react';\nimport type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport { Notice } from '../../components/notice/notice';\nimport { useAdmin } from '../../lib/provider';\nimport { canRefund, canShip } from '../../lib/refund-rules';\nimport { RefundDialog } from './refund-dialog';\nimport { ResolveButton } from './resolve-button';\nimport { ShipForm } from './ship-form';\n\ninterface OrderActionsProps {\n order: AdminOrderDetail;\n reload: () => void;\n}\n\nexport function OrderActions({ order, reload }: OrderActionsProps) {\n const copy = useAdmin().labels.orders.actions;\n const [refunding, setRefunding] = useState(false);\n const [message, setMessage] = useState<string | null>(null);\n\n const done = (text: string) => {\n setRefunding(false);\n setMessage(text);\n reload();\n };\n const closeRefund = () => {\n setRefunding(false);\n reload();\n };\n\n return (\n <div className=\"sfa-order__actions\">\n {message ? (\n <Notice variant=\"success\" onDismiss={() => setMessage(null)}>\n {message}\n </Notice>\n ) : null}\n {canShip(order) ? <ShipForm order={order} onDone={done} /> : null}\n {order.status === 'needs_attention' ? (\n <ResolveButton order={order} onDone={done} />\n ) : null}\n {canRefund(order) ? (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--danger\"\n onClick={() => setRefunding(true)}\n >\n {copy.refund}\n </button>\n ) : null}\n {refunding ? (\n <RefundDialog order={order} onClose={closeRefund} onDone={done} />\n ) : null}\n </div>\n );\n}\n","import type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport { useAdmin } from '../../lib/provider';\n\nexport function OrderFulfillment({ order }: { order: AdminOrderDetail }) {\n const { labels, locale, renderLink } = useAdmin();\n const copy = labels.orders;\n const f = order.fulfillment;\n return (\n <section className=\"sfa-order__section\">\n <h2>{copy.fulfillment}</h2>\n {f ? (\n <dl>\n <dt>{copy.shippedOn}</dt>\n <dd>\n {new Intl.DateTimeFormat(locale).format(new Date(f.shippedAt))}\n </dd>\n {f.carrier ? (\n <>\n <dt>{copy.carrier}</dt>\n <dd>{f.carrier}</dd>\n </>\n ) : null}\n {f.trackingNumber ? (\n <>\n <dt>{copy.tracking}</dt>\n <dd>{f.trackingNumber}</dd>\n </>\n ) : null}\n {f.trackingUrl ? (\n <dd>\n {renderLink({\n href: f.trackingUrl,\n children: copy.trackShipment,\n className: 'sfa-link--tap',\n })}\n </dd>\n ) : null}\n </dl>\n ) : (\n <p>{copy.notShipped}</p>\n )}\n </section>\n );\n}\n","import type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport {\n AdminTable,\n type AdminColumn,\n} from '../../components/admin-table/admin-table';\nimport { Money } from '../../components/money/money';\nimport { useAdmin } from '../../lib/provider';\n\ntype Item = AdminOrderDetail['items'][number];\n\nexport function OrderItems({ order }: { order: AdminOrderDetail }) {\n const { labels } = useAdmin();\n const copy = labels.orders;\n const { currency } = order;\n const columns: AdminColumn<Item>[] = [\n { key: 'name', header: copy.itemColumns.name, render: (i) => i.name },\n {\n key: 'price',\n header: copy.itemColumns.price,\n render: (i) => <Money cents={i.priceCents} currency={currency} />,\n },\n {\n key: 'quantity',\n header: copy.itemColumns.quantity,\n render: (i) => i.quantity,\n },\n {\n key: 'line',\n header: copy.itemColumns.line,\n render: (i) => (\n <Money cents={i.priceCents * i.quantity} currency={currency} />\n ),\n },\n ];\n return (\n <section className=\"sfa-order__section\">\n <h2>{copy.itemsHeading}</h2>\n <AdminTable\n columns={columns}\n rows={order.items}\n rowKey={(i) => i.productId}\n />\n <dl className=\"sfa-order__totals\">\n <dt>{copy.subtotal}</dt>\n <dd>\n <Money cents={order.subtotalCents} currency={currency} />\n </dd>\n {order.discountCents > 0 ? (\n <>\n <dt>\n {labels.discounts.orderRow}\n {order.discountCode ? ` (${order.discountCode})` : ''}\n </dt>\n <dd>\n −<Money cents={order.discountCents} currency={currency} />\n </dd>\n </>\n ) : null}\n <dt>{order.shippingLabel ?? copy.shipping}</dt>\n <dd>\n <Money cents={order.shippingCents} currency={currency} />\n </dd>\n <dt>{copy.total}</dt>\n <dd>\n <Money cents={order.totalCents} currency={currency} />\n </dd>\n </dl>\n </section>\n );\n}\n","import type { AdminOrderDetail } from '@develemit/commerce-contracts';\nimport {\n AdminTable,\n type AdminColumn,\n} from '../../components/admin-table/admin-table';\nimport { Money } from '../../components/money/money';\nimport { useAdmin } from '../../lib/provider';\n\ntype Refund = AdminOrderDetail['refunds'][number];\n\nexport function OrderRefunds({ order }: { order: AdminOrderDetail }) {\n const { labels, locale } = useAdmin();\n const copy = labels.orders;\n const { currency } = order;\n const date = new Intl.DateTimeFormat(locale);\n const columns: AdminColumn<Refund>[] = [\n {\n key: 'amount',\n header: copy.refundColumns.amount,\n render: (r) => <Money cents={r.amountCents} currency={currency} />,\n },\n {\n key: 'reason',\n header: copy.refundColumns.reason,\n render: (r) => r.reason ?? '—',\n },\n {\n key: 'source',\n header: copy.refundColumns.source,\n render: (r) => copy.refundSources[r.source],\n },\n {\n key: 'status',\n header: copy.refundColumns.status,\n render: (r) => (\n <span\n className={`sfa-badge sfa-badge--refund-${r.status}`}\n data-refund-status={r.status}\n >\n {copy.refundStatuses[r.status]}\n </span>\n ),\n },\n {\n key: 'restocked',\n header: copy.refundColumns.restocked,\n render: (r) => (r.restocked ? copy.yes : copy.no),\n },\n {\n key: 'date',\n header: copy.refundColumns.date,\n render: (r) => date.format(new Date(r.createdAt)),\n },\n ];\n const remaining = order.totalCents - order.refundedCents;\n return (\n <section className=\"sfa-order__section\">\n <h2>{copy.refunds}</h2>\n {order.refunds.length === 0 ? (\n <p>{copy.noRefunds}</p>\n ) : (\n <>\n <AdminTable\n columns={columns}\n rows={order.refunds}\n rowKey={(r) => r.id}\n />\n <dl className=\"sfa-order__totals\">\n <dt>{copy.refunded}</dt>\n <dd>\n <Money cents={order.refundedCents} currency={currency} />\n </dd>\n <dt>{copy.remaining}</dt>\n <dd>\n <Money cents={remaining} currency={currency} />\n </dd>\n </dl>\n </>\n )}\n </section>\n );\n}\n","import type { ReactNode } from 'react';\nimport type { AdminOrderDetail as OrderDetail } from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Money } from '../../components/money/money';\nimport { StatusBadge } from '../../components/status-badge/status-badge';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useAdminQuery } from '../../lib/use-admin-query';\nimport { OrderActions } from './order-actions';\nimport { OrderFulfillment } from './order-fulfillment';\nimport { OrderItems } from './order-items';\nimport { OrderRefunds } from './order-refunds';\nimport { AdminPageHeader } from '../../components/page-header/admin-page-header';\n\nexport interface AdminOrderDetailProps {\n orderId: string;\n actions?: (ctx: { order: OrderDetail; reload: () => void }) => ReactNode;\n}\n\nfunction addressLines(order: OrderDetail): string[] {\n const a = order.shippingAddress;\n if (!a) return [];\n const region = [a.city, a.state, a.postalCode].filter(Boolean).join(' ');\n return [a.name, a.line1, a.line2, region, a.country].filter(\n (l): l is string => Boolean(l),\n );\n}\n\nexport function AdminOrderDetail({ orderId, actions }: AdminOrderDetailProps) {\n const client = useAdminClient();\n const { labels, locale, hrefs, renderLink } = useAdmin();\n const copy = labels.orders;\n const query = useAdminQuery(['admin-order', orderId], () =>\n client.getOrder(orderId),\n );\n if (query.error) return <ErrorMessage error={query.error} />;\n const order = query.data;\n if (!order) return <p>{labels.loading}</p>;\n const lines = addressLines(order);\n\n return (\n <article className=\"sfa-order\">\n {renderLink({\n href: hrefs.orders,\n children: copy.back,\n className: 'sfa-link--tap',\n })}\n <AdminPageHeader title={`${copy.detailTitle} ${order.id}`}>\n <div className=\"sfa-order__header\">\n <StatusBadge status={order.status} />\n <span>\n {copy.placed}{' '}\n {new Intl.DateTimeFormat(locale).format(new Date(order.createdAt))}\n </span>\n <Money cents={order.totalCents} currency={order.currency} />\n </div>\n </AdminPageHeader>\n <section className=\"sfa-order__section\">\n <h2>{copy.buyer}</h2>\n <p>{order.email ?? labels.orders.noEmail}</p>\n </section>\n <OrderItems order={order} />\n <section className=\"sfa-order__section\">\n <h2>{copy.shippingAddress}</h2>\n {lines.length === 0 ? (\n <p>{copy.noAddress}</p>\n ) : (\n <address className=\"sfa-order__address\">\n {lines.map((l) => (\n <div key={l}>{l}</div>\n ))}\n </address>\n )}\n </section>\n <OrderFulfillment order={order} />\n <OrderRefunds order={order} />\n <section className=\"sfa-order__section\">\n {actions ? (\n actions({ order, reload: query.reload })\n ) : (\n <OrderActions order={order} reload={query.reload} />\n )}\n </section>\n </article>\n );\n}\n","import {\n shippingRatesInputSchema,\n type ShippingRate,\n type ShippingRateInput,\n} from '@develemit/commerce-contracts';\nimport { formatMoneyInput, parseMoneyInput } from './money-input';\nimport type { ShippingLabels } from './shipping-labels';\n\nexport interface RateDraft {\n key: string;\n label: string;\n amount: string;\n currency: string;\n minDays: string;\n maxDays: string;\n active: boolean;\n}\n\nexport interface RateErrors {\n label?: string;\n amount?: string;\n minDays?: string;\n maxDays?: string;\n currency?: string;\n row?: string;\n}\n\nexport interface DraftCheck {\n rates: ShippingRateInput[];\n rowErrors: Record<string, RateErrors>;\n noActive: boolean;\n valid: boolean;\n}\n\nlet counter = 0;\nexport const newKey = () => `rate-${++counter}`;\n\nexport function toDrafts(rates: ShippingRate[]): RateDraft[] {\n return [...rates]\n .sort((a, b) => a.sort - b.sort)\n .map((rate) => ({\n key: newKey(),\n label: rate.label,\n amount: formatMoneyInput(rate.amountCents),\n currency: rate.currency,\n minDays: rate.minDays == null ? '' : String(rate.minDays),\n maxDays: rate.maxDays == null ? '' : String(rate.maxDays),\n active: rate.active,\n }));\n}\n\nexport function blankDraft(currency: string, label: string): RateDraft {\n return {\n key: newKey(),\n label,\n amount: '',\n currency,\n minDays: '',\n maxDays: '',\n active: true,\n };\n}\n\nexport const snapshot = (drafts: RateDraft[]) =>\n JSON.stringify(drafts.map(({ key: _key, ...rest }) => rest));\n\nfunction parseDays(raw: string): number | null | undefined {\n const text = raw.trim();\n if (text === '') return null;\n return /^\\d+$/.test(text) ? Number(text) : undefined;\n}\n\nexport function checkDrafts(\n drafts: RateDraft[],\n copy: ShippingLabels,\n): DraftCheck {\n const rowErrors: Record<string, RateErrors> = {};\n const rates: ShippingRateInput[] = [];\n const seen = new Map<string, number>();\n drafts.forEach((draft) => {\n const name = draft.label.trim();\n seen.set(name, (seen.get(name) ?? 0) + 1);\n });\n\n drafts.forEach((draft, index) => {\n const errors: RateErrors = {};\n const label = draft.label.trim();\n const cents = parseMoneyInput(draft.amount);\n const min = parseDays(draft.minDays);\n const max = parseDays(draft.maxDays);\n if (label === '') errors.label = copy.labelRequired;\n else if ((seen.get(label) ?? 0) > 1) errors.label = copy.labelDuplicate;\n if (!/^[A-Z]{3}$/.test(draft.currency))\n errors.currency = copy.currencyInvalid;\n if (cents === null) errors.amount = copy.amountInvalid;\n if (min === undefined) errors.minDays = copy.daysInvalid;\n if (max === undefined) errors.maxDays = copy.daysInvalid;\n if (typeof min === 'number' && typeof max === 'number' && min > max) {\n errors.minDays = copy.daysOrder;\n }\n if (Object.keys(errors).length > 0) rowErrors[draft.key] = errors;\n rates.push({\n label,\n amountCents: cents ?? 0,\n currency: draft.currency,\n minDays: min ?? null,\n maxDays: max ?? null,\n active: draft.active,\n sort: index,\n });\n });\n\n if (Object.keys(rowErrors).length === 0) {\n const parsed = shippingRatesInputSchema.safeParse(rates);\n if (!parsed.success) {\n for (const issue of parsed.error.issues) {\n const key =\n typeof issue.path[0] === 'number'\n ? drafts[issue.path[0]]?.key\n : undefined;\n if (key) rowErrors[key] = { row: copy.rowInvalid };\n }\n }\n }\n\n const noActive = !drafts.some((draft) => draft.active);\n return {\n rates,\n rowErrors,\n noActive,\n valid: Object.keys(rowErrors).length === 0 && !noActive,\n };\n}\n\nconst SERVER_FIELDS: Record<string, keyof RateErrors> = {\n label: 'label',\n amountCents: 'amount',\n currency: 'currency',\n minDays: 'minDays',\n maxDays: 'maxDays',\n};\n\nexport function serverRowErrors(\n issues: unknown[],\n drafts: RateDraft[],\n copy: ShippingLabels,\n): Record<string, RateErrors> {\n const result: Record<string, RateErrors> = {};\n for (const issue of issues) {\n const path = (issue as { path?: unknown[] } | null)?.path ?? [];\n const at = path.findIndex((segment) => typeof segment === 'number');\n const key = at >= 0 ? drafts[path[at] as number]?.key : undefined;\n if (!key) continue;\n const last = path[path.length - 1];\n const field =\n path.length - 1 > at && typeof last === 'string'\n ? SERVER_FIELDS[last]\n : undefined;\n result[key] = { ...result[key], [field ?? 'row']: copy.rowInvalid };\n }\n return result;\n}\n","import { fill } from '../../lib/image-rules';\nimport type { RateDraft, RateErrors } from '../../lib/shipping-rates';\nimport type { ShippingLabels } from '../../lib/shipping-labels';\n\nexport type RateMove = 'earlier' | 'later';\n\nexport interface ShippingRateRowProps {\n draft: RateDraft;\n index: number;\n total: number;\n errors: RateErrors;\n disabled: boolean;\n labels: ShippingLabels;\n onChange: (patch: Partial<RateDraft>) => void;\n onMove: (direction: RateMove) => void;\n onRemove: () => void;\n}\n\nexport function ShippingRateRow({\n draft,\n index,\n total,\n errors,\n disabled,\n labels,\n onChange,\n onMove,\n onRemove,\n}: ShippingRateRowProps) {\n const name =\n draft.label.trim() || fill(labels.rowName, { n: String(index + 1) });\n const field = (\n id: string,\n text: string,\n value: string,\n key: 'label' | 'amount' | 'minDays' | 'maxDays',\n inputMode?: 'decimal' | 'numeric',\n ) => {\n const error = errors[key];\n const fieldId = `${draft.key}-${id}`;\n return (\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor={fieldId}>\n {text}\n </label>\n <input\n id={fieldId}\n value={value}\n inputMode={inputMode}\n disabled={disabled}\n aria-invalid={Boolean(error)}\n aria-describedby={error ? `${fieldId}-error` : undefined}\n onChange={(event) => onChange({ [key]: event.target.value })}\n />\n {error ? (\n <p id={`${fieldId}-error`} className=\"sfa-field__error\">\n {error}\n </p>\n ) : null}\n </div>\n );\n };\n\n return (\n <li className=\"sfa-rate\" data-rate-key={draft.key}>\n {field('label', labels.label, draft.label, 'label')}\n {field('amount', labels.amount, draft.amount, 'amount', 'decimal')}\n <div className=\"sfa-field\">\n <span className=\"sfa-field__label\">{labels.currency}</span>\n <span\n className=\"sfa-rate__currency\"\n aria-invalid={Boolean(errors.currency)}\n >\n {draft.currency}\n </span>\n {errors.currency ? (\n <p className=\"sfa-field__error\">{errors.currency}</p>\n ) : null}\n </div>\n {field('min', labels.minDays, draft.minDays, 'minDays', 'numeric')}\n {field('max', labels.maxDays, draft.maxDays, 'maxDays', 'numeric')}\n <label className=\"sfa-rate__active\">\n <input\n type=\"checkbox\"\n checked={draft.active}\n disabled={disabled}\n onChange={(event) => onChange({ active: event.target.checked })}\n />\n {labels.active}\n </label>\n {errors.row ? <p className=\"sfa-field__error\">{errors.row}</p> : null}\n <div className=\"sfa-rate__actions\">\n <button\n type=\"button\"\n className=\"sfa-btn\"\n aria-label={`${labels.moveEarlier}: ${name}`}\n disabled={disabled || index === 0}\n onClick={() => onMove('earlier')}\n >\n {labels.moveEarlier}\n </button>\n <button\n type=\"button\"\n className=\"sfa-btn\"\n aria-label={`${labels.moveLater}: ${name}`}\n disabled={disabled || index === total - 1}\n onClick={() => onMove('later')}\n >\n {labels.moveLater}\n </button>\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--danger\"\n aria-label={`${labels.remove}: ${name}`}\n disabled={disabled}\n onClick={onRemove}\n >\n {labels.remove}\n </button>\n </div>\n </li>\n );\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { AdminInvalidInputError } from '../../client';\nimport { ConfirmDialog } from '../../components/confirm-dialog/confirm-dialog';\nimport { EmptyState } from '../../components/empty-state/empty-state';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Notice } from '../../components/notice/notice';\nimport { fill } from '../../lib/image-rules';\nimport { formatMoneyInput } from '../../lib/money-input';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport {\n blankDraft,\n checkDrafts,\n serverRowErrors,\n snapshot,\n toDrafts,\n type RateDraft,\n type RateErrors,\n} from '../../lib/shipping-rates';\nimport { useAdminMutation } from '../../lib/use-admin-mutation';\nimport { useAdminQuery } from '../../lib/use-admin-query';\nimport { ShippingRateRow, type RateMove } from './shipping-rate-row';\nimport { AdminPageHeader } from '../../components/page-header/admin-page-header';\n\nexport interface SuggestedRate {\n label: string;\n amountCents: number;\n}\n\nexport interface AdminShippingRatesProps {\n suggestedRates?: SuggestedRate[];\n onDirtyChange?: (dirty: boolean) => void;\n}\n\nexport function AdminShippingRates({\n onDirtyChange,\n suggestedRates = [],\n}: AdminShippingRatesProps) {\n const client = useAdminClient();\n const { labels, currency } = useAdmin();\n const copy = labels.shipping;\n const query = useAdminQuery(['shipping-rates'], () =>\n client.listShippingRates(),\n );\n const [drafts, setDrafts] = useState<RateDraft[]>([]);\n const [baseline, setBaseline] = useState('[]');\n const [loaded, setLoaded] = useState<unknown>(undefined);\n const [removing, setRemoving] = useState<RateDraft | null>(null);\n const [rowErrors, setRowErrors] = useState<Record<string, RateErrors>>({});\n const [blocked, setBlocked] = useState(false);\n const [saved, setSaved] = useState(false);\n const [removedAny, setRemovedAny] = useState(false);\n const save = useAdminMutation(\n (rates: Parameters<typeof client.replaceShippingRates>[0]) =>\n client.replaceShippingRates(rates),\n );\n const lastDirty = useRef<boolean | undefined>(undefined);\n\n if (query.data && query.data !== loaded) {\n const next = toDrafts(query.data);\n setLoaded(query.data);\n setDrafts(next);\n setBaseline(snapshot(next));\n }\n\n const dirty = loaded !== undefined && snapshot(drafts) !== baseline;\n useEffect(() => {\n if (lastDirty.current === dirty) return;\n lastDirty.current = dirty;\n onDirtyChange?.(dirty);\n }, [dirty, onDirtyChange]);\n\n const edit = (next: RateDraft[]) => {\n setDrafts(next);\n setSaved(false);\n setBlocked(false);\n };\n\n const patch = (key: string, change: Partial<RateDraft>) => {\n edit(drafts.map((d) => (d.key === key ? { ...d, ...change } : d)));\n setRowErrors(({ [key]: _cleared, ...rest }) => rest);\n };\n\n const move = (index: number, direction: RateMove) => {\n const to = direction === 'earlier' ? index - 1 : index + 1;\n if (to < 0 || to >= drafts.length) return;\n const next = [...drafts];\n [next[index], next[to]] = [next[to], next[index]];\n edit(next);\n };\n\n const add = () => edit([...drafts, blankDraft(currency, copy.newRateLabel)]);\n\n const addSuggested = (rate: SuggestedRate) =>\n edit([\n ...drafts,\n {\n ...blankDraft(currency, rate.label),\n amount: formatMoneyInput(rate.amountCents),\n },\n ]);\n\n const confirmRemove = () => {\n if (!removing) return;\n edit(drafts.filter((d) => d.key !== removing.key));\n setRemovedAny(true);\n setRemoving(null);\n };\n\n const submit = async () => {\n const check = checkDrafts(drafts, copy);\n setRowErrors(check.rowErrors);\n setBlocked(check.noActive);\n if (!check.valid) return;\n const result = await save.run(check.rates);\n if (!result) return;\n const next = toDrafts(result);\n setDrafts(next);\n setBaseline(snapshot(next));\n setRowErrors({});\n setRemovedAny(false);\n setSaved(true);\n };\n\n const mixedCurrency = drafts.some((d) => d.currency !== currency);\n\n const serverErrors =\n save.error instanceof AdminInvalidInputError\n ? serverRowErrors(save.error.issues, drafts, copy)\n : {};\n\n if (query.loading && !query.data) return <p role=\"status\">{copy.loading}</p>;\n if (!query.data) return <ErrorMessage error={query.error} />;\n\n return (\n <div className=\"sfa-shipping\">\n <AdminPageHeader title={copy.title} />\n {removedAny ? (\n <Notice variant=\"warning\">{copy.removalWarning}</Notice>\n ) : null}\n {mixedCurrency ? (\n <Notice variant=\"warning\">\n {fill(copy.mixedCurrency, { currency })}\n </Notice>\n ) : null}\n {blocked ? <Notice variant=\"error\">{copy.noActive}</Notice> : null}\n <ErrorMessage error={save.error} />\n {saved ? <Notice variant=\"success\">{copy.saved}</Notice> : null}\n {dirty ? <p className=\"sfa-field__help\">{copy.unsaved}</p> : null}\n {drafts.length === 0 ? (\n <EmptyState\n icon=\"shipping\"\n title={copy.emptyTitle}\n body={copy.empty}\n action={\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n onClick={add}\n >\n {copy.addOption}\n </button>\n }\n >\n {suggestedRates.length ? (\n <ul className=\"sfa-empty-state__chips\">\n {suggestedRates.map((rate) => (\n <li key={rate.label}>\n <button\n type=\"button\"\n className=\"sfa-chip\"\n onClick={() => addSuggested(rate)}\n >\n {rate.label}\n </button>\n </li>\n ))}\n </ul>\n ) : null}\n </EmptyState>\n ) : null}\n <ul className=\"sfa-rates\">\n {drafts.map((draft, index) => (\n <ShippingRateRow\n key={draft.key}\n draft={draft}\n index={index}\n total={drafts.length}\n errors={{ ...serverErrors[draft.key], ...rowErrors[draft.key] }}\n disabled={save.pending}\n labels={copy}\n onChange={(change) => patch(draft.key, change)}\n onMove={(direction) => move(index, direction)}\n onRemove={() => setRemoving(draft)}\n />\n ))}\n </ul>\n <div className=\"sfa-shipping__actions\">\n {drafts.length > 0 ? (\n <button type=\"button\" className=\"sfa-btn\" onClick={add}>\n {copy.add}\n </button>\n ) : null}\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={save.pending}\n onClick={submit}\n >\n {copy.save}\n </button>\n </div>\n <ConfirmDialog\n open={removing !== null}\n title={copy.removeTitle}\n destructive\n confirmLabel={copy.remove}\n onConfirm={confirmRemove}\n onCancel={() => setRemoving(null)}\n >\n <p>{copy.removeBody}</p>\n </ConfirmDialog>\n </div>\n );\n}\n","import type { Discount, DiscountStatus } from '@develemit/commerce-contracts';\n\ntype StatusFields = Pick<Discount, 'active' | 'startsAt' | 'endsAt'>;\n\nexport function displayDiscountStatus(\n discount: StatusFields,\n now: Date = new Date(),\n): DiscountStatus {\n if (!discount.active) return 'inactive';\n if (discount.startsAt && new Date(discount.startsAt) > now) {\n return 'scheduled';\n }\n if (discount.endsAt && new Date(discount.endsAt) <= now) return 'expired';\n return 'active';\n}\n\nexport function fillTemplate(\n template: string,\n values: Record<string, string | number>,\n): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, key: string) =>\n key in values ? String(values[key]) : match,\n );\n}\n","import type {\n AdminDiscountPage,\n Discount,\n} from '@develemit/commerce-contracts';\nimport type { AdminDiscountQuery } from '../client/admin-client';\nimport { useAdminClient } from './provider';\nimport { usePagedList } from './use-paged-list';\n\nexport function useDiscountPages(query: Omit<AdminDiscountQuery, 'cursor'>) {\n const client = useAdminClient();\n return usePagedList<Discount, AdminDiscountPage>(\n ['admin-discounts', query],\n (cursor) => client.listDiscounts(cursor ? { ...query, cursor } : query),\n );\n}\n","import type { Discount } from '@develemit/commerce-contracts';\nimport { Money } from '../../components/money/money';\n\nexport function DiscountValue({ discount }: { discount: Discount }) {\n if (discount.type === 'percent') return <span>{discount.percentOff}%</span>;\n return (\n <Money\n cents={discount.amountOffCents ?? 0}\n currency={discount.currency ?? 'USD'}\n />\n );\n}\n","import { useState } from 'react';\nimport type { Discount } from '@develemit/commerce-contracts';\nimport {\n AdminTable,\n type AdminColumn,\n} from '../../components/admin-table/admin-table';\nimport { EmptyState } from '../../components/empty-state/empty-state';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { StatusBadge } from '../../components/status-badge/status-badge';\nimport type { DiscountTab } from '../../lib/discount-labels';\nimport { displayDiscountStatus, fillTemplate } from '../../lib/discount-status';\nimport { useAdmin } from '../../lib/provider';\nimport { useDebounced } from '../../lib/use-debounced';\nimport { useDiscountPages } from '../../lib/use-discount-pages';\nimport { DiscountValue } from './discount-value';\nimport { AdminPageHeader } from '../../components/page-header/admin-page-header';\n\nconst TABS: DiscountTab[] = ['active', 'scheduled', 'expired', 'inactive'];\n\nexport function AdminDiscountList() {\n const { labels, hrefs, renderLink } = useAdmin();\n const copy = labels.discounts;\n const [tab, setTab] = useState<DiscountTab>('active');\n const [search, setSearch] = useState('');\n const q = useDebounced(search.trim(), 300);\n const pages = useDiscountPages({ status: tab, ...(q ? { q } : {}) });\n\n const usage = (d: Discount) => {\n const used = d.redeemedCount + d.reservedCount;\n return d.maxRedemptions\n ? fillTemplate(copy.usage, { used, max: d.maxRedemptions })\n : fillTemplate(copy.usageUnlimited, { used });\n };\n\n const columns: AdminColumn<Discount>[] = [\n {\n key: 'code',\n header: copy.columns.code,\n render: (d) =>\n renderLink({\n href: hrefs.discount(d.id),\n children: d.code,\n className: 'sfa-link--tap',\n }),\n },\n {\n key: 'value',\n header: copy.columns.value,\n render: (d) => <DiscountValue discount={d} />,\n },\n {\n key: 'status',\n header: copy.columns.status,\n render: (d) => <StatusBadge status={displayDiscountStatus(d)} />,\n },\n { key: 'usage', header: copy.columns.usage, render: usage },\n ];\n\n return (\n <section className=\"sfa-products\">\n <AdminPageHeader\n title={copy.title}\n actions={renderLink({\n href: hrefs.newDiscount,\n children: copy.newDiscount,\n className: 'sfa-btn sfa-btn--primary',\n })}\n />\n <div className=\"sfa-products__toolbar\">\n <div\n role=\"group\"\n aria-label={copy.columns.status}\n className=\"sfa-filter-group\"\n >\n {TABS.map((value) => (\n <button\n key={value}\n type=\"button\"\n className=\"sfa-chip\"\n aria-pressed={tab === value}\n onClick={() => setTab(value)}\n >\n {copy.tabs[value]}\n </button>\n ))}\n </div>\n <input\n type=\"search\"\n aria-label={copy.searchLabel}\n placeholder={copy.searchPlaceholder}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n <ErrorMessage error={pages.error} />\n {pages.loading && !pages.loaded ? (\n <p>{labels.loading}</p>\n ) : pages.items.length === 0 ? (\n <EmptyState\n icon={q ? 'search' : 'discounts'}\n title={q ? copy.noMatches : copy.empty[tab]}\n body={q ? undefined : copy.emptyHint}\n />\n ) : (\n <AdminTable columns={columns} rows={pages.items} rowKey={(d) => d.id} />\n )}\n {pages.hasMore ? (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-products__more\"\n disabled={pages.loadingMore}\n onClick={pages.loadMore}\n >\n {copy.loadMore}\n </button>\n ) : null}\n </section>\n );\n}\n","import type {\n Discount,\n DiscountInput,\n DiscountPatch,\n DiscountType,\n} from '@develemit/commerce-contracts';\nimport type { DiscountLabels } from './discount-labels';\nimport { formatMoneyInput, parseMoneyInput } from './money-input';\n\nexport interface DiscountForm {\n code: string;\n type: DiscountType;\n percentOff: string;\n amountOff: string;\n minSubtotal: string;\n startsAt: string;\n endsAt: string;\n maxRedemptions: string;\n}\n\nexport type DiscountFieldName = keyof DiscountForm;\nexport type DiscountFieldErrors = Partial<Record<DiscountFieldName, string>>;\n\nexport const emptyDiscountForm: DiscountForm = {\n code: '',\n type: 'percent',\n percentOff: '',\n amountOff: '',\n minSubtotal: '',\n startsAt: '',\n endsAt: '',\n maxRedemptions: '',\n};\n\nconst pad = (n: number) => String(n).padStart(2, '0');\n\nexport function isoToLocalInput(iso: string | null | undefined): string {\n if (!iso) return '';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n\nfunction localInputToIso(value: string): string | null {\n if (value.trim() === '') return null;\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d.toISOString();\n}\n\nexport function formFromDiscount(discount: Discount): DiscountForm {\n return {\n code: discount.code,\n type: discount.type,\n percentOff: discount.percentOff ? String(discount.percentOff) : '',\n amountOff: discount.amountOffCents\n ? formatMoneyInput(discount.amountOffCents)\n : '',\n minSubtotal: discount.minSubtotalCents\n ? formatMoneyInput(discount.minSubtotalCents)\n : '',\n startsAt: isoToLocalInput(discount.startsAt),\n endsAt: isoToLocalInput(discount.endsAt),\n maxRedemptions: discount.maxRedemptions\n ? String(discount.maxRedemptions)\n : '',\n };\n}\n\nexport function isDiscountUsed(discount: Discount | undefined): boolean {\n return Boolean(\n discount && discount.redeemedCount + discount.reservedCount > 0,\n );\n}\n\nexport type DiscountValidation =\n | { ok: true; input: DiscountInput }\n | { ok: false; errors: DiscountFieldErrors };\n\nconst positiveInt = (text: string): number | null =>\n /^\\d+$/.test(text.trim()) && Number(text) > 0 ? Number(text) : null;\n\nexport function validateDiscountForm(\n form: DiscountForm,\n labels: DiscountLabels,\n currency: string,\n usedCount = 0,\n): DiscountValidation {\n const v = labels.validation;\n const errors: DiscountFieldErrors = {};\n const code = form.code.trim().toUpperCase();\n if (!/^[A-Z0-9_-]{1,40}$/.test(code)) errors.code = v.code;\n\n const percentOff = positiveInt(form.percentOff);\n const amountOffCents = parseMoneyInput(form.amountOff);\n if (form.type === 'percent' && (percentOff === null || percentOff > 100)) {\n errors.percentOff = v.percentOff;\n }\n if (form.type === 'fixed' && !amountOffCents) errors.amountOff = v.amountOff;\n\n const minText = form.minSubtotal.trim();\n const minSubtotalCents = minText === '' ? null : parseMoneyInput(minText);\n if (minText !== '' && !minSubtotalCents) errors.minSubtotal = v.minSubtotal;\n\n const limitText = form.maxRedemptions.trim();\n const maxRedemptions = limitText === '' ? null : positiveInt(limitText);\n if (limitText !== '' && maxRedemptions === null) {\n errors.maxRedemptions = v.maxRedemptions;\n } else if (maxRedemptions !== null && maxRedemptions < usedCount) {\n errors.maxRedemptions = v.maxRedemptionsBelowUsage;\n }\n\n const startsAt = localInputToIso(form.startsAt);\n const endsAt = localInputToIso(form.endsAt);\n if (form.startsAt.trim() !== '' && !startsAt) errors.startsAt = v.date;\n if (form.endsAt.trim() !== '' && !endsAt) errors.endsAt = v.date;\n if (startsAt && endsAt && new Date(endsAt) <= new Date(startsAt)) {\n errors.endsAt = v.endsBeforeStart;\n }\n\n if (Object.keys(errors).length > 0) return { ok: false, errors };\n return {\n ok: true,\n input: {\n code,\n type: form.type,\n percentOff: form.type === 'percent' ? percentOff : null,\n amountOffCents: form.type === 'fixed' ? amountOffCents : null,\n currency: form.type === 'fixed' ? currency : null,\n minSubtotalCents,\n startsAt,\n endsAt,\n maxRedemptions,\n active: true,\n },\n };\n}\n\nconst VALUE_KEYS = [\n 'type',\n 'percentOff',\n 'amountOffCents',\n 'currency',\n] as const;\nconst LIMIT_KEYS = [\n 'minSubtotalCents',\n 'startsAt',\n 'endsAt',\n 'maxRedemptions',\n] as const;\n\nexport function buildDiscountPatch(\n original: Discount,\n input: DiscountInput,\n locked: boolean,\n): DiscountPatch {\n const patch: Record<string, unknown> = {};\n const next = input as Record<string, unknown>;\n const prev = original as unknown as Record<string, unknown>;\n const differs = (key: string) => (next[key] ?? null) !== (prev[key] ?? null);\n for (const key of LIMIT_KEYS) if (differs(key)) patch[key] = next[key];\n if (locked) return patch as DiscountPatch;\n if (differs('code')) patch.code = input.code;\n if (VALUE_KEYS.some(differs)) {\n for (const key of VALUE_KEYS) patch[key] = next[key];\n }\n return patch as DiscountPatch;\n}\n\nexport function mapDiscountIssues(\n issues: unknown[],\n message: string,\n): DiscountFieldErrors {\n const names: Record<string, DiscountFieldName> = {\n code: 'code',\n percentOff: 'percentOff',\n amountOffCents: 'amountOff',\n minSubtotalCents: 'minSubtotal',\n startsAt: 'startsAt',\n endsAt: 'endsAt',\n maxRedemptions: 'maxRedemptions',\n };\n const errors: DiscountFieldErrors = {};\n for (const issue of issues) {\n const head = (issue as { path?: unknown[] } | null)?.path?.[0];\n const field = typeof head === 'string' ? names[head] : undefined;\n if (field && !errors[field]) errors[field] = message;\n }\n return errors;\n}\n","import type { ReactNode } from 'react';\nimport type { DiscountType } from '@develemit/commerce-contracts';\nimport type {\n DiscountFieldErrors,\n DiscountFieldName,\n DiscountForm,\n} from '../../lib/discount-form';\nimport type { DiscountLabels } from '../../lib/discount-labels';\nimport { fillTemplate } from '../../lib/discount-status';\n\ninterface ControlProps {\n id: string;\n name: DiscountFieldName;\n disabled: boolean;\n 'aria-invalid': boolean;\n 'aria-describedby'?: string;\n}\n\ninterface ShellProps {\n name: DiscountFieldName;\n label: string;\n error?: string;\n help?: string;\n disabled?: boolean;\n children: (props: ControlProps) => ReactNode;\n}\n\nfunction Shell({ name, label, error, help, disabled, children }: ShellProps) {\n const id = `sfa-field-${name}`;\n const described = [help ? `${id}-help` : '', error ? `${id}-error` : '']\n .filter(Boolean)\n .join(' ');\n return (\n <div className=\"sfa-field\">\n <label htmlFor={id} className=\"sfa-field__label\">\n {label}\n </label>\n {children({\n id,\n name,\n disabled: Boolean(disabled),\n 'aria-invalid': Boolean(error),\n 'aria-describedby': described || undefined,\n })}\n {help ? (\n <p id={`${id}-help`} className=\"sfa-field__help\">\n {help}\n </p>\n ) : null}\n {error ? (\n <p id={`${id}-error`} className=\"sfa-field__error\">\n {error}\n </p>\n ) : null}\n </div>\n );\n}\n\nexport interface DiscountFieldsProps {\n form: DiscountForm;\n errors: DiscountFieldErrors;\n labels: DiscountLabels;\n usedCount: number;\n onChange: <K extends keyof DiscountForm>(\n field: K,\n value: DiscountForm[K],\n ) => void;\n}\n\nconst TYPES: DiscountType[] = ['percent', 'fixed'];\n\nexport function DiscountFields({\n form,\n errors,\n labels,\n usedCount,\n onChange,\n}: DiscountFieldsProps) {\n const locked = usedCount > 0;\n const lockedHelp = locked\n ? fillTemplate(labels.lockedHelp, { count: usedCount })\n : undefined;\n const text = (\n name: DiscountFieldName,\n label: string,\n extra: {\n help?: string;\n locked?: boolean;\n inputMode?: 'decimal' | 'numeric';\n } = {},\n ) => (\n <Shell\n name={name}\n label={label}\n error={errors[name]}\n help={extra.help}\n disabled={extra.locked}\n >\n {(props) => (\n <input\n {...props}\n type=\"text\"\n inputMode={extra.inputMode}\n value={form[name]}\n onChange={(e) => onChange(name, e.target.value)}\n />\n )}\n </Shell>\n );\n const date = (name: 'startsAt' | 'endsAt') => (\n <Shell\n name={name}\n label={labels.fields[name]}\n error={errors[name]}\n help={labels.optionalHelp}\n >\n {(props) => (\n <input\n {...props}\n type=\"datetime-local\"\n value={form[name]}\n onChange={(e) => onChange(name, e.target.value)}\n />\n )}\n </Shell>\n );\n return (\n <>\n {text('code', labels.fields.code, { help: lockedHelp, locked })}\n <Shell name=\"type\" label={labels.fields.type} disabled={locked}>\n {(props) => (\n <select\n {...props}\n value={form.type}\n onChange={(e) => onChange('type', e.target.value as DiscountType)}\n >\n {TYPES.map((type) => (\n <option key={type} value={type}>\n {labels.types[type]}\n </option>\n ))}\n </select>\n )}\n </Shell>\n {form.type === 'percent'\n ? text('percentOff', labels.fields.percentOff, {\n locked,\n inputMode: 'numeric',\n })\n : text('amountOff', labels.fields.amountOff, {\n locked,\n inputMode: 'decimal',\n })}\n {text('minSubtotal', labels.fields.minSubtotal, {\n help: labels.optionalHelp,\n inputMode: 'decimal',\n })}\n {date('startsAt')}\n {date('endsAt')}\n {text('maxRedemptions', labels.fields.maxRedemptions, {\n help: labels.optionalHelp,\n inputMode: 'numeric',\n })}\n </>\n );\n}\n","import { useState, type FormEvent } from 'react';\nimport type { Discount } from '@develemit/commerce-contracts';\nimport {\n AdminInvalidInputError,\n DiscountCodeTakenError,\n MaxRedemptionsBelowUsageError,\n} from '../../client';\nimport { ConfirmDialog } from '../../components/confirm-dialog/confirm-dialog';\nimport { ErrorMessage } from '../../components/error-message/error-message';\nimport { Notice } from '../../components/notice/notice';\nimport {\n buildDiscountPatch,\n emptyDiscountForm,\n formFromDiscount,\n isDiscountUsed,\n mapDiscountIssues,\n validateDiscountForm,\n type DiscountFieldErrors,\n type DiscountForm,\n} from '../../lib/discount-form';\nimport { useAdmin, useAdminClient } from '../../lib/provider';\nimport { useAdminMutation } from '../../lib/use-admin-mutation';\nimport { useAdminQuery } from '../../lib/use-admin-query';\nimport { DiscountFields } from './discount-fields';\nimport { AdminPageHeader } from '../../components/page-header/admin-page-header';\n\nexport interface AdminDiscountEditorProps {\n discountId?: string;\n onSaved?: (discount: Discount) => void;\n}\n\nexport function AdminDiscountEditor({\n discountId,\n onSaved,\n}: AdminDiscountEditorProps) {\n if (!discountId)\n return <DiscountFormView discount={undefined} onSaved={onSaved} />;\n return <ExistingDiscountEditor discountId={discountId} onSaved={onSaved} />;\n}\n\nfunction ExistingDiscountEditor({\n discountId,\n onSaved,\n}: AdminDiscountEditorProps & { discountId: string }) {\n const client = useAdminClient();\n const { labels } = useAdmin();\n const query = useAdminQuery(['admin-discount', discountId], () =>\n client.getDiscount(discountId),\n );\n if (query.error) return <ErrorMessage error={query.error} />;\n if (!query.data) return <p>{labels.loading}</p>;\n return (\n <DiscountFormView\n key={query.data.id}\n discount={query.data}\n onSaved={onSaved}\n />\n );\n}\n\ninterface FormViewProps {\n discount: Discount | undefined;\n onSaved?: (discount: Discount) => void;\n}\n\nfunction DiscountFormView({ discount, onSaved }: FormViewProps) {\n const client = useAdminClient();\n const { labels, currency } = useAdmin();\n const copy = labels.discounts;\n const [base, setBase] = useState(discount);\n const [form, setForm] = useState<DiscountForm>(\n discount ? formFromDiscount(discount) : emptyDiscountForm,\n );\n const [fieldErrors, setFieldErrors] = useState<DiscountFieldErrors>({});\n const [saved, setSaved] = useState(false);\n const [confirming, setConfirming] = useState(false);\n const usedCount = base ? base.redeemedCount + base.reservedCount : 0;\n const locked = isDiscountUsed(base);\n\n const showErrors = (formEl: HTMLFormElement, found: DiscountFieldErrors) => {\n setFieldErrors(found);\n const name = Object.keys(found)[0];\n if (name) (formEl.elements.namedItem(name) as HTMLElement | null)?.focus();\n };\n\n const save = useAdminMutation(\n async (formEl: HTMLFormElement): Promise<Discount | undefined> => {\n const result = validateDiscountForm(\n form,\n copy,\n base?.currency ?? currency,\n usedCount,\n );\n if (!result.ok) {\n showErrors(formEl, result.errors);\n return undefined;\n }\n try {\n if (!base) return await client.createDiscount(result.input);\n const patch = buildDiscountPatch(base, result.input, locked);\n return Object.keys(patch).length === 0\n ? base\n : await client.updateDiscount(base.id, patch);\n } catch (error) {\n if (error instanceof DiscountCodeTakenError) {\n showErrors(formEl, { code: copy.validation.codeTaken });\n return undefined;\n }\n if (error instanceof MaxRedemptionsBelowUsageError) {\n showErrors(formEl, {\n maxRedemptions: copy.validation.maxRedemptionsBelowUsage,\n });\n return undefined;\n }\n if (!(error instanceof AdminInvalidInputError)) throw error;\n showErrors(\n formEl,\n mapDiscountIssues(error.issues, copy.validation.invalid),\n );\n return undefined;\n }\n },\n );\n\n const toggleActive = useAdminMutation((active: boolean) => {\n if (!base) throw new Error('Discount has not been created yet.');\n return client.updateDiscount(base.id, { active });\n });\n\n const adopt = (result: Discount) => {\n setBase(result);\n setForm(formFromDiscount(result));\n setSaved(true);\n onSaved?.(result);\n };\n\n const onChange: Parameters<typeof DiscountFields>[0]['onChange'] = (\n field,\n value,\n ) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n setFieldErrors((prev) => ({ ...prev, [field]: undefined }));\n };\n\n const onSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setSaved(false);\n setFieldErrors({});\n save.reset();\n const result = await save.run(event.currentTarget);\n if (result) adopt(result);\n };\n\n const setActive = async (active: boolean) => {\n setConfirming(false);\n setSaved(false);\n const result = await toggleActive.run(active);\n if (result) adopt(result);\n };\n\n return (\n <form noValidate className=\"sfa-form\" onSubmit={onSubmit}>\n <AdminPageHeader title={base ? copy.editTitle : copy.createTitle} />\n <ErrorMessage error={save.error ?? toggleActive.error} />\n <DiscountFields\n form={form}\n errors={fieldErrors}\n labels={copy}\n usedCount={usedCount}\n onChange={onChange}\n />\n <div className=\"sfa-row-actions\">\n <button\n type=\"submit\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={save.pending}\n >\n {labels.save}\n </button>\n {base?.active ? (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n onClick={() => setConfirming(true)}\n >\n {copy.deactivate}\n </button>\n ) : null}\n {base && !base.active ? (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n disabled={toggleActive.pending}\n onClick={() => setActive(true)}\n >\n {copy.reactivate}\n </button>\n ) : null}\n </div>\n <ConfirmDialog\n open={confirming}\n title={copy.deactivateTitle}\n confirmLabel={copy.deactivate}\n destructive\n pending={toggleActive.pending}\n onConfirm={() => setActive(false)}\n onCancel={() => setConfirming(false)}\n >\n <p>{copy.deactivateBody}</p>\n </ConfirmDialog>\n {saved ? (\n <Notice variant=\"success\" toast onDismiss={() => setSaved(false)}>\n {copy.saved}\n </Notice>\n ) : null}\n </form>\n );\n}\n","import { useCallback, useRef, useState } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { emptyForm } from './product-form';\nimport { draftInput } from './product-draft';\nimport { imageFileProblem } from './image-rules';\nimport { useAdmin, useAdminClient } from './provider';\n\nexport interface BatchItem {\n id: number;\n file: File;\n status: 'queued' | 'uploading' | 'done' | 'error';\n productId?: string;\n product?: AdminProduct;\n reason?: string;\n error?: unknown;\n}\n\nexport function useBatchUpload() {\n const client = useAdminClient();\n const { labels, currency } = useAdmin();\n const [items, setItems] = useState<BatchItem[]>([]);\n const nextId = useRef(0);\n const chain = useRef<Promise<void>>(Promise.resolve());\n\n const patch = (id: number, change: Partial<BatchItem>) =>\n setItems((prev) =>\n prev.map((item) => (item.id === id ? { ...item, ...change } : item)),\n );\n\n const sendOne = async (item: BatchItem) => {\n patch(item.id, { status: 'uploading', error: undefined });\n let productId = item.productId;\n try {\n if (!productId) {\n const created = await client.createProduct(\n draftInput(emptyForm, currency),\n );\n productId = created.id;\n patch(item.id, { productId });\n }\n const product = await client.uploadProductImage(productId, item.file, '');\n patch(item.id, { status: 'done', product });\n } catch (error) {\n patch(item.id, { status: 'error', error });\n }\n };\n\n const drain = (queue: BatchItem[]) => {\n for (const item of queue) {\n chain.current = chain.current.then(() => sendOne(item));\n }\n };\n\n const add = useCallback(\n (files: File[]) => {\n const added: BatchItem[] = files.map((file) => {\n const reason = imageFileProblem(file, labels.products.images);\n return {\n id: nextId.current++,\n file,\n status: reason ? 'error' : 'queued',\n reason: reason ?? undefined,\n };\n });\n setItems((prev) => [...prev, ...added]);\n drain(added.filter((item) => item.status === 'queued'));\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [client, labels, currency],\n );\n\n const retry = () => {\n const failed = items.filter(\n (item) => item.status === 'error' && !item.reason,\n );\n setItems((prev) =>\n prev.map((item) =>\n failed.some((f) => f.id === item.id)\n ? { ...item, status: 'queued' }\n : item,\n ),\n );\n drain(failed);\n };\n\n const done = items.filter((item) => item.status === 'done');\n const failed = items.filter((item) => item.status === 'error');\n const settled =\n items.length > 0 && done.length + failed.length === items.length;\n\n return {\n items,\n add,\n retry,\n done,\n failed,\n settled,\n products: done.flatMap((item) => (item.product ? [item.product] : [])),\n };\n}\n","import type { ChangeEvent } from 'react';\n\nexport interface PhotoPickerProps {\n label: string;\n onFiles: (files: File[]) => void;\n multiple?: boolean;\n primary?: boolean;\n}\n\nexport function PhotoPicker({\n label,\n onFiles,\n multiple = true,\n primary = false,\n}: PhotoPickerProps) {\n const pick = (event: ChangeEvent<HTMLInputElement>) => {\n onFiles(Array.from(event.target.files ?? []));\n event.target.value = '';\n };\n return (\n <label className={`sfa-btn${primary ? ' sfa-btn--primary' : ''}`}>\n {label}\n <input\n type=\"file\"\n accept=\"image/*\"\n multiple={multiple}\n className=\"sfa-sr-only\"\n onChange={pick}\n />\n </label>\n );\n}\n","import type { AdminProduct } from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../../components/error-message/error-message';\nimport { Notice } from '../../../components/notice/notice';\nimport { AdminPageHeader } from '../../../components/page-header/admin-page-header';\nimport { fillCount } from '../../../lib/product-missing';\nimport { useAdmin } from '../../../lib/provider';\nimport { useBatchUpload, type BatchItem } from '../../../lib/use-batch-upload';\nimport { PhotoPicker } from './photo-picker';\n\nexport interface AdminAddSeveralProps {\n onDone: (products: AdminProduct[]) => void;\n}\n\nfunction FailedList({ failed }: { failed: BatchItem[] }) {\n return (\n <ul className=\"sfa-batch__failed\">\n {failed.map((item) => (\n <li key={item.id}>\n <strong>{item.file.name}</strong>\n {item.reason ? (\n <Notice variant=\"error\">{item.reason}</Notice>\n ) : (\n <ErrorMessage error={item.error} />\n )}\n </li>\n ))}\n </ul>\n );\n}\n\nexport function AdminAddSeveral({ onDone }: AdminAddSeveralProps) {\n const { labels } = useAdmin();\n const copy = labels.products.stock.addSeveral;\n const batch = useBatchUpload();\n const total = batch.items.length;\n const retryable = batch.failed.some((item) => !item.reason);\n const finished = batch.done.length + batch.failed.length;\n\n const body = () => {\n if (total === 0) {\n return (\n <div className=\"sfa-batch__intro\">\n <h2>{copy.introTitle}</h2>\n <p>{copy.introBody}</p>\n <PhotoPicker label={copy.choose} onFiles={batch.add} primary />\n </div>\n );\n }\n if (!batch.settled) {\n return (\n <div className=\"sfa-batch__progress\" role=\"status\">\n <progress max={total} value={finished} />\n <p>{fillCount(copy.progress, { done: finished, total })}</p>\n </div>\n );\n }\n if (batch.failed.length === 0) {\n return (\n <div className=\"sfa-batch__result\">\n <h2>{fillCount(copy.doneTitle, { count: batch.done.length })}</h2>\n <p>{copy.doneBody}</p>\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n onClick={() => onDone(batch.products)}\n >\n {copy.next}\n </button>\n </div>\n );\n }\n return (\n <div className=\"sfa-batch__result\">\n <h2>{fillCount(copy.failedTitle, { count: batch.failed.length })}</h2>\n <FailedList failed={batch.failed} />\n <div className=\"sfa-batch__actions\">\n {retryable ? (\n <button type=\"button\" className=\"sfa-btn\" onClick={batch.retry}>\n {copy.retry}\n </button>\n ) : null}\n {batch.done.length ? (\n <button\n type=\"button\"\n className=\"sfa-btn\"\n onClick={() => onDone(batch.products)}\n >\n {copy.continueWithout}\n </button>\n ) : (\n <PhotoPicker label={copy.choose} onFiles={batch.add} />\n )}\n </div>\n </div>\n );\n };\n\n return (\n <section className=\"sfa-batch\">\n <AdminPageHeader title={copy.title} />\n <div className=\"sfa-batch__card\">{body()}</div>\n </section>\n );\n}\n","import { currencySymbol } from '../../../lib/product-draft';\nimport type { ProductForm } from '../../../lib/product-form';\nimport { useAdmin } from '../../../lib/provider';\n\nexport interface PieceFieldsProps {\n form: ProductForm;\n update: <K extends 'name' | 'price' | 'category'>(\n field: K,\n value: string,\n ) => void;\n categories?: string[];\n}\n\nexport function PieceFields({ form, update, categories }: PieceFieldsProps) {\n const { labels, locale, currency } = useAdmin();\n const fields = labels.products.fields;\n const copy = labels.products.flow;\n const choices = [...(categories ?? [])];\n const current = form.category.trim();\n if (current && !choices.includes(current)) choices.push(current);\n return (\n <div className=\"sfa-piece__fields\">\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor=\"sfa-piece-name\">\n {fields.name}\n </label>\n <input\n id=\"sfa-piece-name\"\n type=\"text\"\n autoComplete=\"off\"\n value={form.name}\n onChange={(e) => update('name', e.target.value)}\n />\n </div>\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor=\"sfa-piece-price\">\n {fields.price}\n </label>\n <span className=\"sfa-flow__price\">\n <span aria-hidden=\"true\">{currencySymbol(locale, currency)}</span>\n <input\n id=\"sfa-piece-price\"\n type=\"text\"\n inputMode=\"decimal\"\n placeholder={copy.pricePlaceholder}\n value={form.price}\n onChange={(e) => update('price', e.target.value)}\n />\n </span>\n </div>\n {choices.length ? (\n <div\n className=\"sfa-field\"\n role=\"group\"\n aria-labelledby=\"sfa-piece-category-label\"\n >\n <span id=\"sfa-piece-category-label\" className=\"sfa-field__label\">\n {fields.category}\n </span>\n <div className=\"sfa-flow__chips\">\n {choices.map((choice) => (\n <button\n key={choice}\n type=\"button\"\n className=\"sfa-chip\"\n aria-pressed={current === choice}\n onClick={() => update('category', choice)}\n >\n {choice}\n </button>\n ))}\n </div>\n </div>\n ) : (\n <div className=\"sfa-field\">\n <label className=\"sfa-field__label\" htmlFor=\"sfa-piece-category\">\n {fields.category}\n </label>\n <input\n id=\"sfa-piece-category\"\n type=\"text\"\n value={form.category}\n onChange={(e) => update('category', e.target.value)}\n />\n </div>\n )}\n </div>\n );\n}\n","import { useState } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../../components/error-message/error-message';\nimport { Notice } from '../../../components/notice/notice';\nimport { basicsReady, fillText } from '../../../lib/product-draft';\nimport { formFromProduct, type ProductForm } from '../../../lib/product-form';\nimport { fillCount } from '../../../lib/product-missing';\nimport { useAdmin } from '../../../lib/provider';\nimport { useImageUpload } from '../../../lib/use-image-upload';\nimport { useProductAutosave } from '../../../lib/use-product-autosave';\nimport { PhotoPicker } from '../add-several/photo-picker';\nimport { sortedImages } from '../product-flow/flow-images';\nimport { PieceFields } from './piece-fields';\n\nexport interface PieceCardProps {\n product: AdminProduct;\n index: number;\n total: number;\n categories?: string[];\n onAdvance: (product: AdminProduct) => void;\n onBack?: () => void;\n}\n\nexport function PieceCard({\n product,\n index,\n total,\n categories,\n onAdvance,\n onBack,\n}: PieceCardProps) {\n const { labels, renderImage } = useAdmin();\n const copy = labels.products.stock.queue;\n const [form, setForm] = useState<ProductForm>(() => formFromProduct(product));\n const autosave = useProductAutosave({ initial: product, form });\n const upload = useImageUpload({\n productId: product.id,\n onUploaded: autosave.setProduct,\n });\n const cover = sortedImages(autosave.product)[0];\n const last = index === total - 1;\n const n = String(index + 1);\n\n const update = (field: 'name' | 'price' | 'category', value: string) =>\n setForm((prev) => ({ ...prev, [field]: value }));\n\n const advance = async () => {\n const saved = await autosave.flush();\n if (saved) onAdvance(saved);\n };\n\n return (\n <section className=\"sfa-piece\" aria-labelledby=\"sfa-piece-title\">\n <p className=\"sfa-piece__count\" id=\"sfa-piece-title\">\n {fillCount(copy.pieceOf, { n: index + 1, m: total })}\n </p>\n <progress max={total} value={index + 1} aria-hidden=\"true\" />\n <div className=\"sfa-piece__body\">\n <div className=\"sfa-piece__photo\">\n {cover ? (\n renderImage({\n src: cover.url,\n alt: cover.alt || fillText(copy.coverAlt, { n }),\n sizes: '320px',\n })\n ) : (\n <PhotoPicker\n label={copy.addPhoto}\n multiple={false}\n onFiles={(files) => upload.upload(files, '')}\n />\n )}\n {upload.entries.map((entry) =>\n entry.status === 'error' ? (\n <Notice key={entry.id} variant=\"error\">\n {entry.reason ?? <ErrorMessage error={entry.error} />}\n </Notice>\n ) : null,\n )}\n </div>\n <PieceFields form={form} update={update} categories={categories} />\n </div>\n <ErrorMessage error={autosave.error} />\n <div className=\"sfa-piece__actions\">\n {onBack ? (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--ghost\"\n onClick={onBack}\n >\n {copy.back}\n </button>\n ) : null}\n <button\n type=\"button\"\n className=\"sfa-btn\"\n disabled={autosave.state === 'saving'}\n onClick={advance}\n >\n {copy.skip}\n </button>\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={!basicsReady(form) || autosave.state === 'saving'}\n onClick={advance}\n >\n {last ? copy.review : copy.next}\n </button>\n </div>\n </section>\n );\n}\n","import type { AdminProduct } from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../../components/error-message/error-message';\nimport { Money } from '../../../components/money/money';\nimport { basicsReady } from '../../../lib/product-draft';\nimport { formFromProduct } from '../../../lib/product-form';\nimport { fillCount } from '../../../lib/product-missing';\nimport { useAdmin } from '../../../lib/provider';\nimport { sortedImages } from '../product-flow/flow-images';\n\nexport interface PieceSummaryProps {\n pieces: AdminProduct[];\n pending: boolean;\n failure: unknown;\n onPublish: (ready: AdminProduct[], rest: AdminProduct[]) => void;\n onKeepDrafts: () => void;\n}\n\nexport function isReady(piece: AdminProduct) {\n return basicsReady(formFromProduct(piece));\n}\n\nexport function PieceSummary({\n pieces,\n pending,\n failure,\n onPublish,\n onKeepDrafts,\n}: PieceSummaryProps) {\n const { labels, renderImage } = useAdmin();\n const copy = labels.products.stock.summary;\n const ready = pieces.filter(isReady);\n const rest = pieces.filter((piece) => !isReady(piece));\n return (\n <section className=\"sfa-piece\" aria-labelledby=\"sfa-summary-title\">\n <h2 id=\"sfa-summary-title\">{copy.title}</h2>\n <p>{ready.length ? copy.lede : copy.allSkipped}</p>\n <ul className=\"sfa-summary__list\">\n {pieces.map((piece) => {\n const cover = sortedImages(piece)[0];\n return (\n <li key={piece.id} className=\"sfa-summary__row\">\n <span className=\"sfa-summary__photo\">\n {cover\n ? renderImage({ src: cover.url, alt: '', sizes: '56px' })\n : null}\n </span>\n <span className=\"sfa-summary__name\">\n {piece.name || copy.untitled}\n </span>\n <span className=\"sfa-summary__price\">\n {isReady(piece) && piece.priceCents !== null ? (\n <Money cents={piece.priceCents} currency={piece.currency} />\n ) : (\n copy.needsDetails\n )}\n </span>\n </li>\n );\n })}\n </ul>\n <ErrorMessage error={failure} />\n <div className=\"sfa-piece__actions\">\n <button\n type=\"button\"\n className=\"sfa-btn\"\n disabled={pending}\n onClick={onKeepDrafts}\n >\n {copy.keepDrafts}\n </button>\n {ready.length ? (\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n disabled={pending}\n onClick={() => onPublish(ready, rest)}\n >\n {fillCount(copy.publish, { count: ready.length })}\n </button>\n ) : null}\n </div>\n </section>\n );\n}\n","import type { AdminProduct } from '@develemit/commerce-contracts';\nimport type { AdminClient } from '../client';\nimport { fillText } from './product-draft';\n\nexport async function fillBlankAlts(\n client: AdminClient,\n product: AdminProduct,\n template: string,\n): Promise<AdminProduct> {\n const name = product.name.trim();\n if (!name) return product;\n let next = product;\n const sorted = [...product.images].sort((a, b) => a.position - b.position);\n for (const [index, image] of sorted.entries()) {\n if (image.alt.trim()) continue;\n const alt = fillText(template, { name, n: String(index + 1) });\n next = await client.updateProductImage(product.id, image.id, { alt });\n }\n return next;\n}\n","import { useState } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { ProductIncompleteError } from '../../../client';\nimport { fillBlankAlts } from '../../../lib/fill-alts';\nimport { useAdmin, useAdminClient } from '../../../lib/provider';\n\nexport interface PublishOutcome {\n published: AdminProduct[];\n drafts: AdminProduct[];\n}\n\nexport function usePublishPieces() {\n const client = useAdminClient();\n const { labels } = useAdmin();\n const [pending, setPending] = useState(false);\n const [failure, setFailure] = useState<unknown>(undefined);\n const [outcome, setOutcome] = useState<PublishOutcome | null>(null);\n\n const publish = async (ready: AdminProduct[], rest: AdminProduct[]) => {\n setPending(true);\n setFailure(undefined);\n const published: AdminProduct[] = [];\n const drafts = [...rest];\n for (const piece of ready) {\n try {\n await fillBlankAlts(client, piece, labels.products.flow.altFallback);\n published.push(\n await client.updateProduct(piece.id, { status: 'active' }),\n );\n } catch (error) {\n drafts.push(piece);\n if (!(error instanceof ProductIncompleteError)) setFailure(error);\n }\n }\n setPending(false);\n const result = { published, drafts };\n setOutcome(result);\n return result;\n };\n\n return { publish, pending, failure, outcome };\n}\n","import { useState } from 'react';\nimport type { AdminProduct } from '@develemit/commerce-contracts';\nimport { ErrorMessage } from '../../../components/error-message/error-message';\nimport { AdminPageHeader } from '../../../components/page-header/admin-page-header';\nimport { fillCount } from '../../../lib/product-missing';\nimport { useAdmin, useAdminClient } from '../../../lib/provider';\nimport { useAdminQuery } from '../../../lib/use-admin-query';\nimport { PieceCard } from './piece-card';\nimport { PieceSummary } from './piece-summary';\nimport { usePublishPieces, type PublishOutcome } from './use-publish-pieces';\n\nexport interface AdminFinishDraftsProps {\n productIds?: string[];\n categories?: string[];\n onDone: (result: PublishOutcome) => void;\n}\n\ninterface QueueProps {\n initial: AdminProduct[];\n categories?: string[];\n onDone: (result: PublishOutcome) => void;\n}\n\nfunction Queue({ initial, categories, onDone }: QueueProps) {\n const { labels } = useAdmin();\n const copy = labels.products.stock;\n const [pieces, setPieces] = useState(initial);\n const [index, setIndex] = useState(0);\n const publisher = usePublishPieces();\n\n if (publisher.outcome) {\n const { published, drafts } = publisher.outcome;\n return (\n <section className=\"sfa-piece\">\n <h2>\n {fillCount(copy.summary.publishedTitle, { count: published.length })}\n </h2>\n <p>{copy.summary.publishedBody}</p>\n {drafts.length ? (\n <p>\n {fillCount(copy.summary.stillIncomplete, { count: drafts.length })}\n </p>\n ) : null}\n <div className=\"sfa-piece__actions\">\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n onClick={() => onDone(publisher.outcome!)}\n >\n {copy.queue.done}\n </button>\n </div>\n </section>\n );\n }\n\n if (index >= pieces.length) {\n return (\n <PieceSummary\n pieces={pieces}\n pending={publisher.pending}\n failure={publisher.failure}\n onPublish={publisher.publish}\n onKeepDrafts={() => onDone({ published: [], drafts: pieces })}\n />\n );\n }\n\n const advance = (saved: AdminProduct) => {\n setPieces((prev) => prev.map((p) => (p.id === saved.id ? saved : p)));\n setIndex(index + 1);\n };\n\n return (\n <PieceCard\n key={pieces[index].id}\n product={pieces[index]}\n index={index}\n total={pieces.length}\n categories={categories}\n onAdvance={advance}\n onBack={index > 0 ? () => setIndex(index - 1) : undefined}\n />\n );\n}\n\nexport function AdminFinishDrafts({\n productIds,\n categories,\n onDone,\n}: AdminFinishDraftsProps) {\n const client = useAdminClient();\n const { labels } = useAdmin();\n const copy = labels.products.stock.queue;\n const query = useAdminQuery(['finish-drafts', productIds ?? null], () =>\n productIds\n ? Promise.all(productIds.map((id) => client.getProduct(id)))\n : client\n .listProducts({ incomplete: 'true', limit: 100 })\n .then((page) => [...page.items].reverse()),\n );\n\n const body = () => {\n if (query.error) return <ErrorMessage error={query.error} />;\n if (!query.data) return <p role=\"status\">{copy.loading}</p>;\n if (query.data.length === 0) {\n return (\n <div className=\"sfa-piece\">\n <p>{copy.nothingToFinish}</p>\n <button\n type=\"button\"\n className=\"sfa-btn sfa-btn--primary\"\n onClick={() => onDone({ published: [], drafts: [] })}\n >\n {copy.done}\n </button>\n </div>\n );\n }\n return (\n <Queue initial={query.data} categories={categories} onDone={onDone} />\n );\n };\n\n return (\n <section className=\"sfa-queue\">\n <AdminPageHeader title={copy.title} />\n {body()}\n </section>\n );\n}\n"],"mappings":"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"}
|