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.quebec/private_html/src/components/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/lavocat.quebec/private_html/src/components/CalendarChatIntegration.tsx
import React, { useState, useEffect } from 'react';
import { Calendar, MessageSquare, Users, Clock, MapPin, Bell, FileText, Phone, Video, ArrowRight, CheckCircle, AlertTriangle, Brain, Zap } from 'lucide-react';

interface CalendarEvent {
  id: string;
  title: string;
  date: string;
  time: string;
  type: 'court_hearing' | 'client_meeting' | 'detention_visit' | 'team_meeting';
  location: string;
  participants: string[];
  chatRoomId?: string;
  status: 'scheduled' | 'confirmed' | 'completed';
  priority: 'low' | 'medium' | 'high' | 'critical';
}

interface ChatRoom {
  id: string;
  name: string;
  description: string;
  participantCount: number;
  lastMessage?: string;
  unreadCount: number;
}

interface AIInsight {
  type: 'scheduling' | 'communication' | 'efficiency';
  message: string;
  action: string;
}

const CalendarChatIntegration: React.FC = () => {
  const [selectedDate, setSelectedDate] = useState(new Date());
  const [events, setEvents] = useState<CalendarEvent[]>([]);
  const [detentionChatRooms, setDetentionChatRooms] = useState<ChatRoom[]>([]);
  const [selectedEvent, setSelectedEvent] = useState<CalendarEvent | null>(null);
  const [showChatIntegration, setShowChatIntegration] = useState(false);
  const [aiInsights, setAiInsights] = useState<AIInsight[]>([]);

  useEffect(() => {
    loadCalendarEvents();
    loadDetentionChatRooms();
    loadAIInsights();
  }, []);

  const loadCalendarEvents = () => {
    const sampleEvents: CalendarEvent[] = [
      {
        id: 'evt_001',
        title: 'Bordeaux Detention Center Visit',
        date: '2025-03-10',
        time: '14:00',
        type: 'detention_visit',
        location: 'Bordeaux Detention Center, Montreal',
        participants: ['Client: Marie Dubois', 'Lawyer: Audrey Labrecque'],
        chatRoomId: 'bordeaux_montreal',
        status: 'scheduled',
        priority: 'high'
      },
      {
        id: 'evt_002',
        title: 'Class Action Case Strategy Meeting',
        date: '2025-03-10',
        time: '10:00',
        type: 'team_meeting',
        location: 'Office Conference Room A',
        participants: ['Justin Wee', 'Danny Perez', 'Audrey Labrecque', 'Marie-Christine Vachon'],
        chatRoomId: 'team_strategy',
        status: 'confirmed',
        priority: 'critical'
      },
      {
        id: 'evt_003',
        title: 'Quebec Superior Court Hearing',
        date: '2025-03-12',
        time: '09:30',
        type: 'court_hearing',
        location: 'Palais de Justice de Montréal, Room 2.09',
        participants: ['Justin Wee', 'Opposing Counsel'],
        status: 'scheduled',
        priority: 'critical'
      },
      {
        id: 'evt_004',
        title: 'Family Consultation - Rivière-des-Prairies',
        date: '2025-03-11',
        time: '15:30',
        type: 'client_meeting',
        location: 'Rivière-des-Prairies Detention Center',
        participants: ['Family Member: Jean Tremblay', 'Lawyer: David Frappier'],
        chatRoomId: 'riviere_des_prairies_montreal',
        status: 'scheduled',
        priority: 'medium'
      }
    ];
    setEvents(sampleEvents);
  };

  const loadDetentionChatRooms = () => {
    const quebecDetentionRooms: ChatRoom[] = [
      {
        id: 'bordeaux_montreal',
        name: 'Bordeaux (Montréal)',
        description: 'Établissement de détention de Bordeaux - Montréal',
        participantCount: 8,
        lastMessage: 'Nouvelle visite programmée pour demain',
        unreadCount: 3
      },
      {
        id: 'riviere_des_prairies_montreal',
        name: 'Rivière-des-Prairies (Montréal)',
        description: 'Centre de détention Rivière-des-Prairies',
        participantCount: 5,
        lastMessage: 'Documents médicaux requis',
        unreadCount: 1
      },
      {
        id: 'leclerc_laval',
        name: 'Leclerc (Laval)',
        description: 'Institut Leclerc - Établissement fédéral',
        participantCount: 6,
        lastMessage: 'Transfert prévu la semaine prochaine',
        unreadCount: 0
      },
      {
        id: 'orsainville_quebec',
        name: 'Orsainville (Québec)',
        description: 'Établissement de détention de Québec',
        participantCount: 4,
        lastMessage: 'Rendez-vous médical confirmé',
        unreadCount: 2
      },
      {
        id: 'maison_tanguay_femmes',
        name: 'Maison Tanguay (Femmes)',
        description: 'Établissement pour femmes - Montréal',
        participantCount: 3,
        lastMessage: 'Visite familiale autorisée',
        unreadCount: 0
      },
      {
        id: 'sherbrooke',
        name: 'Sherbrooke',
        description: 'Établissement de détention de Sherbrooke',
        participantCount: 2,
        lastMessage: 'Nouvelle demande de libération conditionnelle',
        unreadCount: 1
      }
    ];
    setDetentionChatRooms(quebecDetentionRooms);
  };

  const loadAIInsights = () => {
    const insights: AIInsight[] = [
      {
        type: 'scheduling',
        message: 'Optimal time for Bordeaux visits: Tuesday-Thursday 2-4 PM (87% success rate)',
        action: 'Reschedule upcoming visits to recommended time slots'
      },
      {
        type: 'communication',
        message: '23 unread messages across detention center chats may contain urgent requests',
        action: 'Review and prioritize detention center communications'
      },
      {
        type: 'efficiency',
        message: 'Calendar-chat integration saved 18.5 hours this month vs manual coordination',
        action: 'Continue using integrated workflow for all detention visits'
      }
    ];
    setAiInsights(insights);
  };

  const handleEventClick = (event: CalendarEvent) => {
    setSelectedEvent(event);
    setShowChatIntegration(true);
  };

  const handleJoinChat = (chatRoomId: string) => {
    // This would integrate with the existing GroupChat component
    window.open(`/chat?room=${chatRoomId}`, '_blank');
  };

  const typeColors = {
    court_hearing: 'bg-red-100 text-red-800 border-red-200',
    client_meeting: 'bg-blue-100 text-blue-800 border-blue-200',
    detention_visit: 'bg-purple-100 text-purple-800 border-purple-200',
    team_meeting: 'bg-green-100 text-green-800 border-green-200'
  };

  const priorityColors = {
    low: 'bg-gray-100 text-gray-800',
    medium: 'bg-yellow-100 text-yellow-800',
    high: 'bg-orange-100 text-orange-800',
    critical: 'bg-red-100 text-red-800'
  };

  const statusIcons = {
    scheduled: Clock,
    confirmed: CheckCircle,
    completed: CheckCircle
  };

  return (
    <div className="min-h-screen bg-gradient-to-br from-blue-50 via-purple-50 to-indigo-50 p-6">
      {/* Header */}
      <div className="mb-8">
        <div className="flex items-center justify-between">
          <div>
            <h1 className="text-3xl font-bold bg-gradient-to-r from-purple-600 to-blue-600 bg-clip-text text-transparent">
              📅💬 Calendar-Chat Integration Demo
            </h1>
            <p className="text-gray-600 mt-2">
              Revolutionary integration between calendar events and Quebec detention center chat rooms
            </p>
          </div>
          <div className="flex items-center space-x-4">
            <div className="bg-white rounded-lg p-3 shadow-md">
              <div className="text-sm font-medium text-gray-600">Quebec Detention Centers</div>
              <div className="text-2xl font-bold text-purple-600">56 Active</div>
            </div>
            <div className="bg-white rounded-lg p-3 shadow-md">
              <div className="text-sm font-medium text-gray-600">Total Participants</div>
              <div className="text-2xl font-bold text-green-600">28</div>
            </div>
          </div>
        </div>
      </div>

      {/* AI Insights */}
      <div className="mb-8 bg-white rounded-xl shadow-lg border border-gray-100 p-6">
        <h2 className="text-xl font-bold text-gray-900 mb-4 flex items-center">
          <Brain className="h-5 w-5 mr-2 text-purple-600" />
          AI-Powered Insights
        </h2>
        <div className="grid grid-cols-3 gap-4">
          {aiInsights.map((insight, index) => (
            <div key={index} className="p-4 bg-gradient-to-r from-purple-50 to-blue-50 rounded-lg border border-purple-200">
              <div className="flex items-center space-x-2 mb-2">
                <Zap className="h-4 w-4 text-purple-600" />
                <span className="text-sm font-semibold text-purple-700 uppercase">{insight.type}</span>
              </div>
              <p className="text-sm text-gray-700 mb-3">{insight.message}</p>
              <button className="text-xs bg-purple-600 text-white px-3 py-1 rounded-full hover:bg-purple-700 transition-colors">
                {insight.action}
              </button>
            </div>
          ))}
        </div>
      </div>

      <div className="grid grid-cols-3 gap-8">
        {/* Calendar Events */}
        <div className="col-span-2">
          <div className="bg-white rounded-xl shadow-lg border border-gray-100 p-6">
            <h2 className="text-xl font-bold text-gray-900 mb-6 flex items-center">
              <Calendar className="h-5 w-5 mr-2" />
              Upcoming Legal Events
            </h2>
            
            <div className="space-y-4">
              {events.map((event) => {
                const StatusIcon = statusIcons[event.status];
                return (
                  <div 
                    key={event.id}
                    onClick={() => handleEventClick(event)}
                    className="p-4 border border-gray-200 rounded-lg hover:shadow-md hover:border-purple-300 transition-all cursor-pointer"
                  >
                    <div className="flex items-center justify-between mb-3">
                      <div className="flex items-center space-x-3">
                        <h3 className="font-semibold text-gray-900">{event.title}</h3>
                        <span className={`px-2 py-1 rounded-full text-xs font-medium ${typeColors[event.type]}`}>
                          {event.type.replace('_', ' ').toUpperCase()}
                        </span>
                      </div>
                      <div className="flex items-center space-x-2">
                        <span className={`px-2 py-1 rounded-full text-xs font-medium ${priorityColors[event.priority]}`}>
                          {event.priority.toUpperCase()}
                        </span>
                        <StatusIcon className="h-4 w-4 text-green-600" />
                      </div>
                    </div>
                    
                    <div className="grid grid-cols-2 gap-4 text-sm text-gray-600">
                      <div className="flex items-center space-x-2">
                        <Clock className="h-4 w-4" />
                        <span>{event.date} at {event.time}</span>
                      </div>
                      <div className="flex items-center space-x-2">
                        <MapPin className="h-4 w-4" />
                        <span>{event.location}</span>
                      </div>
                    </div>
                    
                    <div className="mt-3 flex items-center justify-between">
                      <div className="flex items-center space-x-2 text-sm text-gray-600">
                        <Users className="h-4 w-4" />
                        <span>{event.participants.length} participants</span>
                      </div>
                      
                      <div className="flex items-center space-x-2">
                        {event.chatRoomId && (
                          <button className="flex items-center space-x-1 px-3 py-1 bg-purple-100 text-purple-700 rounded-full text-xs font-medium hover:bg-purple-200 transition-colors">
                            <MessageSquare className="h-3 w-3" />
                            <span>Chat Room</span>
                          </button>
                        )}
                        <button className="flex items-center space-x-1 px-3 py-1 bg-blue-100 text-blue-700 rounded-full text-xs font-medium hover:bg-blue-200 transition-colors">
                          <span>View Details</span>
                          <ArrowRight className="h-3 w-3" />
                        </button>
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>

        {/* Quebec Detention Center Chat Rooms */}
        <div>
          <div className="bg-white rounded-xl shadow-lg border border-gray-100 p-6">
            <h2 className="text-xl font-bold text-gray-900 mb-6 flex items-center">
              <MessageSquare className="h-5 w-5 mr-2" />
              Quebec Detention Centers
            </h2>
            
            <div className="space-y-3">
              {detentionChatRooms.map((room) => (
                <div key={room.id} className="p-3 border border-gray-200 rounded-lg hover:shadow-md transition-all">
                  <div className="flex items-center justify-between mb-2">
                    <h3 className="font-semibold text-gray-900 text-sm">{room.name}</h3>
                    {room.unreadCount > 0 && (
                      <span className="bg-red-500 text-white text-xs px-2 py-1 rounded-full">
                        {room.unreadCount}
                      </span>
                    )}
                  </div>
                  
                  <p className="text-xs text-gray-600 mb-2">{room.description}</p>
                  
                  {room.lastMessage && (
                    <p className="text-xs text-gray-500 italic mb-2">"{room.lastMessage}"</p>
                  )}
                  
                  <div className="flex items-center justify-between">
                    <div className="flex items-center space-x-2 text-xs text-gray-600">
                      <Users className="h-3 w-3" />
                      <span>{room.participantCount} participants</span>
                    </div>
                    
                    <button 
                      onClick={() => handleJoinChat(room.id)}
                      className="flex items-center space-x-1 px-2 py-1 bg-purple-600 text-white rounded text-xs hover:bg-purple-700 transition-colors"
                    >
                      <MessageSquare className="h-3 w-3" />
                      <span>Join</span>
                    </button>
                  </div>
                </div>
              ))}
            </div>
            
            <div className="mt-6 p-4 bg-gradient-to-r from-green-50 to-blue-50 rounded-lg border border-green-200">
              <h4 className="font-semibold text-green-700 mb-2">🏆 Competitive Advantage</h4>
              <ul className="text-xs text-green-600 space-y-1">
                <li>✅ 56 Quebec detention centers integrated</li>
                <li>✅ Real-time bilingual chat support</li>
                <li>✅ Calendar-chat synchronization</li>
                <li>✅ AI-powered scheduling optimization</li>
                <li>❌ Clio: No detention center integration</li>
                <li>❌ MyCase: No Quebec specialization</li>
                <li>❌ LegalZoom: No practice management</li>
              </ul>
            </div>
          </div>
        </div>
      </div>

      {/* Event Detail Modal */}
      {showChatIntegration && selectedEvent && (
        <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
          <div className="bg-white rounded-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto">
            <div className="p-6 border-b border-gray-200">
              <div className="flex items-center justify-between">
                <h2 className="text-xl font-bold text-gray-900">{selectedEvent.title}</h2>
                <button 
                  onClick={() => setShowChatIntegration(false)}
                  className="p-2 hover:bg-gray-100 rounded-lg transition-colors"
                >
                  ✕
                </button>
              </div>
            </div>
            
            <div className="p-6">
              <div className="grid grid-cols-2 gap-6 mb-6">
                <div>
                  <h3 className="font-semibold text-gray-900 mb-3">Event Details</h3>
                  <div className="space-y-2 text-sm">
                    <div className="flex items-center space-x-2">
                      <Clock className="h-4 w-4 text-gray-500" />
                      <span>{selectedEvent.date} at {selectedEvent.time}</span>
                    </div>
                    <div className="flex items-center space-x-2">
                      <MapPin className="h-4 w-4 text-gray-500" />
                      <span>{selectedEvent.location}</span>
                    </div>
                    <div className="flex items-center space-x-2">
                      <Users className="h-4 w-4 text-gray-500" />
                      <span>{selectedEvent.participants.join(', ')}</span>
                    </div>
                  </div>
                </div>
                
                <div>
                  <h3 className="font-semibold text-gray-900 mb-3">Chat Integration</h3>
                  {selectedEvent.chatRoomId ? (
                    <div className="space-y-3">
                      <p className="text-sm text-gray-600">
                        This event is linked to the Quebec detention center chat room
                      </p>
                      <button 
                        onClick={() => handleJoinChat(selectedEvent.chatRoomId!)}
                        className="flex items-center space-x-2 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors"
                      >
                        <MessageSquare className="h-4 w-4" />
                        <span>Join Chat Room</span>
                      </button>
                    </div>
                  ) : (
                    <p className="text-sm text-gray-500">No chat room linked to this event</p>
                  )}
                </div>
              </div>
              
              <div className="border-t pt-6">
                <h3 className="font-semibold text-gray-900 mb-3">Quick Actions</h3>
                <div className="flex items-center space-x-3">
                  <button className="flex items-center space-x-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">
                    <Video className="h-4 w-4" />
                    <span>Start Video Call</span>
                  </button>
                  <button className="flex items-center space-x-2 px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors">
                    <Phone className="h-4 w-4" />
                    <span>Voice Call</span>
                  </button>
                  <button className="flex items-center space-x-2 px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 transition-colors">
                    <FileText className="h-4 w-4" />
                    <span>Generate Documents</span>
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default CalendarChatIntegration; 

CasperSecurity Mini