119 lines
4.7 KiB
TypeScript
119 lines
4.7 KiB
TypeScript
import Link from "next/link";
|
|
import { auth } from "@clerk/nextjs/server";
|
|
import { prisma } from "@/lib/prisma";
|
|
import { redirect } from "next/navigation";
|
|
import { UserButton } from "@clerk/nextjs";
|
|
import CopyButton from "@/components/CopyButton";
|
|
import DeleteMonumentButton from "@/components/DeleteMonumentButton";
|
|
import DeleteImageButton from "@/components/DeleteImageButton";
|
|
|
|
export default async function DashboardPage() {
|
|
const { userId } = await auth();
|
|
if (!userId) redirect("/sign-in");
|
|
|
|
const user = await prisma.user.findUnique({
|
|
where: { clerkId: userId },
|
|
include: { images: { orderBy: { order: "asc" } } },
|
|
});
|
|
|
|
if (!user) {
|
|
redirect("/onboarding");
|
|
}
|
|
|
|
const monumentUrl = `https://${user.subdomain}.${process.env.NEXT_PUBLIC_APP_DOMAIN}`;
|
|
|
|
return (
|
|
<div className="min-h-screen bg-stone-50">
|
|
<header className="border-b border-stone-200 bg-white">
|
|
<div className="mx-auto flex max-w-5xl items-center justify-between px-6 py-4">
|
|
<h1 className="text-xl font-semibold text-stone-900">SpomeniQR</h1>
|
|
<UserButton />
|
|
</div>
|
|
</header>
|
|
|
|
<main className="mx-auto max-w-5xl px-6 py-8">
|
|
<div className="rounded-lg border border-stone-200 bg-white p-6">
|
|
<h2 className="text-2xl font-semibold text-stone-900">{user.title || "Untitled Memorial"}</h2>
|
|
{(user.bornDate || user.passedDate) && (
|
|
<p className="mt-1 text-sm tracking-wider text-stone-400">
|
|
{user.bornDate}{user.bornDate && user.passedDate ? " — " : ""}{user.passedDate}
|
|
</p>
|
|
)}
|
|
<p className="mt-2 text-sm text-stone-500">
|
|
{user.published ? "Published" : "Draft"} · Subdomain: <span className="font-mono">{user.subdomain}</span>
|
|
</p>
|
|
|
|
<div className="mt-6 flex flex-wrap gap-3">
|
|
<Link
|
|
href={monumentUrl}
|
|
target="_blank"
|
|
className="rounded-lg bg-primary px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-primary-light"
|
|
>
|
|
View Monument
|
|
</Link>
|
|
<Link
|
|
href="/dashboard/edit"
|
|
className="rounded-lg border border-stone-200 px-4 py-2 text-sm font-medium text-stone-700 transition-colors hover:bg-stone-50"
|
|
>
|
|
Edit
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
|
|
{user.images.length > 0 && (
|
|
<div className="mt-6">
|
|
<h3 className="text-lg font-medium text-stone-900">Images</h3>
|
|
<div className="mt-3 grid grid-cols-3 gap-4">
|
|
{user.images.map((img) => (
|
|
<div key={img.id} className="group relative overflow-hidden rounded-lg border border-stone-200">
|
|
<img src={img.url} alt="" className="h-40 w-full object-cover" />
|
|
<DeleteImageButton imageId={img.id} />
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
<div className="mt-6">
|
|
<h3 className="text-lg font-medium text-stone-900">Monument QR Code</h3>
|
|
<p className="mt-1 text-sm text-stone-500">Download and display this QR code at your monument location.</p>
|
|
<div className="mt-4 rounded-lg border border-stone-200 bg-white p-4">
|
|
<img
|
|
src={`https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(monumentUrl)}`}
|
|
alt="QR Code"
|
|
className="h-48 w-48"
|
|
/>
|
|
<a
|
|
href={`https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=${encodeURIComponent(monumentUrl)}`}
|
|
download
|
|
className="mt-4 inline-block rounded-lg bg-primary px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-primary-light"
|
|
>
|
|
Download QR
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-6">
|
|
<h3 className="text-lg font-medium text-stone-900">Share Link</h3>
|
|
<div className="mt-2 flex items-center gap-2">
|
|
<input
|
|
type="text"
|
|
readOnly
|
|
value={monumentUrl}
|
|
className="flex-1 rounded-lg border border-stone-200 bg-stone-50 px-3 py-2 font-mono text-sm text-stone-700"
|
|
/>
|
|
<CopyButton text={monumentUrl} />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-10 border-t border-stone-200 pt-6">
|
|
<h3 className="text-sm font-medium text-red-600">Danger Zone</h3>
|
|
<p className="mt-1 text-xs text-stone-500">Permanently delete your monument and all associated images.</p>
|
|
<div className="mt-3">
|
|
<DeleteMonumentButton />
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
} |