This commit is contained in:
Meenadeveloper 2025-11-20 17:52:28 +05:30
parent ea61a44fa1
commit 9a0ff761f6
37 changed files with 4024 additions and 175 deletions

3009
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite --host",
"build": "vite build", "build": "vite build",
"lint": "eslint .", "lint": "eslint .",
"preview": "vite preview" "preview": "vite preview"
@ -17,6 +17,8 @@
"@mui/styled-engine-sc": "^7.3.5", "@mui/styled-engine-sc": "^7.3.5",
"@tailwindcss/vite": "^4.1.17", "@tailwindcss/vite": "^4.1.17",
"axios": "^1.13.2", "axios": "^1.13.2",
"framer-motion": "^12.23.24",
"lightswind": "^3.1.15",
"lucide-react": "^0.553.0", "lucide-react": "^0.553.0",
"react": "^19.2.0", "react": "^19.2.0",
"react-dom": "^19.2.0", "react-dom": "^19.2.0",

View File

@ -1,42 +0,0 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}

View File

@ -1,39 +1,14 @@
import { useState } from 'react' import "./App.css";
import reactLogo from './assets/react.svg' import { BrowserRouter as Router } from "react-router-dom";
import viteLogo from '/vite.svg' import AppRoutes from "./routes/AppRoutes";
import './App.css'
function App() { function App() {
const [count, setCount] = useState(0)
return ( return (
<> <>
<div> <Router>
<a href="https://vite.dev" target="_blank"> <AppRoutes />
<img src={viteLogo} className="logo" alt="Vite logo" /> </Router>
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.jsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
<h1 class="text-3xl font-bold underline">
Hello world!
</h1>
</> </>
) );
} }
export default App export default App;

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
src/assets/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 753 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 153 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

View File

