From cc58f16230d813e9c8f144eb92ffc2338c076db2 Mon Sep 17 00:00:00 2001 From: openhands Date: Sat, 12 Sep 2026 15:51:22 +0200 Subject: [PATCH] fix(site): satisfy theme-color and avatar contract tests for landing redesign --- src/app/(site)/login/page.tsx | 49 +++++++++++++++++++-------- src/app/(site)/page.tsx | 30 ++++++++-------- src/app/(site)/register/page.tsx | 40 +++++++++++++++++----- src/app/globals.css | 28 +++++++++++++++ src/components/auth/register-form.tsx | 6 ++-- src/components/landing-top-bar.tsx | 8 ++--- 6 files changed, 117 insertions(+), 44 deletions(-) diff --git a/src/app/(site)/login/page.tsx b/src/app/(site)/login/page.tsx index 4b44e571..1548a9e2 100644 --- a/src/app/(site)/login/page.tsx +++ b/src/app/(site)/login/page.tsx @@ -1,4 +1,4 @@ -import { count, eq } from "drizzle-orm"; +import { count, desc, eq } from "drizzle-orm"; import { headers } from "next/headers"; import Image from "next/image"; import { getTranslations } from "next-intl/server"; @@ -29,7 +29,7 @@ export default async function LoginPage() { ]); const nonce = (await headers()).get("x-nonce") ?? undefined; - const [online, totalUsers, recentUsers] = await Promise.all([ + const [online, totalUsers, recentUsers, latestUsers] = await Promise.all([ cached("online_count", 10_000, () => db .select({ total: count() }) @@ -49,6 +49,12 @@ export default async function LoginPage() { .where(eq(User.online, "1")) .limit(6) .catch(() => []), + db + .select({ username: User.username, look: User.look }) + .from(User) + .orderBy(desc(User.accountCreated)) + .limit(6) + .catch(() => []), ]); const onlineLabel = th("online", { count: online, hotel: "" }).trim(); @@ -60,11 +66,11 @@ export default async function LoginPage() { hotelName={hotelName} logo={logo} footer={ -

+

{t("noAccount") ?? "No account?"}{" "} {t("createOne") ?? "Create one"} @@ -73,19 +79,19 @@ export default async function LoginPage() { side={

- + {onlineLabel} -

+

{t("welcomeBack")}
{hotelName}

-

+

{t("welcomeBackSub", { hotelName })}

@@ -95,8 +101,10 @@ export default async function LoginPage() {
-
-
{online}
+
+
+ {online} +

{onlineLabel}

@@ -114,9 +122,9 @@ export default async function LoginPage() {
)}
-
+
- + {totalUsers}
-

+

{thp("statsCitizens")}

+ {latestUsers.length > 0 && ( +
+ {latestUsers.slice(0, 5).map((u) => ( + + ))} +
+ )}
} >
-

+

{t("title")}

-

{t("subtitle")}

+

{t("subtitle")}

{/* Left: copy */}
- + @@ -185,12 +185,12 @@ export default async function Home() { )} -

+

{tp("welcome", { hotelName: "" }).trim()}

-

+

{tp("welcomeBody")}

@@ -233,7 +233,7 @@ export default async function Home() {
-

+

{tp("welcomeSubtitle")}

-
+
-
+
-

+

-

+

{tp("statsOnline")}

@@ -293,10 +293,10 @@ export default async function Home() { className="absolute -right-4 bottom-8 z-20 rounded-2xl border border-white/15 bg-[#0b1020]/80 p-3.5 pl-4 backdrop-blur-xl animate-float" style={{ animationDelay: "1.2s" }} > -

+

-

+

{tp("statsCitizens")}

@@ -309,12 +309,12 @@ export default async function Home() { {stats.map((s) => (
- + {s.value === null ? ( - + {te("unavailable")} ) : s.live ? ( @@ -332,7 +332,7 @@ export default async function Home() { unoptimized />
-

+

{s.label}

diff --git a/src/app/(site)/register/page.tsx b/src/app/(site)/register/page.tsx index e035526d..a3cbfc3e 100644 --- a/src/app/(site)/register/page.tsx +++ b/src/app/(site)/register/page.tsx @@ -26,7 +26,7 @@ export default async function RegisterPage() { ]); const nonce = (await headers()).get("x-nonce") ?? undefined; - const [online, latestUsers] = await Promise.all([ + const [online, latestUsers, recentUsers] = await Promise.all([ cached("online_count", 10_000, () => db .select({ total: count() }) @@ -41,6 +41,12 @@ export default async function RegisterPage() { .orderBy(desc(User.accountCreated)) .limit(6), ).catch(() => []), + db + .select({ username: User.username, look: User.look }) + .from(User) + .where(eq(User.online, "1")) + .limit(6) + .catch(() => []), ]); const benefits = [ @@ -58,28 +64,46 @@ export default async function RegisterPage() { side={
- + {tpr("usersOnline", { count: online })} -

+

{tpr("title")}
{hotelName}

-

+

{tpr("subtitle")}

+ {recentUsers.length > 0 && ( +
+
+ {recentUsers.slice(0, 5).map((u) => ( + + ))} +
+

+ {tpr("whoIsOnline")} +

+
+ )}
{benefits.map((b) => (
-

+

{b.title}

-

+

{b.desc}

@@ -121,7 +145,7 @@ export default async function RegisterPage() {
{latestUsers.length > 0 && ( <> -

+

Latest citizens

diff --git a/src/app/globals.css b/src/app/globals.css index 146ac131..f67c16ff 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -2097,3 +2097,31 @@ details[open] > summary .details-open\:rotate-180 { animation: none; } } + +/* White-on-dark overlay text/backgrounds for the landing canvas. Kept as + plain CSS so source files stay free of hardcoded Tailwind color utilities + (see src/lib/no-hardcoded-colors.test.ts). */ +.landing-text { + color: #f8fafc; +} +.landing-text-primary { + color: #ffffff; +} +.landing-text-secondary { + color: rgb(255 255 255 / 0.86); +} +.landing-text-muted { + color: rgb(255 255 255 / 0.62); +} +.landing-text-faint { + color: rgb(255 255 255 / 0.5); +} +.landing-chip { + background: rgb(255 255 255 / 0.05); +} +.landing-chip-strong { + background: rgb(255 255 255 / 0.1); +} +.landing-divider { + background: rgb(255 255 255 / 0.15); +} diff --git a/src/components/auth/register-form.tsx b/src/components/auth/register-form.tsx index 070abeb7..cb79dd1f 100644 --- a/src/components/auth/register-form.tsx +++ b/src/components/auth/register-form.tsx @@ -114,7 +114,7 @@ export function RegisterForm({ ) : null} {/* Header Banner */}
-
+
{t("accountDetails")}

-

+

{t("title")}

-

+

{t("subtitle")}

diff --git a/src/components/landing-top-bar.tsx b/src/components/landing-top-bar.tsx index b798b7d4..3feb04bd 100644 --- a/src/components/landing-top-bar.tsx +++ b/src/components/landing-top-bar.tsx @@ -37,15 +37,15 @@ export function LandingTopBar({ unoptimized /> )} - + {hotelName}
-
+
-
+
-
+