Compare commits

..

No commits in common. "main" and "feature/new_segment" have entirely different histories.

76 changed files with 18081 additions and 14598 deletions

View File

@ -58,6 +58,5 @@
"devDependencies": { "devDependencies": {
"@types/react-icons": "^2.2.7", "@types/react-icons": "^2.2.7",
"@types/react-slick": "^0.23.13" "@types/react-slick": "^0.23.13"
}, }
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1017 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 671 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 536 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 716 B

View File

@ -1,206 +1,41 @@
import { Box, Typography, Button } from "@mui/material"; import { Box, Typography, Button } from "@mui/material";
import ArrowOutwardIcon from "@mui/icons-material/ArrowOutward"; import ArrowOutwardIcon from "@mui/icons-material/ArrowOutward";
import { motion, Variants, Transition } from "framer-motion";
const AboutUs = () => { const AboutUs = () => {
// Type-safe animation variants
const containerVariants: Variants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.3,
duration: 0.8,
},
},
};
const itemVariants: Variants = {
hidden: { y: 30, opacity: 0 },
visible: {
y: 0,
opacity: 1,
transition: {
duration: 0.8,
ease: [0.16, 1, 0.3, 1], // Cubic bezier curve for easeOut
},
},
};
const titleVariants: Variants = {
...itemVariants,
hover: {
scale: 1.02,
transition: {
repeat: Infinity,
repeatType: "reverse",
duration: 1.5,
} as Transition,
},
};
const underlineVariants: Variants = {
hidden: { width: 0 },
visible: {
width: "80px",
transition: {
delay: 0.5,
duration: 0.8,
},
},
hover: {
width: "120px",
backgroundColor: "#00e1ff",
},
};
const buttonContainerVariants: Variants = {
...itemVariants,
hover: {
scale: 1.05,
transition: {
type: "spring",
stiffness: 400,
},
},
};
return ( return (
<Box <Box sx={{ backgroundColor: "#1d2733", color: "#fff", py: 10, px: 3 }}>
component={motion.div} <Box textAlign="center" maxWidth={800} mx="auto">
initial={{ opacity: 0 }} <Typography variant="h4" fontWeight="bold" gutterBottom>
whileInView={{ opacity: 1 }} About Us
viewport={{ once: true, margin: "-100px" }} </Typography>
sx={{ <Typography variant="body1" paragraph>
backgroundColor: "#1d2733", Lorem ipsum dolor sit amet consectetur. Nisl sed sed tortor eros. Enim
color: "#fff", hendrerit elit interdum malesuada sit dis est pharetra suspendisse. In
py: { xs: 8, md: 12 }, dolor venenatis ultricies aliquet lacinia. Faucibus commodo eu gravida
px: 3, auctor eu et sit ut. Sed praesent sed odio aliquam in fermentum. Sit
}} vitae morbi sodales sem velit eu tempus velit nunc. Turpis in in
> luctus et nulla purus nibh ut. Enim sed fermentum purus molestie
<Box parturient morbi nunc aliquet. Aliquam sed etiam turpis non lectus
component={motion.div} commodo cras leo gravida.
variants={containerVariants} </Typography>
initial="hidden" <Button
animate="visible" variant="outlined"
viewport={{ once: true }} endIcon={<ArrowOutwardIcon />}
sx={{ sx={{
textAlign: "center", mt: 2,
maxWidth: 800, borderColor: "#00FFD1",
mx: "auto", color: "#00FFD1",
}} borderRadius: "30px",
> fontWeight: "bold",
{/* Title Section */} px: 4,
<Box "&:hover": {
component={motion.div} backgroundColor: "#00FFD1",
variants={titleVariants} color: "#000",
whileHover="hover" },
sx={{ mb: 4 }} }}
> >
<Typography GET IN TOUCH
variant="h2" </Button>
sx={{
fontFamily: "'Cormorant Garamond', serif",
fontWeight: 600,
fontSize: { xs: "2.5rem", md: "3rem" },
letterSpacing: "1px",
position: "relative",
textShadow: "0 0 8px rgba(0, 225, 255, 0.3)",
}}
>
About Us
<Box
component={motion.div}
variants={underlineVariants}
initial="hidden"
animate="visible"
whileHover="hover"
sx={{
height: "3px",
background: "linear-gradient(90deg, #00e1ff, transparent)",
margin: "20px auto 0",
borderRadius: "2px",
}}
/>
</Typography>
</Box>
{/* Content Section */}
<Box component={motion.div} variants={itemVariants} sx={{ mb: 4 }}>
<Typography
paragraph
sx={{
fontFamily: "'Montserrat', sans-serif",
fontSize: { xs: "1rem", md: "1.1rem" },
lineHeight: 1.9,
fontWeight: 300,
color: "rgba(255,255,255,0.85)",
}}
>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ipsum
repellendus aperiam, nobis debitis nam nemo dolorum! Suscipit
voluptatibus eum tenetur accusantium eveniet iure, optio illum
minima, quo mollitia vitae dolorem.
</Typography>
</Box>
{/* Button Section */}
<Box
component={motion.div}
variants={buttonContainerVariants}
whileHover="hover"
>
<Button
variant="outlined"
endIcon={
<motion.div
animate={{ x: [0, 5, 0] }}
transition={{
duration: 1.5,
repeat: Infinity,
ease: "easeInOut",
}}
>
<ArrowOutwardIcon />
</motion.div>
}
sx={{
borderColor: "#00e1ff",
color: "#00e1ff",
borderRadius: "30px",
fontWeight: 500,
px: 3,
py: 1.1,
fontFamily: "'Montserrat', sans-serif",
letterSpacing: "1px",
fontSize: "0.9rem",
textTransform: "uppercase",
position: "relative",
overflow: "hidden",
"&:hover": {
backgroundColor: "rgba(0, 225, 255, 0.1)",
boxShadow: "0 0 15px rgba(0, 225, 255, 0.4)",
"&::before": {
transform: "translateX(0)",
},
},
"&::before": {
content: '""',
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%",
background:
"linear-gradient(90deg, transparent, rgba(0, 225, 255, 0.2), transparent)",
transform: "translateX(-100%)",
transition: "transform 0.6s ease",
},
}}
>
GET IN TOUCH
</Button>
</Box>
</Box> </Box>
</Box> </Box>
); );

View File

