vkashti / components / ui / Reserve / ReservationForm.tsx
ReservationForm.tsx
Raw
import React from 'react';
import { FaRegCalendarCheck } from 'react-icons/fa';
import { FiCheck, FiX } from 'react-icons/fi';
import { motion } from 'framer-motion';

interface ReservationFormProps {
  handleSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
  handleChange: (
    e: React.ChangeEvent<
      HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
    >
  ) => void;
  person_name: string;
  phone: string;
  countryCode: string;
  persons: string;
  from_date: string;
  from_time: string;
  description: string;
  isSubmitting: boolean;
}

const ReservationForm: React.FC<ReservationFormProps> = ({
  handleSubmit,
  handleChange,
  person_name,
  phone,
  countryCode,
  persons,
  from_date,
  from_time,
  description,
  isSubmitting
}) => {
  const inputVariants = {
    focus: { scale: 1.01, transition: { duration: 0.2 } },
    blur: { scale: 1, transition: { duration: 0.2 } }
  };

  // Validation checks
  const isPhoneValid = phone.length >= 9;
  const showPhoneValidation = phone.length > 0;
  const isNameValid = person_name.length >= 2;
  const showNameValidation = person_name.length > 0;

  return (
    <motion.form 
      className="flex flex-col mx-auto space-y-5 p-1" 
      onSubmit={handleSubmit}
      initial={{ opacity: 0, y: 10 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.4 }}
    >
      <input type="hidden" name="eventType" value="eventType" />
      
      {/* Phone field */}
      <div className="flex space-x-2 items-center relative">
        <select
          id="countryCode"
          name="countryCode"
          value={countryCode}
          onChange={handleChange}
          className="select select-sm border-b border-gray-300 bg-transparent rounded-none focus:outline-none focus:border-warning"
          aria-label="Код на държава"
        >
          <option value="+359">🇧🇬 +359</option>
        </select>
        <motion.input
          id="phone"
          type="text"
          name="phone"
          onChange={handleChange}
          value={phone}
          placeholder="Телефон"
          className="input input-sm w-full border-0 border-b border-gray-300 rounded-none focus:outline-none focus:border-warning bg-transparent px-0"
          required
          whileFocus="focus"
          variants={inputVariants}
        />
        {showPhoneValidation && (
          <div className="absolute right-2">
            {isPhoneValid ? (
              <FiCheck className="text-green-500" />
            ) : (
              <FiX className="text-red-500" />
            )}
          </div>
        )}
      </div>
      
      {/* Number of guests */}
      <motion.input
        id="persons"
        type="number"
        name="persons"
        onChange={handleChange}
        value={persons}
        placeholder="Брой гости"
        className="input input-sm w-full border-0 border-b border-gray-300 rounded-none focus:outline-none focus:border-warning bg-transparent px-0"
        required
        whileFocus="focus"
        variants={inputVariants}
      />
      
      {/* Date and time */}
      <div className="flex space-x-4">
        <div className="flex-1">
          <p className="text-xs text-gray-500 mb-1">Дата</p>
          <motion.input
            id="from_date"
            type="date"
            name="from_date"
            min={new Date().toISOString().split('T')[0]}
            onChange={handleChange}
            value={from_date}
            className="input input-sm w-full border-0 border-b border-gray-300 rounded-none focus:outline-none focus:border-warning bg-transparent px-0"
            required
            whileFocus="focus"
            variants={inputVariants}
          />
        </div>
        <div className="flex-1">
          <p className="text-xs text-gray-500 mb-1">Час</p>
          <motion.input
            id="from_time"
            type="time"
            name="from_time"
            onChange={handleChange}
            value={from_time}
            className="input input-sm w-full border-0 border-b border-gray-300 rounded-none focus:outline-none focus:border-warning bg-transparent px-0"
            required
            whileFocus="focus"
            variants={inputVariants}
          />
        </div>
      </div>

      <div className="pt-2 border-t border-gray-100 mt-2"></div>
      
      {/* Name field - optional */}
      <div className="relative">
        <motion.input
          id="person_name"
          type="text"
          name="person_name"
          onChange={handleChange}
          value={person_name}
          placeholder="Вашето име"
          className="input input-sm w-full border-0 border-b border-gray-300 rounded-none focus:outline-none focus:border-warning bg-transparent px-0"
          whileFocus="focus"
          variants={inputVariants}
        />
        {showNameValidation && (
          <div className="absolute right-2 top-1/2 -translate-y-1/2">
            {isNameValid ? (
              <FiCheck className="text-green-500" />
            ) : (
              <FiX className="text-red-500" />
            )}
          </div>
        )}
      </div>

      {/* Additional info - optional */}
      <motion.textarea
        id="description"
        name="description"
        onChange={handleChange}
        value={description}
        placeholder="Допълнителна информация (незадължително)"
        className="textarea textarea-sm w-full border-0 border-b border-gray-300 rounded-none focus:outline-none focus:border-warning bg-transparent px-0 min-h-[60px] resize-none pt-2"
        whileFocus="focus"
        variants={inputVariants}
      />

      <motion.button
        type="submit"
        className="btn btn-warning w-full mt-6 rounded-full"
        disabled={isSubmitting}
        whileHover={{ scale: 1.02 }}
        whileTap={{ scale: 0.98 }}
      >
        <FaRegCalendarCheck className="inline-block mr-2" />
        Резервирай
      </motion.button>
    </motion.form>
  );
};

export default ReservationForm;