@ -0,0 +1,203 @@
import { useState } from "react";
import * as React from "react";
import AppBar from "@mui/material/AppBar";
import Box from "@mui/material/Box";
import Toolbar from "@mui/material/Toolbar";
import IconButton from "@mui/material/IconButton";
import Typography from "@mui/material/Typography";
import SwipeableDrawer from "@mui/material/SwipeableDrawer";
import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemText from "@mui/material/ListItemText";
import Avatar from "@mui/material/Avatar";
import Container from "@mui/material/Container";
import Button from "@mui/material/Button";
import Tooltip from "@mui/material/Tooltip";
import MenuItem from "@mui/material/MenuItem";
import Menu from "@mui/material/Menu";
import MenuIcon from "@mui/icons-material/Menu";
import CloseIcon from "@mui/icons-material/Close"; // <-- Added
import Divider from "@mui/material/Divider";
import AdbIcon from "@mui/icons-material/Adb";
import ListItemIcon from "@mui/material/ListItemIcon";
import { InboxIcon, MailIcon } from "lucide-react";
const pages = ["Matches", "Search", "Help"];
const settings = ["Profile", "Account", "Dashboard", "Logout"];
const LandingHeader = () => {
const [drawerOpen, setDrawerOpen] = useState(false);
const [anchorElUser, setAnchorElUser] = React.useState(null);
const toggleDrawer = (open) => () => {
setDrawerOpen(open);
};
const handleOpenUserMenu = (event) => {
setAnchorElUser(event.currentTarget);
};
const handleCloseUserMenu = () => {
setAnchorElUser(null);
};
const DrawerList = (
<Box
sx={{ width: 250 }}
role="presentation"
onKeyDown={toggleDrawer(false)}
>
{/* Drawer Header + Close Button */}
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
px: 2,
py: 1.5,
}}
>
<Typography variant="h6">Menu</Typography>
{/* Close Button */}
<IconButton onClick={toggleDrawer(false)}>
<CloseIcon />
</IconButton>
</Box>
<Divider />
<List>
{["Matches", "Search", "Chat", "Mail"].map((text, index) => (
<ListItem key={text} disablePadding>
<ListItemButton>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItemButton>
</ListItem>
))}
</List>
{/* <Divider />
<List>
{["All mail", "Trash", "Spam"].map((text, index) => (
<ListItem key={text} disablePadding>
<ListItemButton>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItemButton>
</ListItem>
))}
</List> */}
</Box>
);
return (
<>
<AppBar position="sticky">
<Container maxWidth="xl">
<Toolbar disableGutters>
{/* Desktop Logo */}
<AdbIcon sx={{ display: { xs: "none", md: "flex" }, mr: 1 }} />
<Typography
variant="h6"
noWrap
component="a"
href="#"
sx={{
mr: 2,
display: { xs: "none", md: "flex" },
fontFamily: "monospace",
fontWeight: 700,
letterSpacing: ".3rem",
color: "inherit",
textDecoration: "none",
position:"sticky",
zIndex:"99"
}}
>
LOGO
</Typography>
{/* Mobile Drawer Button */}
<Box sx={{ flexGrow: 1, display: { xs: "flex", md: "none" } }}>
<IconButton size="large" color="inherit" onClick={toggleDrawer(true)}>
<MenuIcon />
</IconButton>
</Box>
{/* Mobile Logo */}
<AdbIcon sx={{ display: { xs: "flex", md: "none" }, mr: 1 }} />
<Typography
variant="h5"
noWrap
component="a"
href="#"
sx={{
mr: 2,
display: { xs: "flex", md: "none" },
flexGrow: 1,
fontFamily: "monospace",
fontWeight: 700,
letterSpacing: ".3rem",
color: "inherit",
textDecoration: "none",
}}
>
LOGO
</Typography>
{/* Desktop Menu */}
<Box sx={{ flexGrow: 1, display: { xs: "none", md: "flex" } }}>
{pages.map((page) => (
<Button key={page} sx={{ my: 2, color: "white", display: "block" }}>
{page}
</Button>
))}
</Box>
{/* Avatar Menu */}
<Box sx={{ flexGrow: 0 }}>
<Tooltip title="Open settings">
<IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
<Avatar alt="User" src="/static/images/avatar/2.jpg" />
</IconButton>
</Tooltip>
<Menu
sx={{ mt: "45px" }}
anchorEl={anchorElUser}
open={Boolean(anchorElUser)}
onClose={handleCloseUserMenu}
anchorOrigin={{ vertical: "top", horizontal: "right" }}
transformOrigin={{ vertical: "top", horizontal: "right" }}
>
{settings.map((setting) => (
<MenuItem key={setting} onClick={handleCloseUserMenu}>
<Typography textAlign="center">{setting}</Typography>
</MenuItem>
))}
</Menu>
</Box>
</Toolbar>
</Container>
</AppBar>
{/* Drawer */}
<SwipeableDrawer
anchor="left"
open={drawerOpen}
onClose={toggleDrawer(false)}
onOpen={toggleDrawer(true)}
>
{DrawerList}
</SwipeableDrawer>
</>
);
};
export default LandingHeader;

View File

