@voyantjs/finance-ui 0.30.6 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/dist/components/invoice-detail-page.d.ts +113 -0
- package/dist/components/invoice-detail-page.d.ts.map +1 -0
- package/dist/components/invoice-detail-page.js +142 -0
- package/dist/components/invoices-page-skeleton.d.ts +5 -0
- package/dist/components/invoices-page-skeleton.d.ts.map +1 -0
- package/dist/components/invoices-page-skeleton.js +13 -0
- package/dist/components/invoices-page.d.ts +6 -0
- package/dist/components/invoices-page.d.ts.map +1 -0
- package/dist/components/invoices-page.js +109 -0
- package/dist/components/payment-detail-page.d.ts +41 -0
- package/dist/components/payment-detail-page.d.ts.map +1 -0
- package/dist/components/payment-detail-page.js +79 -0
- package/dist/components/payments-page-skeleton.d.ts +5 -0
- package/dist/components/payments-page-skeleton.d.ts.map +1 -0
- package/dist/components/payments-page-skeleton.js +13 -0
- package/dist/components/payments-page.d.ts +20 -0
- package/dist/components/payments-page.d.ts.map +1 -0
- package/dist/components/payments-page.js +151 -0
- package/dist/components/taxes-page.d.ts +11 -0
- package/dist/components/taxes-page.d.ts.map +1 -0
- package/dist/components/taxes-page.js +718 -0
- package/dist/i18n/en.d.ts +308 -0
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +308 -0
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/messages.d.ts +193 -1
- package/dist/i18n/messages.d.ts.map +1 -1
- package/dist/i18n/messages.js +11 -0
- package/dist/i18n/provider.d.ts +616 -0
- package/dist/i18n/provider.d.ts.map +1 -1
- package/dist/i18n/ro.d.ts +308 -0
- package/dist/i18n/ro.d.ts.map +1 -1
- package/dist/i18n/ro.js +308 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/package.json +9 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payments-page-skeleton.d.ts","sourceRoot":"","sources":["../../src/components/payments-page-skeleton.tsx"],"names":[],"mappings":"AAcA,wBAAgB,qBAAqB,CAAC,EAAE,IAAQ,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,2CAkCpE;AAED,wBAAgB,oBAAoB,4CAgBnC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Skeleton } from "@voyantjs/ui/components/skeleton";
|
|
3
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@voyantjs/ui/components/table";
|
|
4
|
+
import { useFinanceUiMessagesOrDefault } from "../i18n/index.js";
|
|
5
|
+
const PAYMENT_WIDTHS = ["w-20", "w-32", "w-32", "w-24", "w-20", "w-24", "w-24"];
|
|
6
|
+
export function PaymentsTableSkeleton({ rows = 8 }) {
|
|
7
|
+
const messages = useFinanceUiMessagesOrDefault();
|
|
8
|
+
const columns = messages.paymentsPage.columns;
|
|
9
|
+
return (_jsx("div", { className: "rounded-md border", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: columns.kind }), _jsx(TableHead, { children: columns.reference }), _jsx(TableHead, { children: columns.party }), _jsx(TableHead, { children: columns.amount }), _jsx(TableHead, { children: columns.status }), _jsx(TableHead, { children: columns.date }), _jsx(TableHead, { children: columns.method })] }) }), _jsx(TableBody, { children: Array.from({ length: rows }).map((_, rowIndex) => (_jsx(TableRow, { children: Array.from({ length: 7 }).map((__, columnIndex) => (_jsx(TableCell, { children: _jsx(Skeleton, { className: `h-4 ${PAYMENT_WIDTHS[columnIndex] ?? "w-1/2"}` }) }, columnIndex))) }, rowIndex))) })] }) }));
|
|
10
|
+
}
|
|
11
|
+
export function PaymentsPageSkeleton() {
|
|
12
|
+
return (_jsxs("div", { className: "flex flex-col gap-6 p-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-7 w-32" }), _jsx(Skeleton, { className: "h-4 w-80" })] }), _jsx(Skeleton, { className: "h-9 w-44" })] }), _jsx(Skeleton, { className: "h-9 w-full max-w-sm" }), _jsx(PaymentsTableSkeleton, { rows: 8 })] }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type FinancePaymentKind } from "@voyantjs/finance-react";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
export interface PaymentSupplierOption {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
}
|
|
7
|
+
export interface RecordPaymentDialogRenderProps {
|
|
8
|
+
open: boolean;
|
|
9
|
+
onOpenChange: (open: boolean) => void;
|
|
10
|
+
defaultKind: FinancePaymentKind;
|
|
11
|
+
}
|
|
12
|
+
export interface PaymentsPageProps {
|
|
13
|
+
className?: string;
|
|
14
|
+
onOpenPayment?: (paymentId: string) => void;
|
|
15
|
+
supplierOptions?: PaymentSupplierOption[];
|
|
16
|
+
onSupplierSearchChange?: (search: string) => void;
|
|
17
|
+
renderRecordPaymentDialog?: (props: RecordPaymentDialogRenderProps) => ReactNode;
|
|
18
|
+
}
|
|
19
|
+
export declare function PaymentsPage({ className, onOpenPayment, supplierOptions, onSupplierSearchChange, renderRecordPaymentDialog, }?: PaymentsPageProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=payments-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payments-page.d.ts","sourceRoot":"","sources":["../../src/components/payments-page.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,yBAAyB,CAAA;AA4BhC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAetC,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,WAAW,EAAE,kBAAkB,CAAA;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,eAAe,CAAC,EAAE,qBAAqB,EAAE,CAAA;IACzC,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IACjD,yBAAyB,CAAC,EAAE,CAAC,KAAK,EAAE,8BAA8B,KAAK,SAAS,CAAA;CACjF;AAaD,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,aAAa,EACb,eAAoB,EACpB,sBAAsB,EACtB,yBAAyB,GAC1B,GAAE,iBAAsB,2CAwYxB"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useAllPayments, } from "@voyantjs/finance-react";
|
|
3
|
+
import { formatMessage } from "@voyantjs/i18n";
|
|
4
|
+
import { Badge, Button, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@voyantjs/ui/components";
|
|
5
|
+
import { AsyncCombobox } from "@voyantjs/ui/components/async-combobox";
|
|
6
|
+
import { CurrencyCombobox } from "@voyantjs/ui/components/currency-combobox";
|
|
7
|
+
import { DateRangePicker } from "@voyantjs/ui/components/date-picker";
|
|
8
|
+
import { Popover, PopoverContent, PopoverTrigger } from "@voyantjs/ui/components/popover";
|
|
9
|
+
import { Skeleton } from "@voyantjs/ui/components/skeleton";
|
|
10
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@voyantjs/ui/components/table";
|
|
11
|
+
import { cn } from "@voyantjs/ui/lib/utils";
|
|
12
|
+
import { ArrowDown, ArrowUp, ArrowUpDown, ListFilter, Plus, Search, X } from "lucide-react";
|
|
13
|
+
import { useState } from "react";
|
|
14
|
+
import { useFinanceUiMessagesOrDefault } from "../i18n/index.js";
|
|
15
|
+
import { paymentMethods, supplierPaymentStatuses } from "../i18n/messages.js";
|
|
16
|
+
const PAGE_SIZE = 25;
|
|
17
|
+
const KIND_ALL = "__all__";
|
|
18
|
+
const STATUS_ALL = "__all__";
|
|
19
|
+
const METHOD_ALL = "__all__";
|
|
20
|
+
const PAYMENT_KINDS = ["customer", "supplier"];
|
|
21
|
+
const paymentStatusVariant = {
|
|
22
|
+
pending: "outline",
|
|
23
|
+
completed: "default",
|
|
24
|
+
failed: "destructive",
|
|
25
|
+
refunded: "secondary",
|
|
26
|
+
};
|
|
27
|
+
function formatAmount(cents, currency) {
|
|
28
|
+
return `${(cents / 100).toFixed(2)} ${currency}`;
|
|
29
|
+
}
|
|
30
|
+
export function PaymentsPage({ className, onOpenPayment, supplierOptions = [], onSupplierSearchChange, renderRecordPaymentDialog, } = {}) {
|
|
31
|
+
const messages = useFinanceUiMessagesOrDefault();
|
|
32
|
+
const [recordDialogOpen, setRecordDialogOpen] = useState(false);
|
|
33
|
+
const [search, setSearch] = useState("");
|
|
34
|
+
const [kind, setKind] = useState(KIND_ALL);
|
|
35
|
+
const [status, setStatus] = useState(STATUS_ALL);
|
|
36
|
+
const [method, setMethod] = useState(METHOD_ALL);
|
|
37
|
+
const [currency, setCurrency] = useState(null);
|
|
38
|
+
const [supplierId, setSupplierId] = useState(null);
|
|
39
|
+
const [selectedSupplier, setSelectedSupplier] = useState(null);
|
|
40
|
+
const [paymentDateRange, setPaymentDateRange] = useState(null);
|
|
41
|
+
const [sortBy, setSortBy] = useState("createdAt");
|
|
42
|
+
const [sortDir, setSortDir] = useState("desc");
|
|
43
|
+
const [pageIndex, setPageIndex] = useState(0);
|
|
44
|
+
const [filterPopoverOpen, setFilterPopoverOpen] = useState(false);
|
|
45
|
+
const { data, isPending, isFetching, isError } = useAllPayments({
|
|
46
|
+
search: search || undefined,
|
|
47
|
+
kind: kind === KIND_ALL ? undefined : kind,
|
|
48
|
+
status: status === STATUS_ALL ? undefined : status,
|
|
49
|
+
paymentMethod: method === METHOD_ALL ? undefined : method,
|
|
50
|
+
currency: currency ?? undefined,
|
|
51
|
+
supplierId: supplierId ?? undefined,
|
|
52
|
+
paymentDateFrom: paymentDateRange?.from ?? undefined,
|
|
53
|
+
paymentDateTo: paymentDateRange?.to ?? undefined,
|
|
54
|
+
sortBy,
|
|
55
|
+
sortDir,
|
|
56
|
+
limit: PAGE_SIZE,
|
|
57
|
+
offset: pageIndex * PAGE_SIZE,
|
|
58
|
+
});
|
|
59
|
+
const payments = data?.data ?? [];
|
|
60
|
+
const total = data?.total ?? 0;
|
|
61
|
+
const page = pageIndex + 1;
|
|
62
|
+
const pageCount = Math.max(1, Math.ceil(total / PAGE_SIZE));
|
|
63
|
+
const showSkeleton = isPending || (isFetching && payments.length === 0);
|
|
64
|
+
const resetPage = () => setPageIndex(0);
|
|
65
|
+
const handleSort = (field) => {
|
|
66
|
+
resetPage();
|
|
67
|
+
if (sortBy !== field) {
|
|
68
|
+
setSortBy(field);
|
|
69
|
+
setSortDir("asc");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (sortDir === "asc") {
|
|
73
|
+
setSortDir("desc");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
setSortBy("createdAt");
|
|
77
|
+
setSortDir("desc");
|
|
78
|
+
};
|
|
79
|
+
const activeFilterCount = (kind !== KIND_ALL ? 1 : 0) +
|
|
80
|
+
(status !== STATUS_ALL ? 1 : 0) +
|
|
81
|
+
(method !== METHOD_ALL ? 1 : 0) +
|
|
82
|
+
(currency !== null ? 1 : 0) +
|
|
83
|
+
(supplierId !== null ? 1 : 0) +
|
|
84
|
+
(paymentDateRange?.from || paymentDateRange?.to ? 1 : 0);
|
|
85
|
+
const hasActiveFilters = activeFilterCount > 0 || search !== "";
|
|
86
|
+
const clearFilters = () => {
|
|
87
|
+
setSearch("");
|
|
88
|
+
setKind(KIND_ALL);
|
|
89
|
+
setStatus(STATUS_ALL);
|
|
90
|
+
setMethod(METHOD_ALL);
|
|
91
|
+
setCurrency(null);
|
|
92
|
+
setSupplierId(null);
|
|
93
|
+
setSelectedSupplier(null);
|
|
94
|
+
setPaymentDateRange(null);
|
|
95
|
+
onSupplierSearchChange?.("");
|
|
96
|
+
resetPage();
|
|
97
|
+
};
|
|
98
|
+
const f = messages.paymentsPage;
|
|
99
|
+
return (_jsxs("div", { className: cn("flex flex-col gap-6 p-6", className), children: [_jsx("div", { className: "flex items-center justify-between", children: _jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-bold tracking-tight", children: f.title }), _jsx("p", { className: "text-sm text-muted-foreground", children: f.description })] }) }), _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("div", { className: "relative min-w-[14rem] flex-1", children: [_jsx(Label, { htmlFor: "payments-search", className: "sr-only", children: f.searchPlaceholder }), _jsx(Search, { className: "absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground", "aria-hidden": "true" }), _jsx(Input, { id: "payments-search", placeholder: f.searchPlaceholder, value: search, onChange: (event) => {
|
|
100
|
+
setSearch(event.target.value);
|
|
101
|
+
resetPage();
|
|
102
|
+
}, className: "pl-9" })] }), _jsxs(Popover, { open: filterPopoverOpen, onOpenChange: setFilterPopoverOpen, children: [_jsx(PopoverTrigger, { render: _jsxs(Button, { variant: "outline", size: "default", children: [_jsx(ListFilter, { className: "mr-2 size-4", "aria-hidden": "true" }), f.filters.button, activeFilterCount > 0 && (_jsx(Badge, { variant: "secondary", className: "ml-2 px-1.5", children: activeFilterCount }))] }) }), _jsx(PopoverContent, { align: "start", className: "w-[24rem] p-4", children: _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "payments-filter-kind", children: f.filters.kindLabel }), _jsxs(Select, { value: kind, onValueChange: (value) => {
|
|
103
|
+
setKind(value ?? KIND_ALL);
|
|
104
|
+
resetPage();
|
|
105
|
+
}, children: [_jsx(SelectTrigger, { id: "payments-filter-kind", className: "w-full", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: KIND_ALL, children: f.filters.kindAll }), PAYMENT_KINDS.map((value) => (_jsx(SelectItem, { value: value, children: f.kindLabels[value] }, value)))] })] })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "payments-filter-status", children: f.filters.statusLabel }), _jsxs(Select, { value: status, onValueChange: (value) => {
|
|
106
|
+
setStatus(value ?? STATUS_ALL);
|
|
107
|
+
resetPage();
|
|
108
|
+
}, children: [_jsx(SelectTrigger, { id: "payments-filter-status", className: "w-full", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: STATUS_ALL, children: f.filters.statusAll }), supplierPaymentStatuses.map((value) => (_jsx(SelectItem, { value: value, children: messages.common.supplierPaymentStatusLabels[value] }, value)))] })] })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "payments-filter-method", children: f.filters.methodLabel }), _jsxs(Select, { value: method, onValueChange: (value) => {
|
|
109
|
+
setMethod(value ?? METHOD_ALL);
|
|
110
|
+
resetPage();
|
|
111
|
+
}, children: [_jsx(SelectTrigger, { id: "payments-filter-method", className: "w-full", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: METHOD_ALL, children: f.filters.methodAll }), paymentMethods.map((value) => (_jsx(SelectItem, { value: value, children: messages.common.paymentMethodLabels[value] }, value)))] })] })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { children: f.filters.supplierLabel }), _jsx(AsyncCombobox, { value: supplierId, onChange: (value) => {
|
|
112
|
+
setSupplierId(value);
|
|
113
|
+
if (!value)
|
|
114
|
+
setSelectedSupplier(null);
|
|
115
|
+
else {
|
|
116
|
+
const match = supplierOptions.find((supplier) => supplier.id === value);
|
|
117
|
+
if (match)
|
|
118
|
+
setSelectedSupplier(match);
|
|
119
|
+
}
|
|
120
|
+
resetPage();
|
|
121
|
+
}, items: supplierOptions, selectedItem: selectedSupplier, getKey: (supplier) => supplier.id, getLabel: (supplier) => supplier.name, onSearchChange: onSupplierSearchChange, placeholder: f.filters.supplierAny, emptyText: f.filters.supplierEmpty })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { children: f.filters.currencyLabel }), _jsx(CurrencyCombobox, { value: currency, onChange: (value) => {
|
|
122
|
+
setCurrency(value);
|
|
123
|
+
resetPage();
|
|
124
|
+
}, placeholder: f.filters.currencyAny })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { children: f.filters.paymentDateLabel }), _jsx(DateRangePicker, { value: paymentDateRange, onChange: (value) => {
|
|
125
|
+
setPaymentDateRange(value);
|
|
126
|
+
resetPage();
|
|
127
|
+
}, placeholder: f.filters.dateAny, clearable: true, className: "w-full" })] })] }) })] }), hasActiveFilters && (_jsxs(Button, { variant: "ghost", size: "sm", onClick: clearFilters, children: [_jsx(X, { className: "mr-1 size-4", "aria-hidden": "true" }), f.filters.clear] })), renderRecordPaymentDialog ? (_jsx("div", { className: "ml-auto", children: _jsxs(Button, { onClick: () => setRecordDialogOpen(true), children: [_jsx(Plus, { className: "mr-2 size-4", "aria-hidden": "true" }), f.actions.recordPayment] }) })) : null] }), _jsx("div", { className: "rounded-md border", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: f.columns.kind }), _jsx(TableHead, { children: f.columns.reference }), _jsx(TableHead, { children: f.columns.party }), _jsx(TableHead, { children: _jsx(SortHeader, { label: f.columns.amount, field: "amountCents", sortBy: sortBy, sortDir: sortDir, onSort: handleSort }) }), _jsx(TableHead, { children: _jsx(SortHeader, { label: f.columns.status, field: "status", sortBy: sortBy, sortDir: sortDir, onSort: handleSort }) }), _jsx(TableHead, { children: _jsx(SortHeader, { label: f.columns.date, field: "paymentDate", sortBy: sortBy, sortDir: sortDir, onSort: handleSort }) }), _jsx(TableHead, { children: f.columns.method })] }) }), _jsx(TableBody, { children: showSkeleton ? (_jsx(PaymentRowSkeleton, { rows: 6 })) : isError ? (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 7, className: "h-24 text-center text-sm text-destructive", children: f.loadFailed }) })) : payments.length === 0 ? (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 7, className: "h-24 text-center text-sm text-muted-foreground", children: f.empty }) })) : (payments.map((row) => {
|
|
128
|
+
const reference = row.kind === "customer" ? row.invoiceNumber : row.bookingNumber;
|
|
129
|
+
const party = row.kind === "supplier"
|
|
130
|
+
? (row.supplierName ?? f.noValue)
|
|
131
|
+
: (row.personName ?? row.organizationName ?? f.noValue);
|
|
132
|
+
return (_jsxs(TableRow, { onClick: () => onOpenPayment?.(row.id), className: cn(onOpenPayment && "cursor-pointer"), children: [_jsx(TableCell, { children: _jsx(Badge, { variant: "outline", className: "capitalize", children: f.kindLabels[row.kind] }) }), _jsx(TableCell, { children: _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "font-medium", children: reference ?? f.noValue }), row.referenceNumber ? (_jsx("span", { className: "text-xs text-muted-foreground", children: row.referenceNumber })) : null] }) }), _jsx(TableCell, { children: party }), _jsx(TableCell, { className: "font-mono", children: formatAmount(row.amountCents, row.currency) }), _jsx(TableCell, { children: _jsx(Badge, { variant: paymentStatusVariant[row.status] ?? "secondary", className: "capitalize", children: messages.common.supplierPaymentStatusLabels[row.status] }) }), _jsx(TableCell, { children: row.paymentDate }), _jsx(TableCell, { className: "capitalize", children: messages.common.paymentMethodLabels[row.paymentMethod] ?? row.paymentMethod })] }, `${row.kind}-${row.id}`));
|
|
133
|
+
})) })] }) }), _jsx(PaginationBar, { shown: payments.length, total: total, page: page, pageCount: pageCount, onPrevious: () => setPageIndex((prev) => Math.max(0, prev - 1)), onNext: () => setPageIndex((prev) => prev + 1), canGoBack: pageIndex > 0, canGoForward: (pageIndex + 1) * PAGE_SIZE < total })] }), renderRecordPaymentDialog?.({
|
|
134
|
+
open: recordDialogOpen,
|
|
135
|
+
onOpenChange: setRecordDialogOpen,
|
|
136
|
+
defaultKind: kind === KIND_ALL ? "customer" : kind,
|
|
137
|
+
})] }));
|
|
138
|
+
}
|
|
139
|
+
function SortHeader({ label, field, sortBy, sortDir, onSort, }) {
|
|
140
|
+
const active = sortBy === field;
|
|
141
|
+
const Icon = active ? (sortDir === "asc" ? ArrowUp : ArrowDown) : ArrowUpDown;
|
|
142
|
+
return (_jsxs("button", { type: "button", onClick: () => onSort(field), className: "-ml-2 inline-flex h-8 items-center gap-1 rounded-sm px-2 hover:bg-muted/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: [_jsx("span", { children: label }), _jsx(Icon, { className: `size-3.5 ${active ? "text-foreground" : "text-muted-foreground/60"}`, "aria-hidden": true })] }));
|
|
143
|
+
}
|
|
144
|
+
function PaginationBar({ shown, total, page, pageCount, onPrevious, onNext, canGoBack, canGoForward, }) {
|
|
145
|
+
const messages = useFinanceUiMessagesOrDefault();
|
|
146
|
+
const f = messages.paymentsPage.pagination;
|
|
147
|
+
return (_jsxs("div", { className: "flex items-center justify-between text-sm text-muted-foreground", children: [_jsx("span", { children: formatMessage(f.showing, { count: shown, total }) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "outline", size: "sm", disabled: !canGoBack, onClick: onPrevious, children: f.previous }), _jsx("span", { children: formatMessage(f.page, { page, pageCount }) }), _jsx(Button, { variant: "outline", size: "sm", disabled: !canGoForward, onClick: onNext, children: f.next })] })] }));
|
|
148
|
+
}
|
|
149
|
+
function PaymentRowSkeleton({ rows }) {
|
|
150
|
+
return (_jsx(_Fragment, { children: Array.from({ length: rows }).map((_, idx) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsx(Skeleton, { className: "h-5 w-20 rounded-full" }) }), _jsx(TableCell, { children: _jsx(Skeleton, { className: "h-4 w-32" }) }), _jsx(TableCell, { children: _jsx(Skeleton, { className: "h-4 w-24" }) }), _jsx(TableCell, { children: _jsx(Skeleton, { className: "h-5 w-20 rounded-full" }) }), _jsx(TableCell, { children: _jsx(Skeleton, { className: "h-4 w-24" }) }), _jsx(TableCell, { children: _jsx(Skeleton, { className: "h-4 w-24" }) }), _jsx(TableCell, { children: _jsx(Skeleton, { className: "h-4 w-32" }) })] }, `skeleton-${idx}`))) }));
|
|
151
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface TaxesPageApi {
|
|
2
|
+
get: <T = unknown>(path: string) => Promise<T>;
|
|
3
|
+
post: <T = unknown>(path: string, body?: unknown) => Promise<T>;
|
|
4
|
+
patch: <T = unknown>(path: string, body?: unknown) => Promise<T>;
|
|
5
|
+
delete: <T = unknown>(path: string) => Promise<T>;
|
|
6
|
+
}
|
|
7
|
+
export interface TaxesPageProps {
|
|
8
|
+
api?: TaxesPageApi;
|
|
9
|
+
}
|
|
10
|
+
export declare function TaxesPage({ api: apiProp }?: TaxesPageProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=taxes-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taxes-page.d.ts","sourceRoot":"","sources":["../../src/components/taxes-page.tsx"],"names":[],"mappings":"AAoDA,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IAC9C,IAAI,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IAC/D,KAAK,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IAChE,MAAM,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;CAClD;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,YAAY,CAAA;CACnB;AAyaD,wBAAgB,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAE,cAAmB,2CAG9D"}
|