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/pages/hire/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/lavocat.ca/private_html/src/pages/hire/case-offer.tsx
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import { useSession } from 'next-auth/react';
import Head from 'next/head';
import LayoutWithSidebar from '../../components/LayoutWithSidebar';
import { motion } from 'framer-motion';
import { 
  Users, FileText, DollarSign, ArrowLeft, ArrowRight, 
  User, CheckCircle, Handshake, Target
} from 'lucide-react';
import toast from 'react-hot-toast';

interface Lawyer {
  id: string;
  name: string;
  hourlyRate?: number;
  specialization?: string;
  isVerified: boolean;
}

interface Case {
  id: string;
  title: string;
  caseType: string;
  status: string;
  priority: string;
  budget?: number;
  description?: string;
}

const CaseOfferPage: React.FC = () => {
  const router = useRouter();
  const { data: session } = useSession();
  const [lawyer, setLawyer] = useState<Lawyer | null>(null);
  const [cases, setCases] = useState<Case[]>([]);
  const [selectedCase, setSelectedCase] = useState<string>('');
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  
  const [formData, setFormData] = useState({
    collaborationType: 'JOINT_REPRESENTATION',
    feeSplit: '50-50',
    proposedRate: '',
    estimatedHours: '',
    message: ''
  });

  const { lawyerId } = router.query;

  useEffect(() => {
    if (session?.user?.id) {
      fetchLawyerDetails();
      fetchUserCases();
    }
  }, [session, lawyerId]);

  const fetchLawyerDetails = async () => {
    try {
      const response = await fetch(`/api/user/${lawyerId}`);
      if (response.ok) {
        const data = await response.json();
        setLawyer(data.user);
      }
    } catch (error) {
      console.error('Error fetching lawyer details:', error);
      toast.error('Failed to load lawyer details');
    }
  };

  const fetchUserCases = async () => {
    try {
      const response = await fetch('/api/user/cases');
      if (response.ok) {
        const data = await response.json();
        setCases(data.cases || []);
      }
    } catch (error) {
      console.error('Error fetching cases:', error);
      toast.error('Failed to load your cases');
    } finally {
      setLoading(false);
    }
  };

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
    const { name, value } = e.target;
    setFormData(prev => ({
      ...prev,
      [name]: value
    }));
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    
    if (!selectedCase) {
      toast.error('Please select a case');
      return;
    }

    setSubmitting(true);
    try {
      const response = await fetch('/api/hire/case-offer', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          lawyerId,
          caseId: selectedCase,
          ...formData
        }),
      });

      if (response.ok) {
        toast.success('Case collaboration request sent successfully!');
        router.push('/user/dashboard');
      } else {
        const error = await response.json();
        toast.error(error.error || 'Failed to send request');
      }
    } catch (error) {
      console.error('Error sending case offer:', error);
      toast.error('Failed to send request');
    } finally {
      setSubmitting(false);
    }
  };

  const collaborationTypes = [
    { value: 'JOINT_REPRESENTATION', label: 'Joint Representation' },
    { value: 'CO_COUNSEL', label: 'Co-Counsel' },
    { value: 'SPECIALIST_CONSULTATION', label: 'Specialist Consultation' },
    { value: 'LEAD_COUNSEL', label: 'Lead Counsel (You Lead)' },
    { value: 'SUPPORTING_COUNSEL', label: 'Supporting Counsel' }
  ];

  const feeSplits = [
    { value: '50-50', label: '50% - 50% (Equal Split)' },
    { value: '60-40', label: '60% - 40% (You Lead)' },
    { value: '40-60', label: '40% - 60% (Lawyer Leads)' },
    { value: '70-30', label: '70% - 30% (You Lead)' },
    { value: '30-70', label: '30% - 70% (Lawyer Leads)' },
    { value: 'NEGOTIABLE', label: 'Negotiable' }
  ];

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

  if (!lawyer) {
    return (
      <LayoutWithSidebar>
        <div className="text-center py-12">
          <h1 className="text-2xl font-bold text-gray-900 mb-4">Lawyer not found</h1>
          <button
            onClick={() => router.back()}
            className="text-blue-600 hover:text-blue-800"
          >
            Go back
          </button>
        </div>
      </LayoutWithSidebar>
    );
  }

  return (
    <LayoutWithSidebar>
      <Head>
        <title>Case Collaboration - {lawyer.name}</title>
      </Head>

      <div className="max-w-4xl mx-auto px-4 py-8">
        {/* Header */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          className="mb-8"
        >
          <div className="flex items-center gap-4 mb-4">
            <button
              onClick={() => router.back()}
              className="p-2 text-gray-600 hover:text-gray-800 transition-colors"
            >
              <ArrowLeft className="h-5 w-5" />
            </button>
            <div>
              <h1 className="text-3xl font-bold text-gray-900">Case Collaboration</h1>
              <p className="text-gray-600">Propose collaboration with {lawyer.name}</p>
            </div>
          </div>
        </motion.div>

        {/* Lawyer Info */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.1 }}
          className="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-6"
        >
          <div className="flex items-center gap-4">
            <div className="w-16 h-16 bg-gradient-to-br from-blue-400 to-purple-500 rounded-full flex items-center justify-center">
              <User className="h-8 w-8 text-white" />
            </div>
            <div>
              <h2 className="text-xl font-semibold text-gray-900 flex items-center">
                {lawyer.name}
                {lawyer.isVerified && (
                  <span className="ml-2 text-blue-600">✓ Verified</span>
                )}
              </h2>
              {lawyer.specialization && (
                <p className="text-gray-600">{lawyer.specialization}</p>
              )}
              {lawyer.hourlyRate && (
                <p className="text-green-600 font-medium">${lawyer.hourlyRate}/hour</p>
              )}
            </div>
          </div>
        </motion.div>

        {/* Case Selection */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.2 }}
          className="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-6"
        >
          <h2 className="text-xl font-semibold text-gray-900 mb-4 flex items-center">
            <FileText className="h-5 w-5 mr-2 text-blue-600" />
            Select Case for Collaboration
          </h2>

          {cases.length === 0 ? (
            <div className="text-center py-8">
              <FileText className="h-16 w-16 text-gray-400 mx-auto mb-4" />
              <h3 className="text-lg font-medium text-gray-900 mb-2">No cases found</h3>
              <p className="text-gray-600 mb-4">You need to have a case to propose collaboration.</p>
              <button
                onClick={() => router.push('/user/cases/new')}
                className="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
              >
                <FileText className="h-4 w-4 mr-2" />
                Create New Case
              </button>
            </div>
          ) : (
            <div className="space-y-4">
              {cases.map((case_) => (
                <div
                  key={case_.id}
                  className={`border-2 rounded-lg p-4 cursor-pointer transition-all duration-200 ${
                    selectedCase === case_.id
                      ? 'border-blue-500 bg-blue-50'
                      : 'border-gray-200 hover:border-blue-300'
                  }`}
                  onClick={() => setSelectedCase(case_.id)}
                >
                  <div className="flex items-start justify-between">
                    <div className="flex-1">
                      <div className="flex items-center gap-2 mb-2">
                        <h3 className="font-semibold text-gray-900">{case_.title}</h3>
                        {selectedCase === case_.id && (
                          <CheckCircle className="h-5 w-5 text-blue-600" />
                        )}
                      </div>
                      
                      <div className="flex items-center gap-4 text-sm text-gray-600 mb-2">
                        <span>{case_.caseType}</span>
                        <span>{case_.status}</span>
                        {case_.budget && (
                          <span className="text-green-600">${case_.budget.toLocaleString()}</span>
                        )}
                      </div>

                      {case_.description && (
                        <p className="text-sm text-gray-600 line-clamp-2">
                          {case_.description}
                        </p>
                      )}

                      <div className="flex items-center gap-2 mt-2">
                        <span className={`px-2 py-1 text-xs rounded-full ${
                          case_.priority === 'HIGH' 
                            ? 'bg-red-100 text-red-800'
                            : case_.priority === 'MEDIUM'
                            ? 'bg-yellow-100 text-yellow-800'
                            : 'bg-green-100 text-green-800'
                        }`}>
                          {case_.priority} Priority
                        </span>
                      </div>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </motion.div>

        {/* Collaboration Form */}
        <motion.form
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.3 }}
          onSubmit={handleSubmit}
          className="bg-white rounded-lg shadow-sm border border-gray-200 p-6"
        >
          <h2 className="text-xl font-semibold text-gray-900 mb-6 flex items-center">
            <Handshake className="h-5 w-5 mr-2 text-blue-600" />
            Collaboration Details
          </h2>

          <div className="space-y-6">
            {/* Collaboration Type */}
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-2">
                Collaboration Type
              </label>
              <select
                name="collaborationType"
                value={formData.collaborationType}
                onChange={handleInputChange}
                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
              >
                {collaborationTypes.map(type => (
                  <option key={type.value} value={type.value}>
                    {type.label}
                  </option>
                ))}
              </select>
            </div>

            {/* Fee Split */}
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-2">
                Fee Split
              </label>
              <select
                name="feeSplit"
                value={formData.feeSplit}
                onChange={handleInputChange}
                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
              >
                {feeSplits.map(split => (
                  <option key={split.value} value={split.value}>
                    {split.label}
                  </option>
                ))}
              </select>
            </div>

            {/* Proposed Rate and Hours */}
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  Proposed Rate (CAD/hour)
                </label>
                <div className="relative">
                  <DollarSign className="absolute left-3 top-1/2 transform -translate-y-1/2 h-5 w-5 text-gray-400" />
                  <input
                    type="number"
                    name="proposedRate"
                    value={formData.proposedRate}
                    onChange={handleInputChange}
                    placeholder="Enter rate"
                    className="w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                  />
                </div>
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  Estimated Hours
                </label>
                <input
                  type="number"
                  name="estimatedHours"
                  value={formData.estimatedHours}
                  onChange={handleInputChange}
                  placeholder="Enter hours"
                  className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                />
              </div>
            </div>

            {/* Message */}
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-2">
                Collaboration Proposal
              </label>
              <textarea
                name="message"
                value={formData.message}
                onChange={handleInputChange}
                rows={4}
                placeholder="Describe your collaboration proposal, roles, and expectations..."
                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
              />
            </div>

            {/* Benefits */}
            <div className="bg-green-50 border border-green-200 rounded-md p-4">
              <h3 className="font-medium text-green-900 mb-3 flex items-center">
                <Target className="h-5 w-5 mr-2" />
                Collaboration Benefits
              </h3>
              <div className="space-y-2 text-sm text-green-800">
                <div className="flex items-center">
                  <CheckCircle className="h-4 w-4 mr-2" />
                  Shared expertise and resources
                </div>
                <div className="flex items-center">
                  <CheckCircle className="h-4 w-4 mr-2" />
                  Reduced workload and risk
                </div>
                <div className="flex items-center">
                  <CheckCircle className="h-4 w-4 mr-2" />
                  Enhanced case strategy
                </div>
                <div className="flex items-center">
                  <CheckCircle className="h-4 w-4 mr-2" />
                  Better client service
                </div>
              </div>
            </div>
          </div>

          {/* Submit Button */}
          <div className="mt-8 flex justify-end">
            <button
              type="submit"
              disabled={!selectedCase || submitting}
              className={`px-6 py-3 rounded-lg transition-colors ${
                !selectedCase || submitting
                  ? 'bg-gray-400 cursor-not-allowed'
                  : 'bg-blue-600 text-white hover:bg-blue-700'
              }`}
            >
              {submitting ? (
                <div className="flex items-center">
                  <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
                  Sending Request...
                </div>
              ) : (
                <div className="flex items-center">
                  Send Collaboration Request
                  <ArrowRight className="h-4 w-4 ml-2" />
                </div>
              )}
            </button>
          </div>
        </motion.form>
      </div>
    </LayoutWithSidebar>
  );
};

export default CaseOfferPage; 

CasperSecurity Mini