309 lines
11 KiB
JavaScript
309 lines
11 KiB
JavaScript
import React, { useState } from "react";
|
|
import { Crown, Bookmark } from "lucide-react";
|
|
import CakeIcon from "@mui/icons-material/Cake";
|
|
import GroupsIcon from "@mui/icons-material/Groups";
|
|
import SchoolIcon from "@mui/icons-material/School";
|
|
import LocationOnIcon from "@mui/icons-material/LocationOn";
|
|
import AccessibilityNewIcon from "@mui/icons-material/AccessibilityNew";
|
|
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 FilterModal from "../../feature/FilterModal";
|
|
|
|
// Profile Card Component
|
|
function ProfileCard({ profile }) {
|
|
const [isLiked, setIsLiked] = useState(false);
|
|
|
|
return (
|
|
<div 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' }}
|
|
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" />
|
|
</motion.div>
|
|
|
|
<motion.button
|
|
whileHover={{ scale: 1 }}
|
|
whileTap={{ scale: 0.9 }}
|
|
className="absolute top-4 right-4 z-10 bg-white rounded-full px-4 py-2 shadow-lg flex items-center space-x-2 hover:bg-gray-50 transition-colors"
|
|
>
|
|
<Bookmark className="w-4 h-4" />
|
|
<span className="text-[12px] font-medium">Shortlist</span>
|
|
</motion.button>
|
|
|
|
<img
|
|
src={profile.image}
|
|
alt="Profile"
|
|
className="w-full h-96 object-cover"
|
|
/>
|
|
|
|
<div
|
|
className="absolute bottom-0 left-0 right-0 h-35 pointer-events-none"
|
|
style={{
|
|
background:
|
|
"linear-gradient(rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.6) 40%, rgb(255, 255, 255) 100%)",
|
|
}}
|
|
></div>
|
|
|
|
<div className="absolute bottom-0 left-0 right-0 p-6 text-gray-900">
|
|
<h1 className="text-[18px] text-green-900 font-bold mb-2">
|
|
{profile.name}
|
|
</h1>
|
|
<p className="text-[14px] text-gray-700 leading-relaxed">
|
|
Matrimony ID: {profile.id}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="px-4 pt-2 pb-4 flex flex-col gap-2 bg-white">
|
|
<div className="flex items-center gap-4">
|
|
<div className="flex items-center gap-2">
|
|
<CakeIcon className="w-4 h-4 text-gray-700" />
|
|
<span className="text-[14px] font-semibold text-gray-900">
|
|
Age: {profile.age}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-2">
|
|
<AccessibilityNewIcon className="w-4 h-4 text-gray-700" />
|
|
<span className="text-[14px] font-semibold text-gray-900">
|
|
Height: {profile.height}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-2">
|
|
<GroupsIcon className="w-4 h-4 text-gray-700" />
|
|
<span className="text-[14px] font-semibold text-gray-900">
|
|
{profile.community}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-2">
|
|
<SchoolIcon className="w-4 h-4 text-gray-700" />
|
|
<span className="text-[14px] font-semibold text-gray-900">
|
|
{profile.education}
|
|
</span>
|
|
</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">
|
|
{profile.location}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="flex gap-3 my-2 justify-between w-full px-[0px]">
|
|
<button className="gap-2 px-3 w-[fit-content] bg-[#A70710] hover:bg-red-600 text-white
|
|
font-semibold text-base py-2 rounded-[20px] shadow-md
|
|
hover:shadow-lg transition-all duration-300 flex items-center justify-center transform hover:scale-95">
|
|
<svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
<path d="M18 6L6 18M6 6l12 12" strokeLinecap="round" strokeLinejoin="round"/>
|
|
</svg>
|
|
Decline
|
|
</button>
|
|
|
|
<button
|
|
className="w-[fit-content] bg-[#034E08] hover:bg-green-700 text-white font-semibold text-base
|
|
rounded-[20px] px-3 gap-2 py-1 shadow-lg hover:shadow-xl transition-all duration-300
|
|
transform hover:scale-105 flex items-center justify-center"
|
|
onClick={() => setIsLiked(!isLiked)}
|
|
>
|
|
{isLiked ? (
|
|
<svg className="w-4 h-4" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" fill="#EF4444"/>
|
|
</svg>
|
|
) : (
|
|
<svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" strokeLinecap="round" strokeLinejoin="round"/>
|
|
</svg>
|
|
)}
|
|
|
|
Interest
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Main Component
|
|
export default function MatchesInterface() {
|
|
const [selectedTab, setSelectedTab] = useState('your-matches');
|
|
|
|
const tabs = [
|
|
{
|
|
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'
|
|
},
|
|
{
|
|
id: 'shortlisted-by-you',
|
|
icon: <StarIcon className="w-6 h-6" />,
|
|
title: 'Shortlisted by you',
|
|
description: 'Matches you have shortlisted',
|
|
category: 'Based on activity'
|
|
},
|
|
{
|
|
id: 'viewed-you',
|
|
icon: <VisibilityIcon className="w-6 h-6" />,
|
|
title: 'Viewed you',
|
|
description: 'Matches who have viewed your profile',
|
|
category: 'Based on activity'
|
|
},
|
|
{
|
|
id: 'shortlisted-you',
|
|
icon: <PersonAddIcon className="w-6 h-6" />,
|
|
title: 'Shortlisted you',
|
|
description: 'Matches who have shortlisted your profile',
|
|
category: 'Based on activity'
|
|
},
|
|
{
|
|
id: 'viewed-by-you',
|
|
icon: <VisibilityIcon className="w-6 h-6" />,
|
|
title: 'Viewed by you',
|
|
description: 'Matches you have viewed',
|
|
category: 'Based on activity'
|
|
}
|
|
];
|
|
|
|
const profiles = [
|
|
{
|
|
id: 'JB2847593',
|
|
name: 'Jerome Bell',
|
|
age: 22,
|
|
height: '5.2',
|
|
community: 'Hindu / Agamudiyar/thular',
|
|
education: 'BCA / Data analyst',
|
|
location: 'Chennai',
|
|
image: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=600&h=800&fit=crop&crop=faces,top'
|
|
},
|
|
{
|
|
id: 'SA8392847',
|
|
name: 'Sarah Anderson',
|
|
age: 24,
|
|
height: '5.4',
|
|
community: 'Hindu / Iyer',
|
|
education: 'MBA / Marketing Manager',
|
|
location: 'Bangalore',
|
|
image: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=600&h=800&fit=crop&crop=faces,top'
|
|
},
|
|
{
|
|
id: 'PR9384756',
|
|
name: 'Priya Reddy',
|
|
age: 23,
|
|
height: '5.3',
|
|
community: 'Hindu / Reddy',
|
|
education: 'B.Tech / Software Engineer',
|
|
location: 'Hyderabad',
|
|
image: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=600&h=800&fit=crop&crop=faces,top'
|
|
},
|
|
{
|
|
id: 'AN4758392',
|
|
name: 'Ananya Krishnan',
|
|
age: 25,
|
|
height: '5.5',
|
|
community: 'Hindu / Nair',
|
|
education: 'MD / Doctor',
|
|
location: 'Kochi',
|
|
image: 'https://images.unsplash.com/photo-1488426862026-3ee34a7d66df?w=600&h=800&fit=crop&crop=faces,top'
|
|
}
|
|
];
|
|
|
|
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 {
|
|
display: none;
|
|
}
|
|
.scrollbar-hide {
|
|
-ms-overflow-style: none;
|
|
scrollbar-width: none;
|
|
}
|
|
`}</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 className="py-6 px-4">
|
|
{tabs.map((tab) => {
|
|
const showCategory = tab.category !== currentCategory;
|
|
if (showCategory) {
|
|
currentCategory = tab.category;
|
|
}
|
|
|
|
return (
|
|
<React.Fragment key={tab.id}>
|
|
{showCategory && (
|
|
<h2 className="text-xl font-bold text-gray-900 mb-4 mt-6 first:mt-0">
|
|
{tab.category}
|
|
</h2>
|
|
)}
|
|
<div
|
|
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'
|
|
}`}
|
|
>
|
|
<div className="flex items-start gap-3">
|
|
<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'
|
|
}`}>
|
|
{tab.title}
|
|
</h3>
|
|
<svg
|
|
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" />
|
|
</svg>
|
|
</div>
|
|
<p className="text-sm text-gray-600 mt-1">{tab.description}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</React.Fragment>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Right Content Area - Scrollable */}
|
|
<div className=" px-2 py-8">
|
|
<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}
|
|
</h1>
|
|
|
|
<FilterModal/>
|
|
</div>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-2">
|
|
{profiles.map((profile) => (
|
|
<ProfileCard key={profile.id} profile={profile} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
} |