@ -0,0 +1,341 @@
import { useState, useEffect } from 'react';
import { motion } from 'framer-motion';
import { Users, Shield, Lock, Download, Smartphone, QrCode } from 'lucide-react';
const AppPromoteSection = () => {
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
setIsVisible(true);
}, []);
const fadeInUp = {
hidden: { opacity: 0, y: 60 },
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.6, ease: "easeOut" }
}
};
const staggerContainer = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.2
}
}
};
const scaleIn = {
hidden: { opacity: 0, scale: 0.8 },
visible: {
opacity: 1,
scale: 1,
transition: { duration: 0.5 }
}
};
const features = [
{
icon: <Users className="w-8 h-8 text-pink-500" />,
title: "100% Screened Profiles",
description: "Search by location, community, profession & more from lakhs of active profiles",
color: "bg-pink-50 dark:bg-pink-900/20"
},
{
icon: <Shield className="w-8 h-8 text-blue-500" />,
title: "Verifications by Personal Visit",
description: "Special listing for profiles verified by our agents through personal visits",
color: "bg-blue-50 dark:bg-blue-900/20"
},
{
icon: <Lock className="w-8 h-8 text-purple-500" />,
title: "Control over Privacy",
description: "Restrict unwanted access to contact details & photos/videos",
color: "bg-purple-50 dark:bg-purple-900/20"
}
];
return (
<>
<div className="min-h-screen bg-gradient-to-br from-gray-50 to-pink-50 dark:from-gray-900 dark:to-pink-900/20">
{/* Hero Section */}
<section className="relative min-h-screen flex items-center justify-center overflow-hidden">
{/* Background Image with Overlay */}
<div
className="absolute inset-0 z-0"
style={{
backgroundImage: 'url(https://images.unsplash.com/photo-1519741497674-611481863552?w=1200)',
backgroundSize: 'cover',
backgroundPosition: 'center',
}}
>
<div className="absolute inset-0 bg-gradient-to-r from-black/70 to-black/50"></div>
</div>
{/* Content */}
<div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20">
<motion.div
initial="hidden"
animate={isVisible ? "visible" : "hidden"}
variants={fadeInUp}
className="text-center"
>
<motion.p
variants={fadeInUp}
className="text-pink-300 text-sm font-medium tracking-wider uppercase mb-4"
>
MORE THAN 25 YEARS OF
</motion.p>
<motion.h1
variants={fadeInUp}
className="text-5xl md:text-7xl font-bold text-white mb-8"
>
Bringing People <span className="text-pink-400">Together</span>
</motion.h1>
</motion.div>
{/* Features Grid */}
<motion.div
variants={staggerContainer}
initial="hidden"
animate={isVisible ? "visible" : "hidden"}
className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-16 max-w-6xl mx-auto"
>
{features.map((feature, index) => (
<motion.div
key={index}
variants={scaleIn}
whileHover={{ scale: 1.05, y: -5 }}
className="bg-white dark:bg-gray-800 rounded-2xl p-8 shadow-xl hover:shadow-2xl transition-all duration-300"
>
<motion.div
className={`${feature.color} w-16 h-16 rounded-full flex items-center justify-center mb-6`}
whileHover={{ rotate: 360 }}
transition={{ duration: 0.6 }}
>
{feature.icon}
</motion.div>
<h3 className="text-xl font-bold text-gray-900 dark:text-white mb-3">
{feature.title}
</h3>
<p className="text-gray-600 dark:text-gray-300 leading-relaxed">
{feature.description}
</p>
</motion.div>
))}
</motion.div>
</div>
</section>
{/* App Download Section */}
<section className="relative py-20 bg-gradient-to-br from-pink-50 to-rose-100 dark:from-pink-900/10 dark:to-rose-900/20">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
{/* Left Content */}
<motion.div
initial={{ opacity: 0, x: -50 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6 }}
>
<h2 className="text-4xl md:text-5xl font-bold text-gray-900 dark:text-white mb-4">
Download the Jeevansathi app
</h2>
<p className="text-xl text-gray-600 dark:text-gray-300 mb-8">
Connect with your matches anytime, anywhere
</p>
<div className="bg-white dark:bg-gray-800 rounded-2xl p-8 shadow-xl">
<p className="text-center text-gray-700 dark:text-gray-300 mb-6 font-medium">
Point your phone camera at the QR code or use<br />one of the download links below
</p>
{/* QR Code */}
<div className="flex justify-center mb-6">
<motion.div
className="bg-white p-4 rounded-xl shadow-lg"
whileHover={{ scale: 1.05 }}
>
<div className="w-32 h-32 bg-gray-900 rounded-lg flex items-center justify-center">
<QrCode className="w-24 h-24 text-white" />
</div>
</motion.div>
</div>
{/* Download Buttons */}
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
className="bg-black text-white px-6 py-3 rounded-lg flex items-center justify-center space-x-2 hover:bg-gray-800 transition-colors"
>
<Smartphone className="w-5 h-5" />
<div className="text-left">
<div className="text-xs">GET IT ON</div>
<div className="font-bold">Google Play</div>
</div>
</motion.button>
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
className="bg-black text-white px-6 py-3 rounded-lg flex items-center justify-center space-x-2 hover:bg-gray-800 transition-colors"
>
<Download className="w-5 h-5" />
<div className="text-left">
<div className="text-xs">Download on the</div>
<div className="font-bold">App Store</div>
</div>
</motion.button>
</div>
<p className="text-center mt-6">
<span className="text-pink-600 dark:text-pink-400 font-medium">
Or get a download link
</span>
<span className="text-gray-600 dark:text-gray-400"> on your SMS/Email</span>
</p>
</div>
</motion.div>
{/* Right - Phone Mockup */}
<motion.div
initial={{ opacity: 0, x: 50 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6 }}
className="relative"
>
<div className="relative">
{/* Phone Frame */}
<motion.div
className="relative mx-auto w-full max-w-sm"
animate={{ y: [0, -10, 0] }}
transition={{ duration: 3, repeat: Infinity, ease: "easeInOut" }}
>
<div className="bg-gray-900 rounded-[3rem] p-4 shadow-2xl">
<div className="bg-white dark:bg-gray-800 rounded-[2.5rem] overflow-hidden">
{/* Phone Screen Content */}
<div className="aspect-[9/19] bg-gradient-to-br from-pink-100 to-purple-100 dark:from-pink-900/20 dark:to-purple-900/20 p-6">
<div className="flex items-center justify-between mb-6">
<h3 className="font-bold text-gray-900 dark:text-white">My Matches</h3>
<div className="flex space-x-2">
<div className="w-8 h-8 rounded-full bg-pink-400"></div>
</div>
</div>
{/* Profile Cards */}
<div className="space-y-4">
{[1, 2].map((i) => (
<motion.div
key={i}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: i * 0.2 }}
className="bg-white dark:bg-gray-700 rounded-2xl p-4 shadow-lg"
>
<div className="flex items-center space-x-3 mb-3">
<div className="w-16 h-16 rounded-full bg-gradient-to-br from-pink-400 to-purple-500"></div>
<div className="flex-1">
<h4 className="font-semibold text-gray-900 dark:text-white">Profile Name</h4>
<p className="text-sm text-gray-600 dark:text-gray-400">25 yrs, 5'6"</p>
</div>
</div>
<div className="flex space-x-2">
<button className="flex-1 bg-pink-500 text-white py-2 rounded-lg text-sm font-medium">
Connect
</button>
<button className="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg">
<span className="text-xl">💬</span>
</button>
</div>
</motion.div>
))}
</div>
{/* Features Tags */}
<div className="mt-6 space-y-2">
<motion.div
className="bg-white dark:bg-gray-700 rounded-full px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 inline-block"
animate={{ x: [0, 5, 0] }}
transition={{ duration: 2, repeat: Infinity }}
>
Easy Verification
</motion.div>
<motion.div
className="bg-white dark:bg-gray-700 rounded-full px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 inline-block ml-2"
animate={{ x: [0, -5, 0] }}
transition={{ duration: 2, repeat: Infinity, delay: 0.3 }}
>
Voice & Video Calls
</motion.div>
</div>
</div>
</div>
</div>
</motion.div>
{/* Download Badge */}
<motion.div
className="absolute -bottom-4 -right-4 bg-white dark:bg-gray-800 rounded-2xl px-6 py-3 shadow-xl"
initial={{ opacity: 0, scale: 0 }}
whileInView={{ opacity: 1, scale: 1 }}
viewport={{ once: true }}
transition={{ delay: 0.5 }}
>
<p className="text-sm text-gray-600 dark:text-gray-400">10M+ downloads</p>
</motion.div>
</div>
</motion.div>
</div>
</div>
</section>
{/* Stats Section */}
<motion.section
className="py-16 bg-white dark:bg-gray-900"
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
viewport={{ once: true }}
>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-2 md:grid-cols-4 gap-8">
{[
{ number: "25+", label: "Years of Trust" },
{ number: "10M+", label: "Happy Users" },
{ number: "100%", label: "Verified Profiles" },
{ number: "24/7", label: "Support" }
].map((stat, index) => (
<motion.div
key={index}
className="text-center"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: index * 0.1 }}
>
<motion.h3
className="text-4xl md:text-5xl font-bold text-pink-500 mb-2"
whileHover={{ scale: 1.1 }}
>
{stat.number}
</motion.h3>
<p className="text-gray-600 dark:text-gray-400 font-medium">{stat.label}</p>
</motion.div>
))}
</div>
</div>
</motion.section>
</div>
</>
)
}
export default AppPromoteSection

