feat:added the privacy page with clean ui
This commit is contained in:
+11
-6
@@ -1,17 +1,19 @@
|
|||||||
import { Toaster } from "@/components/ui/toaster";
|
|
||||||
import { Toaster as Sonner } from "@/components/ui/sonner";
|
import { Toaster as Sonner } from "@/components/ui/sonner";
|
||||||
|
import { Toaster } from "@/components/ui/toaster";
|
||||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||||
import { BrowserRouter, Routes, Route, useLocation } from "react-router-dom";
|
|
||||||
import { ThemeProvider } from "@/contexts/ThemeContext";
|
import { ThemeProvider } from "@/contexts/ThemeContext";
|
||||||
import { AnimatePresence } from "framer-motion";
|
import { AnimatePresence } from "framer-motion";
|
||||||
import Index from "./pages/Index";
|
import { BrowserRouter, Route, Routes, useLocation } from "react-router-dom";
|
||||||
import Projects from "./pages/Projects";
|
import Footer from "./components/Footer";
|
||||||
import ProjectDetails from "./pages/ProjectDetails";
|
import Navbar from "./components/Navbar";
|
||||||
import Blog from "./pages/Blog";
|
import Blog from "./pages/Blog";
|
||||||
import BlogArticle from "./pages/BlogArticle";
|
import BlogArticle from "./pages/BlogArticle";
|
||||||
|
import Index from "./pages/Index";
|
||||||
import NotFound from "./pages/NotFound";
|
import NotFound from "./pages/NotFound";
|
||||||
|
import ProjectDetails from "./pages/ProjectDetails";
|
||||||
|
import Projects from "./pages/Projects";
|
||||||
import { QueryProvider } from "./provider/QueryProvider";
|
import { QueryProvider } from "./provider/QueryProvider";
|
||||||
|
import { PrivacyPolicy } from "./pages/PrivacyPolicy";
|
||||||
|
|
||||||
function AnimatedRoutes() {
|
function AnimatedRoutes() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -26,6 +28,7 @@ function AnimatedRoutes() {
|
|||||||
<Route path="/blog/:id" element={<BlogArticle />} />
|
<Route path="/blog/:id" element={<BlogArticle />} />
|
||||||
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
|
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
|
||||||
<Route path="*" element={<NotFound />} />
|
<Route path="*" element={<NotFound />} />
|
||||||
|
<Route path="/privacy" element={<PrivacyPolicy />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
);
|
);
|
||||||
@@ -38,7 +41,9 @@ const App = () => (
|
|||||||
<Toaster />
|
<Toaster />
|
||||||
<Sonner />
|
<Sonner />
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
|
<Navbar />
|
||||||
<AnimatedRoutes />
|
<AnimatedRoutes />
|
||||||
|
<Footer />
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
|||||||
@@ -1,15 +1,23 @@
|
|||||||
import { useRef, useEffect, useState } from 'react';
|
import { motion, useInView } from "framer-motion";
|
||||||
import { motion, useInView } from 'framer-motion';
|
import { Award, Rocket, Users, Zap } from "lucide-react";
|
||||||
import { Zap, Users, Rocket, Award } from 'lucide-react';
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
const stats = [
|
const stats = [
|
||||||
{ icon: Zap, value: 10, suffix: '+', label: 'Years Experience' },
|
{ icon: Zap, value: 10, suffix: "+", label: "Years Experience" },
|
||||||
{ icon: Rocket, value: 500, suffix: '+', label: 'Projects Completed' },
|
{ icon: Rocket, value: 500, suffix: "+", label: "Projects Completed" },
|
||||||
{ icon: Users, value: 200, suffix: '+', label: 'Happy Clients' },
|
{ icon: Users, value: 200, suffix: "+", label: "Happy Clients" },
|
||||||
{ icon: Award, value: 50, suffix: '+', label: 'Awards Won' },
|
{ icon: Award, value: 50, suffix: "+", label: "Awards Won" },
|
||||||
];
|
];
|
||||||
|
|
||||||
function AnimatedCounter({ value, suffix, isInView }: { value: number; suffix: string; isInView: boolean }) {
|
function AnimatedCounter({
|
||||||
|
value,
|
||||||
|
suffix,
|
||||||
|
isInView,
|
||||||
|
}: {
|
||||||
|
value: number;
|
||||||
|
suffix: string;
|
||||||
|
isInView: boolean;
|
||||||
|
}) {
|
||||||
const [count, setCount] = useState(0);
|
const [count, setCount] = useState(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -34,17 +42,22 @@ function AnimatedCounter({ value, suffix, isInView }: { value: number; suffix: s
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<span className="text-4xl md:text-5xl font-bold text-primary neon-text-glow">
|
<span className="text-4xl md:text-5xl font-bold text-primary neon-text-glow">
|
||||||
{count}{suffix}
|
{count}
|
||||||
|
{suffix}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AboutSection() {
|
export default function AboutSection() {
|
||||||
const ref = useRef<HTMLElement>(null);
|
const ref = useRef<HTMLElement>(null);
|
||||||
const isInView = useInView(ref, { once: true, margin: '-100px' });
|
const isInView = useInView(ref, { once: true, margin: "-100px" });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section id="about" ref={ref} className="py-24 relative overflow-hidden bg-secondary/30">
|
<section
|
||||||
|
id="about"
|
||||||
|
ref={ref}
|
||||||
|
className="py-24 relative overflow-hidden bg-secondary/30"
|
||||||
|
>
|
||||||
{/* Background decoration */}
|
{/* Background decoration */}
|
||||||
<div className="absolute inset-0">
|
<div className="absolute inset-0">
|
||||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[800px] h-[800px] bg-primary/5 rounded-full blur-[200px]" />
|
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[800px] h-[800px] bg-primary/5 rounded-full blur-[200px]" />
|
||||||
@@ -66,15 +79,15 @@ export default function AboutSection() {
|
|||||||
</h2>
|
</h2>
|
||||||
<div className="space-y-4 text-muted-foreground text-lg">
|
<div className="space-y-4 text-muted-foreground text-lg">
|
||||||
<p>
|
<p>
|
||||||
Founded with a passion for innovation, TechZaa is a leading technology
|
Founded with a passion for innovation, TechZaa is a leading
|
||||||
company dedicated to transforming businesses through cutting-edge
|
technology company dedicated to transforming businesses through
|
||||||
digital solutions.
|
cutting-edge digital solutions.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Our team of expert developers, designers, and strategists work
|
Our team of expert developers, designers, and strategists work
|
||||||
collaboratively to deliver exceptional results that exceed expectations.
|
collaboratively to deliver exceptional results that exceed
|
||||||
We believe in the power of technology to solve complex problems and
|
expectations. We believe in the power of technology to solve
|
||||||
create meaningful impact.
|
complex problems and create meaningful impact.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
From startups to enterprises, we've helped hundreds of clients
|
From startups to enterprises, we've helped hundreds of clients
|
||||||
@@ -85,14 +98,16 @@ export default function AboutSection() {
|
|||||||
|
|
||||||
{/* Values */}
|
{/* Values */}
|
||||||
<div className="mt-8 flex flex-wrap gap-3">
|
<div className="mt-8 flex flex-wrap gap-3">
|
||||||
{['Innovation', 'Quality', 'Integrity', 'Excellence'].map((value) => (
|
{["Innovation", "Quality", "Integrity", "Excellence"].map(
|
||||||
|
(value) => (
|
||||||
<span
|
<span
|
||||||
key={value}
|
key={value}
|
||||||
className="px-4 py-2 rounded-full glass border border-primary/30 text-sm font-medium hover:border-primary hover:neon-glow transition-all cursor-default"
|
className="px-4 py-2 rounded-full glass border border-primary/30 text-sm font-medium hover:border-primary hover:neon-glow transition-all cursor-default"
|
||||||
>
|
>
|
||||||
{value}
|
{value}
|
||||||
</span>
|
</span>
|
||||||
))}
|
),
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
@@ -110,7 +125,7 @@ export default function AboutSection() {
|
|||||||
animate={isInView ? { opacity: 1, y: 0 } : {}}
|
animate={isInView ? { opacity: 1, y: 0 } : {}}
|
||||||
transition={{ duration: 0.5, delay: 0.3 + index * 0.1 }}
|
transition={{ duration: 0.5, delay: 0.3 + index * 0.1 }}
|
||||||
whileHover={{ y: -5, scale: 1.02 }}
|
whileHover={{ y: -5, scale: 1.02 }}
|
||||||
className="p-6 rounded-2xl glass border border-border/50 hover:border-primary/50 transition-all text-center group"
|
className="p-6 rounded-2xl glass hover:border-primary/50 transition-all text-center group"
|
||||||
>
|
>
|
||||||
{/* Icon */}
|
{/* Icon */}
|
||||||
<div className="w-12 h-12 rounded-xl bg-primary/10 flex items-center justify-center mx-auto mb-4 group-hover:neon-glow transition-all">
|
<div className="w-12 h-12 rounded-xl bg-primary/10 flex items-center justify-center mx-auto mb-4 group-hover:neon-glow transition-all">
|
||||||
@@ -118,10 +133,16 @@ export default function AboutSection() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Counter */}
|
{/* Counter */}
|
||||||
<AnimatedCounter value={stat.value} suffix={stat.suffix} isInView={isInView} />
|
<AnimatedCounter
|
||||||
|
value={stat.value}
|
||||||
|
suffix={stat.suffix}
|
||||||
|
isInView={isInView}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Label */}
|
{/* Label */}
|
||||||
<p className="text-muted-foreground text-sm mt-2">{stat.label}</p>
|
<p className="text-muted-foreground text-sm mt-2">
|
||||||
|
{stat.label}
|
||||||
|
</p>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
))}
|
))}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { motion } from 'framer-motion';
|
import { Button } from "@/components/ui/button";
|
||||||
import { Calendar, Clock, ArrowRight, User } from 'lucide-react';
|
import { useBlogs } from "@/hooks/queires/useBlogs";
|
||||||
import { Link } from 'react-router-dom';
|
import { motion } from "framer-motion";
|
||||||
import { Button } from '@/components/ui/button';
|
import { ArrowRight, Calendar, Clock, User } from "lucide-react";
|
||||||
import { useBlogs } from '@/hooks/queires/useBlogs';
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
const containerVariants = {
|
const containerVariants = {
|
||||||
hidden: { opacity: 0 },
|
hidden: { opacity: 0 },
|
||||||
@@ -19,18 +19,16 @@ const itemVariants = {
|
|||||||
visible: {
|
visible: {
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
y: 0,
|
y: 0,
|
||||||
transition: { duration: 0.6, ease: 'easeOut' as const },
|
transition: { duration: 0.6, ease: "easeOut" as const },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function BlogSection() {
|
export default function BlogSection() {
|
||||||
|
const { data } = useBlogs();
|
||||||
const {data} = useBlogs()
|
|
||||||
const blogPosts = data?.data.result;
|
const blogPosts = data?.data.result;
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section id="blog" className="py-24 relative overflow-hidden">
|
<section id="blog" className=" pt-20 relative overflow-hidden">
|
||||||
{/* Background elements */}
|
{/* Background elements */}
|
||||||
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-primary/5 to-transparent" />
|
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-primary/5 to-transparent" />
|
||||||
|
|
||||||
@@ -50,7 +48,8 @@ export default function BlogSection() {
|
|||||||
News & <span className="text-primary neon-text-glow">Blog</span>
|
News & <span className="text-primary neon-text-glow">Blog</span>
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
||||||
Stay updated with the latest trends, insights, and thought leadership from our team of experts.
|
Stay updated with the latest trends, insights, and thought
|
||||||
|
leadership from our team of experts.
|
||||||
</p>
|
</p>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
@@ -98,7 +97,10 @@ export default function BlogSection() {
|
|||||||
</span>
|
</span>
|
||||||
<span className="flex items-center gap-1">
|
<span className="flex items-center gap-1">
|
||||||
<Calendar className="w-3 h-3" />
|
<Calendar className="w-3 h-3" />
|
||||||
{new Date(post.date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}
|
{new Date(post.date).toLocaleDateString("en-US", {
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
})}
|
||||||
</span>
|
</span>
|
||||||
<span className="flex items-center gap-1">
|
<span className="flex items-center gap-1">
|
||||||
<Clock className="w-3 h-3" />
|
<Clock className="w-3 h-3" />
|
||||||
@@ -130,7 +132,7 @@ export default function BlogSection() {
|
|||||||
<Link to="/blog">
|
<Link to="/blog">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
className="rounded-full px-8 py-6 glass border-primary/30 hover:neon-glow group"
|
className="font-semibold px-8 py-6 text-lg rounded-full border-primary bg-primary/10 transition-all"
|
||||||
>
|
>
|
||||||
View All Articles
|
View All Articles
|
||||||
<ArrowRight className="w-4 h-4 ml-2 transition-transform group-hover:translate-x-1" />
|
<ArrowRight className="w-4 h-4 ml-2 transition-transform group-hover:translate-x-1" />
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export default function ContactSection() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section id="contact" ref={ref} className="py-24 relative overflow-hidden">
|
<section id="contact" ref={ref} className="relative overflow-hidden pb-24">
|
||||||
{/* Background */}
|
{/* Background */}
|
||||||
<div className="absolute inset-0 opacity-30">
|
<div className="absolute inset-0 opacity-30">
|
||||||
<div className="absolute bottom-0 left-1/4 w-96 h-96 bg-primary/10 rounded-full blur-[150px]" />
|
<div className="absolute bottom-0 left-1/4 w-96 h-96 bg-primary/10 rounded-full blur-[150px]" />
|
||||||
@@ -65,7 +65,7 @@ export default function ContactSection() {
|
|||||||
transition={{ duration: 0.6 }}
|
transition={{ duration: 0.6 }}
|
||||||
className="text-center mb-16"
|
className="text-center mb-16"
|
||||||
>
|
>
|
||||||
<span className="inline-block px-4 py-1.5 rounded-full glass text-sm font-medium text-primary mb-4">
|
<span className="inline-block px-4 py-1.5 rounded-full text-sm font-medium text-primary mb-4">
|
||||||
Let's Connect
|
Let's Connect
|
||||||
</span>
|
</span>
|
||||||
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-4">
|
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-4">
|
||||||
@@ -116,38 +116,6 @@ export default function ContactSection() {
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Decorative illustration */}
|
|
||||||
<motion.div
|
|
||||||
initial={{ opacity: 0 }}
|
|
||||||
animate={isInView ? { opacity: 1 } : {}}
|
|
||||||
transition={{ duration: 0.8, delay: 0.5 }}
|
|
||||||
className="hidden lg:block relative h-48"
|
|
||||||
>
|
|
||||||
<div className="absolute inset-0 flex items-center justify-center">
|
|
||||||
<div className="relative">
|
|
||||||
{[...Array(3)].map((_, i) => (
|
|
||||||
<motion.div
|
|
||||||
key={i}
|
|
||||||
className="absolute w-32 h-32 rounded-full border-2 border-primary/20"
|
|
||||||
style={{
|
|
||||||
left: i * 20,
|
|
||||||
top: i * 10,
|
|
||||||
}}
|
|
||||||
animate={{
|
|
||||||
scale: [1, 1.1, 1],
|
|
||||||
opacity: [0.3, 0.6, 0.3],
|
|
||||||
}}
|
|
||||||
transition={{
|
|
||||||
duration: 3,
|
|
||||||
repeat: Infinity,
|
|
||||||
delay: i * 0.5,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</motion.div>
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
{/* Contact Form */}
|
{/* Contact Form */}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const socials = [
|
|||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
return (
|
return (
|
||||||
<footer className="relative overflow-hidden bg-secondary/50 pt-20 pb-8">
|
<footer className="relative overflow-hidden bg-secondary/50 py-20">
|
||||||
{/* Animated gradient divider */}
|
{/* Animated gradient divider */}
|
||||||
<div className="absolute top-0 left-0 right-0 h-1 gradient-primary-animated" />
|
<div className="absolute top-0 left-0 right-0 h-1 gradient-primary-animated" />
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ export default function Footer() {
|
|||||||
© {new Date().getFullYear()} TechZaa. All rights reserved.
|
© {new Date().getFullYear()} TechZaa. All rights reserved.
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center gap-6 text-sm text-muted-foreground">
|
<div className="flex items-center gap-6 text-sm text-muted-foreground">
|
||||||
<a href="#" className="hover:text-primary transition-colors">
|
<a href="/privacy" className="hover:text-primary transition-colors">
|
||||||
Privacy Policy
|
Privacy Policy
|
||||||
</a>
|
</a>
|
||||||
<a href="#" className="hover:text-primary transition-colors">
|
<a href="#" className="hover:text-primary transition-colors">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useRef } from 'react';
|
import { Button } from "@/components/ui/button";
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from "framer-motion";
|
||||||
import { ArrowRight, ChevronDown } from 'lucide-react';
|
import { ArrowRight, ChevronDown } from "lucide-react";
|
||||||
import { Button } from '@/components/ui/button';
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
export default function HeroSection() {
|
export default function HeroSection() {
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
@@ -15,12 +15,12 @@ export default function HeroSection() {
|
|||||||
const x = (clientX / innerWidth - 0.5) * 20;
|
const x = (clientX / innerWidth - 0.5) * 20;
|
||||||
const y = (clientY / innerHeight - 0.5) * 20;
|
const y = (clientY / innerHeight - 0.5) * 20;
|
||||||
|
|
||||||
containerRef.current.style.setProperty('--mouse-x', `${x}px`);
|
containerRef.current.style.setProperty("--mouse-x", `${x}px`);
|
||||||
containerRef.current.style.setProperty('--mouse-y', `${y}px`);
|
containerRef.current.style.setProperty("--mouse-y", `${y}px`);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('mousemove', handleMouseMove);
|
window.addEventListener("mousemove", handleMouseMove);
|
||||||
return () => window.removeEventListener('mousemove', handleMouseMove);
|
return () => window.removeEventListener("mousemove", handleMouseMove);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -59,29 +59,32 @@ export default function HeroSection() {
|
|||||||
<motion.div
|
<motion.div
|
||||||
className="absolute top-1/4 left-[10%] w-32 h-32 border-2 border-primary/30 rounded-full"
|
className="absolute top-1/4 left-[10%] w-32 h-32 border-2 border-primary/30 rounded-full"
|
||||||
style={{
|
style={{
|
||||||
transform: 'translate(calc(var(--mouse-x, 0) * -1), calc(var(--mouse-y, 0) * -1))',
|
transform:
|
||||||
|
"translate(calc(var(--mouse-x, 0) * -1), calc(var(--mouse-y, 0) * -1))",
|
||||||
}}
|
}}
|
||||||
animate={{ rotate: 360 }}
|
animate={{ rotate: 360 }}
|
||||||
transition={{ duration: 20, repeat: Infinity, ease: 'linear' }}
|
transition={{ duration: 20, repeat: Infinity, ease: "linear" }}
|
||||||
/>
|
/>
|
||||||
<motion.div
|
<motion.div
|
||||||
className="absolute bottom-1/4 right-[15%] w-24 h-24 border-2 border-neon-purple/30 rotate-45"
|
className="absolute bottom-1/4 right-[15%] w-24 h-24 border-2 border-neon-purple/30 rotate-45"
|
||||||
style={{
|
style={{
|
||||||
transform: 'translate(calc(var(--mouse-x, 0) * 0.5), calc(var(--mouse-y, 0) * 0.5)) rotate(45deg)',
|
transform:
|
||||||
|
"translate(calc(var(--mouse-x, 0) * 0.5), calc(var(--mouse-y, 0) * 0.5)) rotate(45deg)",
|
||||||
}}
|
}}
|
||||||
animate={{ rotate: [45, 405] }}
|
animate={{ rotate: [45, 405] }}
|
||||||
transition={{ duration: 25, repeat: Infinity, ease: 'linear' }}
|
transition={{ duration: 25, repeat: Infinity, ease: "linear" }}
|
||||||
/>
|
/>
|
||||||
<motion.div
|
<motion.div
|
||||||
className="absolute top-1/3 right-[25%] w-16 h-16 bg-neon-green/10 rounded-lg"
|
className="absolute top-1/3 right-[25%] w-16 h-16 bg-neon-green/10 rounded-lg"
|
||||||
style={{
|
style={{
|
||||||
transform: 'translate(calc(var(--mouse-x, 0) * 1.5), calc(var(--mouse-y, 0) * 1.5))',
|
transform:
|
||||||
|
"translate(calc(var(--mouse-x, 0) * 1.5), calc(var(--mouse-y, 0) * 1.5))",
|
||||||
}}
|
}}
|
||||||
animate={{
|
animate={{
|
||||||
y: [-10, 10, -10],
|
y: [-10, 10, -10],
|
||||||
rotate: [0, 180, 360],
|
rotate: [0, 180, 360],
|
||||||
}}
|
}}
|
||||||
transition={{ duration: 8, repeat: Infinity, ease: 'easeInOut' }}
|
transition={{ duration: 8, repeat: Infinity, ease: "easeInOut" }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Glowing orbs */}
|
{/* Glowing orbs */}
|
||||||
@@ -135,9 +138,9 @@ export default function HeroSection() {
|
|||||||
transition={{ delay: 0.7 }}
|
transition={{ delay: 0.7 }}
|
||||||
className="text-lg md:text-xl text-muted-foreground max-w-2xl mx-auto mb-10"
|
className="text-lg md:text-xl text-muted-foreground max-w-2xl mx-auto mb-10"
|
||||||
>
|
>
|
||||||
Transforming ideas into powerful digital solutions. We craft innovative
|
Transforming ideas into powerful digital solutions. We craft
|
||||||
web applications, mobile experiences, and AI-powered systems that drive
|
innovative web applications, mobile experiences, and AI-powered
|
||||||
growth and redefine possibilities.
|
systems that drive growth and redefine possibilities.
|
||||||
</motion.p>
|
</motion.p>
|
||||||
|
|
||||||
{/* CTA Buttons */}
|
{/* CTA Buttons */}
|
||||||
@@ -157,7 +160,7 @@ export default function HeroSection() {
|
|||||||
<Button
|
<Button
|
||||||
size="lg"
|
size="lg"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
className="font-semibold px-8 py-6 text-lg rounded-full glass border-primary/50 hover:border-primary hover:bg-primary/10 transition-all"
|
className="font-semibold px-8 py-6 text-lg rounded-full border-primary bg-primary/10 transition-all"
|
||||||
>
|
>
|
||||||
View Our Work
|
View Our Work
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import {
|
||||||
|
Cookie,
|
||||||
|
Database,
|
||||||
|
Eye,
|
||||||
|
FileText,
|
||||||
|
Lock,
|
||||||
|
Share2,
|
||||||
|
UserCheck,
|
||||||
|
} from "lucide-react";
|
||||||
|
|
||||||
|
interface PolicySection {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
icon: React.ReactNode;
|
||||||
|
content: string | string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const privacySections: PolicySection[] = [
|
||||||
|
{
|
||||||
|
id: "info-collect",
|
||||||
|
title: "1. Information We Collect",
|
||||||
|
icon: <Database className="w-5 h-5" />,
|
||||||
|
content: [
|
||||||
|
"Personal information (Name, Email, Phone number)",
|
||||||
|
"Project details you share with us",
|
||||||
|
"Technical data (IP address, browser type, device info)",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "info-use",
|
||||||
|
title: "2. How We Use Information",
|
||||||
|
icon: <Eye className="w-5 h-5" />,
|
||||||
|
content: [
|
||||||
|
"Provide and manage our services",
|
||||||
|
"Communicate with you",
|
||||||
|
"Improve our website and services",
|
||||||
|
"Ensure security and prevent fraud",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "data-sharing",
|
||||||
|
title: "3. Data Sharing",
|
||||||
|
icon: <Share2 className="w-5 h-5" />,
|
||||||
|
content:
|
||||||
|
"We do not sell your personal data. We may share data with trusted service providers (hosting, analytics) and legal authorities if required by law.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "security",
|
||||||
|
title: "4. Data Security",
|
||||||
|
icon: <Lock className="w-5 h-5" />,
|
||||||
|
content:
|
||||||
|
"We implement industry-standard security measures to protect your data from unauthorized access or disclosure.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "rights",
|
||||||
|
title: "6. Your Rights",
|
||||||
|
icon: <UserCheck className="w-5 h-5" />,
|
||||||
|
content: [
|
||||||
|
"Access your data",
|
||||||
|
"Request correction or deletion",
|
||||||
|
"Withdraw consent",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const cookieSections: PolicySection[] = [
|
||||||
|
{
|
||||||
|
id: "cookie-def",
|
||||||
|
title: "What Are Cookies?",
|
||||||
|
icon: <Cookie className="w-5 h-5" />,
|
||||||
|
content:
|
||||||
|
"Cookies are small text files stored on your device to improve website functionality and user experience.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "cookie-types",
|
||||||
|
title: "Types of Cookies",
|
||||||
|
icon: <FileText className="w-5 h-5" />,
|
||||||
|
content: ["Essential Cookies", "Analytics Cookies", "Functional Cookies"],
|
||||||
|
},
|
||||||
|
];
|
||||||
+10
-14
@@ -1,21 +1,18 @@
|
|||||||
import Navbar from '@/components/Navbar';
|
import AboutSection from "@/components/AboutSection";
|
||||||
import HeroSection from '@/components/HeroSection';
|
import BlogSection from "@/components/BlogSection";
|
||||||
import ServicesSection from '@/components/ServicesSection';
|
import ContactSection from "@/components/ContactSection";
|
||||||
import ProjectsSection from '@/components/ProjectsSection';
|
import FAQSection from "@/components/FAQSection";
|
||||||
import TeamSection from '@/components/TeamSection';
|
import HeroSection from "@/components/HeroSection";
|
||||||
import AboutSection from '@/components/AboutSection';
|
import PageTransition from "@/components/PageTransition";
|
||||||
import TestimonialsSection from '@/components/TestimonialsSection';
|
import ProjectsSection from "@/components/ProjectsSection";
|
||||||
import BlogSection from '@/components/BlogSection';
|
import ServicesSection from "@/components/ServicesSection";
|
||||||
import FAQSection from '@/components/FAQSection';
|
import TeamSection from "@/components/TeamSection";
|
||||||
import ContactSection from '@/components/ContactSection';
|
import TestimonialsSection from "@/components/TestimonialsSection";
|
||||||
import Footer from '@/components/Footer';
|
|
||||||
import PageTransition from '@/components/PageTransition';
|
|
||||||
|
|
||||||
const Index = () => {
|
const Index = () => {
|
||||||
return (
|
return (
|
||||||
<PageTransition>
|
<PageTransition>
|
||||||
<div className="min-h-screen bg-background overflow-x-hidden">
|
<div className="min-h-screen bg-background overflow-x-hidden">
|
||||||
<Navbar />
|
|
||||||
<HeroSection />
|
<HeroSection />
|
||||||
<ServicesSection />
|
<ServicesSection />
|
||||||
<ProjectsSection />
|
<ProjectsSection />
|
||||||
@@ -25,7 +22,6 @@ const Index = () => {
|
|||||||
<BlogSection />
|
<BlogSection />
|
||||||
<FAQSection />
|
<FAQSection />
|
||||||
<ContactSection />
|
<ContactSection />
|
||||||
<Footer />
|
|
||||||
</div>
|
</div>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
import { cookieSections, privacySections } from "@/data/privacyData";
|
||||||
|
import { ChevronRight, Cookie, Shield } from "lucide-react";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export const PrivacyPolicy: React.FC = () => {
|
||||||
|
const [activeSection, setActiveSection] = useState("info-collect");
|
||||||
|
|
||||||
|
const allSections = [...privacySections, ...cookieSections];
|
||||||
|
|
||||||
|
const handleScroll = (id: string) => {
|
||||||
|
setActiveSection(id);
|
||||||
|
document
|
||||||
|
.getElementById(id)
|
||||||
|
?.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="mx-auto w-full container px-4 sm:px-6 lg:px-8 py-24">
|
||||||
|
{/* HEADER */}
|
||||||
|
<header className="max-w-3xl mb-12">
|
||||||
|
<div className="flex items-center gap-4 mb-4">
|
||||||
|
<div className="p-3 rounded-xl bg-primary/30">
|
||||||
|
<Shield className="w-6 h-6 " aria-hidden="true" />
|
||||||
|
</div>
|
||||||
|
<h1 className="text-3xl sm:text-4xl font-bold">Privacy Policy</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p className="text-sm text-muted-foreground mb-3">
|
||||||
|
Last Updated: April 19, 2026
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p className="text-base sm:text-lg text-muted-foreground leading-relaxed">
|
||||||
|
This page explains what data we collect, why we collect it, and how we
|
||||||
|
handle it.
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div className="flex flex-col lg:flex-row gap-8">
|
||||||
|
{/* SIDEBAR */}
|
||||||
|
<aside className="lg:w-1/4">
|
||||||
|
<nav
|
||||||
|
className="bg-accent/10 border border-primary/10 rounded-2xl p-4 space-y-2 lg:sticky lg:top-24"
|
||||||
|
aria-label="Privacy policy sections"
|
||||||
|
>
|
||||||
|
<p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-2 px-2">
|
||||||
|
Contents
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{allSections.map((section) => (
|
||||||
|
<button
|
||||||
|
key={section.id}
|
||||||
|
onClick={() => handleScroll(section.id)}
|
||||||
|
aria-current={activeSection === section.id ? "true" : undefined}
|
||||||
|
className={`w-full text-left flex items-center justify-between px-3 py-2.5 rounded-lg text-sm transition-all focus:outline-none focus:ring-2 focus:ring-[hsl(var(--accent-neon))] ${
|
||||||
|
activeSection === section.id
|
||||||
|
? "bg-[hsl(var(--accent-neon)/0.15)] text-primary"
|
||||||
|
: "text-muted-foreground hover:bg-[hsl(var(--accent-neon)/0.08)]"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<span className="truncate">{section.title}</span>
|
||||||
|
<ChevronRight
|
||||||
|
className="w-4 h-4 opacity-60"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
{/* MAIN */}
|
||||||
|
<main className="lg:w-3/4 space-y-8">
|
||||||
|
{/* PRIVACY */}
|
||||||
|
{privacySections.map((section) => (
|
||||||
|
<section
|
||||||
|
key={section.id}
|
||||||
|
id={section.id}
|
||||||
|
className="bg-accent/10 border border-primary/10 rounded-2xl p-6 sm:p-8 transition hover:neon-glow"
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-3 mb-4">
|
||||||
|
<div className="p-2 rounded-lg bg-[hsl(var(--accent-neon)/0.2)]">
|
||||||
|
{section.icon}
|
||||||
|
</div>
|
||||||
|
<h2 className="text-lg sm:text-xl font-semibold">
|
||||||
|
{section.title}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{Array.isArray(section.content) ? (
|
||||||
|
<ul className="space-y-2 ml-5">
|
||||||
|
{section.content.map((item, idx) => (
|
||||||
|
<li key={idx} className="flex gap-2 text-muted-foreground">
|
||||||
|
<span className="mt-2 w-1.5 h-1.5 bg-secondary rounded-full" />
|
||||||
|
{item}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
) : (
|
||||||
|
<p className="ml-5 text-muted-foreground leading-relaxed">
|
||||||
|
{section.content}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</section>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* COOKIES */}
|
||||||
|
<section className="space-y-6">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="p-3 rounded-xl bg-primary/10">
|
||||||
|
<Cookie className="w-6 h-6 " />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-2xl sm:text-3xl font-bold ">
|
||||||
|
Cookies Policy
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{cookieSections.map((section) => (
|
||||||
|
<section
|
||||||
|
key={section.id}
|
||||||
|
id={section.id}
|
||||||
|
className="bg-accent/10 border border-primary/10 rounded-2xl p-6 sm:p-8 transition hover:neon-glow"
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2 mb-3">
|
||||||
|
{section.icon}
|
||||||
|
<h3 className="text-lg font-semibold">{section.title}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{Array.isArray(section.content) ? (
|
||||||
|
<ul className="space-y-2 ml-5">
|
||||||
|
{section.content.map((item, idx) => (
|
||||||
|
<li
|
||||||
|
key={idx}
|
||||||
|
className="flex gap-2 text-muted-foreground"
|
||||||
|
>
|
||||||
|
<span className="mt-2 w-1.5 h-1.5 bg-[hsl(var(--accent-neon))] rounded-full" />
|
||||||
|
{item}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
) : (
|
||||||
|
<p className="ml-5 text-muted-foreground">
|
||||||
|
{section.content}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</section>
|
||||||
|
))}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* FOOTER */}
|
||||||
|
<footer className="bg-accent/10 border border-primary/10 rounded-2xl p-5 text-sm text-muted-foreground">
|
||||||
|
You can disable cookies in your browser settings. Continued use of
|
||||||
|
this site means you accept this policy.
|
||||||
|
</footer>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user