done pages

This commit is contained in:
Meenadeveloper 2025-11-29 14:49:32 +05:30
parent 05f30375d7
commit a0ecee38b1
15 changed files with 1263 additions and 242 deletions

View File

@ -421,7 +421,7 @@ const ForgotPassworForm = () => {
{/* Header */} {/* Header */}
<Box <Box
sx={{ sx={{
background: 'linear-gradient(135deg, #4CAF50 0%, #45a049 100%)', background: 'linear-gradient(135deg, #034E08 0%, #034E08 100%)',
py: 3, py: 3,
px: 4, px: 4,
position: 'relative', position: 'relative',
@ -462,8 +462,8 @@ const ForgotPassworForm = () => {
<StepLabel <StepLabel
StepIconProps={{ StepIconProps={{
sx: { sx: {
'&.Mui-active': { color: '#4CAF50' }, '&.Mui-active': { color: '#034E08' },
'&.Mui-completed': { color: '#4CAF50' }, '&.Mui-completed': { color: '#034E08' },
}, },
}} }}
> >
@ -506,7 +506,7 @@ const ForgotPassworForm = () => {
justifyContent: 'center', justifyContent: 'center',
}} }}
> >
<EmailIcon sx={{ fontSize: 40, color: '#4CAF50' }} /> <EmailIcon sx={{ fontSize: 40, color: '#A70710' }} />
</Box> </Box>
</Box> </Box>
@ -538,11 +538,11 @@ const ForgotPassworForm = () => {
mt: 2, mt: 2,
py: 1.5, py: 1.5,
borderRadius: 50, borderRadius: 50,
backgroundColor: '#FF9800', backgroundColor: '#A70710',
fontSize: '1rem', fontSize: '1rem',
fontWeight: 600, fontWeight: 600,
'&:hover': { backgroundColor: '#F57C00' }, '&:hover': { backgroundColor: '#A70710' },
'&:disabled': { backgroundColor: '#FFB74D', color: 'white' }, '&:disabled': { backgroundColor: '#A70710', color: 'white' },
}} }}
> >
{loading ? ( {loading ? (
@ -556,7 +556,7 @@ const ForgotPassworForm = () => {
<Link <Link
href="/login" href="/login"
sx={{ sx={{
color: '#FF9800', color: '#A70710',
fontWeight: 500, fontWeight: 500,
textDecoration: 'none', textDecoration: 'none',
'&:hover': { textDecoration: 'underline' }, '&:hover': { textDecoration: 'underline' },

View File

@ -15,6 +15,7 @@ import { useState } from 'react'
import MuiDynamicInput from '../../utills/MuiDynamicInput.jsx' import MuiDynamicInput from '../../utills/MuiDynamicInput.jsx'
import CheckCircleIcon from '@mui/icons-material/CheckCircle' import CheckCircleIcon from '@mui/icons-material/CheckCircle'
import { keyframes } from '@mui/system' import { keyframes } from '@mui/system'
import { useNavigate } from 'react-router-dom'
// Define keyframe animations // Define keyframe animations
@ -171,6 +172,7 @@ function SuccessModal({ open, onClose, title, message }) {
} }
const LoginPanel = () => { const LoginPanel = () => {
const navigate = useNavigate();
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
emailOrMobile: '', emailOrMobile: '',
password: '', password: '',
@ -235,14 +237,13 @@ const LoginPanel = () => {
console.log('Navigate to dashboard...') console.log('Navigate to dashboard...')
} }
const handleOTPLogin = () => {
console.log('Navigate to OTP Login')
}
const handleForgotPassword = () => { const handleForgotPassword = () => {
console.log('Navigate to Forgot Password') navigate("/forgot-password");
} }
const handleRegister = ()=>{
navigate("/registration");
}
return ( return (
<> <>
@ -302,15 +303,34 @@ const LoginPanel = () => {
required required
/> />
<Link
component="button"
variant="body2"
onClick={handleForgotPassword}
sx={{
color: '#A70710',
fontWeight: 500,
textDecoration: 'none',
'&:hover': {
textDecoration: 'underline',
color: '#A70710',
},
textAlign:"right",
width:"100%",
}}
>
Forgot Password?
</Link>
{/* Keep me logged in Checkbox */} {/* Keep me logged in Checkbox */}
<MuiDynamicInput {/* <MuiDynamicInput
type="checkbox" type="checkbox"
name="keepLoggedIn" name="keepLoggedIn"
label="Keep me logged in" label="Keep me logged in"
value={formData.keepLoggedIn} value={formData.keepLoggedIn}
onChange={handleChange} onChange={handleChange}
color="success" color="success"
/> /> */}
{/* Login Button */} {/* Login Button */}
<Button <Button
@ -345,7 +365,7 @@ const LoginPanel = () => {
variant="subtitle1" variant="subtitle1"
sx={{ fontWeight: 600, color: 'text.primary', mb: 1 }} sx={{ fontWeight: 600, color: 'text.primary', mb: 1 }}
> >
Trouble logging in? Don't have Account ?
</Typography> </Typography>
<Box <Box
@ -356,7 +376,7 @@ const LoginPanel = () => {
gap: 1, gap: 1,
}} }}
> >
<Link {/* <Link
component="button" component="button"
variant="body2" variant="body2"
onClick={handleOTPLogin} onClick={handleOTPLogin}
@ -373,12 +393,13 @@ const LoginPanel = () => {
Login with OTP Login with OTP
</Link> </Link>
<Divider orientation="vertical" flexItem sx={{ mx: 1 }} /> <Divider orientation="vertical" flexItem sx={{ mx: 1 }} /> */}
<Link <Link
component="button" component="button"
variant="body2" variant="body2"
onClick={handleForgotPassword} onClick={handleRegister}
sx={{ sx={{
color: '#A70710', color: '#A70710',
fontWeight: 500, fontWeight: 500,
@ -389,7 +410,7 @@ const LoginPanel = () => {
}, },
}} }}
> >
Forgot Password? Register
</Link> </Link>
</Box> </Box>
</Box> </Box>

View File

@ -28,7 +28,7 @@ const NAV_LINKS = [
{ label: "Matches", path: "/matches" }, { label: "Matches", path: "/matches" },
{ label: "Interest", path: "/interest" }, { label: "Interest", path: "/interest" },
{ label: "Messages", path: "/chat" }, { label: "Messages", path: "/chat" },
{ label: "Search", path: "/search" }, { label: "Search", path: "/matches" },
{ label: "Notifications", path: "/notifications" } { label: "Notifications", path: "/notifications" }
]; ];

View File

@ -9,7 +9,7 @@ import PersonIcon from "@mui/icons-material/Person";
import StarIcon from "@mui/icons-material/Star"; import StarIcon from "@mui/icons-material/Star";
import VisibilityIcon from "@mui/icons-material/Visibility"; import VisibilityIcon from "@mui/icons-material/Visibility";
import PersonAddIcon from "@mui/icons-material/PersonAdd"; import PersonAddIcon from "@mui/icons-material/PersonAdd";
import { motion } from 'framer-motion'; import { motion } from "framer-motion";
import FilterModal from "../../feature/FilterModal"; import FilterModal from "../../feature/FilterModal";
import bride1 from "../../assets/images/bride1.jpg"; import bride1 from "../../assets/images/bride1.jpg";
import bride2 from "../../assets/images/bride2.jpg"; import bride2 from "../../assets/images/bride2.jpg";
@ -24,21 +24,22 @@ import groom4 from "../../assets/images/groom4.jpg";
import horoscope from "../../assets/images/horoscopeicon.png"; import horoscope from "../../assets/images/horoscopeicon.png";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { Button, Fab } from "@mui/material"; import { Button, Fab } from "@mui/material";
import MessageIcon from '@mui/icons-material/Message'; import MessageIcon from "@mui/icons-material/Message";
import PhoneIcon from '@mui/icons-material/Phone'; import PhoneIcon from "@mui/icons-material/Phone";
// Profile Card Component // Profile Card Component
function ProfileCard({ profile }) { function ProfileCard({ profile }) {
const [isLiked, setIsLiked] = useState(false); const [isLiked, setIsLiked] = useState(false);
const navigate = useNavigate(); const navigate = useNavigate();
return ( return (
<div <div
onClick={() => navigate(`/profile-details/${profile.id}`)} onClick={() => navigate(`/profile-details/${profile.id}`)}
className="w-full max-w-sm rounded-[10px] shadow-xl overflow-hidden border border-green-200"> className="w-full max-w-sm rounded-[10px] shadow-xl overflow-hidden border border-green-200"
>
<div className="relative"> <div className="relative">
<motion.div <motion.div
initial={{ scale: 0 }} initial={{ scale: 0 }}
animate={{ scale: 1 }} animate={{ scale: 1 }}
transition={{ delay: 0.2, type: 'spring' }} transition={{ delay: 0.2, type: "spring" }}
className="absolute top-4 left-4 z-10 bg-orange-500 rounded-full p-2 shadow-lg" className="absolute top-4 left-4 z-10 bg-orange-500 rounded-full p-2 shadow-lg"
> >
<Crown className="w-5 h-5 text-white" /> <Crown className="w-5 h-5 text-white" />
@ -52,17 +53,20 @@ function ProfileCard({ profile }) {
<Bookmark className="w-4 h-4" /> <Bookmark className="w-4 h-4" />
<span className="text-[12px] font-medium">Shortlist</span> <span className="text-[12px] font-medium">Shortlist</span>
</motion.button> </motion.button>
<div classname=" bg-gray-200 overflow-hidden w-full max-w-sm h-[300px]" style={{height:"300px"}}> <div
classname=" bg-gray-200 overflow-hidden w-full max-w-sm h-[300px]"
<img style={{ height: "300px" }}
src={profile.image} >
alt="Profile" <img
className="w-full h-full object-cover bg-gray-200" src={profile.image}
style={{ alt="Profile"
// objectFit:"inherit", className="w-full h-full object-cover bg-gray-200"
objectPosition:"top"}} style={{
/> // objectFit:"inherit",
</div> objectPosition: "top",
}}
/>
</div>
<div <div
className="absolute bottom-0 left-0 right-0 h-25 pointer-events-none" className="absolute bottom-0 left-0 right-0 h-25 pointer-events-none"
style={{ style={{
@ -83,11 +87,9 @@ function ProfileCard({ profile }) {
<div className="px-4 pt-2 pb-4 flex flex-col gap-2 bg-white"> <div className="px-4 pt-2 pb-4 flex flex-col gap-2 bg-white">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<VisibilityIcon /> <VisibilityIcon />
<span className="text-[14px] text-gray-900"> <span className="text-[14px] text-gray-900">{profile.lastseen}</span>
{profile.lastseen} </div>
</span>
</div>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<CakeIcon className="w-4 h-4 text-gray-700" /> <CakeIcon className="w-4 h-4 text-gray-700" />
@ -104,10 +106,6 @@ function ProfileCard({ profile }) {
</div> </div>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<LocationOnIcon className="w-4 h-4 text-gray-700" /> <LocationOnIcon className="w-4 h-4 text-gray-700" />
<span className="text-[14px] font-semibold text-gray-900"> <span className="text-[14px] font-semibold text-gray-900">
@ -154,26 +152,33 @@ function ProfileCard({ profile }) {
</div> */} </div> */}
<div className="flex gap-3 my-2 justify-between w-full px-[0px]"> <div className="flex gap-3 my-2 justify-between w-full px-[0px]">
<div className="flex gap-2"> <div className="flex gap-2">
<Fab size="medium" color="primary" aria-label="add">
<MessageIcon />
</Fab>
<Fab size="medium" color="primary" aria-label="add"> <Fab size="medium" color="secondary" aria-label="add">
<MessageIcon /> <PhoneIcon />
</Fab> </Fab>
</div>
<Fab size="medium" color="secondary" aria-label="add"> <Button
<PhoneIcon /> variant="contained"
</Fab> color="#f5fbff"
onClick={(e) => {
</div> e.stopPropagation();
navigate(`/profile-details/${profile.id}`);
<Button variant="contained" color="#f5fbff" onClick={(e) =>{ e.stopPropagation(); }}
navigate(`/profile-details/${profile.id}`)} sx={{
} sx={{color:"#000000", background:"#f5fbff", fontWeight:"600", borderRadius:"30px"}}> color: "#000000",
background: "#f5fbff",
View Details fontWeight: "600",
</Button> borderRadius: "30px",
}}
</div> >
View Details
</Button>
</div>
</div> </div>
</div> </div>
); );
@ -182,132 +187,134 @@ function ProfileCard({ profile }) {
// Main Component // Main Component
export default function MatchesInterface() { export default function MatchesInterface() {
const navigate = useNavigate(); const navigate = useNavigate();
const [selectedTab, setSelectedTab] = useState('your-matches'); const [selectedTab, setSelectedTab] = useState("your-matches");
const tabs = [ const tabs = [
{ {
id: 'your-matches', id: "your-matches",
icon: <PersonIcon className="w-6 h-6" />, icon: <PersonIcon className="w-6 h-6" />,
title: 'Your Matches', title: "Your Matches",
description: 'View all the profiles that match your preferences', description: "View all the profiles that match your preferences",
category: 'All Matches' category: "All Matches",
}, },
{ {
id: 'shortlisted-by-you', id: "shortlisted-by-you",
icon: <StarIcon className="w-6 h-6" />, icon: <StarIcon className="w-6 h-6" />,
title: 'Shortlisted by you', title: "Shortlisted by you",
description: 'Matches you have shortlisted', description: "Matches you have shortlisted",
category: 'Based on activity' category: "Based on activity",
}, },
{ {
id: 'viewed-you', id: "viewed-you",
icon: <VisibilityIcon className="w-6 h-6" />, icon: <VisibilityIcon className="w-6 h-6" />,
title: 'Viewed you', title: "Viewed you",
description: 'Matches who have viewed your profile', description: "Matches who have viewed your profile",
category: 'Based on activity' category: "Based on activity",
}, },
{ {
id: 'shortlisted-you', id: "shortlisted-you",
icon: <PersonAddIcon className="w-6 h-6" />, icon: <PersonAddIcon className="w-6 h-6" />,
title: 'Shortlisted you', title: "Shortlisted you",
description: 'Matches who have shortlisted your profile', description: "Matches who have shortlisted your profile",
category: 'Based on activity' category: "Based on activity",
}, },
{ {
id: 'viewed-by-you', id: "viewed-by-you",
icon: <VisibilityIcon className="w-6 h-6" />, icon: <VisibilityIcon className="w-6 h-6" />,
title: 'Viewed by you', title: "Viewed by you",
description: 'Matches you have viewed', description: "Matches you have viewed",
category: 'Based on activity' category: "Based on activity",
} },
]; ];
const profiles = [ const profiles = [
{ {
id: 'JB2847593', id: "JB2847593",
name: 'Jerome Bell', name: "Jerome Bell",
age: 22, age: 22,
height: '5.2', height: "5.2",
lastseen: 'Last seen 14 Nov 2025', lastseen: "Last seen 14 Nov 2025",
education: 'BCA / Data analyst', education: "BCA / Data analyst",
location: 'Chennai', location: "Chennai",
image: bride1 image: bride1,
}, },
{ {
id: 'SA8392847', id: "SA8392847",
name: 'Sarah Anderson', name: "Sarah Anderson",
age: 24, age: 24,
height: '5.4', height: "5.4",
lastseen: 'Last seen 14 Nov 2025', lastseen: "Last seen 14 Nov 2025",
education: 'MBA / Marketing Manager', education: "MBA / Marketing Manager",
location: 'Bangalore', location: "Bangalore",
image: bride4 image: bride4,
}, },
{ {
id: 'PR9384756', id: "PR9384756",
name: 'Priya Reddy', name: "Priya Reddy",
age: 23, age: 23,
height: '5.3', height: "5.3",
lastseen: 'Last seen 14 Nov 2025', lastseen: "Last seen 14 Nov 2025",
education: 'B.Tech / Software Engineer', education: "B.Tech / Software Engineer",
location: 'Hyderabad', location: "Hyderabad",
image: bride2 image: bride2,
}, },
{ {
id: 'AN4758392', id: "AN4758392",
name: 'Ananya Krishnan', name: "Ananya Krishnan",
age: 25, age: 25,
height: '5.5', height: "5.5",
lastseen: 'Last seen 14 Nov 2025', lastseen: "Last seen 14 Nov 2025",
education: 'MD / Doctor', education: "MD / Doctor",
location: 'Kochi', location: "Kochi",
image: bride3 image: bride3,
}, },
{ {
id: 'AN4758392', id: "AN4758392",
name: 'Ananya Krishnan', name: "Ananya Krishnan",
age: 25, age: 25,
height: '5.5', height: "5.5",
lastseen: 'Last seen 14 Nov 2025', lastseen: "Last seen 14 Nov 2025",
education: 'MD / Doctor', education: "MD / Doctor",
location: 'Kochi', location: "Kochi",
image: groom1 image: groom1,
}, },
{ {
id: 'AN4758392', id: "AN4758392",
name: 'Ananya Krishnan', name: "Ananya Krishnan",
age: 25, age: 25,
height: '5.5', height: "5.5",
lastseen: 'Last seen 14 Nov 2025', lastseen: "Last seen 14 Nov 2025",
education: 'MD / Doctor', education: "MD / Doctor",
location: 'Kochi', location: "Kochi",
image: groom2 image: groom2,
}, },
{ {
id: 'AN4758392', id: "AN4758392",
name: 'Ananya Krishnan', name: "Ananya Krishnan",
age: 25, age: 25,
height: '5.5', height: "5.5",
lastseen: 'Last seen 14 Nov 2025', lastseen: "Last seen 14 Nov 2025",
education: 'MD / Doctor', education: "MD / Doctor",
location: 'Kochi', location: "Kochi",
image: groom4 image: groom4,
}, },
{ {
id: 'AN4758392', id: "AN4758392",
name: 'Ananya Krishnan', name: "Ananya Krishnan",
age: 25, age: 25,
height: '5.5', height: "5.5",
lastseen: 'Last seen 14 Nov 2025', lastseen: "Last seen 14 Nov 2025",
education: 'MD / Doctor', education: "MD / Doctor",
location: 'Kochi', location: "Kochi",
image: groom3 image: groom3,
} },
]; ];
let currentCategory = ''; let currentCategory = "";
return ( return (
<>
<div className="grid grid-cols-1 md:grid-cols-[300px_auto] md:px-4 gap-2 md:gap-10"> <div className="grid grid-cols-1 md:grid-cols-[300px_auto] md:px-4 gap-2 md:gap-10">
<style>{` <style>{`
.scrollbar-hide::-webkit-scrollbar { .scrollbar-hide::-webkit-scrollbar {
@ -320,8 +327,10 @@ export default function MatchesInterface() {
`}</style> `}</style>
{/* Left Sidebar - Fixed on desktop, scrollable on mobile */} {/* Left Sidebar - Fixed on desktop, scrollable on mobile */}
<div style={{maxHeight:"100vh", position:"sticky", top:"50px"}} <div
className="w-full rounded-[10px] border border-1 border-gray-200 md:w-80 bg-white md:my-6 shadow-lg overflow-y-auto scrollbar-hide flex-shrink-0"> style={{ maxHeight: "100vh", position: "sticky", top: "50px" }}
className="w-full rounded-[10px] border border-1 border-gray-200 md:w-80 bg-white md:my-6 shadow-lg overflow-y-auto scrollbar-hide flex-shrink-0"
>
<div className="py-6 px-4"> <div className="py-6 px-4">
{tabs.map((tab) => { {tabs.map((tab) => {
const showCategory = tab.category !== currentCategory; const showCategory = tab.category !== currentCategory;
@ -340,31 +349,52 @@ export default function MatchesInterface() {
onClick={() => setSelectedTab(tab.id)} onClick={() => setSelectedTab(tab.id)}
className={`p-4 rounded-lg mb-3 cursor-pointer transition-all ${ className={`p-4 rounded-lg mb-3 cursor-pointer transition-all ${
selectedTab === tab.id selectedTab === tab.id
? 'bg-green-50 border-l-4 border-green-600' ? "bg-green-50 border-l-4 border-green-600"
: 'hover:bg-gray-50' : "hover:bg-gray-50"
}`} }`}
> >
<div className="flex items-start gap-3"> <div className="flex items-start gap-3">
<div className={`mt-1 ${selectedTab === tab.id ? 'text-green-600' : 'text-gray-600'}`}> <div
className={`mt-1 ${
selectedTab === tab.id
? "text-green-600"
: "text-gray-600"
}`}
>
{tab.icon} {tab.icon}
</div> </div>
<div className="flex-1"> <div className="flex-1">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h3 className={`font-semibold text-base ${ <h3
selectedTab === tab.id ? 'text-green-900' : 'text-gray-900' className={`font-semibold text-base ${
}`}> selectedTab === tab.id
? "text-green-900"
: "text-gray-900"
}`}
>
{tab.title} {tab.title}
</h3> </h3>
<svg <svg
className={`w-5 h-5 ${selectedTab === tab.id ? 'text-green-600' : 'text-gray-400'}`} className={`w-5 h-5 ${
selectedTab === tab.id
? "text-green-600"
: "text-gray-400"
}`}
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
> >
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" /> <path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M9 5l7 7-7 7"
/>
</svg> </svg>
</div> </div>
<p className="text-sm text-gray-600 mt-1">{tab.description}</p> <p className="text-sm text-gray-600 mt-1">
{tab.description}
</p>
</div> </div>
</div> </div>
</div> </div>
@ -378,17 +408,18 @@ export default function MatchesInterface() {
<div className=" px-2 py-8"> <div className=" px-2 py-8">
<div className="w-[100%] max-w-[1200px] mx-auto"> <div className="w-[100%] max-w-[1200px] mx-auto">
<div className="flex justify-between gap-2 itemes-center mb-8"> <div className="flex justify-between gap-2 itemes-center mb-8">
<h1 className="text-[24px] font-bold text-gray-900 "> <h1 className="text-[24px] font-bold text-gray-900 ">
{tabs.find(t => t.id === selectedTab)?.title} {tabs.find((t) => t.id === selectedTab)?.title}
</h1> </h1>
<div className="flex gap-2 items-center"> <div className="flex gap-2 items-center">
<img
<img src={horoscope} onClick={()=>{ src={horoscope}
navigate("/horoscoper-generate") onClick={() => {
}}/> navigate("/horoscoper-generate");
<FilterModal/> }}
</div> />
<FilterModal />
</div>
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-2"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-2">
{profiles.map((profile) => ( {profiles.map((profile) => (
@ -398,5 +429,24 @@ export default function MatchesInterface() {
</div> </div>
</div> </div>
</div> </div>
</>
); );
} }

View File

@ -28,6 +28,7 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-20 gap-y-10 mb-6"> <div className="grid grid-cols-1 md:grid-cols-2 gap-x-20 gap-y-10 mb-6">
{/* Highest Qualification */} {/* Highest Qualification */}
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Highest Qualification</label>
<TextField <TextField
fullWidth fullWidth
inputRef={inputRef} inputRef={inputRef}
@ -44,6 +45,7 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
{/* Field of Study */} {/* Field of Study */}
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Field of Study</label>
<TextField <TextField
fullWidth fullWidth
name="fieldOfStudy" name="fieldOfStudy"
@ -59,6 +61,7 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
{/* Occupation */} {/* Occupation */}
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Occupation</label>
<TextField <TextField
fullWidth fullWidth
name="occupation" name="occupation"
@ -74,6 +77,7 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
{/* Company / Organization Name */} {/* Company / Organization Name */}
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Company / Organization Name</label>
<TextField <TextField
fullWidth fullWidth
name="organization" name="organization"
@ -89,6 +93,7 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
{/* Annual Income */} {/* Annual Income */}
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Annual Income</label>
<TextField <TextField
fullWidth fullWidth
name="income" name="income"
@ -104,6 +109,7 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
{/* Work Location */} {/* Work Location */}
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Work Location</label>
<TextField <TextField
fullWidth fullWidth
name="workLocation" name="workLocation"
@ -129,10 +135,10 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
}} }}
> >
<Button variant="outlined" onClick={onSkipStep}> <Button variant="outlined" onClick={onSkipStep}>
Skip Next
</Button> </Button>
<Button variant="contained" color="primary" onClick={handleSubmit}> <Button variant="contained" color="primary" onClick={handleSubmit}>
Next Submit
</Button> </Button>
</Grid> </Grid>
</form> </form>

View File

@ -24,6 +24,11 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
dispatch(updateFamilyDetails({ [field]: value })); dispatch(updateFamilyDetails({ [field]: value }));
}; };
const handleSubmit = () => {
console.log("Submitting family details:", data);
onSubmitStep();
};
return ( return (
<> <>
@ -33,7 +38,7 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-20 gap-y-10 mb-6"> <div className="grid grid-cols-1 md:grid-cols-2 gap-x-20 gap-y-10 mb-6">
{/* Highest Qualification */} {/* Highest Qualification */}
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Father Name</label>
<TextField <TextField
fullWidth fullWidth
inputRef={inputRef} inputRef={inputRef}
@ -49,6 +54,8 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
</div> </div>
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Father Occupation</label>
<TextField <TextField
fullWidth fullWidth
@ -64,6 +71,7 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
</div> </div>
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Mother Name</label>
<TextField <TextField
fullWidth fullWidth
name="motherName" name="motherName"
@ -78,6 +86,8 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
</div> </div>
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Mother Occupation</label>
<TextField <TextField
fullWidth fullWidth
name="motherOccupation" name="motherOccupation"
@ -93,6 +103,7 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
</div> </div>
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Number of Brothers / Sisters</label>
<TextField <TextField
fullWidth fullWidth
name="siblings" name="siblings"
@ -108,6 +119,7 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
</div> </div>
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]"> Brothers / Sisters (Married / Unmarried)</label>
<FormControl <FormControl
fullWidth fullWidth
variant="outlined" variant="outlined"
@ -143,15 +155,23 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
</div> </div>
<Grid item xs={12} style={{ marginTop: 16, display: "flex", gap: 16 , justifyContent: "center"}}>
<Button variant="outlined" fullWidth onClick={onSkipStep}> </div>
<Grid item
xs={12} sx={{ marginTop: 10, display: "flex", gap: 4 , justifyContent: "center"}}>
<Button variant="outlined" onClick={onSkipStep}>
Skip Skip
</Button> </Button>
<Button variant="contained" color="primary" fullWidth onClick={onSubmitStep}> <Button variant="contained" color="primary" onClick={handleSubmit}>
Submit & Next Submit
</Button> </Button>
</Grid> </Grid>
</div>
</form> </form>
</div> </div>

View File

@ -95,7 +95,7 @@ const LifestyleDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
item item
xs={12} xs={12}
style={{ style={{
marginTop: 24, marginTop: 50,
display: "flex", display: "flex",
gap: 16, gap: 16,
justifyContent: "center", justifyContent: "center",

View File

@ -52,12 +52,10 @@ const PartnerPreferencesForm = ({ onSubmitStep, onSkipStep, errors }) => {
name="ageRange" name="ageRange"
value={data.ageRange} value={data.ageRange}
onChange={(e) => handleChange("ageRange", e.target.value)} onChange={(e) => handleChange("ageRange", e.target.value)}
displayEmpty
inputRef={inputRef} inputRef={inputRef}
> >
<MenuItem value="">
<em>Select Preferred Age Range</em>
</MenuItem>
<MenuItem value="25 - 28">25 - 28</MenuItem> <MenuItem value="25 - 28">25 - 28</MenuItem>
<MenuItem value="29 - 32">29 - 32</MenuItem> <MenuItem value="29 - 32">29 - 32</MenuItem>
<MenuItem value="33 - 36">33 - 36</MenuItem> <MenuItem value="33 - 36">33 - 36</MenuItem>
@ -97,11 +95,9 @@ const PartnerPreferencesForm = ({ onSubmitStep, onSkipStep, errors }) => {
onChange={(e) => onChange={(e) =>
handleChange("religionCaste", e.target.value) handleChange("religionCaste", e.target.value)
} }
displayEmpty
> >
<MenuItem value="">
<em>Select Religion / Caste Preference</em>
</MenuItem>
<MenuItem value="Hindu">Hindu</MenuItem> <MenuItem value="Hindu">Hindu</MenuItem>
<MenuItem value="Muslim">Muslim</MenuItem> <MenuItem value="Muslim">Muslim</MenuItem>
<MenuItem value="Christian">Christian</MenuItem> <MenuItem value="Christian">Christian</MenuItem>
@ -142,11 +138,9 @@ const PartnerPreferencesForm = ({ onSubmitStep, onSkipStep, errors }) => {
onChange={(e) => onChange={(e) =>
handleChange("occupationPref", e.target.value) handleChange("occupationPref", e.target.value)
} }
displayEmpty
> >
<MenuItem value="">
<em>Select Occupation Preference</em>
</MenuItem>
<MenuItem value="IT, Business">IT, Business</MenuItem> <MenuItem value="IT, Business">IT, Business</MenuItem>
<MenuItem value="Doctor">Doctor</MenuItem> <MenuItem value="Doctor">Doctor</MenuItem>
<MenuItem value="Engineer">Engineer</MenuItem> <MenuItem value="Engineer">Engineer</MenuItem>
@ -187,11 +181,9 @@ const PartnerPreferencesForm = ({ onSubmitStep, onSkipStep, errors }) => {
onChange={(e) => onChange={(e) =>
handleChange("lifestylePref", e.target.value) handleChange("lifestylePref", e.target.value)
} }
displayEmpty
> >
<MenuItem value="">
<em>Select Lifestyle & Habits Preference</em>
</MenuItem>
<MenuItem value="Non-Smoking, Non-Drinking"> <MenuItem value="Non-Smoking, Non-Drinking">
Non-Smoking, Non-Drinking Non-Smoking, Non-Drinking
</MenuItem> </MenuItem>
@ -287,7 +279,7 @@ const PartnerPreferencesForm = ({ onSubmitStep, onSkipStep, errors }) => {
item item
xs={12} xs={12}
style={{ style={{
marginTop: 24, marginTop: 40,
display: "flex", display: "flex",
gap: 16, gap: 16,
justifyContent: "center", justifyContent: "center",

View File

@ -765,7 +765,7 @@ const PersonalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
onClick={handleSubmit} onClick={handleSubmit}
// disabled={!mobileOtpVerified} // disabled={!mobileOtpVerified}
> >
Submit & Next Submit
</Button> </Button>
</Grid> </Grid>
</form> </form>

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { Edit2 } from 'lucide-react'; import { Edit2,Info } from 'lucide-react';
import { import {
Card, Card,
CardContent, CardContent,
@ -45,11 +45,13 @@ const PreviewScreen = ({ onEdit, onSubmit }) => {
]; ];
return ( return (
<Box p={3} maxWidth={720} mx="auto" minHeight="100vh" bgcolor="#f9fafb"> <Box p={3} sx={{maxWidth:"1400px", width:"100%"}} mx="auto" >
<Grid container spacing={3}>
<div className='grid grid-cols-1 md:grid-cols-2 gap-4 my-10'>
{sections.map((section) => ( {sections.map((section) => (
<Grid item xs={12} key={section.title}>
<Card variant="outlined" sx={{ borderRadius: 2 }}> <Card key={section.title} variant="outlined" sx={{ borderRadius: 2, background:"#fff5ed" }}>
<CardHeader <CardHeader
title={ title={
<Typography variant="h6" fontWeight="bold"> <Typography variant="h6" fontWeight="bold">
@ -66,57 +68,122 @@ const PreviewScreen = ({ onEdit, onSubmit }) => {
<Edit2 size={20} /> <Edit2 size={20} />
</IconButton> </IconButton>
} }
sx={{ pb: 0 }} sx={{padding:"15px 15px", background:"#f5fbff" }}
/> />
<Divider /> <Divider />
<CardContent sx={{ pt: 1 }}> <CardContent sx={{ pt: 1, }}>
{Object.entries(section.data).map(([key, value]) => { {Object.entries(section.data).map(([key, value]) => {
if (value && key !== 'profiles') { // if (value && key !== 'profiles') {
// Convert camelCase or camel_Snake_case to readable words // Convert camelCase or camel_Snake_case to readable words
const formattedKey = key const formattedKey = key
.replace(/([A-Z])/g, ' $1') .replace(/([A-Z])/g, ' $1')
.replace(/_/g, ' ') .replace(/_/g, ' ')
.replace(/\b\w/g, (l) => l.toUpperCase()) .replace(/\b\w/g, (l) => l.toUpperCase())
.trim(); .trim();
const isImage =
typeof value === "string" &&
(value.startsWith("http") || value.startsWith("data:image"));
return ( return (
<Box <Box
key={key} key={key}
display="flex" py={0.7}
justifyContent="space-between" borderBottom="1px solid #e0e0e0"
py={0.7} sx={{
borderBottom="1px solid #e0e0e0" display: "grid",
> gridTemplateColumns: {
<Typography color="text.secondary" sx={{ fontWeight: 500 }}> xs: "1fr",
{formattedKey}: sm: "1fr 1fr",
</Typography> },
<Typography gap: "10px",
sx={{ fontWeight: 600, ml: 2, maxWidth: '60%', wordBreak: 'break-word' }} alignItems: "center",
> }}
{value} >
</Typography> <Typography color="text.secondary" sx={{ fontWeight: 500 }}>
</Box> {formattedKey}:
</Typography>
{/* Special Case: Profiles Image Preview */}
{key === "profiles" ? (
<Box display="flex" gap={0} flexWrap="wrap">
{value && value.length > 0 ? (
value.map((imgObj, index) => (
<img
key={index}
src={URL.createObjectURL(imgObj.file)}
alt="Profile"
style={{
width: "90px",
height: "90px",
objectFit: "cover",
borderRadius: "50%",
border: "1px solid #ccc",
marginLeft:"-20px"
}}
/>
))
) : (
<Box display="flex" alignItems="center" gap={1} sx={{ color: "#888" }}>
<Info size={16} />
<Typography>No photos uploaded</Typography>
</Box>
)}
</Box>
) : (
// Text OR No Data
<>
{value ? (
<Typography
sx={{
fontWeight: 600,
wordBreak: "break-word",
textAlign: "left",
}}
>
{value}
</Typography>
) : (
<Box
display="flex"
alignItems="center"
gap={1}
sx={{ color: "#888", fontStyle: "italic" }}
>
<Info size={16} />
<Typography>No data available</Typography>
</Box>
)}
</>
)}
</Box>
); );
}
return null;
})} })}
</CardContent> </CardContent>
</Card> </Card>
</Grid>
))} ))}
<Grid item xs={12}>
</div>
<Grid item xs={12} sx={{display:"flex", justifyContent:"center"}}>
<Button <Button
variant="contained" variant="contained"
color="success" color="success"
fullWidth
size="large" size="large"
onClick={onSubmit} onClick={onSubmit}
sx={{ borderRadius: 2 }} sx={{ borderRadius: 2 }}
> >
Submit Submit full Completed Data
</Button> </Button>
</Grid> </Grid>
</Grid>
</Box> </Box>
); );
}; };

View File

@ -0,0 +1,514 @@
import { Swiper, SwiperSlide } from "swiper/react";
import { Navigation, Autoplay } from "swiper/modules";
import { ChevronLeft, ChevronRight, Edit2 } from "lucide-react";
import { useSelector, useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import "swiper/css";
import "swiper/css/navigation";
import LazyImage from "../components/common/LazyImage";
import weddingpromo1 from "../assets/images/weddingpromo1.jpg";
import weddingpromo2 from "../assets/images/weddingpromo2.jpg";
import weddingpromo3 from "../assets/images/weddingpromo3.jpg";
import weddingpromo4 from "../assets/images/weddingpromo4.jpg";
import ProfileCompletion from "../components/profiledashboard/ProfileCompletion";
import { preloadDummyProfile } from "../redux/registrationFormSlice";
import { useEffect } from "react";
import {
Box,
Button,
Card,
CardContent,
CardHeader,
Divider,
IconButton,
Typography,
} from "@mui/material";
import { Info } from "@mui/icons-material";
const images = [
weddingpromo1, // bride in saree
weddingpromo2, // traditional jewellery
weddingpromo3, // flower details
weddingpromo4, // couple hands
weddingpromo1, // bride close-up
weddingpromo3, // groom + bride portrait
weddingpromo2, // wedding decor
weddingpromo4, // bride in temple
weddingpromo1, // traditional ceremony
weddingpromo3, // couple full shot
];
const ProfilePreviewPage = () => {
const dispatch = useDispatch();
const navigate = useNavigate();
const {
personalDetails,
educationalDetails,
familyDetails,
lifestyleDetails,
partnerPreferences,
} = useSelector((state) => state.registerform);
// For dummy data on first visit
useEffect(() => {
dispatch(preloadDummyProfile());
}, [dispatch]);
const handleEditSection = (stepNum) => {
navigate("/profile-edit", { state: { step: stepNum } });
};
const renderField = (label, value, stepNum = 1) => (
<Box
py={0.7}
borderBottom="1px solid #e0e0e0"
sx={{
display: "grid",
gridTemplateColumns: {
xs: "1fr",
sm: "1fr 1fr",
},
gap: "10px",
alignItems: "center",
}}
>
<Typography color="text.secondary" sx={{ fontWeight: 500 }}>
{label}:
</Typography>
{value ? (
<Typography
sx={{
fontWeight: 600,
wordBreak: "break-word",
textAlign: "left",
}}
>
{value}
</Typography>
) : (
<Box
display="flex"
alignItems="center"
gap={1}
sx={{ color: "#888", fontStyle: "italic" }}
>
<Info size={16} />
<Typography>No data available</Typography>
</Box>
)}
</Box>
);
const renderPersonalSection = () => (
<Card variant="outlined" sx={{ borderRadius: 2, background: "#fff5ed" }}>
<CardHeader
title={
<Typography variant="h6" fontWeight="bold">
Personal Details
</Typography>
}
action={
<IconButton
aria-label="edit"
color="primary"
onClick={() => handleEditSection(1)}
size="large"
>
<Edit2 size={20} />
</IconButton>
}
sx={{ padding: "15px 15px", background: "#f5fbff" }}
/>
<Divider />
<CardContent sx={{ pt: 1 }}>
{renderField("Name", personalDetails.name, 1)}
{renderField("Mobile Number", personalDetails.mobileNumber, 1)}
{renderField("Gender", personalDetails.gender, 1)}
{renderField("Date of Birth", personalDetails.dob, 1)}
{renderField("Height", personalDetails.height, 1)}
{renderField("Weight", personalDetails.weight, 1)}
{renderField("Marital Status", personalDetails.maritalStatus, 1)}
{renderField("Religion", personalDetails.religion, 1)}
{renderField("Caste", personalDetails.caste, 1)}
{renderField("Email", personalDetails.email, 1)}
{renderField("State", personalDetails.state, 1)}
{renderField("City", personalDetails.city, 1)}
{renderField("Pincode", personalDetails.pincode, 1)}
{/* Profile Images */}
<Box
py={0.7}
borderBottom="1px solid #e0e0e0"
sx={{
display: "grid",
gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
gap: "10px",
alignItems: "center",
}}
>
<Typography color="text.secondary" sx={{ fontWeight: 500 }}>
Profile Photos:
</Typography>
{personalDetails.profiles && personalDetails.profiles.length > 0 ? (
<Box display="flex" flexWrap="wrap" gap={1}>
{personalDetails.profiles.slice(0, 4).map((profile, index) => (
<Box
key={index}
width={60}
height={60}
borderRadius={1}
overflow="hidden"
sx={{ border: "1px solid #ddd", position: "relative" }}
>
{profile.preview || profile.url ? (
<img
src={profile.preview || profile.url}
alt={`Profile ${index + 1}`}
style={{
width: "100%",
height: "100%",
objectFit: "cover",
}}
/>
) : (
<Box
display="flex"
alignItems="center"
justifyContent="center"
height="100%"
bgcolor="#f5f5f5"
>
<ImageIcon size={24} />
</Box>
)}
</Box>
))}
{personalDetails.profiles.length > 4 && (
<Typography variant="caption" color="text.secondary">
+{personalDetails.profiles.length - 4} more
</Typography>
)}
</Box>
) : (
<Box
display="flex"
alignItems="center"
gap={1}
sx={{ color: "#888", fontStyle: "italic" }}
>
<Info size={16} />
<Typography>No photos uploaded</Typography>
</Box>
)}
</Box>
</CardContent>
</Card>
);
const renderEducationalSection = () => (
<Card variant="outlined" sx={{ borderRadius: 2, background: "#fff5ed" }}>
<CardHeader
title={
<Typography variant="h6" fontWeight="bold">
Education Details
</Typography>
}
action={
<IconButton
aria-label="edit"
color="primary"
onClick={() => handleEditSection(2)}
size="large"
>
<Edit2 size={20} />
</IconButton>
}
sx={{ padding: "15px 15px", background: "#f5fbff" }}
/>
<Divider />
<CardContent sx={{ pt: 1 }}>
{renderField("Qualification", educationalDetails.qualification, 2)}
{renderField("Field of Study", educationalDetails.fieldOfStudy, 2)}
{renderField("Occupation", educationalDetails.occupation, 2)}
{renderField("Organization", educationalDetails.organization, 2)}
{renderField("Income", educationalDetails.income, 2)}
{renderField("Work Location", educationalDetails.workLocation, 2)}
</CardContent>
</Card>
);
const renderFamilySection = () => (
<Card variant="outlined" sx={{ borderRadius: 2, background: "#fff5ed" }}>
<CardHeader
title={
<Typography variant="h6" fontWeight="bold">
Family Details
</Typography>
}
action={
<IconButton
aria-label="edit"
color="primary"
onClick={() => handleEditSection(2)}
size="large"
>
<Edit2 size={20} />
</IconButton>
}
sx={{ padding: "15px 15px", background: "#f5fbff" }}
/>
<Divider />
<CardContent sx={{ pt: 1 }}>
{renderField("Father Name", familyDetails.fatherName)}
{renderField("Father Occupation", familyDetails.fatherOccupation)}
{renderField("Mother Name", familyDetails.motherName)}
{renderField("Mother Occupation", familyDetails.motherOccupation)}
{renderField("Number of Siblings", familyDetails.siblings)}
{renderField("Siblings Marital status", familyDetails.siblingsStatus)}
</CardContent>
</Card>
);
const renderLifestyleSection = () => (
<Card variant="outlined" sx={{ borderRadius: 2, background: "#fff5ed" }}>
<CardHeader
title={
<Typography variant="h6" fontWeight="bold">
Lifestyle Details
</Typography>
}
action={
<IconButton
aria-label="edit"
color="primary"
onClick={() => handleEditSection(2)}
size="large"
>
<Edit2 size={20} />
</IconButton>
}
sx={{ padding: "15px 15px", background: "#f5fbff" }}
/>
<Divider />
<CardContent sx={{ pt: 1 }}>
{renderField("Diet", lifestyleDetails.diet)}
{renderField("Drinking", lifestyleDetails.drinking)}
{renderField("Smoking", lifestyleDetails.smoking)}
{renderField("Hobbies", lifestyleDetails.hobbies)}
</CardContent>
</Card>
);
const renderPreferenceSection = () => (
<Card variant="outlined" sx={{ borderRadius: 2, background: "#fff5ed" }}>
<CardHeader
title={
<Typography variant="h6" fontWeight="bold">
Lifestyle Details
</Typography>
}
action={
<IconButton
aria-label="edit"
color="primary"
onClick={() => handleEditSection(2)}
size="large"
>
<Edit2 size={20} />
</IconButton>
}
sx={{ padding: "15px 15px", background: "#f5fbff" }}
/>
<Divider />
<CardContent sx={{ pt: 1 }}>
{renderField("Age", partnerPreferences.ageRange)}
{renderField("Religion", partnerPreferences.religionCaste)}
{renderField("Occupation", partnerPreferences.occupationPref)}
{renderField("Life style", partnerPreferences.lifestylePref)}
{renderField("Qualification", partnerPreferences.qualificationPref)}
{renderField("Occupation", partnerPreferences.occupationText)}
{renderField("Income", partnerPreferences.incomePref)}
{renderField("Location", partnerPreferences.locationPref)}
</CardContent>
</Card>
);
return (
<>
<div className="custom-swiper-hero flex items-center justify-center p-4">
<div className="w-full max-w-7xl relative">
{/* Left Arrow */}
<button className="swiper-button-prev-custom absolute left-0 top-1/2 -translate-y-1/2 z-10 w-12 h-12 bg-white/20 backdrop-blur-sm rounded-full flex items-center justify-center hover:bg-white/30 transition-all">
<ChevronLeft className="w-6 h-6 text-white" />
</button>
{/* Right Arrow */}
<button className="swiper-button-next-custom absolute right-0 top-1/2 -translate-y-1/2 z-10 w-12 h-12 bg-white/20 backdrop-blur-sm rounded-full flex items-center justify-center hover:bg-white/30 transition-all">
<ChevronRight className="w-6 h-6 text-white" />
</button>
<Swiper
modules={[Navigation, Autoplay]}
navigation={{
prevEl: ".swiper-button-prev-custom",
nextEl: ".swiper-button-next-custom",
}}
grabCursor={true}
centeredSlides={true}
slidesPerView="auto"
spaceBetween={10}
autoplay={{
delay: 3000,
disableOnInteraction: false,
}}
loop={true}
className="mySwiper"
>
{images.map((img, idx) => (
<SwiperSlide key={idx}>
<div className="relative overflow-hidden rounded-3xl w-[100%] ">
<img
src={img}
alt={`Slide ${idx + 1}`}
className="w-full h-full object-cover"
/>
{/* <LazyImage
src={img}
alt={`Slide ${idx + 1}`}
className="w-full h-full object-cover"
/> */}
{/* <div className="absolute bottom-6 left-1/2 -translate-x-1/2 bg-black/50 backdrop-blur-sm px-6 py-2 rounded-full">
<span className="text-white font-semibold text-lg">Slide {idx + 1}</span>
</div> */}
</div>
</SwiperSlide>
))}
</Swiper>
</div>
<style>{`
.custom-swiper-hero .swiper {
width: 100%;
overflow: visible;
}
.custom-swiper-hero .swiper-slide {
width: 320px;
height: 320px;
transition: all 0.4s ease;
opacity: 1;
transform: scale(0.85);
}
.custom-swiper-hero .swiper-slide-active {
width: 630px !important;
height: 320px !important;
opacity: 1;
transform: scale(1);
z-index: 2;
}
@media only screen and (max-width: 768px) {
.custom-swiper-hero .swiper-slide {
width: 300px;
height: 150px;
}
.custom-swiper-hero .swiper-slide-active {
width: 300px !important;
height: 150px !important;
}
}
.custom-swiper-hero .swiper-slide > div {
width: 100%;
height: 100%;
}
.custom-swiper-hero .swiper-button-prev-custom,
.custom-swiper-hero .swiper-button-next-custom {
cursor: pointer;
}
@media (max-width: 1024px) {
.custom-swiper-hero .swiper-slide {
width: 240px;
height: 340px;
}
.custom-swiper-hero .swiper-slide-active {
width: 380px !important;
height: 480px !important;
}
}
@media (max-width: 768px) {
.custom-swiper-hero .swiper-slide {
width: 180px;
height: 280px;
}
.custom-swiper-hero .swiper-slide-active {
width: 300px !important;
height: 280px !important;
}
.custom-swiper-hero .swiper-button-prev-custom,
.custom-swiper-hero .swiper-button-next-custom {
width: 40px;
height: 40px;
}
}
@media (max-width: 480px) {
.custom-swiper-hero .swiper-slide {
width: 140px;
height: 220px;
}
.custom-swiper-hero .swiper-slide-active {
width: 300px !important;
height: 220px !important;
}
.custom-swiper-hero .swiper-button-prev-custom,
.custom-swiper-hero .swiper-button-next-custom {
width: 36px;
height: 36px;
}
}
`}</style>
</div>
<ProfileCompletion />
{/* personal details start */}
<Box p={3} sx={{ maxWidth: "1400px", width: "100%" }} mx="auto">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 my-5">
{renderPersonalSection()}
{renderEducationalSection()}
{renderFamilySection()}
{renderLifestyleSection()}
{renderPreferenceSection()}
</div>
</Box>
{/* personal details end */}
</>
);
};
export default ProfilePreviewPage;

View File

@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useState,useEffect } from "react";
import { ChevronLeft } from "lucide-react"; import { ChevronLeft } from "lucide-react";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { import {
@ -15,8 +15,10 @@ import FamilyDetailsForm from "./FamilyDetailsForm";
import LifestyleDetailsForm from "./LifestyleDetailsForm"; import LifestyleDetailsForm from "./LifestyleDetailsForm";
import PartnerPreferencesForm from "./PartnerPreferencesForm"; import PartnerPreferencesForm from "./PartnerPreferencesForm";
import PreviewScreen from "./PreviewScreen"; import PreviewScreen from "./PreviewScreen";
import { useLocation } from "react-router-dom";
const Stepper = ({ currentStep, onStepClick }) => { const Stepper = ({ currentStep, onStepClick }) => {
const steps = [ const steps = [
{ num: 1, label: "Personal" }, { num: 1, label: "Personal" },
{ num: 2, label: "Educational" }, { num: 2, label: "Educational" },
@ -59,6 +61,7 @@ const Stepper = ({ currentStep, onStepClick }) => {
const StepperForm = () => { const StepperForm = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const location = useLocation();
const personalDetails = useSelector( const personalDetails = useSelector(
(state) => state.registerform.personalDetails (state) => state.registerform.personalDetails
@ -74,9 +77,24 @@ const StepperForm = () => {
(state) => state.registerform.partnerPreferences (state) => state.registerform.partnerPreferences
); );
const [currentStep, setCurrentStep] = useState(1); const initialStep = location.state?.step || 1;
const [currentStep, setCurrentStep] = useState(initialStep);
const [errors, setErrors] = useState({}); const [errors, setErrors] = useState({});
useEffect(() => {
// in case user comes again with a different step
if (location.state?.step) {
setCurrentStep(location.state.step);
window.scrollTo(0, 0);
}
}, [location.state?.step]);
const validateStep = (step) => { const validateStep = (step) => {
const newErrors = {}; const newErrors = {};
@ -137,8 +155,7 @@ const StepperForm = () => {
"motherOccupation", "motherOccupation",
"siblings", "siblings",
"siblingsStatus", "siblingsStatus",
"familyType",
"nativePlace",
]; ];
required.forEach((field) => { required.forEach((field) => {
if (!familyDetails[field]) { if (!familyDetails[field]) {

View File

@ -0,0 +1,227 @@
import React, { useState } from 'react';
import { Tabs, Tab, IconButton, Menu, MenuItem } from '@mui/material';
import { MoreVert, Delete } from '@mui/icons-material';
const NotificationPage = () => {
const [activeTab, setActiveTab] = useState(0);
const [anchorEl, setAnchorEl] = useState(null);
const [selectedNotification, setSelectedNotification] = useState(null);
const [notifications, setNotifications] = useState([
{
id: 1,
type: 'message',
user: 'Thangavel',
avatar: 'https://i.pravatar.cc/150?img=1',
message: 'has sent you a message',
time: '1d',
action: 'View message',
category: 'all'
},
{
id: 2,
type: 'profile',
user: 'Thangavel',
avatar: 'https://i.pravatar.cc/150?img=2',
message: 'and 3 others have viewed your profile',
time: '1d',
action: 'See who viewed',
category: 'interactions'
},
{
id: 3,
type: 'interest',
user: 'Parthiban',
avatar: 'https://i.pravatar.cc/150?img=3',
message: 'has sent you an interest',
time: '1d',
action: 'View interest',
category: 'urgent'
},
{
id: 4,
type: 'message',
user: 'Rajesh',
avatar: 'https://i.pravatar.cc/150?img=4',
message: 'replied to your message',
time: '2d',
action: 'View message',
category: 'all'
},
{
id: 5,
type: 'profile',
user: 'Priya',
avatar: 'https://i.pravatar.cc/150?img=5',
message: 'viewed your profile',
time: '2d',
action: 'See profile',
category: 'interactions'
},
{
id: 6,
type: 'interest',
user: 'Kumar',
avatar: 'https://i.pravatar.cc/150?img=6',
message: 'accepted your interest',
time: '3d',
action: 'View profile',
category: 'urgent'
}
]);
const handleTabChange = (event, newValue) => {
setActiveTab(newValue);
};
const handleMenuOpen = (event, notificationId) => {
setAnchorEl(event.currentTarget);
setSelectedNotification(notificationId);
};
const handleMenuClose = () => {
setAnchorEl(null);
setSelectedNotification(null);
};
const handleDelete = () => {
setNotifications(notifications.filter(n => n.id !== selectedNotification));
handleMenuClose();
};
const getFilteredNotifications = () => {
if (activeTab === 0) return notifications;
if (activeTab === 1) return notifications.filter(n => n.category === 'interactions');
if (activeTab === 2) return notifications.filter(n => n.category === 'urgent');
return notifications;
};
const filteredNotifications = getFilteredNotifications();
return (
<div className="min-h-screen my-10">
<div className="max-w-[1200px] mx-auto ">
{/* Header */}
<div className="px-2 py-6 ">
<h1 className="text-2xl text-center font-semibold text-gray-900">Notifications</h1>
</div>
{/* Tabs */}
<div className="max-w-[350px] w-full mx-auto " >
<Tabs
value={activeTab}
onChange={handleTabChange}
sx={{
'& .MuiTab-root': {
textTransform: 'none',
fontSize: '15px',
fontWeight: 500,
minWidth: 'auto',
px: 3,
border:"1px solid #074201ff ",
display:"flex",
gap:"10px",
flexWrap:"wrap",
},
'& .Mui-selected': {
color: '#fcfcfcff !important',
backgroundColor: '#074201ff',
},
'& .MuiTabs-indicator': {
backgroundColor: '#074201ff',
}
}}
>
<Tab label="All" />
<Tab label="Interactions" sx={{marginLeft:"10px"}} />
<Tab label="Urgent" sx={{marginLeft:"10px"}}/>
</Tabs>
</div>
{/* Notification List */}
<div className="">
{filteredNotifications.length === 0 ? (
<div className="px-4 py-12 text-center text-gray-500">
No notifications found
</div>
) : (
<>
<div className="px-4 py-3 bg-[#edfffa] my-10">
<h2 className="text-[18px] font-semibold text-gray-700">Yesterday</h2>
</div>
{filteredNotifications.map((notification) => (
<div
key={notification.id}
className="px-4 py-4 hover:bg-gray-50 transition-colors bg-[#fff5ed] border-b border-[#A70710]"
>
<div className="flex items-start gap-3 ">
{/* Avatar */}
<img
src={notification.avatar}
alt={notification.user}
className="w-12 h-12 rounded-full object-cover flex-shrink-0"
/>
{/* Content */}
<div className="flex-1 min-w-0">
<p className="text-sm text-gray-900">
<span className="font-semibold">{notification.user}</span>{' '}
<span className="text-gray-700">{notification.message}</span>
</p>
<button className="mt-2 px-4 py-1.5 text-sm font-medium text-[#A70710] border-1 border-[#A70710] rounded-full hover:bg-[#A70710] hover:text-[#fff] transition-colors">
{notification.action}
</button>
</div>
{/* Time and Menu */}
<div className="flex items-start gap-2 flex-shrink-0">
<span className="text-xs text-gray-500 mt-1">{notification.time}</span>
<IconButton
size="small"
onClick={(e) => handleMenuOpen(e, notification.id)}
sx={{
color: '#6b7280',
'&:hover': { backgroundColor: '#f3f4f6' }
}}
>
<MoreVert fontSize="small" />
</IconButton>
</div>
</div>
</div>
))}
</>
)}
</div>
{/* Delete Menu */}
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleMenuClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
>
<MenuItem
onClick={handleDelete}
sx={{
color: '#ef4444',
'&:hover': { backgroundColor: '#fee2e2' }
}}
>
<Delete fontSize="small" sx={{ mr: 1 }} />
Delete
</MenuItem>
</Menu>
</div>
</div>
);
};
export default NotificationPage;

View File

@ -37,8 +37,7 @@ const registrationformSlice = createSlice({
motherOccupation: "", motherOccupation: "",
siblings: "", siblings: "",
siblingsStatus: "", siblingsStatus: "",
familyType: "",
nativePlace: "",
}, },
lifestyleDetails: { lifestyleDetails: {
diet: "", diet: "",
@ -84,6 +83,103 @@ const registrationformSlice = createSlice({
partnerPreferences: state.partnerPreferences, partnerPreferences: state.partnerPreferences,
}); });
}, },
preloadDummyProfile: (state) => {
state.personalDetails = {
...state.personalDetails,
name: "John Doe",
mobileNumber: "9876543210",
gender: "Male",
dob: "1995-05-01",
height: "175",
weight: "70",
maritalStatus: "Single",
religion: "Hindu",
caste: "Brahmin",
email: "john@example.com",
state: "Tamil Nadu",
city: "Chennai",
pincode: "600001",
profiles: [
{
id: 1,
name: "profile1.jpg",
url: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=200&h=200&fit=crop&crop=face",
preview: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=200&h=200&fit=crop&crop=face",
size: 245760,
},
{
id: 2,
name: "profile2.jpg",
url: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=200&h=200&fit=crop&crop=face",
preview: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=200&h=200&fit=crop&crop=face",
size: 189440,
},
{
id: 3,
name: "profile3.jpg",
url: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=200&h=200&fit=crop&crop=face",
preview: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=200&h=200&fit=crop&crop=face",
size: 312640,
},
{
id: 4,
name: "profile4.jpg",
url: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=200&h=200&fit=crop&crop=face",
preview: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=200&h=200&fit=crop&crop=face",
size: 267392,
},
{
id: 5,
name: "profile5.jpg",
url: "https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?w=200&h=200&fit=crop&crop=face",
preview: "https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?w=200&h=200&fit=crop&crop=face",
size: 198656,
},
],
};
state.educationalDetails = {
...state.educationalDetails,
qualification: "B.E",
fieldOfStudy: "CSE",
occupation: "Software Engineer",
organization: "ABC Pvt Ltd",
income: "10 LPA",
workLocation: "Chennai",
};
state.familyDetails = {
...state.familyDetails,
fatherName: "Father Name",
fatherOccupation: "Business",
motherName: "Mother Name",
motherOccupation: "Homemaker",
siblings: "1",
siblingsStatus: "Married",
};
state.lifestyleDetails = {
...state.lifestyleDetails,
diet: "Veg",
drinking: "No",
smoking: "No",
hobbies: "Reading, Music",
};
state.partnerPreferences = {
...state.partnerPreferences,
ageRange: "24-30",
religionCaste: "Hindu / Brahmin",
occupationPref: "IT / Software",
lifestylePref: "Non-smoker, Non-drinker",
qualificationPref: "Degree",
occupationText: "IT, Banking",
incomePref: "10-20 LPA",
locationPref: "Chennai, Bengaluru",
};
},
}, },
}); });
@ -94,6 +190,7 @@ export const {
updateLifestyleDetails, updateLifestyleDetails,
updatePartnerPreferences, updatePartnerPreferences,
submitForm, submitForm,
preloadDummyProfile,
} = registrationformSlice.actions; } = registrationformSlice.actions;
export default registrationformSlice.reducer; export default registrationformSlice.reducer;

View File

@ -17,6 +17,8 @@ import ContactUsPage from "../pages/ContactUsPage";
import ChangePasswordPage from "../components/auth/ChangePasswordForm"; import ChangePasswordPage from "../components/auth/ChangePasswordForm";
import StepperForm from "../feature/StepperForm"; import StepperForm from "../feature/StepperForm";
import FilterForm from "../feature/FilterForm"; import FilterForm from "../feature/FilterForm";
import ProfilePreviewPage from "../feature/ProfilePreviewPage";
import NotificationPage from "../pages/NotificationPage";
const UserRoutes = () => { const UserRoutes = () => {
@ -52,11 +54,19 @@ const UserRoutes = () => {
<Route path="/horoscoper-generate" element={<HoroscopeGenerator />} /> <Route path="/horoscoper-generate" element={<HoroscopeGenerator />} />
</Route> </Route>
<Route element={<ProfileLayout />}>
<Route path="/notifications" element={<NotificationPage />} />
</Route>
<Route element={<ProfileLayout />}> <Route element={<ProfileLayout />}>
<Route path="/profile-details/:id" element={<ProfileDetailPage />} /> <Route path="/profile-details/:id" element={<ProfileDetailPage />} />
</Route> </Route>
<Route element={<ProfileLayout />}>
<Route path="/profile" element={<ProfilePreviewPage />} />
</Route>
<Route element={<ProfileLayout />}> <Route element={<ProfileLayout />}>
<Route path="/profile-edit" element={<StepperForm />} /> <Route path="/profile-edit" element={<StepperForm />} />
</Route> </Route>
@ -73,7 +83,7 @@ const UserRoutes = () => {
<Route path="/account-settings" element={<AccountSettingPage />} /> <Route path="/account-settings" element={<AccountSettingPage />} />
</Route> </Route>
<Route element={<ProfileLayout />}> <Route element={<ProfileLayout />}>
<Route path="/terms-and-condition" element={<TermsAndConditionPage />} /> <Route path="/terms" element={<TermsAndConditionPage />} />
</Route> </Route>
<Route element={<ProfileLayout />}> <Route element={<ProfileLayout />}>
<Route path="/privacy-policy" element={<PoliciesPage />} /> <Route path="/privacy-policy" element={<PoliciesPage />} />