Untitled

 avatar
unknown
plain_text
10 months ago
14 kB
12
Indexable
import { useState } from "react";
import {
  Calendar,
  Clock,
  CreditCard,
  FileText,
} from "lucide-react";
import { Button } from "../ui/button";
import { Input } from "../ui/input";
import { Label } from "../ui/label";
import { Textarea } from "../ui/textarea";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
} from "../ui/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "../ui/select";
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from "../ui/card";
import { Separator } from "../ui/separator";
import { Badge } from "../ui/badge";
import {
  Avatar,
  AvatarFallback,
  AvatarImage,
} from "../ui/avatar";
import { MentorInfo } from "../mentors/MentorInfo";
import { Mentor } from "../../types";

interface BookingModalProps {
  mentor: Mentor | null;
  isOpen: boolean;
  onClose: () => void;
  onConfirmBooking: (bookingData: {
    mentorId: string;
    date: string;
    time: string;
    duration: number;
    notes: string;
    totalPrice: number;
  }) => void;
}

export function BookingModal({
  mentor,
  isOpen,
  onClose,
  onConfirmBooking,
}: BookingModalProps) {
  const [selectedDate, setSelectedDate] = useState("");
  const [selectedTime, setSelectedTime] = useState("");
  const [duration, setDuration] = useState(60);
  const [notes, setNotes] = useState("");
  const [isLoading, setIsLoading] = useState(false);

  if (!mentor) return null;

  const availableDates = [
    "2024-01-20",
    "2024-01-21",
    "2024-01-22",
    "2024-01-23",
    "2024-01-24",
  ];

  const availableTimes = [
    "09:00",
    "10:00",
    "11:00",
    "14:00",
    "15:00",
    "16:00",
    "17:00",
  ];

  const durationOptions = [
    { value: 30, label: "30 phút" },
    { value: 60, label: "1 giờ" },
    { value: 90, label: "1.5 giờ" },
    { value: 120, label: "2 giờ" },
  ];

  const subtotal = (mentor.hourlyRate * duration) / 60;
  const tax = subtotal * 0.1; // 10% tax
  const platformFee = 2.99;
  const totalPrice = subtotal + tax + platformFee;

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    if (!selectedDate || !selectedTime) return;

    setIsLoading(true);

    try {
      await onConfirmBooking({
        mentorId: mentor.id,
        date: selectedDate,
        time: selectedTime,
        duration,
        notes,
        totalPrice,
      });
      onClose();
    } catch (error) {
      console.error("Booking error:", error);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent
        className="max-w-2xl max-h-[90vh] overflow-y-auto glass-blue-strong border-white/30"
        style={{
          background: "rgba(59, 130, 246, 0.15)",
          backdropFilter: "blur(20px)",
          WebkitBackdropFilter: "blur(20px)",
          border: "1px solid rgba(255, 255, 255, 0.3)",
          boxShadow:
            "0 25px 50px -12px rgba(30, 58, 138, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.1)",
        }}
      >
        <DialogHeader style={{ color: "white" }}>
          <DialogTitle className="text-2xl !text-white">
            Đặt lịch tư vấn
          </DialogTitle>
          <DialogDescription
            className="!text-white"
            style={{ color: "white" }}
          >
            Chọn thời gian và hoàn tất việc đặt lịch tư vấn với
            mentor
          </DialogDescription>
        </DialogHeader>

        <form
          onSubmit={handleSubmit}
          className="space-y-6 [&_*]:!text-white [&_h1]:!text-white [&_h2]:!text-white [&_h3]:!text-white [&_h4]:!text-white [&_p]:!text-white [&_span]:!text-white [&_div]:!text-white [&_label]:!text-white [&_input]:!text-white [&_textarea]:!text-white [&_button]:!text-white"
        >
          {/* Mentor Info */}
          <Card className="glass border-white/30">
            <CardContent className="p-4">
              <div className="flex items-center space-x-4">
                <Avatar className="h-16 w-16 glass border-white/20">
                  <AvatarImage
                    src={mentor.avatar}
                    alt={mentor.fullName}
                  />
                  <AvatarFallback className="bg-gradient-secondary text-white">
                    {mentor.fullName
                      .split(" ")
                      .map((n) => n[0])
                      .join("")}
                  </AvatarFallback>
                </Avatar>
                <div className="flex-1">
                  <h3 className="font-semibold text-lg text-white">
                    {mentor.fullName}
                  </h3>
                  <div className="flex items-center space-x-2 text-sm text-white/70">
                    <span>{mentor.experience}</span>
                    <span>•</span>
                    <span>${mentor.hourlyRate}/giờ</span>
                  </div>
                  <div className="flex flex-wrap gap-1 mt-2">
                    {mentor.skills.slice(0, 3).map((skill) => (
                      <Badge
                        key={skill}
                        className="bg-blue-500/20 text-blue-200 border-blue-500/30 text-xs"
                      >
                        {skill}
                      </Badge>
                    ))}
                  </div>
                </div>
              </div>
            </CardContent>
          </Card>

          {/* Booking Details */}
          <div className="grid md:grid-cols-2 gap-6">
            {/* Date & Time Selection */}
            <div className="space-y-4">
              <div className="space-y-2">
                <Label
                  htmlFor="date"
                  className="flex items-center space-x-2 text-white"
                >
                  <Calendar className="h-4 w-4" />
                  <span>Chọn ngày</span>
                </Label>
                <Select
                  value={selectedDate}
                  onValueChange={setSelectedDate}
                  required
                >
                  <SelectTrigger
                    className="glass border-white/30 text-white"
                    style={{ color: "white" }}
                  >
                    <SelectValue
                      placeholder="Chọn ngày"
                      style={{ color: "white" }}
                    />
                  </SelectTrigger>
                  <SelectContent className="bg-white/95 backdrop-blur-md border-white/30">
                    {availableDates.map((date) => (
                      <SelectItem
                        key={date}
                        value={date}
                        className="focus:bg-blue-100"
                      >
                        {new Date(date).toLocaleDateString(
                          "vi-VN",
                          {
                            weekday: "long",
                            year: "numeric",
                            month: "long",
                            day: "numeric",
                          },
                        )}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-2">
                <Label
                  htmlFor="time"
                  className="flex items-center space-x-2 text-white"
                >
                  <Clock className="h-4 w-4" />
                  <span>Chọn giờ</span>
                </Label>
                <Select
                  value={selectedTime}
                  onValueChange={setSelectedTime}
                  required
                >
                  <SelectTrigger
                    className="glass border-white/30 text-white"
                    style={{ color: "white" }}
                  >
                    <SelectValue
                      placeholder="Chọn giờ"
                      style={{ color: "white" }}
                    />
                  </SelectTrigger>
                  <SelectContent className="bg-white/95 backdrop-blur-md border-white/30">
                    {availableTimes.map((time) => (
                      <SelectItem
                        key={time}
                        value={time}
                        className="focus:bg-blue-100"
                      >
                        {time}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-2">
                <Label
                  htmlFor="duration"
                  className="text-white"
                >
                  Thời lượng
                </Label>
                <Select
                  value={duration.toString()}
                  onValueChange={(value) =>
                    setDuration(parseInt(value))
                  }
                >
                  <SelectTrigger
                    className="glass border-white/30 text-white"
                    style={{ color: "white" }}
                  >
                    <SelectValue style={{ color: "white" }} />
                  </SelectTrigger>
                  <SelectContent className="bg-white/95 backdrop-blur-md border-white/30">
                    {durationOptions.map((option) => (
                      <SelectItem
                        key={option.value}
                        value={option.value.toString()}
                        className="focus:bg-blue-100"
                      >
                        {option.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>

            {/* Price Breakdown */}
            <Card className="glass border-white/30">
              <CardHeader>
                <CardTitle className="flex items-center space-x-2 text-lg text-white">
                  <CreditCard className="h-5 w-5" />
                  <span>Chi tiết thanh toán</span>
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-3">
                <div className="flex justify-between text-white">
                  <span>
                    {duration} phút × ${mentor.hourlyRate}/giờ
                  </span>
                  <span>${subtotal.toFixed(2)}</span>
                </div>
                <div className="flex justify-between text-sm text-white/70">
                  <span>Thuế (10%)</span>
                  <span>${tax.toFixed(2)}</span>
                </div>
                <div className="flex justify-between text-sm text-white/70">
                  <span>Phí dịch vụ</span>
                  <span>${platformFee.toFixed(2)}</span>
                </div>
                <Separator className="bg-white/20" />
                <div className="flex justify-between font-semibold text-lg text-white">
                  <span>Tổng cộng</span>
                  <span>${totalPrice.toFixed(2)}</span>
                </div>
              </CardContent>
            </Card>
          </div>

          {/* Notes */}
          <div className="space-y-2">
            <Label
              htmlFor="notes"
              className="flex items-center space-x-2 text-white"
            >
              <FileText className="h-4 w-4" />
              <span>Ghi chú cho mentor (tùy chọn)</span>
            </Label>
            <Textarea
              id="notes"
              placeholder="Mô tả những gì bạn muốn thảo luận trong buổi tư vấn..."
              value={notes}
              onChange={(e) => setNotes(e.target.value)}
              rows={3}
              // GỠ: liquid-border nếu nó có pseudo-element tô nền
              className="
                !text-white placeholder-white/60 border-white/25
                !bg-transparent hover:!bg-transparent focus:!bg-transparent
                backdrop-blur-md
                ring-0 focus-visible:ring-2 focus-visible:ring-white/30 focus-visible:ring-offset-0
                "
              // Tránh inline style xung đột – chỉ giữ phần cần thiết
              style={{
                WebkitBackdropFilter: "blur(12px)",
                backgroundClip: "padding-box",
              }}
            />
          </div>

          {/* Action Buttons */}
          <div className="flex space-x-3">
            <Button
              type="button"
              variant="outline"
              onClick={onClose}
              className="flex-1 border-white/30 text-white hover:bg-white/10"
            >
              Hủy
            </Button>
            <Button
              type="submit"
              className="flex-1 gradient-secondary hover:scale-105 transition-transform"
              disabled={
                !selectedDate || !selectedTime || isLoading
              }
            >
              {isLoading
                ? "Đang xử lý..."
                : `Xác nhận - ${totalPrice.toFixed(2)}`}
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
}
Editor is loading...
Leave a Comment