video-flow-b/components/layout/dashboard-layout.tsx
2025-09-28 18:08:32 +08:00

84 lines
2.3 KiB
TypeScript

"use client";
import { useState, useEffect } from 'react';
import { Sidebar } from './sidebar';
import { TopBar } from './top-bar';
import { useDeviceType } from '@/hooks/useDeviceType';
import H5TopBar from '@/components/layout/H5TopBar';
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">
{isMobile || isTablet ? (
<H5TopBar />
) : (
<TopBar collapsed={sidebarCollapsed} isDesktop={isDesktop} />
)}
{isDesktop && <Sidebar collapsed={sidebarCollapsed} onToggle={setSidebarCollapsed} />}
<div
className={`fixed right-0 bottom-0 px-4 ${getMobileContainerClasses()}`}
style={{
...getLayoutStyles(),
top: (isMobile || isTablet) ? '3.5rem' : '4rem',
// 移动端使用动态高度计算
height: (isMobile || isTablet)
? 'calc(100dvh - 3.5rem)'
: 'calc(100vh - 4rem)'
}}
>
{children}
</div>
</div>
);
}