@develemit/commerce-admin 0.4.0 → 0.6.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/README.md +1 -1
- package/dist/client/errors.d.ts +3 -0
- package/dist/client/index.js +1 -1
- package/dist/client/transport.d.ts +3 -1
- package/dist/{client--_j5r8ag.js → client-CSjuKdIE.js} +47 -37
- package/dist/client-CSjuKdIE.js.map +1 -0
- package/dist/index.js +641 -666
- package/dist/index.js.map +1 -1
- package/dist/lib/use-order-pages.d.ts +2 -0
- package/dist/lib/use-paged-list.d.ts +15 -0
- package/package.json +2 -2
- 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","TABS","_Fragment","_Fragment","_Fragment","_Fragment","AdminUnauthorizedError","ImageTooLargeError","InvalidOrderStateError","MaxRedemptionsBelowUsageError","RefundOutcomeUnknownError","AdminNotFoundError","InsufficientStockError","RefundGatewayError","DiscountCodeTakenError","RefundExceedsBalanceError","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","errorKey","type","ErrorMessage","isSold","product","displayStatus","serverStatus","filter","serverStock","useDebounced","debounced","setDebounced","delayMs","usePagedList","fetchPage","appended","setAppended","more","page","cursor","extra","nextCursor","useProductPages","query","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-paged-list.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 { 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 { 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 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 { 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 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 { 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 {\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';\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 <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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"}
|