video-flow-b/components/layout/dashboard-layout.tsx
2025-09-25 11:29:53 +08:00

78 lines
2.1 KiB
TypeScript

"use client";
import { useState, useEffect } from 'react';
import { Sidebar } from './sidebar';
import { TopBar } from './top-bar';
import { useDeviceType } from '@/hooks/useDeviceType';
interface DashboardLayoutProps {
children: React.ReactNode;
}
export function DashboardLayout({ children }: DashboardLayoutProps) {
const [sidebarCollapsed, setSidebarCollapsed] = useState(true);
const { deviceType, isMobile, isTablet, isDesktop } = useDeviceType();
// 处理移动端视口高度动态计算
useEffect(() => {
if (isMobile || isTablet) {
const setVH = () => {
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
};
setVH();
window.addEventListener('resize', setVH);
window.addEventListener('orientationchange', setVH);
return () => {
window.removeEventListener('resize', setVH);
window.removeEventListener('orientationchange', setVH);
};
}
}, [isMobile, isTablet]);
// 根据设备类型设置布局样式
const getLayoutStyles = () => {
if (isMobile || isTablet) {
return {
left: '0',
width: '100vw'
};
}
// 桌面端
return {
left: sidebarCollapsed ? '4rem' : '16rem',
width: sidebarCollapsed ? 'calc(100vw - 4rem)' : 'calc(100vw - 16rem)'
};
};
// 获取移动端容器类名
const getMobileContainerClasses = () => {
if (isMobile || isTablet) {
return "mobile-viewport-height mobile-safe-bottom";
}
return "";
};
return (
<div className="min-h-screen bg-background">
<TopBar collapsed={sidebarCollapsed} isDesktop={isDesktop} />
{isDesktop && <Sidebar collapsed={sidebarCollapsed} onToggle={setSidebarCollapsed} />}
<div
className={`top-[4rem] fixed right-0 bottom-0 px-4 ${getMobileContainerClasses()}`}
style={{
...getLayoutStyles(),
// 移动端使用动态高度计算
height: (isMobile || isTablet)
? 'calc(100dvh - 4rem)'
: 'calc(100vh - 4rem)'
}}
>
{children}
</div>
</div>
);
}