Initial commit for iiEasy: all files included

This commit is contained in:
2026-02-03 23:16:16 +05:00
commit 3b3d29e21c
158 changed files with 32962 additions and 0 deletions

146
components/Sidebar.tsx Executable file
View File

@@ -0,0 +1,146 @@
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;