import { render } from "preact";
import { useEffect, useState } from "preact/hooks";
interface InvoiceRow {
id: string;
invoiceNumber: string;
version: number;
kind: string;
issuedAt: string;
status: string;
pdfUrl: string;
cancelledAt: string | null;
sentAt: string | null;
}
interface Payload {
latest: InvoiceRow | null;
history: InvoiceRow[];
}
export default async () => {
render(, document.body);
};
function Extension() {
const { data } = (globalThis as any).shopify;
const orderGid: string | undefined = data?.selected?.[0]?.id;
const orderId = orderGid ? orderGid.split("/").pop() : undefined;
const [payload, setPayload] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
if (!orderId) return;
let cancelled = false;
(async () => {
try {
const res = await fetch(`/api/orders/${orderId}/invoice`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const json: Payload = await res.json();
if (!cancelled) setPayload(json);
} catch (e: any) {
if (!cancelled) setError(e?.message ?? "Failed to load");
} finally {
if (!cancelled) setLoading(false);
}
})();
return () => {
cancelled = true;
};
}, [orderId]);
return (
{loading ? (
Loading…
) : error ? (
{error}
) : !payload?.latest ? (
No invoice yet for this order.
) : (
{payload.latest.invoiceNumber} (v{payload.latest.version})
Issued {new Date(payload.latest.issuedAt).toLocaleDateString()}
{payload.latest.sentAt ? "Sent" : "Not sent"}
{payload.latest.pdfUrl ? (
View PDF
) : null}
{payload.history.length > 1 ? (
{payload.history.length} versions in history
) : null}
)}
);
}