Files
topsysops-app/public-site/components/Header.jsx
T
ogrechkoandClaude Sonnet 5 30e1aea20b Fix SEO/UX audit gaps: canonical tags, org schema, nav, header claims
Add canonical URLs and a sitewide Organization JSON-LD (linked via @id
to page-specific LocalBusiness/Service/Article schemas), move FAQ and
Reviews into the top nav, attach the 24/7 support claim to a tooltip
on the header badge instead of leaving it unexplained, drop the
unverifiable incidents_resolved stat from the hero terminal animation,
and clean up the empty-reviews state instead of showing a thin
placeholder.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013otXCiTZsxdZ4SJKZ9wUky
2026-08-25 23:43:17 +03:00

96 lines
4.0 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useState } from 'react';
import Link from 'next/link';
import { Sun, Moon, Menu, X, Terminal } from 'lucide-react';
import { useTheme } from './ThemeProvider.jsx';
import StatusDot from './StatusDot.jsx';
const NAV_ITEMS = [
{ href: '/', label: 'Главная' },
{ href: '/uslugi', label: 'Услуги' },
{ href: '/aktsii', label: 'Акции' },
{ href: '/keysy', label: 'Кейсы' },
{ href: '/otzyvy', label: 'Отзывы' },
{ href: '/faq', label: 'FAQ' },
{ href: '/o-kompanii', label: 'О компании' },
{ href: '/blog', label: 'Блог' },
{ href: '/kontakty', label: 'Контакты' },
];
export default function Header() {
const { dark, toggle } = useTheme();
const [open, setOpen] = useState(false);
return (
<header className="sticky top-0 z-40 backdrop-blur border-b bg-slate-50/85 border-slate-200 dark:bg-slate-950/85 dark:border-slate-800">
<div className="max-w-6xl mx-auto px-5 sm:px-8">
<div className="flex items-center justify-between h-16">
<Link href="/" className="flex items-center gap-2 font-display">
<Terminal className="h-5 w-5 text-emerald-500" />
<span className="text-base font-bold tracking-tight">TopSysOps</span>
</Link>
<nav className="hidden lg:flex items-center gap-0.5 xl:gap-1">
{NAV_ITEMS.map((item) => (
<Link
key={item.href}
href={item.href}
className="px-2.5 xl:px-3 py-2 rounded-md text-sm font-medium transition-colors text-slate-600 hover:text-slate-900 hover:bg-slate-100 dark:text-slate-300 dark:hover:text-white dark:hover:bg-slate-900"
>
{item.label}
</Link>
))}
</nav>
<div className="flex items-center gap-2">
<button
aria-label={dark ? 'Включить светлую тему' : 'Включить тёмную тему'}
onClick={toggle}
className="p-2 rounded-md transition-colors hover:bg-slate-100 text-slate-700 dark:hover:bg-slate-900 dark:text-amber-400"
>
{dark ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
</button>
<button
aria-label="Открыть меню"
onClick={() => setOpen(!open)}
className="lg:hidden p-2 rounded-md hover:bg-slate-100 dark:hover:bg-slate-900"
>
{open ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
</button>
</div>
</div>
{open && (
<nav className="lg:hidden pb-4 flex flex-col gap-1">
{NAV_ITEMS.map((item) => (
<Link
key={item.href}
href={item.href}
onClick={() => setOpen(false)}
className="text-left px-3 py-2 rounded-md text-sm font-medium text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-900"
>
{item.label}
</Link>
))}
</nav>
)}
</div>
<div className="border-t px-5 sm:px-8 py-1.5 text-xs flex items-center gap-4 max-w-6xl mx-auto border-slate-200 text-slate-500 dark:border-slate-900 dark:text-slate-400">
<StatusDot tone="ok" pulse label="система активна" mono />
<Link
href="/uslugi/support"
title="На тарифе «Премиум»: поддержка 24/7, среднее время реакции ~15 минут. На тарифах «Базовый» и «Бизнес» — по графику 3/4 или 5/2."
className="hidden sm:inline font-mono underline decoration-dotted underline-offset-2 hover:text-emerald-500"
>
24/7 · отклик ~15 мин*
</Link>
<a href="/admin" className="ml-auto underline decoration-dotted underline-offset-2 hover:text-emerald-500">
вход для сотрудников
</a>
</div>
</header>
);
}