import React from 'react';
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
import LeftNav from './LeftNav';
import MobileNav from './MobileNav';
import RightSidebar from './RightSidebar';
import { useSidebar, SIDEBAR_WIDTH_EXPANDED, SIDEBAR_WIDTH_COLLAPSED } from '../../contexts/SidebarContext';
import { Star, Calendar, TrendingUp, User, Sparkles, ChevronLeft, ChevronRight } from 'lucide-react';
import { LifeDestinyResult, UserInput } from '../../types';
interface AppShellProps {
isLoggedIn: boolean;
userInfo: { email: string; points: number } | null;
onLoginClick: () => void;
onLogout: () => void;
onHistorySelect?: (result: LifeDestinyResult, input: UserInput) => void;
onNewCalculation?: () => void;
isAnalysisPanelOpen?: boolean;
}
// Mini sidebar component for collapsed state
const SidebarMini: React.FC<{
onGenerate: () => void;
isLoggedIn: boolean;
}> = ({ onGenerate, isLoggedIn }) => {
const navigate = useNavigate();
const miniItems = [
{ icon: Star, label: '今日', color: 'text-amber-500', onClick: () => navigate('/fortune/daily') },
{ icon: Calendar, label: '本月', color: 'text-blue-500', onClick: () => navigate('/fortune/monthly') },
{ icon: TrendingUp, label: '今年', color: 'text-purple-500', onClick: () => navigate('/fortune/yearly') },
{ icon: Sparkles, label: '测算', color: 'text-primrose', onClick: onGenerate },
];
return (
{miniItems.map((item, index) => (
{item.label}
))}
navigate(isLoggedIn ? '/dashboard' : '/')}
className="w-12 h-12 flex flex-col items-center justify-center rounded-xl hover:bg-white/80 transition-colors group"
title={isLoggedIn ? '个人中心' : '登录'}
>
{isLoggedIn ? '我的' : '登录'}
);
};
const AppShell: React.FC = ({
isLoggedIn,
userInfo,
onLoginClick,
onLogout,
onHistorySelect,
onNewCalculation,
isAnalysisPanelOpen = false,
}) => {
const navigate = useNavigate();
const location = useLocation();
const { isExpanded, isHovered, isCollapsible, setIsHovered, sidebarWidth, toggleExpanded } = useSidebar();
// Check if on homepage
const isHomepage = location.pathname === '/' || location.pathname === '/home';
const handleGenerate = () => {
navigate('/');
window.scrollTo({ top: 0, behavior: 'smooth' });
};
// Determine if sidebar should show full content
const showFullSidebar = isExpanded || isHovered || !isCollapsible;
return (
{/* Desktop: Three-column layout */}
{/* Left Nav - Fixed/Sticky */}
{/* Main Column - Scrollable, width adjusts based on sidebar */}
{/* Right Sidebar - Fixed/Sticky with collapsible support */}
isCollapsible && setIsHovered(true)}
onMouseLeave={() => isCollapsible && setIsHovered(false)}
>
{/* Collapse/Expand Toggle Button */}
{isCollapsible && (
{isExpanded || isHovered ? (
) : (
)}
)}
{/* Full Sidebar Content */}
{/* Mini Sidebar (collapsed state) */}
{isCollapsible && !showFullSidebar && (
)}
{/* Mobile: Single column with bottom nav */}
);
};
export default AppShell;