Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 6 additions & 254 deletions package-lock.json

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions src/app/(dashboard)/customers/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export const metadata = {
title: "Customers | Shade",
description: "Review and manage Shade customers.",
};

export default function CustomersPage() {
return (
<div className="mx-auto w-full max-w-5xl space-y-8">
<header className="space-y-1">
<p className="text-sm font-semibold uppercase text-primary">
Shade merchant
</p>
<h1 className="text-3xl font-bold">Customers</h1>
</header>

<section className="rounded-lg border bg-card p-6 shadow-sm">
<h2 className="text-lg font-semibold text-card-foreground">
Customer management
</h2>
<p className="mt-2 text-sm text-muted-foreground">
Customer profiles and payment history will appear here.
</p>
</section>
</div>
);
}
File renamed without changes.
54 changes: 54 additions & 0 deletions src/app/(dashboard)/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { DollarSign, FileText, TrendingUp, Users } from "lucide-react";

import { ApiKeyManagement } from "@/components/dashboard/api-key-management";
import { StatCard } from "@/components/StatCard";
import { DashboardActions } from "./dashboard-actions";

export const metadata = {
title: "Dashboard | Shade",
description: "Shade merchant dashboard.",
};

export default function DashboardPage() {
return (
<div className="space-y-6">
<div>
<h1 className="text-2xl font-bold text-foreground">Dashboard</h1>
<p className="mt-1 text-sm text-muted-foreground">
Welcome back. Here&apos;s an overview of your business.
</p>
</div>

<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
<StatCard
title="Total revenue"
value="$12,430"
icon={<DollarSign className="size-4" />}
trend={12.5}
/>
<StatCard
title="Active invoices"
value="24"
icon={<FileText className="size-4" />}
trend={-3.2}
/>
<StatCard
title="Total customers"
value="138"
icon={<Users className="size-4" />}
trend={8.1}
/>
<StatCard
title="Payment volume"
value="$9,870"
icon={<TrendingUp className="size-4" />}
trend={5.4}
/>
</div>

<DashboardActions />

<ApiKeyManagement />
</div>
);
}
23 changes: 23 additions & 0 deletions src/app/(dashboard)/invoice-tools/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { InvoiceToolsClient } from "./invoice-tools-client";

export const metadata = {
title: "Invoice tools | Shade",
description: "Validation, lookup, timeline, and avatar components preview.",
};

export default function InvoiceToolsPage() {
return (
<div className="mx-auto w-full max-w-5xl space-y-10">
<header className="space-y-1">
<p className="text-sm font-semibold uppercase text-primary">
Shade merchant
</p>
<h1 className="text-3xl font-bold">Invoice tools</h1>
<p className="text-sm text-muted-foreground">
Validated invoice creation, payer lookup, timeline, and logo uploader.
</p>
</header>
<InvoiceToolsClient />
</div>
);
}
105 changes: 105 additions & 0 deletions src/app/(dashboard)/invoices/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import Link from "next/link";

import { InvoiceStatusBadge } from "@/components/invoice/invoice-status-badge";
import type { InvoiceStatus } from "@/lib/invoice-types";

export const metadata = {
title: "Invoice details | Shade",
description: "View invoice details.",
};

type InvoiceDetailsPageProps = {
params: Promise<{ id: string }>;
};

function formatDate(value: string) {
const date = new Date(value);
if (Number.isNaN(date.getTime())) return value;
return date.toLocaleDateString(undefined, {
year: "numeric",
month: "long",
day: "numeric",
});
}

export default async function InvoiceDetailsPage({
params,
}: InvoiceDetailsPageProps) {
const { id } = await params;

const amount = "450.00";
const token = "USDC";
const status: InvoiceStatus = "pending";
const createdAt = "2026-05-12T14:30:00.000Z";
const dueDate = "2026-06-12T14:30:00.000Z";
const payerName = "Acme Corp";
const payerEmail = "billing@acme.example";

return (
<div className="mx-auto w-full max-w-5xl space-y-8">
<header className="space-y-1">
<Link
href="/invoices"
className="text-sm font-medium text-primary hover:underline"
>
← Back to invoices
</Link>
<p className="text-sm font-semibold uppercase text-primary">
Invoice {id}
</p>
</header>

<section className="rounded-lg border bg-card p-8 shadow-sm">
<div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
<div className="space-y-2">
<p className="text-sm font-medium text-muted-foreground">
Amount due
</p>
<p className="text-4xl font-bold tabular-nums tracking-tight">
{amount}{" "}
<span className="text-2xl font-semibold text-muted-foreground">
{token}
</span>
</p>
</div>
<InvoiceStatusBadge status={status} className="text-sm px-3 py-1.5" />
</div>

<div className="mt-8 grid grid-cols-1 gap-6 border-t pt-8 sm:grid-cols-2">
<div className="space-y-1">
<p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
Created
</p>
<p className="text-sm font-medium">{formatDate(createdAt)}</p>
</div>
<div className="space-y-1">
<p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
Due date
</p>
<p className="text-sm font-medium">{formatDate(dueDate)}</p>
</div>
<div className="space-y-1">
<p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
Payer name
</p>
<p className="text-sm font-medium">{payerName}</p>
</div>
<div className="space-y-1">
<p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
Payer email
</p>
<p className="text-sm font-medium">{payerEmail}</p>
</div>
<div className="space-y-1 sm:col-span-2">
<p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
Description
</p>
<p className="text-sm font-medium">
Brand identity refresh — invoice reference {id}
</p>
</div>
</div>
</section>
</div>
);
}
20 changes: 20 additions & 0 deletions src/app/(dashboard)/invoices/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { InvoicesClient } from "./invoices-client";

export const metadata = {
title: "Invoices | Shade",
description: "Generate and review your Shade invoices.",
};

export default function InvoicesPage() {
return (
<div className="mx-auto w-full max-w-5xl space-y-8">
<header className="space-y-1">
<p className="text-sm font-semibold uppercase text-primary">
Shade merchant
</p>
<h1 className="text-3xl font-bold">Invoices</h1>
</header>
<InvoicesClient />
</div>
);
}
2 changes: 1 addition & 1 deletion src/app/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function DashboardLayout({
<div className="min-h-screen bg-background">
<Sidebar />
<Topbar />
<div className="ml-60 pt-16">
<div className="ml-0 pt-16 md:ml-60">
<main className="min-h-[calc(100vh-4rem)] overflow-y-auto p-6">
{children}
</main>
Expand Down
31 changes: 31 additions & 0 deletions src/app/(dashboard)/settings/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { Metadata } from "next";

import { SettingsNav } from "@/components/settings/settings-nav";

export const metadata: Metadata = {
title: "Settings | Shade",
description: "Manage your Shade merchant profile and API keys.",
};

export default function SettingsLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="mx-auto w-full max-w-5xl space-y-8">
<header className="space-y-1">
<p className="text-sm font-semibold uppercase text-primary">
Shade merchant
</p>
<h1 className="text-3xl font-bold">Settings</h1>
</header>
<div className="flex flex-col gap-6 md:flex-row md:items-start">
<SettingsNav />
<section className="min-w-0 flex-1 rounded-lg border bg-card p-6 shadow-sm">
{children}
</section>
</div>
</div>
);
}
File renamed without changes.
61 changes: 0 additions & 61 deletions src/app/dashboard/page.tsx

This file was deleted.

26 changes: 0 additions & 26 deletions src/app/invoice-tools/page.tsx

This file was deleted.

Loading
Loading