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 } from "@/components/ui/toaster";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { BrowserRouter, Routes, Route, useLocation } from "react-router-dom";
|
||||
import { ThemeProvider } from "@/contexts/ThemeContext";
|
||||
import { AnimatePresence } from "framer-motion";
|
||||
import Index from "./pages/Index";
|
||||
import Projects from "./pages/Projects";
|
||||
import ProjectDetails from "./pages/ProjectDetails";
|
||||
import { BrowserRouter, Route, Routes, useLocation } from "react-router-dom";
|
||||
import Footer from "./components/Footer";
|
||||
import Navbar from "./components/Navbar";
|
||||
import Blog from "./pages/Blog";
|
||||
import BlogArticle from "./pages/BlogArticle";
|
||||
import Index from "./pages/Index";
|
||||
import NotFound from "./pages/NotFound";
|
||||
import ProjectDetails from "./pages/ProjectDetails";
|
||||
import Projects from "./pages/Projects";
|
||||
import { QueryProvider } from "./provider/QueryProvider";
|
||||
|
||||
import { PrivacyPolicy } from "./pages/PrivacyPolicy";
|
||||
|
||||
function AnimatedRoutes() {
|
||||
const location = useLocation();
|
||||
@@ -26,6 +28,7 @@ function AnimatedRoutes() {
|
||||
<Route path="/blog/:id" element={<BlogArticle />} />
|
||||
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
|
||||
<Route path="*" element={<NotFound />} />
|
||||
<Route path="/privacy" element={<PrivacyPolicy />} />
|
||||
</Routes>
|
||||
</AnimatePresence>
|
||||
);
|
||||
@@ -38,7 +41,9 @@ const App = () => (
|
||||
<Toaster />
|
||||
<Sonner />
|
||||
<BrowserRouter>
|
||||
<Navbar />
|
||||
<AnimatedRoutes />
|
||||
<Footer />
|
||||
</BrowserRouter>
|
||||
</TooltipProvider>
|
||||
</ThemeProvider>
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
import { useRef, useEffect, useState } from 'react';
|
||||
import { motion, useInView } from 'framer-motion';
|
||||
import { Zap, Users, Rocket, Award } from 'lucide-react';
|
||||
import { motion, useInView } from "framer-motion";
|
||||
import { Award, Rocket, Users, Zap } from "lucide-react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
const stats = [
|
||||
{ icon: Zap, value: 10, suffix: '+', label: 'Years Experience' },
|
||||
{ icon: Rocket, value: 500, suffix: '+', label: 'Projects Completed' },
|
||||
{ icon: Users, value: 200, suffix: '+', label: 'Happy Clients' },
|
||||
{ icon: Award, value: 50, suffix: '+', label: 'Awards Won' },
|
||||
{ icon: Zap, value: 10, suffix: "+", label: "Years Experience" },
|
||||
{ icon: Rocket, value: 500, suffix: "+", label: "Projects Completed" },
|
||||
{ icon: Users, value: 200, suffix: "+", label: "Happy Clients" },
|
||||
{ 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);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -34,17 +42,22 @@ function AnimatedCounter({ value, suffix, isInView }: { value: number; suffix: s
|
||||
|
||||
return (
|
||||
<span className="text-4xl md:text-5xl font-bold text-primary neon-text-glow">
|
||||
{count}{suffix}
|
||||
{count}
|
||||
{suffix}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AboutSection() {
|
||||
const ref = useRef<HTMLElement>(null);
|
||||
const isInView = useInView(ref, { once: true, margin: '-100px' });
|
||||
const isInView = useInView(ref, { once: true, margin: "-100px" });
|
||||
|
||||
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 */}
|
||||
<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]" />
|
||||
@@ -66,33 +79,35 @@ export default function AboutSection() {
|
||||
</h2>
|
||||
<div className="space-y-4 text-muted-foreground text-lg">
|
||||
<p>
|
||||
Founded with a passion for innovation, TechZaa is a leading technology
|
||||
company dedicated to transforming businesses through cutting-edge
|
||||
digital solutions.
|
||||
Founded with a passion for innovation, TechZaa is a leading
|
||||
technology company dedicated to transforming businesses through
|
||||
cutting-edge digital solutions.
|
||||
</p>
|
||||
<p>
|
||||
Our team of expert developers, designers, and strategists work
|
||||
collaboratively to deliver exceptional results that exceed expectations.
|
||||
We believe in the power of technology to solve complex problems and
|
||||
create meaningful impact.
|
||||
Our team of expert developers, designers, and strategists work
|
||||
collaboratively to deliver exceptional results that exceed
|
||||
expectations. We believe in the power of technology to solve
|
||||
complex problems and create meaningful impact.
|
||||
</p>
|
||||
<p>
|
||||
From startups to enterprises, we've helped hundreds of clients
|
||||
achieve their digital transformation goals with our innovative
|
||||
From startups to enterprises, we've helped hundreds of clients
|
||||
achieve their digital transformation goals with our innovative
|
||||
approach and commitment to excellence.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Values */}
|
||||
<div className="mt-8 flex flex-wrap gap-3">
|
||||
{['Innovation', 'Quality', 'Integrity', 'Excellence'].map((value) => (
|
||||
<span
|
||||
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"
|
||||
>
|
||||
{value}
|
||||
</span>
|
||||
))}
|
||||
{["Innovation", "Quality", "Integrity", "Excellence"].map(
|
||||
(value) => (
|
||||
<span
|
||||
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"
|
||||
>
|
||||
{value}
|
||||
</span>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
@@ -110,7 +125,7 @@ export default function AboutSection() {
|
||||
animate={isInView ? { opacity: 1, y: 0 } : {}}
|
||||
transition={{ duration: 0.5, delay: 0.3 + index * 0.1 }}
|
||||
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 */}
|
||||
<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>
|
||||
|
||||
{/* Counter */}
|
||||
<AnimatedCounter value={stat.value} suffix={stat.suffix} isInView={isInView} />
|
||||
<AnimatedCounter
|
||||
value={stat.value}
|
||||
suffix={stat.suffix}
|
||||
isInView={isInView}
|
||||
/>
|
||||
|
||||
{/* 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>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { Calendar, Clock, ArrowRight, User } from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { useBlogs } from '@/hooks/queires/useBlogs';
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useBlogs } from "@/hooks/queires/useBlogs";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowRight, Calendar, Clock, User } from "lucide-react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
const containerVariants = {
|
||||
hidden: { opacity: 0 },
|
||||
@@ -19,21 +19,19 @@ const itemVariants = {
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: { duration: 0.6, ease: 'easeOut' as const },
|
||||
transition: { duration: 0.6, ease: "easeOut" as const },
|
||||
},
|
||||
};
|
||||
|
||||
export default function BlogSection() {
|
||||
|
||||
const {data} = useBlogs()
|
||||
const { data } = useBlogs();
|
||||
const blogPosts = data?.data.result;
|
||||
|
||||
|
||||
return (
|
||||
<section id="blog" className="py-24 relative overflow-hidden">
|
||||
<section id="blog" className=" pt-20 relative overflow-hidden">
|
||||
{/* Background elements */}
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-primary/5 to-transparent" />
|
||||
|
||||
|
||||
<div className="container mx-auto px-4 relative z-10">
|
||||
{/* Section Header */}
|
||||
<motion.div
|
||||
@@ -50,7 +48,8 @@ export default function BlogSection() {
|
||||
News & <span className="text-primary neon-text-glow">Blog</span>
|
||||
</h2>
|
||||
<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>
|
||||
</motion.div>
|
||||
|
||||
@@ -98,7 +97,10 @@ export default function BlogSection() {
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<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 className="flex items-center gap-1">
|
||||
<Clock className="w-3 h-3" />
|
||||
@@ -130,7 +132,7 @@ export default function BlogSection() {
|
||||
<Link to="/blog">
|
||||
<Button
|
||||
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
|
||||
<ArrowRight className="w-4 h-4 ml-2 transition-transform group-hover:translate-x-1" />
|
||||
|
||||
@@ -50,7 +50,7 @@ export default function ContactSection() {
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="contact" ref={ref} className="py-24 relative overflow-hidden">
|
||||
<section id="contact" ref={ref} className="relative overflow-hidden pb-24">
|
||||
{/* Background */}
|
||||
<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]" />
|
||||
@@ -65,7 +65,7 @@ export default function ContactSection() {
|
||||
transition={{ duration: 0.6 }}
|
||||
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
|
||||
</span>
|
||||
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-4">
|
||||
@@ -116,38 +116,6 @@ export default function ContactSection() {
|
||||
</motion.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>
|
||||
|
||||
{/* Contact Form */}
|
||||
|
||||
@@ -30,7 +30,7 @@ const socials = [
|
||||
|
||||
export default function Footer() {
|
||||
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 */}
|
||||
<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.
|
||||
</p>
|
||||
<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
|
||||
</a>
|
||||
<a href="#" className="hover:text-primary transition-colors">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { ArrowRight, ChevronDown } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowRight, ChevronDown } from "lucide-react";
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
export default function HeroSection() {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
@@ -14,13 +14,13 @@ export default function HeroSection() {
|
||||
const { innerWidth, innerHeight } = window;
|
||||
const x = (clientX / innerWidth - 0.5) * 20;
|
||||
const y = (clientY / innerHeight - 0.5) * 20;
|
||||
|
||||
containerRef.current.style.setProperty('--mouse-x', `${x}px`);
|
||||
containerRef.current.style.setProperty('--mouse-y', `${y}px`);
|
||||
|
||||
containerRef.current.style.setProperty("--mouse-x", `${x}px`);
|
||||
containerRef.current.style.setProperty("--mouse-y", `${y}px`);
|
||||
};
|
||||
|
||||
window.addEventListener('mousemove', handleMouseMove);
|
||||
return () => window.removeEventListener('mousemove', handleMouseMove);
|
||||
window.addEventListener("mousemove", handleMouseMove);
|
||||
return () => window.removeEventListener("mousemove", handleMouseMove);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@@ -31,7 +31,7 @@ export default function HeroSection() {
|
||||
>
|
||||
{/* Animated gradient background */}
|
||||
<div className="absolute inset-0 gradient-primary-animated opacity-10" />
|
||||
|
||||
|
||||
{/* Particle dots */}
|
||||
<div className="absolute inset-0 overflow-hidden">
|
||||
{[...Array(50)].map((_, i) => (
|
||||
@@ -59,29 +59,32 @@ export default function HeroSection() {
|
||||
<motion.div
|
||||
className="absolute top-1/4 left-[10%] w-32 h-32 border-2 border-primary/30 rounded-full"
|
||||
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 }}
|
||||
transition={{ duration: 20, repeat: Infinity, ease: 'linear' }}
|
||||
transition={{ duration: 20, repeat: Infinity, ease: "linear" }}
|
||||
/>
|
||||
<motion.div
|
||||
className="absolute bottom-1/4 right-[15%] w-24 h-24 border-2 border-neon-purple/30 rotate-45"
|
||||
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] }}
|
||||
transition={{ duration: 25, repeat: Infinity, ease: 'linear' }}
|
||||
transition={{ duration: 25, repeat: Infinity, ease: "linear" }}
|
||||
/>
|
||||
<motion.div
|
||||
className="absolute top-1/3 right-[25%] w-16 h-16 bg-neon-green/10 rounded-lg"
|
||||
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],
|
||||
rotate: [0, 180, 360],
|
||||
}}
|
||||
transition={{ duration: 8, repeat: Infinity, ease: 'easeInOut' }}
|
||||
transition={{ duration: 8, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
|
||||
{/* Glowing orbs */}
|
||||
@@ -135,9 +138,9 @@ export default function HeroSection() {
|
||||
transition={{ delay: 0.7 }}
|
||||
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
|
||||
web applications, mobile experiences, and AI-powered systems that drive
|
||||
growth and redefine possibilities.
|
||||
Transforming ideas into powerful digital solutions. We craft
|
||||
innovative web applications, mobile experiences, and AI-powered
|
||||
systems that drive growth and redefine possibilities.
|
||||
</motion.p>
|
||||
|
||||
{/* CTA Buttons */}
|
||||
@@ -157,7 +160,7 @@ export default function HeroSection() {
|
||||
<Button
|
||||
size="lg"
|
||||
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
|
||||
</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 HeroSection from '@/components/HeroSection';
|
||||
import ServicesSection from '@/components/ServicesSection';
|
||||
import ProjectsSection from '@/components/ProjectsSection';
|
||||
import TeamSection from '@/components/TeamSection';
|
||||
import AboutSection from '@/components/AboutSection';
|
||||
import TestimonialsSection from '@/components/TestimonialsSection';
|
||||
import BlogSection from '@/components/BlogSection';
|
||||
import FAQSection from '@/components/FAQSection';
|
||||
import ContactSection from '@/components/ContactSection';
|
||||
import Footer from '@/components/Footer';
|
||||
import PageTransition from '@/components/PageTransition';
|
||||
import AboutSection from "@/components/AboutSection";
|
||||
import BlogSection from "@/components/BlogSection";
|
||||
import ContactSection from "@/components/ContactSection";
|
||||
import FAQSection from "@/components/FAQSection";
|
||||
import HeroSection from "@/components/HeroSection";
|
||||
import PageTransition from "@/components/PageTransition";
|
||||
import ProjectsSection from "@/components/ProjectsSection";
|
||||
import ServicesSection from "@/components/ServicesSection";
|
||||
import TeamSection from "@/components/TeamSection";
|
||||
import TestimonialsSection from "@/components/TestimonialsSection";
|
||||
|
||||
const Index = () => {
|
||||
return (
|
||||
<PageTransition>
|
||||
<div className="min-h-screen bg-background overflow-x-hidden">
|
||||
<Navbar />
|
||||
<HeroSection />
|
||||
<ServicesSection />
|
||||
<ProjectsSection />
|
||||
@@ -25,7 +22,6 @@ const Index = () => {
|
||||
<BlogSection />
|
||||
<FAQSection />
|
||||
<ContactSection />
|
||||
<Footer />
|
||||
</div>
|
||||
</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