View File

@ -0,0 +1,98 @@
import Button from "@mui/material/Button";
import { motion } from "framer-motion";
import React from "react";
const ThreeDMarquee = ({ images = [], className = "", cols = 4, onImageClick }) => {
// Clone the image list twice
const duplicatedImages = [...images, ...images];
const groupSize = Math.ceil(duplicatedImages.length / cols);
const imageGroups = Array.from({ length: cols }, (_, index) =>
duplicatedImages.slice(index * groupSize, (index + 1) * groupSize)
);
const handleImageClick = (image, globalIndex) => {
if (onImageClick) {
onImageClick(image, globalIndex);
} else if (image.href) {
window.open(image.href, image.target || "_self");
}
};
return (
<section
className={`mx-auto block h-[600px] max-sm:h-[400px]
overflow-hidden bg-[#034E08] relative ${className} max-w-[1400px] ` }
style={{background: "linear-gradient(rgba(255, 255, 255, 0) 0%, rgba(2, 77, 14, 1) 70%)"}}
>
<div className="absolute bottom-0 left-0 w-full h-[300px] " style={{background: "linear-gradient(rgba(255, 255, 255, 0) 0%, rgb(255, 255, 255) 70%)"}} />
<div className="absolute top-0 left-0 w-full h-[200px] " style={{background: "linear-gradient(rgba(255, 255, 255, 0.88) 10%, rgba(255, 255, 255, 0) 70% )"}} />
<div className="text-white rounded-[0px] md:rounded-[10px] p-[20px] absolute md:top-[40%] md:left-[30%] w-full md:max-w-[600px] h-[100%] md:h-[230px] z-9 backdrop-blur-[5px] bg-black/50">
<h2 className="text-center text-[45px] font-900 pb-2">Now, chat for free !</h2>
<p className="text-center text-[22px] font-900 pb-4">Finding your perfect match just become easier</p>
<div className="flex itemes-center justify-center ">
<Button variant="contained" size="medium" sx={{width:"fit-content", padding:"10px 20px"}}>Regsiter Now</Button>
</div>
</div>
<div
className="flex w-full h-full items-center justify-center"
style={{
transform: "rotateX(55deg) rotateY(0deg) rotateZ(45deg)",
}}
>
<div className="w-full overflow-hidden scale-90 sm:scale-100">
<div
className={`relative grid h-full w-full origin-center
grid-cols-4 sm:grid-cols-${cols} gap-4 transform
`}
>
{imageGroups.map((imagesInGroup, idx) => (
<motion.div
key={`column-${idx}`}
animate={{ y: idx % 2 === 0 ? 100 : -100 }}
transition={{
// duration: idx % 2 === 0 ? 20 : 15,
duration: idx % 2 === 0 ? 5 : 4,
ease: "linear",
repeat: Infinity,
repeatType: "reverse",
}}
className="flex flex-col items-center gap-6 relative"
>
<div className="absolute left-0 top-0 h-full w-0.5 " />
{imagesInGroup.map((image, imgIdx) => {
const globalIndex = idx * groupSize + imgIdx;
const isClickable = image.href || onImageClick;
return (
<div key={`img-${imgIdx}`} className="relative">
<div className="absolute top-0 left-0 w-full h-0.5 " />
<div className="max-w-[300px] h-[290px] rounded-lg overflow-hidden bg-white">
<motion.img
whileHover={{ y: -10 }}
transition={{ duration: 0.3, ease: "easeInOut" }}
src={image.src}
alt={image.alt}
width={970}
height={700}
className={`aspect-[970/700] w-full h-full object-cover shadow-xl hover:shadow-2xl transition-shadow duration-300 ${
isClickable ? "cursor-pointer" : ""
}`}
onClick={() => handleImageClick(image, globalIndex)}
/>
</div>
</div>
);
})}
</motion.div>
))}
</div>
</div>
</div>
</section>
);
};
export default ThreeDMarquee;

