diff --git a/src/app/(site)/page.tsx b/src/app/(site)/page.tsx index afc4aadb..1a85ebb1 100644 --- a/src/app/(site)/page.tsx +++ b/src/app/(site)/page.tsx @@ -1,6 +1,7 @@ import Image from "next/image"; import Link from "next/link"; import { redirect } from "next/navigation"; +import { headers } from "next/headers"; import { getTranslations } from "next-intl/server"; import { cached } from "@/lib/cache"; import { avatarImageUrl } from "@/lib/format"; @@ -8,9 +9,12 @@ import { formatDate } from "@/lib/format-date"; import { prisma } from "@/lib/prisma"; import { resolveHotelName } from "@/lib/hotel-name"; import { siteSettings } from "@/lib/services/site-settings"; +import { captchaConfig } from "@/lib/services/captcha"; import { auth } from "@/lib/auth"; import { ThemeSwitcher } from "@/components/theme-switcher"; import { LanguageSwitcher } from "@/components/language-switcher"; +import { HomeLoginForm } from "@/components/auth/home-login-form"; +import { Reveal } from "@/components/motion-reveal"; export const revalidate = 120; @@ -53,17 +57,7 @@ async function getHotelData() { .catch(() => []), ]); - return { - hotelName, - imager, - online, - users, - rooms, - articles, - recentUsers, - recentPhotos, - latestUsers, - }; + return { hotelName, imager, online, users, rooms, articles, recentUsers, recentPhotos, latestUsers }; } export default async function Home() { @@ -72,381 +66,434 @@ export default async function Home() { const tp = await getTranslations("pages.home"); const th = await getTranslations("header"); - const { - hotelName, - imager, - online, - users, - rooms, - articles, - recentUsers, - recentPhotos, - latestUsers, - } = await getHotelData(); + const { hotelName, imager, online, users, rooms, articles, recentUsers, recentPhotos, latestUsers } = await getHotelData(); + + const captcha = await captchaConfig(); + const nonce = (await headers()).get("x-nonce") ?? undefined; return ( -
- - {/* ── Toolbar ── */} -
+
+ + {/* ── Hero ── */} +
-
- - {hotelName} - -
- -
- +
+
+
+
+ + + + + {th("online", { count: online, hotel: hotelName })} +
+

+ {tp("welcome", { hotelName })} +

+

+ {th("tagline")} +

+
+ + + {tp("register")} + + + {th("login")} + +
+
+
+
+ Frank +
-
- {/* ── 1. Hero ── */} -
-
-
-
-
+ + + {/* ── Stats ── */} + +
+ {[ + { value: online.toLocaleString(), label: tp("statsOnline"), icon: "/assets/images/icons/navigation/home.png" }, + { value: users.toLocaleString(), label: tp("statsCitizens"), icon: "/assets/images/icons/navigation/me.png" }, + { value: rooms.toLocaleString(), label: tp("statsRooms"), icon: "/assets/images/icons/catalog.png" }, + ].map((s) => (
- - - - - {th("online", { count: online, hotel: hotelName })} -
-

- {tp("welcome", { hotelName })} -

-

- {th("tagline")} -

-
- - - {tp("register")} - - - {th("login")} - -
-
-
-
- Frank -
-
-
- - {/* ── 2. Stats ── */} -
- {[ - { value: online.toLocaleString(), label: tp("statsOnline"), icon: "/assets/images/icons/navigation/home.png" }, - { value: users.toLocaleString(), label: tp("statsCitizens"), icon: "/assets/images/icons/navigation/me.png" }, - { value: rooms.toLocaleString(), label: tp("statsRooms"), icon: "/assets/images/icons/catalog.png" }, - ].map((s) => ( -
-
-
- -
- {s.value} -
-
- {s.label} -
-
-
- ))} -
- - {/* ── 3. Features ── */} -
- {[ - { img: "/assets/images/icons/star.gif", title: tp("featuresAvatar"), desc: tp("featuresAvatarDesc") }, - { img: "/assets/images/icons/catalog.png", title: tp("featuresFurniture"), desc: tp("featuresFurnitureDesc") }, - { img: "/assets/images/icons/navigation/community.png", title: tp("featuresCommunity"), desc: tp("featuresCommunityDesc") }, - { img: "/assets/images/icons/navigation/bb.png", title: tp("featuresGames"), desc: tp("featuresGamesDesc") }, - ].map((f) => ( -
-
- -
-

- {f.title} -

-

- {f.desc} -

-
- ))} -
- - {/* ── 4. Newest citizens ── */} - {latestUsers.length > 0 && ( -
-

- {tp("latestUsers", { count: users.toLocaleString() })} -

-
- {latestUsers.map((u) => (
-
-
- {u.username} + className="absolute -top-6 -right-6 w-20 h-20 rounded-full opacity-[0.06]" + style={{ background: "var(--color-primary)" }} + /> +
+
+ +
+
+ {s.value} +
+
+ {s.label}
- - {u.username} -
- ))} -
+
+ ))}
- )} + - {/* ── 5. News ── */} -
-
-

- {tp("latestNews")} -

- - {tp("allNews")} + {/* ── Login + News ── */} +
+ + {/* Left: Login & Register */} + +
+
+ +

+ Login +

+
+
+ +
+
+ + +
+ Register +
+ + {tp("register")} + -
- {articles.length > 0 ? ( -
- {articles.slice(0, 4).map((a) => ( - 0 && ( +
+
-
- {a.image ? ( - - ) : ( -
- )} -
-
-

- {a.title} -

-

- {formatDate(a.createdAt, "date", "")} -

-
+ +

+ {tp("latestUsers", { count: users.toLocaleString() })} +

+
+
+ {latestUsers.map((u) => ( +
+
+ {u.username} +
+ + {u.username} + +
+ ))} +
+
+ )} + + + {/* Right: News */} + +
+
+
+ +

+ {tp("latestNews")} +

+
+ + {tp("allNews")} - ))} +
+
+ {articles.length > 0 ? ( +
+ {articles.slice(0, 4).map((a) => ( + +
+ {a.title} +
+

+ {a.title} +

+

+ {formatDate(a.createdAt, "date", "")} +

+
+
+ + ))} +
+ ) : ( +

+ {tp("noArticles")} +

+ )} +
- ) : ( -

{tp("noArticles")}

- )} +
- {/* ── 6. Online users row ── */} - {recentUsers.length > 0 && ( -
-

- - {tp("recentUsers")} -

-
- {recentUsers.slice(0, 10).map((u) => ( + {/* ── Features ── */} + +
+
+ +

+ {hotelName} Features +

+
+
+ {[ + { img: "/assets/images/icons/star.gif", title: tp("featuresAvatar"), desc: tp("featuresAvatarDesc") }, + { img: "/assets/images/icons/catalog.png", title: tp("featuresFurniture"), desc: tp("featuresFurnitureDesc") }, + { img: "/assets/images/icons/navigation/community.png", title: tp("featuresCommunity"), desc: tp("featuresCommunityDesc") }, + { img: "/assets/images/icons/navigation/bb.png", title: tp("featuresGames"), desc: tp("featuresGamesDesc") }, + ].map((f) => (
- {u.username} - - {u.username} - +
+ +
+

+ {f.title} +

+

+ {f.desc} +

))}
+
+ + {/* ── Online users ── */} + {recentUsers.length > 0 && ( + +
+
+ +

+ {tp("recentUsers")} +

+
+
+
+ {recentUsers.slice(0, 12).map((u) => ( +
+ {u.username} + + {u.username} + +
+ ))} +
+
+
+
)} - {/* ── 7. Bottom CTA ── */} -
-

- {tp("joinNow", { hotelName })} -

-

- {tp("welcomeBody")} -

- +
- - {tp("register")} - -
- - {/* ── 8. Recent photos (compact) ── */} - {recentPhotos.length > 0 && ( -
-

- {tp("recentPhotos")} -

-
- {recentPhotos.slice(0, 4).map((p) => ( - - - - ))} -
+

+ {tp("joinNow", { hotelName })} +

+

+ {tp("welcomeBody")} +

+ + + {tp("register")} +
+ + + {/* ── Recent photos ── */} + {recentPhotos.length > 0 && ( + +
+
+ +

+ {tp("recentPhotos")} +

+
+
+
+ {recentPhotos.slice(0, 4).map((p) => ( + + + + ))} +
+
+
+
)}
);