163 lines
6.2 KiB
JavaScript
163 lines
6.2 KiB
JavaScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { motion, AnimatePresence } from "framer-motion";
|
|
import { useTranslation } from "react-i18next";
|
|
import toast, { Toaster } from "react-hot-toast";
|
|
import { addOwner, loginWithEmail } from "../../utils/api";
|
|
import AuthService from "../../services/AuthService";
|
|
import { OwnerType } from "../../enums";
|
|
import OtpDialog from "./OtpDialog";
|
|
import HeaderOfSteps from "./HeaderOfSteps";
|
|
import HeaderOfForm from "./HeaderOfForm";
|
|
import { BackgroundElements, fadeInUp, staggerContainer } from "../Animation/OwnerPageAnimation";
|
|
import { validateStep1, validateStep2 } from "../../validations/OwnerValidatoin";
|
|
import OwnerFormStepOne from "./OwnerFormStepOne";
|
|
import ButtomStepOne from "./ButtomStepOne";
|
|
import ButtomStepTwo from "./ButtomStepTwo";
|
|
import OwnerFormStepTwo from "./OwnerFormStepTwo";
|
|
import InteractiveBackground from "../Animation/Background";
|
|
|
|
export default function Owner() {
|
|
const { t } = useTranslation();
|
|
const [step, setStep] = useState(1);
|
|
const [showOtpModal, setShowOtpModal] = useState(false);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [formData, setFormData] = useState({
|
|
firstName: "",
|
|
lastName: "",
|
|
email: "",
|
|
phone: "",
|
|
whatsapp: "",
|
|
phone2: "",
|
|
nationalNumber: "",
|
|
password: "",
|
|
confirmPassword: "",
|
|
ownerType: OwnerType.PERSON,
|
|
agreeTerms: false,
|
|
});
|
|
const [idImages, setIdImages] = useState({ front: null, back: null, license: null });
|
|
const [idImagePreviews, setIdImagePreviews] = useState({ front: "", back: "", license: "" });
|
|
const [errors, setErrors] = useState({});
|
|
|
|
const isCompany = Number(formData.ownerType) === OwnerType.REAL_ESTATE_AGENCY;
|
|
|
|
const handleNextStep = () => {
|
|
if (validateStep1(formData, setErrors, t)) {
|
|
setStep(2);
|
|
window.scrollTo({ top: 0, behavior: "smooth" });
|
|
} else {
|
|
toast.error(t("validation.correctErrors"));
|
|
}
|
|
};
|
|
|
|
const handleSubmit = async (e) => {
|
|
e.preventDefault();
|
|
if (!validateStep2(idImages, setErrors, t)) {
|
|
toast.error(t("register.completeRequiredImages"));
|
|
return;
|
|
}
|
|
if (!formData.agreeTerms) {
|
|
toast.error(t("validation.agreeToTerms"));
|
|
return;
|
|
}
|
|
setIsLoading(true);
|
|
const payload = {
|
|
firstName: formData.firstName,
|
|
lastName: formData.lastName,
|
|
email: formData.email,
|
|
phoneNumber: formData.phone || "",
|
|
whatsAppNumber: formData.whatsapp,
|
|
phone: formData.phone2,
|
|
nationalNumber: formData.nationalNumber,
|
|
password: formData.password,
|
|
ownerType: formData.ownerType,
|
|
};
|
|
|
|
try {
|
|
const licenseImage = isCompany ? idImages.license : null;
|
|
const res = await addOwner(payload, idImages.front, idImages.back,licenseImage);
|
|
if (res.status === 200 || res.ok) {
|
|
toast.success(res.message || t("register.accountCreated")||res.data[0].message , { duration: 4000 });
|
|
const loginRes = await loginWithEmail(formData.email, formData.password);
|
|
if (loginRes.status === 206) {
|
|
const otpToken = loginRes.data;
|
|
if (otpToken) AuthService.addToken(otpToken);
|
|
toast(loginRes.message || t("register.otpSentEmail"), { icon: "📧" });
|
|
setShowOtpModal(true);
|
|
} else if (loginRes.status === 200) {
|
|
const loginToken = loginRes.data;
|
|
if (loginToken) AuthService.addToken(loginToken);
|
|
toast.success(loginRes.message || t("register.loginSuccess"));
|
|
}
|
|
} else {
|
|
toast.error(res.data[0].message || res.data?.message);
|
|
}
|
|
} catch (err) {
|
|
toast.error(err.message || t("register.registrationError"));
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center p-4 relative overflow-hidden">
|
|
<Toaster position="top-center" reverseOrder={false} />
|
|
<div className="absolute inset-0 overflow-hidden">
|
|
<BackgroundElements />
|
|
<InteractiveBackground />
|
|
</div>
|
|
<motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} transition={{ duration: 0.5 }} className="relative z-10 w-full max-w-2xl">
|
|
<HeaderOfSteps step={step} numberStep={[1, 2]} colors={"bg-amber-500"} />
|
|
<motion.div
|
|
key={step}
|
|
initial={{ opacity: 0, x: 20 }}
|
|
animate={{ opacity: 1, x: 0 }}
|
|
exit={{ opacity: 0, x: -20 }}
|
|
transition={{ duration: 0.3 }}
|
|
className="bg-white/5 backdrop-blur-xl rounded-3xl shadow-2xl border border-white/10 overflow-hidden"
|
|
>
|
|
<HeaderOfForm step={step} num={0} />
|
|
<div className="p-8">
|
|
<motion.form
|
|
variants={staggerContainer}
|
|
initial="initial"
|
|
animate="animate"
|
|
onSubmit={
|
|
step === 1
|
|
? (e) => {
|
|
e.preventDefault();
|
|
handleNextStep();
|
|
}
|
|
: handleSubmit
|
|
}
|
|
className="space-y-6"
|
|
>
|
|
{step === 1 && (
|
|
<OwnerFormStepOne
|
|
setErrors={setErrors}
|
|
setFormData={setFormData}
|
|
formData={formData}
|
|
errors={errors}
|
|
isCompany={isCompany}
|
|
setIdImagePreviews={setIdImagePreviews}
|
|
setIdImages={setIdImages}
|
|
type={"owner"}
|
|
/>
|
|
)}
|
|
{step === 2 && (
|
|
<>
|
|
<OwnerFormStepTwo idImagePreviews={idImagePreviews} errors={errors} setIdImagePreviews={setIdImagePreviews} setIdImages={setIdImages} setFormData={setFormData} formData={formData} />
|
|
</>
|
|
)}
|
|
<motion.div variants={fadeInUp} className="flex gap-3 pt-4">
|
|
{step === 1 ? ( <> <ButtomStepOne type={"owner"} /></>) : ( <> <ButtomStepTwo formData={formData} isLoading={isLoading} setStep={setStep} type={"owner"} /> </>)}
|
|
</motion.div>
|
|
</motion.form>
|
|
</div>
|
|
</motion.div>
|
|
</motion.div>
|
|
<AnimatePresence>{showOtpModal && <OtpDialog formData={formData} setShowOtpModal={setShowOtpModal} type={"owner"} />}</AnimatePresence>
|
|
</div>
|
|
);
|
|
}
|