forked from 77media/video-flow
84 lines
2.3 KiB
TypeScript
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>
|
|
);
|
|
}
|