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

View File

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

View File

@ -28,7 +28,7 @@ const NAV_LINKS = [
{ label: "Matches", path: "/matches" },
{ label: "Interest", path: "/interest" },
{ label: "Messages", path: "/chat" },
{ label: "Search", path: "/search" },
{ label: "Search", path: "/matches" },
{ 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 VisibilityIcon from "@mui/icons-material/Visibility";
import PersonAddIcon from "@mui/icons-material/PersonAdd";
import { motion } from 'framer-motion';
import { motion } from "framer-motion";
import FilterModal from "../../feature/FilterModal";
import bride1 from "../../assets/images/bride1.jpg";
import bride2 from "../../assets/images/bride2.jpg";
@ -24,8 +24,8 @@ import groom4 from "../../assets/images/groom4.jpg";
import horoscope from "../../assets/images/horoscopeicon.png";
import { useNavigate } from "react-router-dom";
import { Button, Fab } from "@mui/material";
import MessageIcon from '@mui/icons-material/Message';
import PhoneIcon from '@mui/icons-material/Phone';
import MessageIcon from "@mui/icons-material/Message";
import PhoneIcon from "@mui/icons-material/Phone";
// Profile Card Component
function ProfileCard({ profile }) {
const [isLiked, setIsLiked] = useState(false);
@ -33,12 +33,13 @@ function ProfileCard({ profile }) {
return (
<div
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">
<motion.div
initial={{ scale: 0 }}
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"
>
<Crown className="w-5 h-5 text-white" />
@ -52,17 +53,20 @@ function ProfileCard({ profile }) {
<Bookmark className="w-4 h-4" />
<span className="text-[12px] font-medium">Shortlist</span>
</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]"
style={{ height: "300px" }}
>
<img
src={profile.image}
alt="Profile"
className="w-full h-full object-cover bg-gray-200"
style={{
// objectFit:"inherit",
objectPosition:"top"}}
objectPosition: "top",
}}
/>
</div>
</div>
<div
className="absolute bottom-0 left-0 right-0 h-25 pointer-events-none"
style={{
@ -84,9 +88,7 @@ function ProfileCard({ profile }) {
<div className="px-4 pt-2 pb-4 flex flex-col gap-2 bg-white">
<div className="flex items-center gap-2">
<VisibilityIcon />
<span className="text-[14px] text-gray-900">
{profile.lastseen}
</span>
<span className="text-[14px] text-gray-900">{profile.lastseen}</span>
</div>
<div className="flex items-center gap-4">
<div className="flex items-center gap-2">
@ -104,10 +106,6 @@ function ProfileCard({ profile }) {
</div>
</div>
<div className="flex items-center gap-2">
<LocationOnIcon className="w-4 h-4 text-gray-700" />
<span className="text-[14px] font-semibold text-gray-900">
@ -155,7 +153,6 @@ function ProfileCard({ profile }) {
<div className="flex gap-3 my-2 justify-between w-full px-[0px]">
<div className="flex gap-2">
<Fab size="medium" color="primary" aria-label="add">
<MessageIcon />
</Fab>
@ -163,16 +160,24 @@ function ProfileCard({ profile }) {
<Fab size="medium" color="secondary" aria-label="add">
<PhoneIcon />
</Fab>
</div>
<Button variant="contained" color="#f5fbff" onClick={(e) =>{ e.stopPropagation();
navigate(`/profile-details/${profile.id}`)}
} sx={{color:"#000000", background:"#f5fbff", fontWeight:"600", borderRadius:"30px"}}>
<Button
variant="contained"
color="#f5fbff"
onClick={(e) => {
e.stopPropagation();
navigate(`/profile-details/${profile.id}`);
}}
sx={{
color: "#000000",
background: "#f5fbff",
fontWeight: "600",
borderRadius: "30px",
}}
>
View Details
</Button>
</div>
</div>
</div>
@ -182,132 +187,134 @@ function ProfileCard({ profile }) {
// Main Component
export default function MatchesInterface() {
const navigate = useNavigate();
const [selectedTab, setSelectedTab] = useState('your-matches');
const [selectedTab, setSelectedTab] = useState("your-matches");
const tabs = [
{
id: 'your-matches',
id: "your-matches",
icon: <PersonIcon className="w-6 h-6" />,
title: 'Your Matches',
description: 'View all the profiles that match your preferences',
category: 'All Matches'
title: "Your Matches",
description: "View all the profiles that match your preferences",
category: "All Matches",
},
{
id: 'shortlisted-by-you',
id: "shortlisted-by-you",
icon: <StarIcon className="w-6 h-6" />,
title: 'Shortlisted by you',
description: 'Matches you have shortlisted',
category: 'Based on activity'
title: "Shortlisted by you",
description: "Matches you have shortlisted",
category: "Based on activity",
},
{
id: 'viewed-you',
id: "viewed-you",
icon: <VisibilityIcon className="w-6 h-6" />,
title: 'Viewed you',
description: 'Matches who have viewed your profile',
category: 'Based on activity'
title: "Viewed you",
description: "Matches who have viewed your profile",
category: "Based on activity",
},
{
id: 'shortlisted-you',
id: "shortlisted-you",
icon: <PersonAddIcon className="w-6 h-6" />,
title: 'Shortlisted you',
description: 'Matches who have shortlisted your profile',
category: 'Based on activity'
title: "Shortlisted you",
description: "Matches who have shortlisted your profile",
category: "Based on activity",
},
{
id: 'viewed-by-you',
id: "viewed-by-you",
icon: <VisibilityIcon className="w-6 h-6" />,
title: 'Viewed by you',
description: 'Matches you have viewed',
category: 'Based on activity'
}
title: "Viewed by you",
description: "Matches you have viewed",
category: "Based on activity",
},
];
const profiles = [
{
id: 'JB2847593',
name: 'Jerome Bell',
id: "JB2847593",
name: "Jerome Bell",
age: 22,
height: '5.2',
lastseen: 'Last seen 14 Nov 2025',
education: 'BCA / Data analyst',
location: 'Chennai',
image: bride1
height: "5.2",
lastseen: "Last seen 14 Nov 2025",
education: "BCA / Data analyst",
location: "Chennai",
image: bride1,
},
{
id: 'SA8392847',
name: 'Sarah Anderson',
id: "SA8392847",
name: "Sarah Anderson",
age: 24,
height: '5.4',
lastseen: 'Last seen 14 Nov 2025',
education: 'MBA / Marketing Manager',
location: 'Bangalore',
image: bride4
height: "5.4",
lastseen: "Last seen 14 Nov 2025",
education: "MBA / Marketing Manager",
location: "Bangalore",
image: bride4,
},
{
id: 'PR9384756',
name: 'Priya Reddy',
id: "PR9384756",
name: "Priya Reddy",
age: 23,
height: '5.3',
lastseen: 'Last seen 14 Nov 2025',
education: 'B.Tech / Software Engineer',
location: 'Hyderabad',
image: bride2
height: "5.3",
lastseen: "Last seen 14 Nov 2025",
education: "B.Tech / Software Engineer",
location: "Hyderabad",
image: bride2,
},
{
id: 'AN4758392',
name: 'Ananya Krishnan',
id: "AN4758392",
name: "Ananya Krishnan",
age: 25,
height: '5.5',
lastseen: 'Last seen 14 Nov 2025',
education: 'MD / Doctor',
location: 'Kochi',
image: bride3
height: "5.5",
lastseen: "Last seen 14 Nov 2025",
education: "MD / Doctor",
location: "Kochi",
image: bride3,
},
{
id: 'AN4758392',
name: 'Ananya Krishnan',
id: "AN4758392",
name: "Ananya Krishnan",
age: 25,
height: '5.5',
lastseen: 'Last seen 14 Nov 2025',
education: 'MD / Doctor',
location: 'Kochi',
image: groom1
height: "5.5",
lastseen: "Last seen 14 Nov 2025",
education: "MD / Doctor",
location: "Kochi",
image: groom1,
},
{
id: 'AN4758392',
name: 'Ananya Krishnan',
id: "AN4758392",
name: "Ananya Krishnan",
age: 25,
height: '5.5',
lastseen: 'Last seen 14 Nov 2025',
education: 'MD / Doctor',
location: 'Kochi',
image: groom2
height: "5.5",
lastseen: "Last seen 14 Nov 2025",
education: "MD / Doctor",
location: "Kochi",
image: groom2,
},
{
id: 'AN4758392',
name: 'Ananya Krishnan',
id: "AN4758392",
name: "Ananya Krishnan",
age: 25,
height: '5.5',
lastseen: 'Last seen 14 Nov 2025',
education: 'MD / Doctor',
location: 'Kochi',
image: groom4
height: "5.5",
lastseen: "Last seen 14 Nov 2025",
education: "MD / Doctor",
location: "Kochi",
image: groom4,
},
{
id: 'AN4758392',
name: 'Ananya Krishnan',
id: "AN4758392",
name: "Ananya Krishnan",
age: 25,
height: '5.5',
lastseen: 'Last seen 14 Nov 2025',
education: 'MD / Doctor',
location: 'Kochi',
image: groom3
}
height: "5.5",
lastseen: "Last seen 14 Nov 2025",
education: "MD / Doctor",
location: "Kochi",
image: groom3,
},
];
let currentCategory = '';
let currentCategory = "";
return (
<>
<div className="grid grid-cols-1 md:grid-cols-[300px_auto] md:px-4 gap-2 md:gap-10">
<style>{`
.scrollbar-hide::-webkit-scrollbar {
@ -320,8 +327,10 @@ export default function MatchesInterface() {
`}</style>
{/* Left Sidebar - Fixed on desktop, scrollable on mobile */}
<div 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
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">
{tabs.map((tab) => {
const showCategory = tab.category !== currentCategory;
@ -340,31 +349,52 @@ export default function MatchesInterface() {
onClick={() => setSelectedTab(tab.id)}
className={`p-4 rounded-lg mb-3 cursor-pointer transition-all ${
selectedTab === tab.id
? 'bg-green-50 border-l-4 border-green-600'
: 'hover:bg-gray-50'
? "bg-green-50 border-l-4 border-green-600"
: "hover:bg-gray-50"
}`}
>
<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}
</div>
<div className="flex-1">
<div className="flex items-center justify-between">
<h3 className={`font-semibold text-base ${
selectedTab === tab.id ? 'text-green-900' : 'text-gray-900'
}`}>
<h3
className={`font-semibold text-base ${
selectedTab === tab.id
? "text-green-900"
: "text-gray-900"
}`}
>
{tab.title}
</h3>
<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"
stroke="currentColor"
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>
</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>
@ -379,16 +409,17 @@ export default function MatchesInterface() {
<div className="w-[100%] max-w-[1200px] mx-auto">
<div className="flex justify-between gap-2 itemes-center mb-8">
<h1 className="text-[24px] font-bold text-gray-900 ">
{tabs.find(t => t.id === selectedTab)?.title}
{tabs.find((t) => t.id === selectedTab)?.title}
</h1>
<div className="flex gap-2 items-center">
<img src={horoscope} onClick={()=>{
navigate("/horoscoper-generate")
}}/>
<FilterModal/>
</div>
<div className="flex gap-2 items-center">
<img
src={horoscope}
onClick={() => {
navigate("/horoscoper-generate");
}}
/>
<FilterModal />
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-2">
{profiles.map((profile) => (
@ -398,5 +429,24 @@ export default function MatchesInterface() {
</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">
{/* Highest Qualification */}
<div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Highest Qualification</label>
<TextField
fullWidth
inputRef={inputRef}
@ -44,6 +45,7 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
{/* Field of Study */}
<div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Field of Study</label>
<TextField
fullWidth
name="fieldOfStudy"
@ -59,6 +61,7 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
{/* Occupation */}
<div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Occupation</label>
<TextField
fullWidth
name="occupation"
@ -74,6 +77,7 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
{/* Company / Organization Name */}
<div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Company / Organization Name</label>
<TextField
fullWidth
name="organization"
@ -89,6 +93,7 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
{/* Annual Income */}
<div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Annual Income</label>
<TextField
fullWidth
name="income"
@ -104,6 +109,7 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
{/* Work Location */}
<div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Work Location</label>
<TextField
fullWidth
name="workLocation"
@ -129,10 +135,10 @@ const EducationalDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
}}
>
<Button variant="outlined" onClick={onSkipStep}>
Skip
Next
</Button>
<Button variant="contained" color="primary" onClick={handleSubmit}>
Next
Submit
</Button>
</Grid>
</form>

View File

@ -24,6 +24,11 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
dispatch(updateFamilyDetails({ [field]: value }));
};
const handleSubmit = () => {
console.log("Submitting family details:", data);
onSubmitStep();
};
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">
{/* Highest Qualification */}
<div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Father Name</label>
<TextField
fullWidth
inputRef={inputRef}
@ -49,6 +54,8 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
</div>
<div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Father Occupation</label>
<TextField
fullWidth
@ -64,6 +71,7 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
</div>
<div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Mother Name</label>
<TextField
fullWidth
name="motherName"
@ -78,6 +86,8 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
</div>
<div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Mother Occupation</label>
<TextField
fullWidth
name="motherOccupation"
@ -93,6 +103,7 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
</div>
<div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]">Enter Number of Brothers / Sisters</label>
<TextField
fullWidth
name="siblings"
@ -108,6 +119,7 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
</div>
<div className="flex flex-col gap-4">
<label className="text-gray-900 text-[15px]"> Brothers / Sisters (Married / Unmarried)</label>
<FormControl
fullWidth
variant="outlined"
@ -143,15 +155,23 @@ const FamilyDetailsForm = ({ onSubmitStep, onSkipStep, errors }) => {
</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
</Button>
<Button variant="contained" color="primary" fullWidth onClick={onSubmitStep}>
Submit & Next
<Button variant="contained" color="primary" onClick={handleSubmit}>
Submit
</Button>
</Grid>
</div>
</form>
</div>

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { Edit2 } from 'lucide-react';
import { Edit2,Info } from 'lucide-react';
import {
Card,
CardContent,
@ -45,11 +45,13 @@ const PreviewScreen = ({ onEdit, onSubmit }) => {
];
return (
<Box p={3} maxWidth={720} mx="auto" minHeight="100vh" bgcolor="#f9fafb">
<Grid container spacing={3}>
<Box p={3} sx={{maxWidth:"1400px", width:"100%"}} mx="auto" >
<div className='grid grid-cols-1 md:grid-cols-2 gap-4 my-10'>
{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
title={
<Typography variant="h6" fontWeight="bold">
@ -66,57 +68,122 @@ const PreviewScreen = ({ onEdit, onSubmit }) => {
<Edit2 size={20} />
</IconButton>
}
sx={{ pb: 0 }}
sx={{padding:"15px 15px", background:"#f5fbff" }}
/>
<Divider />
<CardContent sx={{ pt: 1 }}>
<CardContent sx={{ pt: 1, }}>
{Object.entries(section.data).map(([key, value]) => {
if (value && key !== 'profiles') {
// if (value && key !== 'profiles') {
// Convert camelCase or camel_Snake_case to readable words
const formattedKey = key
.replace(/([A-Z])/g, ' $1')
.replace(/_/g, ' ')
.replace(/\b\w/g, (l) => l.toUpperCase())
.trim();
const isImage =
typeof value === "string" &&
(value.startsWith("http") || value.startsWith("data:image"));
return (
<Box
key={key}
display="flex"
justifyContent="space-between"
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 }}>
{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, ml: 2, maxWidth: '60%', wordBreak: 'break-word' }}
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>
</Card>
</Grid>
))}
<Grid item xs={12}>
</div>
<Grid item xs={12} sx={{display:"flex", justifyContent:"center"}}>
<Button
variant="contained"
color="success"
fullWidth
size="large"
onClick={onSubmit}
sx={{ borderRadius: 2 }}
>
Submit
Submit full Completed Data
</Button>
</Grid>
</Grid>
</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 { useDispatch, useSelector } from "react-redux";
import {
@ -15,8 +15,10 @@ import FamilyDetailsForm from "./FamilyDetailsForm";
import LifestyleDetailsForm from "./LifestyleDetailsForm";
import PartnerPreferencesForm from "./PartnerPreferencesForm";
import PreviewScreen from "./PreviewScreen";
import { useLocation } from "react-router-dom";
const Stepper = ({ currentStep, onStepClick }) => {
const steps = [
{ num: 1, label: "Personal" },
{ num: 2, label: "Educational" },
@ -59,6 +61,7 @@ const Stepper = ({ currentStep, onStepClick }) => {
const StepperForm = () => {
const dispatch = useDispatch();
const location = useLocation();
const personalDetails = useSelector(
(state) => state.registerform.personalDetails
@ -74,9 +77,24 @@ const StepperForm = () => {
(state) => state.registerform.partnerPreferences
);
const [currentStep, setCurrentStep] = useState(1);
const initialStep = location.state?.step || 1;
const [currentStep, setCurrentStep] = useState(initialStep);
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 newErrors = {};
@ -137,8 +155,7 @@ const StepperForm = () => {
"motherOccupation",
"siblings",
"siblingsStatus",
"familyType",
"nativePlace",
];
required.forEach((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: "",
siblings: "",
siblingsStatus: "",
familyType: "",
nativePlace: "",
},
lifestyleDetails: {
diet: "",
@ -84,6 +83,103 @@ const registrationformSlice = createSlice({
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,
updatePartnerPreferences,
submitForm,
preloadDummyProfile,
} = registrationformSlice.actions;
export default registrationformSlice.reducer;

View File

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