View File

@ -1,71 +1,3 @@
@import "tailwindcss"; @import "tailwindcss";
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

View File

@ -0,0 +1,14 @@
import { Outlet } from "react-router-dom";
import LandingHeader from "../components/common/LandingHeader";
const LandingLayout = () => {
return (
<>
<LandingHeader/>
<div className="body-container" style={{ marginBottom:'90px' }}>
<Outlet />
</div>
</>
)
}
export default LandingLayout

View File

@ -1,10 +1,14 @@
import { StrictMode } from 'react' import React from "react";
import { createRoot } from 'react-dom/client' import ReactDOM from "react-dom/client";
import './index.css'
import App from './App.jsx'
createRoot(document.getElementById('root')).render( import "./index.css";
<StrictMode> import App from "./App.jsx";
import { ThemeProvider } from "@mui/material/styles";
import theme from "./theme";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<ThemeProvider theme={theme}>
<App /> <App />
</StrictMode>, </ThemeProvider>
) </React.StrictMode>
);

72
src/pages/HomePage.jsx Normal file
View File

@ -0,0 +1,72 @@
import AppPromoteSection from "../components/landing/AppPromoteSection";
import ThreeDMarquee from "../components/ui/ThreeDMarquee";
import wedding1 from "../assets/images/wedding1.jpg";
import wedding2 from "../assets/images/wedding2.jpg";
import wedding3 from "../assets/images/wedding3.jpg";
import wedding4 from "../assets/images/wedding4.webp";
import wedding5 from "../assets/images/wedding5.webp";
import wedding6 from "../assets/images/wedding6.jpeg";
import wedding7 from "../assets/images/wedding7.jpg";
import wedding8 from "../assets/images/wedding8.jpg";
import wedding9 from "../assets/images/wedding9.avif";
import wedding10 from "../assets/images/wedding10.jpg";
import wedding11 from "../assets/images/wedding11.jpg";
import wedding12 from "../assets/images/wedding12.avif";
const HomePage = () => {
const images = [
{
src: wedding1,
alt: "Wedding Image",
},
{
src: wedding2,
alt: "Couple",
},
{
src:wedding3,
alt: "Engagement",
},
{
src: wedding4,
alt: "Wedding Image",
},
{
src: wedding5,
alt: "Couple",
},
{
src: wedding6,
alt: "Engagement",
},
{
src: wedding7,
alt: "Wedding Image",
},
{
src: wedding8,
alt: "Couple",
},
{
src: wedding9,
alt: "Engagement",
},
{
src: wedding10,
alt: "Engagement",
},
];
return (
<div className="">
<ThreeDMarquee images={images} cols = {4} />
<AppPromoteSection/>
</div>
);
};
export default HomePage;

