bug fixing
This commit is contained in:
parent
805c93b3f3
commit
5392a4211e
@ -28,12 +28,13 @@ import axiosInstance, { logoutAPI } from "../../api/axiosInstance";
|
|||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { API_ENDPOINTS } from "../../api/apiEndpoints";
|
import { API_ENDPOINTS } from "../../api/apiEndpoints";
|
||||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
const NAV_LINKS = [
|
const NAV_LINKS = [
|
||||||
// { label: "Home", path: "/" },
|
// { label: "Home", path: "/" },
|
||||||
{ label: "Matches", path: "/matches" },
|
{ label: "Matches", path: "/matches" },
|
||||||
// { label: "ProfileCard", path: "/profile-card" },
|
// { label: "ProfileCard", path: "/profile-card" },
|
||||||
{ label: "Interest", path: "/interest" },
|
{ label: "Interest", path: "/interest" },
|
||||||
{ label: "Horoscope", path: "/horoscoper-generate" },
|
// { label: "Horoscope", path: "/horoscoper-generate" },
|
||||||
{ label: "Messages", path: "/chat" },
|
{ label: "Messages", path: "/chat" },
|
||||||
{ label: "Search", path: "/matches" },
|
{ label: "Search", path: "/matches" },
|
||||||
{ label: "Notifications", path: "/notifications" }
|
{ label: "Notifications", path: "/notifications" }
|
||||||
@ -159,6 +160,14 @@ const ProfileHeader = () => {
|
|||||||
const [deleteModalOpen, setDeleteModalOpen] = useState(false);
|
const [deleteModalOpen, setDeleteModalOpen] = useState(false);
|
||||||
const [logoutModalOpen, setLogoutModalOpen] = useState(false);
|
const [logoutModalOpen, setLogoutModalOpen] = useState(false);
|
||||||
|
|
||||||
|
const { personalDetails } = useSelector((state) => state.registerform);
|
||||||
|
|
||||||
|
const profileImage =
|
||||||
|
personalDetails?.profiles?.[0]?.preview ||
|
||||||
|
personalDetails?.profiles?.[0]?.url ||
|
||||||
|
personalDetails?.profiles?.[0] ||
|
||||||
|
userimg;
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isDesktop = useMediaQuery(theme.breakpoints.up("md"));
|
const isDesktop = useMediaQuery(theme.breakpoints.up("md"));
|
||||||
|
|
||||||
@ -200,7 +209,7 @@ const ProfileHeader = () => {
|
|||||||
|
|
||||||
const deleteAccountMutation = useMutation({
|
const deleteAccountMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
return await axiosInstance.delete(API_ENDPOINTS.DELETE_ACCOUNT);
|
return await axiosInstance.post(API_ENDPOINTS.DELETE_ACCOUNT);
|
||||||
},
|
},
|
||||||
onSuccess: (response) => {
|
onSuccess: (response) => {
|
||||||
toast.success(response?.data?.message || "Account deleted successfully");
|
toast.success(response?.data?.message || "Account deleted successfully");
|
||||||
@ -372,7 +381,7 @@ const ProfileHeader = () => {
|
|||||||
<Box sx={{ flexGrow: 0 }}>
|
<Box sx={{ flexGrow: 0 }}>
|
||||||
<Tooltip title="Account Menu">
|
<Tooltip title="Account Menu">
|
||||||
<IconButton onClick={toggleProfileDrawer(true)}>
|
<IconButton onClick={toggleProfileDrawer(true)}>
|
||||||
<Avatar sx={{width:"50px", height:"50px"}} src={userimg || "/static/images/avatar/2.jpg" }/>
|
<Avatar sx={{width:"50px", height:"50px"}} src={profileImage || userimg || "/static/images/avatar/2.jpg" }/>
|
||||||
|
|
||||||
|
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|||||||
@ -75,12 +75,12 @@ const AdvancedDropzone = ({ value, onChange }) => {
|
|||||||
<>
|
<>
|
||||||
<Dropzone
|
<Dropzone
|
||||||
onChange={updateFiles}
|
onChange={updateFiles}
|
||||||
minHeight="195px"
|
minHeight="200px"
|
||||||
value={extFiles}
|
value={extFiles}
|
||||||
accept="image/*"
|
accept="image/*"
|
||||||
maxFiles={3}
|
maxFiles={3}
|
||||||
maxFileSize={10 * 1024 * 1024}
|
maxFileSize={10 * 1024 * 1024}
|
||||||
label="Drag'n drop up to 3 images (max 10 MB each)"
|
label={<span style={{ fontSize: "16px" }}>Drag'n drop up to 3 images (max 10 MB each)</span>}
|
||||||
uploadConfig={{
|
uploadConfig={{
|
||||||
url: BASE_URL + "/file",
|
url: BASE_URL + "/file",
|
||||||
cleanOnUpload: true,
|
cleanOnUpload: true,
|
||||||
@ -107,14 +107,14 @@ const AdvancedDropzone = ({ value, onChange }) => {
|
|||||||
<FileMosaic
|
<FileMosaic
|
||||||
{...file}
|
{...file}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
onSee={handleSee}
|
// onSee={handleSee}
|
||||||
onWatch={handleWatch}
|
// onWatch={handleWatch}
|
||||||
onAbort={handleAbort}
|
onAbort={handleAbort}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
resultOnTooltip
|
resultOnTooltip
|
||||||
alwaysActive
|
alwaysActive
|
||||||
preview
|
preview
|
||||||
info={false}
|
// info={false}
|
||||||
/>
|
/>
|
||||||
{hoveredId === file.id && (
|
{hoveredId === file.id && (
|
||||||
<div
|
<div
|
||||||
@ -155,9 +155,9 @@ const AdvancedDropzone = ({ value, onChange }) => {
|
|||||||
}}
|
}}
|
||||||
aria-label="Move left"
|
aria-label="Move left"
|
||||||
>
|
>
|
||||||
<ArrowLeftIcon fontSize="small" />
|
<ArrowLeftIcon fontSize="small" sx={{fontSize:"30px"}} />
|
||||||
</button>
|
</button>
|
||||||
<span
|
{/* <span
|
||||||
style={{
|
style={{
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@ -170,7 +170,7 @@ const AdvancedDropzone = ({ value, onChange }) => {
|
|||||||
title={file.name}
|
title={file.name}
|
||||||
>
|
>
|
||||||
{file.name}
|
{file.name}
|
||||||
</span>
|
</span> */}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
@ -197,7 +197,7 @@ const AdvancedDropzone = ({ value, onChange }) => {
|
|||||||
}}
|
}}
|
||||||
aria-label="Move right"
|
aria-label="Move right"
|
||||||
>
|
>
|
||||||
<ArrowRightIcon fontSize="small" />
|
<ArrowRightIcon fontSize="small" sx={{fontSize:"30px"}} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -33,7 +33,7 @@ import {
|
|||||||
} from "../hooks/useDependentMasters";
|
} from "../hooks/useDependentMasters";
|
||||||
import { useSendOtp, useVerifyOtp } from "../hooks/useAuth";
|
import { useSendOtp, useVerifyOtp } from "../hooks/useAuth";
|
||||||
const OTP_LENGTH = 4;
|
const OTP_LENGTH = 4;
|
||||||
const OTP_TIMER_SEC = 120; // 2 minutes
|
const OTP_TIMER_SEC = 60; // 1 minute
|
||||||
|
|
||||||
const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Update }) => {
|
const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Update }) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@ -51,25 +51,19 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat
|
|||||||
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
||||||
const sendOtp = useSendOtp();
|
const sendOtp = useSendOtp();
|
||||||
const verifyOtp = useVerifyOtp();
|
const verifyOtp = useVerifyOtp();
|
||||||
const [verifiedMobileNumber, setVerifiedMobileNumber] = useState(
|
|
||||||
() => localStorage.getItem("registration_verified_mobile") || ""
|
|
||||||
);
|
|
||||||
const initializedVerifiedNumber = useRef(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isStep1Update && data.mobileNumber && !initializedVerifiedNumber.current) {
|
if (isStep1Update && data.mobileNumber && !data.verifiedMobileNumber) {
|
||||||
setVerifiedMobileNumber(data.mobileNumber);
|
dispatch(updatePersonalDetails({ verifiedMobileNumber: data.mobileNumber }));
|
||||||
localStorage.setItem("registration_verified_mobile", data.mobileNumber);
|
|
||||||
setMobileOtpVerified(true);
|
setMobileOtpVerified(true);
|
||||||
initializedVerifiedNumber.current = true;
|
|
||||||
}
|
}
|
||||||
}, [isStep1Update, data.mobileNumber]);
|
}, [isStep1Update, data.mobileNumber, data.verifiedMobileNumber, dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (verifiedMobileNumber && data.mobileNumber === verifiedMobileNumber) {
|
if (data.verifiedMobileNumber && data.mobileNumber === data.verifiedMobileNumber) {
|
||||||
setMobileOtpVerified(true);
|
setMobileOtpVerified(true);
|
||||||
}
|
}
|
||||||
}, [verifiedMobileNumber, data.mobileNumber]);
|
}, [data.verifiedMobileNumber, data.mobileNumber]);
|
||||||
|
|
||||||
const { data: personalMasters, isLoading: isPersonalMastersLoading } =
|
const { data: personalMasters, isLoading: isPersonalMastersLoading } =
|
||||||
usePersonalDetailsMasters();
|
usePersonalDetailsMasters();
|
||||||
@ -282,11 +276,15 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleChange = (field, value) => {
|
const handleChange = (field, value) => {
|
||||||
|
if (field === "name" && !/^[a-zA-Z\s]*$/.test(value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const updates = { [field]: value };
|
const updates = { [field]: value };
|
||||||
const fieldsToClear = [field];
|
const fieldsToClear = [field];
|
||||||
if (field === "mobileNumber") {
|
if (field === "mobileNumber") {
|
||||||
setMobileNumberError("");
|
setMobileNumberError("");
|
||||||
if (verifiedMobileNumber && value === verifiedMobileNumber) {
|
if (data.verifiedMobileNumber && value === data.verifiedMobileNumber) {
|
||||||
setMobileOtpVerified(true);
|
setMobileOtpVerified(true);
|
||||||
setShowOtp(false);
|
setShowOtp(false);
|
||||||
setOtpError("");
|
setOtpError("");
|
||||||
@ -373,8 +371,7 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat
|
|||||||
"OTP verified successfully";
|
"OTP verified successfully";
|
||||||
toast.success(successMessage, { position: "top-right" });
|
toast.success(successMessage, { position: "top-right" });
|
||||||
setMobileOtpVerified(true);
|
setMobileOtpVerified(true);
|
||||||
setVerifiedMobileNumber(data.mobileNumber);
|
dispatch(updatePersonalDetails({ verifiedMobileNumber: data.mobileNumber }));
|
||||||
localStorage.setItem("registration_verified_mobile", data.mobileNumber);
|
|
||||||
setMobileNumberError("");
|
setMobileNumberError("");
|
||||||
setOtpError("");
|
setOtpError("");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -387,6 +384,13 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (showOtp && !mobileOtpVerified && isOtpComplete) {
|
||||||
|
handleOtpSubmit();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [otp]);
|
||||||
|
|
||||||
|
|
||||||
// file upload
|
// file upload
|
||||||
|
|
||||||
@ -583,7 +587,7 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* OTP Inputs */}
|
{/* OTP Inputs */}
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-4">
|
||||||
{showOtp && !mobileOtpVerified && (
|
{showOtp && !mobileOtpVerified && (
|
||||||
<>
|
<>
|
||||||
<Box display="flex" gap={1} alignItems="center">
|
<Box display="flex" gap={1} alignItems="center">
|
||||||
@ -595,7 +599,8 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat
|
|||||||
maxLength: 1,
|
maxLength: 1,
|
||||||
style: {
|
style: {
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
width: 40,
|
width: 20,
|
||||||
|
height:20,
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
backgroundColor: digit
|
backgroundColor: digit
|
||||||
@ -628,14 +633,14 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat
|
|||||||
{otpTimer > 0 ? (
|
{otpTimer > 0 ? (
|
||||||
` ${formatTimer(otpTimer) } Seconds`
|
` ${formatTimer(otpTimer) } Seconds`
|
||||||
) : (
|
) : (
|
||||||
<Link
|
<button
|
||||||
component="button"
|
component="button"
|
||||||
variant="body2"
|
variant="body2"
|
||||||
onClick={resetOtp}
|
onClick={handleMobileSubmit}
|
||||||
disabled={otpTimer > 0}
|
disabled={otpTimer > 0}
|
||||||
>
|
>
|
||||||
Resend OTP
|
Resend OTP
|
||||||
</Link>
|
</button>
|
||||||
)}
|
)}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
@ -1290,6 +1295,11 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat
|
|||||||
dispatch(updatePersonalDetails({ profiles: files }));
|
dispatch(updatePersonalDetails({ profiles: files }));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{errors.profiles && (
|
||||||
|
<p style={{ color: "#d32f2f", fontSize: "0.75rem", margin: "3px 14px 0 14px" }}>
|
||||||
|
{errors.profiles}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import { Swiper, SwiperSlide } from "swiper/react";
|
import { Swiper, SwiperSlide } from "swiper/react";
|
||||||
import { Navigation, Pagination } from "swiper/modules";
|
import { Navigation, Pagination } from "swiper/modules";
|
||||||
import "swiper/css";
|
import "swiper/css";
|
||||||
@ -26,6 +26,7 @@ import {
|
|||||||
import { usePreviewDetails } from "../hooks/usePreview";
|
import { usePreviewDetails } from "../hooks/usePreview";
|
||||||
import { isAuthenticated } from "../utills/auth";
|
import { isAuthenticated } from "../utills/auth";
|
||||||
import horoscopeImg from "../assets/images/horoscopeimg.png";
|
import horoscopeImg from "../assets/images/horoscopeimg.png";
|
||||||
|
import { updatePersonalDetails } from "../redux/registrationFormSlice";
|
||||||
|
|
||||||
const PreviewScreen = ({ onEdit, onSubmit }) => {
|
const PreviewScreen = ({ onEdit, onSubmit }) => {
|
||||||
const formData = useSelector((state) => state.registerform);
|
const formData = useSelector((state) => state.registerform);
|
||||||
@ -34,6 +35,22 @@ const PreviewScreen = ({ onEdit, onSubmit }) => {
|
|||||||
const isLoading = isAuth && apiLoading;
|
const isLoading = isAuth && apiLoading;
|
||||||
const isError = isAuth && apiError;
|
const isError = isAuth && apiError;
|
||||||
|
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const pd = previewData?.personal_details;
|
||||||
|
if (pd) {
|
||||||
|
const images = pd.images || pd.profile_images;
|
||||||
|
if (images && images.length > 0) {
|
||||||
|
// Map images to ensure they have a consistent format for Redux
|
||||||
|
const formattedImages = images.map(img =>
|
||||||
|
typeof img === 'string' ? { url: img, preview: img } : img
|
||||||
|
);
|
||||||
|
dispatch(updatePersonalDetails({ profiles: formattedImages }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [previewData, dispatch]);
|
||||||
|
|
||||||
const [openConfirmDialog, setOpenConfirmDialog] = useState(false);
|
const [openConfirmDialog, setOpenConfirmDialog] = useState(false);
|
||||||
|
|
||||||
const handleConfirmSubmit = () => {
|
const handleConfirmSubmit = () => {
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import { Swiper, SwiperSlide } from "swiper/react";
|
import { Swiper, SwiperSlide } from "swiper/react";
|
||||||
import { Navigation, Autoplay } from "swiper/modules";
|
import { Navigation, Autoplay } from "swiper/modules";
|
||||||
import { ChevronLeft, ChevronRight, Edit2 } from "lucide-react";
|
import { ChevronLeft, ChevronRight, Edit2 } from "lucide-react";
|
||||||
|
import { useEffect } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
import "swiper/css";
|
import "swiper/css";
|
||||||
import "swiper/css/navigation";
|
import "swiper/css/navigation";
|
||||||
import LazyImage from "../components/common/LazyImage";
|
import LazyImage from "../components/common/LazyImage";
|
||||||
@ -28,6 +29,7 @@ import {
|
|||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { Info } from "@mui/icons-material";
|
import { Info } from "@mui/icons-material";
|
||||||
import { usePreviewDetails } from "../hooks/usePreview";
|
import { usePreviewDetails } from "../hooks/usePreview";
|
||||||
|
import { updatePersonalDetails } from "../redux/registrationFormSlice";
|
||||||
|
|
||||||
const images = [
|
const images = [
|
||||||
weddingpromo1, // bride in saree
|
weddingpromo1, // bride in saree
|
||||||
@ -44,8 +46,22 @@ const images = [
|
|||||||
|
|
||||||
const ProfilePreviewPage = () => {
|
const ProfilePreviewPage = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const dispatch = useDispatch();
|
||||||
const { data, isLoading } = usePreviewDetails();
|
const { data, isLoading } = usePreviewDetails();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data?.personal_details) {
|
||||||
|
const pd = data.personal_details;
|
||||||
|
const images = pd.images || pd.profile_images;
|
||||||
|
if (images && images.length > 0) {
|
||||||
|
const formattedImages = images.map((img) =>
|
||||||
|
typeof img === "string" ? { url: img, preview: img } : img
|
||||||
|
);
|
||||||
|
dispatch(updatePersonalDetails({ profiles: formattedImages }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [data, dispatch]);
|
||||||
|
|
||||||
const personalDetails = data?.personal_details
|
const personalDetails = data?.personal_details
|
||||||
? {
|
? {
|
||||||
name: data.personal_details.name,
|
name: data.personal_details.name,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { ChevronLeft } from "lucide-react";
|
import { ChevronLeft } from "lucide-react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import {
|
import {
|
||||||
@ -28,6 +28,7 @@ import axiosInstance, { apiForFiles, setAccessToken } from "../api/axiosInstance
|
|||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { API_ENDPOINTS } from "../api/apiEndpoints";
|
import { API_ENDPOINTS } from "../api/apiEndpoints";
|
||||||
import { isAuthenticated } from "../utills/auth";
|
import { isAuthenticated } from "../utills/auth";
|
||||||
|
import { getPreviewDetails } from "../api/preview.api";
|
||||||
const STEP_FIELD_ORDER = {
|
const STEP_FIELD_ORDER = {
|
||||||
1: [
|
1: [
|
||||||
"name",
|
"name",
|
||||||
@ -228,6 +229,7 @@ const Stepper = ({ currentStep, enabledSteps, completedSteps, onStepClick }) =>
|
|||||||
|
|
||||||
const StepperForm = () => {
|
const StepperForm = () => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const hideStepperRoutes = ["/profile-edit"];
|
const hideStepperRoutes = ["/profile-edit"];
|
||||||
@ -434,10 +436,16 @@ const [completedSteps, setCompletedSteps] = useState([]);
|
|||||||
rawImages.map(async (url, index) => {
|
rawImages.map(async (url, index) => {
|
||||||
const imageUrl = typeof url === "string" ? url : url?.url;
|
const imageUrl = typeof url === "string" ? url : url?.url;
|
||||||
let file = null;
|
let file = null;
|
||||||
|
let mimeType = "image/jpeg";
|
||||||
|
let fileName = `image-${index}.jpg`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(imageUrl);
|
const response = await fetch(imageUrl);
|
||||||
const blob = await response.blob();
|
const blob = await response.blob();
|
||||||
file = new File([blob], `image-${index}.png`, { type: "image/png" });
|
if (blob.type) mimeType = blob.type;
|
||||||
|
const ext = mimeType.split("/")[1] || "jpg";
|
||||||
|
fileName = `image-${index}.${ext}`;
|
||||||
|
file = new File([blob], fileName, { type: mimeType });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error converting image URL to File:", error);
|
console.error("Error converting image URL to File:", error);
|
||||||
}
|
}
|
||||||
@ -446,8 +454,8 @@ const [completedSteps, setCompletedSteps] = useState([]);
|
|||||||
preview: imageUrl,
|
preview: imageUrl,
|
||||||
imageUrl: imageUrl,
|
imageUrl: imageUrl,
|
||||||
file: file,
|
file: file,
|
||||||
name: `image-${index}.png`,
|
name: fileName,
|
||||||
type: "image/png",
|
type: mimeType,
|
||||||
valid: true,
|
valid: true,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@ -669,13 +677,16 @@ useEffect(()=>{
|
|||||||
|
|
||||||
required.forEach((field) => {
|
required.forEach((field) => {
|
||||||
if (!personalDetails[field]) {
|
if (!personalDetails[field]) {
|
||||||
newErrors[field] = "This field is required";
|
const label = field
|
||||||
|
.replace(/([A-Z])/g, " $1")
|
||||||
|
.replace(/^./, (str) => str.toUpperCase());
|
||||||
|
newErrors[field] = `${label} is required`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isStep1Update) {
|
if (!isStep1Update) {
|
||||||
if (!personalDetails.password) newErrors.password = "This field is required";
|
if (!personalDetails.password) newErrors.password = "Password is required";
|
||||||
if (!personalDetails.confirmPassword) newErrors.confirmPassword = "This field is required";
|
if (!personalDetails.confirmPassword) newErrors.confirmPassword = "Confirm Password is required";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -733,19 +744,44 @@ useEffect(()=>{
|
|||||||
newErrors[field] = `${label} is required`;
|
newErrors[field] = `${label} is required`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (familyDetails.fatherName && !/^[a-zA-Z\s]*$/.test(familyDetails.fatherName)) {
|
||||||
|
newErrors.fatherName = "Father Name must contain only alphabets";
|
||||||
|
}
|
||||||
|
if (familyDetails.motherName && !/^[a-zA-Z\s]*$/.test(familyDetails.motherName)) {
|
||||||
|
newErrors.motherName = "Mother Name must contain only alphabets";
|
||||||
|
}
|
||||||
} else if (step === 4) {
|
} else if (step === 4) {
|
||||||
const required = ["diets", "hobbies", "dob", "tob"];
|
const required = ["diets", "hobbies", "dob", "tob"];
|
||||||
required.forEach((field) => {
|
required.forEach((field) => {
|
||||||
const value = lifestyleDetails[field];
|
const value = lifestyleDetails[field];
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
if (value.length === 0) newErrors[field] = "This field is required";
|
if (value.length === 0) {
|
||||||
|
if (field === "hobbies") {
|
||||||
|
newErrors[field] = "Hobbies and Interests is required";
|
||||||
|
} else {
|
||||||
|
newErrors[field] = "This field is required";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (!value) {
|
} else if (!value) {
|
||||||
// newErrors[field] = "This field is required";
|
|
||||||
|
if (field === "dob") {
|
||||||
|
newErrors[field] = "Date of Birth is required";
|
||||||
|
}
|
||||||
|
else if (field === "tob") {
|
||||||
|
newErrors[field] = "Time of Birth is required";
|
||||||
|
}
|
||||||
|
else if (field === "diets") {
|
||||||
|
newErrors[field] = "Diet is required";
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
const label = field
|
const label = field
|
||||||
.replace(/([A-Z])/g, " $1")
|
.replace(/([A-Z])/g, " $1")
|
||||||
.replace(/^./, (str) => str.toUpperCase());
|
.replace(/^./, (str) => str.toUpperCase());
|
||||||
newErrors[field] = `${label} is required`;
|
newErrors[field] = `${label} is required`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (step === 5) {
|
} else if (step === 5) {
|
||||||
@ -764,7 +800,11 @@ useEffect(()=>{
|
|||||||
const value = partnerPreferences[field];
|
const value = partnerPreferences[field];
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
if (value.length === 0) {
|
if (value.length === 0) {
|
||||||
newErrors[field] = "This field is required";
|
// newErrors[field] = "This field is required";
|
||||||
|
const label = field
|
||||||
|
.replace(/([A-Z])/g, " $1")
|
||||||
|
.replace(/^./, (str) => str.toUpperCase());
|
||||||
|
newErrors[field] = `${label} is required`;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -823,8 +863,10 @@ useEffect(()=>{
|
|||||||
try {
|
try {
|
||||||
const response = await fetch(item.preview);
|
const response = await fetch(item.preview);
|
||||||
const blob = await response.blob();
|
const blob = await response.blob();
|
||||||
const fileName = item.name || `profile_image_${index}.jpg`;
|
const mimeType = blob.type || "image/jpeg";
|
||||||
const fileType = item.type || "image/jpeg";
|
const ext = mimeType.split("/")[1] || "jpg";
|
||||||
|
const fileName = item.name || `profile_image_${index}.${ext}`;
|
||||||
|
const fileType = item.type || mimeType;
|
||||||
fileToAppend = new File([blob], fileName, { type: fileType });
|
fileToAppend = new File([blob], fileName, { type: fileType });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`Could not recover file from URL: ${item.preview}`, e);
|
console.error(`Could not recover file from URL: ${item.preview}`, e);
|
||||||
@ -977,6 +1019,23 @@ useEffect(()=>{
|
|||||||
|
|
||||||
if (isStep1Update) {
|
if (isStep1Update) {
|
||||||
res = await apiForFiles.post("/update_personal_details", payload);
|
res = await apiForFiles.post("/update_personal_details", payload);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const previewData = await getPreviewDetails();
|
||||||
|
if (previewData?.personal_details) {
|
||||||
|
const pd = previewData.personal_details;
|
||||||
|
const images = pd.images || pd.profile_images;
|
||||||
|
if (images && images.length > 0) {
|
||||||
|
const formattedImages = images.map((img) =>
|
||||||
|
typeof img === "string" ? { url: img, preview: img } : img
|
||||||
|
);
|
||||||
|
dispatch(updatePersonalDetails({ profiles: formattedImages }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["previewDetails"] });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error refreshing preview details:", error);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
res = await registerStep1.mutateAsync(payload);
|
res = await registerStep1.mutateAsync(payload);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import { getContactUs } from '../api/contact.api';
|
import { getContactUs } from '../api/contact.api';
|
||||||
import LazyImage from '../components/common/LazyImage';
|
import LazyImage from '../components/common/LazyImage';
|
||||||
import InstagramIcon from '@mui/icons-material/Instagram';
|
import InstagramIcon from '@mui/icons-material/Instagram';
|
||||||
|
import WhatsAppIcon from '@mui/icons-material/WhatsApp';
|
||||||
import FacebookIcon from '@mui/icons-material/Facebook';
|
import FacebookIcon from '@mui/icons-material/Facebook';
|
||||||
import SvgIcon from '@mui/material/SvgIcon';
|
import SvgIcon from '@mui/material/SvgIcon';
|
||||||
import { Phone, Mail, ChevronRight } from 'lucide-react';
|
import { Phone, Mail, ChevronRight } from 'lucide-react';
|
||||||
@ -39,7 +40,13 @@ const ContactUsPage = () => {
|
|||||||
icon: <XIcon fontSize="large" />,
|
icon: <XIcon fontSize="large" />,
|
||||||
color: "from-gray-800 to-black",
|
color: "from-gray-800 to-black",
|
||||||
url: contact.x_url
|
url: contact.x_url
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
name: "WhatsApp",
|
||||||
|
icon: <WhatsAppIcon fontSize="large" />,
|
||||||
|
color: "from-green-500 to-green-600",
|
||||||
|
url: contact.whatsapp_mobile ? `https://wa.me/${contact.whatsapp_mobile}` : null
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
|
|||||||
@ -19,9 +19,10 @@ const PublicRoutes = () => {
|
|||||||
<>
|
<>
|
||||||
<Route element={<HomeLayout />}>
|
<Route element={<HomeLayout />}>
|
||||||
<Route path="/" element={<HomePage />} />
|
<Route path="/" element={<HomePage />} />
|
||||||
<Route element={<PublicGuard />}>
|
{/* <Route element={<PublicGuard />}>
|
||||||
<Route path="/registration" element={<StepperForm />} />
|
</Route> */}
|
||||||
</Route>
|
<Route path="/registration" element={<StepperForm />} />
|
||||||
|
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route element={<PublicGuard />}>
|
<Route element={<PublicGuard />}>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user