Add routing
This commit is contained in:
28
src/App.tsx
28
src/App.tsx
@@ -1,27 +1,21 @@
|
||||
import { useState } from 'react';
|
||||
import Sidebar, { type AppId } from './components/Sidebar';
|
||||
import { Routes, Route, Navigate } from 'react-router-dom';
|
||||
import Sidebar from './components/Sidebar';
|
||||
import ImageApprox from './apps/ImageApprox/ImageApprox';
|
||||
import SnakeAI from './apps/SnakeAI/SnakeAI';
|
||||
import './App.css';
|
||||
|
||||
function App() {
|
||||
const [currentApp, setCurrentApp] = useState<AppId>('image-approx');
|
||||
|
||||
const renderApp = () => {
|
||||
switch (currentApp) {
|
||||
case 'image-approx':
|
||||
return <ImageApprox />;
|
||||
case 'snake-ai':
|
||||
return <SnakeAI />;
|
||||
default:
|
||||
return <div>App not found</div>;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="app-layout">
|
||||
<Sidebar currentApp={currentApp} onAppChange={setCurrentApp} />
|
||||
<main className="app-main">{renderApp()}</main>
|
||||
<Sidebar />
|
||||
<main className="app-main">
|
||||
<Routes>
|
||||
<Route path="/" element={<Navigate to="/image-approx" replace />} />
|
||||
<Route path="/image-approx" element={<ImageApprox />} />
|
||||
<Route path="/snake-ai" element={<SnakeAI />} />
|
||||
<Route path="*" element={<div>App not found</div>} />
|
||||
</Routes>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import './Sidebar.css';
|
||||
|
||||
export type AppId = 'image-approx' | 'snake-ai';
|
||||
|
||||
export interface AppInfo {
|
||||
id: AppId;
|
||||
path: string;
|
||||
name: string;
|
||||
icon: string;
|
||||
description: string;
|
||||
@@ -12,24 +14,21 @@ export interface AppInfo {
|
||||
export const APPS: AppInfo[] = [
|
||||
{
|
||||
id: 'image-approx',
|
||||
path: '/image-approx',
|
||||
name: 'Image Approximation',
|
||||
icon: '🎨',
|
||||
description: 'Evolve triangles to approximate images',
|
||||
},
|
||||
{
|
||||
id: 'snake-ai',
|
||||
path: '/snake-ai',
|
||||
name: 'Neural Network Snake',
|
||||
icon: '🐍',
|
||||
description: 'Evolve neural networks to play Snake',
|
||||
},
|
||||
];
|
||||
|
||||
interface SidebarProps {
|
||||
currentApp: AppId;
|
||||
onAppChange: (appId: AppId) => void;
|
||||
}
|
||||
|
||||
export default function Sidebar({ currentApp, onAppChange }: SidebarProps) {
|
||||
export default function Sidebar() {
|
||||
return (
|
||||
<aside className="sidebar">
|
||||
<div className="sidebar-header">
|
||||
@@ -39,15 +38,15 @@ export default function Sidebar({ currentApp, onAppChange }: SidebarProps) {
|
||||
|
||||
<nav className="sidebar-nav">
|
||||
{APPS.map((app) => (
|
||||
<button
|
||||
<NavLink
|
||||
key={app.id}
|
||||
className={`nav-item ${currentApp === app.id ? 'active' : ''}`}
|
||||
onClick={() => onAppChange(app.id)}
|
||||
to={app.path}
|
||||
className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`}
|
||||
title={app.description}
|
||||
>
|
||||
<span className="nav-icon">{app.icon}</span>
|
||||
<span className="nav-name">{app.name}</span>
|
||||
</button>
|
||||
</NavLink>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
import './index.css'
|
||||
import App from './App.tsx'
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</StrictMode>,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user