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/HireLawyerButton.tsx
import React, { useState } from 'react';
import { useSession } from 'next-auth/react';
import { useRouter } from 'next/router';
import { motion, AnimatePresence } from 'framer-motion';
import { 
  Scale, MessageSquare, Calendar, DollarSign, 
  Users, Star, Clock, CheckCircle, XCircle,
  ArrowRight, Phone, Mail, MapPin, Award,
  Shield, TrendingUp, FileText, Zap
} from 'lucide-react';
import toast from 'react-hot-toast';

interface HireLawyerButtonProps {
  lawyer: {
    id: string;
    name: string;
    role: string;
    title?: string;
    specialization?: string;
    yearsOfExperience?: number;
    totalCases: number;
    wonCases: number;
    lostCases: number;
    winRate: number;
    averageRating: number;
    hourlyRate?: number;
    totalBadges: number;
    level: number;
    isVerified: boolean;
    profilePicture?: string;
    bio?: string;
    officeLocation?: string;
    availability?: string;
  };
  businessProfile?: {
    id: string;
    businessName: string;
    isVerified: boolean;
  };
  availableCases?: Array<{
    id: string;
    title: string;
    caseType: string;
    status: string;
    priority: string;
    budget?: number;
    isAcceptingApplications: boolean;
  }>;
  className?: string;
}

