Files
iiEasy/components/Sidebar.tsx

146 lines
5.5 KiB
TypeScript
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from 'react';
import { NAV_LINKS, ABOUT_CONTEXT_NAV_LINKS, BUSINESS_CONTEXT_NAV_LINKS, EDUCATION_CONTEXT_NAV_LINKS, ACCELERATOR_CONTEXT_NAV_LINKS, SECTION_IDS, APP_NAME, FOOTER_CONTENT } from '../constants';
import { NavLinkItem, CurrentView } from '../types';
import { ChevronRightIcon } from './icons';
import Logo from './Logo'; // Import the new Logo component
interface SidebarProps {
isOpen: boolean;
onClose: () => void;
currentView: CurrentView;
setCurrentView: (view: CurrentView) => void;
isDesktopCollapsed: boolean;
}
const Sidebar: React.FC<SidebarProps> = ({ isOpen, onClose, currentView, setCurrentView, isDesktopCollapsed }) => {
const scrollToSection = (hash: string) => {
if (hash.startsWith('#')) {
const sectionId = hash.substring(1);
const element = document.getElementById(sectionId);
if (element) {
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
} else {
console.warn(`Element with ID ${sectionId} not found for scrolling.`);
}
} else {
console.warn(`Invalid hash for scrolling: ${hash}`);
}
};
const handleNavLinkClick = (item: NavLinkItem) => {
if (item.targetView) {
setCurrentView(item.targetView);
setTimeout(() => scrollToSection(item.href), 50); // Increased delay
} else {
setCurrentView('main');
setTimeout(() => scrollToSection(item.href), 50); // Increased delay
}
if (window.innerWidth < 768) { // md breakpoint
onClose();
}
};
const isAboutContextView = ['about', 'mission', 'careers'].includes(currentView);
const isBusinessContextView = ['businessLanding', 'businessServices'].includes(currentView);
const isEducationContextView = ['educationBusiness', 'educationStudents'].includes(currentView);
const isAcceleratorContextView = ['acceleratorAbout', 'acceleratorProjects', 'acceleratorInvestment'].includes(currentView);
let linksToRender: NavLinkItem[];
if (isAboutContextView) {
linksToRender = ABOUT_CONTEXT_NAV_LINKS;
} else if (isBusinessContextView) {
linksToRender = BUSINESS_CONTEXT_NAV_LINKS;
} else if (isEducationContextView) {
linksToRender = EDUCATION_CONTEXT_NAV_LINKS;
} else if (isAcceleratorContextView) {
linksToRender = ACCELERATOR_CONTEXT_NAV_LINKS;
} else {
linksToRender = NAV_LINKS;
}
const getLinkClasses = (item: NavLinkItem) => {
let baseClasses = `relative flex items-center p-3 rounded-lg hover:bg-slate-100
transition-colors duration-150
focus:outline-none focus:ring-2 focus:ring-slate-400 focus:bg-slate-100`;
if (item.label === 'На Главную') {
baseClasses += ' text-slate-500 hover:text-slate-700';
} else {
baseClasses += ' text-slate-700 hover:text-slate-900';
}
const isActive = (isAboutContextView || isBusinessContextView || isEducationContextView || isAcceleratorContextView) && item.targetView === currentView;
if (isActive) {
baseClasses += ' bg-slate-200 text-slate-900 font-semibold';
}
return baseClasses;
};
const sidebarClasses = `h-screen w-72 flex flex-col p-6 transform transition-all duration-300 ease-in-out
fixed top-0 left-0 z-40
bg-white/95 backdrop-blur-sm
md:bg-white md:z-30
${isOpen ? 'translate-x-0' : '-translate-x-full'}
${isDesktopCollapsed ? 'md:-translate-x-full' : 'md:translate-x-0'}`;
return (
<aside
id="sidebar-drawer"
className={sidebarClasses}
aria-label="Sidebar"
>
<div className="flex items-center justify-start mb-8 pl-1">
<a
href={`#${SECTION_IDS.hero}`}
onClick={(e) => {
e.preventDefault();
setCurrentView('main');
setTimeout(() => scrollToSection(`#${SECTION_IDS.hero}`), 50);
if (window.innerWidth < 768) onClose();
}}
className="flex items-center gap-3"
>
<Logo width={32} height={32} />
<span className={`font-quicksand text-2xl font-bold text-slate-900 transition-opacity duration-200 ${isDesktopCollapsed ? 'opacity-0' : 'opacity-100'}`}>
{APP_NAME}
</span>
</a>
</div>
<nav className="flex-grow flex flex-col justify-center overflow-y-auto no-scrollbar">
<ul className="space-y-2 font-medium">
{linksToRender.map((item: NavLinkItem) => (
<li key={item.id} className="group relative">
<a
href={item.href}
onClick={(e) => {
e.preventDefault();
handleNavLinkClick(item);
}}
className={`${getLinkClasses(item)}`}
>
{item.icon && <item.icon className="w-5 h-5 shrink-0 text-slate-500 group-hover:text-slate-700 transition-colors duration-150 mr-4" />}
<span className="font-quicksand text-base whitespace-nowrap">{item.label}</span>
{item.children && (
<ChevronRightIcon className="w-4 h-4 ml-auto opacity-50 group-hover:opacity-100 transition-opacity" />
)}
</a>
</li>
))}
</ul>
</nav>
<div className="pt-4 mt-8 border-t border-slate-200">
<p className="text-xs text-center text-slate-500">
{FOOTER_CONTENT.copyrightText(new Date().getFullYear())}
</p>
</div>
</aside>
);
};
export default Sidebar;