@powerhousedao/contributor-billing 0.0.97 → 0.0.99
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/editors/invoice/components/lineItemCard.d.ts +21 -0
- package/dist/editors/invoice/components/lineItemCard.d.ts.map +1 -0
- package/dist/editors/invoice/components/lineItemCard.js +23 -0
- package/dist/editors/invoice/components/lineItemMobileModal.d.ts +33 -0
- package/dist/editors/invoice/components/lineItemMobileModal.d.ts.map +1 -0
- package/dist/editors/invoice/components/lineItemMobileModal.js +73 -0
- package/dist/editors/invoice/components/lineItemsEmptyState.d.ts +6 -0
- package/dist/editors/invoice/components/lineItemsEmptyState.d.ts.map +1 -0
- package/dist/editors/invoice/components/lineItemsEmptyState.js +5 -0
- package/dist/editors/invoice/editor.d.ts.map +1 -1
- package/dist/editors/invoice/editor.js +37 -19
- package/dist/editors/invoice/ingestPDF.js +1 -1
- package/dist/editors/invoice/invoiceToGnosis.js +1 -1
- package/dist/editors/invoice/lineItemTags/lineItemTags.d.ts.map +1 -1
- package/dist/editors/invoice/lineItemTags/lineItemTags.js +25 -3
- package/dist/editors/invoice/lineItemTags/tagCard.d.ts +15 -0
- package/dist/editors/invoice/lineItemTags/tagCard.d.ts.map +1 -0
- package/dist/editors/invoice/lineItemTags/tagCard.js +13 -0
- package/dist/editors/invoice/lineItemTags/tagMobileModal.d.ts +18 -0
- package/dist/editors/invoice/lineItemTags/tagMobileModal.d.ts.map +1 -0
- package/dist/editors/invoice/lineItemTags/tagMobileModal.js +71 -0
- package/dist/editors/invoice/lineItems.d.ts.map +1 -1
- package/dist/editors/invoice/lineItems.js +73 -37
- package/dist/editors/invoice/requestFinance.js +1 -1
- package/dist/editors/invoice/uploadPdfChunked.js +1 -1
- package/dist/style.css +171 -6
- package/dist/tailwind.config.js +1 -0
- package/package.json +13 -12
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
type LineItem = {
|
|
2
|
+
currency: string;
|
|
3
|
+
description: string;
|
|
4
|
+
id: string;
|
|
5
|
+
quantity: number;
|
|
6
|
+
taxPercent: number;
|
|
7
|
+
totalPriceTaxExcl: number;
|
|
8
|
+
totalPriceTaxIncl: number;
|
|
9
|
+
unitPriceTaxExcl: number;
|
|
10
|
+
unitPriceTaxIncl: number;
|
|
11
|
+
lineItemTag: any[];
|
|
12
|
+
};
|
|
13
|
+
type LineItemCardProps = {
|
|
14
|
+
item: LineItem;
|
|
15
|
+
onEdit: () => void;
|
|
16
|
+
onDelete: () => void;
|
|
17
|
+
currency: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function LineItemCard({ item, onEdit, onDelete, currency, }: LineItemCardProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=lineItemCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineItemCard.d.ts","sourceRoot":"","sources":["../../../../editors/invoice/components/lineItemCard.tsx"],"names":[],"mappings":"AAIA,KAAK,QAAQ,GAAG;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,GAAG,EAAE,CAAC;CACpB,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,QAAQ,GACT,EAAE,iBAAiB,2CAkGnB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Edit, Trash2, MoreVertical } from "lucide-react";
|
|
3
|
+
import { formatNumber } from "../lineItems.js";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
export function LineItemCard({ item, onEdit, onDelete, currency, }) {
|
|
6
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
7
|
+
const [showMenu, setShowMenu] = useState(false);
|
|
8
|
+
const tagCount = item.lineItemTag?.length || 0;
|
|
9
|
+
return (_jsxs("div", { className: "bg-white border border-gray-200 rounded-lg mb-3 overflow-hidden", children: [_jsxs("div", { className: "p-4 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [_jsxs("div", { className: "flex items-start justify-between mb-2", children: [_jsx("div", { className: "flex-1", children: _jsx("h5", { className: "font-medium text-gray-900 text-sm", children: item.description || "Untitled Item" }) }), _jsx("button", { className: "p-1 hover:bg-gray-100 rounded", onClick: (e) => {
|
|
10
|
+
e.stopPropagation();
|
|
11
|
+
setShowMenu(!showMenu);
|
|
12
|
+
}, children: _jsx(MoreVertical, { className: "w-5 h-5 text-gray-500" }) })] }), _jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsxs("div", { className: "flex items-center gap-4 text-gray-600", children: [_jsxs("span", { children: ["Qty: ", item.quantity] }), _jsx("span", { children: "\u2022" }), _jsxs("span", { children: [currency, " ", formatNumber(item.unitPriceTaxExcl)] })] }), _jsxs("div", { className: "font-semibold text-gray-900", children: [currency, " ", formatNumber(item.totalPriceTaxIncl)] })] }), isExpanded && (_jsxs("div", { className: "mt-3 pt-3 border-t border-gray-100 space-y-2 text-sm", children: [_jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-gray-600", children: "Tax %:" }), _jsxs("span", { className: "text-gray-900", children: [item.taxPercent, "%"] })] }), _jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-gray-600", children: "Total (excl. tax):" }), _jsxs("span", { className: "text-gray-900", children: [currency, " ", formatNumber(item.totalPriceTaxExcl)] })] }), _jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-gray-600", children: "Unit Price (incl. tax):" }), _jsxs("span", { className: "text-gray-900", children: [currency, " ", formatNumber(item.unitPriceTaxIncl)] })] })] }))] }), showMenu && (_jsxs("div", { className: "border-t border-gray-200 bg-gray-50", children: [_jsxs("button", { className: "w-full flex items-center gap-3 px-4 py-3 text-sm text-left hover:bg-gray-100 transition-colors", onClick: (e) => {
|
|
13
|
+
e.stopPropagation();
|
|
14
|
+
onEdit();
|
|
15
|
+
setShowMenu(false);
|
|
16
|
+
}, children: [_jsx(Edit, { className: "w-4 h-4 text-blue-600" }), _jsx("span", { children: "Edit Line Item" })] }), _jsxs("button", { className: "w-full flex items-center gap-3 px-4 py-3 text-sm text-left hover:bg-red-50 text-red-600 transition-colors", onClick: (e) => {
|
|
17
|
+
e.stopPropagation();
|
|
18
|
+
if (confirm("Delete this line item?")) {
|
|
19
|
+
onDelete();
|
|
20
|
+
}
|
|
21
|
+
setShowMenu(false);
|
|
22
|
+
}, children: [_jsx(Trash2, { className: "w-4 h-4" }), _jsx("span", { children: "Delete" })] })] }))] }));
|
|
23
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
type LineItem = {
|
|
2
|
+
currency: string;
|
|
3
|
+
description: string;
|
|
4
|
+
id: string;
|
|
5
|
+
quantity: number;
|
|
6
|
+
taxPercent: number;
|
|
7
|
+
totalPriceTaxExcl: number;
|
|
8
|
+
totalPriceTaxIncl: number;
|
|
9
|
+
unitPriceTaxExcl: number;
|
|
10
|
+
unitPriceTaxIncl: number;
|
|
11
|
+
lineItemTag: any[];
|
|
12
|
+
};
|
|
13
|
+
type EditLineItemInput = {
|
|
14
|
+
id: string;
|
|
15
|
+
currency?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
quantity?: number;
|
|
18
|
+
taxPercent?: number;
|
|
19
|
+
totalPriceTaxExcl?: number;
|
|
20
|
+
totalPriceTaxIncl?: number;
|
|
21
|
+
unitPriceTaxExcl?: number;
|
|
22
|
+
unitPriceTaxIncl?: number;
|
|
23
|
+
};
|
|
24
|
+
type LineItemMobileModalProps = {
|
|
25
|
+
item?: Partial<LineItem>;
|
|
26
|
+
currency: string;
|
|
27
|
+
onSave: (item: EditLineItemInput) => void;
|
|
28
|
+
onCancel: () => void;
|
|
29
|
+
isNew?: boolean;
|
|
30
|
+
};
|
|
31
|
+
export declare function LineItemMobileModal({ item, currency, onSave, onCancel, isNew, }: LineItemMobileModalProps): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=lineItemMobileModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineItemMobileModal.d.ts","sourceRoot":"","sources":["../../../../editors/invoice/components/lineItemMobileModal.tsx"],"names":[],"mappings":"AAMA,KAAK,QAAQ,GAAG;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,GAAG,EAAE,CAAC;CACpB,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC1C,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,KAAa,GACd,EAAE,wBAAwB,2CA6M1B"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { X } from "lucide-react";
|
|
3
|
+
import { useState, useMemo, useEffect } from "react";
|
|
4
|
+
import { generateId } from "document-model";
|
|
5
|
+
import { InputField } from "./inputField.js";
|
|
6
|
+
import { NumberForm } from "./numberForm.js";
|
|
7
|
+
export function LineItemMobileModal({ item, currency, onSave, onCancel, isNew = false, }) {
|
|
8
|
+
const [description, setDescription] = useState(item?.description ?? "");
|
|
9
|
+
const [quantity, setQuantity] = useState(item?.quantity ?? 1);
|
|
10
|
+
const [unitPriceTaxExcl, setUnitPriceTaxExcl] = useState(item?.unitPriceTaxExcl ?? 0);
|
|
11
|
+
const [taxPercent, setTaxPercent] = useState(item?.taxPercent ?? 0);
|
|
12
|
+
// Update state when item changes
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
setDescription(item?.description ?? "");
|
|
15
|
+
setQuantity(item?.quantity ?? 1);
|
|
16
|
+
setUnitPriceTaxExcl(item?.unitPriceTaxExcl ?? 0);
|
|
17
|
+
setTaxPercent(item?.taxPercent ?? 0);
|
|
18
|
+
}, [item]);
|
|
19
|
+
// Calculate totals
|
|
20
|
+
const calculatedValues = useMemo(() => {
|
|
21
|
+
const qty = typeof quantity === "string" ? parseFloat(quantity) || 1 : quantity;
|
|
22
|
+
const unitPrice = typeof unitPriceTaxExcl === "string"
|
|
23
|
+
? parseFloat(unitPriceTaxExcl) || 0
|
|
24
|
+
: unitPriceTaxExcl;
|
|
25
|
+
const tax = typeof taxPercent === "string" ? parseFloat(taxPercent) || 0 : taxPercent;
|
|
26
|
+
const taxRate = tax / 100;
|
|
27
|
+
const unitPriceTaxIncl = unitPrice * (1 + taxRate);
|
|
28
|
+
const totalPriceTaxExcl = qty * unitPrice;
|
|
29
|
+
const totalPriceTaxIncl = qty * unitPriceTaxIncl;
|
|
30
|
+
return {
|
|
31
|
+
quantity: qty,
|
|
32
|
+
unitPriceTaxExcl: unitPrice,
|
|
33
|
+
unitPriceTaxIncl,
|
|
34
|
+
taxPercent: tax,
|
|
35
|
+
totalPriceTaxExcl,
|
|
36
|
+
totalPriceTaxIncl,
|
|
37
|
+
};
|
|
38
|
+
}, [quantity, unitPriceTaxExcl, taxPercent]);
|
|
39
|
+
const handleSave = () => {
|
|
40
|
+
// For edit: use existing ID (if valid), For new or empty ID: generate ID
|
|
41
|
+
const needsNewId = isNew || !item?.id || item.id === '';
|
|
42
|
+
const lineItem = {
|
|
43
|
+
id: needsNewId ? generateId() : item.id,
|
|
44
|
+
currency,
|
|
45
|
+
description,
|
|
46
|
+
quantity: calculatedValues.quantity,
|
|
47
|
+
unitPriceTaxExcl: calculatedValues.unitPriceTaxExcl,
|
|
48
|
+
unitPriceTaxIncl: calculatedValues.unitPriceTaxIncl,
|
|
49
|
+
taxPercent: calculatedValues.taxPercent,
|
|
50
|
+
totalPriceTaxExcl: calculatedValues.totalPriceTaxExcl,
|
|
51
|
+
totalPriceTaxIncl: calculatedValues.totalPriceTaxIncl,
|
|
52
|
+
};
|
|
53
|
+
onSave(lineItem);
|
|
54
|
+
};
|
|
55
|
+
// Prevent body scroll when modal is open
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
document.body.style.overflow = "hidden";
|
|
58
|
+
return () => {
|
|
59
|
+
document.body.style.overflow = "unset";
|
|
60
|
+
};
|
|
61
|
+
}, []);
|
|
62
|
+
return (_jsxs("div", { className: "fixed inset-0 z-50 bg-white flex flex-col", children: [_jsxs("div", { className: "flex items-center justify-between p-4 border-b border-gray-200 bg-white", children: [_jsx("button", { onClick: onCancel, className: "p-2 hover:bg-gray-100 rounded-full transition-colors", "aria-label": "Cancel", children: _jsx(X, { className: "w-5 h-5" }) }), _jsx("h2", { className: "text-lg font-semibold", children: isNew ? "Add Line Item" : "Edit Line Item" }), _jsx("button", { onClick: handleSave, className: "px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors font-medium text-sm", children: "Save" })] }), _jsxs("div", { className: "flex-1 overflow-y-auto p-4 space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Description *" }), _jsx(InputField, { value: description, handleInputChange: (e) => setDescription(e.target.value), onBlur: () => { }, placeholder: "Enter item description", className: "w-full" })] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Quantity *" }), _jsx(NumberForm, { number: quantity, handleInputChange: (e) => setQuantity(e.target.value), precision: 0, className: "w-full" })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Unit Price *" }), _jsx(NumberForm, { number: unitPriceTaxExcl, handleInputChange: (e) => setUnitPriceTaxExcl(e.target.value), precision: 2, className: "w-full" })] })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Tax %" }), _jsx(NumberForm, { number: taxPercent, handleInputChange: (e) => setTaxPercent(e.target.value), precision: 2, className: "w-full" })] }), _jsxs("div", { className: "bg-gray-50 rounded-lg p-4 space-y-3", children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-2", children: "Calculated Totals" }), _jsxs("div", { className: "flex justify-between text-sm", children: [_jsx("span", { className: "text-gray-600", children: "Total (excl. tax):" }), _jsxs("span", { className: "font-medium text-gray-900", children: [currency, " ", calculatedValues.totalPriceTaxExcl.toLocaleString("en-US", {
|
|
63
|
+
minimumFractionDigits: 2,
|
|
64
|
+
maximumFractionDigits: 2,
|
|
65
|
+
})] })] }), _jsxs("div", { className: "flex justify-between text-sm", children: [_jsx("span", { className: "text-gray-600", children: "Tax amount:" }), _jsxs("span", { className: "font-medium text-gray-900", children: [currency, " ", (calculatedValues.totalPriceTaxIncl -
|
|
66
|
+
calculatedValues.totalPriceTaxExcl).toLocaleString("en-US", {
|
|
67
|
+
minimumFractionDigits: 2,
|
|
68
|
+
maximumFractionDigits: 2,
|
|
69
|
+
})] })] }), _jsxs("div", { className: "flex justify-between text-sm pt-2 border-t border-gray-200", children: [_jsx("span", { className: "text-gray-900 font-semibold", children: "Total (incl. tax):" }), _jsxs("span", { className: "font-bold text-gray-900", children: [currency, " ", calculatedValues.totalPriceTaxIncl.toLocaleString("en-US", {
|
|
70
|
+
minimumFractionDigits: 2,
|
|
71
|
+
maximumFractionDigits: 2,
|
|
72
|
+
})] })] })] })] }), _jsxs("div", { className: "border-t border-gray-200 p-4 bg-white flex gap-3", children: [_jsx("button", { onClick: onCancel, className: "flex-1 px-4 py-3 border border-gray-300 rounded-md hover:bg-gray-50 transition-colors font-medium text-gray-700", children: "Cancel" }), _jsx("button", { onClick: handleSave, className: "flex-1 px-4 py-3 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors font-medium", children: "Save Line Item" })] })] }));
|
|
73
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineItemsEmptyState.d.ts","sourceRoot":"","sources":["../../../../editors/invoice/components/lineItemsEmptyState.tsx"],"names":[],"mappings":"AAEA,KAAK,wBAAwB,GAAG;IAC9B,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,EAAE,SAAS,EAAE,EAAE,wBAAwB,2CAoB1E"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { FileText } from "lucide-react";
|
|
3
|
+
export function LineItemsEmptyState({ onAddItem }) {
|
|
4
|
+
return (_jsxs("div", { className: "flex flex-col items-center justify-center py-6 px-4 bg-gray-50 rounded-lg border-2 border-dashed border-gray-300", children: [_jsx("div", { className: "w-10 h-10 mb-3 bg-gray-100 rounded-full flex items-center justify-center", children: _jsx(FileText, { className: "w-5 h-5 text-gray-400" }) }), _jsx("h3", { className: "text-base font-semibold text-gray-900 mb-1", children: "No line items yet" }), _jsx("p", { className: "text-sm text-gray-600 mb-4 text-center max-w-xs", children: "Add your first line item to start building your invoice" }), _jsx("button", { onClick: onAddItem, className: "inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors font-medium text-sm", children: "Add Your First Line Item" })] }));
|
|
5
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/invoice/editor.tsx"],"names":[],"mappings":"AA6CA,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,KAAK,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/invoice/editor.tsx"],"names":[],"mappings":"AA6CA,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,KAAK,EAAE,GAAG,kDA0mCxC"}
|
|
@@ -30,6 +30,8 @@ function isFiatCurrency(currency) {
|
|
|
30
30
|
export default function Editor(props) {
|
|
31
31
|
const [doc, dispatch] = useDocumentById(props.documentId);
|
|
32
32
|
const state = doc?.state.global;
|
|
33
|
+
// Mobile header menu state
|
|
34
|
+
const [mobileHeaderOpen, setMobileHeaderOpen] = useState(false);
|
|
33
35
|
if (!state) {
|
|
34
36
|
console.log("Document state not found from document id", props.documentId);
|
|
35
37
|
return null;
|
|
@@ -363,23 +365,39 @@ export default function Editor(props) {
|
|
|
363
365
|
reportPaymentIssue: "Confirm",
|
|
364
366
|
// Add more labels as needed
|
|
365
367
|
};
|
|
366
|
-
return (_jsxs("div", { className: "editor-container", children: [_jsx(ToastContainer, { position: "bottom-right", autoClose: 5000, hideProgressBar: false, newestOnTop: false, closeOnClick: false, rtl: false, pauseOnFocusLoss: true, draggable: true, pauseOnHover: true, theme: "light" }), _jsxs("div", { className: "flex items-center justify-between gap-4
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
368
|
+
return (_jsxs("div", { className: "editor-container", children: [_jsx(ToastContainer, { position: "bottom-right", autoClose: 5000, hideProgressBar: false, newestOnTop: false, closeOnClick: false, rtl: false, pauseOnFocusLoss: true, draggable: true, pauseOnHover: true, theme: "light" }), _jsxs("div", { className: "mb-6", children: [_jsxs("div", { className: "hidden md:flex flex-row items-center justify-between gap-4", children: [_jsxs("div", { className: "flex flex-row items-center gap-4 flex-wrap", children: [_jsx("h1", { className: "text-3xl font-bold whitespace-nowrap", children: "Invoice" }), _jsx(InputField, { placeholder: "Add invoice number", value: invoiceNoInput, handleInputChange: (e) => setInvoiceNoInput(e.target.value), onBlur: (e) => {
|
|
369
|
+
const newValue = e.target.value;
|
|
370
|
+
if (newValue !== state.invoiceNo) {
|
|
371
|
+
dispatch(actions.editInvoice({ invoiceNo: newValue }));
|
|
372
|
+
}
|
|
373
|
+
}, input: invoiceNoInput, validation: invoiceValidation }), _jsxs("div", { className: "relative", ref: uploadDropdownRef, children: [_jsxs("button", { onClick: () => setUploadDropdownOpen(!uploadDropdownOpen), className: "inline-flex items-center h-10 px-4 rounded bg-blue-500 hover:bg-blue-600 text-white font-medium transition-colors whitespace-nowrap cursor-pointer", disabled: isPdfLoading, children: [isPdfLoading ? "Processing..." : "Upload File", _jsx("svg", { className: "w-4 h-4 ml-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }) })] }), uploadDropdownOpen && !isPdfLoading && (_jsx("div", { className: "absolute z-10 mt-1 w-48 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5", children: _jsxs("div", { className: "py-1", role: "menu", "aria-orientation": "vertical", children: [_jsxs("label", { className: "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 cursor-pointer", children: ["Upload UBL", _jsx("input", { accept: ".xml", className: "hidden", onChange: (e) => {
|
|
374
|
+
handleFileUpload(e);
|
|
375
|
+
setUploadDropdownOpen(false);
|
|
376
|
+
}, type: "file" })] }), _jsx(PDFUploader, { dispatch: dispatch, changeDropdownOpen: setUploadDropdownOpen })] }) }))] }), _jsxs("div", { className: "relative", ref: exportDropdownRef, children: [_jsxs("button", { onClick: () => setExportDropdownOpen(!exportDropdownOpen), className: "inline-flex items-center h-10 px-4 rounded bg-black hover:bg-gray-800 text-white font-medium transition-colors whitespace-nowrap cursor-pointer", children: ["Export File", _jsx("svg", { className: "w-4 h-4 ml-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }) })] }), exportDropdownOpen && (_jsx("div", { className: "absolute z-10 mt-1 w-48 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5", children: _jsxs("div", { className: "py-1", role: "menu", "aria-orientation": "vertical", children: [_jsx("button", { onClick: () => {
|
|
377
|
+
handleExportUBL();
|
|
378
|
+
setExportDropdownOpen(false);
|
|
379
|
+
}, className: "block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 cursor-pointer", children: "Export UBL" }), _jsx("button", { onClick: () => {
|
|
380
|
+
handleExportPDF();
|
|
381
|
+
setExportDropdownOpen(false);
|
|
382
|
+
}, className: "block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 cursor-pointer", children: "Export PDF" })] }) }))] })] }), _jsxs("div", { className: "flex flex-row items-center gap-4", children: [_jsx(CurrencyForm, { currency: state.currency, handleInputChange: (e) => {
|
|
383
|
+
handleCurrencyChange(e.target.value);
|
|
384
|
+
}, validation: currencyValidation }), _jsx(SelectField, { options: STATUS_OPTIONS, value: state.status, onChange: (value) => handleStatusChange(value) })] })] }), _jsxs("div", { className: "md:hidden", children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsx("h1", { className: "text-2xl font-bold", children: "Invoice" }), _jsx("button", { onClick: () => setMobileHeaderOpen(!mobileHeaderOpen), className: "inline-flex items-center justify-center w-10 h-10 rounded-lg bg-gray-100 hover:bg-gray-200 transition-colors cursor-pointer", "aria-label": "Toggle invoice settings", children: mobileHeaderOpen ? (_jsx("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) })) : (_jsx("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4" }) })) })] }), !mobileHeaderOpen && (_jsxs("div", { className: "flex items-center gap-2 text-sm text-gray-600 mb-2", children: [_jsx("span", { className: "font-medium", children: state.invoiceNo || "No invoice #" }), _jsx("span", { children: "\u2022" }), _jsx("span", { children: state.currency }), _jsx("span", { children: "\u2022" }), _jsx("span", { className: "inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800", children: state.status })] })), mobileHeaderOpen && (_jsxs("div", { className: "bg-white border border-gray-200 rounded-lg p-4 space-y-4 shadow-sm", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Invoice Number" }), _jsx(InputField, { placeholder: "Add invoice number", value: invoiceNoInput, handleInputChange: (e) => setInvoiceNoInput(e.target.value), onBlur: (e) => {
|
|
385
|
+
const newValue = e.target.value;
|
|
386
|
+
if (newValue !== state.invoiceNo) {
|
|
387
|
+
dispatch(actions.editInvoice({ invoiceNo: newValue }));
|
|
388
|
+
}
|
|
389
|
+
}, input: invoiceNoInput, validation: invoiceValidation })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Currency" }), _jsx(CurrencyForm, { currency: state.currency, handleInputChange: (e) => {
|
|
390
|
+
handleCurrencyChange(e.target.value);
|
|
391
|
+
}, validation: currencyValidation })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Status" }), _jsx(SelectField, { options: STATUS_OPTIONS, value: state.status, onChange: (value) => handleStatusChange(value) })] }), _jsxs("div", { className: "space-y-2 pt-2 border-t border-gray-200", children: [_jsxs("div", { className: "relative", ref: uploadDropdownRef, children: [_jsxs("button", { onClick: () => setUploadDropdownOpen(!uploadDropdownOpen), className: "w-full inline-flex items-center justify-center h-10 px-4 rounded bg-blue-500 hover:bg-blue-600 text-white font-medium transition-colors cursor-pointer", disabled: isPdfLoading, children: [isPdfLoading ? "Processing..." : "Upload File", _jsx("svg", { className: "w-4 h-4 ml-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }) })] }), uploadDropdownOpen && !isPdfLoading && (_jsx("div", { className: "absolute z-10 mt-1 w-full rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5", children: _jsxs("div", { className: "py-1", role: "menu", children: [_jsxs("label", { className: "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 cursor-pointer", children: ["Upload UBL", _jsx("input", { accept: ".xml", className: "hidden", onChange: (e) => {
|
|
392
|
+
handleFileUpload(e);
|
|
393
|
+
setUploadDropdownOpen(false);
|
|
394
|
+
}, type: "file" })] }), _jsx(PDFUploader, { dispatch: dispatch, changeDropdownOpen: setUploadDropdownOpen })] }) }))] }), _jsxs("div", { className: "relative", ref: exportDropdownRef, children: [_jsxs("button", { onClick: () => setExportDropdownOpen(!exportDropdownOpen), className: "w-full inline-flex items-center justify-center h-10 px-4 rounded bg-black hover:bg-gray-800 text-white font-medium transition-colors cursor-pointer", children: ["Export File", _jsx("svg", { className: "w-4 h-4 ml-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }) })] }), exportDropdownOpen && (_jsx("div", { className: "absolute z-10 mt-1 w-full rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5", children: _jsxs("div", { className: "py-1", role: "menu", children: [_jsx("button", { onClick: () => {
|
|
395
|
+
handleExportUBL();
|
|
396
|
+
setExportDropdownOpen(false);
|
|
397
|
+
}, className: "block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 cursor-pointer", children: "Export UBL" }), _jsx("button", { onClick: () => {
|
|
398
|
+
handleExportPDF();
|
|
399
|
+
setExportDropdownOpen(false);
|
|
400
|
+
}, className: "block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 cursor-pointer", children: "Export PDF" })] }) }))] })] })] }))] })] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-0 lg:gap-4", children: [_jsxs("div", { className: "border-0 lg:border lg:border-gray-200 lg:rounded-lg p-0 lg:p-4", children: [_jsx("h3", { className: "text-lg font-semibold mb-4", children: "Issuer" }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "mb-2", children: [_jsx("label", { className: "block mb-1 text-sm", children: "Issue Date:" }), _jsx(DatePicker, { name: "issueDate", className: String.raw `w-full p-0`, onChange: (e) => {
|
|
383
401
|
const newDate = e.target.value.split("T")[0];
|
|
384
402
|
dispatch(actions.editInvoice({
|
|
385
403
|
dateIssued: newDate,
|
|
@@ -389,7 +407,7 @@ export default function Editor(props) {
|
|
|
389
407
|
if (newValue !== state.dateDelivered) {
|
|
390
408
|
dispatch(actions.editInvoice({ dateDelivered: newValue }));
|
|
391
409
|
}
|
|
392
|
-
}, value: state.dateDelivered || "" })] })] }), _jsx(LegalEntityForm, { legalEntity: state.issuer, onChangeInfo: (input) => dispatch(actions.editIssuer(input)), onChangeBank: (input) => dispatch(actions.editIssuerBank(input)), onChangeWallet: (input) => dispatch(actions.editIssuerWallet(input)), basicInfoDisabled: false, bankDisabled: !fiatMode, walletDisabled: fiatMode, currency: state.currency, status: state.status, walletvalidation: walletValidation, mainCountryValidation: mainCountryValidation, bankCountryValidation: bankCountryValidation, ibanvalidation: ibanValidation, bicvalidation: bicValidation, banknamevalidation: bankNameValidation, streetaddressvalidation: streetAddressValidation, cityvalidation: cityValidation, postalcodevalidation: postalCodeValidation, payeremailvalidation: payerEmailValidation, routingNumbervalidation: routingNumberValidation })] }), _jsxs("div", { className: "border border-gray-200 rounded-lg p-4", children: [_jsx("h3", { className: "text-lg font-semibold mb-4", children: "Payer" }), _jsxs("div", { className: "mb-2 w-64", children: [_jsx("label", { className: "block mb-1 text-sm", children: "Due Date:" }), _jsx(DatePicker, { name: "dateDue", className: String.raw `w-full p-0`, onChange: (e) => dispatch(actions.editInvoice({
|
|
410
|
+
}, value: state.dateDelivered || "" })] })] }), _jsx(LegalEntityForm, { legalEntity: state.issuer, onChangeInfo: (input) => dispatch(actions.editIssuer(input)), onChangeBank: (input) => dispatch(actions.editIssuerBank(input)), onChangeWallet: (input) => dispatch(actions.editIssuerWallet(input)), basicInfoDisabled: false, bankDisabled: !fiatMode, walletDisabled: fiatMode, currency: state.currency, status: state.status, walletvalidation: walletValidation, mainCountryValidation: mainCountryValidation, bankCountryValidation: bankCountryValidation, ibanvalidation: ibanValidation, bicvalidation: bicValidation, banknamevalidation: bankNameValidation, streetaddressvalidation: streetAddressValidation, cityvalidation: cityValidation, postalcodevalidation: postalCodeValidation, payeremailvalidation: payerEmailValidation, routingNumbervalidation: routingNumberValidation })] }), _jsxs("div", { className: "border-0 lg:border lg:border-gray-200 lg:rounded-lg p-0 lg:p-4", children: [_jsx("h3", { className: "text-lg font-semibold mb-4", children: "Payer" }), _jsxs("div", { className: "mb-2 w-64", children: [_jsx("label", { className: "block mb-1 text-sm", children: "Due Date:" }), _jsx(DatePicker, { name: "dateDue", className: String.raw `w-full p-0`, onChange: (e) => dispatch(actions.editInvoice({
|
|
393
411
|
dateDue: e.target.value.split("T")[0],
|
|
394
412
|
})), value: state.dateDue })] }), _jsx(LegalEntityForm, { bankDisabled: true, legalEntity: state.payer, onChangeInfo: (input) => dispatch(actions.editPayer(input)), currency: state.currency, status: state.status, payeremailvalidation: payerEmailValidation })] })] }), _jsx("div", { className: "mb-8", children: _jsx(LineItemsTable, { currency: state.currency, lineItems: state.lineItems.map((item) => ({
|
|
395
413
|
...item,
|
|
@@ -397,7 +415,7 @@ export default function Editor(props) {
|
|
|
397
415
|
})), onAddItem: (item) => dispatch(actions.addLineItem(item)), onDeleteItem: (input) => dispatch(actions.deleteLineItem(input)), onUpdateCurrency: (input) => {
|
|
398
416
|
setFiatMode(input.currency !== "USDS");
|
|
399
417
|
dispatch(actions.editInvoice(input));
|
|
400
|
-
}, onUpdateItem: (item) => dispatch(actions.editLineItem(item)), onEditingItemChange: setEditingItemValues, dispatch: dispatch, paymentAccounts: state.invoiceTags || [] }) }), _jsxs("div", { className: "grid grid-cols-
|
|
418
|
+
}, onUpdateItem: (item) => dispatch(actions.editLineItem(item)), onEditingItemChange: setEditingItemValues, dispatch: dispatch, paymentAccounts: state.invoiceTags || [] }) }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx("div", { className: "col-span-1", children: _jsx("div", { className: "", children: _jsx(Textarea, { label: "Notes", placeholder: "Add notes", autoExpand: false, rows: 4, multiline: true, value: notes, onBlur: (e) => {
|
|
401
419
|
const newValue = e.target.value;
|
|
402
420
|
if (newValue !== state.notes) {
|
|
403
421
|
dispatch(actions.editInvoice({ notes: newValue }));
|
|
@@ -6,7 +6,7 @@ import { uploadPdfChunked } from "./uploadPdfChunked.js";
|
|
|
6
6
|
import { getCountryCodeFromName } from "./utils/utils.js";
|
|
7
7
|
let GRAPHQL_URL = 'http://localhost:4001/graphql/invoice';
|
|
8
8
|
if (!window.document.baseURI.includes('localhost')) {
|
|
9
|
-
GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql/invoice';
|
|
9
|
+
GRAPHQL_URL = 'https://switchboard-dev.powerhouse.xyz/graphql/invoice';
|
|
10
10
|
}
|
|
11
11
|
export async function loadPDFFile({ file, dispatch, }) {
|
|
12
12
|
if (!file)
|
|
@@ -4,7 +4,7 @@ import { actions } from "../../document-models/invoice/index.js";
|
|
|
4
4
|
import { generateId } from "document-model";
|
|
5
5
|
let GRAPHQL_URL = "http://localhost:4001/graphql/invoice";
|
|
6
6
|
if (!window.document.baseURI.includes('localhost')) {
|
|
7
|
-
GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql/invoice';
|
|
7
|
+
GRAPHQL_URL = 'https://switchboard-dev.powerhouse.xyz/graphql/invoice';
|
|
8
8
|
}
|
|
9
9
|
const InvoiceToGnosis = ({ docState, dispatch, }) => {
|
|
10
10
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lineItemTags.d.ts","sourceRoot":"","sources":["../../../../editors/invoice/lineItemTags/lineItemTags.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"lineItemTags.d.ts","sourceRoot":"","sources":["../../../../editors/invoice/lineItemTags/lineItemTags.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAY,MAAM,OAAO,CAAC;AAK3C,OAAO,EAAW,UAAU,EAAE,MAAM,2CAA2C,CAAC;AAKhF,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED,UAAU,sBAAsB;IAC9B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IACxB,eAAe,EAAE,UAAU,EAAE,CAAC;CAC/B;AAED,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,OAAO,EACP,QAAQ,EACR,eAAe,GAChB,EAAE,sBAAsB,2CA0PxB"}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
2
3
|
import { X, Tag } from "lucide-react";
|
|
3
4
|
import { Button } from "@powerhousedao/design-system";
|
|
4
5
|
import { Select, DatePicker } from "@powerhousedao/document-engineering/ui";
|
|
5
6
|
import { expenseAccountOptions, paymentAccountOptions } from "./tagMapping.js";
|
|
6
7
|
import { actions } from "../../../document-models/invoice/index.js";
|
|
7
8
|
import { InputField } from "../components/inputField.js";
|
|
9
|
+
import { TagCard } from "./tagCard.js";
|
|
10
|
+
import { TagMobileModal } from "./tagMobileModal.js";
|
|
8
11
|
export function LineItemTagsTable({ lineItems, onClose, dispatch, paymentAccounts, }) {
|
|
12
|
+
const [mobileEditItem, setMobileEditItem] = useState(null);
|
|
13
|
+
const [showMobileModal, setShowMobileModal] = useState(false);
|
|
9
14
|
const handleReset = () => {
|
|
10
15
|
// Resetting all tags to empty values
|
|
11
16
|
lineItems.forEach((item) => {
|
|
@@ -27,11 +32,19 @@ export function LineItemTagsTable({ lineItems, onClose, dispatch, paymentAccount
|
|
|
27
32
|
}));
|
|
28
33
|
});
|
|
29
34
|
};
|
|
35
|
+
const handleMobileEdit = (item) => {
|
|
36
|
+
setMobileEditItem(item);
|
|
37
|
+
setShowMobileModal(true);
|
|
38
|
+
};
|
|
39
|
+
const handleCloseMobileModal = () => {
|
|
40
|
+
setShowMobileModal(false);
|
|
41
|
+
setMobileEditItem(null);
|
|
42
|
+
};
|
|
30
43
|
// Get the last payment account value from the paymentAccounts to display in the payment account select
|
|
31
44
|
const selectedPaymentAccountValue = paymentAccounts && paymentAccounts.length > 0
|
|
32
45
|
? (paymentAccounts[paymentAccounts.length - 1].value ?? "")
|
|
33
46
|
: "";
|
|
34
|
-
return (_jsxs("div", { className: "w-full", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 p-6 bg-white z-10", children: [_jsxs("span", { className: "flex items-center gap-2", children: [_jsx("h2", { className: "text-2xl font-semibold text-gray-900", children: "Assign Tags " }), _jsx(Tag, { style: { width: 28, height: 28, color: "white", fill: "#475264" } })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { color: "light", size: "medium", onClick: handleReset, children: ["Reset", " "] }), _jsx("button", { onClick: onClose, className: "rounded-full p-2 hover:bg-gray-100", children: _jsx(X, { size: 24, className: "text-gray-500" }) })] })] }), _jsx("div", { className: "overflow-x-auto rounded-lg border border-gray-200", children: _jsxs("table", { className: "w-full border-collapse bg-white", children: [_jsx("thead", { className: "bg-gray-50 z-10", children: _jsxs("tr", { children: [_jsx("th", { className: "border-b border-gray-200 p-3 text-left", children: "Item" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-left", children: "Period" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-left", children: "Xero Expense Account" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", children: "Total" })] }) }), _jsx("tbody", { children: lineItems.map((item) => (_jsxs("tr", { className: "hover:bg-gray-50", children: [_jsx("td", { className: "border-b border-gray-200 p-3", children: _jsx(InputField, { value: item.item, handleInputChange: (e) => { }, onBlur: (e) => {
|
|
47
|
+
return (_jsxs("div", { className: "w-full", children: [showMobileModal && mobileEditItem && (_jsx(TagMobileModal, { item: mobileEditItem, onClose: handleCloseMobileModal, dispatch: dispatch })), _jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 p-6 bg-white z-10", children: [_jsxs("span", { className: "flex items-center gap-2", children: [_jsx("h2", { className: "text-2xl font-semibold text-gray-900", children: "Assign Tags " }), _jsx(Tag, { style: { width: 28, height: 28, color: "white", fill: "#475264" } })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { color: "light", size: "medium", onClick: handleReset, children: ["Reset", " "] }), _jsx("button", { onClick: onClose, className: "rounded-full p-2 hover:bg-gray-100", children: _jsx(X, { size: 24, className: "text-gray-500" }) })] })] }), _jsx("div", { className: "hidden md:block overflow-x-auto rounded-lg border border-gray-200", children: _jsxs("table", { className: "w-full border-collapse bg-white", children: [_jsx("thead", { className: "bg-gray-50 z-10", children: _jsxs("tr", { children: [_jsx("th", { className: "border-b border-gray-200 p-3 text-left", children: "Item" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-left", children: "Period" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-left", children: "Xero Expense Account" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", children: "Total" })] }) }), _jsx("tbody", { children: lineItems.map((item) => (_jsxs("tr", { className: "hover:bg-gray-50", children: [_jsx("td", { className: "border-b border-gray-200 p-3", children: _jsx(InputField, { value: item.item, handleInputChange: (e) => { }, onBlur: (e) => {
|
|
35
48
|
dispatch(actions.editLineItem({
|
|
36
49
|
id: item.id,
|
|
37
50
|
description: e.target.value,
|
|
@@ -58,7 +71,16 @@ export function LineItemTagsTable({ lineItems, onClose, dispatch, paymentAccount
|
|
|
58
71
|
value: value,
|
|
59
72
|
label: expenseAccountOptions.find((option) => option.value === value)?.label,
|
|
60
73
|
}));
|
|
61
|
-
} }) }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right font-medium", children: item.total })] }, item.id))) })] }) }), _jsx("div", { className: "border-t border-gray-200 p-6", children: _jsxs("div", { className: "flex items-center justify-end gap-4", children: [_jsx("label", { className: "text-lg font-medium text-gray-900", children: "Payment Account" }), _jsx(Select, { options: paymentAccountOptions, value: paymentAccountOptions.find((option) => option.value === selectedPaymentAccountValue)?.value ?? "", placeholder: "Select Payment Account", searchable: true, onChange: (value) => {
|
|
74
|
+
} }) }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right font-medium", children: item.total })] }, item.id))) })] }) }), _jsx("div", { className: "md:hidden p-4 space-y-3", children: lineItems.map((item) => (_jsx(TagCard, { item: item, onEdit: () => handleMobileEdit(item) }, item.id))) }), _jsx("div", { className: "hidden md:block border-t border-gray-200 p-6", children: _jsxs("div", { className: "flex items-center justify-end gap-4", children: [_jsx("label", { className: "text-lg font-medium text-gray-900", children: "Payment Account" }), _jsx(Select, { options: paymentAccountOptions, value: paymentAccountOptions.find((option) => option.value === selectedPaymentAccountValue)?.value ?? "", placeholder: "Select Payment Account", searchable: true, onChange: (value) => {
|
|
75
|
+
const selectedLabel = paymentAccountOptions.find((option) => option.value === value)
|
|
76
|
+
?.label || "";
|
|
77
|
+
const cleanLabel = selectedLabel.replace(/\s+\w+$/, "").trim();
|
|
78
|
+
dispatch(actions.setInvoiceTag({
|
|
79
|
+
dimension: "xero-payment-account",
|
|
80
|
+
value: value,
|
|
81
|
+
label: cleanLabel,
|
|
82
|
+
}));
|
|
83
|
+
}, style: { width: "230px" } })] }) }), _jsx("div", { className: "md:hidden p-4 border-t border-gray-200", children: _jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Payment Account" }), _jsx(Select, { options: paymentAccountOptions, value: paymentAccountOptions.find((option) => option.value === selectedPaymentAccountValue)?.value ?? "", placeholder: "Select Payment Account", searchable: true, onChange: (value) => {
|
|
62
84
|
const selectedLabel = paymentAccountOptions.find((option) => option.value === value)
|
|
63
85
|
?.label || "";
|
|
64
86
|
const cleanLabel = selectedLabel.replace(/\s+\w+$/, "").trim();
|
|
@@ -67,5 +89,5 @@ export function LineItemTagsTable({ lineItems, onClose, dispatch, paymentAccount
|
|
|
67
89
|
value: value,
|
|
68
90
|
label: cleanLabel,
|
|
69
91
|
}));
|
|
70
|
-
}
|
|
92
|
+
} })] }) })] }));
|
|
71
93
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type TagAssignmentRow = {
|
|
2
|
+
id: string;
|
|
3
|
+
item: string;
|
|
4
|
+
period: string;
|
|
5
|
+
expenseAccount: string;
|
|
6
|
+
total: string;
|
|
7
|
+
lineItemTag: any[];
|
|
8
|
+
};
|
|
9
|
+
type TagCardProps = {
|
|
10
|
+
item: TagAssignmentRow;
|
|
11
|
+
onEdit: () => void;
|
|
12
|
+
};
|
|
13
|
+
export declare function TagCard({ item, onEdit }: TagCardProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=tagCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tagCard.d.ts","sourceRoot":"","sources":["../../../../editors/invoice/lineItemTags/tagCard.tsx"],"names":[],"mappings":"AAGA,KAAK,gBAAgB,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,GAAG,EAAE,CAAC;CACpB,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,YAAY,2CAoErD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { MoreVertical, Edit } from "lucide-react";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
export function TagCard({ item, onEdit }) {
|
|
5
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
6
|
+
// Get tag values
|
|
7
|
+
const periodTag = item.lineItemTag.find((tag) => tag.dimension === "accounting-period");
|
|
8
|
+
const expenseTag = item.lineItemTag.find((tag) => tag.dimension === "xero-expense-account");
|
|
9
|
+
return (_jsxs("div", { className: "bg-white border border-gray-200 rounded-lg mb-3 overflow-hidden", children: [_jsxs("div", { className: "p-4 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [_jsxs("div", { className: "flex items-start justify-between mb-2", children: [_jsx("div", { className: "flex-1", children: _jsx("h5", { className: "font-medium text-gray-900 text-sm", children: item.item || "Untitled Item" }) }), _jsx("button", { className: "p-1 hover:bg-gray-100 rounded", onClick: (e) => {
|
|
10
|
+
e.stopPropagation();
|
|
11
|
+
onEdit();
|
|
12
|
+
}, children: _jsx(MoreVertical, { className: "w-5 h-5 text-gray-500" }) })] }), _jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsx("div", { className: "text-gray-600", children: periodTag?.label || "No period set" }), _jsx("div", { className: "font-semibold text-gray-900", children: item.total })] }), isExpanded && (_jsx("div", { className: "mt-3 pt-3 border-t border-gray-100 space-y-2 text-sm", children: _jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-gray-600", children: "Expense Account:" }), _jsx("span", { className: "text-gray-900 text-right max-w-[60%]", children: expenseTag?.label || "Not set" })] }) }))] }), _jsx("div", { className: "border-t border-gray-200 bg-gray-50", children: _jsxs("button", { className: "w-full flex items-center justify-center gap-3 px-4 py-3 text-sm hover:bg-gray-100 transition-colors", onClick: onEdit, children: [_jsx(Edit, { className: "w-4 h-4 text-blue-600" }), _jsx("span", { children: "Edit Tags" })] }) })] }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Dispatch } from "react";
|
|
2
|
+
import { InvoiceTag } from "../../../document-models/invoice/index.js";
|
|
3
|
+
type TagAssignmentRow = {
|
|
4
|
+
id: string;
|
|
5
|
+
item: string;
|
|
6
|
+
period: string;
|
|
7
|
+
expenseAccount: string;
|
|
8
|
+
total: string;
|
|
9
|
+
lineItemTag: InvoiceTag[];
|
|
10
|
+
};
|
|
11
|
+
type TagMobileModalProps = {
|
|
12
|
+
item: TagAssignmentRow;
|
|
13
|
+
onClose: () => void;
|
|
14
|
+
dispatch: Dispatch<any>;
|
|
15
|
+
};
|
|
16
|
+
export declare function TagMobileModal({ item, onClose, dispatch, }: TagMobileModalProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=tagMobileModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tagMobileModal.d.ts","sourceRoot":"","sources":["../../../../editors/invoice/lineItemTags/tagMobileModal.tsx"],"names":[],"mappings":"AACA,OAAO,EAAuB,QAAQ,EAAE,MAAM,OAAO,CAAC;AAOtD,OAAO,EAAW,UAAU,EAAE,MAAM,2CAA2C,CAAC;AAEhF,KAAK,gBAAgB,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;CACzB,CAAC;AAEF,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,OAAO,EACP,QAAQ,GACT,EAAE,mBAAmB,2CAkLrB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { X } from "lucide-react";
|
|
3
|
+
import { useState, useEffect } from "react";
|
|
4
|
+
import { InputField } from "../components/inputField.js";
|
|
5
|
+
import { Select, DatePicker } from "@powerhousedao/document-engineering/ui";
|
|
6
|
+
import { expenseAccountOptions, } from "./tagMapping.js";
|
|
7
|
+
import { actions } from "../../../document-models/invoice/index.js";
|
|
8
|
+
export function TagMobileModal({ item, onClose, dispatch, }) {
|
|
9
|
+
const [description, setDescription] = useState(item.item);
|
|
10
|
+
// Get current tag values
|
|
11
|
+
const periodTag = item.lineItemTag.find((tag) => tag.dimension === "accounting-period");
|
|
12
|
+
const expenseTag = item.lineItemTag.find((tag) => tag.dimension === "xero-expense-account");
|
|
13
|
+
const [periodValue, setPeriodValue] = useState(periodTag?.label || "");
|
|
14
|
+
const [periodStoredValue, setPeriodStoredValue] = useState(periodTag?.value || "");
|
|
15
|
+
const [expenseValue, setExpenseValue] = useState(expenseTag?.value || "");
|
|
16
|
+
const [expenseLabel, setExpenseLabel] = useState(expenseTag?.label || "");
|
|
17
|
+
// Prevent body scroll when modal is open
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
document.body.style.overflow = "hidden";
|
|
20
|
+
return () => {
|
|
21
|
+
document.body.style.overflow = "unset";
|
|
22
|
+
};
|
|
23
|
+
}, []);
|
|
24
|
+
const handleSave = () => {
|
|
25
|
+
// Save description if changed
|
|
26
|
+
if (description !== item.item) {
|
|
27
|
+
dispatch(actions.editLineItem({
|
|
28
|
+
id: item.id,
|
|
29
|
+
description: description,
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
// Save period if changed
|
|
33
|
+
if (periodStoredValue !== periodTag?.value) {
|
|
34
|
+
dispatch(actions.setLineItemTag({
|
|
35
|
+
lineItemId: item.id,
|
|
36
|
+
dimension: "accounting-period",
|
|
37
|
+
value: periodStoredValue,
|
|
38
|
+
label: periodValue,
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
// Save expense account if changed
|
|
42
|
+
if (expenseValue !== expenseTag?.value) {
|
|
43
|
+
dispatch(actions.setLineItemTag({
|
|
44
|
+
lineItemId: item.id,
|
|
45
|
+
dimension: "xero-expense-account",
|
|
46
|
+
value: expenseValue,
|
|
47
|
+
label: expenseLabel,
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
onClose();
|
|
51
|
+
};
|
|
52
|
+
return (_jsxs("div", { className: "fixed inset-0 z-50 bg-white flex flex-col", children: [_jsxs("div", { className: "flex items-center justify-between p-4 border-b border-gray-200 bg-white", children: [_jsx("button", { onClick: onClose, className: "p-2 hover:bg-gray-100 rounded-full transition-colors", "aria-label": "Cancel", children: _jsx(X, { className: "w-5 h-5" }) }), _jsx("h2", { className: "text-lg font-semibold", children: "Edit Tags" }), _jsx("button", { onClick: handleSave, className: "px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors font-medium text-sm", children: "Save" })] }), _jsxs("div", { className: "flex-1 overflow-y-auto p-4 space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Item Description" }), _jsx(InputField, { value: description, handleInputChange: (e) => setDescription(e.target.value), onBlur: () => { }, placeholder: "Enter item description", className: "w-full" })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Accounting Period" }), _jsx(DatePicker, { name: "period", dateFormat: "YYYY-MM", autoClose: true, placeholder: "Select Period", value: periodValue, onChange: (e) => {
|
|
53
|
+
const newValue = new Date(e.target.value)
|
|
54
|
+
.toLocaleDateString("en-US", {
|
|
55
|
+
year: "numeric",
|
|
56
|
+
month: "numeric",
|
|
57
|
+
})
|
|
58
|
+
.split("/")
|
|
59
|
+
.reverse()
|
|
60
|
+
.join("/");
|
|
61
|
+
const newLabel = new Date(e.target.value).toLocaleDateString("en-US", {
|
|
62
|
+
month: "long",
|
|
63
|
+
year: "numeric",
|
|
64
|
+
});
|
|
65
|
+
setPeriodValue(newLabel);
|
|
66
|
+
setPeriodStoredValue(newValue);
|
|
67
|
+
} })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Xero Expense Account" }), _jsx(Select, { options: expenseAccountOptions, value: expenseValue, placeholder: "Select Expense Account", searchable: true, onChange: (value) => {
|
|
68
|
+
setExpenseValue(value);
|
|
69
|
+
setExpenseLabel(expenseAccountOptions.find((option) => option.value === value)?.label || "");
|
|
70
|
+
} })] }), _jsx("div", { className: "bg-gray-50 rounded-lg p-4", children: _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-600", children: "Total:" }), _jsx("span", { className: "text-lg font-bold text-gray-900", children: item.total })] }) })] }), _jsxs("div", { className: "border-t border-gray-200 p-4 bg-white flex gap-3", children: [_jsx("button", { onClick: onClose, className: "flex-1 px-4 py-3 border border-gray-300 rounded-md hover:bg-gray-50 transition-colors font-medium text-gray-700", children: "Cancel" }), _jsx("button", { onClick: handleSave, className: "flex-1 px-4 py-3 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors font-medium", children: "Save Tags" })] })] }));
|
|
71
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lineItems.d.ts","sourceRoot":"","sources":["../../../editors/invoice/lineItems.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EAChB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAKL,KAAK,QAAQ,EAEd,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"lineItems.d.ts","sourceRoot":"","sources":["../../../editors/invoice/lineItems.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EAChB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAKL,KAAK,QAAQ,EAEd,MAAM,OAAO,CAAC;AAef,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKlD;AAED,KAAK,QAAQ,GAAG;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B,CAAC;AAobF,KAAK,mBAAmB,GAAG;IACzB,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC5D,QAAQ,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7D,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAC7B,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,GAAG,IAAI,KACL,IAAI,CAAC;IACV,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,UAAU,EAAE,CAAC;CACxC,CAAC;AAEF,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,QAAQ,EACR,eAAe,GAChB,EAAE,mBAAmB,2CA8ZrB"}
|
|
@@ -6,6 +6,9 @@ import { Tag } from "lucide-react";
|
|
|
6
6
|
import { NumberForm } from "./components/numberForm.js";
|
|
7
7
|
import { InputField } from "./components/inputField.js";
|
|
8
8
|
import { LineItemTagsTable } from "./lineItemTags/lineItemTags.js";
|
|
9
|
+
import { LineItemCard } from "./components/lineItemCard.js";
|
|
10
|
+
import { LineItemMobileModal } from "./components/lineItemMobileModal.js";
|
|
11
|
+
import { LineItemsEmptyState } from "./components/lineItemsEmptyState.js";
|
|
9
12
|
// Helper function to get precision based on currency
|
|
10
13
|
function getCurrencyPrecision(currency) {
|
|
11
14
|
return currency === "USDS" || currency === "DAI" ? 6 : 2;
|
|
@@ -286,6 +289,8 @@ export function LineItemsTable({ lineItems, currency, onAddItem, onUpdateItem, o
|
|
|
286
289
|
const [editingId, setEditingId] = useState(null);
|
|
287
290
|
const [isAddingNew, setIsAddingNew] = useState(false);
|
|
288
291
|
const [showTagTable, setShowTagTable] = useState(false);
|
|
292
|
+
const [mobileEditItem, setMobileEditItem] = useState(null);
|
|
293
|
+
const [showMobileModal, setShowMobileModal] = useState(false);
|
|
289
294
|
const containerRef = useRef(null);
|
|
290
295
|
const tableContainerRef = useRef(null);
|
|
291
296
|
const tableRef = useRef(null);
|
|
@@ -346,53 +351,84 @@ export function LineItemsTable({ lineItems, currency, onAddItem, onUpdateItem, o
|
|
|
346
351
|
if (showTagTable) {
|
|
347
352
|
return (_jsx(LineItemTagsTable, { lineItems: tagAssignmentRows, onClose: () => setShowTagTable(false), dispatch: dispatch, paymentAccounts: paymentAccounts }));
|
|
348
353
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
354
|
+
// Calculate totals for mobile footer
|
|
355
|
+
const totalPriceTaxExcl = lineItems.reduce((sum, item) => sum + item.totalPriceTaxExcl, 0);
|
|
356
|
+
const totalPriceTaxIncl = lineItems.reduce((sum, item) => sum + item.totalPriceTaxIncl, 0);
|
|
357
|
+
return (_jsxs("div", { ref: containerRef, className: "relative w-full", children: [showMobileModal && (_jsx(LineItemMobileModal, { item: mobileEditItem || {}, currency: currency, isNew: !mobileEditItem?.id || mobileEditItem.id === '', onSave: (item) => {
|
|
358
|
+
try {
|
|
359
|
+
// If editing an item with empty ID, delete it first, then add new one
|
|
360
|
+
if (mobileEditItem?.id === '') {
|
|
361
|
+
onDeleteItem({ id: '' });
|
|
362
|
+
onAddItem(item);
|
|
363
|
+
}
|
|
364
|
+
else if (mobileEditItem?.id) {
|
|
365
|
+
onUpdateItem(item);
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
onAddItem(item);
|
|
369
|
+
}
|
|
370
|
+
setShowMobileModal(false);
|
|
371
|
+
setMobileEditItem(null);
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
toast(error.message || "Failed to save line item", { type: "error" });
|
|
375
|
+
}
|
|
376
|
+
}, onCancel: () => {
|
|
377
|
+
setShowMobileModal(false);
|
|
378
|
+
setMobileEditItem(null);
|
|
379
|
+
} }, mobileEditItem?.id || 'new')), _jsxs("div", { className: "mt-4", children: [_jsxs("div", { className: "mb-4 flex items-center justify-between", children: [_jsx("h4", { className: "text-xl font-semibold text-gray-900", children: "Line Items" }), _jsxs("div", { className: "hidden md:flex items-center gap-3", children: [_jsxs("button", { onClick: () => setShowTagTable(true), className: "flex items-center gap-2 px-4 py-2 border border-gray-300 rounded-md hover:bg-gray-50 transition-colors text-sm font-medium text-gray-700", title: "Manage Tags for All Line Items", children: [_jsx(Tag, { className: "w-4 h-4" }), _jsx("span", { className: "hidden md:inline", children: "Manage Tags" })] }), _jsx(RWAButton, { className: "hidden md:block", disabled: isAddingNew, onClick: handleAddClick, children: "Add Line Item" })] })] }), lineItems.length === 0 && !isAddingNew && (_jsx("div", { className: "md:hidden", children: _jsx(LineItemsEmptyState, { onAddItem: () => {
|
|
380
|
+
setMobileEditItem({});
|
|
381
|
+
setShowMobileModal(true);
|
|
382
|
+
} }) })), lineItems.length === 0 && !isAddingNew && (_jsx("div", { className: "hidden md:block", children: _jsx(LineItemsEmptyState, { onAddItem: handleAddClick }) })), lineItems.length > 0 && (_jsxs("div", { className: "md:hidden space-y-3", children: [_jsxs("div", { className: "flex gap-2 mb-4", children: [_jsxs("button", { onClick: () => setShowTagTable(true), className: "flex items-center justify-center gap-2 px-4 py-3 border border-gray-300 rounded-md hover:bg-gray-50 transition-colors font-medium text-gray-700", title: "Manage Tags for All Line Items", children: [_jsx(Tag, { className: "w-4 h-4" }), _jsx("span", { children: "Tags" })] }), _jsx("button", { onClick: () => {
|
|
383
|
+
setMobileEditItem({});
|
|
384
|
+
setShowMobileModal(true);
|
|
385
|
+
}, className: "flex-1 py-3 px-4 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors font-medium", children: "Add Line Item" })] }), lineItems.map((item) => (_jsx(LineItemCard, { item: item, currency: currency, onEdit: () => {
|
|
386
|
+
setMobileEditItem(item);
|
|
387
|
+
setShowMobileModal(true);
|
|
388
|
+
}, onDelete: () => {
|
|
389
|
+
const input = { id: item.id };
|
|
390
|
+
onDeleteItem(input);
|
|
391
|
+
} }, item.id)))] })), (lineItems.length > 0 || isAddingNew) && (_jsx("div", { ref: tableContainerRef, className: "hidden md:block overflow-x-auto rounded-lg border border-gray-200", children: _jsxs("table", { ref: tableRef, className: "w-full table-fixed border-collapse bg-white", children: [_jsxs("colgroup", { children: [_jsx("col", { style: { width: "30%" } }), _jsx("col", { style: { width: "10%" } }), _jsx("col", { style: { width: "12%" } }), _jsx("col", { style: { width: "8%" } }), _jsx("col", {}), _jsx("col", {}), _jsx("col", {})] }), _jsx("thead", { children: _jsxs("tr", { className: "bg-gray-50", children: [_jsx("th", { className: "border-b border-gray-200 p-3 text-left", children: "Description" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", children: "Quantity" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", children: "Unit Price (excl. tax)" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", children: "Tax %" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", children: "Total (excl. tax)" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", children: "Total (incl. tax)" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-center", children: "Actions" })] }) }), _jsxs("tbody", { children: [lineItems.map((item) => editingId === item.id ? (_jsx(EditableLineItem, { currency: currency, item: item, onCancel: () => setEditingId(null), onSave: (updatedItem) => {
|
|
392
|
+
try {
|
|
393
|
+
onUpdateItem(updatedItem);
|
|
394
|
+
setEditingId(null);
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
console.error(error);
|
|
398
|
+
if (error?.message?.includes("Invalid action input:")) {
|
|
399
|
+
try {
|
|
400
|
+
const zodError = JSON.parse(error.message.split("Invalid action input: ")[1]);
|
|
401
|
+
if (Array.isArray(zodError) &&
|
|
402
|
+
zodError.length > 0) {
|
|
403
|
+
const firstError = zodError[0];
|
|
404
|
+
const errorJSX = (_jsxs("div", { children: [_jsx("p", { className: "font-semibold", children: "Failed to update line item" }), _jsxs("p", { children: [firstError.message, ": "] }), zodError.map((err, index) => (_jsx("ul", { children: _jsxs("li", { className: "text-red-500 font-semibold", children: ["- ", err.path.join(".")] }) }, index)))] }));
|
|
405
|
+
toast(errorJSX, {
|
|
406
|
+
type: "error",
|
|
407
|
+
});
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
catch (parseError) {
|
|
412
|
+
console.error("Failed to parse Zod error:", parseError);
|
|
413
|
+
toast("Invalid input data", {
|
|
370
414
|
type: "error",
|
|
371
415
|
});
|
|
372
416
|
return;
|
|
373
417
|
}
|
|
374
418
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
toast("Invalid input data", {
|
|
419
|
+
else if (error?.message) {
|
|
420
|
+
toast(error.message, {
|
|
378
421
|
type: "error",
|
|
379
422
|
});
|
|
380
423
|
return;
|
|
381
424
|
}
|
|
382
|
-
|
|
383
|
-
else if (error?.message) {
|
|
384
|
-
toast(error.message, {
|
|
425
|
+
toast("Failed to update line item", {
|
|
385
426
|
type: "error",
|
|
386
427
|
});
|
|
387
|
-
return;
|
|
388
428
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
? item.quantity.toString()
|
|
395
|
-
: item.quantity.toFixed(2) }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right table-cell", children: formatNumber(item.unitPriceTaxExcl) }), _jsxs("td", { className: "border-b border-gray-200 p-3 text-right table-cell", children: [typeof item.taxPercent === "number"
|
|
396
|
-
? Math.round(item.taxPercent)
|
|
397
|
-
: 0, "%"] }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right font-medium table-cell", children: formatNumber(item.totalPriceTaxExcl) }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right font-medium table-cell", children: formatNumber(item.totalPriceTaxIncl) }), _jsx("td", { className: "border-b border-gray-200 p-3 table-cell", children: _jsxs("div", { className: "flex justify-center space-x-2", children: [_jsx("button", { className: "rounded bg-blue-500 px-3 py-1 text-white hover:bg-blue-200", onClick: () => setEditingId(item.id), children: "Edit" }), _jsx("button", { className: "rounded bg-red-600 px-3 py-1 text-white hover:bg-red-700", onClick: () => onDeleteItem({ id: item.id }), children: "Delete" })] }) })] }, item.id))), isAddingNew ? (_jsx(EditableLineItem, { currency: currency, item: {}, onCancel: handleCancelNewItem, onSave: handleSaveNewItem, onEditingItemChange: onEditingItemChange })) : null] })] }) })] }) }));
|
|
429
|
+
}, onEditingItemChange: onEditingItemChange }, item.id)) : (_jsxs("tr", { className: "hover:bg-gray-50 table-row", children: [_jsx("td", { className: "border-b border-gray-200 p-3 table-cell", children: item.description }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right table-cell", children: item.quantity % 1 === 0
|
|
430
|
+
? item.quantity.toString()
|
|
431
|
+
: item.quantity.toFixed(2) }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right table-cell", children: formatNumber(item.unitPriceTaxExcl) }), _jsxs("td", { className: "border-b border-gray-200 p-3 text-right table-cell", children: [typeof item.taxPercent === "number"
|
|
432
|
+
? Math.round(item.taxPercent)
|
|
433
|
+
: 0, "%"] }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right font-medium table-cell", children: formatNumber(item.totalPriceTaxExcl) }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right font-medium table-cell", children: formatNumber(item.totalPriceTaxIncl) }), _jsx("td", { className: "border-b border-gray-200 p-3 table-cell", children: _jsxs("div", { className: "flex justify-center space-x-2", children: [_jsx("button", { className: "rounded bg-blue-500 px-3 py-1 text-white hover:bg-blue-200", onClick: () => setEditingId(item.id), children: "Edit" }), _jsx("button", { className: "rounded bg-red-600 px-3 py-1 text-white hover:bg-red-700", onClick: () => onDeleteItem({ id: item.id }), children: "Delete" })] }) })] }, item.id))), isAddingNew ? (_jsx(EditableLineItem, { currency: currency, item: {}, onCancel: handleCancelNewItem, onSave: handleSaveNewItem, onEditingItemChange: onEditingItemChange })) : null] })] }) }))] }), lineItems.length > 0 && (_jsxs("div", { className: "md:hidden mt-4 bg-white border border-gray-200 rounded-lg p-4 space-y-2", children: [_jsxs("div", { className: "flex justify-between text-sm", children: [_jsx("span", { className: "text-gray-600", children: "Subtotal (excl. tax):" }), _jsxs("span", { className: "font-medium text-gray-900", children: [currency, " ", formatNumber(totalPriceTaxExcl)] })] }), _jsxs("div", { className: "flex justify-between text-sm", children: [_jsx("span", { className: "text-gray-600", children: "Total tax:" }), _jsxs("span", { className: "font-medium text-gray-900", children: [currency, " ", formatNumber(totalPriceTaxIncl - totalPriceTaxExcl)] })] }), _jsxs("div", { className: "flex justify-between text-base pt-2 border-t border-gray-200", children: [_jsx("span", { className: "font-semibold text-gray-900", children: "Total (incl. tax):" }), _jsxs("span", { className: "font-bold text-gray-900", children: [currency, " ", formatNumber(totalPriceTaxIncl)] })] })] }))] }));
|
|
398
434
|
}
|
|
@@ -4,7 +4,7 @@ import { actions } from "../../document-models/invoice/index.js";
|
|
|
4
4
|
import { generateId } from "document-model";
|
|
5
5
|
let GRAPHQL_URL = "http://localhost:4001/graphql/invoice";
|
|
6
6
|
if (!window.document.baseURI.includes('localhost')) {
|
|
7
|
-
GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql/invoice';
|
|
7
|
+
GRAPHQL_URL = 'https://switchboard-dev.powerhouse.xyz/graphql/invoice';
|
|
8
8
|
}
|
|
9
9
|
const RequestFinance = ({ docState, dispatch, }) => {
|
|
10
10
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
let GRAPHQL_URL = 'http://localhost:4001/graphql/invoice';
|
|
9
9
|
if (!window.document.baseURI.includes('localhost')) {
|
|
10
|
-
GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql/invoice';
|
|
10
|
+
GRAPHQL_URL = 'https://switchboard-dev.powerhouse.xyz/graphql/invoice';
|
|
11
11
|
}
|
|
12
12
|
export async function uploadPdfChunked(pdfData, endpoint = GRAPHQL_URL, chunkSize = 500 * 1024, // 500KB chunks
|
|
13
13
|
onProgress) {
|
package/dist/style.css
CHANGED
|
@@ -354,6 +354,9 @@
|
|
|
354
354
|
.mt-2 {
|
|
355
355
|
margin-top: calc(var(--spacing) * 2);
|
|
356
356
|
}
|
|
357
|
+
.mt-3 {
|
|
358
|
+
margin-top: calc(var(--spacing) * 3);
|
|
359
|
+
}
|
|
357
360
|
.mt-4 {
|
|
358
361
|
margin-top: calc(var(--spacing) * 4);
|
|
359
362
|
}
|
|
@@ -372,6 +375,9 @@
|
|
|
372
375
|
.mb-2 {
|
|
373
376
|
margin-bottom: calc(var(--spacing) * 2);
|
|
374
377
|
}
|
|
378
|
+
.mb-3 {
|
|
379
|
+
margin-bottom: calc(var(--spacing) * 3);
|
|
380
|
+
}
|
|
375
381
|
.mb-4 {
|
|
376
382
|
margin-bottom: calc(var(--spacing) * 4);
|
|
377
383
|
}
|
|
@@ -427,6 +433,12 @@
|
|
|
427
433
|
.h-4 {
|
|
428
434
|
height: calc(var(--spacing) * 4);
|
|
429
435
|
}
|
|
436
|
+
.h-5 {
|
|
437
|
+
height: calc(var(--spacing) * 5);
|
|
438
|
+
}
|
|
439
|
+
.h-6 {
|
|
440
|
+
height: calc(var(--spacing) * 6);
|
|
441
|
+
}
|
|
430
442
|
.h-8 {
|
|
431
443
|
height: calc(var(--spacing) * 8);
|
|
432
444
|
}
|
|
@@ -460,6 +472,12 @@
|
|
|
460
472
|
.w-4 {
|
|
461
473
|
width: calc(var(--spacing) * 4);
|
|
462
474
|
}
|
|
475
|
+
.w-5 {
|
|
476
|
+
width: calc(var(--spacing) * 5);
|
|
477
|
+
}
|
|
478
|
+
.w-6 {
|
|
479
|
+
width: calc(var(--spacing) * 6);
|
|
480
|
+
}
|
|
463
481
|
.w-8 {
|
|
464
482
|
width: calc(var(--spacing) * 8);
|
|
465
483
|
}
|
|
@@ -496,6 +514,9 @@
|
|
|
496
514
|
.w-full {
|
|
497
515
|
width: 100%;
|
|
498
516
|
}
|
|
517
|
+
.max-w-\[60\%\] {
|
|
518
|
+
max-width: 60%;
|
|
519
|
+
}
|
|
499
520
|
.max-w-\[200px\] {
|
|
500
521
|
max-width: 200px;
|
|
501
522
|
}
|
|
@@ -508,6 +529,9 @@
|
|
|
508
529
|
.max-w-xl {
|
|
509
530
|
max-width: var(--container-xl);
|
|
510
531
|
}
|
|
532
|
+
.max-w-xs {
|
|
533
|
+
max-width: var(--container-xs);
|
|
534
|
+
}
|
|
511
535
|
.min-w-\[142px\] {
|
|
512
536
|
min-width: 142px;
|
|
513
537
|
}
|
|
@@ -566,12 +590,18 @@
|
|
|
566
590
|
.flex-col {
|
|
567
591
|
flex-direction: column;
|
|
568
592
|
}
|
|
569
|
-
.flex-
|
|
570
|
-
flex-
|
|
593
|
+
.flex-row {
|
|
594
|
+
flex-direction: row;
|
|
595
|
+
}
|
|
596
|
+
.flex-wrap {
|
|
597
|
+
flex-wrap: wrap;
|
|
571
598
|
}
|
|
572
599
|
.items-center {
|
|
573
600
|
align-items: center;
|
|
574
601
|
}
|
|
602
|
+
.items-start {
|
|
603
|
+
align-items: flex-start;
|
|
604
|
+
}
|
|
575
605
|
.justify-between {
|
|
576
606
|
justify-content: space-between;
|
|
577
607
|
}
|
|
@@ -581,6 +611,9 @@
|
|
|
581
611
|
.justify-end {
|
|
582
612
|
justify-content: flex-end;
|
|
583
613
|
}
|
|
614
|
+
.gap-0 {
|
|
615
|
+
gap: calc(var(--spacing) * 0);
|
|
616
|
+
}
|
|
584
617
|
.gap-1 {
|
|
585
618
|
gap: calc(var(--spacing) * 1);
|
|
586
619
|
}
|
|
@@ -600,6 +633,13 @@
|
|
|
600
633
|
margin-block-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)));
|
|
601
634
|
}
|
|
602
635
|
}
|
|
636
|
+
.space-y-3 {
|
|
637
|
+
:where(& > :not(:last-child)) {
|
|
638
|
+
--tw-space-y-reverse: 0;
|
|
639
|
+
margin-block-start: calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));
|
|
640
|
+
margin-block-end: calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)));
|
|
641
|
+
}
|
|
642
|
+
}
|
|
603
643
|
.space-y-4 {
|
|
604
644
|
:where(& > :not(:last-child)) {
|
|
605
645
|
--tw-space-y-reverse: 0;
|
|
@@ -640,6 +680,9 @@
|
|
|
640
680
|
.overflow-x-auto {
|
|
641
681
|
overflow-x: auto;
|
|
642
682
|
}
|
|
683
|
+
.overflow-y-auto {
|
|
684
|
+
overflow-y: auto;
|
|
685
|
+
}
|
|
643
686
|
.rounded {
|
|
644
687
|
border-radius: 0.25rem;
|
|
645
688
|
}
|
|
@@ -665,6 +708,14 @@
|
|
|
665
708
|
border-style: var(--tw-border-style);
|
|
666
709
|
border-width: 1px;
|
|
667
710
|
}
|
|
711
|
+
.border-0 {
|
|
712
|
+
border-style: var(--tw-border-style);
|
|
713
|
+
border-width: 0px;
|
|
714
|
+
}
|
|
715
|
+
.border-2 {
|
|
716
|
+
border-style: var(--tw-border-style);
|
|
717
|
+
border-width: 2px;
|
|
718
|
+
}
|
|
668
719
|
.border-t {
|
|
669
720
|
border-top-style: var(--tw-border-style);
|
|
670
721
|
border-top-width: 1px;
|
|
@@ -677,12 +728,19 @@
|
|
|
677
728
|
border-bottom-style: var(--tw-border-style);
|
|
678
729
|
border-bottom-width: 2px;
|
|
679
730
|
}
|
|
731
|
+
.border-dashed {
|
|
732
|
+
--tw-border-style: dashed;
|
|
733
|
+
border-style: dashed;
|
|
734
|
+
}
|
|
680
735
|
.border-blue-100 {
|
|
681
736
|
border-color: var(--color-blue-100);
|
|
682
737
|
}
|
|
683
738
|
.border-blue-500 {
|
|
684
739
|
border-color: var(--color-blue-500);
|
|
685
740
|
}
|
|
741
|
+
.border-gray-100 {
|
|
742
|
+
border-color: var(--color-gray-100);
|
|
743
|
+
}
|
|
686
744
|
.border-gray-200 {
|
|
687
745
|
border-color: var(--color-gray-200);
|
|
688
746
|
}
|
|
@@ -770,6 +828,9 @@
|
|
|
770
828
|
.p-0 {
|
|
771
829
|
padding: calc(var(--spacing) * 0);
|
|
772
830
|
}
|
|
831
|
+
.p-1 {
|
|
832
|
+
padding: calc(var(--spacing) * 1);
|
|
833
|
+
}
|
|
773
834
|
.p-2 {
|
|
774
835
|
padding: calc(var(--spacing) * 2);
|
|
775
836
|
}
|
|
@@ -800,6 +861,9 @@
|
|
|
800
861
|
.px-6 {
|
|
801
862
|
padding-inline: calc(var(--spacing) * 6);
|
|
802
863
|
}
|
|
864
|
+
.py-0\.5 {
|
|
865
|
+
padding-block: calc(var(--spacing) * 0.5);
|
|
866
|
+
}
|
|
803
867
|
.py-1 {
|
|
804
868
|
padding-block: calc(var(--spacing) * 1);
|
|
805
869
|
}
|
|
@@ -809,9 +873,15 @@
|
|
|
809
873
|
.py-3 {
|
|
810
874
|
padding-block: calc(var(--spacing) * 3);
|
|
811
875
|
}
|
|
876
|
+
.py-6 {
|
|
877
|
+
padding-block: calc(var(--spacing) * 6);
|
|
878
|
+
}
|
|
812
879
|
.pt-2 {
|
|
813
880
|
padding-top: calc(var(--spacing) * 2);
|
|
814
881
|
}
|
|
882
|
+
.pt-3 {
|
|
883
|
+
padding-top: calc(var(--spacing) * 3);
|
|
884
|
+
}
|
|
815
885
|
.pt-4 {
|
|
816
886
|
padding-top: calc(var(--spacing) * 4);
|
|
817
887
|
}
|
|
@@ -888,12 +958,18 @@
|
|
|
888
958
|
.text-blue-600 {
|
|
889
959
|
color: var(--color-blue-600);
|
|
890
960
|
}
|
|
961
|
+
.text-blue-800 {
|
|
962
|
+
color: var(--color-blue-800);
|
|
963
|
+
}
|
|
891
964
|
.text-blue-900 {
|
|
892
965
|
color: var(--color-blue-900);
|
|
893
966
|
}
|
|
894
967
|
.text-gray-50 {
|
|
895
968
|
color: var(--color-gray-50);
|
|
896
969
|
}
|
|
970
|
+
.text-gray-400 {
|
|
971
|
+
color: var(--color-gray-400);
|
|
972
|
+
}
|
|
897
973
|
.text-gray-500 {
|
|
898
974
|
color: var(--color-gray-500);
|
|
899
975
|
}
|
|
@@ -1089,6 +1165,13 @@
|
|
|
1089
1165
|
}
|
|
1090
1166
|
}
|
|
1091
1167
|
}
|
|
1168
|
+
.hover\:bg-red-50 {
|
|
1169
|
+
&:hover {
|
|
1170
|
+
@media (hover: hover) {
|
|
1171
|
+
background-color: var(--color-red-50);
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1092
1175
|
.hover\:bg-red-700 {
|
|
1093
1176
|
&:hover {
|
|
1094
1177
|
@media (hover: hover) {
|
|
@@ -1216,6 +1299,26 @@
|
|
|
1216
1299
|
line-height: var(--tw-leading, var(--text-base--line-height));
|
|
1217
1300
|
}
|
|
1218
1301
|
}
|
|
1302
|
+
.md\:block {
|
|
1303
|
+
@media (width >= 48rem) {
|
|
1304
|
+
display: block;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
.md\:flex {
|
|
1308
|
+
@media (width >= 48rem) {
|
|
1309
|
+
display: flex;
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
.md\:hidden {
|
|
1313
|
+
@media (width >= 48rem) {
|
|
1314
|
+
display: none;
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
.md\:inline {
|
|
1318
|
+
@media (width >= 48rem) {
|
|
1319
|
+
display: inline;
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1219
1322
|
.md\:grid-cols-2 {
|
|
1220
1323
|
@media (width >= 48rem) {
|
|
1221
1324
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
@@ -1227,6 +1330,32 @@
|
|
|
1227
1330
|
line-height: var(--tw-leading, var(--text-2xl--line-height));
|
|
1228
1331
|
}
|
|
1229
1332
|
}
|
|
1333
|
+
.lg\:gap-4 {
|
|
1334
|
+
@media (width >= 64rem) {
|
|
1335
|
+
gap: calc(var(--spacing) * 4);
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
.lg\:rounded-lg {
|
|
1339
|
+
@media (width >= 64rem) {
|
|
1340
|
+
border-radius: var(--radius-lg);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
.lg\:border {
|
|
1344
|
+
@media (width >= 64rem) {
|
|
1345
|
+
border-style: var(--tw-border-style);
|
|
1346
|
+
border-width: 1px;
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
.lg\:border-gray-200 {
|
|
1350
|
+
@media (width >= 64rem) {
|
|
1351
|
+
border-color: var(--color-gray-200);
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
.lg\:p-4 {
|
|
1355
|
+
@media (width >= 64rem) {
|
|
1356
|
+
padding: calc(var(--spacing) * 4);
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1230
1359
|
}
|
|
1231
1360
|
/*! tailwindcss v4.1.12 | MIT License | https://tailwindcss.com */
|
|
1232
1361
|
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");
|
|
@@ -19139,15 +19268,15 @@ input[type="number"] {
|
|
|
19139
19268
|
}
|
|
19140
19269
|
@media (max-width: 640px) {
|
|
19141
19270
|
.editor-container {
|
|
19142
|
-
padding: 0.
|
|
19143
|
-
transform:
|
|
19271
|
+
padding: 0.125rem;
|
|
19272
|
+
transform: none;
|
|
19144
19273
|
transform-origin: top left;
|
|
19145
19274
|
}
|
|
19146
19275
|
}
|
|
19147
19276
|
@media (min-width: 641px) and (max-width: 1023px) {
|
|
19148
19277
|
.editor-container {
|
|
19149
|
-
padding: 0.
|
|
19150
|
-
transform:
|
|
19278
|
+
padding: 0.25rem;
|
|
19279
|
+
transform: none;
|
|
19151
19280
|
transform-origin: top left;
|
|
19152
19281
|
}
|
|
19153
19282
|
}
|
|
@@ -19160,6 +19289,42 @@ input[type="number"] {
|
|
|
19160
19289
|
transform: none;
|
|
19161
19290
|
}
|
|
19162
19291
|
}
|
|
19292
|
+
@media (min-width: 768px) {
|
|
19293
|
+
.md\:grid-cols-2 {
|
|
19294
|
+
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
|
|
19295
|
+
}
|
|
19296
|
+
}
|
|
19297
|
+
@media (min-width: 768px) {
|
|
19298
|
+
.md\:flex {
|
|
19299
|
+
display: flex !important;
|
|
19300
|
+
}
|
|
19301
|
+
.md\:hidden {
|
|
19302
|
+
display: none !important;
|
|
19303
|
+
}
|
|
19304
|
+
.md\:block {
|
|
19305
|
+
display: block !important;
|
|
19306
|
+
}
|
|
19307
|
+
.md\:inline {
|
|
19308
|
+
display: inline !important;
|
|
19309
|
+
}
|
|
19310
|
+
}
|
|
19311
|
+
@media (min-width: 1024px) {
|
|
19312
|
+
.lg\:gap-4 {
|
|
19313
|
+
gap: 1rem !important;
|
|
19314
|
+
}
|
|
19315
|
+
.lg\:border {
|
|
19316
|
+
border-width: 1px !important;
|
|
19317
|
+
}
|
|
19318
|
+
.lg\:border-gray-200 {
|
|
19319
|
+
border-color: rgb(229, 231, 235) !important;
|
|
19320
|
+
}
|
|
19321
|
+
.lg\:rounded-lg {
|
|
19322
|
+
border-radius: 0.5rem !important;
|
|
19323
|
+
}
|
|
19324
|
+
.lg\:p-4 {
|
|
19325
|
+
padding: 1rem !important;
|
|
19326
|
+
}
|
|
19327
|
+
}
|
|
19163
19328
|
@property --tw-border-spacing-x {
|
|
19164
19329
|
syntax: "<length>";
|
|
19165
19330
|
inherits: false;
|
package/dist/tailwind.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerhousedao/contributor-billing",
|
|
3
3
|
"description": "Document models that help contributors of open organisations get paid anonymously for their work on a monthly basis.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.99",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
@@ -57,9 +57,9 @@
|
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@google-cloud/documentai": "^8.12.0",
|
|
60
|
-
"@powerhousedao/builder-tools": "^5.0.0-staging.
|
|
61
|
-
"@powerhousedao/common": "^5.0.0-staging.
|
|
62
|
-
"@powerhousedao/design-system": "^5.0.0-staging.
|
|
60
|
+
"@powerhousedao/builder-tools": "^5.0.0-staging.22",
|
|
61
|
+
"@powerhousedao/common": "^5.0.0-staging.22",
|
|
62
|
+
"@powerhousedao/design-system": "^5.0.0-staging.22",
|
|
63
63
|
"@powerhousedao/document-engineering": "^1.38.0",
|
|
64
64
|
"@react-pdf/renderer": "^4.3.0",
|
|
65
65
|
"@safe-global/api-kit": "^3.0.1",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"@types/cors": "^2.8.17",
|
|
70
70
|
"axios": "^1.9.0",
|
|
71
71
|
"cors": "^2.8.5",
|
|
72
|
-
"document-model": "^5.0.0-staging.
|
|
72
|
+
"document-model": "^5.0.0-staging.22",
|
|
73
73
|
"dotenv": "^16.5.0",
|
|
74
74
|
"error": "^10.4.0",
|
|
75
75
|
"ethers": "^6.14.0",
|
|
@@ -84,20 +84,21 @@
|
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@electric-sql/pglite": "^0.2.12",
|
|
86
86
|
"@eslint/js": "^9.25.0",
|
|
87
|
+
"@playwright/test": "^1.56.0",
|
|
87
88
|
"@powerhousedao/analytics-engine-core": "^0.5.0",
|
|
88
|
-
"@powerhousedao/codegen": "^5.0.0-staging.
|
|
89
|
-
"@powerhousedao/ph-cli": "^5.0.0-staging.
|
|
90
|
-
"@powerhousedao/reactor-api": "^5.0.0-staging.
|
|
91
|
-
"@powerhousedao/reactor-browser": "^5.0.0-staging.
|
|
92
|
-
"@powerhousedao/reactor-local": "^5.0.0-staging.
|
|
89
|
+
"@powerhousedao/codegen": "^5.0.0-staging.22",
|
|
90
|
+
"@powerhousedao/ph-cli": "^5.0.0-staging.22",
|
|
91
|
+
"@powerhousedao/reactor-api": "^5.0.0-staging.22",
|
|
92
|
+
"@powerhousedao/reactor-browser": "^5.0.0-staging.22",
|
|
93
|
+
"@powerhousedao/reactor-local": "^5.0.0-staging.22",
|
|
93
94
|
"@powerhousedao/scalars": "^1.33.1-staging.5",
|
|
94
|
-
"@powerhousedao/switchboard": "^5.0.0-staging.
|
|
95
|
+
"@powerhousedao/switchboard": "^5.0.0-staging.22",
|
|
95
96
|
"@tailwindcss/cli": "^4.1.4",
|
|
96
97
|
"@testing-library/react": "^16.3.0",
|
|
97
98
|
"@types/node": "^22.14.1",
|
|
98
99
|
"@types/react": "^18.3.20",
|
|
99
100
|
"@vitejs/plugin-react": "^4.4.1",
|
|
100
|
-
"document-drive": "^5.0.0-staging.
|
|
101
|
+
"document-drive": "^5.0.0-staging.22",
|
|
101
102
|
"eslint": "^9.25.0",
|
|
102
103
|
"eslint-plugin-react": "^7.37.5",
|
|
103
104
|
"eslint-plugin-react-hooks": "^5.2.0",
|