fix(layout): refactor desktop shell rails

This commit is contained in:
lizerk 2026-04-15 00:20:32 +03:00
parent 14d21fb297
commit f300bdc02d
3 changed files with 38 additions and 19 deletions

View File

@ -10,6 +10,7 @@ import { useNotifications } from "@/hooks/useApi";
import { getVerbCategory } from "@/lib/verbTranslations";
import { NotificationCenter, NotificationPanel } from "@/components/NotificationCenter";
import { CalendarSidebar } from "@/components/calendar/CalendarSidebar";
import { DesktopStickyRail } from "@/components/layout/DesktopStickyRail";
import { useCalendarModals } from "@/hooks/useCalendarModals";
import { CalendarModals } from "@/components/layout/CalendarModals";
import { MobileLeftDrawer, MobileCalendarDrawer } from "@/components/layout/MobileDrawers";
@ -339,17 +340,13 @@ function LeftNavContent({ onNavigate }: LeftNavContentProps) {
);
}
function LeftNav({ fixedDesktop = false }: { fixedDesktop?: boolean }) {
function LeftNav({ pinnedDesktop = true }: { pinnedDesktop?: boolean }) {
return (
<aside className="hidden w-64 flex-shrink-0 lg:block">
<div
className={`space-y-4 lg:max-h-[calc(100vh-7.5rem)] lg:overflow-y-auto lg:pb-2 ${
fixedDesktop ? "lg:fixed lg:top-[5.5rem] lg:w-64" : "lg:sticky lg:top-8"
}`}
>
<DesktopStickyRail widthClass="w-64" pinned={pinnedDesktop}>
<div className="space-y-4">
<LeftNavContent />
</div>
</aside>
</DesktopStickyRail>
);
}
@ -459,7 +456,7 @@ export function AppShell({ children }: AppShellProps) {
onOpenCalendar={() => setIsMobileCalendarOpen(true)}
/>
<div className={`mx-auto flex w-full flex-1 min-h-0 max-w-6xl ${isMessageDialogPage ? 'gap-0 px-0 py-0 lg:gap-6 lg:px-8 lg:py-8' : 'gap-6 px-4 py-4 sm:px-8 lg:py-8'}`}>
<LeftNav fixedDesktop={!isMessageDialogPage} />
<LeftNav pinnedDesktop={!isMessageDialogPage} />
<main className={`flex-1 min-w-0 min-h-0 space-y-6 ${isMessageDialogPage ? 'overflow-visible' : ''}`}>{children}</main>
<CalendarSidebar
onOpenCalendarModal={cal.handleOpenCalendarModal}
@ -469,7 +466,7 @@ export function AppShell({ children }: AppShellProps) {
setEventsRefreshTrigger={cal.handleSetEventsRefreshTrigger}
setSidebarEvents={cal.handleSetSidebarEvents}
onCalendarChange={cal.handleCalendarChange}
fixedDesktop={!isMessageDialogPage}
pinnedDesktop={!isMessageDialogPage}
/>
</div>

View File

@ -2,6 +2,7 @@
import { memo } from "react";
import { CalendarCard } from "@/components/calendar/CalendarCard";
import { DesktopStickyRail } from "@/components/layout/DesktopStickyRail";
import type { CalendarEvent } from "@/services/calendarService";
interface CalendarSidebarProps {
@ -15,23 +16,19 @@ interface CalendarSidebarProps {
setEventsRefreshTrigger: (value: number | ((prev: number) => number)) => void;
setSidebarEvents: (events: CalendarEvent[]) => void;
onCalendarChange: (calendarId: number | null) => void;
fixedDesktop?: boolean;
pinnedDesktop?: boolean;
}
/**
* Обертка для календаря в правом сайдбаре (десктоп)
*/
export const CalendarSidebar = memo(function CalendarSidebar(props: CalendarSidebarProps) {
const { fixedDesktop = false, ...calendarProps } = props;
const { pinnedDesktop = true, ...calendarProps } = props;
return (
<aside className="hidden w-72 flex-shrink-0 space-y-4 lg:block">
<div
className={`space-y-4 lg:max-h-[calc(100vh-7.5rem)] lg:overflow-y-auto lg:pb-2 ${
fixedDesktop ? "lg:fixed lg:top-[5.5rem] lg:w-72" : "lg:sticky lg:top-8"
}`}
>
<DesktopStickyRail widthClass="w-72" pinned={pinnedDesktop}>
<div className="space-y-4">
<CalendarCard {...calendarProps} />
</div>
</aside>
</DesktopStickyRail>
);
});

View File

@ -0,0 +1,25 @@
"use client";
import type { ReactNode } from "react";
type DesktopStickyRailProps = {
widthClass: string;
pinned?: boolean;
children: ReactNode;
};
export function DesktopStickyRail({ widthClass, pinned = true, children }: DesktopStickyRailProps) {
return (
<aside className={`hidden flex-shrink-0 lg:block ${widthClass}`}>
<div
className={`space-y-4 ${
pinned
? "lg:sticky lg:top-[5.5rem] lg:max-h-[calc(100dvh-5.5rem)] lg:overflow-y-auto lg:pb-2"
: "lg:h-full lg:min-h-0 lg:overflow-y-auto"
}`}
>
{children}
</div>
</aside>
);
}