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/public_html/src/components/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/lavocat.ca/public_html/src/components/LiveCaseFeed.tsx
import React, { useState, useEffect, useRef } from 'react';
import { useSession } from 'next-auth/react';
import Link from 'next/link';
import { motion, AnimatePresence, useInView } from 'framer-motion';
import { useRouter } from 'next/router';
import { 
  Eye, MessageCircle, Users, Clock, DollarSign, Badge, Star, 
  Heart, Share2, BookOpen, Scale, AlertTriangle, TrendingUp,
  Filter, Search, Calendar, MapPin, User, Award, Briefcase,
  ExternalLink, Send, ThumbsUp, MessageSquare, UserPlus, CheckCircle,
  Zap, Sparkles, Diamond, Crown, Brain,
  ArrowRight, ArrowUpRight, Target, Globe, Shield, X as XIcon,
  FileText
} from 'lucide-react';
import toast from 'react-hot-toast';
import LawyerRatingStars from './LawyerRatingStars';
import { CompetitionCountdown } from './CompetitionCountdown';
import EnhancedShareButton from './EnhancedShareButton';
import OpenGraphMeta from './OpenGraphMeta';

interface LiveCase {
  id: string;
  title: string;
  description: string;
  publicSummary?: string;
  category: string;
  legalArea: string;
  urgencyLevel: 'URGENT' | 'HIGH' | 'NORMAL' | 'LOW';
  status: string;
  jurisdiction: string;
  court?: string;
  viewCount: number;
  supporterCount: number;
  estimatedValue?: number;
  riskLevel: 'HIGH' | 'MEDIUM' | 'LOW';
  tags?: string[];
  createdAt: string;
  updatedAt: string;
  competitionDeadline?: string;
  minimumBid?: number;
  currentHighestBid?: number;
  totalBidders?: number;
  averageBidAmount?: number;
  competitionType?: 'AUCTION' | 'TENDER' | 'NEGOTIATION';
  isPublic: boolean;
  logoUrl?: string;
  leadLawyer: {
    id: string;
    name: string;
    username?: string;
    profilePicture?: string;
    specialization?: string;
    averageRating?: number;
    totalCases: number;
    wonCases: number;
    proBono: boolean;
    hourlyRate?: number;
    isVerified: boolean;
    successRate?: number;
    totalEarnings?: number;
    responseTime?: number;
    clientSatisfaction?: number;
  };
  creator: {
    id: string;
    name: string;
    username?: string;
  };
  _count: {
    offers: number;
    registrations: number;
    supporters: number;
    views: number;
    comments: number;
    lawyerRequests: number;
  };
  comments?: CaseComment[];
  lawyerRequests?: LawyerRequest[];
}

interface CaseComment {
  id: string;
  content: string;
  createdAt: string;
  user: {
    id: string;
    name: string;
    profilePicture?: string;
    role: string;
  };
  likes: number;
  replies?: CaseComment[];
}

interface LawyerRequest {
  id: string;
  lawyerId: string;
  message: string;
  proposedRate?: number;
  estimatedHours?: number;
  reasoning: string;
  status: 'PENDING' | 'APPROVED' | 'REJECTED';
  createdAt: string;
  lawyer: {
    id: string;
    name: string;
    profilePicture?: string;
    specialization?: string;
    averageRating?: number;
    proBono: boolean;
    isVerified: boolean;
    successRate?: number;
    totalCases: number;
    wonCases: number;
  };
}

