Improve look and performance of orders table

This commit is contained in:
Dominic Ferrando
2026-07-17 15:33:17 -04:00
parent 1673bc5498
commit fdbfbb125d
3 changed files with 147 additions and 67 deletions
@@ -1,12 +0,0 @@
import { printful } from "$lib/printful";
import { webflow } from "$lib/webflow";
import type { PageServerLoad } from "./$types";
export const load = async ({ }: Parameters<PageServerLoad>[0]) => {
return {
orders: {
printful: printful.Orders.list({ forceAll: true }),
webflow: webflow.Orders.list({ forceAll: true }),
},
};
};
@@ -1,62 +1,128 @@
<script lang="ts">
import { api } from "$lib/api.js";
import type { Webflow } from "@blade-and-brawn/commerce";
import { onMount } from "svelte";
const { data } = $props();
type OrderRow = NonNullable<
Awaited<ReturnType<typeof api.commerce.orders.get>>["data"]
>[number];
const isOrderSynced = async (wOrder: Webflow.Orders.Order) => {
const pOrders = await data.orders.printful;
return pOrders.some((pOrder) => pOrder.external_id === wOrder.orderId);
};
const LIMIT = 25;
let orders = $state<OrderRow[]>([]);
let loading = $state(true);
let loadError = $state<string | null>(null);
let offset = $state(0);
function errorMessage(err: unknown): string {
const value = (err as { value?: { error?: string } })?.value;
return (
value?.error ??
(err instanceof Error ? err.message : "Unknown error")
);
}
async function refresh() {
loading = true;
loadError = null;
try {
const res = await api.commerce.orders.get({
query: {
limit: LIMIT,
offset,
},
});
if (res.error) throw res.error;
orders = res.data as OrderRow[];
} catch (err) {
loadError = errorMessage(err);
} finally {
loading = false;
}
}
function prevPage() {
offset = Math.max(0, offset - LIMIT);
refresh();
}
function nextPage() {
offset += LIMIT;
refresh();
}
onMount(refresh);
</script>
{#await data.orders.webflow}
<p>Loading...</p>
{:then wOrders}
<div class="w-full mt-10 overflow-x-auto">
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{#each wOrders as wOrder}
<tr class="hover:bg-base-300">
<td
><button
onclick={async () => {
const res = await api.commerce
.orders({
wOrderId: wOrder.orderId,
})
.get();
console.log(res.data);
}}
class="cursor-pointer underline"
>
{wOrder.orderId}
</button></td
>
<td>
{#await isOrderSynced(wOrder) then isSynced}
{#if isSynced}
<div class="badge badge-success">
Synced
</div>
{:else}
<div class="badge badge-error">
Desynced
</div>
{/if}
{/await}
</td>
</tr>
{/each}
</tbody>
</table>
<div class="w-full flex items-center gap-2 flex-wrap mt-10 mb-5">
<button class="btn btn-sm" onclick={refresh} disabled={loading}>
{loading ? "Refreshing..." : "Refresh"}
</button>
<div class="flex-1"></div>
<button
class="btn btn-sm"
onclick={prevPage}
disabled={offset === 0 || loading}
>
Prev
</button>
<button
class="btn btn-sm"
onclick={nextPage}
disabled={orders.length < LIMIT || loading}
>
Next
</button>
</div>
{#if loadError}
<div role="alert" class="alert alert-error w-full mb-4">
<span>{loadError}</span>
</div>
{:catch error}
<p>Something went wrong: {error.message}</p>
{/await}
{/if}
<div class="w-full overflow-x-auto">
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{#each orders as order (order.wOrder.orderId)}
<tr class="hover:bg-base-300">
<td
><button
onclick={async () => {
const res = await api.commerce
.orders({
wOrderId: order.wOrder.orderId,
})
.get();
console.log(res.data);
}}
class="cursor-pointer underline"
>
{order.wOrder.orderId}
</button></td
>
<td>
{#if order.isSynced}
<div class="badge badge-success">Synced</div>
{:else}
<div class="badge badge-error">Desynced</div>
{/if}
</td>
</tr>
{:else}
<tr>
<td colspan="2" class="text-center opacity-60">
{loading ? "Loading..." : "No orders found"}
</td>
</tr>
{/each}
</tbody>
</table>
</div>