From e0a28af46e4591c37e6600b1dc8e4c6e015a882b Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Wed, 17 Dec 2025 13:46:12 +0100 Subject: [PATCH] feat(bookings): conditionally show heading/subtitle based on view (#25889) * feat(bookings): conditionally show heading/subtitle based on view - Add heading and subtitle props back to ShellMainAppDir in page.tsx - Use headerClassName marker to identify the heading element - Add useLayoutEffect in BookingCalendarContainer to hide heading when calendar view is mounted - Restore heading visibility when switching back to list view Co-Authored-By: eunjae@cal.com * refactor(bookings): extract shell heading visibility into reusable hook - Create useBookingsShellHeadingVisibility hook with explicit visible parameter - Move visibility logic from BookingCalendarContainer to BookingsContent - Use data attribute to track if we hid the header (idempotent/Strict-Mode-safe) - Explicit show/hide based on view state instead of relying on unmount Co-Authored-By: eunjae@cal.com * refactor(bookings): simplify shell heading visibility hook Remove HIDDEN_DATA_ATTR tracking since the header wrapper won't have a hidden class from any other source Co-Authored-By: eunjae@cal.com --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../(main-nav)/bookings/[status]/page.tsx | 8 ++++-- .../useBookingsShellHeadingVisibility.ts | 25 +++++++++++++++++++ .../modules/bookings/views/bookings-view.tsx | 3 +++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 apps/web/modules/bookings/hooks/useBookingsShellHeadingVisibility.ts diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/bookings/[status]/page.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/bookings/[status]/page.tsx index fe7fedbf51..2176941549 100644 --- a/apps/web/app/(use-page-wrapper)/(main-nav)/bookings/[status]/page.tsx +++ b/apps/web/app/(use-page-wrapper)/(main-nav)/bookings/[status]/page.tsx @@ -1,6 +1,6 @@ import { ShellMainAppDir } from "app/(use-page-wrapper)/(main-nav)/ShellMainAppDir"; import type { PageProps } from "app/_types"; -import { _generateMetadata } from "app/_utils"; +import { _generateMetadata, getTranslate } from "app/_utils"; import { cookies, headers } from "next/headers"; import { redirect } from "next/navigation"; import { z } from "zod"; @@ -34,6 +34,7 @@ const Page = async ({ params }: PageProps) => { if (!parsed.success) { redirect("/bookings/upcoming"); } + const t = await getTranslate(); const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) }); let canReadOthersBookings = false; @@ -59,7 +60,10 @@ const Page = async ({ params }: PageProps) => { : false; return ( - + { + const marker = document.querySelector(`.${MARKER_CLASS}`); + if (!marker) return; + + const headerWrapper = marker.closest("header")?.parentElement; + if (!headerWrapper) return; + + if (visible) { + headerWrapper.classList.remove("hidden"); + } else { + headerWrapper.classList.add("hidden"); + } + + return () => { + headerWrapper.classList.remove("hidden"); + }; + }, [visible]); +} diff --git a/apps/web/modules/bookings/views/bookings-view.tsx b/apps/web/modules/bookings/views/bookings-view.tsx index a6b434cbd3..0eafa81e7c 100644 --- a/apps/web/modules/bookings/views/bookings-view.tsx +++ b/apps/web/modules/bookings/views/bookings-view.tsx @@ -10,6 +10,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale"; import classNames from "@calcom/ui/classNames"; import { BookingListContainer } from "../components/BookingListContainer"; +import { useBookingsShellHeadingVisibility } from "../hooks/useBookingsShellHeadingVisibility"; import { useBookingsView } from "../hooks/useBookingsView"; import type { validStatuses } from "../lib/validStatuses"; @@ -70,6 +71,8 @@ export default function Bookings(props: BookingsProps) { function BookingsContent({ status, permissions, bookingsV3Enabled }: BookingsProps) { const [view] = useBookingsView({ bookingsV3Enabled }); + useBookingsShellHeadingVisibility({ visible: view === "list" }); + return (
{view === "list" && (