@tallyui/components 3.3.0 → 3.4.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/dist/index.js CHANGED
@@ -3962,8 +3962,9 @@ function ConnectorStatus({
3962
3962
  }
3963
3963
 
3964
3964
  // src/sale/cart.tsx
3965
- import { useState as useState18 } from "react";
3966
- import { Pressable as Pressable25, Text as Text34, View as View56 } from "react-native";
3965
+ import { useState as useState19 } from "react";
3966
+ import { Pressable as Pressable26, Text as Text35, View as View57 } from "react-native";
3967
+ import { formatMoney as formatMoney12 } from "@tallyui/core";
3967
3968
  import { buildReceiptData } from "@tallyui/pos";
3968
3969
 
3969
3970
  // src/sale/discount-form.tsx
@@ -4119,17 +4120,113 @@ function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
4119
4120
  ] });
4120
4121
  }
4121
4122
 
4122
- // src/sale/cart.tsx
4123
+ // src/sale/charge-form.tsx
4124
+ import { useState as useState18 } from "react";
4125
+ import { Pressable as Pressable25, Text as Text34, TextInput as TextInput11, View as View56 } from "react-native";
4123
4126
  import { Fragment as Fragment5, jsx as jsx90, jsxs as jsxs49 } from "react/jsx-runtime";
