@tallyui/components 2.0.0 → 3.0.0-next.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
@@ -1694,9 +1694,9 @@ import { cn as cn39 } from "@tallyui/theme";
1694
1694
  import { jsx as jsx41 } from "react/jsx-runtime";
1695
1695
  function ProductSku({ doc, fallback = "\u2014", className, ...textProps }) {
1696
1696
  const { getSku, getVariantCount } = useProductTraits4();
1697
- const count = getVariantCount(doc);
1697
+ const count2 = getVariantCount(doc);
1698
1698
  const sku = getSku(doc);
1699
- return /* @__PURE__ */ jsx41(Text, { className: cn39("text-xs text-muted-foreground", className), ...textProps, children: count > 1 ? `${count} variants` : sku ?? fallback });
1699
+ return /* @__PURE__ */ jsx41(Text, { className: cn39("text-xs text-muted-foreground", className), ...textProps, children: count2 > 1 ? `${count2} variants` : sku ?? fallback });
1700
1700
  }
1701
1701
 
1702
1702
  // src/product/product-stock-badge.tsx
@@ -1794,10 +1794,13 @@ function ProductCard({ doc, onPress, imageSize = 80, currencySymbol: currencySym
1794
1794
  }
1795
1795
 
1796
1796
  // src/product/product-grid.tsx
1797
- import { ScrollView as ScrollView2, View as View19 } from "react-native";
1797
+ import { FlatList, View as View19 } from "react-native";
1798
1798
  import { cn as cn42 } from "@tallyui/theme";
1799
1799
  import { useProductTraits as useProductTraits6 } from "@tallyui/core";
1800
1800
  import { jsx as jsx44, jsxs as jsxs8 } from "react/jsx-runtime";
1801
+ var INITIAL_ROWS = 8;
1802
+ var BATCH_ROWS = 8;
1803
+ var WINDOW_SIZE = 5;
1801
1804
  function ProductGrid({
1802
1805
  items,
1803
1806
  renderItem,
@@ -1820,12 +1823,25 @@ function ProductGrid({
1820
1823
  return /* @__PURE__ */ jsxs8(VStack, { space: "none", className: cn42("flex-1", className), ...viewProps, children: [
1821
1824
  searchSlot && /* @__PURE__ */ jsx44(View19, { className: "px-3 py-2", children: searchSlot }),
1822
1825
  filterSlot && /* @__PURE__ */ jsx44(View19, { className: "px-3 pb-2", children: filterSlot }),
1823
- hasItems ? /* @__PURE__ */ jsx44(ScrollView2, { contentContainerClassName: "flex-row flex-wrap p-1", children: visibleItems.map((item, index) => /* @__PURE__ */ jsx44(View19, { style: { width: `${100 / numColumns}%` }, className: "p-1", children: renderItem(item, index) }, item.id ?? index)) }) : emptyState ?? null
1826
+ hasItems ? /* @__PURE__ */ jsx44(
1827
+ FlatList,
1828
+ {
1829
+ data: visibleItems,
1830
+ numColumns,
1831
+ keyExtractor: (item, index) => String(item.id ?? index),
1832
+ contentContainerClassName: "p-1",
1833
+ initialNumToRender: INITIAL_ROWS,
1834
+ maxToRenderPerBatch: BATCH_ROWS,
1835
+ windowSize: WINDOW_SIZE,
1836
+ renderItem: ({ item, index }) => /* @__PURE__ */ jsx44(View19, { style: { width: `${100 / numColumns}%` }, className: "p-1", children: renderItem(item, index) })
1837
+ },
1838
+ numColumns
1839
+ ) : emptyState ?? null
1824
1840
  ] });
1825
1841
  }
1826
1842
 
1827
1843
  // src/product/product-list.tsx
1828
- import { ScrollView as ScrollView3, View as View20 } from "react-native";
1844
+ import { ScrollView as ScrollView2, View as View20 } from "react-native";
1829
1845
  import { cn as cn43 } from "@tallyui/theme";
1830
1846
  import { jsx as jsx45, jsxs as jsxs9 } from "react/jsx-runtime";
1831
1847
  function ProductList({
@@ -1841,12 +1857,12 @@ function ProductList({
1841
1857
  return /* @__PURE__ */ jsxs9(View20, { className: cn43("flex-1", className), ...viewProps, children: [
1842
1858
  searchSlot && /* @__PURE__ */ jsx45(View20, { className: "px-3 py-2", children: searchSlot }),
1843
1859
  filterSlot && /* @__PURE__ */ jsx45(View20, { className: "px-3 pb-2", children: filterSlot }),
1844
- hasItems ? /* @__PURE__ */ jsx45(ScrollView3, { className: "flex-1", children: items.map((item, index) => /* @__PURE__ */ jsx45(View20, { className: "border-b border-border", children: renderItem(item, index) }, item.id ?? index)) }) : emptyState ?? null
1860
+ hasItems ? /* @__PURE__ */ jsx45(ScrollView2, { className: "flex-1", children: items.map((item, index) => /* @__PURE__ */ jsx45(View20, { className: "border-b border-border", children: renderItem(item, index) }, item.id ?? index)) }) : emptyState ?? null
1845
1861
  ] });
1846
1862
  }
1847
1863
 
1848
1864
  // src/product/category-nav.tsx
1849
- import { Pressable as Pressable8, ScrollView as ScrollView4, Text as Text11, View as View21 } from "react-native";
1865
+ import { Pressable as Pressable8, ScrollView as ScrollView3, Text as Text11, View as View21 } from "react-native";
1850
1866
  import { cn as cn44 } from "@tallyui/theme";
1851
1867
  import { jsx as jsx46 } from "react/jsx-runtime";
1852
1868
  function CategoryNav({
@@ -1884,7 +1900,7 @@ function CategoryNav({
1884
1900
  });
1885
1901
  if (isHorizontal) {
1886
1902
  return /* @__PURE__ */ jsx46(
1887
- ScrollView4,
1903
+ ScrollView3,
1888
1904
  {
1889
1905
  horizontal: true,
1890
1906
  showsHorizontalScrollIndicator: false,
@@ -1993,7 +2009,7 @@ function CartTotal({
1993
2009
  }
1994
2010
 
1995
2011
  // src/cart/cart-panel.tsx
1996
- import { ScrollView as ScrollView5, View as View23 } from "react-native";
2012
+ import { ScrollView as ScrollView4, View as View23 } from "react-native";
1997
2013
  import { cn as cn48 } from "@tallyui/theme";
1998
2014
  import { jsx as jsx50, jsxs as jsxs13 } from "react/jsx-runtime";
1999
2015
  function defaultKey(item, index) {
@@ -2014,7 +2030,7 @@ function CartPanel({
2014
2030
  const hasItems = items.length > 0;
2015
2031
  return /* @__PURE__ */ jsxs13(VStack, { space: "none", className: cn48("flex-1 min-h-0", className), ...props, children: [
2016
2032
  header && /* @__PURE__ */ jsx50(View23, { className: "border-b border-border px-3 py-2", children: header }),
2017
- /* @__PURE__ */ jsxs13(ScrollView5, { className: "flex-1 min-h-0", contentContainerClassName: "flex-grow", children: [
2033
+ /* @__PURE__ */ jsxs13(ScrollView4, { className: "flex-1 min-h-0", contentContainerClassName: "flex-grow", children: [
2018
2034
  hasItems ? items.map((item, index) => /* @__PURE__ */ jsx50(View23, { children: renderItem(item, index) }, keyExtractor ? keyExtractor(item, index) : defaultKey(item, index))) : emptyState ?? null,
2019
2035
  afterItems
2020
2036
  ] }),
@@ -2138,7 +2154,7 @@ function SearchInput({ value, onChangeText, className, placeholder = "Search..."
2138
2154
 
2139
2155
  // src/input/filter-chip.tsx
2140
2156
  import { useMemo } from "react";
2141
- import { Pressable as Pressable12, ScrollView as ScrollView6 } from "react-native";
2157
+ import { Pressable as Pressable12, ScrollView as ScrollView5 } from "react-native";
2142
2158
  import { ToggleGroup as ToggleGroup3 } from "@tallyui/primitives";
2143
2159
  import { cn as cn53 } from "@tallyui/theme";
2144
2160
  import { jsx as jsx55 } from "react/jsx-runtime";
@@ -2191,7 +2207,7 @@ function FilterChipGroup({ chips, onChipPress, className, ...viewProps }) {
2191
2207
  onValueChange: handleValueChange,
2192
2208
  asChild: true,
2193
2209
  children: /* @__PURE__ */ jsx55(
2194
- ScrollView6,
2210
+ ScrollView5,
2195
2211
  {
2196
2212
  horizontal: true,
2197
2213
  showsHorizontalScrollIndicator: false,
@@ -2267,9 +2283,12 @@ function QuantityStepper({
2267
2283
  import { useCustomerTraits } from "@tallyui/core";
2268
2284
  import { cn as cn55 } from "@tallyui/theme";
2269
2285
  import { jsx as jsx57, jsxs as jsxs17 } from "react/jsx-runtime";
2270
- function CustomerCard({ doc, className, ...props }) {
2286
+ function CustomerCardFromContext(props) {
2271
2287
  const traits = useCustomerTraits();
2272
- if (!traits) return null;
2288
+ return traits ? /* @__PURE__ */ jsx57(CustomerCard, { ...props, traits }) : null;
2289
+ }
2290
+ function CustomerCard({ doc, traits, className, ...props }) {
2291
+ if (!traits) return /* @__PURE__ */ jsx57(CustomerCardFromContext, { doc, className, ...props });
2273
2292
  const name = traits.getName(doc);
2274
2293
  const email = traits.getEmail(doc);
2275
2294
  const address = traits.getAddressSummary(doc);
@@ -2281,21 +2300,27 @@ function CustomerCard({ doc, className, ...props }) {
2281
2300
  }
2282
2301
 
2283
2302
  // src/customer/customer-select.tsx
2284
- import { ScrollView as ScrollView7, View as View29 } from "react-native";
2303
+ import { Pressable as Pressable14, ScrollView as ScrollView6, View as View29 } from "react-native";
2285
2304
  import { Select as Select2 } from "@tallyui/primitives";
2286
2305
  import { useCustomerTraits as useCustomerTraits2 } from "@tallyui/core";
2287
2306
  import { cn as cn56 } from "@tallyui/theme";
2288
2307
  import { jsx as jsx58, jsxs as jsxs18 } from "react/jsx-runtime";
2289
- function CustomerSelect({
2308
+ function CustomerSelect(props) {
2309
+ return props.traits ? /* @__PURE__ */ jsx58(CustomerSelectView, { ...props }) : /* @__PURE__ */ jsx58(CustomerSelectFromContext, { ...props });
2310
+ }
2311
+ function CustomerSelectFromContext(props) {
2312
+ return /* @__PURE__ */ jsx58(CustomerSelectView, { ...props, traits: useCustomerTraits2() });
2313
+ }
2314
+ function CustomerSelectView({
2290
2315
  customers,
2291
2316
  selected,
2292
2317
  onSelect,
2293
2318
  onSearch,
2294
2319
  placeholder = "Search customers...",
2295
2320
  className,
2321
+ traits,
2296
2322
  ...props
2297
2323
  }) {
2298
- const traits = useCustomerTraits2();
2299
2324
  const selectedOption = selected && traits ? { value: traits.getId(selected), label: traits.getName(selected) } : void 0;
2300
2325
  const customerById = /* @__PURE__ */ new Map();
2301
2326
  if (traits) {
@@ -2314,17 +2339,18 @@ function CustomerSelect({
2314
2339
  onValueChange: handleValueChange,
2315
2340
  defaultOpen: true,
2316
2341
  children: /* @__PURE__ */ jsxs18(VStack, { space: "sm", className: cn56(className), ...props, children: [
2317
- selected && traits && /* @__PURE__ */ jsx58(Select2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx58(View29, { className: "rounded-lg border border-primary bg-primary/5 px-3 py-2", children: /* @__PURE__ */ jsx58(CustomerCard, { doc: selected }) }) }),
2318
- customers.length > 0 && /* @__PURE__ */ jsx58(Select2.Content, { asChild: true, forceMount: true, disablePositioningStyle: true, children: /* @__PURE__ */ jsx58(ScrollView7, { className: "max-h-60", children: customers.map((customer, index) => {
2342
+ selected && traits && /* @__PURE__ */ jsx58(Select2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx58(View29, { className: "rounded-lg border border-primary bg-primary/5 px-3 py-2", children: /* @__PURE__ */ jsx58(CustomerCard, { doc: selected, traits }) }) }),
2343
+ customers.length > 0 && /* @__PURE__ */ jsx58(Select2.Content, { asChild: true, forceMount: true, disablePositioningStyle: true, children: /* @__PURE__ */ jsx58(ScrollView6, { className: "max-h-60", children: customers.map((customer, index) => {
2319
2344
  const id = traits?.getId(customer) ?? String(index);
2320
2345
  const label = traits?.getName(customer) ?? "";
2346
+ const email = traits?.getEmail(customer);
2321
2347
  return /* @__PURE__ */ jsx58(
2322
2348
  Select2.Item,
2323
2349
  {
2324
2350
  value: id,
2325
2351
  label,
2326
2352
  asChild: true,
2327
- children: /* @__PURE__ */ jsx58(View29, { className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ jsx58(CustomerCard, { doc: customer }) })
2353
+ children: /* @__PURE__ */ jsx58(Pressable14, { accessibilityLabel: email ? `${label}, ${email}` : label, className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ jsx58(CustomerCard, { doc: customer, traits }) })
2328
2354
  },
2329
2355
  id
2330
2356
  );
@@ -2335,7 +2361,7 @@ function CustomerSelect({
2335
2361
  }
2336
2362
 
2337
2363
  // src/customer/customer-form.tsx
2338
- import { Pressable as Pressable14, Text as Text17, TextInput as TextInput6, View as View30 } from "react-native";
2364
+ import { Pressable as Pressable15, Text as Text17, TextInput as TextInput6, View as View30 } from "react-native";
2339
2365
  import { cn as cn57 } from "@tallyui/theme";
2340
2366
  import { jsx as jsx59, jsxs as jsxs19 } from "react/jsx-runtime";
2341
2367
  function FormField({
@@ -2363,6 +2389,7 @@ function CustomerForm({
2363
2389
  onChangeField,
2364
2390
  onSubmit,
2365
2391
  submitLabel = "Save Customer",
2392
+ showAddress = true,
2366
2393
  className,
2367
2394
  ...viewProps
2368
2395
  }) {
@@ -2373,13 +2400,13 @@ function CustomerForm({
2373
2400
  ] }),
2374
2401
  /* @__PURE__ */ jsx59(FormField, { label: "Email", value: values.email, onChangeText: (v) => onChangeField("email", v), placeholder: "email@example.com", keyboardType: "email-address" }),
2375
2402
  /* @__PURE__ */ jsx59(FormField, { label: "Phone", value: values.phone, onChangeText: (v) => onChangeField("phone", v), placeholder: "Phone number", keyboardType: "phone-pad" }),
2376
- /* @__PURE__ */ jsx59(FormField, { label: "Address", value: values.address, onChangeText: (v) => onChangeField("address", v), placeholder: "Street address", multiline: true }),
2377
- onSubmit && /* @__PURE__ */ jsx59(Pressable14, { onPress: onSubmit, className: "items-center rounded-lg bg-primary px-4 py-3", children: /* @__PURE__ */ jsx59(Text17, { className: "text-sm font-semibold text-primary-foreground", children: submitLabel }) })
2403
+ showAddress && /* @__PURE__ */ jsx59(FormField, { label: "Address", value: values.address, onChangeText: (v) => onChangeField("address", v), placeholder: "Street address", multiline: true }),
2404
+ onSubmit && /* @__PURE__ */ jsx59(Pressable15, { onPress: onSubmit, className: "items-center rounded-lg bg-primary px-4 py-3", children: /* @__PURE__ */ jsx59(Text17, { className: "text-sm font-semibold text-primary-foreground", children: submitLabel }) })
2378
2405
  ] });
2379
2406
  }
2380
2407
 
2381
2408
  // src/customer/customer-order-history.tsx
2382
- import { ScrollView as ScrollView8, Text as Text18, View as View31 } from "react-native";
2409
+ import { ScrollView as ScrollView7, Text as Text18, View as View31 } from "react-native";
2383
2410
  import { cn as cn58 } from "@tallyui/theme";
2384
2411
  import { jsx as jsx60, jsxs as jsxs20 } from "react/jsx-runtime";
2385
2412
  function CustomerOrderHistory({
@@ -2391,45 +2418,198 @@ function CustomerOrderHistory({
2391
2418
  }) {
2392
2419
  return /* @__PURE__ */ jsxs20(View31, { className: cn58("flex-1", className), ...viewProps, children: [
2393
2420
  /* @__PURE__ */ jsx60(Text18, { className: "px-3 py-2 text-xs font-semibold text-muted-foreground", children: "Order History" }),
2394
- orders.length > 0 ? /* @__PURE__ */ jsx60(ScrollView8, { contentContainerClassName: "gap-2 px-3 pb-3", children: orders.map((order, index) => /* @__PURE__ */ jsx60(View31, { children: renderItem(order, index) }, order.id ?? index)) }) : emptyState ?? null
2421
+ orders.length > 0 ? /* @__PURE__ */ jsx60(ScrollView7, { contentContainerClassName: "gap-2 px-3 pb-3", children: orders.map((order, index) => /* @__PURE__ */ jsx60(View31, { children: renderItem(order, index) }, order.id ?? index)) }) : emptyState ?? null
2395
2422
  ] });
2396
2423
  }
2397
2424
 
2398
- // src/checkout/payment-method-card.tsx
2399
- import { Pressable as Pressable15, View as View32 } from "react-native";
2425
+ // src/customer/customer-picker.tsx
2426
+ import { useEffect, useRef, useState as useState6 } from "react";
2427
+ import { Pressable as Pressable16, Text as Text19, TextInput as TextInput7, View as View32 } from "react-native";
2428
+ import { customerTraits, CustomerServiceError, ConnectorUnauthorizedError } from "@tallyui/core";
2400
2429
  import { cn as cn59 } from "@tallyui/theme";
2401
2430
  import { jsx as jsx61, jsxs as jsxs21 } from "react/jsx-runtime";
2431
+ var EMAIL_MAX = 254;
2432
+ var EMAIL_SHAPE = /^[^\s@\u0000]+@[^\s@\u0000]+\.[^\s@\u0000]+$/u;
2433
+ function CustomerPicker({ search, create, selected, onSelect, onError, online, debounceMs = 250, className }) {
2434
+ const [query, setQuery] = useState6("");
2435
+ const [customers, setCustomers] = useState6([]);
2436
+ const [error, setError] = useState6(null);
2437
+ const [showForm, setShowForm] = useState6(false);
2438
+ const [creating, setCreating] = useState6(false);
2439
+ const [values, setValues] = useState6({ firstName: "", lastName: "", email: "", phone: "", address: "" });
2440
+ const sequence = useRef(0);
2441
+ const searchRef = useRef(search);
2442
+ searchRef.current = search;
2443
+ const [noResults, setNoResults] = useState6(false);
2444
+ function handleError(error2) {
2445
+ if (error2 instanceof CustomerServiceError) {
2446
+ setError(error2.code === "network" ? "Couldn't reach the store. Try again." : error2.code === "server" ? "The store couldn't do that. Try again." : error2.message);
2447
+ } else {
2448
+ setError(error2 instanceof ConnectorUnauthorizedError ? "Sign in again to continue." : "Something went wrong. Try again.");
2449
+ onError?.(error2);
2450
+ }
2451
+ }
2452
+ useEffect(() => {
2453
+ const current = ++sequence.current;
2454
+ setNoResults(false);
2455
+ setError(null);
2456
+ if (!online || !query.trim()) {
2457
+ setCustomers([]);
2458
+ return;
2459
+ }
2460
+ const timer = setTimeout(async () => {
2461
+ try {
2462
+ const results = await searchRef.current(query);
2463
+ if (current === sequence.current) {
2464
+ setCustomers(results);
2465
+ setNoResults(results.length === 0);
2466
+ }
2467
+ } catch (error2) {
2468
+ if (current === sequence.current) handleError(error2);
2469
+ }
2470
+ }, debounceMs);
2471
+ return () => {
2472
+ clearTimeout(timer);
2473
+ sequence.current++;
2474
+ };
2475
+ }, [query, online, debounceMs]);
2476
+ async function submit() {
2477
+ const email = values.email.trim();
2478
+ if (!online || !create || creating || !email) return;
2479
+ if (email.length > EMAIL_MAX || !EMAIL_SHAPE.test(email)) return setError(`Enter a valid email address (up to ${EMAIL_MAX} characters)`);
2480
+ setCreating(true);
2481
+ setError(null);
2482
+ try {
2483
+ const created = await create({
2484
+ email,
2485
+ ...values.firstName.trim() ? { firstName: values.firstName.trim() } : {},
2486
+ ...values.lastName.trim() ? { lastName: values.lastName.trim() } : {},
2487
+ ...values.phone.trim() ? { phone: values.phone.trim() } : {}
2488
+ });
2489
+ onSelect(created);
2490
+ setValues({ firstName: "", lastName: "", email: "", phone: "", address: "" });
2491
+ setShowForm(false);
2492
+ } catch (error2) {
2493
+ handleError(error2);
2494
+ } finally {
2495
+ setCreating(false);
2496
+ }
2497
+ }
2498
+ return /* @__PURE__ */ jsxs21(View32, { className: cn59("gap-3", className), children: [
2499
+ selected && /* @__PURE__ */ jsxs21(View32, { children: [
2500
+ /* @__PURE__ */ jsx61(CustomerCard, { doc: selected, traits: customerTraits }),
2501
+ /* @__PURE__ */ jsx61(Pressable16, { accessibilityRole: "button", className: "items-center rounded-lg border border-border px-4 py-3", onPress: () => onSelect(null), children: /* @__PURE__ */ jsx61(Text19, { className: "text-sm font-semibold text-foreground", children: "Remove customer" }) })
2502
+ ] }),
2503
+ /* @__PURE__ */ jsx61(Text19, { className: "text-xs font-medium text-muted-foreground", children: "Search customers" }),
2504
+ /* @__PURE__ */ jsx61(
2505
+ TextInput7,
2506
+ {
2507
+ accessibilityLabel: "Search customers",
2508
+ value: query,
2509
+ onChangeText: setQuery,
2510
+ editable: online,
2511
+ className: "rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground",
2512
+ placeholderTextColorClassName: "accent-muted-foreground",
2513
+ placeholder: "Name or email"
2514
+ }
2515
+ ),
2516
+ !online && /* @__PURE__ */ jsx61(Text19, { className: "text-sm text-muted-foreground", children: "Connect to search or add customers." }),
2517
+ noResults && /* @__PURE__ */ jsx61(Text19, { className: "text-sm text-muted-foreground", children: "No customers found." }),
2518
+ error && /* @__PURE__ */ jsx61(Text19, { accessibilityRole: "alert", className: "text-sm text-destructive", children: error }),
2519
+ /* @__PURE__ */ jsx61(
2520
+ CustomerSelect,
2521
+ {
2522
+ customers,
2523
+ traits: customerTraits,
2524
+ onSearch: setQuery,
2525
+ onSelect: (customer) => {
2526
+ onSelect(customer);
2527
+ setQuery("");
2528
+ }
2529
+ }
2530
+ ),
2531
+ create && /* @__PURE__ */ jsx61(
2532
+ Pressable16,
2533
+ {
2534
+ accessibilityRole: "button",
2535
+ disabled: !online || creating,
2536
+ onPress: () => setShowForm(true),
2537
+ className: cn59("items-center rounded-lg border border-border px-4 py-3", (!online || creating) && "opacity-50"),
2538
+ children: /* @__PURE__ */ jsx61(Text19, { className: "text-sm font-semibold text-foreground", children: "New customer" })
2539
+ }
2540
+ ),
2541
+ showForm && /* @__PURE__ */ jsxs21(View32, { children: [
2542
+ /* @__PURE__ */ jsx61(
2543
+ CustomerForm,
2544
+ {
2545
+ values,
2546
+ showAddress: false,
2547
+ onChangeField: (field, value) => setValues((current) => ({ ...current, [field]: value }))
2548
+ }
2549
+ ),
2550
+ /* @__PURE__ */ jsxs21(View32, { className: "flex-row gap-3", children: [
2551
+ /* @__PURE__ */ jsx61(
2552
+ Pressable16,
2553
+ {
2554
+ accessibilityRole: "button",
2555
+ disabled: !online || creating || !values.email.trim(),
2556
+ onPress: submit,
2557
+ className: cn59("items-center rounded-lg bg-primary px-4 py-3", (!online || creating || !values.email.trim()) && "opacity-50"),
2558
+ children: /* @__PURE__ */ jsx61(Text19, { className: "text-sm font-semibold text-primary-foreground", children: "Save Customer" })
2559
+ }
2560
+ ),
2561
+ /* @__PURE__ */ jsx61(
2562
+ Pressable16,
2563
+ {
2564
+ accessibilityRole: "button",
2565
+ className: "items-center rounded-lg border border-border px-4 py-3",
2566
+ onPress: () => {
2567
+ setShowForm(false);
2568
+ setValues({ firstName: "", lastName: "", email: "", phone: "", address: "" });
2569
+ },
2570
+ children: /* @__PURE__ */ jsx61(Text19, { className: "text-sm font-semibold text-foreground", children: "Cancel" })
2571
+ }
2572
+ )
2573
+ ] })
2574
+ ] })
2575
+ ] });
2576
+ }
2577
+
2578
+ // src/checkout/payment-method-card.tsx
2579
+ import { Pressable as Pressable17, View as View33 } from "react-native";
2580
+ import { cn as cn60 } from "@tallyui/theme";
2581
+ import { jsx as jsx62, jsxs as jsxs22 } from "react/jsx-runtime";
2402
2582
  function PaymentMethodCard({ label, selected, onPress, icon, className, ...props }) {
2403
- return /* @__PURE__ */ jsx61(Pressable15, { onPress, ...props, children: /* @__PURE__ */ jsxs21(
2583
+ return /* @__PURE__ */ jsx62(Pressable17, { onPress, ...props, children: /* @__PURE__ */ jsxs22(
2404
2584
  HStack,
2405
2585
  {
2406
- className: cn59(
2586
+ className: cn60(
2407
2587
  "rounded-lg border px-4 py-3",
2408
2588
  selected ? "border-primary bg-primary/5" : "border-border bg-card",
2409
2589
  className
2410
2590
  ),
2411
2591
  children: [
2412
- icon && /* @__PURE__ */ jsx61(View32, { children: icon }),
2413
- /* @__PURE__ */ jsx61(Text, { className: cn59("flex-1 text-sm font-medium", selected ? "text-primary" : ""), children: label }),
2414
- selected && /* @__PURE__ */ jsx61(View32, { className: "h-5 w-5 items-center justify-center rounded-full bg-primary", children: /* @__PURE__ */ jsx61(Text, { className: "text-xs text-primary-foreground", children: "\u2713" }) })
2592
+ icon && /* @__PURE__ */ jsx62(View33, { children: icon }),
2593
+ /* @__PURE__ */ jsx62(Text, { className: cn60("flex-1 text-sm font-medium", selected ? "text-primary" : ""), children: label }),
2594
+ selected && /* @__PURE__ */ jsx62(View33, { className: "h-5 w-5 items-center justify-center rounded-full bg-primary", children: /* @__PURE__ */ jsx62(Text, { className: "text-xs text-primary-foreground", children: "\u2713" }) })
2415
2595
  ]
2416
2596
  }
2417
2597
  ) });
2418
2598
  }
2419
2599
 
2420
2600
  // src/checkout/order-summary-line.tsx
2421
- import { cn as cn60 } from "@tallyui/theme";
2422
- import { jsx as jsx62, jsxs as jsxs22 } from "react/jsx-runtime";
2601
+ import { cn as cn61 } from "@tallyui/theme";
2602
+ import { jsx as jsx63, jsxs as jsxs23 } from "react/jsx-runtime";
2423
2603
  function OrderSummaryLine({ label, amount, bold = false, className, ...props }) {
2424
- return /* @__PURE__ */ jsxs22(HStack, { space: "none", className: cn60("justify-between", className), ...props, children: [
2425
- /* @__PURE__ */ jsx62(Text, { className: cn60("text-sm", bold ? "font-bold" : "text-muted-foreground"), children: label }),
2426
- /* @__PURE__ */ jsx62(Text, { className: cn60("text-sm", bold && "font-bold"), children: amount })
2604
+ return /* @__PURE__ */ jsxs23(HStack, { space: "none", className: cn61("justify-between", className), ...props, children: [
2605
+ /* @__PURE__ */ jsx63(Text, { className: cn61("text-sm", bold ? "font-bold" : "text-muted-foreground"), children: label }),
2606
+ /* @__PURE__ */ jsx63(Text, { className: cn61("text-sm", bold && "font-bold"), children: amount })
2427
2607
  ] });
2428
2608
  }
2429
2609
 
2430
2610
  // src/checkout/payment-selector.tsx
2431
- import { cn as cn61 } from "@tallyui/theme";
2432
- import { jsx as jsx63 } from "react/jsx-runtime";
2611
+ import { cn as cn62 } from "@tallyui/theme";
2612
+ import { jsx as jsx64 } from "react/jsx-runtime";
2433
2613
  function PaymentSelector({
2434
2614
  methods,
2435
2615
  selected,
@@ -2437,7 +2617,7 @@ function PaymentSelector({
2437
2617
  className,
2438
2618
  ...props
2439
2619
  }) {
2440
- return /* @__PURE__ */ jsx63(VStack, { space: "sm", className: cn61(className), ...props, children: methods.map((method) => /* @__PURE__ */ jsx63(
2620
+ return /* @__PURE__ */ jsx64(VStack, { space: "sm", className: cn62(className), ...props, children: methods.map((method) => /* @__PURE__ */ jsx64(
2441
2621
  PaymentMethodCard,
2442
2622
  {
2443
2623
  label: method.label,
@@ -2450,9 +2630,9 @@ function PaymentSelector({
2450
2630
  }
2451
2631
 
2452
2632
  // src/checkout/order-summary.tsx
2453
- import { View as View33 } from "react-native";
2454
- import { cn as cn62 } from "@tallyui/theme";
2455
- import { jsx as jsx64, jsxs as jsxs23 } from "react/jsx-runtime";
2633
+ import { View as View34 } from "react-native";
2634
+ import { cn as cn63 } from "@tallyui/theme";
2635
+ import { jsx as jsx65, jsxs as jsxs24 } from "react/jsx-runtime";
2456
2636
  function OrderSummary({
2457
2637
  subtotal,
2458
2638
  tax,
@@ -2464,34 +2644,34 @@ function OrderSummary({
2464
2644
  className,
2465
2645
  ...props
2466
2646
  }) {
2467
- return /* @__PURE__ */ jsxs23(VStack, { space: "none", className: cn62("gap-1.5 px-3 py-3", className), ...props, children: [
2468
- header && /* @__PURE__ */ jsx64(View33, { className: "mb-2", children: header }),
2469
- /* @__PURE__ */ jsx64(OrderSummaryLine, { label: "Subtotal", amount: subtotal }),
2470
- tax && /* @__PURE__ */ jsx64(OrderSummaryLine, { label: taxLabel, amount: tax }),
2471
- /* @__PURE__ */ jsx64(OrderSummaryLine, { label: "Total", amount: total, bold: true }),
2472
- payments && payments.length > 0 && /* @__PURE__ */ jsx64(VStack, { space: "none", className: "mt-2 gap-1.5 border-t border-border pt-2", children: payments.map((payment) => /* @__PURE__ */ jsx64(OrderSummaryLine, { label: payment.label, amount: payment.amount }, payment.label)) }),
2473
- footer && /* @__PURE__ */ jsx64(View33, { className: "mt-2", children: footer })
2647
+ return /* @__PURE__ */ jsxs24(VStack, { space: "none", className: cn63("gap-1.5 px-3 py-3", className), ...props, children: [
2648
+ header && /* @__PURE__ */ jsx65(View34, { className: "mb-2", children: header }),
2649
+ /* @__PURE__ */ jsx65(OrderSummaryLine, { label: "Subtotal", amount: subtotal }),
2650
+ tax && /* @__PURE__ */ jsx65(OrderSummaryLine, { label: taxLabel, amount: tax }),
2651
+ /* @__PURE__ */ jsx65(OrderSummaryLine, { label: "Total", amount: total, bold: true }),
2652
+ payments && payments.length > 0 && /* @__PURE__ */ jsx65(VStack, { space: "none", className: "mt-2 gap-1.5 border-t border-border pt-2", children: payments.map((payment) => /* @__PURE__ */ jsx65(OrderSummaryLine, { label: payment.label, amount: payment.amount }, payment.label)) }),
2653
+ footer && /* @__PURE__ */ jsx65(View34, { className: "mt-2", children: footer })
2474
2654
  ] });
2475
2655
  }
2476
2656
 
2477
2657
  // src/checkout/change-display.tsx
2478
- import { Text as Text19, View as View34 } from "react-native";
2658
+ import { Text as Text20, View as View35 } from "react-native";
2479
2659
  import { formatMoney as formatMoney4 } from "@tallyui/core";
2480
- import { cn as cn63 } from "@tallyui/theme";
2481
- import { jsx as jsx65, jsxs as jsxs24 } from "react/jsx-runtime";
2660
+ import { cn as cn64 } from "@tallyui/theme";
2661
+ import { jsx as jsx66, jsxs as jsxs25 } from "react/jsx-runtime";
2482
2662
  function ChangeDisplay({ change, locale, className, ...viewProps }) {
2483
- return /* @__PURE__ */ jsxs24(View34, { className: cn63("items-center gap-1 rounded-xl bg-muted p-4", className), ...viewProps, children: [
2484
- /* @__PURE__ */ jsx65(Text19, { className: "text-sm text-muted-foreground", children: "Change Due" }),
2485
- /* @__PURE__ */ jsx65(Text19, { className: "text-3xl font-bold text-success", children: formatMoney4(change, locale) ?? "\u2014" })
2663
+ return /* @__PURE__ */ jsxs25(View35, { className: cn64("items-center gap-1 rounded-xl bg-muted p-4", className), ...viewProps, children: [
2664
+ /* @__PURE__ */ jsx66(Text20, { className: "text-sm text-muted-foreground", children: "Change Due" }),
2665
+ /* @__PURE__ */ jsx66(Text20, { className: "text-3xl font-bold text-success", children: formatMoney4(change, locale) ?? "\u2014" })
2486
2666
  ] });
2487
2667
  }
2488
2668
 
2489
2669
  // src/checkout/cash-tendered.tsx
2490
- import { useEffect, useRef, useState as useState6 } from "react";
2491
- import { Pressable as Pressable16, Text as Text20, TextInput as TextInput7, View as View35 } from "react-native";
2670
+ import { useEffect as useEffect2, useRef as useRef2, useState as useState7 } from "react";
2671
+ import { Pressable as Pressable18, Text as Text21, TextInput as TextInput8, View as View36 } from "react-native";
2492
2672
  import { formatMoney as formatMoney5, minorUnitDigits as minorUnitDigits2, moneyFromDecimalString } from "@tallyui/core";
2493
- import { cn as cn64 } from "@tallyui/theme";
2494
- import { jsx as jsx66, jsxs as jsxs25 } from "react/jsx-runtime";
2673
+ import { cn as cn65 } from "@tallyui/theme";
2674
+ import { jsx as jsx67, jsxs as jsxs26 } from "react/jsx-runtime";
2495
2675
  function defaultQuickAmounts(total) {
2496
2676
  const unit = 10 ** minorUnitDigits2(total.currency);
2497
2677
  const amounts = [
@@ -2512,15 +2692,15 @@ function CashTendered({
2512
2692
  className,
2513
2693
  ...viewProps
2514
2694
  }) {
2515
- const [internalAmount, setInternalAmount] = useState6(defaultAmount ?? total);
2695
+ const [internalAmount, setInternalAmount] = useState7(defaultAmount ?? total);
2516
2696
  const amount = controlledAmount ?? internalAmount;
2517
2697
  const buttons = quickAmounts ?? defaultQuickAmounts(total);
2518
2698
  const digits = minorUnitDigits2(amount.currency);
2519
2699
  const amountText = String(Math.abs(amount.amount)).padStart(digits + 1, "0");
2520
2700
  const decimal2 = (amount.amount < 0 ? "-" : "") + (digits ? `${amountText.slice(0, -digits)}.${amountText.slice(-digits)}` : amountText);
2521
- const [text, setText] = useState6(decimal2);
2522
- const lastTextAmount = useRef(amount);
2523
- useEffect(() => {
2701
+ const [text, setText] = useState7(decimal2);
2702
+ const lastTextAmount = useRef2(amount);
2703
+ useEffect2(() => {
2524
2704
  if (amount.amount !== lastTextAmount.current.amount || amount.currency !== lastTextAmount.current.currency) {
2525
2705
  setText(decimal2);
2526
2706
  lastTextAmount.current = amount;
@@ -2530,20 +2710,20 @@ function CashTendered({
2530
2710
  if (controlledAmount === void 0) setInternalAmount(value);
2531
2711
  onChangeAmount?.(value);
2532
2712
  };
2533
- return /* @__PURE__ */ jsxs25(View35, { className: cn64("gap-3", className), ...viewProps, children: [
2534
- /* @__PURE__ */ jsx66(Text20, { className: "text-sm font-semibold text-foreground", children: "Cash Tendered" }),
2535
- /* @__PURE__ */ jsx66(View35, { className: "flex-row flex-wrap gap-2", children: buttons.map((val) => /* @__PURE__ */ jsx66(
2536
- Pressable16,
2713
+ return /* @__PURE__ */ jsxs26(View36, { className: cn65("gap-3", className), ...viewProps, children: [
2714
+ /* @__PURE__ */ jsx67(Text21, { className: "text-sm font-semibold text-foreground", children: "Cash Tendered" }),
2715
+ /* @__PURE__ */ jsx67(View36, { className: "flex-row flex-wrap gap-2", children: buttons.map((val) => /* @__PURE__ */ jsx67(
2716
+ Pressable18,
2537
2717
  {
2538
2718
  onPress: () => handleChange(val),
2539
- className: cn64(
2719
+ className: cn65(
2540
2720
  "rounded-lg border px-4 py-2",
2541
2721
  amount.amount === val.amount && amount.currency === val.currency ? "border-primary bg-primary" : "border-input bg-card"
2542
2722
  ),
2543
- children: /* @__PURE__ */ jsx66(
2544
- Text20,
2723
+ children: /* @__PURE__ */ jsx67(
2724
+ Text21,
2545
2725
  {
2546
- className: cn64(
2726
+ className: cn65(
2547
2727
  "text-sm font-semibold",
2548
2728
  amount.amount === val.amount && amount.currency === val.currency ? "text-primary-foreground" : "text-foreground"
2549
2729
  ),
@@ -2553,8 +2733,8 @@ function CashTendered({
2553
2733
  },
2554
2734
  `${val.currency}:${val.amount}`
2555
2735
  )) }),
2556
- /* @__PURE__ */ jsx66(
2557
- TextInput7,
2736
+ /* @__PURE__ */ jsx67(
2737
+ TextInput8,
2558
2738
  {
2559
2739
  value: text,
2560
2740
  onChangeText: (text2) => {
@@ -2575,9 +2755,9 @@ function CashTendered({
2575
2755
  }
2576
2756
 
2577
2757
  // src/checkout/receipt-preview.tsx
2578
- import { Text as Text21, View as View36 } from "react-native";
2579
- import { cn as cn65 } from "@tallyui/theme";
2580
- import { jsx as jsx67, jsxs as jsxs26 } from "react/jsx-runtime";
2758
+ import { Text as Text22, View as View37 } from "react-native";
2759
+ import { cn as cn66 } from "@tallyui/theme";
2760
+ import { jsx as jsx68, jsxs as jsxs27 } from "react/jsx-runtime";
2581
2761
  function ReceiptPreview({
2582
2762
  items,
2583
2763
  subtotal,
@@ -2589,42 +2769,42 @@ function ReceiptPreview({
2589
2769
  className,
2590
2770
  ...viewProps
2591
2771
  }) {
2592
- return /* @__PURE__ */ jsxs26(View36, { className: cn65("rounded-lg border border-border bg-card p-4", className), ...viewProps, children: [
2593
- headerSlot && /* @__PURE__ */ jsx67(View36, { className: "mb-3 items-center border-b border-dashed border-border pb-3", children: headerSlot }),
2594
- /* @__PURE__ */ jsx67(View36, { className: "gap-1", children: items.map((item, i) => /* @__PURE__ */ jsxs26(View36, { className: "flex-row justify-between", children: [
2595
- /* @__PURE__ */ jsxs26(Text21, { className: "flex-1 text-sm text-foreground", children: [
2772
+ return /* @__PURE__ */ jsxs27(View37, { className: cn66("rounded-lg border border-border bg-card p-4", className), ...viewProps, children: [
2773
+ headerSlot && /* @__PURE__ */ jsx68(View37, { className: "mb-3 items-center border-b border-dashed border-border pb-3", children: headerSlot }),
2774
+ /* @__PURE__ */ jsx68(View37, { className: "gap-1", children: items.map((item, i) => /* @__PURE__ */ jsxs27(View37, { className: "flex-row justify-between", children: [
2775
+ /* @__PURE__ */ jsxs27(Text22, { className: "flex-1 text-sm text-foreground", children: [
2596
2776
  item.name,
2597
2777
  " x",
2598
2778
  item.quantity
2599
2779
  ] }),
2600
- /* @__PURE__ */ jsx67(Text21, { className: "text-sm text-foreground", children: item.total })
2780
+ /* @__PURE__ */ jsx68(Text22, { className: "text-sm text-foreground", children: item.total })
2601
2781
  ] }, i)) }),
2602
- /* @__PURE__ */ jsxs26(View36, { className: "mt-3 gap-1 border-t border-dashed border-border pt-3", children: [
2603
- /* @__PURE__ */ jsxs26(View36, { className: "flex-row justify-between", children: [
2604
- /* @__PURE__ */ jsx67(Text21, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
2605
- /* @__PURE__ */ jsx67(Text21, { className: "text-sm text-foreground", children: subtotal })
2782
+ /* @__PURE__ */ jsxs27(View37, { className: "mt-3 gap-1 border-t border-dashed border-border pt-3", children: [
2783
+ /* @__PURE__ */ jsxs27(View37, { className: "flex-row justify-between", children: [
2784
+ /* @__PURE__ */ jsx68(Text22, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
2785
+ /* @__PURE__ */ jsx68(Text22, { className: "text-sm text-foreground", children: subtotal })
2606
2786
  ] }),
2607
- /* @__PURE__ */ jsxs26(View36, { className: "flex-row justify-between", children: [
2608
- /* @__PURE__ */ jsx67(Text21, { className: "text-sm text-muted-foreground", children: "Tax" }),
2609
- /* @__PURE__ */ jsx67(Text21, { className: "text-sm text-foreground", children: tax })
2787
+ /* @__PURE__ */ jsxs27(View37, { className: "flex-row justify-between", children: [
2788
+ /* @__PURE__ */ jsx68(Text22, { className: "text-sm text-muted-foreground", children: "Tax" }),
2789
+ /* @__PURE__ */ jsx68(Text22, { className: "text-sm text-foreground", children: tax })
2610
2790
  ] }),
2611
- /* @__PURE__ */ jsxs26(View36, { className: "flex-row justify-between border-t border-border pt-1", children: [
2612
- /* @__PURE__ */ jsx67(Text21, { className: "text-sm font-bold text-foreground", children: "Total" }),
2613
- /* @__PURE__ */ jsx67(Text21, { className: "text-sm font-bold text-foreground", children: total })
2791
+ /* @__PURE__ */ jsxs27(View37, { className: "flex-row justify-between border-t border-border pt-1", children: [
2792
+ /* @__PURE__ */ jsx68(Text22, { className: "text-sm font-bold text-foreground", children: "Total" }),
2793
+ /* @__PURE__ */ jsx68(Text22, { className: "text-sm font-bold text-foreground", children: total })
2614
2794
  ] })
2615
2795
  ] }),
2616
- payments && payments.length > 0 && /* @__PURE__ */ jsx67(View36, { className: "mt-3 gap-1 border-t border-dashed border-border pt-3", children: payments.map((p, i) => /* @__PURE__ */ jsxs26(View36, { className: "flex-row justify-between", children: [
2617
- /* @__PURE__ */ jsx67(Text21, { className: "text-sm text-muted-foreground", children: p.method }),
2618
- /* @__PURE__ */ jsx67(Text21, { className: "text-sm text-foreground", children: p.amount })
2796
+ payments && payments.length > 0 && /* @__PURE__ */ jsx68(View37, { className: "mt-3 gap-1 border-t border-dashed border-border pt-3", children: payments.map((p, i) => /* @__PURE__ */ jsxs27(View37, { className: "flex-row justify-between", children: [
2797
+ /* @__PURE__ */ jsx68(Text22, { className: "text-sm text-muted-foreground", children: p.method }),
2798
+ /* @__PURE__ */ jsx68(Text22, { className: "text-sm text-foreground", children: p.amount })
2619
2799
  ] }, i)) }),
2620
- footerSlot && /* @__PURE__ */ jsx67(View36, { className: "mt-3 items-center border-t border-dashed border-border pt-3", children: footerSlot })
2800
+ footerSlot && /* @__PURE__ */ jsx68(View37, { className: "mt-3 items-center border-t border-dashed border-border pt-3", children: footerSlot })
2621
2801
  ] });
2622
2802
  }
2623
2803
 
2624
2804
  // src/order/order-status-badge.tsx
2625
- import { Text as Text22, View as View37 } from "react-native";
2626
- import { cn as cn66 } from "@tallyui/theme";
2627
- import { jsx as jsx68, jsxs as jsxs27 } from "react/jsx-runtime";
2805
+ import { Text as Text23, View as View38 } from "react-native";
2806
+ import { cn as cn67 } from "@tallyui/theme";
2807
+ import { jsx as jsx69, jsxs as jsxs28 } from "react/jsx-runtime";
2628
2808
  var STATUS_CONFIG = {
2629
2809
  pending: { label: "Pending", badge: "bg-warning/15", dot: "bg-warning", text: "text-foreground" },
2630
2810
  processing: { label: "Processing", badge: "bg-info/15", dot: "bg-info", text: "text-foreground" },
@@ -2634,23 +2814,23 @@ var STATUS_CONFIG = {
2634
2814
  };
2635
2815
  function OrderStatusBadge({ status, className, ...viewProps }) {
2636
2816
  const config = STATUS_CONFIG[status] ?? STATUS_CONFIG.pending;
2637
- return /* @__PURE__ */ jsxs27(
2638
- View37,
2817
+ return /* @__PURE__ */ jsxs28(
2818
+ View38,
2639
2819
  {
2640
- className: cn66("flex-row items-center self-start gap-1.5 rounded-xl px-2 py-1", config.badge, className),
2820
+ className: cn67("flex-row items-center self-start gap-1.5 rounded-xl px-2 py-1", config.badge, className),
2641
2821
  ...viewProps,
2642
2822
  children: [
2643
- /* @__PURE__ */ jsx68(View37, { className: cn66("h-1.5 w-1.5 rounded-full", config.dot) }),
2644
- /* @__PURE__ */ jsx68(Text22, { className: cn66("text-xs font-semibold", config.text), children: config.label })
2823
+ /* @__PURE__ */ jsx69(View38, { className: cn67("h-1.5 w-1.5 rounded-full", config.dot) }),
2824
+ /* @__PURE__ */ jsx69(Text23, { className: cn67("text-xs font-semibold", config.text), children: config.label })
2645
2825
  ]
2646
2826
  }
2647
2827
  );
2648
2828
  }
2649
2829
 
2650
2830
  // src/order/order-card.tsx
2651
- import { Pressable as Pressable17, Text as Text23, View as View38 } from "react-native";
2652
- import { cn as cn67 } from "@tallyui/theme";
2653
- import { jsx as jsx69, jsxs as jsxs28 } from "react/jsx-runtime";
2831
+ import { Pressable as Pressable19, Text as Text24, View as View39 } from "react-native";
2832
+ import { cn as cn68 } from "@tallyui/theme";
2833
+ import { jsx as jsx70, jsxs as jsxs29 } from "react/jsx-runtime";
2654
2834
  function OrderCard({
2655
2835
  orderNumber,
2656
2836
  date,
@@ -2661,24 +2841,24 @@ function OrderCard({
2661
2841
  className,
2662
2842
  ...viewProps
2663
2843
  }) {
2664
- const Wrapper = onPress ? Pressable17 : View38;
2665
- return /* @__PURE__ */ jsxs28(
2844
+ const Wrapper = onPress ? Pressable19 : View39;
2845
+ return /* @__PURE__ */ jsxs29(
2666
2846
  Wrapper,
2667
2847
  {
2668
2848
  onPress,
2669
- className: cn67("gap-2 rounded-lg border border-border bg-card p-3", className),
2849
+ className: cn68("gap-2 rounded-lg border border-border bg-card p-3", className),
2670
2850
  ...viewProps,
2671
2851
  children: [
2672
- /* @__PURE__ */ jsxs28(View38, { className: "flex-row items-center justify-between", children: [
2673
- /* @__PURE__ */ jsx69(Text23, { className: "text-sm font-semibold text-foreground", children: orderNumber }),
2674
- /* @__PURE__ */ jsx69(OrderStatusBadge, { status })
2852
+ /* @__PURE__ */ jsxs29(View39, { className: "flex-row items-center justify-between", children: [
2853
+ /* @__PURE__ */ jsx70(Text24, { className: "text-sm font-semibold text-foreground", children: orderNumber }),
2854
+ /* @__PURE__ */ jsx70(OrderStatusBadge, { status })
2675
2855
  ] }),
2676
- /* @__PURE__ */ jsxs28(View38, { className: "flex-row items-center justify-between", children: [
2677
- /* @__PURE__ */ jsxs28(View38, { className: "gap-0.5", children: [
2678
- /* @__PURE__ */ jsx69(Text23, { className: "text-xs text-muted-foreground", children: date }),
2679
- customerName && /* @__PURE__ */ jsx69(Text23, { className: "text-xs text-muted-foreground", children: customerName })
2856
+ /* @__PURE__ */ jsxs29(View39, { className: "flex-row items-center justify-between", children: [
2857
+ /* @__PURE__ */ jsxs29(View39, { className: "gap-0.5", children: [
2858
+ /* @__PURE__ */ jsx70(Text24, { className: "text-xs text-muted-foreground", children: date }),
2859
+ customerName && /* @__PURE__ */ jsx70(Text24, { className: "text-xs text-muted-foreground", children: customerName })
2680
2860
  ] }),
2681
- /* @__PURE__ */ jsx69(Text23, { className: "text-sm font-semibold text-foreground", children: total })
2861
+ /* @__PURE__ */ jsx70(Text24, { className: "text-sm font-semibold text-foreground", children: total })
2682
2862
  ] })
2683
2863
  ]
2684
2864
  }
@@ -2686,9 +2866,9 @@ function OrderCard({
2686
2866
  }
2687
2867
 
2688
2868
  // src/order/order-list.tsx
2689
- import { ScrollView as ScrollView9, View as View39 } from "react-native";
2690
- import { cn as cn68 } from "@tallyui/theme";
2691
- import { jsx as jsx70, jsxs as jsxs29 } from "react/jsx-runtime";
2869
+ import { ScrollView as ScrollView8, View as View40 } from "react-native";
2870
+ import { cn as cn69 } from "@tallyui/theme";
2871
+ import { jsx as jsx71, jsxs as jsxs30 } from "react/jsx-runtime";
2692
2872
  function OrderList({
2693
2873
  items,
2694
2874
  renderItem,
@@ -2698,16 +2878,16 @@ function OrderList({
2698
2878
  ...viewProps
2699
2879
  }) {
2700
2880
  const hasItems = items.length > 0;
2701
- return /* @__PURE__ */ jsxs29(View39, { className: cn68("flex-1", className), ...viewProps, children: [
2702
- headerSlot && /* @__PURE__ */ jsx70(View39, { className: "px-3 py-2", children: headerSlot }),
2703
- hasItems ? /* @__PURE__ */ jsx70(ScrollView9, { contentContainerClassName: "gap-2 p-3", children: items.map((item, index) => /* @__PURE__ */ jsx70(View39, { children: renderItem(item, index) }, item.id ?? index)) }) : emptyState ?? null
2881
+ return /* @__PURE__ */ jsxs30(View40, { className: cn69("flex-1", className), ...viewProps, children: [
2882
+ headerSlot && /* @__PURE__ */ jsx71(View40, { className: "px-3 py-2", children: headerSlot }),
2883
+ hasItems ? /* @__PURE__ */ jsx71(ScrollView8, { contentContainerClassName: "gap-2 p-3", children: items.map((item, index) => /* @__PURE__ */ jsx71(View40, { children: renderItem(item, index) }, item.id ?? index)) }) : emptyState ?? null
2704
2884
  ] });
2705
2885
  }
2706
2886
 
2707
2887
  // src/order/order-detail.tsx
2708
- import { ScrollView as ScrollView10, Text as Text24, View as View40 } from "react-native";
2709
- import { cn as cn69 } from "@tallyui/theme";
2710
- import { jsx as jsx71, jsxs as jsxs30 } from "react/jsx-runtime";
2888
+ import { ScrollView as ScrollView9, Text as Text25, View as View41 } from "react-native";
2889
+ import { cn as cn70 } from "@tallyui/theme";
2890
+ import { jsx as jsx72, jsxs as jsxs31 } from "react/jsx-runtime";
2711
2891
  function OrderDetail({
2712
2892
  orderNumber,
2713
2893
  status,
@@ -2721,47 +2901,47 @@ function OrderDetail({
2721
2901
  className,
2722
2902
  ...viewProps
2723
2903
  }) {
2724
- return /* @__PURE__ */ jsx71(ScrollView10, { className: cn69("flex-1", className), ...viewProps, children: /* @__PURE__ */ jsxs30(View40, { className: "gap-4 p-4", children: [
2725
- /* @__PURE__ */ jsxs30(View40, { className: "flex-row items-center justify-between", children: [
2726
- /* @__PURE__ */ jsx71(Text24, { className: "text-lg font-bold text-foreground", children: orderNumber }),
2727
- /* @__PURE__ */ jsx71(OrderStatusBadge, { status })
2904
+ return /* @__PURE__ */ jsx72(ScrollView9, { className: cn70("flex-1", className), ...viewProps, children: /* @__PURE__ */ jsxs31(View41, { className: "gap-4 p-4", children: [
2905
+ /* @__PURE__ */ jsxs31(View41, { className: "flex-row items-center justify-between", children: [
2906
+ /* @__PURE__ */ jsx72(Text25, { className: "text-lg font-bold text-foreground", children: orderNumber }),
2907
+ /* @__PURE__ */ jsx72(OrderStatusBadge, { status })
2728
2908
  ] }),
2729
- customerSlot && /* @__PURE__ */ jsx71(View40, { className: "border-b border-border pb-3", children: customerSlot }),
2730
- /* @__PURE__ */ jsxs30(View40, { className: "gap-1", children: [
2731
- /* @__PURE__ */ jsx71(Text24, { className: "text-xs font-semibold text-muted-foreground", children: "Items" }),
2732
- lineItems.map((item, i) => /* @__PURE__ */ jsxs30(View40, { className: "flex-row items-center justify-between py-1", children: [
2733
- /* @__PURE__ */ jsxs30(Text24, { className: "flex-1 text-sm text-foreground", children: [
2909
+ customerSlot && /* @__PURE__ */ jsx72(View41, { className: "border-b border-border pb-3", children: customerSlot }),
2910
+ /* @__PURE__ */ jsxs31(View41, { className: "gap-1", children: [
2911
+ /* @__PURE__ */ jsx72(Text25, { className: "text-xs font-semibold text-muted-foreground", children: "Items" }),
2912
+ lineItems.map((item, i) => /* @__PURE__ */ jsxs31(View41, { className: "flex-row items-center justify-between py-1", children: [
2913
+ /* @__PURE__ */ jsxs31(Text25, { className: "flex-1 text-sm text-foreground", children: [
2734
2914
  item.name,
2735
2915
  " x",
2736
2916
  item.quantity
2737
2917
  ] }),
2738
- /* @__PURE__ */ jsx71(Text24, { className: "text-sm text-foreground", children: item.total })
2918
+ /* @__PURE__ */ jsx72(Text25, { className: "text-sm text-foreground", children: item.total })
2739
2919
  ] }, i))
2740
2920
  ] }),
2741
- /* @__PURE__ */ jsxs30(View40, { className: "gap-1 border-t border-border pt-3", children: [
2742
- /* @__PURE__ */ jsxs30(View40, { className: "flex-row justify-between", children: [
2743
- /* @__PURE__ */ jsx71(Text24, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
2744
- /* @__PURE__ */ jsx71(Text24, { className: "text-sm text-foreground", children: subtotal })
2921
+ /* @__PURE__ */ jsxs31(View41, { className: "gap-1 border-t border-border pt-3", children: [
2922
+ /* @__PURE__ */ jsxs31(View41, { className: "flex-row justify-between", children: [
2923
+ /* @__PURE__ */ jsx72(Text25, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
2924
+ /* @__PURE__ */ jsx72(Text25, { className: "text-sm text-foreground", children: subtotal })
2745
2925
  ] }),
2746
- /* @__PURE__ */ jsxs30(View40, { className: "flex-row justify-between", children: [
2747
- /* @__PURE__ */ jsx71(Text24, { className: "text-sm text-muted-foreground", children: "Tax" }),
2748
- /* @__PURE__ */ jsx71(Text24, { className: "text-sm text-foreground", children: tax })
2926
+ /* @__PURE__ */ jsxs31(View41, { className: "flex-row justify-between", children: [
2927
+ /* @__PURE__ */ jsx72(Text25, { className: "text-sm text-muted-foreground", children: "Tax" }),
2928
+ /* @__PURE__ */ jsx72(Text25, { className: "text-sm text-foreground", children: tax })
2749
2929
  ] }),
2750
- /* @__PURE__ */ jsxs30(View40, { className: "flex-row justify-between pt-1", children: [
2751
- /* @__PURE__ */ jsx71(Text24, { className: "text-sm font-bold text-foreground", children: "Total" }),
2752
- /* @__PURE__ */ jsx71(Text24, { className: "text-sm font-bold text-foreground", children: total })
2930
+ /* @__PURE__ */ jsxs31(View41, { className: "flex-row justify-between pt-1", children: [
2931
+ /* @__PURE__ */ jsx72(Text25, { className: "text-sm font-bold text-foreground", children: "Total" }),
2932
+ /* @__PURE__ */ jsx72(Text25, { className: "text-sm font-bold text-foreground", children: total })
2753
2933
  ] })
2754
2934
  ] }),
2755
- paymentSlot && /* @__PURE__ */ jsx71(View40, { className: "border-t border-border pt-3", children: paymentSlot }),
2756
- footerSlot && /* @__PURE__ */ jsx71(View40, { className: "border-t border-border pt-3", children: footerSlot })
2935
+ paymentSlot && /* @__PURE__ */ jsx72(View41, { className: "border-t border-border pt-3", children: paymentSlot }),
2936
+ footerSlot && /* @__PURE__ */ jsx72(View41, { className: "border-t border-border pt-3", children: footerSlot })
2757
2937
  ] }) });
2758
2938
  }
2759
2939
 
2760
2940
  // src/register/cash-count-input.tsx
2761
- import { useState as useState7 } from "react";
2762
- import { Text as Text25, View as View41 } from "react-native";
2763
- import { cn as cn70 } from "@tallyui/theme";
2764
- import { jsx as jsx72, jsxs as jsxs31 } from "react/jsx-runtime";
2941
+ import { useState as useState8 } from "react";
2942
+ import { Text as Text26, View as View42 } from "react-native";
2943
+ import { cn as cn71 } from "@tallyui/theme";
2944
+ import { jsx as jsx73, jsxs as jsxs32 } from "react/jsx-runtime";
2765
2945
  var DEFAULT_DENOMINATIONS = [
2766
2946
  { label: "$100", value: 100 },
2767
2947
  { label: "$50", value: 50 },
@@ -2783,7 +2963,7 @@ function CashCountInput({
2783
2963
  className,
2784
2964
  ...viewProps
2785
2965
  }) {
2786
- const [internalCounts, setInternalCounts] = useState7(defaultCounts ?? {});
2966
+ const [internalCounts, setInternalCounts] = useState8(defaultCounts ?? {});
2787
2967
  const counts = controlledCounts ?? internalCounts;
2788
2968
  const total = denominations2.reduce(
2789
2969
  (sum, d) => sum + d.value * (counts[d.value] ?? 0),
@@ -2799,10 +2979,10 @@ function CashCountInput({
2799
2979
  );
2800
2980
  onChangeTotal?.(newTotal);
2801
2981
  };
2802
- return /* @__PURE__ */ jsxs31(View41, { className: cn70("gap-2", className), ...viewProps, children: [
2803
- denominations2.map((d) => /* @__PURE__ */ jsxs31(View41, { className: "flex-row items-center justify-between px-3 py-1", children: [
2804
- /* @__PURE__ */ jsx72(Text25, { className: "w-16 text-sm font-medium text-foreground", children: d.label }),
2805
- /* @__PURE__ */ jsx72(
2982
+ return /* @__PURE__ */ jsxs32(View42, { className: cn71("gap-2", className), ...viewProps, children: [
2983
+ denominations2.map((d) => /* @__PURE__ */ jsxs32(View42, { className: "flex-row items-center justify-between px-3 py-1", children: [
2984
+ /* @__PURE__ */ jsx73(Text26, { className: "w-16 text-sm font-medium text-foreground", children: d.label }),
2985
+ /* @__PURE__ */ jsx73(
2806
2986
  QuantityStepper,
2807
2987
  {
2808
2988
  quantity: counts[d.value] ?? 0,
@@ -2810,9 +2990,9 @@ function CashCountInput({
2810
2990
  onChangeQuantity: (qty) => handleCountChange(d.value, qty)
2811
2991
  }
2812
2992
  ),
2813
- /* @__PURE__ */ jsx72(Text25, { className: "w-20 text-right text-sm text-muted-foreground", children: (d.value * (counts[d.value] ?? 0)).toFixed(2) })
2993
+ /* @__PURE__ */ jsx73(Text26, { className: "w-20 text-right text-sm text-muted-foreground", children: (d.value * (counts[d.value] ?? 0)).toFixed(2) })
2814
2994
  ] }, d.value)),
2815
- /* @__PURE__ */ jsx72(View41, { className: "border-t border-border px-3 pt-2", children: /* @__PURE__ */ jsxs31(Text25, { className: "text-right text-base font-bold text-foreground", children: [
2995
+ /* @__PURE__ */ jsx73(View42, { className: "border-t border-border px-3 pt-2", children: /* @__PURE__ */ jsxs32(Text26, { className: "text-right text-base font-bold text-foreground", children: [
2816
2996
  "Total: ",
2817
2997
  total.toFixed(2)
2818
2998
  ] }) })
@@ -2820,9 +3000,9 @@ function CashCountInput({
2820
3000
  }
2821
3001
 
2822
3002
  // src/register/register-summary.tsx
2823
- import { Text as Text26, View as View42 } from "react-native";
2824
- import { cn as cn71 } from "@tallyui/theme";
2825
- import { jsx as jsx73, jsxs as jsxs32 } from "react/jsx-runtime";
3003
+ import { Text as Text27, View as View43 } from "react-native";
3004
+ import { cn as cn72 } from "@tallyui/theme";
3005
+ import { jsx as jsx74, jsxs as jsxs33 } from "react/jsx-runtime";
2826
3006
  function RegisterSummary({
2827
3007
  expectedCash,
2828
3008
  actualCash,
@@ -2833,37 +3013,37 @@ function RegisterSummary({
2833
3013
  ...viewProps
2834
3014
  }) {
2835
3015
  const discrepancy = actualCash - expectedCash;
2836
- return /* @__PURE__ */ jsxs32(View42, { className: cn71("gap-4 rounded-lg border border-border bg-card p-4", className), ...viewProps, children: [
3016
+ return /* @__PURE__ */ jsxs33(View43, { className: cn72("gap-4 rounded-lg border border-border bg-card p-4", className), ...viewProps, children: [
2837
3017
  headerSlot,
2838
- /* @__PURE__ */ jsxs32(View42, { className: "gap-2", children: [
2839
- /* @__PURE__ */ jsx73(Text26, { className: "text-xs font-semibold text-muted-foreground", children: "Cash Drawer" }),
2840
- /* @__PURE__ */ jsxs32(View42, { className: "flex-row justify-between", children: [
2841
- /* @__PURE__ */ jsx73(Text26, { className: "text-sm text-foreground", children: "Expected" }),
2842
- /* @__PURE__ */ jsx73(Text26, { className: "text-sm text-foreground", children: expectedCash.toFixed(2) })
3018
+ /* @__PURE__ */ jsxs33(View43, { className: "gap-2", children: [
3019
+ /* @__PURE__ */ jsx74(Text27, { className: "text-xs font-semibold text-muted-foreground", children: "Cash Drawer" }),
3020
+ /* @__PURE__ */ jsxs33(View43, { className: "flex-row justify-between", children: [
3021
+ /* @__PURE__ */ jsx74(Text27, { className: "text-sm text-foreground", children: "Expected" }),
3022
+ /* @__PURE__ */ jsx74(Text27, { className: "text-sm text-foreground", children: expectedCash.toFixed(2) })
2843
3023
  ] }),
2844
- /* @__PURE__ */ jsxs32(View42, { className: "flex-row justify-between", children: [
2845
- /* @__PURE__ */ jsx73(Text26, { className: "text-sm text-foreground", children: "Actual" }),
2846
- /* @__PURE__ */ jsx73(Text26, { className: "text-sm text-foreground", children: actualCash.toFixed(2) })
3024
+ /* @__PURE__ */ jsxs33(View43, { className: "flex-row justify-between", children: [
3025
+ /* @__PURE__ */ jsx74(Text27, { className: "text-sm text-foreground", children: "Actual" }),
3026
+ /* @__PURE__ */ jsx74(Text27, { className: "text-sm text-foreground", children: actualCash.toFixed(2) })
2847
3027
  ] }),
2848
- /* @__PURE__ */ jsxs32(View42, { className: "flex-row justify-between border-t border-border pt-1", children: [
2849
- /* @__PURE__ */ jsx73(Text26, { className: "text-sm font-semibold text-foreground", children: "Discrepancy" }),
2850
- /* @__PURE__ */ jsxs32(Text26, { className: cn71("text-sm font-semibold", discrepancy === 0 ? "text-success" : "text-destructive"), children: [
3028
+ /* @__PURE__ */ jsxs33(View43, { className: "flex-row justify-between border-t border-border pt-1", children: [
3029
+ /* @__PURE__ */ jsx74(Text27, { className: "text-sm font-semibold text-foreground", children: "Discrepancy" }),
3030
+ /* @__PURE__ */ jsxs33(Text27, { className: cn72("text-sm font-semibold", discrepancy === 0 ? "text-success" : "text-destructive"), children: [
2851
3031
  discrepancy >= 0 ? "" : "-",
2852
3032
  Math.abs(discrepancy).toFixed(2)
2853
3033
  ] })
2854
3034
  ] })
2855
3035
  ] }),
2856
- transactions.length > 0 && /* @__PURE__ */ jsxs32(View42, { className: "gap-2", children: [
2857
- /* @__PURE__ */ jsx73(Text26, { className: "text-xs font-semibold text-muted-foreground", children: "Transactions" }),
2858
- transactions.map((t) => /* @__PURE__ */ jsxs32(View42, { className: "flex-row items-center justify-between", children: [
2859
- /* @__PURE__ */ jsxs32(View42, { className: "gap-0.5", children: [
2860
- /* @__PURE__ */ jsx73(Text26, { className: "text-sm text-foreground", children: t.method }),
2861
- /* @__PURE__ */ jsxs32(Text26, { className: "text-xs text-muted-foreground", children: [
3036
+ transactions.length > 0 && /* @__PURE__ */ jsxs33(View43, { className: "gap-2", children: [
3037
+ /* @__PURE__ */ jsx74(Text27, { className: "text-xs font-semibold text-muted-foreground", children: "Transactions" }),
3038
+ transactions.map((t) => /* @__PURE__ */ jsxs33(View43, { className: "flex-row items-center justify-between", children: [
3039
+ /* @__PURE__ */ jsxs33(View43, { className: "gap-0.5", children: [
3040
+ /* @__PURE__ */ jsx74(Text27, { className: "text-sm text-foreground", children: t.method }),
3041
+ /* @__PURE__ */ jsxs33(Text27, { className: "text-xs text-muted-foreground", children: [
2862
3042
  t.count,
2863
3043
  " transactions"
2864
3044
  ] })
2865
3045
  ] }),
2866
- /* @__PURE__ */ jsx73(Text26, { className: "text-sm font-semibold text-foreground", children: t.total.toFixed(2) })
3046
+ /* @__PURE__ */ jsx74(Text27, { className: "text-sm font-semibold text-foreground", children: t.total.toFixed(2) })
2867
3047
  ] }, t.method))
2868
3048
  ] }),
2869
3049
  footerSlot
@@ -2871,9 +3051,9 @@ function RegisterSummary({
2871
3051
  }
2872
3052
 
2873
3053
  // src/register/register-open-close.tsx
2874
- import { Pressable as Pressable18, Text as Text27, View as View43 } from "react-native";
2875
- import { cn as cn72 } from "@tallyui/theme";
2876
- import { jsx as jsx74, jsxs as jsxs33 } from "react/jsx-runtime";
3054
+ import { Pressable as Pressable20, Text as Text28, View as View44 } from "react-native";
3055
+ import { cn as cn73 } from "@tallyui/theme";
3056
+ import { jsx as jsx75, jsxs as jsxs34 } from "react/jsx-runtime";
2877
3057
  function RegisterOpenClose({
2878
3058
  isOpen,
2879
3059
  onOpen,
@@ -2884,67 +3064,67 @@ function RegisterOpenClose({
2884
3064
  className,
2885
3065
  ...viewProps
2886
3066
  }) {
2887
- return /* @__PURE__ */ jsxs33(View43, { className: cn72("gap-4 p-4", className), ...viewProps, children: [
2888
- /* @__PURE__ */ jsx74(Text27, { className: "text-lg font-bold text-foreground", children: isOpen ? "Close Register" : "Open Register" }),
2889
- isOpen && expectedBalance != null && /* @__PURE__ */ jsxs33(View43, { className: "flex-row justify-between rounded-lg bg-muted px-3 py-2", children: [
2890
- /* @__PURE__ */ jsx74(Text27, { className: "text-sm text-muted-foreground", children: "Expected Balance" }),
2891
- /* @__PURE__ */ jsx74(Text27, { className: "text-sm font-semibold text-foreground", children: expectedBalance.toFixed(2) })
3067
+ return /* @__PURE__ */ jsxs34(View44, { className: cn73("gap-4 p-4", className), ...viewProps, children: [
3068
+ /* @__PURE__ */ jsx75(Text28, { className: "text-lg font-bold text-foreground", children: isOpen ? "Close Register" : "Open Register" }),
3069
+ isOpen && expectedBalance != null && /* @__PURE__ */ jsxs34(View44, { className: "flex-row justify-between rounded-lg bg-muted px-3 py-2", children: [
3070
+ /* @__PURE__ */ jsx75(Text28, { className: "text-sm text-muted-foreground", children: "Expected Balance" }),
3071
+ /* @__PURE__ */ jsx75(Text28, { className: "text-sm font-semibold text-foreground", children: expectedBalance.toFixed(2) })
2892
3072
  ] }),
2893
- cashCountSlot && /* @__PURE__ */ jsx74(View43, { children: cashCountSlot }),
2894
- notesSlot && /* @__PURE__ */ jsx74(View43, { children: notesSlot }),
2895
- /* @__PURE__ */ jsx74(
2896
- Pressable18,
3073
+ cashCountSlot && /* @__PURE__ */ jsx75(View44, { children: cashCountSlot }),
3074
+ notesSlot && /* @__PURE__ */ jsx75(View44, { children: notesSlot }),
3075
+ /* @__PURE__ */ jsx75(
3076
+ Pressable20,
2897
3077
  {
2898
3078
  onPress: isOpen ? onClose : onOpen,
2899
3079
  className: "items-center rounded-lg bg-primary px-4 py-3",
2900
- children: /* @__PURE__ */ jsx74(Text27, { className: "text-sm font-semibold text-primary-foreground", children: isOpen ? "Close Register" : "Open Register" })
3080
+ children: /* @__PURE__ */ jsx75(Text28, { className: "text-sm font-semibold text-primary-foreground", children: isOpen ? "Close Register" : "Open Register" })
2901
3081
  }
2902
3082
  )
2903
3083
  ] });
2904
3084
  }
2905
3085
 
2906
3086
  // src/register/register-picker.tsx
2907
- import { ScrollView as ScrollView11 } from "react-native";
2908
- import { jsx as jsx75, jsxs as jsxs34 } from "react/jsx-runtime";
3087
+ import { ScrollView as ScrollView10 } from "react-native";
3088
+ import { jsx as jsx76, jsxs as jsxs35 } from "react/jsx-runtime";
2909
3089
  function RegisterPicker({ registers, onPick, className }) {
2910
- return /* @__PURE__ */ jsxs34(Card, { testID: "register-picker", className, children: [
2911
- /* @__PURE__ */ jsx75(CardHeader, { children: /* @__PURE__ */ jsx75(CardTitle, { children: "Choose a register" }) }),
2912
- /* @__PURE__ */ jsx75(CardContent, { children: /* @__PURE__ */ jsxs34(ScrollView11, { children: [
2913
- registers.map((register) => /* @__PURE__ */ jsx75(
3090
+ return /* @__PURE__ */ jsxs35(Card, { testID: "register-picker", className, children: [
3091
+ /* @__PURE__ */ jsx76(CardHeader, { children: /* @__PURE__ */ jsx76(CardTitle, { children: "Choose a register" }) }),
3092
+ /* @__PURE__ */ jsx76(CardContent, { children: /* @__PURE__ */ jsxs35(ScrollView10, { children: [
3093
+ registers.map((register) => /* @__PURE__ */ jsx76(
2914
3094
  Button,
2915
3095
  {
2916
3096
  testID: `register-picker-row-${register.id}`,
2917
3097
  variant: "ghost",
2918
3098
  className: "h-auto min-h-11 items-start justify-start py-2",
2919
3099
  onPress: () => onPick(register.id),
2920
- children: /* @__PURE__ */ jsxs34(VStack, { space: "none", children: [
2921
- /* @__PURE__ */ jsx75(Text, { numberOfLines: 1, children: register.name }),
2922
- /* @__PURE__ */ jsx75(Text, { testID: `register-picker-row-${register.id}-status`, className: "text-muted-foreground text-sm", children: "Not opened" })
3100
+ children: /* @__PURE__ */ jsxs35(VStack, { space: "none", children: [
3101
+ /* @__PURE__ */ jsx76(Text, { numberOfLines: 1, children: register.name }),
3102
+ /* @__PURE__ */ jsx76(Text, { testID: `register-picker-row-${register.id}-status`, className: "text-muted-foreground text-sm", children: "Not opened" })
2923
3103
  ] })
2924
3104
  },
2925
3105
  register.id
2926
3106
  )),
2927
- registers.length === 0 && /* @__PURE__ */ jsx75(Text, { testID: "register-picker-empty", className: "text-muted-foreground p-4", children: "No registers are set up for this store yet." })
3107
+ registers.length === 0 && /* @__PURE__ */ jsx76(Text, { testID: "register-picker-empty", className: "text-muted-foreground p-4", children: "No registers are set up for this store yet." })
2928
3108
  ] }) })
2929
3109
  ] });
2930
3110
  }
2931
3111
 
2932
3112
  // src/register/open-register-card.tsx
2933
- import { useState as useState8 } from "react";
2934
- import { View as View44 } from "react-native";
3113
+ import { useState as useState9 } from "react";
3114
+ import { View as View45 } from "react-native";
2935
3115
  import { parseMinor, validAmount } from "@tallyui/pos";
2936
3116
  import { currencySymbol, formatMoney as formatMoney6, minorUnitDigits as minorUnitDigits3 } from "@tallyui/core";
2937
- import { cn as cn73 } from "@tallyui/theme";
2938
- import { jsx as jsx76, jsxs as jsxs35 } from "react/jsx-runtime";
3117
+ import { cn as cn74 } from "@tallyui/theme";
3118
+ import { jsx as jsx77, jsxs as jsxs36 } from "react/jsx-runtime";
2939
3119
  var AMOUNT_LABEL_ID = "open-register-amount-label";
2940
3120
  function OpenRegisterCard({ register, currency, configuredFloatMinor, className }) {
2941
3121
  const digits = minorUnitDigits3(currency);
2942
3122
  const lastCountedMinor = register.lastClosure?.counted?.cash ?? null;
2943
3123
  const expectedFloatMinor = configuredFloatMinor ?? lastCountedMinor ?? null;
2944
- const [enteredAmount, setEnteredAmount] = useState8(null);
3124
+ const [enteredAmount, setEnteredAmount] = useState9(null);
2945
3125
  const amount = enteredAmount ?? (expectedFloatMinor != null ? decimal(expectedFloatMinor, digits) : "");
2946
- const [busy, setBusy] = useState8(false);
2947
- const [error, setError] = useState8("");
3126
+ const [busy, setBusy] = useState9(false);
3127
+ const [error, setError] = useState9("");
2948
3128
  const valid = validAmount(amount, digits);
2949
3129
  const countedMinor = valid ? parseMinor(amount, digits) : NaN;
2950
3130
  const open = async () => {
@@ -2960,10 +3140,10 @@ function OpenRegisterCard({ register, currency, configuredFloatMinor, className
2960
3140
  }
2961
3141
  };
2962
3142
  const amountLabel = `Cash in the drawer to start (${currencySymbol(currency)})`;
2963
- return /* @__PURE__ */ jsxs35(View44, { testID: "open-register-card", className: cn73("bg-card gap-3 rounded-md p-4", className), children: [
2964
- /* @__PURE__ */ jsx76(Text, { className: "text-lg font-semibold", children: "Open register" }),
2965
- /* @__PURE__ */ jsx76(Label, { testID: "open-register-amount-label", nativeID: AMOUNT_LABEL_ID, children: amountLabel }),
2966
- /* @__PURE__ */ jsx76(Input, { children: /* @__PURE__ */ jsx76(
3143
+ return /* @__PURE__ */ jsxs36(View45, { testID: "open-register-card", className: cn74("bg-card gap-3 rounded-md p-4", className), children: [
3144
+ /* @__PURE__ */ jsx77(Text, { className: "text-lg font-semibold", children: "Open register" }),
3145
+ /* @__PURE__ */ jsx77(Label, { testID: "open-register-amount-label", nativeID: AMOUNT_LABEL_ID, children: amountLabel }),
3146
+ /* @__PURE__ */ jsx77(Input, { children: /* @__PURE__ */ jsx77(
2967
3147
  Input.Field,
2968
3148
  {
2969
3149
  testID: "open-register-amount",
@@ -2974,40 +3154,40 @@ function OpenRegisterCard({ register, currency, configuredFloatMinor, className
2974
3154
  accessibilityLabelledBy: AMOUNT_LABEL_ID
2975
3155
  }
2976
3156
  ) }),
2977
- configuredFloatMinor != null && /* @__PURE__ */ jsx76(
3157
+ configuredFloatMinor != null && /* @__PURE__ */ jsx77(
2978
3158
  Button,
2979
3159
  {
2980
3160
  testID: "open-register-chip-configured",
2981
3161
  variant: "outline",
2982
3162
  className: "min-h-11",
2983
3163
  onPress: () => setEnteredAmount(decimal(configuredFloatMinor, digits)),
2984
- children: /* @__PURE__ */ jsxs35(Text, { children: [
3164
+ children: /* @__PURE__ */ jsxs36(Text, { children: [
2985
3165
  "Use the configured float (",
2986
3166
  formatMoney6({ amount: configuredFloatMinor, currency }),
2987
3167
  ")"
2988
3168
  ] })
2989
3169
  }
2990
3170
  ),
2991
- lastCountedMinor != null && /* @__PURE__ */ jsx76(
3171
+ lastCountedMinor != null && /* @__PURE__ */ jsx77(
2992
3172
  Button,
2993
3173
  {
2994
3174
  testID: "open-register-chip-last",
2995
3175
  variant: "outline",
2996
3176
  className: "min-h-11",
2997
3177
  onPress: () => setEnteredAmount(decimal(lastCountedMinor, digits)),
2998
- children: /* @__PURE__ */ jsxs35(Text, { children: [
3178
+ children: /* @__PURE__ */ jsxs36(Text, { children: [
2999
3179
  "Use the last counted cash (",
3000
3180
  formatMoney6({ amount: lastCountedMinor, currency }),
3001
3181
  ")"
3002
3182
  ] })
3003
3183
  }
3004
3184
  ),
3005
- expectedFloatMinor !== null && valid && countedMinor !== expectedFloatMinor && /* @__PURE__ */ jsxs35(Text, { testID: "opening-variance", children: [
3185
+ expectedFloatMinor !== null && valid && countedMinor !== expectedFloatMinor && /* @__PURE__ */ jsxs36(Text, { testID: "opening-variance", children: [
3006
3186
  formatMoney6({ amount: countedMinor - expectedFloatMinor, currency }),
3007
3187
  " vs the expected float"
3008
3188
  ] }),
3009
- !!error && /* @__PURE__ */ jsx76(Text, { className: "text-destructive", children: error }),
3010
- /* @__PURE__ */ jsx76(Button, { testID: "open-register-button", className: "min-h-14", disabled: busy || !valid, onPress: open, children: /* @__PURE__ */ jsx76(Text, { children: busy ? "Opening\u2026" : "Open register" }) })
3189
+ !!error && /* @__PURE__ */ jsx77(Text, { className: "text-destructive", children: error }),
3190
+ /* @__PURE__ */ jsx77(Button, { testID: "open-register-button", className: "min-h-14", disabled: busy || !valid, onPress: open, children: /* @__PURE__ */ jsx77(Text, { children: busy ? "Opening\u2026" : "Open register" }) })
3011
3191
  ] });
3012
3192
  }
3013
3193
  function decimal(minor, digits) {
@@ -3016,8 +3196,8 @@ function decimal(minor, digits) {
3016
3196
  }
3017
3197
 
3018
3198
  // src/register/register-bar.tsx
3019
- import { Pressable as Pressable19, View as View45 } from "react-native";
3020
- import { cn as cn74 } from "@tallyui/theme";
3199
+ import { Pressable as Pressable21, View as View46 } from "react-native";
3200
+ import { cn as cn75 } from "@tallyui/theme";
3021
3201
 
3022
3202
  // src/register/register-bar.helpers.ts
3023
3203
  function describeRegisterBarPill({
@@ -3040,7 +3220,7 @@ function describeRegisterBarPill({
3040
3220
  }
3041
3221
 
3042
3222
  // src/register/register-bar.tsx
3043
- import { jsx as jsx77, jsxs as jsxs36 } from "react/jsx-runtime";
3223
+ import { jsx as jsx78, jsxs as jsxs37 } from "react/jsx-runtime";
3044
3224
  function RegisterBar({
3045
3225
  register,
3046
3226
  registerId,
@@ -3061,10 +3241,10 @@ function RegisterBar({
3061
3241
  sessionsOn: enabled,
3062
3242
  closing
3063
3243
  });
3064
- return /* @__PURE__ */ jsxs36(HStack, { testID: "register-bar", className: cn74("bg-card border-border h-12 border-b px-3", className), children: [
3065
- /* @__PURE__ */ jsx77(View45, { className: "min-w-0 flex-1 shrink", children: multiRegister && registerId !== null && /* @__PURE__ */ jsx77(Text, { testID: "register-bar-name", numberOfLines: 1, children: registerName }) }),
3066
- pill && (onPressPill ? /* @__PURE__ */ jsx77(Pressable19, { testID: "register-bar-pill", accessibilityRole: "button", accessibilityLabel: pill, onPress: onPressPill, children: /* @__PURE__ */ jsx77(Badge, { label: pill, variant: "warning" }) }) : /* @__PURE__ */ jsx77(Badge, { testID: "register-bar-pill", label: pill, variant: "warning" })),
3067
- (session || lastClosure) && /* @__PURE__ */ jsx77(
3244
+ return /* @__PURE__ */ jsxs37(HStack, { testID: "register-bar", className: cn75("bg-card border-border h-12 border-b px-3", className), children: [
3245
+ /* @__PURE__ */ jsx78(View46, { className: "min-w-0 flex-1 shrink", children: multiRegister && registerId !== null && /* @__PURE__ */ jsx78(Text, { testID: "register-bar-name", numberOfLines: 1, children: registerName }) }),
3246
+ pill && (onPressPill ? /* @__PURE__ */ jsx78(Pressable21, { testID: "register-bar-pill", accessibilityRole: "button", accessibilityLabel: pill, onPress: onPressPill, children: /* @__PURE__ */ jsx78(Badge, { label: pill, variant: "warning" }) }) : /* @__PURE__ */ jsx78(Badge, { testID: "register-bar-pill", label: pill, variant: "warning" })),
3247
+ (session || lastClosure) && /* @__PURE__ */ jsx78(
3068
3248
  Button,
3069
3249
  {
3070
3250
  variant: "ghost",
@@ -3072,17 +3252,17 @@ function RegisterBar({
3072
3252
  testID: "register-bar-open-panel",
3073
3253
  accessibilityLabel: "Open register panel",
3074
3254
  onPress: onOpenPanel,
3075
- children: /* @__PURE__ */ jsx77(Text, { className: overdue ? "text-warning" : void 0, children: "Register \u203A" })
3255
+ children: /* @__PURE__ */ jsx78(Text, { className: overdue ? "text-warning" : void 0, children: "Register \u203A" })
3076
3256
  }
3077
3257
  )
3078
3258
  ] });
3079
3259
  }
3080
3260
 
3081
3261
  // src/register/movement-sheet.tsx
3082
- import { useRef as useRef2, useState as useState9 } from "react";
3262
+ import { useRef as useRef3, useState as useState10 } from "react";
3083
3263
  import { movementFieldError, normalizeAmount, parseMinor as parseMinor2 } from "@tallyui/pos";
3084
3264
  import { currencySymbol as currencySymbol2, minorUnitDigits as minorUnitDigits4 } from "@tallyui/core";
3085
- import { Fragment as Fragment2, jsx as jsx78, jsxs as jsxs37 } from "react/jsx-runtime";
3265
+ import { Fragment as Fragment2, jsx as jsx79, jsxs as jsxs38 } from "react/jsx-runtime";
3086
3266
  var LABELS = {
3087
3267
  paid_in: "Paid in",
3088
3268
  paid_out: "Paid out",
@@ -3092,11 +3272,11 @@ var AMOUNT_LABEL_ID2 = "movement-amount-label";
3092
3272
  var REASON_LABEL_ID = "movement-reason-label";
3093
3273
  function MovementSheet({ register, type, currency, onDone, onOpenChange, onOpenDrawer }) {
3094
3274
  const digits = minorUnitDigits4(currency);
3095
- const [amount, setAmount] = useState9("");
3096
- const [reason, setReason] = useState9("");
3097
- const [busy, setBusy] = useState9(false);
3098
- const busyRef = useRef2(false);
3099
- const [error, setError] = useState9("");
3275
+ const [amount, setAmount] = useState10("");
3276
+ const [reason, setReason] = useState10("");
3277
+ const [busy, setBusy] = useState10(false);
3278
+ const busyRef = useRef3(false);
3279
+ const [error, setError] = useState10("");
3100
3280
  const invalid = movementFieldError({ type, amount, reason });
3101
3281
  const confirm = async () => {
3102
3282
  if (invalid || busyRef.current) return;
@@ -3118,11 +3298,11 @@ function MovementSheet({ register, type, currency, onDone, onOpenChange, onOpenD
3118
3298
  setBusy(false);
3119
3299
  }
3120
3300
  };
3121
- return /* @__PURE__ */ jsx78(Dialog, { open: true, onOpenChange, children: /* @__PURE__ */ jsxs37(DialogContent, { testID: "movement-sheet", children: [
3122
- /* @__PURE__ */ jsx78(DialogTitle, { children: LABELS[type] }),
3123
- type !== "no_sale" && /* @__PURE__ */ jsxs37(Fragment2, { children: [
3124
- /* @__PURE__ */ jsx78(Label, { testID: "movement-amount-label", nativeID: AMOUNT_LABEL_ID2, children: `Amount (${currencySymbol2(currency)})` }),
3125
- /* @__PURE__ */ jsx78(Input, { children: /* @__PURE__ */ jsx78(
3301
+ return /* @__PURE__ */ jsx79(Dialog, { open: true, onOpenChange, children: /* @__PURE__ */ jsxs38(DialogContent, { testID: "movement-sheet", children: [
3302
+ /* @__PURE__ */ jsx79(DialogTitle, { children: LABELS[type] }),
3303
+ type !== "no_sale" && /* @__PURE__ */ jsxs38(Fragment2, { children: [
3304
+ /* @__PURE__ */ jsx79(Label, { testID: "movement-amount-label", nativeID: AMOUNT_LABEL_ID2, children: `Amount (${currencySymbol2(currency)})` }),
3305
+ /* @__PURE__ */ jsx79(Input, { children: /* @__PURE__ */ jsx79(
3126
3306
  Input.Field,
3127
3307
  {
3128
3308
  testID: "movement-amount",
@@ -3134,8 +3314,8 @@ function MovementSheet({ register, type, currency, onDone, onOpenChange, onOpenD
3134
3314
  }
3135
3315
  ) })
3136
3316
  ] }),
3137
- /* @__PURE__ */ jsx78(Label, { testID: "movement-reason-label", nativeID: REASON_LABEL_ID, children: "Reason" }),
3138
- /* @__PURE__ */ jsx78(Input, { children: /* @__PURE__ */ jsx78(
3317
+ /* @__PURE__ */ jsx79(Label, { testID: "movement-reason-label", nativeID: REASON_LABEL_ID, children: "Reason" }),
3318
+ /* @__PURE__ */ jsx79(Input, { children: /* @__PURE__ */ jsx79(
3139
3319
  Input.Field,
3140
3320
  {
3141
3321
  testID: "movement-reason",
@@ -3146,25 +3326,25 @@ function MovementSheet({ register, type, currency, onDone, onOpenChange, onOpenD
3146
3326
  accessibilityLabelledBy: REASON_LABEL_ID
3147
3327
  }
3148
3328
  ) }),
3149
- !!error && /* @__PURE__ */ jsx78(Text, { className: "text-destructive", children: error }),
3150
- !!invalid && /* @__PURE__ */ jsx78(Text, { testID: "movement-invalid", className: "text-muted-foreground", children: invalid === "amount" ? "Enter a valid amount." : "Enter a reason." }),
3151
- /* @__PURE__ */ jsx78(Button, { testID: "movement-confirm", disabled: !!invalid || busy, onPress: confirm, children: /* @__PURE__ */ jsx78(Text, { children: busy ? "Recording\u2026" : "Record" }) })
3329
+ !!error && /* @__PURE__ */ jsx79(Text, { className: "text-destructive", children: error }),
3330
+ !!invalid && /* @__PURE__ */ jsx79(Text, { testID: "movement-invalid", className: "text-muted-foreground", children: invalid === "amount" ? "Enter a valid amount." : "Enter a reason." }),
3331
+ /* @__PURE__ */ jsx79(Button, { testID: "movement-confirm", disabled: !!invalid || busy, onPress: confirm, children: /* @__PURE__ */ jsx79(Text, { children: busy ? "Recording\u2026" : "Record" }) })
3152
3332
  ] }) });
3153
3333
  }
3154
3334
 
3155
3335
  // src/register/register-panel.tsx
3156
- import { useState as useState10 } from "react";
3157
- import { ScrollView as ScrollView12, useWindowDimensions, View as View46 } from "react-native";
3336
+ import { useState as useState11 } from "react";
3337
+ import { ScrollView as ScrollView11, useWindowDimensions, View as View47 } from "react-native";
3158
3338
  import { formatMoney as formatMoney7 } from "@tallyui/core";
3159
- import { jsx as jsx79, jsxs as jsxs38 } from "react/jsx-runtime";
3339
+ import { jsx as jsx80, jsxs as jsxs39 } from "react/jsx-runtime";
3160
3340
  var DIALOG_VERTICAL_MARGIN = 64;
3161
3341
  function RegisterPanel({ register, currency, registerName, open, onOpenChange, className }) {
3162
3342
  const { session, expected, salesCount, blind, movements, lastClosure, actions } = register;
3163
3343
  const { height: windowHeight } = useWindowDimensions();
3164
3344
  const maxHeight = Math.max(280, windowHeight - DIALOG_VERTICAL_MARGIN);
3165
- const [movementType, setMovementType] = useState10(null);
3166
- const [expanded, setExpanded] = useState10(false);
3167
- const [error, setError] = useState10("");
3345
+ const [movementType, setMovementType] = useState11(null);
3346
+ const [expanded, setExpanded] = useState11(false);
3347
+ const [error, setError] = useState11("");
3168
3348
  const attempt = async (action) => {
3169
3349
  try {
3170
3350
  await action();
@@ -3176,22 +3356,22 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
3176
3356
  const activeMovements = movements.filter(
3177
3357
  (row) => row.type !== "void" && !row.voided_by && !movements.some((entry) => entry.voids === row.id)
3178
3358
  );
3179
- return /* @__PURE__ */ jsx79(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs38(
3359
+ return /* @__PURE__ */ jsx80(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs39(
3180
3360
  DialogContent,
3181
3361
  {
3182
3362
  testID: "register-panel",
3183
3363
  className: `flex-col overflow-hidden ${className ?? ""}`,
3184
3364
  style: { maxHeight },
3185
3365
  children: [
3186
- /* @__PURE__ */ jsx79(DialogTitle, { testID: "register-panel-amount", children: registerName ?? "Register" }),
3187
- /* @__PURE__ */ jsxs38(Text, { testID: "register-panel-sales-count", children: [
3366
+ /* @__PURE__ */ jsx80(DialogTitle, { testID: "register-panel-amount", children: registerName ?? "Register" }),
3367
+ /* @__PURE__ */ jsxs39(Text, { testID: "register-panel-sales-count", children: [
3188
3368
  salesCount,
3189
3369
  " sale",
3190
3370
  salesCount === 1 ? "" : "s",
3191
3371
  " this session"
3192
3372
  ] }),
3193
- /* @__PURE__ */ jsxs38(ScrollView12, { testID: "register-panel-body", className: "flex-1", contentContainerClassName: "gap-3", children: [
3194
- /* @__PURE__ */ jsx79(View46, { className: "flex-row gap-2", children: ["paid_in", "paid_out", "no_sale"].map((type) => /* @__PURE__ */ jsx79(
3373
+ /* @__PURE__ */ jsxs39(ScrollView11, { testID: "register-panel-body", className: "flex-1", contentContainerClassName: "gap-3", children: [
3374
+ /* @__PURE__ */ jsx80(View47, { className: "flex-row gap-2", children: ["paid_in", "paid_out", "no_sale"].map((type) => /* @__PURE__ */ jsx80(
3195
3375
  Button,
3196
3376
  {
3197
3377
  testID: `register-panel-${type.replace("_", "-")}`,
@@ -3199,33 +3379,33 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
3199
3379
  variant: "outline",
3200
3380
  disabled: session?.status !== "open",
3201
3381
  onPress: () => setMovementType(type),
3202
- children: /* @__PURE__ */ jsx79(Text, { children: type === "paid_in" ? "Paid in" : type === "paid_out" ? "Paid out" : "No sale" })
3382
+ children: /* @__PURE__ */ jsx80(Text, { children: type === "paid_in" ? "Paid in" : type === "paid_out" ? "Paid out" : "No sale" })
3203
3383
  },
3204
3384
  type
3205
3385
  )) }),
3206
- !blind && /* @__PURE__ */ jsxs38(View46, { testID: "register-panel-expected", className: "gap-1", children: [
3207
- /* @__PURE__ */ jsx79(Text, { className: "text-muted-foreground text-sm font-semibold", children: "Expected in the drawer" }),
3208
- Object.entries(expected).map(([method, amount]) => /* @__PURE__ */ jsxs38(View46, { className: "min-h-11 flex-row items-center justify-between", children: [
3209
- /* @__PURE__ */ jsx79(Text, { className: "capitalize", children: method === "cash" ? "Cash" : method }),
3210
- /* @__PURE__ */ jsx79(Text, { className: "tabular-nums", children: formatMoney7({ amount, currency }) })
3386
+ !blind && /* @__PURE__ */ jsxs39(View47, { testID: "register-panel-expected", className: "gap-1", children: [
3387
+ /* @__PURE__ */ jsx80(Text, { className: "text-muted-foreground text-sm font-semibold", children: "Expected in the drawer" }),
3388
+ Object.entries(expected).map(([method, amount]) => /* @__PURE__ */ jsxs39(View47, { className: "min-h-11 flex-row items-center justify-between", children: [
3389
+ /* @__PURE__ */ jsx80(Text, { className: "capitalize", children: method === "cash" ? "Cash" : method }),
3390
+ /* @__PURE__ */ jsx80(Text, { className: "tabular-nums", children: formatMoney7({ amount, currency }) })
3211
3391
  ] }, method))
3212
3392
  ] }),
3213
- /* @__PURE__ */ jsx79(
3393
+ /* @__PURE__ */ jsx80(
3214
3394
  Button,
3215
3395
  {
3216
3396
  testID: "register-panel-movements",
3217
3397
  variant: "ghost",
3218
3398
  className: "min-h-11",
3219
3399
  onPress: () => setExpanded(!expanded),
3220
- children: /* @__PURE__ */ jsx79(Text, { children: "Paid in / out" })
3400
+ children: /* @__PURE__ */ jsx80(Text, { children: "Paid in / out" })
3221
3401
  }
3222
3402
  ),
3223
- expanded && activeMovements.map((row) => /* @__PURE__ */ jsxs38(View46, { className: "min-h-11 flex-row items-center gap-2", children: [
3224
- /* @__PURE__ */ jsxs38(Text, { testID: `movement-row-${row.id}`, className: "flex-1", children: [
3403
+ expanded && activeMovements.map((row) => /* @__PURE__ */ jsxs39(View47, { className: "min-h-11 flex-row items-center gap-2", children: [
3404
+ /* @__PURE__ */ jsxs39(Text, { testID: `movement-row-${row.id}`, className: "flex-1", children: [
3225
3405
  row.type === "paid_in" ? "Paid in" : row.type === "paid_out" ? "Paid out" : "No sale",
3226
3406
  !blind ? ` \xB7 ${formatMoney7({ amount: row.amountMinor, currency })} \xB7 ${row.reason}` : ""
3227
3407
  ] }),
3228
- /* @__PURE__ */ jsx79(
3408
+ /* @__PURE__ */ jsx80(
3229
3409
  Button,
3230
3410
  {
3231
3411
  variant: "ghost",
@@ -3233,12 +3413,12 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
3233
3413
  testID: `movement-void-${row.id}`,
3234
3414
  disabled: session?.status !== "open",
3235
3415
  onPress: () => attempt(() => actions.voidMovement(row.id)),
3236
- children: /* @__PURE__ */ jsx79(Text, { children: "Undo" })
3416
+ children: /* @__PURE__ */ jsx80(Text, { children: "Undo" })
3237
3417
  }
3238
3418
  )
3239
3419
  ] }, row.id)),
3240
- !!error && /* @__PURE__ */ jsx79(Text, { className: "text-destructive", children: error }),
3241
- /* @__PURE__ */ jsx79(
3420
+ !!error && /* @__PURE__ */ jsx80(Text, { className: "text-destructive", children: error }),
3421
+ /* @__PURE__ */ jsx80(
3242
3422
  Button,
3243
3423
  {
3244
3424
  testID: "register-panel-close",
@@ -3249,11 +3429,11 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
3249
3429
  await actions.startCounting();
3250
3430
  onOpenChange(false);
3251
3431
  }),
3252
- children: /* @__PURE__ */ jsx79(Text, { children: "Close register" })
3432
+ children: /* @__PURE__ */ jsx80(Text, { children: "Close register" })
3253
3433
  }
3254
3434
  )
3255
3435
  ] }),
3256
- movementType && /* @__PURE__ */ jsx79(
3436
+ movementType && /* @__PURE__ */ jsx80(
3257
3437
  MovementSheet,
3258
3438
  {
3259
3439
  register,
@@ -3271,9 +3451,9 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
3271
3451
  }
3272
3452
 
3273
3453
  // src/register/register-column.tsx
3274
- import { useState as useState11 } from "react";
3275
- import { View as View47 } from "react-native";
3276
- import { Fragment as Fragment3, jsx as jsx80, jsxs as jsxs39 } from "react/jsx-runtime";
3454
+ import { useState as useState12 } from "react";
3455
+ import { View as View48 } from "react-native";
3456
+ import { Fragment as Fragment3, jsx as jsx81, jsxs as jsxs40 } from "react/jsx-runtime";
3277
3457
  function RegisterColumn({
3278
3458
  register,
3279
3459
  registerId,
@@ -3285,30 +3465,30 @@ function RegisterColumn({
3285
3465
  cartEmpty,
3286
3466
  children
3287
3467
  }) {
3288
- const [finishing, setFinishing] = useState11(false);
3468
+ const [finishing, setFinishing] = useState12(false);
3289
3469
  if (registerId === null) {
3290
- return /* @__PURE__ */ jsx80(RegisterPicker, { registers, onPick, className: "flex-1" });
3470
+ return /* @__PURE__ */ jsx81(RegisterPicker, { registers, onPick, className: "flex-1" });
3291
3471
  }
3292
3472
  if (register.session?.status === "closed") {
3293
- return register.closing && !finishing ? /* @__PURE__ */ jsx80(Fragment3, { children: countSlot }) : /* @__PURE__ */ jsx80(FinishClose, { register, busy: finishing, setBusy: setFinishing });
3473
+ return register.closing && !finishing ? /* @__PURE__ */ jsx81(Fragment3, { children: countSlot }) : /* @__PURE__ */ jsx81(FinishClose, { register, busy: finishing, setBusy: setFinishing });
3294
3474
  }
3295
3475
  if (!register.session) {
3296
- return /* @__PURE__ */ jsx80(OpenRegisterCard, { register, currency, configuredFloatMinor, className: "flex-1" });
3476
+ return /* @__PURE__ */ jsx81(OpenRegisterCard, { register, currency, configuredFloatMinor, className: "flex-1" });
3297
3477
  }
3298
3478
  if (register.session.status === "counting") {
3299
- return /* @__PURE__ */ jsx80(Fragment3, { children: countSlot });
3479
+ return /* @__PURE__ */ jsx81(Fragment3, { children: countSlot });
3300
3480
  }
3301
- return /* @__PURE__ */ jsxs39(View47, { testID: "register-column", className: "flex-1", children: [
3302
- register.overdue && cartEmpty && /* @__PURE__ */ jsxs39(View47, { testID: "register-column-overdue", className: "bg-warning/10 flex-row items-center justify-between gap-2 px-3 py-2", children: [
3303
- /* @__PURE__ */ jsx80(Text, { className: "flex-1", children: "This register is overdue for closing." }),
3304
- /* @__PURE__ */ jsx80(
3481
+ return /* @__PURE__ */ jsxs40(View48, { testID: "register-column", className: "flex-1", children: [
3482
+ register.overdue && cartEmpty && /* @__PURE__ */ jsxs40(View48, { testID: "register-column-overdue", className: "bg-warning/10 flex-row items-center justify-between gap-2 px-3 py-2", children: [
3483
+ /* @__PURE__ */ jsx81(Text, { className: "flex-1", children: "This register is overdue for closing." }),
3484
+ /* @__PURE__ */ jsx81(
3305
3485
  Button,
3306
3486
  {
3307
3487
  testID: "register-column-close-overdue",
3308
3488
  variant: "outline",
3309
3489
  className: "min-h-11",
3310
3490
  onPress: () => register.actions.startCounting(),
3311
- children: /* @__PURE__ */ jsx80(Text, { children: "Close register" })
3491
+ children: /* @__PURE__ */ jsx81(Text, { children: "Close register" })
3312
3492
  }
3313
3493
  )
3314
3494
  ] }),
@@ -3316,7 +3496,7 @@ function RegisterColumn({
3316
3496
  ] });
3317
3497
  }
3318
3498
  function FinishClose({ register, busy, setBusy }) {
3319
- const [error, setError] = useState11("");
3499
+ const [error, setError] = useState12("");
3320
3500
  const finish = async () => {
3321
3501
  setBusy(true);
3322
3502
  setError("");
@@ -3328,16 +3508,16 @@ function FinishClose({ register, busy, setBusy }) {
3328
3508
  setBusy(false);
3329
3509
  }
3330
3510
  };
3331
- return /* @__PURE__ */ jsxs39(View47, { testID: "register-column-finish-close", className: "flex-1 gap-3 p-4", children: [
3332
- /* @__PURE__ */ jsx80(Text, { children: "The last close didn't finish." }),
3333
- /* @__PURE__ */ jsx80(Button, { testID: "register-column-finish-close-button", nativeID: "register-column-finish-close-button", disabled: busy, onPress: finish, children: /* @__PURE__ */ jsx80(Text, { children: "Finish closing" }) }),
3334
- !!error && /* @__PURE__ */ jsx80(Text, { testID: "register-column-finish-close-error", className: "text-destructive", children: error })
3511
+ return /* @__PURE__ */ jsxs40(View48, { testID: "register-column-finish-close", className: "flex-1 gap-3 p-4", children: [
3512
+ /* @__PURE__ */ jsx81(Text, { children: "The last close didn't finish." }),
3513
+ /* @__PURE__ */ jsx81(Button, { testID: "register-column-finish-close-button", nativeID: "register-column-finish-close-button", disabled: busy, onPress: finish, children: /* @__PURE__ */ jsx81(Text, { children: "Finish closing" }) }),
3514
+ !!error && /* @__PURE__ */ jsx81(Text, { testID: "register-column-finish-close-error", className: "text-destructive", children: error })
3335
3515
  ] });
3336
3516
  }
3337
3517
 
3338
3518
  // src/register/register-count.tsx
3339
- import { useEffect as useEffect2, useRef as useRef3, useState as useState12 } from "react";
3340
- import { Platform, Pressable as Pressable20, ScrollView as ScrollView13, useWindowDimensions as useWindowDimensions2, View as View48 } from "react-native";
3519
+ import { useEffect as useEffect3, useRef as useRef4, useState as useState13 } from "react";
3520
+ import { Platform, Pressable as Pressable22, ScrollView as ScrollView12, useWindowDimensions as useWindowDimensions2, View as View49 } from "react-native";
3341
3521
  import {
3342
3522
  closeNeedsApproval,
3343
3523
  countVariance,
@@ -3349,8 +3529,8 @@ import {
3349
3529
  varianceText
3350
3530
  } from "@tallyui/pos";
3351
3531
  import { currencySymbol as currencySymbol3, formatMoney as formatMoney8, minorUnitDigits as minorUnitDigits5 } from "@tallyui/core";
3352
- import { cn as cn75 } from "@tallyui/theme";
3353
- import { jsx as jsx81, jsxs as jsxs40 } from "react/jsx-runtime";
3532
+ import { cn as cn76 } from "@tallyui/theme";
3533
+ import { jsx as jsx82, jsxs as jsxs41 } from "react/jsx-runtime";
3354
3534
  var AMOUNT_LABEL_ID3 = "count-amount-label";
3355
3535
  var APPROVAL_REQUIRED_TEXT = "Manager approval needed. Ask a manager to approve, or count again.";
3356
3536
  function varianceWord(key) {
@@ -3372,17 +3552,17 @@ function tileLabel(value, currency) {
3372
3552
  return formatter.format(value / 10 ** minorUnitDigits5(currency));
3373
3553
  }
3374
3554
  var tenderLabel = (method) => method.charAt(0).toUpperCase() + method.slice(1);
3375
- function DenominationTile({ value, count, currency, onAdd }) {
3555
+ function DenominationTile({ value, count: count2, currency, onAdd }) {
3376
3556
  const label = tileLabel(value, currency);
3377
- const held = useRef3(false);
3378
- const timer = useRef3(void 0);
3557
+ const held = useRef4(false);
3558
+ const timer = useRef4(void 0);
3379
3559
  const stop = () => {
3380
3560
  if (timer.current !== void 0) clearInterval(timer.current);
3381
3561
  timer.current = void 0;
3382
3562
  };
3383
- useEffect2(() => stop, []);
3384
- return /* @__PURE__ */ jsxs40(
3385
- Pressable20,
3563
+ useEffect3(() => stop, []);
3564
+ return /* @__PURE__ */ jsxs41(
3565
+ Pressable22,
3386
3566
  {
3387
3567
  testID: `den-tile-${value}`,
3388
3568
  accessibilityRole: "button",
@@ -3403,8 +3583,8 @@ function DenominationTile({ value, count, currency, onAdd }) {
3403
3583
  if (!held.current) onAdd(1);
3404
3584
  },
3405
3585
  children: [
3406
- /* @__PURE__ */ jsx81(Text, { className: "text-sm tabular-nums", numberOfLines: 1, children: label }),
3407
- /* @__PURE__ */ jsx81(Text, { testID: `den-count-${value}`, className: "bg-background min-w-6 rounded-full px-1.5 text-center text-xs tabular-nums", children: count })
3586
+ /* @__PURE__ */ jsx82(Text, { className: "text-sm tabular-nums", numberOfLines: 1, children: label }),
3587
+ /* @__PURE__ */ jsx82(Text, { testID: `den-count-${value}`, className: "bg-background min-w-6 rounded-full px-1.5 text-center text-xs tabular-nums", children: count2 })
3408
3588
  ]
3409
3589
  }
3410
3590
  );
@@ -3415,18 +3595,18 @@ function RegisterCount({ register, currency, approve, className }) {
3415
3595
  const faces = denominations[currency] ?? denominations.default;
3416
3596
  const { width } = useWindowDimensions2();
3417
3597
  const columns = width < 480 ? 3 : 4;
3418
- const [pieces, setPieces] = useState12({});
3419
- const [cashText, setCashText] = useState12(
3598
+ const [pieces, setPieces] = useState13({});
3599
+ const [cashText, setCashText] = useState13(
3420
3600
  () => session?.counted?.cash != null ? minorToDecimal(session.counted.cash, digits) : ""
3421
3601
  );
3422
- const [others, setOthers] = useState12(
3602
+ const [others, setOthers] = useState13(
3423
3603
  () => Object.fromEntries(
3424
3604
  Object.entries(session?.counted ?? {}).filter(([method]) => method !== "cash").map(([method, minor]) => [method, minorToDecimal(minor, digits)])
3425
3605
  )
3426
3606
  );
3427
- const [busy, setBusy] = useState12(false);
3428
- const [error, setError] = useState12("");
3429
- const [refusal, setRefusal] = useState12("");
3607
+ const [busy, setBusy] = useState13(false);
3608
+ const [error, setError] = useState13("");
3609
+ const [refusal, setRefusal] = useState13("");
3430
3610
  const usingTiles = Object.keys(pieces).length > 0;
3431
3611
  const tilesTotal = denominationTotal(pieces);
3432
3612
  const displayAmount = usingTiles ? minorToDecimal(tilesTotal, digits) : cashText;
@@ -3474,11 +3654,11 @@ function RegisterCount({ register, currency, approve, className }) {
3474
3654
  void attempt(() => actions.closeSession({ counted }));
3475
3655
  };
3476
3656
  if (!session) return null;
3477
- return /* @__PURE__ */ jsxs40(View48, { testID: "register-count", className: cn75("bg-card flex-1 rounded-md", className), children: [
3478
- /* @__PURE__ */ jsxs40(ScrollView13, { className: "flex-1", contentContainerClassName: "gap-3 p-4", children: [
3479
- /* @__PURE__ */ jsx81(Text, { className: "min-h-11 text-lg font-semibold", children: "Count the drawer" }),
3480
- /* @__PURE__ */ jsx81(Label, { testID: "count-amount-label", nativeID: AMOUNT_LABEL_ID3, children: `Cash counted (${currencySymbol3(currency)})` }),
3481
- /* @__PURE__ */ jsx81(Input, { children: /* @__PURE__ */ jsx81(
3657
+ return /* @__PURE__ */ jsxs41(View49, { testID: "register-count", className: cn76("bg-card flex-1 rounded-md", className), children: [
3658
+ /* @__PURE__ */ jsxs41(ScrollView12, { className: "flex-1", contentContainerClassName: "gap-3 p-4", children: [
3659
+ /* @__PURE__ */ jsx82(Text, { className: "min-h-11 text-lg font-semibold", children: "Count the drawer" }),
3660
+ /* @__PURE__ */ jsx82(Label, { testID: "count-amount-label", nativeID: AMOUNT_LABEL_ID3, children: `Cash counted (${currencySymbol3(currency)})` }),
3661
+ /* @__PURE__ */ jsx82(Input, { children: /* @__PURE__ */ jsx82(
3482
3662
  Input.Field,
3483
3663
  {
3484
3664
  testID: "count-amount",
@@ -3492,16 +3672,16 @@ function RegisterCount({ register, currency, approve, className }) {
3492
3672
  accessibilityLabelledBy: AMOUNT_LABEL_ID3
3493
3673
  }
3494
3674
  ) }),
3495
- !blind && valid && /* @__PURE__ */ jsx81(Text, { testID: "count-variance", className: "min-h-11 tabular-nums", children: `Expected ${formatMoney8({ amount: expected.cash ?? 0, currency })} \xB7 ${varianceText(
3675
+ !blind && valid && /* @__PURE__ */ jsx82(Text, { testID: "count-variance", className: "min-h-11 tabular-nums", children: `Expected ${formatMoney8({ amount: expected.cash ?? 0, currency })} \xB7 ${varianceText(
3496
3676
  variance,
3497
3677
  digits,
3498
3678
  (major) => formatMoney8({ amount: Math.round(major * 10 ** digits), currency }) ?? "",
3499
3679
  varianceWord
3500
3680
  )}` }),
3501
- /* @__PURE__ */ jsxs40(View48, { testID: "count-denominations", className: "gap-2", children: [
3502
- Array.from({ length: Math.ceil(faces.length / columns) }, (_, row) => /* @__PURE__ */ jsx81(View48, { className: "flex-row gap-2", children: Array.from({ length: columns }, (_2, column) => {
3681
+ /* @__PURE__ */ jsxs41(View49, { testID: "count-denominations", className: "gap-2", children: [
3682
+ Array.from({ length: Math.ceil(faces.length / columns) }, (_, row) => /* @__PURE__ */ jsx82(View49, { className: "flex-row gap-2", children: Array.from({ length: columns }, (_2, column) => {
3503
3683
  const value = faces[row * columns + column];
3504
- return value ? /* @__PURE__ */ jsx81(
3684
+ return value ? /* @__PURE__ */ jsx82(
3505
3685
  DenominationTile,
3506
3686
  {
3507
3687
  value,
@@ -3510,9 +3690,9 @@ function RegisterCount({ register, currency, approve, className }) {
3510
3690
  onAdd: (n) => addPieces(value, n)
3511
3691
  },
3512
3692
  value
3513
- ) : /* @__PURE__ */ jsx81(View48, { className: "flex-1" }, column);
3693
+ ) : /* @__PURE__ */ jsx82(View49, { className: "flex-1" }, column);
3514
3694
  }) }, row)),
3515
- /* @__PURE__ */ jsx81(
3695
+ /* @__PURE__ */ jsx82(
3516
3696
  Button,
3517
3697
  {
3518
3698
  testID: "count-clear",
@@ -3522,16 +3702,16 @@ function RegisterCount({ register, currency, approve, className }) {
3522
3702
  setPieces({});
3523
3703
  setCashText(minorToDecimal(0, digits));
3524
3704
  },
3525
- children: /* @__PURE__ */ jsx81(Text, { children: "Clear" })
3705
+ children: /* @__PURE__ */ jsx82(Text, { children: "Clear" })
3526
3706
  }
3527
3707
  )
3528
3708
  ] }),
3529
3709
  otherMethods.map((method) => {
3530
3710
  const labelId = `count-tender-${method}-label`;
3531
3711
  const label = `${tenderLabel(method)} counted (${currencySymbol3(currency)})`;
3532
- return /* @__PURE__ */ jsxs40(View48, { className: "gap-2", children: [
3533
- /* @__PURE__ */ jsx81(Label, { testID: labelId, nativeID: labelId, children: label }),
3534
- /* @__PURE__ */ jsx81(Input, { children: /* @__PURE__ */ jsx81(
3712
+ return /* @__PURE__ */ jsxs41(View49, { className: "gap-2", children: [
3713
+ /* @__PURE__ */ jsx82(Label, { testID: labelId, nativeID: labelId, children: label }),
3714
+ /* @__PURE__ */ jsx82(Input, { children: /* @__PURE__ */ jsx82(
3535
3715
  Input.Field,
3536
3716
  {
3537
3717
  testID: `count-tender-${method}`,
@@ -3544,11 +3724,11 @@ function RegisterCount({ register, currency, approve, className }) {
3544
3724
  ) })
3545
3725
  ] }, method);
3546
3726
  }),
3547
- !!refusal && /* @__PURE__ */ jsx81(Text, { testID: "count-manager-line", className: "text-warning min-h-11", children: refusal }),
3548
- !!error && /* @__PURE__ */ jsx81(Text, { testID: "count-error", className: "text-destructive min-h-11", children: error })
3727
+ !!refusal && /* @__PURE__ */ jsx82(Text, { testID: "count-manager-line", className: "text-warning min-h-11", children: refusal }),
3728
+ !!error && /* @__PURE__ */ jsx82(Text, { testID: "count-error", className: "text-destructive min-h-11", children: error })
3549
3729
  ] }),
3550
- /* @__PURE__ */ jsxs40(View48, { className: "gap-2 border-t border-border p-4", children: [
3551
- /* @__PURE__ */ jsx81(
3730
+ /* @__PURE__ */ jsxs41(View49, { className: "gap-2 border-t border-border p-4", children: [
3731
+ /* @__PURE__ */ jsx82(
3552
3732
  Button,
3553
3733
  {
3554
3734
  testID: "count-back",
@@ -3556,17 +3736,17 @@ function RegisterCount({ register, currency, approve, className }) {
3556
3736
  className: "min-h-11",
3557
3737
  disabled: busy,
3558
3738
  onPress: () => attempt(actions.backToSelling),
3559
- children: /* @__PURE__ */ jsx81(Text, { children: "Back to selling" })
3739
+ children: /* @__PURE__ */ jsx82(Text, { children: "Back to selling" })
3560
3740
  }
3561
3741
  ),
3562
- /* @__PURE__ */ jsx81(
3742
+ /* @__PURE__ */ jsx82(
3563
3743
  Button,
3564
3744
  {
3565
3745
  testID: "count-close",
3566
3746
  className: "min-h-14",
3567
3747
  disabled: !valid || otherTendersInvalid || busy,
3568
3748
  onPress: onClose,
3569
- children: /* @__PURE__ */ jsx81(Text, { children: busy ? "Closing\u2026" : "Close register" })
3749
+ children: /* @__PURE__ */ jsx82(Text, { children: busy ? "Closing\u2026" : "Close register" })
3570
3750
  }
3571
3751
  )
3572
3752
  ] })
@@ -3574,15 +3754,15 @@ function RegisterCount({ register, currency, approve, className }) {
3574
3754
  }
3575
3755
 
3576
3756
  // src/register/closure-sheet.tsx
3577
- import { useEffect as useEffect3, useRef as useRef4, useState as useState13 } from "react";
3578
- import { AccessibilityInfo, Animated, View as View49 } from "react-native";
3579
- import { countVariance as countVariance2, varianceText as varianceText2 } from "@tallyui/pos";
3757
+ import { useEffect as useEffect4, useRef as useRef5, useState as useState14 } from "react";
3758
+ import { AccessibilityInfo, Animated, View as View50 } from "react-native";
3759
+ import { countVariance as countVariance2, TAX_ROUNDING_MIXED_NOTE, varianceText as varianceText2 } from "@tallyui/pos";
3580
3760
  import { formatMoney as formatMoney9, minorUnitDigits as minorUnitDigits6 } from "@tallyui/core";
3581
- import { jsx as jsx82, jsxs as jsxs41 } from "react/jsx-runtime";
3761
+ import { jsx as jsx83, jsxs as jsxs42 } from "react/jsx-runtime";
3582
3762
  function useCompletionMotion() {
3583
- const opacity = useRef4(new Animated.Value(0)).current;
3584
- const scale = useRef4(new Animated.Value(0.6)).current;
3585
- useEffect3(() => {
3763
+ const opacity = useRef5(new Animated.Value(0)).current;
3764
+ const scale = useRef5(new Animated.Value(0.6)).current;
3765
+ useEffect4(() => {
3586
3766
  let cancelled = false;
3587
3767
  AccessibilityInfo.isReduceMotionEnabled().then((reduced) => {
3588
3768
  if (cancelled) return;
@@ -3606,8 +3786,8 @@ function ClosureSheet({ register, currency, onPrint, onDone }) {
3606
3786
  const { lastClosure: closure, blind } = register;
3607
3787
  const digits = minorUnitDigits6(currency);
3608
3788
  const { opacity, scale } = useCompletionMotion();
3609
- const [busy, setBusy] = useState13(false);
3610
- const [error, setError] = useState13("");
3789
+ const [busy, setBusy] = useState14(false);
3790
+ const [error, setError] = useState14("");
3611
3791
  if (!closure) return null;
3612
3792
  const methods = Object.keys(closure.counted);
3613
3793
  const approvedByName = closure.breakdowns.approved_by_name;
@@ -3625,34 +3805,34 @@ function ClosureSheet({ register, currency, onPrint, onDone }) {
3625
3805
  setBusy(false);
3626
3806
  }
3627
3807
  };
3628
- return /* @__PURE__ */ jsx82(
3808
+ return /* @__PURE__ */ jsx83(
3629
3809
  Dialog,
3630
3810
  {
3631
3811
  open: true,
3632
3812
  onOpenChange: (open) => {
3633
3813
  if (!open) onDone();
3634
3814
  },
3635
- children: /* @__PURE__ */ jsxs41(DialogContent, { testID: "closure-sheet", children: [
3636
- /* @__PURE__ */ jsx82(
3815
+ children: /* @__PURE__ */ jsxs42(DialogContent, { testID: "closure-sheet", children: [
3816
+ /* @__PURE__ */ jsx83(
3637
3817
  Animated.View,
3638
3818
  {
3639
3819
  testID: "closure-check",
3640
3820
  style: { opacity, transform: [{ scale }] },
3641
3821
  className: "bg-success/10 h-10 w-10 items-center justify-center rounded-full",
3642
- children: /* @__PURE__ */ jsx82(Text, { className: "text-success text-lg font-bold", accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", children: "\u2713" })
3822
+ children: /* @__PURE__ */ jsx83(Text, { className: "text-success text-lg font-bold", accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", children: "\u2713" })
3643
3823
  }
3644
3824
  ),
3645
- /* @__PURE__ */ jsx82(DialogTitle, { testID: "closure-title", children: "Register closed" }),
3646
- /* @__PURE__ */ jsx82(Text, { testID: "closure-number", className: "text-muted-foreground min-h-11", children: `Closure #${closure.number}` }),
3647
- !blind && /* @__PURE__ */ jsx82(View49, { testID: "closure-figures", className: "gap-3", children: methods.map((method) => {
3825
+ /* @__PURE__ */ jsx83(DialogTitle, { testID: "closure-title", children: "Register closed" }),
3826
+ /* @__PURE__ */ jsx83(Text, { testID: "closure-number", className: "text-muted-foreground min-h-11", children: `Closure #${closure.number}` }),
3827
+ !blind && /* @__PURE__ */ jsx83(View50, { testID: "closure-figures", className: "gap-3", children: methods.map((method) => {
3648
3828
  const countedMinor = closure.counted[method] ?? 0;
3649
3829
  const expectedMinor = closure.expected[method] ?? 0;
3650
3830
  const varianceMinor = closure.variance[method] ?? countVariance2(countedMinor, expectedMinor);
3651
- return /* @__PURE__ */ jsxs41(View49, { className: "gap-1", children: [
3652
- /* @__PURE__ */ jsx82(Text, { className: "text-muted-foreground text-xs font-semibold", children: tenderLabel(method) }),
3653
- /* @__PURE__ */ jsx82(Text, { testID: `closure-counted-${method}`, className: "min-h-11 tabular-nums", children: `Counted ${formatMoney9({ amount: countedMinor, currency })}` }),
3654
- /* @__PURE__ */ jsx82(Text, { testID: `closure-expected-${method}`, className: "min-h-11 tabular-nums", children: `Expected ${formatMoney9({ amount: expectedMinor, currency })}` }),
3655
- /* @__PURE__ */ jsx82(Text, { testID: `closure-variance-${method}`, className: "min-h-11 tabular-nums", children: varianceText2(
3831
+ return /* @__PURE__ */ jsxs42(View50, { className: "gap-1", children: [
3832
+ /* @__PURE__ */ jsx83(Text, { className: "text-muted-foreground text-xs font-semibold", children: tenderLabel(method) }),
3833
+ /* @__PURE__ */ jsx83(Text, { testID: `closure-counted-${method}`, className: "min-h-11 tabular-nums", children: `Counted ${formatMoney9({ amount: countedMinor, currency })}` }),
3834
+ /* @__PURE__ */ jsx83(Text, { testID: `closure-expected-${method}`, className: "min-h-11 tabular-nums", children: `Expected ${formatMoney9({ amount: expectedMinor, currency })}` }),
3835
+ /* @__PURE__ */ jsx83(Text, { testID: `closure-variance-${method}`, className: "min-h-11 tabular-nums", children: varianceText2(
3656
3836
  varianceMinor,
3657
3837
  digits,
3658
3838
  (major) => formatMoney9({ amount: Math.round(major * 10 ** digits), currency }) ?? "",
@@ -3660,52 +3840,53 @@ function ClosureSheet({ register, currency, onPrint, onDone }) {
3660
3840
  ) })
3661
3841
  ] }, method);
3662
3842
  }) }),
3663
- !!approvedBy && /* @__PURE__ */ jsxs41(Text, { testID: "closure-approved-by", children: [
3843
+ !!approvedBy && /* @__PURE__ */ jsxs42(Text, { testID: "closure-approved-by", children: [
3664
3844
  "Approved by ",
3665
3845
  approvedBy
3666
3846
  ] }),
3667
- !!error && /* @__PURE__ */ jsx82(Text, { testID: "closure-print-error", className: "text-destructive", children: error }),
3668
- !blind && !!onPrint && /* @__PURE__ */ jsx82(Button, { testID: "closure-print", className: "min-h-14", disabled: busy, onPress: print, children: /* @__PURE__ */ jsx82(Text, { children: busy ? "Printing\u2026" : "Print the Z report" }) }),
3669
- /* @__PURE__ */ jsx82(Button, { testID: "closure-done", variant: "outline", className: "min-h-14", onPress: onDone, children: /* @__PURE__ */ jsx82(Text, { children: "Done" }) })
3847
+ closure.breakdowns.tax_rounding_mixed === true && /* @__PURE__ */ jsx83(Text, { testID: "closure-tax-rounding-mixed", className: "text-muted-foreground", children: TAX_ROUNDING_MIXED_NOTE }),
3848
+ !!error && /* @__PURE__ */ jsx83(Text, { testID: "closure-print-error", className: "text-destructive", children: error }),
3849
+ !blind && !!onPrint && /* @__PURE__ */ jsx83(Button, { testID: "closure-print", className: "min-h-14", disabled: busy, onPress: print, children: /* @__PURE__ */ jsx83(Text, { children: busy ? "Printing\u2026" : "Print the Z report" }) }),
3850
+ /* @__PURE__ */ jsx83(Button, { testID: "closure-done", variant: "outline", className: "min-h-14", onPress: onDone, children: /* @__PURE__ */ jsx83(Text, { children: "Done" }) })
3670
3851
  ] })
3671
3852
  }
3672
3853
  );
3673
3854
  }
3674
3855
 
3675
3856
  // src/settings/settings-row.tsx
3676
- import { Text as Text28, View as View50 } from "react-native";
3677
- import { cn as cn76 } from "@tallyui/theme";
3678
- import { jsx as jsx83, jsxs as jsxs42 } from "react/jsx-runtime";
3857
+ import { Text as Text29, View as View51 } from "react-native";
3858
+ import { cn as cn77 } from "@tallyui/theme";
3859
+ import { jsx as jsx84, jsxs as jsxs43 } from "react/jsx-runtime";
3679
3860
  function SettingsRow({ label, description, action, className, ...viewProps }) {
3680
- return /* @__PURE__ */ jsxs42(View50, { className: cn76("flex-row items-center gap-3 px-4 py-3", className), ...viewProps, children: [
3681
- /* @__PURE__ */ jsxs42(View50, { className: "flex-1 gap-0.5", children: [
3682
- /* @__PURE__ */ jsx83(Text28, { className: "text-sm font-medium text-foreground", children: label }),
3683
- description && /* @__PURE__ */ jsx83(Text28, { className: "text-xs text-muted-foreground", children: description })
3861
+ return /* @__PURE__ */ jsxs43(View51, { className: cn77("flex-row items-center gap-3 px-4 py-3", className), ...viewProps, children: [
3862
+ /* @__PURE__ */ jsxs43(View51, { className: "flex-1 gap-0.5", children: [
3863
+ /* @__PURE__ */ jsx84(Text29, { className: "text-sm font-medium text-foreground", children: label }),
3864
+ description && /* @__PURE__ */ jsx84(Text29, { className: "text-xs text-muted-foreground", children: description })
3684
3865
  ] }),
3685
- action && /* @__PURE__ */ jsx83(View50, { children: action })
3866
+ action && /* @__PURE__ */ jsx84(View51, { children: action })
3686
3867
  ] });
3687
3868
  }
3688
3869
 
3689
3870
  // src/settings/settings-group.tsx
3690
- import { Text as Text29, View as View51 } from "react-native";
3691
- import { cn as cn77 } from "@tallyui/theme";
3692
- import { jsx as jsx84, jsxs as jsxs43 } from "react/jsx-runtime";
3871
+ import { Text as Text30, View as View52 } from "react-native";
3872
+ import { cn as cn78 } from "@tallyui/theme";
3873
+ import { jsx as jsx85, jsxs as jsxs44 } from "react/jsx-runtime";
3693
3874
  function SettingsGroup({ title, description, children, className, ...viewProps }) {
3694
- return /* @__PURE__ */ jsxs43(View51, { className: cn77("gap-1", className), ...viewProps, children: [
3695
- /* @__PURE__ */ jsxs43(View51, { className: "px-4 py-2", children: [
3696
- /* @__PURE__ */ jsx84(Text29, { className: "text-sm font-semibold text-foreground", children: title }),
3697
- description && /* @__PURE__ */ jsx84(Text29, { className: "text-xs text-muted-foreground", children: description })
3875
+ return /* @__PURE__ */ jsxs44(View52, { className: cn78("gap-1", className), ...viewProps, children: [
3876
+ /* @__PURE__ */ jsxs44(View52, { className: "px-4 py-2", children: [
3877
+ /* @__PURE__ */ jsx85(Text30, { className: "text-sm font-semibold text-foreground", children: title }),
3878
+ description && /* @__PURE__ */ jsx85(Text30, { className: "text-xs text-muted-foreground", children: description })
3698
3879
  ] }),
3699
- /* @__PURE__ */ jsx84(View51, { className: "rounded-lg border border-border bg-card", children })
3880
+ /* @__PURE__ */ jsx85(View52, { className: "rounded-lg border border-border bg-card", children })
3700
3881
  ] });
3701
3882
  }
3702
3883
 
3703
3884
  // src/settings/connector-status.tsx
3704
- import { Text as Text30, View as View52 } from "react-native";
3705
- import { cn as cn78 } from "@tallyui/theme";
3706
- import { jsx as jsx85, jsxs as jsxs44 } from "react/jsx-runtime";
3707
- function defaultFormatUnsold(count, stale) {
3708
- return `${count} ${count === 1 ? "product" : "products"} not sold in this channel${stale ? " (last check failed)" : ""}`;
3885
+ import { Text as Text31, View as View53 } from "react-native";
3886
+ import { cn as cn79 } from "@tallyui/theme";
3887
+ import { jsx as jsx86, jsxs as jsxs45 } from "react/jsx-runtime";
3888
+ function defaultFormatUnsold(count2, stale) {
3889
+ return `${count2} ${count2 === 1 ? "product" : "products"} not sold in this channel${stale ? " (last check failed)" : ""}`;
3709
3890
  }
3710
3891
  var STATUS_CONFIG2 = {
3711
3892
  connected: { label: "Connected", dot: "bg-success", text: "text-success" },
@@ -3725,33 +3906,33 @@ function ConnectorStatus({
3725
3906
  ...viewProps
3726
3907
  }) {
3727
3908
  const config = STATUS_CONFIG2[status];
3728
- return /* @__PURE__ */ jsxs44(View52, { className: cn78("gap-2 rounded-lg border border-border bg-card p-3", className), ...viewProps, children: [
3729
- /* @__PURE__ */ jsxs44(View52, { className: "flex-row items-center justify-between", children: [
3730
- /* @__PURE__ */ jsx85(Text30, { className: "text-sm font-semibold text-foreground", children: name }),
3731
- /* @__PURE__ */ jsxs44(View52, { className: "flex-row items-center gap-1.5", children: [
3732
- /* @__PURE__ */ jsx85(View52, { className: cn78("h-2 w-2 rounded-full", config.dot) }),
3733
- /* @__PURE__ */ jsx85(Text30, { className: cn78("text-xs font-medium", config.text), children: config.label })
3909
+ return /* @__PURE__ */ jsxs45(View53, { className: cn79("gap-2 rounded-lg border border-border bg-card p-3", className), ...viewProps, children: [
3910
+ /* @__PURE__ */ jsxs45(View53, { className: "flex-row items-center justify-between", children: [
3911
+ /* @__PURE__ */ jsx86(Text31, { className: "text-sm font-semibold text-foreground", children: name }),
3912
+ /* @__PURE__ */ jsxs45(View53, { className: "flex-row items-center gap-1.5", children: [
3913
+ /* @__PURE__ */ jsx86(View53, { className: cn79("h-2 w-2 rounded-full", config.dot) }),
3914
+ /* @__PURE__ */ jsx86(Text31, { className: cn79("text-xs font-medium", config.text), children: config.label })
3734
3915
  ] })
3735
3916
  ] }),
3736
- lastSync && /* @__PURE__ */ jsxs44(Text30, { className: "text-xs text-muted-foreground", children: [
3917
+ lastSync && /* @__PURE__ */ jsxs45(Text31, { className: "text-xs text-muted-foreground", children: [
3737
3918
  "Last sync: ",
3738
3919
  lastSync
3739
3920
  ] }),
3740
- error && /* @__PURE__ */ jsx85(Text30, { className: "text-xs text-destructive", children: error }),
3741
- !!unsoldCount && /* @__PURE__ */ jsx85(Text30, { className: cn78("text-xs", unsoldStale ? "text-muted-foreground" : "text-warning"), children: formatUnsold(unsoldCount, !!unsoldStale) })
3921
+ error && /* @__PURE__ */ jsx86(Text31, { className: "text-xs text-destructive", children: error }),
3922
+ !!unsoldCount && /* @__PURE__ */ jsx86(Text31, { className: cn79("text-xs", unsoldStale ? "text-muted-foreground" : "text-warning"), children: formatUnsold(unsoldCount, !!unsoldStale) })
3742
3923
  ] });
3743
3924
  }
3744
3925
 
3745
3926
  // src/sale/cart.tsx
3746
- import { useState as useState15 } from "react";
3747
- import { Pressable as Pressable22, Text as Text32, View as View54 } from "react-native";
3927
+ import { useState as useState16 } from "react";
3928
+ import { Pressable as Pressable24, Text as Text33, View as View55 } from "react-native";
3748
3929
  import { buildReceiptData } from "@tallyui/pos";
3749
3930
 
3750
3931
  // src/sale/discount-form.tsx
3751
- import { useState as useState14 } from "react";
3752
- import { Pressable as Pressable21, Text as Text31, TextInput as TextInput8, View as View53 } from "react-native";
3932
+ import { useState as useState15 } from "react";
3933
+ import { Pressable as Pressable23, Text as Text32, TextInput as TextInput9, View as View54 } from "react-native";
3753
3934
  import { formatMoney as formatMoney10, minorUnitDigits as minorUnitDigits7, moneyFromDecimalString as moneyFromDecimalString2 } from "@tallyui/core";
3754
- import { jsx as jsx86, jsxs as jsxs45 } from "react/jsx-runtime";
3935
+ import { jsx as jsx87, jsxs as jsxs46 } from "react/jsx-runtime";
3755
3936
  function parseDiscount(type, text, currency) {
3756
3937
  const raw = text.trim();
3757
3938
  const trimmed = raw.split(",").length === 2 ? raw.replace(",", ".") : raw;
@@ -3768,31 +3949,31 @@ function parseDiscount(type, text, currency) {
3768
3949
  var discountLabel = (discount, currency) => discount.type === "percentage" ? `${discount.value}%` : formatMoney10({ amount: discount.amountMinor, currency }) ?? String(discount.amountMinor);
3769
3950
  var button = "rounded-md border border-border px-3 py-2 min-h-11 items-center justify-center";
3770
3951
  function DiscountForm({ title, currency, onApply, onClose }) {
3771
- const [type, setType] = useState14("percentage");
3772
- const [text, setText] = useState14("");
3773
- const [error, setError] = useState14(null);
3952
+ const [type, setType] = useState15("percentage");
3953
+ const [text, setText] = useState15("");
3954
+ const [error, setError] = useState15(null);
3774
3955
  function apply() {
3775
3956
  const parsed = parseDiscount(type, text, currency);
3776
3957
  const refused = typeof parsed === "string" ? parsed : onApply(parsed);
3777
3958
  setError(refused);
3778
3959
  if (refused === null) onClose();
3779
3960
  }
3780
- return /* @__PURE__ */ jsxs45(View53, { role: "group", accessibilityLabel: title, className: "gap-2 px-3 py-2", children: [
3781
- /* @__PURE__ */ jsx86(Text31, { className: "font-semibold text-foreground", children: title }),
3782
- /* @__PURE__ */ jsxs45(View53, { className: "flex-row gap-2", children: [
3783
- ["percentage", "fixed"].map((option) => /* @__PURE__ */ jsx86(
3784
- Pressable21,
3961
+ return /* @__PURE__ */ jsxs46(View54, { role: "group", accessibilityLabel: title, className: "gap-2 px-3 py-2", children: [
3962
+ /* @__PURE__ */ jsx87(Text32, { className: "font-semibold text-foreground", children: title }),
3963
+ /* @__PURE__ */ jsxs46(View54, { className: "flex-row gap-2", children: [
3964
+ ["percentage", "fixed"].map((option) => /* @__PURE__ */ jsx87(
3965
+ Pressable23,
3785
3966
  {
3786
3967
  accessibilityRole: "button",
3787
3968
  accessibilityState: { selected: type === option },
3788
3969
  onPress: () => setType(option),
3789
3970
  className: `${button} ${type === option ? "bg-primary" : "bg-card"}`,
3790
- children: /* @__PURE__ */ jsx86(Text31, { className: type === option ? "text-primary-foreground" : "text-foreground", children: option === "percentage" ? "Percent" : "Amount" })
3971
+ children: /* @__PURE__ */ jsx87(Text32, { className: type === option ? "text-primary-foreground" : "text-foreground", children: option === "percentage" ? "Percent" : "Amount" })
3791
3972
  },
3792
3973
  option
3793
3974
  )),
3794
- /* @__PURE__ */ jsx86(
3795
- TextInput8,
3975
+ /* @__PURE__ */ jsx87(
3976
+ TextInput9,
3796
3977
  {
3797
3978
  accessibilityLabel: "Discount value",
3798
3979
  value: text,
@@ -3804,16 +3985,16 @@ function DiscountForm({ title, currency, onApply, onClose }) {
3804
3985
  }
3805
3986
  )
3806
3987
  ] }),
3807
- error ? /* @__PURE__ */ jsx86(Text31, { accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
3808
- /* @__PURE__ */ jsxs45(View53, { className: "flex-row gap-2", children: [
3809
- /* @__PURE__ */ jsx86(Pressable21, { accessibilityRole: "button", onPress: apply, className: `${button} bg-primary`, children: /* @__PURE__ */ jsx86(Text31, { className: "font-semibold text-primary-foreground", children: "Apply" }) }),
3810
- /* @__PURE__ */ jsx86(Pressable21, { accessibilityRole: "button", onPress: onClose, className: `${button} bg-card`, children: /* @__PURE__ */ jsx86(Text31, { className: "text-foreground", children: "Cancel" }) })
3988
+ error ? /* @__PURE__ */ jsx87(Text32, { accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
3989
+ /* @__PURE__ */ jsxs46(View54, { className: "flex-row gap-2", children: [
3990
+ /* @__PURE__ */ jsx87(Pressable23, { accessibilityRole: "button", onPress: apply, className: `${button} bg-primary`, children: /* @__PURE__ */ jsx87(Text32, { className: "font-semibold text-primary-foreground", children: "Apply" }) }),
3991
+ /* @__PURE__ */ jsx87(Pressable23, { accessibilityRole: "button", onPress: onClose, className: `${button} bg-card`, children: /* @__PURE__ */ jsx87(Text32, { className: "text-foreground", children: "Cancel" }) })
3811
3992
  ] })
3812
3993
  ] });
3813
3994
  }
3814
3995
  function DiscountChips({ discounts, currency, onRemove, prefix, amounts = [] }) {
3815
3996
  if (!discounts.length) return null;
3816
- return /* @__PURE__ */ jsx86(View53, { className: "flex-row flex-wrap gap-2 px-3", children: discounts.map((discount) => {
3997
+ return /* @__PURE__ */ jsx87(View54, { className: "flex-row flex-wrap gap-2 px-3", children: discounts.map((discount) => {
3817
3998
  const amount = amounts.find((row) => row.discountId === discount.id)?.amountMinor;
3818
3999
  const own = discountLabel(discount, currency);
3819
4000
  const label = [
@@ -3821,16 +4002,16 @@ function DiscountChips({ discounts, currency, onRemove, prefix, amounts = [] })
3821
4002
  amount === void 0 ? prefix ? `\u2212${own}` : own : discount.type === "percentage" ? own : null,
3822
4003
  amount === void 0 ? null : `\u2212${formatMoney10({ amount, currency })}`
3823
4004
  ].filter(Boolean).join(" ");
3824
- return /* @__PURE__ */ jsxs45(
3825
- Pressable21,
4005
+ return /* @__PURE__ */ jsxs46(
4006
+ Pressable23,
3826
4007
  {
3827
4008
  accessibilityRole: "button",
3828
4009
  accessibilityLabel: `Remove discount ${label}`,
3829
4010
  onPress: () => onRemove(discount.id),
3830
4011
  className: "min-h-11 flex-row items-center gap-1",
3831
4012
  children: [
3832
- /* @__PURE__ */ jsx86(DiscountBadge, { label, className: "self-center" }),
3833
- /* @__PURE__ */ jsx86(Text31, { className: "text-muted-foreground", children: "\u2715" })
4013
+ /* @__PURE__ */ jsx87(DiscountBadge, { label, className: "self-center" }),
4014
+ /* @__PURE__ */ jsx87(Text32, { className: "text-muted-foreground", children: "\u2715" })
3834
4015
  ]
3835
4016
  },
3836
4017
  discount.id
@@ -3839,7 +4020,7 @@ function DiscountChips({ discounts, currency, onRemove, prefix, amounts = [] })
3839
4020
  }
3840
4021
 
3841
4022
  // src/sale/cart.tsx
3842
- import { Fragment as Fragment4, jsx as jsx87, jsxs as jsxs46 } from "react/jsx-runtime";
4023
+ import { Fragment as Fragment4, jsx as jsx88, jsxs as jsxs47 } from "react/jsx-runtime";
3843
4024
  function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%` }) {
3844
4025
  const { order } = sale;
3845
4026
  const money = (amount) => ({ amount, currency: order.currency });
@@ -3847,8 +4028,8 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%` }) {
3847
4028
  const taxRows = totals.taxLines.map((line) => ({ label: taxLabel(line.ratePpm), amount: money(line.amountMinor) }));
3848
4029
  const display = (lineId) => order.display.lines.find((line) => line.lineId === lineId);
3849
4030
  const orderAmounts = order.discounts.length === 1 ? [{ discountId: order.discounts[0].id, amountMinor: order.display.orderDiscountMinor }] : [];
3850
- const [form, setForm] = useState15(null);
3851
- const discountForm = (lineId, title) => form?.lineId === lineId ? /* @__PURE__ */ jsx87(
4031
+ const [form, setForm] = useState16(null);
4032
+ const discountForm = (lineId, title) => form?.lineId === lineId ? /* @__PURE__ */ jsx88(
3852
4033
  DiscountForm,
3853
4034
  {
3854
4035
  title,
@@ -3859,8 +4040,8 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%` }) {
3859
4040
  lineId ?? "order"
3860
4041
  ) : null;
3861
4042
  const pay = `min-h-12 flex-1 justify-center rounded-md bg-primary px-4 py-3 ${!order.lineItems.length ? "opacity-50" : ""}`;
3862
- const renderItem = (line) => /* @__PURE__ */ jsxs46(Fragment4, { children: [
3863
- /* @__PURE__ */ jsx87(CartLineActions, { actions: [{ id: "discount", label: "Discount", color: "text-primary", onPress: () => setForm({ lineId: line.id }) }], children: /* @__PURE__ */ jsx87(
4043
+ const renderItem = (line) => /* @__PURE__ */ jsxs47(Fragment4, { children: [
4044
+ /* @__PURE__ */ jsx88(CartLineActions, { actions: [{ id: "discount", label: "Discount", color: "text-primary", onPress: () => setForm({ lineId: line.id }) }], children: /* @__PURE__ */ jsx88(
3864
4045
  CartLine,
3865
4046
  {
3866
4047
  name: line.name,
@@ -3869,50 +4050,50 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%` }) {
3869
4050
  lineTotal: money(display(line.id).amountMinor)
3870
4051
  }
3871
4052
  ) }),
3872
- /* @__PURE__ */ jsx87(DiscountChips, { discounts: line.discounts, amounts: display(line.id).discounts, currency: order.currency, onRemove: sale.removeDiscount }),
3873
- /* @__PURE__ */ jsxs46(View54, { className: "flex-row gap-4 px-3 py-2", children: [
3874
- /* @__PURE__ */ jsx87(
3875
- Pressable22,
4053
+ /* @__PURE__ */ jsx88(DiscountChips, { discounts: line.discounts, amounts: display(line.id).discounts, currency: order.currency, onRemove: sale.removeDiscount }),
4054
+ /* @__PURE__ */ jsxs47(View55, { className: "flex-row gap-4 px-3 py-2", children: [
4055
+ /* @__PURE__ */ jsx88(
4056
+ Pressable24,
3876
4057
  {
3877
4058
  accessibilityRole: "button",
3878
4059
  accessibilityLabel: `Decrease ${line.name}`,
3879
4060
  onPress: () => sale.setQuantity(line.id, line.quantity - 1),
3880
4061
  className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
3881
- children: /* @__PURE__ */ jsx87(Text32, { className: "text-center text-foreground", children: "\u2212" })
4062
+ children: /* @__PURE__ */ jsx88(Text33, { className: "text-center text-foreground", children: "\u2212" })
3882
4063
  }
3883
4064
  ),
3884
- /* @__PURE__ */ jsx87(
3885
- Pressable22,
4065
+ /* @__PURE__ */ jsx88(
4066
+ Pressable24,
3886
4067
  {
3887
4068
  accessibilityRole: "button",
3888
4069
  accessibilityLabel: `Increase ${line.name}`,
3889
4070
  onPress: () => sale.setQuantity(line.id, line.quantity + 1),
3890
4071
  className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
3891
- children: /* @__PURE__ */ jsx87(Text32, { className: "text-center text-foreground", children: "+" })
4072
+ children: /* @__PURE__ */ jsx88(Text33, { className: "text-center text-foreground", children: "+" })
3892
4073
  }
3893
4074
  ),
3894
- /* @__PURE__ */ jsx87(
3895
- Pressable22,
4075
+ /* @__PURE__ */ jsx88(
4076
+ Pressable24,
3896
4077
  {
3897
4078
  accessibilityRole: "button",
3898
4079
  accessibilityLabel: `Remove ${line.name}`,
3899
4080
  onPress: () => sale.remove(line.id),
3900
4081
  className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
3901
- children: /* @__PURE__ */ jsx87(Text32, { className: "text-center text-foreground", children: "Remove" })
4082
+ children: /* @__PURE__ */ jsx88(Text33, { className: "text-center text-foreground", children: "Remove" })
3902
4083
  }
3903
4084
  )
3904
4085
  ] }),
3905
4086
  discountForm(line.id, `Discount on ${line.name}`)
3906
4087
  ] });
3907
- return /* @__PURE__ */ jsx87(
4088
+ return /* @__PURE__ */ jsx88(
3908
4089
  CartPanel,
3909
4090
  {
3910
4091
  dataSet: { print: "hide" },
3911
4092
  items: order.lineItems,
3912
4093
  renderItem,
3913
- emptyState: /* @__PURE__ */ jsx87(Text32, { className: "text-muted-foreground", children: "Scan or tap a product to start a sale." }),
3914
- afterItems: order.lineItems.length ? /* @__PURE__ */ jsxs46(View54, { className: "gap-3 px-3 py-2", children: [
3915
- /* @__PURE__ */ jsx87(
4094
+ emptyState: /* @__PURE__ */ jsx88(Text33, { className: "text-muted-foreground", children: "Scan or tap a product to start a sale." }),
4095
+ afterItems: order.lineItems.length ? /* @__PURE__ */ jsxs47(View55, { className: "gap-3 px-3 py-2", children: [
4096
+ /* @__PURE__ */ jsx88(
3916
4097
  DiscountChips,
3917
4098
  {
3918
4099
  discounts: order.discounts,
@@ -3922,18 +4103,18 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%` }) {
3922
4103
  prefix: "Order discount"
3923
4104
  }
3924
4105
  ),
3925
- form?.lineId === null ? discountForm(null, "Order discount") : /* @__PURE__ */ jsx87(
3926
- Pressable22,
4106
+ form?.lineId === null ? discountForm(null, "Order discount") : /* @__PURE__ */ jsx88(
4107
+ Pressable24,
3927
4108
  {
3928
4109
  accessibilityRole: "button",
3929
4110
  onPress: () => setForm({ lineId: null }),
3930
4111
  className: "self-start rounded-md border border-border bg-card px-4 py-2 min-h-11 justify-center",
3931
- children: /* @__PURE__ */ jsx87(Text32, { className: "text-foreground", children: "Order discount" })
4112
+ children: /* @__PURE__ */ jsx88(Text33, { className: "text-foreground", children: "Order discount" })
3932
4113
  }
3933
4114
  )
3934
4115
  ] }) : void 0,
3935
- footer: /* @__PURE__ */ jsxs46(View54, { testID: "cart-footer", className: "gap-3 pb-4", children: [
3936
- /* @__PURE__ */ jsx87(
4116
+ footer: /* @__PURE__ */ jsxs47(View55, { testID: "cart-footer", className: "gap-3 pb-4", children: [
4117
+ /* @__PURE__ */ jsx88(
3937
4118
  CartTotal,
3938
4119
  {
3939
4120
  subtotal: money(totals.subtotalMinor),
@@ -3943,10 +4124,10 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%` }) {
3943
4124
  taxInclusive: totals.taxInclusive
3944
4125
  }
3945
4126
  ),
3946
- sale.error ? /* @__PURE__ */ jsx87(Text32, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
3947
- /* @__PURE__ */ jsxs46(View54, { className: "flex-row gap-3", children: [
3948
- /* @__PURE__ */ jsx87(Pressable22, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("cash"), className: pay, children: /* @__PURE__ */ jsx87(Text32, { className: "text-center font-semibold text-primary-foreground", children: "Cash" }) }),
3949
- /* @__PURE__ */ jsx87(Pressable22, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("external"), className: pay, children: /* @__PURE__ */ jsx87(Text32, { className: "text-center font-semibold text-primary-foreground", children: "Card terminal" }) })
4127
+ sale.error ? /* @__PURE__ */ jsx88(Text33, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4128
+ /* @__PURE__ */ jsxs47(View55, { className: "flex-row gap-3", children: [
4129
+ /* @__PURE__ */ jsx88(Pressable24, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("cash"), className: pay, children: /* @__PURE__ */ jsx88(Text33, { className: "text-center font-semibold text-primary-foreground", children: "Cash" }) }),
4130
+ /* @__PURE__ */ jsx88(Pressable24, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("external"), className: pay, children: /* @__PURE__ */ jsx88(Text33, { className: "text-center font-semibold text-primary-foreground", children: "Card terminal" }) })
3950
4131
  ] })
3951
4132
  ] })
3952
4133
  }
@@ -3954,26 +4135,26 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%` }) {
3954
4135
  }
3955
4136
 
3956
4137
  // src/sale/cart-bar.tsx
3957
- import { Pressable as Pressable23, Text as Text33 } from "react-native";
4138
+ import { Pressable as Pressable25, Text as Text34 } from "react-native";
3958
4139
  import { formatMoney as formatMoney11 } from "@tallyui/core";
3959
4140
  import { buildReceiptData as buildReceiptData2 } from "@tallyui/pos";
3960
- import { jsx as jsx88, jsxs as jsxs47 } from "react/jsx-runtime";
4141
+ import { jsx as jsx89, jsxs as jsxs48 } from "react/jsx-runtime";
3961
4142
  function CartBar({ sale, onOpen }) {
3962
4143
  const { order } = sale;
3963
- const count = order.lineItems.reduce((sum, line) => sum + line.quantity, 0);
4144
+ const count2 = order.lineItems.reduce((sum, line) => sum + line.quantity, 0);
3964
4145
  const total = formatMoney11({ amount: buildReceiptData2(order, { storeName: "" }).totals.totalMinor, currency: order.currency });
3965
- const items = `${count} ${count === 1 ? "item" : "items"}`;
3966
- return /* @__PURE__ */ jsxs47(
3967
- Pressable23,
4146
+ const items = `${count2} ${count2 === 1 ? "item" : "items"}`;
4147
+ return /* @__PURE__ */ jsxs48(
4148
+ Pressable25,
3968
4149
  {
3969
4150
  accessibilityRole: "button",
3970
- accessibilityLabel: count ? `Open cart, ${items}, ${total}` : "Cart is empty",
3971
- disabled: !count,
4151
+ accessibilityLabel: count2 ? `Open cart, ${items}, ${total}` : "Cart is empty",
4152
+ disabled: !count2,
3972
4153
  onPress: onOpen,
3973
- className: `min-h-14 mx-3 mb-3 flex-row items-center justify-between rounded-md bg-primary px-4 py-3 ${count ? "" : "opacity-50"}`,
4154
+ 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"}`,
3974
4155
  children: [
3975
- /* @__PURE__ */ jsx88(Text33, { className: "font-bold text-primary-foreground", children: count ? `Cart \xB7 ${items}` : "Cart is empty" }),
3976
- count ? /* @__PURE__ */ jsxs47(Text33, { className: "font-bold text-primary-foreground", children: [
4156
+ /* @__PURE__ */ jsx89(Text34, { className: "font-bold text-primary-foreground", children: count2 ? `Cart \xB7 ${items}` : "Cart is empty" }),
4157
+ count2 ? /* @__PURE__ */ jsxs48(Text34, { className: "font-bold text-primary-foreground", children: [
3977
4158
  total,
3978
4159
  " \u203A"
3979
4160
  ] }) : null
@@ -3983,16 +4164,17 @@ function CartBar({ sale, onOpen }) {
3983
4164
  }
3984
4165
 
3985
4166
  // src/sale/tender.tsx
3986
- import { Pressable as Pressable24, Text as Text34, TextInput as TextInput9, View as View55 } from "react-native";
4167
+ import { Pressable as Pressable26, Text as Text35, TextInput as TextInput10, View as View56 } from "react-native";
3987
4168
  import { formatMoney as formatMoney12 } from "@tallyui/core";
3988
- import { Fragment as Fragment5, jsx as jsx89, jsxs as jsxs48 } from "react/jsx-runtime";
4169
+ import { Fragment as Fragment5, jsx as jsx90, jsxs as jsxs49 } from "react/jsx-runtime";
4170
+ var REFERENCE_MAX = 255;
3989
4171
  function Tender({ sale }) {
3990
4172
  const { order, stage } = sale;
3991
4173
  if (stage.kind !== "tender") return null;
3992
4174
  const money = (amount) => ({ amount, currency: order.currency });
3993
- return /* @__PURE__ */ jsxs48(View55, { dataSet: { print: "hide" }, className: "gap-4 p-4", children: [
3994
- stage.method === "cash" ? /* @__PURE__ */ jsxs48(Fragment5, { children: [
3995
- /* @__PURE__ */ jsx89(
4175
+ return /* @__PURE__ */ jsxs49(View56, { dataSet: { print: "hide" }, className: "gap-4 p-4", children: [
4176
+ stage.method === "cash" ? /* @__PURE__ */ jsxs49(Fragment5, { children: [
4177
+ /* @__PURE__ */ jsx90(
3996
4178
  CashTendered,
3997
4179
  {
3998
4180
  total: money(order.totalMinor),
@@ -4000,43 +4182,45 @@ function Tender({ sale }) {
4000
4182
  onChangeAmount: (amount) => sale.setTender({ method: "cash", amountMinor: amount.amount })
4001
4183
  }
4002
4184
  ),
4003
- /* @__PURE__ */ jsx89(ChangeDisplay, { change: money(order.changeDueMinor) }),
4004
- order.balanceDueMinor > 0 ? /* @__PURE__ */ jsxs48(Text34, { className: "text-foreground", children: [
4185
+ /* @__PURE__ */ jsx90(ChangeDisplay, { change: money(order.changeDueMinor) }),
4186
+ order.balanceDueMinor > 0 ? /* @__PURE__ */ jsxs49(Text35, { className: "text-foreground", children: [
4005
4187
  "Balance due: ",
4006
4188
  formatMoney12(money(order.balanceDueMinor))
4007
4189
  ] }) : null,
4008
- /* @__PURE__ */ jsx89(Pressable24, { 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__ */ jsx89(Text34, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" }) })
4009
- ] }) : /* @__PURE__ */ jsxs48(Fragment5, { children: [
4010
- /* @__PURE__ */ jsxs48(Text34, { className: "text-foreground", children: [
4190
+ /* @__PURE__ */ jsx90(Pressable26, { 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__ */ jsx90(Text35, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" }) })
4191
+ ] }) : /* @__PURE__ */ jsxs49(Fragment5, { children: [
4192
+ /* @__PURE__ */ jsxs49(Text35, { className: "text-foreground", children: [
4011
4193
  "Card terminal: ",
4012
4194
  formatMoney12(money(order.totalMinor))
4013
4195
  ] }),
4014
- /* @__PURE__ */ jsx89(
4015
- TextInput9,
4196
+ /* @__PURE__ */ jsx90(
4197
+ TextInput10,
4016
4198
  {
4017
4199
  accessibilityLabel: "Terminal reference",
4018
4200
  placeholder: "Terminal reference",
4201
+ maxLength: REFERENCE_MAX,
4019
4202
  value: order.payments[0]?.reference ?? "",
4020
4203
  onChangeText: (reference) => sale.setTender({ method: "external", amountMinor: order.totalMinor, reference }),
4021
4204
  className: "rounded-md border border-border px-3 py-2 text-foreground"
4022
4205
  }
4023
4206
  ),
4024
- /* @__PURE__ */ jsx89(Pressable24, { accessibilityRole: "button", onPress: sale.complete, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx89(Text34, { className: "text-center font-semibold text-primary-foreground", children: "Payment approved on terminal" }) })
4207
+ /* @__PURE__ */ jsx90(Pressable26, { accessibilityRole: "button", onPress: sale.complete, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx90(Text35, { className: "text-center font-semibold text-primary-foreground", children: "Payment approved on terminal" }) })
4025
4208
  ] }),
4026
- sale.error ? /* @__PURE__ */ jsx89(Text34, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4027
- sale.canContinue ? /* @__PURE__ */ jsxs48(Fragment5, { children: [
4028
- /* @__PURE__ */ jsx89(Text34, { className: "text-foreground", children: "This sale is stored and will be sent. Continue to the next sale." }),
4029
- /* @__PURE__ */ jsx89(Pressable24, { accessibilityRole: "button", onPress: () => sale.continueSale(), className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx89(Text34, { className: "text-center font-semibold text-primary-foreground", children: "Continue" }) })
4209
+ sale.error ? /* @__PURE__ */ jsx90(Text35, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4210
+ sale.canContinue ? /* @__PURE__ */ jsxs49(Fragment5, { children: [
4211
+ /* @__PURE__ */ jsx90(Text35, { className: "text-foreground", children: "This sale is stored and will be sent. Continue to the next sale." }),
4212
+ /* @__PURE__ */ jsx90(Pressable26, { accessibilityRole: "button", onPress: () => sale.continueSale(), className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx90(Text35, { className: "text-center font-semibold text-primary-foreground", children: "Continue" }) })
4030
4213
  ] }) : null,
4031
- /* @__PURE__ */ jsx89(Pressable24, { accessibilityRole: "button", onPress: sale.cancelTender, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx89(Text34, { className: "text-center text-foreground", children: "Back" }) })
4214
+ /* @__PURE__ */ jsx90(Pressable26, { accessibilityRole: "button", onPress: sale.cancelTender, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx90(Text35, { className: "text-center text-foreground", children: "Back" }) })
4032
4215
  ] });
4033
4216
  }
4034
4217
 
4035
4218
  // src/sale/catalogue.tsx
4036
- import { useEffect as useEffect4, useMemo as useMemo2, useState as useState16 } from "react";
4037
- import { Pressable as Pressable25, Text as Text35, View as View56 } from "react-native";
4219
+ import { useEffect as useEffect5, useMemo as useMemo2, useState as useState17 } from "react";
4220
+ import { Pressable as Pressable27, Text as Text36, View as View57 } from "react-native";
4221
+ import { useStockOverlaid, useStockOverlayAsOf } from "@tallyui/core";
4038
4222
  import { catalogueEntries, findEntryByCode, searchProducts, variantPriceLabel } from "@tallyui/pos";
4039
- import { jsx as jsx90, jsxs as jsxs49 } from "react/jsx-runtime";
4223
+ import { jsx as jsx91, jsxs as jsxs50 } from "react/jsx-runtime";
4040
4224
  var MIN_TILE_WIDTH = 160;
4041
4225
  var STOCK_LABEL = {
4042
4226
  in_stock: "In Stock",
@@ -4056,24 +4240,28 @@ function laterOf(a, b) {
4056
4240
  return a.getTime() >= b.getTime() ? a : b;
4057
4241
  }
4058
4242
  function Catalogue({ products, traits, currency, onSelect, statusText, statusAccessory, lastSyncedAt, lastStockCheckAt, hour12, minCodeLength }) {
4059
- const stockAsOf = laterOf(lastStockCheckAt, lastSyncedAt);
4060
- const [query, setQuery] = useState16("");
4061
- const [chooserId, setChooserId] = useState16(null);
4062
- const [width, setWidth] = useState16(0);
4243
+ const shown = useStockOverlaid(products);
4244
+ const overlayAsOf = useStockOverlayAsOf();
4245
+ const parsedOverlayAsOf = overlayAsOf ? new Date(overlayAsOf) : void 0;
4246
+ const validOverlayAsOf = parsedOverlayAsOf && !isNaN(parsedOverlayAsOf.getTime()) ? parsedOverlayAsOf : void 0;
4247
+ const stockAsOf = laterOf(laterOf(lastStockCheckAt, validOverlayAsOf), lastSyncedAt);
4248
+ const [query, setQuery] = useState17("");
4249
+ const [chooserId, setChooserId] = useState17(null);
4250
+ const [width, setWidth] = useState17(0);
4063
4251
  const columns = Math.max(2, Math.min(6, Math.floor((width - 8) / (MIN_TILE_WIDTH + 8))));
4064
- const entries = useMemo2(() => catalogueEntries(products, traits), [products, traits]);
4065
- const results = useMemo2(() => searchProducts(products, query, traits), [products, query, traits]);
4252
+ const entries = useMemo2(() => catalogueEntries(shown, traits), [shown, traits]);
4253
+ const results = useMemo2(() => searchProducts(shown, query, traits), [shown, query, traits]);
4066
4254
  const choices = useMemo2(() => chooserId === null ? [] : entries.filter((entry) => traits.getId(entry.product) === chooserId), [entries, chooserId, traits]);
4067
- useEffect4(() => {
4255
+ useEffect5(() => {
4068
4256
  if (chooserId !== null && choices.length === 0) setChooserId(null);
4069
4257
  }, [chooserId, choices]);
4070
4258
  function select(entry) {
4071
4259
  onSelect(entry);
4072
4260
  setChooserId(null);
4073
4261
  }
4074
- return /* @__PURE__ */ jsxs49(View56, { className: "flex-1", onLayout: (event) => setWidth(event.nativeEvent.layout.width), children: [
4075
- /* @__PURE__ */ jsxs49(View56, { className: "gap-2 border-b border-border bg-card px-4 pb-3 pt-3", children: [
4076
- /* @__PURE__ */ jsx90(
4262
+ return /* @__PURE__ */ jsxs50(View57, { className: "flex-1", onLayout: (event) => setWidth(event.nativeEvent.layout.width), children: [
4263
+ /* @__PURE__ */ jsxs50(View57, { className: "gap-2 border-b border-border bg-card px-4 pb-3 pt-3", children: [
4264
+ /* @__PURE__ */ jsx91(
4077
4265
  SearchInput,
4078
4266
  {
4079
4267
  value: query,
@@ -4090,25 +4278,25 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4090
4278
  }
4091
4279
  }
4092
4280
  ),
4093
- statusText || statusAccessory ? /* @__PURE__ */ jsxs49(View56, { testID: "catalogue-status-row", className: "flex-row items-center gap-2", children: [
4094
- statusText ? /* @__PURE__ */ jsxs49(Text35, { className: "flex-1 text-xs text-muted-foreground", numberOfLines: statusAccessory ? 1 : void 0, children: [
4281
+ statusText || statusAccessory ? /* @__PURE__ */ jsxs50(View57, { testID: "catalogue-status-row", className: "flex-row items-center gap-2", children: [
4282
+ statusText ? /* @__PURE__ */ jsxs50(Text36, { className: "flex-1 text-xs text-muted-foreground", numberOfLines: statusAccessory ? 1 : void 0, children: [
4095
4283
  statusText,
4096
4284
  query.trim() ? ` \xB7 ${results.length.toLocaleString()} matching` : ""
4097
4285
  ] }) : null,
4098
4286
  statusAccessory
4099
4287
  ] }) : null,
4100
- choices.length > 0 ? /* @__PURE__ */ jsxs49(View56, { accessibilityLabel: "Choose variant", className: "gap-2", children: [
4101
- choices.map((entry) => /* @__PURE__ */ jsxs49(
4102
- Pressable25,
4288
+ choices.length > 0 ? /* @__PURE__ */ jsxs50(View57, { accessibilityLabel: "Choose variant", className: "gap-2", children: [
4289
+ choices.map((entry) => /* @__PURE__ */ jsxs50(
4290
+ Pressable27,
4103
4291
  {
4104
4292
  accessibilityRole: "button",
4105
4293
  onPress: () => select(entry),
4106
4294
  className: "gap-1 rounded-md border border-border p-3",
4107
4295
  children: [
4108
- /* @__PURE__ */ jsx90(Text35, { className: "font-semibold text-foreground", children: entry.variant.title }),
4109
- /* @__PURE__ */ jsx90(Text35, { className: "text-muted-foreground", children: entry.variant.sku }),
4110
- /* @__PURE__ */ jsx90(Text35, { className: "text-foreground", children: variantPriceLabel(entry.variant, currency) }),
4111
- /* @__PURE__ */ jsxs49(Text35, { className: "text-muted-foreground", children: [
4296
+ /* @__PURE__ */ jsx91(Text36, { className: "font-semibold text-foreground", children: entry.variant.title }),
4297
+ /* @__PURE__ */ jsx91(Text36, { className: "text-muted-foreground", children: entry.variant.sku }),
4298
+ /* @__PURE__ */ jsx91(Text36, { className: "text-foreground", children: variantPriceLabel(entry.variant, currency) }),
4299
+ /* @__PURE__ */ jsxs50(Text36, { className: "text-muted-foreground", children: [
4112
4300
  STOCK_LABEL[entry.variant.stock.status],
4113
4301
  " \xB7 ",
4114
4302
  stockAsOf ? `as of ${formatStockSyncTime(stockAsOf, void 0, hour12)}` : "not yet synced"
@@ -4117,10 +4305,10 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4117
4305
  },
4118
4306
  entry.variant.id
4119
4307
  )),
4120
- /* @__PURE__ */ jsx90(Pressable25, { accessibilityRole: "button", onPress: () => setChooserId(null), className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx90(Text35, { className: "text-center text-foreground", children: "Cancel" }) })
4308
+ /* @__PURE__ */ jsx91(Pressable27, { accessibilityRole: "button", onPress: () => setChooserId(null), className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx91(Text36, { className: "text-center text-foreground", children: "Cancel" }) })
4121
4309
  ] }) : null
4122
4310
  ] }),
4123
- /* @__PURE__ */ jsx90(
4311
+ /* @__PURE__ */ jsx91(
4124
4312
  ProductGrid,
4125
4313
  {
4126
4314
  items: results,
@@ -4129,26 +4317,26 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4129
4317
  // TallyUI's ProductCard has no children slot, so the tile is composed directly here
4130
4318
  // (same structure/classes as ProductCard) to add the stock badge as a fourth child,
4131
4319
  // inside the card and centred with the rest, rather than adding a slot to ProductCard (out of scope for TV6b).
4132
- /* @__PURE__ */ jsx90(Pressable25, { accessibilityRole: "button", testID: `product-tile-${traits.getName(product)}`, onPress: () => {
4320
+ /* @__PURE__ */ jsx91(Pressable27, { accessibilityRole: "button", testID: `product-tile-${traits.getName(product)}`, onPress: () => {
4133
4321
  const variants = entries.filter((entry) => entry.product === product);
4134
4322
  if (variants.length === 1) select(variants[0]);
4135
4323
  else setChooserId(traits.getId(product));
4136
- }, children: /* @__PURE__ */ jsxs49(VStack, { space: "sm", className: "items-center rounded-lg border border-border bg-card p-3", children: [
4137
- /* @__PURE__ */ jsx90(ProductImage, { doc: product, size: 80, className: "rounded-md" }),
4138
- /* @__PURE__ */ jsx90(ProductTitle, { doc: product, className: "text-sm", numberOfLines: 2 }),
4139
- /* @__PURE__ */ jsx90(ProductPrice, { doc: product }),
4140
- /* @__PURE__ */ jsx90(ProductStockBadge, { doc: product, showAsOf: false, className: "self-center" })
4324
+ }, children: /* @__PURE__ */ jsxs50(VStack, { space: "sm", className: "items-center rounded-lg border border-border bg-card p-3", children: [
4325
+ /* @__PURE__ */ jsx91(ProductImage, { doc: product, size: 80, className: "rounded-md" }),
4326
+ /* @__PURE__ */ jsx91(ProductTitle, { doc: product, className: "text-sm", numberOfLines: 2 }),
4327
+ /* @__PURE__ */ jsx91(ProductPrice, { doc: product }),
4328
+ /* @__PURE__ */ jsx91(ProductStockBadge, { doc: product, showAsOf: false, className: "self-center" })
4141
4329
  ] }) })
4142
4330
  ),
4143
- emptyState: /* @__PURE__ */ jsx90(Text35, { className: "mt-10 text-center text-sm text-muted-foreground", children: query.trim() ? `No products match "${query.trim()}".` : "No products yet." })
4331
+ emptyState: /* @__PURE__ */ jsx91(Text36, { className: "mt-10 text-center text-sm text-muted-foreground", children: query.trim() ? `No products match "${query.trim()}".` : "No products yet." })
4144
4332
  }
4145
4333
  )
4146
4334
  ] });
4147
4335
  }
4148
4336
 
4149
4337
  // src/sale/receipt.tsx
4150
- import { useEffect as useEffect5 } from "react";
4151
- import { Pressable as Pressable26, Text as Text36, View as View57 } from "react-native";
4338
+ import { useEffect as useEffect6 } from "react";
4339
+ import { Pressable as Pressable28, Text as Text37, View as View58 } from "react-native";
4152
4340
  import { formatMoney as formatMoney13 } from "@tallyui/core";
4153
4341
  import { buildReceiptData as buildReceiptData3 } from "@tallyui/pos";
4154
4342
 
@@ -4163,7 +4351,7 @@ function injectPrintStyle() {
4163
4351
  }
4164
4352
 
4165
4353
  // src/sale/receipt.tsx
4166
- import { Fragment as Fragment6, jsx as jsx91, jsxs as jsxs50 } from "react/jsx-runtime";
4354
+ import { Fragment as Fragment6, jsx as jsx92, jsxs as jsxs51 } from "react/jsx-runtime";
4167
4355
  var defaultFormatDate = (iso) => new Intl.DateTimeFormat(void 0, { dateStyle: "medium", timeStyle: "short" }).format(new Date(iso));
4168
4356
  function Receipt({
4169
4357
  order,
@@ -4175,7 +4363,7 @@ function Receipt({
4175
4363
  topInset = 0,
4176
4364
  formatDate = defaultFormatDate
4177
4365
  }) {
4178
- useEffect5(injectPrintStyle, []);
4366
+ useEffect6(injectPrintStyle, []);
4179
4367
  const receipt = buildReceiptData3(order, {
4180
4368
  storeName: store.name,
4181
4369
  storeAddress: store.address,
@@ -4183,30 +4371,34 @@ function Receipt({
4183
4371
  register: registerId
4184
4372
  });
4185
4373
  const money = (amount) => formatMoney13({ amount, currency: receipt.currency }) ?? "";
4186
- const row = (label, amount, bold = false, key) => /* @__PURE__ */ jsxs50(View57, { accessibilityLabel: `${label}: ${amount}`, className: "flex-row justify-between gap-4", children: [
4187
- /* @__PURE__ */ jsx91(Text36, { className: `text-foreground ${bold ? "font-semibold" : ""}`, children: label }),
4188
- /* @__PURE__ */ jsx91(Text36, { className: `text-right text-foreground ${bold ? "font-semibold" : ""}`, children: amount })
4374
+ const row = (label, amount, bold = false, key) => /* @__PURE__ */ jsxs51(View58, { accessibilityLabel: `${label}: ${amount}`, className: "flex-row justify-between gap-4", children: [
4375
+ /* @__PURE__ */ jsx92(Text37, { className: `text-foreground ${bold ? "font-semibold" : ""}`, children: label }),
4376
+ /* @__PURE__ */ jsx92(Text37, { className: `text-right text-foreground ${bold ? "font-semibold" : ""}`, children: amount })
4189
4377
  ] }, key);
4190
4378
  const { totals } = receipt;
4191
4379
  const taxRows = totals.taxLines.map((line, index) => row(`${totals.taxInclusive ? "incl. " : ""}${taxLabel(line.ratePpm)}`, money(line.amountMinor), false, index));
4192
- return /* @__PURE__ */ jsxs50(Fragment6, { children: [
4193
- topInset > 0 ? /* @__PURE__ */ jsx91(View57, { dataSet: { print: "hide" }, style: { height: topInset, flexShrink: 0 } }) : null,
4194
- /* @__PURE__ */ jsxs50(View57, { className: "w-full max-w-md self-center gap-3 p-4 bg-card", children: [
4195
- /* @__PURE__ */ jsx91(Text36, { className: "text-lg font-semibold text-foreground", children: receipt.header.storeName }),
4196
- receipt.header.storeAddress ? /* @__PURE__ */ jsx91(Text36, { className: "text-muted-foreground", children: receipt.header.storeAddress }) : null,
4197
- /* @__PURE__ */ jsxs50(Text36, { className: "text-foreground", children: [
4380
+ return /* @__PURE__ */ jsxs51(Fragment6, { children: [
4381
+ topInset > 0 ? /* @__PURE__ */ jsx92(View58, { dataSet: { print: "hide" }, style: { height: topInset, flexShrink: 0 } }) : null,
4382
+ /* @__PURE__ */ jsxs51(View58, { className: "w-full max-w-md self-center gap-3 p-4 bg-card", children: [
4383
+ /* @__PURE__ */ jsx92(Text37, { className: "text-lg font-semibold text-foreground", children: receipt.header.storeName }),
4384
+ receipt.header.storeAddress ? /* @__PURE__ */ jsx92(Text37, { className: "text-muted-foreground", children: receipt.header.storeAddress }) : null,
4385
+ /* @__PURE__ */ jsxs51(Text37, { className: "text-foreground", children: [
4198
4386
  "Order ",
4199
4387
  receipt.header.orderNumber.slice(-8)
4200
4388
  ] }),
4201
- /* @__PURE__ */ jsx91(Text36, { className: "text-muted-foreground", children: formatDate(receipt.header.date) }),
4202
- /* @__PURE__ */ jsxs50(Text36, { className: "text-muted-foreground", children: [
4389
+ /* @__PURE__ */ jsx92(Text37, { className: "text-muted-foreground", children: formatDate(receipt.header.date) }),
4390
+ /* @__PURE__ */ jsxs51(Text37, { className: "text-muted-foreground", children: [
4203
4391
  "Cashier: ",
4204
4392
  receipt.header.cashier
4205
4393
  ] }),
4206
- receipt.lineItems.map((line, index) => /* @__PURE__ */ jsxs50(View57, { children: [
4207
- /* @__PURE__ */ jsx91(Text36, { className: "text-foreground", children: line.name }),
4394
+ receipt.header.customer && /* @__PURE__ */ jsxs51(Text37, { className: "text-muted-foreground", children: [
4395
+ "Customer: ",
4396
+ receipt.header.customer
4397
+ ] }),
4398
+ receipt.lineItems.map((line, index) => /* @__PURE__ */ jsxs51(View58, { children: [
4399
+ /* @__PURE__ */ jsx92(Text37, { className: "text-foreground", children: line.name }),
4208
4400
  row(`${line.quantity} \xD7 ${money(line.unitPriceMinor)}`, money(line.displayAmountMinor)),
4209
- line.displayDiscounts.map((discount, i) => /* @__PURE__ */ jsx91(View57, { className: "pl-4", children: row(`${discountLabel(
4401
+ line.displayDiscounts.map((discount, i) => /* @__PURE__ */ jsx92(View58, { className: "pl-4", children: row(`${discountLabel(
4210
4402
  order.lineItems[index].discounts[i],
4211
4403
  receipt.currency
4212
4404
  )} off`, `\u2212${money(discount.amountMinor)}`) }, i))
@@ -4223,82 +4415,165 @@ function Receipt({
4223
4415
  index
4224
4416
  )),
4225
4417
  row("Change", money(receipt.changeDueMinor)),
4226
- /* @__PURE__ */ jsxs50(View57, { dataSet: { print: "hide" }, className: "flex-row gap-4", children: [
4227
- /* @__PURE__ */ jsx91(Pressable26, { accessibilityRole: "button", onPress: () => {
4418
+ /* @__PURE__ */ jsxs51(View58, { dataSet: { print: "hide" }, className: "flex-row gap-4", children: [
4419
+ /* @__PURE__ */ jsx92(Pressable28, { accessibilityRole: "button", onPress: () => {
4228
4420
  if (typeof window !== "undefined" && typeof window.print === "function") window.print();
4229
- }, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx91(Text36, { className: "text-center text-foreground", children: "Print receipt" }) }),
4230
- /* @__PURE__ */ jsx91(Pressable26, { accessibilityRole: "button", onPress: newSale, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx91(Text36, { className: "text-center font-semibold text-primary-foreground", children: "New sale" }) })
4421
+ }, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx92(Text37, { className: "text-center text-foreground", children: "Print receipt" }) }),
4422
+ /* @__PURE__ */ jsx92(Pressable28, { accessibilityRole: "button", onPress: newSale, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx92(Text37, { className: "text-center font-semibold text-primary-foreground", children: "New sale" }) })
4231
4423
  ] })
4232
4424
  ] })
4233
4425
  ] });
4234
4426
  }
4235
4427
 
4236
4428
  // src/sale/sync-status.tsx
4237
- import { useEffect as useEffect6, useState as useState17 } from "react";
4238
- import { Text as Text37 } from "react-native";
4239
- import { jsxs as jsxs51 } from "react/jsx-runtime";
4240
- function SyncStatus({ state }) {
4241
- const [now, setNow] = useState17(Date.now);
4242
- useEffect6(() => {
4429
+ import { useEffect as useEffect7, useRef as useRef6, useState as useState18 } from "react";
4430
+ import { AccessibilityInfo as AccessibilityInfo2, Platform as Platform3, Text as Text38, View as View59 } from "react-native";
4431
+ import { Fragment as Fragment7, jsx as jsx93, jsxs as jsxs52 } from "react/jsx-runtime";
4432
+ var PULL_NOTICE_TEXT = {
4433
+ unauthorized: {
4434
+ line: () => "Products aren't updating: this till needs to sign in to the online store again.",
4435
+ detail: () => "You can keep selling. Products, prices and stock stay as they were until someone signs in again."
4436
+ },
4437
+ till_update_required: {
4438
+ line: () => "Products aren't updating: this till needs updating.",
4439
+ detail: () => "You can keep selling. Products, prices and stock stay as they were until this till is updated."
4440
+ },
4441
+ unsupported_store: {
4442
+ line: () => "Products aren't updating: the online store needs a software update.",
4443
+ detail: ({ software, minVersion }) => software && minVersion ? `You can keep selling. Ask the store owner to update ${software} to version ${minVersion} or later.` : "You can keep selling. Ask the store owner to update the store's software."
4444
+ },
4445
+ missing_plugin: {
4446
+ line: (pluginName) => `Products aren't updating: the online store is missing ${pluginName}.`,
4447
+ detail: (_notice, pluginName) => `You can keep selling. This till couldn't find ${pluginName} on the online store. Ask the store owner to check that it is installed and switched on, and that the store address in this till's settings is right.`
4448
+ },
4449
+ store_misconfigured: {
4450
+ line: () => "Products aren't updating: a setting on the online store needs changing.",
4451
+ detail: ({ fix }) => fix ? `You can keep selling. Ask the store owner to ${fix}.` : "You can keep selling. Ask the store owner to check the store's settings."
4452
+ }
4453
+ };
4454
+ var PULL_NOTICE_FALLBACK = {
4455
+ line: () => "Products aren't updating.",
4456
+ detail: () => "You can keep selling. Products, prices and stock stay as they were. Restart the app; if it keeps happening, tell the store owner."
4457
+ };
4458
+ var BACKEND_MISSING = "Sales aren't reaching the online store. Keep selling: they're saved on this till and will send by themselves.";
4459
+ var BACKEND_MISSING_SINCE = "Sales haven't reached the online store since {time}. Keep selling: they're saved on this till and will send by themselves.";
4460
+ var TILL_UPDATES_MISSING = "Till updates aren't reaching the online store. Keep selling: they're saved on this till and will send by themselves.";
4461
+ var TILL_UPDATES_MISSING_SINCE = "Till updates haven't reached the online store since {time}. Keep selling: they're saved on this till and will send by themselves.";
4462
+ var BACKEND_MISSING_DETAIL = "This till couldn't find {pluginName} on the online store{lastTime}. Ask the store owner to check that it is installed and switched on, and that the store address in this till's settings is right.";
4463
+ var REFUSED = (n, waiting) => n === 1 ? `1 sale needs attention${waiting} \xB7 The online store refused it. Ask the store owner to look at the till's sync log.` : `${n} sales need attention${waiting} \xB7 The online store refused them. Ask the store owner to look at the till's sync log.`;
4464
+ var REFUSED_DETAIL = "Refused sales stay on this till under Needs attention, each with what to do next.";
4465
+ var SALES_REFUSED = "The online store refused the last send. This till will try again with the next sale, or when the app is reopened.";
4466
+ var TILL_UPDATES_REFUSED = "The online store refused the last send. This till will try again with the next till update.";
4467
+ var count = (n, noun) => `${n} ${noun}${n === 1 ? "" : "s"}`;
4468
+ function useAnnounceOnIos(...texts) {
4469
+ const announced = useRef6(texts);
4470
+ useEffect7(() => {
4471
+ const changed = texts.filter((text, index) => text && text !== announced.current[index]);
4472
+ announced.current = texts;
4473
+ if (changed.length > 0 && Platform3.OS === "ios") AccessibilityInfo2.announceForAccessibility(changed.join(" "));
4474
+ }, texts);
4475
+ }
4476
+ function SyncStatus({ state, registerState, pluginName = "the POS plugin", pullNotice }) {
4477
+ const updates = registerState?.pending ?? 0;
4478
+ const outbox = state.pending === 0 && registerState?.pending ? registerState : state;
4479
+ const [now, setNow] = useState18(Date.now);
4480
+ useEffect7(() => {
4243
4481
  setNow(Date.now());
4244
- if (!state.nextAttemptAt) return;
4482
+ if (!outbox.nextAttemptAt) return;
4245
4483
  const timer = setInterval(() => setNow(Date.now()), 1e3);
4246
4484
  return () => clearInterval(timer);
4247
- }, [state.nextAttemptAt]);
4248
- const seconds = Math.max(0, Math.ceil(((state.nextAttemptAt ?? now) - now) / 1e3));
4249
- const label = state.pending === 0 ? "All sales synced" : `${state.pending} sale${state.pending === 1 ? "" : "s"} waiting to sync`;
4250
- return /* @__PURE__ */ jsxs51(Text37, { accessibilityLabel: "Sync status", className: "px-4 py-2 text-xs text-muted-foreground", children: [
4251
- label,
4252
- state.sending ? " \xB7 sending" : state.lastRetryReason ? ` \xB7 retrying (${state.lastRetryReason}) in ${seconds}s` : ""
4485
+ }, [outbox.nextAttemptAt]);
4486
+ const seconds = Math.max(0, Math.ceil(((outbox.nextAttemptAt ?? now) - now) / 1e3));
4487
+ const label = [
4488
+ state.pending && count(state.pending, "sale"),
4489
+ updates && count(updates, "till update")
4490
+ ].filter(Boolean).join(" and ") + " waiting to sync";
4491
+ const { stuck } = state;
4492
+ const backendMissing = state.backendMissing ?? registerState?.backendMissing;
4493
+ const at = (time) => new Date(time).toLocaleTimeString(void 0, { hour: "numeric", minute: "2-digit" });
4494
+ const backendMissingText = state.pending === 0 && updates > 0 ? registerState?.stuck ? TILL_UPDATES_MISSING_SINCE.replace("{time}", () => at(registerState.stuck.since)) : TILL_UPDATES_MISSING : stuck ? BACKEND_MISSING_SINCE.replace("{time}", () => at(stuck.since)) : BACKEND_MISSING;
4495
+ const upToDate = state.pending === 0 && updates === 0;
4496
+ const sentence = outbox.refused ? ` \xB7 ${outbox === state ? SALES_REFUSED : TILL_UPDATES_REFUSED}` : backendMissing || (state.pending === 0 && updates > 0 ? registerState?.stuck : stuck) ? ` \xB7 ${backendMissingText}` : "";
4497
+ const refused = state.rejected ? REFUSED(state.rejected, upToDate ? "" : `, ${updates ? label : `${state.pending} waiting to sync`}`) : "";
4498
+ const spoken = refused || (upToDate ? "Sales are up to date." : label + sentence);
4499
+ const doing = refused || upToDate || backendMissing || outbox.refused ? "" : outbox.sending ? "Sending\u2026" : outbox.lastRetryReason ? `Retrying in ${seconds} s.` : "";
4500
+ const text = pullNotice && (Object.hasOwn(PULL_NOTICE_TEXT, pullNotice.code) ? PULL_NOTICE_TEXT[pullNotice.code] : PULL_NOTICE_FALLBACK);
4501
+ const notice = pullNotice && text && { line: text.line(pluginName), detail: text.detail(pullNotice, pluginName) };
4502
+ useAnnounceOnIos(notice?.line, spoken);
4503
+ const oneDetail = pullNotice?.code === "missing_plugin" && !!backendMissing;
4504
+ return /* @__PURE__ */ jsxs52(View59, { children: [
4505
+ notice ? /* @__PURE__ */ jsxs52(Fragment7, { children: [
4506
+ /* @__PURE__ */ jsx93(Text38, { accessibilityLiveRegion: "polite", className: "px-4 py-2 text-xs text-muted-foreground", children: notice.line }),
4507
+ oneDetail ? null : /* @__PURE__ */ jsx93(Text38, { className: "px-4 pb-2 text-xs text-muted-foreground", children: notice.detail })
4508
+ ] }) : null,
4509
+ /* @__PURE__ */ jsx93(Text38, { accessibilityLabel: spoken, accessibilityLiveRegion: "polite", className: "px-4 py-2 text-xs text-muted-foreground", children: spoken }),
4510
+ doing ? /* @__PURE__ */ jsx93(Text38, { className: "px-4 pb-2 text-xs text-muted-foreground", children: doing }) : null,
4511
+ refused ? /* @__PURE__ */ jsx93(Text38, { className: "px-4 pb-2 text-xs text-muted-foreground", children: REFUSED_DETAIL }) : null,
4512
+ oneDetail && notice ? /* @__PURE__ */ jsx93(Text38, { className: "px-4 pb-2 text-xs text-muted-foreground", children: notice.detail }) : backendMissing ? /* @__PURE__ */ jsx93(Text38, { 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
4253
4513
  ] });
4254
4514
  }
4255
4515
 
4256
4516
  // src/sale/orders-list.tsx
4257
- import { useEffect as useEffect7, useRef as useRef5, useState as useState18 } from "react";
4258
- import { Pressable as Pressable27, ScrollView as ScrollView14, Text as Text38, View as View58 } from "react-native";
4259
- import { formatMoney as formatMoney14 } from "@tallyui/core";
4517
+ import { useEffect as useEffect8, useRef as useRef7, useState as useState19 } from "react";
4518
+ import { Pressable as Pressable29, ScrollView as ScrollView13, Text as Text39, View as View60 } from "react-native";
4519
+ import { formatMoney as formatMoney14, knownWarnings } from "@tallyui/core";
4260
4520
  import { needsAttention } from "@tallyui/pos";
4261
- import { jsx as jsx92, jsxs as jsxs52 } from "react/jsx-runtime";
4521
+ import { jsx as jsx94, jsxs as jsxs53 } from "react/jsx-runtime";
4262
4522
  var STATUS_LABEL = { pending: "Waiting to sync", applied: "Synced", rejected: "Not accepted" };
4523
+ var FIGURE_LABELS = /* @__PURE__ */ new Map([["subtotalMinor", "Subtotal"], ["taxMinor", "Tax"], ["discountMinor", "Discount"]]);
4524
+ var REFUSAL_SENTENCES = /* @__PURE__ */ new Map([
4525
+ ["invalid_payload", "The online store refused this sale: this till sent it in a form the store can't read. Ask the store owner to look at the till's sync log."],
4526
+ ["unsupported_version", "The online store refused this sale: the store's software is older than this till's. Ask the store owner to update the POS plugin."],
4527
+ ["idempotency_mismatch", "The online store has a different sale under this sale's number. Don't send it again; ask the store owner to compare the two."],
4528
+ ["store_configuration", "The online store refused this sale: a setting on the store needs changing. Once the store owner fixes it, press Retry."],
4529
+ ["platform_error", "The online store refused this sale. Ask the store owner to look at the till's sync log."],
4530
+ ["internal_error", "The online store hit a fault in its POS plugin and refused this sale. Ask the store owner to look at the till's sync log."],
4531
+ ["insufficient_stock", "The online store refused this sale: it doesn't have enough stock of one of the items."],
4532
+ ["unsupported_tax_mode", "The online store refused this sale: its tax settings can't take a sale like this one. Ask the store owner to check them."],
4533
+ ["unknown_variant", "The online store refused this sale: that product variation no longer exists."],
4534
+ ["invalid_quantity", "The online store refused this sale: a quantity or a discount on it isn't allowed."],
4535
+ ["underpaid", "The online store refused this sale: the payments add up to less than the total."],
4536
+ ["unsupported_currency", "The online store refused this sale: the store doesn't take this currency."]
4537
+ ]);
4538
+ var refusalSentence = (code) => REFUSAL_SENTENCES.get(code ?? "") ?? REFUSAL_SENTENCES.get("platform_error");
4263
4539
  function defaultFormatDate2(iso) {
4264
4540
  const date = new Date(iso);
4265
4541
  return Number.isNaN(date.getTime()) ? iso : new Intl.DateTimeFormat(void 0, { dateStyle: "medium", timeStyle: "short" }).format(date);
4266
4542
  }
4267
- function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer }) {
4268
- const retrying = useRef5(/* @__PURE__ */ new Set());
4269
- const [retryingIds, setRetryingIds] = useState18(/* @__PURE__ */ new Set());
4270
- useEffect7(() => {
4543
+ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer, stuck }) {
4544
+ const retrying = useRef7(/* @__PURE__ */ new Set());
4545
+ const [retryingIds, setRetryingIds] = useState19(/* @__PURE__ */ new Set());
4546
+ useEffect8(() => {
4271
4547
  for (const id of retrying.current) {
4272
4548
  if (!orders.some((order) => order.id === id && order.syncStatus === "rejected")) retrying.current.delete(id);
4273
4549
  }
4274
4550
  setRetryingIds(new Set(retrying.current));
4275
4551
  }, [orders]);
4276
- return /* @__PURE__ */ jsxs52(ScrollView14, { className: "flex-1 bg-background p-4", children: [
4277
- [{ title: "Needs attention", orders: needsAttention(orders) }, { title: "Recent", orders }].filter((section) => section.title === "Recent" || section.orders.length > 0).map((section) => /* @__PURE__ */ jsxs52(View58, { className: "mb-6 gap-3", children: [
4278
- /* @__PURE__ */ jsx92(Text38, { accessibilityRole: "header", className: "text-xl font-semibold text-foreground", children: section.title }),
4552
+ return /* @__PURE__ */ jsxs53(ScrollView13, { className: "flex-1 bg-background p-4", children: [
4553
+ [{ title: "Needs attention", orders: needsAttention(orders, { stuckCommandIds: stuck?.commandIds }) }, { title: "Recent", orders }].filter((section) => section.title === "Recent" || section.orders.length > 0).map((section) => /* @__PURE__ */ jsxs53(View60, { className: "mb-6 gap-3", children: [
4554
+ /* @__PURE__ */ jsx94(Text39, { accessibilityRole: "header", className: "text-xl font-semibold text-foreground", children: section.title }),
4279
4555
  section.orders.map((order) => {
4280
- const count = order.lines.reduce((sum, line) => sum + line.quantity, 0);
4281
- return /* @__PURE__ */ jsxs52(View58, { className: "gap-1 rounded-md border border-border bg-card p-3", children: [
4282
- /* @__PURE__ */ jsxs52(Text38, { className: "text-foreground", children: [
4556
+ const count2 = order.lines.reduce((sum, line) => sum + line.quantity, 0);
4557
+ const stuckEntry = order.syncStatus === "pending" ? stuck?.orders.find((entry) => entry.commandId === order.commandId) : void 0;
4558
+ return /* @__PURE__ */ jsxs53(View60, { className: "gap-1 rounded-md border border-border bg-card p-3", children: [
4559
+ /* @__PURE__ */ jsxs53(Text39, { className: "text-foreground", children: [
4283
4560
  order.serverRefs?.displayId ? `Order #${order.serverRefs.displayId} \xB7 ` : "",
4284
- count,
4561
+ count2,
4285
4562
  " ",
4286
- count === 1 ? "item" : "items"
4563
+ count2 === 1 ? "item" : "items"
4287
4564
  ] }),
4288
- /* @__PURE__ */ jsxs52(Text38, { className: "text-muted-foreground", children: [
4565
+ /* @__PURE__ */ jsxs53(Text39, { className: "text-muted-foreground", children: [
4289
4566
  formatDate(order.createdAt),
4290
4567
  " \xB7 ",
4291
4568
  formatMoney14({ amount: order.totalMinor, currency: order.currency }),
4292
4569
  " \xB7 ",
4293
4570
  STATUS_LABEL[order.syncStatus]
4294
4571
  ] }),
4295
- order.syncStatus === "rejected" && order.error ? /* @__PURE__ */ jsxs52(Text38, { className: "text-destructive", children: [
4296
- order.error.code,
4297
- ": ",
4298
- order.error.message
4299
- ] }) : null,
4300
- order.lateSessionId !== void 0 ? /* @__PURE__ */ jsx92(Text38, { className: "text-foreground", children: "Taken after the register closed. It is not in that register's closure." }) : null,
4301
- section.title === "Needs attention" && order.syncStatus === "rejected" ? order.error?.code === "idempotency_mismatch" ? /* @__PURE__ */ jsx92(Text38, { className: "text-foreground", children: "This sale needs checking against the store before it can be sent again." }) : /* @__PURE__ */ jsx92(Pressable27, { accessibilityRole: "button", disabled: retryingIds.has(order.id), onPress: async () => {
4572
+ stuckEntry ? /* @__PURE__ */ jsx94(Text39, { className: "text-destructive", children: `Hasn't reached the online store since ${new Date(stuckEntry.since).toLocaleTimeString(void 0, { hour: "numeric", minute: "2-digit" })}.` }) : null,
4573
+ order.syncStatus === "rejected" ? /* @__PURE__ */ jsx94(Text39, { className: "text-destructive", children: refusalSentence(order.error?.code) }) : null,
4574
+ order.lateSessionId !== void 0 ? /* @__PURE__ */ jsx94(Text39, { className: "text-foreground", children: "Taken after the register closed. It is not in that register's closure." }) : null,
4575
+ order.localWarnings?.map((warning, index) => /* @__PURE__ */ jsx94(Text39, { 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)),
4576
+ section.title === "Needs attention" && order.syncStatus === "rejected" && order.error?.code !== "idempotency_mismatch" ? /* @__PURE__ */ jsx94(Pressable29, { accessibilityRole: "button", disabled: retryingIds.has(order.id), onPress: async () => {
4302
4577
  if (retrying.current.has(order.id)) return;
4303
4578
  retrying.current.add(order.id);
4304
4579
  setRetryingIds(new Set(retrying.current));
@@ -4306,8 +4581,8 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer }
4306
4581
  retrying.current.delete(order.id);
4307
4582
  setRetryingIds(new Set(retrying.current));
4308
4583
  }
4309
- }, className: "rounded-md bg-primary px-4 py-2", children: /* @__PURE__ */ jsx92(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Retry" }) }) : null,
4310
- order.warnings?.map((warning, index) => /* @__PURE__ */ jsx92(View58, { className: "border-l-4 border-warning pl-2", children: /* @__PURE__ */ jsx92(Text38, { className: "text-foreground", children: warning.code === "insufficient_stock" ? `Stock short by ${warning.quantity} for ${order.lines.find((line) => line.variantId === warning.variantId)?.name}` : `Store total ${formatMoney14({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney14({ amount: warning.expectedMinor, currency: order.currency })}` }) }, index))
4584
+ }, className: "rounded-md bg-primary px-4 py-2", children: /* @__PURE__ */ jsx94(Text39, { className: "text-center font-semibold text-primary-foreground", children: "Retry" }) }) : null,
4585
+ knownWarnings(order.warnings).map((warning, index) => /* @__PURE__ */ jsx94(View60, { className: "border-l-4 border-warning pl-2", children: /* @__PURE__ */ jsx94(Text39, { 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 ${formatMoney14({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney14({ 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 ${formatMoney14({ amount: tillMinor, currency: order.currency })}, store ${formatMoney14({ amount: serverMinor, currency: order.currency })}.`).join(" ")}` : warning.bridgeMinor !== void 0 ? `Store calculated ${formatMoney14({ amount: warning.serverMinor, currency: order.currency })}; a rounding line of ${warning.bridgeMinor > 0 ? "+" : ""}${formatMoney14({ amount: warning.bridgeMinor, currency: order.currency })} brought it to ${formatMoney14({ amount: warning.expectedMinor, currency: order.currency })}` : `Store total ${formatMoney14({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney14({ amount: warning.expectedMinor, currency: order.currency })}` }) }, index))
4311
4586
  ] }, order.id);
4312
4587
  })
4313
4588
  ] }, section.title)),
@@ -4316,10 +4591,10 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer }
4316
4591
  }
4317
4592
 
4318
4593
  // src/layout/pos-layout.tsx
4319
- import { useState as useState19 } from "react";
4320
- import { Pressable as Pressable28, Text as Text39, View as View59, useWindowDimensions as useWindowDimensions3 } from "react-native";
4321
- import { cn as cn79 } from "@tallyui/theme";
4322
- import { Fragment as Fragment7, jsx as jsx93, jsxs as jsxs53 } from "react/jsx-runtime";
4594
+ import { useState as useState20 } from "react";
4595
+ import { Pressable as Pressable30, Text as Text40, View as View61, useWindowDimensions as useWindowDimensions3 } from "react-native";
4596
+ import { cn as cn80 } from "@tallyui/theme";
4597
+ import { Fragment as Fragment8, jsx as jsx95, jsxs as jsxs54 } from "react/jsx-runtime";
4323
4598
  function POSLayout({
4324
4599
  browseSlot,
4325
4600
  cartSlot,
@@ -4331,40 +4606,40 @@ function POSLayout({
4331
4606
  }) {
4332
4607
  const { width } = useWindowDimensions3();
4333
4608
  const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
4334
- const [activeTab, setActiveTab] = useState19("browse");
4335
- return /* @__PURE__ */ jsxs53(View59, { className: cn79("flex-1 bg-bg", className), ...viewProps, children: [
4336
- headerSlot && /* @__PURE__ */ jsx93(View59, { className: "border-b border-border", children: headerSlot }),
4337
- layout === "split" ? /* @__PURE__ */ jsxs53(View59, { className: "flex-1 flex-row", children: [
4338
- /* @__PURE__ */ jsx93(View59, { className: "flex-[3]", children: browseSlot }),
4339
- /* @__PURE__ */ jsx93(View59, { className: "flex-[2] border-l border-border", children: cartSlot })
4340
- ] }) : /* @__PURE__ */ jsxs53(Fragment7, { children: [
4341
- /* @__PURE__ */ jsxs53(View59, { className: "flex-row border-b border-border", children: [
4342
- /* @__PURE__ */ jsx93(
4343
- Pressable28,
4609
+ const [activeTab, setActiveTab] = useState20("browse");
4610
+ return /* @__PURE__ */ jsxs54(View61, { className: cn80("flex-1 bg-bg", className), ...viewProps, children: [
4611
+ headerSlot && /* @__PURE__ */ jsx95(View61, { className: "border-b border-border", children: headerSlot }),
4612
+ layout === "split" ? /* @__PURE__ */ jsxs54(View61, { className: "flex-1 flex-row", children: [
4613
+ /* @__PURE__ */ jsx95(View61, { className: "flex-[3]", children: browseSlot }),
4614
+ /* @__PURE__ */ jsx95(View61, { className: "flex-[2] border-l border-border", children: cartSlot })
4615
+ ] }) : /* @__PURE__ */ jsxs54(Fragment8, { children: [
4616
+ /* @__PURE__ */ jsxs54(View61, { className: "flex-row border-b border-border", children: [
4617
+ /* @__PURE__ */ jsx95(
4618
+ Pressable30,
4344
4619
  {
4345
4620
  onPress: () => setActiveTab("browse"),
4346
- className: cn79("flex-1 py-3", activeTab === "browse" && "border-b-2 border-primary"),
4347
- children: /* @__PURE__ */ jsx93(Text39, { className: cn79("text-center text-sm font-semibold", activeTab === "browse" ? "text-primary" : "text-muted-foreground"), children: "Browse" })
4621
+ className: cn80("flex-1 py-3", activeTab === "browse" && "border-b-2 border-primary"),
4622
+ children: /* @__PURE__ */ jsx95(Text40, { className: cn80("text-center text-sm font-semibold", activeTab === "browse" ? "text-primary" : "text-muted-foreground"), children: "Browse" })
4348
4623
  }
4349
4624
  ),
4350
- /* @__PURE__ */ jsx93(
4351
- Pressable28,
4625
+ /* @__PURE__ */ jsx95(
4626
+ Pressable30,
4352
4627
  {
4353
4628
  onPress: () => setActiveTab("cart"),
4354
- className: cn79("flex-1 py-3", activeTab === "cart" && "border-b-2 border-primary"),
4355
- children: /* @__PURE__ */ jsx93(Text39, { className: cn79("text-center text-sm font-semibold", activeTab === "cart" ? "text-primary" : "text-muted-foreground"), children: "Cart" })
4629
+ className: cn80("flex-1 py-3", activeTab === "cart" && "border-b-2 border-primary"),
4630
+ children: /* @__PURE__ */ jsx95(Text40, { className: cn80("text-center text-sm font-semibold", activeTab === "cart" ? "text-primary" : "text-muted-foreground"), children: "Cart" })
4356
4631
  }
4357
4632
  )
4358
4633
  ] }),
4359
- /* @__PURE__ */ jsx93(View59, { className: "flex-1", children: activeTab === "browse" ? browseSlot : cartSlot })
4634
+ /* @__PURE__ */ jsx95(View61, { className: "flex-1", children: activeTab === "browse" ? browseSlot : cartSlot })
4360
4635
  ] })
4361
4636
  ] });
4362
4637
  }
4363
4638
 
4364
4639
  // src/layout/checkout-layout.tsx
4365
- import { ScrollView as ScrollView15, View as View60, useWindowDimensions as useWindowDimensions4 } from "react-native";
4366
- import { cn as cn80 } from "@tallyui/theme";
4367
- import { jsx as jsx94, jsxs as jsxs54 } from "react/jsx-runtime";
4640
+ import { ScrollView as ScrollView14, View as View62, useWindowDimensions as useWindowDimensions4 } from "react-native";
4641
+ import { cn as cn81 } from "@tallyui/theme";
4642
+ import { jsx as jsx96, jsxs as jsxs55 } from "react/jsx-runtime";
4368
4643
  function CheckoutLayout({
4369
4644
  summarySlot,
4370
4645
  paymentSlot,
@@ -4376,12 +4651,12 @@ function CheckoutLayout({
4376
4651
  }) {
4377
4652
  const { width } = useWindowDimensions4();
4378
4653
  const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
4379
- return /* @__PURE__ */ jsxs54(View60, { className: cn80("flex-1 bg-bg", className), ...viewProps, children: [
4380
- headerSlot && /* @__PURE__ */ jsx94(View60, { className: "border-b border-border", children: headerSlot }),
4381
- layout === "split" ? /* @__PURE__ */ jsxs54(View60, { className: "flex-1 flex-row", children: [
4382
- /* @__PURE__ */ jsx94(View60, { className: "flex-1 border-r border-border", children: summarySlot }),
4383
- /* @__PURE__ */ jsx94(View60, { className: "flex-1", children: paymentSlot })
4384
- ] }) : /* @__PURE__ */ jsx94(ScrollView15, { className: "flex-1", children: /* @__PURE__ */ jsxs54(View60, { className: "gap-4 p-4", children: [
4654
+ return /* @__PURE__ */ jsxs55(View62, { className: cn81("flex-1 bg-bg", className), ...viewProps, children: [
4655
+ headerSlot && /* @__PURE__ */ jsx96(View62, { className: "border-b border-border", children: headerSlot }),
4656
+ layout === "split" ? /* @__PURE__ */ jsxs55(View62, { className: "flex-1 flex-row", children: [
4657
+ /* @__PURE__ */ jsx96(View62, { className: "flex-1 border-r border-border", children: summarySlot }),
4658
+ /* @__PURE__ */ jsx96(View62, { className: "flex-1", children: paymentSlot })
4659
+ ] }) : /* @__PURE__ */ jsx96(ScrollView14, { className: "flex-1", children: /* @__PURE__ */ jsxs55(View62, { className: "gap-4 p-4", children: [
4385
4660
  summarySlot,
4386
4661
  paymentSlot
4387
4662
  ] }) })
@@ -4389,10 +4664,10 @@ function CheckoutLayout({
4389
4664
  }
4390
4665
 
4391
4666
  // src/layout/settings-layout.tsx
4392
- import { useState as useState20 } from "react";
4393
- import { Pressable as Pressable29, Text as Text40, View as View61, useWindowDimensions as useWindowDimensions5 } from "react-native";
4394
- import { cn as cn81 } from "@tallyui/theme";
4395
- import { jsx as jsx95, jsxs as jsxs55 } from "react/jsx-runtime";
4667
+ import { useState as useState21 } from "react";
4668
+ import { Pressable as Pressable31, Text as Text41, View as View63, useWindowDimensions as useWindowDimensions5 } from "react-native";
4669
+ import { cn as cn82 } from "@tallyui/theme";
4670
+ import { jsx as jsx97, jsxs as jsxs56 } from "react/jsx-runtime";
4396
4671
  function SettingsLayout({
4397
4672
  navSlot,
4398
4673
  contentSlot,
@@ -4404,26 +4679,26 @@ function SettingsLayout({
4404
4679
  }) {
4405
4680
  const { width } = useWindowDimensions5();
4406
4681
  const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
4407
- const [showNav, setShowNav] = useState20(false);
4408
- return /* @__PURE__ */ jsxs55(View61, { className: cn81("flex-1 bg-bg", className), ...viewProps, children: [
4409
- headerSlot && /* @__PURE__ */ jsx95(View61, { className: "border-b border-border", children: headerSlot }),
4410
- layout === "split" ? /* @__PURE__ */ jsxs55(View61, { className: "flex-1 flex-row", children: [
4411
- /* @__PURE__ */ jsx95(View61, { className: "w-64 border-r border-border", children: navSlot }),
4412
- /* @__PURE__ */ jsx95(View61, { className: "flex-1", children: contentSlot })
4413
- ] }) : /* @__PURE__ */ jsx95(View61, { className: "flex-1", children: showNav ? /* @__PURE__ */ jsxs55(View61, { className: "flex-1", children: [
4682
+ const [showNav, setShowNav] = useState21(false);
4683
+ return /* @__PURE__ */ jsxs56(View63, { className: cn82("flex-1 bg-bg", className), ...viewProps, children: [
4684
+ headerSlot && /* @__PURE__ */ jsx97(View63, { className: "border-b border-border", children: headerSlot }),
4685
+ layout === "split" ? /* @__PURE__ */ jsxs56(View63, { className: "flex-1 flex-row", children: [
4686
+ /* @__PURE__ */ jsx97(View63, { className: "w-64 border-r border-border", children: navSlot }),
4687
+ /* @__PURE__ */ jsx97(View63, { className: "flex-1", children: contentSlot })
4688
+ ] }) : /* @__PURE__ */ jsx97(View63, { className: "flex-1", children: showNav ? /* @__PURE__ */ jsxs56(View63, { className: "flex-1", children: [
4414
4689
  navSlot,
4415
- /* @__PURE__ */ jsx95(Pressable29, { onPress: () => setShowNav(false), className: "border-t border-border p-3", children: /* @__PURE__ */ jsx95(Text40, { className: "text-center text-sm font-medium text-primary", children: "Done" }) })
4416
- ] }) : /* @__PURE__ */ jsxs55(View61, { className: "flex-1", children: [
4417
- /* @__PURE__ */ jsx95(Pressable29, { onPress: () => setShowNav(true), className: "border-b border-border px-4 py-2", children: /* @__PURE__ */ jsx95(Text40, { className: "text-sm font-medium text-primary", children: "Menu" }) }),
4690
+ /* @__PURE__ */ jsx97(Pressable31, { onPress: () => setShowNav(false), className: "border-t border-border p-3", children: /* @__PURE__ */ jsx97(Text41, { className: "text-center text-sm font-medium text-primary", children: "Done" }) })
4691
+ ] }) : /* @__PURE__ */ jsxs56(View63, { className: "flex-1", children: [
4692
+ /* @__PURE__ */ jsx97(Pressable31, { onPress: () => setShowNav(true), className: "border-b border-border px-4 py-2", children: /* @__PURE__ */ jsx97(Text41, { className: "text-sm font-medium text-primary", children: "Menu" }) }),
4418
4693
  contentSlot
4419
4694
  ] }) })
4420
4695
  ] });
4421
4696
  }
4422
4697
 
4423
4698
  // src/layout/live-tab-screen.tsx
4424
- import { Pressable as Pressable30, Text as Text41, View as View62 } from "react-native";
4425
- import { cn as cn82 } from "@tallyui/theme";
4426
- import { jsx as jsx96, jsxs as jsxs56 } from "react/jsx-runtime";
4699
+ import { Pressable as Pressable32, Text as Text42, View as View64 } from "react-native";
4700
+ import { cn as cn83 } from "@tallyui/theme";
4701
+ import { jsx as jsx98, jsxs as jsxs57 } from "react/jsx-runtime";
4427
4702
  function LiveTabScreen({
4428
4703
  state,
4429
4704
  onUseHere,
@@ -4440,21 +4715,21 @@ function LiveTabScreen({
4440
4715
  const body = state === "parked" ? parkedBody : blockedBody;
4441
4716
  const buttonLabel = state === "parked" ? useHereLabel : reloadLabel;
4442
4717
  const onPress = state === "parked" ? onUseHere : onReload;
4443
- return /* @__PURE__ */ jsxs56(View62, { className: cn82("flex-1 items-center justify-center gap-4 bg-bg p-6", className), ...viewProps, children: [
4444
- /* @__PURE__ */ jsx96(Text41, { className: "text-center text-lg font-bold text-foreground", children: parkedTitle }),
4445
- /* @__PURE__ */ jsx96(Text41, { className: "text-center text-sm text-muted-foreground", children: body }),
4446
- /* @__PURE__ */ jsx96(Pressable30, { onPress, className: "items-center rounded-lg bg-primary px-4 py-3", children: /* @__PURE__ */ jsx96(Text41, { className: "text-sm font-semibold text-primary-foreground", children: buttonLabel }) })
4718
+ return /* @__PURE__ */ jsxs57(View64, { className: cn83("flex-1 items-center justify-center gap-4 bg-bg p-6", className), ...viewProps, children: [
4719
+ /* @__PURE__ */ jsx98(Text42, { className: "text-center text-lg font-bold text-foreground", children: parkedTitle }),
4720
+ /* @__PURE__ */ jsx98(Text42, { className: "text-center text-sm text-muted-foreground", children: body }),
4721
+ /* @__PURE__ */ jsx98(Pressable32, { onPress, className: "items-center rounded-lg bg-primary px-4 py-3", children: /* @__PURE__ */ jsx98(Text42, { className: "text-sm font-semibold text-primary-foreground", children: buttonLabel }) })
4447
4722
  ] });
4448
4723
  }
4449
4724
 
4450
4725
  // src/layout/store-settings-choice-screen.tsx
4451
- import { useState as useState21 } from "react";
4452
- import { Pressable as Pressable31, Text as Text42, View as View63 } from "react-native";
4453
- import { cn as cn83 } from "@tallyui/theme";
4454
- import { jsx as jsx97, jsxs as jsxs57 } from "react/jsx-runtime";
4726
+ import { useState as useState22 } from "react";
4727
+ import { Pressable as Pressable33, Text as Text43, View as View65 } from "react-native";
4728
+ import { cn as cn84 } from "@tallyui/theme";
4729
+ import { jsx as jsx99, jsxs as jsxs58 } from "react/jsx-runtime";
4455
4730
  function useSectionSelection(options, initialValue) {
4456
4731
  const preset = options.length === 1 ? options[0].value : options.find((o) => o.value === initialValue)?.value;
4457
- return useState21(preset);
4732
+ return useState22(preset);
4458
4733
  }
4459
4734
  function defaultCountryName(code, locale) {
4460
4735
  try {
@@ -4500,41 +4775,41 @@ function StoreSettingsChoiceScreen({
4500
4775
  else if (initial?.channel !== void 0) choice.channel = initial.channel;
4501
4776
  onSubmit(choice);
4502
4777
  };
4503
- return /* @__PURE__ */ jsxs57(View63, { className: cn83("w-full max-w-[560px] flex-1 self-center gap-6 bg-bg p-6", className), ...viewProps, children: [
4504
- /* @__PURE__ */ jsxs57(View63, { className: "gap-2", children: [
4505
- /* @__PURE__ */ jsx97(Text42, { className: "text-lg font-bold text-foreground", children: title }),
4506
- /* @__PURE__ */ jsx97(Text42, { className: "text-sm text-muted-foreground", children: body })
4778
+ return /* @__PURE__ */ jsxs58(View65, { className: cn84("w-full max-w-[560px] flex-1 self-center gap-6 bg-bg p-6", className), ...viewProps, children: [
4779
+ /* @__PURE__ */ jsxs58(View65, { className: "gap-2", children: [
4780
+ /* @__PURE__ */ jsx99(Text43, { className: "text-lg font-bold text-foreground", children: title }),
4781
+ /* @__PURE__ */ jsx99(Text43, { className: "text-sm text-muted-foreground", children: body })
4507
4782
  ] }),
4508
- showRegions && /* @__PURE__ */ jsx97(ChoiceSection, { label: regionLabel, options: regionOptions, selected: region, onSelect: setRegion }),
4509
- showCountries && /* @__PURE__ */ jsx97(ChoiceSection, { label: countryLabel, options: countryOptions, selected: country, onSelect: setCountry }),
4510
- showChannels && /* @__PURE__ */ jsx97(ChoiceSection, { label: channelLabel, options: channelOptions, selected: channel, onSelect: setChannel }),
4511
- /* @__PURE__ */ jsx97(
4512
- Pressable31,
4783
+ showRegions && /* @__PURE__ */ jsx99(ChoiceSection, { label: regionLabel, options: regionOptions, selected: region, onSelect: setRegion }),
4784
+ showCountries && /* @__PURE__ */ jsx99(ChoiceSection, { label: countryLabel, options: countryOptions, selected: country, onSelect: setCountry }),
4785
+ showChannels && /* @__PURE__ */ jsx99(ChoiceSection, { label: channelLabel, options: channelOptions, selected: channel, onSelect: setChannel }),
4786
+ /* @__PURE__ */ jsx99(
4787
+ Pressable33,
4513
4788
  {
4514
4789
  onPress: handleSubmit,
4515
4790
  disabled: !complete,
4516
- className: cn83("items-center rounded-lg bg-primary px-4 py-3", !complete && "opacity-50"),
4517
- children: /* @__PURE__ */ jsx97(Text42, { className: "text-sm font-semibold text-primary-foreground", children: submitLabel })
4791
+ className: cn84("items-center rounded-lg bg-primary px-4 py-3", !complete && "opacity-50"),
4792
+ children: /* @__PURE__ */ jsx99(Text43, { className: "text-sm font-semibold text-primary-foreground", children: submitLabel })
4518
4793
  }
4519
4794
  )
4520
4795
  ] });
4521
4796
  }
4522
4797
  function ChoiceSection({ label, options, selected, onSelect }) {
4523
- return /* @__PURE__ */ jsxs57(View63, { className: "gap-1.5", children: [
4524
- /* @__PURE__ */ jsx97(Text42, { className: "text-xs font-semibold text-muted-foreground", children: label }),
4525
- /* @__PURE__ */ jsx97(View63, { className: "rounded-lg border border-border", children: options.map((option, index) => {
4798
+ return /* @__PURE__ */ jsxs58(View65, { className: "gap-1.5", children: [
4799
+ /* @__PURE__ */ jsx99(Text43, { className: "text-xs font-semibold text-muted-foreground", children: label }),
4800
+ /* @__PURE__ */ jsx99(View65, { className: "rounded-lg border border-border", children: options.map((option, index) => {
4526
4801
  const checked = option.value === selected;
4527
- return /* @__PURE__ */ jsxs57(
4528
- Pressable31,
4802
+ return /* @__PURE__ */ jsxs58(
4803
+ Pressable33,
4529
4804
  {
4530
4805
  onPress: () => onSelect(option.value),
4531
4806
  accessibilityRole: "radio",
4532
4807
  "aria-checked": checked,
4533
4808
  testID: `choice-option-${option.value}`,
4534
- className: cn83("flex-row items-center gap-3 px-4 py-3", index > 0 && "border-t border-border", checked && "bg-primary/10"),
4809
+ className: cn84("flex-row items-center gap-3 px-4 py-3", index > 0 && "border-t border-border", checked && "bg-primary/10"),
4535
4810
  children: [
4536
- /* @__PURE__ */ jsx97(View63, { className: "h-4 w-4 items-center justify-center rounded-full border border-primary", children: checked && /* @__PURE__ */ jsx97(View63, { testID: `choice-option-${option.value}-dot`, className: "h-2.5 w-2.5 rounded-full bg-primary" }) }),
4537
- /* @__PURE__ */ jsx97(Text42, { className: cn83("text-sm", checked ? "font-semibold text-primary" : "text-foreground"), children: option.label })
4811
+ /* @__PURE__ */ jsx99(View65, { className: "h-4 w-4 items-center justify-center rounded-full border border-primary", children: checked && /* @__PURE__ */ jsx99(View65, { testID: `choice-option-${option.value}-dot`, className: "h-2.5 w-2.5 rounded-full bg-primary" }) }),
4812
+ /* @__PURE__ */ jsx99(Text43, { className: cn84("text-sm", checked ? "font-semibold text-primary" : "text-foreground"), children: option.label })
4538
4813
  ]
4539
4814
  },
4540
4815
  option.value
@@ -4610,6 +4885,7 @@ export {
4610
4885
  CustomerCard,
4611
4886
  CustomerForm,
4612
4887
  CustomerOrderHistory,
4888
+ CustomerPicker,
4613
4889
  CustomerSelect,
4614
4890
  Dialog,
4615
4891
  DialogClose,