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/RealTimeStatusIndicator.tsx
'use client';

import React, { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { formatDistanceToNow } from 'date-fns';
import { 
  Wifi, 
  WifiOff, 
  Clock, 
  Activity,
  Zap
} from 'lucide-react';

interface UserStatus {
  userId: string;
  status: 'online' | 'away' | 'offline';
  timestamp: number;
}

interface RealTimeStatusIndicatorProps {
  userId: string;
  showDetails?: boolean;
  showPulse?: boolean;
}

const RealTimeStatusIndicator: React.FC<RealTimeStatusIndicatorProps> = ({ 
  userId, 
  showDetails = true,
  showPulse = true 
}) => {
  const [status, setStatus] = useState<UserStatus | null>(null);
  const [isLive, setIsLive] = useState(false);
  const [lastUpdate, setLastUpdate] = useState<number | null>(null);

  // Simulate real-time status updates (in real implementation, this would come from WebSocket)
  useEffect(() => {
    // Simulate initial status
    const initialStatus: UserStatus = {
      userId,
      status: Math.random() > 0.5 ? 'online' : 'away',
      timestamp: Date.now()
    };
    setStatus(initialStatus);
    setLastUpdate(Date.now());

    // Simulate status changes
    const interval = setInterval(() => {
      const shouldChangeStatus = Math.random() < 0.05; // 5% chance every 10 seconds
      
      if (shouldChangeStatus) {
        const newStatus: UserStatus = {
          userId,
          status: ['online', 'away', 'offline'][Math.floor(Math.random() * 3)] as UserStatus['status'],
          timestamp: Date.now()
        };
        
        setStatus(newStatus);
        setLastUpdate(Date.now());
        setIsLive(true);
        
        // Hide live indicator after 2 seconds
        setTimeout(() => setIsLive(false), 2000);
      }
    }, 10000);

    return () => clearInterval(interval);
  }, [userId]);

  const getStatusIcon = (status: UserStatus['status']) => {
    switch (status) {
      case 'online':
        return <Wifi className="h-4 w-4 text-green-500" />;
      case 'away':
        return <Clock className="h-4 w-4 text-yellow-500" />;
      case 'offline':
        return <WifiOff className="h-4 w-4 text-gray-400" />;
      default:
        return <Activity className="h-4 w-4 text-gray-400" />;
    }
  };

  const getStatusText = (status: UserStatus['status']) => {
    switch (status) {
      case 'online':
        return 'Online';
      case 'away':
        return 'Away';
      case 'offline':
        return 'Offline';
      default:
        return 'Unknown';
    }
  };

  const getStatusColor = (status: UserStatus['status']) => {
    switch (status) {
      case 'online':
        return 'text-green-600 bg-green-50 border-green-200';
      case 'away':
        return 'text-yellow-600 bg-yellow-50 border-yellow-200';
      case 'offline':
        return 'text-gray-500 bg-gray-50 border-gray-200';
      default:
        return 'text-gray-500 bg-gray-50 border-gray-200';
    }
  };

  const getPulseColor = (status: UserStatus['status']) => {
    switch (status) {
      case 'online':
        return 'bg-green-500';
      case 'away':
        return 'bg-yellow-500';
      case 'offline':
        return 'bg-gray-400';
      default:
        return 'bg-gray-400';
    }
  };

  if (!status) {
    return (
      <div className="flex items-center gap-2 text-gray-400">
        <Activity className="h-4 w-4 animate-spin" />
        <span className="text-sm">Loading status...</span>
      </div>
    );
  }

  return (
    <div className="flex items-center gap-2">
      {/* Status Indicator */}
      <div className="relative">
        <div className="flex items-center gap-2">
          {getStatusIcon(status.status)}
          
          {/* Pulse indicator for online status */}
          {showPulse && status.status === 'online' && (
            <motion.div
              className={`w-2 h-2 rounded-full ${getPulseColor(status.status)}`}
              animate={{ 
                scale: [1, 1.2, 1],
                opacity: [1, 0.7, 1]
              }}
              transition={{
                duration: 2,
                repeat: Infinity,
                ease: "easeInOut"
              }}
            />
          )}
        </div>
      </div>

      {/* Status Details */}
      {showDetails && (
        <div className="flex items-center gap-2">
          <span className={`text-sm font-medium ${getStatusColor(status.status).split(' ')[0]}`}>
            {getStatusText(status.status)}
          </span>
          
          {/* Live indicator */}
          {isLive && (
            <motion.div
              initial={{ opacity: 0, scale: 0.8 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.8 }}
              className="flex items-center gap-1"
            >
              <Zap className="h-3 w-3 text-green-500 animate-pulse" />
              <span className="text-xs text-green-600">Live</span>
            </motion.div>
          )}
          
          {/* Last update time */}
          {lastUpdate && (
            <span className="text-xs text-gray-400">
              {formatDistanceToNow(lastUpdate, { addSuffix: true })}
            </span>
          )}
        </div>
      )}
    </div>
  );
};

export default RealTimeStatusIndicator; 

CasperSecurity Mini