10
src/pages/LandingPage.jsx Normal file
View File

@ -0,0 +1,10 @@
const LandingPage = () => {
return (
<>
</>
)
}
export default LandingPage

19
src/routes/AppRoutes.jsx Normal file
View File

@ -0,0 +1,19 @@
import { Route, Routes } from 'react-router-dom';
import UserRoutes from './UserRoutes';
import PublicRoutes from './PublicRoutes';
const AppRoutes = () => {
return (
<>
{/* Wrap UserRoutes inside AuthProvider separately */}
<Routes>
{UserRoutes()}
{PublicRoutes()}
</Routes>
</>
);
};
export default AppRoutes;

View File

@ -0,0 +1,15 @@
import { Route } from "react-router-dom";
import HomePage from "../pages/HomePage";
import LandingLayout from "../layout/LandingLayout";
const PublicRoutes = () => {
return (
<>
<Route element={<LandingLayout />}>
<Route path="/" element={<HomePage />} />
</Route>
</>
)
}
export default PublicRoutes

13
src/routes/UserRoutes.jsx Normal file
View File

@ -0,0 +1,13 @@
import { Route, useNavigate } from "react-router-dom";
const UserRoutes = () => {
return (
<>
{/* <Route element={<MasterLayout />}>
<Route path="/" element={<HomePage />} />
</Route> */}
</>
)
}
export default UserRoutes

17
src/theme.js Normal file
View File

@ -0,0 +1,17 @@
import { createTheme, ThemeProvider } from "@mui/material/styles";
const theme = createTheme({
palette: {
primary: {
main: "#034E08", // Indigo
contrastText: "#ffffff",
},
secondary: {
main: "#A70710", // Pink
contrastText: "#ffffff",
},
},
});
export default theme;

View File

@ -1,7 +1,13 @@
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react' import react from '@vitejs/plugin-react'
import path from "path"
import tailwindcss from '@tailwindcss/vite' import tailwindcss from '@tailwindcss/vite'
// https://vite.dev/config/ // https://vite.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react(), tailwindcss(),], plugins: [react(), tailwindcss(),],
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
},
},
}) })