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:
kkfluous
2026-03-27 19:36:41 +08:00
parent f051e3f5aa
commit df1ab64c97

View File

@@ -861,7 +861,7 @@ export default function App() {
</div> </div>
{/* Department Operations Statistics */} {/* 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="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="flex items-center gap-3">
<div className="w-1.5 h-6 bg-blue-600 rounded-full"></div> <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"> <div className="p-0 sm:p-2 bg-gray-50/30">
{/* Overall Total Summary (Compact) */} {/* Overall Total Summary (Compact) */}
<div className="m-2 bg-slate-800 rounded-xl p-3 text-white shadow-lg"> <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"> <div className="flex flex-col">
<span className="text-[9px] opacity-50 uppercase font-bold tracking-widest mb-0.5"></span> <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> <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)} {deptData.reduce((acc, d) => acc + d.idleCount, 0)}
</span> </span>
</div> </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>
</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"> <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> <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>} {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' && ( {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-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-green-500"></th>
<th className="p-2 font-bold border-r border-gray-100 text-center w-24 text-gray-400"></th> <th className="p-2 font-bold border-r border-gray-100 text-center w-24 text-gray-400"></th>
</> </>
)} )}
{deptViewMode === 'manager' && ( {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">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"></th>
<th className="p-2 font-bold border-r border-gray-100 text-center w-20">18T</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"> <td className="p-2 border-r border-gray-100 font-bold text-gray-800">
{dept.department} {dept.department}
</td> </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"> <td className="p-2 border-r border-gray-100 text-center font-black text-gray-800 text-sm">
{dept.totalAssets} {dept.totalAssets}
</td> </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"> <td className="p-2 border-r border-gray-100 text-center font-black text-green-500 text-sm">
{dept.operatingCount} {dept.operatingCount}
</td> </td>
@@ -990,7 +997,7 @@ export default function App() {
</tr> </tr>
{isExpanded && ( {isExpanded && (
<tr className="bg-gray-50/50"> <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"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-2">
{dept.managers.map(m => { {dept.managers.map(m => {
const isManagerExpanded = expandedManagerDetails.has(m.manager); const isManagerExpanded = expandedManagerDetails.has(m.manager);
@@ -1007,7 +1014,7 @@ export default function App() {
<button <button
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); 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" 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" 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) => { onClick={(e) => {
e.stopPropagation(); 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} {m.total}
@@ -1106,7 +1113,7 @@ export default function App() {
<button <button
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); 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" className="text-blue-500 hover:text-blue-700 transition-colors"
> >
@@ -1160,19 +1167,26 @@ export default function App() {
deptData.map((dept) => { deptData.map((dept) => {
const isExpanded = expandedDepts.has(dept.department); const isExpanded = expandedDepts.has(dept.department);
return ( 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 <div
className="p-3 cursor-pointer" className="p-3 cursor-pointer"
onClick={() => toggleDept(dept.department)} onClick={() => toggleDept(dept.department)}
> >
<div className="flex justify-between items-center mb-2"> <div className="flex justify-between items-center mb-2">
<h3 className="text-sm font-bold text-gray-800">{dept.department}</h3> <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>
<div className="grid grid-cols-3 gap-2"> <div className="grid grid-cols-4 gap-2">
<div className="text-center"> <div className="text-center">
<div className="text-[8px] text-gray-400 uppercase font-bold mb-0.5"></div> <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 className="text-xs font-black text-gray-800">{dept.totalAssets}</div>
</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-center">
<div className="text-[8px] text-green-500 uppercase font-bold mb-0.5"></div> <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> <div className="text-xs font-black text-green-500">{dept.operatingCount}</div>
@@ -1203,7 +1217,7 @@ export default function App() {
<button <button
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); 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" 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) => { managerStats.map((m) => {
const isManagerExpanded = expandedManagerDetails.has(m.manager); const isManagerExpanded = expandedManagerDetails.has(m.manager);
return ( 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 <div
className="p-2 cursor-pointer flex items-center justify-between gap-2" className="p-2 cursor-pointer flex items-center justify-between gap-2"
onClick={() => toggleManagerDetails(m.manager)} onClick={() => toggleManagerDetails(m.manager)}
@@ -1283,7 +1297,7 @@ export default function App() {
className="text-[11px] font-bold text-blue-600 whitespace-nowrap" className="text-[11px] font-bold text-blue-600 whitespace-nowrap"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); 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} : {m.total}
@@ -1294,7 +1308,7 @@ export default function App() {
<button <button
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); 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" 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> </section>
{/* Region - Vehicle - Customer 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="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="flex items-center gap-3">
<div className="w-1.5 h-6 bg-slate-400 rounded-full"></div> <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 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"></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-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> <th className="p-2 font-semibold text-center bg-slate-100/50 w-32"></th>
</tr> </tr>
</thead> </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" className="p-2 text-center text-orange-600 font-bold cursor-pointer hover:bg-orange-50"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Inventory' }); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Pending' });
}} }}
> >
{r.inventoryCount} {r.inventoryCount}
@@ -1530,7 +1544,7 @@ export default function App() {
</td> </td>
<td <td
className="p-2 text-center text-orange-600 cursor-pointer hover:bg-orange-50" 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} {tb.inventory}
</td> </td>
@@ -1579,9 +1593,9 @@ export default function App() {
</div> </div>
<div <div
className="bg-white p-2 rounded border border-slate-100 cursor-pointer active:bg-orange-50" 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 className="text-xs font-bold text-orange-600">{r.inventoryCount}</div>
</div> </div>
</div> </div>
@@ -1601,9 +1615,9 @@ export default function App() {
</span> </span>
<span <span
className="font-bold text-orange-600 cursor-pointer" 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> </span>
</div> </div>
</div> </div>
@@ -1620,7 +1634,7 @@ export default function App() {
</section> </section>
{/* Customer Operations Statistics 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="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="flex items-center gap-3">
<div className="w-1.5 h-6 bg-emerald-400 rounded-full"></div> <div className="w-1.5 h-6 bg-emerald-400 rounded-full"></div>