juntekim.com/stripe_to_invoice/app/dashboard/page.tsx
2026-02-07 17:02:18 +00:00

113 lines
3.2 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
export default function DashboardPage() {
const [salesAccountCode, setSalesAccountCode] = useState("");
const [stripeClearingAccountCode, setStripeClearingAccountCode] =
useState("");
const [stripeAccountId, setStripeAccountId] = useState("");
const [xeroTenantId, setXeroTenantId] = useState("");
const [loading, setLoading] = useState(true);
const [saved, setSaved] = useState(false);
useEffect(() => {
Promise.all([
fetch("/api/dashboard/xero-settings").then((res) => res.json()),
fetch("/api/dashboard/connections").then((res) => res.json()),
]).then(([settings, connections]) => {
setSalesAccountCode(settings.salesAccountCode ?? "");
setStripeClearingAccountCode(settings.stripeClearingAccountCode ?? "");
setStripeAccountId(connections.stripeAccountId ?? "");
setXeroTenantId(connections.xeroTenantId ?? "");
setLoading(false);
});
}, []);
async function save() {
setSaved(false);
await fetch("/api/dashboard/xero-settings", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
salesAccountCode,
stripeClearingAccountCode,
}),
});
setSaved(true);
}
if (loading) return <p>Loading</p>;
return (
<div className="max-w-xl space-y-6">
<h1 className="text-2xl font-semibold">
Stripe Xero settings
</h1>
{/* Connected Accounts */}
<div className="border rounded p-4 bg-gray-50 space-y-3">
<h2 className="font-medium text-sm text-gray-600">Connected Accounts</h2>
<div className="space-y-2 text-sm">
<p>
<span className="font-medium">Stripe:</span>{" "}
<code className="bg-white px-2 py-1 rounded text-xs">
{stripeAccountId || "Not connected"}
</code>
</p>
<p>
<span className="font-medium">Xero:</span>{" "}
<code className="bg-white px-2 py-1 rounded text-xs">
{xeroTenantId || "Not connected"}
</code>
</p>
</div>
</div>
<div>
<label className="block text-sm font-medium">
Sales account code
</label>
<input
className="mt-1 w-full border px-3 py-2"
value={salesAccountCode}
onChange={(e) => setSalesAccountCode(e.target.value)}
/>
<p className="text-sm text-zinc-500">
Used on invoice line items
</p>
</div>
<div>
<label className="block text-sm font-medium">
Stripe clearing account code
</label>
<input
className="mt-1 w-full border px-3 py-2"
value={stripeClearingAccountCode}
onChange={(e) =>
setStripeClearingAccountCode(e.target.value)
}
/>
<p className="text-sm text-zinc-500">
Receives Stripe payments
</p>
</div>
<button
onClick={save}
className="rounded bg-black px-4 py-2 text-white"
>
Save
</button>
{saved && (
<p className="text-sm text-green-600">
Saved
</p>
)}
</div>
);
}