From b40293bd0621cf99422a8e8c4f325e8571b935d1 Mon Sep 17 00:00:00 2001 From: openhands Date: Sun, 18 Oct 2026 19:38:32 +0200 Subject: [PATCH] feat(home): clean shared top bar with live online counter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The homepage duplicated the online count and recent-user avatars (hero plus community sidebar), and the public pages each kept their own chrome. Put one AuthTopBar at the top of index, login and register — logo + hotel name plus a live online indicator and the language/clock/theme controls — and drop the duplicated hero rows. --- src/app/(site)/page.tsx | 76 +------------------ src/components/auth/auth-landing.tsx | 1 + src/components/auth/auth-page-frame.tsx | 5 +- src/components/auth/auth-top-bar.tsx | 44 +++++++++-- .../shared/public-avatar-contract.test.ts | 2 +- 5 files changed, 45 insertions(+), 83 deletions(-) diff --git a/src/app/(site)/page.tsx b/src/app/(site)/page.tsx index 95e37da9..277ff43b 100644 --- a/src/app/(site)/page.tsx +++ b/src/app/(site)/page.tsx @@ -10,7 +10,6 @@ import { AnimatedCounter } from "@/components/animated-counter"; import { AuthTopBar } from "@/components/auth/auth-top-bar"; import { LoginForm } from "@/components/auth/login-form"; import Link from "@/components/link"; -import { LiveOnlineCounter } from "@/components/live-online-counter"; import { Reveal } from "@/components/motion-reveal"; import { PublicLoadError } from "@/components/public/load-error"; import { UserAvatarThumbnail } from "@/components/shared/user-avatar-thumbnail"; @@ -402,9 +401,9 @@ async function Home() { return (
- {/* ── Top bar ── */} + {/* ── Top bar: logo + live online + language/clock/theme ── */}
- +
{/* ── Cinematic hero ── */} @@ -454,46 +453,6 @@ async function Home() { style={{ opacity: 0.5, zIndex: 1 }} />
- - - - - - - {tp("onlineNow")} - - {online === null ? ( - {te("unavailable")} - ) : ( - - - - )} - -

- {recentUsers !== null && recentUsers.length > 0 && ( -
-
- {recentUsers.slice(0, 4).map((u) => ( - - ))} -
- - {tp("recentUsers")} - -
- )} -
- +
diff --git a/src/components/auth/auth-top-bar.tsx b/src/components/auth/auth-top-bar.tsx index 5ef15c12..511d721e 100644 --- a/src/components/auth/auth-top-bar.tsx +++ b/src/components/auth/auth-top-bar.tsx @@ -1,29 +1,33 @@ import Image from "next/image"; import { Clock } from "@/components/clock"; import { LanguageSwitcher } from "@/components/language-switcher"; +import { LiveOnlineCounter } from "@/components/live-online-counter"; import { Reveal } from "@/components/motion-reveal"; import { ThemeSwitcher } from "@/components/theme-switcher"; import { ICON_LIGHTHOUSE } from "@/lib/site-icons"; /** - * Shared frosted-glass top bar for the public auth pages (login, register, - * etc.). Shows the hotel logo + name on the left and language / clock / theme - * controls on the right. Defaults mirror the homepage top bar so auth pages - * share one consistent look. + * Shared frosted-glass top bar for the public pages (index, login, register). + * Shows the hotel logo + name on the left and the live online count, language / + * clock / theme controls on the right. One component so every public page keeps + * the exact same chrome instead of duplicating it. */ export function AuthTopBar({ hotelName, logo, + online, showHotelName = true, }: { hotelName: string; logo?: string | null; + /** Live online count; omit (or pass null) to hide the indicator. */ + online?: number | null; showHotelName?: boolean; }) { return (
-
+
{logo ? ( {hotelName} @@ -83,6 +87,32 @@ export function AuthTopBar({ "color-mix(in srgb, var(--color-text-muted) 5%, transparent)", }} > + {typeof online === "number" && ( + + + + + + + + + + )}
([ ["src/app/(site)/leaderboard/page.tsx", 1], ["src/app/(site)/me/page.tsx", 1], ["src/app/(site)/messages/page.tsx", 2], - ["src/app/(site)/page.tsx", 2], + ["src/app/(site)/page.tsx", 1], ["src/app/(site)/radio/leaderboard/page.tsx", 1], ["src/app/(site)/radio/shouts/page.tsx", 1], ["src/app/(site)/rankings/page.tsx", 1],