@tallyui/components 3.3.0 → 3.5.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.d.ts +105 -5
- package/dist/index.js +1338 -927
- package/package.json +9 -9
- package/src/index.ts +8 -0
- package/src/product/category-nav.tsx +7 -2
- package/src/product/index.ts +2 -0
- package/src/product/product-table.tsx +153 -0
- package/src/product/view-toggle.tsx +31 -0
- package/src/sale/cart.tsx +32 -6
- package/src/sale/catalogue.tsx +108 -21
- package/src/sale/charge-form.tsx +71 -0
- package/src/sale/index.ts +1 -0
- package/src/sale/receipt.tsx +2 -0
package/dist/index.js
CHANGED
|
@@ -1848,10 +1848,158 @@ function ProductGrid({
|
|
|
1848
1848
|
] });
|
|
1849
1849
|
}
|
|
1850
1850
|
|
|
1851
|
-
// src/product/
|
|
1852
|
-
import {
|
|
1851
|
+
// src/product/view-toggle.tsx
|
|
1852
|
+
import { Pressable as Pressable8, Text as Text11, View as View20 } from "react-native";
|
|
1853
1853
|
import { cn as cn43 } from "@tallyui/theme";
|
|
1854
|
-
import { jsx as jsx46
|
|
1854
|
+
import { jsx as jsx46 } from "react/jsx-runtime";
|
|
1855
|
+
function ViewToggle({ value, onChange, labels, className, ...viewProps }) {
|
|
1856
|
+
return /* @__PURE__ */ jsx46(
|
|
1857
|
+
View20,
|
|
1858
|
+
{
|
|
1859
|
+
...viewProps,
|
|
1860
|
+
role: "radiogroup",
|
|
1861
|
+
accessibilityLabel: "View",
|
|
1862
|
+
testID: "view-toggle",
|
|
1863
|
+
className: cn43("flex-row self-start overflow-hidden rounded-md border border-border", className),
|
|
1864
|
+
children: ["grid", "table"].map((view) => {
|
|
1865
|
+
const selected = value === view;
|
|
1866
|
+
const label = labels?.[view] ?? (view === "grid" ? "Grid" : "Table");
|
|
1867
|
+
return /* @__PURE__ */ jsx46(
|
|
1868
|
+
Pressable8,
|
|
1869
|
+
{
|
|
1870
|
+
role: "radio",
|
|
1871
|
+
"aria-checked": selected,
|
|
1872
|
+
testID: `view-toggle-${view}`,
|
|
1873
|
+
accessibilityLabel: label,
|
|
1874
|
+
onPress: () => {
|
|
1875
|
+
if (!selected) onChange(view);
|
|
1876
|
+
},
|
|
1877
|
+
className: cn43("px-3 py-2", selected ? "bg-primary" : "bg-card"),
|
|
1878
|
+
children: /* @__PURE__ */ jsx46(Text11, { className: cn43("text-sm font-medium", selected ? "text-primary-foreground" : "text-foreground"), children: label })
|
|
1879
|
+
},
|
|
1880
|
+
view
|
|
1881
|
+
);
|
|
1882
|
+
})
|
|
1883
|
+
}
|
|
1884
|
+
);
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
// src/product/product-table.tsx
|
|
1888
|
+
import { useMemo, useState as useState3 } from "react";
|
|
1889
|
+
import { FlatList as FlatList2, Pressable as Pressable9, View as View21 } from "react-native";
|
|
1890
|
+
import { useProductTraits as useProductTraits7, useTraitContext as useTraitContext2, useStockOverlaid } from "@tallyui/core";
|
|
1891
|
+
import { productSortValue, sortProducts } from "@tallyui/pos";
|
|
1892
|
+
import { cn as cn44 } from "@tallyui/theme";
|
|
1893
|
+
import { jsx as jsx47, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1894
|
+
var INITIAL_ROWS2 = 8;
|
|
1895
|
+
var BATCH_ROWS2 = 8;
|
|
1896
|
+
var WINDOW_SIZE2 = 5;
|
|
1897
|
+
function defaultProductColumns(traits, context, options) {
|
|
1898
|
+
const columns = [
|
|
1899
|
+
{ id: "name", header: "Name", flex: 3, render: (doc) => /* @__PURE__ */ jsx47(ProductTitle, { doc, numberOfLines: 2 }) },
|
|
1900
|
+
{ id: "sku", header: "SKU", flex: 1, render: (doc) => /* @__PURE__ */ jsx47(ProductSku, { doc }) },
|
|
1901
|
+
{ id: "barcode", header: "Barcode", flex: 1, render: (doc) => /* @__PURE__ */ jsx47(Text, { children: traits.getBarcode(doc) ?? "\u2014" }) },
|
|
1902
|
+
{ id: "price", header: "Price", flex: 1, render: (doc) => /* @__PURE__ */ jsx47(ProductPrice, { doc, currencySymbol: options?.currencySymbol }) },
|
|
1903
|
+
{ id: "stock", header: "Stock", flex: 1, render: (doc) => /* @__PURE__ */ jsx47(ProductStockBadge, { doc, showQuantity: true, showAsOf: false }) },
|
|
1904
|
+
{ id: "category", header: "Category", flex: 2, render: (doc) => /* @__PURE__ */ jsx47(Text, { children: traits.getCategoryNames(doc).join(", ") || "\u2014" }) }
|
|
1905
|
+
];
|
|
1906
|
+
return columns.map((column) => ({
|
|
1907
|
+
...column,
|
|
1908
|
+
sortValue: (doc) => productSortValue(doc, column.id, traits, context)
|
|
1909
|
+
}));
|
|
1910
|
+
}
|
|
1911
|
+
function useDefaultProductColumns(options) {
|
|
1912
|
+
const traits = useProductTraits7();
|
|
1913
|
+
const context = useTraitContext2();
|
|
1914
|
+
const currencySymbol4 = options?.currencySymbol;
|
|
1915
|
+
return useMemo(() => defaultProductColumns(traits, context, { currencySymbol: currencySymbol4 }), [traits, context, currencySymbol4]);
|
|
1916
|
+
}
|
|
1917
|
+
function ProductTable({
|
|
1918
|
+
items,
|
|
1919
|
+
columns,
|
|
1920
|
+
sort,
|
|
1921
|
+
defaultSort = null,
|
|
1922
|
+
onSortChange,
|
|
1923
|
+
sortItems = true,
|
|
1924
|
+
onSelect,
|
|
1925
|
+
searchSlot,
|
|
1926
|
+
filterSlot,
|
|
1927
|
+
emptyState,
|
|
1928
|
+
showUnsellable = false,
|
|
1929
|
+
currencySymbol: currencySymbol4,
|
|
1930
|
+
className,
|
|
1931
|
+
...viewProps
|
|
1932
|
+
}) {
|
|
1933
|
+
let traits;
|
|
1934
|
+
try {
|
|
1935
|
+
traits = useProductTraits7();
|
|
1936
|
+
} catch {
|
|
1937
|
+
traits = void 0;
|
|
1938
|
+
}
|
|
1939
|
+
const context = useTraitContext2();
|
|
1940
|
+
const resolvedColumns = useMemo(() => columns ?? (traits ? defaultProductColumns(traits, context, { currencySymbol: currencySymbol4 }) : []), [columns, traits, context, currencySymbol4]);
|
|
1941
|
+
const [internalSort, setInternalSort] = useState3(defaultSort);
|
|
1942
|
+
const activeSort = sort === void 0 ? internalSort : sort;
|
|
1943
|
+
const visibleItems = showUnsellable || !traits ? items : items.filter((item) => traits.isSellable(item));
|
|
1944
|
+
const overlaidItems = useStockOverlaid(visibleItems);
|
|
1945
|
+
const rows = sortItems ? sortProducts(
|
|
1946
|
+
[...overlaidItems],
|
|
1947
|
+
activeSort,
|
|
1948
|
+
(doc, field) => resolvedColumns.find((column) => column.id === field)?.sortValue?.(doc)
|
|
1949
|
+
) : overlaidItems;
|
|
1950
|
+
const changeSort = (id) => {
|
|
1951
|
+
const next = activeSort?.field !== id ? { field: id, dir: "asc" } : activeSort.dir === "asc" ? { field: id, dir: "desc" } : null;
|
|
1952
|
+
if (sort === void 0) setInternalSort(next);
|
|
1953
|
+
onSortChange?.(next);
|
|
1954
|
+
};
|
|
1955
|
+
return /* @__PURE__ */ jsxs10(VStack, { space: "none", className: cn44("flex-1", className), ...viewProps, children: [
|
|
1956
|
+
searchSlot && /* @__PURE__ */ jsx47(View21, { className: "px-3 py-2", children: searchSlot }),
|
|
1957
|
+
filterSlot && /* @__PURE__ */ jsx47(View21, { className: "px-3 pb-2", children: filterSlot }),
|
|
1958
|
+
rows.length ? /* @__PURE__ */ jsxs10(Table, { className: "flex-1", children: [
|
|
1959
|
+
/* @__PURE__ */ jsx47(TableHeader, { children: /* @__PURE__ */ jsx47(TableRow, { children: resolvedColumns.map((column) => /* @__PURE__ */ jsx47(
|
|
1960
|
+
TableHead,
|
|
1961
|
+
{
|
|
1962
|
+
style: { flex: column.flex ?? 1 },
|
|
1963
|
+
...column.sortValue ? { "aria-sort": activeSort?.field === column.id ? activeSort.dir === "asc" ? "ascending" : "descending" : "none" } : {},
|
|
1964
|
+
children: column.sortValue ? /* @__PURE__ */ jsx47(
|
|
1965
|
+
Pressable9,
|
|
1966
|
+
{
|
|
1967
|
+
accessibilityRole: "button",
|
|
1968
|
+
accessibilityLabel: "Sort by " + column.header,
|
|
1969
|
+
testID: "product-table-sort-" + column.id,
|
|
1970
|
+
onPress: () => changeSort(column.id),
|
|
1971
|
+
children: /* @__PURE__ */ jsxs10(Text, { children: [
|
|
1972
|
+
column.header,
|
|
1973
|
+
activeSort?.field === column.id ? activeSort.dir === "asc" ? " \u25B2" : " \u25BC" : ""
|
|
1974
|
+
] })
|
|
1975
|
+
}
|
|
1976
|
+
) : /* @__PURE__ */ jsx47(Text, { children: column.header })
|
|
1977
|
+
},
|
|
1978
|
+
column.id
|
|
1979
|
+
)) }) }),
|
|
1980
|
+
/* @__PURE__ */ jsx47(TableBody, { className: "flex-1", children: /* @__PURE__ */ jsx47(
|
|
1981
|
+
FlatList2,
|
|
1982
|
+
{
|
|
1983
|
+
data: rows,
|
|
1984
|
+
keyExtractor: (item, index) => String(item.id ?? index),
|
|
1985
|
+
initialNumToRender: INITIAL_ROWS2,
|
|
1986
|
+
maxToRenderPerBatch: BATCH_ROWS2,
|
|
1987
|
+
windowSize: WINDOW_SIZE2,
|
|
1988
|
+
renderItem: ({ item, index }) => {
|
|
1989
|
+
const key = String(item.id ?? index);
|
|
1990
|
+
const row = /* @__PURE__ */ jsx47(TableRow, { testID: onSelect ? void 0 : "product-row-" + key, children: resolvedColumns.map((column) => /* @__PURE__ */ jsx47(TableCell, { style: { flex: column.flex ?? 1 }, children: column.render(item) }, column.id)) });
|
|
1991
|
+
return onSelect ? /* @__PURE__ */ jsx47(Pressable9, { accessibilityRole: "button", testID: "product-row-" + key, onPress: () => onSelect(item), children: row }) : row;
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
) })
|
|
1995
|
+
] }) : emptyState ?? null
|
|
1996
|
+
] });
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
// src/product/product-list.tsx
|
|
2000
|
+
import { ScrollView as ScrollView2, View as View22 } from "react-native";
|
|
2001
|
+
import { cn as cn45 } from "@tallyui/theme";
|
|
2002
|
+
import { jsx as jsx48, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1855
2003
|
function ProductList({
|
|
1856
2004
|
items,
|
|
1857
2005
|
renderItem,
|
|
@@ -1862,17 +2010,17 @@ function ProductList({
|
|
|
1862
2010
|
...viewProps
|
|
1863
2011
|
}) {
|
|
1864
2012
|
const hasItems = items.length > 0;
|
|
1865
|
-
return /* @__PURE__ */
|
|
1866
|
-
searchSlot && /* @__PURE__ */
|
|
1867
|
-
filterSlot && /* @__PURE__ */
|
|
1868
|
-
hasItems ? /* @__PURE__ */
|
|
2013
|
+
return /* @__PURE__ */ jsxs11(View22, { className: cn45("flex-1", className), ...viewProps, children: [
|
|
2014
|
+
searchSlot && /* @__PURE__ */ jsx48(View22, { className: "px-3 py-2", children: searchSlot }),
|
|
2015
|
+
filterSlot && /* @__PURE__ */ jsx48(View22, { className: "px-3 pb-2", children: filterSlot }),
|
|
2016
|
+
hasItems ? /* @__PURE__ */ jsx48(ScrollView2, { className: "flex-1", children: items.map((item, index) => /* @__PURE__ */ jsx48(View22, { className: "border-b border-border", children: renderItem(item, index) }, item.id ?? index)) }) : emptyState ?? null
|
|
1869
2017
|
] });
|
|
1870
2018
|
}
|
|
1871
2019
|
|
|
1872
2020
|
// src/product/category-nav.tsx
|
|
1873
|
-
import { Pressable as
|
|
1874
|
-
import { cn as
|
|
1875
|
-
import { jsx as
|
|
2021
|
+
import { Pressable as Pressable10, ScrollView as ScrollView3, Text as Text12, View as View23 } from "react-native";
|
|
2022
|
+
import { cn as cn46 } from "@tallyui/theme";
|
|
2023
|
+
import { jsx as jsx49 } from "react/jsx-runtime";
|
|
1876
2024
|
function CategoryNav({
|
|
1877
2025
|
categories,
|
|
1878
2026
|
selectedId,
|
|
@@ -1884,18 +2032,21 @@ function CategoryNav({
|
|
|
1884
2032
|
const isHorizontal = orientation === "horizontal";
|
|
1885
2033
|
const content = categories.map((cat) => {
|
|
1886
2034
|
const active = cat.id === selectedId;
|
|
1887
|
-
return /* @__PURE__ */
|
|
1888
|
-
|
|
2035
|
+
return /* @__PURE__ */ jsx49(
|
|
2036
|
+
Pressable10,
|
|
1889
2037
|
{
|
|
2038
|
+
testID: `category-nav-${cat.id}`,
|
|
2039
|
+
role: "radio",
|
|
2040
|
+
"aria-checked": active,
|
|
1890
2041
|
onPress: () => onSelect(cat.id),
|
|
1891
|
-
className:
|
|
1892
|
-
"rounded-
|
|
2042
|
+
className: cn46(
|
|
2043
|
+
"rounded-md px-3 py-1.5",
|
|
1893
2044
|
active ? "bg-primary" : "bg-muted"
|
|
1894
2045
|
),
|
|
1895
|
-
children: /* @__PURE__ */
|
|
1896
|
-
|
|
2046
|
+
children: /* @__PURE__ */ jsx49(
|
|
2047
|
+
Text12,
|
|
1897
2048
|
{
|
|
1898
|
-
className:
|
|
2049
|
+
className: cn46(
|
|
1899
2050
|
"text-sm font-medium",
|
|
1900
2051
|
active ? "text-primary-foreground" : "text-foreground"
|
|
1901
2052
|
),
|
|
@@ -1907,25 +2058,27 @@ function CategoryNav({
|
|
|
1907
2058
|
);
|
|
1908
2059
|
});
|
|
1909
2060
|
if (isHorizontal) {
|
|
1910
|
-
return /* @__PURE__ */
|
|
2061
|
+
return /* @__PURE__ */ jsx49(
|
|
1911
2062
|
ScrollView3,
|
|
1912
2063
|
{
|
|
1913
2064
|
horizontal: true,
|
|
1914
2065
|
showsHorizontalScrollIndicator: false,
|
|
1915
2066
|
contentContainerClassName: "flex-row gap-2 px-3 py-2",
|
|
1916
2067
|
className,
|
|
2068
|
+
role: "radiogroup",
|
|
2069
|
+
accessibilityLabel: "Categories",
|
|
1917
2070
|
...viewProps,
|
|
1918
2071
|
children: content
|
|
1919
2072
|
}
|
|
1920
2073
|
);
|
|
1921
2074
|
}
|
|
1922
|
-
return /* @__PURE__ */
|
|
2075
|
+
return /* @__PURE__ */ jsx49(View23, { className: cn46("gap-1 p-2", className), role: "radiogroup", accessibilityLabel: "Categories", ...viewProps, children: content });
|
|
1923
2076
|
}
|
|
1924
2077
|
|
|
1925
2078
|
// src/product/product-variant-picker.tsx
|
|
1926
|
-
import { Pressable as
|
|
1927
|
-
import { cn as
|
|
1928
|
-
import { jsx as
|
|
2079
|
+
import { Pressable as Pressable11, Text as Text13, View as View24 } from "react-native";
|
|
2080
|
+
import { cn as cn47 } from "@tallyui/theme";
|
|
2081
|
+
import { jsx as jsx50, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1929
2082
|
function ProductVariantPicker({
|
|
1930
2083
|
options,
|
|
1931
2084
|
selected = {},
|
|
@@ -1936,22 +2089,22 @@ function ProductVariantPicker({
|
|
|
1936
2089
|
const handleSelect = (optionName, value) => {
|
|
1937
2090
|
onSelect?.({ ...selected, [optionName]: value });
|
|
1938
2091
|
};
|
|
1939
|
-
return /* @__PURE__ */
|
|
1940
|
-
/* @__PURE__ */
|
|
1941
|
-
/* @__PURE__ */
|
|
2092
|
+
return /* @__PURE__ */ jsx50(View24, { className: cn47("gap-3", className), ...viewProps, children: options.map((option) => /* @__PURE__ */ jsxs12(View24, { className: "gap-1.5", children: [
|
|
2093
|
+
/* @__PURE__ */ jsx50(Text13, { className: "text-xs font-semibold text-muted-foreground", children: option.name }),
|
|
2094
|
+
/* @__PURE__ */ jsx50(View24, { className: "flex-row flex-wrap gap-2", children: option.values.map((value) => {
|
|
1942
2095
|
const active = selected[option.name] === value;
|
|
1943
|
-
return /* @__PURE__ */
|
|
1944
|
-
|
|
2096
|
+
return /* @__PURE__ */ jsx50(
|
|
2097
|
+
Pressable11,
|
|
1945
2098
|
{
|
|
1946
2099
|
onPress: () => handleSelect(option.name, value),
|
|
1947
|
-
className:
|
|
2100
|
+
className: cn47(
|
|
1948
2101
|
"rounded-lg border px-3 py-1.5",
|
|
1949
2102
|
active ? "border-primary bg-primary/10" : "border-border bg-card"
|
|
1950
2103
|
),
|
|
1951
|
-
children: /* @__PURE__ */
|
|
1952
|
-
|
|
2104
|
+
children: /* @__PURE__ */ jsx50(
|
|
2105
|
+
Text13,
|
|
1953
2106
|
{
|
|
1954
|
-
className:
|
|
2107
|
+
className: cn47(
|
|
1955
2108
|
"text-sm font-medium",
|
|
1956
2109
|
active ? "text-primary" : "text-foreground"
|
|
1957
2110
|
),
|
|
@@ -1967,22 +2120,22 @@ function ProductVariantPicker({
|
|
|
1967
2120
|
|
|
1968
2121
|
// src/cart/cart-line.tsx
|
|
1969
2122
|
import { formatMoney as formatMoney2 } from "@tallyui/core";
|
|
1970
|
-
import { cn as
|
|
1971
|
-
import { jsx as
|
|
2123
|
+
import { cn as cn48 } from "@tallyui/theme";
|
|
2124
|
+
import { jsx as jsx51, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1972
2125
|
function CartLine({ name, quantity, unitPrice, lineTotal, locale, className, ...props }) {
|
|
1973
|
-
return /* @__PURE__ */
|
|
1974
|
-
/* @__PURE__ */
|
|
1975
|
-
/* @__PURE__ */
|
|
1976
|
-
/* @__PURE__ */
|
|
2126
|
+
return /* @__PURE__ */ jsxs13(HStack, { className: cn48("px-3 py-2.5", className), ...props, children: [
|
|
2127
|
+
/* @__PURE__ */ jsxs13(VStack, { space: "none", className: "flex-1 gap-0.5", children: [
|
|
2128
|
+
/* @__PURE__ */ jsx51(Text, { className: "text-sm font-medium", numberOfLines: 1, children: name }),
|
|
2129
|
+
/* @__PURE__ */ jsx51(Text, { className: "text-xs text-muted-foreground", children: `${formatMoney2(unitPrice, locale) ?? "\u2014"} \xD7 ${quantity}` })
|
|
1977
2130
|
] }),
|
|
1978
|
-
/* @__PURE__ */
|
|
2131
|
+
/* @__PURE__ */ jsx51(Text, { className: "text-sm font-semibold", children: formatMoney2(lineTotal, locale) ?? "\u2014" })
|
|
1979
2132
|
] });
|
|
1980
2133
|
}
|
|
1981
2134
|
|
|
1982
2135
|
// src/cart/cart-total.tsx
|
|
1983
2136
|
import { formatMoney as formatMoney3 } from "@tallyui/core";
|
|
1984
|
-
import { cn as
|
|
1985
|
-
import { jsx as
|
|
2137
|
+
import { cn as cn49 } from "@tallyui/theme";
|
|
2138
|
+
import { jsx as jsx52, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1986
2139
|
function CartTotal({
|
|
1987
2140
|
subtotal,
|
|
1988
2141
|
taxLines,
|
|
@@ -1993,33 +2146,33 @@ function CartTotal({
|
|
|
1993
2146
|
className,
|
|
1994
2147
|
...props
|
|
1995
2148
|
}) {
|
|
1996
|
-
return /* @__PURE__ */
|
|
1997
|
-
/* @__PURE__ */
|
|
1998
|
-
/* @__PURE__ */
|
|
1999
|
-
/* @__PURE__ */
|
|
2149
|
+
return /* @__PURE__ */ jsxs14(VStack, { space: "none", className: cn49("gap-1.5 px-3 py-3", className), ...props, children: [
|
|
2150
|
+
/* @__PURE__ */ jsxs14(HStack, { space: "none", className: "justify-between", children: [
|
|
2151
|
+
/* @__PURE__ */ jsx52(Text, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
|
|
2152
|
+
/* @__PURE__ */ jsx52(Text, { className: "text-sm", children: formatMoney3(subtotal, locale) ?? "\u2014" })
|
|
2000
2153
|
] }),
|
|
2001
|
-
discount && discount.amount > 0 && /* @__PURE__ */
|
|
2002
|
-
/* @__PURE__ */
|
|
2003
|
-
/* @__PURE__ */
|
|
2154
|
+
discount && discount.amount > 0 && /* @__PURE__ */ jsxs14(HStack, { space: "none", className: "justify-between", children: [
|
|
2155
|
+
/* @__PURE__ */ jsx52(Text, { className: "text-sm text-muted-foreground", children: "Discount" }),
|
|
2156
|
+
/* @__PURE__ */ jsxs14(Text, { className: "text-sm", children: [
|
|
2004
2157
|
"\u2212",
|
|
2005
2158
|
formatMoney3(discount, locale) ?? "\u2014"
|
|
2006
2159
|
] })
|
|
2007
2160
|
] }),
|
|
2008
|
-
taxLines?.map((line, index) => /* @__PURE__ */
|
|
2009
|
-
/* @__PURE__ */
|
|
2010
|
-
/* @__PURE__ */
|
|
2161
|
+
taxLines?.map((line, index) => /* @__PURE__ */ jsxs14(HStack, { space: "none", className: "justify-between", children: [
|
|
2162
|
+
/* @__PURE__ */ jsx52(Text, { className: "text-sm text-muted-foreground", children: taxInclusive ? `incl. ${line.label}` : line.label }),
|
|
2163
|
+
/* @__PURE__ */ jsx52(Text, { className: "text-sm", children: formatMoney3(line.amount, locale) ?? "\u2014" })
|
|
2011
2164
|
] }, index)),
|
|
2012
|
-
/* @__PURE__ */
|
|
2013
|
-
/* @__PURE__ */
|
|
2014
|
-
/* @__PURE__ */
|
|
2165
|
+
/* @__PURE__ */ jsxs14(HStack, { space: "none", className: "mt-1.5 justify-between border-t border-border pt-2", children: [
|
|
2166
|
+
/* @__PURE__ */ jsx52(Text, { className: "font-bold", children: "Total" }),
|
|
2167
|
+
/* @__PURE__ */ jsx52(Text, { className: "font-bold", children: formatMoney3(total, locale) ?? "\u2014" })
|
|
2015
2168
|
] })
|
|
2016
2169
|
] });
|
|
2017
2170
|
}
|
|
2018
2171
|
|
|
2019
2172
|
// src/cart/cart-panel.tsx
|
|
2020
|
-
import { ScrollView as ScrollView4, View as
|
|
2021
|
-
import { cn as
|
|
2022
|
-
import { jsx as
|
|
2173
|
+
import { ScrollView as ScrollView4, View as View25 } from "react-native";
|
|
2174
|
+
import { cn as cn50 } from "@tallyui/theme";
|
|
2175
|
+
import { jsx as jsx53, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2023
2176
|
function defaultKey(item, index) {
|
|
2024
2177
|
const id = item?.id;
|
|
2025
2178
|
return typeof id === "string" || typeof id === "number" ? String(id) : String(index);
|
|
@@ -2036,36 +2189,36 @@ function CartPanel({
|
|
|
2036
2189
|
...props
|
|
2037
2190
|
}) {
|
|
2038
2191
|
const hasItems = items.length > 0;
|
|
2039
|
-
return /* @__PURE__ */
|
|
2040
|
-
header && /* @__PURE__ */
|
|
2041
|
-
/* @__PURE__ */
|
|
2042
|
-
hasItems ? items.map((item, index) => /* @__PURE__ */
|
|
2192
|
+
return /* @__PURE__ */ jsxs15(VStack, { space: "none", className: cn50("flex-1 min-h-0", className), ...props, children: [
|
|
2193
|
+
header && /* @__PURE__ */ jsx53(View25, { className: "border-b border-border px-3 py-2", children: header }),
|
|
2194
|
+
/* @__PURE__ */ jsxs15(ScrollView4, { className: "flex-1 min-h-0", contentContainerClassName: "flex-grow", children: [
|
|
2195
|
+
hasItems ? items.map((item, index) => /* @__PURE__ */ jsx53(View25, { children: renderItem(item, index) }, keyExtractor ? keyExtractor(item, index) : defaultKey(item, index))) : emptyState ?? null,
|
|
2043
2196
|
afterItems
|
|
2044
2197
|
] }),
|
|
2045
|
-
footer && /* @__PURE__ */
|
|
2198
|
+
footer && /* @__PURE__ */ jsx53(View25, { className: "border-t border-border px-3 py-2", children: footer })
|
|
2046
2199
|
] });
|
|
2047
2200
|
}
|
|
2048
2201
|
|
|
2049
2202
|
// src/cart/discount-badge.tsx
|
|
2050
|
-
import { Text as
|
|
2051
|
-
import { cn as
|
|
2052
|
-
import { jsx as
|
|
2203
|
+
import { Text as Text14, View as View26 } from "react-native";
|
|
2204
|
+
import { cn as cn51 } from "@tallyui/theme";
|
|
2205
|
+
import { jsx as jsx54 } from "react/jsx-runtime";
|
|
2053
2206
|
function DiscountBadge({ label, className, ...viewProps }) {
|
|
2054
|
-
return /* @__PURE__ */
|
|
2055
|
-
|
|
2207
|
+
return /* @__PURE__ */ jsx54(
|
|
2208
|
+
View26,
|
|
2056
2209
|
{
|
|
2057
|
-
className:
|
|
2210
|
+
className: cn51("flex-row items-center self-start gap-1 rounded-md bg-sale/15 px-1.5 py-0.5", className),
|
|
2058
2211
|
...viewProps,
|
|
2059
|
-
children: /* @__PURE__ */
|
|
2212
|
+
children: /* @__PURE__ */ jsx54(Text14, { className: "text-xs font-semibold text-sale", children: label })
|
|
2060
2213
|
}
|
|
2061
2214
|
);
|
|
2062
2215
|
}
|
|
2063
2216
|
|
|
2064
2217
|
// src/cart/cart-note-input.tsx
|
|
2065
|
-
import { useState as
|
|
2066
|
-
import { Pressable as
|
|
2067
|
-
import { cn as
|
|
2068
|
-
import { jsx as
|
|
2218
|
+
import { useState as useState4 } from "react";
|
|
2219
|
+
import { Pressable as Pressable12, Text as Text15, TextInput as TextInput4, View as View27 } from "react-native";
|
|
2220
|
+
import { cn as cn52 } from "@tallyui/theme";
|
|
2221
|
+
import { jsx as jsx55 } from "react/jsx-runtime";
|
|
2069
2222
|
function CartNoteInput({
|
|
2070
2223
|
value,
|
|
2071
2224
|
onChangeText,
|
|
@@ -2073,19 +2226,19 @@ function CartNoteInput({
|
|
|
2073
2226
|
className,
|
|
2074
2227
|
...viewProps
|
|
2075
2228
|
}) {
|
|
2076
|
-
const [expanded, setExpanded] =
|
|
2229
|
+
const [expanded, setExpanded] = useState4(value.length > 0);
|
|
2077
2230
|
if (!expanded) {
|
|
2078
|
-
return /* @__PURE__ */
|
|
2079
|
-
|
|
2231
|
+
return /* @__PURE__ */ jsx55(
|
|
2232
|
+
Pressable12,
|
|
2080
2233
|
{
|
|
2081
2234
|
onPress: () => setExpanded(true),
|
|
2082
|
-
className:
|
|
2235
|
+
className: cn52("flex-row items-center gap-1.5 px-3 py-2", className),
|
|
2083
2236
|
...viewProps,
|
|
2084
|
-
children: /* @__PURE__ */
|
|
2237
|
+
children: /* @__PURE__ */ jsx55(Text15, { className: "text-xs text-primary", children: "Add note" })
|
|
2085
2238
|
}
|
|
2086
2239
|
);
|
|
2087
2240
|
}
|
|
2088
|
-
return /* @__PURE__ */
|
|
2241
|
+
return /* @__PURE__ */ jsx55(View27, { className: cn52("px-3 py-2", className), ...viewProps, children: /* @__PURE__ */ jsx55(
|
|
2089
2242
|
TextInput4,
|
|
2090
2243
|
{
|
|
2091
2244
|
value,
|
|
@@ -2099,20 +2252,20 @@ function CartNoteInput({
|
|
|
2099
2252
|
}
|
|
2100
2253
|
|
|
2101
2254
|
// src/cart/cart-line-actions.tsx
|
|
2102
|
-
import { Pressable as
|
|
2103
|
-
import { cn as
|
|
2104
|
-
import { jsx as
|
|
2255
|
+
import { Pressable as Pressable13, Text as Text16, View as View28 } from "react-native";
|
|
2256
|
+
import { cn as cn53 } from "@tallyui/theme";
|
|
2257
|
+
import { jsx as jsx56, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2105
2258
|
function CartLineActions({ children, actions, className, ...viewProps }) {
|
|
2106
|
-
return /* @__PURE__ */
|
|
2107
|
-
/* @__PURE__ */
|
|
2108
|
-
/* @__PURE__ */
|
|
2109
|
-
|
|
2259
|
+
return /* @__PURE__ */ jsxs16(View28, { className: cn53("flex-row items-center", className), ...viewProps, children: [
|
|
2260
|
+
/* @__PURE__ */ jsx56(View28, { className: "flex-1", children }),
|
|
2261
|
+
/* @__PURE__ */ jsx56(View28, { className: "flex-row gap-1 px-2", children: actions.map((action) => /* @__PURE__ */ jsxs16(
|
|
2262
|
+
Pressable13,
|
|
2110
2263
|
{
|
|
2111
2264
|
onPress: action.onPress,
|
|
2112
2265
|
className: "rounded-md px-2 py-1.5",
|
|
2113
2266
|
children: [
|
|
2114
2267
|
action.iconSlot,
|
|
2115
|
-
/* @__PURE__ */
|
|
2268
|
+
/* @__PURE__ */ jsx56(Text16, { className: cn53("text-xs font-medium", action.color ?? "text-destructive"), children: action.label })
|
|
2116
2269
|
]
|
|
2117
2270
|
},
|
|
2118
2271
|
action.id
|
|
@@ -2121,21 +2274,21 @@ function CartLineActions({ children, actions, className, ...viewProps }) {
|
|
|
2121
2274
|
}
|
|
2122
2275
|
|
|
2123
2276
|
// src/input/search-input.tsx
|
|
2124
|
-
import { useId, useState as
|
|
2125
|
-
import { TextInput as TextInput5, View as
|
|
2277
|
+
import { useId, useState as useState5 } from "react";
|
|
2278
|
+
import { TextInput as TextInput5, View as View29 } from "react-native";
|
|
2126
2279
|
import { Label as Label3 } from "@tallyui/primitives";
|
|
2127
|
-
import { cn as
|
|
2128
|
-
import { jsx as
|
|
2280
|
+
import { cn as cn54 } from "@tallyui/theme";
|
|
2281
|
+
import { jsx as jsx57, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2129
2282
|
function SearchInput({ value, onChangeText, className, placeholder = "Search...", style, onFocus, onBlur, ...props }) {
|
|
2130
2283
|
const labelId = useId();
|
|
2131
|
-
const [focused, setFocused] =
|
|
2132
|
-
return /* @__PURE__ */
|
|
2284
|
+
const [focused, setFocused] = useState5(false);
|
|
2285
|
+
return /* @__PURE__ */ jsxs17(HStack, { space: "sm", className: cn54(
|
|
2133
2286
|
"rounded-lg border bg-card px-3 py-2.5",
|
|
2134
2287
|
focused ? "border-ring" : "border-border",
|
|
2135
2288
|
className
|
|
2136
2289
|
), children: [
|
|
2137
|
-
/* @__PURE__ */
|
|
2138
|
-
/* @__PURE__ */
|
|
2290
|
+
/* @__PURE__ */ jsx57(Label3.Root, { nativeID: labelId, asChild: true, children: /* @__PURE__ */ jsx57(View29, { "aria-hidden": true, className: "text-muted-foreground", children: /* @__PURE__ */ jsx57(SearchIcon, { size: 16 }) }) }),
|
|
2291
|
+
/* @__PURE__ */ jsx57(
|
|
2139
2292
|
TextInput5,
|
|
2140
2293
|
{
|
|
2141
2294
|
role: "searchbox",
|
|
@@ -2161,39 +2314,39 @@ function SearchInput({ value, onChangeText, className, placeholder = "Search..."
|
|
|
2161
2314
|
}
|
|
2162
2315
|
|
|
2163
2316
|
// src/input/filter-chip.tsx
|
|
2164
|
-
import { useMemo } from "react";
|
|
2165
|
-
import { Pressable as
|
|
2317
|
+
import { useMemo as useMemo2 } from "react";
|
|
2318
|
+
import { Pressable as Pressable14, ScrollView as ScrollView5 } from "react-native";
|
|
2166
2319
|
import { ToggleGroup as ToggleGroup3 } from "@tallyui/primitives";
|
|
2167
|
-
import { cn as
|
|
2168
|
-
import { jsx as
|
|
2320
|
+
import { cn as cn55 } from "@tallyui/theme";
|
|
2321
|
+
import { jsx as jsx58 } from "react/jsx-runtime";
|
|
2169
2322
|
function FilterChip({ label, active, onPress, className }) {
|
|
2170
|
-
const value =
|
|
2171
|
-
return /* @__PURE__ */
|
|
2323
|
+
const value = useMemo2(() => active ? [label] : [], [active, label]);
|
|
2324
|
+
return /* @__PURE__ */ jsx58(
|
|
2172
2325
|
ToggleGroup3.Root,
|
|
2173
2326
|
{
|
|
2174
2327
|
type: "multiple",
|
|
2175
2328
|
value,
|
|
2176
2329
|
onValueChange: () => onPress(),
|
|
2177
|
-
children: /* @__PURE__ */
|
|
2178
|
-
|
|
2330
|
+
children: /* @__PURE__ */ jsx58(ToggleGroup3.Item, { value: label, asChild: true, children: /* @__PURE__ */ jsx58(
|
|
2331
|
+
Pressable14,
|
|
2179
2332
|
{
|
|
2180
|
-
className:
|
|
2333
|
+
className: cn55(
|
|
2181
2334
|
"rounded-full px-3 py-1.5",
|
|
2182
2335
|
active ? "bg-primary" : "bg-accent",
|
|
2183
2336
|
className
|
|
2184
2337
|
),
|
|
2185
|
-
children: /* @__PURE__ */
|
|
2338
|
+
children: /* @__PURE__ */ jsx58(Text, { className: cn55("text-xs font-semibold", active ? "text-primary-foreground" : "text-muted-foreground"), children: label })
|
|
2186
2339
|
}
|
|
2187
2340
|
) })
|
|
2188
2341
|
}
|
|
2189
2342
|
);
|
|
2190
2343
|
}
|
|
2191
2344
|
function FilterChipGroup({ chips, onChipPress, className, ...viewProps }) {
|
|
2192
|
-
const activeValues =
|
|
2345
|
+
const activeValues = useMemo2(
|
|
2193
2346
|
() => chips.filter((c) => c.active).map((c) => c.label),
|
|
2194
2347
|
[chips]
|
|
2195
2348
|
);
|
|
2196
|
-
const labelToIndex =
|
|
2349
|
+
const labelToIndex = useMemo2(() => {
|
|
2197
2350
|
const map = /* @__PURE__ */ new Map();
|
|
2198
2351
|
chips.forEach((chip, i) => map.set(chip.label, i));
|
|
2199
2352
|
return map;
|
|
@@ -2207,28 +2360,28 @@ function FilterChipGroup({ chips, onChipPress, className, ...viewProps }) {
|
|
|
2207
2360
|
if (index !== void 0) onChipPress(index);
|
|
2208
2361
|
}
|
|
2209
2362
|
}
|
|
2210
|
-
return /* @__PURE__ */
|
|
2363
|
+
return /* @__PURE__ */ jsx58(
|
|
2211
2364
|
ToggleGroup3.Root,
|
|
2212
2365
|
{
|
|
2213
2366
|
type: "multiple",
|
|
2214
2367
|
value: activeValues,
|
|
2215
2368
|
onValueChange: handleValueChange,
|
|
2216
2369
|
asChild: true,
|
|
2217
|
-
children: /* @__PURE__ */
|
|
2370
|
+
children: /* @__PURE__ */ jsx58(
|
|
2218
2371
|
ScrollView5,
|
|
2219
2372
|
{
|
|
2220
2373
|
horizontal: true,
|
|
2221
2374
|
showsHorizontalScrollIndicator: false,
|
|
2222
|
-
contentContainerClassName:
|
|
2375
|
+
contentContainerClassName: cn55("flex-row gap-2", className),
|
|
2223
2376
|
...viewProps,
|
|
2224
|
-
children: chips.map((chip) => /* @__PURE__ */
|
|
2225
|
-
|
|
2377
|
+
children: chips.map((chip) => /* @__PURE__ */ jsx58(ToggleGroup3.Item, { value: chip.label, asChild: true, children: /* @__PURE__ */ jsx58(
|
|
2378
|
+
Pressable14,
|
|
2226
2379
|
{
|
|
2227
|
-
className:
|
|
2380
|
+
className: cn55(
|
|
2228
2381
|
"rounded-full px-3 py-1.5",
|
|
2229
2382
|
chip.active ? "bg-primary" : "bg-accent"
|
|
2230
2383
|
),
|
|
2231
|
-
children: /* @__PURE__ */
|
|
2384
|
+
children: /* @__PURE__ */ jsx58(Text, { className: cn55("text-xs font-semibold", chip.active ? "text-primary-foreground" : "text-muted-foreground"), children: chip.label })
|
|
2232
2385
|
}
|
|
2233
2386
|
) }, chip.label))
|
|
2234
2387
|
}
|
|
@@ -2238,10 +2391,10 @@ function FilterChipGroup({ chips, onChipPress, className, ...viewProps }) {
|
|
|
2238
2391
|
}
|
|
2239
2392
|
|
|
2240
2393
|
// src/input/quantity-stepper.tsx
|
|
2241
|
-
import { useState as
|
|
2242
|
-
import { Pressable as
|
|
2243
|
-
import { cn as
|
|
2244
|
-
import { jsx as
|
|
2394
|
+
import { useState as useState6 } from "react";
|
|
2395
|
+
import { Pressable as Pressable15, Text as Text17, View as View30 } from "react-native";
|
|
2396
|
+
import { cn as cn56 } from "@tallyui/theme";
|
|
2397
|
+
import { jsx as jsx59, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2245
2398
|
function QuantityStepper({
|
|
2246
2399
|
defaultQuantity = 1,
|
|
2247
2400
|
quantity: controlledQuantity,
|
|
@@ -2251,37 +2404,37 @@ function QuantityStepper({
|
|
|
2251
2404
|
className,
|
|
2252
2405
|
...viewProps
|
|
2253
2406
|
}) {
|
|
2254
|
-
const [internalQuantity, setInternalQuantity] =
|
|
2407
|
+
const [internalQuantity, setInternalQuantity] = useState6(defaultQuantity);
|
|
2255
2408
|
const quantity = controlledQuantity ?? internalQuantity;
|
|
2256
2409
|
const handleChange = (next) => {
|
|
2257
2410
|
if (next < min || next > max) return;
|
|
2258
2411
|
if (controlledQuantity === void 0) setInternalQuantity(next);
|
|
2259
2412
|
onChangeQuantity?.(next);
|
|
2260
2413
|
};
|
|
2261
|
-
return /* @__PURE__ */
|
|
2262
|
-
/* @__PURE__ */
|
|
2263
|
-
|
|
2414
|
+
return /* @__PURE__ */ jsxs18(View30, { className: cn56("flex-row items-center gap-2", className), ...viewProps, children: [
|
|
2415
|
+
/* @__PURE__ */ jsx59(
|
|
2416
|
+
Pressable15,
|
|
2264
2417
|
{
|
|
2265
2418
|
onPress: () => handleChange(quantity - 1),
|
|
2266
2419
|
disabled: quantity <= min,
|
|
2267
|
-
className:
|
|
2420
|
+
className: cn56(
|
|
2268
2421
|
"h-8 w-8 items-center justify-center rounded-lg",
|
|
2269
2422
|
quantity <= min ? "bg-muted/50" : "bg-muted"
|
|
2270
2423
|
),
|
|
2271
|
-
children: /* @__PURE__ */
|
|
2424
|
+
children: /* @__PURE__ */ jsx59(Text17, { className: cn56("text-base font-semibold", quantity <= min ? "text-muted-foreground" : "text-foreground"), children: "\u2212" })
|
|
2272
2425
|
}
|
|
2273
2426
|
),
|
|
2274
|
-
/* @__PURE__ */
|
|
2275
|
-
/* @__PURE__ */
|
|
2276
|
-
|
|
2427
|
+
/* @__PURE__ */ jsx59(Text17, { className: "min-w-[2rem] text-center text-base font-semibold text-foreground", children: quantity }),
|
|
2428
|
+
/* @__PURE__ */ jsx59(
|
|
2429
|
+
Pressable15,
|
|
2277
2430
|
{
|
|
2278
2431
|
onPress: () => handleChange(quantity + 1),
|
|
2279
2432
|
disabled: quantity >= max,
|
|
2280
|
-
className:
|
|
2433
|
+
className: cn56(
|
|
2281
2434
|
"h-8 w-8 items-center justify-center rounded-lg",
|
|
2282
2435
|
quantity >= max ? "bg-muted/50" : "bg-muted"
|
|
2283
2436
|
),
|
|
2284
|
-
children: /* @__PURE__ */
|
|
2437
|
+
children: /* @__PURE__ */ jsx59(Text17, { className: cn56("text-base font-semibold", quantity >= max ? "text-muted-foreground" : "text-foreground"), children: "+" })
|
|
2285
2438
|
}
|
|
2286
2439
|
)
|
|
2287
2440
|
] });
|
|
@@ -2289,36 +2442,36 @@ function QuantityStepper({
|
|
|
2289
2442
|
|
|
2290
2443
|
// src/customer/customer-card.tsx
|
|
2291
2444
|
import { useCustomerTraits } from "@tallyui/core";
|
|
2292
|
-
import { cn as
|
|
2293
|
-
import { jsx as
|
|
2445
|
+
import { cn as cn57 } from "@tallyui/theme";
|
|
2446
|
+
import { jsx as jsx60, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2294
2447
|
function CustomerCardFromContext(props) {
|
|
2295
2448
|
const traits = useCustomerTraits();
|
|
2296
|
-
return traits ? /* @__PURE__ */
|
|
2449
|
+
return traits ? /* @__PURE__ */ jsx60(CustomerCard, { ...props, traits }) : null;
|
|
2297
2450
|
}
|
|
2298
2451
|
function CustomerCard({ doc, traits, className, ...props }) {
|
|
2299
|
-
if (!traits) return /* @__PURE__ */
|
|
2452
|
+
if (!traits) return /* @__PURE__ */ jsx60(CustomerCardFromContext, { doc, className, ...props });
|
|
2300
2453
|
const name = traits.getName(doc);
|
|
2301
2454
|
const email = traits.getEmail(doc);
|
|
2302
2455
|
const address = traits.getAddressSummary(doc);
|
|
2303
|
-
return /* @__PURE__ */
|
|
2304
|
-
/* @__PURE__ */
|
|
2305
|
-
email && /* @__PURE__ */
|
|
2306
|
-
address && /* @__PURE__ */
|
|
2456
|
+
return /* @__PURE__ */ jsxs19(VStack, { space: "none", className: cn57("gap-0.5", className), ...props, children: [
|
|
2457
|
+
/* @__PURE__ */ jsx60(Text, { className: "text-sm font-semibold", children: name }),
|
|
2458
|
+
email && /* @__PURE__ */ jsx60(Text, { className: "text-xs text-muted-foreground", children: email }),
|
|
2459
|
+
address && /* @__PURE__ */ jsx60(Text, { className: "text-xs text-muted-foreground", children: address })
|
|
2307
2460
|
] });
|
|
2308
2461
|
}
|
|
2309
2462
|
|
|
2310
2463
|
// src/customer/customer-select.tsx
|
|
2311
|
-
import { useState as
|
|
2312
|
-
import { Pressable as
|
|
2464
|
+
import { useState as useState7 } from "react";
|
|
2465
|
+
import { Pressable as Pressable16, ScrollView as ScrollView6, View as View31 } from "react-native";
|
|
2313
2466
|
import { Select as Select2 } from "@tallyui/primitives";
|
|
2314
2467
|
import { useCustomerTraits as useCustomerTraits2 } from "@tallyui/core";
|
|
2315
|
-
import { cn as
|
|
2316
|
-
import { jsx as
|
|
2468
|
+
import { cn as cn58 } from "@tallyui/theme";
|
|
2469
|
+
import { jsx as jsx61, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2317
2470
|
function CustomerSelect(props) {
|
|
2318
|
-
return props.traits ? /* @__PURE__ */
|
|
2471
|
+
return props.traits ? /* @__PURE__ */ jsx61(CustomerSelectView, { ...props }) : /* @__PURE__ */ jsx61(CustomerSelectFromContext, { ...props });
|
|
2319
2472
|
}
|
|
2320
2473
|
function CustomerSelectFromContext(props) {
|
|
2321
|
-
return /* @__PURE__ */
|
|
2474
|
+
return /* @__PURE__ */ jsx61(CustomerSelectView, { ...props, traits: useCustomerTraits2() });
|
|
2322
2475
|
}
|
|
2323
2476
|
function CustomerSelectView({
|
|
2324
2477
|
customers,
|
|
@@ -2331,7 +2484,7 @@ function CustomerSelectView({
|
|
|
2331
2484
|
traits,
|
|
2332
2485
|
...props
|
|
2333
2486
|
}) {
|
|
2334
|
-
const [search, setSearch] =
|
|
2487
|
+
const [search, setSearch] = useState7("");
|
|
2335
2488
|
const selectedOption = selected && traits ? { value: traits.getId(selected), label: traits.getName(selected) } : void 0;
|
|
2336
2489
|
const customerById = /* @__PURE__ */ new Map();
|
|
2337
2490
|
if (traits) {
|
|
@@ -2343,14 +2496,14 @@ function CustomerSelectView({
|
|
|
2343
2496
|
const doc = customerById.get(option.value);
|
|
2344
2497
|
if (doc) onSelect(doc);
|
|
2345
2498
|
}
|
|
2346
|
-
return /* @__PURE__ */
|
|
2499
|
+
return /* @__PURE__ */ jsx61(
|
|
2347
2500
|
Select2.Root,
|
|
2348
2501
|
{
|
|
2349
2502
|
value: selectedOption,
|
|
2350
2503
|
onValueChange: handleValueChange,
|
|
2351
2504
|
defaultOpen: true,
|
|
2352
|
-
children: /* @__PURE__ */
|
|
2353
|
-
showSearch && /* @__PURE__ */
|
|
2505
|
+
children: /* @__PURE__ */ jsxs20(VStack, { space: "sm", className: cn58(className), ...props, children: [
|
|
2506
|
+
showSearch && /* @__PURE__ */ jsx61(
|
|
2354
2507
|
SearchInput,
|
|
2355
2508
|
{
|
|
2356
2509
|
value: search,
|
|
@@ -2363,18 +2516,18 @@ function CustomerSelectView({
|
|
|
2363
2516
|
accessibilityLabel: "Search customers"
|
|
2364
2517
|
}
|
|
2365
2518
|
),
|
|
2366
|
-
selected && traits && /* @__PURE__ */
|
|
2367
|
-
customers.length > 0 && /* @__PURE__ */
|
|
2519
|
+
selected && traits && /* @__PURE__ */ jsx61(Select2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx61(View31, { className: "rounded-lg border border-primary bg-primary/5 px-3 py-2", children: /* @__PURE__ */ jsx61(CustomerCard, { doc: selected, traits }) }) }),
|
|
2520
|
+
customers.length > 0 && /* @__PURE__ */ jsx61(Select2.Content, { asChild: true, forceMount: true, disablePositioningStyle: true, children: /* @__PURE__ */ jsx61(ScrollView6, { className: "max-h-60", children: customers.map((customer, index) => {
|
|
2368
2521
|
const id = traits?.getId(customer) ?? String(index);
|
|
2369
2522
|
const label = traits?.getName(customer) ?? "";
|
|
2370
2523
|
const email = traits?.getEmail(customer);
|
|
2371
|
-
return /* @__PURE__ */
|
|
2524
|
+
return /* @__PURE__ */ jsx61(
|
|
2372
2525
|
Select2.Item,
|
|
2373
2526
|
{
|
|
2374
2527
|
value: id,
|
|
2375
2528
|
label,
|
|
2376
2529
|
asChild: true,
|
|
2377
|
-
children: /* @__PURE__ */
|
|
2530
|
+
children: /* @__PURE__ */ jsx61(Pressable16, { accessibilityLabel: email ? `${label}, ${email}` : label, className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ jsx61(CustomerCard, { doc: customer, traits }) })
|
|
2378
2531
|
},
|
|
2379
2532
|
id
|
|
2380
2533
|
);
|
|
@@ -2385,18 +2538,18 @@ function CustomerSelectView({
|
|
|
2385
2538
|
}
|
|
2386
2539
|
|
|
2387
2540
|
// src/customer/customer-form.tsx
|
|
2388
|
-
import { Pressable as
|
|
2389
|
-
import { cn as
|
|
2390
|
-
import { jsx as
|
|
2541
|
+
import { Pressable as Pressable17, Text as Text18, TextInput as TextInput6, View as View32 } from "react-native";
|
|
2542
|
+
import { cn as cn59 } from "@tallyui/theme";
|
|
2543
|
+
import { jsx as jsx62, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2391
2544
|
function FormField({
|
|
2392
2545
|
label,
|
|
2393
2546
|
value,
|
|
2394
2547
|
onChangeText,
|
|
2395
2548
|
...props
|
|
2396
2549
|
}) {
|
|
2397
|
-
return /* @__PURE__ */
|
|
2398
|
-
/* @__PURE__ */
|
|
2399
|
-
/* @__PURE__ */
|
|
2550
|
+
return /* @__PURE__ */ jsxs21(View32, { className: "gap-1", children: [
|
|
2551
|
+
/* @__PURE__ */ jsx62(Text18, { className: "text-xs font-medium text-muted-foreground", children: label }),
|
|
2552
|
+
/* @__PURE__ */ jsx62(
|
|
2400
2553
|
TextInput6,
|
|
2401
2554
|
{
|
|
2402
2555
|
value,
|
|
@@ -2417,22 +2570,22 @@ function CustomerForm({
|
|
|
2417
2570
|
className,
|
|
2418
2571
|
...viewProps
|
|
2419
2572
|
}) {
|
|
2420
|
-
return /* @__PURE__ */
|
|
2421
|
-
/* @__PURE__ */
|
|
2422
|
-
/* @__PURE__ */
|
|
2423
|
-
/* @__PURE__ */
|
|
2573
|
+
return /* @__PURE__ */ jsxs21(View32, { className: cn59("gap-3 p-4", className), ...viewProps, children: [
|
|
2574
|
+
/* @__PURE__ */ jsxs21(View32, { className: "flex-row gap-3", children: [
|
|
2575
|
+
/* @__PURE__ */ jsx62(View32, { className: "flex-1", children: /* @__PURE__ */ jsx62(FormField, { label: "First Name", value: values.firstName, onChangeText: (v) => onChangeField("firstName", v), placeholder: "First name" }) }),
|
|
2576
|
+
/* @__PURE__ */ jsx62(View32, { className: "flex-1", children: /* @__PURE__ */ jsx62(FormField, { label: "Last Name", value: values.lastName, onChangeText: (v) => onChangeField("lastName", v), placeholder: "Last name" }) })
|
|
2424
2577
|
] }),
|
|
2425
|
-
/* @__PURE__ */
|
|
2426
|
-
/* @__PURE__ */
|
|
2427
|
-
showAddress && /* @__PURE__ */
|
|
2428
|
-
onSubmit && /* @__PURE__ */
|
|
2578
|
+
/* @__PURE__ */ jsx62(FormField, { label: "Email", value: values.email, onChangeText: (v) => onChangeField("email", v), placeholder: "email@example.com", keyboardType: "email-address" }),
|
|
2579
|
+
/* @__PURE__ */ jsx62(FormField, { label: "Phone", value: values.phone, onChangeText: (v) => onChangeField("phone", v), placeholder: "Phone number", keyboardType: "phone-pad" }),
|
|
2580
|
+
showAddress && /* @__PURE__ */ jsx62(FormField, { label: "Address", value: values.address, onChangeText: (v) => onChangeField("address", v), placeholder: "Street address", multiline: true }),
|
|
2581
|
+
onSubmit && /* @__PURE__ */ jsx62(Pressable17, { onPress: onSubmit, className: "items-center rounded-lg bg-primary px-4 py-3", children: /* @__PURE__ */ jsx62(Text18, { className: "text-sm font-semibold text-primary-foreground", children: submitLabel }) })
|
|
2429
2582
|
] });
|
|
2430
2583
|
}
|
|
2431
2584
|
|
|
2432
2585
|
// src/customer/customer-order-history.tsx
|
|
2433
|
-
import { ScrollView as ScrollView7, Text as
|
|
2434
|
-
import { cn as
|
|
2435
|
-
import { jsx as
|
|
2586
|
+
import { ScrollView as ScrollView7, Text as Text19, View as View33 } from "react-native";
|
|
2587
|
+
import { cn as cn60 } from "@tallyui/theme";
|
|
2588
|
+
import { jsx as jsx63, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2436
2589
|
function CustomerOrderHistory({
|
|
2437
2590
|
orders,
|
|
2438
2591
|
renderItem,
|
|
@@ -2440,31 +2593,31 @@ function CustomerOrderHistory({
|
|
|
2440
2593
|
className,
|
|
2441
2594
|
...viewProps
|
|
2442
2595
|
}) {
|
|
2443
|
-
return /* @__PURE__ */
|
|
2444
|
-
/* @__PURE__ */
|
|
2445
|
-
orders.length > 0 ? /* @__PURE__ */
|
|
2596
|
+
return /* @__PURE__ */ jsxs22(View33, { className: cn60("flex-1", className), ...viewProps, children: [
|
|
2597
|
+
/* @__PURE__ */ jsx63(Text19, { className: "px-3 py-2 text-xs font-semibold text-muted-foreground", children: "Order History" }),
|
|
2598
|
+
orders.length > 0 ? /* @__PURE__ */ jsx63(ScrollView7, { contentContainerClassName: "gap-2 px-3 pb-3", children: orders.map((order, index) => /* @__PURE__ */ jsx63(View33, { children: renderItem(order, index) }, order.id ?? index)) }) : emptyState ?? null
|
|
2446
2599
|
] });
|
|
2447
2600
|
}
|
|
2448
2601
|
|
|
2449
2602
|
// src/customer/customer-picker.tsx
|
|
2450
|
-
import { useEffect, useRef, useState as
|
|
2451
|
-
import { Pressable as
|
|
2603
|
+
import { useEffect, useRef, useState as useState8 } from "react";
|
|
2604
|
+
import { Pressable as Pressable18, Text as Text20, TextInput as TextInput7, View as View34 } from "react-native";
|
|
2452
2605
|
import { customerTraits, CustomerServiceError, ConnectorUnauthorizedError } from "@tallyui/core";
|
|
2453
|
-
import { cn as
|
|
2454
|
-
import { jsx as
|
|
2606
|
+
import { cn as cn61 } from "@tallyui/theme";
|
|
2607
|
+
import { jsx as jsx64, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2455
2608
|
var EMAIL_MAX = 254;
|
|
2456
2609
|
var EMAIL_SHAPE = /^[^\s@\u0000]+@[^\s@\u0000]+\.[^\s@\u0000]+$/u;
|
|
2457
2610
|
function CustomerPicker({ search, create, selected, onSelect, onError, online, debounceMs = 250, className }) {
|
|
2458
|
-
const [query, setQuery] =
|
|
2459
|
-
const [customers, setCustomers] =
|
|
2460
|
-
const [error, setError] =
|
|
2461
|
-
const [showForm, setShowForm] =
|
|
2462
|
-
const [creating, setCreating] =
|
|
2463
|
-
const [values, setValues] =
|
|
2611
|
+
const [query, setQuery] = useState8("");
|
|
2612
|
+
const [customers, setCustomers] = useState8([]);
|
|
2613
|
+
const [error, setError] = useState8(null);
|
|
2614
|
+
const [showForm, setShowForm] = useState8(false);
|
|
2615
|
+
const [creating, setCreating] = useState8(false);
|
|
2616
|
+
const [values, setValues] = useState8({ firstName: "", lastName: "", email: "", phone: "", address: "" });
|
|
2464
2617
|
const sequence = useRef(0);
|
|
2465
2618
|
const searchRef = useRef(search);
|
|
2466
2619
|
searchRef.current = search;
|
|
2467
|
-
const [noResults, setNoResults] =
|
|
2620
|
+
const [noResults, setNoResults] = useState8(false);
|
|
2468
2621
|
function handleError(error2) {
|
|
2469
2622
|
if (error2 instanceof CustomerServiceError) {
|
|
2470
2623
|
setError(error2.code === "network" ? "Couldn't reach the store. Try again." : error2.code === "server" ? "The store couldn't do that. Try again." : error2.message);
|
|
@@ -2519,13 +2672,13 @@ function CustomerPicker({ search, create, selected, onSelect, onError, online, d
|
|
|
2519
2672
|
setCreating(false);
|
|
2520
2673
|
}
|
|
2521
2674
|
}
|
|
2522
|
-
return /* @__PURE__ */
|
|
2523
|
-
selected && /* @__PURE__ */
|
|
2524
|
-
/* @__PURE__ */
|
|
2525
|
-
/* @__PURE__ */
|
|
2675
|
+
return /* @__PURE__ */ jsxs23(View34, { className: cn61("gap-3", className), children: [
|
|
2676
|
+
selected && /* @__PURE__ */ jsxs23(View34, { children: [
|
|
2677
|
+
/* @__PURE__ */ jsx64(CustomerCard, { doc: selected, traits: customerTraits }),
|
|
2678
|
+
/* @__PURE__ */ jsx64(Pressable18, { accessibilityRole: "button", className: "items-center rounded-lg border border-border px-4 py-3", onPress: () => onSelect(null), children: /* @__PURE__ */ jsx64(Text20, { className: "text-sm font-semibold text-foreground", children: "Remove customer" }) })
|
|
2526
2679
|
] }),
|
|
2527
|
-
/* @__PURE__ */
|
|
2528
|
-
/* @__PURE__ */
|
|
2680
|
+
/* @__PURE__ */ jsx64(Text20, { className: "text-xs font-medium text-muted-foreground", children: "Search customers" }),
|
|
2681
|
+
/* @__PURE__ */ jsx64(
|
|
2529
2682
|
TextInput7,
|
|
2530
2683
|
{
|
|
2531
2684
|
accessibilityLabel: "Search customers",
|
|
@@ -2537,10 +2690,10 @@ function CustomerPicker({ search, create, selected, onSelect, onError, online, d
|
|
|
2537
2690
|
placeholder: "Name or email"
|
|
2538
2691
|
}
|
|
2539
2692
|
),
|
|
2540
|
-
!online && /* @__PURE__ */
|
|
2541
|
-
noResults && /* @__PURE__ */
|
|
2542
|
-
error && /* @__PURE__ */
|
|
2543
|
-
/* @__PURE__ */
|
|
2693
|
+
!online && /* @__PURE__ */ jsx64(Text20, { className: "text-sm text-muted-foreground", children: "Connect to search or add customers." }),
|
|
2694
|
+
noResults && /* @__PURE__ */ jsx64(Text20, { className: "text-sm text-muted-foreground", children: "No customers found." }),
|
|
2695
|
+
error && /* @__PURE__ */ jsx64(Text20, { accessibilityRole: "alert", className: "text-sm text-destructive", children: error }),
|
|
2696
|
+
/* @__PURE__ */ jsx64(
|
|
2544
2697
|
CustomerSelect,
|
|
2545
2698
|
{
|
|
2546
2699
|
customers,
|
|
@@ -2553,18 +2706,18 @@ function CustomerPicker({ search, create, selected, onSelect, onError, online, d
|
|
|
2553
2706
|
}
|
|
2554
2707
|
}
|
|
2555
2708
|
),
|
|
2556
|
-
create && /* @__PURE__ */
|
|
2557
|
-
|
|
2709
|
+
create && /* @__PURE__ */ jsx64(
|
|
2710
|
+
Pressable18,
|
|
2558
2711
|
{
|
|
2559
2712
|
accessibilityRole: "button",
|
|
2560
2713
|
disabled: !online || creating,
|
|
2561
2714
|
onPress: () => setShowForm(true),
|
|
2562
|
-
className:
|
|
2563
|
-
children: /* @__PURE__ */
|
|
2715
|
+
className: cn61("items-center rounded-lg border border-border px-4 py-3", (!online || creating) && "opacity-50"),
|
|
2716
|
+
children: /* @__PURE__ */ jsx64(Text20, { className: "text-sm font-semibold text-foreground", children: "New customer" })
|
|
2564
2717
|
}
|
|
2565
2718
|
),
|
|
2566
|
-
showForm && /* @__PURE__ */
|
|
2567
|
-
/* @__PURE__ */
|
|
2719
|
+
showForm && /* @__PURE__ */ jsxs23(View34, { children: [
|
|
2720
|
+
/* @__PURE__ */ jsx64(
|
|
2568
2721
|
CustomerForm,
|
|
2569
2722
|
{
|
|
2570
2723
|
values,
|
|
@@ -2572,19 +2725,19 @@ function CustomerPicker({ search, create, selected, onSelect, onError, online, d
|
|
|
2572
2725
|
onChangeField: (field, value) => setValues((current) => ({ ...current, [field]: value }))
|
|
2573
2726
|
}
|
|
2574
2727
|
),
|
|
2575
|
-
/* @__PURE__ */
|
|
2576
|
-
/* @__PURE__ */
|
|
2577
|
-
|
|
2728
|
+
/* @__PURE__ */ jsxs23(View34, { className: "flex-row gap-3", children: [
|
|
2729
|
+
/* @__PURE__ */ jsx64(
|
|
2730
|
+
Pressable18,
|
|
2578
2731
|
{
|
|
2579
2732
|
accessibilityRole: "button",
|
|
2580
2733
|
disabled: !online || creating || !values.email.trim(),
|
|
2581
2734
|
onPress: submit,
|
|
2582
|
-
className:
|
|
2583
|
-
children: /* @__PURE__ */
|
|
2735
|
+
className: cn61("items-center rounded-lg bg-primary px-4 py-3", (!online || creating || !values.email.trim()) && "opacity-50"),
|
|
2736
|
+
children: /* @__PURE__ */ jsx64(Text20, { className: "text-sm font-semibold text-primary-foreground", children: "Save Customer" })
|
|
2584
2737
|
}
|
|
2585
2738
|
),
|
|
2586
|
-
/* @__PURE__ */
|
|
2587
|
-
|
|
2739
|
+
/* @__PURE__ */ jsx64(
|
|
2740
|
+
Pressable18,
|
|
2588
2741
|
{
|
|
2589
2742
|
accessibilityRole: "button",
|
|
2590
2743
|
className: "items-center rounded-lg border border-border px-4 py-3",
|
|
@@ -2592,7 +2745,7 @@ function CustomerPicker({ search, create, selected, onSelect, onError, online, d
|
|
|
2592
2745
|
setShowForm(false);
|
|
2593
2746
|
setValues({ firstName: "", lastName: "", email: "", phone: "", address: "" });
|
|
2594
2747
|
},
|
|
2595
|
-
children: /* @__PURE__ */
|
|
2748
|
+
children: /* @__PURE__ */ jsx64(Text20, { className: "text-sm font-semibold text-foreground", children: "Cancel" })
|
|
2596
2749
|
}
|
|
2597
2750
|
)
|
|
2598
2751
|
] })
|
|
@@ -2601,40 +2754,40 @@ function CustomerPicker({ search, create, selected, onSelect, onError, online, d
|
|
|
2601
2754
|
}
|
|
2602
2755
|
|
|
2603
2756
|
// src/checkout/payment-method-card.tsx
|
|
2604
|
-
import { Pressable as
|
|
2605
|
-
import { cn as
|
|
2606
|
-
import { jsx as
|
|
2757
|
+
import { Pressable as Pressable19, View as View35 } from "react-native";
|
|
2758
|
+
import { cn as cn62 } from "@tallyui/theme";
|
|
2759
|
+
import { jsx as jsx65, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2607
2760
|
function PaymentMethodCard({ label, selected, onPress, icon, className, ...props }) {
|
|
2608
|
-
return /* @__PURE__ */
|
|
2761
|
+
return /* @__PURE__ */ jsx65(Pressable19, { onPress, ...props, children: /* @__PURE__ */ jsxs24(
|
|
2609
2762
|
HStack,
|
|
2610
2763
|
{
|
|
2611
|
-
className:
|
|
2764
|
+
className: cn62(
|
|
2612
2765
|
"rounded-lg border px-4 py-3",
|
|
2613
2766
|
selected ? "border-primary bg-primary/5" : "border-border bg-card",
|
|
2614
2767
|
className
|
|
2615
2768
|
),
|
|
2616
2769
|
children: [
|
|
2617
|
-
icon && /* @__PURE__ */
|
|
2618
|
-
/* @__PURE__ */
|
|
2619
|
-
selected && /* @__PURE__ */
|
|
2770
|
+
icon && /* @__PURE__ */ jsx65(View35, { children: icon }),
|
|
2771
|
+
/* @__PURE__ */ jsx65(Text, { className: cn62("flex-1 text-sm font-medium", selected ? "text-primary" : ""), children: label }),
|
|
2772
|
+
selected && /* @__PURE__ */ jsx65(View35, { className: "h-5 w-5 items-center justify-center rounded-full bg-primary", children: /* @__PURE__ */ jsx65(Text, { className: "text-xs text-primary-foreground", children: "\u2713" }) })
|
|
2620
2773
|
]
|
|
2621
2774
|
}
|
|
2622
2775
|
) });
|
|
2623
2776
|
}
|
|
2624
2777
|
|
|
2625
2778
|
// src/checkout/order-summary-line.tsx
|
|
2626
|
-
import { cn as
|
|
2627
|
-
import { jsx as
|
|
2779
|
+
import { cn as cn63 } from "@tallyui/theme";
|
|
2780
|
+
import { jsx as jsx66, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2628
2781
|
function OrderSummaryLine({ label, amount, bold = false, className, ...props }) {
|
|
2629
|
-
return /* @__PURE__ */
|
|
2630
|
-
/* @__PURE__ */
|
|
2631
|
-
/* @__PURE__ */
|
|
2782
|
+
return /* @__PURE__ */ jsxs25(HStack, { space: "none", className: cn63("justify-between", className), ...props, children: [
|
|
2783
|
+
/* @__PURE__ */ jsx66(Text, { className: cn63("text-sm", bold ? "font-bold" : "text-muted-foreground"), children: label }),
|
|
2784
|
+
/* @__PURE__ */ jsx66(Text, { className: cn63("text-sm", bold && "font-bold"), children: amount })
|
|
2632
2785
|
] });
|
|
2633
2786
|
}
|
|
2634
2787
|
|
|
2635
2788
|
// src/checkout/payment-selector.tsx
|
|
2636
|
-
import { cn as
|
|
2637
|
-
import { jsx as
|
|
2789
|
+
import { cn as cn64 } from "@tallyui/theme";
|
|
2790
|
+
import { jsx as jsx67 } from "react/jsx-runtime";
|
|
2638
2791
|
function PaymentSelector({
|
|
2639
2792
|
methods,
|
|
2640
2793
|
selected,
|
|
@@ -2642,7 +2795,7 @@ function PaymentSelector({
|
|
|
2642
2795
|
className,
|
|
2643
2796
|
...props
|
|
2644
2797
|
}) {
|
|
2645
|
-
return /* @__PURE__ */
|
|
2798
|
+
return /* @__PURE__ */ jsx67(VStack, { space: "sm", className: cn64(className), ...props, children: methods.map((method) => /* @__PURE__ */ jsx67(
|
|
2646
2799
|
PaymentMethodCard,
|
|
2647
2800
|
{
|
|
2648
2801
|
label: method.label,
|
|
@@ -2655,9 +2808,9 @@ function PaymentSelector({
|
|
|
2655
2808
|
}
|
|
2656
2809
|
|
|
2657
2810
|
// src/checkout/order-summary.tsx
|
|
2658
|
-
import { View as
|
|
2659
|
-
import { cn as
|
|
2660
|
-
import { jsx as
|
|
2811
|
+
import { View as View36 } from "react-native";
|
|
2812
|
+
import { cn as cn65 } from "@tallyui/theme";
|
|
2813
|
+
import { jsx as jsx68, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2661
2814
|
function OrderSummary({
|
|
2662
2815
|
subtotal,
|
|
2663
2816
|
tax,
|
|
@@ -2669,34 +2822,34 @@ function OrderSummary({
|
|
|
2669
2822
|
className,
|
|
2670
2823
|
...props
|
|
2671
2824
|
}) {
|
|
2672
|
-
return /* @__PURE__ */
|
|
2673
|
-
header && /* @__PURE__ */
|
|
2674
|
-
/* @__PURE__ */
|
|
2675
|
-
tax && /* @__PURE__ */
|
|
2676
|
-
/* @__PURE__ */
|
|
2677
|
-
payments && payments.length > 0 && /* @__PURE__ */
|
|
2678
|
-
footer && /* @__PURE__ */
|
|
2825
|
+
return /* @__PURE__ */ jsxs26(VStack, { space: "none", className: cn65("gap-1.5 px-3 py-3", className), ...props, children: [
|
|
2826
|
+
header && /* @__PURE__ */ jsx68(View36, { className: "mb-2", children: header }),
|
|
2827
|
+
/* @__PURE__ */ jsx68(OrderSummaryLine, { label: "Subtotal", amount: subtotal }),
|
|
2828
|
+
tax && /* @__PURE__ */ jsx68(OrderSummaryLine, { label: taxLabel, amount: tax }),
|
|
2829
|
+
/* @__PURE__ */ jsx68(OrderSummaryLine, { label: "Total", amount: total, bold: true }),
|
|
2830
|
+
payments && payments.length > 0 && /* @__PURE__ */ jsx68(VStack, { space: "none", className: "mt-2 gap-1.5 border-t border-border pt-2", children: payments.map((payment) => /* @__PURE__ */ jsx68(OrderSummaryLine, { label: payment.label, amount: payment.amount }, payment.label)) }),
|
|
2831
|
+
footer && /* @__PURE__ */ jsx68(View36, { className: "mt-2", children: footer })
|
|
2679
2832
|
] });
|
|
2680
2833
|
}
|
|
2681
2834
|
|
|
2682
2835
|
// src/checkout/change-display.tsx
|
|
2683
|
-
import { Text as
|
|
2836
|
+
import { Text as Text21, View as View37 } from "react-native";
|
|
2684
2837
|
import { formatMoney as formatMoney4 } from "@tallyui/core";
|
|
2685
|
-
import { cn as
|
|
2686
|
-
import { jsx as
|
|
2838
|
+
import { cn as cn66 } from "@tallyui/theme";
|
|
2839
|
+
import { jsx as jsx69, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2687
2840
|
function ChangeDisplay({ change, locale, className, ...viewProps }) {
|
|
2688
|
-
return /* @__PURE__ */
|
|
2689
|
-
/* @__PURE__ */
|
|
2690
|
-
/* @__PURE__ */
|
|
2841
|
+
return /* @__PURE__ */ jsxs27(View37, { className: cn66("items-center gap-1 rounded-xl bg-muted p-4", className), ...viewProps, children: [
|
|
2842
|
+
/* @__PURE__ */ jsx69(Text21, { className: "text-sm text-muted-foreground", children: "Change Due" }),
|
|
2843
|
+
/* @__PURE__ */ jsx69(Text21, { className: "text-3xl font-bold text-success", children: formatMoney4(change, locale) ?? "\u2014" })
|
|
2691
2844
|
] });
|
|
2692
2845
|
}
|
|
2693
2846
|
|
|
2694
2847
|
// src/checkout/cash-tendered.tsx
|
|
2695
|
-
import { useEffect as useEffect2, useRef as useRef2, useState as
|
|
2696
|
-
import { Pressable as
|
|
2848
|
+
import { useEffect as useEffect2, useRef as useRef2, useState as useState9 } from "react";
|
|
2849
|
+
import { Pressable as Pressable20, Text as Text22, TextInput as TextInput8, View as View38 } from "react-native";
|
|
2697
2850
|
import { formatMoney as formatMoney5, minorUnitDigits as minorUnitDigits2, moneyFromDecimalString } from "@tallyui/core";
|
|
2698
|
-
import { cn as
|
|
2699
|
-
import { jsx as
|
|
2851
|
+
import { cn as cn67 } from "@tallyui/theme";
|
|
2852
|
+
import { jsx as jsx70, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2700
2853
|
function defaultQuickAmounts(total) {
|
|
2701
2854
|
const unit = 10 ** minorUnitDigits2(total.currency);
|
|
2702
2855
|
const amounts = [
|
|
@@ -2717,13 +2870,13 @@ function CashTendered({
|
|
|
2717
2870
|
className,
|
|
2718
2871
|
...viewProps
|
|
2719
2872
|
}) {
|
|
2720
|
-
const [internalAmount, setInternalAmount] =
|
|
2873
|
+
const [internalAmount, setInternalAmount] = useState9(defaultAmount ?? total);
|
|
2721
2874
|
const amount = controlledAmount ?? internalAmount;
|
|
2722
2875
|
const buttons = quickAmounts ?? defaultQuickAmounts(total);
|
|
2723
2876
|
const digits = minorUnitDigits2(amount.currency);
|
|
2724
2877
|
const amountText = String(Math.abs(amount.amount)).padStart(digits + 1, "0");
|
|
2725
2878
|
const decimal2 = (amount.amount < 0 ? "-" : "") + (digits ? `${amountText.slice(0, -digits)}.${amountText.slice(-digits)}` : amountText);
|
|
2726
|
-
const [text, setText] =
|
|
2879
|
+
const [text, setText] = useState9(decimal2);
|
|
2727
2880
|
const lastTextAmount = useRef2(amount);
|
|
2728
2881
|
useEffect2(() => {
|
|
2729
2882
|
if (amount.amount !== lastTextAmount.current.amount || amount.currency !== lastTextAmount.current.currency) {
|
|
@@ -2735,20 +2888,20 @@ function CashTendered({
|
|
|
2735
2888
|
if (controlledAmount === void 0) setInternalAmount(value);
|
|
2736
2889
|
onChangeAmount?.(value);
|
|
2737
2890
|
};
|
|
2738
|
-
return /* @__PURE__ */
|
|
2739
|
-
/* @__PURE__ */
|
|
2740
|
-
/* @__PURE__ */
|
|
2741
|
-
|
|
2891
|
+
return /* @__PURE__ */ jsxs28(View38, { className: cn67("gap-3", className), ...viewProps, children: [
|
|
2892
|
+
/* @__PURE__ */ jsx70(Text22, { className: "text-sm font-semibold text-foreground", children: "Cash Tendered" }),
|
|
2893
|
+
/* @__PURE__ */ jsx70(View38, { className: "flex-row flex-wrap gap-2", children: buttons.map((val) => /* @__PURE__ */ jsx70(
|
|
2894
|
+
Pressable20,
|
|
2742
2895
|
{
|
|
2743
2896
|
onPress: () => handleChange(val),
|
|
2744
|
-
className:
|
|
2897
|
+
className: cn67(
|
|
2745
2898
|
"rounded-lg border px-4 py-2",
|
|
2746
2899
|
amount.amount === val.amount && amount.currency === val.currency ? "border-primary bg-primary" : "border-input bg-card"
|
|
2747
2900
|
),
|
|
2748
|
-
children: /* @__PURE__ */
|
|
2749
|
-
|
|
2901
|
+
children: /* @__PURE__ */ jsx70(
|
|
2902
|
+
Text22,
|
|
2750
2903
|
{
|
|
2751
|
-
className:
|
|
2904
|
+
className: cn67(
|
|
2752
2905
|
"text-sm font-semibold",
|
|
2753
2906
|
amount.amount === val.amount && amount.currency === val.currency ? "text-primary-foreground" : "text-foreground"
|
|
2754
2907
|
),
|
|
@@ -2758,7 +2911,7 @@ function CashTendered({
|
|
|
2758
2911
|
},
|
|
2759
2912
|
`${val.currency}:${val.amount}`
|
|
2760
2913
|
)) }),
|
|
2761
|
-
/* @__PURE__ */
|
|
2914
|
+
/* @__PURE__ */ jsx70(
|
|
2762
2915
|
TextInput8,
|
|
2763
2916
|
{
|
|
2764
2917
|
value: text,
|
|
@@ -2780,9 +2933,9 @@ function CashTendered({
|
|
|
2780
2933
|
}
|
|
2781
2934
|
|
|
2782
2935
|
// src/checkout/receipt-preview.tsx
|
|
2783
|
-
import { Text as
|
|
2784
|
-
import { cn as
|
|
2785
|
-
import { jsx as
|
|
2936
|
+
import { Text as Text23, View as View39 } from "react-native";
|
|
2937
|
+
import { cn as cn68 } from "@tallyui/theme";
|
|
2938
|
+
import { jsx as jsx71, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2786
2939
|
function ReceiptPreview({
|
|
2787
2940
|
items,
|
|
2788
2941
|
subtotal,
|
|
@@ -2794,42 +2947,42 @@ function ReceiptPreview({
|
|
|
2794
2947
|
className,
|
|
2795
2948
|
...viewProps
|
|
2796
2949
|
}) {
|
|
2797
|
-
return /* @__PURE__ */
|
|
2798
|
-
headerSlot && /* @__PURE__ */
|
|
2799
|
-
/* @__PURE__ */
|
|
2800
|
-
/* @__PURE__ */
|
|
2950
|
+
return /* @__PURE__ */ jsxs29(View39, { className: cn68("rounded-lg border border-border bg-card p-4", className), ...viewProps, children: [
|
|
2951
|
+
headerSlot && /* @__PURE__ */ jsx71(View39, { className: "mb-3 items-center border-b border-dashed border-border pb-3", children: headerSlot }),
|
|
2952
|
+
/* @__PURE__ */ jsx71(View39, { className: "gap-1", children: items.map((item, i) => /* @__PURE__ */ jsxs29(View39, { className: "flex-row justify-between", children: [
|
|
2953
|
+
/* @__PURE__ */ jsxs29(Text23, { className: "flex-1 text-sm text-foreground", children: [
|
|
2801
2954
|
item.name,
|
|
2802
2955
|
" x",
|
|
2803
2956
|
item.quantity
|
|
2804
2957
|
] }),
|
|
2805
|
-
/* @__PURE__ */
|
|
2958
|
+
/* @__PURE__ */ jsx71(Text23, { className: "text-sm text-foreground", children: item.total })
|
|
2806
2959
|
] }, i)) }),
|
|
2807
|
-
/* @__PURE__ */
|
|
2808
|
-
/* @__PURE__ */
|
|
2809
|
-
/* @__PURE__ */
|
|
2810
|
-
/* @__PURE__ */
|
|
2960
|
+
/* @__PURE__ */ jsxs29(View39, { className: "mt-3 gap-1 border-t border-dashed border-border pt-3", children: [
|
|
2961
|
+
/* @__PURE__ */ jsxs29(View39, { className: "flex-row justify-between", children: [
|
|
2962
|
+
/* @__PURE__ */ jsx71(Text23, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
|
|
2963
|
+
/* @__PURE__ */ jsx71(Text23, { className: "text-sm text-foreground", children: subtotal })
|
|
2811
2964
|
] }),
|
|
2812
|
-
/* @__PURE__ */
|
|
2813
|
-
/* @__PURE__ */
|
|
2814
|
-
/* @__PURE__ */
|
|
2965
|
+
/* @__PURE__ */ jsxs29(View39, { className: "flex-row justify-between", children: [
|
|
2966
|
+
/* @__PURE__ */ jsx71(Text23, { className: "text-sm text-muted-foreground", children: "Tax" }),
|
|
2967
|
+
/* @__PURE__ */ jsx71(Text23, { className: "text-sm text-foreground", children: tax })
|
|
2815
2968
|
] }),
|
|
2816
|
-
/* @__PURE__ */
|
|
2817
|
-
/* @__PURE__ */
|
|
2818
|
-
/* @__PURE__ */
|
|
2969
|
+
/* @__PURE__ */ jsxs29(View39, { className: "flex-row justify-between border-t border-border pt-1", children: [
|
|
2970
|
+
/* @__PURE__ */ jsx71(Text23, { className: "text-sm font-bold text-foreground", children: "Total" }),
|
|
2971
|
+
/* @__PURE__ */ jsx71(Text23, { className: "text-sm font-bold text-foreground", children: total })
|
|
2819
2972
|
] })
|
|
2820
2973
|
] }),
|
|
2821
|
-
payments && payments.length > 0 && /* @__PURE__ */
|
|
2822
|
-
/* @__PURE__ */
|
|
2823
|
-
/* @__PURE__ */
|
|
2974
|
+
payments && payments.length > 0 && /* @__PURE__ */ jsx71(View39, { className: "mt-3 gap-1 border-t border-dashed border-border pt-3", children: payments.map((p, i) => /* @__PURE__ */ jsxs29(View39, { className: "flex-row justify-between", children: [
|
|
2975
|
+
/* @__PURE__ */ jsx71(Text23, { className: "text-sm text-muted-foreground", children: p.method }),
|
|
2976
|
+
/* @__PURE__ */ jsx71(Text23, { className: "text-sm text-foreground", children: p.amount })
|
|
2824
2977
|
] }, i)) }),
|
|
2825
|
-
footerSlot && /* @__PURE__ */
|
|
2978
|
+
footerSlot && /* @__PURE__ */ jsx71(View39, { className: "mt-3 items-center border-t border-dashed border-border pt-3", children: footerSlot })
|
|
2826
2979
|
] });
|
|
2827
2980
|
}
|
|
2828
2981
|
|
|
2829
2982
|
// src/order/order-status-badge.tsx
|
|
2830
|
-
import { Text as
|
|
2831
|
-
import { cn as
|
|
2832
|
-
import { jsx as
|
|
2983
|
+
import { Text as Text24, View as View40 } from "react-native";
|
|
2984
|
+
import { cn as cn69 } from "@tallyui/theme";
|
|
2985
|
+
import { jsx as jsx72, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2833
2986
|
var STATUS_CONFIG = {
|
|
2834
2987
|
pending: { label: "Pending", badge: "bg-warning/15", dot: "bg-warning", text: "text-foreground" },
|
|
2835
2988
|
processing: { label: "Processing", badge: "bg-info/15", dot: "bg-info", text: "text-foreground" },
|
|
@@ -2839,23 +2992,23 @@ var STATUS_CONFIG = {
|
|
|
2839
2992
|
};
|
|
2840
2993
|
function OrderStatusBadge({ status, className, ...viewProps }) {
|
|
2841
2994
|
const config = STATUS_CONFIG[status] ?? STATUS_CONFIG.pending;
|
|
2842
|
-
return /* @__PURE__ */
|
|
2843
|
-
|
|
2995
|
+
return /* @__PURE__ */ jsxs30(
|
|
2996
|
+
View40,
|
|
2844
2997
|
{
|
|
2845
|
-
className:
|
|
2998
|
+
className: cn69("flex-row items-center self-start gap-1.5 rounded-xl px-2 py-1", config.badge, className),
|
|
2846
2999
|
...viewProps,
|
|
2847
3000
|
children: [
|
|
2848
|
-
/* @__PURE__ */
|
|
2849
|
-
/* @__PURE__ */
|
|
3001
|
+
/* @__PURE__ */ jsx72(View40, { className: cn69("h-1.5 w-1.5 rounded-full", config.dot) }),
|
|
3002
|
+
/* @__PURE__ */ jsx72(Text24, { className: cn69("text-xs font-semibold", config.text), children: config.label })
|
|
2850
3003
|
]
|
|
2851
3004
|
}
|
|
2852
3005
|
);
|
|
2853
3006
|
}
|
|
2854
3007
|
|
|
2855
3008
|
// src/order/order-card.tsx
|
|
2856
|
-
import { Pressable as
|
|
2857
|
-
import { cn as
|
|
2858
|
-
import { jsx as
|
|
3009
|
+
import { Pressable as Pressable21, Text as Text25, View as View41 } from "react-native";
|
|
3010
|
+
import { cn as cn70 } from "@tallyui/theme";
|
|
3011
|
+
import { jsx as jsx73, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2859
3012
|
function OrderCard({
|
|
2860
3013
|
orderNumber,
|
|
2861
3014
|
date,
|
|
@@ -2866,24 +3019,24 @@ function OrderCard({
|
|
|
2866
3019
|
className,
|
|
2867
3020
|
...viewProps
|
|
2868
3021
|
}) {
|
|
2869
|
-
const Wrapper = onPress ?
|
|
2870
|
-
return /* @__PURE__ */
|
|
3022
|
+
const Wrapper = onPress ? Pressable21 : View41;
|
|
3023
|
+
return /* @__PURE__ */ jsxs31(
|
|
2871
3024
|
Wrapper,
|
|
2872
3025
|
{
|
|
2873
3026
|
onPress,
|
|
2874
|
-
className:
|
|
3027
|
+
className: cn70("gap-2 rounded-lg border border-border bg-card p-3", className),
|
|
2875
3028
|
...viewProps,
|
|
2876
3029
|
children: [
|
|
2877
|
-
/* @__PURE__ */
|
|
2878
|
-
/* @__PURE__ */
|
|
2879
|
-
/* @__PURE__ */
|
|
3030
|
+
/* @__PURE__ */ jsxs31(View41, { className: "flex-row items-center justify-between", children: [
|
|
3031
|
+
/* @__PURE__ */ jsx73(Text25, { className: "text-sm font-semibold text-foreground", children: orderNumber }),
|
|
3032
|
+
/* @__PURE__ */ jsx73(OrderStatusBadge, { status })
|
|
2880
3033
|
] }),
|
|
2881
|
-
/* @__PURE__ */
|
|
2882
|
-
/* @__PURE__ */
|
|
2883
|
-
/* @__PURE__ */
|
|
2884
|
-
customerName && /* @__PURE__ */
|
|
3034
|
+
/* @__PURE__ */ jsxs31(View41, { className: "flex-row items-center justify-between", children: [
|
|
3035
|
+
/* @__PURE__ */ jsxs31(View41, { className: "gap-0.5", children: [
|
|
3036
|
+
/* @__PURE__ */ jsx73(Text25, { className: "text-xs text-muted-foreground", children: date }),
|
|
3037
|
+
customerName && /* @__PURE__ */ jsx73(Text25, { className: "text-xs text-muted-foreground", children: customerName })
|
|
2885
3038
|
] }),
|
|
2886
|
-
/* @__PURE__ */
|
|
3039
|
+
/* @__PURE__ */ jsx73(Text25, { className: "text-sm font-semibold text-foreground", children: total })
|
|
2887
3040
|
] })
|
|
2888
3041
|
]
|
|
2889
3042
|
}
|
|
@@ -2891,9 +3044,9 @@ function OrderCard({
|
|
|
2891
3044
|
}
|
|
2892
3045
|
|
|
2893
3046
|
// src/order/order-list.tsx
|
|
2894
|
-
import { ScrollView as ScrollView8, View as
|
|
2895
|
-
import { cn as
|
|
2896
|
-
import { jsx as
|
|
3047
|
+
import { ScrollView as ScrollView8, View as View42 } from "react-native";
|
|
3048
|
+
import { cn as cn71 } from "@tallyui/theme";
|
|
3049
|
+
import { jsx as jsx74, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2897
3050
|
function OrderList({
|
|
2898
3051
|
items,
|
|
2899
3052
|
renderItem,
|
|
@@ -2903,16 +3056,16 @@ function OrderList({
|
|
|
2903
3056
|
...viewProps
|
|
2904
3057
|
}) {
|
|
2905
3058
|
const hasItems = items.length > 0;
|
|
2906
|
-
return /* @__PURE__ */
|
|
2907
|
-
headerSlot && /* @__PURE__ */
|
|
2908
|
-
hasItems ? /* @__PURE__ */
|
|
3059
|
+
return /* @__PURE__ */ jsxs32(View42, { className: cn71("flex-1", className), ...viewProps, children: [
|
|
3060
|
+
headerSlot && /* @__PURE__ */ jsx74(View42, { className: "px-3 py-2", children: headerSlot }),
|
|
3061
|
+
hasItems ? /* @__PURE__ */ jsx74(ScrollView8, { contentContainerClassName: "gap-2 p-3", children: items.map((item, index) => /* @__PURE__ */ jsx74(View42, { children: renderItem(item, index) }, item.id ?? index)) }) : emptyState ?? null
|
|
2909
3062
|
] });
|
|
2910
3063
|
}
|
|
2911
3064
|
|
|
2912
3065
|
// src/order/order-detail.tsx
|
|
2913
|
-
import { ScrollView as ScrollView9, Text as
|
|
2914
|
-
import { cn as
|
|
2915
|
-
import { jsx as
|
|
3066
|
+
import { ScrollView as ScrollView9, Text as Text26, View as View43 } from "react-native";
|
|
3067
|
+
import { cn as cn72 } from "@tallyui/theme";
|
|
3068
|
+
import { jsx as jsx75, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2916
3069
|
function OrderDetail({
|
|
2917
3070
|
orderNumber,
|
|
2918
3071
|
status,
|
|
@@ -2926,47 +3079,47 @@ function OrderDetail({
|
|
|
2926
3079
|
className,
|
|
2927
3080
|
...viewProps
|
|
2928
3081
|
}) {
|
|
2929
|
-
return /* @__PURE__ */
|
|
2930
|
-
/* @__PURE__ */
|
|
2931
|
-
/* @__PURE__ */
|
|
2932
|
-
/* @__PURE__ */
|
|
3082
|
+
return /* @__PURE__ */ jsx75(ScrollView9, { className: cn72("flex-1", className), ...viewProps, children: /* @__PURE__ */ jsxs33(View43, { className: "gap-4 p-4", children: [
|
|
3083
|
+
/* @__PURE__ */ jsxs33(View43, { className: "flex-row items-center justify-between", children: [
|
|
3084
|
+
/* @__PURE__ */ jsx75(Text26, { className: "text-lg font-bold text-foreground", children: orderNumber }),
|
|
3085
|
+
/* @__PURE__ */ jsx75(OrderStatusBadge, { status })
|
|
2933
3086
|
] }),
|
|
2934
|
-
customerSlot && /* @__PURE__ */
|
|
2935
|
-
/* @__PURE__ */
|
|
2936
|
-
/* @__PURE__ */
|
|
2937
|
-
lineItems.map((item, i) => /* @__PURE__ */
|
|
2938
|
-
/* @__PURE__ */
|
|
3087
|
+
customerSlot && /* @__PURE__ */ jsx75(View43, { className: "border-b border-border pb-3", children: customerSlot }),
|
|
3088
|
+
/* @__PURE__ */ jsxs33(View43, { className: "gap-1", children: [
|
|
3089
|
+
/* @__PURE__ */ jsx75(Text26, { className: "text-xs font-semibold text-muted-foreground", children: "Items" }),
|
|
3090
|
+
lineItems.map((item, i) => /* @__PURE__ */ jsxs33(View43, { className: "flex-row items-center justify-between py-1", children: [
|
|
3091
|
+
/* @__PURE__ */ jsxs33(Text26, { className: "flex-1 text-sm text-foreground", children: [
|
|
2939
3092
|
item.name,
|
|
2940
3093
|
" x",
|
|
2941
3094
|
item.quantity
|
|
2942
3095
|
] }),
|
|
2943
|
-
/* @__PURE__ */
|
|
3096
|
+
/* @__PURE__ */ jsx75(Text26, { className: "text-sm text-foreground", children: item.total })
|
|
2944
3097
|
] }, i))
|
|
2945
3098
|
] }),
|
|
2946
|
-
/* @__PURE__ */
|
|
2947
|
-
/* @__PURE__ */
|
|
2948
|
-
/* @__PURE__ */
|
|
2949
|
-
/* @__PURE__ */
|
|
3099
|
+
/* @__PURE__ */ jsxs33(View43, { className: "gap-1 border-t border-border pt-3", children: [
|
|
3100
|
+
/* @__PURE__ */ jsxs33(View43, { className: "flex-row justify-between", children: [
|
|
3101
|
+
/* @__PURE__ */ jsx75(Text26, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
|
|
3102
|
+
/* @__PURE__ */ jsx75(Text26, { className: "text-sm text-foreground", children: subtotal })
|
|
2950
3103
|
] }),
|
|
2951
|
-
/* @__PURE__ */
|
|
2952
|
-
/* @__PURE__ */
|
|
2953
|
-
/* @__PURE__ */
|
|
3104
|
+
/* @__PURE__ */ jsxs33(View43, { className: "flex-row justify-between", children: [
|
|
3105
|
+
/* @__PURE__ */ jsx75(Text26, { className: "text-sm text-muted-foreground", children: "Tax" }),
|
|
3106
|
+
/* @__PURE__ */ jsx75(Text26, { className: "text-sm text-foreground", children: tax })
|
|
2954
3107
|
] }),
|
|
2955
|
-
/* @__PURE__ */
|
|
2956
|
-
/* @__PURE__ */
|
|
2957
|
-
/* @__PURE__ */
|
|
3108
|
+
/* @__PURE__ */ jsxs33(View43, { className: "flex-row justify-between pt-1", children: [
|
|
3109
|
+
/* @__PURE__ */ jsx75(Text26, { className: "text-sm font-bold text-foreground", children: "Total" }),
|
|
3110
|
+
/* @__PURE__ */ jsx75(Text26, { className: "text-sm font-bold text-foreground", children: total })
|
|
2958
3111
|
] })
|
|
2959
3112
|
] }),
|
|
2960
|
-
paymentSlot && /* @__PURE__ */
|
|
2961
|
-
footerSlot && /* @__PURE__ */
|
|
3113
|
+
paymentSlot && /* @__PURE__ */ jsx75(View43, { className: "border-t border-border pt-3", children: paymentSlot }),
|
|
3114
|
+
footerSlot && /* @__PURE__ */ jsx75(View43, { className: "border-t border-border pt-3", children: footerSlot })
|
|
2962
3115
|
] }) });
|
|
2963
3116
|
}
|
|
2964
3117
|
|
|
2965
3118
|
// src/register/cash-count-input.tsx
|
|
2966
|
-
import { useState as
|
|
2967
|
-
import { Text as
|
|
2968
|
-
import { cn as
|
|
2969
|
-
import { jsx as
|
|
3119
|
+
import { useState as useState10 } from "react";
|
|
3120
|
+
import { Text as Text27, View as View44 } from "react-native";
|
|
3121
|
+
import { cn as cn73 } from "@tallyui/theme";
|
|
3122
|
+
import { jsx as jsx76, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
2970
3123
|
var DEFAULT_DENOMINATIONS = [
|
|
2971
3124
|
{ label: "$100", value: 100 },
|
|
2972
3125
|
{ label: "$50", value: 50 },
|
|
@@ -2988,7 +3141,7 @@ function CashCountInput({
|
|
|
2988
3141
|
className,
|
|
2989
3142
|
...viewProps
|
|
2990
3143
|
}) {
|
|
2991
|
-
const [internalCounts, setInternalCounts] =
|
|
3144
|
+
const [internalCounts, setInternalCounts] = useState10(defaultCounts ?? {});
|
|
2992
3145
|
const counts = controlledCounts ?? internalCounts;
|
|
2993
3146
|
const total = denominations2.reduce(
|
|
2994
3147
|
(sum, d) => sum + d.value * (counts[d.value] ?? 0),
|
|
@@ -3004,10 +3157,10 @@ function CashCountInput({
|
|
|
3004
3157
|
);
|
|
3005
3158
|
onChangeTotal?.(newTotal);
|
|
3006
3159
|
};
|
|
3007
|
-
return /* @__PURE__ */
|
|
3008
|
-
denominations2.map((d) => /* @__PURE__ */
|
|
3009
|
-
/* @__PURE__ */
|
|
3010
|
-
/* @__PURE__ */
|
|
3160
|
+
return /* @__PURE__ */ jsxs34(View44, { className: cn73("gap-2", className), ...viewProps, children: [
|
|
3161
|
+
denominations2.map((d) => /* @__PURE__ */ jsxs34(View44, { className: "flex-row items-center justify-between px-3 py-1", children: [
|
|
3162
|
+
/* @__PURE__ */ jsx76(Text27, { className: "w-16 text-sm font-medium text-foreground", children: d.label }),
|
|
3163
|
+
/* @__PURE__ */ jsx76(
|
|
3011
3164
|
QuantityStepper,
|
|
3012
3165
|
{
|
|
3013
3166
|
quantity: counts[d.value] ?? 0,
|
|
@@ -3015,9 +3168,9 @@ function CashCountInput({
|
|
|
3015
3168
|
onChangeQuantity: (qty) => handleCountChange(d.value, qty)
|
|
3016
3169
|
}
|
|
3017
3170
|
),
|
|
3018
|
-
/* @__PURE__ */
|
|
3171
|
+
/* @__PURE__ */ jsx76(Text27, { className: "w-20 text-right text-sm text-muted-foreground", children: (d.value * (counts[d.value] ?? 0)).toFixed(2) })
|
|
3019
3172
|
] }, d.value)),
|
|
3020
|
-
/* @__PURE__ */
|
|
3173
|
+
/* @__PURE__ */ jsx76(View44, { className: "border-t border-border px-3 pt-2", children: /* @__PURE__ */ jsxs34(Text27, { className: "text-right text-base font-bold text-foreground", children: [
|
|
3021
3174
|
"Total: ",
|
|
3022
3175
|
total.toFixed(2)
|
|
3023
3176
|
] }) })
|
|
@@ -3025,9 +3178,9 @@ function CashCountInput({
|
|
|
3025
3178
|
}
|
|
3026
3179
|
|
|
3027
3180
|
// src/register/register-summary.tsx
|
|
3028
|
-
import { Text as
|
|
3029
|
-
import { cn as
|
|
3030
|
-
import { jsx as
|
|
3181
|
+
import { Text as Text28, View as View45 } from "react-native";
|
|
3182
|
+
import { cn as cn74 } from "@tallyui/theme";
|
|
3183
|
+
import { jsx as jsx77, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
3031
3184
|
function RegisterSummary({
|
|
3032
3185
|
expectedCash,
|
|
3033
3186
|
actualCash,
|
|
@@ -3038,37 +3191,37 @@ function RegisterSummary({
|
|
|
3038
3191
|
...viewProps
|
|
3039
3192
|
}) {
|
|
3040
3193
|
const discrepancy = actualCash - expectedCash;
|
|
3041
|
-
return /* @__PURE__ */
|
|
3194
|
+
return /* @__PURE__ */ jsxs35(View45, { className: cn74("gap-4 rounded-lg border border-border bg-card p-4", className), ...viewProps, children: [
|
|
3042
3195
|
headerSlot,
|
|
3043
|
-
/* @__PURE__ */
|
|
3044
|
-
/* @__PURE__ */
|
|
3045
|
-
/* @__PURE__ */
|
|
3046
|
-
/* @__PURE__ */
|
|
3047
|
-
/* @__PURE__ */
|
|
3196
|
+
/* @__PURE__ */ jsxs35(View45, { className: "gap-2", children: [
|
|
3197
|
+
/* @__PURE__ */ jsx77(Text28, { className: "text-xs font-semibold text-muted-foreground", children: "Cash Drawer" }),
|
|
3198
|
+
/* @__PURE__ */ jsxs35(View45, { className: "flex-row justify-between", children: [
|
|
3199
|
+
/* @__PURE__ */ jsx77(Text28, { className: "text-sm text-foreground", children: "Expected" }),
|
|
3200
|
+
/* @__PURE__ */ jsx77(Text28, { className: "text-sm text-foreground", children: expectedCash.toFixed(2) })
|
|
3048
3201
|
] }),
|
|
3049
|
-
/* @__PURE__ */
|
|
3050
|
-
/* @__PURE__ */
|
|
3051
|
-
/* @__PURE__ */
|
|
3202
|
+
/* @__PURE__ */ jsxs35(View45, { className: "flex-row justify-between", children: [
|
|
3203
|
+
/* @__PURE__ */ jsx77(Text28, { className: "text-sm text-foreground", children: "Actual" }),
|
|
3204
|
+
/* @__PURE__ */ jsx77(Text28, { className: "text-sm text-foreground", children: actualCash.toFixed(2) })
|
|
3052
3205
|
] }),
|
|
3053
|
-
/* @__PURE__ */
|
|
3054
|
-
/* @__PURE__ */
|
|
3055
|
-
/* @__PURE__ */
|
|
3206
|
+
/* @__PURE__ */ jsxs35(View45, { className: "flex-row justify-between border-t border-border pt-1", children: [
|
|
3207
|
+
/* @__PURE__ */ jsx77(Text28, { className: "text-sm font-semibold text-foreground", children: "Discrepancy" }),
|
|
3208
|
+
/* @__PURE__ */ jsxs35(Text28, { className: cn74("text-sm font-semibold", discrepancy === 0 ? "text-success" : "text-destructive"), children: [
|
|
3056
3209
|
discrepancy >= 0 ? "" : "-",
|
|
3057
3210
|
Math.abs(discrepancy).toFixed(2)
|
|
3058
3211
|
] })
|
|
3059
3212
|
] })
|
|
3060
3213
|
] }),
|
|
3061
|
-
transactions.length > 0 && /* @__PURE__ */
|
|
3062
|
-
/* @__PURE__ */
|
|
3063
|
-
transactions.map((t) => /* @__PURE__ */
|
|
3064
|
-
/* @__PURE__ */
|
|
3065
|
-
/* @__PURE__ */
|
|
3066
|
-
/* @__PURE__ */
|
|
3214
|
+
transactions.length > 0 && /* @__PURE__ */ jsxs35(View45, { className: "gap-2", children: [
|
|
3215
|
+
/* @__PURE__ */ jsx77(Text28, { className: "text-xs font-semibold text-muted-foreground", children: "Transactions" }),
|
|
3216
|
+
transactions.map((t) => /* @__PURE__ */ jsxs35(View45, { className: "flex-row items-center justify-between", children: [
|
|
3217
|
+
/* @__PURE__ */ jsxs35(View45, { className: "gap-0.5", children: [
|
|
3218
|
+
/* @__PURE__ */ jsx77(Text28, { className: "text-sm text-foreground", children: t.method }),
|
|
3219
|
+
/* @__PURE__ */ jsxs35(Text28, { className: "text-xs text-muted-foreground", children: [
|
|
3067
3220
|
t.count,
|
|
3068
3221
|
" transactions"
|
|
3069
3222
|
] })
|
|
3070
3223
|
] }),
|
|
3071
|
-
/* @__PURE__ */
|
|
3224
|
+
/* @__PURE__ */ jsx77(Text28, { className: "text-sm font-semibold text-foreground", children: t.total.toFixed(2) })
|
|
3072
3225
|
] }, t.method))
|
|
3073
3226
|
] }),
|
|
3074
3227
|
footerSlot
|
|
@@ -3076,9 +3229,9 @@ function RegisterSummary({
|
|
|
3076
3229
|
}
|
|
3077
3230
|
|
|
3078
3231
|
// src/register/register-open-close.tsx
|
|
3079
|
-
import { Pressable as
|
|
3080
|
-
import { cn as
|
|
3081
|
-
import { jsx as
|
|
3232
|
+
import { Pressable as Pressable22, Text as Text29, View as View46 } from "react-native";
|
|
3233
|
+
import { cn as cn75 } from "@tallyui/theme";
|
|
3234
|
+
import { jsx as jsx78, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3082
3235
|
function RegisterOpenClose({
|
|
3083
3236
|
isOpen,
|
|
3084
3237
|
onOpen,
|
|
@@ -3089,20 +3242,20 @@ function RegisterOpenClose({
|
|
|
3089
3242
|
className,
|
|
3090
3243
|
...viewProps
|
|
3091
3244
|
}) {
|
|
3092
|
-
return /* @__PURE__ */
|
|
3093
|
-
/* @__PURE__ */
|
|
3094
|
-
isOpen && expectedBalance != null && /* @__PURE__ */
|
|
3095
|
-
/* @__PURE__ */
|
|
3096
|
-
/* @__PURE__ */
|
|
3245
|
+
return /* @__PURE__ */ jsxs36(View46, { className: cn75("gap-4 p-4", className), ...viewProps, children: [
|
|
3246
|
+
/* @__PURE__ */ jsx78(Text29, { className: "text-lg font-bold text-foreground", children: isOpen ? "Close Register" : "Open Register" }),
|
|
3247
|
+
isOpen && expectedBalance != null && /* @__PURE__ */ jsxs36(View46, { className: "flex-row justify-between rounded-lg bg-muted px-3 py-2", children: [
|
|
3248
|
+
/* @__PURE__ */ jsx78(Text29, { className: "text-sm text-muted-foreground", children: "Expected Balance" }),
|
|
3249
|
+
/* @__PURE__ */ jsx78(Text29, { className: "text-sm font-semibold text-foreground", children: expectedBalance.toFixed(2) })
|
|
3097
3250
|
] }),
|
|
3098
|
-
cashCountSlot && /* @__PURE__ */
|
|
3099
|
-
notesSlot && /* @__PURE__ */
|
|
3100
|
-
/* @__PURE__ */
|
|
3101
|
-
|
|
3251
|
+
cashCountSlot && /* @__PURE__ */ jsx78(View46, { children: cashCountSlot }),
|
|
3252
|
+
notesSlot && /* @__PURE__ */ jsx78(View46, { children: notesSlot }),
|
|
3253
|
+
/* @__PURE__ */ jsx78(
|
|
3254
|
+
Pressable22,
|
|
3102
3255
|
{
|
|
3103
3256
|
onPress: isOpen ? onClose : onOpen,
|
|
3104
3257
|
className: "items-center rounded-lg bg-primary px-4 py-3",
|
|
3105
|
-
children: /* @__PURE__ */
|
|
3258
|
+
children: /* @__PURE__ */ jsx78(Text29, { className: "text-sm font-semibold text-primary-foreground", children: isOpen ? "Close Register" : "Open Register" })
|
|
3106
3259
|
}
|
|
3107
3260
|
)
|
|
3108
3261
|
] });
|
|
@@ -3110,46 +3263,46 @@ function RegisterOpenClose({
|
|
|
3110
3263
|
|
|
3111
3264
|
// src/register/register-picker.tsx
|
|
3112
3265
|
import { ScrollView as ScrollView10 } from "react-native";
|
|
3113
|
-
import { jsx as
|
|
3266
|
+
import { jsx as jsx79, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3114
3267
|
function RegisterPicker({ registers, onPick, className }) {
|
|
3115
|
-
return /* @__PURE__ */
|
|
3116
|
-
/* @__PURE__ */
|
|
3117
|
-
/* @__PURE__ */
|
|
3118
|
-
registers.map((register) => /* @__PURE__ */
|
|
3268
|
+
return /* @__PURE__ */ jsxs37(Card, { testID: "register-picker", className, children: [
|
|
3269
|
+
/* @__PURE__ */ jsx79(CardHeader, { children: /* @__PURE__ */ jsx79(CardTitle, { children: "Choose a register" }) }),
|
|
3270
|
+
/* @__PURE__ */ jsx79(CardContent, { children: /* @__PURE__ */ jsxs37(ScrollView10, { children: [
|
|
3271
|
+
registers.map((register) => /* @__PURE__ */ jsx79(
|
|
3119
3272
|
Button,
|
|
3120
3273
|
{
|
|
3121
3274
|
testID: `register-picker-row-${register.id}`,
|
|
3122
3275
|
variant: "ghost",
|
|
3123
3276
|
className: "h-auto min-h-11 items-start justify-start py-2",
|
|
3124
3277
|
onPress: () => onPick(register.id),
|
|
3125
|
-
children: /* @__PURE__ */
|
|
3126
|
-
/* @__PURE__ */
|
|
3127
|
-
/* @__PURE__ */
|
|
3278
|
+
children: /* @__PURE__ */ jsxs37(VStack, { space: "none", children: [
|
|
3279
|
+
/* @__PURE__ */ jsx79(Text, { numberOfLines: 1, children: register.name }),
|
|
3280
|
+
/* @__PURE__ */ jsx79(Text, { testID: `register-picker-row-${register.id}-status`, className: "text-muted-foreground text-sm", children: "Not opened" })
|
|
3128
3281
|
] })
|
|
3129
3282
|
},
|
|
3130
3283
|
register.id
|
|
3131
3284
|
)),
|
|
3132
|
-
registers.length === 0 && /* @__PURE__ */
|
|
3285
|
+
registers.length === 0 && /* @__PURE__ */ jsx79(Text, { testID: "register-picker-empty", className: "text-muted-foreground p-4", children: "No registers are set up for this store yet." })
|
|
3133
3286
|
] }) })
|
|
3134
3287
|
] });
|
|
3135
3288
|
}
|
|
3136
3289
|
|
|
3137
3290
|
// src/register/open-register-card.tsx
|
|
3138
|
-
import { useState as
|
|
3139
|
-
import { View as
|
|
3291
|
+
import { useState as useState11 } from "react";
|
|
3292
|
+
import { View as View47 } from "react-native";
|
|
3140
3293
|
import { parseMinor, validAmount } from "@tallyui/pos";
|
|
3141
3294
|
import { currencySymbol, formatMoney as formatMoney6, minorUnitDigits as minorUnitDigits3 } from "@tallyui/core";
|
|
3142
|
-
import { cn as
|
|
3143
|
-
import { jsx as
|
|
3295
|
+
import { cn as cn76 } from "@tallyui/theme";
|
|
3296
|
+
import { jsx as jsx80, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3144
3297
|
var AMOUNT_LABEL_ID = "open-register-amount-label";
|
|
3145
3298
|
function OpenRegisterCard({ register, currency, configuredFloatMinor, className }) {
|
|
3146
3299
|
const digits = minorUnitDigits3(currency);
|
|
3147
3300
|
const lastCountedMinor = register.lastClosure?.counted?.cash ?? null;
|
|
3148
3301
|
const expectedFloatMinor = configuredFloatMinor ?? lastCountedMinor ?? null;
|
|
3149
|
-
const [enteredAmount, setEnteredAmount] =
|
|
3302
|
+
const [enteredAmount, setEnteredAmount] = useState11(null);
|
|
3150
3303
|
const amount = enteredAmount ?? (expectedFloatMinor != null ? decimal(expectedFloatMinor, digits) : "");
|
|
3151
|
-
const [busy, setBusy] =
|
|
3152
|
-
const [error, setError] =
|
|
3304
|
+
const [busy, setBusy] = useState11(false);
|
|
3305
|
+
const [error, setError] = useState11("");
|
|
3153
3306
|
const valid = validAmount(amount, digits);
|
|
3154
3307
|
const countedMinor = valid ? parseMinor(amount, digits) : NaN;
|
|
3155
3308
|
const open = async () => {
|
|
@@ -3165,10 +3318,10 @@ function OpenRegisterCard({ register, currency, configuredFloatMinor, className
|
|
|
3165
3318
|
}
|
|
3166
3319
|
};
|
|
3167
3320
|
const amountLabel = `Cash in the drawer to start (${currencySymbol(currency)})`;
|
|
3168
|
-
return /* @__PURE__ */
|
|
3169
|
-
/* @__PURE__ */
|
|
3170
|
-
/* @__PURE__ */
|
|
3171
|
-
/* @__PURE__ */
|
|
3321
|
+
return /* @__PURE__ */ jsxs38(View47, { testID: "open-register-card", className: cn76("bg-card gap-3 rounded-md p-4", className), children: [
|
|
3322
|
+
/* @__PURE__ */ jsx80(Text, { className: "text-lg font-semibold", children: "Open register" }),
|
|
3323
|
+
/* @__PURE__ */ jsx80(Label, { testID: "open-register-amount-label", nativeID: AMOUNT_LABEL_ID, children: amountLabel }),
|
|
3324
|
+
/* @__PURE__ */ jsx80(Input, { children: /* @__PURE__ */ jsx80(
|
|
3172
3325
|
Input.Field,
|
|
3173
3326
|
{
|
|
3174
3327
|
testID: "open-register-amount",
|
|
@@ -3179,40 +3332,40 @@ function OpenRegisterCard({ register, currency, configuredFloatMinor, className
|
|
|
3179
3332
|
accessibilityLabelledBy: AMOUNT_LABEL_ID
|
|
3180
3333
|
}
|
|
3181
3334
|
) }),
|
|
3182
|
-
configuredFloatMinor != null && /* @__PURE__ */
|
|
3335
|
+
configuredFloatMinor != null && /* @__PURE__ */ jsx80(
|
|
3183
3336
|
Button,
|
|
3184
3337
|
{
|
|
3185
3338
|
testID: "open-register-chip-configured",
|
|
3186
3339
|
variant: "outline",
|
|
3187
3340
|
className: "min-h-11",
|
|
3188
3341
|
onPress: () => setEnteredAmount(decimal(configuredFloatMinor, digits)),
|
|
3189
|
-
children: /* @__PURE__ */
|
|
3342
|
+
children: /* @__PURE__ */ jsxs38(Text, { children: [
|
|
3190
3343
|
"Use the configured float (",
|
|
3191
3344
|
formatMoney6({ amount: configuredFloatMinor, currency }),
|
|
3192
3345
|
")"
|
|
3193
3346
|
] })
|
|
3194
3347
|
}
|
|
3195
3348
|
),
|
|
3196
|
-
lastCountedMinor != null && /* @__PURE__ */
|
|
3349
|
+
lastCountedMinor != null && /* @__PURE__ */ jsx80(
|
|
3197
3350
|
Button,
|
|
3198
3351
|
{
|
|
3199
3352
|
testID: "open-register-chip-last",
|
|
3200
3353
|
variant: "outline",
|
|
3201
3354
|
className: "min-h-11",
|
|
3202
3355
|
onPress: () => setEnteredAmount(decimal(lastCountedMinor, digits)),
|
|
3203
|
-
children: /* @__PURE__ */
|
|
3356
|
+
children: /* @__PURE__ */ jsxs38(Text, { children: [
|
|
3204
3357
|
"Use the last counted cash (",
|
|
3205
3358
|
formatMoney6({ amount: lastCountedMinor, currency }),
|
|
3206
3359
|
")"
|
|
3207
3360
|
] })
|
|
3208
3361
|
}
|
|
3209
3362
|
),
|
|
3210
|
-
expectedFloatMinor !== null && valid && countedMinor !== expectedFloatMinor && /* @__PURE__ */
|
|
3363
|
+
expectedFloatMinor !== null && valid && countedMinor !== expectedFloatMinor && /* @__PURE__ */ jsxs38(Text, { testID: "opening-variance", children: [
|
|
3211
3364
|
formatMoney6({ amount: countedMinor - expectedFloatMinor, currency }),
|
|
3212
3365
|
" vs the expected float"
|
|
3213
3366
|
] }),
|
|
3214
|
-
!!error && /* @__PURE__ */
|
|
3215
|
-
/* @__PURE__ */
|
|
3367
|
+
!!error && /* @__PURE__ */ jsx80(Text, { className: "text-destructive", children: error }),
|
|
3368
|
+
/* @__PURE__ */ jsx80(Button, { testID: "open-register-button", className: "min-h-14", disabled: busy || !valid, onPress: open, children: /* @__PURE__ */ jsx80(Text, { children: busy ? "Opening\u2026" : "Open register" }) })
|
|
3216
3369
|
] });
|
|
3217
3370
|
}
|
|
3218
3371
|
function decimal(minor, digits) {
|
|
@@ -3221,8 +3374,8 @@ function decimal(minor, digits) {
|
|
|
3221
3374
|
}
|
|
3222
3375
|
|
|
3223
3376
|
// src/register/register-bar.tsx
|
|
3224
|
-
import { Pressable as
|
|
3225
|
-
import { cn as
|
|
3377
|
+
import { Pressable as Pressable23, View as View48 } from "react-native";
|
|
3378
|
+
import { cn as cn77 } from "@tallyui/theme";
|
|
3226
3379
|
|
|
3227
3380
|
// src/register/register-bar.helpers.ts
|
|
3228
3381
|
function describeRegisterBarPill({
|
|
@@ -3245,7 +3398,7 @@ function describeRegisterBarPill({
|
|
|
3245
3398
|
}
|
|
3246
3399
|
|
|
3247
3400
|
// src/register/register-bar.tsx
|
|
3248
|
-
import { jsx as
|
|
3401
|
+
import { jsx as jsx81, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3249
3402
|
function RegisterBar({
|
|
3250
3403
|
register,
|
|
3251
3404
|
registerId,
|
|
@@ -3266,10 +3419,10 @@ function RegisterBar({
|
|
|
3266
3419
|
sessionsOn: enabled,
|
|
3267
3420
|
closing
|
|
3268
3421
|
});
|
|
3269
|
-
return /* @__PURE__ */
|
|
3270
|
-
/* @__PURE__ */
|
|
3271
|
-
pill && (onPressPill ? /* @__PURE__ */
|
|
3272
|
-
(session || lastClosure) && /* @__PURE__ */
|
|
3422
|
+
return /* @__PURE__ */ jsxs39(HStack, { testID: "register-bar", className: cn77("bg-card border-border h-12 border-b px-3", className), children: [
|
|
3423
|
+
/* @__PURE__ */ jsx81(View48, { className: "min-w-0 flex-1 shrink", children: multiRegister && registerId !== null && /* @__PURE__ */ jsx81(Text, { testID: "register-bar-name", numberOfLines: 1, children: registerName }) }),
|
|
3424
|
+
pill && (onPressPill ? /* @__PURE__ */ jsx81(Pressable23, { testID: "register-bar-pill", accessibilityRole: "button", accessibilityLabel: pill, onPress: onPressPill, children: /* @__PURE__ */ jsx81(Badge, { label: pill, variant: "warning" }) }) : /* @__PURE__ */ jsx81(Badge, { testID: "register-bar-pill", label: pill, variant: "warning" })),
|
|
3425
|
+
(session || lastClosure) && /* @__PURE__ */ jsx81(
|
|
3273
3426
|
Button,
|
|
3274
3427
|
{
|
|
3275
3428
|
variant: "ghost",
|
|
@@ -3277,17 +3430,17 @@ function RegisterBar({
|
|
|
3277
3430
|
testID: "register-bar-open-panel",
|
|
3278
3431
|
accessibilityLabel: "Open register panel",
|
|
3279
3432
|
onPress: onOpenPanel,
|
|
3280
|
-
children: /* @__PURE__ */
|
|
3433
|
+
children: /* @__PURE__ */ jsx81(Text, { className: overdue ? "text-warning" : void 0, children: "Register \u203A" })
|
|
3281
3434
|
}
|
|
3282
3435
|
)
|
|
3283
3436
|
] });
|
|
3284
3437
|
}
|
|
3285
3438
|
|
|
3286
3439
|
// src/register/movement-sheet.tsx
|
|
3287
|
-
import { useRef as useRef3, useState as
|
|
3440
|
+
import { useRef as useRef3, useState as useState12 } from "react";
|
|
3288
3441
|
import { movementFieldError, normalizeAmount, parseMinor as parseMinor2 } from "@tallyui/pos";
|
|
3289
3442
|
import { currencySymbol as currencySymbol2, minorUnitDigits as minorUnitDigits4 } from "@tallyui/core";
|
|
3290
|
-
import { Fragment as Fragment3, jsx as
|
|
3443
|
+
import { Fragment as Fragment3, jsx as jsx82, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
3291
3444
|
var LABELS = {
|
|
3292
3445
|
paid_in: "Paid in",
|
|
3293
3446
|
paid_out: "Paid out",
|
|
@@ -3297,11 +3450,11 @@ var AMOUNT_LABEL_ID2 = "movement-amount-label";
|
|
|
3297
3450
|
var REASON_LABEL_ID = "movement-reason-label";
|
|
3298
3451
|
function MovementSheet({ register, type, currency, onDone, onOpenChange, onOpenDrawer }) {
|
|
3299
3452
|
const digits = minorUnitDigits4(currency);
|
|
3300
|
-
const [amount, setAmount] =
|
|
3301
|
-
const [reason, setReason] =
|
|
3302
|
-
const [busy, setBusy] =
|
|
3453
|
+
const [amount, setAmount] = useState12("");
|
|
3454
|
+
const [reason, setReason] = useState12("");
|
|
3455
|
+
const [busy, setBusy] = useState12(false);
|
|
3303
3456
|
const busyRef = useRef3(false);
|
|
3304
|
-
const [error, setError] =
|
|
3457
|
+
const [error, setError] = useState12("");
|
|
3305
3458
|
const invalid = movementFieldError({ type, amount, reason });
|
|
3306
3459
|
const confirm = async () => {
|
|
3307
3460
|
if (invalid || busyRef.current) return;
|
|
@@ -3323,11 +3476,11 @@ function MovementSheet({ register, type, currency, onDone, onOpenChange, onOpenD
|
|
|
3323
3476
|
setBusy(false);
|
|
3324
3477
|
}
|
|
3325
3478
|
};
|
|
3326
|
-
return /* @__PURE__ */
|
|
3327
|
-
/* @__PURE__ */
|
|
3328
|
-
type !== "no_sale" && /* @__PURE__ */
|
|
3329
|
-
/* @__PURE__ */
|
|
3330
|
-
/* @__PURE__ */
|
|
3479
|
+
return /* @__PURE__ */ jsx82(Dialog, { open: true, onOpenChange, children: /* @__PURE__ */ jsxs40(DialogContent, { testID: "movement-sheet", children: [
|
|
3480
|
+
/* @__PURE__ */ jsx82(DialogTitle, { children: LABELS[type] }),
|
|
3481
|
+
type !== "no_sale" && /* @__PURE__ */ jsxs40(Fragment3, { children: [
|
|
3482
|
+
/* @__PURE__ */ jsx82(Label, { testID: "movement-amount-label", nativeID: AMOUNT_LABEL_ID2, children: `Amount (${currencySymbol2(currency)})` }),
|
|
3483
|
+
/* @__PURE__ */ jsx82(Input, { children: /* @__PURE__ */ jsx82(
|
|
3331
3484
|
Input.Field,
|
|
3332
3485
|
{
|
|
3333
3486
|
testID: "movement-amount",
|
|
@@ -3339,8 +3492,8 @@ function MovementSheet({ register, type, currency, onDone, onOpenChange, onOpenD
|
|
|
3339
3492
|
}
|
|
3340
3493
|
) })
|
|
3341
3494
|
] }),
|
|
3342
|
-
/* @__PURE__ */
|
|
3343
|
-
/* @__PURE__ */
|
|
3495
|
+
/* @__PURE__ */ jsx82(Label, { testID: "movement-reason-label", nativeID: REASON_LABEL_ID, children: "Reason" }),
|
|
3496
|
+
/* @__PURE__ */ jsx82(Input, { children: /* @__PURE__ */ jsx82(
|
|
3344
3497
|
Input.Field,
|
|
3345
3498
|
{
|
|
3346
3499
|
testID: "movement-reason",
|
|
@@ -3351,20 +3504,20 @@ function MovementSheet({ register, type, currency, onDone, onOpenChange, onOpenD
|
|
|
3351
3504
|
accessibilityLabelledBy: REASON_LABEL_ID
|
|
3352
3505
|
}
|
|
3353
3506
|
) }),
|
|
3354
|
-
!!error && /* @__PURE__ */
|
|
3355
|
-
!!invalid && /* @__PURE__ */
|
|
3356
|
-
/* @__PURE__ */
|
|
3507
|
+
!!error && /* @__PURE__ */ jsx82(Text, { className: "text-destructive", children: error }),
|
|
3508
|
+
!!invalid && /* @__PURE__ */ jsx82(Text, { testID: "movement-invalid", className: "text-muted-foreground", children: invalid === "amount" ? "Enter a valid amount." : "Enter a reason." }),
|
|
3509
|
+
/* @__PURE__ */ jsx82(Button, { testID: "movement-confirm", disabled: !!invalid || busy, onPress: confirm, children: /* @__PURE__ */ jsx82(Text, { children: busy ? "Recording\u2026" : "Record" }) })
|
|
3357
3510
|
] }) });
|
|
3358
3511
|
}
|
|
3359
3512
|
|
|
3360
3513
|
// src/register/register-panel.tsx
|
|
3361
|
-
import { useState as
|
|
3362
|
-
import { ScrollView as ScrollView12, useWindowDimensions as useWindowDimensions2, View as
|
|
3514
|
+
import { useState as useState14 } from "react";
|
|
3515
|
+
import { ScrollView as ScrollView12, useWindowDimensions as useWindowDimensions2, View as View50 } from "react-native";
|
|
3363
3516
|
import { formatMoney as formatMoney8 } from "@tallyui/core";
|
|
3364
3517
|
|
|
3365
3518
|
// src/register/register-count.tsx
|
|
3366
|
-
import { useEffect as useEffect3, useRef as useRef4, useState as
|
|
3367
|
-
import { Platform, Pressable as
|
|
3519
|
+
import { useEffect as useEffect3, useRef as useRef4, useState as useState13 } from "react";
|
|
3520
|
+
import { Platform, Pressable as Pressable24, ScrollView as ScrollView11, useWindowDimensions, View as View49 } from "react-native";
|
|
3368
3521
|
import {
|
|
3369
3522
|
closeNeedsApproval,
|
|
3370
3523
|
countVariance,
|
|
@@ -3376,8 +3529,8 @@ import {
|
|
|
3376
3529
|
varianceText
|
|
3377
3530
|
} from "@tallyui/pos";
|
|
3378
3531
|
import { currencySymbol as currencySymbol3, formatMoney as formatMoney7, minorUnitDigits as minorUnitDigits5 } from "@tallyui/core";
|
|
3379
|
-
import { cn as
|
|
3380
|
-
import { jsx as
|
|
3532
|
+
import { cn as cn78 } from "@tallyui/theme";
|
|
3533
|
+
import { jsx as jsx83, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
3381
3534
|
var AMOUNT_LABEL_ID3 = "count-amount-label";
|
|
3382
3535
|
var APPROVAL_REQUIRED_TEXT = "Manager approval needed. Ask a manager to approve, or count again.";
|
|
3383
3536
|
function varianceWord(key) {
|
|
@@ -3408,8 +3561,8 @@ function DenominationTile({ value, count: count2, currency, onAdd }) {
|
|
|
3408
3561
|
timer.current = void 0;
|
|
3409
3562
|
};
|
|
3410
3563
|
useEffect3(() => stop, []);
|
|
3411
|
-
return /* @__PURE__ */
|
|
3412
|
-
|
|
3564
|
+
return /* @__PURE__ */ jsxs41(
|
|
3565
|
+
Pressable24,
|
|
3413
3566
|
{
|
|
3414
3567
|
testID: `den-tile-${value}`,
|
|
3415
3568
|
accessibilityRole: "button",
|
|
@@ -3430,8 +3583,8 @@ function DenominationTile({ value, count: count2, currency, onAdd }) {
|
|
|
3430
3583
|
if (!held.current) onAdd(1);
|
|
3431
3584
|
},
|
|
3432
3585
|
children: [
|
|
3433
|
-
/* @__PURE__ */
|
|
3434
|
-
/* @__PURE__ */
|
|
3586
|
+
/* @__PURE__ */ jsx83(Text, { className: "text-sm tabular-nums", numberOfLines: 1, children: label }),
|
|
3587
|
+
/* @__PURE__ */ jsx83(Text, { testID: `den-count-${value}`, className: "bg-background min-w-6 rounded-full px-1.5 text-center text-xs tabular-nums", children: count2 })
|
|
3435
3588
|
]
|
|
3436
3589
|
}
|
|
3437
3590
|
);
|
|
@@ -3442,18 +3595,18 @@ function RegisterCount({ register, currency, approve, className }) {
|
|
|
3442
3595
|
const faces = denominations[currency] ?? denominations.default;
|
|
3443
3596
|
const { width } = useWindowDimensions();
|
|
3444
3597
|
const columns = width < 480 ? 3 : 4;
|
|
3445
|
-
const [pieces, setPieces] =
|
|
3446
|
-
const [cashText, setCashText] =
|
|
3598
|
+
const [pieces, setPieces] = useState13({});
|
|
3599
|
+
const [cashText, setCashText] = useState13(
|
|
3447
3600
|
() => session?.counted?.cash != null ? minorToDecimal(session.counted.cash, digits) : ""
|
|
3448
3601
|
);
|
|
3449
|
-
const [others, setOthers] =
|
|
3602
|
+
const [others, setOthers] = useState13(
|
|
3450
3603
|
() => Object.fromEntries(
|
|
3451
3604
|
Object.entries(session?.counted ?? {}).filter(([method]) => method !== "cash").map(([method, minor]) => [method, minorToDecimal(minor, digits)])
|
|
3452
3605
|
)
|
|
3453
3606
|
);
|
|
3454
|
-
const [busy, setBusy] =
|
|
3455
|
-
const [error, setError] =
|
|
3456
|
-
const [refusal, setRefusal] =
|
|
3607
|
+
const [busy, setBusy] = useState13(false);
|
|
3608
|
+
const [error, setError] = useState13("");
|
|
3609
|
+
const [refusal, setRefusal] = useState13("");
|
|
3457
3610
|
const usingTiles = Object.keys(pieces).length > 0;
|
|
3458
3611
|
const tilesTotal = denominationTotal(pieces);
|
|
3459
3612
|
const displayAmount = usingTiles ? minorToDecimal(tilesTotal, digits) : cashText;
|
|
@@ -3501,11 +3654,11 @@ function RegisterCount({ register, currency, approve, className }) {
|
|
|
3501
3654
|
void attempt(() => actions.closeSession({ counted }));
|
|
3502
3655
|
};
|
|
3503
3656
|
if (!session) return null;
|
|
3504
|
-
return /* @__PURE__ */
|
|
3505
|
-
/* @__PURE__ */
|
|
3506
|
-
/* @__PURE__ */
|
|
3507
|
-
/* @__PURE__ */
|
|
3508
|
-
/* @__PURE__ */
|
|
3657
|
+
return /* @__PURE__ */ jsxs41(View49, { testID: "register-count", className: cn78("bg-card flex-1 rounded-md", className), children: [
|
|
3658
|
+
/* @__PURE__ */ jsxs41(ScrollView11, { className: "flex-1", contentContainerClassName: "gap-3 p-4", children: [
|
|
3659
|
+
/* @__PURE__ */ jsx83(Text, { className: "min-h-11 text-lg font-semibold", children: "Count the drawer" }),
|
|
3660
|
+
/* @__PURE__ */ jsx83(Label, { testID: "count-amount-label", nativeID: AMOUNT_LABEL_ID3, children: `Cash counted (${currencySymbol3(currency)})` }),
|
|
3661
|
+
/* @__PURE__ */ jsx83(Input, { children: /* @__PURE__ */ jsx83(
|
|
3509
3662
|
Input.Field,
|
|
3510
3663
|
{
|
|
3511
3664
|
testID: "count-amount",
|
|
@@ -3519,16 +3672,16 @@ function RegisterCount({ register, currency, approve, className }) {
|
|
|
3519
3672
|
accessibilityLabelledBy: AMOUNT_LABEL_ID3
|
|
3520
3673
|
}
|
|
3521
3674
|
) }),
|
|
3522
|
-
!blind && valid && /* @__PURE__ */
|
|
3675
|
+
!blind && valid && /* @__PURE__ */ jsx83(Text, { testID: "count-variance", className: "min-h-11 tabular-nums", children: `Expected ${formatMoney7({ amount: expected.cash ?? 0, currency })} \xB7 ${varianceText(
|
|
3523
3676
|
variance,
|
|
3524
3677
|
digits,
|
|
3525
3678
|
(major) => formatMoney7({ amount: Math.round(major * 10 ** digits), currency }) ?? "",
|
|
3526
3679
|
varianceWord
|
|
3527
3680
|
)}` }),
|
|
3528
|
-
/* @__PURE__ */
|
|
3529
|
-
Array.from({ length: Math.ceil(faces.length / columns) }, (_, row) => /* @__PURE__ */
|
|
3681
|
+
/* @__PURE__ */ jsxs41(View49, { testID: "count-denominations", className: "gap-2", children: [
|
|
3682
|
+
Array.from({ length: Math.ceil(faces.length / columns) }, (_, row) => /* @__PURE__ */ jsx83(View49, { className: "flex-row gap-2", children: Array.from({ length: columns }, (_2, column) => {
|
|
3530
3683
|
const value = faces[row * columns + column];
|
|
3531
|
-
return value ? /* @__PURE__ */
|
|
3684
|
+
return value ? /* @__PURE__ */ jsx83(
|
|
3532
3685
|
DenominationTile,
|
|
3533
3686
|
{
|
|
3534
3687
|
value,
|
|
@@ -3537,9 +3690,9 @@ function RegisterCount({ register, currency, approve, className }) {
|
|
|
3537
3690
|
onAdd: (n) => addPieces(value, n)
|
|
3538
3691
|
},
|
|
3539
3692
|
value
|
|
3540
|
-
) : /* @__PURE__ */
|
|
3693
|
+
) : /* @__PURE__ */ jsx83(View49, { className: "flex-1" }, column);
|
|
3541
3694
|
}) }, row)),
|
|
3542
|
-
/* @__PURE__ */
|
|
3695
|
+
/* @__PURE__ */ jsx83(
|
|
3543
3696
|
Button,
|
|
3544
3697
|
{
|
|
3545
3698
|
testID: "count-clear",
|
|
@@ -3549,16 +3702,16 @@ function RegisterCount({ register, currency, approve, className }) {
|
|
|
3549
3702
|
setPieces({});
|
|
3550
3703
|
setCashText(minorToDecimal(0, digits));
|
|
3551
3704
|
},
|
|
3552
|
-
children: /* @__PURE__ */
|
|
3705
|
+
children: /* @__PURE__ */ jsx83(Text, { children: "Clear" })
|
|
3553
3706
|
}
|
|
3554
3707
|
)
|
|
3555
3708
|
] }),
|
|
3556
3709
|
otherMethods.map((method) => {
|
|
3557
3710
|
const labelId = `count-tender-${method}-label`;
|
|
3558
3711
|
const label = `${tenderLabel(method)} counted (${currencySymbol3(currency)})`;
|
|
3559
|
-
return /* @__PURE__ */
|
|
3560
|
-
/* @__PURE__ */
|
|
3561
|
-
/* @__PURE__ */
|
|
3712
|
+
return /* @__PURE__ */ jsxs41(View49, { className: "gap-2", children: [
|
|
3713
|
+
/* @__PURE__ */ jsx83(Label, { testID: labelId, nativeID: labelId, children: label }),
|
|
3714
|
+
/* @__PURE__ */ jsx83(Input, { children: /* @__PURE__ */ jsx83(
|
|
3562
3715
|
Input.Field,
|
|
3563
3716
|
{
|
|
3564
3717
|
testID: `count-tender-${method}`,
|
|
@@ -3571,11 +3724,11 @@ function RegisterCount({ register, currency, approve, className }) {
|
|
|
3571
3724
|
) })
|
|
3572
3725
|
] }, method);
|
|
3573
3726
|
}),
|
|
3574
|
-
!!refusal && /* @__PURE__ */
|
|
3575
|
-
!!error && /* @__PURE__ */
|
|
3727
|
+
!!refusal && /* @__PURE__ */ jsx83(Text, { testID: "count-manager-line", className: "text-warning min-h-11", children: refusal }),
|
|
3728
|
+
!!error && /* @__PURE__ */ jsx83(Text, { testID: "count-error", className: "text-destructive min-h-11", children: error })
|
|
3576
3729
|
] }),
|
|
3577
|
-
/* @__PURE__ */
|
|
3578
|
-
/* @__PURE__ */
|
|
3730
|
+
/* @__PURE__ */ jsxs41(View49, { className: "gap-2 border-t border-border p-4", children: [
|
|
3731
|
+
/* @__PURE__ */ jsx83(
|
|
3579
3732
|
Button,
|
|
3580
3733
|
{
|
|
3581
3734
|
testID: "count-back",
|
|
@@ -3583,17 +3736,17 @@ function RegisterCount({ register, currency, approve, className }) {
|
|
|
3583
3736
|
className: "min-h-11",
|
|
3584
3737
|
disabled: busy,
|
|
3585
3738
|
onPress: () => attempt(actions.backToSelling),
|
|
3586
|
-
children: /* @__PURE__ */
|
|
3739
|
+
children: /* @__PURE__ */ jsx83(Text, { children: "Back to selling" })
|
|
3587
3740
|
}
|
|
3588
3741
|
),
|
|
3589
|
-
/* @__PURE__ */
|
|
3742
|
+
/* @__PURE__ */ jsx83(
|
|
3590
3743
|
Button,
|
|
3591
3744
|
{
|
|
3592
3745
|
testID: "count-close",
|
|
3593
3746
|
className: "min-h-14",
|
|
3594
3747
|
disabled: !valid || otherTendersInvalid || busy,
|
|
3595
3748
|
onPress: onClose,
|
|
3596
|
-
children: /* @__PURE__ */
|
|
3749
|
+
children: /* @__PURE__ */ jsx83(Text, { children: busy ? "Closing\u2026" : "Close register" })
|
|
3597
3750
|
}
|
|
3598
3751
|
)
|
|
3599
3752
|
] })
|
|
@@ -3601,16 +3754,16 @@ function RegisterCount({ register, currency, approve, className }) {
|
|
|
3601
3754
|
}
|
|
3602
3755
|
|
|
3603
3756
|
// src/register/register-panel.tsx
|
|
3604
|
-
import { jsx as
|
|
3757
|
+
import { jsx as jsx84, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
3605
3758
|
var DIALOG_VERTICAL_MARGIN = 64;
|
|
3606
3759
|
function RegisterPanel({ register, currency, registerName, open, onOpenChange, className }) {
|
|
3607
3760
|
const { session, expected, salesCount, blind, movements, lastClosure, actions } = register;
|
|
3608
3761
|
const otherTenders = Object.entries(expected).filter(([method, amount]) => method !== "cash" && amount !== 0);
|
|
3609
3762
|
const { height: windowHeight } = useWindowDimensions2();
|
|
3610
3763
|
const maxHeight = Math.max(280, windowHeight - DIALOG_VERTICAL_MARGIN);
|
|
3611
|
-
const [movementType, setMovementType] =
|
|
3612
|
-
const [expanded, setExpanded] =
|
|
3613
|
-
const [error, setError] =
|
|
3764
|
+
const [movementType, setMovementType] = useState14(null);
|
|
3765
|
+
const [expanded, setExpanded] = useState14(false);
|
|
3766
|
+
const [error, setError] = useState14("");
|
|
3614
3767
|
const attempt = async (action) => {
|
|
3615
3768
|
try {
|
|
3616
3769
|
await action();
|
|
@@ -3622,25 +3775,25 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
|
|
|
3622
3775
|
const activeMovements = movements.filter(
|
|
3623
3776
|
(row) => row.type !== "void" && !row.voided_by && !movements.some((entry) => entry.voids === row.id)
|
|
3624
3777
|
);
|
|
3625
|
-
return /* @__PURE__ */
|
|
3778
|
+
return /* @__PURE__ */ jsx84(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs42(
|
|
3626
3779
|
DialogContent,
|
|
3627
3780
|
{
|
|
3628
3781
|
testID: "register-panel",
|
|
3629
3782
|
className: `flex-col overflow-hidden ${className ?? ""}`,
|
|
3630
3783
|
style: { maxHeight },
|
|
3631
3784
|
children: [
|
|
3632
|
-
/* @__PURE__ */
|
|
3633
|
-
/* @__PURE__ */
|
|
3634
|
-
/* @__PURE__ */
|
|
3785
|
+
/* @__PURE__ */ jsxs42(View50, { className: "flex-row items-center justify-between gap-2", children: [
|
|
3786
|
+
/* @__PURE__ */ jsx84(DialogTitle, { testID: "register-panel-amount", children: registerName ?? "Register" }),
|
|
3787
|
+
/* @__PURE__ */ jsx84(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx84(IconButton, { variant: "ghost", size: "sm", testID: "register-panel-dismiss", accessibilityLabel: "Close panel", children: /* @__PURE__ */ jsx84(XIcon, { size: 16 }) }) })
|
|
3635
3788
|
] }),
|
|
3636
|
-
/* @__PURE__ */
|
|
3789
|
+
/* @__PURE__ */ jsxs42(Text, { testID: "register-panel-sales-count", children: [
|
|
3637
3790
|
salesCount,
|
|
3638
3791
|
" sale",
|
|
3639
3792
|
salesCount === 1 ? "" : "s",
|
|
3640
3793
|
" this session"
|
|
3641
3794
|
] }),
|
|
3642
|
-
/* @__PURE__ */
|
|
3643
|
-
/* @__PURE__ */
|
|
3795
|
+
/* @__PURE__ */ jsxs42(ScrollView12, { testID: "register-panel-body", className: "flex-1", contentContainerClassName: "gap-3", children: [
|
|
3796
|
+
/* @__PURE__ */ jsx84(View50, { className: "flex-row gap-2", children: ["paid_in", "paid_out", "no_sale"].map((type) => /* @__PURE__ */ jsx84(
|
|
3644
3797
|
Button,
|
|
3645
3798
|
{
|
|
3646
3799
|
testID: `register-panel-${type.replace("_", "-")}`,
|
|
@@ -3648,40 +3801,40 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
|
|
|
3648
3801
|
variant: "outline",
|
|
3649
3802
|
disabled: session?.status !== "open",
|
|
3650
3803
|
onPress: () => setMovementType(type),
|
|
3651
|
-
children: /* @__PURE__ */
|
|
3804
|
+
children: /* @__PURE__ */ jsx84(Text, { children: type === "paid_in" ? "Paid in" : type === "paid_out" ? "Paid out" : "No sale" })
|
|
3652
3805
|
},
|
|
3653
3806
|
type
|
|
3654
3807
|
)) }),
|
|
3655
|
-
!blind && /* @__PURE__ */
|
|
3656
|
-
/* @__PURE__ */
|
|
3657
|
-
Object.entries(expected).filter(([method]) => method === "cash").map(([method, amount]) => /* @__PURE__ */
|
|
3658
|
-
/* @__PURE__ */
|
|
3659
|
-
/* @__PURE__ */
|
|
3808
|
+
!blind && /* @__PURE__ */ jsxs42(View50, { testID: "register-panel-expected", className: "gap-1", children: [
|
|
3809
|
+
/* @__PURE__ */ jsx84(Text, { className: "text-muted-foreground text-sm font-semibold", children: "Expected in the drawer" }),
|
|
3810
|
+
Object.entries(expected).filter(([method]) => method === "cash").map(([method, amount]) => /* @__PURE__ */ jsxs42(View50, { className: "min-h-11 flex-row items-center justify-between", children: [
|
|
3811
|
+
/* @__PURE__ */ jsx84(Text, { children: tenderLabel("cash") }),
|
|
3812
|
+
/* @__PURE__ */ jsx84(Text, { className: "tabular-nums", children: formatMoney8({ amount, currency }) })
|
|
3660
3813
|
] }, method))
|
|
3661
3814
|
] }),
|
|
3662
|
-
!blind && otherTenders.length > 0 && /* @__PURE__ */
|
|
3663
|
-
/* @__PURE__ */
|
|
3664
|
-
otherTenders.map(([method, amount]) => /* @__PURE__ */
|
|
3665
|
-
/* @__PURE__ */
|
|
3666
|
-
/* @__PURE__ */
|
|
3815
|
+
!blind && otherTenders.length > 0 && /* @__PURE__ */ jsxs42(View50, { testID: "register-panel-other-tenders", className: "gap-1", children: [
|
|
3816
|
+
/* @__PURE__ */ jsx84(Text, { className: "text-muted-foreground text-sm font-semibold", children: "Other tenders" }),
|
|
3817
|
+
otherTenders.map(([method, amount]) => /* @__PURE__ */ jsxs42(View50, { className: "min-h-11 flex-row items-center justify-between", children: [
|
|
3818
|
+
/* @__PURE__ */ jsx84(Text, { children: tenderLabel(method) }),
|
|
3819
|
+
/* @__PURE__ */ jsx84(Text, { className: "tabular-nums", children: formatMoney8({ amount, currency }) })
|
|
3667
3820
|
] }, method))
|
|
3668
3821
|
] }),
|
|
3669
|
-
/* @__PURE__ */
|
|
3822
|
+
/* @__PURE__ */ jsx84(
|
|
3670
3823
|
Button,
|
|
3671
3824
|
{
|
|
3672
3825
|
testID: "register-panel-movements",
|
|
3673
3826
|
variant: "ghost",
|
|
3674
3827
|
className: "min-h-11",
|
|
3675
3828
|
onPress: () => setExpanded(!expanded),
|
|
3676
|
-
children: /* @__PURE__ */
|
|
3829
|
+
children: /* @__PURE__ */ jsx84(Text, { children: "Paid in / out" })
|
|
3677
3830
|
}
|
|
3678
3831
|
),
|
|
3679
|
-
expanded && activeMovements.map((row) => /* @__PURE__ */
|
|
3680
|
-
/* @__PURE__ */
|
|
3832
|
+
expanded && activeMovements.map((row) => /* @__PURE__ */ jsxs42(View50, { className: "min-h-11 flex-row items-center gap-2", children: [
|
|
3833
|
+
/* @__PURE__ */ jsxs42(Text, { testID: `movement-row-${row.id}`, className: "flex-1", children: [
|
|
3681
3834
|
row.type === "paid_in" ? "Paid in" : row.type === "paid_out" ? "Paid out" : "No sale",
|
|
3682
3835
|
!blind ? ` \xB7 ${formatMoney8({ amount: row.amountMinor, currency })} \xB7 ${row.reason}` : ""
|
|
3683
3836
|
] }),
|
|
3684
|
-
/* @__PURE__ */
|
|
3837
|
+
/* @__PURE__ */ jsx84(
|
|
3685
3838
|
Button,
|
|
3686
3839
|
{
|
|
3687
3840
|
variant: "ghost",
|
|
@@ -3689,12 +3842,12 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
|
|
|
3689
3842
|
testID: `movement-void-${row.id}`,
|
|
3690
3843
|
disabled: session?.status !== "open",
|
|
3691
3844
|
onPress: () => attempt(() => actions.voidMovement(row.id)),
|
|
3692
|
-
children: /* @__PURE__ */
|
|
3845
|
+
children: /* @__PURE__ */ jsx84(Text, { children: "Undo" })
|
|
3693
3846
|
}
|
|
3694
3847
|
)
|
|
3695
3848
|
] }, row.id)),
|
|
3696
|
-
!!error && /* @__PURE__ */
|
|
3697
|
-
/* @__PURE__ */
|
|
3849
|
+
!!error && /* @__PURE__ */ jsx84(Text, { className: "text-destructive", children: error }),
|
|
3850
|
+
/* @__PURE__ */ jsx84(
|
|
3698
3851
|
Button,
|
|
3699
3852
|
{
|
|
3700
3853
|
testID: "register-panel-close",
|
|
@@ -3705,11 +3858,11 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
|
|
|
3705
3858
|
await actions.startCounting();
|
|
3706
3859
|
onOpenChange(false);
|
|
3707
3860
|
}),
|
|
3708
|
-
children: /* @__PURE__ */
|
|
3861
|
+
children: /* @__PURE__ */ jsx84(Text, { children: "Close register" })
|
|
3709
3862
|
}
|
|
3710
3863
|
)
|
|
3711
3864
|
] }),
|
|
3712
|
-
movementType && /* @__PURE__ */
|
|
3865
|
+
movementType && /* @__PURE__ */ jsx84(
|
|
3713
3866
|
MovementSheet,
|
|
3714
3867
|
{
|
|
3715
3868
|
register,
|
|
@@ -3727,9 +3880,9 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
|
|
|
3727
3880
|
}
|
|
3728
3881
|
|
|
3729
3882
|
// src/register/register-column.tsx
|
|
3730
|
-
import { useState as
|
|
3731
|
-
import { View as
|
|
3732
|
-
import { Fragment as Fragment4, jsx as
|
|
3883
|
+
import { useState as useState15 } from "react";
|
|
3884
|
+
import { View as View51 } from "react-native";
|
|
3885
|
+
import { Fragment as Fragment4, jsx as jsx85, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
3733
3886
|
function RegisterColumn({
|
|
3734
3887
|
register,
|
|
3735
3888
|
registerId,
|
|
@@ -3741,30 +3894,30 @@ function RegisterColumn({
|
|
|
3741
3894
|
cartEmpty,
|
|
3742
3895
|
children
|
|
3743
3896
|
}) {
|
|
3744
|
-
const [finishing, setFinishing] =
|
|
3897
|
+
const [finishing, setFinishing] = useState15(false);
|
|
3745
3898
|
if (registerId === null) {
|
|
3746
|
-
return /* @__PURE__ */
|
|
3899
|
+
return /* @__PURE__ */ jsx85(RegisterPicker, { registers, onPick, className: "flex-1" });
|
|
3747
3900
|
}
|
|
3748
3901
|
if (register.session?.status === "closed") {
|
|
3749
|
-
return register.closing && !finishing ? /* @__PURE__ */
|
|
3902
|
+
return register.closing && !finishing ? /* @__PURE__ */ jsx85(Fragment4, { children: countSlot }) : /* @__PURE__ */ jsx85(FinishClose, { register, busy: finishing, setBusy: setFinishing });
|
|
3750
3903
|
}
|
|
3751
3904
|
if (!register.session) {
|
|
3752
|
-
return /* @__PURE__ */
|
|
3905
|
+
return /* @__PURE__ */ jsx85(OpenRegisterCard, { register, currency, configuredFloatMinor, className: "flex-1" });
|
|
3753
3906
|
}
|
|
3754
3907
|
if (register.session.status === "counting") {
|
|
3755
|
-
return /* @__PURE__ */
|
|
3908
|
+
return /* @__PURE__ */ jsx85(Fragment4, { children: countSlot });
|
|
3756
3909
|
}
|
|
3757
|
-
return /* @__PURE__ */
|
|
3758
|
-
register.overdue && cartEmpty && /* @__PURE__ */
|
|
3759
|
-
/* @__PURE__ */
|
|
3760
|
-
/* @__PURE__ */
|
|
3910
|
+
return /* @__PURE__ */ jsxs43(View51, { testID: "register-column", className: "flex-1", children: [
|
|
3911
|
+
register.overdue && cartEmpty && /* @__PURE__ */ jsxs43(View51, { testID: "register-column-overdue", className: "bg-warning/10 flex-row items-center justify-between gap-2 px-3 py-2", children: [
|
|
3912
|
+
/* @__PURE__ */ jsx85(Text, { className: "flex-1", children: "This register is overdue for closing." }),
|
|
3913
|
+
/* @__PURE__ */ jsx85(
|
|
3761
3914
|
Button,
|
|
3762
3915
|
{
|
|
3763
3916
|
testID: "register-column-close-overdue",
|
|
3764
3917
|
variant: "outline",
|
|
3765
3918
|
className: "min-h-11",
|
|
3766
3919
|
onPress: () => register.actions.startCounting(),
|
|
3767
|
-
children: /* @__PURE__ */
|
|
3920
|
+
children: /* @__PURE__ */ jsx85(Text, { children: "Close register" })
|
|
3768
3921
|
}
|
|
3769
3922
|
)
|
|
3770
3923
|
] }),
|
|
@@ -3772,7 +3925,7 @@ function RegisterColumn({
|
|
|
3772
3925
|
] });
|
|
3773
3926
|
}
|
|
3774
3927
|
function FinishClose({ register, busy, setBusy }) {
|
|
3775
|
-
const [error, setError] =
|
|
3928
|
+
const [error, setError] = useState15("");
|
|
3776
3929
|
const finish = async () => {
|
|
3777
3930
|
setBusy(true);
|
|
3778
3931
|
setError("");
|
|
@@ -3784,19 +3937,19 @@ function FinishClose({ register, busy, setBusy }) {
|
|
|
3784
3937
|
setBusy(false);
|
|
3785
3938
|
}
|
|
3786
3939
|
};
|
|
3787
|
-
return /* @__PURE__ */
|
|
3788
|
-
/* @__PURE__ */
|
|
3789
|
-
/* @__PURE__ */
|
|
3790
|
-
!!error && /* @__PURE__ */
|
|
3940
|
+
return /* @__PURE__ */ jsxs43(View51, { testID: "register-column-finish-close", className: "flex-1 gap-3 p-4", children: [
|
|
3941
|
+
/* @__PURE__ */ jsx85(Text, { children: "The last close didn't finish." }),
|
|
3942
|
+
/* @__PURE__ */ jsx85(Button, { testID: "register-column-finish-close-button", nativeID: "register-column-finish-close-button", disabled: busy, onPress: finish, children: /* @__PURE__ */ jsx85(Text, { children: "Finish closing" }) }),
|
|
3943
|
+
!!error && /* @__PURE__ */ jsx85(Text, { testID: "register-column-finish-close-error", className: "text-destructive", children: error })
|
|
3791
3944
|
] });
|
|
3792
3945
|
}
|
|
3793
3946
|
|
|
3794
3947
|
// src/register/closure-sheet.tsx
|
|
3795
|
-
import { useEffect as useEffect4, useRef as useRef5, useState as
|
|
3796
|
-
import { AccessibilityInfo, Animated, View as
|
|
3948
|
+
import { useEffect as useEffect4, useRef as useRef5, useState as useState16 } from "react";
|
|
3949
|
+
import { AccessibilityInfo, Animated, View as View52 } from "react-native";
|
|
3797
3950
|
import { countVariance as countVariance2, TAX_ROUNDING_MIXED_NOTE, varianceText as varianceText2 } from "@tallyui/pos";
|
|
3798
3951
|
import { formatMoney as formatMoney9, minorUnitDigits as minorUnitDigits6 } from "@tallyui/core";
|
|
3799
|
-
import { jsx as
|
|
3952
|
+
import { jsx as jsx86, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
3800
3953
|
function useCompletionMotion() {
|
|
3801
3954
|
const opacity = useRef5(new Animated.Value(0)).current;
|
|
3802
3955
|
const scale = useRef5(new Animated.Value(0.6)).current;
|
|
@@ -3824,8 +3977,8 @@ function ClosureSheet({ register, currency, onPrint, onDone }) {
|
|
|
3824
3977
|
const { lastClosure: closure, blind } = register;
|
|
3825
3978
|
const digits = minorUnitDigits6(currency);
|
|
3826
3979
|
const { opacity, scale } = useCompletionMotion();
|
|
3827
|
-
const [busy, setBusy] =
|
|
3828
|
-
const [error, setError] =
|
|
3980
|
+
const [busy, setBusy] = useState16(false);
|
|
3981
|
+
const [error, setError] = useState16("");
|
|
3829
3982
|
if (!closure) return null;
|
|
3830
3983
|
const methods = Object.keys(closure.counted);
|
|
3831
3984
|
const approvedByName = closure.breakdowns.approved_by_name;
|
|
@@ -3843,34 +3996,34 @@ function ClosureSheet({ register, currency, onPrint, onDone }) {
|
|
|
3843
3996
|
setBusy(false);
|
|
3844
3997
|
}
|
|
3845
3998
|
};
|
|
3846
|
-
return /* @__PURE__ */
|
|
3999
|
+
return /* @__PURE__ */ jsx86(
|
|
3847
4000
|
Dialog,
|
|
3848
4001
|
{
|
|
3849
4002
|
open: true,
|
|
3850
4003
|
onOpenChange: (open) => {
|
|
3851
4004
|
if (!open) onDone();
|
|
3852
4005
|
},
|
|
3853
|
-
children: /* @__PURE__ */
|
|
3854
|
-
/* @__PURE__ */
|
|
4006
|
+
children: /* @__PURE__ */ jsxs44(DialogContent, { testID: "closure-sheet", children: [
|
|
4007
|
+
/* @__PURE__ */ jsx86(
|
|
3855
4008
|
Animated.View,
|
|
3856
4009
|
{
|
|
3857
4010
|
testID: "closure-check",
|
|
3858
4011
|
style: { opacity, transform: [{ scale }] },
|
|
3859
4012
|
className: "bg-success/10 h-10 w-10 items-center justify-center rounded-full",
|
|
3860
|
-
children: /* @__PURE__ */
|
|
4013
|
+
children: /* @__PURE__ */ jsx86(Text, { className: "text-success text-lg font-bold", accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", children: "\u2713" })
|
|
3861
4014
|
}
|
|
3862
4015
|
),
|
|
3863
|
-
/* @__PURE__ */
|
|
3864
|
-
/* @__PURE__ */
|
|
3865
|
-
!blind && /* @__PURE__ */
|
|
4016
|
+
/* @__PURE__ */ jsx86(DialogTitle, { testID: "closure-title", children: "Register closed" }),
|
|
4017
|
+
/* @__PURE__ */ jsx86(Text, { testID: "closure-number", className: "text-muted-foreground min-h-11", children: `Closure #${closure.number}` }),
|
|
4018
|
+
!blind && /* @__PURE__ */ jsx86(View52, { testID: "closure-figures", className: "gap-3", children: methods.map((method) => {
|
|
3866
4019
|
const countedMinor = closure.counted[method] ?? 0;
|
|
3867
4020
|
const expectedMinor = closure.expected[method] ?? 0;
|
|
3868
4021
|
const varianceMinor = closure.variance[method] ?? countVariance2(countedMinor, expectedMinor);
|
|
3869
|
-
return /* @__PURE__ */
|
|
3870
|
-
/* @__PURE__ */
|
|
3871
|
-
/* @__PURE__ */
|
|
3872
|
-
/* @__PURE__ */
|
|
3873
|
-
/* @__PURE__ */
|
|
4022
|
+
return /* @__PURE__ */ jsxs44(View52, { className: "gap-1", children: [
|
|
4023
|
+
/* @__PURE__ */ jsx86(Text, { className: "text-muted-foreground text-xs font-semibold", children: tenderLabel(method) }),
|
|
4024
|
+
/* @__PURE__ */ jsx86(Text, { testID: `closure-counted-${method}`, className: "min-h-11 tabular-nums", children: `Counted ${formatMoney9({ amount: countedMinor, currency })}` }),
|
|
4025
|
+
/* @__PURE__ */ jsx86(Text, { testID: `closure-expected-${method}`, className: "min-h-11 tabular-nums", children: `Expected ${formatMoney9({ amount: expectedMinor, currency })}` }),
|
|
4026
|
+
/* @__PURE__ */ jsx86(Text, { testID: `closure-variance-${method}`, className: "min-h-11 tabular-nums", children: varianceText2(
|
|
3874
4027
|
varianceMinor,
|
|
3875
4028
|
digits,
|
|
3876
4029
|
(major) => formatMoney9({ amount: Math.round(major * 10 ** digits), currency }) ?? "",
|
|
@@ -3878,51 +4031,51 @@ function ClosureSheet({ register, currency, onPrint, onDone }) {
|
|
|
3878
4031
|
) })
|
|
3879
4032
|
] }, method);
|
|
3880
4033
|
}) }),
|
|
3881
|
-
!!approvedBy && /* @__PURE__ */
|
|
4034
|
+
!!approvedBy && /* @__PURE__ */ jsxs44(Text, { testID: "closure-approved-by", children: [
|
|
3882
4035
|
"Approved by ",
|
|
3883
4036
|
approvedBy
|
|
3884
4037
|
] }),
|
|
3885
|
-
closure.breakdowns.tax_rounding_mixed === true && /* @__PURE__ */
|
|
3886
|
-
!!error && /* @__PURE__ */
|
|
3887
|
-
!blind && !!onPrint && /* @__PURE__ */
|
|
3888
|
-
/* @__PURE__ */
|
|
4038
|
+
closure.breakdowns.tax_rounding_mixed === true && /* @__PURE__ */ jsx86(Text, { testID: "closure-tax-rounding-mixed", className: "text-muted-foreground", children: TAX_ROUNDING_MIXED_NOTE }),
|
|
4039
|
+
!!error && /* @__PURE__ */ jsx86(Text, { testID: "closure-print-error", className: "text-destructive", children: error }),
|
|
4040
|
+
!blind && !!onPrint && /* @__PURE__ */ jsx86(Button, { testID: "closure-print", className: "min-h-14", disabled: busy, onPress: print, children: /* @__PURE__ */ jsx86(Text, { children: busy ? "Printing\u2026" : "Print the Z report" }) }),
|
|
4041
|
+
/* @__PURE__ */ jsx86(Button, { testID: "closure-done", variant: "outline", className: "min-h-14", onPress: onDone, children: /* @__PURE__ */ jsx86(Text, { children: "Done" }) })
|
|
3889
4042
|
] })
|
|
3890
4043
|
}
|
|
3891
4044
|
);
|
|
3892
4045
|
}
|
|
3893
4046
|
|
|
3894
4047
|
// src/settings/settings-row.tsx
|
|
3895
|
-
import { Text as
|
|
3896
|
-
import { cn as
|
|
3897
|
-
import { jsx as
|
|
4048
|
+
import { Text as Text30, View as View53 } from "react-native";
|
|
4049
|
+
import { cn as cn79 } from "@tallyui/theme";
|
|
4050
|
+
import { jsx as jsx87, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
3898
4051
|
function SettingsRow({ label, description, action, className, ...viewProps }) {
|
|
3899
|
-
return /* @__PURE__ */
|
|
3900
|
-
/* @__PURE__ */
|
|
3901
|
-
/* @__PURE__ */
|
|
3902
|
-
description && /* @__PURE__ */
|
|
4052
|
+
return /* @__PURE__ */ jsxs45(View53, { className: cn79("flex-row items-center gap-3 px-4 py-3", className), ...viewProps, children: [
|
|
4053
|
+
/* @__PURE__ */ jsxs45(View53, { className: "flex-1 gap-0.5", children: [
|
|
4054
|
+
/* @__PURE__ */ jsx87(Text30, { className: "text-sm font-medium text-foreground", children: label }),
|
|
4055
|
+
description && /* @__PURE__ */ jsx87(Text30, { className: "text-xs text-muted-foreground", children: description })
|
|
3903
4056
|
] }),
|
|
3904
|
-
action && /* @__PURE__ */
|
|
4057
|
+
action && /* @__PURE__ */ jsx87(View53, { children: action })
|
|
3905
4058
|
] });
|
|
3906
4059
|
}
|
|
3907
4060
|
|
|
3908
4061
|
// src/settings/settings-group.tsx
|
|
3909
|
-
import { Text as
|
|
3910
|
-
import { cn as
|
|
3911
|
-
import { jsx as
|
|
4062
|
+
import { Text as Text31, View as View54 } from "react-native";
|
|
4063
|
+
import { cn as cn80 } from "@tallyui/theme";
|
|
4064
|
+
import { jsx as jsx88, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
3912
4065
|
function SettingsGroup({ title, description, children, className, ...viewProps }) {
|
|
3913
|
-
return /* @__PURE__ */
|
|
3914
|
-
/* @__PURE__ */
|
|
3915
|
-
/* @__PURE__ */
|
|
3916
|
-
description && /* @__PURE__ */
|
|
4066
|
+
return /* @__PURE__ */ jsxs46(View54, { className: cn80("gap-1", className), ...viewProps, children: [
|
|
4067
|
+
/* @__PURE__ */ jsxs46(View54, { className: "px-4 py-2", children: [
|
|
4068
|
+
/* @__PURE__ */ jsx88(Text31, { className: "text-sm font-semibold text-foreground", children: title }),
|
|
4069
|
+
description && /* @__PURE__ */ jsx88(Text31, { className: "text-xs text-muted-foreground", children: description })
|
|
3917
4070
|
] }),
|
|
3918
|
-
/* @__PURE__ */
|
|
4071
|
+
/* @__PURE__ */ jsx88(View54, { className: "rounded-lg border border-border bg-card", children })
|
|
3919
4072
|
] });
|
|
3920
4073
|
}
|
|
3921
4074
|
|
|
3922
4075
|
// src/settings/connector-status.tsx
|
|
3923
|
-
import { Text as
|
|
3924
|
-
import { cn as
|
|
3925
|
-
import { jsx as
|
|
4076
|
+
import { Text as Text32, View as View55 } from "react-native";
|
|
4077
|
+
import { cn as cn81 } from "@tallyui/theme";
|
|
4078
|
+
import { jsx as jsx89, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
3926
4079
|
function defaultFormatUnsold(count2, stale) {
|
|
3927
4080
|
return `${count2} ${count2 === 1 ? "product" : "products"} not sold in this channel${stale ? " (last check failed)" : ""}`;
|
|
3928
4081
|
}
|
|
@@ -3944,33 +4097,34 @@ function ConnectorStatus({
|
|
|
3944
4097
|
...viewProps
|
|
3945
4098
|
}) {
|
|
3946
4099
|
const config = STATUS_CONFIG2[status];
|
|
3947
|
-
return /* @__PURE__ */
|
|
3948
|
-
/* @__PURE__ */
|
|
3949
|
-
/* @__PURE__ */
|
|
3950
|
-
/* @__PURE__ */
|
|
3951
|
-
/* @__PURE__ */
|
|
3952
|
-
/* @__PURE__ */
|
|
4100
|
+
return /* @__PURE__ */ jsxs47(View55, { className: cn81("gap-2 rounded-lg border border-border bg-card p-3", className), ...viewProps, children: [
|
|
4101
|
+
/* @__PURE__ */ jsxs47(View55, { className: "flex-row items-center justify-between", children: [
|
|
4102
|
+
/* @__PURE__ */ jsx89(Text32, { className: "text-sm font-semibold text-foreground", children: name }),
|
|
4103
|
+
/* @__PURE__ */ jsxs47(View55, { className: "flex-row items-center gap-1.5", children: [
|
|
4104
|
+
/* @__PURE__ */ jsx89(View55, { className: cn81("h-2 w-2 rounded-full", config.dot) }),
|
|
4105
|
+
/* @__PURE__ */ jsx89(Text32, { className: cn81("text-xs font-medium", config.text), children: config.label })
|
|
3953
4106
|
] })
|
|
3954
4107
|
] }),
|
|
3955
|
-
lastSync && /* @__PURE__ */
|
|
4108
|
+
lastSync && /* @__PURE__ */ jsxs47(Text32, { className: "text-xs text-muted-foreground", children: [
|
|
3956
4109
|
"Last sync: ",
|
|
3957
4110
|
lastSync
|
|
3958
4111
|
] }),
|
|
3959
|
-
error && /* @__PURE__ */
|
|
3960
|
-
!!unsoldCount && /* @__PURE__ */
|
|
4112
|
+
error && /* @__PURE__ */ jsx89(Text32, { className: "text-xs text-destructive", children: error }),
|
|
4113
|
+
!!unsoldCount && /* @__PURE__ */ jsx89(Text32, { className: cn81("text-xs", unsoldStale ? "text-muted-foreground" : "text-warning"), children: formatUnsold(unsoldCount, !!unsoldStale) })
|
|
3961
4114
|
] });
|
|
3962
4115
|
}
|
|
3963
4116
|
|
|
3964
4117
|
// src/sale/cart.tsx
|
|
3965
|
-
import { useState as
|
|
3966
|
-
import { Pressable as
|
|
4118
|
+
import { useState as useState20 } from "react";
|
|
4119
|
+
import { Pressable as Pressable28, Text as Text36, View as View59 } from "react-native";
|
|
4120
|
+
import { formatMoney as formatMoney12 } from "@tallyui/core";
|
|
3967
4121
|
import { buildReceiptData } from "@tallyui/pos";
|
|
3968
4122
|
|
|
3969
4123
|
// src/sale/discount-form.tsx
|
|
3970
|
-
import { useState as
|
|
3971
|
-
import { Pressable as
|
|
4124
|
+
import { useState as useState17 } from "react";
|
|
4125
|
+
import { Pressable as Pressable25, Text as Text33, TextInput as TextInput9, View as View56 } from "react-native";
|
|
3972
4126
|
import { formatMoney as formatMoney10, minorUnitDigits as minorUnitDigits7, moneyFromDecimalString as moneyFromDecimalString2 } from "@tallyui/core";
|
|
3973
|
-
import { jsx as
|
|
4127
|
+
import { jsx as jsx90, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
3974
4128
|
function parseDiscount(type, text, currency) {
|
|
3975
4129
|
const raw = text.trim();
|
|
3976
4130
|
const trimmed = raw.split(",").length === 2 ? raw.replace(",", ".") : raw;
|
|
@@ -3987,30 +4141,30 @@ function parseDiscount(type, text, currency) {
|
|
|
3987
4141
|
var discountLabel = (discount, currency) => discount.type === "percentage" ? `${discount.value}%` : formatMoney10({ amount: discount.amountMinor, currency }) ?? String(discount.amountMinor);
|
|
3988
4142
|
var button = "rounded-md border border-border px-3 py-2 min-h-11 items-center justify-center";
|
|
3989
4143
|
function DiscountForm({ title, currency, onApply, onClose }) {
|
|
3990
|
-
const [type, setType] =
|
|
3991
|
-
const [text, setText] =
|
|
3992
|
-
const [error, setError] =
|
|
4144
|
+
const [type, setType] = useState17("percentage");
|
|
4145
|
+
const [text, setText] = useState17("");
|
|
4146
|
+
const [error, setError] = useState17(null);
|
|
3993
4147
|
function apply() {
|
|
3994
4148
|
const parsed = parseDiscount(type, text, currency);
|
|
3995
4149
|
const refused = typeof parsed === "string" ? parsed : onApply(parsed);
|
|
3996
4150
|
setError(refused);
|
|
3997
4151
|
if (refused === null) onClose();
|
|
3998
4152
|
}
|
|
3999
|
-
return /* @__PURE__ */
|
|
4000
|
-
/* @__PURE__ */
|
|
4001
|
-
/* @__PURE__ */
|
|
4002
|
-
["percentage", "fixed"].map((option) => /* @__PURE__ */
|
|
4003
|
-
|
|
4153
|
+
return /* @__PURE__ */ jsxs48(View56, { role: "group", accessibilityLabel: title, className: "gap-2 px-3 py-2", children: [
|
|
4154
|
+
/* @__PURE__ */ jsx90(Text33, { className: "font-semibold text-foreground", children: title }),
|
|
4155
|
+
/* @__PURE__ */ jsxs48(View56, { className: "flex-row gap-2", children: [
|
|
4156
|
+
["percentage", "fixed"].map((option) => /* @__PURE__ */ jsx90(
|
|
4157
|
+
Pressable25,
|
|
4004
4158
|
{
|
|
4005
4159
|
accessibilityRole: "button",
|
|
4006
4160
|
accessibilityState: { selected: type === option },
|
|
4007
4161
|
onPress: () => setType(option),
|
|
4008
4162
|
className: `${button} ${type === option ? "bg-primary" : "bg-card"}`,
|
|
4009
|
-
children: /* @__PURE__ */
|
|
4163
|
+
children: /* @__PURE__ */ jsx90(Text33, { className: type === option ? "text-primary-foreground" : "text-foreground", children: option === "percentage" ? "Percent" : "Amount" })
|
|
4010
4164
|
},
|
|
4011
4165
|
option
|
|
4012
4166
|
)),
|
|
4013
|
-
/* @__PURE__ */
|
|
4167
|
+
/* @__PURE__ */ jsx90(
|
|
4014
4168
|
TextInput9,
|
|
4015
4169
|
{
|
|
4016
4170
|
accessibilityLabel: "Discount value",
|
|
@@ -4023,16 +4177,16 @@ function DiscountForm({ title, currency, onApply, onClose }) {
|
|
|
4023
4177
|
}
|
|
4024
4178
|
)
|
|
4025
4179
|
] }),
|
|
4026
|
-
error ? /* @__PURE__ */
|
|
4027
|
-
/* @__PURE__ */
|
|
4028
|
-
/* @__PURE__ */
|
|
4029
|
-
/* @__PURE__ */
|
|
4180
|
+
error ? /* @__PURE__ */ jsx90(Text33, { accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
|
|
4181
|
+
/* @__PURE__ */ jsxs48(View56, { className: "flex-row gap-2", children: [
|
|
4182
|
+
/* @__PURE__ */ jsx90(Pressable25, { accessibilityRole: "button", onPress: apply, className: `${button} bg-primary`, children: /* @__PURE__ */ jsx90(Text33, { className: "font-semibold text-primary-foreground", children: "Apply" }) }),
|
|
4183
|
+
/* @__PURE__ */ jsx90(Pressable25, { accessibilityRole: "button", onPress: onClose, className: `${button} bg-card`, children: /* @__PURE__ */ jsx90(Text33, { className: "text-foreground", children: "Cancel" }) })
|
|
4030
4184
|
] })
|
|
4031
4185
|
] });
|
|
4032
4186
|
}
|
|
4033
4187
|
function DiscountChips({ discounts, currency, onRemove, prefix, amounts = [] }) {
|
|
4034
4188
|
if (!discounts.length) return null;
|
|
4035
|
-
return /* @__PURE__ */
|
|
4189
|
+
return /* @__PURE__ */ jsx90(View56, { className: "flex-row flex-wrap gap-2 px-3", children: discounts.map((discount) => {
|
|
4036
4190
|
const amount = amounts.find((row) => row.discountId === discount.id)?.amountMinor;
|
|
4037
4191
|
const own = discountLabel(discount, currency);
|
|
4038
4192
|
const label = [
|
|
@@ -4040,16 +4194,16 @@ function DiscountChips({ discounts, currency, onRemove, prefix, amounts = [] })
|
|
|
4040
4194
|
amount === void 0 ? prefix ? `\u2212${own}` : own : discount.type === "percentage" ? own : null,
|
|
4041
4195
|
amount === void 0 ? null : `\u2212${formatMoney10({ amount, currency })}`
|
|
4042
4196
|
].filter(Boolean).join(" ");
|
|
4043
|
-
return /* @__PURE__ */
|
|
4044
|
-
|
|
4197
|
+
return /* @__PURE__ */ jsxs48(
|
|
4198
|
+
Pressable25,
|
|
4045
4199
|
{
|
|
4046
4200
|
accessibilityRole: "button",
|
|
4047
4201
|
accessibilityLabel: `Remove discount ${label}`,
|
|
4048
4202
|
onPress: () => onRemove(discount.id),
|
|
4049
4203
|
className: "min-h-11 flex-row items-center gap-1",
|
|
4050
4204
|
children: [
|
|
4051
|
-
/* @__PURE__ */
|
|
4052
|
-
/* @__PURE__ */
|
|
4205
|
+
/* @__PURE__ */ jsx90(DiscountBadge, { label, className: "self-center" }),
|
|
4206
|
+
/* @__PURE__ */ jsx90(Text33, { className: "text-muted-foreground", children: "\u2715" })
|
|
4053
4207
|
]
|
|
4054
4208
|
},
|
|
4055
4209
|
discount.id
|
|
@@ -4058,10 +4212,10 @@ function DiscountChips({ discounts, currency, onRemove, prefix, amounts = [] })
|
|
|
4058
4212
|
}
|
|
4059
4213
|
|
|
4060
4214
|
// src/sale/price-form.tsx
|
|
4061
|
-
import { useState as
|
|
4062
|
-
import { Pressable as
|
|
4215
|
+
import { useState as useState18 } from "react";
|
|
4216
|
+
import { Pressable as Pressable26, Text as Text34, TextInput as TextInput10, View as View57 } from "react-native";
|
|
4063
4217
|
import { formatMoney as formatMoney11, minorUnitDigits as minorUnitDigits8, moneyFromDecimalString as moneyFromDecimalString3 } from "@tallyui/core";
|
|
4064
|
-
import { jsx as
|
|
4218
|
+
import { jsx as jsx91, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
4065
4219
|
function parsePrice(text, currency) {
|
|
4066
4220
|
const raw = text.trim();
|
|
4067
4221
|
const trimmed = raw.split(",").length === 2 ? raw.replace(",", ".") : raw;
|
|
@@ -4074,9 +4228,9 @@ function parsePrice(text, currency) {
|
|
|
4074
4228
|
}
|
|
4075
4229
|
var button2 = "rounded-md border border-border px-3 py-2 min-h-11 items-center justify-center";
|
|
4076
4230
|
function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
|
|
4077
|
-
const [text, setText] =
|
|
4078
|
-
const [reason, setReason] =
|
|
4079
|
-
const [error, setError] =
|
|
4231
|
+
const [text, setText] = useState18("");
|
|
4232
|
+
const [reason, setReason] = useState18("");
|
|
4233
|
+
const [error, setError] = useState18(null);
|
|
4080
4234
|
const title = `Price for ${lineName}`;
|
|
4081
4235
|
function apply() {
|
|
4082
4236
|
const parsed = parsePrice(text, currency);
|
|
@@ -4084,10 +4238,10 @@ function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
|
|
|
4084
4238
|
setError(refused);
|
|
4085
4239
|
if (refused === null) onClose();
|
|
4086
4240
|
}
|
|
4087
|
-
return /* @__PURE__ */
|
|
4088
|
-
/* @__PURE__ */
|
|
4089
|
-
/* @__PURE__ */
|
|
4090
|
-
/* @__PURE__ */
|
|
4241
|
+
return /* @__PURE__ */ jsxs49(View57, { testID: "price-form", role: "group", accessibilityLabel: title, className: "gap-2 px-3 py-2", children: [
|
|
4242
|
+
/* @__PURE__ */ jsx91(Text34, { className: "font-semibold text-foreground", children: title }),
|
|
4243
|
+
/* @__PURE__ */ jsx91(Text34, { className: "text-muted-foreground", children: formatMoney11({ amount: currentMinor, currency }) }),
|
|
4244
|
+
/* @__PURE__ */ jsx91(
|
|
4091
4245
|
TextInput10,
|
|
4092
4246
|
{
|
|
4093
4247
|
testID: "price-input",
|
|
@@ -4100,7 +4254,7 @@ function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
|
|
|
4100
4254
|
className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
|
|
4101
4255
|
}
|
|
4102
4256
|
),
|
|
4103
|
-
/* @__PURE__ */
|
|
4257
|
+
/* @__PURE__ */ jsx91(
|
|
4104
4258
|
TextInput10,
|
|
4105
4259
|
{
|
|
4106
4260
|
testID: "price-reason",
|
|
@@ -4111,25 +4265,121 @@ function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
|
|
|
4111
4265
|
className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
|
|
4112
4266
|
}
|
|
4113
4267
|
),
|
|
4114
|
-
error ? /* @__PURE__ */
|
|
4115
|
-
/* @__PURE__ */
|
|
4116
|
-
/* @__PURE__ */
|
|
4117
|
-
/* @__PURE__ */
|
|
4268
|
+
error ? /* @__PURE__ */ jsx91(Text34, { testID: "price-error", accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
|
|
4269
|
+
/* @__PURE__ */ jsxs49(View57, { className: "flex-row gap-2", children: [
|
|
4270
|
+
/* @__PURE__ */ jsx91(Pressable26, { testID: "price-apply", accessibilityRole: "button", onPress: apply, className: `${button2} bg-primary`, children: /* @__PURE__ */ jsx91(Text34, { className: "font-semibold text-primary-foreground", children: "Apply" }) }),
|
|
4271
|
+
/* @__PURE__ */ jsx91(Pressable26, { testID: "price-cancel", accessibilityRole: "button", onPress: onClose, className: `${button2} bg-card`, children: /* @__PURE__ */ jsx91(Text34, { className: "text-foreground", children: "Cancel" }) })
|
|
4272
|
+
] })
|
|
4273
|
+
] });
|
|
4274
|
+
}
|
|
4275
|
+
|
|
4276
|
+
// src/sale/charge-form.tsx
|
|
4277
|
+
import { useState as useState19 } from "react";
|
|
4278
|
+
import { Pressable as Pressable27, Text as Text35, TextInput as TextInput11, View as View58 } from "react-native";
|
|
4279
|
+
import { Fragment as Fragment5, jsx as jsx92, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
4280
|
+
var button3 = "rounded-md border border-border px-3 py-2 min-h-11 items-center justify-center";
|
|
4281
|
+
function ChargeForm({ currency, lineTax, taxClasses, shippingTaxFromStore, onApply, onClose }) {
|
|
4282
|
+
const [kind, setKind] = useState19("fee");
|
|
4283
|
+
const [name, setName] = useState19("");
|
|
4284
|
+
const [text, setText] = useState19("");
|
|
4285
|
+
const [noTax, setNoTax] = useState19(false);
|
|
4286
|
+
const [taxClass, setTaxClass] = useState19("");
|
|
4287
|
+
const [error, setError] = useState19(null);
|
|
4288
|
+
const storeShipping = kind === "shipping" && shippingTaxFromStore;
|
|
4289
|
+
function apply() {
|
|
4290
|
+
const parsed = parsePrice(text, currency);
|
|
4291
|
+
const refused = !name.trim() ? "Enter a name." : typeof parsed === "string" ? parsed : onApply({
|
|
4292
|
+
kind,
|
|
4293
|
+
name: name.trim(),
|
|
4294
|
+
amountMinor: parsed,
|
|
4295
|
+
taxStatus: !storeShipping && lineTax?.none && noTax ? "none" : void 0,
|
|
4296
|
+
taxClass: !storeShipping && lineTax?.classes && taxClasses?.length ? taxClass || void 0 : void 0
|
|
4297
|
+
});
|
|
4298
|
+
setError(refused);
|
|
4299
|
+
if (refused === null) onClose();
|
|
4300
|
+
}
|
|
4301
|
+
return /* @__PURE__ */ jsxs50(View58, { testID: "charge-form", role: "group", accessibilityLabel: "Add charge", className: "gap-2 px-3 py-2", children: [
|
|
4302
|
+
/* @__PURE__ */ jsx92(Text35, { className: "font-semibold text-foreground", children: "Add charge" }),
|
|
4303
|
+
/* @__PURE__ */ jsx92(View58, { className: "flex-row gap-2", children: ["fee", "shipping", "custom"].map((option) => /* @__PURE__ */ jsx92(
|
|
4304
|
+
Pressable27,
|
|
4305
|
+
{
|
|
4306
|
+
accessibilityRole: "button",
|
|
4307
|
+
accessibilityState: { selected: kind === option },
|
|
4308
|
+
"aria-selected": kind === option,
|
|
4309
|
+
onPress: () => setKind(option),
|
|
4310
|
+
className: `${button3} ${kind === option ? "bg-primary" : "bg-card"}`,
|
|
4311
|
+
children: /* @__PURE__ */ jsx92(Text35, { className: kind === option ? "text-primary-foreground" : "text-foreground", children: option === "fee" ? "Fee" : option === "shipping" ? "Shipping" : "Custom item" })
|
|
4312
|
+
},
|
|
4313
|
+
option
|
|
4314
|
+
)) }),
|
|
4315
|
+
/* @__PURE__ */ jsx92(
|
|
4316
|
+
TextInput11,
|
|
4317
|
+
{
|
|
4318
|
+
accessibilityLabel: "Name",
|
|
4319
|
+
placeholder: "Name",
|
|
4320
|
+
value: name,
|
|
4321
|
+
onChangeText: setName,
|
|
4322
|
+
className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
|
|
4323
|
+
}
|
|
4324
|
+
),
|
|
4325
|
+
/* @__PURE__ */ jsx92(
|
|
4326
|
+
TextInput11,
|
|
4327
|
+
{
|
|
4328
|
+
accessibilityLabel: "Amount",
|
|
4329
|
+
value: text,
|
|
4330
|
+
onChangeText: setText,
|
|
4331
|
+
onSubmitEditing: apply,
|
|
4332
|
+
inputMode: "decimal",
|
|
4333
|
+
placeholder: currency,
|
|
4334
|
+
className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
|
|
4335
|
+
}
|
|
4336
|
+
),
|
|
4337
|
+
storeShipping ? /* @__PURE__ */ jsx92(Text35, { className: "text-muted-foreground", children: "Shipping is taxed at the store's shipping tax class." }) : /* @__PURE__ */ jsxs50(Fragment5, { children: [
|
|
4338
|
+
lineTax?.none ? /* @__PURE__ */ jsx92(
|
|
4339
|
+
Pressable27,
|
|
4340
|
+
{
|
|
4341
|
+
accessibilityRole: "switch",
|
|
4342
|
+
accessibilityLabel: "No tax",
|
|
4343
|
+
accessibilityState: { checked: noTax },
|
|
4344
|
+
"aria-checked": noTax,
|
|
4345
|
+
onPress: () => setNoTax(!noTax),
|
|
4346
|
+
className: `${button3} ${noTax ? "bg-primary" : "bg-card"}`,
|
|
4347
|
+
children: /* @__PURE__ */ jsx92(Text35, { className: noTax ? "text-primary-foreground" : "text-foreground", children: "No tax" })
|
|
4348
|
+
}
|
|
4349
|
+
) : null,
|
|
4350
|
+
lineTax?.classes && taxClasses?.length ? /* @__PURE__ */ jsx92(View58, { role: "group", accessibilityLabel: "Tax class", className: "flex-row flex-wrap gap-2", children: [{ id: "", label: "No class" }, ...taxClasses].map((option) => /* @__PURE__ */ jsx92(
|
|
4351
|
+
Pressable27,
|
|
4352
|
+
{
|
|
4353
|
+
accessibilityRole: "button",
|
|
4354
|
+
accessibilityState: { selected: taxClass === option.id },
|
|
4355
|
+
"aria-selected": taxClass === option.id,
|
|
4356
|
+
onPress: () => setTaxClass(option.id),
|
|
4357
|
+
className: `${button3} ${taxClass === option.id ? "bg-primary" : "bg-card"}`,
|
|
4358
|
+
children: /* @__PURE__ */ jsx92(Text35, { className: taxClass === option.id ? "text-primary-foreground" : "text-foreground", children: option.label })
|
|
4359
|
+
},
|
|
4360
|
+
option.id
|
|
4361
|
+
)) }) : null
|
|
4362
|
+
] }),
|
|
4363
|
+
error ? /* @__PURE__ */ jsx92(Text35, { accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
|
|
4364
|
+
/* @__PURE__ */ jsxs50(View58, { className: "flex-row gap-2", children: [
|
|
4365
|
+
/* @__PURE__ */ jsx92(Pressable27, { accessibilityRole: "button", onPress: apply, className: `${button3} bg-primary`, children: /* @__PURE__ */ jsx92(Text35, { className: "font-semibold text-primary-foreground", children: "Apply" }) }),
|
|
4366
|
+
/* @__PURE__ */ jsx92(Pressable27, { accessibilityRole: "button", onPress: onClose, className: `${button3} bg-card`, children: /* @__PURE__ */ jsx92(Text35, { className: "text-foreground", children: "Cancel" }) })
|
|
4118
4367
|
] })
|
|
4119
4368
|
] });
|
|
4120
4369
|
}
|
|
4121
4370
|
|
|
4122
4371
|
// src/sale/cart.tsx
|
|
4123
|
-
import { Fragment as
|
|
4124
|
-
function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPrice = false, onPriceChange }) {
|
|
4372
|
+
import { Fragment as Fragment6, jsx as jsx93, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
4373
|
+
function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPrice = false, onPriceChange, taxClasses }) {
|
|
4125
4374
|
const { order } = sale;
|
|
4126
4375
|
const money = (amount) => ({ amount, currency: order.currency });
|
|
4127
4376
|
const { totals } = buildReceiptData(order, { storeName: "" });
|
|
4128
4377
|
const taxRows = totals.taxLines.map((line) => ({ label: taxLabel(line.ratePpm), amount: money(line.amountMinor) }));
|
|
4129
4378
|
const display = (lineId) => order.display.lines.find((line) => line.lineId === lineId);
|
|
4130
4379
|
const orderAmounts = order.discounts.length === 1 ? [{ discountId: order.discounts[0].id, amountMinor: order.display.orderDiscountMinor }] : [];
|
|
4131
|
-
const [form, setForm] =
|
|
4132
|
-
const
|
|
4380
|
+
const [form, setForm] = useState20(null);
|
|
4381
|
+
const chargesOffered = (sale.capabilities?.orderCreate ?? 0) >= 5;
|
|
4382
|
+
const discountForm = (lineId, title) => form?.type === "discount" && form.lineId === lineId ? /* @__PURE__ */ jsx93(
|
|
4133
4383
|
DiscountForm,
|
|
4134
4384
|
{
|
|
4135
4385
|
title,
|
|
@@ -4140,11 +4390,11 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4140
4390
|
lineId ?? "order"
|
|
4141
4391
|
) : null;
|
|
4142
4392
|
const pay = `min-h-12 flex-1 justify-center rounded-md bg-primary px-4 py-3 ${!order.lineItems.length ? "opacity-50" : ""}`;
|
|
4143
|
-
const renderItem = (line) => /* @__PURE__ */
|
|
4144
|
-
/* @__PURE__ */
|
|
4393
|
+
const renderItem = (line) => /* @__PURE__ */ jsxs51(Fragment6, { children: [
|
|
4394
|
+
/* @__PURE__ */ jsx93(CartLineActions, { actions: [
|
|
4145
4395
|
{ id: "discount", label: "Discount", color: "text-primary", onPress: () => setForm({ type: "discount", lineId: line.id }) },
|
|
4146
4396
|
...canEditPrice ? [{ id: "price", label: "Price", color: "text-primary", onPress: () => setForm({ type: "price", lineId: line.id }) }] : []
|
|
4147
|
-
], children: /* @__PURE__ */
|
|
4397
|
+
], children: /* @__PURE__ */ jsx93(
|
|
4148
4398
|
CartLine,
|
|
4149
4399
|
{
|
|
4150
4400
|
name: line.name,
|
|
@@ -4153,41 +4403,41 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4153
4403
|
lineTotal: money(display(line.id).amountMinor)
|
|
4154
4404
|
}
|
|
4155
4405
|
) }),
|
|
4156
|
-
/* @__PURE__ */
|
|
4157
|
-
/* @__PURE__ */
|
|
4158
|
-
/* @__PURE__ */
|
|
4159
|
-
|
|
4406
|
+
/* @__PURE__ */ jsx93(DiscountChips, { discounts: line.discounts, amounts: display(line.id).discounts, currency: order.currency, onRemove: sale.removeDiscount }),
|
|
4407
|
+
/* @__PURE__ */ jsxs51(View59, { className: "flex-row gap-4 px-3 py-2", children: [
|
|
4408
|
+
/* @__PURE__ */ jsx93(
|
|
4409
|
+
Pressable28,
|
|
4160
4410
|
{
|
|
4161
4411
|
accessibilityRole: "button",
|
|
4162
4412
|
accessibilityLabel: `Decrease ${line.name}`,
|
|
4163
4413
|
onPress: () => sale.setQuantity(line.id, line.quantity - 1),
|
|
4164
4414
|
className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
|
|
4165
|
-
children: /* @__PURE__ */
|
|
4415
|
+
children: /* @__PURE__ */ jsx93(Text36, { className: "text-center text-foreground", children: "\u2212" })
|
|
4166
4416
|
}
|
|
4167
4417
|
),
|
|
4168
|
-
/* @__PURE__ */
|
|
4169
|
-
|
|
4418
|
+
/* @__PURE__ */ jsx93(
|
|
4419
|
+
Pressable28,
|
|
4170
4420
|
{
|
|
4171
4421
|
accessibilityRole: "button",
|
|
4172
4422
|
accessibilityLabel: `Increase ${line.name}`,
|
|
4173
4423
|
onPress: () => sale.setQuantity(line.id, line.quantity + 1),
|
|
4174
4424
|
className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
|
|
4175
|
-
children: /* @__PURE__ */
|
|
4425
|
+
children: /* @__PURE__ */ jsx93(Text36, { className: "text-center text-foreground", children: "+" })
|
|
4176
4426
|
}
|
|
4177
4427
|
),
|
|
4178
|
-
/* @__PURE__ */
|
|
4179
|
-
|
|
4428
|
+
/* @__PURE__ */ jsx93(
|
|
4429
|
+
Pressable28,
|
|
4180
4430
|
{
|
|
4181
4431
|
accessibilityRole: "button",
|
|
4182
4432
|
accessibilityLabel: `Remove ${line.name}`,
|
|
4183
4433
|
onPress: () => sale.remove(line.id),
|
|
4184
4434
|
className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
|
|
4185
|
-
children: /* @__PURE__ */
|
|
4435
|
+
children: /* @__PURE__ */ jsx93(Text36, { className: "text-center text-foreground", children: "Remove" })
|
|
4186
4436
|
}
|
|
4187
4437
|
)
|
|
4188
4438
|
] }),
|
|
4189
4439
|
discountForm(line.id, `Discount on ${line.name}`),
|
|
4190
|
-
canEditPrice && form?.type === "price" && form.lineId === line.id ? /* @__PURE__ */
|
|
4440
|
+
canEditPrice && form?.type === "price" && form.lineId === line.id ? /* @__PURE__ */ jsx93(
|
|
4191
4441
|
PriceForm,
|
|
4192
4442
|
{
|
|
4193
4443
|
lineName: line.name,
|
|
@@ -4204,36 +4454,76 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4204
4454
|
line.id
|
|
4205
4455
|
) : null
|
|
4206
4456
|
] });
|
|
4207
|
-
return /* @__PURE__ */
|
|
4457
|
+
return /* @__PURE__ */ jsx93(
|
|
4208
4458
|
CartPanel,
|
|
4209
4459
|
{
|
|
4210
4460
|
dataSet: { print: "hide" },
|
|
4211
4461
|
items: order.lineItems,
|
|
4212
4462
|
renderItem,
|
|
4213
|
-
emptyState: /* @__PURE__ */
|
|
4214
|
-
afterItems:
|
|
4215
|
-
/* @__PURE__ */
|
|
4216
|
-
|
|
4217
|
-
{
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4463
|
+
emptyState: /* @__PURE__ */ jsx93(Text36, { testID: "cart-empty", className: "px-3 py-2 text-muted-foreground", children: "Scan or tap a product to start a sale." }),
|
|
4464
|
+
afterItems: /* @__PURE__ */ jsxs51(Fragment6, { children: [
|
|
4465
|
+
["fees", "shipping"].map((kind) => order[kind]?.map((charge, index) => /* @__PURE__ */ jsxs51(View59, { testID: `cart-${kind === "fees" ? "fee" : "shipping"}-${index}`, className: "flex-row items-center gap-3 px-3 py-2", children: [
|
|
4466
|
+
/* @__PURE__ */ jsx93(Text36, { className: "flex-1 text-foreground", children: charge.name }),
|
|
4467
|
+
/* @__PURE__ */ jsx93(Text36, { className: "text-foreground", children: formatMoney12(money(order.display[kind].find((row) => row.id === charge.id).amountMinor)) }),
|
|
4468
|
+
/* @__PURE__ */ jsx93(
|
|
4469
|
+
Pressable28,
|
|
4470
|
+
{
|
|
4471
|
+
accessibilityRole: "button",
|
|
4472
|
+
accessibilityLabel: `Remove ${charge.name}`,
|
|
4473
|
+
onPress: () => kind === "fees" ? sale.removeFee(charge.id) : sale.removeShipping(charge.id),
|
|
4474
|
+
className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 items-center justify-center",
|
|
4475
|
+
children: /* @__PURE__ */ jsx93(Text36, { className: "text-foreground", children: "Remove" })
|
|
4476
|
+
}
|
|
4477
|
+
)
|
|
4478
|
+
] }, charge.id))),
|
|
4479
|
+
order.lineItems.length || chargesOffered ? /* @__PURE__ */ jsxs51(View59, { className: "gap-3 px-3 py-2", children: [
|
|
4480
|
+
order.lineItems.length ? /* @__PURE__ */ jsxs51(Fragment6, { children: [
|
|
4481
|
+
/* @__PURE__ */ jsx93(
|
|
4482
|
+
DiscountChips,
|
|
4483
|
+
{
|
|
4484
|
+
discounts: order.discounts,
|
|
4485
|
+
amounts: orderAmounts,
|
|
4486
|
+
currency: order.currency,
|
|
4487
|
+
onRemove: sale.removeDiscount,
|
|
4488
|
+
prefix: "Order discount"
|
|
4489
|
+
}
|
|
4490
|
+
),
|
|
4491
|
+
form?.type === "discount" && form.lineId === null ? discountForm(null, "Order discount") : /* @__PURE__ */ jsx93(
|
|
4492
|
+
Pressable28,
|
|
4493
|
+
{
|
|
4494
|
+
accessibilityRole: "button",
|
|
4495
|
+
onPress: () => setForm({ type: "discount", lineId: null }),
|
|
4496
|
+
className: "self-start rounded-md border border-border bg-card px-4 py-2 min-h-11 justify-center",
|
|
4497
|
+
children: /* @__PURE__ */ jsx93(Text36, { className: "text-foreground", children: "Order discount" })
|
|
4498
|
+
}
|
|
4499
|
+
)
|
|
4500
|
+
] }) : null,
|
|
4501
|
+
chargesOffered ? form?.type === "charge" ? /* @__PURE__ */ jsx93(
|
|
4502
|
+
ChargeForm,
|
|
4503
|
+
{
|
|
4504
|
+
currency: order.currency,
|
|
4505
|
+
lineTax: sale.capabilities?.lineTax,
|
|
4506
|
+
taxClasses,
|
|
4507
|
+
shippingTaxFromStore: sale.capabilities?.taxRounding?.granularity === "woocommerce",
|
|
4508
|
+
onClose: () => setForm(null),
|
|
4509
|
+
onApply: ({ kind, name, amountMinor, taxStatus, taxClass }) => {
|
|
4510
|
+
const result = kind === "custom" ? sale.addCustomLine({ name, priceMinor: amountMinor, taxStatus, taxClass }) : kind === "fee" ? sale.addFee({ name, amountMinor, taxStatus, taxClass }) : sale.addShipping({ name, amountMinor, taxStatus, taxClass });
|
|
4511
|
+
return typeof result === "string" ? result : null;
|
|
4512
|
+
}
|
|
4513
|
+
}
|
|
4514
|
+
) : /* @__PURE__ */ jsx93(
|
|
4515
|
+
Pressable28,
|
|
4516
|
+
{
|
|
4517
|
+
accessibilityRole: "button",
|
|
4518
|
+
onPress: () => setForm({ type: "charge" }),
|
|
4519
|
+
className: "self-start rounded-md border border-border bg-card px-4 py-2 min-h-11 justify-center",
|
|
4520
|
+
children: /* @__PURE__ */ jsx93(Text36, { className: "text-foreground", children: "Add charge" })
|
|
4521
|
+
}
|
|
4522
|
+
) : null
|
|
4523
|
+
] }) : null
|
|
4524
|
+
] }),
|
|
4525
|
+
footer: /* @__PURE__ */ jsxs51(View59, { testID: "cart-footer", className: "gap-3 pb-4", children: [
|
|
4526
|
+
/* @__PURE__ */ jsx93(
|
|
4237
4527
|
CartTotal,
|
|
4238
4528
|
{
|
|
4239
4529
|
subtotal: money(totals.subtotalMinor),
|
|
@@ -4243,10 +4533,10 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4243
4533
|
taxInclusive: totals.taxInclusive
|
|
4244
4534
|
}
|
|
4245
4535
|
),
|
|
4246
|
-
sale.error ? /* @__PURE__ */
|
|
4247
|
-
/* @__PURE__ */
|
|
4248
|
-
/* @__PURE__ */
|
|
4249
|
-
/* @__PURE__ */
|
|
4536
|
+
sale.error ? /* @__PURE__ */ jsx93(Text36, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
|
|
4537
|
+
/* @__PURE__ */ jsxs51(View59, { className: "flex-row gap-3", children: [
|
|
4538
|
+
/* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("cash"), className: pay, children: /* @__PURE__ */ jsx93(Text36, { className: "text-center font-semibold text-primary-foreground", children: "Cash" }) }),
|
|
4539
|
+
/* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("external"), className: pay, children: /* @__PURE__ */ jsx93(Text36, { className: "text-center font-semibold text-primary-foreground", children: "Card terminal" }) })
|
|
4250
4540
|
] })
|
|
4251
4541
|
] })
|
|
4252
4542
|
}
|
|
@@ -4254,17 +4544,17 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4254
4544
|
}
|
|
4255
4545
|
|
|
4256
4546
|
// src/sale/cart-bar.tsx
|
|
4257
|
-
import { Pressable as
|
|
4258
|
-
import { formatMoney as
|
|
4547
|
+
import { Pressable as Pressable29, Text as Text37 } from "react-native";
|
|
4548
|
+
import { formatMoney as formatMoney13 } from "@tallyui/core";
|
|
4259
4549
|
import { buildReceiptData as buildReceiptData2 } from "@tallyui/pos";
|
|
4260
|
-
import { jsx as
|
|
4550
|
+
import { jsx as jsx94, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
4261
4551
|
function CartBar({ sale, onOpen }) {
|
|
4262
4552
|
const { order } = sale;
|
|
4263
4553
|
const count2 = order.lineItems.reduce((sum, line) => sum + line.quantity, 0);
|
|
4264
|
-
const total =
|
|
4554
|
+
const total = formatMoney13({ amount: buildReceiptData2(order, { storeName: "" }).totals.totalMinor, currency: order.currency });
|
|
4265
4555
|
const items = `${count2} ${count2 === 1 ? "item" : "items"}`;
|
|
4266
|
-
return /* @__PURE__ */
|
|
4267
|
-
|
|
4556
|
+
return /* @__PURE__ */ jsxs52(
|
|
4557
|
+
Pressable29,
|
|
4268
4558
|
{
|
|
4269
4559
|
accessibilityRole: "button",
|
|
4270
4560
|
accessibilityLabel: count2 ? `Open cart, ${items}, ${total}` : "Cart is empty",
|
|
@@ -4272,8 +4562,8 @@ function CartBar({ sale, onOpen }) {
|
|
|
4272
4562
|
onPress: onOpen,
|
|
4273
4563
|
className: `min-h-14 mx-3 mb-3 flex-row items-center justify-between rounded-md bg-primary px-4 py-3 ${count2 ? "" : "opacity-50"}`,
|
|
4274
4564
|
children: [
|
|
4275
|
-
/* @__PURE__ */
|
|
4276
|
-
count2 ? /* @__PURE__ */
|
|
4565
|
+
/* @__PURE__ */ jsx94(Text37, { className: "font-bold text-primary-foreground", children: count2 ? `Cart \xB7 ${items}` : "Cart is empty" }),
|
|
4566
|
+
count2 ? /* @__PURE__ */ jsxs52(Text37, { className: "font-bold text-primary-foreground", children: [
|
|
4277
4567
|
total,
|
|
4278
4568
|
" \u203A"
|
|
4279
4569
|
] }) : null
|
|
@@ -4283,17 +4573,17 @@ function CartBar({ sale, onOpen }) {
|
|
|
4283
4573
|
}
|
|
4284
4574
|
|
|
4285
4575
|
// src/sale/tender.tsx
|
|
4286
|
-
import { Pressable as
|
|
4287
|
-
import { formatMoney as
|
|
4288
|
-
import { Fragment as
|
|
4576
|
+
import { Pressable as Pressable30, Text as Text38, TextInput as TextInput12, View as View60 } from "react-native";
|
|
4577
|
+
import { formatMoney as formatMoney14 } from "@tallyui/core";
|
|
4578
|
+
import { Fragment as Fragment7, jsx as jsx95, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
4289
4579
|
var REFERENCE_MAX = 255;
|
|
4290
4580
|
function Tender({ sale }) {
|
|
4291
4581
|
const { order, stage } = sale;
|
|
4292
4582
|
if (stage.kind !== "tender") return null;
|
|
4293
4583
|
const money = (amount) => ({ amount, currency: order.currency });
|
|
4294
|
-
return /* @__PURE__ */
|
|
4295
|
-
stage.method === "cash" ? /* @__PURE__ */
|
|
4296
|
-
/* @__PURE__ */
|
|
4584
|
+
return /* @__PURE__ */ jsxs53(View60, { dataSet: { print: "hide" }, className: "gap-4 p-4", children: [
|
|
4585
|
+
stage.method === "cash" ? /* @__PURE__ */ jsxs53(Fragment7, { children: [
|
|
4586
|
+
/* @__PURE__ */ jsx95(
|
|
4297
4587
|
CashTendered,
|
|
4298
4588
|
{
|
|
4299
4589
|
total: money(order.totalMinor),
|
|
@@ -4301,19 +4591,19 @@ function Tender({ sale }) {
|
|
|
4301
4591
|
onChangeAmount: (amount) => sale.setTender({ method: "cash", amountMinor: amount.amount })
|
|
4302
4592
|
}
|
|
4303
4593
|
),
|
|
4304
|
-
/* @__PURE__ */
|
|
4305
|
-
order.balanceDueMinor > 0 ? /* @__PURE__ */
|
|
4594
|
+
/* @__PURE__ */ jsx95(ChangeDisplay, { change: money(order.changeDueMinor) }),
|
|
4595
|
+
order.balanceDueMinor > 0 ? /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
|
|
4306
4596
|
"Balance due: ",
|
|
4307
|
-
|
|
4597
|
+
formatMoney14(money(order.balanceDueMinor))
|
|
4308
4598
|
] }) : null,
|
|
4309
|
-
/* @__PURE__ */
|
|
4310
|
-
] }) : /* @__PURE__ */
|
|
4311
|
-
/* @__PURE__ */
|
|
4599
|
+
/* @__PURE__ */ jsx95(Pressable30, { 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__ */ jsx95(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" }) })
|
|
4600
|
+
] }) : /* @__PURE__ */ jsxs53(Fragment7, { children: [
|
|
4601
|
+
/* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
|
|
4312
4602
|
"Card terminal: ",
|
|
4313
|
-
|
|
4603
|
+
formatMoney14(money(order.totalMinor))
|
|
4314
4604
|
] }),
|
|
4315
|
-
/* @__PURE__ */
|
|
4316
|
-
|
|
4605
|
+
/* @__PURE__ */ jsx95(
|
|
4606
|
+
TextInput12,
|
|
4317
4607
|
{
|
|
4318
4608
|
accessibilityLabel: "Terminal reference",
|
|
4319
4609
|
placeholder: "Terminal reference",
|
|
@@ -4323,30 +4613,30 @@ function Tender({ sale }) {
|
|
|
4323
4613
|
className: "rounded-md border border-border px-3 py-2 text-foreground"
|
|
4324
4614
|
}
|
|
4325
4615
|
),
|
|
4326
|
-
/* @__PURE__ */
|
|
4616
|
+
/* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", onPress: sale.complete, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx95(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Payment approved on terminal" }) })
|
|
4327
4617
|
] }),
|
|
4328
|
-
sale.error ? /* @__PURE__ */
|
|
4329
|
-
sale.canContinue ? /* @__PURE__ */
|
|
4330
|
-
/* @__PURE__ */
|
|
4331
|
-
/* @__PURE__ */
|
|
4618
|
+
sale.error ? /* @__PURE__ */ jsx95(Text38, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
|
|
4619
|
+
sale.canContinue ? /* @__PURE__ */ jsxs53(Fragment7, { children: [
|
|
4620
|
+
/* @__PURE__ */ jsx95(Text38, { className: "text-foreground", children: "This sale is stored and will be sent. Continue to the next sale." }),
|
|
4621
|
+
/* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", onPress: () => sale.continueSale(), className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx95(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Continue" }) })
|
|
4332
4622
|
] }) : null,
|
|
4333
|
-
/* @__PURE__ */
|
|
4623
|
+
/* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", onPress: sale.cancelTender, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx95(Text38, { className: "text-center text-foreground", children: "Back" }) })
|
|
4334
4624
|
] });
|
|
4335
4625
|
}
|
|
4336
4626
|
|
|
4337
4627
|
// src/sale/split-tender.tsx
|
|
4338
|
-
import { useState as
|
|
4339
|
-
import { Pressable as
|
|
4340
|
-
import { formatMoney as
|
|
4341
|
-
import { Fragment as
|
|
4628
|
+
import { useState as useState21 } from "react";
|
|
4629
|
+
import { Pressable as Pressable31, Text as Text39, TextInput as TextInput13, View as View61 } from "react-native";
|
|
4630
|
+
import { formatMoney as formatMoney15, minorUnitDigits as minorUnitDigits9 } from "@tallyui/core";
|
|
4631
|
+
import { Fragment as Fragment8, jsx as jsx96, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
4342
4632
|
function SplitTender({ sale }) {
|
|
4343
4633
|
const { order, stage } = sale;
|
|
4344
|
-
const [method, setMethod] =
|
|
4345
|
-
const [amount, setAmount] =
|
|
4346
|
-
const [reference, setReference] =
|
|
4347
|
-
const [error, setError] =
|
|
4634
|
+
const [method, setMethod] = useState21("cash");
|
|
4635
|
+
const [amount, setAmount] = useState21(null);
|
|
4636
|
+
const [reference, setReference] = useState21("");
|
|
4637
|
+
const [error, setError] = useState21(null);
|
|
4348
4638
|
if (stage.kind !== "tender") return null;
|
|
4349
|
-
const money = (value) =>
|
|
4639
|
+
const money = (value) => formatMoney15({ amount: value, currency: order.currency });
|
|
4350
4640
|
const digits = minorUnitDigits9(order.currency);
|
|
4351
4641
|
const amountText = amount ?? (order.balanceDueMinor / 10 ** digits).toFixed(digits);
|
|
4352
4642
|
const incomplete = order.balanceDueMinor > 0 || order.payments.length === 0;
|
|
@@ -4369,59 +4659,59 @@ function SplitTender({ sale }) {
|
|
|
4369
4659
|
setReference("");
|
|
4370
4660
|
setAmount(null);
|
|
4371
4661
|
}
|
|
4372
|
-
return /* @__PURE__ */
|
|
4373
|
-
/* @__PURE__ */
|
|
4374
|
-
/* @__PURE__ */
|
|
4662
|
+
return /* @__PURE__ */ jsxs54(View61, { dataSet: { print: "hide" }, className: "gap-4 p-4", children: [
|
|
4663
|
+
/* @__PURE__ */ jsxs54(View61, { testID: "split-tender-summary", className: "gap-2", children: [
|
|
4664
|
+
/* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
|
|
4375
4665
|
"Total: ",
|
|
4376
4666
|
money(order.totalMinor)
|
|
4377
4667
|
] }),
|
|
4378
|
-
/* @__PURE__ */
|
|
4668
|
+
/* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
|
|
4379
4669
|
"Paid: ",
|
|
4380
4670
|
money(order.paidMinor)
|
|
4381
4671
|
] }),
|
|
4382
|
-
/* @__PURE__ */
|
|
4672
|
+
/* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
|
|
4383
4673
|
"Remaining: ",
|
|
4384
4674
|
money(order.balanceDueMinor)
|
|
4385
4675
|
] }),
|
|
4386
|
-
order.changeDueMinor > 0 ? /* @__PURE__ */
|
|
4676
|
+
order.changeDueMinor > 0 ? /* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
|
|
4387
4677
|
"Change: ",
|
|
4388
4678
|
money(order.changeDueMinor)
|
|
4389
4679
|
] }) : null
|
|
4390
4680
|
] }),
|
|
4391
|
-
/* @__PURE__ */
|
|
4392
|
-
/* @__PURE__ */
|
|
4681
|
+
/* @__PURE__ */ jsx96(View61, { testID: "split-tender-list", className: "gap-2", children: order.payments.map((payment) => /* @__PURE__ */ jsxs54(View61, { testID: `split-tender-row-${payment.id}`, className: "gap-2", children: [
|
|
4682
|
+
/* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
|
|
4393
4683
|
tenderLabel(payment.method),
|
|
4394
4684
|
" ",
|
|
4395
4685
|
money(payment.amountMinor)
|
|
4396
4686
|
] }),
|
|
4397
|
-
payment.reference ? /* @__PURE__ */
|
|
4398
|
-
/* @__PURE__ */
|
|
4399
|
-
|
|
4687
|
+
payment.reference ? /* @__PURE__ */ jsx96(Text39, { className: "text-foreground", children: payment.reference }) : null,
|
|
4688
|
+
/* @__PURE__ */ jsx96(
|
|
4689
|
+
Pressable31,
|
|
4400
4690
|
{
|
|
4401
4691
|
testID: `split-tender-remove-${payment.id}`,
|
|
4402
4692
|
accessibilityRole: "button",
|
|
4403
4693
|
accessibilityLabel: "Remove tender",
|
|
4404
4694
|
onPress: () => sale.removeTender(payment.id),
|
|
4405
4695
|
className: "rounded-md border border-border bg-card px-4 py-3",
|
|
4406
|
-
children: /* @__PURE__ */
|
|
4696
|
+
children: /* @__PURE__ */ jsx96(Text39, { className: "text-center text-foreground", children: "Remove" })
|
|
4407
4697
|
}
|
|
4408
4698
|
)
|
|
4409
4699
|
] }, payment.id)) }),
|
|
4410
|
-
/* @__PURE__ */
|
|
4411
|
-
/* @__PURE__ */
|
|
4412
|
-
|
|
4700
|
+
/* @__PURE__ */ jsxs54(View61, { testID: "split-tender-add", className: "gap-2", children: [
|
|
4701
|
+
/* @__PURE__ */ jsx96(View61, { className: "flex-row gap-2", children: ["cash", "external"].map((value) => /* @__PURE__ */ jsx96(
|
|
4702
|
+
Pressable31,
|
|
4413
4703
|
{
|
|
4414
4704
|
testID: `split-tender-method-${value === "cash" ? "cash" : "card"}`,
|
|
4415
4705
|
accessibilityRole: "button",
|
|
4416
4706
|
accessibilityState: { selected: method === value },
|
|
4417
4707
|
onPress: () => setMethod(value),
|
|
4418
4708
|
className: `rounded-md border border-border px-4 py-3 ${method === value ? "bg-primary" : "bg-card"}`,
|
|
4419
|
-
children: /* @__PURE__ */
|
|
4709
|
+
children: /* @__PURE__ */ jsx96(Text39, { className: `text-center ${method === value ? "text-primary-foreground" : "text-foreground"}`, children: tenderLabel(value) })
|
|
4420
4710
|
},
|
|
4421
4711
|
value
|
|
4422
4712
|
)) }),
|
|
4423
|
-
/* @__PURE__ */
|
|
4424
|
-
|
|
4713
|
+
/* @__PURE__ */ jsx96(
|
|
4714
|
+
TextInput13,
|
|
4425
4715
|
{
|
|
4426
4716
|
testID: "split-tender-amount",
|
|
4427
4717
|
accessibilityLabel: "Tender amount",
|
|
@@ -4431,8 +4721,8 @@ function SplitTender({ sale }) {
|
|
|
4431
4721
|
className: "rounded-md border border-border px-3 py-2 text-foreground"
|
|
4432
4722
|
}
|
|
4433
4723
|
),
|
|
4434
|
-
method === "external" ? /* @__PURE__ */
|
|
4435
|
-
|
|
4724
|
+
method === "external" ? /* @__PURE__ */ jsx96(
|
|
4725
|
+
TextInput13,
|
|
4436
4726
|
{
|
|
4437
4727
|
testID: "split-tender-reference",
|
|
4438
4728
|
accessibilityLabel: "Terminal reference",
|
|
@@ -4443,36 +4733,48 @@ function SplitTender({ sale }) {
|
|
|
4443
4733
|
className: "rounded-md border border-border px-3 py-2 text-foreground"
|
|
4444
4734
|
}
|
|
4445
4735
|
) : null,
|
|
4446
|
-
error ? /* @__PURE__ */
|
|
4447
|
-
/* @__PURE__ */
|
|
4736
|
+
error ? /* @__PURE__ */ jsx96(Text39, { testID: "split-tender-error", accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
|
|
4737
|
+
/* @__PURE__ */ jsx96(Pressable31, { testID: "split-tender-add-button", accessibilityRole: "button", onPress: add, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx96(Text39, { className: "text-center font-semibold text-primary-foreground", children: "Add" }) })
|
|
4448
4738
|
] }),
|
|
4449
|
-
/* @__PURE__ */
|
|
4450
|
-
|
|
4739
|
+
/* @__PURE__ */ jsx96(
|
|
4740
|
+
Pressable31,
|
|
4451
4741
|
{
|
|
4452
4742
|
testID: "split-tender-complete",
|
|
4453
4743
|
accessibilityRole: "button",
|
|
4454
4744
|
disabled: incomplete,
|
|
4455
4745
|
onPress: sale.complete,
|
|
4456
4746
|
className: `rounded-md bg-primary px-4 py-3 ${incomplete ? "opacity-50" : ""}`,
|
|
4457
|
-
children: /* @__PURE__ */
|
|
4747
|
+
children: /* @__PURE__ */ jsx96(Text39, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" })
|
|
4458
4748
|
}
|
|
4459
4749
|
),
|
|
4460
|
-
sale.error ? /* @__PURE__ */
|
|
4461
|
-
sale.canContinue ? /* @__PURE__ */
|
|
4462
|
-
/* @__PURE__ */
|
|
4463
|
-
/* @__PURE__ */
|
|
4750
|
+
sale.error ? /* @__PURE__ */ jsx96(Text39, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
|
|
4751
|
+
sale.canContinue ? /* @__PURE__ */ jsxs54(Fragment8, { children: [
|
|
4752
|
+
/* @__PURE__ */ jsx96(Text39, { className: "text-foreground", children: "This sale is stored and will be sent. Continue to the next sale." }),
|
|
4753
|
+
/* @__PURE__ */ jsx96(Pressable31, { accessibilityRole: "button", onPress: () => sale.continueSale(), className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx96(Text39, { className: "text-center font-semibold text-primary-foreground", children: "Continue" }) })
|
|
4464
4754
|
] }) : null,
|
|
4465
|
-
/* @__PURE__ */
|
|
4755
|
+
/* @__PURE__ */ jsx96(Pressable31, { accessibilityRole: "button", onPress: sale.cancelTender, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx96(Text39, { className: "text-center text-foreground", children: "Back" }) })
|
|
4466
4756
|
] });
|
|
4467
4757
|
}
|
|
4468
4758
|
|
|
4469
4759
|
// src/sale/catalogue.tsx
|
|
4470
|
-
import { useEffect as useEffect5, useMemo as
|
|
4471
|
-
import { Pressable as
|
|
4472
|
-
import { useStockOverlaid, useStockOverlayAsOf } from "@tallyui/core";
|
|
4473
|
-
import {
|
|
4474
|
-
|
|
4475
|
-
|
|
4760
|
+
import { useEffect as useEffect5, useMemo as useMemo3, useRef as useRef6, useState as useState22 } from "react";
|
|
4761
|
+
import { Pressable as Pressable32, Text as Text40, View as View62 } from "react-native";
|
|
4762
|
+
import { useStockOverlaid as useStockOverlaid2, useStockOverlayAsOf } from "@tallyui/core";
|
|
4763
|
+
import {
|
|
4764
|
+
catalogueEntries,
|
|
4765
|
+
findEntryByCode,
|
|
4766
|
+
searchProducts,
|
|
4767
|
+
variantPriceLabel,
|
|
4768
|
+
sortProducts as sortProducts2,
|
|
4769
|
+
productSortValue as productSortValue2,
|
|
4770
|
+
catalogueViewReducer,
|
|
4771
|
+
normalizeCatalogueViewState,
|
|
4772
|
+
resolveGridColumns,
|
|
4773
|
+
DEFAULT_CATALOGUE_VIEW_STATE,
|
|
4774
|
+
listCategories,
|
|
4775
|
+
inCategory
|
|
4776
|
+
} from "@tallyui/pos";
|
|
4777
|
+
import { jsx as jsx97, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
4476
4778
|
var STOCK_LABEL = {
|
|
4477
4779
|
in_stock: "In Stock",
|
|
4478
4780
|
out_of_stock: "Out of Stock",
|
|
@@ -4490,20 +4792,98 @@ function laterOf(a, b) {
|
|
|
4490
4792
|
if (!b) return a;
|
|
4491
4793
|
return a.getTime() >= b.getTime() ? a : b;
|
|
4492
4794
|
}
|
|
4493
|
-
function Catalogue({
|
|
4795
|
+
function Catalogue({
|
|
4796
|
+
products,
|
|
4797
|
+
traits,
|
|
4798
|
+
currency,
|
|
4799
|
+
onSelect,
|
|
4800
|
+
statusText,
|
|
4801
|
+
statusAccessory,
|
|
4802
|
+
lastSyncedAt,
|
|
4803
|
+
loading,
|
|
4804
|
+
pullError,
|
|
4805
|
+
lastStockCheckAt,
|
|
4806
|
+
hour12,
|
|
4807
|
+
minCodeLength,
|
|
4808
|
+
viewState,
|
|
4809
|
+
defaultViewState,
|
|
4810
|
+
loadViewState,
|
|
4811
|
+
saveViewState,
|
|
4812
|
+
onViewStateError,
|
|
4813
|
+
onStateChange,
|
|
4814
|
+
showViewToggle = false,
|
|
4815
|
+
items,
|
|
4816
|
+
onQueryChange,
|
|
4817
|
+
showCategoryNav = false,
|
|
4818
|
+
categories
|
|
4819
|
+
}) {
|
|
4820
|
+
const [initial] = useState22(() => {
|
|
4821
|
+
const state2 = normalizeCatalogueViewState({ ...DEFAULT_CATALOGUE_VIEW_STATE, ...defaultViewState });
|
|
4822
|
+
if (viewState !== void 0 || !loadViewState) return { state: state2 };
|
|
4823
|
+
try {
|
|
4824
|
+
const value = loadViewState();
|
|
4825
|
+
if (value instanceof Promise) return { state: state2, pending: value };
|
|
4826
|
+
const loaded = normalizeCatalogueViewState(value, state2);
|
|
4827
|
+
return { state: loaded, loaded };
|
|
4828
|
+
} catch (error) {
|
|
4829
|
+
return { state: state2, failed: true, error };
|
|
4830
|
+
}
|
|
4831
|
+
});
|
|
4832
|
+
const [internalState, setInternalState] = useState22(initial.state);
|
|
4833
|
+
const state = viewState ?? internalState;
|
|
4834
|
+
const cashierChanged = useRef6(false);
|
|
4835
|
+
useEffect5(() => {
|
|
4836
|
+
let mounted = true;
|
|
4837
|
+
if (initial.loaded) onStateChange?.(initial.loaded);
|
|
4838
|
+
if (initial.failed) onViewStateError?.(initial.error);
|
|
4839
|
+
initial.pending?.then((value) => {
|
|
4840
|
+
if (!mounted || cashierChanged.current) return;
|
|
4841
|
+
const loaded = normalizeCatalogueViewState(value, initial.state);
|
|
4842
|
+
setInternalState(loaded);
|
|
4843
|
+
onStateChange?.(loaded);
|
|
4844
|
+
}, (error) => {
|
|
4845
|
+
if (mounted) onViewStateError?.(error);
|
|
4846
|
+
});
|
|
4847
|
+
return () => {
|
|
4848
|
+
mounted = false;
|
|
4849
|
+
};
|
|
4850
|
+
}, [initial]);
|
|
4851
|
+
function changeState(action) {
|
|
4852
|
+
const next = catalogueViewReducer(state, action);
|
|
4853
|
+
if (next === state) return;
|
|
4854
|
+
cashierChanged.current = true;
|
|
4855
|
+
if (viewState !== void 0) {
|
|
4856
|
+
onStateChange?.(next);
|
|
4857
|
+
return;
|
|
4858
|
+
}
|
|
4859
|
+
setInternalState(next);
|
|
4860
|
+
onStateChange?.(next);
|
|
4861
|
+
try {
|
|
4862
|
+
Promise.resolve(saveViewState?.(next)).catch((error) => onViewStateError?.(error));
|
|
4863
|
+
} catch (error) {
|
|
4864
|
+
onViewStateError?.(error);
|
|
4865
|
+
}
|
|
4866
|
+
}
|
|
4494
4867
|
const isLoading = loading ?? (lastSyncedAt === null && pullError == null);
|
|
4495
|
-
const shown =
|
|
4868
|
+
const shown = useStockOverlaid2(products);
|
|
4869
|
+
const categoryList = useMemo3(() => categories ?? listCategories(shown, traits), [categories, shown, traits]);
|
|
4870
|
+
const activeCategory = showCategoryNav ? categoryList.find((category) => category.id === state.categoryId) : void 0;
|
|
4871
|
+
const suppliedItems = useStockOverlaid2(items ?? products);
|
|
4496
4872
|
const overlayAsOf = useStockOverlayAsOf();
|
|
4497
4873
|
const parsedOverlayAsOf = overlayAsOf ? new Date(overlayAsOf) : void 0;
|
|
4498
4874
|
const validOverlayAsOf = parsedOverlayAsOf && !isNaN(parsedOverlayAsOf.getTime()) ? parsedOverlayAsOf : void 0;
|
|
4499
4875
|
const stockAsOf = laterOf(laterOf(lastStockCheckAt, validOverlayAsOf), lastSyncedAt);
|
|
4500
|
-
const [query, setQuery] =
|
|
4501
|
-
const [chooserId, setChooserId] =
|
|
4502
|
-
const [width, setWidth] =
|
|
4503
|
-
const columns =
|
|
4504
|
-
const entries =
|
|
4505
|
-
const results =
|
|
4506
|
-
|
|
4876
|
+
const [query, setQuery] = useState22("");
|
|
4877
|
+
const [chooserId, setChooserId] = useState22(null);
|
|
4878
|
+
const [width, setWidth] = useState22(0);
|
|
4879
|
+
const columns = resolveGridColumns(state.gridColumns, width);
|
|
4880
|
+
const entries = useMemo3(() => catalogueEntries(shown, traits, { currency }), [shown, traits, currency]);
|
|
4881
|
+
const results = useMemo3(() => {
|
|
4882
|
+
if (items !== void 0) return suppliedItems;
|
|
4883
|
+
const filtered = searchProducts(activeCategory ? shown.filter((doc) => inCategory(doc, activeCategory.id, traits)) : shown, query, traits);
|
|
4884
|
+
return state.sort ? sortProducts2(filtered, state.sort, (doc, field) => productSortValue2(doc, field, traits, { currency })) : filtered;
|
|
4885
|
+
}, [items, suppliedItems, shown, query, traits, state.sort, currency, showCategoryNav, activeCategory]);
|
|
4886
|
+
const choices = useMemo3(() => chooserId === null ? [] : entries.filter((entry) => traits.getId(entry.product) === chooserId), [entries, chooserId, traits]);
|
|
4507
4887
|
useEffect5(() => {
|
|
4508
4888
|
if (chooserId !== null && choices.length === 0) setChooserId(null);
|
|
4509
4889
|
}, [chooserId, choices]);
|
|
@@ -4511,13 +4891,22 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
|
|
|
4511
4891
|
onSelect(entry);
|
|
4512
4892
|
setChooserId(null);
|
|
4513
4893
|
}
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4894
|
+
function selectProduct(product) {
|
|
4895
|
+
const variants = entries.filter((entry) => traits.getId(entry.product) === traits.getId(product));
|
|
4896
|
+
if (variants.length === 1) select(variants[0]);
|
|
4897
|
+
else setChooserId(traits.getId(product));
|
|
4898
|
+
}
|
|
4899
|
+
const emptyState = /* @__PURE__ */ jsx97(Text40, { className: "mt-10 text-center text-sm text-muted-foreground", children: query.trim() ? `No products match "${query.trim()}".` : activeCategory ? `No products in ${activeCategory.name}.` : isLoading ? "Loading products\u2026" : "No products yet." });
|
|
4900
|
+
return /* @__PURE__ */ jsxs55(View62, { className: "flex-1", onLayout: (event) => setWidth(event.nativeEvent.layout.width), children: [
|
|
4901
|
+
/* @__PURE__ */ jsxs55(View62, { className: "gap-2 border-b border-border bg-card px-4 pb-3 pt-3", children: [
|
|
4902
|
+
/* @__PURE__ */ jsx97(
|
|
4517
4903
|
SearchInput,
|
|
4518
4904
|
{
|
|
4519
4905
|
value: query,
|
|
4520
|
-
onChangeText:
|
|
4906
|
+
onChangeText: (text) => {
|
|
4907
|
+
setQuery(text);
|
|
4908
|
+
onQueryChange?.(text);
|
|
4909
|
+
},
|
|
4521
4910
|
placeholder: "Search or scan barcode / SKU",
|
|
4522
4911
|
autoFocus: true,
|
|
4523
4912
|
onSubmitEditing: () => {
|
|
@@ -4530,25 +4919,34 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
|
|
|
4530
4919
|
}
|
|
4531
4920
|
}
|
|
4532
4921
|
),
|
|
4533
|
-
statusText || statusAccessory ? /* @__PURE__ */
|
|
4534
|
-
statusText ? /* @__PURE__ */
|
|
4922
|
+
statusText || statusAccessory || showViewToggle ? /* @__PURE__ */ jsxs55(View62, { testID: "catalogue-status-row", className: "flex-row items-center gap-2", children: [
|
|
4923
|
+
statusText ? /* @__PURE__ */ jsxs55(Text40, { className: "flex-1 text-xs text-muted-foreground", numberOfLines: statusAccessory ? 1 : void 0, children: [
|
|
4535
4924
|
statusText,
|
|
4536
4925
|
query.trim() ? ` \xB7 ${results.length.toLocaleString()} matching` : ""
|
|
4537
4926
|
] }) : null,
|
|
4538
|
-
statusAccessory
|
|
4927
|
+
statusAccessory,
|
|
4928
|
+
showViewToggle ? /* @__PURE__ */ jsx97(ViewToggle, { value: state.view, onChange: (view) => changeState({ type: "setView", view }) }) : null
|
|
4539
4929
|
] }) : null,
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4930
|
+
showCategoryNav ? /* @__PURE__ */ jsx97(
|
|
4931
|
+
CategoryNav,
|
|
4932
|
+
{
|
|
4933
|
+
categories: [{ id: "", name: "All products" }, ...categoryList],
|
|
4934
|
+
selectedId: activeCategory?.id ?? "",
|
|
4935
|
+
onSelect: (id) => changeState({ type: "setCategory", categoryId: id === "" ? null : id })
|
|
4936
|
+
}
|
|
4937
|
+
) : null,
|
|
4938
|
+
choices.length > 0 ? /* @__PURE__ */ jsxs55(View62, { accessibilityLabel: "Choose variant", className: "gap-2", children: [
|
|
4939
|
+
choices.map((entry) => /* @__PURE__ */ jsxs55(
|
|
4940
|
+
Pressable32,
|
|
4543
4941
|
{
|
|
4544
4942
|
accessibilityRole: "button",
|
|
4545
4943
|
onPress: () => select(entry),
|
|
4546
4944
|
className: "gap-1 rounded-md border border-border p-3",
|
|
4547
4945
|
children: [
|
|
4548
|
-
/* @__PURE__ */
|
|
4549
|
-
/* @__PURE__ */
|
|
4550
|
-
/* @__PURE__ */
|
|
4551
|
-
/* @__PURE__ */
|
|
4946
|
+
/* @__PURE__ */ jsx97(Text40, { className: "font-semibold text-foreground", children: entry.variant.title }),
|
|
4947
|
+
/* @__PURE__ */ jsx97(Text40, { className: "text-muted-foreground", children: entry.variant.sku }),
|
|
4948
|
+
/* @__PURE__ */ jsx97(Text40, { className: "text-foreground", children: variantPriceLabel(entry.variant, currency) }),
|
|
4949
|
+
/* @__PURE__ */ jsxs55(Text40, { className: "text-muted-foreground", children: [
|
|
4552
4950
|
STOCK_LABEL[entry.variant.stock.status],
|
|
4553
4951
|
" \xB7 ",
|
|
4554
4952
|
stockAsOf ? `as of ${formatStockSyncTime(stockAsOf, void 0, hour12)}` : "not yet synced"
|
|
@@ -4557,10 +4955,20 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
|
|
|
4557
4955
|
},
|
|
4558
4956
|
entry.variant.id
|
|
4559
4957
|
)),
|
|
4560
|
-
/* @__PURE__ */
|
|
4958
|
+
/* @__PURE__ */ jsx97(Pressable32, { accessibilityRole: "button", onPress: () => setChooserId(null), className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx97(Text40, { className: "text-center text-foreground", children: "Cancel" }) })
|
|
4561
4959
|
] }) : null
|
|
4562
4960
|
] }),
|
|
4563
|
-
/* @__PURE__ */
|
|
4961
|
+
state.view === "table" ? /* @__PURE__ */ jsx97(
|
|
4962
|
+
ProductTable,
|
|
4963
|
+
{
|
|
4964
|
+
items: results,
|
|
4965
|
+
sort: state.sort,
|
|
4966
|
+
onSortChange: (sort) => changeState({ type: "setSort", sort }),
|
|
4967
|
+
sortItems: false,
|
|
4968
|
+
onSelect: selectProduct,
|
|
4969
|
+
emptyState
|
|
4970
|
+
}
|
|
4971
|
+
) : /* @__PURE__ */ jsx97(
|
|
4564
4972
|
ProductGrid,
|
|
4565
4973
|
{
|
|
4566
4974
|
items: results,
|
|
@@ -4569,18 +4977,14 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
|
|
|
4569
4977
|
// TallyUI's ProductCard has no children slot, so the tile is composed directly here
|
|
4570
4978
|
// (same structure/classes as ProductCard) to add the stock badge as a fourth child,
|
|
4571
4979
|
// inside the card and centred with the rest, rather than adding a slot to ProductCard (out of scope for TV6b).
|
|
4572
|
-
/* @__PURE__ */
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
/* @__PURE__ */ jsx94(ProductImage, { doc: product, size: 80, className: "rounded-md" }),
|
|
4578
|
-
/* @__PURE__ */ jsx94(ProductTitle, { doc: product, className: "text-sm", numberOfLines: 2 }),
|
|
4579
|
-
/* @__PURE__ */ jsx94(ProductPrice, { doc: product }),
|
|
4580
|
-
/* @__PURE__ */ jsx94(ProductStockBadge, { doc: product, showAsOf: false, className: "self-center" })
|
|
4980
|
+
/* @__PURE__ */ jsx97(Pressable32, { accessibilityRole: "button", testID: `product-tile-${traits.getName(product)}`, onPress: () => selectProduct(product), children: /* @__PURE__ */ jsxs55(VStack, { space: "sm", className: "items-center rounded-lg border border-border bg-card p-3", children: [
|
|
4981
|
+
/* @__PURE__ */ jsx97(ProductImage, { doc: product, size: 80, className: "rounded-md" }),
|
|
4982
|
+
/* @__PURE__ */ jsx97(ProductTitle, { doc: product, className: "text-sm", numberOfLines: 2 }),
|
|
4983
|
+
/* @__PURE__ */ jsx97(ProductPrice, { doc: product }),
|
|
4984
|
+
/* @__PURE__ */ jsx97(ProductStockBadge, { doc: product, showAsOf: false, className: "self-center" })
|
|
4581
4985
|
] }) })
|
|
4582
4986
|
),
|
|
4583
|
-
emptyState
|
|
4987
|
+
emptyState
|
|
4584
4988
|
}
|
|
4585
4989
|
)
|
|
4586
4990
|
] });
|
|
@@ -4588,8 +4992,8 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
|
|
|
4588
4992
|
|
|
4589
4993
|
// src/sale/receipt.tsx
|
|
4590
4994
|
import { useEffect as useEffect6 } from "react";
|
|
4591
|
-
import { Pressable as
|
|
4592
|
-
import { formatMoney as
|
|
4995
|
+
import { Pressable as Pressable33, Text as Text41, View as View63 } from "react-native";
|
|
4996
|
+
import { formatMoney as formatMoney16 } from "@tallyui/core";
|
|
4593
4997
|
import { buildReceiptData as buildReceiptData3 } from "@tallyui/pos";
|
|
4594
4998
|
|
|
4595
4999
|
// src/sale/print-style.ts
|
|
@@ -4609,7 +5013,7 @@ function orderReference(order) {
|
|
|
4609
5013
|
}
|
|
4610
5014
|
|
|
4611
5015
|
// src/sale/receipt.tsx
|
|
4612
|
-
import { Fragment as
|
|
5016
|
+
import { Fragment as Fragment9, jsx as jsx98, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
4613
5017
|
var defaultFormatDate = (iso) => new Intl.DateTimeFormat(void 0, { dateStyle: "medium", timeStyle: "short" }).format(new Date(iso));
|
|
4614
5018
|
function Receipt({
|
|
4615
5019
|
order,
|
|
@@ -4629,37 +5033,39 @@ function Receipt({
|
|
|
4629
5033
|
cashier,
|
|
4630
5034
|
register: registerId
|
|
4631
5035
|
});
|
|
4632
|
-
const money = (amount) =>
|
|
4633
|
-
const row = (label, amount, bold = false, key) => /* @__PURE__ */
|
|
4634
|
-
/* @__PURE__ */
|
|
4635
|
-
/* @__PURE__ */
|
|
5036
|
+
const money = (amount) => formatMoney16({ amount, currency: receipt.currency }) ?? "";
|
|
5037
|
+
const row = (label, amount, bold = false, key) => /* @__PURE__ */ jsxs56(View63, { accessibilityLabel: `${label}: ${amount}`, className: "flex-row justify-between gap-4", children: [
|
|
5038
|
+
/* @__PURE__ */ jsx98(Text41, { className: `text-foreground ${bold ? "font-semibold" : ""}`, children: label }),
|
|
5039
|
+
/* @__PURE__ */ jsx98(Text41, { className: `text-right text-foreground ${bold ? "font-semibold" : ""}`, children: amount })
|
|
4636
5040
|
] }, key);
|
|
4637
5041
|
const { totals } = receipt;
|
|
4638
5042
|
const lineDiscountMinor = totals.discountMinor - receipt.orderDiscountMinor;
|
|
4639
5043
|
const taxRows = totals.taxLines.map((line, index) => row(`${totals.taxInclusive ? "incl. " : ""}${taxLabel(line.ratePpm)}`, money(line.amountMinor), false, index));
|
|
4640
|
-
return /* @__PURE__ */
|
|
4641
|
-
topInset > 0 ? /* @__PURE__ */
|
|
4642
|
-
/* @__PURE__ */
|
|
4643
|
-
/* @__PURE__ */
|
|
4644
|
-
receipt.header.storeAddress ? /* @__PURE__ */
|
|
4645
|
-
/* @__PURE__ */
|
|
4646
|
-
/* @__PURE__ */
|
|
4647
|
-
/* @__PURE__ */
|
|
5044
|
+
return /* @__PURE__ */ jsxs56(Fragment9, { children: [
|
|
5045
|
+
topInset > 0 ? /* @__PURE__ */ jsx98(View63, { dataSet: { print: "hide" }, style: { height: topInset, flexShrink: 0 } }) : null,
|
|
5046
|
+
/* @__PURE__ */ jsxs56(View63, { className: "w-full max-w-md self-center gap-3 p-4 bg-card", children: [
|
|
5047
|
+
/* @__PURE__ */ jsx98(Text41, { className: "text-lg font-semibold text-foreground", children: receipt.header.storeName }),
|
|
5048
|
+
receipt.header.storeAddress ? /* @__PURE__ */ jsx98(Text41, { className: "text-muted-foreground", children: receipt.header.storeAddress }) : null,
|
|
5049
|
+
/* @__PURE__ */ jsx98(Text41, { testID: "receipt-order", className: "text-foreground", children: posOrder ? `Order ${orderReference(posOrder)}` : `Order ${receipt.header.orderNumber.slice(-8)} (draft)` }),
|
|
5050
|
+
/* @__PURE__ */ jsx98(Text41, { className: "text-muted-foreground", children: formatDate(posOrder?.createdAt ?? receipt.header.date) }),
|
|
5051
|
+
/* @__PURE__ */ jsxs56(Text41, { className: "text-muted-foreground", children: [
|
|
4648
5052
|
"Cashier: ",
|
|
4649
5053
|
receipt.header.cashier
|
|
4650
5054
|
] }),
|
|
4651
|
-
receipt.header.customer && /* @__PURE__ */
|
|
5055
|
+
receipt.header.customer && /* @__PURE__ */ jsxs56(Text41, { className: "text-muted-foreground", children: [
|
|
4652
5056
|
"Customer: ",
|
|
4653
5057
|
receipt.header.customer
|
|
4654
5058
|
] }),
|
|
4655
|
-
receipt.lineItems.map((line, index) => /* @__PURE__ */
|
|
4656
|
-
/* @__PURE__ */
|
|
5059
|
+
receipt.lineItems.map((line, index) => /* @__PURE__ */ jsxs56(View63, { children: [
|
|
5060
|
+
/* @__PURE__ */ jsx98(Text41, { className: "text-foreground", children: line.name }),
|
|
4657
5061
|
row(`${line.quantity} \xD7 ${money(line.unitPriceMinor)}`, money(line.displayAmountMinor)),
|
|
4658
|
-
line.displayDiscounts.map((discount, i) => /* @__PURE__ */
|
|
5062
|
+
line.displayDiscounts.map((discount, i) => /* @__PURE__ */ jsx98(View63, { className: "pl-4", children: row(`${discountLabel(
|
|
4659
5063
|
order.lineItems[index].discounts[i],
|
|
4660
5064
|
receipt.currency
|
|
4661
5065
|
)} off`, `\u2212${money(discount.amountMinor)}`) }, i))
|
|
4662
5066
|
] }, index)),
|
|
5067
|
+
receipt.fees.map((charge, index) => row(charge.name, money(charge.amountMinor), false, index)),
|
|
5068
|
+
receipt.shipping.map((charge, index) => row(charge.name, money(charge.amountMinor), false, index)),
|
|
4663
5069
|
row("Subtotal", money(totals.subtotalMinor)),
|
|
4664
5070
|
lineDiscountMinor > 0 ? row("Line discounts", `\u2212${money(lineDiscountMinor)}`) : null,
|
|
4665
5071
|
receipt.orderDiscountMinor > 0 ? row("Order discount", `\u2212${money(receipt.orderDiscountMinor)}`) : null,
|
|
@@ -4672,19 +5078,19 @@ function Receipt({
|
|
|
4672
5078
|
index
|
|
4673
5079
|
)),
|
|
4674
5080
|
row("Change", money(receipt.changeDueMinor)),
|
|
4675
|
-
/* @__PURE__ */
|
|
4676
|
-
/* @__PURE__ */
|
|
5081
|
+
/* @__PURE__ */ jsxs56(View63, { dataSet: { print: "hide" }, className: "flex-row gap-4", children: [
|
|
5082
|
+
/* @__PURE__ */ jsx98(Pressable33, { accessibilityRole: "button", onPress: () => {
|
|
4677
5083
|
if (typeof window !== "undefined" && typeof window.print === "function") window.print();
|
|
4678
|
-
}, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */
|
|
4679
|
-
/* @__PURE__ */
|
|
5084
|
+
}, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx98(Text41, { className: "text-center text-foreground", children: "Print receipt" }) }),
|
|
5085
|
+
/* @__PURE__ */ jsx98(Pressable33, { accessibilityRole: "button", onPress: newSale, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx98(Text41, { className: "text-center font-semibold text-primary-foreground", children: "New sale" }) })
|
|
4680
5086
|
] })
|
|
4681
5087
|
] })
|
|
4682
5088
|
] });
|
|
4683
5089
|
}
|
|
4684
5090
|
|
|
4685
5091
|
// src/sale/sync-status.tsx
|
|
4686
|
-
import { useEffect as useEffect7, useRef as
|
|
4687
|
-
import { AccessibilityInfo as AccessibilityInfo2, Platform as Platform3, Text as
|
|
5092
|
+
import { useEffect as useEffect7, useRef as useRef7, useState as useState23 } from "react";
|
|
5093
|
+
import { AccessibilityInfo as AccessibilityInfo2, Platform as Platform3, Text as Text42, View as View64 } from "react-native";
|
|
4688
5094
|
|
|
4689
5095
|
// src/sale/since-text.ts
|
|
4690
5096
|
function sinceText(clock) {
|
|
@@ -4693,7 +5099,7 @@ function sinceText(clock) {
|
|
|
4693
5099
|
}
|
|
4694
5100
|
|
|
4695
5101
|
// src/sale/sync-status.tsx
|
|
4696
|
-
import { Fragment as
|
|
5102
|
+
import { Fragment as Fragment10, jsx as jsx99, jsxs as jsxs57 } from "react/jsx-runtime";
|
|
4697
5103
|
var PULL_NOTICE_TEXT = {
|
|
4698
5104
|
unauthorized: {
|
|
4699
5105
|
line: () => "Products aren't updating: this till needs to sign in to the online store again.",
|
|
@@ -4735,7 +5141,7 @@ var SALES_REFUSED = "The online store refused the last send. This till will try
|
|
|
4735
5141
|
var TILL_UPDATES_REFUSED = "The online store refused the last send. This till will try again with the next till update, or when the app is reopened.";
|
|
4736
5142
|
var count = (n, noun) => `${n} ${noun}${n === 1 ? "" : "s"}`;
|
|
4737
5143
|
function useAnnounceOnIos(...texts) {
|
|
4738
|
-
const announced =
|
|
5144
|
+
const announced = useRef7(texts);
|
|
4739
5145
|
useEffect7(() => {
|
|
4740
5146
|
const changed = texts.filter((text, index) => text && text !== announced.current[index]);
|
|
4741
5147
|
announced.current = texts;
|
|
@@ -4745,7 +5151,7 @@ function useAnnounceOnIos(...texts) {
|
|
|
4745
5151
|
function SyncStatus({ state, registerState, pluginName = "the POS plugin", pullNotice }) {
|
|
4746
5152
|
const updates = registerState?.pending ?? 0;
|
|
4747
5153
|
const outbox = state.pending === 0 && registerState?.pending ? registerState : state;
|
|
4748
|
-
const [now, setNow] =
|
|
5154
|
+
const [now, setNow] = useState23(Date.now);
|
|
4749
5155
|
useEffect7(() => {
|
|
4750
5156
|
setNow(Date.now());
|
|
4751
5157
|
if (!outbox.nextAttemptAt) return;
|
|
@@ -4769,24 +5175,24 @@ function SyncStatus({ state, registerState, pluginName = "the POS plugin", pullN
|
|
|
4769
5175
|
const notice = pullNotice && text && { line: text.line(pluginName), detail: text.detail(pullNotice, pluginName) };
|
|
4770
5176
|
useAnnounceOnIos(notice?.line, spoken);
|
|
4771
5177
|
const oneDetail = pullNotice?.code === "missing_plugin" && !!backendMissing;
|
|
4772
|
-
return /* @__PURE__ */
|
|
4773
|
-
notice ? /* @__PURE__ */
|
|
4774
|
-
/* @__PURE__ */
|
|
4775
|
-
oneDetail ? null : /* @__PURE__ */
|
|
5178
|
+
return /* @__PURE__ */ jsxs57(View64, { children: [
|
|
5179
|
+
notice ? /* @__PURE__ */ jsxs57(Fragment10, { children: [
|
|
5180
|
+
/* @__PURE__ */ jsx99(Text42, { accessibilityLiveRegion: "polite", className: "px-4 py-2 text-xs text-muted-foreground", children: notice.line }),
|
|
5181
|
+
oneDetail ? null : /* @__PURE__ */ jsx99(Text42, { className: "px-4 pb-2 text-xs text-muted-foreground", children: notice.detail })
|
|
4776
5182
|
] }) : null,
|
|
4777
|
-
/* @__PURE__ */
|
|
4778
|
-
doing ? /* @__PURE__ */
|
|
4779
|
-
refused ? /* @__PURE__ */
|
|
4780
|
-
oneDetail && notice ? /* @__PURE__ */
|
|
5183
|
+
/* @__PURE__ */ jsx99(Text42, { accessibilityLabel: spoken, accessibilityLiveRegion: "polite", className: "px-4 py-2 text-xs text-muted-foreground", children: spoken }),
|
|
5184
|
+
doing ? /* @__PURE__ */ jsx99(Text42, { className: "px-4 pb-2 text-xs text-muted-foreground", children: doing }) : null,
|
|
5185
|
+
refused ? /* @__PURE__ */ jsx99(Text42, { className: "px-4 pb-2 text-xs text-muted-foreground", children: REFUSED_DETAIL }) : null,
|
|
5186
|
+
oneDetail && notice ? /* @__PURE__ */ jsx99(Text42, { className: "px-4 pb-2 text-xs text-muted-foreground", children: notice.detail }) : backendMissing ? /* @__PURE__ */ jsx99(Text42, { className: "px-4 pb-2 text-xs text-muted-foreground", children: BACKEND_MISSING_DETAIL.replace("{pluginName}", () => pluginName).replace("{lastTime}", () => upToDate ? " the last time it checked" : "") }) : null
|
|
4781
5187
|
] });
|
|
4782
5188
|
}
|
|
4783
5189
|
|
|
4784
5190
|
// src/sale/orders-list.tsx
|
|
4785
|
-
import { useEffect as useEffect8, useRef as
|
|
4786
|
-
import { Pressable as
|
|
4787
|
-
import { formatMoney as
|
|
5191
|
+
import { useEffect as useEffect8, useRef as useRef8, useState as useState24 } from "react";
|
|
5192
|
+
import { Pressable as Pressable34, ScrollView as ScrollView13, Text as Text43, View as View65 } from "react-native";
|
|
5193
|
+
import { formatMoney as formatMoney17, knownWarnings } from "@tallyui/core";
|
|
4788
5194
|
import { needsAttention } from "@tallyui/pos";
|
|
4789
|
-
import { jsx as
|
|
5195
|
+
import { jsx as jsx100, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
4790
5196
|
var STATUS_LABEL = { pending: "Waiting to sync", applied: "Synced", rejected: "Not accepted" };
|
|
4791
5197
|
var FIGURE_LABELS = /* @__PURE__ */ new Map([["subtotalMinor", "Subtotal"], ["taxMinor", "Tax"], ["discountMinor", "Discount"]]);
|
|
4792
5198
|
var REFUSAL_SENTENCES = /* @__PURE__ */ new Map([
|
|
@@ -4809,27 +5215,27 @@ function defaultFormatDate2(iso) {
|
|
|
4809
5215
|
return Number.isNaN(date.getTime()) ? iso : new Intl.DateTimeFormat(void 0, { dateStyle: "medium", timeStyle: "short" }).format(date);
|
|
4810
5216
|
}
|
|
4811
5217
|
function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer, stuck }) {
|
|
4812
|
-
const retrying =
|
|
4813
|
-
const [retryingIds, setRetryingIds] =
|
|
4814
|
-
const [expanded, setExpanded] =
|
|
5218
|
+
const retrying = useRef8(/* @__PURE__ */ new Set());
|
|
5219
|
+
const [retryingIds, setRetryingIds] = useState24(/* @__PURE__ */ new Set());
|
|
5220
|
+
const [expanded, setExpanded] = useState24(/* @__PURE__ */ new Set());
|
|
4815
5221
|
useEffect8(() => {
|
|
4816
5222
|
for (const id of retrying.current) {
|
|
4817
5223
|
if (!orders.some((order) => order.id === id && order.syncStatus === "rejected")) retrying.current.delete(id);
|
|
4818
5224
|
}
|
|
4819
5225
|
setRetryingIds(new Set(retrying.current));
|
|
4820
5226
|
}, [orders]);
|
|
4821
|
-
return /* @__PURE__ */
|
|
4822
|
-
[{ title: "Needs attention", orders: needsAttention(orders, { stuckCommandIds: stuck?.commandIds }) }, { title: "Recent", orders }].filter((section) => section.title === "Recent" || section.orders.length > 0).map((section) => /* @__PURE__ */
|
|
4823
|
-
/* @__PURE__ */
|
|
4824
|
-
section.title === "Recent" && orders.length === 0 ? /* @__PURE__ */
|
|
5227
|
+
return /* @__PURE__ */ jsxs58(ScrollView13, { className: "flex-1 bg-background p-4", children: [
|
|
5228
|
+
[{ title: "Needs attention", orders: needsAttention(orders, { stuckCommandIds: stuck?.commandIds }) }, { title: "Recent", orders }].filter((section) => section.title === "Recent" || section.orders.length > 0).map((section) => /* @__PURE__ */ jsxs58(View65, { className: "mb-6 gap-3", children: [
|
|
5229
|
+
/* @__PURE__ */ jsx100(Text43, { accessibilityRole: "header", className: "text-xl font-semibold text-foreground", children: section.title }),
|
|
5230
|
+
section.title === "Recent" && orders.length === 0 ? /* @__PURE__ */ jsx100(Text43, { testID: "orders-empty", className: "text-muted-foreground", children: "No sales yet. Completed sales appear here." }) : null,
|
|
4825
5231
|
section.orders.map((order) => {
|
|
4826
5232
|
const count2 = order.lines.reduce((sum, line) => sum + line.quantity, 0);
|
|
4827
5233
|
const key = `${section.title}:${order.id}`;
|
|
4828
5234
|
const isExpanded = expanded.has(key);
|
|
4829
5235
|
const stuckEntry = order.syncStatus === "pending" ? stuck?.orders.find((entry) => entry.commandId === order.commandId) : void 0;
|
|
4830
|
-
return /* @__PURE__ */
|
|
4831
|
-
/* @__PURE__ */
|
|
4832
|
-
|
|
5236
|
+
return /* @__PURE__ */ jsxs58(View65, { className: "gap-1 rounded-md border border-border bg-card p-3", children: [
|
|
5237
|
+
/* @__PURE__ */ jsxs58(
|
|
5238
|
+
Pressable34,
|
|
4833
5239
|
{
|
|
4834
5240
|
accessibilityRole: "button",
|
|
4835
5241
|
"aria-expanded": isExpanded,
|
|
@@ -4843,26 +5249,26 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
|
|
|
4843
5249
|
return next;
|
|
4844
5250
|
}),
|
|
4845
5251
|
children: [
|
|
4846
|
-
/* @__PURE__ */
|
|
4847
|
-
/* @__PURE__ */
|
|
5252
|
+
/* @__PURE__ */ jsx100(Text43, { className: "text-foreground", children: `Order ${orderReference(order)} \xB7 ${count2} ${count2 === 1 ? "item" : "items"}` }),
|
|
5253
|
+
/* @__PURE__ */ jsxs58(Text43, { className: "text-muted-foreground", children: [
|
|
4848
5254
|
formatDate(order.createdAt),
|
|
4849
5255
|
" \xB7 ",
|
|
4850
|
-
|
|
5256
|
+
formatMoney17({ amount: order.totalMinor, currency: order.currency }),
|
|
4851
5257
|
" \xB7 ",
|
|
4852
5258
|
STATUS_LABEL[order.syncStatus]
|
|
4853
5259
|
] })
|
|
4854
5260
|
]
|
|
4855
5261
|
}
|
|
4856
5262
|
),
|
|
4857
|
-
isExpanded ? /* @__PURE__ */
|
|
4858
|
-
order.lines.map((line) => /* @__PURE__ */
|
|
4859
|
-
order.payments.map((payment) => /* @__PURE__ */
|
|
5263
|
+
isExpanded ? /* @__PURE__ */ jsxs58(View65, { testID: `order-detail-${order.id}`, className: "mt-1 gap-1 border-t border-border pt-2", children: [
|
|
5264
|
+
order.lines.map((line) => /* @__PURE__ */ jsx100(Text43, { className: "text-foreground", children: `${line.quantity} \xD7 ${line.name}` }, line.id)),
|
|
5265
|
+
order.payments.map((payment) => /* @__PURE__ */ jsx100(Text43, { className: "text-muted-foreground", children: `${payment.method === "cash" ? "Cash" : "Card terminal"} ${formatMoney17({ amount: payment.amountMinor, currency: order.currency })}${payment.reference ? ` \xB7 ${payment.reference}` : ""}` }, payment.id))
|
|
4860
5266
|
] }) : null,
|
|
4861
|
-
stuckEntry ? /* @__PURE__ */
|
|
4862
|
-
order.syncStatus === "rejected" ? /* @__PURE__ */
|
|
4863
|
-
order.lateSessionId !== void 0 ? /* @__PURE__ */
|
|
4864
|
-
order.localWarnings?.map((warning, index) => /* @__PURE__ */
|
|
4865
|
-
section.title === "Needs attention" && order.syncStatus === "rejected" && order.error?.code !== "idempotency_mismatch" ? /* @__PURE__ */
|
|
5267
|
+
stuckEntry ? /* @__PURE__ */ jsx100(Text43, { className: "text-destructive", children: `Hasn't reached the online store since ${sinceText(stuckEntry)}.` }) : null,
|
|
5268
|
+
order.syncStatus === "rejected" ? /* @__PURE__ */ jsx100(Text43, { className: "text-destructive", children: refusalSentence(order.error?.code) }) : null,
|
|
5269
|
+
order.lateSessionId !== void 0 ? /* @__PURE__ */ jsx100(Text43, { className: "text-foreground", children: "Taken after the register closed. It is not in that register's closure." }) : null,
|
|
5270
|
+
order.localWarnings?.map((warning, index) => /* @__PURE__ */ jsx100(Text43, { 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)),
|
|
5271
|
+
section.title === "Needs attention" && order.syncStatus === "rejected" && order.error?.code !== "idempotency_mismatch" ? /* @__PURE__ */ jsx100(Pressable34, { accessibilityRole: "button", disabled: retryingIds.has(order.id), onPress: async () => {
|
|
4866
5272
|
if (retrying.current.has(order.id)) return;
|
|
4867
5273
|
retrying.current.add(order.id);
|
|
4868
5274
|
setRetryingIds(new Set(retrying.current));
|
|
@@ -4870,8 +5276,8 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
|
|
|
4870
5276
|
retrying.current.delete(order.id);
|
|
4871
5277
|
setRetryingIds(new Set(retrying.current));
|
|
4872
5278
|
}
|
|
4873
|
-
}, className: "rounded-md bg-primary px-4 py-2", children: /* @__PURE__ */
|
|
4874
|
-
knownWarnings(order.warnings).map((warning, index) => /* @__PURE__ */
|
|
5279
|
+
}, className: "rounded-md bg-primary px-4 py-2", children: /* @__PURE__ */ jsx100(Text43, { className: "text-center font-semibold text-primary-foreground", children: "Retry" }) }) : null,
|
|
5280
|
+
knownWarnings(order.warnings).map((warning, index) => /* @__PURE__ */ jsx100(View65, { className: "border-l-4 border-warning pl-2", children: /* @__PURE__ */ jsx100(Text43, { className: "text-foreground", children: warning.code === "insufficient_stock" ? `Stock short by ${warning.quantity} for ${order.lines.find((line) => line.variantId === warning.variantId)?.name}` : warning.code === "tax_rate_mismatch" ? `Tax at ${(warning.ratePpm / 1e4).toLocaleString(void 0, { maximumFractionDigits: 4 })}%: store ${formatMoney17({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney17({ amount: warning.expectedMinor, currency: order.currency })}` : warning.code === "customer_ignored" ? `The online store didn't recognise the customer on this sale, so it was saved as a guest sale. Customer id: ${warning.customerId}.` : warning.code === "figures_mismatch" ? `The online store worked out different figures for this sale. ${warning.fields.map(({ field, tillMinor, serverMinor }) => `${FIGURE_LABELS.get(field) ?? field}: till ${formatMoney17({ amount: tillMinor, currency: order.currency })}, store ${formatMoney17({ amount: serverMinor, currency: order.currency })}.`).join(" ")}` : warning.bridgeMinor !== void 0 ? `Store calculated ${formatMoney17({ amount: warning.serverMinor, currency: order.currency })}; a rounding line of ${warning.bridgeMinor > 0 ? "+" : ""}${formatMoney17({ amount: warning.bridgeMinor, currency: order.currency })} brought it to ${formatMoney17({ amount: warning.expectedMinor, currency: order.currency })}` : `Store total ${formatMoney17({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney17({ amount: warning.expectedMinor, currency: order.currency })}` }) }, index))
|
|
4875
5281
|
] }, order.id);
|
|
4876
5282
|
})
|
|
4877
5283
|
] }, section.title)),
|
|
@@ -4880,15 +5286,15 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
|
|
|
4880
5286
|
}
|
|
4881
5287
|
|
|
4882
5288
|
// src/sale/parked-sales.tsx
|
|
4883
|
-
import { useState as
|
|
4884
|
-
import { ScrollView as ScrollView14, useWindowDimensions as useWindowDimensions3, View as
|
|
4885
|
-
import { formatMoney as
|
|
4886
|
-
import { Fragment as
|
|
5289
|
+
import { useState as useState25 } from "react";
|
|
5290
|
+
import { ScrollView as ScrollView14, useWindowDimensions as useWindowDimensions3, View as View66 } from "react-native";
|
|
5291
|
+
import { formatMoney as formatMoney18 } from "@tallyui/core";
|
|
5292
|
+
import { Fragment as Fragment11, jsx as jsx101, jsxs as jsxs59 } from "react/jsx-runtime";
|
|
4887
5293
|
function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open, onOpenChange, hour12 }) {
|
|
4888
5294
|
const { height: windowHeight } = useWindowDimensions3();
|
|
4889
5295
|
const maxHeight = Math.max(280, windowHeight - 64);
|
|
4890
|
-
const [confirming, setConfirming] =
|
|
4891
|
-
const [error, setError] =
|
|
5296
|
+
const [confirming, setConfirming] = useState25(null);
|
|
5297
|
+
const [error, setError] = useState25("");
|
|
4892
5298
|
const attempt = async (action) => {
|
|
4893
5299
|
setError("");
|
|
4894
5300
|
try {
|
|
@@ -4897,28 +5303,28 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
|
|
|
4897
5303
|
setError(String(e));
|
|
4898
5304
|
}
|
|
4899
5305
|
};
|
|
4900
|
-
return /* @__PURE__ */
|
|
4901
|
-
/* @__PURE__ */
|
|
4902
|
-
/* @__PURE__ */
|
|
4903
|
-
/* @__PURE__ */
|
|
5306
|
+
return /* @__PURE__ */ jsx101(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs59(DialogContent, { testID: "parked-sales", className: "flex-col overflow-hidden", style: { maxHeight }, children: [
|
|
5307
|
+
/* @__PURE__ */ jsxs59(View66, { className: "flex-row items-center justify-between gap-2", children: [
|
|
5308
|
+
/* @__PURE__ */ jsx101(DialogTitle, { children: "Parked sales" }),
|
|
5309
|
+
/* @__PURE__ */ jsx101(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx101(IconButton, { variant: "ghost", size: "sm", testID: "parked-sales-dismiss", accessibilityLabel: "Close panel", children: /* @__PURE__ */ jsx101(XIcon, { size: 16 }) }) })
|
|
4904
5310
|
] }),
|
|
4905
|
-
/* @__PURE__ */
|
|
4906
|
-
/* @__PURE__ */
|
|
5311
|
+
/* @__PURE__ */ jsxs59(ScrollView14, { className: "flex-1", contentContainerClassName: "gap-3", children: [
|
|
5312
|
+
/* @__PURE__ */ jsx101(
|
|
4907
5313
|
Button,
|
|
4908
5314
|
{
|
|
4909
5315
|
testID: "parked-sales-park",
|
|
4910
5316
|
accessibilityLabel: "Park this sale",
|
|
4911
5317
|
disabled: sale.order.lineItems.length === 0,
|
|
4912
5318
|
onPress: () => attempt(async () => setError(await (onPark ?? sale.park)() ?? "")),
|
|
4913
|
-
children: /* @__PURE__ */
|
|
5319
|
+
children: /* @__PURE__ */ jsx101(Text, { children: "Park this sale" })
|
|
4914
5320
|
}
|
|
4915
5321
|
),
|
|
4916
|
-
!!error && /* @__PURE__ */
|
|
4917
|
-
parked.length === 0 && /* @__PURE__ */
|
|
4918
|
-
parked.map((row) => /* @__PURE__ */
|
|
4919
|
-
/* @__PURE__ */
|
|
4920
|
-
/* @__PURE__ */
|
|
4921
|
-
/* @__PURE__ */
|
|
5322
|
+
!!error && /* @__PURE__ */ jsx101(Text, { testID: "parked-sales-error", className: "text-destructive", children: error }),
|
|
5323
|
+
parked.length === 0 && /* @__PURE__ */ jsx101(Text, { testID: "parked-sales-empty", children: "No parked sales." }),
|
|
5324
|
+
parked.map((row) => /* @__PURE__ */ jsx101(View66, { testID: `parked-row-${row.id}`, className: "gap-2 rounded-md border border-border p-3", children: confirming === row.id ? /* @__PURE__ */ jsxs59(Fragment11, { children: [
|
|
5325
|
+
/* @__PURE__ */ jsx101(Text, { children: "Discard this parked sale?" }),
|
|
5326
|
+
/* @__PURE__ */ jsxs59(View66, { className: "flex-row gap-2", children: [
|
|
5327
|
+
/* @__PURE__ */ jsx101(
|
|
4922
5328
|
Button,
|
|
4923
5329
|
{
|
|
4924
5330
|
testID: `parked-discard-confirm-${row.id}`,
|
|
@@ -4927,22 +5333,22 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
|
|
|
4927
5333
|
await onDiscard(row.id);
|
|
4928
5334
|
setConfirming(null);
|
|
4929
5335
|
}),
|
|
4930
|
-
children: /* @__PURE__ */
|
|
5336
|
+
children: /* @__PURE__ */ jsx101(Text, { children: "Discard" })
|
|
4931
5337
|
}
|
|
4932
5338
|
),
|
|
4933
|
-
/* @__PURE__ */
|
|
5339
|
+
/* @__PURE__ */ jsx101(Button, { testID: `parked-discard-cancel-${row.id}`, variant: "outline", onPress: () => setConfirming(null), children: /* @__PURE__ */ jsx101(Text, { children: "Cancel" }) })
|
|
4934
5340
|
] })
|
|
4935
|
-
] }) : /* @__PURE__ */
|
|
4936
|
-
/* @__PURE__ */
|
|
4937
|
-
/* @__PURE__ */
|
|
5341
|
+
] }) : /* @__PURE__ */ jsxs59(Fragment11, { children: [
|
|
5342
|
+
/* @__PURE__ */ jsx101(Text, { children: formatStockSyncTime(new Date(row.parkedAt), void 0, hour12) }),
|
|
5343
|
+
/* @__PURE__ */ jsxs59(Text, { children: [
|
|
4938
5344
|
row.itemCount,
|
|
4939
5345
|
" ",
|
|
4940
5346
|
row.itemCount === 1 ? "item" : "items"
|
|
4941
5347
|
] }),
|
|
4942
|
-
/* @__PURE__ */
|
|
4943
|
-
!!row.customerName && /* @__PURE__ */
|
|
4944
|
-
/* @__PURE__ */
|
|
4945
|
-
/* @__PURE__ */
|
|
5348
|
+
/* @__PURE__ */ jsx101(Text, { children: formatMoney18({ amount: row.totalMinor, currency }) }),
|
|
5349
|
+
!!row.customerName && /* @__PURE__ */ jsx101(Text, { children: row.customerName }),
|
|
5350
|
+
/* @__PURE__ */ jsxs59(View66, { className: "flex-row gap-2", children: [
|
|
5351
|
+
/* @__PURE__ */ jsx101(
|
|
4946
5352
|
Button,
|
|
4947
5353
|
{
|
|
4948
5354
|
testID: `parked-resume-${row.id}`,
|
|
@@ -4952,17 +5358,17 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
|
|
|
4952
5358
|
if (refusal === null) onOpenChange(false);
|
|
4953
5359
|
else setError(refusal);
|
|
4954
5360
|
}),
|
|
4955
|
-
children: /* @__PURE__ */
|
|
5361
|
+
children: /* @__PURE__ */ jsx101(Text, { children: "Resume" })
|
|
4956
5362
|
}
|
|
4957
5363
|
),
|
|
4958
|
-
/* @__PURE__ */
|
|
5364
|
+
/* @__PURE__ */ jsx101(
|
|
4959
5365
|
Button,
|
|
4960
5366
|
{
|
|
4961
5367
|
testID: `parked-discard-${row.id}`,
|
|
4962
5368
|
accessibilityLabel: "Discard parked sale",
|
|
4963
5369
|
variant: "outline",
|
|
4964
5370
|
onPress: () => setConfirming(row.id),
|
|
4965
|
-
children: /* @__PURE__ */
|
|
5371
|
+
children: /* @__PURE__ */ jsx101(Text, { children: "Discard" })
|
|
4966
5372
|
}
|
|
4967
5373
|
)
|
|
4968
5374
|
] })
|
|
@@ -4972,10 +5378,10 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
|
|
|
4972
5378
|
}
|
|
4973
5379
|
|
|
4974
5380
|
// src/layout/pos-layout.tsx
|
|
4975
|
-
import { useState as
|
|
4976
|
-
import { Pressable as
|
|
4977
|
-
import { cn as
|
|
4978
|
-
import { Fragment as
|
|
5381
|
+
import { useState as useState26 } from "react";
|
|
5382
|
+
import { Pressable as Pressable35, Text as Text44, View as View67, useWindowDimensions as useWindowDimensions4 } from "react-native";
|
|
5383
|
+
import { cn as cn82 } from "@tallyui/theme";
|
|
5384
|
+
import { Fragment as Fragment12, jsx as jsx102, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
4979
5385
|
function POSLayout({
|
|
4980
5386
|
browseSlot,
|
|
4981
5387
|
cartSlot,
|
|
@@ -4987,40 +5393,40 @@ function POSLayout({
|
|
|
4987
5393
|
}) {
|
|
4988
5394
|
const { width } = useWindowDimensions4();
|
|
4989
5395
|
const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
|
|
4990
|
-
const [activeTab, setActiveTab] =
|
|
4991
|
-
return /* @__PURE__ */
|
|
4992
|
-
headerSlot && /* @__PURE__ */
|
|
4993
|
-
layout === "split" ? /* @__PURE__ */
|
|
4994
|
-
/* @__PURE__ */
|
|
4995
|
-
/* @__PURE__ */
|
|
4996
|
-
] }) : /* @__PURE__ */
|
|
4997
|
-
/* @__PURE__ */
|
|
4998
|
-
/* @__PURE__ */
|
|
4999
|
-
|
|
5396
|
+
const [activeTab, setActiveTab] = useState26("browse");
|
|
5397
|
+
return /* @__PURE__ */ jsxs60(View67, { className: cn82("flex-1 bg-bg", className), ...viewProps, children: [
|
|
5398
|
+
headerSlot && /* @__PURE__ */ jsx102(View67, { className: "border-b border-border", children: headerSlot }),
|
|
5399
|
+
layout === "split" ? /* @__PURE__ */ jsxs60(View67, { className: "flex-1 flex-row", children: [
|
|
5400
|
+
/* @__PURE__ */ jsx102(View67, { className: "flex-[3]", children: browseSlot }),
|
|
5401
|
+
/* @__PURE__ */ jsx102(View67, { className: "flex-[2] border-l border-border", children: cartSlot })
|
|
5402
|
+
] }) : /* @__PURE__ */ jsxs60(Fragment12, { children: [
|
|
5403
|
+
/* @__PURE__ */ jsxs60(View67, { className: "flex-row border-b border-border", children: [
|
|
5404
|
+
/* @__PURE__ */ jsx102(
|
|
5405
|
+
Pressable35,
|
|
5000
5406
|
{
|
|
5001
5407
|
onPress: () => setActiveTab("browse"),
|
|
5002
|
-
className:
|
|
5003
|
-
children: /* @__PURE__ */
|
|
5408
|
+
className: cn82("flex-1 py-3", activeTab === "browse" && "border-b-2 border-primary"),
|
|
5409
|
+
children: /* @__PURE__ */ jsx102(Text44, { className: cn82("text-center text-sm font-semibold", activeTab === "browse" ? "text-primary" : "text-muted-foreground"), children: "Browse" })
|
|
5004
5410
|
}
|
|
5005
5411
|
),
|
|
5006
|
-
/* @__PURE__ */
|
|
5007
|
-
|
|
5412
|
+
/* @__PURE__ */ jsx102(
|
|
5413
|
+
Pressable35,
|
|
5008
5414
|
{
|
|
5009
5415
|
onPress: () => setActiveTab("cart"),
|
|
5010
|
-
className:
|
|
5011
|
-
children: /* @__PURE__ */
|
|
5416
|
+
className: cn82("flex-1 py-3", activeTab === "cart" && "border-b-2 border-primary"),
|
|
5417
|
+
children: /* @__PURE__ */ jsx102(Text44, { className: cn82("text-center text-sm font-semibold", activeTab === "cart" ? "text-primary" : "text-muted-foreground"), children: "Cart" })
|
|
5012
5418
|
}
|
|
5013
5419
|
)
|
|
5014
5420
|
] }),
|
|
5015
|
-
/* @__PURE__ */
|
|
5421
|
+
/* @__PURE__ */ jsx102(View67, { className: "flex-1", children: activeTab === "browse" ? browseSlot : cartSlot })
|
|
5016
5422
|
] })
|
|
5017
5423
|
] });
|
|
5018
5424
|
}
|
|
5019
5425
|
|
|
5020
5426
|
// src/layout/checkout-layout.tsx
|
|
5021
|
-
import { ScrollView as ScrollView15, View as
|
|
5022
|
-
import { cn as
|
|
5023
|
-
import { jsx as
|
|
5427
|
+
import { ScrollView as ScrollView15, View as View68, useWindowDimensions as useWindowDimensions5 } from "react-native";
|
|
5428
|
+
import { cn as cn83 } from "@tallyui/theme";
|
|
5429
|
+
import { jsx as jsx103, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
5024
5430
|
function CheckoutLayout({
|
|
5025
5431
|
summarySlot,
|
|
5026
5432
|
paymentSlot,
|
|
@@ -5032,12 +5438,12 @@ function CheckoutLayout({
|
|
|
5032
5438
|
}) {
|
|
5033
5439
|
const { width } = useWindowDimensions5();
|
|
5034
5440
|
const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
|
|
5035
|
-
return /* @__PURE__ */
|
|
5036
|
-
headerSlot && /* @__PURE__ */
|
|
5037
|
-
layout === "split" ? /* @__PURE__ */
|
|
5038
|
-
/* @__PURE__ */
|
|
5039
|
-
/* @__PURE__ */
|
|
5040
|
-
] }) : /* @__PURE__ */
|
|
5441
|
+
return /* @__PURE__ */ jsxs61(View68, { className: cn83("flex-1 bg-bg", className), ...viewProps, children: [
|
|
5442
|
+
headerSlot && /* @__PURE__ */ jsx103(View68, { className: "border-b border-border", children: headerSlot }),
|
|
5443
|
+
layout === "split" ? /* @__PURE__ */ jsxs61(View68, { className: "flex-1 flex-row", children: [
|
|
5444
|
+
/* @__PURE__ */ jsx103(View68, { className: "flex-1 border-r border-border", children: summarySlot }),
|
|
5445
|
+
/* @__PURE__ */ jsx103(View68, { className: "flex-1", children: paymentSlot })
|
|
5446
|
+
] }) : /* @__PURE__ */ jsx103(ScrollView15, { className: "flex-1", children: /* @__PURE__ */ jsxs61(View68, { className: "gap-4 p-4", children: [
|
|
5041
5447
|
summarySlot,
|
|
5042
5448
|
paymentSlot
|
|
5043
5449
|
] }) })
|
|
@@ -5045,10 +5451,10 @@ function CheckoutLayout({
|
|
|
5045
5451
|
}
|
|
5046
5452
|
|
|
5047
5453
|
// src/layout/settings-layout.tsx
|
|
5048
|
-
import { useState as
|
|
5049
|
-
import { Pressable as
|
|
5050
|
-
import { cn as
|
|
5051
|
-
import { jsx as
|
|
5454
|
+
import { useState as useState27 } from "react";
|
|
5455
|
+
import { Pressable as Pressable36, Text as Text45, View as View69, useWindowDimensions as useWindowDimensions6 } from "react-native";
|
|
5456
|
+
import { cn as cn84 } from "@tallyui/theme";
|
|
5457
|
+
import { jsx as jsx104, jsxs as jsxs62 } from "react/jsx-runtime";
|
|
5052
5458
|
function SettingsLayout({
|
|
5053
5459
|
navSlot,
|
|
5054
5460
|
contentSlot,
|
|
@@ -5060,26 +5466,26 @@ function SettingsLayout({
|
|
|
5060
5466
|
}) {
|
|
5061
5467
|
const { width } = useWindowDimensions6();
|
|
5062
5468
|
const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
|
|
5063
|
-
const [showNav, setShowNav] =
|
|
5064
|
-
return /* @__PURE__ */
|
|
5065
|
-
headerSlot && /* @__PURE__ */
|
|
5066
|
-
layout === "split" ? /* @__PURE__ */
|
|
5067
|
-
/* @__PURE__ */
|
|
5068
|
-
/* @__PURE__ */
|
|
5069
|
-
] }) : /* @__PURE__ */
|
|
5469
|
+
const [showNav, setShowNav] = useState27(false);
|
|
5470
|
+
return /* @__PURE__ */ jsxs62(View69, { className: cn84("flex-1 bg-bg", className), ...viewProps, children: [
|
|
5471
|
+
headerSlot && /* @__PURE__ */ jsx104(View69, { className: "border-b border-border", children: headerSlot }),
|
|
5472
|
+
layout === "split" ? /* @__PURE__ */ jsxs62(View69, { className: "flex-1 flex-row", children: [
|
|
5473
|
+
/* @__PURE__ */ jsx104(View69, { className: "w-64 border-r border-border", children: navSlot }),
|
|
5474
|
+
/* @__PURE__ */ jsx104(View69, { className: "flex-1", children: contentSlot })
|
|
5475
|
+
] }) : /* @__PURE__ */ jsx104(View69, { className: "flex-1", children: showNav ? /* @__PURE__ */ jsxs62(View69, { className: "flex-1", children: [
|
|
5070
5476
|
navSlot,
|
|
5071
|
-
/* @__PURE__ */
|
|
5072
|
-
] }) : /* @__PURE__ */
|
|
5073
|
-
/* @__PURE__ */
|
|
5477
|
+
/* @__PURE__ */ jsx104(Pressable36, { onPress: () => setShowNav(false), className: "border-t border-border p-3", children: /* @__PURE__ */ jsx104(Text45, { className: "text-center text-sm font-medium text-primary", children: "Done" }) })
|
|
5478
|
+
] }) : /* @__PURE__ */ jsxs62(View69, { className: "flex-1", children: [
|
|
5479
|
+
/* @__PURE__ */ jsx104(Pressable36, { onPress: () => setShowNav(true), className: "border-b border-border px-4 py-2", children: /* @__PURE__ */ jsx104(Text45, { className: "text-sm font-medium text-primary", children: "Menu" }) }),
|
|
5074
5480
|
contentSlot
|
|
5075
5481
|
] }) })
|
|
5076
5482
|
] });
|
|
5077
5483
|
}
|
|
5078
5484
|
|
|
5079
5485
|
// src/layout/live-tab-screen.tsx
|
|
5080
|
-
import { Pressable as
|
|
5081
|
-
import { cn as
|
|
5082
|
-
import { jsx as
|
|
5486
|
+
import { Pressable as Pressable37, Text as Text46, View as View70 } from "react-native";
|
|
5487
|
+
import { cn as cn85 } from "@tallyui/theme";
|
|
5488
|
+
import { jsx as jsx105, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
5083
5489
|
function LiveTabScreen({
|
|
5084
5490
|
state,
|
|
5085
5491
|
onUseHere,
|
|
@@ -5096,21 +5502,21 @@ function LiveTabScreen({
|
|
|
5096
5502
|
const body = state === "parked" ? parkedBody : blockedBody;
|
|
5097
5503
|
const buttonLabel = state === "parked" ? useHereLabel : reloadLabel;
|
|
5098
5504
|
const onPress = state === "parked" ? onUseHere : onReload;
|
|
5099
|
-
return /* @__PURE__ */
|
|
5100
|
-
/* @__PURE__ */
|
|
5101
|
-
/* @__PURE__ */
|
|
5102
|
-
/* @__PURE__ */
|
|
5505
|
+
return /* @__PURE__ */ jsxs63(View70, { className: cn85("flex-1 items-center justify-center gap-4 bg-bg p-6", className), ...viewProps, children: [
|
|
5506
|
+
/* @__PURE__ */ jsx105(Text46, { className: "text-center text-lg font-bold text-foreground", children: parkedTitle }),
|
|
5507
|
+
/* @__PURE__ */ jsx105(Text46, { className: "text-center text-sm text-muted-foreground", children: body }),
|
|
5508
|
+
/* @__PURE__ */ jsx105(Pressable37, { onPress, className: "items-center rounded-lg bg-primary px-4 py-3", children: /* @__PURE__ */ jsx105(Text46, { className: "text-sm font-semibold text-primary-foreground", children: buttonLabel }) })
|
|
5103
5509
|
] });
|
|
5104
5510
|
}
|
|
5105
5511
|
|
|
5106
5512
|
// src/layout/store-settings-choice-screen.tsx
|
|
5107
|
-
import { useState as
|
|
5108
|
-
import { Pressable as
|
|
5109
|
-
import { cn as
|
|
5110
|
-
import { jsx as
|
|
5513
|
+
import { useState as useState28 } from "react";
|
|
5514
|
+
import { Pressable as Pressable38, Text as Text47, View as View71 } from "react-native";
|
|
5515
|
+
import { cn as cn86 } from "@tallyui/theme";
|
|
5516
|
+
import { jsx as jsx106, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
5111
5517
|
function useSectionSelection(options, initialValue) {
|
|
5112
5518
|
const preset = options.length === 1 ? options[0].value : options.find((o) => o.value === initialValue)?.value;
|
|
5113
|
-
return
|
|
5519
|
+
return useState28(preset);
|
|
5114
5520
|
}
|
|
5115
5521
|
function defaultCountryName(code, locale) {
|
|
5116
5522
|
try {
|
|
@@ -5156,41 +5562,41 @@ function StoreSettingsChoiceScreen({
|
|
|
5156
5562
|
else if (initial?.channel !== void 0) choice.channel = initial.channel;
|
|
5157
5563
|
onSubmit(choice);
|
|
5158
5564
|
};
|
|
5159
|
-
return /* @__PURE__ */
|
|
5160
|
-
/* @__PURE__ */
|
|
5161
|
-
/* @__PURE__ */
|
|
5162
|
-
/* @__PURE__ */
|
|
5565
|
+
return /* @__PURE__ */ jsxs64(View71, { className: cn86("w-full max-w-[560px] flex-1 self-center gap-6 bg-bg p-6", className), ...viewProps, children: [
|
|
5566
|
+
/* @__PURE__ */ jsxs64(View71, { className: "gap-2", children: [
|
|
5567
|
+
/* @__PURE__ */ jsx106(Text47, { className: "text-lg font-bold text-foreground", children: title }),
|
|
5568
|
+
/* @__PURE__ */ jsx106(Text47, { className: "text-sm text-muted-foreground", children: body })
|
|
5163
5569
|
] }),
|
|
5164
|
-
showRegions && /* @__PURE__ */
|
|
5165
|
-
showCountries && /* @__PURE__ */
|
|
5166
|
-
showChannels && /* @__PURE__ */
|
|
5167
|
-
/* @__PURE__ */
|
|
5168
|
-
|
|
5570
|
+
showRegions && /* @__PURE__ */ jsx106(ChoiceSection, { label: regionLabel, options: regionOptions, selected: region, onSelect: setRegion }),
|
|
5571
|
+
showCountries && /* @__PURE__ */ jsx106(ChoiceSection, { label: countryLabel, options: countryOptions, selected: country, onSelect: setCountry }),
|
|
5572
|
+
showChannels && /* @__PURE__ */ jsx106(ChoiceSection, { label: channelLabel, options: channelOptions, selected: channel, onSelect: setChannel }),
|
|
5573
|
+
/* @__PURE__ */ jsx106(
|
|
5574
|
+
Pressable38,
|
|
5169
5575
|
{
|
|
5170
5576
|
onPress: handleSubmit,
|
|
5171
5577
|
disabled: !complete,
|
|
5172
|
-
className:
|
|
5173
|
-
children: /* @__PURE__ */
|
|
5578
|
+
className: cn86("items-center rounded-lg bg-primary px-4 py-3", !complete && "opacity-50"),
|
|
5579
|
+
children: /* @__PURE__ */ jsx106(Text47, { className: "text-sm font-semibold text-primary-foreground", children: submitLabel })
|
|
5174
5580
|
}
|
|
5175
5581
|
)
|
|
5176
5582
|
] });
|
|
5177
5583
|
}
|
|
5178
5584
|
function ChoiceSection({ label, options, selected, onSelect }) {
|
|
5179
|
-
return /* @__PURE__ */
|
|
5180
|
-
/* @__PURE__ */
|
|
5181
|
-
/* @__PURE__ */
|
|
5585
|
+
return /* @__PURE__ */ jsxs64(View71, { className: "gap-1.5", children: [
|
|
5586
|
+
/* @__PURE__ */ jsx106(Text47, { className: "text-xs font-semibold text-muted-foreground", children: label }),
|
|
5587
|
+
/* @__PURE__ */ jsx106(View71, { className: "rounded-lg border border-border", children: options.map((option, index) => {
|
|
5182
5588
|
const checked = option.value === selected;
|
|
5183
|
-
return /* @__PURE__ */
|
|
5184
|
-
|
|
5589
|
+
return /* @__PURE__ */ jsxs64(
|
|
5590
|
+
Pressable38,
|
|
5185
5591
|
{
|
|
5186
5592
|
onPress: () => onSelect(option.value),
|
|
5187
5593
|
accessibilityRole: "radio",
|
|
5188
5594
|
"aria-checked": checked,
|
|
5189
5595
|
testID: `choice-option-${option.value}`,
|
|
5190
|
-
className:
|
|
5596
|
+
className: cn86("flex-row items-center gap-3 px-4 py-3", index > 0 && "border-t border-border", checked && "bg-primary/10"),
|
|
5191
5597
|
children: [
|
|
5192
|
-
/* @__PURE__ */
|
|
5193
|
-
/* @__PURE__ */
|
|
5598
|
+
/* @__PURE__ */ jsx106(View71, { className: "h-4 w-4 items-center justify-center rounded-full border border-primary", children: checked && /* @__PURE__ */ jsx106(View71, { testID: `choice-option-${option.value}-dot`, className: "h-2.5 w-2.5 rounded-full bg-primary" }) }),
|
|
5599
|
+
/* @__PURE__ */ jsx106(Text47, { className: cn86("text-sm", checked ? "font-semibold text-primary" : "text-foreground"), children: option.label })
|
|
5194
5600
|
]
|
|
5195
5601
|
},
|
|
5196
5602
|
option.value
|
|
@@ -5236,6 +5642,7 @@ export {
|
|
|
5236
5642
|
Catalogue,
|
|
5237
5643
|
CategoryNav,
|
|
5238
5644
|
ChangeDisplay,
|
|
5645
|
+
ChargeForm,
|
|
5239
5646
|
Checkbox,
|
|
5240
5647
|
CheckoutLayout,
|
|
5241
5648
|
ClosureSheet,
|
|
@@ -5334,6 +5741,7 @@ export {
|
|
|
5334
5741
|
ProductPrice,
|
|
5335
5742
|
ProductSku,
|
|
5336
5743
|
ProductStockBadge,
|
|
5744
|
+
ProductTable,
|
|
5337
5745
|
ProductTitle,
|
|
5338
5746
|
ProductVariantPicker,
|
|
5339
5747
|
Progress,
|
|
@@ -5394,6 +5802,7 @@ export {
|
|
|
5394
5802
|
TooltipContent,
|
|
5395
5803
|
TooltipTrigger,
|
|
5396
5804
|
VStack,
|
|
5805
|
+
ViewToggle,
|
|
5397
5806
|
XIcon,
|
|
5398
5807
|
avatarVariants,
|
|
5399
5808
|
badgeTextVariants,
|
|
@@ -5401,6 +5810,7 @@ export {
|
|
|
5401
5810
|
buttonTextVariants,
|
|
5402
5811
|
buttonVariants,
|
|
5403
5812
|
createSvgIcon,
|
|
5813
|
+
defaultProductColumns,
|
|
5404
5814
|
describeRegisterBarPill,
|
|
5405
5815
|
discountLabel,
|
|
5406
5816
|
formatStockSyncTime,
|
|
@@ -5416,6 +5826,7 @@ export {
|
|
|
5416
5826
|
toastVariants,
|
|
5417
5827
|
toggleTextVariants,
|
|
5418
5828
|
toggleVariants,
|
|
5829
|
+
useDefaultProductColumns,
|
|
5419
5830
|
useInputContext,
|
|
5420
5831
|
vstackVariants
|
|
5421
5832
|
};
|