@ -1,294 +1,92 @@
import React from "react"; import React from 'react';
import { import {
Box, Box, Container, Grid, Typography, Link, Divider, Stack, useMediaQuery, useTheme
Container, } from '@mui/material';
Grid, import {
Typography, Instagram, YouTube, Facebook, LinkedIn
Link, } from '@mui/icons-material';
Divider, import { motion } from 'framer-motion';
Stack,
useMediaQuery,
useTheme,
} from "@mui/material";
import { Instagram, YouTube, Facebook, LinkedIn } from "@mui/icons-material";
import { motion, Variants } from "framer-motion";
export default function Footer() { export default function Footer() {
const theme = useTheme(); const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm")); const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
const isTablet = useMediaQuery(theme.breakpoints.between("sm", "md"));
// Animation variants
const containerVariants: Variants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
when: "beforeChildren",
},
},
};
const itemVariants: Variants = {
hidden: { y: 20, opacity: 0 },
visible: {
y: 0,
opacity: 1,
transition: {
duration: 0.5,
ease: "easeOut",
},
},
hover: {
scale: 1.05,
color: "#00E0FF",
transition: { duration: 0.2 },
},
};
const socialIconVariants: Variants = {
hidden: { scale: 0 },
visible: {
scale: 1,
transition: {
type: "spring",
stiffness: 500,
damping: 15,
},
},
hover: {
scale: 1.2,
transition: { duration: 0.2 },
},
};
return ( return (
<Box <Box sx={{ backgroundColor: '#0F111A', color: '#fff', pt: 6, pb: 2 }}>
component="footer"
sx={{
backgroundColor: "#0F111A",
color: "#fff",
pt: 8,
pb: 4,
overflow: "hidden",
}}
>
<Container maxWidth="lg"> <Container maxWidth="lg">
<motion.div <motion.div
initial="hidden" initial={{ opacity: 0, y: 10 }}
whileInView="visible" animate={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-50px" }} transition={{ duration: 0.8 }}
variants={containerVariants}
> >
<Grid container spacing={isMobile ? 3 : 4}> <Grid container spacing={4}>
{/* Column 1: Explore Links */} {/* Column 1: Explore Links */}
<Grid item xs={12} sm={6} md={3}> <Grid item xs={12} sm={6} md={3}>
<Typography
component={motion.div}
variants={itemVariants}
variant="h6"
fontWeight={600}
gutterBottom
sx={{ color: "#00E0FF" }}
>
Explore
</Typography>
<Stack spacing={1}> <Stack spacing={1}>
{["About Us", "Portfolio", "Blogs", "Services"].map((item) => ( <Link href="#" color="inherit" underline="hover">About Us</Link>
<Link <Link href="#" color="inherit" underline="hover">Portfolio</Link>
key={item} <Link href="#" color="inherit" underline="hover">Blogs</Link>
component={motion.a} <Link href="#" color="inherit" underline="hover">Services</Link>
variants={itemVariants}
whileHover="hover"
href="#"
color="inherit"
underline="hover"
sx={{
display: "inline-block",
transition: "color 0.2s ease",
}}
>
{item}
</Link>
))}
</Stack> </Stack>
</Grid> </Grid>
{/* Column 2: Support Links */} {/* Column 2: Support Links */}
<Grid item xs={12} sm={6} md={3}> <Grid item xs={12} sm={6} md={3}>
<Typography
component={motion.div}
variants={itemVariants}
variant="h6"
fontWeight={600}
gutterBottom
sx={{ color: "#00E0FF" }}
>
Support
</Typography>
<Stack spacing={1}> <Stack spacing={1}>
{["FAQs", "Terms & Conditions", "Privacy Policy"].map( <Link href="#" color="inherit" underline="hover">FAQs</Link>
(item) => ( <Link href="#" color="inherit" underline="hover">Terms & Conditions</Link>
<Link <Link href="#" color="inherit" underline="hover">Privacy Policy</Link>
key={item}
component={motion.a}
variants={itemVariants}
whileHover="hover"
href="#"
color="inherit"
underline="hover"
sx={{
display: "inline-block",
transition: "color 0.2s ease",
}}
>
{item}
</Link>
)
)}
</Stack> </Stack>
</Grid> </Grid>
{/* Column 3: Logo */} {/* Column 3: Logo (only visible on md+) */}
<Grid item xs={12} sm={6} md={3}> {!isMobile && (
<Box <Grid item xs={12} sm={6} md={3}>
component={motion.div} <Box sx={{ display: 'flex', justifyContent: { sm: 'center', md: 'flex-end' }, mb: 2 }}>
variants={itemVariants} <img
sx={{ src="/logo.png" // Replace with actual logo
display: "flex", alt="Quadra Edge"
justifyContent: isMobile style={{ maxWidth: '180px', height: 'auto' }}
? "flex-start" />
: isTablet </Box>
? "center" </Grid>
: "flex-end", )}
mb: 2,
height: "100%",
alignItems: isMobile ? "flex-start" : "center",
}}
>
<motion.img
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{
type: "spring",
stiffness: 300,
damping: 15,
delay: 0.2,
}}
src="/logo.png"
alt="Quadra Edge"
style={{
maxWidth: isMobile ? "140px" : "180px",
height: "auto",
filter: "drop-shadow(0 0 8px rgba(0, 224, 255, 0.4))",
}}
/>
</Box>
</Grid>
{/* Column 4: Contact Info + Socials */} {/* Column 4: Contact Info + Socials */}
<Grid item xs={12} sm={6} md={3}> <Grid item xs={12} sm={6} md={3}>
<Typography {/* Mobile: show logo here instead */}
component={motion.div} {isMobile && (
variants={itemVariants} <Box sx={{ display: 'flex', justifyContent: 'flex-end', mb: 2 }}>
variant="h6" <img
fontWeight={600} src="/logo.png" // Replace with actual logo
gutterBottom alt="Quadra Edge"
sx={{ color: "#00E0FF" }} style={{ maxWidth: '180px', height: 'auto' }}
> />
Contact Us </Box>
</Typography> )}
<Typography <Typography fontWeight={600} gutterBottom>Contact Us</Typography>
component={motion.div} <Typography variant="body2" mb={1}>Number</Typography>
variants={itemVariants} <Typography variant="body2">Address</Typography>
variant="body2"
mb={1}
>
+1 (123) 456-7890
</Typography>
<Typography
component={motion.div}
variants={itemVariants}
variant="body2"
>
123 Business Ave, Suite 100
<br />
New York, NY 10001
</Typography>
<Stack <Stack
direction="row" direction="row"
spacing={2} spacing={2}
sx={{ mt: 3 }} sx={{ mt: 2 }}
component={motion.div}
variants={containerVariants}
> >
{[ <Link href="#"><Instagram sx={{ color: '#00E0FF' }} /></Link>
{ icon: <Instagram />, name: "Instagram" }, <Link href="#"><YouTube sx={{ color: '#00E0FF' }} /></Link>
{ icon: <YouTube />, name: "YouTube" }, <Link href="#"><Facebook sx={{ color: '#00E0FF' }} /></Link>
{ icon: <Facebook />, name: "Facebook" }, <Link href="#"><LinkedIn sx={{ color: '#00E0FF' }} /></Link>
{ icon: <LinkedIn />, name: "LinkedIn" },
].map((social, index) => (
<Link
key={social.name}
component={motion.a}
variants={socialIconVariants}
whileHover="hover"
href="#"
sx={{
color: "#00E0FF",
display: "flex",
alignItems: "center",
}}
aria-label={social.name}
>
{React.cloneElement(social.icon, {
sx: {
fontSize: isMobile ? "1.8rem" : "2rem",
transition: "transform 0.2s ease",
},
})}
</Link>
))}
</Stack> </Stack>
</Grid> </Grid>
</Grid> </Grid>
<Divider <Divider sx={{ my: 4, borderColor: '#00E0FF' }} />
component={motion.hr}
initial={{ scaleX: 0 }}
whileInView={{ scaleX: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.8, delay: 0.2 }}
sx={{
my: 4,
borderColor: "#00E0FF",
borderBottomWidth: 2,
opacity: 0.6,
}}
/>
<Box <Box textAlign="center">
component={motion.div} <Typography variant="body2" sx={{ color: '#00E0FF' }}>
initial={{ opacity: 0 }} Copyright © 2025 QuadraEdge
whileInView={{ opacity: 1 }}
viewport={{ once: true }}
transition={{ delay: 0.4 }}
textAlign="center"
>
<Typography
variant="body2"
sx={{
color: "#00E0FF",
fontSize: isMobile ? "0.8rem" : "0.9rem",
letterSpacing: "0.5px",
}}
>
Copyright © {new Date().getFullYear()} QuadraEdge. All rights
reserved.
</Typography> </Typography>
</Box> </Box>
</motion.div> </motion.div>

View File

@ -2,9 +2,11 @@ import React, { useState } from "react";
import { import {
AppBar, AppBar,
Toolbar, Toolbar,
Typography,
IconButton, IconButton,
Drawer, Drawer,
List, List,
ListItem,
ListItemText, ListItemText,
Button, Button,
useMediaQuery, useMediaQuery,
@ -12,77 +14,49 @@ import {
Box, Box,
Container, Container,
ListItemButton, ListItemButton,
Divider,
} from "@mui/material"; } from "@mui/material";
import MenuIcon from "@mui/icons-material/Menu"; import MenuIcon from "@mui/icons-material/Menu";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import HomeIcon from "@mui/icons-material/Home";
import BuildIcon from "@mui/icons-material/Build";
import WorkIcon from "@mui/icons-material/Work";
import InfoIcon from "@mui/icons-material/Info";
import ArticleIcon from "@mui/icons-material/Article";
import logo from "../QE Website design/Logo.png";
const navItems = [ const navItems = ["Home", "Services", "Portfolio", "About Us", "Blog"];
{ label: "Home", icon: <HomeIcon />, href: "#" },
{ label: "Services", icon: <BuildIcon />, href: "#" },
{ label: "Portfolio", icon: <WorkIcon />, href: "#" },
{ label: "About Us", icon: <InfoIcon />, href: "#" },
{ label: "Blog", icon: <ArticleIcon />, href: "#" },
];
const Header = () => { const Header = () => {
const [mobileOpen, setMobileOpen] = useState(false); const [mobileOpen, setMobileOpen] = useState(false);
const theme = useTheme(); const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("md")); const isMobile = useMediaQuery(theme.breakpoints.down("md"));
const toggleDrawer = () => setMobileOpen(!mobileOpen); const toggleDrawer = () => {
setMobileOpen(!mobileOpen);
};
const drawer = ( const drawer = (
<Box <Box sx={{ width: 250, backgroundColor: "#000" }} onClick={toggleDrawer}>
sx={{ width: 260, height: "100%", backgroundColor: "#000" }} <List>
onClick={toggleDrawer}
>
<ListItemButton
component="a"
href="#"
sx={{ justifyContent: "center", my: 2 }}
>
<Box component="img" src={logo} alt="Logo" sx={{ height: 40 }} />
</ListItemButton>
<Divider sx={{ backgroundColor: "#444" }} />
<Box>
{navItems.map((item) => ( {navItems.map((item) => (
<ListItemButton component="a" href={item.href} key={item.label}> <ListItemButton component="a" href="#" key={item}>
<Box <ListItemText primary={item} sx={{ color: "#fff" }} />
sx={{ display: "flex", alignItems: "center", color: "#00E0FF" }}
>
<Box sx={{ mr: 2 }}>{item.icon}</Box>
<ListItemText primary={item.label} sx={{ color: "#fff" }} />
</Box>
</ListItemButton> </ListItemButton>
))} ))}
</Box> <ListItem disablePadding>
<Divider sx={{ backgroundColor: "#444", my: 2 }} /> <Button
<Box px={2}> variant="outlined"
<Button fullWidth
variant="outlined" sx={{
fullWidth borderColor: "#00E0FF",
sx={{ color: "#00E0FF",
borderColor: "#00E0FF", backgroundColor: "transparent",
color: "#00E0FF", borderRadius: "8px",
borderRadius: "24px", m: 2,
fontWeight: 600, "&:hover": {
textTransform: "none", backgroundColor: "#00E0FF",
"&:hover": { color: "#000",
backgroundColor: "#00E0FF", },
color: "#000", }}
}, >
}} Contact Us
> </Button>
Contact Us </ListItem>
</Button> </List>
</Box>
</Box> </Box>
); );
@ -92,10 +66,20 @@ const Header = () => {
sx={{ backgroundColor: "#000", boxShadow: "none" }} sx={{ backgroundColor: "#000", boxShadow: "none" }}
> >
<Container maxWidth="lg"> <Container maxWidth="lg">
<Toolbar sx={{ justifyContent: "space-between", py: 1.5 }}> <Toolbar sx={{ justifyContent: "space-between", padding: "16px 0" }}>
<motion.div
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
>
<Typography variant="h6" sx={{ fontWeight: 700, color: "#fff" }}>
QUADRA EDGE
</Typography>
</motion.div>
{isMobile ? ( {isMobile ? (
<> <>
<IconButton edge="end" onClick={toggleDrawer}> <IconButton color="inherit" edge="end" onClick={toggleDrawer}>
<MenuIcon sx={{ color: "#fff" }} /> <MenuIcon sx={{ color: "#fff" }} />
</IconButton> </IconButton>
<Drawer <Drawer
@ -108,78 +92,44 @@ const Header = () => {
</Drawer> </Drawer>
</> </>
) : ( ) : (
<Box <Box sx={{ display: "flex", gap: 4, alignItems: "center" }}>
sx={{ {navItems.map((item, index) => (
display: "flex", <motion.div
justifyContent: "space-between", key={item}
alignItems: "center", initial={{ opacity: 0, y: -5 }}
width: "100%", animate={{ opacity: 1, y: 0 }}
}} transition={{ delay: 0.1 * index }}
>
{/* Left - Logo */}
<motion.div
initial={{ opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6 }}
>
<Box
component="a"
href="#"
sx={{ display: "flex", alignItems: "center" }}
> >
<Box <Typography
component="img" variant="body1"
src={logo} component="a"
alt="Logo" href="#"
sx={{ height: 40, width: "auto", objectFit: "contain" }} sx={{
/> color: "#fff",
</Box> textDecoration: "none",
</motion.div> "&:hover": {
color: "#00E0FF",
{/* Center - Navigation */} },
<Box sx={{ display: "flex", gap: 4, alignItems: "center" }}> }}
{navItems.map((item, index) => (
<motion.div
key={item.label}
initial={{ opacity: 0, y: -5 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.1 * index }}
> >
<Box {item}
component="a" </Typography>
href={item.href} </motion.div>
sx={{ ))}
color: "#fff",
textDecoration: "none",
fontWeight: 500,
fontSize: "1rem",
"&:hover": {
color: "#00E0FF",
},
}}
>
{item.label}
</Box>
</motion.div>
))}
</Box>
{/* Right - Contact Us */}
<motion.div <motion.div
initial={{ opacity: 0, x: 10 }} initial={{ opacity: 0, y: -5 }}
animate={{ opacity: 1, x: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }} transition={{ delay: 0.5 }}
> >
<Button <Button
variant="outlined" variant="outlined"
sx={{ sx={{
borderColor: "#00E0FF", borderColor: "#00E0FF",
color: "#00E0FF", color: "#00E0FF",
borderRadius: "24px", backgroundColor: "transparent",
borderRadius: "8px",
textTransform: "none", textTransform: "none",
fontWeight: 600, padding: "8px 24px",
px: 3,
py: 1,
"&:hover": { "&:hover": {
backgroundColor: "#00E0FF", backgroundColor: "#00E0FF",
color: "#000", color: "#000",

View File

@ -1,101 +1,48 @@
import { Box, Button, Container, Grid, Typography } from "@mui/material"; import { Box, Button, Container, Grid, Typography } from "@mui/material";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import backgroundImg from "../hero/Frame 22.png"; import backgroundImg from "../hero/Frame 22.png";
export default function Hero() { export default function Hero() {
return ( return (
<Box sx={{ backgroundColor: "#0F111A", color: "#fff", py: 10 }}> <Box sx={{ backgroundColor: "#0F111A", color: "#fff", py: 10 }}>
<Container maxWidth="lg"> <Container maxWidth="lg">
<motion.div <motion.div
initial={{ opacity: 0, y: -30 }} initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ duration: 1 }} transition={{ duration: 0.8 }}
> >
<Grid container spacing={4} alignItems="center"> <Grid container>
<Grid item xs={12} md={6}> <Grid item md={6}>
<Box> <Typography variant="h3" fontWeight="bold" gutterBottom>
<Typography We Create <br />
variant="h2" Brands That Stick
fontWeight="bold" </Typography>
gutterBottom
sx={{
fontSize: { xs: "2rem", sm: "2.8rem", md: "3.4rem" },
lineHeight: 1.2,
}}
>
We Create <br />
Brands That Stick
</Typography>
{/* Sliding second line after 7s */}
<motion.div
initial={{ opacity: 0, x: 50 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 7, duration: 1 }}
>
<Typography
variant="h5"
sx={{
mt: 2,
fontWeight: 300,
color: "#00E0FF",
fontStyle: "italic",
}}
>
"Let your brand speak before you do."
</Typography>
</motion.div>
</Box>
</Grid> </Grid>
<Grid item md={6}>
<Grid item xs={12} md={6}> <Typography variant="body1" maxWidth="sm">
<motion.div We help founders grow through bold design, sharp strategy, and
initial={{ opacity: 0, y: 20 }} smart marketing that drives recognition, engagement and
animate={{ opacity: 1, y: 0 }} long-term brand loyalty.
transition={{ delay: 1, duration: 1 }} </Typography>
<Button
variant="outlined"
sx={{
mt: 4,
borderColor: "#00E0FF",
color: "#00E0FF",
"&:hover": {
backgroundColor: "#00E0FF",
color: "#000",
},
}}
> >
<Typography Get in Touch
variant="body1" </Button>
sx={{ maxWidth: "500px", fontSize: "1.1rem", color: "#ccc" }}
>
We help founders grow through bold design, sharp strategy, and
smart marketing that drives recognition, engagement and
long-term brand loyalty.
</Typography>
<Button
variant="outlined"
sx={{
mt: 4,
borderColor: "#00E0FF",
color: "#00E0FF",
borderRadius: "24px",
px: 4,
py: 1.5,
textTransform: "none",
fontWeight: 600,
"&:hover": {
backgroundColor: "#00E0FF",
color: "#000",
},
}}
>
Get in Touch
</Button>
</motion.div>
</Grid> </Grid>
</Grid> </Grid>
</motion.div> </motion.div>
</Container> </Container>
<Box width="100%">
<Box width="100%" mt={8}> <img src={backgroundImg} alt="" width={"100%"} />
<motion.img
src={backgroundImg}
alt="Hero Background"
width="100%"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 1.5, duration: 1 }}
/>
</Box> </Box>
</Box> </Box>
); );

View File

@ -6,213 +6,109 @@ import {
Grid, Grid,
Typography, Typography,
Button, Button,
Container,
useMediaQuery,
useTheme,
} from "@mui/material"; } from "@mui/material";
import { motion } from "framer-motion";
import portfolioImg from "../ourwork/Rectangle 6.png"; import portfolioImg from "../ourwork/Rectangle 6.png";
const works = [ const works = [
{ {
title: "Project Aurora", title: "Project Name",
image: portfolioImg, image: portfolioImg,
description: "Modern web design with seamless user experience",
}, },
{ {
title: "Project Nexus", title: "Project Name",
image: portfolioImg, image: portfolioImg,
description: "Mobile application development for enterprise",
}, },
{ {
title: "Project Horizon", title: "Project Name",
image: portfolioImg, image: portfolioImg,
description: "Brand identity and marketing campaign",
}, },
]; ];
const OurWorks = () => { const OurWorks = () => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
return ( return (
<Box <Box sx={{ backgroundColor: "#1d2733", color: "#fff", py: 8, px: 2 }}>
sx={{ <Typography variant="h4" align="center" fontWeight="bold" gutterBottom>
backgroundColor: "#1d2733", Our Works
color: "#fff", </Typography>
py: 8, <Typography variant="subtitle1" align="center" mb={6}>
px: { xs: 2, sm: 4 }, Weve helped brands grow through bold strategy and creative execution.
}} Explore our recent success stories.
> </Typography>
<Container maxWidth="md">
<motion.div
initial={{ opacity: 0, y: -20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
viewport={{ once: true }}
>
<Typography
variant="h4"
align="center"
fontWeight={700}
gutterBottom
sx={{
mb: 2,
fontFamily: "'Montserrat', sans-serif",
letterSpacing: 0.5,
}}
>
Our Portfolio
</Typography>
<Typography
variant="subtitle1"
align="center"
mb={6}
sx={{
maxWidth: 600,
mx: "auto",
color: "rgba(255,255,255,0.8)",
fontFamily: "'Open Sans', sans-serif",
}}
>
We craft digital experiences that drive results
</Typography>
</motion.div>
<Grid container spacing={isMobile ? 3 : 4} justifyContent="center"> <Grid container spacing={4} justifyContent="center">
{works.map((work, index) => ( {works.map((work, index) => (
<Grid item xs={12} sm={6} md={4} key={index}> <Grid item xs={12} sm={6} md={4} key={index}>
<motion.div <Card
initial={{ opacity: 0, y: 30 }} sx={{
whileInView={{ opacity: 1, y: 0 }} borderRadius: 3,
transition={{ duration: 0.5, delay: index * 0.1 }} overflow: "hidden",
viewport={{ once: true }} bgcolor: "#fff",
whileHover={{ y: -5 }} maxWidth: 320,
> margin: "0 auto",
<Card }}
elevation={3}
>
<CardContent>
<Typography
variant="subtitle1"
fontWeight="bold"
color="Black"
gutterBottom
>
{work.title}
</Typography>
</CardContent>
<CardMedia
component="img"
image={work.image}
alt={work.title}
sx={{
objectFit: "contain",
height: 250,
px: 2,
}}
/>
<CardContent>
<Button
variant="contained"
fullWidth
sx={{ sx={{
borderRadius: 2, backgroundColor: "#000",
overflow: "hidden", color: "#00FFD1",
bgcolor: "#fff", fontWeight: "bold",
maxWidth: 320,
height: "100%",
display: "flex",
flexDirection: "column",
boxShadow: "0 4px 12px rgba(0,0,0,0.08)",
transition: "all 0.3s ease",
"&:hover": { "&:hover": {
boxShadow: "0 8px 24px rgba(0,0,0,0.12)", backgroundColor: "#333",
}, },
borderRadius: "30px",
}} }}
> >
<Box VIEW DEMO
sx={{ </Button>
height: 180, </CardContent>
display: "flex", </Card>
alignItems: "center", </Grid>
justifyContent: "center", ))}
bgcolor: "#f8f9fa", </Grid>
overflow: "hidden",
}}
>
<CardMedia
component="img"
image={work.image}
alt={work.title}
sx={{
width: "90%",
height: "90%",
objectFit: "contain",
transition: "transform 0.3s ease",
"&:hover": {
transform: "scale(1.05)",
},
}}
/>
</Box>
<CardContent sx={{ flexGrow: 1, px: 3, py: 2 }}>
<Typography
variant="h6"
fontWeight={600}
color="#000"
gutterBottom
sx={{
fontFamily: "'Montserrat', sans-serif",
fontSize: "1.1rem",
}}
>
{work.title}
</Typography>
<Typography
variant="body2"
color="#000"
sx={{
mb: 2,
fontFamily: "'Open Sans', sans-serif",
fontSize: "0.875rem",
}}
>
{work.description}
</Typography>
</CardContent>
<CardContent sx={{ px: 3, py: 0, pb: 3 }}>
<Button
variant="outlined"
fullWidth
sx={{
borderRadius: "20px",
border: "1px solid #000",
color: "#000",
fontWeight: 600,
py: 1,
fontSize: "0.8rem",
textTransform: "none",
letterSpacing: 0.5,
fontFamily: "'Montserrat', sans-serif",
"&:hover": {
backgroundColor: "#000",
color: "#fff",
border: "1px solid #000",
},
transition: "all 0.3s ease",
}}
>
View Case Study
</Button>
</CardContent>
</Card>
</motion.div>
</Grid>
))}
</Grid>
<Box mt={6} display="flex" justifyContent="center"> <Box mt={6} display="flex" justifyContent="center">
<motion.div whileHover={{ scale: 1.03 }} whileTap={{ scale: 0.98 }}> <Button
<Button variant="outlined"
variant="outlined" sx={{
sx={{ borderRadius: "30px",
borderRadius: "20px", borderColor: "#00FFD1",
border: "1px solid #00E0FF", color: "#00FFD1",
color: "#00E0FF", px: 4,
px: 4, py: 1.5,
py: 1, fontWeight: "bold",
fontWeight: 600, "&:hover": {
fontSize: "0.9rem", backgroundColor: "#00FFD1",
textTransform: "none", color: "#000",
letterSpacing: 0.5, },
fontFamily: "'Montserrat', sans-serif", }}
"&:hover": { >
backgroundColor: "rgba(0, 225, 255, 0.19)", VIEW FULL PORTFOLIO
border: "1px solid #00e1ff", </Button>
}, </Box>
transition: "all 0.3s ease",
}}
>
Explore Full Portfolio
</Button>
</motion.div>
</Box>
</Container>
</Box> </Box>
); );
}; };

View File

@ -7,7 +7,6 @@ import {
Container, Container,
useMediaQuery, useMediaQuery,
useTheme, useTheme,
Grid,
} from "@mui/material"; } from "@mui/material";
import { motion, AnimatePresence, PanInfo } from "framer-motion"; import { motion, AnimatePresence, PanInfo } from "framer-motion";
import { useState } from "react"; import { useState } from "react";
@ -36,17 +35,18 @@ const services = [
const Services = () => { const Services = () => {
const theme = useTheme(); const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("md")); const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [currentIndex, setCurrentIndex] = useState(0); const [currentIndex, setCurrentIndex] = useState(0);
const [hoveredCard, setHoveredCard] = useState<number | null>(null);
const handleDragEnd = ( const handleDragEnd = (
event: MouseEvent | TouchEvent | PointerEvent, event: MouseEvent | TouchEvent | PointerEvent,
info: PanInfo info: PanInfo
) => { ) => {
if (info.offset.x > 50) { if (info.offset.x > 50) {
// Swiped right
setCurrentIndex((prev) => (prev === 0 ? services.length - 1 : prev - 1)); setCurrentIndex((prev) => (prev === 0 ? services.length - 1 : prev - 1));
} else if (info.offset.x < -50) { } else if (info.offset.x < -50) {
// Swiped left
setCurrentIndex((prev) => (prev === services.length - 1 ? 0 : prev + 1)); setCurrentIndex((prev) => (prev === services.length - 1 ? 0 : prev + 1));
} }
}; };
@ -58,29 +58,23 @@ const Services = () => {
initial={{ opacity: 0, y: -20 }} initial={{ opacity: 0, y: -20 }}
whileInView={{ opacity: 1, y: 0 }} whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }} transition={{ duration: 0.6 }}
viewport={{ once: true, margin: "-100px" }} viewport={{ once: true }}
> >
<Typography <Typography
variant="h4" variant="h4"
align="center" align="center"
fontWeight="bold" fontWeight="bold"
gutterBottom gutterBottom
sx={{ mb: 2 }}
> >
Our Services Services
</Typography> </Typography>
<Typography <Typography variant="subtitle1" align="center" mb={6}>
variant="subtitle1" We offer design, development & marketing services
align="center"
mb={6}
sx={{ maxWidth: 600, mx: "auto" }}
>
Professional solutions tailored to your needs
</Typography> </Typography>
</motion.div> </motion.div>
{isMobile ? ( {isMobile ? (
<Box sx={{ position: "relative", height: 380 }}> <Box sx={{ position: "relative", height: 400, overflow: "hidden" }}>
<AnimatePresence initial={false}> <AnimatePresence initial={false}>
<motion.div <motion.div
key={currentIndex} key={currentIndex}
@ -97,216 +91,144 @@ const Services = () => {
padding: "0 16px", padding: "0 16px",
}} }}
> >
<motion.div <Card
whileHover={{ scale: 1.02 }} sx={{
whileTap={{ scale: 0.98 }} borderRadius: 5,
overflow: "hidden",
height: "100%",
bgcolor: "#fff",
display: "flex",
flexDirection: "column",
maxWidth: 345,
mx: "auto",
}}
elevation={3}
> >
<Card <Box
sx={{ sx={{
borderRadius: 2, height: 200,
overflow: "hidden",
height: "100%",
bgcolor: "#fff",
display: "flex", display: "flex",
flexDirection: "column", alignItems: "center",
maxWidth: 300, justifyContent: "center",
mx: "auto", overflow: "hidden",
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.1)",
}} }}
> >
<Box <CardMedia
component="img"
image={services[currentIndex].image}
alt={services[currentIndex].title}
sx={{ sx={{
objectFit: "contain",
width: "100%", width: "100%",
height: 150, height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
bgcolor: "#f8f9fa",
overflow: "hidden",
}} }}
/>
</Box>
<CardContent sx={{ flexGrow: 1 }}>
<Typography
variant="h6"
fontWeight="bold"
gutterBottom
color="black"
> >
<motion.div {services[currentIndex].title}
animate={{ </Typography>
scale: hoveredCard === currentIndex ? 1.05 : 1, <Typography variant="body2" color="black">
y: hoveredCard === currentIndex ? -5 : 0, {services[currentIndex].description}
}} </Typography>
transition={{ duration: 0.3 }} </CardContent>
style={{ width: "100%" }} </Card>
>
<CardMedia
component="img"
image={services[currentIndex].image}
alt={services[currentIndex].title}
sx={{
width: "100%",
height: "auto",
objectFit: "cover",
}}
/>
</motion.div>
</Box>
<CardContent sx={{ flexGrow: 1 }}>
<Typography
variant="h6"
fontWeight="bold"
gutterBottom
color="#000"
>
{services[currentIndex].title}
</Typography>
<Typography variant="body2" color="#000" sx={{ mb: 2 }}>
{services[currentIndex].description}
</Typography>
<motion.div
whileHover={{ x: 5 }}
transition={{ type: "spring", stiffness: 300 }}
>
<Typography
variant="caption"
color="primary"
fontWeight="bold"
sx={{ cursor: "pointer" }}
>
Learn more
</Typography>
</motion.div>
</CardContent>
</Card>
</motion.div>
</motion.div> </motion.div>
</AnimatePresence> </AnimatePresence>
{/* Dots indicator */}
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
justifyContent: "center", justifyContent: "center",
mt: 3, mt: 2,
gap: 1.5, gap: 1,
}} }}
> >
{services.map((_, index) => ( {services.map((_, index) => (
<motion.div <Box
key={index} key={index}
onClick={() => setCurrentIndex(index)} onClick={() => setCurrentIndex(index)}
whileHover={{ scale: 1.2 }} sx={{
whileTap={{ scale: 0.9 }} width: 10,
> height: 10,
<Box borderRadius: "50%",
sx={{ bgcolor: index === currentIndex ? "#00E0FF" : "#ffffff80",
width: 10, cursor: "pointer",
height: 10, }}
borderRadius: "50%", />
bgcolor: index === currentIndex ? "#00E0FF" : "#ffffff80",
cursor: "pointer",
}}
/>
</motion.div>
))} ))}
</Box> </Box>
</Box> </Box>
) : ( ) : (
<Grid container spacing={3} justifyContent="center"> <Box
sx={{
display: "grid",
gridTemplateColumns: "repeat(auto-fit, minmax(300px, 1fr))",
gap: 4,
}}
>
{services.map((service, index) => ( {services.map((service, index) => (
<Grid <motion.div
item
xs={12}
sm={6}
md={4}
key={index} key={index}
sx={{ display: "flex", justifyContent: "center" }} whileHover={{ y: -5 }}
transition={{ duration: 0.3 }}
> >
<motion.div <Card
initial={{ opacity: 0, y: 50 }} sx={{
whileInView={{ opacity: 1, y: 0 }} borderRadius: 5,
transition={{ duration: 0.5, delay: index * 0.1 }} overflow: "hidden",
viewport={{ once: true, margin: "-100px" }} height: "100%",
onHoverStart={() => setHoveredCard(index)} bgcolor: "#fff",
onHoverEnd={() => setHoveredCard(null)} display: "flex",
style={{ width: "100%", maxWidth: 280 }} flexDirection: "column",
}}
elevation={3}
> >
<motion.div <Box
whileHover={{ sx={{
y: -8, height: 200,
boxShadow: "0 15px 30px -5px rgba(0, 0, 0, 0.2)", display: "flex",
alignItems: "center",
justifyContent: "center",
overflow: "hidden",
}} }}
transition={{ type: "spring", stiffness: 400, damping: 10 }}
style={{ height: "100%" }}
> >
<Card <motion.div whileHover={{ scale: 1.05 }}>
sx={{ <CardMedia
borderRadius: 2, component="img"
overflow: "hidden", image={service.image}
height: "100%", alt={service.title}
bgcolor: "#fff",
display: "flex",
flexDirection: "column",
boxShadow: "0 5px 15px rgba(0, 0, 0, 0.1)",
width: "100%",
}}
>
<Box
sx={{ sx={{
objectFit: "contain",
width: "100%", width: "100%",
height: 160, height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
bgcolor: "#f8f9fa",
overflow: "hidden",
}} }}
> />
<motion.div </motion.div>
animate={{ </Box>
scale: hoveredCard === index ? 1.1 : 1, <CardContent sx={{ flexGrow: 1 }}>
y: hoveredCard === index ? -5 : 0, <Typography
}} variant="h6"
transition={{ duration: 0.3 }} fontWeight="bold"
style={{ width: "100%" }} gutterBottom
> color="black"
<CardMedia >
component="img" {service.title}
image={service.image} </Typography>
alt={service.title} <Typography variant="body2" color="black">
sx={{ {service.description}
width: "100%", </Typography>
height: "auto", </CardContent>
objectFit: "cover", </Card>
}} </motion.div>
/>
</motion.div>
</Box>
<CardContent sx={{ flexGrow: 1 }}>
<Typography
variant="h6"
fontWeight="bold"
gutterBottom
color="#000"
>
{service.title}
</Typography>
<Typography variant="body2" color="#000" sx={{ mb: 2 }}>
{service.description}
</Typography>
<motion.div
whileHover={{ x: 5 }}
transition={{ type: "spring", stiffness: 300 }}
>
<Typography
variant="caption"
color="primary"
fontWeight="bold"
sx={{ cursor: "pointer" }}
>
Learn more
</Typography>
</motion.div>
</CardContent>
</Card>
</motion.div>
</motion.div>
</Grid>
))} ))}
</Grid> </Box>
)} )}
</Container> </Container>
</Box> </Box>

View File

@ -3,348 +3,98 @@ import {
Box, Box,
Card, Card,
CardContent, CardContent,
Grid,
Typography, Typography,
IconButton,
} from "@mui/material"; } from "@mui/material";
import { motion, AnimatePresence, useAnimation, Variants } from "framer-motion";
import { useEffect, useState } from "react";
import { KeyboardArrowLeft, KeyboardArrowRight } from "@mui/icons-material";
import testimonialImg from "../testomonials/b7bef0298c881712fbc6437106d2aaef27c4fad8.jpg"; import testimonialImg from "../testomonials/b7bef0298c881712fbc6437106d2aaef27c4fad8.jpg";
const testimonials = [ const testimonials = [
{ {
name: "Sarah Johnson", name: "Name",
role: "Marketing Director", role: "Role",
company: "Tech Innovations Inc.", company: "Company Name & Logo",
feedback: "Working with this team transformed our digital presence.", feedback:
"Lorem ipsum dolor sit amet consectetur. Vitae dictum quam senectus posuere sit justo est turpis interdum. Ut vitae platea et adipiscing nisl.",
rating: 5, rating: 5,
}, },
{ {
name: "Michael Chen", name: "John Dae",
role: "Sr. Manager", role: "Sr Manager",
company: "Wells Fargo", company: "Wells Fargo",
feedback: "Exceptional service from start to finish.", feedback:
"Lorem ipsum dolor sit amet consectetur. Vitae dictum quam senectus posuere sit justo est turpis interdum. Ut vitae platea et adipiscing nisl.",
rating: 5, rating: 5,
}, },
{ {
name: "Emily Rodriguez", name: "Name",
role: "Product Owner", role: "Role",
company: "Nexus Enterprises", company: "Company Name & Logo",
feedback: "The team's technical expertise was outstanding.", feedback:
"Lorem ipsum dolor sit amet consectetur. Vitae dictum quam senectus posuere sit justo est turpis interdum. Ut vitae platea et adipiscing nisl.",
rating: 4, rating: 4,
}, },
]; ];
// Properly typed animation variants
const containerVariants: Variants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.2,
duration: 0.8,
},
},
};
const itemVariants: Variants = {
hidden: { y: 50, opacity: 0 },
visible: {
y: 0,
opacity: 1,
transition: {
duration: 0.6,
ease: "easeOut", // Using string literal instead of array
},
},
hover: {
y: -10,
transition: { duration: 0.3 },
},
};
const Testimonials = () => { const Testimonials = () => {
const [currentIndex, setCurrentIndex] = useState(0);
const [isMobile, setIsMobile] = useState(false);
const controls = useAnimation();
useEffect(() => {
const handleResize = () => {
setIsMobile(window.innerWidth < 600);
};
handleResize();
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
useEffect(() => {
if (!isMobile) return;
const timer = setInterval(() => {
handleNext();
}, 5000);
return () => clearInterval(timer);
}, [currentIndex, isMobile]);
const handleNext = () => {
controls
.start({
x: "-100%",
opacity: 0,
transition: { duration: 0.3 },
})
.then(() => {
setCurrentIndex((prev) => (prev + 1) % testimonials.length);
controls
.start({
x: "100%",
opacity: 0,
})
.then(() => {
controls.start({
x: 0,
opacity: 1,
transition: { duration: 0.5 },
});
});
});
};
const handlePrev = () => {
controls
.start({
x: "100%",
opacity: 0,
transition: { duration: 0.3 },
})
.then(() => {
setCurrentIndex(
(prev) => (prev - 1 + testimonials.length) % testimonials.length
);
controls
.start({
x: "-100%",
opacity: 0,
})
.then(() => {
controls.start({
x: 0,
opacity: 1,
transition: { duration: 0.5 },
});
});
});
};
return ( return (
<Box <Box sx={{ backgroundColor: "#1d2733", color: "#fff", py: 10, px: 3 }}>
sx={{ <Box textAlign="center" mb={6}>
backgroundColor: "#1d2733", <Typography variant="h4" fontWeight="bold" gutterBottom>
color: "#fff",
py: { xs: 6, md: 10 },
px: { xs: 2, md: 3 },
overflow: "hidden",
}}
>
{/* Header Section */}
<Box
component={motion.div}
initial="hidden"
animate="visible"
variants={containerVariants}
textAlign="center"
mb={{ xs: 4, md: 6 }}
sx={{ maxWidth: 800, mx: "auto" }}
>
<Typography variant="h3" fontWeight="bold" gutterBottom>
Testimonials Testimonials
</Typography> </Typography>
<Typography variant="subtitle1"> <Typography variant="subtitle1">
Don't just take our word for it Dont just take our word for it -- hear directly from our clients
</Typography> </Typography>
</Box> </Box>
{/* Mobile Carousel */} <Grid container spacing={4} justifyContent="center">
{isMobile ? ( {testimonials.map((t, idx) => (
<Box sx={{ position: "relative", height: 450 }}> <Grid item xs={12} sm={6} md={4} key={idx}>
<AnimatePresence> <Card
<Box
component={motion.div}
key={currentIndex}
animate={controls}
initial={{ x: 0, opacity: 1 }}
exit={{ x: 0, opacity: 0 }}
sx={{ sx={{
position: "absolute", borderRadius: 3,
width: "100%", maxWidth: 320,
display: "flex", margin: "0 auto",
justifyContent: "center", textAlign: "center",
py: 3,
}} }}
> >
<TestimonialCard testimonial={testimonials[currentIndex]} /> <Avatar
</Box> src={testimonialImg}
</AnimatePresence> alt={t.name}
sx={{ width: 100, height: 100, margin: "0 auto", mb: 2 }}
<NavigationArrows handlePrev={handlePrev} handleNext={handleNext} /> />
</Box> <CardContent>
) : ( <Typography variant="subtitle1" fontWeight="bold">
/* Desktop Grid */ {t.name} ,{" "}
<Box <span style={{ fontWeight: "normal" }}>{t.role}</span>
component={motion.div} </Typography>
initial="hidden" <Typography variant="body2" color="text.secondary" mb={1}>
animate="visible" {t.company}
variants={containerVariants} </Typography>
sx={{ <Typography variant="body2" color="text.secondary" mb={2}>
display: "flex", {t.feedback}
justifyContent: "center", </Typography>
flexWrap: "wrap", <Box>
gap: 4, {Array.from({ length: 5 }).map((_, i) => (
px: { md: 4 }, <span
}} key={i}
> style={{
{testimonials.map((t, idx) => ( color: i < t.rating ? "#00FFD1" : "#ccc",
<Box fontSize: "1.2rem",
key={idx} }}
component={motion.div} >
variants={itemVariants}
whileHover="hover" </span>
sx={{ ))}
width: { md: 350 }, </Box>
flex: { md: "1 1 300px" }, </CardContent>
}} </Card>
> </Grid>
<TestimonialCard testimonial={t} /> ))}
</Box> </Grid>
))}
</Box>
)}
</Box> </Box>
); );
}; };
// Extracted Card Component
const TestimonialCard = ({
testimonial,
}: {
testimonial: (typeof testimonials)[0];
}) => (
<Card
sx={{
borderRadius: 3,
width: "100%",
minHeight: 400,
textAlign: "center",
py: 3,
px: 2,
background: "linear-gradient(145deg, #1d2733, #232f3e)",
boxShadow: "0 8px 32px rgba(0, 0, 0, 0.2)",
border: "1px solid rgba(0, 225, 255, 0.1)",
transition: "all 0.3s ease",
"&:hover": {
boxShadow: "0 12px 40px rgba(0, 225, 255, 0.15)",
borderColor: "rgba(0, 225, 255, 0.3)",
transform: "translateY(-5px)",
},
}}
>
<Avatar
src={testimonialImg}
alt={testimonial.name}
sx={{
width: 80,
height: 80,
margin: "0 auto",
mb: 2,
border: "2px solid #00e1ff",
boxShadow: "0 0 15px rgba(0, 225, 255, 0.4)",
}}
/>
<CardContent>
<Typography variant="h6" fontWeight="bold" color="#00e1ff">
{testimonial.name}
</Typography>
<Typography variant="subtitle1" color="rgba(255,255,255,0.8)" mb={0.5}>
{testimonial.role}
</Typography>
<Typography variant="body2" color="rgba(255,255,255,0.6)" mb={2}>
{testimonial.company}
</Typography>
<Typography
variant="body1"
color="rgba(255,255,255,0.8)"
mb={3}
fontStyle="italic"
>
{testimonial.feedback}
</Typography>
<Box>
{Array.from({ length: 5 }).map((_, i) => (
<Box
component="span"
key={i}
sx={{
color:
i < testimonial.rating ? "#00e1ff" : "rgba(255,255,255,0.2)",
fontSize: "1.5rem",
mx: 0.5,
textShadow:
i < testimonial.rating
? "0 0 8px rgba(0, 225, 255, 0.5)"
: "none",
}}
>
</Box>
))}
</Box>
</CardContent>
</Card>
);
// Extracted Navigation Component
const NavigationArrows = ({
handlePrev,
handleNext,
}: {
handlePrev: () => void;
handleNext: () => void;
}) => (
<>
<IconButton
onClick={handlePrev}
sx={{
position: "absolute",
left: 10,
top: "50%",
transform: "translateY(-50%)",
color: "#00e1ff",
backgroundColor: "rgba(0, 225, 255, 0.1)",
"&:hover": {
backgroundColor: "rgba(0, 225, 255, 0.2)",
},
}}
>
<KeyboardArrowLeft fontSize="large" />
</IconButton>
<IconButton
onClick={handleNext}
sx={{
position: "absolute",
right: 10,
top: "50%",
transform: "translateY(-50%)",
color: "#00e1ff",
backgroundColor: "rgba(0, 225, 255, 0.1)",
"&:hover": {
backgroundColor: "rgba(0, 225, 255, 0.2)",
},
}}
>
<KeyboardArrowRight fontSize="large" />
</IconButton>
</>
);
export default Testimonials; export default Testimonials;

26118
yarn.lock

File diff suppressed because it is too large Load Diff