Files
cms-automotivo/components/Header.tsx
MMrp89 c0bd6d7e3d feat: Initialize CAR Auto Center project with Vite and React
Sets up the foundational structure for the CAR Auto Center application using Vite and React. Includes project dependencies, basic HTML structure, TypeScript configuration, and initial README content. This commit establishes the project's build tool, core libraries, and essential configuration files.
2026-02-19 16:22:10 -03:00

108 lines
3.9 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { Menu, X, Phone } from 'lucide-react';
import { Link, useLocation } from 'react-router-dom';
import { Button, Container } from './Shared';
import { useData } from '../contexts/DataContext';
export const Header: React.FC = () => {
const { data, getWhatsAppLink } = useData();
const [isScrolled, setIsScrolled] = useState(false);
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const location = useLocation();
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 50);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const handleCtaClick = () => {
const { url } = data.header.ctaButton;
if (url && url.trim() !== '') {
window.open(url, '_blank');
} else {
window.open(getWhatsAppLink("Olá! Gostaria de agendar um horário."), '_blank');
}
};
return (
<header
className={`fixed w-full z-50 transition-all duration-300 ${
isScrolled ? 'bg-black/90 backdrop-blur-md py-4 shadow-lg border-b border-zinc-800' : 'bg-transparent py-6'
}`}
>
<Container>
<div className="flex items-center justify-between">
<Link to="/" className="flex items-center gap-2">
{data.settings.logoUrl ? (
<img src={data.settings.logoUrl} alt={data.settings.siteName} className="h-10 object-contain" />
) : (
<div className="text-2xl font-black italic tracking-tighter text-white">
{data.settings.siteName}<span className="text-primary">.</span>
</div>
)}
</Link>
{/* Desktop Nav */}
<nav className="hidden lg:flex items-center gap-8">
{data.header.items.map((item, index) => (
<Link
key={index}
to={item.href}
className={`text-sm font-medium transition-colors ${
location.pathname === item.href
? 'text-primary'
: 'text-gray-300 hover:text-primary'
}`}
>
{item.label}
</Link>
))}
</nav>
<div className="hidden lg:flex items-center gap-4">
<div className="flex items-center gap-2 text-white mr-4">
<Phone size={18} className="text-primary" />
<span className="font-semibold text-sm">{data.settings.contactPhoneDisplay}</span>
</div>
{data.header.ctaButton.show && (
<Button size="sm" onClick={handleCtaClick}>{data.header.ctaButton.text}</Button>
)}
</div>
{/* Mobile Toggle */}
<button
className="lg:hidden text-white"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
>
{isMobileMenuOpen ? <X size={28} /> : <Menu size={28} />}
</button>
</div>
{/* Mobile Menu */}
{isMobileMenuOpen && (
<div className="absolute top-full left-0 w-full bg-zinc-900 border-t border-zinc-800 p-6 lg:hidden flex flex-col gap-4 shadow-2xl">
{data.header.items.map((item, index) => (
<Link
key={index}
to={item.href}
className={`text-lg font-medium hover:text-primary ${
location.pathname === item.href ? 'text-primary' : 'text-gray-200'
}`}
onClick={() => setIsMobileMenuOpen(false)}
>
{item.label}
</Link>
))}
<hr className="border-zinc-800 my-2"/>
{data.header.ctaButton.show && (
<Button className="w-full" onClick={handleCtaClick}>{data.header.ctaButton.text}</Button>
)}
</div>
)}
</Container>
</header>
);
};