import React, { useEffect, useState, useCallback } from "react"; import { useNavigate, useLocation } from "react-router-dom"; import { Modal } from "react-bootstrap"; import Breadcrumb from "../common/Breadcrumb"; import { apiTenant } from "./apiTenant"; import { useCreateTenant } from "./useTenants"; import TenantSubscription from "./TenantSubscription"; import { useQueryClient } from "@tanstack/react-query"; const defaultAvatar = "https://via.placeholder.com/100x100.png?text=Avatar"; const initialData = { firstName: "", lastName: "", email: "", phone: "", mobile: "", domainName: "", organizationName: "", description: "", organizationSize: "", industryId: "", reference: "", taxId: "", billingAddress: "", onBoardingDate: "", status: "", }; // RequiredLabel component remains the same for mandatory fields const RequiredLabel = ({ label, name }) => ( ); // Regular label for non-mandatory fields const RegularLabel = ({ label, name }) => ( ); const validateForm = (form, step) => { let errors = {}; let fieldsToValidate = []; // Updated list of mandatory fields for each step if (step === 1) { fieldsToValidate = [ "firstName", "lastName", "email", "phone", "billingAddress", ]; } else if (step === 2) { fieldsToValidate = [ "organizationName", "onBoardingDate", "organizationSize", "industryId", "reference", "status", ]; } fieldsToValidate.forEach((field) => { if (!form?.[field] || String(form?.[field]).trim() === "") { const fieldName = field.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase()); errors[field] = `${fieldName} is required.`; } }); if (step === 1 && form.phone && !/^[0-9]{10}$/.test(form.phone)) { errors.phone = "Phone number must be a 10-digit number."; } return errors; }; const CreateTenant = () => { const navigate = useNavigate(); const { state } = useLocation(); const formData = state?.formData || null; // const { createTenant, updateTenant, loading } = useCreateTenant(); const { mutate: createTenant, isPending } = useCreateTenant(); const queryClient = useQueryClient(); const [form, setForm] = useState(initialData); const [formErrors, setFormErrors] = useState({}); const [imagePreview, setImagePreview] = useState(defaultAvatar); const [imageFile, setImageFile] = useState(null); const [showImageModal, setShowImageModal] = useState(false); const [showImageSizeModal, setShowImageSizeModal] = useState(false); const [industryOptions, setIndustryOptions] = useState([]); const [step, setStep] = useState(1); useEffect(() => { if (formData) { const { contactName, contactNumber, logoImage, ...rest } = formData; const [firstName, ...lastNameParts] = (contactName || "").trim().split(" "); const lastName = lastNameParts.join(" "); setForm({ ...initialData, ...rest, firstName, lastName, phone: contactNumber || "" }); if (logoImage) setImagePreview(logoImage); } }, [formData]); useEffect(() => { const fetchIndustries = async () => { try { const { data } = await apiTenant.getIndustries(); if (Array.isArray(data)) { setIndustryOptions(data); if (formData?.industry) { const matchedIndustry = data.find((i) => i.name === formData.industry.name); if (matchedIndustry) setForm((prev) => ({ ...prev, industryId: matchedIndustry.id })); } } } catch (err) { console.error("Failed to load industries:", err); } }; fetchIndustries(); }, [formData]); const handleChange = (e) => { const { name, value } = e.target; const sanitizedValue = name === "phone" ? value.replace(/\D/g, "") : value; setForm((prev) => ({ ...prev, [name]: sanitizedValue })); if (formErrors?.[name]) { setFormErrors((prev) => { const newErrors = { ...prev }; delete newErrors?.[name]; return newErrors; }); } }; const handleImageChange = (e) => { const file = e.target.files?.[0]; if (!file) return; if (file.size > 200 * 1024) { setShowImageSizeModal(true); return; } setImageFile(file); const reader = new FileReader(); reader.onloadend = () => setImagePreview(reader.result); reader.readAsDataURL(file); }; const handleImageReset = () => { setImageFile(null); setImagePreview(defaultAvatar); }; const handleClearForm = () => { setForm(initialData); setFormErrors({}); handleImageReset(); setStep(1); }; const handleNext = () => { const errors = validateForm(form, step); if (Object.keys(errors).length > 0) { setFormErrors(errors); return; } setFormErrors({}); setStep((prev) => prev + 1); }; const handleSubmit = useCallback( async (e) => { e.preventDefault(); const errors = validateForm(form, 2); if (Object.keys(errors).length > 0) { setFormErrors(errors); setStep(2); return; } setFormErrors({}); const finalLogoImage = imageFile || (imagePreview === defaultAvatar ? null : imagePreview); const tenantPayload = { ...form, logoImage: finalLogoImage, contactNumber: form.phone, contactName: `${form.firstName} ${form.lastName}`.trim(), }; let result; if (formData?.id) { // result = await updateTenant(formData.id, tenantPayload); if (result) navigate("/tenant/profile", { state: { newTenant: result } }); } else { // result = await createTenant(submissionData); // if (result) navigate("/tenant/profile/viewtenant", { state: { formData: result } }); createTenant(tenantPayload); } }, [form, imagePreview, imageFile, formData, navigate, createTenant] ); const renderFormStep = () => { switch (step) { case 1: return ( <>
{formErrors?.firstName && (

{formErrors.firstName}

)}
{formErrors?.lastName && (

{formErrors.lastName}

)}
{formErrors?.email && (

{formErrors.email}

)}
{formErrors?.phone && (

{formErrors.phone}

)}
{formErrors?.billingAddress && (

{formErrors.billingAddress}

)}
); case 2: return ( <>
{formErrors?.onBoardingDate && (

{formErrors.onBoardingDate}

)}
{formErrors?.organizationName && (

{formErrors.organizationName}

)}
{formErrors?.organizationSize && (

{formErrors.organizationSize}

)}
{formErrors?.industryId && (

{formErrors.industryId}

)}
{formErrors?.reference && (

{formErrors.reference}

)}
{formErrors?.status && (

{formErrors.status}

)}
{formErrors?.taxId && (

{formErrors.taxId}

)}
{formErrors?.domainName && (

{formErrors.domainName}

)}
{formErrors?.mobile && (

{formErrors.mobile}

)}
{formErrors?.description && (

{formErrors.description}

)}
Profile Preview setShowImageModal(true)} style={{ width: "100px", height: "100px", objectFit: "cover", borderRadius: "8px", border: "1px solid #ccc", cursor: "pointer", }} />
Allowed JPG, GIF or PNG. Max size of 200KB
); case 3: return (
); default: return null; } }; const steps = [ { label: "Contact Info", subtitle: "Provide contact details", icon: "bx-user" }, { label: "Organization Details", subtitle: "Enter organization info", icon: "bx-buildings" }, { label: "Subscription", subtitle: "Select a plan", icon: "bx-credit-card" }, ]; return (
{formData?.id ? "Update Tenant" : "Create Tenant"}
{step !== 3 && ()}
{/* Steps Container with vertical divider */}
{steps.map((s, index) => (
))}
{/* Form Content */}
{renderFormStep()}
{step > 1 && ()} {step < 3 && ()} {step === 3 && ()}
setShowImageModal(false)} centered size="lg"> Preview setShowImageSizeModal(false)} centered> Image Size Warning The selected image file must be less than 200KB. Please choose a smaller file.
); }; export default CreateTenant;