-
-
-
- {/* TABLE HEADER */}
-
-
-
-
-
- |
-
-
-
- |
-
- BLOCK |
-
- FLOOR |
-
- ZONE |
-
- DEPARTMENT |
-
- LOCATION |
-
- WINDOW |
-
- TAT |
-
- SCHED. |
-
- APPROVAL |
-
- STATUS |
-
- ACTIONS |
-
-
-
-
-
-
-
- {/* TABLE BODY */}
-
-
-
- {mockData.map((row) => {
-
- const isSelected = selectedIds.includes(row.id);
-
-
-
- return (
-
-
-
- {/* Left Selection Indicator Bar (for Row 1 / Selected Rows) */}
-
- |
-
- {isSelected && (
-
-
-
- )}
-
- 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"
-
- />
-
- |
-
-
-
- {/* Block */}
-
-
-
- {row.block}
-
- |
-
-
-
- {/* Floor */}
-
-
-
- {row.floor}
-
- |
-
-
-
- {/* Zone */}
-
-
-
- {row.zone}
-
- |
-
-
-
- {/* Department */}
-
-
-
- {row.department}
-
- |
-
-
-
- {/* Location */}
-
-
-
- {row.location}
-
- |
-
-
-
- {/* Window */}
-
-
-
- {row.window}
-
- |
-
-
-
- {/* TAT */}
-
-
-
- {row.tat}
-
- |
-
-
-
- {/* Sched */}
-
-
-
- {row.sched}
-
- |
-
-
-
- {/* Approval */}
-
-
-
- {row.approval ? (
-
-
-
-
-
- Yes
-
-
-
- ) : (
-
- ——
-
- )}
-
- |
-
-
-
- {/* Status Badge */}
-
-
-
- {row.status === 'ACTIVE' ? (
-
-
-
-
-
- ACTIVE
-
-
-
- ) : (
-
-
-
-
-
- INACTIVE
-
-
-
- )}
-
- |
-
-
-
- {/* Action Icon Buttons */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- |
-
-
-
- );
-
- })}
-
-
-
-
-
+
+
+
+ Apple One — HQ Tower
+
+ •
+
+ Operations
+
+ •
+
+ Equipment
+
+
+
+
+
+ Equipment & maintenance
+
+
+
+
+
+ Asset register, preventive (PPM) and
+
+ contract (AMC) maintenance, scoped to the active tenant.
+
+
+
+
+
+
+ {/* Navigation Tabs */}
+
+
+ {/* --- STAT CARDS (4 CARDS MATCHING SCREENSHOT) --- */}
+
+ {/* Total equipment */}
+
+
+ {/* Critical assets */}
+
+
+ {/* PPM attention */}
+
+
+ {/* On plan */}
+
+ {/* --- ROW 2: SEARCH, FILTERS & ACTION BUTTONS --- */}
+
+ {/* Search & Group Dropdown */}
+
+ {/* Search Bar */}
+
+
+
+
+ {/* All groups dropdown */}
+
+
-
+ {/* Action Buttons Right Side */}
+
+ {/* All QR */}
+
+ {/* Download */}
+
+
+ {/* Bulk upload */}
+
+
+ {/* Add equipment */}
+
+
+
+
+ {/* Data Table */}
+
+
+ {/* Info Banner */}
+
+
+
-
);
-
-}
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/components/dashboard/helpDesk.tsx b/components/dashboard/helpDesk.tsx
index e4ebb9e..e5dc16d 100644
--- a/components/dashboard/helpDesk.tsx
+++ b/components/dashboard/helpDesk.tsx
@@ -1,31 +1,312 @@
-
-
-import { useState } from 'react';
+import { useState } from 'react';
import {
Layers,
ShieldCheck,
CheckSquare,
Clock,
Search,
- QrCode,
+ QrCode,
+ Power,
+ List,
+ Pencil,
Plus,
} from 'lucide-react';
import Button from "@/utils/button";
import StatCard from "@/utils/dashStatCard";
-import LocationTable from '@/utils/dataTable';
+import Table from "@/utils/dataTable";
import NavigationTabs from '@/utils/tabs';
import { helpdeskTtabs } from '@/constants/constant';
+const StatusBadge = ({
+ text,
+ color,
+}: {
+ text: string;
+ color: string;
+}) => (
+
+
+ {text}
+
+);
+
+const ActionButtons = ({ active }: { active: boolean }) => (
+
+
+
+
+
+
+
+
+
+
+
+);
+
+const headers = [
+ "",
+ "Block",
+ "Floor",
+ "Zone",
+ "Department",
+ "Location",
+ "Window",
+ "TAT",
+ "Sched.",
+ "Approval",
+ "Status",
+ "Actions",
+];
+
+const checkbox = (
+
+);
+
+const rows = [
+ [
+ checkbox,
+ "Block 2",
+ "1",
+ "Z2",
+ "HVAC",
+
Parking P1,
+
01:56–18:00,
+ "60m",
+ "4",
+
✓ Yes,
+
,
+
,
+ ],
+
+ [
+ checkbox,
+ "Block 1",
+ "2",
+ "Z1",
+ "Inspection work",
+
Cafeteria,
+
01:56–23:59,
+ "360m",
+ "6",
+
—,
+
,
+
,
+ ],
+
+ [
+ checkbox,
+ "Block 2",
+ "G",
+ "N",
+ "Inspection work",
+
Main lobby,
+
08:00–23:59,
+ "360m",
+ "4",
+
✓ Yes,
+
,
+
,
+ ],
+
+ [
+ checkbox,
+ "Block 1",
+ "2",
+ "Z2",
+ "Electrical",
+
Reception,
+
08:00–18:00,
+ "360m",
+ "4",
+
—,
+
,
+
,
+ ],
+
+ [
+ checkbox,
+ "Block 2",
+ "3",
+ "Z1",
+ "Housekeeping",
+
Cafeteria,
+
08:00–18:00,
+ "20m",
+ "8",
+
✓ Yes,
+
,
+
,
+ ],
+
+ [
+ checkbox,
+ "Block 1",
+ "3",
+ "Z1",
+ "Electrical",
+
Food court,
+
08:00–17:30,
+ "20m",
+ "8",
+
—,
+
,
+
,
+ ],
+
+ [
+ checkbox,
+ "Block 2",
+ "1",
+ "Z2",
+ "HVAC",
+
Parking P1,
+
01:56–18:00,
+ "60m",
+ "4",
+
✓ Yes,
+
,
+
,
+ ],
+
+ [
+ checkbox,
+ "Block 1",
+ "2",
+ "Z1",
+ "Inspection work",
+
Cafeteria,
+
01:56–23:59,
+ "360m",
+ "6",
+
—,
+
,
+
,
+ ],
+
+ [
+ checkbox,
+ "Block 2",
+ "G",
+ "N",
+ "Inspection work",
+
Main lobby,
+
08:00–23:59,
+ "360m",
+ "4",
+
✓ Yes,
+
,
+
,
+ ],
+
+ [
+ checkbox,
+ "Block 1",
+ "2",
+ "Z2",
+ "Electrical",
+
Reception,
+
08:00–18:00,
+ "360m",
+ "4",
+
—,
+
,
+
,
+ ],
+
+ [
+ checkbox,
+ "Block 2",
+ "3",
+ "Z1",
+ "Housekeeping",
+
Cafeteria,
+
08:00–18:00,
+ "20m",
+ "8",
+
✓ Yes,
+
,
+
,
+ ],
+
+ [
+ checkbox,
+ "Block 1",
+ "3",
+ "Z1",
+ "Electrical",
+
Food court,
+
08:00–17:30,
+ "20m",
+ "8",
+
—,
+
,
+
,
+ ],
+];
export default function HelpDeskPortal() {
const [activeTab, setActiveTab] = useState
('Location');
-
-
return (
-
+
{/* --- HEADER SECTION --- */}
-
+
Apple One — HQ Tower
@@ -34,123 +315,118 @@ export default function HelpDeskPortal() {
•
Help Desk
-
+
Help Desk & checklists
-
+
Scheduled location and equipment inspections, missed-checklist recovery, and HSQE incident management.
-
- {/* Reusable Navigation Tabs */}
-
-
- {/* Rest of your page content */}
-
-
- {/* Total Checklists */}
-
-
- {/* Active */}
-
+
+ {/* Reusable Navigation Tabs */}
+
+
- {/* Approval Set */}
-
-
- {/* Avg TAT */}
-
-
+
+ {/* Total Checklists */}
+
+
+ {/* Active */}
+
-
+ {/* Approval Set */}
+
+
+ {/* Avg TAT */}
+
+
{/* --- ROW 2: SEARCH, FILTERS & ACTION BUTTONS --- */}
-
+
{/* Search & Select Filters */}
-
+
{/* Search Bar */}
-
-
+
+
{/* Block Dropdown */}
-
+
-{/* Status Dropdown (Active State matching the screenshot) */}
-
+ {/* Status Dropdown */}
+
{/* Action Buttons */}
-
-
-
-
-
-
-
+ {/* --- TABLE CONTAINER --- */}
+
);
-}
-
+}
\ No newline at end of file
diff --git a/components/dashboard/request.tsx b/components/dashboard/request.tsx
index 26e426d..24230fb 100644
--- a/components/dashboard/request.tsx
+++ b/components/dashboard/request.tsx
@@ -5,6 +5,190 @@ import LocationTable from '@/utils/dataTable';
import NavigationTabs from '@/utils/tabs';
import { Reqeusttabs,statusFilters } from '@/constants/constant';
import FilterTabs from '@/utils/roundedFilters';
+import Table from '@/utils/dataTable';
+
+
+const StatusBadge = ({
+ text,
+ color,
+}: {
+ text: string;
+ color: string;
+}) => (
+
+
+ {text}
+
+);
+
+const headers = [
+ "Request No.",
+ "Department",
+ "Issue",
+ "Location",
+ "Assignee",
+ "Source",
+ "Status",
+];
+const rows = [
+ [
+
TFM/AP/2026/1009,
+ "Electrical",
+ "Lighting out",
+ "Block 1 · G",
+ "ME Local",
+
Line,
+
,
+ ],
+
+ [
+
TFM/AP/2026/1016,
+ "HVAC",
+ "AHU not cooling",
+ "Lobby · 1",
+ "Dhananjay T.",
+
Walk-in,
+
,
+ ],
+
+ [
+
TFM/AP/2026/1023,
+ "HVAC",
+ "Thermostat fault",
+ "Block 1 · 1",
+ "ME Local",
+
Mobile app,
+
,
+ ],
+
+ [
+
TFM/AP/2026/1030,
+ "HVAC",
+ "Thermostat fault",
+ "Block 1 · 1",
+ "Dhananjay T.",
+
Mobile app,
+
,
+ ],
+
+ [
+
TFM/AP/2026/1037,
+ "Civil",
+ "Glass break",
+ "Block 1 · 1",
+ "Local Helpdesk",
+
Walk-in,
+
,
+ ],
+
+ [
+
TFM/AP/2026/1044,
+ "HVAC",
+ "Chiller alarm",
+ "Block 1 · 1",
+ "Dhananjay T.",
+
Mobile app,
+
,
+ ],
+
+ [
+
TFM/AP/2026/1051,
+ "Plumbing",
+ "Water leakage",
+ "Lobby · 1",
+ "Local Helpdesk",
+
Walk-in,
+
,
+ ],
+
+ [
+
TFM/AP/2026/1058,
+ "Civil",
+ "Glass break",
+ "Block 2 · 2",
+ "Dhananjay T.",
+
Walk-in,
+
,
+ ],
+
+ [
+
TFM/AP/2026/1065,
+ "Civil",
+ "Ceiling crack",
+ "Lobby · G",
+ "ME Local",
+
Line,
+
,
+ ],
+
+ [
+
TFM/AP/2026/1072,
+ "Plumbing",
+ "Water leakage",
+ "Block 2 · G",
+ "TECH Local",
+
Line,
+
,
+ ],
+
+ [
+
TFM/AP/2026/1079,
+ "Electrical",
+ "DB switch fault",
+ "Tower A · 1",
+ "TECH Local",
+
Mobile app,
+
,
+ ],
+
+ [
+
TFM/AP/2026/1086,
+ "HVAC",
+ "AHU not cooling",
+ "Lobby · 3",
+ "TECH Local",
+
Walk-in,
+
,
+ ],
+];
export default function ServiceRequestsPortal() {
const [activeTab, setActiveTab] = useState
('TFM Requests');
@@ -36,7 +220,9 @@ export default function ServiceRequestsPortal() {
{/* --- NAVIGATION TABS & TOP ACTION BUTTONS --- */}
-
+
{/* Navigation Tabs */}
-
+
+
+
+
);
}
\ No newline at end of file
diff --git a/components/dashboard/visitorManagement.tsx b/components/dashboard/visitorManagement.tsx
new file mode 100644
index 0000000..93f97c8
--- /dev/null
+++ b/components/dashboard/visitorManagement.tsx
@@ -0,0 +1,279 @@
+import { useState } from 'react';
+import {
+ Star,
+ ShieldCheck,
+ Activity,
+ Clock,
+ BarChart2,
+ Plus
+} from "lucide-react";
+import Button from "@/utils/button";
+import StatCard from "@/utils/dashStatCard";
+import InfoBanner from "@/utils/infoBanner";
+import FilterTabs from '@/utils/roundedFilters';
+import { visitorFilters } from '@/constants/constant';
+import Table from '@/utils/dataTable';
+
+export default function VistiorManagementPortal() {
+ const headers = [
+ "Pass",
+ "Visitor",
+ "Company",
+ "Host",
+ "Purpose",
+ "Type",
+ "In",
+ "Out",
+ "Status",
+ "",
+];
+const Badge = ({
+ text,
+ color,
+}: {
+ text: string;
+ color: string;
+}) => (
+
+
+ {text}
+
+);
+
+const rows = [
+ [
+ VIS-4145,
+ Rahul Mehta,
+ "Voltas Ltd",
+ "Dhananjay T.",
+ "Maintenance visit",
+ Contractor,
+ "09:12",
+ "—",
+ ,
+ Check out,
+ ],
+
+ [
+ VIS-4146,
+ Anita Desai,
+ "Siemens",
+ "ME Local",
+ "Interview",
+ Interview,
+ "—",
+ "—",
+ ,
+ Check in,
+ ],
+
+ [
+ VIS-4147,
+ Karthik R.,
+ "Schindler",
+ "Site FM Lead",
+ "Client meeting",
+ Guest,
+ "08:05",
+ "10:40",
+ ,
+ —,
+ ],
+
+ [
+ VIS-4148,
+ Priya Nair,
+ "Amazon Logistics",
+ "Estates Office",
+ "Material delivery",
+ Delivery,
+ "—",
+ "—",
+ ,
+ Check in,
+ ],
+
+ [
+ VIS-4149,
+ Imran Q.,
+ "FreshMenu",
+ "TECH Local",
+ "AMC service",
+ Contractor,
+ "10:30",
+ "—",
+ ,
+ Check out,
+ ],
+ [
+ VIS-4145,
+ Rahul Mehta,
+ "Voltas Ltd",
+ "Dhananjay T.",
+ "Maintenance visit",
+ Contractor,
+ "09:12",
+ "—",
+ ,
+ Check out,
+ ],
+
+ [
+ VIS-4146,
+ Anita Desai,
+ "Siemens",
+ "ME Local",
+ "Interview",
+ Interview,
+ "—",
+ "—",
+ ,
+ Check in,
+ ],
+
+ [
+ VIS-4147,
+ Karthik R.,
+ "Schindler",
+ "Site FM Lead",
+ "Client meeting",
+ Guest,
+ "08:05",
+ "10:40",
+ ,
+ —,
+ ],
+
+ [
+ VIS-4148,
+ Priya Nair,
+ "Amazon Logistics",
+ "Estates Office",
+ "Material delivery",
+ Delivery,
+ "—",
+ "—",
+ ,
+ Check in,
+ ],
+
+ [
+ VIS-4149,
+ Imran Q.,
+ "FreshMenu",
+ "TECH Local",
+ "AMC service",
+ Contractor,
+ "10:30",
+ "—",
+ ,
+ Check out,
+ ],
+];
+
+const [activeFilter, setActiveFilter] = useState('All');
+ return (
+
+ {/* --- HEADER SECTION --- */}
+
+
+
+ Apple One — HQ Tower
+ •
+ Workplace
+ •
+ Visitors
+
+
+ Visitor management
+
+
+ Pre-registration, QR / OTP check-in, host notifications and on-site visitor tracking with a full audit trail.
+
+
+
+ {/* --- HEADER BUTTONS --- */}
+
+
+
+ Scan QR
+
+
+
+
+ Pre Register
+
+
+
+
+ {/* --- STAT CARDS --- */}
+
+ {/* Active vendors */}
+
+
+ {/* Avg SLA adherence */}
+
+
+ {/* Open field jobs */}
+
+
+ {/* Avg response time */}
+
+
+
+ {/* --- STATUS PILL FILTERS --- */}
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/constants/constant.ts b/constants/constant.ts
index 1effc72..0840e80 100644
--- a/constants/constant.ts
+++ b/constants/constant.ts
@@ -226,6 +226,15 @@ export const Reqeusttabs: string[] = [
{ label: 'Rejected', count: 1 },
];
+ export const visitorFilters = [
+ { label: 'All', count: 12 },
+ { label: 'Expected', count: 2 },
+ { label: 'Pre-Reg', count: 2},
+ { label: 'Onsite', count: 4 },
+ { label: 'Left', count: 3 },
+ { label: 'Denied', count: 1 },
+
+ ];
// Data model interface
diff --git a/utils/dataTable.tsx b/utils/dataTable.tsx
index 36b2d52..d2812ea 100644
--- a/utils/dataTable.tsx
+++ b/utils/dataTable.tsx
@@ -1,397 +1,55 @@
-import { useState } from 'react';
-
-import {
-
- Pencil,
-
- Menu,
-
- ShieldCheck,
-
- QrCode,
-
- Power,
-
- Check,
-
- Sparkles,
-
-} from 'lucide-react';
-
-import { mockData } from '@/constants/constant';
-
-
-
-
-
-export default function LocationTable(){
-
- const [selectedIds, setSelectedIds] = useState(['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]
-
- );
-
- };
-
+import React from "react";
+type TableProps = {
+ headers: string[];
+ rows: React.ReactNode[][];
+};
+export default function Table({ headers, rows }: TableProps) {
return (
-
-
-
+
-
-
-
- {/* TABLE HEADER */}
-
+
-
-
-
- |
-
-
-
- |
-
- BLOCK |
-
- FLOOR |
-
- ZONE |
-
- DEPARTMENT |
-
- LOCATION |
-
- WINDOW |
-
- TAT |
-
- SCHED. |
-
- APPROVAL |
-
- STATUS |
-
- ACTIONS |
-
+
+ {headers.map((header, index) => (
+ |
+ {header}
+ |
+ ))}
-
-
-
- {/* TABLE BODY */}
-
-
-
- {mockData.map((row) => {
-
- const isSelected = selectedIds.includes(row.id);
-
-
-
- return (
-
-
-
- {/* Left Selection Indicator Bar (for Row 1 / Selected Rows) */}
-
- |
-
- {isSelected && (
-
-
-
- )}
-
- 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"
-
- />
-
+ |
+ {rows.map((row, rowIndex) => (
+
+ {row.map((cell, cellIndex) => (
+ |
+ {cell}
|
-
-
-
- {/* Block */}
-
-
-
- {row.block}
-
- |
-
-
-
- {/* Floor */}
-
-
-
- {row.floor}
-
- |
-
-
-
- {/* Zone */}
-
-
-
- {row.zone}
-
- |
-
-
-
- {/* Department */}
-
-
-
- {row.department}
-
- |
-
-
-
- {/* Location */}
-
-
-
- {row.location}
-
- |
-
-
-
- {/* Window */}
-
-
-
- {row.window}
-
- |
-
-
-
- {/* TAT */}
-
-
-
- {row.tat}
-
- |
-
-
-
- {/* Sched */}
-
-
-
- {row.sched}
-
- |
-
-
-
- {/* Approval */}
-
-
-
- {row.approval ? (
-
-
-
-
-
- Yes
-
-
-
- ) : (
-
- ——
-
- )}
-
- |
-
-
-
- {/* Status Badge */}
-
-
-
- {row.status === 'ACTIVE' ? (
-
-
-
-
-
- ACTIVE
-
-
-
- ) : (
-
-
-
-
-
- INACTIVE
-
-
-
- )}
-
- |
-
-
-
- {/* Action Icon Buttons */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- |
-
-
-
- );
-
- })}
-
+ ))}
+
+ ))}
-
-
-
-
-
-
-
-
);
-
-}
\ No newline at end of file
+}
\ No newline at end of file