Operations dashboard screens are added
This commit is contained in:
226
utils/table.tsx
Normal file
226
utils/table.tsx
Normal file
@@ -0,0 +1,226 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Pencil,
|
||||
Menu,
|
||||
ShieldCheck,
|
||||
QrCode,
|
||||
Power,
|
||||
Check,
|
||||
Sparkles,
|
||||
} from 'lucide-react';
|
||||
|
||||
// Data model interface
|
||||
interface TableRowData {
|
||||
id: string;
|
||||
block: string;
|
||||
floor: string;
|
||||
zone: string;
|
||||
department: string;
|
||||
location: string;
|
||||
window: string;
|
||||
tat: string;
|
||||
sched: number;
|
||||
approval: boolean;
|
||||
status: 'ACTIVE' | 'INACTIVE';
|
||||
}
|
||||
|
||||
// Sample data extracted from your screenshot
|
||||
const mockData: TableRowData[] = [
|
||||
{ id: '1', block: 'Block 1', floor: 'G', zone: 'Z2', department: 'Electrical', location: 'Main lobby', window: '06:00–17:30', tat: '60m', sched: 8, approval: true, status: 'INACTIVE' },
|
||||
{ id: '2', block: 'Block 2', floor: '3', zone: 'Z2', department: 'Electrical', location: 'Main lobby', window: '08:00–23:59', tat: '30m', sched: 4, approval: false, status: 'ACTIVE' },
|
||||
{ id: '3', block: 'Block 2', floor: '3', zone: 'Z1', department: 'Inspection work', location: 'Cafeteria', window: '06:00–17:30', tat: '20m', sched: 8, approval: true, status: 'ACTIVE' },
|
||||
{ id: '4', block: 'Block 1', floor: 'G', zone: 'Z1', department: 'HVAC', location: 'Server room', window: '08:00–18:00', tat: '30m', sched: 4, approval: false, status: 'INACTIVE' },
|
||||
{ id: '5', block: 'Block 2', floor: '3', zone: 'N', department: 'Inspection work', location: 'Server room', window: '08:00–18:00', tat: '60m', sched: 8, approval: true, status: 'ACTIVE' },
|
||||
{ id: '6', block: 'Block 2', floor: 'G', zone: 'Z1', department: 'Electrical', location: 'Reception', window: '06:00–18:00', tat: '60m', sched: 6, approval: false, status: 'ACTIVE' },
|
||||
{ id: '7', block: 'Block 1', floor: 'G', zone: 'Z2', department: 'Electrical', location: 'Food court', window: '06:00–17:30', tat: '60m', sched: 8, approval: true, status: 'ACTIVE' },
|
||||
{ id: '8', block: 'Block 2', floor: '3', zone: 'Z2', department: 'Electrical', location: 'Cafeteria', window: '08:00–23:59', tat: '30m', sched: 4, approval: false, status: 'ACTIVE' },
|
||||
{ id: '9', block: 'Block 2', floor: '3', zone: 'Z1', department: 'Inspection work', location: 'Gym', window: '06:00–17:30', tat: '20m', sched: 8, approval: true, status: 'INACTIVE' },
|
||||
{ id: '10', block: 'Block 1', floor: 'G', zone: 'Z1', department: 'HVAC', location: 'Lobby', window: '08:00–18:00', tat: '30m', sched: 4, approval: false, status: 'ACTIVE' },
|
||||
];
|
||||
|
||||
export default function LocationTable(){
|
||||
const [selectedIds, setSelectedIds] = useState<string[]>(['1']); // Row 1 selected by default (teal indicator bar)
|
||||
|
||||
const toggleSelectAll = () => {
|
||||
if (selectedIds.length === mockData.length) {
|
||||
setSelectedIds([]);
|
||||
} else {
|
||||
setSelectedIds(mockData.map((row) => row.id));
|
||||
}
|
||||
};
|
||||
|
||||
const toggleSelectRow = (id: string) => {
|
||||
setSelectedIds((prev) =>
|
||||
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full bg-[#071321] text-slate-300 rounded-xl overflow-hidden border border-slate-800/80 shadow-2xl relative font-sans">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-left text-xs border-collapse">
|
||||
{/* TABLE HEADER */}
|
||||
<thead>
|
||||
<tr className="border-b border-slate-800/90 text-[11px] font-bold tracking-wider text-slate-500 uppercase font-mono">
|
||||
<th className="py-4 px-4 w-12 text-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedIds.length === mockData.length}
|
||||
onChange={toggleSelectAll}
|
||||
className="rounded border-slate-700 bg-slate-900/80 text-teal-400 focus:ring-0 focus:ring-offset-0 cursor-pointer accent-teal-400 h-3.5 w-3.5"
|
||||
/>
|
||||
</th>
|
||||
<th className="py-4 px-3 font-mono">BLOCK</th>
|
||||
<th className="py-4 px-3 font-mono">FLOOR</th>
|
||||
<th className="py-4 px-3 font-mono">ZONE</th>
|
||||
<th className="py-4 px-3 font-mono">DEPARTMENT</th>
|
||||
<th className="py-4 px-3 font-mono">LOCATION</th>
|
||||
<th className="py-4 px-3 font-mono">WINDOW</th>
|
||||
<th className="py-4 px-3 font-mono">TAT</th>
|
||||
<th className="py-4 px-3 font-mono">SCHED.</th>
|
||||
<th className="py-4 px-3 font-mono">APPROVAL</th>
|
||||
<th className="py-4 px-3 font-mono">STATUS</th>
|
||||
<th className="py-4 px-4 font-mono text-right pr-6">ACTIONS</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
{/* TABLE BODY */}
|
||||
<tbody className="divide-y divide-slate-800/50">
|
||||
{mockData.map((row) => {
|
||||
const isSelected = selectedIds.includes(row.id);
|
||||
|
||||
return (
|
||||
<tr
|
||||
key={row.id}
|
||||
className={`group relative transition-colors ${
|
||||
isSelected
|
||||
? 'bg-[#0e2238]/60 hover:bg-[#122942]/80'
|
||||
: 'hover:bg-slate-800/30'
|
||||
}`}
|
||||
>
|
||||
{/* Left Selection Indicator Bar (for Row 1 / Selected Rows) */}
|
||||
<td className="py-3 px-4 text-center relative">
|
||||
{isSelected && (
|
||||
<span className="absolute left-0 top-0 bottom-0 w-[3px] bg-teal-400 rounded-r" />
|
||||
)}
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={isSelected}
|
||||
onChange={() => toggleSelectRow(row.id)}
|
||||
className="rounded border-slate-700 bg-slate-900/80 text-teal-400 focus:ring-0 focus:ring-offset-0 cursor-pointer accent-teal-400 h-3.5 w-3.5"
|
||||
/>
|
||||
</td>
|
||||
|
||||
{/* Block */}
|
||||
<td className="py-3 px-3 font-semibold text-slate-100 whitespace-nowrap">
|
||||
{row.block}
|
||||
</td>
|
||||
|
||||
{/* Floor */}
|
||||
<td className="py-3 px-3 font-medium text-slate-200">
|
||||
{row.floor}
|
||||
</td>
|
||||
|
||||
{/* Zone */}
|
||||
<td className="py-3 px-3 font-medium text-slate-300">
|
||||
{row.zone}
|
||||
</td>
|
||||
|
||||
{/* Department */}
|
||||
<td className="py-3 px-3 font-semibold text-slate-200 whitespace-nowrap">
|
||||
{row.department}
|
||||
</td>
|
||||
|
||||
{/* Location */}
|
||||
<td className="py-3 px-3 font-extrabold text-white whitespace-nowrap">
|
||||
{row.location}
|
||||
</td>
|
||||
|
||||
{/* Window */}
|
||||
<td className="py-3 px-3 font-mono text-slate-400 text-[11px] whitespace-nowrap">
|
||||
{row.window}
|
||||
</td>
|
||||
|
||||
{/* TAT */}
|
||||
<td className="py-3 px-3 font-mono text-slate-200 font-medium">
|
||||
{row.tat}
|
||||
</td>
|
||||
|
||||
{/* Sched */}
|
||||
<td className="py-3 px-3 font-mono text-slate-200 font-medium">
|
||||
{row.sched}
|
||||
</td>
|
||||
|
||||
{/* Approval */}
|
||||
<td className="py-3 px-3 whitespace-nowrap">
|
||||
{row.approval ? (
|
||||
<span className="inline-flex items-center gap-1.5 text-emerald-400 font-semibold">
|
||||
<Check size={14} className="stroke-[3]" />
|
||||
<span>Yes</span>
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-slate-500 font-mono">——</span>
|
||||
)}
|
||||
</td>
|
||||
|
||||
{/* Status Badge */}
|
||||
<td className="py-3 px-3 whitespace-nowrap">
|
||||
{row.status === 'ACTIVE' ? (
|
||||
<span className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[10px] font-bold font-mono tracking-wider bg-emerald-950/80 border border-emerald-800/40 text-emerald-400">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-emerald-400"></span>
|
||||
ACTIVE
|
||||
</span>
|
||||
) : (
|
||||
<span className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[10px] font-bold font-mono tracking-wider bg-slate-800/80 border border-slate-700/50 text-slate-400">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-slate-400"></span>
|
||||
INACTIVE
|
||||
</span>
|
||||
)}
|
||||
</td>
|
||||
|
||||
{/* Action Icon Buttons */}
|
||||
<td className="py-3 px-4 text-right whitespace-nowrap pr-6">
|
||||
<div className="inline-flex items-center gap-1.5">
|
||||
<button
|
||||
title="Edit"
|
||||
className="p-1.5 rounded-md bg-[#0b1b2d] hover:bg-slate-700/60 border border-slate-800 text-slate-400 hover:text-slate-200 transition-colors"
|
||||
>
|
||||
<Pencil size={13} />
|
||||
</button>
|
||||
<button
|
||||
title="Options"
|
||||
className="p-1.5 rounded-md bg-[#0b1b2d] hover:bg-slate-700/60 border border-slate-800 text-slate-400 hover:text-slate-200 transition-colors"
|
||||
>
|
||||
<Menu size={13} />
|
||||
</button>
|
||||
<button
|
||||
title="Security"
|
||||
className="p-1.5 rounded-md bg-[#0b1b2d] hover:bg-slate-700/60 border border-slate-800 text-slate-400 hover:text-slate-200 transition-colors"
|
||||
>
|
||||
<ShieldCheck size={13} />
|
||||
</button>
|
||||
<button
|
||||
title="QR Code"
|
||||
className="p-1.5 rounded-md bg-[#0b1b2d] hover:bg-slate-700/60 border border-slate-800 text-slate-400 hover:text-slate-200 transition-colors"
|
||||
>
|
||||
<QrCode size={13} />
|
||||
</button>
|
||||
<button
|
||||
title="Toggle Power"
|
||||
className="p-1.5 rounded-md bg-[#0b1b2d] hover:bg-slate-700/60 border border-slate-800 text-slate-400 hover:text-slate-200 transition-colors"
|
||||
>
|
||||
<Power size={13} />
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user