Add data-driven public pages (home, news, profile)
Real App Router pages reading the converted Prisma models: - home: latest 4 articles (websiteArticles) + hotel_name from settings - /news + /news/[slug]: article index and detail - /u/[username]: profile (avatar via imager helper, motto, rank, credits, online) - shared SiteNav (reads session via auth() + hotel_name), globals.css - src/lib/format.ts: avatarImageUrl + excerpt helpers (unit-tested) Verified: tsc exit 0, vitest 43/43, next build exit 0 (7 routes). Pages render against a live DB (deferred until DATABASE_URL is provided). i18n to be layered on next.
This commit is contained in:
1 parent
8fca407f0f
commit
6e34d485d4
9 files changed
+327
-7
No files matched your search
@@ -0,0 +1,52 @@
|
||||
import { notFound } from "next/navigation";
|
||||
import { avatarImageUrl } from "@/lib/format";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { siteSettings } from "@/lib/services/site-settings";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export default async function ProfilePage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ username: string }>;
|
||||
}) {
|
||||
const { username } = await params;
|
||||
|
||||
const [user, imagerBase] = await Promise.all([
|
||||
prisma.user.findUnique({
|
||||
where: { username },
|
||||
select: {
|
||||
username: true,
|
||||
motto: true,
|
||||
look: true,
|
||||
rank: true,
|
||||
credits: true,
|
||||
online: true,
|
||||
accountCreated: true,
|
||||
},
|
||||
}),
|
||||
siteSettings.get("habbo_imaging_url", "https://www.habbo.com/habbo-imaging/avatarimage"),
|
||||
]);
|
||||
|
||||
if (!user) notFound();
|
||||
|
||||
const avatar = avatarImageUrl(imagerBase ?? "", user.look, { size: "l" });
|
||||
const registered = new Date(user.accountCreated * 1000).toISOString().slice(0, 10);
|
||||
|
||||
return (
|
||||
<main>
|
||||
<div className="card" style={{ display: "flex", gap: "1.5rem", alignItems: "center" }}>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img src={avatar} alt={`${user.username} avatar`} width={100} height={150} />
|
||||
<div>
|
||||
<h1 style={{ margin: "0 0 0.25rem" }}>{user.username}</h1>
|
||||
<p style={{ margin: "0 0 0.5rem" }}>{user.motto || <span className="muted">No motto</span>}</p>
|
||||
<p className="muted" style={{ margin: 0 }}>
|
||||
Rank {user.rank} · {user.credits} credits · {user.online === "1" ? "Online" : "Offline"} ·
|
||||
Registered {registered}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user