T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/domains/lavocat.ca/private_html/src/components/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/lavocat.ca/private_html/src/components/Sidebar.tsx
import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import Link from 'next/link';
import { motion, AnimatePresence } from 'framer-motion';
import {
  Home,
  User,
  FileText,
  MessageSquare,
  Users,
  BarChart3,
  Star,
  Settings,
  Building,
  Scale,
  HelpCircle,
  Info,
  Mail,
  UserPlus,
  ChevronDown,
  ChevronRight,
  Menu,
  X,
  Lock,
  Eye,
  EyeOff,
  CheckCircle,
  AlertTriangle,
  Clock,
  Calendar,
  DollarSign,
  Phone,
  Globe,
  MapPin,
  Linkedin,
  Upload,
  Edit,
  Trash2,
  Plus,
  Search,
  Filter,
  Download,
  RefreshCw,
  RotateCcw,
  RotateCw,
  ZoomIn,
  ZoomOut,
  Maximize,
  Minimize,
  Move,
  Grid,
  List,
  Columns,
  Rows,
  Layout,
  MoreHorizontal,
  MoreVertical,
  Circle,
  Square,
  Triangle,
  Hexagon,
  Octagon,
  ThumbsUp,
  ThumbsDown,
  Flag,
  Bookmark,
  Tag,
  Hash,
  AtSign,
  Percent,
} from 'lucide-react';
import { Command } from 'cmdk';
import { useSession } from 'next-auth/react';

interface SidebarProps {
  isFrench?: boolean;
}

