mobile: Optimizations for Maps Drawer, Legend, and Customer Profile Tabs

This commit is contained in:
Satyam
2026-02-10 20:36:44 +05:30
parent 91b47e83c3
commit 83250d687e
15 changed files with 1140 additions and 91 deletions
+62 -10
View File
@@ -1,14 +1,15 @@
import React, { useRef, useState } from 'react';
import { Outlet, NavLink, useNavigate, useLocation } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
import { LayoutDashboard, Map, Calendar, LogOut, User, Home, MessageSquare, ChevronLeft, ChevronRight } from 'lucide-react';
import { useTheme } from '../context/ThemeContext';
import { LayoutDashboard, Map, Calendar, LogOut, User, Home, MessageSquare, ChevronLeft, ChevronRight, Sun, Moon } from 'lucide-react';
import PageTransition from './PageTransition';
import Chatbot from './Chatbot';
import Logo from '../assets/images/LynkedUp_Pro_F_logo_Y.png';
// Rainbow Sidebar Item Component
const SidebarItem = ({ to, icon: Icon, label, isCollapsed }) => {
const SidebarItem = ({ to, icon: Icon, label, isCollapsed, onClick }) => {
const divRef = useRef(null);
const [position, setPosition] = useState({ x: 0, y: 0 });
const [opacity, setOpacity] = useState(0);
@@ -29,6 +30,7 @@ const SidebarItem = ({ to, icon: Icon, label, isCollapsed }) => {
<NavLink
to={to}
ref={divRef}
onClick={onClick}
onMouseMove={handleMouseMove}
onFocus={handleFocus}
onBlur={handleBlur}
@@ -76,10 +78,12 @@ const SidebarItem = ({ to, icon: Icon, label, isCollapsed }) => {
const Layout = () => {
const { user, logout } = useAuth();
const { theme, toggleTheme } = useTheme();
const navigate = useNavigate();
const location = useLocation();
const [isCollapsed, setIsCollapsed] = useState(false);
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const handleLogout = () => {
logout();
@@ -99,14 +103,45 @@ const Layout = () => {
return (
<div className="flex h-screen bg-zinc-50 dark:bg-[#050505] text-zinc-900 dark:text-white overflow-hidden font-sans selection:bg-blue-500/20 dark:selection:bg-white/20 transition-colors duration-300">
{/* Mobile Header */}
<div className="md:hidden fixed top-0 left-0 right-0 h-16 bg-white/80 dark:bg-zinc-900/80 backdrop-blur-md border-b border-zinc-200 dark:border-white/5 flex items-center justify-between px-4 z-40">
<div className="flex items-center gap-2">
<img src={Logo} alt="Logo" className="w-8 h-8" />
<span className="font-bold text-lg">LynkedUp</span>
</div>
<button
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
className="p-2 rounded-lg hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors"
>
{isMobileMenuOpen ? <ChevronRight size={24} className="rotate-180 transition-transform" /> : <LayoutDashboard size={24} />}
</button>
</div>
{/* Mobile Backdrop */}
{isMobileMenuOpen && (
<div
className="fixed inset-0 bg-black/50 backdrop-blur-sm z-40 md:hidden"
onClick={() => setIsMobileMenuOpen(false)}
/>
)}
{/* Sidebar */}
{/* Enhanced glassmorphism with light/dark support */}
<aside className={`${isCollapsed ? 'w-20' : 'w-72'} bg-white/60 dark:bg-zinc-900/60 backdrop-blur-2xl border-r border-zinc-200 dark:border-white/5 flex flex-col shrink-0 z-30 shadow-[4px_0_24px_rgba(0,0,0,0.05)] dark:shadow-[4px_0_24px_rgba(0,0,0,0.4)] relative transition-all duration-300 ease-in-out`}>
<aside className={`
fixed md:static inset-y-0 left-0 z-50
${isMobileMenuOpen ? 'translate-x-0' : '-translate-x-full md:translate-x-0'}
${isCollapsed ? 'w-20' : 'w-72'}
bg-white/95 md:bg-white/60 dark:bg-zinc-900/95 md:dark:bg-zinc-900/60
backdrop-blur-2xl border-r border-zinc-200 dark:border-white/5
flex flex-col shrink-0 shadow-[4px_0_24px_rgba(0,0,0,0.05)] dark:shadow-[4px_0_24px_rgba(0,0,0,0.4)]
transition-all duration-300 ease-in-out
`}>
{/* Collapse Toggle Button */}
{/* Collapse Toggle Button (Desktop Only) */}
<button
onClick={() => setIsCollapsed(!isCollapsed)}
className="absolute -right-3 top-9 w-6 h-6 bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-white/10 rounded-full flex items-center justify-center text-zinc-500 hover:text-zinc-900 dark:hover:text-white shadow-sm z-50 transition-colors"
className="hidden md:flex absolute -right-3 top-9 w-6 h-6 bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-white/10 rounded-full items-center justify-center text-zinc-500 hover:text-zinc-900 dark:hover:text-white shadow-sm z-50 transition-colors"
>
{isCollapsed ? <ChevronRight size={14} /> : <ChevronLeft size={14} />}
</button>
@@ -128,24 +163,41 @@ const Layout = () => {
{user?.role === 'FIELD_AGENT' || user?.role === 'ADMIN' ? (
<>
<SidebarItem to="/emp/fa/dashboard" icon={LayoutDashboard} label="Dashboard" isCollapsed={isCollapsed} />
<SidebarItem to="/emp/fa/maps" icon={Map} label="Territory Map" isCollapsed={isCollapsed} />
<SidebarItem to="/emp/fa/dashboard" icon={LayoutDashboard} label="Dashboard" isCollapsed={isCollapsed} onClick={() => setIsMobileMenuOpen(false)} />
<SidebarItem to="/emp/fa/maps" icon={Map} label="Territory Map" isCollapsed={isCollapsed} onClick={() => setIsMobileMenuOpen(false)} />
</>
) : null}
{user?.role === 'ADMIN' && (
<SidebarItem to="/admin/schedule" icon={Calendar} label="Team Schedule" isCollapsed={isCollapsed} />
<SidebarItem to="/admin/schedule" icon={Calendar} label="Team Schedule" isCollapsed={isCollapsed} onClick={() => setIsMobileMenuOpen(false)} />
)}
{/* Common Links */}
<div className={`pt-6 mt-6 border-t border-zinc-200 dark:border-white/5 transition-all duration-300 ${isCollapsed ? 'flex justify-center' : ''}`}>
<div className={`text-[10px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest mb-4 pl-4 whitespace-nowrap overflow-hidden transition-all duration-300 ${isCollapsed ? 'opacity-0 h-0 scale-y-0' : 'opacity-100 h-auto scale-y-100'}`}>System</div>
<SidebarItem to="/" icon={MessageSquare} label="Public Site" isCollapsed={isCollapsed} />
<SidebarItem to="/" icon={MessageSquare} label="Public Site" isCollapsed={isCollapsed} onClick={() => setIsMobileMenuOpen(false)} />
{user?.role === 'CUSTOMER' && (
<SidebarItem to="/portal/profile" icon={User} label="My Profile" isCollapsed={isCollapsed} onClick={() => setIsMobileMenuOpen(false)} />
)}
</div>
</nav>
</div>
<div className="mt-auto p-4 border-t border-zinc-200 dark:border-white/5 bg-zinc-50/50 dark:bg-black/20 relative z-10">
{/* Theme Toggle */}
<button
onClick={toggleTheme}
className={`flex items-center ${isCollapsed ? 'justify-center' : 'space-x-3'} w-full mb-3 p-3 rounded-xl bg-white/40 dark:bg-white/5 border border-zinc-200 dark:border-white/5 backdrop-blur-md transition-all duration-300 hover:bg-white/60 dark:hover:bg-white/10 group text-zinc-600 dark:text-zinc-400`}
title={isCollapsed ? "Toggle Theme" : ""}
>
<div className="shrink-0">
{theme === 'dark' ? <Sun size={18} /> : <Moon size={18} />}
</div>
<span className={`font-medium text-sm whitespace-nowrap overflow-hidden transition-all duration-300 ${isCollapsed ? 'w-0 opacity-0' : 'w-auto opacity-100'}`}>
{theme === 'dark' ? 'Light Mode' : 'Dark Mode'}
</span>
</button>
<div className={`flex items-center ${isCollapsed ? 'justify-center' : 'space-x-3'} p-3 mb-3 rounded-xl bg-white/40 dark:bg-white/5 border border-zinc-200 dark:border-white/5 backdrop-blur-md transition-all duration-300 hover:bg-white/60 dark:hover:bg-white/10 group cursor-default`}>
<div className="w-10 h-10 rounded-full bg-zinc-200 dark:bg-zinc-800 flex items-center justify-center text-zinc-600 dark:text-zinc-400 border border-zinc-300 dark:border-white/5 group-hover:border-zinc-400 dark:group-hover:border-white/20 transition-colors shrink-0">
<User size={18} />
@@ -168,7 +220,7 @@ const Layout = () => {
</aside>
{/* Main Content */}
<main className="flex-1 overflow-auto relative bg-zinc-50 dark:bg-[#09090b] scroll-smooth transition-colors duration-300">
<main className="flex-1 overflow-auto relative bg-zinc-50 dark:bg-[#09090b] scroll-smooth transition-colors duration-300 pt-16 md:pt-0">
<PageTransition>
<Outlet />
</PageTransition>