reg
This commit is contained in:
parent
8b52dd4a29
commit
564b5ed50f
@ -27,4 +27,12 @@ REGISTER_STEP5:"update_preferred_details", // partner preference details updat
|
||||
PREVIEW_DETAILS: "get_preview_details",
|
||||
REVIEWS: "reviews",
|
||||
|
||||
// edit api's autopapulated
|
||||
|
||||
EDIT_PERSONAL_DETAILS: "get_personal_details",
|
||||
EDIT_EDUCATION_DETAILS: "get_educational_details",
|
||||
EDIT_FAMILY_DETAILS: "get_family_details",
|
||||
EDIT_LIFESTYLE_DETAILS: "get_lifestyle_details",
|
||||
EDIT_PREFERED_PARTNER_DETAILS: "get_preferred_details",
|
||||
|
||||
};
|
||||
|
||||
@ -91,8 +91,6 @@ const AdvancedDropzone = ({ value, onChange }) => {
|
||||
actionButtons={{
|
||||
position: "after",
|
||||
abortButton: {},
|
||||
deleteButton: {},
|
||||
uploadButton: {},
|
||||
}}
|
||||
>
|
||||
{extFiles.map((file, index) => (
|
||||
|
||||
@ -106,7 +106,7 @@ const EducationalDetailsForm = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full max-w-[1200px] mx-auto bg-[#fff2f2] py-6 md:px-2 rounded-8">
|
||||
<div className="w-full max-w-[1200px] mx-auto py-6 md:px-2 rounded-8">
|
||||
<form noValidate autoComplete="off" style={{ padding: 16 }}>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-20 gap-y-10 mb-6">
|
||||
{/* Field of Study */}
|
||||
|
||||
@ -209,7 +209,7 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors, onFieldChange })
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full max-w-[1200px] mx-auto bg-[#fff2f2] py-6 md:px-2 rounded-8">
|
||||
<div className="w-full max-w-[1200px] mx-auto py-6 md:px-2 rounded-8">
|
||||
<form noValidate autoComplete="off" style={{ padding: 16 }}>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-20 gap-y-10 mb-6">
|
||||
<div className="flex flex-col gap-4">
|
||||
|
||||
@ -181,7 +181,7 @@ const LifestyleDetailsForm = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full max-w-[1200px] mx-auto bg-[#fff2f2] py-6 md:px-2 rounded-8">
|
||||
<div className="w-full max-w-[1200px] mx-auto py-6 md:px-2 rounded-8">
|
||||
<form noValidate autoComplete="off" style={{ padding: 16 }}>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-20 gap-y-10 mb-6">
|
||||
<div className="flex flex-col gap-2">
|
||||
@ -316,6 +316,7 @@ const LifestyleDetailsForm = ({
|
||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||
<DatePicker
|
||||
format="dd/MM/yyyy"
|
||||
disableFuture
|
||||
value={parseDateValue(data.dob)}
|
||||
onChange={(value) => handleChange("dob", formatDate(value))}
|
||||
slotProps={{
|
||||
|
||||
@ -198,7 +198,7 @@ const PartnerPreferencesForm = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="w-full max-w-[1200px] mx-auto bg-[#fff2f2] py-6 md:px-2 rounded-8">
|
||||
<div className="w-full max-w-[1200px] mx-auto py-6 md:px-2 rounded-8">
|
||||
<form noValidate autoComplete="off" style={{ padding: 16 }}>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-20 gap-y-10 mb-6">
|
||||
{/* Age Range */}
|
||||
|
||||
@ -433,7 +433,7 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat
|
||||
const parseDobValue = data.dob ? new Date(data.dob) : null;
|
||||
return (
|
||||
<>
|
||||
<div className="w-full max-w-[1200px] mx-auto bg-[#fff2f2] py-6 md:px-2 rounded-8">
|
||||
<div className="w-full max-w-[1200px] mx-auto py-6 md:px-2 rounded-8">
|
||||
<form noValidate autoComplete="off" style={{ padding: 16 }}>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-20 gap-y-10 mb-6">
|
||||
{/* Name */}
|
||||
@ -648,6 +648,7 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat
|
||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||
<DatePicker
|
||||
format="dd/MM/yyyy"
|
||||
disableFuture
|
||||
value={parseDobValue}
|
||||
onChange={(value) => {
|
||||
let formatted = "";
|
||||
|
||||
@ -16,12 +16,17 @@ import {
|
||||
IconButton,
|
||||
Button,
|
||||
Grid,
|
||||
Tooltip,
|
||||
} from '@mui/material';
|
||||
import { usePreviewDetails } from "../hooks/usePreview";
|
||||
import { isAuthenticated } from "../utills/auth";
|
||||
|
||||
const PreviewScreen = ({ onEdit, onSubmit }) => {
|
||||
const formData = useSelector((state) => state.registerform);
|
||||
const { data: previewData, isLoading, isError } = usePreviewDetails();
|
||||
const isAuth = isAuthenticated();
|
||||
const { data: previewData, isLoading: apiLoading, isError: apiError } = usePreviewDetails(isAuth);
|
||||
const isLoading = isAuth && apiLoading;
|
||||
const isError = isAuth && apiError;
|
||||
|
||||
const sections = previewData?.personal_details
|
||||
? [
|
||||
@ -136,6 +141,59 @@ const PreviewScreen = ({ onEdit, onSubmit }) => {
|
||||
return value || "-";
|
||||
};
|
||||
|
||||
const renderChartGrid = (getDataForCell, title) => {
|
||||
const renderCell = (i) => {
|
||||
const items = getDataForCell(i);
|
||||
const label = Array.isArray(items) ? items.join(', ') : '';
|
||||
|
||||
return (
|
||||
<Tooltip key={i} title={label} arrow placement="top" disableHoverListener={!items || items.length === 0}>
|
||||
<Box
|
||||
sx={{
|
||||
border: '1px solid #ccc',
|
||||
bgcolor: '#fff',
|
||||
height: '60px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
textAlign: 'center',
|
||||
fontSize: '0.65rem',
|
||||
fontWeight: 'bold',
|
||||
overflow: 'hidden',
|
||||
p: 0.5,
|
||||
wordBreak: 'break-word',
|
||||
lineHeight: 1.1,
|
||||
cursor: items && items.length > 0 ? 'help' : 'default'
|
||||
}}
|
||||
>
|
||||
{items && items.length > 2 ? (
|
||||
<Box>
|
||||
{items.slice(0, 2).join(', ')}
|
||||
<Box component="span" sx={{ color: 'primary.main', display: 'block', fontSize:'0.6rem' }}>+{items.length - 2}</Box>
|
||||
</Box>
|
||||
) : label}
|
||||
</Box>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Typography variant="subtitle2" align="center" gutterBottom sx={{ fontWeight: 600 }}>{title}</Typography>
|
||||
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 0.5, maxWidth: '300px', mx: 'auto', p: 1, bgcolor: '#fff3e0', borderRadius: 2 }}>
|
||||
{renderCell(1)} {renderCell(2)} {renderCell(3)} {renderCell(4)}
|
||||
{renderCell(5)}
|
||||
<Box sx={{ gridColumn: 'span 2', gridRow: 'span 2', bgcolor: '#fff', border: '1px solid #eee', display:'flex', alignItems:'center', justifyContent:'center', fontSize:'0.7rem', fontWeight:'bold', color:'#aaa' }}>
|
||||
{title.toUpperCase()}
|
||||
</Box>
|
||||
{renderCell(6)}
|
||||
{renderCell(7)} {renderCell(8)}
|
||||
{renderCell(9)} {renderCell(10)} {renderCell(11)} {renderCell(12)}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box p={3} sx={{maxWidth:"1400px", width:"100%"}} mx="auto" >
|
||||
|
||||
@ -188,6 +246,50 @@ const PreviewScreen = ({ onEdit, onSubmit }) => {
|
||||
<Divider />
|
||||
<CardContent sx={{ pt: 1, }}>
|
||||
{Object.entries(section.data || {}).map(([key, value]) => {
|
||||
// Filter out ID fields
|
||||
if (key === 'id' || key.endsWith('_id') || key.endsWith('Id') || key.endsWith('_ids') || key.endsWith('Ids') || key === 'created_at' || key === 'updated_at') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Handle Horoscope Chart (Server Data)
|
||||
if (key === 'horoscope' && value && typeof value === 'object') {
|
||||
return (
|
||||
<Box key={key} sx={{ width: '100%', mt: 2, mb: 2, borderTop: '1px solid #e0e0e0', pt: 2, gridColumn: '1 / -1' }}>
|
||||
<Typography variant="subtitle1" fontWeight="bold" gutterBottom>Horoscope Details</Typography>
|
||||
<Grid container spacing={4} justifyContent="center">
|
||||
<Grid item xs={12} md={6}>
|
||||
{renderChartGrid((i) => {
|
||||
const val = value[`graha_${i}`];
|
||||
return val ? val.split(',') : [];
|
||||
}, 'Rasi')}
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
{renderChartGrid((i) => {
|
||||
const val = value[`amsam_${i}`];
|
||||
return val ? val.split(',') : [];
|
||||
}, 'Navamsam')}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
// Handle Horoscope Chart (Redux Data)
|
||||
if (key === 'graha' && value) {
|
||||
return (
|
||||
<Box key={key} sx={{ width: '100%', mt: 2, mb: 2, gridColumn: '1 / -1' }}>
|
||||
{renderChartGrid((i) => value[i] || [], 'Rasi')}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
if (key === 'amsam' && value) {
|
||||
return (
|
||||
<Box key={key} sx={{ width: '100%', mt: 2, mb: 2, gridColumn: '1 / -1' }}>
|
||||
{renderChartGrid((i) => value[i] || [], 'Navamsam')}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
// Handle brothers and sisters arrays specifically
|
||||
if ((key === 'brothers' || key === 'sisters') && Array.isArray(value) && value.length > 0) {
|
||||
return (
|
||||
@ -229,7 +331,17 @@ const PreviewScreen = ({ onEdit, onSubmit }) => {
|
||||
<SwiperSlide key={idx}>
|
||||
<Card variant="outlined" sx={{ bgcolor: '#fff', height: '100%' }}>
|
||||
<CardContent sx={{ p: 2, '&:last-child': { pb: 2 } }}>
|
||||
{Object.entries(sibling).map(([sKey, sVal]) => (
|
||||
{Object.entries(sibling).map(([sKey, sVal]) => {
|
||||
if (sKey === 'id' || sKey.endsWith('_id') || sKey.endsWith('Id') || sKey === 'created_at' || sKey === 'updated_at') return null;
|
||||
let displayValue = sVal;
|
||||
if (sKey === 'haveChildrens' || sKey === 'have_childrens') {
|
||||
if (sVal === true || sVal === 1 || sVal === '1') {
|
||||
displayValue = 'Yes';
|
||||
} else if (sVal === false || sVal === 0 || sVal === '0') {
|
||||
displayValue = 'No';
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Box key={sKey} display="grid" gridTemplateColumns="45% 55%" gap={1} mb={0.8} alignItems="start">
|
||||
<Typography variant="caption" color="text.secondary" sx={{ fontWeight: 500 }}>
|
||||
{sKey
|
||||
@ -239,10 +351,10 @@ const PreviewScreen = ({ onEdit, onSubmit }) => {
|
||||
.trim()}
|
||||
</Typography>
|
||||
<Typography variant="body2" fontWeight={600} sx={{ wordBreak: 'break-word' }}>
|
||||
{sVal || '-'}
|
||||
{displayValue ?? '-'}
|
||||
</Typography>
|
||||
</Box>
|
||||
))}
|
||||
)})}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</SwiperSlide>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { ChevronLeft } from "lucide-react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import {
|
||||
@ -15,7 +16,7 @@ import FamilyDetailsForm from "./FamilyDetailsForm";
|
||||
import LifestyleDetailsForm from "./LifestyleDetailsForm";
|
||||
import PartnerPreferencesForm from "./PartnerPreferencesForm";
|
||||
import PreviewScreen from "./PreviewScreen";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import {
|
||||
useRegisterStep1,
|
||||
useRegisterStep2,
|
||||
@ -23,8 +24,10 @@ import {
|
||||
useRegisterStep4,
|
||||
useRegisterStep5,
|
||||
} from "../hooks/useRegister";
|
||||
import axiosInstance, { setAccessToken } from "../api/axiosInstance";
|
||||
import axiosInstance, { apiForFiles, setAccessToken } from "../api/axiosInstance";
|
||||
import toast from "react-hot-toast";
|
||||
import { API_ENDPOINTS } from "../api/apiEndpoints";
|
||||
import { isAuthenticated } from "../utills/auth";
|
||||
|
||||
const STEP_FIELD_ORDER = {
|
||||
1: [
|
||||
@ -162,6 +165,7 @@ const Stepper = ({ currentStep, onStepClick }) => {
|
||||
const StepperForm = () => {
|
||||
const dispatch = useDispatch();
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const personalDetails = useSelector(
|
||||
(state) => state.registerform.personalDetails
|
||||
@ -177,11 +181,17 @@ const StepperForm = () => {
|
||||
(state) => state.registerform.partnerPreferences
|
||||
);
|
||||
|
||||
const initialStep = location.state?.step || 1;
|
||||
const [currentStep, setCurrentStep] = useState(() => {
|
||||
if (location.state?.step) {
|
||||
return location.state.step;
|
||||
}
|
||||
const savedStep = localStorage.getItem("registration_current_step");
|
||||
return savedStep ? Number(savedStep) : 1;
|
||||
});
|
||||
|
||||
const [currentStep, setCurrentStep] = useState(initialStep);
|
||||
const [isStep1Update, setIsStep1Update] = useState(false);
|
||||
const [errors, setErrors] = useState({});
|
||||
const isAuth = isAuthenticated();
|
||||
|
||||
const registerStep1 = useRegisterStep1();
|
||||
const registerStep2 = useRegisterStep2();
|
||||
@ -189,6 +199,10 @@ const StepperForm = () => {
|
||||
const registerStep4 = useRegisterStep4();
|
||||
const registerStep5 = useRegisterStep5();
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem("registration_current_step", currentStep);
|
||||
}, [currentStep]);
|
||||
|
||||
const normalizeStep1Field = (key) => {
|
||||
if (!key) return key;
|
||||
const trimmed = String(key).trim();
|
||||
@ -331,19 +345,45 @@ const StepperForm = () => {
|
||||
}, [location.state?.step]);
|
||||
|
||||
useEffect(() => {
|
||||
// Clear the state so it doesn't persist on refresh
|
||||
if (location.state?.step) {
|
||||
navigate(location.pathname, { replace: true, state: {} });
|
||||
}
|
||||
}, [location.state, navigate, location.pathname]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAuth) return;
|
||||
const fetchPersonalDetails = async () => {
|
||||
try {
|
||||
const response = await axiosInstance.get("/get_personal_details");
|
||||
const response = await axiosInstance.get(API_ENDPOINTS.EDIT_PERSONAL_DETAILS);
|
||||
const data = response.data;
|
||||
if (data.status === "success" && data.personal_details) {
|
||||
const pd = data.personal_details;
|
||||
setIsStep1Update(true);
|
||||
|
||||
const mappedImages = (pd.images || []).map((url, index) => ({
|
||||
id: `server-${index}`,
|
||||
preview: url,
|
||||
name: `image-${index}.png`,
|
||||
}));
|
||||
const rawImages = pd.profile_images || pd.images || [];
|
||||
const mappedImages = await Promise.all(
|
||||
rawImages.map(async (url, index) => {
|
||||
const imageUrl = typeof url === "string" ? url : url?.url;
|
||||
let file = null;
|
||||
try {
|
||||
const response = await fetch(imageUrl);
|
||||
const blob = await response.blob();
|
||||
file = new File([blob], `image-${index}.png`, { type: "image/png" });
|
||||
} catch (error) {
|
||||
console.error("Error converting image URL to File:", error);
|
||||
}
|
||||
return {
|
||||
id: `server-${index}`,
|
||||
preview: imageUrl,
|
||||
imageUrl: imageUrl,
|
||||
file: file,
|
||||
name: `image-${index}.png`,
|
||||
type: "image/png",
|
||||
valid: true,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
const formattedDob = pd.dob ? pd.dob.split("T")[0] : "";
|
||||
|
||||
@ -376,7 +416,167 @@ const StepperForm = () => {
|
||||
}
|
||||
};
|
||||
fetchPersonalDetails();
|
||||
}, [dispatch]);
|
||||
}, [dispatch, isAuth]);
|
||||
|
||||
|
||||
// Fetch Educational Details
|
||||
const { data: educationalData } = useQuery({
|
||||
queryKey: ["educationalDetails"],
|
||||
queryFn: async () => {
|
||||
const response = await axiosInstance.get(API_ENDPOINTS.EDIT_EDUCATION_DETAILS);
|
||||
return response.data;
|
||||
},
|
||||
enabled: isAuth,
|
||||
retry: false,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (educationalData?.status === "success" && educationalData?.educational_details) {
|
||||
const ed = educationalData.educational_details;
|
||||
dispatch(
|
||||
updateEducationalDetails({
|
||||
fieldOfStudy: ed.study_field_id || "",
|
||||
qualification: ed.education_id || "",
|
||||
collegeName: ed.college_name || "",
|
||||
occupation: ed.occupation_id || "",
|
||||
organization: ed.company_name || "",
|
||||
employeeType: ed.employee_type_id || "",
|
||||
income: ed.annual_income_id || "",
|
||||
workLocation: ed.work_location || "",
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [educationalData, dispatch]);
|
||||
|
||||
|
||||
|
||||
// Fetch family details
|
||||
const {data:familyData} = useQuery({
|
||||
queryKey:["familyDetails"],
|
||||
queryFn: async()=>{
|
||||
const response = await axiosInstance.get(API_ENDPOINTS.EDIT_FAMILY_DETAILS);
|
||||
return response.data;
|
||||
},
|
||||
enabled: isAuth,
|
||||
retry:false,
|
||||
refetchOnWindowFocus:false,
|
||||
});
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
if (familyData?.status === "success" && familyData?.family_details) {
|
||||
const fd = familyData.family_details;
|
||||
|
||||
const mappedBrothers = (fd.brothers || []).map((b) => ({
|
||||
name: b.name || "",
|
||||
occupation: b.occupation_name || "",
|
||||
maritalStatus: b.marital_status || "",
|
||||
haveChildrens: b.have_childrens === true ? 1 : (b.have_childrens === false ? 0 : b.have_childrens),
|
||||
}));
|
||||
|
||||
const mappedSisters = (fd.sisters || []).map((s) => ({
|
||||
name: s.name || "",
|
||||
occupation: s.occupation_name || "",
|
||||
maritalStatus: s.marital_status || "",
|
||||
haveChildrens: s.have_childrens === true ? 1 : (s.have_childrens === false ? 0 : s.have_childrens),
|
||||
}));
|
||||
|
||||
dispatch(
|
||||
updateFamilyDetails({
|
||||
fatherName: fd.father_name || "",
|
||||
fatherOccupation: fd.father_occupation || "",
|
||||
motherName: fd.mother_name || "",
|
||||
motherOccupation: fd.mother_occupation || "",
|
||||
familyStatus: fd.family_status_id || "",
|
||||
nativePlace: fd.native_place || "",
|
||||
brotherCount: fd.brother_count || 0,
|
||||
sisterCount: fd.sister_count || 0,
|
||||
brothers: mappedBrothers,
|
||||
sisters: mappedSisters,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
},[familyData,dispatch])
|
||||
|
||||
// Fetch Lifestyle Details
|
||||
const { data: lifestyleData } = useQuery({
|
||||
queryKey: ["lifestyleDetails"],
|
||||
queryFn: async () => {
|
||||
const response = await axiosInstance.get(API_ENDPOINTS.EDIT_LIFESTYLE_DETAILS);
|
||||
return response.data;
|
||||
},
|
||||
enabled: isAuth,
|
||||
retry: false,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (lifestyleData?.status === "success" && lifestyleData?.lifestyle_details) {
|
||||
const ld = lifestyleData.lifestyle_details;
|
||||
const horoscope = ld.horoscope || {};
|
||||
|
||||
const mapChart = (prefix) => {
|
||||
const chart = {};
|
||||
for (let i = 1; i <= 12; i++) {
|
||||
const key = `${prefix}_${i}`;
|
||||
const val = horoscope[key];
|
||||
chart[i] = val ? val.split(",") : [];
|
||||
}
|
||||
return chart;
|
||||
};
|
||||
|
||||
dispatch(
|
||||
updateLifestyleDetails({
|
||||
diets: ld.diet_id ? [ld.diet_id] : [],
|
||||
hobbies: ld.hobbies_ids || [],
|
||||
dob: ld.date_of_birth || "",
|
||||
tob: ld.time_of_birth ? ld.time_of_birth.substring(0, 5) : "",
|
||||
placeOfBirth: ld.place_of_birth || "",
|
||||
graha: mapChart("graha"),
|
||||
amsam: mapChart("amsam"),
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [lifestyleData, dispatch]);
|
||||
|
||||
|
||||
// Fetch Partner Preferences
|
||||
const { data: partnerData } = useQuery({
|
||||
queryKey: ["partnerPreferences"],
|
||||
queryFn: async () => {
|
||||
const response = await axiosInstance.get(API_ENDPOINTS.EDIT_PREFERED_PARTNER_DETAILS);
|
||||
return response.data;
|
||||
},
|
||||
enabled: isAuth,
|
||||
retry: false,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (partnerData?.status === "success" && partnerData?.partner_preferences) {
|
||||
const pp = partnerData.partner_preferences;
|
||||
dispatch(
|
||||
updatePartnerPreferences({
|
||||
ageRange: pp.preferred_age_range_id || "",
|
||||
annualIncome: pp.preferred_annual_income_id || "",
|
||||
castes: pp.preferred_castes_ids || [],
|
||||
subCastes: pp.preferred_sub_castes_ids || [],
|
||||
occupations: pp.preferred_occupations_ids || [],
|
||||
educations: pp.preferred_educations_ids || [],
|
||||
hobbies: pp.preferred_hobbies_ids || [],
|
||||
states: pp.preferred_states_ids || [],
|
||||
districts: pp.preferred_districts_ids || [],
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [partnerData, dispatch]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -528,29 +728,34 @@ const StepperForm = () => {
|
||||
formData.append("web_fcm_token", localStorage.getItem("fcm_token") || "");
|
||||
|
||||
if (personalDetails.profiles && Array.isArray(personalDetails.profiles)) {
|
||||
for (const [index, item] of personalDetails.profiles.entries()) {
|
||||
// If the file object is intact (e.g., just added), use it directly.
|
||||
if (item.file && (item.file instanceof Blob || (typeof item.file === 'object' && item.file !== null && item.file.name))) {
|
||||
formData.append(`profile_images[${index}]`, item.file);
|
||||
}
|
||||
// If the file object was lost due to Redux serialization,
|
||||
// try to recover it from the blob URL preview.
|
||||
else if (
|
||||
item.preview &&
|
||||
typeof item.preview === "string"
|
||||
) {
|
||||
try {
|
||||
const response = await fetch(item.preview);
|
||||
const blob = await response.blob();
|
||||
const fileName = item.name || `profile_image_${index}.jpg`;
|
||||
const fileType = item.type || "image/jpeg";
|
||||
const recoveredFile = new File([blob], fileName, { type: fileType });
|
||||
formData.append(`profile_images[${index}]`, recoveredFile);
|
||||
} catch (e) {
|
||||
console.error(`Could not recover file from blob URL: ${item.preview}`, e);
|
||||
await Promise.all(
|
||||
personalDetails.profiles.map(async (item, index) => {
|
||||
let fileToAppend = item.file;
|
||||
// Check if it's a valid File/Blob. Redux might turn it into {}
|
||||
const isValidFile =
|
||||
fileToAppend &&
|
||||
(fileToAppend instanceof Blob || (typeof fileToAppend === "object" && fileToAppend.name));
|
||||
|
||||
if (!isValidFile && item.preview && typeof item.preview === "string") {
|
||||
try {
|
||||
const response = await fetch(item.preview);
|
||||
const blob = await response.blob();
|
||||
const fileName = item.name || `profile_image_${index}.jpg`;
|
||||
const fileType = item.type || "image/jpeg";
|
||||
fileToAppend = new File([blob], fileName, { type: fileType });
|
||||
} catch (e) {
|
||||
console.error(`Could not recover file from URL: ${item.preview}`, e);
|
||||
fileToAppend = null;
|
||||
}
|
||||
} else if (!isValidFile) {
|
||||
fileToAppend = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fileToAppend) {
|
||||
formData.append(`profile_images[${index}]`, fileToAppend);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
return formData;
|
||||
};
|
||||
@ -686,7 +891,7 @@ const StepperForm = () => {
|
||||
const payload = await buildRegisterStep1Payload();
|
||||
let res;
|
||||
if (isStep1Update) {
|
||||
res = await axiosInstance.post("/update_personal_details", payload);
|
||||
res = await apiForFiles.post("/update_personal_details", payload);
|
||||
} else {
|
||||
res = await registerStep1.mutateAsync(payload);
|
||||
}
|
||||
@ -769,6 +974,8 @@ const StepperForm = () => {
|
||||
// final combined API call - replace with your final API
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
toast.success("Form submitted successfully!", { position: "top-right" });
|
||||
localStorage.removeItem("registration_current_step");
|
||||
navigate("/dashboard-home");
|
||||
} catch (e) {
|
||||
toast.error("Failed to submit form.", { position: "top-right" });
|
||||
}
|
||||
@ -844,7 +1051,7 @@ const StepperForm = () => {
|
||||
<div className="">
|
||||
<div className="max-w-[1400px] mx-auto bg-white ">
|
||||
{/* Header */}
|
||||
<div className="my-4 rounded-[10px] py-4 bg-[#e3ffed] w-full max-w-[1200px] mx-auto">
|
||||
<div className="my-4 rounded-[10px] py-4 w-full max-w-[1200px] mx-auto">
|
||||
|
||||
<Stepper currentStep={currentStep} onStepClick={handleStepClick} />
|
||||
<div className="flex items-center p-4 justify-center">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user