diff --git a/src/feature/LifestyleDetailsForm.jsx b/src/feature/LifestyleDetailsForm.jsx index a3ccddf..15915c8 100644 --- a/src/feature/LifestyleDetailsForm.jsx +++ b/src/feature/LifestyleDetailsForm.jsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useRef } from "react"; +import React, { useEffect, useMemo, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { updateLifestyleDetails } from "../redux/registrationFormSlice"; import { @@ -11,12 +11,18 @@ import { TextField, Checkbox, ListItemText, + Dialog, + DialogTitle, + DialogContent, + DialogContentText, + DialogActions, } from "@mui/material"; import { LocalizationProvider } from "@mui/x-date-pickers"; import { DatePicker } from "@mui/x-date-pickers/DatePicker"; import { TimePicker } from "@mui/x-date-pickers/TimePicker"; import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; import { useLifestyleMasters } from "../hooks/useMasters"; +import horoscopeImg from "../assets/images/horoscopeimg.png"; const LifestyleDetailsForm = ({ onSubmitStep, @@ -53,6 +59,15 @@ const LifestyleDetailsForm = ({ return raw.grahas || raw.graha || []; }, [lifestyleMasters]); + const [confirmDialog, setConfirmDialog] = useState({ + open: false, + type: "", + house: null, + item: "", + sourceHouse: null, + pendingValue: [], + }); + useEffect(() => { inputRef.current?.focus(); }, []); @@ -68,23 +83,74 @@ const LifestyleDetailsForm = ({ if (onFieldChange) onFieldChange(field); }; - const handleGrahaChange = (house, value) => { - const next = { ...(data.graha || {}) }; - next[house] = value; - dispatch(updateLifestyleDetails({ graha: next })); - if (onFieldChange) onFieldChange("graha"); + const handleChartChange = (type, house, newValue) => { + const currentChart = type === "graha" ? data.graha : data.amsam; + const currentHouseValue = currentChart?.[house] || []; + + // Find added items + const addedItems = newValue.filter((item) => !currentHouseValue.includes(item)); + + if (addedItems.length > 0) { + for (const addedItem of addedItems) { + for (const [otherHouse, items] of Object.entries(currentChart || {})) { + if (String(otherHouse) !== String(house) && items && items.includes(addedItem)) { + setConfirmDialog({ + open: true, + type, + house, + item: addedItem, + sourceHouse: otherHouse, + pendingValue: newValue, + }); + return; + } + } + } + } + + // No duplicates, proceed with update + const updates = {}; + const nextChart = { ...(currentChart || {}) }; + nextChart[house] = newValue; + + if (type === "graha") { + updates.graha = nextChart; + } else { + updates.amsam = nextChart; + } + + dispatch(updateLifestyleDetails(updates)); + if (onFieldChange) onFieldChange(type); }; - const handleAmsamChange = (house, value) => { - const next = { ...(data.amsam || {}) }; - next[house] = value; - dispatch(updateLifestyleDetails({ amsam: next })); - if (onFieldChange) onFieldChange("amsam"); + const handleConfirmMove = () => { + const { type, house, item, sourceHouse, pendingValue } = confirmDialog; + const currentChart = type === "graha" ? data.graha : data.amsam; + const nextChart = { ...(currentChart || {}) }; + + // Remove from source house + if (nextChart[sourceHouse]) { + nextChart[sourceHouse] = nextChart[sourceHouse].filter((i) => i !== item); + } + + // Add to target house + nextChart[house] = pendingValue; + + const updates = type === "graha" ? { graha: nextChart } : { amsam: nextChart }; + dispatch(updateLifestyleDetails(updates)); + if (onFieldChange) onFieldChange(type); + + setConfirmDialog({ ...confirmDialog, open: false }); + }; + + const handleCancelMove = () => { + setConfirmDialog({ ...confirmDialog, open: false }); }; const handleSubmit = () => { console.log("Submitting lifestyle details:", data); onSubmitStep(); + }; const parseDateValue = (value) => { @@ -151,9 +217,7 @@ const LifestyleDetailsForm = ({ const getValue = (house) => (type === "graha" ? data.graha : data.amsam)?.[house] || []; const onChange = (house, value) => - type === "graha" - ? handleGrahaChange(house, value) - : handleAmsamChange(house, value); + handleChartChange(type, house, value); const label = type === "graha" ? "Rasi" : "Navamsam"; return ( @@ -165,7 +229,9 @@ const LifestyleDetailsForm = ({ {renderChartCell(label, getValue(5), (value) => onChange(5, value))}
-
+
+ Horoscope +
{renderChartCell(label, getValue(6), (value) => onChange(6, value))} @@ -403,6 +469,24 @@ const LifestyleDetailsForm = ({ {onSkipStep ? "Next" : "Update"} + + + {"Duplicate Selection"} + + + {confirmDialog.item} is already selected in House {confirmDialog.sourceHouse}. Do you want to move it to House {confirmDialog.house}? + + + + + + +
); diff --git a/src/feature/PersonalDetailsForm.jsx b/src/feature/PersonalDetailsForm.jsx index 2f9648c..cd49dc6 100644 --- a/src/feature/PersonalDetailsForm.jsx +++ b/src/feature/PersonalDetailsForm.jsx @@ -51,6 +51,25 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat const [showConfirmPassword, setShowConfirmPassword] = useState(false); const sendOtp = useSendOtp(); const verifyOtp = useVerifyOtp(); + const [verifiedMobileNumber, setVerifiedMobileNumber] = useState( + () => localStorage.getItem("registration_verified_mobile") || "" + ); + const initializedVerifiedNumber = useRef(false); + + useEffect(() => { + if (isStep1Update && data.mobileNumber && !initializedVerifiedNumber.current) { + setVerifiedMobileNumber(data.mobileNumber); + localStorage.setItem("registration_verified_mobile", data.mobileNumber); + setMobileOtpVerified(true); + initializedVerifiedNumber.current = true; + } + }, [isStep1Update, data.mobileNumber]); + + useEffect(() => { + if (verifiedMobileNumber && data.mobileNumber === verifiedMobileNumber) { + setMobileOtpVerified(true); + } + }, [verifiedMobileNumber, data.mobileNumber]); const { data: personalMasters, isLoading: isPersonalMastersLoading } = usePersonalDetailsMasters(); @@ -267,11 +286,17 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat const fieldsToClear = [field]; if (field === "mobileNumber") { setMobileNumberError(""); - setShowOtp(false); - setOtp(new Array(OTP_LENGTH).fill("")); - setOtpError(""); - setOtpTimer(0); - setMobileOtpVerified(false); + if (verifiedMobileNumber && value === verifiedMobileNumber) { + setMobileOtpVerified(true); + setShowOtp(false); + setOtpError(""); + } else { + setShowOtp(false); + setOtp(new Array(OTP_LENGTH).fill("")); + setOtpError(""); + setOtpTimer(0); + setMobileOtpVerified(false); + } } if (field === "religion") { updates.caste = ""; @@ -348,6 +373,8 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat "OTP verified successfully"; toast.success(successMessage, { position: "top-right" }); setMobileOtpVerified(true); + setVerifiedMobileNumber(data.mobileNumber); + localStorage.setItem("registration_verified_mobile", data.mobileNumber); setMobileNumberError(""); setOtpError(""); } catch (error) { @@ -505,6 +532,7 @@ const PersonalDetailsForm = ({ onSubmitStep, errors, onFieldChange, isStep1Updat label="Mobile Number" type="tel" value={data.mobileNumber} + disabled={isStep1Update} onChange={(e) => handleChange("mobileNumber", e.target.value)} error={ Boolean(errors.mobileNumber) || Boolean(mobileNumberError) diff --git a/src/feature/PreviewScreen.jsx b/src/feature/PreviewScreen.jsx index 53925e5..7b30f24 100644 --- a/src/feature/PreviewScreen.jsx +++ b/src/feature/PreviewScreen.jsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import { useSelector } from 'react-redux'; import { Swiper, SwiperSlide } from "swiper/react"; import { Navigation, Pagination } from "swiper/modules"; @@ -17,9 +17,15 @@ import { Button, Grid, Tooltip, + Dialog, + DialogTitle, + DialogContent, + DialogContentText, + DialogActions, } from '@mui/material'; import { usePreviewDetails } from "../hooks/usePreview"; import { isAuthenticated } from "../utills/auth"; +import horoscopeImg from "../assets/images/horoscopeimg.png"; const PreviewScreen = ({ onEdit, onSubmit }) => { const formData = useSelector((state) => state.registerform); @@ -28,6 +34,21 @@ const PreviewScreen = ({ onEdit, onSubmit }) => { const isLoading = isAuth && apiLoading; const isError = isAuth && apiError; + const [openConfirmDialog, setOpenConfirmDialog] = useState(false); + + const handleConfirmSubmit = () => { + setOpenConfirmDialog(true); + }; + + const handleProceedSubmit = () => { + setOpenConfirmDialog(false); + onSubmit(); + }; + + const handleCancelSubmit = () => { + setOpenConfirmDialog(false); + }; + const sections = previewData?.personal_details ? [ { @@ -183,8 +204,8 @@ const PreviewScreen = ({ onEdit, onSubmit }) => { {renderCell(1)} {renderCell(2)} {renderCell(3)} {renderCell(4)} {renderCell(5)} - - {title.toUpperCase()} + + {title} {renderCell(6)} {renderCell(7)} {renderCell(8)} @@ -224,7 +245,10 @@ const PreviewScreen = ({ onEdit, onSubmit }) => { {!isLoading && sections.map((section) => ( - + @@ -243,11 +267,25 @@ const PreviewScreen = ({ onEdit, onSubmit }) => { } sx={{padding:"15px 15px", background:"#f5fbff" }} /> - + {/* */} {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') { + const hiddenFields = [ + "id", + "created_at", + "updated_at", + "phone_number_visibility", + "chat_alert_notification", + "chat_protection", + "profile_photo_protect", + "call_protection", + "match_alert_preference", + "who_can_message", + "who_can_message_categories", + "user_status", + ]; + if (hiddenFields.includes(key) || key.endsWith('_id') || key.endsWith('Id') || key.endsWith('_ids') || key.endsWith('Ids')) { return null; } @@ -304,14 +342,21 @@ const PreviewScreen = ({ onEdit, onSubmit }) => { color: #d32f2f; width: 25px; height: 25px; + overflow: 'hidden'; + padding:5px; + display: 'flex'; + align-items: 'center'; + justify-content: 'center'; background: rgba(255, 255, 255, 0.9); border-radius: 50%; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .custom-swiper-${key} .swiper-button-next::after, .custom-swiper-${key} .swiper-button-prev::after { - font-size: 12px; + font-size: 8px; font-weight: bold; + width:20px; + } .custom-swiper-${key} .swiper-pagination-bullet-active { background-color: #d32f2f; @@ -329,7 +374,8 @@ const PreviewScreen = ({ onEdit, onSubmit }) => { > {value.map((sibling, idx) => ( - + {Object.entries(sibling).map(([sKey, sVal]) => { if (sKey === 'id' || sKey.endsWith('_id') || sKey.endsWith('Id') || sKey === 'created_at' || sKey === 'updated_at') return null; @@ -375,7 +421,7 @@ const PreviewScreen = ({ onEdit, onSubmit }) => { { color="success" size="large" - onClick={onSubmit} + onClick={handleConfirmSubmit} sx={{ borderRadius: 2 }} > Submit full Completed Data + + + + {"Confirm Submission"} + + + + Once you submit your details, you will not be able to edit the following fields: Place of Birth, Date of Birth, Rasi and Navamsam. + + + + + + + ); diff --git a/src/feature/StepperForm.jsx b/src/feature/StepperForm.jsx index 1b97cb3..dd9c162 100644 --- a/src/feature/StepperForm.jsx +++ b/src/feature/StepperForm.jsx @@ -600,8 +600,8 @@ useEffect(()=>{ updateLifestyleDetails({ diets: ld.diet_id || "", hobbies: ld.hobbies_ids || [], - dob: ld.date_of_birth || "", - tob: ld.time_of_birth ? ld.time_of_birth.substring(0, 5) : "", + dob: ld.time_of_birth || "", + tob: ld.date_of_birth ? ld.date_of_birth.substring(0, 5) : "", placeOfBirth: ld.place_of_birth || "", graha: mapChart("graha"), amsam: mapChart("amsam"), @@ -1009,6 +1009,12 @@ useEffect(()=>{ break; } + if (shouldHideStepper) { + toast.success("Updated successfully", { position: "top-right" }); + navigate("/profile"); + return; + } + // Mark step completed (tick icon) setCompletedSteps((prev) => prev.includes(currentStep) ? prev : [...prev, currentStep] @@ -1189,15 +1195,20 @@ useEffect(() => { enabledSteps={enabledSteps} completedSteps={completedSteps} /> )} + + + + +
- {currentStep > 1 && currentStep < 6 && ( + {/* {currentStep > 1 && currentStep < 6 && ( - )} + )} */}

{getTitle()}