This commit is contained in:
Tim Bendt
2024-11-01 11:32:37 -05:00
parent 22cb743835
commit fb36fb8303
12 changed files with 751 additions and 159 deletions

View File

@@ -0,0 +1,112 @@
import {
Box,
Button,
Container,
Flex,
Flow,
Screen,
ScrollableList,
Text,
} from "wretched";
import {
ClientResponse,
InvoiceResponse,
getAllClients,
getAllInvoices,
getAllProjects,
} from "../services/pancakeApi.js";
import { compact, find, reverse, sortBy } from "lodash-es";
import Table from "cli-table3";
import { differenceInBusinessDays, format, parse } from "date-fns";
import { tableCellBox } from "./helpers/tableCellBox.js";
import { Theme } from "wretched/dist/Theme.js";
import {
distanceInBizDays,
parseServiceDateString,
simpleFormat,
} from "./helpers/dates.js";
export const renderInvoiceList = async (
clientId: string,
onSelect: (selectedInvoiceId: string | number) => void,
) => {
if (clientId === undefined) {
console.warn("No Client Id");
return new Text({ text: " --" });
}
const invResp = await getAllInvoices({ client_id: clientId });
const invoices: Array<InvoiceResponse> = invResp.invoices
.sort((a, b) => Number(a.invoice_number) - Number(b.invoice_number))
.reverse();
if (!invoices?.length) {
console.warn("No invoices");
return new Text({ text: " --" });
}
type FormattedInvoice = InvoiceResponse & { dueDistance: string };
const transformInvoice = (invoice: InvoiceResponse): FormattedInvoice => {
const ret: FormattedInvoice = { ...invoice, dueDistance: "" };
try {
if (invoice.due_date?.length > 0) {
const due = parseServiceDateString(invoice.due_date);
ret.due_date = simpleFormat(due);
ret.dueDistance = `Due in ${distanceInBizDays(due)} biz days.`;
}
if (invoice.payment_date?.length > 0) {
ret.payment_date = simpleFormat(
parseServiceDateString(invoice.payment_date),
);
}
ret.amount = "$" + Number(invoice.amount).toFixed(2).padEnd(2, "0");
} catch (error) {
console.error("Error transforming date", error);
} finally {
return ret;
}
};
// const detailsTable = new Table({
// head: ["Invoice#", "Amount", "Due", "Paid?", "Overdue?"],
// });
// const detailsTable: string[] | undefined = new Array();
// detailsTable.concat(
// ...invoices.map((x) => [
// x.invoice_number,
// Number(x.amount).toFixed(2),
// x.due_date?.substring(0, 10),
// x.is_paid ? "💰" : "⏳",
// x.overdue ? "🔥" : "✅",
// ]),
// );
return new ScrollableList({
cellForItem: (item, row) => {
return Flex.right({
children: [
new Button({
onClick: () => onSelect(item.id),
border: "none",
width: 6,
text: item.invoice_number,
}),
tableCellBox(item.amount, {
theme: item.is_paid ? Theme.green : Theme.secondary,
padding: { left: 1, right: 1, top: 0, bottom: 0 },
borders: { right: false },
width: 15,
alignment: "right",
}),
tableCellBox(item.dueDistance, {
theme: !item.is_paid && item.overdue ? Theme.red : Theme.secondary,
borders: { right: false },
padding: { left: 1, right: 1, top: 0, bottom: 0 },
width: 20,
alignment: "center",
}),
],
});
},
items: invoices.map(transformInvoice),
showScrollbars: undefined,
});
};