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/consultation.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 { 
  MessageSquare, Calendar, Clock, DollarSign, 
  ArrowLeft, ArrowRight, User, FileText
} from 'lucide-react';
import toast from 'react-hot-toast';

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

const ConsultationPage: React.FC = () => {
  const router = useRouter();
  const { data: session } = useSession();
  const [lawyer, setLawyer] = useState<Lawyer | null>(null);
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  
  const [formData, setFormData] = useState({
    preferredDate: '',
    preferredTime: '',
    duration: '60',
    consultationType: 'GENERAL',
    message: ''
  });

  const { lawyerId } = router.query;

  useEffect(() => {
    if (lawyerId) {
      fetchLawyerDetails();
    }
  }, [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');
    } 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 (!formData.preferredDate || !formData.preferredTime) {
      toast.error('Please select a date and time');
      return;
    }

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

      if (response.ok) {
        toast.success('Consultation 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 consultation request:', error);
      toast.error('Failed to send request');
    } finally {
      setSubmitting(false);
    }
  };

  const consultationTypes = [
    { value: 'GENERAL', label: 'General Legal Advice' },
    { value: 'CASE_REVIEW', label: 'Case Review' },
    { value: 'DOCUMENT_REVIEW', label: 'Document Review' },
    { value: 'CONTRACT_REVIEW', label: 'Contract Review' },
    { value: 'LITIGATION_STRATEGY', label: 'Litigation Strategy' },
    { value: 'SETTLEMENT_NEGOTIATION', label: 'Settlement Negotiation' }
  ];

  const timeSlots = [
    '09:00', '09:30', '10:00', '10:30', '11:00', '11:30',
    '13:00', '13:30', '14:00', '14:30', '15:00', '15:30',
    '16:00', '16:30', '17:00', '17:30'
  ];

  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>Book Consultation - {lawyer.name}</title>
      </Head>

      <div className="max-w-2xl 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">Book Consultation</h1>
              <p className="text-gray-600">Schedule a consultation 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>

        {/* Consultation Form */}
        <motion.form
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.2 }}
          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">
            <MessageSquare className="h-5 w-5 mr-2 text-blue-600" />
            Consultation Details
          </h2>

          <div className="space-y-6">
            {/* Consultation Type */}
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-2">
                Consultation Type
              </label>
              <select
                name="consultationType"
                value={formData.consultationType}
                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"
              >
                {consultationTypes.map(type => (
                  <option key={type.value} value={type.value}>
                    {type.label}
                  </option>
                ))}
              </select>
            </div>

            {/* Date and Time */}
            <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">
                  Preferred Date
                </label>
                <input
                  type="date"
                  name="preferredDate"
                  value={formData.preferredDate}
                  onChange={handleInputChange}
                  min={new Date().toISOString().split('T')[0]}
                  className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                  required
                />
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  Preferred Time
                </label>
                <select
                  name="preferredTime"
                  value={formData.preferredTime}
                  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"
                  required
                >
                  <option value="">Select time</option>
                  {timeSlots.map(time => (
                    <option key={time} value={time}>
                      {time}
                    </option>
                  ))}
                </select>
              </div>
            </div>

            {/* Duration */}
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-2">
                Duration
              </label>
              <select
                name="duration"
                value={formData.duration}
                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"
              >
                <option value="30">30 minutes</option>
                <option value="60">1 hour</option>
                <option value="90">1.5 hours</option>
                <option value="120">2 hours</option>
              </select>
            </div>

            {/* Message */}
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-2">
                Additional Details
              </label>
              <textarea
                name="message"
                value={formData.message}
                onChange={handleInputChange}
                rows={4}
                placeholder="Describe your legal issue or what you'd like to discuss..."
                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
              />
            </div>

            {/* Cost Estimate */}
            {lawyer.hourlyRate && (
              <div className="bg-blue-50 border border-blue-200 rounded-md p-4">
                <div className="flex items-center justify-between">
                  <div>
                    <h3 className="font-medium text-blue-900">Estimated Cost</h3>
                    <p className="text-sm text-blue-700">
                      {lawyer.hourlyRate} × {parseInt(formData.duration) / 60} hours
                    </p>
                  </div>
                  <div className="text-right">
                    <div className="text-lg font-bold text-blue-900">
                      ${((lawyer.hourlyRate * parseInt(formData.duration)) / 60).toFixed(2)}
                    </div>
                    <div className="text-sm text-blue-700">CAD</div>
                  </div>
                </div>
              </div>
            )}
          </div>

          {/* Submit Button */}
          <div className="mt-8 flex justify-end">
            <button
              type="submit"
              disabled={submitting}
              className={`px-6 py-3 rounded-lg transition-colors ${
                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">
                  Book Consultation
                  <ArrowRight className="h-4 w-4 ml-2" />
                </div>
              )}
            </button>
          </div>
        </motion.form>
      </div>
    </LayoutWithSidebar>
  );
};

export default ConsultationPage; 

CasperSecurity Mini