const HireLawyerButton: React.FC<HireLawyerButtonProps> = ({ 
  lawyer, 
  businessProfile, 
  availableCases = [],
  className = '' 
}) => {
  const { data: session } = useSession();
  const router = useRouter();
  const [showModal, setShowModal] = useState(false);
  const [selectedOption, setSelectedOption] = useState<string>('');
  const [loading, setLoading] = useState(false);

  const hiringOptions = [
    {
      id: 'case-representation',
      title: 'Case Representation',
      description: 'Hire for a specific legal case',
      icon: Scale,
      color: 'bg-blue-500',
      features: [
        'Full case representation',
        'Court appearances',
        'Document preparation',
        'Client communication',
        'Case strategy development'
      ],
      price: lawyer.hourlyRate ? `$${lawyer.hourlyRate}/hour` : 'Contact for pricing',
      duration: 'Case duration',
      popular: true
    },
    {
      id: 'consultation',
      title: 'Legal Consultation',
      description: 'One-time legal advice session',
      icon: MessageSquare,
      color: 'bg-green-500',
      features: [
        '1-hour consultation',
        'Legal advice',
        'Case evaluation',
        'Strategy recommendations',
        'Follow-up summary'
      ],
      price: lawyer.hourlyRate ? `$${lawyer.hourlyRate}/hour` : 'Contact for pricing',
      duration: '1 hour',
      popular: false
    },
    {
      id: 'retainer',
      title: 'Monthly Retainer',
      description: 'Ongoing legal services',
      icon: Calendar,
      color: 'bg-purple-500',
      features: [
        'Monthly legal services',
        'Priority access',
        'Regular check-ins',
        'Document review',
        'Legal strategy support'
      ],
      price: lawyer.hourlyRate ? `$${Math.round(lawyer.hourlyRate * 0.8 * 20)}/month` : 'Contact for pricing',
      duration: 'Monthly',
      popular: false
    },
    {
      id: 'case-offer',
      title: 'Make Case Offer',
      description: 'Propose collaboration on a case',
      icon: Users,
      color: 'bg-orange-500',
      features: [
        'Case collaboration',
        'Shared responsibilities',
        'Split fees',
        'Joint strategy',
        'Team approach'
      ],
      price: 'Negotiable',
      duration: 'Case duration',
      popular: false
    }
  ];

  const handleHire = async (optionId: string) => {
    if (!session) {
      toast.error('Please log in to hire a lawyer');
      router.push('/auth/login');
      return;
    }

    setLoading(true);
    setSelectedOption(optionId);

    try {
      switch (optionId) {
        case 'case-representation':
          // Redirect to case selection or creation
          if (availableCases.length > 0) {
            router.push(`/hire/case-selection?lawyerId=${lawyer.id}`);
          } else {
            router.push(`/hire/new-case?lawyerId=${lawyer.id}`);
          }
          break;

        case 'consultation':
          // Create consultation booking
          router.push(`/hire/consultation?lawyerId=${lawyer.id}`);
          break;

        case 'retainer':
          // Setup retainer agreement
          router.push(`/hire/retainer?lawyerId=${lawyer.id}`);
          break;

        case 'case-offer':
          // Make case offer
          if (availableCases.length > 0) {
            router.push(`/hire/case-offer?lawyerId=${lawyer.id}`);
          } else {
            toast.error('No cases available for collaboration');
          }
          break;

        default:
          toast.error('Invalid hiring option');
      }
    } catch (error) {
      console.error('Error processing hire request:', error);
      toast.error('Error processing request');
    } finally {
      setLoading(false);
    }
  };

  const getLevelBadge = (level: number) => {
    if (level >= 50) return { color: 'bg-purple-500', text: 'Legendary' };
    if (level >= 30) return { color: 'bg-red-500', text: 'Master' };
    if (level >= 20) return { color: 'bg-orange-500', text: 'Expert' };
    if (level >= 10) return { color: 'bg-blue-500', text: 'Advanced' };
    return { color: 'bg-gray-500', text: 'Beginner' };
  };

  const levelBadge = getLevelBadge(lawyer.level);

  return (
    <>
      {/* Hire Button */}
      <button
        onClick={() => setShowModal(true)}
        className={`inline-flex items-center px-6 py-3 bg-gradient-to-r from-blue-600 to-purple-600 text-white font-semibold rounded-lg hover:from-blue-700 hover:to-purple-700 transition-all duration-200 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5 ${className}`}
      >
        <Scale className="h-5 w-5 mr-2" />
        Hire {lawyer.name.split(' ')[0]}
        <ArrowRight className="h-4 w-4 ml-2" />
      </button>

      {/* Hiring Modal */}
      <AnimatePresence>
        {showModal && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4"
            onClick={() => setShowModal(false)}
          >
            <motion.div
              initial={{ scale: 0.9, opacity: 0 }}
              animate={{ scale: 1, opacity: 1 }}
              exit={{ scale: 0.9, opacity: 0 }}
              className="bg-white dark:bg-gray-800 rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-y-auto"
              onClick={(e) => e.stopPropagation()}
            >
              {/* Header */}
              <div className="p-6 border-b border-gray-200 dark:border-gray-700">
                <div className="flex items-center justify-between">
                  <div className="flex items-center space-x-4">
                    {lawyer.profilePicture ? (
                      <img
                        src={lawyer.profilePicture}
                        alt={lawyer.name}
                        className="w-16 h-16 rounded-full object-cover"
                      />
                    ) : (
                      <div className="w-16 h-16 bg-gradient-to-br from-blue-400 to-purple-500 rounded-full flex items-center justify-center">
                        <Users className="h-8 w-8 text-white" />
                      </div>
                    )}
                    <div>
                      <h2 className="text-2xl font-bold text-gray-900 dark:text-white flex items-center">
                        {lawyer.name}
                        {lawyer.isVerified && (
                          <Shield className="h-6 w-6 ml-2 text-blue-600" />
                        )}
                      </h2>
                      <p className="text-gray-600 dark:text-gray-400">{lawyer.title}</p>
                      <div className="flex items-center space-x-2 mt-1">
                        <span className={`px-2 py-1 text-xs text-white rounded-full ${levelBadge.color}`}>
                          {levelBadge.text} (Lv.{lawyer.level})
                        </span>
                        <div className="flex items-center text-yellow-500">
                          <Star className="h-4 w-4" />
                          <span className="text-sm ml-1">{lawyer.averageRating ? lawyer.averageRating.toFixed(1) : 'N/A'}</span>
                        </div>
                      </div>
                    </div>
                  </div>
                  <button
                    onClick={() => setShowModal(false)}
                    className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
                  >
                    <XCircle className="h-6 w-6" />
                  </button>
                </div>

                {/* Lawyer Stats */}
                <div className="grid grid-cols-4 gap-4 mt-6">
                  <div className="text-center p-3 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
                    <div className="text-lg font-bold text-blue-600">{lawyer.totalCases}</div>
                    <div className="text-xs text-gray-600 dark:text-gray-400">Total Cases</div>
                  </div>
                  <div className="text-center p-3 bg-green-50 dark:bg-green-900/20 rounded-lg">
                    <div className="text-lg font-bold text-green-600">
                      {typeof lawyer.winRate === 'number' ? `${lawyer.winRate.toFixed(1)}%` : 'N/A'}
                    </div>
                    <div className="text-xs text-gray-600 dark:text-gray-400">Win Rate</div>
                  </div>
                  <div className="text-center p-3 bg-purple-50 dark:bg-purple-900/20 rounded-lg">
                    <div className="text-lg font-bold text-purple-600">{lawyer.yearsOfExperience || 0}</div>
                    <div className="text-xs text-gray-600 dark:text-gray-400">Years Exp.</div>
                  </div>
                  <div className="text-center p-3 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg">
                    <div className="text-lg font-bold text-yellow-600">{lawyer.totalBadges}</div>
                    <div className="text-xs text-gray-600 dark:text-gray-400">Badges</div>
                  </div>
                </div>
              </div>

              {/* Hiring Options */}
              <div className="p-6">
                <h3 className="text-xl font-semibold text-gray-900 dark:text-white mb-6">
                  Choose Your Hiring Option
                </h3>

                <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                  {hiringOptions.map((option) => (
                    <motion.div
                      key={option.id}
                      whileHover={{ scale: 1.02 }}
                      className={`relative border-2 rounded-xl p-6 cursor-pointer transition-all duration-200 ${
                        option.popular 
                          ? 'border-blue-500 bg-blue-50 dark:bg-blue-900/10' 
                          : 'border-gray-200 dark:border-gray-700 hover:border-blue-300'
                      }`}
                      onClick={() => handleHire(option.id)}
                    >
                      {option.popular && (
                        <div className="absolute -top-3 left-1/2 transform -translate-x-1/2">
                          <span className="bg-blue-500 text-white px-3 py-1 rounded-full text-xs font-semibold">
                            Most Popular
                          </span>
                        </div>
                      )}

                      <div className="flex items-start space-x-4">
                        <div className={`p-3 rounded-lg ${option.color} text-white`}>
                          <option.icon className="h-6 w-6" />
                        </div>
                        <div className="flex-1">
                          <h4 className="text-lg font-semibold text-gray-900 dark:text-white">
                            {option.title}
                          </h4>
                          <p className="text-gray-600 dark:text-gray-400 text-sm mb-4">
                            {option.description}
                          </p>

                          <div className="space-y-2 mb-4">
                            {option.features.map((feature, index) => (
                              <div key={index} className="flex items-center text-sm text-gray-600 dark:text-gray-400">
                                <CheckCircle className="h-4 w-4 text-green-500 mr-2 flex-shrink-0" />
                                {feature}
                              </div>
                            ))}
                          </div>

                          <div className="flex items-center justify-between">
                            <div>
                              <div className="text-lg font-bold text-gray-900 dark:text-white">
                                {option.price}
                              </div>
                              <div className="text-sm text-gray-600 dark:text-gray-400">
                                {option.duration}
                              </div>
                            </div>
                            <ArrowRight className="h-5 w-5 text-blue-600" />
                          </div>
                        </div>
                      </div>
                    </motion.div>
                  ))}
                </div>

                {/* Available Cases (if any) */}
                {availableCases.length > 0 && (
                  <div className="mt-8 p-4 bg-gray-50 dark:bg-gray-700 rounded-lg">
                    <h4 className="font-semibold text-gray-900 dark:text-white mb-3 flex items-center">
                      <FileText className="h-5 w-5 mr-2" />
                      Available Cases for Collaboration
                    </h4>
                    <div className="space-y-2">
                      {availableCases.slice(0, 3).map((case_) => (
                        <div key={case_.id} className="flex items-center justify-between p-3 bg-white dark:bg-gray-600 rounded-lg">
                          <div>
                            <div className="font-medium text-gray-900 dark:text-white">{case_.title}</div>
                            <div className="text-sm text-gray-600 dark:text-gray-400">
                              {case_.caseType} • {case_.priority} priority
                            </div>
                          </div>
                          <div className="text-right">
                            <div className="text-sm font-medium text-gray-900 dark:text-white">
                              {case_.budget ? `$${case_.budget.toLocaleString()}` : 'Contact for budget'}
                            </div>
                            <div className="text-xs text-gray-600 dark:text-gray-400">
                              {case_.status}
                            </div>
                          </div>
                        </div>
                      ))}
                    </div>
                  </div>
                )}

                {/* Contact Information */}
                <div className="mt-6 p-4 bg-blue-50 dark:bg-blue-900/10 rounded-lg">
                  <h4 className="font-semibold text-gray-900 dark:text-white mb-3">
                    Need to discuss first?
                  </h4>
                  <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                    <div className="flex items-center text-gray-600 dark:text-gray-400">
                      <Phone className="h-4 w-4 mr-2" />
                      <span>Call for consultation</span>
                    </div>
                    <div className="flex items-center text-gray-600 dark:text-gray-400">
                      <Mail className="h-4 w-4 mr-2" />
                      <span>Send message</span>
                    </div>
                    <div className="flex items-center text-gray-600 dark:text-gray-400">
                      <MapPin className="h-4 w-4 mr-2" />
                      <span>{lawyer.officeLocation || 'Office location'}</span>
                    </div>
                  </div>
                </div>
              </div>
            </motion.div>
          </motion.div>
        )}
      </AnimatePresence>
    </>
  );
};

export default HireLawyerButton; 

CasperSecurity Mini