feat(sprint-5.5): add block version snapshots with switching between versions
- Add BlockSnapshot Prisma model (html, css, version, changelog) + migration - Add API endpoints: POST/GET /blocks/snapshots, GET /blocks/snapshots/:id - BlockMetaBar: version dropdown, HTML capture on save, onSnapshotSelect prop - "Сохранить версию" now captures innerHTML snapshot + CSS and stores in DB - Selecting archived version shows stored HTML snapshot instead of live component - Yellow banner "Архивная версия" with link to return to current - Split all 8 block pages into Server Component (metadata) + Client Component - Add data-block-capture attribute for snapshot capture targeting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,291 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { LlmBlock, LlmSection, LlmTable, LlmRules } from "@/components/llm/LlmBlock";
|
||||
import { NavigationBlock } from "@/components/blocks/NavigationBlock";
|
||||
import { NAV_ITEMS } from "@/components/blocks/navData";
|
||||
import { BlockMetaBar, type SnapshotData } from "@/components/ui/BlockMetaBar";
|
||||
import { type ChangelogEntry } from "@/components/ui/BlockChangelog";
|
||||
|
||||
const BLOCK_PATH = "/blocks/navigation";
|
||||
|
||||
const LLM_NAV_TEXT = `
|
||||
БЛОК: Шапка и навигация сайта (Header)
|
||||
Источник: perm.oclinica.ru/lor — реальная шапка сайта
|
||||
Версия: v1.3
|
||||
|
||||
СТРУКТУРА ШАПКИ (2 зоны сверху вниз):
|
||||
|
||||
1. ВЕРХНЯЯ ПАНЕЛЬ (фон #fff, без рамок)
|
||||
Три столбца:
|
||||
— Столбец 1 (лево): Логотип клиники (logo-main.png, h-20)
|
||||
— Столбец 2 (центр): Три ссылки вертикально с иконкой 📍:
|
||||
· К. Цеткин, 9 (цвет #52b4bd, подчёркнутая)
|
||||
· Клиника лечения кашля и аллергии (цвет #52b4bd, подчёркнутая)
|
||||
· Центр диагностики и реабилитации (цвет #52b4bd, подчёркнутая)
|
||||
— Столбец 3 (право): Телефон «/342/ 255-53-84» (25px, bold, #000) + кнопка «Заказать звонок» (bb-btn-md bb-btn-pill)
|
||||
|
||||
2. ГЛАВНОЕ МЕНЮ (~46px, фон #fff, border-top 1px solid #e5e7eb)
|
||||
Пункты (8 штук): Клиника | ЛОР врачи | Заболевания | Вопрос-ответ | ЛОР операции | Сурдология | Цены | Контакты
|
||||
Шрифт: 18px, weight 400
|
||||
Цвет ссылок: #000
|
||||
Активный / Hover: #0089c3
|
||||
Разделители: border-right 1px solid #f3f4f6 между пунктами
|
||||
|
||||
ПРАВИЛА:
|
||||
✓ Логотип всегда кликабелен — ведёт на главную страницу раздела
|
||||
✓ Кнопка «Заказать звонок» всегда видна, pill-стиль
|
||||
✓ Телефон кликабелен (tel: ссылка)
|
||||
✓ Активный пункт меню — цвет #0089c3, остальные #000
|
||||
✕ Не добавлять пункты меню, которых нет на сайте
|
||||
✕ Не менять порядок пунктов меню
|
||||
`.trim();
|
||||
|
||||
const CHANGELOG: ChangelogEntry[] = [
|
||||
{
|
||||
version: "v1.3",
|
||||
date: "24.03.2026",
|
||||
changes: [
|
||||
"Подменю: выпадающие списки при hover для Клиника, Заболевания, Вопрос-ответ, ЛОР операции",
|
||||
"Hover-эффект: бежевый фон #f5f0e6 при наведении на пункт меню",
|
||||
"Пункты меню подчёркнуты (underline), без разделителей между ними",
|
||||
"Убрана рамка между шапкой и меню (border-top)",
|
||||
"Все пункты меню чёрного цвета #000 (было: первый #0089c3)",
|
||||
"Уменьшен padding пунктов (px-2.5 вместо px-4) — все помещаются в ширину экрана",
|
||||
],
|
||||
},
|
||||
{
|
||||
version: "v1.2",
|
||||
date: "24.03.2026",
|
||||
changes: [
|
||||
"Убрана рамка и тень вокруг шапки (как на реальном сайте)",
|
||||
"Структура: 3 столбца (логотип | ссылки вертикально | телефон+кнопка) вместо горизонтального ряда",
|
||||
"Логотип: реальный logo-main.png вместо кружка, размер h-20 (было h-12)",
|
||||
"Кнопка: bb-btn-md (было bb-btn-sm)",
|
||||
"Анатомия шапки: обновлена — 2 зоны вместо 3",
|
||||
],
|
||||
},
|
||||
{
|
||||
version: "v1.1",
|
||||
date: "24.03.2026",
|
||||
changes: [
|
||||
"Адрес: «Б. Цитная, 3» заменён на «К. Цеткин, 9»",
|
||||
"Ссылки: обновлены на «Клиника лечения кашля и аллергии» и «Центр диагностики и реабилитации»",
|
||||
"Телефон: размер 25px (было ~14px)",
|
||||
"Меню: font-size 18px (было 14px), цвет ссылок #000 (было #53514e)",
|
||||
"Цвет ссылки адреса: #52b4bd (было #0089c3)",
|
||||
"«ЛОР операции» без дефиса (было «ЛОР-операции»)",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default function NavigationPageClient() {
|
||||
const [snapshot, setSnapshot] = useState<SnapshotData | null>(null);
|
||||
|
||||
return (
|
||||
<div className="p-8 max-w-5xl mx-auto space-y-10">
|
||||
{/* Заголовок страницы */}
|
||||
<div>
|
||||
<p
|
||||
className="text-xs font-semibold uppercase tracking-widest mb-1"
|
||||
style={{ color: "var(--brand-053m)" }}
|
||||
>
|
||||
Блоки
|
||||
</p>
|
||||
<h1 className="text-2xl font-bold mb-2" style={{ color: "var(--bb-text)" }}>
|
||||
Шапка и навигация
|
||||
</h1>
|
||||
<BlockMetaBar
|
||||
path={BLOCK_PATH}
|
||||
defaultVersion="v1.3"
|
||||
defaultIsInPreview={true}
|
||||
defaultChangelog={CHANGELOG}
|
||||
onSnapshotSelect={setSnapshot}
|
||||
/>
|
||||
<p className="text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Точное воспроизведение шапки с perm.oclinica.ru/lor. Три зоны: топ-бар, логотип, главное меню.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Живой пример */}
|
||||
<section className="space-y-3">
|
||||
<h2 className="font-semibold text-base" style={{ color: "var(--bb-text)" }}>
|
||||
Живой пример
|
||||
</h2>
|
||||
{snapshot ? (
|
||||
<div className="rounded-xl" style={{ paddingBottom: 40 }}>
|
||||
<style dangerouslySetInnerHTML={{ __html: snapshot.css }} />
|
||||
<div dangerouslySetInnerHTML={{ __html: snapshot.html }} />
|
||||
</div>
|
||||
) : (
|
||||
<div data-block-capture={BLOCK_PATH} className="rounded-xl" style={{ paddingBottom: 40 }}>
|
||||
<NavigationBlock />
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
|
||||
{/* Анатомия */}
|
||||
<section className="space-y-4">
|
||||
<h2 className="font-semibold text-base" style={{ color: "var(--bb-text)" }}>
|
||||
Анатомия шапки
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{[
|
||||
{
|
||||
zone: "1. Верхняя панель",
|
||||
bg: "#f0f9ff",
|
||||
desc: "Три столбца: логотип (logo-main.png) | три ссылки вертикально с 📍 (К. Цеткин 9, Клиника кашля, Центр диагностики) | телефон 25px + кнопка «Заказать звонок» (pill)",
|
||||
details: "Фон: #fff · Без рамок · Ссылки: #52b4bd, подчёркнутые",
|
||||
},
|
||||
{
|
||||
zone: "2. Главное меню",
|
||||
bg: "#fefce8",
|
||||
desc: "8 горизонтальных пунктов: Клиника | ЛОР врачи | Заболевания | Вопрос-ответ | ЛОР операции | Сурдология | Цены | Контакты",
|
||||
details: "Фон: #fff · border-top · 18px · Активный: #0089c3, остальные: #000",
|
||||
},
|
||||
].map((z) => (
|
||||
<div
|
||||
key={z.zone}
|
||||
className="rounded-xl p-4 space-y-2"
|
||||
style={{ background: z.bg, border: "1px solid var(--bb-border)" }}
|
||||
>
|
||||
<p className="font-semibold text-sm" style={{ color: "var(--bb-text)" }}>
|
||||
{z.zone}
|
||||
</p>
|
||||
<p className="text-xs" style={{ color: "var(--bb-text-muted)" }}>
|
||||
{z.desc}
|
||||
</p>
|
||||
<p className="text-[11px] font-mono mt-1" style={{ color: "var(--bb-text-muted)" }}>
|
||||
{z.details}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Пункты меню */}
|
||||
<section className="space-y-3">
|
||||
<h2 className="font-semibold text-base" style={{ color: "var(--bb-text)" }}>
|
||||
Пункты главного меню
|
||||
</h2>
|
||||
<div className="rounded-xl border overflow-visible" style={{ borderColor: "var(--bb-border)", background: "#fff" }}>
|
||||
<div className="flex items-center justify-center flex-wrap" style={{ borderTop: "1px solid #e5e7eb" }}>
|
||||
{NAV_ITEMS.map((item) => (
|
||||
<div key={item.label} className="bb-nav-item-wrap relative group">
|
||||
<a
|
||||
href="#"
|
||||
className="bb-nav-item px-2.5 py-3 whitespace-nowrap inline-flex items-center gap-1"
|
||||
style={{
|
||||
fontSize: 18,
|
||||
color: "#000",
|
||||
fontWeight: 400,
|
||||
textDecoration: "underline",
|
||||
textUnderlineOffset: "4px",
|
||||
}}
|
||||
>
|
||||
{item.label}
|
||||
{item.submenu.length > 0 && (
|
||||
<span className="text-xs" style={{ color: "#9ca3af", textDecoration: "none", display: "inline-block" }}>▾</span>
|
||||
)}
|
||||
</a>
|
||||
{item.submenu.length > 0 && (
|
||||
<div
|
||||
className="absolute left-0 top-full z-50 hidden group-hover:block min-w-[220px] py-1 rounded shadow-lg"
|
||||
style={{ background: "#fff", border: "1px solid #e5e7eb" }}
|
||||
>
|
||||
{item.submenu.map((sub) => (
|
||||
<a
|
||||
key={sub}
|
||||
href="#"
|
||||
className="block px-4 py-2 text-sm bb-nav-sub-item"
|
||||
style={{ color: "#333", textDecoration: "none" }}
|
||||
>
|
||||
{sub}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Порядок фиксирован. Все пункты чёрные (#000), подчёркнуты. Hover — бежевый фон #f5f0e6. ▾ — выпадающее подменю при наведении.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Токены */}
|
||||
<section className="space-y-3">
|
||||
<h2 className="font-semibold text-base" style={{ color: "var(--bb-text)" }}>
|
||||
Цвета и токены
|
||||
</h2>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
||||
{[
|
||||
{ label: "Фон шапки", value: "#ffffff", token: "—" },
|
||||
{ label: "Пункты меню", value: "#000000", token: "—" },
|
||||
{ label: "Hover фон меню", value: "#f5f0e6", token: "bb-nav-item:hover" },
|
||||
{ label: "Ссылки адресов", value: "#52b4bd", token: "—" },
|
||||
{ label: "Кнопка «Заказать»", value: "#e9e4d4", token: "bb-btn-pill" },
|
||||
{ label: "Подменю фон", value: "#ffffff", token: "—" },
|
||||
{ label: "Подменю hover", value: "#f5f0e6", token: "bb-nav-sub-item:hover" },
|
||||
{ label: "Телефон", value: "#000000", token: "25px, bold" },
|
||||
].map((t) => (
|
||||
<div
|
||||
key={t.label}
|
||||
className="p-3 rounded-xl space-y-2"
|
||||
style={{ background: "var(--bb-sidebar-bg)", border: "1px solid var(--bb-border)" }}
|
||||
>
|
||||
<div
|
||||
className="w-8 h-8 rounded border"
|
||||
style={{ background: t.value, borderColor: "var(--bb-border)" }}
|
||||
/>
|
||||
<p className="text-xs font-medium" style={{ color: "var(--bb-text)" }}>
|
||||
{t.label}
|
||||
</p>
|
||||
<p className="text-[10px] font-mono" style={{ color: "var(--bb-text-muted)" }}>
|
||||
{t.value}
|
||||
</p>
|
||||
<p className="text-[10px]" style={{ color: "var(--bb-text-muted)" }}>
|
||||
{t.token}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* LLM блок */}
|
||||
<LlmBlock path="/blocks/navigation" version="v1.3" specText={LLM_NAV_TEXT}>
|
||||
<LlmSection title="Зоны шапки" />
|
||||
<LlmTable
|
||||
headers={["Зона", "Фон", "Содержимое"]}
|
||||
rows={[
|
||||
["Верхняя панель", "#fff, без рамок", "Логотип (logo-main.png) | 3 ссылки вертикально с 📍 (#52b4bd) | Телефон 25px + кнопка pill"],
|
||||
["Главное меню", "#fff, border-top", "8 пунктов 18px: Клиника / ЛОР врачи / Заболевания / Вопрос-ответ / ЛОР операции / Сурдология / Цены / Контакты"],
|
||||
]}
|
||||
/>
|
||||
<LlmSection title="Цвета" />
|
||||
<LlmTable
|
||||
headers={["Элемент", "Цвет", "Токен"]}
|
||||
rows={[
|
||||
["Фон шапки", "#ffffff", "—"],
|
||||
["Ссылки меню (default)", "#000000", "—"],
|
||||
["Активный пункт / hover", "#0089c3", "--brand-053m"],
|
||||
["Кнопка «Заказать звонок»", "#e9e4d4 / border #d5cfbd", "bb-btn-pill"],
|
||||
["Телефон", "#111827, font-weight bold", "—"],
|
||||
]}
|
||||
/>
|
||||
<LlmSection title="Правила" />
|
||||
<LlmRules
|
||||
rules={[
|
||||
{ ok: true, text: "Логотип ведёт на главную страницу раздела" },
|
||||
{ ok: true, text: "Кнопка «Заказать звонок» всегда видна, pill-стиль" },
|
||||
{ ok: true, text: "Телефон — кликабельная ссылка tel:" },
|
||||
{ ok: true, text: "Активный пункт меню — цвет #0089c3" },
|
||||
{ ok: false, text: "Не добавлять пункты меню, которых нет на сайте" },
|
||||
{ ok: false, text: "Не менять порядок 8 пунктов меню" },
|
||||
]}
|
||||
/>
|
||||
</LlmBlock>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,276 +1,10 @@
|
||||
import type { Metadata } from "next";
|
||||
import { LlmBlock, LlmSection, LlmTable, LlmRules } from "@/components/llm/LlmBlock";
|
||||
import { NavigationBlock } from "@/components/blocks/NavigationBlock";
|
||||
import { NAV_ITEMS } from "@/components/blocks/navData";
|
||||
import { BlockMetaBar } from "@/components/ui/BlockMetaBar";
|
||||
import { type ChangelogEntry } from "@/components/ui/BlockChangelog";
|
||||
import NavigationPageClient from "./NavigationPageClient";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Шапка и навигация. Цифровой брендбук Клиники ухо, горло, нос им. проф. Е.Н.Оленевой",
|
||||
};
|
||||
|
||||
const LLM_NAV_TEXT = `
|
||||
БЛОК: Шапка и навигация сайта (Header)
|
||||
Источник: perm.oclinica.ru/lor — реальная шапка сайта
|
||||
Версия: v1.3
|
||||
|
||||
СТРУКТУРА ШАПКИ (2 зоны сверху вниз):
|
||||
|
||||
1. ВЕРХНЯЯ ПАНЕЛЬ (фон #fff, без рамок)
|
||||
Три столбца:
|
||||
— Столбец 1 (лево): Логотип клиники (logo-main.png, h-20)
|
||||
— Столбец 2 (центр): Три ссылки вертикально с иконкой 📍:
|
||||
· К. Цеткин, 9 (цвет #52b4bd, подчёркнутая)
|
||||
· Клиника лечения кашля и аллергии (цвет #52b4bd, подчёркнутая)
|
||||
· Центр диагностики и реабилитации (цвет #52b4bd, подчёркнутая)
|
||||
— Столбец 3 (право): Телефон «/342/ 255-53-84» (25px, bold, #000) + кнопка «Заказать звонок» (bb-btn-md bb-btn-pill)
|
||||
|
||||
2. ГЛАВНОЕ МЕНЮ (~46px, фон #fff, border-top 1px solid #e5e7eb)
|
||||
Пункты (8 штук): Клиника | ЛОР врачи | Заболевания | Вопрос-ответ | ЛОР операции | Сурдология | Цены | Контакты
|
||||
Шрифт: 18px, weight 400
|
||||
Цвет ссылок: #000
|
||||
Активный / Hover: #0089c3
|
||||
Разделители: border-right 1px solid #f3f4f6 между пунктами
|
||||
|
||||
ПРАВИЛА:
|
||||
✓ Логотип всегда кликабелен — ведёт на главную страницу раздела
|
||||
✓ Кнопка «Заказать звонок» всегда видна, pill-стиль
|
||||
✓ Телефон кликабелен (tel: ссылка)
|
||||
✓ Активный пункт меню — цвет #0089c3, остальные #000
|
||||
✕ Не добавлять пункты меню, которых нет на сайте
|
||||
✕ Не менять порядок пунктов меню
|
||||
`.trim();
|
||||
|
||||
const CHANGELOG: ChangelogEntry[] = [
|
||||
{
|
||||
version: "v1.3",
|
||||
date: "24.03.2026",
|
||||
changes: [
|
||||
"Подменю: выпадающие списки при hover для Клиника, Заболевания, Вопрос-ответ, ЛОР операции",
|
||||
"Hover-эффект: бежевый фон #f5f0e6 при наведении на пункт меню",
|
||||
"Пункты меню подчёркнуты (underline), без разделителей между ними",
|
||||
"Убрана рамка между шапкой и меню (border-top)",
|
||||
"Все пункты меню чёрного цвета #000 (было: первый #0089c3)",
|
||||
"Уменьшен padding пунктов (px-2.5 вместо px-4) — все помещаются в ширину экрана",
|
||||
],
|
||||
},
|
||||
{
|
||||
version: "v1.2",
|
||||
date: "24.03.2026",
|
||||
changes: [
|
||||
"Убрана рамка и тень вокруг шапки (как на реальном сайте)",
|
||||
"Структура: 3 столбца (логотип | ссылки вертикально | телефон+кнопка) вместо горизонтального ряда",
|
||||
"Логотип: реальный logo-main.png вместо кружка, размер h-20 (было h-12)",
|
||||
"Кнопка: bb-btn-md (было bb-btn-sm)",
|
||||
"Анатомия шапки: обновлена — 2 зоны вместо 3",
|
||||
],
|
||||
},
|
||||
{
|
||||
version: "v1.1",
|
||||
date: "24.03.2026",
|
||||
changes: [
|
||||
"Адрес: «Б. Цитная, 3» заменён на «К. Цеткин, 9»",
|
||||
"Ссылки: обновлены на «Клиника лечения кашля и аллергии» и «Центр диагностики и реабилитации»",
|
||||
"Телефон: размер 25px (было ~14px)",
|
||||
"Меню: font-size 18px (было 14px), цвет ссылок #000 (было #53514e)",
|
||||
"Цвет ссылки адреса: #52b4bd (было #0089c3)",
|
||||
"«ЛОР операции» без дефиса (было «ЛОР-операции»)",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default function NavigationPage() {
|
||||
return (
|
||||
<div className="p-8 max-w-5xl mx-auto space-y-10">
|
||||
{/* Заголовок страницы */}
|
||||
<div>
|
||||
<p
|
||||
className="text-xs font-semibold uppercase tracking-widest mb-1"
|
||||
style={{ color: "var(--brand-053m)" }}
|
||||
>
|
||||
Блоки
|
||||
</p>
|
||||
<h1 className="text-2xl font-bold mb-2" style={{ color: "var(--bb-text)" }}>
|
||||
Шапка и навигация
|
||||
</h1>
|
||||
<BlockMetaBar path="/blocks/navigation" defaultVersion="v1.3" defaultIsInPreview={true} defaultChangelog={CHANGELOG} />
|
||||
<p className="text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Точное воспроизведение шапки с perm.oclinica.ru/lor. Три зоны: топ-бар, логотип, главное меню.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Живой пример */}
|
||||
<section className="space-y-3">
|
||||
<h2 className="font-semibold text-base" style={{ color: "var(--bb-text)" }}>
|
||||
Живой пример
|
||||
</h2>
|
||||
<div className="rounded-xl" style={{ paddingBottom: 40 }}>
|
||||
<NavigationBlock />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Анатомия */}
|
||||
<section className="space-y-4">
|
||||
<h2 className="font-semibold text-base" style={{ color: "var(--bb-text)" }}>
|
||||
Анатомия шапки
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{[
|
||||
{
|
||||
zone: "1. Верхняя панель",
|
||||
bg: "#f0f9ff",
|
||||
desc: "Три столбца: логотип (logo-main.png) | три ссылки вертикально с 📍 (К. Цеткин 9, Клиника кашля, Центр диагностики) | телефон 25px + кнопка «Заказать звонок» (pill)",
|
||||
details: "Фон: #fff · Без рамок · Ссылки: #52b4bd, подчёркнутые",
|
||||
},
|
||||
{
|
||||
zone: "2. Главное меню",
|
||||
bg: "#fefce8",
|
||||
desc: "8 горизонтальных пунктов: Клиника | ЛОР врачи | Заболевания | Вопрос-ответ | ЛОР операции | Сурдология | Цены | Контакты",
|
||||
details: "Фон: #fff · border-top · 18px · Активный: #0089c3, остальные: #000",
|
||||
},
|
||||
].map((z) => (
|
||||
<div
|
||||
key={z.zone}
|
||||
className="rounded-xl p-4 space-y-2"
|
||||
style={{ background: z.bg, border: "1px solid var(--bb-border)" }}
|
||||
>
|
||||
<p className="font-semibold text-sm" style={{ color: "var(--bb-text)" }}>
|
||||
{z.zone}
|
||||
</p>
|
||||
<p className="text-xs" style={{ color: "var(--bb-text-muted)" }}>
|
||||
{z.desc}
|
||||
</p>
|
||||
<p className="text-[11px] font-mono mt-1" style={{ color: "var(--bb-text-muted)" }}>
|
||||
{z.details}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Пункты меню */}
|
||||
<section className="space-y-3">
|
||||
<h2 className="font-semibold text-base" style={{ color: "var(--bb-text)" }}>
|
||||
Пункты главного меню
|
||||
</h2>
|
||||
<div className="rounded-xl border overflow-visible" style={{ borderColor: "var(--bb-border)", background: "#fff" }}>
|
||||
<div className="flex items-center justify-center flex-wrap" style={{ borderTop: "1px solid #e5e7eb" }}>
|
||||
{NAV_ITEMS.map((item, i) => (
|
||||
<div key={item.label} className="bb-nav-item-wrap relative group">
|
||||
<a
|
||||
href="#"
|
||||
className="bb-nav-item px-2.5 py-3 whitespace-nowrap inline-flex items-center gap-1"
|
||||
style={{
|
||||
fontSize: 18,
|
||||
color: "#000",
|
||||
fontWeight: 400,
|
||||
textDecoration: "underline",
|
||||
textUnderlineOffset: "4px",
|
||||
}}
|
||||
>
|
||||
{item.label}
|
||||
{item.submenu.length > 0 && (
|
||||
<span className="text-xs" style={{ color: "#9ca3af", textDecoration: "none", display: "inline-block" }}>▾</span>
|
||||
)}
|
||||
</a>
|
||||
{item.submenu.length > 0 && (
|
||||
<div
|
||||
className="absolute left-0 top-full z-50 hidden group-hover:block min-w-[220px] py-1 rounded shadow-lg"
|
||||
style={{ background: "#fff", border: "1px solid #e5e7eb" }}
|
||||
>
|
||||
{item.submenu.map((sub) => (
|
||||
<a
|
||||
key={sub}
|
||||
href="#"
|
||||
className="block px-4 py-2 text-sm bb-nav-sub-item"
|
||||
style={{ color: "#333", textDecoration: "none" }}
|
||||
>
|
||||
{sub}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Порядок фиксирован. Все пункты чёрные (#000), подчёркнуты. Hover — бежевый фон #f5f0e6. ▾ — выпадающее подменю при наведении.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Токены */}
|
||||
<section className="space-y-3">
|
||||
<h2 className="font-semibold text-base" style={{ color: "var(--bb-text)" }}>
|
||||
Цвета и токены
|
||||
</h2>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
||||
{[
|
||||
{ label: "Фон шапки", value: "#ffffff", token: "—" },
|
||||
{ label: "Пункты меню", value: "#000000", token: "—" },
|
||||
{ label: "Hover фон меню", value: "#f5f0e6", token: "bb-nav-item:hover" },
|
||||
{ label: "Ссылки адресов", value: "#52b4bd", token: "—" },
|
||||
{ label: "Кнопка «Заказать»", value: "#e9e4d4", token: "bb-btn-pill" },
|
||||
{ label: "Подменю фон", value: "#ffffff", token: "—" },
|
||||
{ label: "Подменю hover", value: "#f5f0e6", token: "bb-nav-sub-item:hover" },
|
||||
{ label: "Телефон", value: "#000000", token: "25px, bold" },
|
||||
].map((t) => (
|
||||
<div
|
||||
key={t.label}
|
||||
className="p-3 rounded-xl space-y-2"
|
||||
style={{ background: "var(--bb-sidebar-bg)", border: "1px solid var(--bb-border)" }}
|
||||
>
|
||||
<div
|
||||
className="w-8 h-8 rounded border"
|
||||
style={{ background: t.value, borderColor: "var(--bb-border)" }}
|
||||
/>
|
||||
<p className="text-xs font-medium" style={{ color: "var(--bb-text)" }}>
|
||||
{t.label}
|
||||
</p>
|
||||
<p className="text-[10px] font-mono" style={{ color: "var(--bb-text-muted)" }}>
|
||||
{t.value}
|
||||
</p>
|
||||
<p className="text-[10px]" style={{ color: "var(--bb-text-muted)" }}>
|
||||
{t.token}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* LLM блок */}
|
||||
<LlmBlock path="/blocks/navigation" version="v1.3" specText={LLM_NAV_TEXT}>
|
||||
<LlmSection title="Зоны шапки" />
|
||||
<LlmTable
|
||||
headers={["Зона", "Фон", "Содержимое"]}
|
||||
rows={[
|
||||
["Верхняя панель", "#fff, без рамок", "Логотип (logo-main.png) | 3 ссылки вертикально с 📍 (#52b4bd) | Телефон 25px + кнопка pill"],
|
||||
["Главное меню", "#fff, border-top", "8 пунктов 18px: Клиника / ЛОР врачи / Заболевания / Вопрос-ответ / ЛОР операции / Сурдология / Цены / Контакты"],
|
||||
]}
|
||||
/>
|
||||
<LlmSection title="Цвета" />
|
||||
<LlmTable
|
||||
headers={["Элемент", "Цвет", "Токен"]}
|
||||
rows={[
|
||||
["Фон шапки", "#ffffff", "—"],
|
||||
["Ссылки меню (default)", "#000000", "—"],
|
||||
["Активный пункт / hover", "#0089c3", "--brand-053m"],
|
||||
["Кнопка «Заказать звонок»", "#e9e4d4 / border #d5cfbd", "bb-btn-pill"],
|
||||
["Телефон", "#111827, font-weight bold", "—"],
|
||||
]}
|
||||
/>
|
||||
<LlmSection title="Правила" />
|
||||
<LlmRules
|
||||
rules={[
|
||||
{ ok: true, text: "Логотип ведёт на главную страницу раздела" },
|
||||
{ ok: true, text: "Кнопка «Заказать звонок» всегда видна, pill-стиль" },
|
||||
{ ok: true, text: "Телефон — кликабельная ссылка tel:" },
|
||||
{ ok: true, text: "Активный пункт меню — цвет #0089c3" },
|
||||
{ ok: false, text: "Не добавлять пункты меню, которых нет на сайте" },
|
||||
{ ok: false, text: "Не менять порядок 8 пунктов меню" },
|
||||
]}
|
||||
/>
|
||||
</LlmBlock>
|
||||
</div>
|
||||
);
|
||||
return <NavigationPageClient />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user