customeragent-api / client /src /components /PublicLayout.jsx
anasraza526's picture
Clean deploy to Hugging Face
ac90985
import React, { useState, useEffect } from 'react';
import { Link, useLocation, Outlet } from 'react-router-dom';
import { Menu, X, ChevronRight, Twitter, Linkedin, Facebook, Youtube } from 'lucide-react';
const PublicLayout = ({ children }) => {
const location = useLocation();
const [isScrolled, setIsScrolled] = useState(false);
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 20);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const isActive = (path) => location.pathname === path;
const navLinks = [
{ path: '/', label: 'Home' },
{ path: '/pricing', label: 'Pricing' },
{ path: '/about', label: 'About' },
{ path: '/contact', label: 'Contact' },
{ path: '/blog', label: 'Blog' },
];
return (
<div className="min-h-screen flex flex-col bg-secondary-50 dark:bg-secondary-950 transition-colors duration-300">
{/* Navigation */}
<nav
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${isScrolled ? 'glass py-3' : 'bg-transparent py-5'
}`}
>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between">
{/* Logo */}
<Link to="/" className="flex items-center gap-2 group">
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-accent-500 flex items-center justify-center text-white font-bold text-xl shadow-lg group-hover:scale-105 transition-transform">
CA
</div>
<span className="font-bold text-xl text-secondary-900 dark:text-white tracking-tight">
Customer<span className="text-primary-600">Agent</span>
</span>
</Link>
{/* Desktop Navigation */}
<div className="hidden md:flex items-center gap-8">
{navLinks.map((link) => (
<Link
key={link.path}
to={link.path}
className={`text-sm font-medium transition-colors hover:text-primary-600 ${isActive(link.path)
? 'text-primary-600'
: 'text-secondary-600 dark:text-secondary-300'
}`}
>
{link.label}
</Link>
))}
<div className="flex items-center gap-4">
<Link
to="/login"
className="text-sm font-medium text-secondary-600 dark:text-secondary-300 hover:text-primary-600 transition-colors"
>
Log In
</Link>
<Link
to="/register"
className="px-5 py-2.5 rounded-lg bg-primary-600 text-white text-sm font-semibold shadow-lg shadow-primary-500/30 hover:bg-primary-700 hover:-translate-y-0.5 transition-all"
>
Start Free Trial
</Link>
</div>
</div>
{/* Mobile Menu Button */}
<button
className="md:hidden p-2 text-secondary-600 dark:text-secondary-300"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
>
{isMobileMenuOpen ? <X size={24} /> : <Menu size={24} />}
</button>
</div>
</div>
{/* Mobile Menu */}
{isMobileMenuOpen && (
<div className="md:hidden absolute top-full left-0 right-0 bg-white dark:bg-secondary-900 border-b border-secondary-200 dark:border-secondary-800 shadow-xl animate-fade-in">
<div className="px-4 py-6 space-y-4">
{navLinks.map((link) => (
<Link
key={link.path}
to={link.path}
className={`block text-base font-medium ${isActive(link.path)
? 'text-primary-600'
: 'text-secondary-600 dark:text-secondary-300'
}`}
onClick={() => setIsMobileMenuOpen(false)}
>
{link.label}
</Link>
))}
<div className="pt-4 border-t border-secondary-200 dark:border-secondary-800 flex flex-col gap-4">
<Link
to="/login"
className="text-center text-secondary-600 dark:text-secondary-300 font-medium"
onClick={() => setIsMobileMenuOpen(false)}
>
Log In
</Link>
<Link
to="/register"
className="block text-center px-5 py-3 rounded-lg bg-primary-600 text-white font-semibold"
onClick={() => setIsMobileMenuOpen(false)}
>
Start Free Trial
</Link>
</div>
</div>
</div>
)}
</nav>
{/* Main Content */}
<main className="flex-grow pt-20">
<Outlet />
</main>
{/* Footer */}
<footer className="bg-white dark:bg-secondary-900 border-t border-secondary-200 dark:border-secondary-800 pt-16 pb-8">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-12 mb-12">
<div className="space-y-4">
<div className="flex items-center gap-2">
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-primary-500 to-accent-500 flex items-center justify-center text-white font-bold text-lg">
CA
</div>
<span className="font-bold text-lg text-secondary-900 dark:text-white">
CustomerAgent
</span>
</div>
<p className="text-secondary-500 dark:text-secondary-400 text-sm leading-relaxed">
AI-powered customer support platform that helps businesses deliver exceptional experiences at scale.
</p>
<div className="flex gap-4">
{[Twitter, Linkedin, Facebook, Youtube].map((Icon, i) => (
<a key={i} href="#" className="text-secondary-400 hover:text-primary-500 transition-colors">
<Icon size={20} />
</a>
))}
</div>
</div>
<div>
<h4 className="font-semibold text-secondary-900 dark:text-white mb-6">Product</h4>
<ul className="space-y-3">
{['Features', 'Pricing', 'Integrations', 'Enterprise', 'Changelog'].map((item) => (
<li key={item}>
<Link to={`/${item.toLowerCase()}`} className="text-secondary-500 dark:text-secondary-400 hover:text-primary-600 text-sm transition-colors">
{item}
</Link>
</li>
))}
</ul>
</div>
<div>
<h4 className="font-semibold text-secondary-900 dark:text-white mb-6">Resources</h4>
<ul className="space-y-3">
{[
{ name: 'Documentation', path: '/docs' },
{ name: 'API Reference', path: '/api' },
{ name: 'Blog', path: '/blog' },
{ name: 'Community', path: '/community' },
{ name: 'Help Center', path: '/help-center' }
].map((item) => (
<li key={item.name}>
<Link to={item.path} className="text-secondary-500 dark:text-secondary-400 hover:text-primary-600 text-sm transition-colors">
{item.name}
</Link>
</li>
))}
</ul>
</div>
<div>
<h4 className="font-semibold text-secondary-900 dark:text-white mb-6">Legal</h4>
<ul className="space-y-3">
{[
{ name: 'Privacy Policy', path: '/privacy' },
{ name: 'Terms of Service', path: '/terms' },
{ name: 'Cookie Policy', path: '/cookie-policy' },
{ name: 'GDPR', path: '/gdpr' },
{ name: 'Security', path: '/security' }
].map((item) => (
<li key={item.name}>
<Link to={item.path} className="text-secondary-500 dark:text-secondary-400 hover:text-primary-600 text-sm transition-colors">
{item.name}
</Link>
</li>
))}
</ul>
</div>
</div>
<div className="pt-8 border-t border-secondary-200 dark:border-secondary-800 flex flex-col md:flex-row justify-between items-center gap-4">
<p className="text-secondary-400 text-sm">
&copy; {new Date().getFullYear()} CustomerAgent. All rights reserved.
</p>
<div className="flex items-center gap-6">
<span className="flex items-center gap-2 text-sm text-secondary-500">
<span className="w-2 h-2 rounded-full bg-green-500"></span>
All systems operational
</span>
</div>
</div>
</div>
</footer>
</div>
);
};
export default PublicLayout;