Add atom-theme visual design (header/footer, theme system, restyled pages)

Faithful port of AtomCMS's "atom" theme look (light, Habbo-retro, golden
#eeb425 / amber #f59e0b accents, white cards, 12px radii, Nunito-first stack):
- globals.css: full token set + components (.site-header/.nav-item, .btn-*,
  .card, .hero, currency pills, article cards, inputs, tables, footer).
- SiteHeader (brand + nav + currency pills + auth box, staff-aware) + SiteFooter;
  layout wraps header/content/footer. Removed the bare SiteNav.
- Restyled home (hero + article cards), login (centered card).
- siteSettings now falls back to DEFAULTS on missing key OR DB error, so pages
  render without a DB; DATABASE_CONNECT_TIMEOUT_MS env + pool acquireTimeout make
  the no-DB fallback fast.

Verified in a real browser (computed styles): header white/sticky, golden logo
gradient, uppercase nav, amber primary button @12px radius, golden outline,
hero gradient — all correct. tsc exit 0, vitest 48/48, next build exit 0.
This commit is contained in:
Simo committed 2026-06-28 13:13:00 +02:00
1 parent 5f8b465451
commit 9a79acebe7
10 files changed
+490 -109

No files matched your search

+27 -10
View File
@@ -6,18 +6,35 @@ import { siteSettings } from "@/lib/services/site-settings";
export const dynamic = "force-dynamic";
export default async function HomePage() {
const [hotelName, articles] = await Promise.all([
siteSettings.get("hotel_name", "Atom"),
prisma.websiteArticles.findMany({
const hotelName = (await siteSettings.get("hotel_name", "Atom")) ?? "Atom";
let articles: Array<{ slug: string; title: string; shortStory: string; image: string }> = [];
try {
articles = await prisma.websiteArticles.findMany({
orderBy: { createdAt: "desc" },
take: 4,
}),
]);
select: { slug: true, title: true, shortStory: true, image: true },
});
} catch {
// DB unavailable — show the shell without articles.
}
return (
<main>
<h1>Welcome to {hotelName ?? "Atom"}</h1>
<p className="muted">AtomCMS → Next.js. Reading live data through the converted Prisma schema.</p>
<section className="hero">
<h1 style={{ fontSize: 36, marginTop: 0 }}>Welcome to {hotelName}</h1>
<p className="muted" style={{ fontSize: 16 }}>
Your retro hotel, now powered by Next.js. Hang out, collect furni, and meet friends.
</p>
<div style={{ display: "flex", gap: "0.6rem", marginTop: "0.5rem" }}>
<Link className="btn btn-primary" href="/client">
Enter hotel
</Link>
<Link className="btn btn-outline" href="/news">
Latest news
</Link>
</div>
</section>
<h2>Latest news</h2>
{articles.length === 0 ? (
@@ -25,9 +42,9 @@ export default async function HomePage() {
) : (
<div className="grid cols-2">
{articles.map((a) => (
<article key={a.slug} className="card" style={{ padding: 0, overflow: "hidden" }}>
{a.image ? <img className="article-img" src={a.image} alt="" /> : null}
<div style={{ padding: "0.9rem 1.1rem" }}>
<article key={a.slug} className="card hover article">
{a.image ? <img className="article-img" src={a.image} alt="" /> : <div className="article-img" />}
<div className="body">
<h3 style={{ margin: "0 0 0.3rem" }}>
<Link href={`/news/${a.slug}`}>{a.title}</Link>
</h3>