4124
- function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPrice = false, onPriceChange }) {
4127
+ var button3 = "rounded-md border border-border px-3 py-2 min-h-11 items-center justify-center";
4128
+ function ChargeForm({ currency, lineTax, taxClasses, shippingTaxFromStore, onApply, onClose }) {
4129
+ const [kind, setKind] = useState18("fee");
4130
+ const [name, setName] = useState18("");
4131
+ const [text, setText] = useState18("");
4132
+ const [noTax, setNoTax] = useState18(false);
4133
+ const [taxClass, setTaxClass] = useState18("");
4134
+ const [error, setError] = useState18(null);
4135
+ const storeShipping = kind === "shipping" && shippingTaxFromStore;
4136
+ function apply() {
4137
+ const parsed = parsePrice(text, currency);
4138
+ const refused = !name.trim() ? "Enter a name." : typeof parsed === "string" ? parsed : onApply({
4139
+ kind,
4140
+ name: name.trim(),
4141
+ amountMinor: parsed,
4142
+ taxStatus: !storeShipping && lineTax?.none && noTax ? "none" : void 0,
4143
+ taxClass: !storeShipping && lineTax?.classes && taxClasses?.length ? taxClass || void 0 : void 0
4144
+ });
4145
+ setError(refused);
4146
+ if (refused === null) onClose();
4147
+ }
4148
+ return /* @__PURE__ */ jsxs49(View56, { testID: "charge-form", role: "group", accessibilityLabel: "Add charge", className: "gap-2 px-3 py-2", children: [
4149
+ /* @__PURE__ */ jsx90(Text34, { className: "font-semibold text-foreground", children: "Add charge" }),
4150
+ /* @__PURE__ */ jsx90(View56, { className: "flex-row gap-2", children: ["fee", "shipping", "custom"].map((option) => /* @__PURE__ */ jsx90(
4151
+ Pressable25,
4152
+ {
4153
+ accessibilityRole: "button",
4154
+ accessibilityState: { selected: kind === option },
4155
+ "aria-selected": kind === option,
4156
+ onPress: () => setKind(option),
4157
+ className: `${button3} ${kind === option ? "bg-primary" : "bg-card"}`,
4158
+ children: /* @__PURE__ */ jsx90(Text34, { className: kind === option ? "text-primary-foreground" : "text-foreground", children: option === "fee" ? "Fee" : option === "shipping" ? "Shipping" : "Custom item" })
4159
+ },
4160
+ option
4161
+ )) }),
4162
+ /* @__PURE__ */ jsx90(
4163
+ TextInput11,
4164
+ {
4165
+ accessibilityLabel: "Name",
4166
+ placeholder: "Name",
4167
+ value: name,
4168
+ onChangeText: setName,
4169
+ className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
4170
+ }
4171
+ ),
4172
+ /* @__PURE__ */ jsx90(
4173
+ TextInput11,
4174
+ {
4175
+ accessibilityLabel: "Amount",
4176
+ value: text,
4177
+ onChangeText: setText,
4178
+ onSubmitEditing: apply,
4179
+ inputMode: "decimal",
4180
+ placeholder: currency,
4181
+ className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
4182
+ }
4183
+ ),
4184
+ storeShipping ? /* @__PURE__ */ jsx90(Text34, { className: "text-muted-foreground", children: "Shipping is taxed at the store's shipping tax class." }) : /* @__PURE__ */ jsxs49(Fragment5, { children: [
4185
+ lineTax?.none ? /* @__PURE__ */ jsx90(
4186
+ Pressable25,
4187
+ {
4188
+ accessibilityRole: "switch",
4189
+ accessibilityLabel: "No tax",
4190
+ accessibilityState: { checked: noTax },
4191
+ "aria-checked": noTax,
4192
+ onPress: () => setNoTax(!noTax),
4193
+ className: `${button3} ${noTax ? "bg-primary" : "bg-card"}`,
4194
+ children: /* @__PURE__ */ jsx90(Text34, { className: noTax ? "text-primary-foreground" : "text-foreground", children: "No tax" })
4195
+ }
4196
+ ) : null,
4197
+ lineTax?.classes && taxClasses?.length ? /* @__PURE__ */ jsx90(View56, { role: "group", accessibilityLabel: "Tax class", className: "flex-row flex-wrap gap-2", children: [{ id: "", label: "No class" }, ...taxClasses].map((option) => /* @__PURE__ */ jsx90(
4198
+ Pressable25,
4199
+ {
4200
+ accessibilityRole: "button",
4201
+ accessibilityState: { selected: taxClass === option.id },
4202
+ "aria-selected": taxClass === option.id,
4203
+ onPress: () => setTaxClass(option.id),
4204
+ className: `${button3} ${taxClass === option.id ? "bg-primary" : "bg-card"}`,
4205
+ children: /* @__PURE__ */ jsx90(Text34, { className: taxClass === option.id ? "text-primary-foreground" : "text-foreground", children: option.label })
4206
+ },
4207
+ option.id
4208
+ )) }) : null
4209
+ ] }),
4210
+ error ? /* @__PURE__ */ jsx90(Text34, { accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
4211
+ /* @__PURE__ */ jsxs49(View56, { className: "flex-row gap-2", children: [
4212
+ /* @__PURE__ */ jsx90(Pressable25, { accessibilityRole: "button", onPress: apply, className: `${button3} bg-primary`, children: /* @__PURE__ */ jsx90(Text34, { className: "font-semibold text-primary-foreground", children: "Apply" }) }),
4213
+ /* @__PURE__ */ jsx90(Pressable25, { accessibilityRole: "button", onPress: onClose, className: `${button3} bg-card`, children: /* @__PURE__ */ jsx90(Text34, { className: "text-foreground", children: "Cancel" }) })
4214
+ ] })
4215
+ ] });
4216
+ }
4217
+
4218
+ // src/sale/cart.tsx
4219
+ import { Fragment as Fragment6, jsx as jsx91, jsxs as jsxs50 } from "react/jsx-runtime";
4220
+ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPrice = false, onPriceChange, taxClasses }) {
4125
4221
  const { order } = sale;
4126
4222
  const money = (amount) => ({ amount, currency: order.currency });
4127
4223
  const { totals } = buildReceiptData(order, { storeName: "" });
4128
4224
  const taxRows = totals.taxLines.map((line) => ({ label: taxLabel(line.ratePpm), amount: money(line.amountMinor) }));
4129
4225
  const display = (lineId) => order.display.lines.find((line) => line.lineId === lineId);
4130
4226
  const orderAmounts = order.discounts.length === 1 ? [{ discountId: order.discounts[0].id, amountMinor: order.display.orderDiscountMinor }] : [];
4131
- const [form, setForm] = useState18(null);
4132
- const discountForm = (lineId, title) => form?.type === "discount" && form.lineId === lineId ? /* @__PURE__ */ jsx90(
4227
+ const [form, setForm] = useState19(null);
4228
+ const chargesOffered = (sale.capabilities?.orderCreate ?? 0) >= 5;
4229
+ const discountForm = (lineId, title) => form?.type === "discount" && form.lineId === lineId ? /* @__PURE__ */ jsx91(
4133
4230
  DiscountForm,
4134
4231
  {
4135
4232
  title,
@@ -4140,11 +4237,11 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4140
4237
  lineId ?? "order"
4141
4238
  ) : null;
4142
4239
  const pay = `min-h-12 flex-1 justify-center rounded-md bg-primary px-4 py-3 ${!order.lineItems.length ? "opacity-50" : ""}`;
4143
- const renderItem = (line) => /* @__PURE__ */ jsxs49(Fragment5, { children: [
4144
- /* @__PURE__ */ jsx90(CartLineActions, { actions: [
4240
+ const renderItem = (line) => /* @__PURE__ */ jsxs50(Fragment6, { children: [
4241
+ /* @__PURE__ */ jsx91(CartLineActions, { actions: [
4145
4242
  { id: "discount", label: "Discount", color: "text-primary", onPress: () => setForm({ type: "discount", lineId: line.id }) },
4146
4243
  ...canEditPrice ? [{ id: "price", label: "Price", color: "text-primary", onPress: () => setForm({ type: "price", lineId: line.id }) }] : []
4147
- ], children: /* @__PURE__ */ jsx90(
4244
+ ], children: /* @__PURE__ */ jsx91(
4148
4245
  CartLine,
4149
4246
  {
4150
4247
  name: line.name,
@@ -4153,41 +4250,41 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4153
4250
  lineTotal: money(display(line.id).amountMinor)
4154
4251
  }
4155
4252
  ) }),
4156
- /* @__PURE__ */ jsx90(DiscountChips, { discounts: line.discounts, amounts: display(line.id).discounts, currency: order.currency, onRemove: sale.removeDiscount }),
4157
- /* @__PURE__ */ jsxs49(View56, { className: "flex-row gap-4 px-3 py-2", children: [
4158
- /* @__PURE__ */ jsx90(
4159
- Pressable25,
4253
+ /* @__PURE__ */ jsx91(DiscountChips, { discounts: line.discounts, amounts: display(line.id).discounts, currency: order.currency, onRemove: sale.removeDiscount }),
4254
+ /* @__PURE__ */ jsxs50(View57, { className: "flex-row gap-4 px-3 py-2", children: [
4255
+ /* @__PURE__ */ jsx91(
4256
+ Pressable26,
4160
4257
  {
4161
4258
  accessibilityRole: "button",
4162
4259
  accessibilityLabel: `Decrease ${line.name}`,
4163
4260
  onPress: () => sale.setQuantity(line.id, line.quantity - 1),
4164
4261
  className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
4165
- children: /* @__PURE__ */ jsx90(Text34, { className: "text-center text-foreground", children: "\u2212" })
4262
+ children: /* @__PURE__ */ jsx91(Text35, { className: "text-center text-foreground", children: "\u2212" })
4166
4263
  }
4167
4264
  ),
4168
- /* @__PURE__ */ jsx90(
4169
- Pressable25,
4265
+ /* @__PURE__ */ jsx91(
4266
+ Pressable26,
4170
4267
  {
4171
4268
  accessibilityRole: "button",
4172
4269
  accessibilityLabel: `Increase ${line.name}`,
4173
4270
  onPress: () => sale.setQuantity(line.id, line.quantity + 1),
4174
4271
  className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
4175
- children: /* @__PURE__ */ jsx90(Text34, { className: "text-center text-foreground", children: "+" })
4272
+ children: /* @__PURE__ */ jsx91(Text35, { className: "text-center text-foreground", children: "+" })
4176
4273
  }
4177
4274
  ),
4178
- /* @__PURE__ */ jsx90(
4179
- Pressable25,
4275
+ /* @__PURE__ */ jsx91(
4276
+ Pressable26,
4180
4277
  {
4181
4278
  accessibilityRole: "button",
4182
4279
  accessibilityLabel: `Remove ${line.name}`,
4183
4280
  onPress: () => sale.remove(line.id),
4184
4281
  className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
4185
- children: /* @__PURE__ */ jsx90(Text34, { className: "text-center text-foreground", children: "Remove" })
4282
+ children: /* @__PURE__ */ jsx91(Text35, { className: "text-center text-foreground", children: "Remove" })
4186
4283
  }
4187
4284
  )
4188
4285
  ] }),
4189
4286
  discountForm(line.id, `Discount on ${line.name}`),
4190
- canEditPrice && form?.type === "price" && form.lineId === line.id ? /* @__PURE__ */ jsx90(
4287
+ canEditPrice && form?.type === "price" && form.lineId === line.id ? /* @__PURE__ */ jsx91(
4191
4288
  PriceForm,
4192
4289
  {
4193
4290
  lineName: line.name,
@@ -4204,36 +4301,76 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4204
4301
  line.id
4205
4302
  ) : null
4206
4303
  ] });
4207
- return /* @__PURE__ */ jsx90(
4304
+ return /* @__PURE__ */ jsx91(
4208
4305
  CartPanel,
4209
4306
  {
4210
4307
  dataSet: { print: "hide" },
4211
4308
  items: order.lineItems,
4212
4309
  renderItem,
4213
- emptyState: /* @__PURE__ */ jsx90(Text34, { testID: "cart-empty", className: "px-3 py-2 text-muted-foreground", children: "Scan or tap a product to start a sale." }),
4214
- afterItems: order.lineItems.length ? /* @__PURE__ */ jsxs49(View56, { className: "gap-3 px-3 py-2", children: [
4215
- /* @__PURE__ */ jsx90(
4216
- DiscountChips,
4217
- {
4218
- discounts: order.discounts,
4219
- amounts: orderAmounts,
4220
- currency: order.currency,
4221
- onRemove: sale.removeDiscount,
4222
- prefix: "Order discount"
4223
- }
4224
- ),
4225
- form?.lineId === null ? discountForm(null, "Order discount") : /* @__PURE__ */ jsx90(
4226
- Pressable25,
4227
- {
4228
- accessibilityRole: "button",
4229
- onPress: () => setForm({ type: "discount", lineId: null }),
4230
- className: "self-start rounded-md border border-border bg-card px-4 py-2 min-h-11 justify-center",
4231
- children: /* @__PURE__ */ jsx90(Text34, { className: "text-foreground", children: "Order discount" })
4232
- }
4233
- )
4234
- ] }) : void 0,
4235
- footer: /* @__PURE__ */ jsxs49(View56, { testID: "cart-footer", className: "gap-3 pb-4", children: [
4236
- /* @__PURE__ */ jsx90(
4310
+ emptyState: /* @__PURE__ */ jsx91(Text35, { testID: "cart-empty", className: "px-3 py-2 text-muted-foreground", children: "Scan or tap a product to start a sale." }),
4311
+ afterItems: /* @__PURE__ */ jsxs50(Fragment6, { children: [
4312
+ ["fees", "shipping"].map((kind) => order[kind]?.map((charge, index) => /* @__PURE__ */ jsxs50(View57, { testID: `cart-${kind === "fees" ? "fee" : "shipping"}-${index}`, className: "flex-row items-center gap-3 px-3 py-2", children: [
4313
+ /* @__PURE__ */ jsx91(Text35, { className: "flex-1 text-foreground", children: charge.name }),
4314
+ /* @__PURE__ */ jsx91(Text35, { className: "text-foreground", children: formatMoney12(money(order.display[kind].find((row) => row.id === charge.id).amountMinor)) }),
4315
+ /* @__PURE__ */ jsx91(
4316
+ Pressable26,
4317
+ {
4318
+ accessibilityRole: "button",
4319
+ accessibilityLabel: `Remove ${charge.name}`,
4320
+ onPress: () => kind === "fees" ? sale.removeFee(charge.id) : sale.removeShipping(charge.id),
4321
+ className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 items-center justify-center",
4322
+ children: /* @__PURE__ */ jsx91(Text35, { className: "text-foreground", children: "Remove" })
4323
+ }
4324
+ )
4325
+ ] }, charge.id))),
4326
+ order.lineItems.length || chargesOffered ? /* @__PURE__ */ jsxs50(View57, { className: "gap-3 px-3 py-2", children: [
4327
+ order.lineItems.length ? /* @__PURE__ */ jsxs50(Fragment6, { children: [
4328
+ /* @__PURE__ */ jsx91(
4329
+ DiscountChips,
4330
+ {
4331
+ discounts: order.discounts,
4332
+ amounts: orderAmounts,
4333
+ currency: order.currency,
4334
+ onRemove: sale.removeDiscount,
4335
+ prefix: "Order discount"
4336
+ }
4337
+ ),
4338
+ form?.type === "discount" && form.lineId === null ? discountForm(null, "Order discount") : /* @__PURE__ */ jsx91(
4339
+ Pressable26,
4340
+ {
4341
+ accessibilityRole: "button",
4342
+ onPress: () => setForm({ type: "discount", lineId: null }),
4343
+ className: "self-start rounded-md border border-border bg-card px-4 py-2 min-h-11 justify-center",
4344
+ children: /* @__PURE__ */ jsx91(Text35, { className: "text-foreground", children: "Order discount" })
4345
+ }
4346
+ )
4347
+ ] }) : null,
4348
+ chargesOffered ? form?.type === "charge" ? /* @__PURE__ */ jsx91(
4349
+ ChargeForm,
4350
+ {
4351
+ currency: order.currency,
4352
+ lineTax: sale.capabilities?.lineTax,
4353
+ taxClasses,
4354
+ shippingTaxFromStore: sale.capabilities?.taxRounding?.granularity === "woocommerce",
4355
+ onClose: () => setForm(null),
4356
+ onApply: ({ kind, name, amountMinor, taxStatus, taxClass }) => {
4357
+ const result = kind === "custom" ? sale.addCustomLine({ name, priceMinor: amountMinor, taxStatus, taxClass }) : kind === "fee" ? sale.addFee({ name, amountMinor, taxStatus, taxClass }) : sale.addShipping({ name, amountMinor, taxStatus, taxClass });
4358
+ return typeof result === "string" ? result : null;
4359
+ }
4360
+ }
4361
+ ) : /* @__PURE__ */ jsx91(
4362
+ Pressable26,
4363
+ {
4364
+ accessibilityRole: "button",
4365
+ onPress: () => setForm({ type: "charge" }),
4366
+ className: "self-start rounded-md border border-border bg-card px-4 py-2 min-h-11 justify-center",
4367
+ children: /* @__PURE__ */ jsx91(Text35, { className: "text-foreground", children: "Add charge" })
4368
+ }
4369
+ ) : null
4370
+ ] }) : null
4371
+ ] }),
4372
+ footer: /* @__PURE__ */ jsxs50(View57, { testID: "cart-footer", className: "gap-3 pb-4", children: [
4373
+ /* @__PURE__ */ jsx91(
4237
4374
  CartTotal,
4238
4375
  {
4239
4376
  subtotal: money(totals.subtotalMinor),
@@ -4243,10 +4380,10 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4243
4380
  taxInclusive: totals.taxInclusive
4244
4381
  }
4245
4382
  ),
4246
- sale.error ? /* @__PURE__ */ jsx90(Text34, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4247
- /* @__PURE__ */ jsxs49(View56, { className: "flex-row gap-3", children: [
4248
- /* @__PURE__ */ jsx90(Pressable25, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("cash"), className: pay, children: /* @__PURE__ */ jsx90(Text34, { className: "text-center font-semibold text-primary-foreground", children: "Cash" }) }),
4249
- /* @__PURE__ */ jsx90(Pressable25, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("external"), className: pay, children: /* @__PURE__ */ jsx90(Text34, { className: "text-center font-semibold text-primary-foreground", children: "Card terminal" }) })
4383
+ sale.error ? /* @__PURE__ */ jsx91(Text35, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4384
+ /* @__PURE__ */ jsxs50(View57, { className: "flex-row gap-3", children: [
4385
+ /* @__PURE__ */ jsx91(Pressable26, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("cash"), className: pay, children: /* @__PURE__ */ jsx91(Text35, { className: "text-center font-semibold text-primary-foreground", children: "Cash" }) }),
4386
+ /* @__PURE__ */ jsx91(Pressable26, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("external"), className: pay, children: /* @__PURE__ */ jsx91(Text35, { className: "text-center font-semibold text-primary-foreground", children: "Card terminal" }) })
4250
4387
  ] })
4251
4388
  ] })
4252
4389
  }
@@ -4254,17 +4391,17 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4254
4391
  }
4255
4392
 
4256
4393
  // src/sale/cart-bar.tsx
4257
- import { Pressable as Pressable26, Text as Text35 } from "react-native";
4258
- import { formatMoney as formatMoney12 } from "@tallyui/core";
4394
+ import { Pressable as Pressable27, Text as Text36 } from "react-native";
4395
+ import { formatMoney as formatMoney13 } from "@tallyui/core";
4259
4396
  import { buildReceiptData as buildReceiptData2 } from "@tallyui/pos";
4260
- import { jsx as jsx91, jsxs as jsxs50 } from "react/jsx-runtime";
4397
+ import { jsx as jsx92, jsxs as jsxs51 } from "react/jsx-runtime";
4261
4398
  function CartBar({ sale, onOpen }) {
4262
4399
  const { order } = sale;
4263
4400
  const count2 = order.lineItems.reduce((sum, line) => sum + line.quantity, 0);
4264
- const total = formatMoney12({ amount: buildReceiptData2(order, { storeName: "" }).totals.totalMinor, currency: order.currency });
4401
+ const total = formatMoney13({ amount: buildReceiptData2(order, { storeName: "" }).totals.totalMinor, currency: order.currency });
4265
4402
  const items = `${count2} ${count2 === 1 ? "item" : "items"}`;
4266
- return /* @__PURE__ */ jsxs50(
4267
- Pressable26,
4403
+ return /* @__PURE__ */ jsxs51(
4404
+ Pressable27,
4268
4405
  {
4269
4406
  accessibilityRole: "button",
4270
4407
  accessibilityLabel: count2 ? `Open cart, ${items}, ${total}` : "Cart is empty",
@@ -4272,8 +4409,8 @@ function CartBar({ sale, onOpen }) {
4272
4409
  onPress: onOpen,
4273
4410
  className: `min-h-14 mx-3 mb-3 flex-row items-center justify-between rounded-md bg-primary px-4 py-3 ${count2 ? "" : "opacity-50"}`,
4274
4411
  children: [
4275
- /* @__PURE__ */ jsx91(Text35, { className: "font-bold text-primary-foreground", children: count2 ? `Cart \xB7 ${items}` : "Cart is empty" }),
4276
- count2 ? /* @__PURE__ */ jsxs50(Text35, { className: "font-bold text-primary-foreground", children: [
4412
+ /* @__PURE__ */ jsx92(Text36, { className: "font-bold text-primary-foreground", children: count2 ? `Cart \xB7 ${items}` : "Cart is empty" }),
4413
+ count2 ? /* @__PURE__ */ jsxs51(Text36, { className: "font-bold text-primary-foreground", children: [
4277
4414
  total,
4278
4415
  " \u203A"
4279
4416
  ] }) : null
@@ -4283,17 +4420,17 @@ function CartBar({ sale, onOpen }) {
4283
4420
  }
4284
4421
 
4285
4422
  // src/sale/tender.tsx
4286
- import { Pressable as Pressable27, Text as Text36, TextInput as TextInput11, View as View57 } from "react-native";
4287
- import { formatMoney as formatMoney13 } from "@tallyui/core";
4288
- import { Fragment as Fragment6, jsx as jsx92, jsxs as jsxs51 } from "react/jsx-runtime";
4423
+ import { Pressable as Pressable28, Text as Text37, TextInput as TextInput12, View as View58 } from "react-native";
4424
+ import { formatMoney as formatMoney14 } from "@tallyui/core";
4425
+ import { Fragment as Fragment7, jsx as jsx93, jsxs as jsxs52 } from "react/jsx-runtime";
4289
4426
  var REFERENCE_MAX = 255;
4290
4427
  function Tender({ sale }) {
4291
4428
  const { order, stage } = sale;
4292
4429
  if (stage.kind !== "tender") return null;
4293
4430
  const money = (amount) => ({ amount, currency: order.currency });
4294
- return /* @__PURE__ */ jsxs51(View57, { dataSet: { print: "hide" }, className: "gap-4 p-4", children: [
4295
- stage.method === "cash" ? /* @__PURE__ */ jsxs51(Fragment6, { children: [
4296
- /* @__PURE__ */ jsx92(
4431
+ return /* @__PURE__ */ jsxs52(View58, { dataSet: { print: "hide" }, className: "gap-4 p-4", children: [
4432
+ stage.method === "cash" ? /* @__PURE__ */ jsxs52(Fragment7, { children: [
4433
+ /* @__PURE__ */ jsx93(
4297
4434
  CashTendered,
4298
4435
  {
4299
4436
  total: money(order.totalMinor),
@@ -4301,19 +4438,19 @@ function Tender({ sale }) {
4301
4438
  onChangeAmount: (amount) => sale.setTender({ method: "cash", amountMinor: amount.amount })
4302
4439
  }
4303
4440
  ),
4304
- /* @__PURE__ */ jsx92(ChangeDisplay, { change: money(order.changeDueMinor) }),
4305
- order.balanceDueMinor > 0 ? /* @__PURE__ */ jsxs51(Text36, { className: "text-foreground", children: [
4441
+ /* @__PURE__ */ jsx93(ChangeDisplay, { change: money(order.changeDueMinor) }),
4442
+ order.balanceDueMinor > 0 ? /* @__PURE__ */ jsxs52(Text37, { className: "text-foreground", children: [
4306
4443
  "Balance due: ",
4307
- formatMoney13(money(order.balanceDueMinor))
4444
+ formatMoney14(money(order.balanceDueMinor))
4308
4445
  ] }) : null,
4309
- /* @__PURE__ */ jsx92(Pressable27, { accessibilityRole: "button", disabled: order.balanceDueMinor > 0, onPress: sale.complete, className: `rounded-md bg-primary px-4 py-3 ${order.balanceDueMinor > 0 ? "opacity-50" : ""}`, children: /* @__PURE__ */ jsx92(Text36, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" }) })
4310
- ] }) : /* @__PURE__ */ jsxs51(Fragment6, { children: [
4311
- /* @__PURE__ */ jsxs51(Text36, { className: "text-foreground", children: [
4446
+ /* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", disabled: order.balanceDueMinor > 0, onPress: sale.complete, className: `rounded-md bg-primary px-4 py-3 ${order.balanceDueMinor > 0 ? "opacity-50" : ""}`, children: /* @__PURE__ */ jsx93(Text37, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" }) })
4447
+ ] }) : /* @__PURE__ */ jsxs52(Fragment7, { children: [
4448
+ /* @__PURE__ */ jsxs52(Text37, { className: "text-foreground", children: [
4312
4449
  "Card terminal: ",
4313
- formatMoney13(money(order.totalMinor))
4450
+ formatMoney14(money(order.totalMinor))
4314
4451
  ] }),
4315
- /* @__PURE__ */ jsx92(
4316
- TextInput11,
4452
+ /* @__PURE__ */ jsx93(
4453
+ TextInput12,
4317
4454
  {
4318
4455
  accessibilityLabel: "Terminal reference",
4319
4456
  placeholder: "Terminal reference",
@@ -4323,30 +4460,30 @@ function Tender({ sale }) {
4323
4460
  className: "rounded-md border border-border px-3 py-2 text-foreground"
4324
4461
  }
4325
4462
  ),
4326
- /* @__PURE__ */ jsx92(Pressable27, { accessibilityRole: "button", onPress: sale.complete, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx92(Text36, { className: "text-center font-semibold text-primary-foreground", children: "Payment approved on terminal" }) })
4463
+ /* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", onPress: sale.complete, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx93(Text37, { className: "text-center font-semibold text-primary-foreground", children: "Payment approved on terminal" }) })
4327
4464
  ] }),
4328
- sale.error ? /* @__PURE__ */ jsx92(Text36, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4329
- sale.canContinue ? /* @__PURE__ */ jsxs51(Fragment6, { children: [
4330
- /* @__PURE__ */ jsx92(Text36, { className: "text-foreground", children: "This sale is stored and will be sent. Continue to the next sale." }),
4331
- /* @__PURE__ */ jsx92(Pressable27, { accessibilityRole: "button", onPress: () => sale.continueSale(), className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx92(Text36, { className: "text-center font-semibold text-primary-foreground", children: "Continue" }) })
4465
+ sale.error ? /* @__PURE__ */ jsx93(Text37, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4466
+ sale.canContinue ? /* @__PURE__ */ jsxs52(Fragment7, { children: [
4467
+ /* @__PURE__ */ jsx93(Text37, { className: "text-foreground", children: "This sale is stored and will be sent. Continue to the next sale." }),
4468
+ /* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", onPress: () => sale.continueSale(), className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx93(Text37, { className: "text-center font-semibold text-primary-foreground", children: "Continue" }) })
4332
4469
  ] }) : null,
4333
- /* @__PURE__ */ jsx92(Pressable27, { accessibilityRole: "button", onPress: sale.cancelTender, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx92(Text36, { className: "text-center text-foreground", children: "Back" }) })
4470
+ /* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", onPress: sale.cancelTender, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx93(Text37, { className: "text-center text-foreground", children: "Back" }) })
4334
4471
  ] });
4335
4472
  }
4336
4473
 
4337
4474
  // src/sale/split-tender.tsx
4338
- import { useState as useState19 } from "react";
4339
- import { Pressable as Pressable28, Text as Text37, TextInput as TextInput12, View as View58 } from "react-native";
4340
- import { formatMoney as formatMoney14, minorUnitDigits as minorUnitDigits9 } from "@tallyui/core";
4341
- import { Fragment as Fragment7, jsx as jsx93, jsxs as jsxs52 } from "react/jsx-runtime";
4475
+ import { useState as useState20 } from "react";
4476
+ import { Pressable as Pressable29, Text as Text38, TextInput as TextInput13, View as View59 } from "react-native";
4477
+ import { formatMoney as formatMoney15, minorUnitDigits as minorUnitDigits9 } from "@tallyui/core";
4478
+ import { Fragment as Fragment8, jsx as jsx94, jsxs as jsxs53 } from "react/jsx-runtime";
4342
4479
  function SplitTender({ sale }) {
4343
4480
  const { order, stage } = sale;
4344
- const [method, setMethod] = useState19("cash");
4345
- const [amount, setAmount] = useState19(null);
4346
- const [reference, setReference] = useState19("");
4347
- const [error, setError] = useState19(null);
4481
+ const [method, setMethod] = useState20("cash");
4482
+ const [amount, setAmount] = useState20(null);
4483
+ const [reference, setReference] = useState20("");
4484
+ const [error, setError] = useState20(null);
4348
4485
  if (stage.kind !== "tender") return null;
4349
- const money = (value) => formatMoney14({ amount: value, currency: order.currency });
4486
+ const money = (value) => formatMoney15({ amount: value, currency: order.currency });
4350
4487
  const digits = minorUnitDigits9(order.currency);
4351
4488
  const amountText = amount ?? (order.balanceDueMinor / 10 ** digits).toFixed(digits);
4352
4489
  const incomplete = order.balanceDueMinor > 0 || order.payments.length === 0;
@@ -4369,59 +4506,59 @@ function SplitTender({ sale }) {
4369
4506
  setReference("");
4370
4507
  setAmount(null);
4371
4508
  }
4372
- return /* @__PURE__ */ jsxs52(View58, { dataSet: { print: "hide" }, className: "gap-4 p-4", children: [
4373
- /* @__PURE__ */ jsxs52(View58, { testID: "split-tender-summary", className: "gap-2", children: [
4374
- /* @__PURE__ */ jsxs52(Text37, { className: "text-foreground", children: [
4509
+ return /* @__PURE__ */ jsxs53(View59, { dataSet: { print: "hide" }, className: "gap-4 p-4", children: [
4510
+ /* @__PURE__ */ jsxs53(View59, { testID: "split-tender-summary", className: "gap-2", children: [
4511
+ /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
4375
4512
  "Total: ",
4376
4513
  money(order.totalMinor)
4377
4514
  ] }),
4378
- /* @__PURE__ */ jsxs52(Text37, { className: "text-foreground", children: [
4515
+ /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
4379
4516
  "Paid: ",
4380
4517
  money(order.paidMinor)
4381
4518
  ] }),
4382
- /* @__PURE__ */ jsxs52(Text37, { className: "text-foreground", children: [
4519
+ /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
4383
4520
  "Remaining: ",
4384
4521
  money(order.balanceDueMinor)
4385
4522
  ] }),
4386
- order.changeDueMinor > 0 ? /* @__PURE__ */ jsxs52(Text37, { className: "text-foreground", children: [
4523
+ order.changeDueMinor > 0 ? /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
4387
4524
  "Change: ",
4388
4525
  money(order.changeDueMinor)
4389
4526
  ] }) : null
4390
4527
  ] }),
4391
- /* @__PURE__ */ jsx93(View58, { testID: "split-tender-list", className: "gap-2", children: order.payments.map((payment) => /* @__PURE__ */ jsxs52(View58, { testID: `split-tender-row-${payment.id}`, className: "gap-2", children: [
4392
- /* @__PURE__ */ jsxs52(Text37, { className: "text-foreground", children: [
4528
+ /* @__PURE__ */ jsx94(View59, { testID: "split-tender-list", className: "gap-2", children: order.payments.map((payment) => /* @__PURE__ */ jsxs53(View59, { testID: `split-tender-row-${payment.id}`, className: "gap-2", children: [
4529
+ /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
4393
4530
  tenderLabel(payment.method),
4394
4531
  " ",
4395
4532
  money(payment.amountMinor)
4396
4533
  ] }),
4397
- payment.reference ? /* @__PURE__ */ jsx93(Text37, { className: "text-foreground", children: payment.reference }) : null,
4398
- /* @__PURE__ */ jsx93(
4399
- Pressable28,
4534
+ payment.reference ? /* @__PURE__ */ jsx94(Text38, { className: "text-foreground", children: payment.reference }) : null,
4535
+ /* @__PURE__ */ jsx94(
4536
+ Pressable29,
4400
4537
  {
4401
4538
  testID: `split-tender-remove-${payment.id}`,
4402
4539
  accessibilityRole: "button",
4403
4540
  accessibilityLabel: "Remove tender",
4404
4541
  onPress: () => sale.removeTender(payment.id),
4405
4542
  className: "rounded-md border border-border bg-card px-4 py-3",
4406
- children: /* @__PURE__ */ jsx93(Text37, { className: "text-center text-foreground", children: "Remove" })
4543
+ children: /* @__PURE__ */ jsx94(Text38, { className: "text-center text-foreground", children: "Remove" })
4407
4544
  }
4408
4545
  )
4409
4546
  ] }, payment.id)) }),
4410
- /* @__PURE__ */ jsxs52(View58, { testID: "split-tender-add", className: "gap-2", children: [
4411
- /* @__PURE__ */ jsx93(View58, { className: "flex-row gap-2", children: ["cash", "external"].map((value) => /* @__PURE__ */ jsx93(
4412
- Pressable28,
4547
+ /* @__PURE__ */ jsxs53(View59, { testID: "split-tender-add", className: "gap-2", children: [
4548
+ /* @__PURE__ */ jsx94(View59, { className: "flex-row gap-2", children: ["cash", "external"].map((value) => /* @__PURE__ */ jsx94(
4549
+ Pressable29,
4413
4550
  {
4414
4551
  testID: `split-tender-method-${value === "cash" ? "cash" : "card"}`,
4415
4552
  accessibilityRole: "button",
4416
4553
  accessibilityState: { selected: method === value },
4417
4554
  onPress: () => setMethod(value),
4418
4555
  className: `rounded-md border border-border px-4 py-3 ${method === value ? "bg-primary" : "bg-card"}`,
4419
- children: /* @__PURE__ */ jsx93(Text37, { className: `text-center ${method === value ? "text-primary-foreground" : "text-foreground"}`, children: tenderLabel(value) })
4556
+ children: /* @__PURE__ */ jsx94(Text38, { className: `text-center ${method === value ? "text-primary-foreground" : "text-foreground"}`, children: tenderLabel(value) })
4420
4557
  },
4421
4558
  value
4422
4559
  )) }),
4423
- /* @__PURE__ */ jsx93(
4424
- TextInput12,
4560
+ /* @__PURE__ */ jsx94(
4561
+ TextInput13,
4425
4562
  {
4426
4563
  testID: "split-tender-amount",
4427
4564
  accessibilityLabel: "Tender amount",
@@ -4431,8 +4568,8 @@ function SplitTender({ sale }) {
4431
4568
  className: "rounded-md border border-border px-3 py-2 text-foreground"
4432
4569
  }
4433
4570
  ),
4434
- method === "external" ? /* @__PURE__ */ jsx93(
4435
- TextInput12,
4571
+ method === "external" ? /* @__PURE__ */ jsx94(
4572
+ TextInput13,
4436
4573
  {
4437
4574
  testID: "split-tender-reference",
4438
4575
  accessibilityLabel: "Terminal reference",
@@ -4443,35 +4580,35 @@ function SplitTender({ sale }) {
4443
4580
  className: "rounded-md border border-border px-3 py-2 text-foreground"
4444
4581
  }
4445
4582
  ) : null,
4446
- error ? /* @__PURE__ */ jsx93(Text37, { testID: "split-tender-error", accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
4447
- /* @__PURE__ */ jsx93(Pressable28, { testID: "split-tender-add-button", accessibilityRole: "button", onPress: add, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx93(Text37, { className: "text-center font-semibold text-primary-foreground", children: "Add" }) })
4583
+ error ? /* @__PURE__ */ jsx94(Text38, { testID: "split-tender-error", accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
4584
+ /* @__PURE__ */ jsx94(Pressable29, { testID: "split-tender-add-button", accessibilityRole: "button", onPress: add, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx94(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Add" }) })
4448
4585
  ] }),
4449
- /* @__PURE__ */ jsx93(
4450
- Pressable28,
4586
+ /* @__PURE__ */ jsx94(
4587
+ Pressable29,
4451
4588
  {
4452
4589
  testID: "split-tender-complete",
4453
4590
  accessibilityRole: "button",
4454
4591
  disabled: incomplete,
4455
4592
  onPress: sale.complete,
4456
4593
  className: `rounded-md bg-primary px-4 py-3 ${incomplete ? "opacity-50" : ""}`,
4457
- children: /* @__PURE__ */ jsx93(Text37, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" })
4594
+ children: /* @__PURE__ */ jsx94(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" })
4458
4595
  }
4459
4596
  ),
4460
- sale.error ? /* @__PURE__ */ jsx93(Text37, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4461
- sale.canContinue ? /* @__PURE__ */ jsxs52(Fragment7, { children: [
4462
- /* @__PURE__ */ jsx93(Text37, { className: "text-foreground", children: "This sale is stored and will be sent. Continue to the next sale." }),
4463
- /* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", onPress: () => sale.continueSale(), className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx93(Text37, { className: "text-center font-semibold text-primary-foreground", children: "Continue" }) })
4597
+ sale.error ? /* @__PURE__ */ jsx94(Text38, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4598
+ sale.canContinue ? /* @__PURE__ */ jsxs53(Fragment8, { children: [
4599
+ /* @__PURE__ */ jsx94(Text38, { className: "text-foreground", children: "This sale is stored and will be sent. Continue to the next sale." }),
4600
+ /* @__PURE__ */ jsx94(Pressable29, { accessibilityRole: "button", onPress: () => sale.continueSale(), className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx94(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Continue" }) })
4464
4601
  ] }) : null,
4465
- /* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", onPress: sale.cancelTender, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx93(Text37, { className: "text-center text-foreground", children: "Back" }) })
4602
+ /* @__PURE__ */ jsx94(Pressable29, { accessibilityRole: "button", onPress: sale.cancelTender, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx94(Text38, { className: "text-center text-foreground", children: "Back" }) })
4466
4603
  ] });
4467
4604
  }
4468
4605
 
4469
4606
  // src/sale/catalogue.tsx
4470
- import { useEffect as useEffect5, useMemo as useMemo2, useState as useState20 } from "react";
4471
- import { Pressable as Pressable29, Text as Text38, View as View59 } from "react-native";
4607
+ import { useEffect as useEffect5, useMemo as useMemo2, useState as useState21 } from "react";
4608
+ import { Pressable as Pressable30, Text as Text39, View as View60 } from "react-native";
4472
4609
  import { useStockOverlaid, useStockOverlayAsOf } from "@tallyui/core";
4473
4610
  import { catalogueEntries, findEntryByCode, searchProducts, variantPriceLabel } from "@tallyui/pos";
4474
- import { jsx as jsx94, jsxs as jsxs53 } from "react/jsx-runtime";
4611
+ import { jsx as jsx95, jsxs as jsxs54 } from "react/jsx-runtime";
4475
4612
  var MIN_TILE_WIDTH = 160;
4476
4613
  var STOCK_LABEL = {
4477
4614
  in_stock: "In Stock",
@@ -4497,9 +4634,9 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4497
4634
  const parsedOverlayAsOf = overlayAsOf ? new Date(overlayAsOf) : void 0;
4498
4635
  const validOverlayAsOf = parsedOverlayAsOf && !isNaN(parsedOverlayAsOf.getTime()) ? parsedOverlayAsOf : void 0;
4499
4636
  const stockAsOf = laterOf(laterOf(lastStockCheckAt, validOverlayAsOf), lastSyncedAt);
4500
- const [query, setQuery] = useState20("");
4501
- const [chooserId, setChooserId] = useState20(null);
4502
- const [width, setWidth] = useState20(0);
4637
+ const [query, setQuery] = useState21("");
4638
+ const [chooserId, setChooserId] = useState21(null);
4639
+ const [width, setWidth] = useState21(0);
4503
4640
  const columns = Math.max(2, Math.min(6, Math.floor((width - 8) / (MIN_TILE_WIDTH + 8))));
4504
4641
  const entries = useMemo2(() => catalogueEntries(shown, traits, { currency }), [shown, traits, currency]);
4505
4642
  const results = useMemo2(() => searchProducts(shown, query, traits), [shown, query, traits]);
@@ -4511,9 +4648,9 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4511
4648
  onSelect(entry);
4512
4649
  setChooserId(null);
4513
4650
  }
4514
- return /* @__PURE__ */ jsxs53(View59, { className: "flex-1", onLayout: (event) => setWidth(event.nativeEvent.layout.width), children: [
4515
- /* @__PURE__ */ jsxs53(View59, { className: "gap-2 border-b border-border bg-card px-4 pb-3 pt-3", children: [
4516
- /* @__PURE__ */ jsx94(
4651
+ return /* @__PURE__ */ jsxs54(View60, { className: "flex-1", onLayout: (event) => setWidth(event.nativeEvent.layout.width), children: [
4652
+ /* @__PURE__ */ jsxs54(View60, { className: "gap-2 border-b border-border bg-card px-4 pb-3 pt-3", children: [
4653
+ /* @__PURE__ */ jsx95(
4517
4654
  SearchInput,
4518
4655
  {
4519
4656
  value: query,
@@ -4530,25 +4667,25 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4530
4667
  }
4531
4668
  }
4532
4669
  ),
4533
- statusText || statusAccessory ? /* @__PURE__ */ jsxs53(View59, { testID: "catalogue-status-row", className: "flex-row items-center gap-2", children: [
4534
- statusText ? /* @__PURE__ */ jsxs53(Text38, { className: "flex-1 text-xs text-muted-foreground", numberOfLines: statusAccessory ? 1 : void 0, children: [
4670
+ statusText || statusAccessory ? /* @__PURE__ */ jsxs54(View60, { testID: "catalogue-status-row", className: "flex-row items-center gap-2", children: [
4671
+ statusText ? /* @__PURE__ */ jsxs54(Text39, { className: "flex-1 text-xs text-muted-foreground", numberOfLines: statusAccessory ? 1 : void 0, children: [
4535
4672
  statusText,
4536
4673
  query.trim() ? ` \xB7 ${results.length.toLocaleString()} matching` : ""
4537
4674
  ] }) : null,
4538
4675
  statusAccessory
4539
4676
  ] }) : null,
4540
- choices.length > 0 ? /* @__PURE__ */ jsxs53(View59, { accessibilityLabel: "Choose variant", className: "gap-2", children: [
4541
- choices.map((entry) => /* @__PURE__ */ jsxs53(
4542
- Pressable29,
4677
+ choices.length > 0 ? /* @__PURE__ */ jsxs54(View60, { accessibilityLabel: "Choose variant", className: "gap-2", children: [
4678
+ choices.map((entry) => /* @__PURE__ */ jsxs54(
4679
+ Pressable30,
4543
4680
  {
4544
4681
  accessibilityRole: "button",
4545
4682
  onPress: () => select(entry),
4546
4683
  className: "gap-1 rounded-md border border-border p-3",
4547
4684
  children: [
4548
- /* @__PURE__ */ jsx94(Text38, { className: "font-semibold text-foreground", children: entry.variant.title }),
4549
- /* @__PURE__ */ jsx94(Text38, { className: "text-muted-foreground", children: entry.variant.sku }),
4550
- /* @__PURE__ */ jsx94(Text38, { className: "text-foreground", children: variantPriceLabel(entry.variant, currency) }),
4551
- /* @__PURE__ */ jsxs53(Text38, { className: "text-muted-foreground", children: [
4685
+ /* @__PURE__ */ jsx95(Text39, { className: "font-semibold text-foreground", children: entry.variant.title }),
4686
+ /* @__PURE__ */ jsx95(Text39, { className: "text-muted-foreground", children: entry.variant.sku }),
4687
+ /* @__PURE__ */ jsx95(Text39, { className: "text-foreground", children: variantPriceLabel(entry.variant, currency) }),
4688
+ /* @__PURE__ */ jsxs54(Text39, { className: "text-muted-foreground", children: [
4552
4689
  STOCK_LABEL[entry.variant.stock.status],
4553
4690
  " \xB7 ",
4554
4691
  stockAsOf ? `as of ${formatStockSyncTime(stockAsOf, void 0, hour12)}` : "not yet synced"
@@ -4557,10 +4694,10 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4557
4694
  },
4558
4695
  entry.variant.id
4559
4696
  )),
4560
- /* @__PURE__ */ jsx94(Pressable29, { accessibilityRole: "button", onPress: () => setChooserId(null), className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx94(Text38, { className: "text-center text-foreground", children: "Cancel" }) })
4697
+ /* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", onPress: () => setChooserId(null), className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx95(Text39, { className: "text-center text-foreground", children: "Cancel" }) })
4561
4698
  ] }) : null
4562
4699
  ] }),
4563
- /* @__PURE__ */ jsx94(
4700
+ /* @__PURE__ */ jsx95(
4564
4701
  ProductGrid,
4565
4702
  {
4566
4703
  items: results,
@@ -4569,18 +4706,18 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4569
4706
  // TallyUI's ProductCard has no children slot, so the tile is composed directly here
4570
4707
  // (same structure/classes as ProductCard) to add the stock badge as a fourth child,
4571
4708
  // inside the card and centred with the rest, rather than adding a slot to ProductCard (out of scope for TV6b).
4572
- /* @__PURE__ */ jsx94(Pressable29, { accessibilityRole: "button", testID: `product-tile-${traits.getName(product)}`, onPress: () => {
4709
+ /* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", testID: `product-tile-${traits.getName(product)}`, onPress: () => {
4573
4710
  const variants = entries.filter((entry) => entry.product === product);
4574
4711
  if (variants.length === 1) select(variants[0]);
4575
4712
  else setChooserId(traits.getId(product));
4576
- }, children: /* @__PURE__ */ jsxs53(VStack, { space: "sm", className: "items-center rounded-lg border border-border bg-card p-3", children: [
4577
- /* @__PURE__ */ jsx94(ProductImage, { doc: product, size: 80, className: "rounded-md" }),
4578
- /* @__PURE__ */ jsx94(ProductTitle, { doc: product, className: "text-sm", numberOfLines: 2 }),
4579
- /* @__PURE__ */ jsx94(ProductPrice, { doc: product }),
4580
- /* @__PURE__ */ jsx94(ProductStockBadge, { doc: product, showAsOf: false, className: "self-center" })
4713
+ }, children: /* @__PURE__ */ jsxs54(VStack, { space: "sm", className: "items-center rounded-lg border border-border bg-card p-3", children: [
4714
+ /* @__PURE__ */ jsx95(ProductImage, { doc: product, size: 80, className: "rounded-md" }),
4715
+ /* @__PURE__ */ jsx95(ProductTitle, { doc: product, className: "text-sm", numberOfLines: 2 }),
4716
+ /* @__PURE__ */ jsx95(ProductPrice, { doc: product }),
4717
+ /* @__PURE__ */ jsx95(ProductStockBadge, { doc: product, showAsOf: false, className: "self-center" })
4581
4718
  ] }) })
4582
4719
  ),
4583
- emptyState: /* @__PURE__ */ jsx94(Text38, { className: "mt-10 text-center text-sm text-muted-foreground", children: query.trim() ? `No products match "${query.trim()}".` : isLoading ? "Loading products\u2026" : "No products yet." })
4720
+ emptyState: /* @__PURE__ */ jsx95(Text39, { className: "mt-10 text-center text-sm text-muted-foreground", children: query.trim() ? `No products match "${query.trim()}".` : isLoading ? "Loading products\u2026" : "No products yet." })
4584
4721
  }
4585
4722
  )
4586
4723
  ] });
@@ -4588,8 +4725,8 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4588
4725
 
4589
4726
  // src/sale/receipt.tsx
4590
4727
  import { useEffect as useEffect6 } from "react";
4591
- import { Pressable as Pressable30, Text as Text39, View as View60 } from "react-native";
4592
- import { formatMoney as formatMoney15 } from "@tallyui/core";
4728
+ import { Pressable as Pressable31, Text as Text40, View as View61 } from "react-native";
4729
+ import { formatMoney as formatMoney16 } from "@tallyui/core";
4593
4730
  import { buildReceiptData as buildReceiptData3 } from "@tallyui/pos";
4594
4731
 
4595
4732
  // src/sale/print-style.ts
@@ -4609,7 +4746,7 @@ function orderReference(order) {
4609
4746
  }
4610
4747
 
4611
4748
  // src/sale/receipt.tsx
4612
- import { Fragment as Fragment8, jsx as jsx95, jsxs as jsxs54 } from "react/jsx-runtime";
4749
+ import { Fragment as Fragment9, jsx as jsx96, jsxs as jsxs55 } from "react/jsx-runtime";
4613
4750
  var defaultFormatDate = (iso) => new Intl.DateTimeFormat(void 0, { dateStyle: "medium", timeStyle: "short" }).format(new Date(iso));
4614
4751
  function Receipt({
4615
4752
  order,
@@ -4629,37 +4766,39 @@ function Receipt({
4629
4766
  cashier,
4630
4767
  register: registerId
4631
4768
  });
4632
- const money = (amount) => formatMoney15({ amount, currency: receipt.currency }) ?? "";
4633
- const row = (label, amount, bold = false, key) => /* @__PURE__ */ jsxs54(View60, { accessibilityLabel: `${label}: ${amount}`, className: "flex-row justify-between gap-4", children: [
4634
- /* @__PURE__ */ jsx95(Text39, { className: `text-foreground ${bold ? "font-semibold" : ""}`, children: label }),
4635
- /* @__PURE__ */ jsx95(Text39, { className: `text-right text-foreground ${bold ? "font-semibold" : ""}`, children: amount })
4769
+ const money = (amount) => formatMoney16({ amount, currency: receipt.currency }) ?? "";
4770
+ const row = (label, amount, bold = false, key) => /* @__PURE__ */ jsxs55(View61, { accessibilityLabel: `${label}: ${amount}`, className: "flex-row justify-between gap-4", children: [
4771
+ /* @__PURE__ */ jsx96(Text40, { className: `text-foreground ${bold ? "font-semibold" : ""}`, children: label }),
4772
+ /* @__PURE__ */ jsx96(Text40, { className: `text-right text-foreground ${bold ? "font-semibold" : ""}`, children: amount })
4636
4773
  ] }, key);
4637
4774
  const { totals } = receipt;
4638
4775
  const lineDiscountMinor = totals.discountMinor - receipt.orderDiscountMinor;
4639
4776
  const taxRows = totals.taxLines.map((line, index) => row(`${totals.taxInclusive ? "incl. " : ""}${taxLabel(line.ratePpm)}`, money(line.amountMinor), false, index));
4640
- return /* @__PURE__ */ jsxs54(Fragment8, { children: [
4641
- topInset > 0 ? /* @__PURE__ */ jsx95(View60, { dataSet: { print: "hide" }, style: { height: topInset, flexShrink: 0 } }) : null,
4642
- /* @__PURE__ */ jsxs54(View60, { className: "w-full max-w-md self-center gap-3 p-4 bg-card", children: [
4643
- /* @__PURE__ */ jsx95(Text39, { className: "text-lg font-semibold text-foreground", children: receipt.header.storeName }),
4644
- receipt.header.storeAddress ? /* @__PURE__ */ jsx95(Text39, { className: "text-muted-foreground", children: receipt.header.storeAddress }) : null,
4645
- /* @__PURE__ */ jsx95(Text39, { testID: "receipt-order", className: "text-foreground", children: posOrder ? `Order ${orderReference(posOrder)}` : `Order ${receipt.header.orderNumber.slice(-8)} (draft)` }),
4646
- /* @__PURE__ */ jsx95(Text39, { className: "text-muted-foreground", children: formatDate(posOrder?.createdAt ?? receipt.header.date) }),
4647
- /* @__PURE__ */ jsxs54(Text39, { className: "text-muted-foreground", children: [
4777
+ return /* @__PURE__ */ jsxs55(Fragment9, { children: [
4778
+ topInset > 0 ? /* @__PURE__ */ jsx96(View61, { dataSet: { print: "hide" }, style: { height: topInset, flexShrink: 0 } }) : null,
4779
+ /* @__PURE__ */ jsxs55(View61, { className: "w-full max-w-md self-center gap-3 p-4 bg-card", children: [
4780
+ /* @__PURE__ */ jsx96(Text40, { className: "text-lg font-semibold text-foreground", children: receipt.header.storeName }),
4781
+ receipt.header.storeAddress ? /* @__PURE__ */ jsx96(Text40, { className: "text-muted-foreground", children: receipt.header.storeAddress }) : null,
4782
+ /* @__PURE__ */ jsx96(Text40, { testID: "receipt-order", className: "text-foreground", children: posOrder ? `Order ${orderReference(posOrder)}` : `Order ${receipt.header.orderNumber.slice(-8)} (draft)` }),
4783
+ /* @__PURE__ */ jsx96(Text40, { className: "text-muted-foreground", children: formatDate(posOrder?.createdAt ?? receipt.header.date) }),
4784
+ /* @__PURE__ */ jsxs55(Text40, { className: "text-muted-foreground", children: [
4648
4785
  "Cashier: ",
4649
4786
  receipt.header.cashier
4650
4787
  ] }),
4651
- receipt.header.customer && /* @__PURE__ */ jsxs54(Text39, { className: "text-muted-foreground", children: [
4788
+ receipt.header.customer && /* @__PURE__ */ jsxs55(Text40, { className: "text-muted-foreground", children: [
4652
4789
  "Customer: ",
4653
4790
  receipt.header.customer
4654
4791
  ] }),
4655
- receipt.lineItems.map((line, index) => /* @__PURE__ */ jsxs54(View60, { children: [
4656
- /* @__PURE__ */ jsx95(Text39, { className: "text-foreground", children: line.name }),
4792
+ receipt.lineItems.map((line, index) => /* @__PURE__ */ jsxs55(View61, { children: [
4793
+ /* @__PURE__ */ jsx96(Text40, { className: "text-foreground", children: line.name }),
4657
4794
  row(`${line.quantity} \xD7 ${money(line.unitPriceMinor)}`, money(line.displayAmountMinor)),
4658
- line.displayDiscounts.map((discount, i) => /* @__PURE__ */ jsx95(View60, { className: "pl-4", children: row(`${discountLabel(
4795
+ line.displayDiscounts.map((discount, i) => /* @__PURE__ */ jsx96(View61, { className: "pl-4", children: row(`${discountLabel(
4659
4796
  order.lineItems[index].discounts[i],
4660
4797
  receipt.currency
4661
4798
  )} off`, `\u2212${money(discount.amountMinor)}`) }, i))
4662
4799
  ] }, index)),
4800
+ receipt.fees.map((charge, index) => row(charge.name, money(charge.amountMinor), false, index)),
4801
+ receipt.shipping.map((charge, index) => row(charge.name, money(charge.amountMinor), false, index)),
4663
4802
  row("Subtotal", money(totals.subtotalMinor)),
4664
4803
  lineDiscountMinor > 0 ? row("Line discounts", `\u2212${money(lineDiscountMinor)}`) : null,
4665
4804
  receipt.orderDiscountMinor > 0 ? row("Order discount", `\u2212${money(receipt.orderDiscountMinor)}`) : null,
@@ -4672,19 +4811,19 @@ function Receipt({
4672
4811
  index
4673
4812
  )),
4674
4813
  row("Change", money(receipt.changeDueMinor)),
4675
- /* @__PURE__ */ jsxs54(View60, { dataSet: { print: "hide" }, className: "flex-row gap-4", children: [
4676
- /* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", onPress: () => {
4814
+ /* @__PURE__ */ jsxs55(View61, { dataSet: { print: "hide" }, className: "flex-row gap-4", children: [
4815
+ /* @__PURE__ */ jsx96(Pressable31, { accessibilityRole: "button", onPress: () => {
4677
4816
  if (typeof window !== "undefined" && typeof window.print === "function") window.print();
4678
- }, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx95(Text39, { className: "text-center text-foreground", children: "Print receipt" }) }),
4679
- /* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", onPress: newSale, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx95(Text39, { className: "text-center font-semibold text-primary-foreground", children: "New sale" }) })
4817
+ }, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx96(Text40, { className: "text-center text-foreground", children: "Print receipt" }) }),
4818
+ /* @__PURE__ */ jsx96(Pressable31, { accessibilityRole: "button", onPress: newSale, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx96(Text40, { className: "text-center font-semibold text-primary-foreground", children: "New sale" }) })
4680
4819
  ] })
4681
4820
  ] })
4682
4821
  ] });
4683
4822
  }
4684
4823
 
4685
4824
  // src/sale/sync-status.tsx
4686
- import { useEffect as useEffect7, useRef as useRef6, useState as useState21 } from "react";
4687
- import { AccessibilityInfo as AccessibilityInfo2, Platform as Platform3, Text as Text40, View as View61 } from "react-native";
4825
+ import { useEffect as useEffect7, useRef as useRef6, useState as useState22 } from "react";
4826
+ import { AccessibilityInfo as AccessibilityInfo2, Platform as Platform3, Text as Text41, View as View62 } from "react-native";
4688
4827
 
4689
4828
  // src/sale/since-text.ts
4690
4829
  function sinceText(clock) {
@@ -4693,7 +4832,7 @@ function sinceText(clock) {
4693
4832
  }
4694
4833
 
4695
4834
  // src/sale/sync-status.tsx
4696
- import { Fragment as Fragment9, jsx as jsx96, jsxs as jsxs55 } from "react/jsx-runtime";
4835
+ import { Fragment as Fragment10, jsx as jsx97, jsxs as jsxs56 } from "react/jsx-runtime";
4697
4836
  var PULL_NOTICE_TEXT = {
4698
4837
  unauthorized: {
4699
4838
  line: () => "Products aren't updating: this till needs to sign in to the online store again.",
@@ -4745,7 +4884,7 @@ function useAnnounceOnIos(...texts) {
4745
4884
  function SyncStatus({ state, registerState, pluginName = "the POS plugin", pullNotice }) {
4746
4885
  const updates = registerState?.pending ?? 0;
4747
4886
  const outbox = state.pending === 0 && registerState?.pending ? registerState : state;
4748
- const [now, setNow] = useState21(Date.now);
4887
+ const [now, setNow] = useState22(Date.now);
4749
4888
  useEffect7(() => {
4750
4889
  setNow(Date.now());
4751
4890
  if (!outbox.nextAttemptAt) return;
@@ -4769,24 +4908,24 @@ function SyncStatus({ state, registerState, pluginName = "the POS plugin", pullN
4769
4908
  const notice = pullNotice && text && { line: text.line(pluginName), detail: text.detail(pullNotice, pluginName) };
4770
4909
  useAnnounceOnIos(notice?.line, spoken);
4771
4910
  const oneDetail = pullNotice?.code === "missing_plugin" && !!backendMissing;
4772
- return /* @__PURE__ */ jsxs55(View61, { children: [
4773
- notice ? /* @__PURE__ */ jsxs55(Fragment9, { children: [
4774
- /* @__PURE__ */ jsx96(Text40, { accessibilityLiveRegion: "polite", className: "px-4 py-2 text-xs text-muted-foreground", children: notice.line }),
4775
- oneDetail ? null : /* @__PURE__ */ jsx96(Text40, { className: "px-4 pb-2 text-xs text-muted-foreground", children: notice.detail })
4911
+ return /* @__PURE__ */ jsxs56(View62, { children: [
4912
+ notice ? /* @__PURE__ */ jsxs56(Fragment10, { children: [
4913
+ /* @__PURE__ */ jsx97(Text41, { accessibilityLiveRegion: "polite", className: "px-4 py-2 text-xs text-muted-foreground", children: notice.line }),
4914
+ oneDetail ? null : /* @__PURE__ */ jsx97(Text41, { className: "px-4 pb-2 text-xs text-muted-foreground", children: notice.detail })
4776
4915
  ] }) : null,
4777
- /* @__PURE__ */ jsx96(Text40, { accessibilityLabel: spoken, accessibilityLiveRegion: "polite", className: "px-4 py-2 text-xs text-muted-foreground", children: spoken }),
4778
- doing ? /* @__PURE__ */ jsx96(Text40, { className: "px-4 pb-2 text-xs text-muted-foreground", children: doing }) : null,
4779
- refused ? /* @__PURE__ */ jsx96(Text40, { className: "px-4 pb-2 text-xs text-muted-foreground", children: REFUSED_DETAIL }) : null,
4780
- oneDetail && notice ? /* @__PURE__ */ jsx96(Text40, { className: "px-4 pb-2 text-xs text-muted-foreground", children: notice.detail }) : backendMissing ? /* @__PURE__ */ jsx96(Text40, { className: "px-4 pb-2 text-xs text-muted-foreground", children: BACKEND_MISSING_DETAIL.replace("{pluginName}", () => pluginName).replace("{lastTime}", () => upToDate ? " the last time it checked" : "") }) : null
4916
+ /* @__PURE__ */ jsx97(Text41, { accessibilityLabel: spoken, accessibilityLiveRegion: "polite", className: "px-4 py-2 text-xs text-muted-foreground", children: spoken }),
4917
+ doing ? /* @__PURE__ */ jsx97(Text41, { className: "px-4 pb-2 text-xs text-muted-foreground", children: doing }) : null,
4918
+ refused ? /* @__PURE__ */ jsx97(Text41, { className: "px-4 pb-2 text-xs text-muted-foreground", children: REFUSED_DETAIL }) : null,
4919
+ oneDetail && notice ? /* @__PURE__ */ jsx97(Text41, { className: "px-4 pb-2 text-xs text-muted-foreground", children: notice.detail }) : backendMissing ? /* @__PURE__ */ jsx97(Text41, { className: "px-4 pb-2 text-xs text-muted-foreground", children: BACKEND_MISSING_DETAIL.replace("{pluginName}", () => pluginName).replace("{lastTime}", () => upToDate ? " the last time it checked" : "") }) : null
4781
4920
  ] });
4782
4921
  }
4783
4922
 
4784
4923
  // src/sale/orders-list.tsx
4785
- import { useEffect as useEffect8, useRef as useRef7, useState as useState22 } from "react";
4786
- import { Pressable as Pressable31, ScrollView as ScrollView13, Text as Text41, View as View62 } from "react-native";
4787
- import { formatMoney as formatMoney16, knownWarnings } from "@tallyui/core";
4924
+ import { useEffect as useEffect8, useRef as useRef7, useState as useState23 } from "react";
4925
+ import { Pressable as Pressable32, ScrollView as ScrollView13, Text as Text42, View as View63 } from "react-native";
4926
+ import { formatMoney as formatMoney17, knownWarnings } from "@tallyui/core";
4788
4927
  import { needsAttention } from "@tallyui/pos";
4789
- import { jsx as jsx97, jsxs as jsxs56 } from "react/jsx-runtime";
4928
+ import { jsx as jsx98, jsxs as jsxs57 } from "react/jsx-runtime";
4790
4929
  var STATUS_LABEL = { pending: "Waiting to sync", applied: "Synced", rejected: "Not accepted" };
4791
4930
  var FIGURE_LABELS = /* @__PURE__ */ new Map([["subtotalMinor", "Subtotal"], ["taxMinor", "Tax"], ["discountMinor", "Discount"]]);
4792
4931
  var REFUSAL_SENTENCES = /* @__PURE__ */ new Map([
@@ -4810,26 +4949,26 @@ function defaultFormatDate2(iso) {
4810
4949
  }
4811
4950
  function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer, stuck }) {
4812
4951
  const retrying = useRef7(/* @__PURE__ */ new Set());
4813
- const [retryingIds, setRetryingIds] = useState22(/* @__PURE__ */ new Set());
4814
- const [expanded, setExpanded] = useState22(/* @__PURE__ */ new Set());
4952
+ const [retryingIds, setRetryingIds] = useState23(/* @__PURE__ */ new Set());
4953
+ const [expanded, setExpanded] = useState23(/* @__PURE__ */ new Set());
4815
4954
  useEffect8(() => {
4816
4955
  for (const id of retrying.current) {
4817
4956
  if (!orders.some((order) => order.id === id && order.syncStatus === "rejected")) retrying.current.delete(id);
4818
4957
  }
4819
4958
  setRetryingIds(new Set(retrying.current));
4820
4959
  }, [orders]);
4821
- return /* @__PURE__ */ jsxs56(ScrollView13, { className: "flex-1 bg-background p-4", children: [
4822
- [{ title: "Needs attention", orders: needsAttention(orders, { stuckCommandIds: stuck?.commandIds }) }, { title: "Recent", orders }].filter((section) => section.title === "Recent" || section.orders.length > 0).map((section) => /* @__PURE__ */ jsxs56(View62, { className: "mb-6 gap-3", children: [
4823
- /* @__PURE__ */ jsx97(Text41, { accessibilityRole: "header", className: "text-xl font-semibold text-foreground", children: section.title }),
4824
- section.title === "Recent" && orders.length === 0 ? /* @__PURE__ */ jsx97(Text41, { testID: "orders-empty", className: "text-muted-foreground", children: "No sales yet. Completed sales appear here." }) : null,
4960
+ return /* @__PURE__ */ jsxs57(ScrollView13, { className: "flex-1 bg-background p-4", children: [
4961
+ [{ title: "Needs attention", orders: needsAttention(orders, { stuckCommandIds: stuck?.commandIds }) }, { title: "Recent", orders }].filter((section) => section.title === "Recent" || section.orders.length > 0).map((section) => /* @__PURE__ */ jsxs57(View63, { className: "mb-6 gap-3", children: [
4962
+ /* @__PURE__ */ jsx98(Text42, { accessibilityRole: "header", className: "text-xl font-semibold text-foreground", children: section.title }),
4963
+ section.title === "Recent" && orders.length === 0 ? /* @__PURE__ */ jsx98(Text42, { testID: "orders-empty", className: "text-muted-foreground", children: "No sales yet. Completed sales appear here." }) : null,
4825
4964
  section.orders.map((order) => {
4826
4965
  const count2 = order.lines.reduce((sum, line) => sum + line.quantity, 0);
4827
4966
  const key = `${section.title}:${order.id}`;
4828
4967
  const isExpanded = expanded.has(key);
4829
4968
  const stuckEntry = order.syncStatus === "pending" ? stuck?.orders.find((entry) => entry.commandId === order.commandId) : void 0;
4830
- return /* @__PURE__ */ jsxs56(View62, { className: "gap-1 rounded-md border border-border bg-card p-3", children: [
4831
- /* @__PURE__ */ jsxs56(
4832
- Pressable31,
4969
+ return /* @__PURE__ */ jsxs57(View63, { className: "gap-1 rounded-md border border-border bg-card p-3", children: [
4970
+ /* @__PURE__ */ jsxs57(
4971
+ Pressable32,
4833
4972
  {
4834
4973
  accessibilityRole: "button",
4835
4974
  "aria-expanded": isExpanded,
@@ -4843,26 +4982,26 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
4843
4982
  return next;
4844
4983
  }),
4845
4984
  children: [
4846
- /* @__PURE__ */ jsx97(Text41, { className: "text-foreground", children: `Order ${orderReference(order)} \xB7 ${count2} ${count2 === 1 ? "item" : "items"}` }),
4847
- /* @__PURE__ */ jsxs56(Text41, { className: "text-muted-foreground", children: [
4985
+ /* @__PURE__ */ jsx98(Text42, { className: "text-foreground", children: `Order ${orderReference(order)} \xB7 ${count2} ${count2 === 1 ? "item" : "items"}` }),
4986
+ /* @__PURE__ */ jsxs57(Text42, { className: "text-muted-foreground", children: [
4848
4987
  formatDate(order.createdAt),
4849
4988
  " \xB7 ",
4850
- formatMoney16({ amount: order.totalMinor, currency: order.currency }),
4989
+ formatMoney17({ amount: order.totalMinor, currency: order.currency }),
4851
4990
  " \xB7 ",
4852
4991
  STATUS_LABEL[order.syncStatus]
4853
4992
  ] })
4854
4993
  ]
4855
4994
  }
4856
4995
  ),
4857
- isExpanded ? /* @__PURE__ */ jsxs56(View62, { testID: `order-detail-${order.id}`, className: "mt-1 gap-1 border-t border-border pt-2", children: [
4858
- order.lines.map((line) => /* @__PURE__ */ jsx97(Text41, { className: "text-foreground", children: `${line.quantity} \xD7 ${line.name}` }, line.id)),
4859
- order.payments.map((payment) => /* @__PURE__ */ jsx97(Text41, { className: "text-muted-foreground", children: `${payment.method === "cash" ? "Cash" : "Card terminal"} ${formatMoney16({ amount: payment.amountMinor, currency: order.currency })}${payment.reference ? ` \xB7 ${payment.reference}` : ""}` }, payment.id))
4996
+ isExpanded ? /* @__PURE__ */ jsxs57(View63, { testID: `order-detail-${order.id}`, className: "mt-1 gap-1 border-t border-border pt-2", children: [
4997
+ order.lines.map((line) => /* @__PURE__ */ jsx98(Text42, { className: "text-foreground", children: `${line.quantity} \xD7 ${line.name}` }, line.id)),
4998
+ order.payments.map((payment) => /* @__PURE__ */ jsx98(Text42, { className: "text-muted-foreground", children: `${payment.method === "cash" ? "Cash" : "Card terminal"} ${formatMoney17({ amount: payment.amountMinor, currency: order.currency })}${payment.reference ? ` \xB7 ${payment.reference}` : ""}` }, payment.id))
4860
4999
  ] }) : null,
4861
- stuckEntry ? /* @__PURE__ */ jsx97(Text41, { className: "text-destructive", children: `Hasn't reached the online store since ${sinceText(stuckEntry)}.` }) : null,
4862
- order.syncStatus === "rejected" ? /* @__PURE__ */ jsx97(Text41, { className: "text-destructive", children: refusalSentence(order.error?.code) }) : null,
4863
- order.lateSessionId !== void 0 ? /* @__PURE__ */ jsx97(Text41, { className: "text-foreground", children: "Taken after the register closed. It is not in that register's closure." }) : null,
4864
- order.localWarnings?.map((warning, index) => /* @__PURE__ */ jsx97(Text41, { className: "text-foreground", children: warning.code === "customer_omitted" ? `The customer's ${warning.field} couldn't be sent to the store, so the order isn't linked to them.` : "The terminal's payment reference couldn't be kept; the payment is recorded without it." }, index)),
4865
- section.title === "Needs attention" && order.syncStatus === "rejected" && order.error?.code !== "idempotency_mismatch" ? /* @__PURE__ */ jsx97(Pressable31, { accessibilityRole: "button", disabled: retryingIds.has(order.id), onPress: async () => {
5000
+ stuckEntry ? /* @__PURE__ */ jsx98(Text42, { className: "text-destructive", children: `Hasn't reached the online store since ${sinceText(stuckEntry)}.` }) : null,
5001
+ order.syncStatus === "rejected" ? /* @__PURE__ */ jsx98(Text42, { className: "text-destructive", children: refusalSentence(order.error?.code) }) : null,
5002
+ order.lateSessionId !== void 0 ? /* @__PURE__ */ jsx98(Text42, { className: "text-foreground", children: "Taken after the register closed. It is not in that register's closure." }) : null,
5003
+ order.localWarnings?.map((warning, index) => /* @__PURE__ */ jsx98(Text42, { className: "text-foreground", children: warning.code === "customer_omitted" ? `The customer's ${warning.field} couldn't be sent to the store, so the order isn't linked to them.` : "The terminal's payment reference couldn't be kept; the payment is recorded without it." }, index)),
5004
+ section.title === "Needs attention" && order.syncStatus === "rejected" && order.error?.code !== "idempotency_mismatch" ? /* @__PURE__ */ jsx98(Pressable32, { accessibilityRole: "button", disabled: retryingIds.has(order.id), onPress: async () => {
4866
5005
  if (retrying.current.has(order.id)) return;
4867
5006
  retrying.current.add(order.id);
4868
5007
  setRetryingIds(new Set(retrying.current));
@@ -4870,8 +5009,8 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
4870
5009
  retrying.current.delete(order.id);
4871
5010
  setRetryingIds(new Set(retrying.current));
4872
5011
  }
4873
- }, className: "rounded-md bg-primary px-4 py-2", children: /* @__PURE__ */ jsx97(Text41, { className: "text-center font-semibold text-primary-foreground", children: "Retry" }) }) : null,
4874
- knownWarnings(order.warnings).map((warning, index) => /* @__PURE__ */ jsx97(View62, { className: "border-l-4 border-warning pl-2", children: /* @__PURE__ */ jsx97(Text41, { className: "text-foreground", children: warning.code === "insufficient_stock" ? `Stock short by ${warning.quantity} for ${order.lines.find((line) => line.variantId === warning.variantId)?.name}` : warning.code === "tax_rate_mismatch" ? `Tax at ${(warning.ratePpm / 1e4).toLocaleString(void 0, { maximumFractionDigits: 4 })}%: store ${formatMoney16({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney16({ amount: warning.expectedMinor, currency: order.currency })}` : warning.code === "customer_ignored" ? `The online store didn't recognise the customer on this sale, so it was saved as a guest sale. Customer id: ${warning.customerId}.` : warning.code === "figures_mismatch" ? `The online store worked out different figures for this sale. ${warning.fields.map(({ field, tillMinor, serverMinor }) => `${FIGURE_LABELS.get(field) ?? field}: till ${formatMoney16({ amount: tillMinor, currency: order.currency })}, store ${formatMoney16({ amount: serverMinor, currency: order.currency })}.`).join(" ")}` : warning.bridgeMinor !== void 0 ? `Store calculated ${formatMoney16({ amount: warning.serverMinor, currency: order.currency })}; a rounding line of ${warning.bridgeMinor > 0 ? "+" : ""}${formatMoney16({ amount: warning.bridgeMinor, currency: order.currency })} brought it to ${formatMoney16({ amount: warning.expectedMinor, currency: order.currency })}` : `Store total ${formatMoney16({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney16({ amount: warning.expectedMinor, currency: order.currency })}` }) }, index))
5012
+ }, className: "rounded-md bg-primary px-4 py-2", children: /* @__PURE__ */ jsx98(Text42, { className: "text-center font-semibold text-primary-foreground", children: "Retry" }) }) : null,
5013
+ knownWarnings(order.warnings).map((warning, index) => /* @__PURE__ */ jsx98(View63, { className: "border-l-4 border-warning pl-2", children: /* @__PURE__ */ jsx98(Text42, { className: "text-foreground", children: warning.code === "insufficient_stock" ? `Stock short by ${warning.quantity} for ${order.lines.find((line) => line.variantId === warning.variantId)?.name}` : warning.code === "tax_rate_mismatch" ? `Tax at ${(warning.ratePpm / 1e4).toLocaleString(void 0, { maximumFractionDigits: 4 })}%: store ${formatMoney17({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney17({ amount: warning.expectedMinor, currency: order.currency })}` : warning.code === "customer_ignored" ? `The online store didn't recognise the customer on this sale, so it was saved as a guest sale. Customer id: ${warning.customerId}.` : warning.code === "figures_mismatch" ? `The online store worked out different figures for this sale. ${warning.fields.map(({ field, tillMinor, serverMinor }) => `${FIGURE_LABELS.get(field) ?? field}: till ${formatMoney17({ amount: tillMinor, currency: order.currency })}, store ${formatMoney17({ amount: serverMinor, currency: order.currency })}.`).join(" ")}` : warning.bridgeMinor !== void 0 ? `Store calculated ${formatMoney17({ amount: warning.serverMinor, currency: order.currency })}; a rounding line of ${warning.bridgeMinor > 0 ? "+" : ""}${formatMoney17({ amount: warning.bridgeMinor, currency: order.currency })} brought it to ${formatMoney17({ amount: warning.expectedMinor, currency: order.currency })}` : `Store total ${formatMoney17({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney17({ amount: warning.expectedMinor, currency: order.currency })}` }) }, index))
4875
5014
  ] }, order.id);
4876
5015
  })
4877
5016
  ] }, section.title)),
@@ -4880,15 +5019,15 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
4880
5019
  }
4881
5020
 
4882
5021
  // src/sale/parked-sales.tsx
4883
- import { useState as useState23 } from "react";
4884
- import { ScrollView as ScrollView14, useWindowDimensions as useWindowDimensions3, View as View63 } from "react-native";
4885
- import { formatMoney as formatMoney17 } from "@tallyui/core";
4886
- import { Fragment as Fragment10, jsx as jsx98, jsxs as jsxs57 } from "react/jsx-runtime";
5022
+ import { useState as useState24 } from "react";
5023
+ import { ScrollView as ScrollView14, useWindowDimensions as useWindowDimensions3, View as View64 } from "react-native";
5024
+ import { formatMoney as formatMoney18 } from "@tallyui/core";
5025
+ import { Fragment as Fragment11, jsx as jsx99, jsxs as jsxs58 } from "react/jsx-runtime";
4887
5026
  function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open, onOpenChange, hour12 }) {
4888
5027
  const { height: windowHeight } = useWindowDimensions3();
4889
5028
  const maxHeight = Math.max(280, windowHeight - 64);
4890
- const [confirming, setConfirming] = useState23(null);
4891
- const [error, setError] = useState23("");
5029
+ const [confirming, setConfirming] = useState24(null);
5030
+ const [error, setError] = useState24("");
4892
5031
  const attempt = async (action) => {
4893
5032
  setError("");
4894
5033
  try {
@@ -4897,28 +5036,28 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
4897
5036
  setError(String(e));
4898
5037
  }
4899
5038
  };
4900
- return /* @__PURE__ */ jsx98(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs57(DialogContent, { testID: "parked-sales", className: "flex-col overflow-hidden", style: { maxHeight }, children: [
4901
- /* @__PURE__ */ jsxs57(View63, { className: "flex-row items-center justify-between gap-2", children: [
4902
- /* @__PURE__ */ jsx98(DialogTitle, { children: "Parked sales" }),
4903
- /* @__PURE__ */ jsx98(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx98(IconButton, { variant: "ghost", size: "sm", testID: "parked-sales-dismiss", accessibilityLabel: "Close panel", children: /* @__PURE__ */ jsx98(XIcon, { size: 16 }) }) })
5039
+ return /* @__PURE__ */ jsx99(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs58(DialogContent, { testID: "parked-sales", className: "flex-col overflow-hidden", style: { maxHeight }, children: [
5040
+ /* @__PURE__ */ jsxs58(View64, { className: "flex-row items-center justify-between gap-2", children: [
5041
+ /* @__PURE__ */ jsx99(DialogTitle, { children: "Parked sales" }),
5042
+ /* @__PURE__ */ jsx99(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx99(IconButton, { variant: "ghost", size: "sm", testID: "parked-sales-dismiss", accessibilityLabel: "Close panel", children: /* @__PURE__ */ jsx99(XIcon, { size: 16 }) }) })
4904
5043
  ] }),
4905
- /* @__PURE__ */ jsxs57(ScrollView14, { className: "flex-1", contentContainerClassName: "gap-3", children: [
4906
- /* @__PURE__ */ jsx98(
5044
+ /* @__PURE__ */ jsxs58(ScrollView14, { className: "flex-1", contentContainerClassName: "gap-3", children: [
5045
+ /* @__PURE__ */ jsx99(
4907
5046
  Button,
4908
5047
  {
4909
5048
  testID: "parked-sales-park",
4910
5049
  accessibilityLabel: "Park this sale",
4911
5050
  disabled: sale.order.lineItems.length === 0,
4912
5051
  onPress: () => attempt(async () => setError(await (onPark ?? sale.park)() ?? "")),
4913
- children: /* @__PURE__ */ jsx98(Text, { children: "Park this sale" })
5052
+ children: /* @__PURE__ */ jsx99(Text, { children: "Park this sale" })
4914
5053
  }
4915
5054
  ),
4916
- !!error && /* @__PURE__ */ jsx98(Text, { testID: "parked-sales-error", className: "text-destructive", children: error }),
4917
- parked.length === 0 && /* @__PURE__ */ jsx98(Text, { testID: "parked-sales-empty", children: "No parked sales." }),
4918
- parked.map((row) => /* @__PURE__ */ jsx98(View63, { testID: `parked-row-${row.id}`, className: "gap-2 rounded-md border border-border p-3", children: confirming === row.id ? /* @__PURE__ */ jsxs57(Fragment10, { children: [
4919
- /* @__PURE__ */ jsx98(Text, { children: "Discard this parked sale?" }),
4920
- /* @__PURE__ */ jsxs57(View63, { className: "flex-row gap-2", children: [
4921
- /* @__PURE__ */ jsx98(
5055
+ !!error && /* @__PURE__ */ jsx99(Text, { testID: "parked-sales-error", className: "text-destructive", children: error }),
5056
+ parked.length === 0 && /* @__PURE__ */ jsx99(Text, { testID: "parked-sales-empty", children: "No parked sales." }),
5057
+ parked.map((row) => /* @__PURE__ */ jsx99(View64, { testID: `parked-row-${row.id}`, className: "gap-2 rounded-md border border-border p-3", children: confirming === row.id ? /* @__PURE__ */ jsxs58(Fragment11, { children: [
5058
+ /* @__PURE__ */ jsx99(Text, { children: "Discard this parked sale?" }),
5059
+ /* @__PURE__ */ jsxs58(View64, { className: "flex-row gap-2", children: [
5060
+ /* @__PURE__ */ jsx99(
4922
5061
  Button,
4923
5062
  {
4924
5063
  testID: `parked-discard-confirm-${row.id}`,
@@ -4927,22 +5066,22 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
4927
5066
  await onDiscard(row.id);
4928
5067
  setConfirming(null);
4929
5068
  }),
4930
- children: /* @__PURE__ */ jsx98(Text, { children: "Discard" })
5069
+ children: /* @__PURE__ */ jsx99(Text, { children: "Discard" })
4931
5070
  }
4932
5071
  ),
4933
- /* @__PURE__ */ jsx98(Button, { testID: `parked-discard-cancel-${row.id}`, variant: "outline", onPress: () => setConfirming(null), children: /* @__PURE__ */ jsx98(Text, { children: "Cancel" }) })
5072
+ /* @__PURE__ */ jsx99(Button, { testID: `parked-discard-cancel-${row.id}`, variant: "outline", onPress: () => setConfirming(null), children: /* @__PURE__ */ jsx99(Text, { children: "Cancel" }) })
4934
5073
  ] })
4935
- ] }) : /* @__PURE__ */ jsxs57(Fragment10, { children: [
4936
- /* @__PURE__ */ jsx98(Text, { children: formatStockSyncTime(new Date(row.parkedAt), void 0, hour12) }),
4937
- /* @__PURE__ */ jsxs57(Text, { children: [
5074
+ ] }) : /* @__PURE__ */ jsxs58(Fragment11, { children: [
5075
+ /* @__PURE__ */ jsx99(Text, { children: formatStockSyncTime(new Date(row.parkedAt), void 0, hour12) }),
5076
+ /* @__PURE__ */ jsxs58(Text, { children: [
4938
5077
  row.itemCount,
4939
5078
  " ",
4940
5079
  row.itemCount === 1 ? "item" : "items"
4941
5080
  ] }),
4942
- /* @__PURE__ */ jsx98(Text, { children: formatMoney17({ amount: row.totalMinor, currency }) }),
4943
- !!row.customerName && /* @__PURE__ */ jsx98(Text, { children: row.customerName }),
4944
- /* @__PURE__ */ jsxs57(View63, { className: "flex-row gap-2", children: [
4945
- /* @__PURE__ */ jsx98(
5081
+ /* @__PURE__ */ jsx99(Text, { children: formatMoney18({ amount: row.totalMinor, currency }) }),
5082
+ !!row.customerName && /* @__PURE__ */ jsx99(Text, { children: row.customerName }),
5083
+ /* @__PURE__ */ jsxs58(View64, { className: "flex-row gap-2", children: [
5084
+ /* @__PURE__ */ jsx99(
4946
5085
  Button,
4947
5086
  {
4948
5087
  testID: `parked-resume-${row.id}`,
@@ -4952,17 +5091,17 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
4952
5091
  if (refusal === null) onOpenChange(false);
4953
5092
  else setError(refusal);
4954
5093
  }),
4955
- children: /* @__PURE__ */ jsx98(Text, { children: "Resume" })
5094
+ children: /* @__PURE__ */ jsx99(Text, { children: "Resume" })
4956
5095
  }
4957
5096
  ),
4958
- /* @__PURE__ */ jsx98(
5097
+ /* @__PURE__ */ jsx99(
4959
5098
  Button,
4960
5099
  {
4961
5100
  testID: `parked-discard-${row.id}`,
4962
5101
  accessibilityLabel: "Discard parked sale",
4963
5102
  variant: "outline",
4964
5103
  onPress: () => setConfirming(row.id),
4965
- children: /* @__PURE__ */ jsx98(Text, { children: "Discard" })
5104
+ children: /* @__PURE__ */ jsx99(Text, { children: "Discard" })
4966
5105
  }
4967
5106
  )
4968
5107
  ] })
@@ -4972,10 +5111,10 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
4972
5111
  }
4973
5112
 
4974
5113
  // src/layout/pos-layout.tsx
4975
- import { useState as useState24 } from "react";
4976
- import { Pressable as Pressable32, Text as Text42, View as View64, useWindowDimensions as useWindowDimensions4 } from "react-native";
5114
+ import { useState as useState25 } from "react";
5115
+ import { Pressable as Pressable33, Text as Text43, View as View65, useWindowDimensions as useWindowDimensions4 } from "react-native";
4977
5116
  import { cn as cn80 } from "@tallyui/theme";
4978
- import { Fragment as Fragment11, jsx as jsx99, jsxs as jsxs58 } from "react/jsx-runtime";
5117
+ import { Fragment as Fragment12, jsx as jsx100, jsxs as jsxs59 } from "react/jsx-runtime";
4979
5118
  function POSLayout({
4980
5119
  browseSlot,
4981
5120
  cartSlot,
@@ -4987,40 +5126,40 @@ function POSLayout({
4987
5126
  }) {
4988
5127
  const { width } = useWindowDimensions4();
4989
5128
  const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
4990
- const [activeTab, setActiveTab] = useState24("browse");
4991
- return /* @__PURE__ */ jsxs58(View64, { className: cn80("flex-1 bg-bg", className), ...viewProps, children: [
4992
- headerSlot && /* @__PURE__ */ jsx99(View64, { className: "border-b border-border", children: headerSlot }),
4993
- layout === "split" ? /* @__PURE__ */ jsxs58(View64, { className: "flex-1 flex-row", children: [
4994
- /* @__PURE__ */ jsx99(View64, { className: "flex-[3]", children: browseSlot }),
4995
- /* @__PURE__ */ jsx99(View64, { className: "flex-[2] border-l border-border", children: cartSlot })
4996
- ] }) : /* @__PURE__ */ jsxs58(Fragment11, { children: [
4997
- /* @__PURE__ */ jsxs58(View64, { className: "flex-row border-b border-border", children: [
4998
- /* @__PURE__ */ jsx99(
4999
- Pressable32,
5129
+ const [activeTab, setActiveTab] = useState25("browse");
5130
+ return /* @__PURE__ */ jsxs59(View65, { className: cn80("flex-1 bg-bg", className), ...viewProps, children: [
5131
+ headerSlot && /* @__PURE__ */ jsx100(View65, { className: "border-b border-border", children: headerSlot }),
5132
+ layout === "split" ? /* @__PURE__ */ jsxs59(View65, { className: "flex-1 flex-row", children: [
5133
+ /* @__PURE__ */ jsx100(View65, { className: "flex-[3]", children: browseSlot }),
5134
+ /* @__PURE__ */ jsx100(View65, { className: "flex-[2] border-l border-border", children: cartSlot })
5135
+ ] }) : /* @__PURE__ */ jsxs59(Fragment12, { children: [
5136
+ /* @__PURE__ */ jsxs59(View65, { className: "flex-row border-b border-border", children: [
5137
+ /* @__PURE__ */ jsx100(
5138
+ Pressable33,
5000
5139
  {
5001
5140
  onPress: () => setActiveTab("browse"),
5002
5141
  className: cn80("flex-1 py-3", activeTab === "browse" && "border-b-2 border-primary"),
5003
- children: /* @__PURE__ */ jsx99(Text42, { className: cn80("text-center text-sm font-semibold", activeTab === "browse" ? "text-primary" : "text-muted-foreground"), children: "Browse" })
5142
+ children: /* @__PURE__ */ jsx100(Text43, { className: cn80("text-center text-sm font-semibold", activeTab === "browse" ? "text-primary" : "text-muted-foreground"), children: "Browse" })
5004
5143
  }
5005
5144
  ),
5006
- /* @__PURE__ */ jsx99(
5007
- Pressable32,
5145
+ /* @__PURE__ */ jsx100(
5146
+ Pressable33,
5008
5147
  {
5009
5148
  onPress: () => setActiveTab("cart"),
5010
5149
  className: cn80("flex-1 py-3", activeTab === "cart" && "border-b-2 border-primary"),
5011
- children: /* @__PURE__ */ jsx99(Text42, { className: cn80("text-center text-sm font-semibold", activeTab === "cart" ? "text-primary" : "text-muted-foreground"), children: "Cart" })
5150
+ children: /* @__PURE__ */ jsx100(Text43, { className: cn80("text-center text-sm font-semibold", activeTab === "cart" ? "text-primary" : "text-muted-foreground"), children: "Cart" })
5012
5151
  }
5013
5152
  )
5014
5153
  ] }),
5015
- /* @__PURE__ */ jsx99(View64, { className: "flex-1", children: activeTab === "browse" ? browseSlot : cartSlot })
5154
+ /* @__PURE__ */ jsx100(View65, { className: "flex-1", children: activeTab === "browse" ? browseSlot : cartSlot })
5016
5155
  ] })
5017
5156
  ] });
5018
5157
  }
5019
5158
 
5020
5159
  // src/layout/checkout-layout.tsx
5021
- import { ScrollView as ScrollView15, View as View65, useWindowDimensions as useWindowDimensions5 } from "react-native";
5160
+ import { ScrollView as ScrollView15, View as View66, useWindowDimensions as useWindowDimensions5 } from "react-native";
5022
5161
  import { cn as cn81 } from "@tallyui/theme";
5023
- import { jsx as jsx100, jsxs as jsxs59 } from "react/jsx-runtime";
5162
+ import { jsx as jsx101, jsxs as jsxs60 } from "react/jsx-runtime";
5024
5163
  function CheckoutLayout({
5025
5164
  summarySlot,
5026
5165
  paymentSlot,
@@ -5032,12 +5171,12 @@ function CheckoutLayout({
5032
5171
  }) {
5033
5172
  const { width } = useWindowDimensions5();
5034
5173
  const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
5035
- return /* @__PURE__ */ jsxs59(View65, { className: cn81("flex-1 bg-bg", className), ...viewProps, children: [
5036
- headerSlot && /* @__PURE__ */ jsx100(View65, { className: "border-b border-border", children: headerSlot }),
5037
- layout === "split" ? /* @__PURE__ */ jsxs59(View65, { className: "flex-1 flex-row", children: [
5038
- /* @__PURE__ */ jsx100(View65, { className: "flex-1 border-r border-border", children: summarySlot }),
5039
- /* @__PURE__ */ jsx100(View65, { className: "flex-1", children: paymentSlot })
5040
- ] }) : /* @__PURE__ */ jsx100(ScrollView15, { className: "flex-1", children: /* @__PURE__ */ jsxs59(View65, { className: "gap-4 p-4", children: [
5174
+ return /* @__PURE__ */ jsxs60(View66, { className: cn81("flex-1 bg-bg", className), ...viewProps, children: [
5175
+ headerSlot && /* @__PURE__ */ jsx101(View66, { className: "border-b border-border", children: headerSlot }),
5176
+ layout === "split" ? /* @__PURE__ */ jsxs60(View66, { className: "flex-1 flex-row", children: [
5177
+ /* @__PURE__ */ jsx101(View66, { className: "flex-1 border-r border-border", children: summarySlot }),
5178
+ /* @__PURE__ */ jsx101(View66, { className: "flex-1", children: paymentSlot })
5179
+ ] }) : /* @__PURE__ */ jsx101(ScrollView15, { className: "flex-1", children: /* @__PURE__ */ jsxs60(View66, { className: "gap-4 p-4", children: [
5041
5180
  summarySlot,
5042
5181
  paymentSlot
5043
5182
  ] }) })
@@ -5045,10 +5184,10 @@ function CheckoutLayout({
5045
5184
  }
5046
5185
 
5047
5186
  // src/layout/settings-layout.tsx
5048
- import { useState as useState25 } from "react";
5049
- import { Pressable as Pressable33, Text as Text43, View as View66, useWindowDimensions as useWindowDimensions6 } from "react-native";
5187
+ import { useState as useState26 } from "react";
5188
+ import { Pressable as Pressable34, Text as Text44, View as View67, useWindowDimensions as useWindowDimensions6 } from "react-native";
5050
5189
  import { cn as cn82 } from "@tallyui/theme";
5051
- import { jsx as jsx101, jsxs as jsxs60 } from "react/jsx-runtime";
5190
+ import { jsx as jsx102, jsxs as jsxs61 } from "react/jsx-runtime";
5052
5191
  function SettingsLayout({
5053
5192
  navSlot,
5054
5193
  contentSlot,
@@ -5060,26 +5199,26 @@ function SettingsLayout({
5060
5199
  }) {
5061
5200
  const { width } = useWindowDimensions6();
5062
5201
  const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
5063
- const [showNav, setShowNav] = useState25(false);
5064
- return /* @__PURE__ */ jsxs60(View66, { className: cn82("flex-1 bg-bg", className), ...viewProps, children: [
5065
- headerSlot && /* @__PURE__ */ jsx101(View66, { className: "border-b border-border", children: headerSlot }),
5066
- layout === "split" ? /* @__PURE__ */ jsxs60(View66, { className: "flex-1 flex-row", children: [
5067
- /* @__PURE__ */ jsx101(View66, { className: "w-64 border-r border-border", children: navSlot }),
5068
- /* @__PURE__ */ jsx101(View66, { className: "flex-1", children: contentSlot })
5069
- ] }) : /* @__PURE__ */ jsx101(View66, { className: "flex-1", children: showNav ? /* @__PURE__ */ jsxs60(View66, { className: "flex-1", children: [
5202
+ const [showNav, setShowNav] = useState26(false);
5203
+ return /* @__PURE__ */ jsxs61(View67, { className: cn82("flex-1 bg-bg", className), ...viewProps, children: [
5204
+ headerSlot && /* @__PURE__ */ jsx102(View67, { className: "border-b border-border", children: headerSlot }),
5205
+ layout === "split" ? /* @__PURE__ */ jsxs61(View67, { className: "flex-1 flex-row", children: [
5206
+ /* @__PURE__ */ jsx102(View67, { className: "w-64 border-r border-border", children: navSlot }),
5207
+ /* @__PURE__ */ jsx102(View67, { className: "flex-1", children: contentSlot })
5208
+ ] }) : /* @__PURE__ */ jsx102(View67, { className: "flex-1", children: showNav ? /* @__PURE__ */ jsxs61(View67, { className: "flex-1", children: [
5070
5209
  navSlot,
5071
- /* @__PURE__ */ jsx101(Pressable33, { onPress: () => setShowNav(false), className: "border-t border-border p-3", children: /* @__PURE__ */ jsx101(Text43, { className: "text-center text-sm font-medium text-primary", children: "Done" }) })
5072
- ] }) : /* @__PURE__ */ jsxs60(View66, { className: "flex-1", children: [
5073
- /* @__PURE__ */ jsx101(Pressable33, { onPress: () => setShowNav(true), className: "border-b border-border px-4 py-2", children: /* @__PURE__ */ jsx101(Text43, { className: "text-sm font-medium text-primary", children: "Menu" }) }),
5210
+ /* @__PURE__ */ jsx102(Pressable34, { onPress: () => setShowNav(false), className: "border-t border-border p-3", children: /* @__PURE__ */ jsx102(Text44, { className: "text-center text-sm font-medium text-primary", children: "Done" }) })
5211
+ ] }) : /* @__PURE__ */ jsxs61(View67, { className: "flex-1", children: [
5212
+ /* @__PURE__ */ jsx102(Pressable34, { onPress: () => setShowNav(true), className: "border-b border-border px-4 py-2", children: /* @__PURE__ */ jsx102(Text44, { className: "text-sm font-medium text-primary", children: "Menu" }) }),
5074
5213
  contentSlot
5075
5214
  ] }) })
5076
5215
  ] });
5077
5216
  }
5078
5217
 
5079
5218
  // src/layout/live-tab-screen.tsx
5080
- import { Pressable as Pressable34, Text as Text44, View as View67 } from "react-native";
5219
+ import { Pressable as Pressable35, Text as Text45, View as View68 } from "react-native";
5081
5220
  import { cn as cn83 } from "@tallyui/theme";
5082
- import { jsx as jsx102, jsxs as jsxs61 } from "react/jsx-runtime";
5221
+ import { jsx as jsx103, jsxs as jsxs62 } from "react/jsx-runtime";
5083
5222
  function LiveTabScreen({
5084
5223
  state,
5085
5224
  onUseHere,
@@ -5096,21 +5235,21 @@ function LiveTabScreen({
5096
5235
  const body = state === "parked" ? parkedBody : blockedBody;
5097
5236
  const buttonLabel = state === "parked" ? useHereLabel : reloadLabel;
5098
5237
  const onPress = state === "parked" ? onUseHere : onReload;
5099
- return /* @__PURE__ */ jsxs61(View67, { className: cn83("flex-1 items-center justify-center gap-4 bg-bg p-6", className), ...viewProps, children: [
5100
- /* @__PURE__ */ jsx102(Text44, { className: "text-center text-lg font-bold text-foreground", children: parkedTitle }),
5101
- /* @__PURE__ */ jsx102(Text44, { className: "text-center text-sm text-muted-foreground", children: body }),
5102
- /* @__PURE__ */ jsx102(Pressable34, { onPress, className: "items-center rounded-lg bg-primary px-4 py-3", children: /* @__PURE__ */ jsx102(Text44, { className: "text-sm font-semibold text-primary-foreground", children: buttonLabel }) })
5238
+ return /* @__PURE__ */ jsxs62(View68, { className: cn83("flex-1 items-center justify-center gap-4 bg-bg p-6", className), ...viewProps, children: [
5239
+ /* @__PURE__ */ jsx103(Text45, { className: "text-center text-lg font-bold text-foreground", children: parkedTitle }),
5240
+ /* @__PURE__ */ jsx103(Text45, { className: "text-center text-sm text-muted-foreground", children: body }),
5241
+ /* @__PURE__ */ jsx103(Pressable35, { onPress, className: "items-center rounded-lg bg-primary px-4 py-3", children: /* @__PURE__ */ jsx103(Text45, { className: "text-sm font-semibold text-primary-foreground", children: buttonLabel }) })
5103
5242
  ] });
5104
5243
  }
5105
5244
 
5106
5245
  // src/layout/store-settings-choice-screen.tsx
5107
- import { useState as useState26 } from "react";
5108
- import { Pressable as Pressable35, Text as Text45, View as View68 } from "react-native";
5246
+ import { useState as useState27 } from "react";
5247
+ import { Pressable as Pressable36, Text as Text46, View as View69 } from "react-native";
5109
5248
  import { cn as cn84 } from "@tallyui/theme";
5110
- import { jsx as jsx103, jsxs as jsxs62 } from "react/jsx-runtime";
5249
+ import { jsx as jsx104, jsxs as jsxs63 } from "react/jsx-runtime";
5111
5250
  function useSectionSelection(options, initialValue) {
5112
5251
  const preset = options.length === 1 ? options[0].value : options.find((o) => o.value === initialValue)?.value;
5113
- return useState26(preset);
5252
+ return useState27(preset);
5114
5253
  }
5115
5254
  function defaultCountryName(code, locale) {
5116
5255
  try {
@@ -5156,32 +5295,32 @@ function StoreSettingsChoiceScreen({
5156
5295
  else if (initial?.channel !== void 0) choice.channel = initial.channel;
5157
5296
  onSubmit(choice);
5158
5297
  };
5159
- return /* @__PURE__ */ jsxs62(View68, { className: cn84("w-full max-w-[560px] flex-1 self-center gap-6 bg-bg p-6", className), ...viewProps, children: [
5160
- /* @__PURE__ */ jsxs62(View68, { className: "gap-2", children: [
5161
- /* @__PURE__ */ jsx103(Text45, { className: "text-lg font-bold text-foreground", children: title }),
5162
- /* @__PURE__ */ jsx103(Text45, { className: "text-sm text-muted-foreground", children: body })
5298
+ return /* @__PURE__ */ jsxs63(View69, { className: cn84("w-full max-w-[560px] flex-1 self-center gap-6 bg-bg p-6", className), ...viewProps, children: [
5299
+ /* @__PURE__ */ jsxs63(View69, { className: "gap-2", children: [
5300
+ /* @__PURE__ */ jsx104(Text46, { className: "text-lg font-bold text-foreground", children: title }),
5301
+ /* @__PURE__ */ jsx104(Text46, { className: "text-sm text-muted-foreground", children: body })
5163
5302
  ] }),
5164
- showRegions && /* @__PURE__ */ jsx103(ChoiceSection, { label: regionLabel, options: regionOptions, selected: region, onSelect: setRegion }),
5165
- showCountries && /* @__PURE__ */ jsx103(ChoiceSection, { label: countryLabel, options: countryOptions, selected: country, onSelect: setCountry }),
5166
- showChannels && /* @__PURE__ */ jsx103(ChoiceSection, { label: channelLabel, options: channelOptions, selected: channel, onSelect: setChannel }),
5167
- /* @__PURE__ */ jsx103(
5168
- Pressable35,
5303
+ showRegions && /* @__PURE__ */ jsx104(ChoiceSection, { label: regionLabel, options: regionOptions, selected: region, onSelect: setRegion }),
5304
+ showCountries && /* @__PURE__ */ jsx104(ChoiceSection, { label: countryLabel, options: countryOptions, selected: country, onSelect: setCountry }),
5305
+ showChannels && /* @__PURE__ */ jsx104(ChoiceSection, { label: channelLabel, options: channelOptions, selected: channel, onSelect: setChannel }),
5306
+ /* @__PURE__ */ jsx104(
5307
+ Pressable36,
5169
5308
  {
5170
5309
  onPress: handleSubmit,
5171
5310
  disabled: !complete,
5172
5311
  className: cn84("items-center rounded-lg bg-primary px-4 py-3", !complete && "opacity-50"),
5173
- children: /* @__PURE__ */ jsx103(Text45, { className: "text-sm font-semibold text-primary-foreground", children: submitLabel })
5312
+ children: /* @__PURE__ */ jsx104(Text46, { className: "text-sm font-semibold text-primary-foreground", children: submitLabel })
5174
5313
  }
5175
5314
  )
5176
5315
  ] });
5177
5316
  }
5178
5317
  function ChoiceSection({ label, options, selected, onSelect }) {
5179
- return /* @__PURE__ */ jsxs62(View68, { className: "gap-1.5", children: [
5180
- /* @__PURE__ */ jsx103(Text45, { className: "text-xs font-semibold text-muted-foreground", children: label }),
5181
- /* @__PURE__ */ jsx103(View68, { className: "rounded-lg border border-border", children: options.map((option, index) => {
5318
+ return /* @__PURE__ */ jsxs63(View69, { className: "gap-1.5", children: [
5319
+ /* @__PURE__ */ jsx104(Text46, { className: "text-xs font-semibold text-muted-foreground", children: label }),
5320
+ /* @__PURE__ */ jsx104(View69, { className: "rounded-lg border border-border", children: options.map((option, index) => {
5182
5321
  const checked = option.value === selected;
5183
- return /* @__PURE__ */ jsxs62(
5184
- Pressable35,
5322
+ return /* @__PURE__ */ jsxs63(
5323
+ Pressable36,
5185
5324
  {
5186
5325
  onPress: () => onSelect(option.value),
5187
5326
  accessibilityRole: "radio",
@@ -5189,8 +5328,8 @@ function ChoiceSection({ label, options, selected, onSelect }) {
5189
5328
  testID: `choice-option-${option.value}`,
5190
5329
  className: cn84("flex-row items-center gap-3 px-4 py-3", index > 0 && "border-t border-border", checked && "bg-primary/10"),
5191
5330
  children: [
5192
- /* @__PURE__ */ jsx103(View68, { className: "h-4 w-4 items-center justify-center rounded-full border border-primary", children: checked && /* @__PURE__ */ jsx103(View68, { testID: `choice-option-${option.value}-dot`, className: "h-2.5 w-2.5 rounded-full bg-primary" }) }),
5193
- /* @__PURE__ */ jsx103(Text45, { className: cn84("text-sm", checked ? "font-semibold text-primary" : "text-foreground"), children: option.label })
5331
+ /* @__PURE__ */ jsx104(View69, { className: "h-4 w-4 items-center justify-center rounded-full border border-primary", children: checked && /* @__PURE__ */ jsx104(View69, { testID: `choice-option-${option.value}-dot`, className: "h-2.5 w-2.5 rounded-full bg-primary" }) }),
5332
+ /* @__PURE__ */ jsx104(Text46, { className: cn84("text-sm", checked ? "font-semibold text-primary" : "text-foreground"), children: option.label })
5194
5333
  ]
5195
5334
  },
5196
5335
  option.value
@@ -5236,6 +5375,7 @@ export {
5236
5375
  Catalogue,
5237
5376
  CategoryNav,
5238
5377
  ChangeDisplay,
5378
+ ChargeForm,
5239
5379
  Checkbox,
5240
5380
  CheckoutLayout,
5241
5381
  ClosureSheet,