wip
This commit is contained in:
112
src/components/listInvoices.ts
Normal file
112
src/components/listInvoices.ts
Normal 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,
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user