const LiveCaseFeed: React.FC = () => {
  const { data: session } = useSession();
  const router = useRouter();
  const [cases, setCases] = useState<LiveCase[]>([]);
  const [loading, setLoading] = useState(true);
  const [filter, setFilter] = useState('all');
  const [sortBy, setSortBy] = useState('newest');
  const [searchTerm, setSearchTerm] = useState('');
  const [selectedCase, setSelectedCase] = useState<LiveCase | null>(null);
  const [showRequestModal, setShowRequestModal] = useState(false);
  const [showCommentsModal, setShowCommentsModal] = useState(false);
  const [newComment, setNewComment] = useState('');
  const [requestData, setRequestData] = useState({
    message: '',
    proposedRate: '',
    estimatedHours: '',
    reasoning: ''
  });

  useEffect(() => {
    fetchLiveCases();
  }, [filter, sortBy, searchTerm]);

  const fetchLiveCases = async () => {
    try {
      setLoading(true);
      const params = new URLSearchParams({
        filter,
        sortBy,
        search: searchTerm
      });
      
      const response = await fetch(`/api/live-cases?${params}`);
      if (response.ok) {
        const data = await response.json();
        setCases(Array.isArray(data.cases) ? data.cases : []);
      } else {
        console.error('Failed to load cases:', response.status, response.statusText);
        toast.error('Failed to load cases');
        setCases([]);
      }
    } catch (error) {
      console.error('Error fetching cases:', error);
      toast.error('Error loading cases');
      setCases([]);
    } finally {
      setLoading(false);
    }
  };

  const handleViewCase = async (caseId: string) => {
    await fetch(`/api/live-cases/${caseId}/view`, { method: 'POST' });
    setCases(prev => prev.map(c => 
      c.id === caseId ? { ...c, viewCount: c.viewCount + 1 } : c
    ));
  };

  const handleSupportCase = async (caseId: string) => {
    if (!session) {
      toast.error('Please login to support cases');
      return;
    }

    try {
      const response = await fetch(`/api/live-cases/${caseId}/support`, {
        method: 'POST'
      });
      
      if (response.ok) {
        setCases(prev => prev.map(c => 
          c.id === caseId ? { ...c, supporterCount: c.supporterCount + 1 } : c
        ));
        toast.success('Case supported! 💪');
      }
    } catch (error) {
      toast.error('Failed to support case');
    }
  };

  const handleRequestCase = async (caseId: string) => {
    if (!session || session.user.role !== 'LAWYER') {
      toast.error('Only verified lawyers can request cases');
      return;
    }

    const selectedCaseData = cases.find(c => c.id === caseId);
    setSelectedCase(selectedCaseData || null);
    setShowRequestModal(true);
  };

  const submitRequest = async () => {
    if (!selectedCase || !requestData.message || !requestData.reasoning) {
      toast.error('Please fill in all required fields');
      return;
    }

    try {
      const response = await fetch(`/api/live-cases/${selectedCase.id}/request`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          message: requestData.message,
          proposedRate: requestData.proposedRate ? parseFloat(requestData.proposedRate) : undefined,
          estimatedHours: requestData.estimatedHours ? parseInt(requestData.estimatedHours) : undefined,
          reasoning: requestData.reasoning
        }),
      });

      if (response.ok) {
        toast.success('Request sent successfully! 🎉');
        setShowRequestModal(false);
        setRequestData({ message: '', proposedRate: '', estimatedHours: '', reasoning: '' });
      } else {
        toast.error('Failed to send request');
      }
    } catch (error) {
      toast.error('Error sending request');
    }
  };

  const handleAddComment = async (caseId: string) => {
    if (!newComment.trim()) {
      toast.error('Please enter a comment');
      return;
    }

    try {
      const response = await fetch(`/api/live-cases/${caseId}/comments`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ content: newComment }),
      });

      if (response.ok) {
        setNewComment('');
        toast.success('Comment added! 💬');
        // Refresh comments
        fetchLiveCases();
      } else {
        toast.error('Failed to add comment');
      }
    } catch (error) {
      toast.error('Error adding comment');
    }
  };

  const handleLikeComment = async (caseId: string, commentId: string) => {
    try {
      const response = await fetch(`/api/live-cases/${caseId}/comments/${commentId}/like`, {
        method: 'POST',
      });

      if (response.ok) {
        toast.success('Comment liked! 👍');
        // Refresh comments
        fetchLiveCases();
      }
    } catch (error) {
      toast.error('Error liking comment');
    }
  };

  const getUrgencyColor = (urgency: string) => {
    switch (urgency) {
      case 'URGENT':
        return 'bg-red-500/20 text-red-300 border-red-500/30';
      case 'HIGH':
        return 'bg-orange-500/20 text-orange-300 border-orange-500/30';
      case 'NORMAL':
        return 'bg-blue-500/20 text-blue-300 border-blue-500/30';
      case 'LOW':
        return 'bg-green-500/20 text-green-300 border-green-500/30';
      default:
        return 'bg-gray-500/20 text-gray-300 border-gray-500/30';
    }
  };

  const getRiskColor = (risk: string) => {
    switch (risk) {
      case 'HIGH':
        return 'bg-red-500/20 text-red-300 border-red-500/30';
      case 'MEDIUM':
        return 'bg-yellow-500/20 text-yellow-300 border-yellow-500/30';
      case 'LOW':
        return 'bg-green-500/20 text-green-300 border-green-500/30';
      default:
        return 'bg-gray-500/20 text-gray-300 border-gray-500/30';
    }
  };

  const getCompetitionStatus = (case_: LiveCase) => {
    if (!case_.competitionDeadline) return null;
    const deadline = new Date(case_.competitionDeadline);
    const now = new Date();
    const diff = deadline.getTime() - now.getTime();
    const hoursLeft = diff / (1000 * 60 * 60);
    
    if (hoursLeft < 0) return 'ENDED';
    if (hoursLeft < 24) return 'ENDING_SOON';
    return 'LIVE';
  };

  const getCompetitionBadge = (case_: LiveCase) => {
    const status = getCompetitionStatus(case_);
    if (!status) return null;

    const badges = {
      LIVE: { text: '🔥 Live', color: 'bg-green-500/20 text-green-300 border-green-500/30' },
      ENDING_SOON: { text: '⏰ Ending Soon', color: 'bg-orange-500/20 text-orange-300 border-orange-500/30' },
      ENDED: { text: '🏁 Ended', color: 'bg-gray-500/20 text-gray-300 border-gray-500/30' }
    };

    return badges[status];
  };

  // Enhanced Case Card Component
  const CaseCard = ({ case_: caseData, index }: { case_: LiveCase; index: number }) => {
    const cardRef = useRef<HTMLDivElement>(null);
    const isInView = useInView(cardRef, { once: true, margin: "-50px" });
    const competitionBadge = getCompetitionBadge(caseData);

    return (
      <motion.div
        ref={cardRef}
        key={caseData.id}
        className="relative group overflow-hidden"
        initial={{ opacity: 0, y: 50, scale: 0.9 }}
        animate={isInView ? { opacity: 1, y: 0, scale: 1 } : {}}
        transition={{ duration: 0.6, delay: index * 0.1 }}
        whileHover={{ 
          scale: 1.02,
          y: -5,
          transition: { duration: 0.3 }
        }}
      >
        {/* Glassmorphism Card Background */}
        <div className="bg-white rounded-3xl border border-gray-200 shadow-md overflow-hidden">
          {/* Animated gradient overlay */}
          <div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/5 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-1000 ease-out"></div>
          
          {/* Floating particles */}
          <div className="absolute top-4 right-4 opacity-20 group-hover:opacity-40 transition-opacity">
            <Sparkles className="h-5 w-5 text-gray-400 animate-pulse" />
      </div>

          <div className="relative p-8">
            <div className="flex items-start gap-6">
              {/* Case Logo */}
              <div className="flex-shrink-0">
                <div className="relative">
                  {caseData.logoUrl ? (
                    <img
                      src={caseData.logoUrl}
                      alt={`${caseData.title} Logo`}
                      className="w-16 h-16 rounded-2xl object-cover border-2 border-gray-200 shadow-sm"
                    />
                  ) : (
                    <div className="w-16 h-16 rounded-2xl bg-gradient-to-br from-blue-500/20 to-indigo-500/20 border-2 border-gray-200 flex items-center justify-center">
                      <FileText className="w-8 h-8 text-gray-600" />
                    </div>
                  )}
                </div>
              </div>

              {/* Enhanced Avatar */}
              <div className="flex-shrink-0">
                <div className="relative">
                  {caseData.leadLawyer.profilePicture ? (
                    <img
                      src={caseData.leadLawyer.profilePicture}
                      alt={caseData.leadLawyer.name}
                      className="w-16 h-16 rounded-2xl object-cover border-2 border-gray-200"
                  />
                ) : (
                    <div className="w-16 h-16 rounded-2xl bg-gradient-to-br from-purple-500/20 to-pink-500/20 border-2 border-gray-200 flex items-center justify-center">
                      <User className="w-8 h-8 text-gray-600" />
                    </div>
                  )}
                  {caseData.leadLawyer.isVerified && (
                    <div className="absolute -top-1 -right-1 p-1 bg-blue-500 rounded-full">
                      <CheckCircle className="w-4 h-4 text-white" />
                  </div>
                )}
                </div>
              </div>

              {/* Content */}
              <div className="flex-1 min-w-0">
                <div className="flex items-start justify-between mb-4">
                  <div className="flex-1">
                    <div className="flex items-center gap-3 mb-3">
                      <h3 className="text-xl font-bold text-gray-900 group-hover:text-blue-600 transition-colors">
                        {caseData.title}
                    </h3>
                      {competitionBadge && (
                        <span className={`px-3 py-1 text-xs rounded-full border ${competitionBadge.color}`}>
                          {competitionBadge.text}
                        </span>
                      )}
                    </div>
                    
                    <div className="flex items-center gap-3 mb-4 flex-wrap">
                      <span className="text-sm text-gray-700 bg-blue-100 px-3 py-1 rounded-full">
                        {caseData.legalArea}
                      </span>
                      <span className={`px-3 py-1 text-xs rounded-full border ${getUrgencyColor(caseData.urgencyLevel)}`}>
                        {caseData.urgencyLevel}
                      </span>
                      <span className={`px-3 py-1 text-xs rounded-full border ${getRiskColor(caseData.riskLevel)}`}>
                        {caseData.riskLevel} Risk
                      </span>
                      {caseData.estimatedValue && (
                        <span className="text-sm text-green-300 bg-green-100 px-3 py-1 rounded-full">
                          ${caseData.estimatedValue.toLocaleString()}
                        </span>
                      )}
                    </div>
                  </div>
                  
                  <div className="text-right text-sm text-gray-600">
                    <div className="flex items-center gap-1 mb-1">
                      <Calendar className="w-4 h-4" />
                      {new Date(caseData.createdAt).toLocaleDateString()}
                    </div>
                    <div className="text-xs bg-gray-100 px-2 py-1 rounded-full">
                      {caseData.status}
                    </div>
                  </div>
                </div>

                <p className="text-gray-800 mb-6 leading-relaxed">
                  {(caseData.publicSummary || caseData.description).length > 200 
                    ? (caseData.publicSummary || caseData.description).substring(0, 200) + '...'
                    : (caseData.publicSummary || caseData.description)
                  }
                </p>

                {/* Enhanced Stats */}
                <div className="flex items-center gap-6 text-sm text-gray-600 mb-6">
                  <div className="flex items-center gap-2 bg-gray-100 px-3 py-2 rounded-full">
                    <Eye className="w-4 h-4" />
                    <span className="font-medium">{caseData.viewCount}</span>
                  </div>
                  <div className="flex items-center gap-2 bg-gray-100 px-3 py-2 rounded-full">
                    <Users className="w-4 h-4" />
                    <span className="font-medium">{caseData.supporterCount}</span>
                  </div>
                  <div className="flex items-center gap-2 bg-gray-100 px-3 py-2 rounded-full">
                    <MessageCircle className="w-4 h-4" />
                    <span className="font-medium">{caseData._count.comments || 0}</span>
                  </div>
                  <div className="flex items-center gap-2 bg-gray-100 px-3 py-2 rounded-full">
                    <UserPlus className="w-4 h-4" />
                    <span className="font-medium">{caseData._count.registrations || 0}</span>
                  </div>
                </div>

                {/* Enhanced Actions */}
                <div className="flex gap-3 flex-wrap">
                  <button
                    onClick={() => router.push(`/public/cases/${caseData.id}`)}
                    className="px-5 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors font-medium flex items-center gap-2"
                  >
                    <Eye className="w-4 h-4 group-hover/btn:scale-110 transition-transform" />
                    View Details
                  </button>
                  
                  {session?.user?.role === 'LAWYER' ? (
                    <button
                      onClick={() => handleRequestCase(caseData.id)}
                      className="px-5 py-2 bg-blue-100 text-blue-700 rounded-md hover:bg-blue-200 transition-colors font-medium flex items-center gap-2"
                    >
                      <Target className="w-4 h-4" />
                      Request
                    </button>
                  ) : session?.user && (
                    <button
                      onClick={() => router.push(`/user/registrations/new?caseId=${caseData.id}`)}
                      className="px-5 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors font-medium flex items-center gap-2"
                    >
                      <ArrowRight className="w-4 h-4" />
                      Apply
                    </button>
                  )}
                  
                  <button
                    onClick={() => handleSupportCase(caseData.id)}
                    className="px-5 py-2 border border-gray-300 text-blue-700 rounded-md hover:bg-gray-50 transition-colors font-medium flex items-center gap-2"
                  >
                    <Heart className="w-4 h-4" />
                    Support
                  </button>
                  
                  <EnhancedShareButton
                    url={`${typeof window !== 'undefined' ? window.location.origin : ''}/public/cases/${caseData.id}`}
                    title={caseData.title}
                    description={caseData.publicSummary || caseData.description}
                    hashtags={caseData.tags || ['legal', 'case', caseData.legalArea.toLowerCase()]}
                    variant="minimal"
                    className="px-5 py-2 border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50 transition-colors font-medium flex items-center gap-2 z-50"
                  />
                </div>
              </div>
            </div>
          </div>
        </div>
      </motion.div>
    );
  };

  if (loading) {
    return (
      <div className="flex justify-center items-center py-12">
        <div className="relative">
          <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
        </div>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Filter/Search Bar - dashboard style */}
      <div className="bg-white rounded-lg shadow-sm border p-4 flex flex-col md:flex-row md:items-center gap-4 mb-2">
        <div className="flex-1">
          <div className="relative">
            <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-5 w-5" />
            <input
              type="text"
              placeholder="Search cases by title, description, or legal area..."
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
              className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent text-gray-900 placeholder-gray-400 bg-white"
            />
          </div>
        </div>
        <div className="flex gap-2">
          <select
            value={filter}
            onChange={(e) => setFilter(e.target.value)}
            className="px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent text-gray-900 bg-white"
          >
            <option value="all">All Cases</option>
            <option value="urgent">Urgent</option>
            <option value="criminal">Criminal</option>
            <option value="civil">Civil</option>
            <option value="human_rights">Human Rights</option>
            <option value="immigration">Immigration</option>
            <option value="family">Family</option>
            <option value="corporate">Corporate</option>
          </select>
          <select
            value={sortBy}
            onChange={(e) => setSortBy(e.target.value)}
            className="px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent text-gray-900 bg-white"
          >
            <option value="newest">Newest</option>
            <option value="urgent">Most Urgent</option>
            <option value="popular">Most Popular</option>
            <option value="deadline">Deadline</option>
          </select>
        </div>
      </div>

      {/* Cases List */}
      <div className="space-y-4">
        {cases.length === 0 ? (
          <div className="text-center py-16">
            <div className="bg-white rounded-lg border shadow-sm p-12">
              <BookOpen className="w-16 h-16 text-gray-200 mx-auto mb-6" />
              <h3 className="text-2xl font-bold text-gray-900 mb-4">No Cases Found</h3>
              <p className="text-gray-500 text-lg mb-8">
                Try adjusting your filters or search terms to find more cases.
              </p>
              <button
                onClick={() => {
                  setFilter('all');
                  setSearchTerm('');
                  setSortBy('newest');
                }}
                className="px-8 py-4 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-all duration-300 font-medium"
              >
                Reset Filters
              </button>
            </div>
          </div>
        ) : (
          cases.map((case_, index) => (
            <CaseCard key={case_.id} case_={case_} index={index} />
          ))
        )}
      </div>

      {/* Enhanced Lawyer Request Modal */}
      <AnimatePresence>
        {showRequestModal && selectedCase && (
          <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm">
            <motion.div
              initial={{ opacity: 0, scale: 0.95 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.95 }}
              className="bg-white/10 backdrop-blur-xl rounded-3xl border border-white/20 shadow-2xl max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto"
            >
              <div className="p-8">
                <div className="flex items-center justify-between mb-6">
                  <h3 className="text-2xl font-bold text-white">Request to Represent</h3>
                  <button
                    onClick={() => setShowRequestModal(false)}
                    className="text-white/50 hover:text-white transition-colors p-2 hover:bg-white/10 rounded-full"
                  >
                    <XIcon className="w-6 h-6" />
                  </button>
                </div>

                <div className="mb-6 p-4 bg-white/10 rounded-2xl border border-white/20">
                  <h4 className="font-bold text-lg text-white mb-2">{selectedCase.title}</h4>
                  <p className="text-white/70">{selectedCase.legalArea}</p>
                </div>

                <div className="space-y-6">
                  <div>
                    <label className="block text-sm font-medium text-white/80 mb-2">
                      Message to Client *
                    </label>
                    <textarea
                      value={requestData.message}
                      onChange={(e) => setRequestData({...requestData, message: e.target.value})}
                      placeholder="Introduce yourself and explain your interest in this case..."
                      className="w-full px-4 py-3 bg-white/10 border border-white/20 rounded-2xl focus:ring-2 focus:ring-purple-500 focus:border-transparent text-white placeholder-white/50 backdrop-blur-sm"
                      rows={3}
                    />
                  </div>

                  <div>
                    <label className="block text-sm font-medium text-white/80 mb-2">
                      Why You're the Best Fit *
                    </label>
                    <textarea
                      value={requestData.reasoning}
                      onChange={(e) => setRequestData({...requestData, reasoning: e.target.value})}
                      placeholder="Explain your experience, expertise, and why you're uniquely qualified..."
                      className="w-full px-4 py-3 bg-white/10 border border-white/20 rounded-2xl focus:ring-2 focus:ring-purple-500 focus:border-transparent text-white placeholder-white/50 backdrop-blur-sm"
                      rows={3}
                    />
                  </div>

                  <div className="grid grid-cols-2 gap-4">
                    <div>
                      <label className="block text-sm font-medium text-white/80 mb-2">
                        Proposed Rate (CAD/hr)
                      </label>
                      <input
                        type="number"
                        value={requestData.proposedRate}
                        onChange={(e) => setRequestData({...requestData, proposedRate: e.target.value})}
                        placeholder="200"
                        className="w-full px-4 py-3 bg-white/10 border border-white/20 rounded-2xl focus:ring-2 focus:ring-purple-500 focus:border-transparent text-white placeholder-white/50 backdrop-blur-sm"
                      />
                    </div>
                    <div>
                      <label className="block text-sm font-medium text-white/80 mb-2">
                        Est. Hours
                      </label>
                      <input
                        type="number"
                        value={requestData.estimatedHours}
                        onChange={(e) => setRequestData({...requestData, estimatedHours: e.target.value})}
                        placeholder="40"
                        className="w-full px-4 py-3 bg-white/10 border border-white/20 rounded-2xl focus:ring-2 focus:ring-purple-500 focus:border-transparent text-white placeholder-white/50 backdrop-blur-sm"
                      />
                    </div>
                  </div>
                </div>

                <div className="flex gap-4 mt-8">
                  <button
                    onClick={() => setShowRequestModal(false)}
                    className="flex-1 px-6 py-4 border border-white/20 text-white/80 rounded-2xl hover:bg-white/10 transition-all duration-300 font-medium"
                  >
                    Cancel
                  </button>
                  <button
                    onClick={submitRequest}
                    className="flex-1 bg-gradient-to-r from-purple-500 to-pink-600 text-white px-6 py-4 rounded-2xl hover:from-purple-600 hover:to-pink-700 transition-all duration-300 font-medium"
                  >
                    Send Request
                  </button>
                </div>
              </div>
            </motion.div>
          </div>
        )}
      </AnimatePresence>

      {/* Enhanced Comments Modal */}
      <AnimatePresence>
        {showCommentsModal && selectedCase && (
          <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm">
            <motion.div
              initial={{ opacity: 0, scale: 0.95 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.95 }}
              className="bg-white/10 backdrop-blur-xl rounded-3xl border border-white/20 shadow-2xl max-w-4xl w-full mx-4 max-h-[90vh] overflow-y-auto"
            >
              <div className="p-8">
                <div className="flex items-center justify-between mb-6">
                  <h3 className="text-2xl font-bold text-white">Comments & Discussion</h3>
                  <button
                    onClick={() => setShowCommentsModal(false)}
                    className="text-white/50 hover:text-white transition-colors p-2 hover:bg-white/10 rounded-full"
                  >
                    <XIcon className="w-6 h-6" />
                  </button>
                </div>

                <div className="mb-6 p-4 bg-white/10 rounded-2xl border border-white/20">
                  <h4 className="font-bold text-lg text-white mb-2">{selectedCase.title}</h4>
                  <p className="text-white/70">{selectedCase.legalArea}</p>
                </div>

                {/* Comments List */}
                <div className="space-y-6 mb-8">
                  {selectedCase.comments?.map((comment) => (
                    <div key={comment.id} className="border-b border-white/10 pb-6">
                      <div className="flex items-start gap-4">
                        <div className="w-10 h-10 rounded-full bg-gradient-to-br from-purple-500/20 to-pink-500/20 border border-white/20 flex items-center justify-center">
                          <User className="w-5 h-5 text-white/70" />
                        </div>
                        <div className="flex-1">
                          <div className="flex items-center gap-3 mb-2">
                            <span className="font-medium text-white">{comment.user.name}</span>
                            <span className="text-xs text-white/50 bg-white/10 px-2 py-1 rounded-full">{comment.user.role}</span>
                            <span className="text-xs text-white/40">
                              {new Date(comment.createdAt).toLocaleDateString()}
                            </span>
                          </div>
                          <p className="text-white/80 mb-3 leading-relaxed">{comment.content}</p>
                          <div className="flex items-center gap-4">
                            <button
                              onClick={() => handleLikeComment(selectedCase.id, comment.id)}
                              className="flex items-center gap-2 text-xs text-white/50 hover:text-purple-300 transition-colors"
                            >
                              <ThumbsUp className="w-3 h-3" />
                              {comment.likes}
                            </button>
                            <button className="text-xs text-white/50 hover:text-purple-300 transition-colors">
                              Reply
                            </button>
                          </div>
                        </div>
                      </div>
                    </div>
                  ))}
                </div>

                {/* Add Comment */}
                <div className="space-y-4">
                  <textarea
                    value={newComment}
                    onChange={(e) => setNewComment(e.target.value)}
                    placeholder="Add a comment..."
                    className="w-full px-4 py-3 bg-white/10 border border-white/20 rounded-2xl focus:ring-2 focus:ring-purple-500 focus:border-transparent text-white placeholder-white/50 backdrop-blur-sm"
                    rows={3}
                  />
                  <div className="flex justify-end">
                    <button
                      onClick={() => handleAddComment(selectedCase.id)}
                      className="px-6 py-3 bg-gradient-to-r from-purple-500 to-pink-600 text-white rounded-2xl hover:from-purple-600 hover:to-pink-700 transition-all duration-300 font-medium"
                    >
                      Add Comment
                    </button>
                  </div>
                </div>
              </div>
            </motion.div>
          </div>
        )}
      </AnimatePresence>
    </div>
  );
};

export default LiveCaseFeed; 

CasperSecurity Mini