export const Sidebar: React.FC<SidebarProps> = ({ isFrench = false }) => {
  const router = useRouter();
  const { data: session } = useSession();
  const [isCollapsed, setIsCollapsed] = useState(false);
  const [isCommandOpen, setIsCommandOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');

  // Determine user role
  const userRole = session?.user?.role;

  // Store sidebar state in localStorage
  useEffect(() => {
    const savedState = localStorage.getItem('sidebarCollapsed');
    if (savedState) {
      setIsCollapsed(JSON.parse(savedState));
    }
  }, []);

  const toggleSidebar = () => {
    const newState = !isCollapsed;
    setIsCollapsed(newState);
    localStorage.setItem('sidebarCollapsed', JSON.stringify(newState));
  };

  // Build navigation with role-aware Cases link
  const navigation = [
    { name: isFrench ? 'Accueil' : 'Home', href: '/', icon: Home },
    { name: isFrench ? 'À Propos' : 'About', href: '/about', icon: Info },
    { name: isFrench ? 'Qui Est Concerné' : 'Who Is Concerned', href: '/who', icon: User },
    { name: isFrench ? 'Ressources' : 'Resources', href: '/resources', icon: FileText },
    { name: isFrench ? 'FAQ' : 'FAQ', href: '/faq', icon: HelpCircle },
    { name: isFrench ? 'Contact' : 'Contact', href: '/contact', icon: Mail },
    { name: isFrench ? 'Groupe de discussion' : 'Group Chat', href: '/group-chat', icon: MessageSquare },
  ];

  // Add role-based Cases link
  if (userRole === 'SUPERADMIN' || userRole === 'ADMIN') {
    navigation.push({ name: isFrench ? 'Dossiers' : 'Cases', href: '/admin/cases', icon: Scale });
  } else if (userRole === 'LAWYER') {
    navigation.push({ name: isFrench ? 'Dossiers' : 'Cases', href: '/lawyer/cases', icon: Scale });
  } else if (userRole === 'CLIENT' || userRole === 'USER') {
    navigation.push({ name: isFrench ? 'Dossiers' : 'Cases', href: '/client/cases', icon: Scale });
  }

  const filteredNavigation = navigation.filter(item =>
    item.name.toLowerCase().includes(searchQuery.toLowerCase())
  );

  return (
    <>
      <aside 
        className={`fixed top-0 left-0 h-screen bg-gradient-to-b from-primary to-primary-dark text-white transition-all duration-300 ease-in-out z-30 ${
          isCollapsed ? 'w-16' : 'w-64'
        }`}
      >
        <div className="flex flex-col h-full">
          {/* Logo and Toggle */}
          <div className="flex items-center justify-between p-4">
            {!isCollapsed && (
              <img src="/images/Logo_w.png" alt="Logo" className="h-8" />
            )}
            <button
              onClick={toggleSidebar}
              className="p-2 rounded-lg hover:bg-white/10 transition-colors"
            >
              {isCollapsed ? (
                <ChevronRight className="h-5 w-5" />
              ) : (
                <ChevronDown className="h-5 w-5" />
              )}
            </button>
          </div>

          {/* Command Palette Trigger */}
          <button
            onClick={() => setIsCommandOpen(true)}
            className="mx-4 mb-4 flex items-center space-x-2 px-4 py-2 bg-white/10 rounded-lg hover:bg-white/20 transition-colors"
          >
            <Search className="h-5 w-5" />
            {!isCollapsed && <span>{isFrench ? 'Rechercher...' : 'Search...'}</span>}
          </button>

          {/* Navigation and Sticky Logout */}
          <div className="flex-1 flex flex-col min-h-0">
            <nav className="flex-1 overflow-y-auto min-h-0">
              <ul className="space-y-2 px-4">
                {navigation.map((item) => (
                  <motion.li
                    key={item.href}
                    whileHover={{ scale: 1.02 }}
                    whileTap={{ scale: 0.98 }}
                  >
                    <Link
                      href={item.href}
                      className={`flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors ${
                        router.pathname === item.href
                          ? 'bg-white/10 text-white'
                          : 'text-white/70 hover:bg-white/5 hover:text-white'
                      }`}
                    >
                      <item.icon className="h-5 w-5 flex-shrink-0" />
                      {!isCollapsed && <span>{item.name}</span>}
                    </Link>
                  </motion.li>
                ))}
              </ul>
            </nav>
            {/* Sticky Logout Button */}
            <div className="sticky bottom-0 bg-gradient-to-t from-primary to-transparent p-4 mt-4">
              <button
                onClick={() => router.push('/auth/logout')}
                className="w-full flex items-center justify-center px-4 py-3 rounded-lg bg-white/20 hover:bg-white/30 text-white font-semibold transition-colors"
              >
                <Lock className="h-5 w-5 mr-2" />
                {!isCollapsed && (isFrench ? 'Déconnexion' : 'Logout')}
              </button>
            </div>
          </div>
        </div>
      </aside>

      {/* Command Palette */}
      <AnimatePresence>
        {isCommandOpen && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4"
            onClick={() => setIsCommandOpen(false)}
          >
            <motion.div
              initial={{ scale: 0.95, opacity: 0 }}
              animate={{ scale: 1, opacity: 1 }}
              exit={{ scale: 0.95, opacity: 0 }}
              className="bg-white rounded-xl shadow-xl w-full max-w-md overflow-hidden"
              onClick={e => e.stopPropagation()}
            >
              <Command className="p-4">
                <div className="flex items-center space-x-2 border-b pb-4">
                  <Search className="h-5 w-5 text-gray-400" />
                  <input
                    type="text"
                    placeholder={isFrench ? "Rechercher..." : "Search..."}
                    className="flex-1 outline-none"
                    value={searchQuery}
                    onChange={(e) => setSearchQuery(e.target.value)}
                  />
                </div>
                <div className="mt-4">
                  <Command.List>
                    {filteredNavigation.map((item) => (
                      <Command.Item
                        key={item.href}
                        onSelect={() => {
                          router.push(item.href);
                          setIsCommandOpen(false);
                        }}
                        className="flex items-center space-x-3 px-4 py-3 rounded-lg hover:bg-gray-100 cursor-pointer"
                      >
                        <item.icon className="h-5 w-5 text-primary" />
                        <span>{item.name}</span>
                      </Command.Item>
                    ))}
                  </Command.List>
                </div>
              </Command>
            </motion.div>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Main Content Spacer */}
      <div className={`transition-all duration-300 ease-in-out ${isCollapsed ? 'ml-16' : 'ml-64'}`} />
    </>
  );
}; 

CasperSecurity Mini