feat: initial frontend - React + TypeScript + Vite
- Login page with JWT auth - Dashboard with stats and charts - Issues list with pagination, filtering - Issue detail with comments, status transitions - Create issue form - Dark theme UI - Docker (nginx) with API proxy to backend - Sidebar navigation
This commit is contained in:
37
src/components/Sidebar.tsx
Normal file
37
src/components/Sidebar.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Link, useLocation } from 'react-router-dom'
|
||||
import type { User } from '@/types'
|
||||
|
||||
interface Props {
|
||||
user: User | null
|
||||
onLogout: () => void
|
||||
}
|
||||
|
||||
export default function Sidebar({ user, onLogout }: Props) {
|
||||
const { pathname } = useLocation()
|
||||
const links = [
|
||||
{ to: '/', icon: '📊', label: '仪表盘' },
|
||||
{ to: '/issues', icon: '📋', label: 'Issues' },
|
||||
{ to: '/projects', icon: '📁', label: '项目' },
|
||||
]
|
||||
|
||||
return (
|
||||
<nav className="sidebar">
|
||||
<div className="sidebar-header">
|
||||
<h1>⚓ HarborForge</h1>
|
||||
</div>
|
||||
<ul className="nav-links">
|
||||
{links.map((l) => (
|
||||
<li key={l.to} className={pathname === l.to ? 'active' : ''}>
|
||||
<Link to={l.to}>{l.icon} {l.label}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{user && (
|
||||
<div className="sidebar-footer">
|
||||
<span>👤 {user.username}</span>
|
||||
<button onClick={onLogout}>退出</button>
|
||||
</div>
|
||||
)}
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user