Changes done in ui screens
This commit is contained in:
@@ -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]">
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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'>
|
||||
|
||||
@@ -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:00–06: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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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() {
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user