fix(mobile): add top tab switcher and remove dead settings entry

Sidebar was hidden on mobile with no fallback, so users were stuck on
the default view. Add a horizontal tab strip under the header for
mobile viewports and drop the "后台系统设置" button which had no handler
or matching view.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
kkfluous
2026-04-29 18:27:12 +08:00
parent da191b0dbf
commit e028fed508
2 changed files with 34 additions and 19 deletions

View File

@@ -1,7 +1,8 @@
import { useState } from 'react'; import { useState } from 'react';
import { Dashboard } from './components/Dashboard'; import { Dashboard } from './components/Dashboard';
import { Sidebar } from './components/Sidebar'; import { Sidebar, sidebarMenuItems } from './components/Sidebar';
import { Header } from './components/Header'; import { Header } from './components/Header';
import { cn } from './lib/utils';
export default function App() { export default function App() {
const [currentView, setCurrentView] = useState('overall'); const [currentView, setCurrentView] = useState('overall');
@@ -17,6 +18,28 @@ export default function App() {
<Sidebar currentView={currentView} setCurrentView={setCurrentView} /> <Sidebar currentView={currentView} setCurrentView={setCurrentView} />
<div className="flex flex-col flex-1 overflow-hidden"> <div className="flex flex-col flex-1 overflow-hidden">
<Header title={viewTitles[currentView] || '数据分析'} /> <Header title={viewTitles[currentView] || '数据分析'} />
<nav className="md:hidden bg-white border-b border-slate-200 px-2 shrink-0 overflow-x-auto">
<div className="flex gap-1 min-w-max">
{sidebarMenuItems.map((item) => {
const active = currentView === item.id;
return (
<button
key={item.id}
onClick={() => setCurrentView(item.id)}
className={cn(
"flex items-center gap-1.5 px-3 py-2.5 text-xs font-semibold whitespace-nowrap border-b-2 transition-colors",
active
? "text-indigo-600 border-indigo-500"
: "text-slate-500 border-transparent active:text-slate-700"
)}
>
<item.icon className={cn("w-4 h-4", active ? "text-indigo-500" : "text-slate-400")} />
{item.name}
</button>
);
})}
</div>
</nav>
<main className="flex-1 overflow-y-auto p-4 md:p-6 lg:p-8"> <main className="flex-1 overflow-y-auto p-4 md:p-6 lg:p-8">
<Dashboard currentView={currentView} /> <Dashboard currentView={currentView} />
</main> </main>

View File

@@ -1,14 +1,14 @@
import React from 'react'; import React from 'react';
import { BarChart3, Calendar, Settings, Fuel, Users, ShieldCheck } from 'lucide-react'; import { BarChart3, Calendar, Fuel, Users } from 'lucide-react';
import { cn } from '../lib/utils'; import { cn } from '../lib/utils';
export function Sidebar({ currentView, setCurrentView }: { currentView: string; setCurrentView: (v: string) => void }) { export const sidebarMenuItems = [
const menuItems = [ { id: 'overall', name: '全网运营总览', icon: Calendar },
{ id: 'overall', name: '全网运营总览', icon: Calendar }, { id: 'users', name: '司机与车辆大盘', icon: Users },
{ id: 'users', name: '司机与车辆大盘', icon: Users }, { id: 'efficiency', name: '站点效能监控', icon: BarChart3 },
{ id: 'efficiency', name: '站点效能监控', icon: BarChart3 }, ];
];
export function Sidebar({ currentView, setCurrentView }: { currentView: string; setCurrentView: (v: string) => void }) {
return ( return (
<aside className="w-64 bg-slate-900 border-r border-slate-800 hidden md:flex flex-col text-slate-300 shadow-xl overflow-hidden relative"> <aside className="w-64 bg-slate-900 border-r border-slate-800 hidden md:flex flex-col text-slate-300 shadow-xl overflow-hidden relative">
<div className="absolute top-0 left-0 w-full h-[600px] bg-gradient-to-b from-indigo-500/10 to-transparent pointer-events-none" /> <div className="absolute top-0 left-0 w-full h-[600px] bg-gradient-to-b from-indigo-500/10 to-transparent pointer-events-none" />
@@ -18,14 +18,14 @@ export function Sidebar({ currentView, setCurrentView }: { currentView: string;
</div> </div>
<nav className="flex-1 py-6 px-4 space-y-2 z-10 overflow-y-auto"> <nav className="flex-1 py-6 px-4 space-y-2 z-10 overflow-y-auto">
<div className="text-xs font-bold text-slate-500/80 uppercase tracking-wider mb-4 px-3"></div> <div className="text-xs font-bold text-slate-500/80 uppercase tracking-wider mb-4 px-3"></div>
{menuItems.map((item) => ( {sidebarMenuItems.map((item) => (
<button <button
key={item.id} key={item.id}
onClick={() => setCurrentView(item.id)} onClick={() => setCurrentView(item.id)}
className={cn( className={cn(
"flex items-center w-full px-3 py-3 rounded-xl text-sm font-semibold transition-all duration-200 text-left group", "flex items-center w-full px-3 py-3 rounded-xl text-sm font-semibold transition-all duration-200 text-left group",
currentView === item.id currentView === item.id
? "bg-indigo-500/15 text-indigo-300 shadow-sm border border-indigo-500/30" ? "bg-indigo-500/15 text-indigo-300 shadow-sm border border-indigo-500/30"
: "hover:bg-slate-800/80 hover:text-slate-100 border border-transparent text-slate-400" : "hover:bg-slate-800/80 hover:text-slate-100 border border-transparent text-slate-400"
)} )}
> >
@@ -33,14 +33,6 @@ export function Sidebar({ currentView, setCurrentView }: { currentView: string;
{item.name} {item.name}
</button> </button>
))} ))}
<div className="mt-8 pt-6 border-t border-white/5">
<div className="text-xs font-bold text-slate-500/80 uppercase tracking-wider mb-2 px-3"></div>
<button className="flex items-center w-full px-3 py-2.5 rounded-lg text-sm font-medium transition-colors text-left text-slate-400 hover:bg-slate-800 hover:text-slate-100">
<Settings className="w-5 h-5 mr-3 text-slate-500" />
</button>
</div>
</nav> </nav>
<div className="p-4 border-t border-white/5 bg-slate-900 z-10 shrink-0"> <div className="p-4 border-t border-white/5 bg-slate-900 z-10 shrink-0">