Changes done in ui screens

This commit is contained in:
2026-07-28 19:11:10 +05:30
parent b8e833dbb9
commit 7ce1f2705e
33 changed files with 1944 additions and 1248 deletions

View File

@@ -4,7 +4,7 @@
import AlarmRulesPortal from "@/components/dashboard/iotapplication/alarmsRules";
import DeviceFleetPortal from "@/components/dashboard/iotapplication/deviceFleet";

View File

@@ -7,7 +7,7 @@ type TableProps = {
export default function Table({ headers, rows }: TableProps) {
return (
<div className="w-full overflow-hidden rounded-2xl border
<div className="w-full overflow-hidden border
border-slate-800 bg-[#0B1727] shadow-xl">
<div className="overflow-x-auto">
<table className="w-full border-collapse text-[12px]">

View File

@@ -22,12 +22,12 @@ export default function AuditSurveyPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest uppercase font-mono">
<span className="text-teal-400">Apple One HQ Tower</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">COMPLIANCE</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">AUDIT & SURVEY</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">COMPLIANCE</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">AUDIT & SURVEY</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-2">
Audit & survey management

View File

@@ -21,12 +21,12 @@ export default function ContractsPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-emerald-400 uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-emerald-400 uppercase font-mono">
<span>Apple One HQ Tower</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">COMPLIANCE</span>
<span className="text-slate-500"></span>
<span className="text-slate-500"> Contracts</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">COMPLIANCE</span>
<span className="text-slate-600"></span>
<span className="text-slate-400"> Contracts</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-2">
Contract management

View File

@@ -23,12 +23,12 @@ export default function FireSafetyPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest uppercase font-mono">
<span className="text-teal-400">Apple One HQ Tower</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">COMPLIANCE</span>
<span className="text-slate-500"></span>
<span className="text-slate-500"> FIRE & SAFETY</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">COMPLIANCE</span>
<span className="text-slate-600"></span>
<span className="text-slate-400"> FIRE & SAFETY</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-2">
Fire & safety management
@@ -102,7 +102,7 @@ export default function FireSafetyPortal() {
{/* --- MAIN CONTENT LAYOUT --- */}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
{/* Left Column: Safety equipment inspection Table */}
<div className="lg:col-span-2 rounded-xl border border-slate-800/80 bg-[#071321]/80 p-5">
<div className="lg:col-span-2 rounded-xl border border-slate-800/80 p-5">
<div className="flex items-center justify-between mb-4">
<h2 className="text-base font-bold text-slate-100">
Safety equipment inspection

View File

@@ -1,4 +1,4 @@
import { useState } from 'react';
import {
Layers,
ShieldCheck,
@@ -32,12 +32,12 @@ export default function StatutoryCompliancePortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<span className="text-teal-400">Apple One HQ Tower</span>
<span></span>
<span>Compliance</span>
<span></span>
<span>Statutory</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">Compliance</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">Statutory</span>
</div>
<h1 className="text-2xl font-extrabold text-white tracking-tight mt-1.5">
Statutory compliance tracker

View File

@@ -1,10 +1,8 @@
import { useState } from 'react';
import {
ShieldCheck,
Clock,
AlertTriangle,
Calendar,
Layers,
Plus,
GraduationCap,
Star,
@@ -28,12 +26,12 @@ export default function TrainingPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest uppercase font-mono">
<span className="text-teal-400">Apple One HQ Tower</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">COMPLIANCE</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">TRAINING</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">COMPLIANCE</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">TRAINING</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-2">
Training & onboarding

View File

@@ -20,12 +20,12 @@ export default function WasteESGPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest uppercase font-mono">
<span className="text-teal-400">Apple One HQ Tower</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">SUSTAINABILITY</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">WASTE</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">SUSTAINABILITY</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">WASTE</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-2">
Waste management
@@ -97,7 +97,7 @@ export default function WasteESGPortal() {
</div>
{/* --- MAIN CONTENT SECTION BELOW STAT CARDS --- */}
<div className="grid grid-cols-1 lg:grid-cols-5 gap-4 mb-6">
<div className="grid grid-cols-1 lg:grid-cols-5 gap-4 mb-4">
{/* Waste by Stream Progress Chart */}
<div className="lg:col-span-3 rounded-xl border border-slate-800/80 bg-[#071321]/80 p-5 flex flex-col justify-between">
<div className="flex items-center justify-between mb-6">

View File

@@ -1,25 +1,24 @@
"use client";
import React, { useState } from "react";
import { Plus, QrCode, Sparkles } from "lucide-react";
import { useState } from "react";
import { Plus, } from "lucide-react";
import Button from "@/components/common/button";
import { blocks, floors, zones } from "@/constants/constant";
export default function MasterDataPortal() {
const [activeTab, setActiveTab] = useState("Block / Floor / Zone");
// Sample data for the hierarchy cards
const blocks = ["Block 1", "Block 2", "Tower A"];
const floors = ["Ground", "Floor 1", "Floor 2"];
const zones = ["Zone N", "Zone Z1", "Zone Z2"];
return (
<div className=" text-slate-100 font-sans my-15">
{/* --- BREADCRUMB --- */}
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-emerald-400 uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-emerald-400 uppercase font-mono">
<span>APPLE ONE HQ TOWER</span>
<span className="text-slate-600"></span>
<span className="text-slate-500">CONFIGURE</span>
<span className="text-slate-400">CONFIGURE</span>
<span className="text-slate-600"></span>
<span className="text-slate-500">MASTER DATA</span>
<span className="text-slate-400">MASTER DATA</span>
</div>
{/* --- PAGE HEADER --- */}
@@ -40,7 +39,7 @@ export default function MasterDataPortal() {
<span className="text-[10px] uppercase font-mono tracking-wider text-slate-500 font-bold">
SITE & LOCATION
</span>
<button
<Button
onClick={() => setActiveTab("Block / Floor / Zone")}
className={`px-3 py-1.5 rounded-lg border text-xs font-semibold transition-all ${
activeTab === "Block / Floor / Zone"
@@ -49,7 +48,7 @@ export default function MasterDataPortal() {
}`}
>
Block / Floor / Zone
</button>
</Button>
</div>
{/* ASSETS */}
@@ -59,7 +58,7 @@ export default function MasterDataPortal() {
</span>
<div className="flex flex-wrap gap-2">
{["Manufacturer", "Service Provider", "Criticality"].map((item) => (
<button
<Button
key={item}
onClick={() => setActiveTab(item)}
className={`px-3 py-1.5 rounded-lg border text-xs transition-all ${
@@ -69,7 +68,7 @@ export default function MasterDataPortal() {
}`}
>
{item}
</button>
</Button>
))}
</div>
</div>
@@ -81,7 +80,7 @@ export default function MasterDataPortal() {
</span>
<div className="flex flex-wrap gap-2">
{["Service Type", "Unit", "Store", "Partners"].map((item) => (
<button
<Button
key={item}
onClick={() => setActiveTab(item)}
className={`px-3 py-1.5 rounded-lg border text-xs transition-all ${
@@ -91,7 +90,7 @@ export default function MasterDataPortal() {
}`}
>
{item}
</button>
</Button>
))}
</div>
</div>
@@ -103,7 +102,7 @@ export default function MasterDataPortal() {
</span>
<div className="flex flex-wrap gap-2">
{["Budget Category", "Budget Type"].map((item) => (
<button
<Button
key={item}
onClick={() => setActiveTab(item)}
className={`px-3 py-1.5 rounded-lg border text-xs transition-all ${
@@ -113,7 +112,7 @@ export default function MasterDataPortal() {
}`}
>
{item}
</button>
</Button>
))}
</div>
</div>
@@ -125,7 +124,7 @@ export default function MasterDataPortal() {
PEOPLE
</span>
<div>
<button
<Button
onClick={() => setActiveTab("Course")}
className={`px-3 py-1.5 rounded-lg border text-xs font-semibold transition-all ${
activeTab === "Course"
@@ -134,7 +133,7 @@ export default function MasterDataPortal() {
}`}
>
Course
</button>
</Button>
</div>
</div>
</div>
@@ -200,18 +199,18 @@ export default function MasterDataPortal() {
<span className="flex items-center gap-1 text-[10px] font-mono font-bold text-emerald-400 uppercase tracking-wider">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400"></span> ACTIVE
</span>
<button className="text-[11px] text-slate-400 border border-slate-800 bg-slate-900/60 hover:bg-slate-800 px-2.5 py-1 rounded-md transition-colors">
<Button className="text-[11px] text-slate-400 border border-slate-800 bg-slate-900/60 hover:bg-slate-800 px-2.5 py-1 rounded-md transition-colors">
Remove
</button>
</Button>
</div>
</div>
))}
</div>
</div>
<button className="mt-6 flex items-center gap-1.5 text-xs font-bold text-emerald-400 hover:text-emerald-300 transition-colors w-fit">
<Button className="mt-6 flex items-center gap-1.5 text-xs font-bold text-emerald-400 hover:text-emerald-300 transition-colors w-fit">
<Plus className="w-3.5 h-3.5 stroke-[3]" />
<span>Add floor</span>
</button>
</Button>
</div>
{/* Zone Column */}
@@ -229,22 +228,23 @@ export default function MasterDataPortal() {
<span className="flex items-center gap-1 text-[10px] font-mono font-bold text-emerald-400 uppercase tracking-wider">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400"></span> ACTIVE
</span>
<button className="text-[11px] text-slate-400 border border-slate-800 bg-slate-900/60 hover:bg-slate-800 px-2.5 py-1 rounded-md transition-colors">
<Button className="text-[11px] text-slate-400 border border-slate-800 bg-slate-900/60 hover:bg-slate-800 px-2.5 py-1 rounded-md transition-colors">
Remove
</button>
</Button>
</div>
</div>
))}
</div>
</div>
<button className="mt-6 flex items-center gap-1.5 text-xs font-bold text-emerald-400 hover:text-emerald-300 transition-colors w-fit">
<Button className="mt-6 flex items-center gap-1.5 text-xs font-bold text-emerald-400 hover:text-emerald-300 transition-colors w-fit">
<Plus className="w-3.5 h-3.5 stroke-[3]" />
<span>Add zone</span>
</button>
</Button>
</div>
</div>
</div>
);
}

View File

@@ -3,61 +3,9 @@
import React, { useState } from "react";
import { Check } from "lucide-react";
import Button from "@/components/common/button";
import { initialPermissions, rolesList } from "@/constants/constant";
// Initial roles state
const rolesList = [
{ id: "admin", label: "Admin", badge: "all" },
{ id: "helpdesk", label: "Helpdesk", badge: "scoped" },
{ id: "mne_supervisor", label: "M&E Supervisor", badge: "scoped" },
{ id: "technician", label: "Technician", badge: "scoped" },
{ id: "tenant", label: "Tenant", badge: "scoped" },
];
// Initial permissions table data
const initialPermissions = [
{
id: 1,
module: "Help Desk",
menu: "Daily Location Checklist",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
{
id: 2,
module: "Equipment",
menu: "Site-Wise Equipment",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
{
id: 3,
module: "Equipment",
menu: "AMC Schedule",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
{
id: 4,
module: "Request",
menu: "TFM Request",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
{
id: 5,
module: "Energy",
menu: "Meter Reading",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
{
id: 6,
module: "Master",
menu: "Request Location",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
{
id: 7,
module: "Security",
menu: "Users",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
];
export default function RolesAccessPortal() {
const [activeTopTab, setActiveTopTab] = useState("Roles & Permissions");
@@ -68,16 +16,16 @@ export default function RolesAccessPortal() {
return (
<div className="my-15 text-slate-100 font-sans">
{/* --- BREADCRUMB --- */}
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-emerald-400 uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-emerald-400 uppercase font-mono">
<span>APPLE ONE HQ TOWER</span>
<span className="text-slate-600"></span>
<span className="text-slate-500">CONFIGURE</span>
<span className="text-slate-400">CONFIGURE</span>
<span className="text-slate-600"></span>
<span className="text-slate-500">ROLES & ACCESS</span>
<span className="text-slate-400">ROLES & ACCESS</span>
</div>
{/* --- PAGE HEADER --- */}
<h1 className="text-3xl font-bold text-white tracking-tight mt-1">
<h1 className="text-2xl font-bold text-white tracking-tight mt-1">
Roles & access
</h1>
<p className="text-sm font-medium text-slate-400 mt-2 max-w-2xl leading-relaxed">
@@ -88,7 +36,7 @@ export default function RolesAccessPortal() {
{/* --- MAIN TABS --- */}
<div className="flex items-center gap-8 border-b border-slate-800/80 mt-8 text-sm font-semibold">
{["Roles & Permissions", "Tenant Access", "Escalation Matrix"].map((tab) => (
<button
<Button
key={tab}
onClick={() => setActiveTopTab(tab)}
className={`pb-3 relative transition-colors ${
@@ -101,7 +49,7 @@ export default function RolesAccessPortal() {
{activeTopTab === tab && (
<span className="absolute bottom-0 left-0 right-0 h-0.5 bg-emerald-400 rounded-full" />
)}
</button>
</Button>
))}
</div>
@@ -112,7 +60,7 @@ export default function RolesAccessPortal() {
{rolesList.map((role) => {
const isSelected = selectedRole === role.id;
return (
<button
<Button
key={role.id}
onClick={() => setSelectedRole(role.id)}
className={`w-full flex items-center justify-between px-5 py-4 text-left transition-all relative ${
@@ -136,7 +84,7 @@ export default function RolesAccessPortal() {
>
{role.badge}
</span>
</button>
</Button>
);
})}
</div>
@@ -176,8 +124,8 @@ export default function RolesAccessPortal() {
const isChecked = row.permissions[permKey];
return (
<td key={permKey} className="py-4 px-4 text-center">
<button
type="button"
<Button
className={`w-5 h-5 rounded flex items-center justify-center transition-all border mx-auto ${
isChecked
@@ -186,7 +134,7 @@ export default function RolesAccessPortal() {
}`}
>
{isChecked && <Check className="w-3.5 h-3.5 stroke-[3]" />}
</button>
</Button>
</td>
);
}

View File

@@ -26,29 +26,23 @@ export default function SettingsPortal() {
return (
<div className="my-15 text-slate-200 font-sans">
{/* Top Header & Breadcrumb */}
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4 mb-6">
<div>
<div className="text-xs uppercase tracking-wider text-slate-400 mb-2 font-medium">
<span className="hover:text-slate-200 cursor-pointer">
APPLE ONE HQ TOWER
</span>{" "}
<span className="hover:text-slate-200 cursor-pointer">CONFIGURE</span>{" "}
<span className="text-slate-300">SETTINGS</span>
</div>
<h1 className="text-2xl font-bold text-white mb-1">Settings</h1>
<p className="text-slate-400 text-sm">
Personal and notification preferences for this tenant workspace.
</p>
</div>
{/* Save Changes Button */}
<div>
<button className="bg-[#2DD4BF] hover:bg-[#26b8a5] text-[#070D19] font-semibold text-sm px-5 py-2.5 rounded-lg transition-colors shadow-sm">
Save changes
</button>
</div>
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-emerald-400 uppercase font-mono">
<span>APPLE ONE HQ TOWER</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">CONFIGURE</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">SETTINGS</span>
</div>
{/* --- PAGE HEADER --- */}
<h1 className="text-2xl font-bold text-white tracking-tight mt-1">
Settings
</h1>
<p className="text-sm font-medium text-slate-400 mt-2 max-w-2xl leading-relaxed">
Personal and notification preferences for this tenant workspace.
</p>
{/* Main Grid Layout */}
<div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
{/* Left Column: App Settings */}
@@ -66,7 +60,7 @@ export default function SettingsPortal() {
<p className="text-xs text-slate-400">Workspace loaded on sign-in</p>
</div>
<select
value={appSettings.defaultTenant}
className="bg-[#080E21] border border-slate-700/80 text-slate-200 text-xs rounded-lg px-3 py-2 w-full sm:w-48 focus:outline-none focus:border-[#2DD4BF] cursor-pointer"
>

View File

@@ -1,71 +1,38 @@
"use client";
import Button from "@/components/common/button";
import { userData } from "@/constants/constant";
import React, { useState } from "react";
// Mock user location data matching the screenshot
const userData = [
{
name: "Dhananjay T.",
email: "dhananjay@kafm.io",
mobile: "7489477369",
latitude: "18.5450",
longitude: "73.7935",
site: "Apple One",
// Relative coordinates for the map visual dots (X%, Y%)
x: "19%",
y: "38%",
},
{
name: "ME Local",
email: "me.local@kafm.io",
mobile: "9876543210",
latitude: "18.5469",
longitude: "73.7945",
site: "Apple One",
x: "44%",
y: "43%",
},
{
name: "TECH Local",
email: "tech.local@kafm.io",
mobile: "9123456780",
latitude: "18.5441",
longitude: "73.7951",
site: "Apple One",
x: "69%",
y: "48%",
},
];
export default function UserLocationPortal() {
const [viewMode, setViewMode] = useState<"map" | "table">("table");
const [mapType, setMapType] = useState<"MAP" | "SATELLITE">("MAP");
return (
<div className="my-15 text-slate-200 font-sans">
<div className="my-15 min-h-screen h-full text-slate-200 font-sans">
{/* Top Breadcrumb & Header */}
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4 mb-6">
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
{/* Breadcrumb */}
<div className="text-xs uppercase tracking-wider text-slate-400 mb-2 font-medium">
<span className="hover:text-slate-200 cursor-pointer">
APPLE ONE HQ TOWER
</span>{" "}
<span className="hover:text-slate-200 cursor-pointer">CONFIGURE</span>{" "}
<span className="text-slate-300">USER LOCATION</span>
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest uppercase font-mono">
<span className="text-teal-400">APPLE ONE HQ TOWER</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">CONFIGURE</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">USER LOCATION</span>
</div>
{/* Main Title */}
<h1 className="text-3xl font-bold text-white mb-2">User location</h1>
<p className="text-slate-400 text-sm max-w-2xl leading-relaxed">
Live position of active technicians, captured from the mobile app. Map
and table views.
<h1 className="text-2xl font-bold text-white tracking-tight mt-2">
User location
</h1>
<p className="text-sm font-medium text-slate-400 mt-2 max-w-xl leading-relaxed">
Live position of active technicians, captured from the mobile app. Map and table views.
</p>
</div>
{/* View Switcher Buttons */}
<div className="flex bg-[#0F172A] p-1 rounded-lg border border-slate-800 self-start md:self-auto">
<button
<Button
onClick={() => setViewMode("map")}
className={`px-4 py-2 rounded-md text-sm font-medium transition-all ${
viewMode === "map"
@@ -74,8 +41,8 @@ export default function UserLocationPortal() {
}`}
>
Map view
</button>
<button
</Button>
<Button
onClick={() => setViewMode("table")}
className={`px-4 py-2 rounded-md text-sm font-medium transition-all ${
viewMode === "table"
@@ -84,7 +51,7 @@ export default function UserLocationPortal() {
}`}
>
Table view
</button>
</Button>
</div>
</div>
@@ -139,23 +106,23 @@ export default function UserLocationPortal() {
{/* Map Type Toggle (Bottom Right of Map Area) */}
<div className="absolute bottom-2 right-4 flex items-center space-x-2 text-[10px] font-mono tracking-wider text-slate-500">
<button
<Button
onClick={() => setMapType("MAP")}
className={`hover:text-slate-300 transition-colors ${
mapType === "MAP" ? "text-slate-300 font-bold" : ""
}`}
>
MAP
</button>
</Button>
<span></span>
<button
<Button
onClick={() => setMapType("SATELLITE")}
className={`hover:text-slate-300 transition-colors ${
mapType === "SATELLITE" ? "text-slate-300 font-bold" : ""
}`}
>
SATELLITE
</button>
</Button>
</div>
</div>

View File

@@ -19,12 +19,12 @@ export default function WorkFlowAutomationPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest uppercase font-mono">
<span className="text-teal-400">APPLE ONE HQ TOWER</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">CONFIGURE</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">AUTOMATION</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">CONFIGURE</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">AUTOMATION</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-2">
Workflow automation
@@ -113,9 +113,9 @@ export default function WorkFlowAutomationPortal() {
<span className="text-[10px] font-mono tracking-widest text-slate-400 uppercase">
WHEN
</span>
<button className="px-3.5 py-1.5 rounded-lg border border-[#2DD4BF]/40 text-[#2DD4BF] text-xs font-mono font-medium transition-colors">
<Button className="px-3.5 py-1.5 rounded-lg border border-[#2DD4BF]/40 text-[#2DD4BF] text-xs font-mono font-medium transition-colors">
Trigger event
</button>
</Button>
</div>
{/* IF Step */}
@@ -123,9 +123,9 @@ export default function WorkFlowAutomationPortal() {
<span className="text-[10px] font-mono tracking-widest text-slate-400 uppercase">
IF
</span>
<button className="px-3.5 py-1.5 rounded-lg border border-slate-700 text-slate-300 text-xs font-mono font-medium transition-colors">
<Button className="px-3.5 py-1.5 rounded-lg border border-slate-700 text-slate-300 text-xs font-mono font-medium transition-colors">
Condition
</button>
</Button>
</div>
{/* THEN Step */}
@@ -133,9 +133,9 @@ export default function WorkFlowAutomationPortal() {
<span className="text-[10px] font-mono tracking-widest text-slate-400 uppercase">
THEN
</span>
<button className="px-3.5 py-1.5 rounded-lg border border-[#2DD4BF]/30 text-[#2DD4BF] text-xs font-mono font-medium transition-colors">
<Button className="px-3.5 py-1.5 rounded-lg border border-[#2DD4BF]/30 text-[#2DD4BF] text-xs font-mono font-medium transition-colors">
Action
</button>
</Button>
</div>
</div>

View File

@@ -12,6 +12,9 @@ import StatCard from "@/components/common/dashStatCard";
import { Card } from '@/components/common/cardWrapper';
import { CardHeader } from '@/components/common/cardHeader';
import { approvalQueueData, categoryData } from "@/constants/constant";
import Table from "@/components/common/dataTable";
import { budgetPerformanceRows } from "@/constants/tabledata";
import { budgetPerformanceHeaders } from "@/constants/tabledata";
@@ -21,12 +24,12 @@ export default function BudgetPortal() {
{/* --- HEADER SECTION WITH BUTTONS --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<span className="text-teal-400">Apple One HQ Tower</span>
<span></span>
<span>FINANCE</span>
<span></span>
<span>O&M BUDGET</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">FINANCE</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">O&M BUDGET</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-2">
@@ -99,63 +102,23 @@ export default function BudgetPortal() {
</div>
{/* --- BUDGET DETAILS & APPROVAL QUEUE SECTION --- */}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8">
<div className="grid grid-cols-2 gap-3 mb-8">
{/* Planned vs Actual Table (Left 2 Columns) */}
<Card className="lg:col-span-2 justify-start">
<CardHeader
title="Planned vs actual · by category"
subtitle="CAPEX ₹35.0 L • OPEX ₹1.56 Cr"
/>
<div className="overflow-x-auto mt-2">
<table className="w-full text-left border-collapse">
<thead>
<tr className="border-b border-[#162942]/60 text-[11px] font-mono font-bold text-slate-500 uppercase tracking-wider">
<th className="py-2.5 px-2">Category</th>
<th className="py-2.5 px-2">Type</th>
<th className="py-2.5 px-2 font-mono">Planned</th>
<th className="py-2.5 px-2 font-mono">Actual</th>
<th className="py-2.5 px-2 font-mono">Variance</th>
<th className="py-2.5 px-2 font-mono min-w-[120px]">Utilization</th>
</tr>
</thead>
<tbody className="divide-y divide-[#162942]/40 text-xs">
{categoryData.map((row, idx) => (
<tr key={idx} className="hover:bg-slate-900/30 transition-colors">
<td className="py-3 px-2 font-semibold text-slate-100">
{row.category}
</td>
<td className="py-3 px-2">
<span className="bg-[#12233a] border border-[#1d3554] text-slate-300 font-mono text-[10px] px-2 py-0.5 rounded">
{row.type}
</span>
</td>
<td className="py-3 px-2 font-mono text-slate-300">
{row.planned}
</td>
<td className="py-3 px-2 font-mono text-slate-300">
{row.actual}
</td>
<td className={`py-3 px-2 font-mono font-semibold ${row.varianceColor}`}>
{row.variance}
</td>
<td className="py-3 px-2">
<div className="w-full bg-[#12233a] h-1.5 rounded-full overflow-hidden mb-1">
<div
className={`h-full ${row.barColor}`}
style={{ width: `${Math.min(row.utilization, 100)}%` }}
/>
</div>
<span className="text-[10px] font-mono text-slate-400">
{row.utilization}%
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
</Card>
<div className=" border border-slate-800/80 rounded-lg ">
<div className="flex items-center justify-between
px-4 py-4 border-b border-slate-800/80">
<h2 className="text-base font-semibold text-white">
Planned vs actual·by category</h2>
</div>
{/* Corrected column layout and removed horizontal scrollbar to align with the right UI. */}
<Table headers={budgetPerformanceHeaders} rows={budgetPerformanceRows} />
</div>
{/* Approval Queue Panel (Right 1 Column) */}
<Card className="justify-start">
@@ -174,9 +137,9 @@ export default function BudgetPortal() {
</div>
{item.status === "pending" ? (
<button className="bg-[#12233a] hover:bg-[#1a3252] border border-[#1d3554] text-slate-200 text-xs font-semibold px-3 py-1 rounded transition-colors whitespace-nowrap">
<Button className="bg-[#12233a] hover:bg-[#1a3252] border border-[#1d3554] text-slate-200 text-xs font-semibold px-3 py-1 rounded transition-colors whitespace-nowrap">
Approve
</button>
</Button>
) : (
<span className="flex items-center gap-1.5 bg-emerald-950/40 border border-emerald-800/30 text-emerald-400 text-[10px] font-mono font-bold px-2.5 py-1 rounded-full whitespace-nowrap">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400" />

View File

@@ -22,12 +22,12 @@ export default function CostInvoicePortal() {
{/* --- HEADER SECTION WITH BUTTONS --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<span className="text-teal-400">Apple One HQ Tower</span>
<span></span>
<span>FINANCE</span>
<span></span>
<span>COSTING & INVOICING</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">FINANCE</span>
<span className="text-gray-400"></span>
<span className="text-gray-400">COSTING & INVOICING</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-2">

View File

@@ -1,5 +1,5 @@
import { useState } from 'react';
import { Plus, Download } from 'lucide-react';
import Button from "@/components/common/button";
import NavigationTabs from '@/components/common/tabs';
import { reportFilters, reporttabs, Reqeusttabs, statusFilters } from '@/constants/constant';
@@ -22,12 +22,12 @@ export default function ReportPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<span className="text-teal-400">Apple One HQ Tower</span>
<span></span>
<span>INSIGHT</span>
<span></span>
<span>REPORTS</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">INSIGHT</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">REPORTS</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-2">
Reports & MMR
@@ -59,11 +59,11 @@ export default function ReportPortal() {
onChange={setActiveFilter}
/>
<button
<Button
className="inline-flex items-center gap-2 rounded-xl bg-teal-400 px-5 py-2.5 text-sm font-semibold text-slate-950 hover:bg-teal-300 transition-colors focus:outline-none focus:ring-2 focus:ring-teal-400/50 shrink-0"
>
Download
</button>
</Button>
</div>
<div className='mt-5'>

View File

@@ -22,12 +22,12 @@ export default function AlarmRulesPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-emerald-400 uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-emerald-400 uppercase font-mono">
<span>APPLE ONE HQ TOWER</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">IOT</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">ALARMS & RULES</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">IOT</span>
<span className="text-slate-600"></span>
<span className="text-slate-400">ALARMS & RULES</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-1">
Alarms & automation rules
@@ -237,8 +237,8 @@ export default function AlarmRulesPortal() {
Raises a Help Desk request with the asset and fault pre-filled
</p>
</div>
<button
type="button"
<Button
onClick={() => setAutoWorkOrder(!autoWorkOrder)}
className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none ${
autoWorkOrder ? 'bg-[#2dd4bf]' : 'bg-slate-700'
@@ -249,7 +249,7 @@ export default function AlarmRulesPortal() {
autoWorkOrder ? 'translate-x-5' : 'translate-x-0'
}`}
/>
</button>
</Button>
</div>
{/* Rule 2 */}
@@ -262,8 +262,8 @@ export default function AlarmRulesPortal() {
Notifies the escalation matrix after 15 minutes
</p>
</div>
<button
type="button"
<Button
onClick={() => setEscalateCriticals(!escalateCriticals)}
className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none ${
escalateCriticals ? 'bg-[#2dd4bf]' : 'bg-slate-700'
@@ -274,7 +274,7 @@ export default function AlarmRulesPortal() {
escalateCriticals ? 'translate-x-5' : 'translate-x-0'
}`}
/>
</button>
</Button>
</div>
{/* Rule 3 */}
@@ -287,8 +287,8 @@ export default function AlarmRulesPortal() {
Widens comfort bands 22:0006:00 to save energy
</p>
</div>
<button
type="button"
<Button
onClick={() => setOffHoursSetpoint(!offHoursSetpoint)}
className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none ${
offHoursSetpoint ? 'bg-[#2dd4bf]' : 'bg-slate-700'
@@ -299,7 +299,7 @@ export default function AlarmRulesPortal() {
offHoursSetpoint ? 'translate-x-5' : 'translate-x-0'
}`}
/>
</button>
</Button>
</div>
{/* Rule 4 */}
@@ -312,8 +312,8 @@ export default function AlarmRulesPortal() {
Adds a filter change to the next PPM visit automatically
</p>
</div>
<button
type="button"
<Button
onClick={() => setFilterPpmTask(!filterPpmTask)}
className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none ${
filterPpmTask ? 'bg-[#2dd4bf]' : 'bg-slate-800'
@@ -324,7 +324,7 @@ export default function AlarmRulesPortal() {
filterPpmTask ? 'translate-x-5 bg-slate-950' : 'translate-x-0'
}`}
/>
</button>
</Button>
</div>
</div>
</div>

View File

@@ -14,17 +14,17 @@ export default function CommandCenterPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[11px] font-semibold tracking-widest text-[#4e6178] uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-semibold tracking-widest text-[#4e6178] uppercase font-mono">
<span className="text-emerald-400 font-bold">APPLE ONE HQ TOWER</span>
<span></span>
<span>IOT</span>
<span></span>
<span>COMMAND CENTER</span>
<span className='text-gray-600'></span>
<span className='text-gray-400'>IOT</span>
<span className='text-gray-600'></span>
<span className='text-gray-400'>COMMAND CENTER</span>
</div>
<h1 className="text-3xl font-bold text-white tracking-tight mt-1">
IoT command center
</h1>
<p className="text-sm text-[#7f93ac] mt-2 max-w-xl leading-relaxed">
<p className="text-sm text-[#7f93ac] font-medium mt-2 max-w-xl leading-relaxed">
Every gateway, controller and sensor across the portfolio on one live board scoped to Apple One.
</p>
</div>
@@ -192,9 +192,9 @@ export default function CommandCenterPortal() {
<div>
<div className="flex justify-between items-center mb-1">
<h3 className="font-semibold text-white text-base">Live alarm feed</h3>
<button className="text-xs text-[#10b981] font-semibold hover:underline">
<Button className="text-xs text-[#10b981] font-semibold hover:underline">
All alarms
</button>
</Button>
</div>
<p className="text-[11px] text-[#4e6178] font-mono mb-4">streaming</p>

View File

@@ -1,17 +1,17 @@
import { useState } from 'react';
import {
Grid2X2,
AlertTriangle,
Sun,
Disc,
Smartphone,
FileText
} from "lucide-react";
import Button from "@/components/common/button";
import StatCard from "@/components/common/dashStatCard";
import InfoBanner from "@/components/common/infoBanner";
import Table from '@/components/common/dataTable';
import { contractheaders, contractrows, devicefleetheaders, devicefleetrows } from '@/constants/tabledata';
import { devicefleetheaders, devicefleetrows } from '@/constants/tabledata';
export default function DeviceFleetPortal() {
return (
@@ -19,12 +19,12 @@ export default function DeviceFleetPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-emerald-400 uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-emerald-400 uppercase font-mono">
<span>APPLE ONE HQ TOWER</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">IOT</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">DEVICE FLEET</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">IOT</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">DEVICE FLEET</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-1">
Gateways, controllers & sensors

View File

@@ -13,17 +13,17 @@ export default function EnergyUtilityPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[11px] font-semibold tracking-widest text-[#4e6178] uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-semibold tracking-widest text-[#4e6178] uppercase font-mono">
<span className="text-emerald-400 font-bold">APPLE ONE HQ TOWER</span>
<span></span>
<span>IOT</span>
<span></span>
<span>ENERGY & UTILITIES</span>
<span className='text-gray-600'></span>
<span className='text-gray-400'>IOT</span>
<span className='text-gray-600'></span>
<span className='text-gray-400'>ENERGY & UTILITIES</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-1">
Energy & utilities telemetry
</h1>
<p className="text-sm text-[#7f93ac] mt-2 max-w-xl leading-relaxed">
<p className="text-sm text-[#7f93ac] font-medium mt-2 max-w-xl leading-relaxed">
Live smart-meter streams for power, water and gas the same spine that feeds the Energy module and ESG reporting.
</p>
</div>

View File

@@ -4,22 +4,9 @@ import Button from "@/components/common/button";
import { Card } from '@/components/common/cardWrapper';
import BarChart from "@/components/charts/barchart"; // Replace path with your actual BarChart component import path
import { plantLoadData } from '@/constants/constant';
const plantLoadData = [
{ month: '08', height: 'h-[35%]' },
{ month: '09', height: 'h-[38%]' },
{ month: '10', height: 'h-[32%]' },
{ month: '11', height: 'h-[40%]' },
{ month: '12', height: 'h-[52%]' },
{ month: '13', height: 'h-[68%]' },
{ month: '14', height: 'h-[78%]' },
{ month: '15', height: 'h-[78%]' },
{ month: '16', height: 'h-[78%]' },
{ month: '17', height: 'h-[78%]' },
{ month: '18', height: 'h-[78%]' },
{ month: '19', height: 'h-[78%]' }
];
export default function HVACPlantPortal() {
return (
<div className="my-15 text-slate-100 font-sans">
@@ -27,17 +14,17 @@ export default function HVACPlantPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[11px] font-semibold tracking-widest text-[#4e6178] uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-semibold tracking-widest text-[#4e6178] uppercase font-mono">
<span className="text-emerald-400 font-bold">APPLE ONE HQ TOWER</span>
<span></span>
<span>IOT</span>
<span></span>
<span>HVAC PLANT</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">IOT</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">HVAC PLANT</span>
</div>
<h1 className="text-3xl font-bold text-white tracking-tight mt-1">
Chiller plant & air side
</h1>
<p className="text-sm text-[#7f93ac] mt-2 max-w-xl leading-relaxed">
<p className="text-sm text-[#7f93ac] font-medium mt-2 max-w-xl leading-relaxed">
Live chiller, AHU and plant telemetry with start/stop control commands are audit-logged.
</p>
</div>
@@ -221,9 +208,9 @@ export default function HVACPlantPortal() {
<td className="py-3.5 text-slate-500"> / </td>
<td className="py-3.5 text-slate-400">0</td>
<td className="py-3.5 text-right">
<button className="px-3 py-1 rounded border border-[#162942] text-slate-300 bg-[#0e1c2e] hover:bg-slate-800 text-[11px] font-semibold transition-colors">
<Button className="px-3 py-1 rounded border border-[#162942] text-slate-300 bg-[#0e1c2e] hover:bg-slate-800 text-[11px] font-semibold transition-colors">
Start
</button>
</Button>
</td>
</tr>
</tbody>

View File

@@ -42,17 +42,35 @@ export default function EnergyPortal() {
</div>
{/* --- TABLES GRID (SIDE-BY-SIDE) --- */}
<div className="grid grid-cols-1 xl:grid-cols-2 gap-2 items-start">
<div className="grid grid-cols-1 xl:grid-cols-2 gap-6 items-start">
{/* LEFT TABLE: METER MASTER */}
<Table headers={meterHeaders} rows={meterRows}/>
{/* Right table */}
<Table headers={readingHeaders} rows={readingRows}/>
</div>
{/* LEFT TABLE: STOCK MASTER */}
<div className=" border border-slate-800/80 rounded-lg ">
<div className="flex items-center justify-between px-4
py-4 border-b border-slate-800/80">
<h2 className="text-base font-semibold text-white">Meter Master</h2>
</div>
{/* Corrected column layout and removed horizontal scrollbar to align with the right UI. */}
<Table headers={meterHeaders} rows={meterRows}/>
</div>
{/* RIGHT TABLE: CONSUMPTION LEDGER */}
<div className=" w-full border
border-slate-800/80 rounded-lg overflow-hidden">
<div className="flex items-center justify-between px-6 py-4 border-b border-slate-800/80">
<h2 className="text-base font-semibold text-white">Latest Readings</h2>
</div>
<Table headers={readingHeaders} rows={readingRows}/>
</div>
</div>
</div>
);
}
}

View File

@@ -9,7 +9,8 @@ import {
import Button from "@/components/common/button";
import StatCard from "@/components/common/dashStatCard";
import InfoBanner from "@/components/common/infoBanner";
import { consumptionLedger, stockItems } from "@/constants/constant";
import Table from "@/components/common/dataTable";
import { consumptionHeaders, consumptionRows, inventoryHeaders, inventoryRows, } from "@/constants/tabledata";
@@ -104,87 +105,19 @@ export default function InventoryPortal() {
<div className="grid grid-cols-1 xl:grid-cols-2 gap-6 items-start">
{/* LEFT TABLE: STOCK MASTER */}
<div className="bg-[#0b1329] border border-slate-800/80 rounded-lg overflow-hidden">
<div className="flex items-center justify-between px-6 py-4 border-b border-slate-800/80">
<div className=" border border-slate-800/80 rounded-lg ">
<div className="flex items-center justify-between px-4
py-4 border-b border-slate-800/80">
<h2 className="text-base font-semibold text-white">Stock master</h2>
<span className="text-xs font-mono text-slate-500">7 items</span>
</div>
{/* Corrected column layout and removed horizontal scrollbar to align with the right UI. */}
<div className="">
<table className="w-full h-full text-left text-sm">
<thead>
<tr className="border-b border-slate-800/60 text-[11px] font-bold uppercase tracking-wider text-slate-400">
<th className="py-3 px-4">Item</th>
<th className="py-3 px-4">Group</th>
<th className="py-3 px-4">Store</th>
<th className="py-3 px-4">Min</th>
<th className="py-3 px-4">Present</th>
<th className="py-3 px-4">Status</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-800/40">
{stockItems.map((row, index) => {
const isOverdue = row.status === "OVERDUE";
return (
<tr
key={index}
className={`transition-colors relative ${
row.isHighlighted
? "bg-[#0e2238]"
: "hover:bg-slate-800/30"
}`}
>
<td className="py-3 px-4 font-semibold text-slate-100 relative">
{row.isHighlighted && (
<div className="absolute left-0 top-0 bottom-0 w-[3px] bg-teal-400" />
)}
{row.item}
</td>
<td className="py-3 px-4 text-slate-300 font-medium whitespace-nowrap">
{row.group}
</td>
<td className="py-3 px-4 text-slate-300 font-medium whitespace-nowrap">
{row.store}
</td>
<td className="py-3 px-4 text-slate-300 font-medium whitespace-nowrap">
{row.min}
</td>
<td className="py-3 px-4 font-semibold whitespace-nowrap">
<span className={isOverdue ? "text-rose-400" : "text-white"}>
{row.presentValue}{" "}
</span>
<span
className={`font-mono text-xs ${
isOverdue ? "text-rose-400" : "text-slate-300"
}`}
>
{row.unit}
</span>
</td>
<td className="py-3 px-4">
{row.status === "COMPLETED" ? (
<span className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[10px] font-bold tracking-wider bg-emerald-950/60 text-emerald-400 border border-emerald-800/30">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400"></span>
COMPLETED
</span>
) : (
<span className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[10px] font-bold tracking-wider bg-rose-950/40 text-rose-400 border border-rose-900/30">
<span className="w-1.5 h-1.5 rounded-full bg-rose-400"></span>
OVERDUE
</span>
)}
</td>
</tr>
);
})}
</tbody>
</table>
</div>
<Table headers={inventoryHeaders} rows={inventoryRows} />
</div>
{/* RIGHT TABLE: CONSUMPTION LEDGER */}
<div className="bg-[#0b1329] border border-slate-800/80 rounded-lg overflow-hidden">
<div className="h-full w-full border border-slate-800/80 rounded-lg overflow-hidden">
<div className="flex items-center justify-between px-6 py-4 border-b border-slate-800/80">
<h2 className="text-base font-semibold text-white">Consumption ledger</h2>
<span className="text-xs font-mono text-slate-500 lowercase">
@@ -192,54 +125,7 @@ export default function InventoryPortal() {
</span>
</div>
<div>
<table className="w-full h-full text-left text-sm">
<thead>
<tr className="border-b border-slate-800/60 text-[11px] font-bold uppercase tracking-wider text-slate-400">
<th className="py-3 px-4">Txn</th>
<th className="py-3 px-4">Item</th>
<th className="py-3 px-4">Type</th>
<th className="py-3 px-4">Qty</th>
<th className="py-3 px-4">Job Card</th>
<th className="py-3 px-4">Date</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-800/40">
{consumptionLedger.map((row, index) => (
<tr key={index} className="hover:bg-slate-800/30 transition-colors">
<td className="py-3 px-4 font-mono text-teal-400 font-medium text-xs whitespace-nowrap">
{row.txn}
</td>
<td className="py-3 px-4 font-semibold text-slate-100 max-w-[140px]">
{row.item}
</td>
<td className="py-3 px-4 whitespace-nowrap">
{row.type === "Consume" ? (
<span className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium bg-amber-950/40 text-amber-300 border border-amber-800/30">
<span className="w-1.5 h-1.5 rounded-full bg-amber-400"></span>
Consume
</span>
) : (
<span className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-950/40 text-blue-300 border border-blue-800/30">
<span className="w-1.5 h-1.5 rounded-full bg-blue-400"></span>
Receipt
</span>
)}
</td>
<td className="py-3 px-4 font-medium text-slate-200 whitespace-nowrap">
{row.qty}
</td>
<td className="py-3 px-4 font-mono text-teal-400 text-xs whitespace-nowrap">
{row.jobCard}
</td>
<td className="py-3 px-4 text-slate-300 text-xs font-medium whitespace-nowrap">
{row.date}
</td>
</tr>
))}
</tbody>
</table>
</div>
<Table headers={consumptionHeaders} rows={consumptionRows} />
</div>
</div>

View File

@@ -1,16 +1,18 @@
import { useState } from 'react';
import {
Star,
ShieldCheck,
Activity,
Clock,
BarChart2,
Plus
Plus,
} from "lucide-react";
import Button from "@/components/common/button";
import StatCard from "@/components/common/dashStatCard";
import InfoBanner from "@/components/common/infoBanner";
import { fieldCrewData, vendorData } from '@/constants/constant';
import Table from "@/components/common/dataTable";
import { teamStatusRows, teamStatusHeaders, vendorPerformanceHeaders, vendorPerformanceRows } from "@/constants/tabledata";
export default function VendorServicePortal() {
@@ -99,111 +101,23 @@ export default function VendorServicePortal() {
<div className="grid grid-cols-1 xl:grid-cols-3 gap-6 items-start">
{/* LEFT TABLE: VENDOR SCORECARD */}
<div className="xl:col-span-2 bg-[#0b1329] border border-slate-800/80 rounded-lg overflow-hidden">
<div className="xl:col-span-2 border border-slate-800/80 rounded-lg overflow-hidden">
<div className="flex items-center justify-between px-6 py-4 border-b border-slate-800/80">
<h2 className="text-base font-semibold text-white">Vendor scorecard</h2>
<span className="text-xs font-mono text-slate-500 lowercase">
SLA rating jobs
</span>
</div>
<div className="overflow-x-auto">
<table className="w-full text-left text-sm">
<thead>
<tr className="border-b border-slate-800/60 text-[11px] font-bold uppercase tracking-wider text-slate-400">
<th className="py-3 px-6">Vendor</th>
<th className="py-3 px-4">Scope</th>
<th className="py-3 px-4">Rating</th>
<th className="py-3 px-4">SLA</th>
<th className="py-3 px-4">Response</th>
<th className="py-3 px-6">Open</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-800/40">
{vendorData.map((row, index) => (
<tr key={index} className="hover:bg-slate-800/30 transition-colors">
<td className="py-4 px-6">
<div className="font-semibold text-slate-100">{row.name}</div>
<div className="text-xs font-mono text-slate-500 mt-0.5">{row.id}</div>
</td>
<td className="py-4 px-4 text-slate-300 font-medium whitespace-nowrap">
{row.scope}
</td>
<td className="py-4 px-4 font-medium text-slate-200 whitespace-nowrap">
<div className="flex items-center gap-1">
<span>{row.rating}</span>
<Star className="w-3.5 h-3.5 fill-amber-400 text-amber-400" />
</div>
</td>
<td className={`py-4 px-4 font-semibold whitespace-nowrap ${row.slaColor}`}>
{row.sla}
</td>
<td className="py-4 px-4 text-slate-300 font-medium whitespace-nowrap">
{row.response}
</td>
<td className="py-4 px-6 font-semibold text-blue-400 whitespace-nowrap">
{row.openJobs}
</td>
</tr>
))}
</tbody>
</table>
</div>
<Table headers={vendorPerformanceHeaders} rows={vendorPerformanceRows} />
</div>
{/* RIGHT TABLE: FIELD CREW • LIVE */}
<div className="bg-[#0b1329] border border-slate-800/80 rounded-lg overflow-hidden">
<div className=" border border-slate-800/80 rounded-lg overflow-hidden">
<div className="flex items-center justify-between px-6 py-4 border-b border-slate-800/80">
<h2 className="text-base font-semibold text-white">Field crew live</h2>
<span className="text-xs font-mono text-slate-500 lowercase">
4 on site
</span>
</div>
<div className="p-4 space-y-3">
{fieldCrewData.map((crew, index) => {
return (
<div
key={index}
className="flex items-center justify-between p-3 rounded-lg bg-[#0d1835]/50 hover:bg-slate-800/30 transition-colors border border-slate-800/40"
>
<div className="flex items-center gap-3">
<div className="w-9 h-9 rounded-lg bg-teal-950/60 border border-teal-800/30 text-teal-400 text-xs font-bold flex items-center justify-center shrink-0">
{crew.initials}
</div>
<div>
<div className="font-semibold text-slate-100 text-sm">{crew.name}</div>
<div className="text-xs text-slate-400 mt-0.5">{crew.role}</div>
</div>
</div>
<div className="text-right shrink-0">
{crew.statusType === "onsite" && (
<span className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-[10px] font-bold tracking-wider bg-emerald-950/60 text-emerald-400 border border-emerald-800/30">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400"></span>
{crew.status}
</span>
)}
{crew.statusType === "enroute" && (
<span className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-[10px] font-bold tracking-wider bg-amber-950/60 text-amber-400 border border-amber-800/30">
<span className="w-1.5 h-1.5 rounded-full bg-amber-400"></span>
{crew.status}
</span>
)}
{crew.statusType === "offsite" && (
<span className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-[10px] font-bold tracking-wider bg-slate-800/80 text-slate-400 border border-slate-700/50">
<span className="w-1.5 h-1.5 rounded-full bg-slate-500"></span>
{crew.status}
</span>
)}
<div className="text-[11px] font-mono text-slate-500 mt-1">
{crew.time}
</div>
</div>
</div>
);
})}
</div>
<Table headers={teamStatusHeaders} rows={teamStatusRows} />
</div>
</div>

View File

@@ -5,6 +5,8 @@ import { permitsData, workPermitFilters } from '@/constants/constant';
import FilterTabs from '@/components/common/roundedFilters';
import StatCard from '@/components/common/dashStatCard';
import InfoBanner from '@/components/common/infoBanner';
import Table from '@/components/common/dataTable';
import { workPermitHeaders, workPermitRows } from '@/constants/tabledata';
export default function WorkPermitPortal() {
@@ -13,61 +15,7 @@ export default function WorkPermitPortal() {
// Permit Data matching the UI
const renderStatusBadge = (status: string) => {
switch (status) {
case "ACTIVE":
return (
<span className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-[10px] font-bold tracking-wider bg-emerald-950/60 text-emerald-400 border border-emerald-800/40">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400"></span>
ACTIVE
</span>
);
case "SUBMITTED":
return (
<span className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-[10px] font-bold tracking-wider bg-amber-950/50 text-amber-300 border border-amber-800/40">
<span className="w-1.5 h-1.5 rounded-full bg-amber-400"></span>
SUBMITTED
</span>
);
case "APPROVED":
return (
<span className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-[10px] font-bold tracking-wider bg-blue-950/60 text-blue-400 border border-blue-800/40">
<span className="w-1.5 h-1.5 rounded-full bg-blue-400"></span>
APPROVED
</span>
);
case "EXPIRED":
return (
<span className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-[10px] font-bold tracking-wider bg-rose-950/40 text-rose-400 border border-rose-900/30">
<span className="w-1.5 h-1.5 rounded-full bg-rose-400"></span>
EXPIRED
</span>
);
case "CLOSED":
return (
<span className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-[10px] font-bold tracking-wider bg-slate-800/80 text-slate-400 border border-slate-700/50">
<span className="w-1.5 h-1.5 rounded-full bg-slate-400"></span>
CLOSED
</span>
);
case "REJECTED":
return (
<span className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-[10px] font-bold tracking-wider bg-rose-950/40 text-rose-400 border border-rose-900/30">
<span className="w-1.5 h-1.5 rounded-full bg-rose-400"></span>
REJECTED
</span>
);
case "DRAFT":
return (
<span className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-[10px] font-bold tracking-wider bg-slate-800/80 text-slate-400 border border-slate-700/50">
<span className="w-1.5 h-1.5 rounded-full bg-slate-400"></span>
DRAFT
</span>
);
default:
return null;
}
};
return (
<div className="my-15 text-slate-100 font-sans">
@@ -103,10 +51,7 @@ export default function WorkPermitPortal() {
</div>
</div>
{/* --- NAVIGATION TABS & TOP ACTION BUTTONS --- */}
<div className="flex flex-col md:flex-row md:items-center justify-between border-b border-slate-800/80 mb-6 gap-4">
{/* Navigation tabs component if needed */}
</div>
{/* --- STAT CARDS --- */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
@@ -166,94 +111,7 @@ export default function WorkPermitPortal() {
{/* --- PERMIT TABLE SECTION --- */}
<div className="bg-[#0b1329] border border-slate-800/80 rounded-lg overflow-x-auto">
<table className="w-full text-left text-sm">
<thead>
<tr className="border-b border-slate-800/80 text-[11px] font-bold uppercase tracking-wider text-slate-400">
<th className="py-3 px-4">Permit</th>
<th className="py-3 px-4">Working Type</th>
<th className="py-3 px-4">Location</th>
<th className="py-3 px-4">Contractor</th>
<th className="py-3 px-4">Validity</th>
<th className="py-3 px-4">Crew</th>
<th className="py-3 px-4">Status</th>
<th className="py-3 px-4 text-right"></th>
</tr>
</thead>
<tbody className="divide-y divide-slate-800/40">
{permitsData.map((row, index) => (
<tr
key={index}
className={`transition-colors relative ${
row.isHighlighted ? "bg-[#0e2238]" : "hover:bg-slate-800/30"
}`}
>
{/* Permit ID */}
<td className="py-4 px-4 font-mono text-teal-400 font-medium text-xs whitespace-nowrap relative">
{row.isHighlighted && (
<div className="absolute left-0 top-0 bottom-0 w-[3px] bg-teal-400" />
)}
{row.permit}
</td>
{/* Working Type */}
<td className="py-4 px-4 font-semibold text-slate-100 whitespace-nowrap">
{row.workingType}
</td>
{/* Location */}
<td className="py-4 px-4 text-slate-300 font-medium whitespace-nowrap">
{row.location}
</td>
{/* Contractor */}
<td className="py-4 px-4 text-slate-300 font-medium whitespace-nowrap">
{row.contractor}
</td>
{/* Validity */}
<td className="py-4 px-4 whitespace-nowrap">
<div className="text-xs text-slate-300 font-medium">{row.validityDate}</div>
<div className="text-[11px] font-mono text-slate-500">{row.validityTime}</div>
</td>
{/* Crew */}
<td className="py-4 px-4 text-slate-300 font-medium whitespace-nowrap">
{row.crew}
</td>
{/* Status Badge */}
<td className="py-4 px-4 whitespace-nowrap">
{renderStatusBadge(row.status)}
</td>
{/* Actions */}
<td className="py-4 px-4 text-right whitespace-nowrap">
<div className="flex items-center justify-end gap-2">
{row.hasViewIconOnly ? (
<div className="flex flex-col gap-1">
<button className="p-1.5 text-slate-400 hover:text-white bg-slate-800/40 hover:bg-slate-800 rounded border border-slate-700/50 transition-colors">
<FileText size={14} />
</button>
<button className="p-1.5 text-slate-400 hover:text-white bg-slate-800/40 hover:bg-slate-800 rounded border border-slate-700/50 transition-colors">
<Eye size={14} />
</button>
</div>
) : (
<div className="flex flex-col items-center gap-1">
<button className="p-1.5 text-slate-400 hover:text-white bg-slate-800/40 hover:bg-slate-800 rounded border border-slate-700/50 transition-colors">
<FileText size={14} />
</button>
<button className="text-teal-400 hover:text-teal-300 text-xs font-semibold hover:underline">
{row.actionText}
</button>
</div>
)}
</div>
</td>
</tr>
))}
</tbody>
</table>
<Table headers={workPermitHeaders} rows={workPermitRows}/>
</div>
<div className="mb-10 mt-10">

View File

@@ -3,12 +3,13 @@ import { Check } from 'lucide-react';
import BarChart from "@/components/charts/barchart";
import StatCard from "@/components/common/dashStatCard";
import ActivityFeed from "@/components/dashboard/overview/activityFeed";
import {activities, chartData, schedulePerformanceHeaders, schedulePerformanceRows} from "@/constants/constant"
import {activities, chartData} from "@/constants/constant"
import { Card } from '@/components/common/cardWrapper';
import {CardHeader} from '@/components/common/cardHeader';
import {ProgressBarRow }from '@/components/charts/progressBarRow';
import {StatusProgressRow} from '@/components/charts/statusProgressRow';
import Table from '@/components/common/dataTable';
import { schedulePerformanceHeaders, schedulePerformanceRows } from '@/constants/tabledata';
export default function Dashboard() {

View File

@@ -22,12 +22,12 @@ export default function MeetingRoomPortal() {
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<span className="text-teal-400">Apple One HQ Tower</span>
<span></span>
<span>WORKPLACE</span>
<span></span>
<span>MEETING ROOMS</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">WORKPLACE</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">MEETING ROOMS</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-1">
Meeting room booking
@@ -136,15 +136,15 @@ export default function MeetingRoomPortal() {
<div className="flex items-center justify-between border-t border-[#162942]/60 pt-3 mt-2">
<span className="text-xs text-slate-400">{room.subtitle}</span>
<div className="flex items-center gap-1.5">
<button className="bg-[#12233a] hover:bg-[#1a3252] border border-[#1d3554] text-slate-200 text-xs font-semibold px-3 py-1.5 rounded transition-colors">
<Button className="bg-[#12233a] hover:bg-[#1a3252] border border-[#1d3554] text-slate-200 text-xs font-semibold px-3 py-1.5 rounded transition-colors">
{room.actionType === "book" ? "Book" : "View"}
</button>
<button className="bg-[#12233a] hover:bg-[#1a3252] border border-[#1d3554] text-slate-400 hover:text-slate-200 p-1.5 rounded transition-colors">
</Button>
<Button className="bg-[#12233a] hover:bg-[#1a3252] border border-[#1d3554] text-slate-400 hover:text-slate-200 p-1.5 rounded transition-colors">
<Pencil className="w-3.5 h-3.5" />
</button>
<button className="bg-[#12233a] hover:bg-[#1a3252] border border-[#1d3554] text-slate-400 hover:text-rose-400 p-1.5 rounded transition-colors">
</Button>
<Button className="bg-[#12233a] hover:bg-[#1a3252] border border-[#1d3554] text-slate-400 hover:text-rose-400 p-1.5 rounded transition-colors">
<Trash2 className="w-3.5 h-3.5" />
</button>
</Button>
</div>
</div>
</Card>

View File

@@ -23,12 +23,12 @@ const [activeFilter, setActiveFilter] = useState<string>('All');
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<span className="text-teal-400">Apple One HQ Tower</span>
<span></span>
<span>Workplace</span>
<span></span>
<span>Visitors</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">Workplace</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">Visitors</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-2">
Visitor management

View File

@@ -22,8 +22,7 @@ import { CardHeader } from '@/components/common/cardHeader';
export default function WorkSpacePortal() {
const [activeTab, setActiveTab] = useState<string>("Desk Booking");
// Grid state matching the UI: 4 rows x 12 columns (48 seats)
// Types: 'occupied' (red/purple outline), 'free' (teal), 'reserved' (amber)
const deskGrid = Array.from({ length: 48 }).map((_, index) => {
if (index === 42) return "reserved"; // 1 Reserved desk
if (index >= 36) return "free"; // Free desks on the bottom row
@@ -35,12 +34,12 @@ export default function WorkSpacePortal() {
{/* --- HEADER SECTION WITH BUTTONS --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<div className="flex items-center gap-2 text-[12px] font-bold tracking-widest text-slate-500 uppercase font-mono">
<span className="text-teal-400">Apple One HQ Tower</span>
<span></span>
<span>WORKPLACE</span>
<span></span>
<span>WORKSPACE</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">WORKPLACE</span>
<span className="text-gray-600"></span>
<span className="text-gray-400">WORKSPACE</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-2">
@@ -192,12 +191,12 @@ export default function WorkSpacePortal() {
{/* Value & Actions */}
<div className="flex items-center gap-2 font-mono text-xs text-slate-200">
<span className="font-bold">{zone.current}/{zone.max}</span>
<button className="bg-[#12233a] hover:bg-[#1a3252] border border-[#1d3554] text-slate-400 hover:text-slate-200 p-1 rounded transition-colors">
<Button className="bg-[#12233a] hover:bg-[#1a3252] border border-[#1d3554] text-slate-400 hover:text-slate-200 p-1 rounded transition-colors">
<Pencil className="w-3 h-3" />
</button>
<button className="bg-[#12233a] hover:bg-[#1a3252] border border-[#1d3554] text-slate-400 hover:text-rose-400 p-1 rounded transition-colors">
</Button>
<Button className="bg-[#12233a] hover:bg-[#1a3252] border border-[#1d3554] text-slate-400 hover:text-rose-400 p-1 rounded transition-colors">
<Trash2 className="w-3 h-3" />
</button>
</Button>
</div>
</div>
);

View File

@@ -1,6 +1,6 @@
"use client";
import { OPERATIONS_SIDEBAR_ITEMS, ADMIN_SIDEBAR_ITEMS } from "@/constants/constant";
import { OPERATIONS_SIDEBAR_ITEMS, ADMIN_SIDEBAR_ITEMS } from "@/constants/sidebarConstant";
import SidebarItem from "./sideBarItem";
import { ShieldCheck, Activity, ChevronDown, ChevronsLeft } from "lucide-react";
import { useSession, signOut } from "next-auth/react";

View File

@@ -1,178 +1,6 @@
import {
LayoutGrid,
Smile,
Building2,
User,
Target,
CheckSquare,
FileText,
Box,
Zap,
ClipboardList,
Star,
Monitor,
UserCheck,
Calendar,
Layers,
Coins,
Receipt,
ShieldCheck,
Flame,
Recycle,
GraduationCap,
Brain,
Activity,
Bot,
Gauge,
Snowflake,
Leaf,
MapPin,
BarChart3,
Sun,
Shield,
Settings,
Wallet,
Radar,
Cog,
Smartphone,
Users,
Database,
Globe,
LayoutDashboard,
} from "lucide-react";
//Side bar Drop Down menu
export const OPERATIONS_SIDEBAR_ITEMS = [
{
title: "Overview",
icon: LayoutGrid,
children: [
{ title: "Dashboard", href: "/dashboard/overview/dashboard", icon: LayoutGrid },
{ title: "Engagement", href: "/dashboard/overview/engagement", icon: Smile },
{ title: "Building Owner", href: "/dashboard/overview/buildingOwner", icon: Building2 },
{ title: "Property Manager", href: "/dashboard/overview/propertyManager", icon: User },
{ title: "Service Engineer", href: "/dashboard/overview/serviceEngineer", icon: Target },
],
},
{
title: "Operations",
icon: Settings,
children: [
{ title: "Help Desk", href: "/dashboard/operations/helpDesk", icon: CheckSquare, badge: 6, badgeColor: "bg-amber-500 text-black" },
{ title: "Equipment", href: "/dashboard/operations/equipment", icon: Target },
{ title: "Requests", href: "/dashboard/operations/request", icon: FileText, badge: 15, badgeColor: "bg-amber-400 text-black" },
{ title: "Inventory", href: "/dashboard/operations/inventory", icon: Box },
{ title: "Energy", href: "/dashboard/operations/energy", icon: Zap },
{ title: "Work Permit", href: "/dashboard/operations/workPermit", icon: ClipboardList, badge: 3, badgeColor: "bg-amber-500 text-black" },
{ title: "Vendor & Field Service", href: "/dashboard/operations/vendorFieldService", icon: Star, badge: 12, badgeColor: "bg-sky-400 text-black" },
],
},
{
title: "Workplace",
icon: Monitor,
children: [
{ title: "Visitor Management", href: "/dashboard/workplace/visitorManagement", icon: UserCheck },
{ title: "Meeting Rooms", href: "/dashboard/workplace/meetingRoom", icon: Calendar },
{ title: "Workspace", href: "/dashboard/workplace/workspace", icon: Layers },
],
},
{
title: "Finance",
icon: Wallet,
children: [
{ title: "O&M Budget", href: "/dashboard/finance/budget", icon: Coins },
{ title: "Costing & Invoicing", href: "/dashboard/finance/costinvoice", icon: Receipt },
],
},
{
title: "Compliance & Safety",
icon: ShieldCheck,
children: [
{ title: "Statutory Compliance", href: "/dashboard/compliance-safety/statutoryCompliance", icon: ShieldCheck },
{ title: "Contracts & SLA", href: "/dashboard/compliance-safety/contracts", icon: FileText },
{ title: "Fire & Safety", href: "/dashboard/compliance-safety/fireAndSafety", icon: Flame },
{ title: "Waste & ESG", href: "/dashboard/compliance-safety/wasteAndEsg", icon: Recycle },
{ title: "Training", href: "/dashboard/compliance-safety/training", icon: GraduationCap },
{ title: "Audit & Survey", href: "/dashboard/compliance-safety/auditAndSurvey", icon: GraduationCap },
],
},
{
title: "Intelligence",
icon: Brain,
children: [{ title: "AI & Predictive", href: "/dashboard/intelligence/aiPredictive", icon: Brain },
{ title: "Asset Health", href: "/dashboard/intelligence/assetHealth", icon: ShieldCheck },
{ title: "Energy Benchmarking", href: "/dashboard/intelligence/energyBenchmarking", icon: Activity },
{ title: "AI Helpdesk", href: "/dashboard/intelligence/aiHelpdesk", icon: Bot },
{ title: "Connected Ops", href: "/dashboard/intelligence/connectedOps", icon: Gauge },
{ title: "Connected Assets", href: "/dashboard/intelligence/connectedAsset", icon: Snowflake },
{ title: "Sustainability", href: "/dashboard/intelligence/sustainability", icon: Leaf },
{ title: "GPS Tracking", href: "/dashboard/intelligence/gpstracking", icon: MapPin },],
},
{
title: "IoT Application",
icon: Radar,
children: [{ title: "Command Center", href: "/dashboard/iot-app/commandCenter", icon: Gauge },
{ title: "HVAC Plant", href: "/dashboard/iot-app/hvacPlant", icon: Snowflake },
{ title: "Energy & Utilities", href: "/dashboard/iot-app/energyUtility", icon: Zap },
{ title: "Device Fleet", href: "/dashboard/iot-app/deviceFleet", icon: LayoutGrid },
{ title: "Alarms & Rules", href: "/dashboard/iot-app/alarmsRules", icon: Shield, badge: 7, badgeColor: "bg-rose-500 text-white" },],
},
{
title: "Insight",
icon: BarChart3,
children: [{ title: "Reports & MMR", href: "/dashboard/insight/report", icon: BarChart3 },],
},
{
title: "Configure",
icon: Cog,
children: [{ title: "Master Data", href: "/dashboard/configure/masterdata", icon: Layers },
{ title: "Roles & Access", href: "/dashboard/configure/rolesAndAccess", icon: Shield },
{ title: "Workflow Automation", href: "/dashboard/configure/workflowautomation", icon: Bot },
{ title: "User Location", href: "/dashboard/configure/userLocation", icon: MapPin },
{ title: "Settings", href: "/dashboard/configure/settings", icon: Sun },],
},
];
export const ADMIN_SIDEBAR_ITEMS = [
{
title: "Platform",
icon: Building2,
children: [
{ title: "Overview", href: "/dashboard/admin/overview", icon: LayoutGrid },
{ title: "Tenants", href: "/dashboard/admin/tenants", icon: Building2 },
{ title: "Users", href: "/dashboard/admin/users", icon: Users },
{ title: "Sites", href: "/dashboard/admin/site", icon: MapPin },
{ title: "Security", href: "/dashboard/admin/security", icon: Shield },
],
},
{
title: "Configuration",
icon: LayoutGrid,
children: [
{ title: "Modules", href: "/dashboard/admin/modules", icon: LayoutGrid },
{ title: "Language", href: "/dashboard/admin/language", icon: Globe },
{ title: "Dynamic Dashboard", href: "/dashboard/admin/dynamicDashboard", icon: LayoutDashboard },
{ title: "Mobile Flows", href: "/dashboard/admin/mobileFlow", icon: Smartphone },
],
},
];
export const schedulePerformanceHeaders = [
"Schedule",
"Total",
"Done",
"On Time",
"Delayed",
];
export const schedulePerformanceRows = [
["PPM", 24, 19, 17, 2],
["AMC", 8, 6, 6, 0],
];
//Overview dashboard data
export const chartData = [
{ month: 'J', height: 'h-24' },
@@ -562,325 +390,117 @@ export const scheduleItems = [
{ frequency: "On call", stream: "Hazardous", vendor: "Ramky Enviro" },
];
export const stockItems = [
{
item: "Cooling tower fan belt",
group: "HVAC",
store: "Block Store",
min: 5,
presentValue: 8,
unit: "Gallon",
status: "COMPLETED",
isHighlighted: false,
},
{
item: "Air filter 24×24",
group: "HVAC",
store: "Block Store",
min: 5,
presentValue: 2,
unit: "Nos",
status: "OVERDUE",
isHighlighted: true,
},
{
item: "MCB 32A",
group: "Electrical",
store: "Block Store",
min: 5,
presentValue: 8,
unit: "Nos",
status: "COMPLETED",
isHighlighted: false,
},
{
item: "Contactor 40A",
group: "Electrical",
store: "Block Store",
min: 2,
presentValue: 2,
unit: "Nos",
status: "OVERDUE",
isHighlighted: false,
},
{
item: "PVC pipe 1\"",
group: "Plumbing",
store: "Main Store",
min: 3,
presentValue: 0,
unit: "Mtr",
status: "OVERDUE",
isHighlighted: false,
},
{
item: "Submersible pump seal",
group: "Plumbing",
store: "Main Store",
min: 3,
presentValue: 2,
unit: "Nos",
status: "OVERDUE",
isHighlighted: false,
},
{
item: "Refrigerant R410a",
group: "HVAC",
store: "Block Store",
min: 5,
presentValue: 0,
unit: "Kg",
status: "OVERDUE",
isHighlighted: false,
},
];
export const consumptionLedger = [
{
txn: "TXN-5200",
item: "Cooling tower fan belt",
type: "Consume",
qty: "2 Gallon",
jobCard: "026/1009",
date: "Jun 20, 2026",
},
{
txn: "TXN-5201",
item: "MCB 32A",
type: "Consume",
qty: "1 Nos",
jobCard: "026/1016",
date: "Jun 21, 2026",
},
{
txn: "TXN-5202",
item: "Air filter 24×24",
type: "Receipt",
qty: "10 Nos",
jobCard: "—",
date: "Jun 22, 2026",
},
{
txn: "TXN-5203",
item: "Submersible pump seal",
type: "Consume",
qty: "1 Nos",
jobCard: "026/1023",
date: "Jun 23, 2026",
},
{
txn: "TXN-5204",
item: "Air filter 24×24",
type: "Consume",
qty: "3 Nos",
jobCard: "026/1030",
date: "Jun 24, 2026",
},
{
txn: "TXN-5205",
item: "PVC pipe 1\"",
type: "Receipt",
qty: "20 Mtr",
jobCard: "—",
date: "Jun 25, 2026",
},
{
txn: "TXN-5406",
item: "Cooling tower fan belt",
type: "Consume",
qty: "2 Gallon",
jobCard: "026/1009",
date: "Jun 7, 2026",
},
{
txn: "TXN-5407",
item: "MCB 32A",
type: "Consume",
qty: "1 Nos",
jobCard: "026/1016",
date: "Jun 7, 2026",
},
{
txn: "TXN-5200",
item: "Cooling tower fan belt",
type: "Consume",
qty: "2 Gallon",
jobCard: "026/1009",
date: "Jun 20, 2026",
},
{
txn: "TXN-5201",
item: "MCB 32A",
type: "Consume",
qty: "1 Nos",
jobCard: "026/1016",
date: "Jun 21, 2026",
},
{
txn: "TXN-5202",
item: "Air filter 24×24",
type: "Receipt",
qty: "10 Nos",
jobCard: "—",
date: "Jun 22, 2026",
},
{
txn: "TXN-5203",
item: "Submersible pump seal",
type: "Consume",
qty: "1 Nos",
jobCard: "026/1023",
date: "Jun 23, 2026",
},
{
txn: "TXN-5204",
item: "Air filter 24×24",
type: "Consume",
qty: "3 Nos",
jobCard: "026/1030",
date: "Jun 24, 2026",
},
{
txn: "TXN-5205",
item: "PVC pipe 1\"",
type: "Receipt",
qty: "20 Mtr",
jobCard: "—",
date: "Jun 25, 2026",
},
{
txn: "TXN-5406",
item: "Cooling tower fan belt",
type: "Consume",
qty: "2 Gallon",
jobCard: "026/1009",
date: "Jun 7, 2026",
},
{
txn: "TXN-5407",
item: "MCB 32A",
type: "Consume",
qty: "1 Nos",
jobCard: "026/1016",
date: "Jun 7, 2026",
},
];
export const plantLoadData = [
{ month: '08', height: 'h-[35%]' },
{ month: '09', height: 'h-[38%]' },
{ month: '10', height: 'h-[32%]' },
{ month: '11', height: 'h-[40%]' },
{ month: '12', height: 'h-[52%]' },
{ month: '13', height: 'h-[68%]' },
{ month: '14', height: 'h-[78%]' },
{ month: '15', height: 'h-[78%]' },
{ month: '16', height: 'h-[78%]' },
{ month: '17', height: 'h-[78%]' },
{ month: '18', height: 'h-[78%]' },
{ month: '19', height: 'h-[78%]' }
];
// Initial roles state
export const rolesList = [
{ id: "admin", label: "Admin", badge: "all" },
{ id: "helpdesk", label: "Helpdesk", badge: "scoped" },
{ id: "mne_supervisor", label: "M&E Supervisor", badge: "scoped" },
{ id: "technician", label: "Technician", badge: "scoped" },
{ id: "tenant", label: "Tenant", badge: "scoped" },
];
export const vendorData = [
{
name: "Voltas Ltd",
id: "CTR-700",
scope: "HVAC AMC & breakdown",
rating: "4.6",
sla: "95%",
slaColor: "text-emerald-400",
response: "4.0h",
openJobs: "2",
},
{
name: "Blue Star",
id: "CTR-701",
scope: "Chiller & VRV service",
rating: "4.1",
sla: "88%",
slaColor: "text-amber-400",
response: "1.2h",
openJobs: "2",
},
{
name: "Sterling FM",
id: "CTR-702",
scope: "Integrated FM / soft services",
rating: "3.4",
sla: "94%",
slaColor: "text-emerald-400",
response: "2.4h",
openJobs: "4",
},
{
name: "OTIS Elevators",
id: "CTR-704",
scope: "Elevator AMC",
rating: "4.8",
sla: "95%",
slaColor: "text-emerald-400",
response: "2.8h",
openJobs: "—",
},
{
name: "Sodexo",
id: "CTR-705",
scope: "Soft services & cafeteria",
rating: "4.3",
sla: "90%",
slaColor: "text-amber-400",
response: "2.8h",
openJobs: "1",
},
{
name: "In-house team",
id: "—",
scope: "Day-to-day maintenance",
rating: "4.0",
sla: "93%",
slaColor: "text-amber-400",
response: "3.2h",
openJobs: "3",
},
];
// Initial permissions table data
export const initialPermissions = [
{
id: 1,
module: "Help Desk",
menu: "Daily Location Checklist",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
{
id: 2,
module: "Equipment",
menu: "Site-Wise Equipment",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
{
id: 3,
module: "Equipment",
menu: "AMC Schedule",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
{
id: 4,
module: "Request",
menu: "TFM Request",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
{
id: 5,
module: "Energy",
menu: "Meter Reading",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
{
id: 6,
module: "Master",
menu: "Request Location",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
{
id: 7,
module: "Security",
menu: "Users",
permissions: { all: false, view: true, add: true, edit: true, delete: false, cancel: true, print: true },
},
];
export const fieldCrewData = [
{
initials: "RK",
name: "Ravi Kumar",
role: "M&E Technician • Chiller plant",
status: "ON-SITE",
statusType: "onsite",
time: "6.4h today",
},
{
initials: "SI",
name: "Sana Iqbal",
role: "HVAC Engineer • AHU room L7",
status: "ON-SITE",
statusType: "onsite",
time: "6.1h today",
},
{
initials: "MD",
name: "Mohan D.",
role: "Electrician • En route",
status: "EN-ROUTE",
statusType: "enroute",
time: "—",
},
{
initials: "LN",
name: "Lakshmi N.",
role: "Housekeeping Lead • Lobby + L2",
status: "ON-SITE",
statusType: "onsite",
time: "6.7h today",
},
{
initials: "AP",
name: "Arjun P.",
role: "Plumber • Off-site",
status: "OFF-SITE",
statusType: "offsite",
time: "—",
},
{
initials: "FR",
name: "Fatima R.",
role: "BMS Operator • Control room",
status: "ON-SITE",
statusType: "onsite",
time: "7.6h today",
},
];
export const blocks = ["Block 1", "Block 2", "Tower A"];
export const floors = ["Ground", "Floor 1", "Floor 2"];
export const zones = ["Zone N", "Zone Z1", "Zone Z2"];
// Mock user location data matching the screenshot
export const userData = [
{
name: "Dhananjay T.",
email: "dhananjay@kafm.io",
mobile: "7489477369",
latitude: "18.5450",
longitude: "73.7935",
site: "Apple One",
// Relative coordinates for the map visual dots (X%, Y%)
x: "19%",
y: "38%",
},
{
name: "ME Local",
email: "me.local@kafm.io",
mobile: "9876543210",
latitude: "18.5469",
longitude: "73.7945",
site: "Apple One",
x: "44%",
y: "43%",
},
{
name: "TECH Local",
email: "tech.local@kafm.io",
mobile: "9123456780",
latitude: "18.5441",
longitude: "73.7951",
site: "Apple One",
x: "69%",
y: "48%",
},
];
export const permitsData = [
{
permit: "PTW-2663",

View File

@@ -0,0 +1,160 @@
import {
LayoutGrid,
Smile,
Building2,
User,
Target,
CheckSquare,
FileText,
Box,
Zap,
ClipboardList,
Star,
Monitor,
UserCheck,
Calendar,
Layers,
Coins,
Receipt,
ShieldCheck,
Flame,
Recycle,
GraduationCap,
Brain,
Activity,
Bot,
Gauge,
Snowflake,
Leaf,
MapPin,
BarChart3,
Sun,
Shield,
Settings,
Wallet,
Radar,
Cog,
Smartphone,
Users,
Globe,
LayoutDashboard,
} from "lucide-react";
export const OPERATIONS_SIDEBAR_ITEMS = [
{
title: "Overview",
icon: LayoutGrid,
children: [
{ title: "Dashboard", href: "/dashboard/overview/dashboard", icon: LayoutGrid },
{ title: "Engagement", href: "/dashboard/overview/engagement", icon: Smile },
{ title: "Building Owner", href: "/dashboard/overview/buildingOwner", icon: Building2 },
{ title: "Property Manager", href: "/dashboard/overview/propertyManager", icon: User },
{ title: "Service Engineer", href: "/dashboard/overview/serviceEngineer", icon: Target },
],
},
{
title: "Operations",
icon: Settings,
children: [
{ title: "Help Desk", href: "/dashboard/operations/helpDesk", icon: CheckSquare, badge: 6, badgeColor: "bg-amber-500 text-black" },
{ title: "Equipment", href: "/dashboard/operations/equipment", icon: Target },
{ title: "Requests", href: "/dashboard/operations/request", icon: FileText, badge: 15, badgeColor: "bg-amber-400 text-black" },
{ title: "Inventory", href: "/dashboard/operations/inventory", icon: Box },
{ title: "Energy", href: "/dashboard/operations/energy", icon: Zap },
{ title: "Work Permit", href: "/dashboard/operations/workPermit", icon: ClipboardList, badge: 3, badgeColor: "bg-amber-500 text-black" },
{ title: "Vendor & Field Service", href: "/dashboard/operations/vendorFieldService", icon: Star, badge: 12, badgeColor: "bg-sky-400 text-black" },
],
},
{
title: "Workplace",
icon: Monitor,
children: [
{ title: "Visitor Management", href: "/dashboard/workplace/visitorManagement", icon: UserCheck },
{ title: "Meeting Rooms", href: "/dashboard/workplace/meetingRoom", icon: Calendar },
{ title: "Workspace", href: "/dashboard/workplace/workspace", icon: Layers },
],
},
{
title: "Finance",
icon: Wallet,
children: [
{ title: "O&M Budget", href: "/dashboard/finance/budget", icon: Coins },
{ title: "Costing & Invoicing", href: "/dashboard/finance/costinvoice", icon: Receipt },
],
},
{
title: "Compliance & Safety",
icon: ShieldCheck,
children: [
{ title: "Statutory Compliance", href: "/dashboard/compliance-safety/statutoryCompliance", icon: ShieldCheck },
{ title: "Contracts & SLA", href: "/dashboard/compliance-safety/contracts", icon: FileText },
{ title: "Fire & Safety", href: "/dashboard/compliance-safety/fireAndSafety", icon: Flame },
{ title: "Waste & ESG", href: "/dashboard/compliance-safety/wasteAndEsg", icon: Recycle },
{ title: "Training", href: "/dashboard/compliance-safety/training", icon: GraduationCap },
{ title: "Audit & Survey", href: "/dashboard/compliance-safety/auditAndSurvey", icon: GraduationCap },
],
},
{
title: "Intelligence",
icon: Brain,
children: [{ title: "AI & Predictive", href: "/dashboard/intelligence/aiPredictive", icon: Brain },
{ title: "Asset Health", href: "/dashboard/intelligence/assetHealth", icon: ShieldCheck },
{ title: "Energy Benchmarking", href: "/dashboard/intelligence/energyBenchmarking", icon: Activity },
{ title: "AI Helpdesk", href: "/dashboard/intelligence/aiHelpdesk", icon: Bot },
{ title: "Connected Ops", href: "/dashboard/intelligence/connectedOps", icon: Gauge },
{ title: "Connected Assets", href: "/dashboard/intelligence/connectedAsset", icon: Snowflake },
{ title: "Sustainability", href: "/dashboard/intelligence/sustainability", icon: Leaf },
{ title: "GPS Tracking", href: "/dashboard/intelligence/gpstracking", icon: MapPin },],
},
{
title: "IoT Application",
icon: Radar,
children: [{ title: "Command Center", href: "/dashboard/iot-app/commandCenter", icon: Gauge },
{ title: "HVAC Plant", href: "/dashboard/iot-app/hvacPlant", icon: Snowflake },
{ title: "Energy & Utilities", href: "/dashboard/iot-app/energyUtility", icon: Zap },
{ title: "Device Fleet", href: "/dashboard/iot-app/deviceFleet", icon: LayoutGrid },
{ title: "Alarms & Rules", href: "/dashboard/iot-app/alarmRule", icon: Shield, badge: 7, badgeColor: "bg-rose-500 text-white" },],
},
{
title: "Insight",
icon: BarChart3,
children: [{ title: "Reports & MMR", href: "/dashboard/insight/report", icon: BarChart3 },],
},
{
title: "Configure",
icon: Cog,
children: [{ title: "Master Data", href: "/dashboard/configure/masterdata", icon: Layers },
{ title: "Roles & Access", href: "/dashboard/configure/rolesAndAccess", icon: Shield },
{ title: "Workflow Automation", href: "/dashboard/configure/workflowautomation", icon: Bot },
{ title: "User Location", href: "/dashboard/configure/userLocation", icon: MapPin },
{ title: "Settings", href: "/dashboard/configure/settings", icon: Sun },],
},
];
export const ADMIN_SIDEBAR_ITEMS = [
{
title: "Platform",
icon: Building2,
children: [
{ title: "Overview", href: "/dashboard/admin/overview", icon: LayoutGrid },
{ title: "Tenants", href: "/dashboard/admin/tenants", icon: Building2 },
{ title: "Users", href: "/dashboard/admin/users", icon: Users },
{ title: "Sites", href: "/dashboard/admin/site", icon: MapPin },
{ title: "Security", href: "/dashboard/admin/security", icon: Shield },
],
},
{
title: "Configuration",
icon: LayoutGrid,
children: [
{ title: "Modules", href: "/dashboard/admin/modules", icon: LayoutGrid },
{ title: "Language", href: "/dashboard/admin/language", icon: Globe },
{ title: "Dynamic Dashboard", href: "/dashboard/admin/dynamicDashboard", icon: LayoutDashboard },
{ title: "Mobile Flows", href: "/dashboard/admin/mobileFlow", icon: Smartphone },
],
},
];

File diff suppressed because it is too large Load Diff