@tallyui/components 3.4.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 +77 -4
- package/dist/index.js +1205 -934
- package/package.json +9 -9
- package/src/index.ts +7 -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/catalogue.tsx +108 -21
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,34 +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";
|
|
3967
4120
|
import { formatMoney as formatMoney12 } from "@tallyui/core";
|
|
3968
4121
|
import { buildReceiptData } from "@tallyui/pos";
|
|
3969
4122
|
|
|
3970
4123
|
// src/sale/discount-form.tsx
|
|
3971
|
-
import { useState as
|
|
3972
|
-
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";
|
|
3973
4126
|
import { formatMoney as formatMoney10, minorUnitDigits as minorUnitDigits7, moneyFromDecimalString as moneyFromDecimalString2 } from "@tallyui/core";
|
|
3974
|
-
import { jsx as
|
|
4127
|
+
import { jsx as jsx90, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
3975
4128
|
function parseDiscount(type, text, currency) {
|
|
3976
4129
|
const raw = text.trim();
|
|
3977
4130
|
const trimmed = raw.split(",").length === 2 ? raw.replace(",", ".") : raw;
|
|
@@ -3988,30 +4141,30 @@ function parseDiscount(type, text, currency) {
|
|
|
3988
4141
|
var discountLabel = (discount, currency) => discount.type === "percentage" ? `${discount.value}%` : formatMoney10({ amount: discount.amountMinor, currency }) ?? String(discount.amountMinor);
|
|
3989
4142
|
var button = "rounded-md border border-border px-3 py-2 min-h-11 items-center justify-center";
|
|
3990
4143
|
function DiscountForm({ title, currency, onApply, onClose }) {
|
|
3991
|
-
const [type, setType] =
|
|
3992
|
-
const [text, setText] =
|
|
3993
|
-
const [error, setError] =
|
|
4144
|
+
const [type, setType] = useState17("percentage");
|
|
4145
|
+
const [text, setText] = useState17("");
|
|
4146
|
+
const [error, setError] = useState17(null);
|
|
3994
4147
|
function apply() {
|
|
3995
4148
|
const parsed = parseDiscount(type, text, currency);
|
|
3996
4149
|
const refused = typeof parsed === "string" ? parsed : onApply(parsed);
|
|
3997
4150
|
setError(refused);
|
|
3998
4151
|
if (refused === null) onClose();
|
|
3999
4152
|
}
|
|
4000
|
-
return /* @__PURE__ */
|
|
4001
|
-
/* @__PURE__ */
|
|
4002
|
-
/* @__PURE__ */
|
|
4003
|
-
["percentage", "fixed"].map((option) => /* @__PURE__ */
|
|
4004
|
-
|
|
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,
|
|
4005
4158
|
{
|
|
4006
4159
|
accessibilityRole: "button",
|
|
4007
4160
|
accessibilityState: { selected: type === option },
|
|
4008
4161
|
onPress: () => setType(option),
|
|
4009
4162
|
className: `${button} ${type === option ? "bg-primary" : "bg-card"}`,
|
|
4010
|
-
children: /* @__PURE__ */
|
|
4163
|
+
children: /* @__PURE__ */ jsx90(Text33, { className: type === option ? "text-primary-foreground" : "text-foreground", children: option === "percentage" ? "Percent" : "Amount" })
|
|
4011
4164
|
},
|
|
4012
4165
|
option
|
|
4013
4166
|
)),
|
|
4014
|
-
/* @__PURE__ */
|
|
4167
|
+
/* @__PURE__ */ jsx90(
|
|
4015
4168
|
TextInput9,
|
|
4016
4169
|
{
|
|
4017
4170
|
accessibilityLabel: "Discount value",
|
|
@@ -4024,16 +4177,16 @@ function DiscountForm({ title, currency, onApply, onClose }) {
|
|
|
4024
4177
|
}
|
|
4025
4178
|
)
|
|
4026
4179
|
] }),
|
|
4027
|
-
error ? /* @__PURE__ */
|
|
4028
|
-
/* @__PURE__ */
|
|
4029
|
-
/* @__PURE__ */
|
|
4030
|
-
/* @__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" }) })
|
|
4031
4184
|
] })
|
|
4032
4185
|
] });
|
|
4033
4186
|
}
|
|
4034
4187
|
function DiscountChips({ discounts, currency, onRemove, prefix, amounts = [] }) {
|
|
4035
4188
|
if (!discounts.length) return null;
|
|
4036
|
-
return /* @__PURE__ */
|
|
4189
|
+
return /* @__PURE__ */ jsx90(View56, { className: "flex-row flex-wrap gap-2 px-3", children: discounts.map((discount) => {
|
|
4037
4190
|
const amount = amounts.find((row) => row.discountId === discount.id)?.amountMinor;
|
|
4038
4191
|
const own = discountLabel(discount, currency);
|
|
4039
4192
|
const label = [
|
|
@@ -4041,16 +4194,16 @@ function DiscountChips({ discounts, currency, onRemove, prefix, amounts = [] })
|
|
|
4041
4194
|
amount === void 0 ? prefix ? `\u2212${own}` : own : discount.type === "percentage" ? own : null,
|
|
4042
4195
|
amount === void 0 ? null : `\u2212${formatMoney10({ amount, currency })}`
|
|
4043
4196
|
].filter(Boolean).join(" ");
|
|
4044
|
-
return /* @__PURE__ */
|
|
4045
|
-
|
|
4197
|
+
return /* @__PURE__ */ jsxs48(
|
|
4198
|
+
Pressable25,
|
|
4046
4199
|
{
|
|
4047
4200
|
accessibilityRole: "button",
|
|
4048
4201
|
accessibilityLabel: `Remove discount ${label}`,
|
|
4049
4202
|
onPress: () => onRemove(discount.id),
|
|
4050
4203
|
className: "min-h-11 flex-row items-center gap-1",
|
|
4051
4204
|
children: [
|
|
4052
|
-
/* @__PURE__ */
|
|
4053
|
-
/* @__PURE__ */
|
|
4205
|
+
/* @__PURE__ */ jsx90(DiscountBadge, { label, className: "self-center" }),
|
|
4206
|
+
/* @__PURE__ */ jsx90(Text33, { className: "text-muted-foreground", children: "\u2715" })
|
|
4054
4207
|
]
|
|
4055
4208
|
},
|
|
4056
4209
|
discount.id
|
|
@@ -4059,10 +4212,10 @@ function DiscountChips({ discounts, currency, onRemove, prefix, amounts = [] })
|
|
|
4059
4212
|
}
|
|
4060
4213
|
|
|
4061
4214
|
// src/sale/price-form.tsx
|
|
4062
|
-
import { useState as
|
|
4063
|
-
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";
|
|
4064
4217
|
import { formatMoney as formatMoney11, minorUnitDigits as minorUnitDigits8, moneyFromDecimalString as moneyFromDecimalString3 } from "@tallyui/core";
|
|
4065
|
-
import { jsx as
|
|
4218
|
+
import { jsx as jsx91, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
4066
4219
|
function parsePrice(text, currency) {
|
|
4067
4220
|
const raw = text.trim();
|
|
4068
4221
|
const trimmed = raw.split(",").length === 2 ? raw.replace(",", ".") : raw;
|
|
@@ -4075,9 +4228,9 @@ function parsePrice(text, currency) {
|
|
|
4075
4228
|
}
|
|
4076
4229
|
var button2 = "rounded-md border border-border px-3 py-2 min-h-11 items-center justify-center";
|
|
4077
4230
|
function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
|
|
4078
|
-
const [text, setText] =
|
|
4079
|
-
const [reason, setReason] =
|
|
4080
|
-
const [error, setError] =
|
|
4231
|
+
const [text, setText] = useState18("");
|
|
4232
|
+
const [reason, setReason] = useState18("");
|
|
4233
|
+
const [error, setError] = useState18(null);
|
|
4081
4234
|
const title = `Price for ${lineName}`;
|
|
4082
4235
|
function apply() {
|
|
4083
4236
|
const parsed = parsePrice(text, currency);
|
|
@@ -4085,10 +4238,10 @@ function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
|
|
|
4085
4238
|
setError(refused);
|
|
4086
4239
|
if (refused === null) onClose();
|
|
4087
4240
|
}
|
|
4088
|
-
return /* @__PURE__ */
|
|
4089
|
-
/* @__PURE__ */
|
|
4090
|
-
/* @__PURE__ */
|
|
4091
|
-
/* @__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(
|
|
4092
4245
|
TextInput10,
|
|
4093
4246
|
{
|
|
4094
4247
|
testID: "price-input",
|
|
@@ -4101,7 +4254,7 @@ function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
|
|
|
4101
4254
|
className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
|
|
4102
4255
|
}
|
|
4103
4256
|
),
|
|
4104
|
-
/* @__PURE__ */
|
|
4257
|
+
/* @__PURE__ */ jsx91(
|
|
4105
4258
|
TextInput10,
|
|
4106
4259
|
{
|
|
4107
4260
|
testID: "price-reason",
|
|
@@ -4112,26 +4265,26 @@ function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
|
|
|
4112
4265
|
className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
|
|
4113
4266
|
}
|
|
4114
4267
|
),
|
|
4115
|
-
error ? /* @__PURE__ */
|
|
4116
|
-
/* @__PURE__ */
|
|
4117
|
-
/* @__PURE__ */
|
|
4118
|
-
/* @__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" }) })
|
|
4119
4272
|
] })
|
|
4120
4273
|
] });
|
|
4121
4274
|
}
|
|
4122
4275
|
|
|
4123
4276
|
// src/sale/charge-form.tsx
|
|
4124
|
-
import { useState as
|
|
4125
|
-
import { Pressable as
|
|
4126
|
-
import { Fragment as Fragment5, jsx as
|
|
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";
|
|
4127
4280
|
var button3 = "rounded-md border border-border px-3 py-2 min-h-11 items-center justify-center";
|
|
4128
4281
|
function ChargeForm({ currency, lineTax, taxClasses, shippingTaxFromStore, onApply, onClose }) {
|
|
4129
|
-
const [kind, setKind] =
|
|
4130
|
-
const [name, setName] =
|
|
4131
|
-
const [text, setText] =
|
|
4132
|
-
const [noTax, setNoTax] =
|
|
4133
|
-
const [taxClass, setTaxClass] =
|
|
4134
|
-
const [error, setError] =
|
|
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);
|
|
4135
4288
|
const storeShipping = kind === "shipping" && shippingTaxFromStore;
|
|
4136
4289
|
function apply() {
|
|
4137
4290
|
const parsed = parsePrice(text, currency);
|
|
@@ -4145,21 +4298,21 @@ function ChargeForm({ currency, lineTax, taxClasses, shippingTaxFromStore, onApp
|
|
|
4145
4298
|
setError(refused);
|
|
4146
4299
|
if (refused === null) onClose();
|
|
4147
4300
|
}
|
|
4148
|
-
return /* @__PURE__ */
|
|
4149
|
-
/* @__PURE__ */
|
|
4150
|
-
/* @__PURE__ */
|
|
4151
|
-
|
|
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,
|
|
4152
4305
|
{
|
|
4153
4306
|
accessibilityRole: "button",
|
|
4154
4307
|
accessibilityState: { selected: kind === option },
|
|
4155
4308
|
"aria-selected": kind === option,
|
|
4156
4309
|
onPress: () => setKind(option),
|
|
4157
4310
|
className: `${button3} ${kind === option ? "bg-primary" : "bg-card"}`,
|
|
4158
|
-
children: /* @__PURE__ */
|
|
4311
|
+
children: /* @__PURE__ */ jsx92(Text35, { className: kind === option ? "text-primary-foreground" : "text-foreground", children: option === "fee" ? "Fee" : option === "shipping" ? "Shipping" : "Custom item" })
|
|
4159
4312
|
},
|
|
4160
4313
|
option
|
|
4161
4314
|
)) }),
|
|
4162
|
-
/* @__PURE__ */
|
|
4315
|
+
/* @__PURE__ */ jsx92(
|
|
4163
4316
|
TextInput11,
|
|
4164
4317
|
{
|
|
4165
4318
|
accessibilityLabel: "Name",
|
|
@@ -4169,7 +4322,7 @@ function ChargeForm({ currency, lineTax, taxClasses, shippingTaxFromStore, onApp
|
|
|
4169
4322
|
className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
|
|
4170
4323
|
}
|
|
4171
4324
|
),
|
|
4172
|
-
/* @__PURE__ */
|
|
4325
|
+
/* @__PURE__ */ jsx92(
|
|
4173
4326
|
TextInput11,
|
|
4174
4327
|
{
|
|
4175
4328
|
accessibilityLabel: "Amount",
|
|
@@ -4181,9 +4334,9 @@ function ChargeForm({ currency, lineTax, taxClasses, shippingTaxFromStore, onApp
|
|
|
4181
4334
|
className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
|
|
4182
4335
|
}
|
|
4183
4336
|
),
|
|
4184
|
-
storeShipping ? /* @__PURE__ */
|
|
4185
|
-
lineTax?.none ? /* @__PURE__ */
|
|
4186
|
-
|
|
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,
|
|
4187
4340
|
{
|
|
4188
4341
|
accessibilityRole: "switch",
|
|
4189
4342
|
accessibilityLabel: "No tax",
|
|
@@ -4191,32 +4344,32 @@ function ChargeForm({ currency, lineTax, taxClasses, shippingTaxFromStore, onApp
|
|
|
4191
4344
|
"aria-checked": noTax,
|
|
4192
4345
|
onPress: () => setNoTax(!noTax),
|
|
4193
4346
|
className: `${button3} ${noTax ? "bg-primary" : "bg-card"}`,
|
|
4194
|
-
children: /* @__PURE__ */
|
|
4347
|
+
children: /* @__PURE__ */ jsx92(Text35, { className: noTax ? "text-primary-foreground" : "text-foreground", children: "No tax" })
|
|
4195
4348
|
}
|
|
4196
4349
|
) : null,
|
|
4197
|
-
lineTax?.classes && taxClasses?.length ? /* @__PURE__ */
|
|
4198
|
-
|
|
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,
|
|
4199
4352
|
{
|
|
4200
4353
|
accessibilityRole: "button",
|
|
4201
4354
|
accessibilityState: { selected: taxClass === option.id },
|
|
4202
4355
|
"aria-selected": taxClass === option.id,
|
|
4203
4356
|
onPress: () => setTaxClass(option.id),
|
|
4204
4357
|
className: `${button3} ${taxClass === option.id ? "bg-primary" : "bg-card"}`,
|
|
4205
|
-
children: /* @__PURE__ */
|
|
4358
|
+
children: /* @__PURE__ */ jsx92(Text35, { className: taxClass === option.id ? "text-primary-foreground" : "text-foreground", children: option.label })
|
|
4206
4359
|
},
|
|
4207
4360
|
option.id
|
|
4208
4361
|
)) }) : null
|
|
4209
4362
|
] }),
|
|
4210
|
-
error ? /* @__PURE__ */
|
|
4211
|
-
/* @__PURE__ */
|
|
4212
|
-
/* @__PURE__ */
|
|
4213
|
-
/* @__PURE__ */
|
|
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" }) })
|
|
4214
4367
|
] })
|
|
4215
4368
|
] });
|
|
4216
4369
|
}
|
|
4217
4370
|
|
|
4218
4371
|
// src/sale/cart.tsx
|
|
4219
|
-
import { Fragment as Fragment6, jsx as
|
|
4372
|
+
import { Fragment as Fragment6, jsx as jsx93, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
4220
4373
|
function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPrice = false, onPriceChange, taxClasses }) {
|
|
4221
4374
|
const { order } = sale;
|
|
4222
4375
|
const money = (amount) => ({ amount, currency: order.currency });
|
|
@@ -4224,9 +4377,9 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4224
4377
|
const taxRows = totals.taxLines.map((line) => ({ label: taxLabel(line.ratePpm), amount: money(line.amountMinor) }));
|
|
4225
4378
|
const display = (lineId) => order.display.lines.find((line) => line.lineId === lineId);
|
|
4226
4379
|
const orderAmounts = order.discounts.length === 1 ? [{ discountId: order.discounts[0].id, amountMinor: order.display.orderDiscountMinor }] : [];
|
|
4227
|
-
const [form, setForm] =
|
|
4380
|
+
const [form, setForm] = useState20(null);
|
|
4228
4381
|
const chargesOffered = (sale.capabilities?.orderCreate ?? 0) >= 5;
|
|
4229
|
-
const discountForm = (lineId, title) => form?.type === "discount" && form.lineId === lineId ? /* @__PURE__ */
|
|
4382
|
+
const discountForm = (lineId, title) => form?.type === "discount" && form.lineId === lineId ? /* @__PURE__ */ jsx93(
|
|
4230
4383
|
DiscountForm,
|
|
4231
4384
|
{
|
|
4232
4385
|
title,
|
|
@@ -4237,11 +4390,11 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4237
4390
|
lineId ?? "order"
|
|
4238
4391
|
) : null;
|
|
4239
4392
|
const pay = `min-h-12 flex-1 justify-center rounded-md bg-primary px-4 py-3 ${!order.lineItems.length ? "opacity-50" : ""}`;
|
|
4240
|
-
const renderItem = (line) => /* @__PURE__ */
|
|
4241
|
-
/* @__PURE__ */
|
|
4393
|
+
const renderItem = (line) => /* @__PURE__ */ jsxs51(Fragment6, { children: [
|
|
4394
|
+
/* @__PURE__ */ jsx93(CartLineActions, { actions: [
|
|
4242
4395
|
{ id: "discount", label: "Discount", color: "text-primary", onPress: () => setForm({ type: "discount", lineId: line.id }) },
|
|
4243
4396
|
...canEditPrice ? [{ id: "price", label: "Price", color: "text-primary", onPress: () => setForm({ type: "price", lineId: line.id }) }] : []
|
|
4244
|
-
], children: /* @__PURE__ */
|
|
4397
|
+
], children: /* @__PURE__ */ jsx93(
|
|
4245
4398
|
CartLine,
|
|
4246
4399
|
{
|
|
4247
4400
|
name: line.name,
|
|
@@ -4250,41 +4403,41 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4250
4403
|
lineTotal: money(display(line.id).amountMinor)
|
|
4251
4404
|
}
|
|
4252
4405
|
) }),
|
|
4253
|
-
/* @__PURE__ */
|
|
4254
|
-
/* @__PURE__ */
|
|
4255
|
-
/* @__PURE__ */
|
|
4256
|
-
|
|
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,
|
|
4257
4410
|
{
|
|
4258
4411
|
accessibilityRole: "button",
|
|
4259
4412
|
accessibilityLabel: `Decrease ${line.name}`,
|
|
4260
4413
|
onPress: () => sale.setQuantity(line.id, line.quantity - 1),
|
|
4261
4414
|
className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
|
|
4262
|
-
children: /* @__PURE__ */
|
|
4415
|
+
children: /* @__PURE__ */ jsx93(Text36, { className: "text-center text-foreground", children: "\u2212" })
|
|
4263
4416
|
}
|
|
4264
4417
|
),
|
|
4265
|
-
/* @__PURE__ */
|
|
4266
|
-
|
|
4418
|
+
/* @__PURE__ */ jsx93(
|
|
4419
|
+
Pressable28,
|
|
4267
4420
|
{
|
|
4268
4421
|
accessibilityRole: "button",
|
|
4269
4422
|
accessibilityLabel: `Increase ${line.name}`,
|
|
4270
4423
|
onPress: () => sale.setQuantity(line.id, line.quantity + 1),
|
|
4271
4424
|
className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
|
|
4272
|
-
children: /* @__PURE__ */
|
|
4425
|
+
children: /* @__PURE__ */ jsx93(Text36, { className: "text-center text-foreground", children: "+" })
|
|
4273
4426
|
}
|
|
4274
4427
|
),
|
|
4275
|
-
/* @__PURE__ */
|
|
4276
|
-
|
|
4428
|
+
/* @__PURE__ */ jsx93(
|
|
4429
|
+
Pressable28,
|
|
4277
4430
|
{
|
|
4278
4431
|
accessibilityRole: "button",
|
|
4279
4432
|
accessibilityLabel: `Remove ${line.name}`,
|
|
4280
4433
|
onPress: () => sale.remove(line.id),
|
|
4281
4434
|
className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
|
|
4282
|
-
children: /* @__PURE__ */
|
|
4435
|
+
children: /* @__PURE__ */ jsx93(Text36, { className: "text-center text-foreground", children: "Remove" })
|
|
4283
4436
|
}
|
|
4284
4437
|
)
|
|
4285
4438
|
] }),
|
|
4286
4439
|
discountForm(line.id, `Discount on ${line.name}`),
|
|
4287
|
-
canEditPrice && form?.type === "price" && form.lineId === line.id ? /* @__PURE__ */
|
|
4440
|
+
canEditPrice && form?.type === "price" && form.lineId === line.id ? /* @__PURE__ */ jsx93(
|
|
4288
4441
|
PriceForm,
|
|
4289
4442
|
{
|
|
4290
4443
|
lineName: line.name,
|
|
@@ -4301,31 +4454,31 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4301
4454
|
line.id
|
|
4302
4455
|
) : null
|
|
4303
4456
|
] });
|
|
4304
|
-
return /* @__PURE__ */
|
|
4457
|
+
return /* @__PURE__ */ jsx93(
|
|
4305
4458
|
CartPanel,
|
|
4306
4459
|
{
|
|
4307
4460
|
dataSet: { print: "hide" },
|
|
4308
4461
|
items: order.lineItems,
|
|
4309
4462
|
renderItem,
|
|
4310
|
-
emptyState: /* @__PURE__ */
|
|
4311
|
-
afterItems: /* @__PURE__ */
|
|
4312
|
-
["fees", "shipping"].map((kind) => order[kind]?.map((charge, index) => /* @__PURE__ */
|
|
4313
|
-
/* @__PURE__ */
|
|
4314
|
-
/* @__PURE__ */
|
|
4315
|
-
/* @__PURE__ */
|
|
4316
|
-
|
|
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,
|
|
4317
4470
|
{
|
|
4318
4471
|
accessibilityRole: "button",
|
|
4319
4472
|
accessibilityLabel: `Remove ${charge.name}`,
|
|
4320
4473
|
onPress: () => kind === "fees" ? sale.removeFee(charge.id) : sale.removeShipping(charge.id),
|
|
4321
4474
|
className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 items-center justify-center",
|
|
4322
|
-
children: /* @__PURE__ */
|
|
4475
|
+
children: /* @__PURE__ */ jsx93(Text36, { className: "text-foreground", children: "Remove" })
|
|
4323
4476
|
}
|
|
4324
4477
|
)
|
|
4325
4478
|
] }, charge.id))),
|
|
4326
|
-
order.lineItems.length || chargesOffered ? /* @__PURE__ */
|
|
4327
|
-
order.lineItems.length ? /* @__PURE__ */
|
|
4328
|
-
/* @__PURE__ */
|
|
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(
|
|
4329
4482
|
DiscountChips,
|
|
4330
4483
|
{
|
|
4331
4484
|
discounts: order.discounts,
|
|
@@ -4335,17 +4488,17 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4335
4488
|
prefix: "Order discount"
|
|
4336
4489
|
}
|
|
4337
4490
|
),
|
|
4338
|
-
form?.type === "discount" && form.lineId === null ? discountForm(null, "Order discount") : /* @__PURE__ */
|
|
4339
|
-
|
|
4491
|
+
form?.type === "discount" && form.lineId === null ? discountForm(null, "Order discount") : /* @__PURE__ */ jsx93(
|
|
4492
|
+
Pressable28,
|
|
4340
4493
|
{
|
|
4341
4494
|
accessibilityRole: "button",
|
|
4342
4495
|
onPress: () => setForm({ type: "discount", lineId: null }),
|
|
4343
4496
|
className: "self-start rounded-md border border-border bg-card px-4 py-2 min-h-11 justify-center",
|
|
4344
|
-
children: /* @__PURE__ */
|
|
4497
|
+
children: /* @__PURE__ */ jsx93(Text36, { className: "text-foreground", children: "Order discount" })
|
|
4345
4498
|
}
|
|
4346
4499
|
)
|
|
4347
4500
|
] }) : null,
|
|
4348
|
-
chargesOffered ? form?.type === "charge" ? /* @__PURE__ */
|
|
4501
|
+
chargesOffered ? form?.type === "charge" ? /* @__PURE__ */ jsx93(
|
|
4349
4502
|
ChargeForm,
|
|
4350
4503
|
{
|
|
4351
4504
|
currency: order.currency,
|
|
@@ -4358,19 +4511,19 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4358
4511
|
return typeof result === "string" ? result : null;
|
|
4359
4512
|
}
|
|
4360
4513
|
}
|
|
4361
|
-
) : /* @__PURE__ */
|
|
4362
|
-
|
|
4514
|
+
) : /* @__PURE__ */ jsx93(
|
|
4515
|
+
Pressable28,
|
|
4363
4516
|
{
|
|
4364
4517
|
accessibilityRole: "button",
|
|
4365
4518
|
onPress: () => setForm({ type: "charge" }),
|
|
4366
4519
|
className: "self-start rounded-md border border-border bg-card px-4 py-2 min-h-11 justify-center",
|
|
4367
|
-
children: /* @__PURE__ */
|
|
4520
|
+
children: /* @__PURE__ */ jsx93(Text36, { className: "text-foreground", children: "Add charge" })
|
|
4368
4521
|
}
|
|
4369
4522
|
) : null
|
|
4370
4523
|
] }) : null
|
|
4371
4524
|
] }),
|
|
4372
|
-
footer: /* @__PURE__ */
|
|
4373
|
-
/* @__PURE__ */
|
|
4525
|
+
footer: /* @__PURE__ */ jsxs51(View59, { testID: "cart-footer", className: "gap-3 pb-4", children: [
|
|
4526
|
+
/* @__PURE__ */ jsx93(
|
|
4374
4527
|
CartTotal,
|
|
4375
4528
|
{
|
|
4376
4529
|
subtotal: money(totals.subtotalMinor),
|
|
@@ -4380,10 +4533,10 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4380
4533
|
taxInclusive: totals.taxInclusive
|
|
4381
4534
|
}
|
|
4382
4535
|
),
|
|
4383
|
-
sale.error ? /* @__PURE__ */
|
|
4384
|
-
/* @__PURE__ */
|
|
4385
|
-
/* @__PURE__ */
|
|
4386
|
-
/* @__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" }) })
|
|
4387
4540
|
] })
|
|
4388
4541
|
] })
|
|
4389
4542
|
}
|
|
@@ -4391,17 +4544,17 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
|
|
|
4391
4544
|
}
|
|
4392
4545
|
|
|
4393
4546
|
// src/sale/cart-bar.tsx
|
|
4394
|
-
import { Pressable as
|
|
4547
|
+
import { Pressable as Pressable29, Text as Text37 } from "react-native";
|
|
4395
4548
|
import { formatMoney as formatMoney13 } from "@tallyui/core";
|
|
4396
4549
|
import { buildReceiptData as buildReceiptData2 } from "@tallyui/pos";
|
|
4397
|
-
import { jsx as
|
|
4550
|
+
import { jsx as jsx94, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
4398
4551
|
function CartBar({ sale, onOpen }) {
|
|
4399
4552
|
const { order } = sale;
|
|
4400
4553
|
const count2 = order.lineItems.reduce((sum, line) => sum + line.quantity, 0);
|
|
4401
4554
|
const total = formatMoney13({ amount: buildReceiptData2(order, { storeName: "" }).totals.totalMinor, currency: order.currency });
|
|
4402
4555
|
const items = `${count2} ${count2 === 1 ? "item" : "items"}`;
|
|
4403
|
-
return /* @__PURE__ */
|
|
4404
|
-
|
|
4556
|
+
return /* @__PURE__ */ jsxs52(
|
|
4557
|
+
Pressable29,
|
|
4405
4558
|
{
|
|
4406
4559
|
accessibilityRole: "button",
|
|
4407
4560
|
accessibilityLabel: count2 ? `Open cart, ${items}, ${total}` : "Cart is empty",
|
|
@@ -4409,8 +4562,8 @@ function CartBar({ sale, onOpen }) {
|
|
|
4409
4562
|
onPress: onOpen,
|
|
4410
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"}`,
|
|
4411
4564
|
children: [
|
|
4412
|
-
/* @__PURE__ */
|
|
4413
|
-
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: [
|
|
4414
4567
|
total,
|
|
4415
4568
|
" \u203A"
|
|
4416
4569
|
] }) : null
|
|
@@ -4420,17 +4573,17 @@ function CartBar({ sale, onOpen }) {
|
|
|
4420
4573
|
}
|
|
4421
4574
|
|
|
4422
4575
|
// src/sale/tender.tsx
|
|
4423
|
-
import { Pressable as
|
|
4576
|
+
import { Pressable as Pressable30, Text as Text38, TextInput as TextInput12, View as View60 } from "react-native";
|
|
4424
4577
|
import { formatMoney as formatMoney14 } from "@tallyui/core";
|
|
4425
|
-
import { Fragment as Fragment7, jsx as
|
|
4578
|
+
import { Fragment as Fragment7, jsx as jsx95, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
4426
4579
|
var REFERENCE_MAX = 255;
|
|
4427
4580
|
function Tender({ sale }) {
|
|
4428
4581
|
const { order, stage } = sale;
|
|
4429
4582
|
if (stage.kind !== "tender") return null;
|
|
4430
4583
|
const money = (amount) => ({ amount, currency: order.currency });
|
|
4431
|
-
return /* @__PURE__ */
|
|
4432
|
-
stage.method === "cash" ? /* @__PURE__ */
|
|
4433
|
-
/* @__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(
|
|
4434
4587
|
CashTendered,
|
|
4435
4588
|
{
|
|
4436
4589
|
total: money(order.totalMinor),
|
|
@@ -4438,18 +4591,18 @@ function Tender({ sale }) {
|
|
|
4438
4591
|
onChangeAmount: (amount) => sale.setTender({ method: "cash", amountMinor: amount.amount })
|
|
4439
4592
|
}
|
|
4440
4593
|
),
|
|
4441
|
-
/* @__PURE__ */
|
|
4442
|
-
order.balanceDueMinor > 0 ? /* @__PURE__ */
|
|
4594
|
+
/* @__PURE__ */ jsx95(ChangeDisplay, { change: money(order.changeDueMinor) }),
|
|
4595
|
+
order.balanceDueMinor > 0 ? /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
|
|
4443
4596
|
"Balance due: ",
|
|
4444
4597
|
formatMoney14(money(order.balanceDueMinor))
|
|
4445
4598
|
] }) : null,
|
|
4446
|
-
/* @__PURE__ */
|
|
4447
|
-
] }) : /* @__PURE__ */
|
|
4448
|
-
/* @__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: [
|
|
4449
4602
|
"Card terminal: ",
|
|
4450
4603
|
formatMoney14(money(order.totalMinor))
|
|
4451
4604
|
] }),
|
|
4452
|
-
/* @__PURE__ */
|
|
4605
|
+
/* @__PURE__ */ jsx95(
|
|
4453
4606
|
TextInput12,
|
|
4454
4607
|
{
|
|
4455
4608
|
accessibilityLabel: "Terminal reference",
|
|
@@ -4460,28 +4613,28 @@ function Tender({ sale }) {
|
|
|
4460
4613
|
className: "rounded-md border border-border px-3 py-2 text-foreground"
|
|
4461
4614
|
}
|
|
4462
4615
|
),
|
|
4463
|
-
/* @__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" }) })
|
|
4464
4617
|
] }),
|
|
4465
|
-
sale.error ? /* @__PURE__ */
|
|
4466
|
-
sale.canContinue ? /* @__PURE__ */
|
|
4467
|
-
/* @__PURE__ */
|
|
4468
|
-
/* @__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" }) })
|
|
4469
4622
|
] }) : null,
|
|
4470
|
-
/* @__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" }) })
|
|
4471
4624
|
] });
|
|
4472
4625
|
}
|
|
4473
4626
|
|
|
4474
4627
|
// src/sale/split-tender.tsx
|
|
4475
|
-
import { useState as
|
|
4476
|
-
import { Pressable 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";
|
|
4477
4630
|
import { formatMoney as formatMoney15, minorUnitDigits as minorUnitDigits9 } from "@tallyui/core";
|
|
4478
|
-
import { Fragment as Fragment8, jsx as
|
|
4631
|
+
import { Fragment as Fragment8, jsx as jsx96, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
4479
4632
|
function SplitTender({ sale }) {
|
|
4480
4633
|
const { order, stage } = sale;
|
|
4481
|
-
const [method, setMethod] =
|
|
4482
|
-
const [amount, setAmount] =
|
|
4483
|
-
const [reference, setReference] =
|
|
4484
|
-
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);
|
|
4485
4638
|
if (stage.kind !== "tender") return null;
|
|
4486
4639
|
const money = (value) => formatMoney15({ amount: value, currency: order.currency });
|
|
4487
4640
|
const digits = minorUnitDigits9(order.currency);
|
|
@@ -4506,58 +4659,58 @@ function SplitTender({ sale }) {
|
|
|
4506
4659
|
setReference("");
|
|
4507
4660
|
setAmount(null);
|
|
4508
4661
|
}
|
|
4509
|
-
return /* @__PURE__ */
|
|
4510
|
-
/* @__PURE__ */
|
|
4511
|
-
/* @__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: [
|
|
4512
4665
|
"Total: ",
|
|
4513
4666
|
money(order.totalMinor)
|
|
4514
4667
|
] }),
|
|
4515
|
-
/* @__PURE__ */
|
|
4668
|
+
/* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
|
|
4516
4669
|
"Paid: ",
|
|
4517
4670
|
money(order.paidMinor)
|
|
4518
4671
|
] }),
|
|
4519
|
-
/* @__PURE__ */
|
|
4672
|
+
/* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
|
|
4520
4673
|
"Remaining: ",
|
|
4521
4674
|
money(order.balanceDueMinor)
|
|
4522
4675
|
] }),
|
|
4523
|
-
order.changeDueMinor > 0 ? /* @__PURE__ */
|
|
4676
|
+
order.changeDueMinor > 0 ? /* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
|
|
4524
4677
|
"Change: ",
|
|
4525
4678
|
money(order.changeDueMinor)
|
|
4526
4679
|
] }) : null
|
|
4527
4680
|
] }),
|
|
4528
|
-
/* @__PURE__ */
|
|
4529
|
-
/* @__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: [
|
|
4530
4683
|
tenderLabel(payment.method),
|
|
4531
4684
|
" ",
|
|
4532
4685
|
money(payment.amountMinor)
|
|
4533
4686
|
] }),
|
|
4534
|
-
payment.reference ? /* @__PURE__ */
|
|
4535
|
-
/* @__PURE__ */
|
|
4536
|
-
|
|
4687
|
+
payment.reference ? /* @__PURE__ */ jsx96(Text39, { className: "text-foreground", children: payment.reference }) : null,
|
|
4688
|
+
/* @__PURE__ */ jsx96(
|
|
4689
|
+
Pressable31,
|
|
4537
4690
|
{
|
|
4538
4691
|
testID: `split-tender-remove-${payment.id}`,
|
|
4539
4692
|
accessibilityRole: "button",
|
|
4540
4693
|
accessibilityLabel: "Remove tender",
|
|
4541
4694
|
onPress: () => sale.removeTender(payment.id),
|
|
4542
4695
|
className: "rounded-md border border-border bg-card px-4 py-3",
|
|
4543
|
-
children: /* @__PURE__ */
|
|
4696
|
+
children: /* @__PURE__ */ jsx96(Text39, { className: "text-center text-foreground", children: "Remove" })
|
|
4544
4697
|
}
|
|
4545
4698
|
)
|
|
4546
4699
|
] }, payment.id)) }),
|
|
4547
|
-
/* @__PURE__ */
|
|
4548
|
-
/* @__PURE__ */
|
|
4549
|
-
|
|
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,
|
|
4550
4703
|
{
|
|
4551
4704
|
testID: `split-tender-method-${value === "cash" ? "cash" : "card"}`,
|
|
4552
4705
|
accessibilityRole: "button",
|
|
4553
4706
|
accessibilityState: { selected: method === value },
|
|
4554
4707
|
onPress: () => setMethod(value),
|
|
4555
4708
|
className: `rounded-md border border-border px-4 py-3 ${method === value ? "bg-primary" : "bg-card"}`,
|
|
4556
|
-
children: /* @__PURE__ */
|
|
4709
|
+
children: /* @__PURE__ */ jsx96(Text39, { className: `text-center ${method === value ? "text-primary-foreground" : "text-foreground"}`, children: tenderLabel(value) })
|
|
4557
4710
|
},
|
|
4558
4711
|
value
|
|
4559
4712
|
)) }),
|
|
4560
|
-
/* @__PURE__ */
|
|
4713
|
+
/* @__PURE__ */ jsx96(
|
|
4561
4714
|
TextInput13,
|
|
4562
4715
|
{
|
|
4563
4716
|
testID: "split-tender-amount",
|
|
@@ -4568,7 +4721,7 @@ function SplitTender({ sale }) {
|
|
|
4568
4721
|
className: "rounded-md border border-border px-3 py-2 text-foreground"
|
|
4569
4722
|
}
|
|
4570
4723
|
),
|
|
4571
|
-
method === "external" ? /* @__PURE__ */
|
|
4724
|
+
method === "external" ? /* @__PURE__ */ jsx96(
|
|
4572
4725
|
TextInput13,
|
|
4573
4726
|
{
|
|
4574
4727
|
testID: "split-tender-reference",
|
|
@@ -4580,36 +4733,48 @@ function SplitTender({ sale }) {
|
|
|
4580
4733
|
className: "rounded-md border border-border px-3 py-2 text-foreground"
|
|
4581
4734
|
}
|
|
4582
4735
|
) : null,
|
|
4583
|
-
error ? /* @__PURE__ */
|
|
4584
|
-
/* @__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" }) })
|
|
4585
4738
|
] }),
|
|
4586
|
-
/* @__PURE__ */
|
|
4587
|
-
|
|
4739
|
+
/* @__PURE__ */ jsx96(
|
|
4740
|
+
Pressable31,
|
|
4588
4741
|
{
|
|
4589
4742
|
testID: "split-tender-complete",
|
|
4590
4743
|
accessibilityRole: "button",
|
|
4591
4744
|
disabled: incomplete,
|
|
4592
4745
|
onPress: sale.complete,
|
|
4593
4746
|
className: `rounded-md bg-primary px-4 py-3 ${incomplete ? "opacity-50" : ""}`,
|
|
4594
|
-
children: /* @__PURE__ */
|
|
4747
|
+
children: /* @__PURE__ */ jsx96(Text39, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" })
|
|
4595
4748
|
}
|
|
4596
4749
|
),
|
|
4597
|
-
sale.error ? /* @__PURE__ */
|
|
4598
|
-
sale.canContinue ? /* @__PURE__ */
|
|
4599
|
-
/* @__PURE__ */
|
|
4600
|
-
/* @__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" }) })
|
|
4601
4754
|
] }) : null,
|
|
4602
|
-
/* @__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" }) })
|
|
4603
4756
|
] });
|
|
4604
4757
|
}
|
|
4605
4758
|
|
|
4606
4759
|
// src/sale/catalogue.tsx
|
|
4607
|
-
import { useEffect as useEffect5, useMemo as
|
|
4608
|
-
import { Pressable as
|
|
4609
|
-
import { useStockOverlaid, useStockOverlayAsOf } from "@tallyui/core";
|
|
4610
|
-
import {
|
|
4611
|
-
|
|
4612
|
-
|
|
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";
|
|
4613
4778
|
var STOCK_LABEL = {
|
|
4614
4779
|
in_stock: "In Stock",
|
|
4615
4780
|
out_of_stock: "Out of Stock",
|
|
@@ -4627,20 +4792,98 @@ function laterOf(a, b) {
|
|
|
4627
4792
|
if (!b) return a;
|
|
4628
4793
|
return a.getTime() >= b.getTime() ? a : b;
|
|
4629
4794
|
}
|
|
4630
|
-
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
|
+
}
|
|
4631
4867
|
const isLoading = loading ?? (lastSyncedAt === null && pullError == null);
|
|
4632
|
-
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);
|
|
4633
4872
|
const overlayAsOf = useStockOverlayAsOf();
|
|
4634
4873
|
const parsedOverlayAsOf = overlayAsOf ? new Date(overlayAsOf) : void 0;
|
|
4635
4874
|
const validOverlayAsOf = parsedOverlayAsOf && !isNaN(parsedOverlayAsOf.getTime()) ? parsedOverlayAsOf : void 0;
|
|
4636
4875
|
const stockAsOf = laterOf(laterOf(lastStockCheckAt, validOverlayAsOf), lastSyncedAt);
|
|
4637
|
-
const [query, setQuery] =
|
|
4638
|
-
const [chooserId, setChooserId] =
|
|
4639
|
-
const [width, setWidth] =
|
|
4640
|
-
const columns =
|
|
4641
|
-
const entries =
|
|
4642
|
-
const results =
|
|
4643
|
-
|
|
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]);
|
|
4644
4887
|
useEffect5(() => {
|
|
4645
4888
|
if (chooserId !== null && choices.length === 0) setChooserId(null);
|
|
4646
4889
|
}, [chooserId, choices]);
|
|
@@ -4648,13 +4891,22 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
|
|
|
4648
4891
|
onSelect(entry);
|
|
4649
4892
|
setChooserId(null);
|
|
4650
4893
|
}
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
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(
|
|
4654
4903
|
SearchInput,
|
|
4655
4904
|
{
|
|
4656
4905
|
value: query,
|
|
4657
|
-
onChangeText:
|
|
4906
|
+
onChangeText: (text) => {
|
|
4907
|
+
setQuery(text);
|
|
4908
|
+
onQueryChange?.(text);
|
|
4909
|
+
},
|
|
4658
4910
|
placeholder: "Search or scan barcode / SKU",
|
|
4659
4911
|
autoFocus: true,
|
|
4660
4912
|
onSubmitEditing: () => {
|
|
@@ -4667,25 +4919,34 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
|
|
|
4667
4919
|
}
|
|
4668
4920
|
}
|
|
4669
4921
|
),
|
|
4670
|
-
statusText || statusAccessory ? /* @__PURE__ */
|
|
4671
|
-
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: [
|
|
4672
4924
|
statusText,
|
|
4673
4925
|
query.trim() ? ` \xB7 ${results.length.toLocaleString()} matching` : ""
|
|
4674
4926
|
] }) : null,
|
|
4675
|
-
statusAccessory
|
|
4927
|
+
statusAccessory,
|
|
4928
|
+
showViewToggle ? /* @__PURE__ */ jsx97(ViewToggle, { value: state.view, onChange: (view) => changeState({ type: "setView", view }) }) : null
|
|
4676
4929
|
] }) : null,
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
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,
|
|
4680
4941
|
{
|
|
4681
4942
|
accessibilityRole: "button",
|
|
4682
4943
|
onPress: () => select(entry),
|
|
4683
4944
|
className: "gap-1 rounded-md border border-border p-3",
|
|
4684
4945
|
children: [
|
|
4685
|
-
/* @__PURE__ */
|
|
4686
|
-
/* @__PURE__ */
|
|
4687
|
-
/* @__PURE__ */
|
|
4688
|
-
/* @__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: [
|
|
4689
4950
|
STOCK_LABEL[entry.variant.stock.status],
|
|
4690
4951
|
" \xB7 ",
|
|
4691
4952
|
stockAsOf ? `as of ${formatStockSyncTime(stockAsOf, void 0, hour12)}` : "not yet synced"
|
|
@@ -4694,10 +4955,20 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
|
|
|
4694
4955
|
},
|
|
4695
4956
|
entry.variant.id
|
|
4696
4957
|
)),
|
|
4697
|
-
/* @__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" }) })
|
|
4698
4959
|
] }) : null
|
|
4699
4960
|
] }),
|
|
4700
|
-
/* @__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(
|
|
4701
4972
|
ProductGrid,
|
|
4702
4973
|
{
|
|
4703
4974
|
items: results,
|
|
@@ -4706,18 +4977,14 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
|
|
|
4706
4977
|
// TallyUI's ProductCard has no children slot, so the tile is composed directly here
|
|
4707
4978
|
// (same structure/classes as ProductCard) to add the stock badge as a fourth child,
|
|
4708
4979
|
// inside the card and centred with the rest, rather than adding a slot to ProductCard (out of scope for TV6b).
|
|
4709
|
-
/* @__PURE__ */
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
/* @__PURE__ */ jsx95(ProductImage, { doc: product, size: 80, className: "rounded-md" }),
|
|
4715
|
-
/* @__PURE__ */ jsx95(ProductTitle, { doc: product, className: "text-sm", numberOfLines: 2 }),
|
|
4716
|
-
/* @__PURE__ */ jsx95(ProductPrice, { doc: product }),
|
|
4717
|
-
/* @__PURE__ */ jsx95(ProductStockBadge, { doc: product, showAsOf: false, className: "self-center" })
|
|
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" })
|
|
4718
4985
|
] }) })
|
|
4719
4986
|
),
|
|
4720
|
-
emptyState
|
|
4987
|
+
emptyState
|
|
4721
4988
|
}
|
|
4722
4989
|
)
|
|
4723
4990
|
] });
|
|
@@ -4725,7 +4992,7 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
|
|
|
4725
4992
|
|
|
4726
4993
|
// src/sale/receipt.tsx
|
|
4727
4994
|
import { useEffect as useEffect6 } from "react";
|
|
4728
|
-
import { Pressable as
|
|
4995
|
+
import { Pressable as Pressable33, Text as Text41, View as View63 } from "react-native";
|
|
4729
4996
|
import { formatMoney as formatMoney16 } from "@tallyui/core";
|
|
4730
4997
|
import { buildReceiptData as buildReceiptData3 } from "@tallyui/pos";
|
|
4731
4998
|
|
|
@@ -4746,7 +5013,7 @@ function orderReference(order) {
|
|
|
4746
5013
|
}
|
|
4747
5014
|
|
|
4748
5015
|
// src/sale/receipt.tsx
|
|
4749
|
-
import { Fragment as Fragment9, jsx as
|
|
5016
|
+
import { Fragment as Fragment9, jsx as jsx98, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
4750
5017
|
var defaultFormatDate = (iso) => new Intl.DateTimeFormat(void 0, { dateStyle: "medium", timeStyle: "short" }).format(new Date(iso));
|
|
4751
5018
|
function Receipt({
|
|
4752
5019
|
order,
|
|
@@ -4767,32 +5034,32 @@ function Receipt({
|
|
|
4767
5034
|
register: registerId
|
|
4768
5035
|
});
|
|
4769
5036
|
const money = (amount) => formatMoney16({ amount, currency: receipt.currency }) ?? "";
|
|
4770
|
-
const row = (label, amount, bold = false, key) => /* @__PURE__ */
|
|
4771
|
-
/* @__PURE__ */
|
|
4772
|
-
/* @__PURE__ */
|
|
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 })
|
|
4773
5040
|
] }, key);
|
|
4774
5041
|
const { totals } = receipt;
|
|
4775
5042
|
const lineDiscountMinor = totals.discountMinor - receipt.orderDiscountMinor;
|
|
4776
5043
|
const taxRows = totals.taxLines.map((line, index) => row(`${totals.taxInclusive ? "incl. " : ""}${taxLabel(line.ratePpm)}`, money(line.amountMinor), false, index));
|
|
4777
|
-
return /* @__PURE__ */
|
|
4778
|
-
topInset > 0 ? /* @__PURE__ */
|
|
4779
|
-
/* @__PURE__ */
|
|
4780
|
-
/* @__PURE__ */
|
|
4781
|
-
receipt.header.storeAddress ? /* @__PURE__ */
|
|
4782
|
-
/* @__PURE__ */
|
|
4783
|
-
/* @__PURE__ */
|
|
4784
|
-
/* @__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: [
|
|
4785
5052
|
"Cashier: ",
|
|
4786
5053
|
receipt.header.cashier
|
|
4787
5054
|
] }),
|
|
4788
|
-
receipt.header.customer && /* @__PURE__ */
|
|
5055
|
+
receipt.header.customer && /* @__PURE__ */ jsxs56(Text41, { className: "text-muted-foreground", children: [
|
|
4789
5056
|
"Customer: ",
|
|
4790
5057
|
receipt.header.customer
|
|
4791
5058
|
] }),
|
|
4792
|
-
receipt.lineItems.map((line, index) => /* @__PURE__ */
|
|
4793
|
-
/* @__PURE__ */
|
|
5059
|
+
receipt.lineItems.map((line, index) => /* @__PURE__ */ jsxs56(View63, { children: [
|
|
5060
|
+
/* @__PURE__ */ jsx98(Text41, { className: "text-foreground", children: line.name }),
|
|
4794
5061
|
row(`${line.quantity} \xD7 ${money(line.unitPriceMinor)}`, money(line.displayAmountMinor)),
|
|
4795
|
-
line.displayDiscounts.map((discount, i) => /* @__PURE__ */
|
|
5062
|
+
line.displayDiscounts.map((discount, i) => /* @__PURE__ */ jsx98(View63, { className: "pl-4", children: row(`${discountLabel(
|
|
4796
5063
|
order.lineItems[index].discounts[i],
|
|
4797
5064
|
receipt.currency
|
|
4798
5065
|
)} off`, `\u2212${money(discount.amountMinor)}`) }, i))
|
|
@@ -4811,19 +5078,19 @@ function Receipt({
|
|
|
4811
5078
|
index
|
|
4812
5079
|
)),
|
|
4813
5080
|
row("Change", money(receipt.changeDueMinor)),
|
|
4814
|
-
/* @__PURE__ */
|
|
4815
|
-
/* @__PURE__ */
|
|
5081
|
+
/* @__PURE__ */ jsxs56(View63, { dataSet: { print: "hide" }, className: "flex-row gap-4", children: [
|
|
5082
|
+
/* @__PURE__ */ jsx98(Pressable33, { accessibilityRole: "button", onPress: () => {
|
|
4816
5083
|
if (typeof window !== "undefined" && typeof window.print === "function") window.print();
|
|
4817
|
-
}, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */
|
|
4818
|
-
/* @__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" }) })
|
|
4819
5086
|
] })
|
|
4820
5087
|
] })
|
|
4821
5088
|
] });
|
|
4822
5089
|
}
|
|
4823
5090
|
|
|
4824
5091
|
// src/sale/sync-status.tsx
|
|
4825
|
-
import { useEffect as useEffect7, useRef as
|
|
4826
|
-
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";
|
|
4827
5094
|
|
|
4828
5095
|
// src/sale/since-text.ts
|
|
4829
5096
|
function sinceText(clock) {
|
|
@@ -4832,7 +5099,7 @@ function sinceText(clock) {
|
|
|
4832
5099
|
}
|
|
4833
5100
|
|
|
4834
5101
|
// src/sale/sync-status.tsx
|
|
4835
|
-
import { Fragment as Fragment10, jsx as
|
|
5102
|
+
import { Fragment as Fragment10, jsx as jsx99, jsxs as jsxs57 } from "react/jsx-runtime";
|
|
4836
5103
|
var PULL_NOTICE_TEXT = {
|
|
4837
5104
|
unauthorized: {
|
|
4838
5105
|
line: () => "Products aren't updating: this till needs to sign in to the online store again.",
|
|
@@ -4874,7 +5141,7 @@ var SALES_REFUSED = "The online store refused the last send. This till will try
|
|
|
4874
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.";
|
|
4875
5142
|
var count = (n, noun) => `${n} ${noun}${n === 1 ? "" : "s"}`;
|
|
4876
5143
|
function useAnnounceOnIos(...texts) {
|
|
4877
|
-
const announced =
|
|
5144
|
+
const announced = useRef7(texts);
|
|
4878
5145
|
useEffect7(() => {
|
|
4879
5146
|
const changed = texts.filter((text, index) => text && text !== announced.current[index]);
|
|
4880
5147
|
announced.current = texts;
|
|
@@ -4884,7 +5151,7 @@ function useAnnounceOnIos(...texts) {
|
|
|
4884
5151
|
function SyncStatus({ state, registerState, pluginName = "the POS plugin", pullNotice }) {
|
|
4885
5152
|
const updates = registerState?.pending ?? 0;
|
|
4886
5153
|
const outbox = state.pending === 0 && registerState?.pending ? registerState : state;
|
|
4887
|
-
const [now, setNow] =
|
|
5154
|
+
const [now, setNow] = useState23(Date.now);
|
|
4888
5155
|
useEffect7(() => {
|
|
4889
5156
|
setNow(Date.now());
|
|
4890
5157
|
if (!outbox.nextAttemptAt) return;
|
|
@@ -4908,24 +5175,24 @@ function SyncStatus({ state, registerState, pluginName = "the POS plugin", pullN
|
|
|
4908
5175
|
const notice = pullNotice && text && { line: text.line(pluginName), detail: text.detail(pullNotice, pluginName) };
|
|
4909
5176
|
useAnnounceOnIos(notice?.line, spoken);
|
|
4910
5177
|
const oneDetail = pullNotice?.code === "missing_plugin" && !!backendMissing;
|
|
4911
|
-
return /* @__PURE__ */
|
|
4912
|
-
notice ? /* @__PURE__ */
|
|
4913
|
-
/* @__PURE__ */
|
|
4914
|
-
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 })
|
|
4915
5182
|
] }) : null,
|
|
4916
|
-
/* @__PURE__ */
|
|
4917
|
-
doing ? /* @__PURE__ */
|
|
4918
|
-
refused ? /* @__PURE__ */
|
|
4919
|
-
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
|
|
4920
5187
|
] });
|
|
4921
5188
|
}
|
|
4922
5189
|
|
|
4923
5190
|
// src/sale/orders-list.tsx
|
|
4924
|
-
import { useEffect as useEffect8, useRef as
|
|
4925
|
-
import { Pressable 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";
|
|
4926
5193
|
import { formatMoney as formatMoney17, knownWarnings } from "@tallyui/core";
|
|
4927
5194
|
import { needsAttention } from "@tallyui/pos";
|
|
4928
|
-
import { jsx as
|
|
5195
|
+
import { jsx as jsx100, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
4929
5196
|
var STATUS_LABEL = { pending: "Waiting to sync", applied: "Synced", rejected: "Not accepted" };
|
|
4930
5197
|
var FIGURE_LABELS = /* @__PURE__ */ new Map([["subtotalMinor", "Subtotal"], ["taxMinor", "Tax"], ["discountMinor", "Discount"]]);
|
|
4931
5198
|
var REFUSAL_SENTENCES = /* @__PURE__ */ new Map([
|
|
@@ -4948,27 +5215,27 @@ function defaultFormatDate2(iso) {
|
|
|
4948
5215
|
return Number.isNaN(date.getTime()) ? iso : new Intl.DateTimeFormat(void 0, { dateStyle: "medium", timeStyle: "short" }).format(date);
|
|
4949
5216
|
}
|
|
4950
5217
|
function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer, stuck }) {
|
|
4951
|
-
const retrying =
|
|
4952
|
-
const [retryingIds, setRetryingIds] =
|
|
4953
|
-
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());
|
|
4954
5221
|
useEffect8(() => {
|
|
4955
5222
|
for (const id of retrying.current) {
|
|
4956
5223
|
if (!orders.some((order) => order.id === id && order.syncStatus === "rejected")) retrying.current.delete(id);
|
|
4957
5224
|
}
|
|
4958
5225
|
setRetryingIds(new Set(retrying.current));
|
|
4959
5226
|
}, [orders]);
|
|
4960
|
-
return /* @__PURE__ */
|
|
4961
|
-
[{ title: "Needs attention", orders: needsAttention(orders, { stuckCommandIds: stuck?.commandIds }) }, { title: "Recent", orders }].filter((section) => section.title === "Recent" || section.orders.length > 0).map((section) => /* @__PURE__ */
|
|
4962
|
-
/* @__PURE__ */
|
|
4963
|
-
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,
|
|
4964
5231
|
section.orders.map((order) => {
|
|
4965
5232
|
const count2 = order.lines.reduce((sum, line) => sum + line.quantity, 0);
|
|
4966
5233
|
const key = `${section.title}:${order.id}`;
|
|
4967
5234
|
const isExpanded = expanded.has(key);
|
|
4968
5235
|
const stuckEntry = order.syncStatus === "pending" ? stuck?.orders.find((entry) => entry.commandId === order.commandId) : void 0;
|
|
4969
|
-
return /* @__PURE__ */
|
|
4970
|
-
/* @__PURE__ */
|
|
4971
|
-
|
|
5236
|
+
return /* @__PURE__ */ jsxs58(View65, { className: "gap-1 rounded-md border border-border bg-card p-3", children: [
|
|
5237
|
+
/* @__PURE__ */ jsxs58(
|
|
5238
|
+
Pressable34,
|
|
4972
5239
|
{
|
|
4973
5240
|
accessibilityRole: "button",
|
|
4974
5241
|
"aria-expanded": isExpanded,
|
|
@@ -4982,8 +5249,8 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
|
|
|
4982
5249
|
return next;
|
|
4983
5250
|
}),
|
|
4984
5251
|
children: [
|
|
4985
|
-
/* @__PURE__ */
|
|
4986
|
-
/* @__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: [
|
|
4987
5254
|
formatDate(order.createdAt),
|
|
4988
5255
|
" \xB7 ",
|
|
4989
5256
|
formatMoney17({ amount: order.totalMinor, currency: order.currency }),
|
|
@@ -4993,15 +5260,15 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
|
|
|
4993
5260
|
]
|
|
4994
5261
|
}
|
|
4995
5262
|
),
|
|
4996
|
-
isExpanded ? /* @__PURE__ */
|
|
4997
|
-
order.lines.map((line) => /* @__PURE__ */
|
|
4998
|
-
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))
|
|
4999
5266
|
] }) : null,
|
|
5000
|
-
stuckEntry ? /* @__PURE__ */
|
|
5001
|
-
order.syncStatus === "rejected" ? /* @__PURE__ */
|
|
5002
|
-
order.lateSessionId !== void 0 ? /* @__PURE__ */
|
|
5003
|
-
order.localWarnings?.map((warning, index) => /* @__PURE__ */
|
|
5004
|
-
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 () => {
|
|
5005
5272
|
if (retrying.current.has(order.id)) return;
|
|
5006
5273
|
retrying.current.add(order.id);
|
|
5007
5274
|
setRetryingIds(new Set(retrying.current));
|
|
@@ -5009,8 +5276,8 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
|
|
|
5009
5276
|
retrying.current.delete(order.id);
|
|
5010
5277
|
setRetryingIds(new Set(retrying.current));
|
|
5011
5278
|
}
|
|
5012
|
-
}, className: "rounded-md bg-primary px-4 py-2", children: /* @__PURE__ */
|
|
5013
|
-
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))
|
|
5014
5281
|
] }, order.id);
|
|
5015
5282
|
})
|
|
5016
5283
|
] }, section.title)),
|
|
@@ -5019,15 +5286,15 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
|
|
|
5019
5286
|
}
|
|
5020
5287
|
|
|
5021
5288
|
// src/sale/parked-sales.tsx
|
|
5022
|
-
import { useState as
|
|
5023
|
-
import { ScrollView as ScrollView14, useWindowDimensions as useWindowDimensions3, View as
|
|
5289
|
+
import { useState as useState25 } from "react";
|
|
5290
|
+
import { ScrollView as ScrollView14, useWindowDimensions as useWindowDimensions3, View as View66 } from "react-native";
|
|
5024
5291
|
import { formatMoney as formatMoney18 } from "@tallyui/core";
|
|
5025
|
-
import { Fragment as Fragment11, jsx as
|
|
5292
|
+
import { Fragment as Fragment11, jsx as jsx101, jsxs as jsxs59 } from "react/jsx-runtime";
|
|
5026
5293
|
function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open, onOpenChange, hour12 }) {
|
|
5027
5294
|
const { height: windowHeight } = useWindowDimensions3();
|
|
5028
5295
|
const maxHeight = Math.max(280, windowHeight - 64);
|
|
5029
|
-
const [confirming, setConfirming] =
|
|
5030
|
-
const [error, setError] =
|
|
5296
|
+
const [confirming, setConfirming] = useState25(null);
|
|
5297
|
+
const [error, setError] = useState25("");
|
|
5031
5298
|
const attempt = async (action) => {
|
|
5032
5299
|
setError("");
|
|
5033
5300
|
try {
|
|
@@ -5036,28 +5303,28 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
|
|
|
5036
5303
|
setError(String(e));
|
|
5037
5304
|
}
|
|
5038
5305
|
};
|
|
5039
|
-
return /* @__PURE__ */
|
|
5040
|
-
/* @__PURE__ */
|
|
5041
|
-
/* @__PURE__ */
|
|
5042
|
-
/* @__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 }) }) })
|
|
5043
5310
|
] }),
|
|
5044
|
-
/* @__PURE__ */
|
|
5045
|
-
/* @__PURE__ */
|
|
5311
|
+
/* @__PURE__ */ jsxs59(ScrollView14, { className: "flex-1", contentContainerClassName: "gap-3", children: [
|
|
5312
|
+
/* @__PURE__ */ jsx101(
|
|
5046
5313
|
Button,
|
|
5047
5314
|
{
|
|
5048
5315
|
testID: "parked-sales-park",
|
|
5049
5316
|
accessibilityLabel: "Park this sale",
|
|
5050
5317
|
disabled: sale.order.lineItems.length === 0,
|
|
5051
5318
|
onPress: () => attempt(async () => setError(await (onPark ?? sale.park)() ?? "")),
|
|
5052
|
-
children: /* @__PURE__ */
|
|
5319
|
+
children: /* @__PURE__ */ jsx101(Text, { children: "Park this sale" })
|
|
5053
5320
|
}
|
|
5054
5321
|
),
|
|
5055
|
-
!!error && /* @__PURE__ */
|
|
5056
|
-
parked.length === 0 && /* @__PURE__ */
|
|
5057
|
-
parked.map((row) => /* @__PURE__ */
|
|
5058
|
-
/* @__PURE__ */
|
|
5059
|
-
/* @__PURE__ */
|
|
5060
|
-
/* @__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(
|
|
5061
5328
|
Button,
|
|
5062
5329
|
{
|
|
5063
5330
|
testID: `parked-discard-confirm-${row.id}`,
|
|
@@ -5066,22 +5333,22 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
|
|
|
5066
5333
|
await onDiscard(row.id);
|
|
5067
5334
|
setConfirming(null);
|
|
5068
5335
|
}),
|
|
5069
|
-
children: /* @__PURE__ */
|
|
5336
|
+
children: /* @__PURE__ */ jsx101(Text, { children: "Discard" })
|
|
5070
5337
|
}
|
|
5071
5338
|
),
|
|
5072
|
-
/* @__PURE__ */
|
|
5339
|
+
/* @__PURE__ */ jsx101(Button, { testID: `parked-discard-cancel-${row.id}`, variant: "outline", onPress: () => setConfirming(null), children: /* @__PURE__ */ jsx101(Text, { children: "Cancel" }) })
|
|
5073
5340
|
] })
|
|
5074
|
-
] }) : /* @__PURE__ */
|
|
5075
|
-
/* @__PURE__ */
|
|
5076
|
-
/* @__PURE__ */
|
|
5341
|
+
] }) : /* @__PURE__ */ jsxs59(Fragment11, { children: [
|
|
5342
|
+
/* @__PURE__ */ jsx101(Text, { children: formatStockSyncTime(new Date(row.parkedAt), void 0, hour12) }),
|
|
5343
|
+
/* @__PURE__ */ jsxs59(Text, { children: [
|
|
5077
5344
|
row.itemCount,
|
|
5078
5345
|
" ",
|
|
5079
5346
|
row.itemCount === 1 ? "item" : "items"
|
|
5080
5347
|
] }),
|
|
5081
|
-
/* @__PURE__ */
|
|
5082
|
-
!!row.customerName && /* @__PURE__ */
|
|
5083
|
-
/* @__PURE__ */
|
|
5084
|
-
/* @__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(
|
|
5085
5352
|
Button,
|
|
5086
5353
|
{
|
|
5087
5354
|
testID: `parked-resume-${row.id}`,
|
|
@@ -5091,17 +5358,17 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
|
|
|
5091
5358
|
if (refusal === null) onOpenChange(false);
|
|
5092
5359
|
else setError(refusal);
|
|
5093
5360
|
}),
|
|
5094
|
-
children: /* @__PURE__ */
|
|
5361
|
+
children: /* @__PURE__ */ jsx101(Text, { children: "Resume" })
|
|
5095
5362
|
}
|
|
5096
5363
|
),
|
|
5097
|
-
/* @__PURE__ */
|
|
5364
|
+
/* @__PURE__ */ jsx101(
|
|
5098
5365
|
Button,
|
|
5099
5366
|
{
|
|
5100
5367
|
testID: `parked-discard-${row.id}`,
|
|
5101
5368
|
accessibilityLabel: "Discard parked sale",
|
|
5102
5369
|
variant: "outline",
|
|
5103
5370
|
onPress: () => setConfirming(row.id),
|
|
5104
|
-
children: /* @__PURE__ */
|
|
5371
|
+
children: /* @__PURE__ */ jsx101(Text, { children: "Discard" })
|
|
5105
5372
|
}
|
|
5106
5373
|
)
|
|
5107
5374
|
] })
|
|
@@ -5111,10 +5378,10 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
|
|
|
5111
5378
|
}
|
|
5112
5379
|
|
|
5113
5380
|
// src/layout/pos-layout.tsx
|
|
5114
|
-
import { useState as
|
|
5115
|
-
import { Pressable as
|
|
5116
|
-
import { cn as
|
|
5117
|
-
import { Fragment as Fragment12, jsx 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";
|
|
5118
5385
|
function POSLayout({
|
|
5119
5386
|
browseSlot,
|
|
5120
5387
|
cartSlot,
|
|
@@ -5126,40 +5393,40 @@ function POSLayout({
|
|
|
5126
5393
|
}) {
|
|
5127
5394
|
const { width } = useWindowDimensions4();
|
|
5128
5395
|
const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
|
|
5129
|
-
const [activeTab, setActiveTab] =
|
|
5130
|
-
return /* @__PURE__ */
|
|
5131
|
-
headerSlot && /* @__PURE__ */
|
|
5132
|
-
layout === "split" ? /* @__PURE__ */
|
|
5133
|
-
/* @__PURE__ */
|
|
5134
|
-
/* @__PURE__ */
|
|
5135
|
-
] }) : /* @__PURE__ */
|
|
5136
|
-
/* @__PURE__ */
|
|
5137
|
-
/* @__PURE__ */
|
|
5138
|
-
|
|
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,
|
|
5139
5406
|
{
|
|
5140
5407
|
onPress: () => setActiveTab("browse"),
|
|
5141
|
-
className:
|
|
5142
|
-
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" })
|
|
5143
5410
|
}
|
|
5144
5411
|
),
|
|
5145
|
-
/* @__PURE__ */
|
|
5146
|
-
|
|
5412
|
+
/* @__PURE__ */ jsx102(
|
|
5413
|
+
Pressable35,
|
|
5147
5414
|
{
|
|
5148
5415
|
onPress: () => setActiveTab("cart"),
|
|
5149
|
-
className:
|
|
5150
|
-
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" })
|
|
5151
5418
|
}
|
|
5152
5419
|
)
|
|
5153
5420
|
] }),
|
|
5154
|
-
/* @__PURE__ */
|
|
5421
|
+
/* @__PURE__ */ jsx102(View67, { className: "flex-1", children: activeTab === "browse" ? browseSlot : cartSlot })
|
|
5155
5422
|
] })
|
|
5156
5423
|
] });
|
|
5157
5424
|
}
|
|
5158
5425
|
|
|
5159
5426
|
// src/layout/checkout-layout.tsx
|
|
5160
|
-
import { ScrollView as ScrollView15, View as
|
|
5161
|
-
import { cn as
|
|
5162
|
-
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";
|
|
5163
5430
|
function CheckoutLayout({
|
|
5164
5431
|
summarySlot,
|
|
5165
5432
|
paymentSlot,
|
|
@@ -5171,12 +5438,12 @@ function CheckoutLayout({
|
|
|
5171
5438
|
}) {
|
|
5172
5439
|
const { width } = useWindowDimensions5();
|
|
5173
5440
|
const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
|
|
5174
|
-
return /* @__PURE__ */
|
|
5175
|
-
headerSlot && /* @__PURE__ */
|
|
5176
|
-
layout === "split" ? /* @__PURE__ */
|
|
5177
|
-
/* @__PURE__ */
|
|
5178
|
-
/* @__PURE__ */
|
|
5179
|
-
] }) : /* @__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: [
|
|
5180
5447
|
summarySlot,
|
|
5181
5448
|
paymentSlot
|
|
5182
5449
|
] }) })
|
|
@@ -5184,10 +5451,10 @@ function CheckoutLayout({
|
|
|
5184
5451
|
}
|
|
5185
5452
|
|
|
5186
5453
|
// src/layout/settings-layout.tsx
|
|
5187
|
-
import { useState as
|
|
5188
|
-
import { Pressable as
|
|
5189
|
-
import { cn as
|
|
5190
|
-
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";
|
|
5191
5458
|
function SettingsLayout({
|
|
5192
5459
|
navSlot,
|
|
5193
5460
|
contentSlot,
|
|
@@ -5199,26 +5466,26 @@ function SettingsLayout({
|
|
|
5199
5466
|
}) {
|
|
5200
5467
|
const { width } = useWindowDimensions6();
|
|
5201
5468
|
const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
|
|
5202
|
-
const [showNav, setShowNav] =
|
|
5203
|
-
return /* @__PURE__ */
|
|
5204
|
-
headerSlot && /* @__PURE__ */
|
|
5205
|
-
layout === "split" ? /* @__PURE__ */
|
|
5206
|
-
/* @__PURE__ */
|
|
5207
|
-
/* @__PURE__ */
|
|
5208
|
-
] }) : /* @__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: [
|
|
5209
5476
|
navSlot,
|
|
5210
|
-
/* @__PURE__ */
|
|
5211
|
-
] }) : /* @__PURE__ */
|
|
5212
|
-
/* @__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" }) }),
|
|
5213
5480
|
contentSlot
|
|
5214
5481
|
] }) })
|
|
5215
5482
|
] });
|
|
5216
5483
|
}
|
|
5217
5484
|
|
|
5218
5485
|
// src/layout/live-tab-screen.tsx
|
|
5219
|
-
import { Pressable as
|
|
5220
|
-
import { cn as
|
|
5221
|
-
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";
|
|
5222
5489
|
function LiveTabScreen({
|
|
5223
5490
|
state,
|
|
5224
5491
|
onUseHere,
|
|
@@ -5235,21 +5502,21 @@ function LiveTabScreen({
|
|
|
5235
5502
|
const body = state === "parked" ? parkedBody : blockedBody;
|
|
5236
5503
|
const buttonLabel = state === "parked" ? useHereLabel : reloadLabel;
|
|
5237
5504
|
const onPress = state === "parked" ? onUseHere : onReload;
|
|
5238
|
-
return /* @__PURE__ */
|
|
5239
|
-
/* @__PURE__ */
|
|
5240
|
-
/* @__PURE__ */
|
|
5241
|
-
/* @__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 }) })
|
|
5242
5509
|
] });
|
|
5243
5510
|
}
|
|
5244
5511
|
|
|
5245
5512
|
// src/layout/store-settings-choice-screen.tsx
|
|
5246
|
-
import { useState as
|
|
5247
|
-
import { Pressable as
|
|
5248
|
-
import { cn as
|
|
5249
|
-
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";
|
|
5250
5517
|
function useSectionSelection(options, initialValue) {
|
|
5251
5518
|
const preset = options.length === 1 ? options[0].value : options.find((o) => o.value === initialValue)?.value;
|
|
5252
|
-
return
|
|
5519
|
+
return useState28(preset);
|
|
5253
5520
|
}
|
|
5254
5521
|
function defaultCountryName(code, locale) {
|
|
5255
5522
|
try {
|
|
@@ -5295,41 +5562,41 @@ function StoreSettingsChoiceScreen({
|
|
|
5295
5562
|
else if (initial?.channel !== void 0) choice.channel = initial.channel;
|
|
5296
5563
|
onSubmit(choice);
|
|
5297
5564
|
};
|
|
5298
|
-
return /* @__PURE__ */
|
|
5299
|
-
/* @__PURE__ */
|
|
5300
|
-
/* @__PURE__ */
|
|
5301
|
-
/* @__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 })
|
|
5302
5569
|
] }),
|
|
5303
|
-
showRegions && /* @__PURE__ */
|
|
5304
|
-
showCountries && /* @__PURE__ */
|
|
5305
|
-
showChannels && /* @__PURE__ */
|
|
5306
|
-
/* @__PURE__ */
|
|
5307
|
-
|
|
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,
|
|
5308
5575
|
{
|
|
5309
5576
|
onPress: handleSubmit,
|
|
5310
5577
|
disabled: !complete,
|
|
5311
|
-
className:
|
|
5312
|
-
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 })
|
|
5313
5580
|
}
|
|
5314
5581
|
)
|
|
5315
5582
|
] });
|
|
5316
5583
|
}
|
|
5317
5584
|
function ChoiceSection({ label, options, selected, onSelect }) {
|
|
5318
|
-
return /* @__PURE__ */
|
|
5319
|
-
/* @__PURE__ */
|
|
5320
|
-
/* @__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) => {
|
|
5321
5588
|
const checked = option.value === selected;
|
|
5322
|
-
return /* @__PURE__ */
|
|
5323
|
-
|
|
5589
|
+
return /* @__PURE__ */ jsxs64(
|
|
5590
|
+
Pressable38,
|
|
5324
5591
|
{
|
|
5325
5592
|
onPress: () => onSelect(option.value),
|
|
5326
5593
|
accessibilityRole: "radio",
|
|
5327
5594
|
"aria-checked": checked,
|
|
5328
5595
|
testID: `choice-option-${option.value}`,
|
|
5329
|
-
className:
|
|
5596
|
+
className: cn86("flex-row items-center gap-3 px-4 py-3", index > 0 && "border-t border-border", checked && "bg-primary/10"),
|
|
5330
5597
|
children: [
|
|
5331
|
-
/* @__PURE__ */
|
|
5332
|
-
/* @__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 })
|
|
5333
5600
|
]
|
|
5334
5601
|
},
|
|
5335
5602
|
option.value
|
|
@@ -5474,6 +5741,7 @@ export {
|
|
|
5474
5741
|
ProductPrice,
|
|
5475
5742
|
ProductSku,
|
|
5476
5743
|
ProductStockBadge,
|
|
5744
|
+
ProductTable,
|
|
5477
5745
|
ProductTitle,
|
|
5478
5746
|
ProductVariantPicker,
|
|
5479
5747
|
Progress,
|
|
@@ -5534,6 +5802,7 @@ export {
|
|
|
5534
5802
|
TooltipContent,
|
|
5535
5803
|
TooltipTrigger,
|
|
5536
5804
|
VStack,
|
|
5805
|
+
ViewToggle,
|
|
5537
5806
|
XIcon,
|
|
5538
5807
|
avatarVariants,
|
|
5539
5808
|
badgeTextVariants,
|
|
@@ -5541,6 +5810,7 @@ export {
|
|
|
5541
5810
|
buttonTextVariants,
|
|
5542
5811
|
buttonVariants,
|
|
5543
5812
|
createSvgIcon,
|
|
5813
|
+
defaultProductColumns,
|
|
5544
5814
|
describeRegisterBarPill,
|
|
5545
5815
|
discountLabel,
|
|
5546
5816
|
formatStockSyncTime,
|
|
@@ -5556,6 +5826,7 @@ export {
|
|
|
5556
5826
|
toastVariants,
|
|
5557
5827
|
toggleTextVariants,
|
|
5558
5828
|
toggleVariants,
|
|
5829
|
+
useDefaultProductColumns,
|
|
5559
5830
|
useInputContext,
|
|
5560
5831
|
vstackVariants
|
|
5561
5832
|
};
|