fix: match prototype UI 1:1 for dept/region/customer sections
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
58
src/App.tsx
58
src/App.tsx
@@ -861,7 +861,7 @@ export default function App() {
|
||||
</div>
|
||||
|
||||
{/* Department Operations Statistics */}
|
||||
<section className="bg-white rounded-sm border border-gray-100 shadow-sm overflow-hidden mb-6">
|
||||
<section className="bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden mb-6">
|
||||
<div className="p-3 sm:p-4 border-b border-gray-50 flex items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-1.5 h-6 bg-blue-600 rounded-full"></div>
|
||||
@@ -875,7 +875,7 @@ export default function App() {
|
||||
<div className="p-0 sm:p-2 bg-gray-50/30">
|
||||
{/* Overall Total Summary (Compact) */}
|
||||
<div className="m-2 bg-slate-800 rounded-xl p-3 text-white shadow-lg">
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[9px] opacity-50 uppercase font-bold tracking-widest mb-0.5">总资产</span>
|
||||
<span className="text-xl font-black">{deptData.reduce((s, d) => s + d.totalAssets, 0)}</span>
|
||||
@@ -892,6 +892,10 @@ export default function App() {
|
||||
{deptData.reduce((acc, d) => acc + d.idleCount, 0)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[9px] opacity-50 uppercase font-bold tracking-widest mb-0.5 text-blue-400">平均出勤</span>
|
||||
<span className="text-xl font-black text-blue-400">—</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -939,16 +943,17 @@ export default function App() {
|
||||
<tr className="bg-gray-100/50 text-[11px] text-gray-500 uppercase tracking-wider border-b border-gray-200">
|
||||
<th className="p-2 font-bold border-r border-gray-100 w-48">{deptViewMode === 'department' ? '部门名称' : '业务员'}</th>
|
||||
{deptViewMode === 'manager' && <th className="p-2 font-bold border-r border-gray-100 w-32">所属部门</th>}
|
||||
<th className="p-2 font-bold border-r border-gray-100 text-center w-24">{deptViewMode === 'department' ? '出勤率' : '合计资产'}</th>
|
||||
{deptViewMode === 'department' && (
|
||||
<>
|
||||
<th className="p-2 font-bold border-r border-gray-100 text-center w-24">资产总数</th>
|
||||
<th className="p-2 font-bold border-r border-gray-100 text-center w-28">日均里程</th>
|
||||
<th className="p-2 font-bold border-r border-gray-100 text-center w-24 text-green-500">运营中</th>
|
||||
<th className="p-2 font-bold border-r border-gray-100 text-center w-24 text-gray-400">闲置中</th>
|
||||
</>
|
||||
)}
|
||||
{deptViewMode === 'manager' && (
|
||||
<>
|
||||
<th className="p-2 font-bold border-r border-gray-100 text-center w-24">合计资产</th>
|
||||
<th className="p-2 font-bold border-r border-gray-100 text-center w-20">4.5T</th>
|
||||
<th className="p-2 font-bold border-r border-gray-100 text-center w-20">冷链</th>
|
||||
<th className="p-2 font-bold border-r border-gray-100 text-center w-20">18T</th>
|
||||
@@ -975,9 +980,11 @@ export default function App() {
|
||||
<td className="p-2 border-r border-gray-100 font-bold text-gray-800">
|
||||
{dept.department}
|
||||
</td>
|
||||
<td className="p-2 border-r border-gray-100 text-center"><span className="bg-blue-50 text-blue-600 text-[10px] font-bold px-2 py-0.5 rounded-full">—</span></td>
|
||||
<td className="p-2 border-r border-gray-100 text-center font-black text-gray-800 text-sm">
|
||||
{dept.totalAssets}
|
||||
</td>
|
||||
<td className="p-2 border-r border-gray-100 text-center"><div className="flex items-baseline justify-center gap-1"><span className="font-black text-gray-400 text-sm">—</span></div></td>
|
||||
<td className="p-2 border-r border-gray-100 text-center font-black text-green-500 text-sm">
|
||||
{dept.operatingCount}
|
||||
</td>
|
||||
@@ -990,7 +997,7 @@ export default function App() {
|
||||
</tr>
|
||||
{isExpanded && (
|
||||
<tr className="bg-gray-50/50">
|
||||
<td colSpan={5} className="p-2">
|
||||
<td colSpan={7} className="p-2">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-2">
|
||||
{dept.managers.map(m => {
|
||||
const isManagerExpanded = expandedManagerDetails.has(m.manager);
|
||||
@@ -1007,7 +1014,7 @@ export default function App() {
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager });
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating' });
|
||||
}}
|
||||
className="text-[10px] font-bold text-blue-600 bg-blue-50 px-2 py-0.5 rounded hover:bg-blue-100 transition-colors"
|
||||
>
|
||||
@@ -1091,7 +1098,7 @@ export default function App() {
|
||||
className="p-2 border-r border-gray-100 text-center font-black text-blue-600 text-sm cursor-pointer hover:bg-blue-50"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager });
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating' });
|
||||
}}
|
||||
>
|
||||
{m.total}
|
||||
@@ -1106,7 +1113,7 @@ export default function App() {
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager });
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating' });
|
||||
}}
|
||||
className="text-blue-500 hover:text-blue-700 transition-colors"
|
||||
>
|
||||
@@ -1160,19 +1167,26 @@ export default function App() {
|
||||
deptData.map((dept) => {
|
||||
const isExpanded = expandedDepts.has(dept.department);
|
||||
return (
|
||||
<div key={dept.department} className="bg-white rounded-sm border border-gray-100 shadow-sm overflow-hidden">
|
||||
<div key={dept.department} className="bg-white rounded-xl border border-gray-100 shadow-sm overflow-hidden">
|
||||
<div
|
||||
className="p-3 cursor-pointer"
|
||||
onClick={() => toggleDept(dept.department)}
|
||||
>
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<h3 className="text-sm font-bold text-gray-800">{dept.department}</h3>
|
||||
<span className="bg-blue-50 text-blue-600 text-[9px] font-bold px-2 py-0.5 rounded-full">
|
||||
出勤率: —
|
||||
</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
<div className="grid grid-cols-4 gap-2">
|
||||
<div className="text-center">
|
||||
<div className="text-[8px] text-gray-400 uppercase font-bold mb-0.5">资产</div>
|
||||
<div className="text-xs font-black text-gray-800">{dept.totalAssets}</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-[8px] text-gray-400 uppercase font-bold mb-0.5">里程</div>
|
||||
<div className="text-xs font-black text-gray-400">—</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-[8px] text-green-500 uppercase font-bold mb-0.5">运营</div>
|
||||
<div className="text-xs font-black text-green-500">{dept.operatingCount}</div>
|
||||
@@ -1203,7 +1217,7 @@ export default function App() {
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager });
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating' });
|
||||
}}
|
||||
className="text-[10px] font-bold text-blue-600 bg-blue-50 px-2 py-0.5 rounded"
|
||||
>
|
||||
@@ -1269,7 +1283,7 @@ export default function App() {
|
||||
managerStats.map((m) => {
|
||||
const isManagerExpanded = expandedManagerDetails.has(m.manager);
|
||||
return (
|
||||
<div key={m.manager} className="bg-white rounded-sm border border-gray-100 shadow-sm overflow-hidden">
|
||||
<div key={m.manager} className="bg-white rounded-xl border border-gray-100 shadow-sm overflow-hidden">
|
||||
<div
|
||||
className="p-2 cursor-pointer flex items-center justify-between gap-2"
|
||||
onClick={() => toggleManagerDetails(m.manager)}
|
||||
@@ -1283,7 +1297,7 @@ export default function App() {
|
||||
className="text-[11px] font-bold text-blue-600 whitespace-nowrap"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager });
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating' });
|
||||
}}
|
||||
>
|
||||
资产: {m.total}
|
||||
@@ -1294,7 +1308,7 @@ export default function App() {
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager });
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating' });
|
||||
}}
|
||||
className="text-blue-500 p-1 hover:bg-blue-50 rounded transition-colors flex-shrink-0"
|
||||
>
|
||||
@@ -1357,7 +1371,7 @@ export default function App() {
|
||||
</section>
|
||||
|
||||
{/* Region - Vehicle - Customer Section */}
|
||||
<section className="bg-white rounded-sm shadow-sm border border-gray-100 overflow-hidden mb-6">
|
||||
<section className="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden mb-6">
|
||||
<div className="p-3 sm:p-4 border-b border-gray-50 flex items-center justify-between bg-slate-50 relative">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-1.5 h-6 bg-slate-400 rounded-full"></div>
|
||||
@@ -1467,7 +1481,7 @@ export default function App() {
|
||||
<th className="p-2 font-semibold border-r border-slate-100 w-48">区域 / 车型 / 客户</th>
|
||||
<th className="p-2 font-semibold border-r border-slate-100 text-center w-24">资产总数</th>
|
||||
<th className="p-2 font-semibold border-r border-slate-100 text-center w-24 text-green-600">运营中</th>
|
||||
<th className="p-2 font-semibold border-r border-slate-100 text-center w-24 text-orange-600">库存</th>
|
||||
<th className="p-2 font-semibold border-r border-slate-100 text-center w-24 text-orange-600">待交车</th>
|
||||
<th className="p-2 font-semibold text-center bg-slate-100/50 w-32">主要客户</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -1501,7 +1515,7 @@ export default function App() {
|
||||
className="p-2 text-center text-orange-600 font-bold cursor-pointer hover:bg-orange-50"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Inventory' });
|
||||
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Pending' });
|
||||
}}
|
||||
>
|
||||
{r.inventoryCount}
|
||||
@@ -1530,7 +1544,7 @@ export default function App() {
|
||||
</td>
|
||||
<td
|
||||
className="p-2 text-center text-orange-600 cursor-pointer hover:bg-orange-50"
|
||||
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', vehicleType, category: 'Inventory' })}
|
||||
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', vehicleType, category: 'Pending' })}
|
||||
>
|
||||
{tb.inventory}
|
||||
</td>
|
||||
@@ -1579,9 +1593,9 @@ export default function App() {
|
||||
</div>
|
||||
<div
|
||||
className="bg-white p-2 rounded border border-slate-100 cursor-pointer active:bg-orange-50"
|
||||
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Inventory' })}
|
||||
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Pending' })}
|
||||
>
|
||||
<div className="text-[9px] text-gray-400 uppercase">库存</div>
|
||||
<div className="text-[9px] text-gray-400 uppercase">待交车</div>
|
||||
<div className="text-xs font-bold text-orange-600">{r.inventoryCount}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1601,9 +1615,9 @@ export default function App() {
|
||||
</span>
|
||||
<span
|
||||
className="font-bold text-orange-600 cursor-pointer"
|
||||
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', vehicleType, category: 'Inventory' })}
|
||||
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', vehicleType, category: 'Pending' })}
|
||||
>
|
||||
库:{tb.inventory}
|
||||
待:{tb.inventory}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1620,7 +1634,7 @@ export default function App() {
|
||||
</section>
|
||||
|
||||
{/* Customer Operations Statistics Section */}
|
||||
<section className="bg-white rounded-sm shadow-sm border border-gray-100 overflow-hidden mb-6">
|
||||
<section className="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden mb-6">
|
||||
<div className="p-3 sm:p-4 border-b border-gray-50 flex items-center justify-between bg-emerald-800 text-white relative">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-1.5 h-6 bg-emerald-400 rounded-full"></div>
|
||||
|
||||
Reference in New Issue
Block a user