Admin part is added and navbar context file is added

This commit is contained in:
2026-07-27 19:05:11 +05:30
parent cdb52e717e
commit 954de712a7
23 changed files with 2525 additions and 131 deletions

View File

@@ -0,0 +1,31 @@
"use client";
import React, { createContext, useContext, useState } from "react";
type Mode = "operations" | "admin";
interface NavContextType {
mode: Mode;
setMode: (mode: Mode) => void;
}
// 1. Provide default values so useContext never returns null/undefined
const NavContext = createContext<NavContextType>({
mode: "operations",
setMode: () => {},
});
export function NavProvider({ children }: { children: React.ReactNode }) {
const [mode, setMode] = useState<Mode>("operations");
return (
<NavContext.Provider value={{ mode, setMode }}>
{children}
</NavContext.Provider>
);
}
export function useNav() {
const context = useContext(NavContext);
return context;
}

View File

@@ -1,83 +1,133 @@
import { Search, HelpCircle, Globe, Sun, Bell, ChevronDown, MapPin } from 'lucide-react';
"use client";
import { Search, HelpCircle, Globe, Sun, Bell, ChevronDown, MapPin, ShieldCheck } from "lucide-react";
import { useNav } from "./context/navContext";
export default function Navbar() {
const { mode } = useNav();
return (
/*
- 'fixed top-0 right-0 left-64' anchors the navbar to the top of the screen,
leaving room exactly for your 64-width sidebar.
- 'bg-[#071321]' matches your master UI background.
- 'h-16' gives it a consistent height.
*/
<header className="fixed top-0 right-0 left-64 z-30 flex h-16 items-center justify-between border-b border-[#142538]/50 bg-[#071321] px-8">
{/* Left Group */}
<div className="flex items-center gap-2">
{/* Company Selector */}
<div className="flex items-center gap-2 rounded-full bg-[#0a1826] px-3 py-1.5 text-sm font-semibold text-[#10b981] border border-[#132338] cursor-pointer hover:bg-[#0f2338] transition whitespace-nowrap">
<span className="h-2 w-2 rounded-full bg-[#10b981] shrink-0"></span>
<span className="font-semibold">Apple One</span>
<ChevronDown className="h-3.5 w-3.5 text-[#10b981]" />
</div>
{mode === "operations" ? (
/* ================= OPERATIONS NAVBAR ================= */
<>
{/* Left Group */}
<div className="flex items-center gap-2">
{/* Company Selector */}
<div className="flex items-center gap-2 rounded-full bg-[#0a1826] px-3 py-1.5 text-sm font-semibold text-[#10b981] border border-[#132338] cursor-pointer hover:bg-[#0f2338] transition whitespace-nowrap relative">
<span className="h-2 w-2 rounded-full bg-[#10b981] shrink-0"></span>
{/* Location Selector */}
<div className="flex items-center gap-2 rounded-full bg-[#0a1826] px-4 py-2 text-sm font-medium text-[#cbd5e1] border border-[#132338] cursor-pointer hover:bg-[#0f2338] transition whitespace-nowrap">
<MapPin className="h-4 w-4 text-gray-500 shrink-0" />
<span className="whitespace-nowrap">
Apple One <span className="text-[#cbd5e1] font-semibold">HQ Tower</span>
</span>
<ChevronDown className="h-4 w-4 text-gray-500 shrink-0" />
</div>
<select
className=" bg-[#0a1826] outline-none cursor-pointer font-medium pr-5"
defaultValue="Apple One"
>
<option>Apple One</option>
<option>Novotel Pune</option>
<option>SRM Campus</option>
<option>Local 1</option>
</select>
{/* Search Bar */}
<div className="relative w-60">
<Search className="absolute left-4 top-2.5 h-4 w-4 text-gray-500" />
<input
type="text"
placeholder="Search requests, equipment, met"
className="w-full rounded-xl bg-[#0a1826] pl-10 pr-4 py-2 text-sm text-white placeholder-gray-500 border border-[#132338] focus:outline-none focus:border-[#3de0c4]/50"
/>
</div>
</div>
<ChevronDown className="absolute right-3 h-3.5 w-3.5 pointer-events-none" />
</div>
{/* Location Selector */}
<div className="flex items-center gap-2 rounded-full bg-[#0a1826] px-4 py-2 text-sm font-medium text-[#cbd5e1] border border-[#132338] cursor-pointer hover:bg-[#0f2338] transition whitespace-nowrap relative">
<MapPin className="h-4 w-4 text-gray-500 shrink-0" />
{/* Right Utilities */}
<div className="flex items-center gap-3">
{/* Tour */}
<button className="flex items-center gap-2 rounded-xl border border-[#132338] bg-[#0a1826] px-4 py-2 text-sm font-semibold text-white transition hover:bg-[#14253d]">
<HelpCircle className="h-4 w-4 text-gray-400" />
<span>Tour</span>
</button>
{/* Language */}
<div className="flex items-center gap-1.5 rounded-xl border border-[#132338] bg-[#0a1826] px-4 py-2 text-sm font-semibold text-[#cbd5e1] cursor-pointer hover:bg-[#14253d]">
<Globe className="h-4 w-4 text-gray-400" />
<span>English</span>
<ChevronDown className="h-4 w-4 text-gray-500" />
</div>
<select
className=" bg-[#0a1826] outline-none cursor-pointer font-medium pr-5"
defaultValue="Apple One — HQ Tower"
>
<option>Apple One HQ Tower</option>
<option>Apple One Annexe</option>
</select>
{/* Live Indicator */}
<div className="flex items-center gap-2 px-1 text-sm font-bold text-[#10b981] tracking-wider">
<span className="h-1.5 w-1.5 rounded-full bg-[#10b981]"></span>
<span className="text-xs font-bold text-gray-400">LIVE</span>
</div>
<ChevronDown className="absolute right-4 h-4 w-4 text-gray-500 pointer-events-none" />
</div>
{/* Theme Toggle */}
<button className="flex h-9 w-9 items-center justify-center rounded-xl border border-[#132338] bg-[#0a1826] text-gray-400 hover:text-white transition">
<Sun className="h-4 w-4" />
</button>
{/* Search Bar */}
<div className="relative w-60">
<Search className="absolute left-4 top-2.5 h-4 w-4 text-gray-500" />
<input
type="text"
placeholder="Search requests, equipment, met"
className="w-full rounded-xl bg-[#0a1826] pl-10 pr-4 py-2 text-sm text-white placeholder-gray-500 border border-[#132338] focus:outline-none focus:border-[#3de0c4]/50"
/>
</div>
</div>
{/* Notifications */}
<div className="relative flex h-9 w-9 items-center justify-center rounded-xl border border-[#132338] bg-[#0a1826] cursor-pointer hover:bg-[#14253d] transition">
<Bell className="h-4 w-4 text-gray-400" />
<span className="absolute -top-1 -right-1 flex h-4 w-4 items-center justify-center rounded-full bg-[#ef4444] text-[9px] font-bold text-white">
8
</span>
</div>
{/* Right Utilities */}
<div className="flex items-center gap-3">
<button className="flex items-center gap-2 rounded-xl border border-[#132338] bg-[#0a1826] px-4 py-2 text-sm font-semibold text-white transition hover:bg-[#14253d]">
<HelpCircle className="h-4 w-4 text-gray-400" />
<span>Tour</span>
</button>
{/* Profile Avatar */}
<div className="flex h-9 w-9 items-center justify-center rounded-full bg-[#1b3454] text-xs font-bold text-white cursor-pointer hover:opacity-90 transition">
DH
</div>
</div>
<div className="flex items-center gap-1.5 rounded-xl border border-[#132338] bg-[#0a1826] px-4 py-2 text-sm font-semibold text-[#cbd5e1] cursor-pointer hover:bg-[#14253d]">
<Globe className="h-4 w-4 text-gray-400" />
<span>English</span>
<ChevronDown className="h-4 w-4 text-gray-500" />
</div>
<div className="flex items-center gap-2 px-1 text-sm font-bold text-[#10b981] tracking-wider">
<span className="h-1.5 w-1.5 rounded-full bg-[#10b981]"></span>
<span className="text-xs font-bold text-gray-400">LIVE</span>
</div>
<button className="flex h-9 w-9 items-center justify-center rounded-xl border border-[#132338] bg-[#0a1826] text-gray-400 hover:text-white transition">
<Sun className="h-4 w-4" />
</button>
<div className="relative flex h-9 w-9 items-center justify-center rounded-xl border border-[#132338] bg-[#0a1826] cursor-pointer hover:bg-[#14253d] transition">
<Bell className="h-4 w-4 text-gray-400" />
<span className="absolute -top-1 -right-1 flex h-4 w-4 items-center justify-center rounded-full bg-[#ef4444] text-[9px] font-bold text-white">
8
</span>
</div>
<div className="flex h-9 w-9 items-center justify-center rounded-full bg-[#1b3454] text-xs font-bold text-white cursor-pointer hover:opacity-90 transition">
DH
</div>
</div>
</>
) : (
/* ================= ADMIN NAVBAR ================= */
<>
{/* Left Breadcrumb */}
<div className="flex items-center gap-2 text-sm text-slate-300">
<ShieldCheck size={18} className="text-[#3de0c4]" />
<span className="font-bold text-white">Administration</span>
<span className="text-slate-500">&rsaquo;</span>
<span className="text-slate-400">Mobile Flows</span>
</div>
{/* Right Utilities */}
<div className="flex items-center gap-3">
<div className="relative w-64">
<Search className="absolute left-3 top-2.5 h-4 w-4 text-slate-400" />
<input
type="text"
placeholder="Search tenants, users, sites..."
className="w-full rounded-lg bg-[#0a1826] pl-9 pr-4 py-1.5 text-xs text-white placeholder-slate-500 border border-[#132338] focus:outline-none focus:border-[#3de0c4]/50"
/>
</div>
<div className="flex items-center gap-1.5 rounded-full border border-teal-500/30 bg-teal-500/10 px-3 py-1 text-xs font-bold text-[#3de0c4]">
<span className="h-2 w-2 rounded-full bg-[#3de0c4]"></span>
<span>PRODUCTION &bull; us-east-1</span>
</div>
<button className="flex h-8 w-8 items-center justify-center rounded-lg border border-[#132338] bg-[#0a1826] text-slate-400 hover:text-white transition">
<Sun className="h-4 w-4" />
</button>
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-[#1b3454] text-xs font-bold text-white">
SA
</div>
</div>
</>
)}
</header>
);
}

View File

@@ -1,65 +1,78 @@
import { SIDEBAR_ITEMS } from "@/constants/constant";
"use client";
import { OPERATIONS_SIDEBAR_ITEMS, ADMIN_SIDEBAR_ITEMS } from "@/constants/constant";
import SidebarItem from "./sideBarItem";
import {
ShieldCheck,
Activity,
ChevronDown,
ChevronsLeft,
} from "lucide-react";
import { ShieldCheck, Activity, ChevronDown, ChevronsLeft } from "lucide-react";
import { useSession, signOut } from "next-auth/react";
import { useNav } from "./context/navContext";
export default function Sidebar() {
const { data: session } = useSession();
console.log("Session data ",session?.user?.name)
console.log("Session data ",session?.user?.email)
const { mode, setMode } = useNav();
const currentItems = mode === "operations" ? OPERATIONS_SIDEBAR_ITEMS : ADMIN_SIDEBAR_ITEMS;
return (
<aside className="fixed bg-[#071321] text-white h-screen overflow-y-auto [scrollbar-color:#1b2a40_#071321] [scrollbar-width:thin]">
<div className="flex items-center gap-2 px-2 pt-2 pb-3">
<div className="flex h-9 w-9 items-center justify-center rounded-lg
bg-[#3de0c4] font-bold text-[#05111d] text-sm">
<aside className="fixed bg-[#071321] text-white h-screen w-64 overflow-y-auto [scrollbar-color:#1b2a40_#071321] [scrollbar-width:thin]">
{/* App Logo */}
<div className="flex items-center gap-2 px-4 pt-3 pb-3">
<div className="flex h-9 w-9 items-center justify-center rounded-lg bg-[#3de0c4] font-bold text-[#05111d] text-sm">
K
</div>
<span className="text-sm font-bold tracking-tight text-white">
KA<span className="text-[#3de0c4]">FM</span>
</span>
</div>
<hr className="border-[#142538]" />
<div className="mx-4 my-4 flex rounded-xl
bg-[#091624] p-2 border border-[#142538]">
<button className="flex flex-1
items-center justify-center gap-1 rounded-lg bg-[#3de0c4] py-1.5 text-xs
text-black font-bold shadow-sm">
{/* Mode Switcher Buttons */}
<div className="mx-4 my-4 flex rounded-xl bg-[#091624] p-1 border border-[#142538]">
<button
onClick={() => setMode("operations")}
className={`flex flex-1 items-center justify-center gap-1 rounded-lg py-1.5 text-xs font-bold transition-all ${
mode === "operations"
? "bg-[#3de0c4] text-black shadow-sm"
: "text-slate-400 hover:text-white"
}`}
>
<Activity size={14} />
Operations
</button>
<button className="flex flex-1 items-center justify-center gap-1
rounded-lg py-1 text-xs text-slate-400 font-medium hover:text-white transition-colors">
<button
onClick={() => setMode("admin")}
className={`flex flex-1 items-center justify-center gap-1 rounded-lg py-1.5 text-xs font-bold transition-all ${
mode === "admin"
? "bg-[#3de0c4] text-black shadow-sm"
: "text-slate-400 hover:text-white"
}`}
>
<ShieldCheck size={14} />
Admin
</button>
</div>
<p className="px-2 text-xs font-semibold uppercase
tracking-wider text-slate-500">
Tenant runtime
<p className="px-4 text-[10px] font-semibold uppercase tracking-wider text-slate-500">
{mode === "operations" ? "Tenant Runtime" : "System Platform"}
</p>
{/* Dynamic Navigation Items */}
<div className="py-1">
{SIDEBAR_ITEMS.map((item) => (
<SidebarItem
key={item.title}
item={item}
/>
{currentItems.map((item) => (
<SidebarItem key={item.title} item={item} />
))}
</div>
<div className="px-3 pb-2 pt-1
border-t border-[#0f1f30]">
<div className="px-3 pb-2 pt-1 border-t border-[#0f1f30]">
<button className="flex w-full items-center gap-2 rounded-xl py-2 px-3 text-xs text-slate-400 hover:bg-[#091624] hover:text-white transition-colors">
<ChevronsLeft size={16} />
Minimise menu
</button>
</div>
{/* Profile Card Section */}
{/* Profile Card */}
<div className="m-3 mt-0 rounded-xl border border-[#142538] bg-[#071321] p-2.5">
<div className="flex items-center justify-between">
<div className="flex gap-2.5 items-center">
@@ -67,16 +80,19 @@ console.log("Session data ",session?.user?.email)
DT
</div>
<div className="min-w-0 leading-tight">
<h4 className="font-semibold text-xs text-white truncate">{session?.user?.name}</h4>
<h4 className="font-semibold text-xs text-white truncate">{session?.user?.name || "User"}</h4>
<p className="text-[11px] text-slate-500 truncate">
{session?.user?.email}
{session?.user?.email || "user@example.com"}
</p>
</div>
</div>
<ChevronDown className="-rotate-90 text-slate-500 shrink-0" size={14}
onClick={() => signOut({ callbackUrl: "/login" })} />
</div>
<ChevronDown
className="-rotate-90 text-slate-500 shrink-0 cursor-pointer"
size={14}
onClick={() => signOut({ callbackUrl: "/login" })}
/>
</div>
</div>
</aside>
);
}