feat(sprint-5.5): add "Save version" button, update navigation block and block components
- Add "Сохранить версию" button to BlockMetaBar that persists current version + changelog from code to PostgreSQL via PATCH API - Update navigation page: menu items section now renders like live example with underlined links, hover dropdowns, and submenus - Restore uncommitted changes from previous session (thirsty-mayer worktree): navigation v1.3 with dropdowns, updated hero/ceo/doctors/reviews/news/ contact-forms/footer blocks, navData.ts extraction, seed updates - Extract nav menu data to shared navData.ts module Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+40
-5
@@ -9,18 +9,36 @@ const BLOCKS = [
|
||||
{
|
||||
path: '/blocks/navigation',
|
||||
name: 'Шапка / Навигация',
|
||||
version: 'v1.0',
|
||||
version: 'v1.3',
|
||||
isInPreview: true,
|
||||
changelog: [
|
||||
{ version: 'v1.3', date: '24.03.2026', changes: [
|
||||
'Подменю: выпадающие списки при hover',
|
||||
'Hover-эффект: бежевый фон #f5f0e6',
|
||||
'Пункты подчёркнуты, без разделителей',
|
||||
'Все пункты чёрного цвета #000',
|
||||
]},
|
||||
{ version: 'v1.2', date: '24.03.2026', changes: [
|
||||
'Убрана рамка и тень вокруг шапки',
|
||||
'3 столбца: логотип | ссылки | телефон+кнопка',
|
||||
'Реальный логотип logo-main.png',
|
||||
]},
|
||||
{ version: 'v1.1', date: '24.03.2026', changes: [
|
||||
'Адрес: «К. Цеткин, 9», ссылки, телефон 25px, меню 18px',
|
||||
]},
|
||||
{ version: 'v1.0', date: '23.03.2026', changes: ['Топ-бар, логотип, главное меню из 8 пунктов'] },
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/blocks/hero',
|
||||
name: 'Hero-баннер',
|
||||
version: 'v1.2',
|
||||
version: 'v1.3',
|
||||
isInPreview: true,
|
||||
changelog: [
|
||||
{ version: 'v1.3', date: '24.03.2026', changes: [
|
||||
'Счётчик: «Поделиться ✉ 98572» (было «👁 98 573 просмотра»)',
|
||||
'Убраны кнопки VK/FB/TW',
|
||||
]},
|
||||
{ version: 'v1.2', date: '24.03.2026', changes: [
|
||||
'H1: цвет #cb9768, размер 36px (было ~20px #53514e)',
|
||||
'Заголовок баннера: 22px #333 (было 16px #111827)',
|
||||
@@ -36,9 +54,13 @@ const BLOCKS = [
|
||||
{
|
||||
path: '/blocks/ceo',
|
||||
name: 'Вводный текст (CEO-блок)',
|
||||
version: 'v1.0',
|
||||
version: 'v1.1',
|
||||
isInPreview: false,
|
||||
changelog: [
|
||||
{ version: 'v1.1', date: '24.03.2026', changes: [
|
||||
'Адрес: «ул. Цитная, 9» → «ул. Клары Цеткин, 9»',
|
||||
'Цвет ссылок: #52b4bd (было #0089c3)',
|
||||
]},
|
||||
{ version: 'v1.0', date: '23.03.2026', changes: ['Текст специализации клиники, вопросы-стимулы'] },
|
||||
],
|
||||
},
|
||||
@@ -76,9 +98,13 @@ const BLOCKS = [
|
||||
{
|
||||
path: '/blocks/contact-forms',
|
||||
name: 'Формы записи',
|
||||
version: 'v1.1',
|
||||
version: 'v1.2',
|
||||
isInPreview: true,
|
||||
changelog: [
|
||||
{ version: 'v1.2', date: '24.03.2026', changes: [
|
||||
'Кнопка: bb-btn-lg 18px bold (было bb-btn-md 14px)',
|
||||
'border-radius кнопки: 4px (было 7px)',
|
||||
]},
|
||||
{ version: 'v1.1', date: '24.03.2026', changes: [
|
||||
'H2: 36px #000000',
|
||||
'Фон формы 1: #b8e6ed → #d4f6f8',
|
||||
@@ -107,9 +133,18 @@ const BLOCKS = [
|
||||
{
|
||||
path: '/blocks/contact',
|
||||
name: 'Подвал / Контакт',
|
||||
version: 'v1.0',
|
||||
version: 'v1.1',
|
||||
isInPreview: false,
|
||||
changelog: [
|
||||
{ version: 'v1.1', date: '24.03.2026', changes: [
|
||||
'Колонка «О клинике»: 13 ссылок по реальному сайту (было 7)',
|
||||
'Колонка «Заболевания»: 5 категорий (было 6 конкретных диагнозов)',
|
||||
'Колонка «Вопрос-ответ»: 6 пунктов по реальному сайту',
|
||||
'Колонка «Операции»: 11 операций (было 6)',
|
||||
'Два адреса: Клары Цеткин 9 + Газеты Звезда 31А',
|
||||
'Два графика работы по филиалам',
|
||||
'Соцсети: добавлен Дзен',
|
||||
]},
|
||||
{ version: 'v1.0', date: '23.03.2026', changes: ['4 колонки ссылок, адрес, часы работы'] },
|
||||
],
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import { LlmBlock, LlmSection, LlmTable, LlmRules } from "@/components/llm/LlmBlock";
|
||||
import { BlockMetaBar } from "@/components/ui/BlockMetaBar";
|
||||
import { type ChangelogEntry } from "@/components/ui/BlockChangelog";
|
||||
import { CeoBlock, CEO_QUESTIONS } from "@/components/blocks/CeoBlock";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
@@ -10,7 +11,7 @@ export const metadata: Metadata = {
|
||||
const LLM_CEO_TEXT = `
|
||||
БЛОК: Вводный текст клиники (CEO-блок)
|
||||
Источник: perm.oclinica.ru/lor — секция после баннера
|
||||
Версия: v1.0
|
||||
Версия: v1.1
|
||||
|
||||
НАЗНАЧЕНИЕ:
|
||||
Информационный блок под hero-баннером. Рассказывает о специализации клиники
|
||||
@@ -49,6 +50,17 @@ const LLM_CEO_TEXT = `
|
||||
`.trim();
|
||||
|
||||
|
||||
const CHANGELOG: ChangelogEntry[] = [
|
||||
{
|
||||
version: "v1.1",
|
||||
date: "24.03.2026",
|
||||
changes: [
|
||||
"Адрес: «ул. Цитная, 9» заменён на «ул. Клары Цеткин, 9»",
|
||||
"Цвет ссылок: #52b4bd (было #0089c3)",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default function CeoPage() {
|
||||
return (
|
||||
<div className="p-8 max-w-5xl mx-auto space-y-10">
|
||||
@@ -63,7 +75,7 @@ export default function CeoPage() {
|
||||
<h1 className="text-2xl font-bold mb-2" style={{ color: "var(--bb-text)" }}>
|
||||
Вводный текст (CEO-блок)
|
||||
</h1>
|
||||
<BlockMetaBar path="/blocks/ceo" defaultVersion="v1.0" defaultIsInPreview={false} />
|
||||
<BlockMetaBar path="/blocks/ceo" defaultVersion="v1.1" defaultIsInPreview={false} defaultChangelog={CHANGELOG} />
|
||||
<p className="text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Блок после hero-баннера на perm.oclinica.ru/lor. Описание специализации клиники
|
||||
+ вопросы-стимулы для пациентов.
|
||||
@@ -152,7 +164,7 @@ export default function CeoPage() {
|
||||
</section>
|
||||
|
||||
{/* LLM блок */}
|
||||
<LlmBlock path="/blocks/ceo" version="v1.0" specText={LLM_CEO_TEXT}>
|
||||
<LlmBlock path="/blocks/ceo" version="v1.1" specText={LLM_CEO_TEXT}>
|
||||
<LlmSection title="Структура блока" />
|
||||
<LlmTable
|
||||
headers={["Часть", "Содержимое", "Примечание"]}
|
||||
|
||||
@@ -11,7 +11,7 @@ export const metadata: Metadata = {
|
||||
const LLM_FORMS_TEXT = `
|
||||
БЛОК: Формы записи и обратной связи
|
||||
Источник: perm.oclinica.ru/lor — два блока форм на одной странице
|
||||
Версия: v1.1
|
||||
Версия: v1.2
|
||||
|
||||
ФОРМА 1: «Будьте здоровы!» (форма записи на приём)
|
||||
Позиция: после блока отзывов
|
||||
@@ -52,6 +52,14 @@ const LLM_FORMS_TEXT = `
|
||||
`.trim();
|
||||
|
||||
const CHANGELOG: ChangelogEntry[] = [
|
||||
{
|
||||
version: "v1.2",
|
||||
date: "24.03.2026",
|
||||
changes: [
|
||||
"Кнопка: bb-btn-md заменена на bb-btn-lg (18px, bold, как на реальном сайте)",
|
||||
"border-radius кнопки: 7px исправлен на 4px (исправлено в globals.css)",
|
||||
],
|
||||
},
|
||||
{
|
||||
version: "v1.1",
|
||||
date: "24.03.2026",
|
||||
@@ -77,7 +85,7 @@ export default function ContactFormsPage() {
|
||||
<h1 className="text-2xl font-bold mb-2" style={{ color: "var(--bb-text)" }}>
|
||||
Формы записи
|
||||
</h1>
|
||||
<BlockMetaBar path="/blocks/contact-forms" defaultVersion="v1.1" defaultIsInPreview={false} defaultChangelog={CHANGELOG} />
|
||||
<BlockMetaBar path="/blocks/contact-forms" defaultVersion="v1.2" defaultIsInPreview={false} defaultChangelog={CHANGELOG} />
|
||||
<p className="text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Два блока форм с perm.oclinica.ru/lor — запись на приём и запрос стоимости операции.
|
||||
</p>
|
||||
@@ -126,7 +134,7 @@ export default function ContactFormsPage() {
|
||||
</section>
|
||||
|
||||
{/* LLM блок */}
|
||||
<LlmBlock path="/blocks/contact-forms" version="v1.1" specText={LLM_FORMS_TEXT}>
|
||||
<LlmBlock path="/blocks/contact-forms" version="v1.2" specText={LLM_FORMS_TEXT}>
|
||||
<LlmSection title="Форма 1 — Запись на приём" />
|
||||
<LlmTable
|
||||
headers={["Поле", "Тип", "Placeholder"]}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import { LlmBlock, LlmSection, LlmTable, LlmRules } from "@/components/llm/LlmBlock";
|
||||
import { BlockMetaBar } from "@/components/ui/BlockMetaBar";
|
||||
import { type ChangelogEntry } from "@/components/ui/BlockChangelog";
|
||||
import { FooterBlock } from "@/components/blocks/FooterBlock";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
@@ -34,7 +35,7 @@ const FOOTER_COLUMNS = [
|
||||
const LLM_FOOTER_TEXT = `
|
||||
БЛОК: Подвал сайта (Footer)
|
||||
Источник: perm.oclinica.ru/lor — нижняя часть страницы
|
||||
Версия: v1.0
|
||||
Версия: v1.1
|
||||
|
||||
СТРУКТУРА ПОДВАЛА:
|
||||
|
||||
@@ -70,6 +71,22 @@ const LLM_FOOTER_TEXT = `
|
||||
✕ Не менять структуру 4 колонок
|
||||
`.trim();
|
||||
|
||||
const CHANGELOG: ChangelogEntry[] = [
|
||||
{
|
||||
version: "v1.1",
|
||||
date: "24.03.2026",
|
||||
changes: [
|
||||
"Колонка «О клинике»: обновлены все ссылки по реальному сайту (13 ссылок)",
|
||||
"Колонка «Заболевания»: обновлены ссылки (5 категорий)",
|
||||
"Колонка «Вопрос-ответ»: обновлены ссылки (6 пунктов)",
|
||||
"Колонка «Операции»: обновлены ссылки (11 операций, было 6)",
|
||||
"Два адреса: Клары Цеткин, 9 + Газеты Звезда, 31А",
|
||||
"Два графика работы по филиалам",
|
||||
"Соцсети: добавлен Дзен",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default function ContactFooterPage() {
|
||||
return (
|
||||
<div className="p-8 max-w-5xl mx-auto space-y-10">
|
||||
@@ -84,7 +101,7 @@ export default function ContactFooterPage() {
|
||||
<h1 className="text-2xl font-bold mb-2" style={{ color: "var(--bb-text)" }}>
|
||||
Подвал (Footer)
|
||||
</h1>
|
||||
<BlockMetaBar path="/blocks/contact" defaultVersion="v1.0" defaultIsInPreview={false} />
|
||||
<BlockMetaBar path="/blocks/contact" defaultVersion="v1.1" defaultIsInPreview={false} defaultChangelog={CHANGELOG} />
|
||||
<p className="text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Подвал сайта с perm.oclinica.ru — 4 колонки ссылок, логотип, адрес, часы работы, соцсети.
|
||||
</p>
|
||||
@@ -122,7 +139,7 @@ export default function ContactFooterPage() {
|
||||
</section>
|
||||
|
||||
{/* LLM блок */}
|
||||
<LlmBlock path="/blocks/contact" version="v1.0" specText={LLM_FOOTER_TEXT}>
|
||||
<LlmBlock path="/blocks/contact" version="v1.1" specText={LLM_FOOTER_TEXT}>
|
||||
<LlmSection title="Структура подвала" />
|
||||
<LlmTable
|
||||
headers={["Зона", "Содержимое", "Фон"]}
|
||||
|
||||
@@ -11,7 +11,7 @@ export const metadata: Metadata = {
|
||||
const LLM_HERO_TEXT = `
|
||||
БЛОК: Hero-баннер (главный баннер страницы)
|
||||
Источник: perm.oclinica.ru/lor — реальный баннер раздела ЛОР
|
||||
Версия: v1.2
|
||||
Версия: v1.3
|
||||
|
||||
ЗАГОЛОВОК СТРАНИЦЫ (H1, над баннером):
|
||||
«ЛОР Клиника ухо, горло, нос - медицинский центр лечения ЛОР заболеваний у детей и взрослых»
|
||||
@@ -52,6 +52,14 @@ const LLM_HERO_TEXT = `
|
||||
`.trim();
|
||||
|
||||
const CHANGELOG: ChangelogEntry[] = [
|
||||
{
|
||||
version: "v1.3",
|
||||
date: "24.03.2026",
|
||||
changes: [
|
||||
"Счётчик: «98 573 просмотра» заменён на «Поделиться / 98572» (как на реальном сайте)",
|
||||
"Убраны кнопки VK/FB/TW",
|
||||
],
|
||||
},
|
||||
{
|
||||
version: "v1.2",
|
||||
date: "24.03.2026",
|
||||
@@ -86,7 +94,7 @@ export default function HeroPage() {
|
||||
<h1 className="text-2xl font-bold mb-2" style={{ color: "var(--bb-text)" }}>
|
||||
Hero-баннер
|
||||
</h1>
|
||||
<BlockMetaBar path="/blocks/hero" defaultVersion="v1.2" defaultIsInPreview={true} defaultChangelog={CHANGELOG} />
|
||||
<BlockMetaBar path="/blocks/hero" defaultVersion="v1.3" defaultIsInPreview={true} defaultChangelog={CHANGELOG} />
|
||||
<p className="text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Главный баннер страницы раздела ЛОР — perm.oclinica.ru/lor. Двухколоночный блок, единый светло-кремовый фон{" "}
|
||||
<strong>#f9f4e7</strong>.
|
||||
@@ -161,7 +169,7 @@ export default function HeroPage() {
|
||||
</section>
|
||||
|
||||
{/* LLM блок */}
|
||||
<LlmBlock path="/blocks/hero" version="v1.2" specText={LLM_HERO_TEXT}>
|
||||
<LlmBlock path="/blocks/hero" version="v1.3" specText={LLM_HERO_TEXT}>
|
||||
<LlmSection title="Структура баннера" />
|
||||
<LlmTable
|
||||
headers={["Зона", "Ширина", "Фон", "Содержимое"]}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import type { Metadata } from "next";
|
||||
import { LlmBlock, LlmSection, LlmTable, LlmRules } from "@/components/llm/LlmBlock";
|
||||
import { NavigationBlock, NAV_ITEMS } from "@/components/blocks/NavigationBlock";
|
||||
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";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Шапка и навигация. Цифровой брендбук Клиники ухо, горло, нос им. проф. Е.Н.Оленевой",
|
||||
@@ -10,40 +12,73 @@ export const metadata: Metadata = {
|
||||
const LLM_NAV_TEXT = `
|
||||
БЛОК: Шапка и навигация сайта (Header)
|
||||
Источник: perm.oclinica.ru/lor — реальная шапка сайта
|
||||
Версия: v1.0
|
||||
Версия: v1.3
|
||||
|
||||
СТРУКТУРА ШАПКИ (3 зоны сверху вниз):
|
||||
СТРУКТУРА ШАПКИ (2 зоны сверху вниз):
|
||||
|
||||
1. ТОП-БАР (~40px высота, фон #fff, border-bottom 1px solid #e5e7eb)
|
||||
Левая часть:
|
||||
— Адрес: «Б. Цитная, 3» с иконкой 📍
|
||||
— Ссылка: «Клиника ухо горло нос и аллергия»
|
||||
— Ссылка: «Центр аллергологии и пульмонологии»
|
||||
Правая часть:
|
||||
— Телефон: «/342/ 255-53-84» (font-weight: bold, color: #111827)
|
||||
— Кнопка «Заказать звонок» — стиль bb-btn-pill (#e9e4d4, border #d5cfbd, border-radius 25px)
|
||||
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. ЛОГОТИП (~64px, фон #fff)
|
||||
— Иконка кружок синий (#0089c3) с крестом
|
||||
— Текст «КЛИНИКА УХО ГОРЛО НОС» жирный uppercase, цвет #53514e
|
||||
— Подпись «им. проф. Е.Н.Оленевой» мелкий, цвет #9ca3af
|
||||
|
||||
3. ГЛАВНОЕ МЕНЮ (~46px, фон #fff, border-top 1px solid #e5e7eb)
|
||||
Пункты (8 штук): Клиника | ЛОР врачи | Заболевания | Вопрос-ответ | ЛОР-операции | Сурдология | Цены | Контакты
|
||||
Шрифт: Fira Sans 14px, weight 400
|
||||
Цвет ссылок: #53514e (--brand-073m)
|
||||
Активный / Hover: #0089c3 (--brand-053m)
|
||||
2. ГЛАВНОЕ МЕНЮ (~46px, фон #fff, border-top 1px solid #e5e7eb)
|
||||
Пункты (8 штук): Клиника | ЛОР врачи | Заболевания | Вопрос-ответ | ЛОР операции | Сурдология | Цены | Контакты
|
||||
Шрифт: 18px, weight 400
|
||||
Цвет ссылок: #000
|
||||
Активный / Hover: #0089c3
|
||||
Разделители: border-right 1px solid #f3f4f6 между пунктами
|
||||
|
||||
ПРАВИЛА:
|
||||
✓ Логотип всегда кликабелен — ведёт на главную страницу раздела
|
||||
✓ Кнопка «Заказать звонок» всегда видна, pill-стиль
|
||||
✓ Телефон кликабелен (tel: ссылка)
|
||||
✓ Активный пункт меню — цвет #0089c3, остальные #53514e
|
||||
✓ Активный пункт меню — цвет #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">
|
||||
@@ -58,7 +93,7 @@ export default function NavigationPage() {
|
||||
<h1 className="text-2xl font-bold mb-2" style={{ color: "var(--bb-text)" }}>
|
||||
Шапка и навигация
|
||||
</h1>
|
||||
<BlockMetaBar path="/blocks/navigation" defaultVersion="v1.0" defaultIsInPreview={true} />
|
||||
<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>
|
||||
@@ -69,7 +104,7 @@ export default function NavigationPage() {
|
||||
<h2 className="font-semibold text-base" style={{ color: "var(--bb-text)" }}>
|
||||
Живой пример
|
||||
</h2>
|
||||
<div className="rounded-xl overflow-hidden">
|
||||
<div className="rounded-xl" style={{ paddingBottom: 40 }}>
|
||||
<NavigationBlock />
|
||||
</div>
|
||||
</section>
|
||||
@@ -79,28 +114,19 @@ export default function NavigationPage() {
|
||||
<h2 className="font-semibold text-base" style={{ color: "var(--bb-text)" }}>
|
||||
Анатомия шапки
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{[
|
||||
{
|
||||
zone: "1. Топ-бар",
|
||||
zone: "1. Верхняя панель",
|
||||
bg: "#f0f9ff",
|
||||
height: "~40px",
|
||||
color: "Фон: #fff",
|
||||
desc: "Адрес, ссылки на разделы клиники, телефон, кнопка «Заказать звонок» (pill)",
|
||||
desc: "Три столбца: логотип (logo-main.png) | три ссылки вертикально с 📍 (К. Цеткин 9, Клиника кашля, Центр диагностики) | телефон 25px + кнопка «Заказать звонок» (pill)",
|
||||
details: "Фон: #fff · Без рамок · Ссылки: #52b4bd, подчёркнутые",
|
||||
},
|
||||
{
|
||||
zone: "2. Логотип",
|
||||
bg: "#f0fdf4",
|
||||
height: "~64px",
|
||||
color: "Фон: #fff",
|
||||
desc: "Иконка-кружок (#0089c3) + название клиники двумя строками + подпись мелким",
|
||||
},
|
||||
{
|
||||
zone: "3. Навигация",
|
||||
zone: "2. Главное меню",
|
||||
bg: "#fefce8",
|
||||
height: "~46px",
|
||||
color: "Фон: #fff, border-top",
|
||||
desc: "8 горизонтальных пунктов, активный = #0089c3, остальные = #53514e",
|
||||
desc: "8 горизонтальных пунктов: Клиника | ЛОР врачи | Заболевания | Вопрос-ответ | ЛОР операции | Сурдология | Цены | Контакты",
|
||||
details: "Фон: #fff · border-top · 18px · Активный: #0089c3, остальные: #000",
|
||||
},
|
||||
].map((z) => (
|
||||
<div
|
||||
@@ -115,7 +141,7 @@ export default function NavigationPage() {
|
||||
{z.desc}
|
||||
</p>
|
||||
<p className="text-[11px] font-mono mt-1" style={{ color: "var(--bb-text-muted)" }}>
|
||||
H: {z.height} · {z.color}
|
||||
{z.details}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
@@ -127,29 +153,49 @@ export default function NavigationPage() {
|
||||
<h2 className="font-semibold text-base" style={{ color: "var(--bb-text)" }}>
|
||||
Пункты главного меню
|
||||
</h2>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{NAV_ITEMS.map((item, i) => (
|
||||
<span
|
||||
key={item}
|
||||
className="px-3 py-1.5 rounded text-sm"
|
||||
style={{
|
||||
background: i === 0 ? "#dff0fa" : "var(--bb-sidebar-bg)",
|
||||
color: i === 0 ? "var(--brand-053m)" : "var(--bb-text)",
|
||||
border: "1px solid var(--bb-border)",
|
||||
fontWeight: i === 0 ? 500 : 400,
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
{i === 0 && (
|
||||
<span className="ml-1.5 text-[10px]" style={{ color: "var(--bb-text-muted)" }}>
|
||||
(активный)
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
))}
|
||||
<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)" }}>
|
||||
Порядок пунктов фиксирован. Hover и активный пункт — цвет #0089c3 (--brand-053m).
|
||||
Порядок фиксирован. Все пункты чёрные (#000), подчёркнуты. Hover — бежевый фон #f5f0e6. ▾ — выпадающее подменю при наведении.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -161,9 +207,13 @@ export default function NavigationPage() {
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
||||
{[
|
||||
{ label: "Фон шапки", value: "#ffffff", token: "—" },
|
||||
{ label: "Ссылки меню", value: "#53514e", token: "--brand-073m" },
|
||||
{ label: "Активный / hover", value: "#0089c3", token: "--brand-053m" },
|
||||
{ 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}
|
||||
@@ -189,14 +239,13 @@ export default function NavigationPage() {
|
||||
</section>
|
||||
|
||||
{/* LLM блок */}
|
||||
<LlmBlock path="/blocks/navigation" version="v1.0" specText={LLM_NAV_TEXT}>
|
||||
<LlmBlock path="/blocks/navigation" version="v1.3" specText={LLM_NAV_TEXT}>
|
||||
<LlmSection title="Зоны шапки" />
|
||||
<LlmTable
|
||||
headers={["Зона", "Высота", "Фон", "Содержимое"]}
|
||||
headers={["Зона", "Фон", "Содержимое"]}
|
||||
rows={[
|
||||
["Топ-бар", "~40px", "#fff", "Адрес, ссылки разделов, телефон /342/ 255-53-84, кнопка «Заказать звонок»"],
|
||||
["Логотип", "~64px", "#fff", "Кружок #0089c3 + «КЛИНИКА УХО ГОРЛО НОС ИМ. ПРОФ. Е.Н.ОЛЕНЕВОЙ»"],
|
||||
["Навигация", "~46px", "#fff + border-top", "8 пунктов: Клиника / ЛОР врачи / Заболевания / Вопрос-ответ / ЛОР-операции / Сурдология / Цены / Контакты"],
|
||||
["Верхняя панель", "#fff, без рамок", "Логотип (logo-main.png) | 3 ссылки вертикально с 📍 (#52b4bd) | Телефон 25px + кнопка pill"],
|
||||
["Главное меню", "#fff, border-top", "8 пунктов 18px: Клиника / ЛОР врачи / Заболевания / Вопрос-ответ / ЛОР операции / Сурдология / Цены / Контакты"],
|
||||
]}
|
||||
/>
|
||||
<LlmSection title="Цвета" />
|
||||
@@ -204,7 +253,7 @@ export default function NavigationPage() {
|
||||
headers={["Элемент", "Цвет", "Токен"]}
|
||||
rows={[
|
||||
["Фон шапки", "#ffffff", "—"],
|
||||
["Ссылки меню (default)", "#53514e", "--brand-073m"],
|
||||
["Ссылки меню (default)", "#000000", "—"],
|
||||
["Активный пункт / hover", "#0089c3", "--brand-053m"],
|
||||
["Кнопка «Заказать звонок»", "#e9e4d4 / border #d5cfbd", "bb-btn-pill"],
|
||||
["Телефон", "#111827, font-weight bold", "—"],
|
||||
|
||||
@@ -80,8 +80,8 @@ body {
|
||||
background: #FFA39C;
|
||||
color: #fff;
|
||||
border-color: #FF847B;
|
||||
border-radius: 7px;
|
||||
font-weight: bold;
|
||||
border-radius: 4px;
|
||||
font-weight: 700;
|
||||
box-shadow: 0px 0px 5px rgba(0,0,0,0.4), 0px 3px 5px rgba(0,0,0,0.25);
|
||||
}
|
||||
|
||||
@@ -109,6 +109,20 @@ body {
|
||||
border-radius: 25px;
|
||||
}
|
||||
|
||||
/* ─── Навигация сайта ────────────────────────────────────────── */
|
||||
.bb-nav-item {
|
||||
transition: background 0.15s;
|
||||
}
|
||||
.bb-nav-item:hover {
|
||||
background: #f5f0e6;
|
||||
}
|
||||
.bb-nav-sub-item {
|
||||
transition: background 0.1s;
|
||||
}
|
||||
.bb-nav-sub-item:hover {
|
||||
background: #f5f0e6;
|
||||
}
|
||||
|
||||
/* ─── Форм-контролы (Sprint 3) ───────────────────────────────── */
|
||||
.bb-input,
|
||||
.bb-textarea,
|
||||
|
||||
@@ -20,10 +20,10 @@ export function CeoBlock() {
|
||||
>
|
||||
<p>
|
||||
Клиника ухо, нос специализируется на оториноларингологии – лечении взрослых и детей
|
||||
с ЛОР заболеваниями. ЛОР клиника представлена на двух адресах:{" "}
|
||||
<a href="#" style={{ color: "#0089c3" }}>ул. Цитная, 9</a>,{" "}
|
||||
<a href="#" style={{ color: "#0089c3" }}>ул. Г. Звезда, 31а</a>.{" "}
|
||||
Это <a href="#" style={{ color: "#0089c3" }}>Клиника лечения кашля и аллергии</a>.
|
||||
с ЛОР заболеваниями. ЛОР клиника ухо, горло, нос в Перми представлена по двум адресам:{" "}
|
||||
<a href="#" style={{ color: "#52b4bd" }}>ул. Клары Цеткин, 9</a> |{" "}
|
||||
<a href="#" style={{ color: "#52b4bd" }}>ул. Г. Звезда, 31а</a>.{" "}
|
||||
Это <a href="#" style={{ color: "#52b4bd" }}>Клиника лечения кашля и аллергии</a>.
|
||||
</p>
|
||||
|
||||
<div style={{ marginTop: 16 }}>
|
||||
|
||||
@@ -36,7 +36,7 @@ export function ContactFormsBlock() {
|
||||
Отправляя данные, я даю согласие на обработку персональных данных
|
||||
</span>
|
||||
</label>
|
||||
<button className="bb-btn bb-btn-md bb-btn-primary w-full">
|
||||
<button className="bb-btn bb-btn-lg bb-btn-primary w-full">
|
||||
Запишите меня!
|
||||
</button>
|
||||
</div>
|
||||
@@ -74,7 +74,7 @@ export function ContactFormsBlock() {
|
||||
Отправляя данные, я даю согласие на обработку персональных данных
|
||||
</span>
|
||||
</label>
|
||||
<button className="bb-btn bb-btn-md bb-btn-primary w-full">
|
||||
<button className="bb-btn bb-btn-lg bb-btn-primary w-full">
|
||||
Перезвоните мне
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -1,24 +1,37 @@
|
||||
const FOOTER_COLUMNS = [
|
||||
{
|
||||
title: "О клинике",
|
||||
links: ["Лицензия", "Миссия", "Врачи", "Вакансии", "История", "Образовательная деятельность", "При инфо"],
|
||||
links: [
|
||||
"Врачи", "Цены", "Контакты", "Новости", "Отзывы", "История",
|
||||
"Официальная информация", "Оборудование", "Слуховые аппараты",
|
||||
"ЛОР конференции", "Вакансии", "Клиника кашля и аллергии", "Доверенность",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Заболевания",
|
||||
links: ["Ринит", "Отит", "Гайморит", "Тонзиллит", "Полипы носа", "Искривление перегородки"],
|
||||
links: [
|
||||
"Заболевания уха", "Заболевания горла", "Заболевания носа",
|
||||
"У детей", "У беременных",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Вопрос-ответ",
|
||||
links: [
|
||||
"Что нужно знать до операции на ухо",
|
||||
"Что нужно знать до операции на нос",
|
||||
"Отзывы до и после лечения у детей",
|
||||
"Что нужно знать при лечении у детей",
|
||||
"Вопросы-ответы по заболеваниям уха",
|
||||
"Вопросы-ответы по заболеваниям горла",
|
||||
"Вопросы-ответы по заболеваниям носа",
|
||||
"Вопросы-ответы по детским заболеваниям",
|
||||
"Вопросы-ответы по операциям",
|
||||
"Задать свой вопрос?",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Операции",
|
||||
links: ["Септопластика", "Турбинопластика", "Тонзиллэктомия", "Аденотомия", "Тимпанопластика", "Мирингопластика"],
|
||||
links: [
|
||||
"Аденотомия", "Вазотомия", "Мастоидэктомия", "Мирингопластика",
|
||||
"Оссикулопластика", "Септопластика", "Стапедопластика",
|
||||
"Тимпанопластика", "Тонзиллотомия", "Микрогайморотомия", "Полипотомия",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -43,8 +56,8 @@ export function FooterBlock() {
|
||||
<li key={link}>
|
||||
<a
|
||||
href="#"
|
||||
className="text-xs bb-nav-link"
|
||||
style={{ color: "#53514e", textDecoration: "none" }}
|
||||
className="text-xs"
|
||||
style={{ color: "#52b4bd", textDecoration: "none" }}
|
||||
>
|
||||
{link}
|
||||
</a>
|
||||
@@ -61,33 +74,23 @@ export function FooterBlock() {
|
||||
style={{ background: "#fff" }}
|
||||
>
|
||||
{/* Логотип */}
|
||||
<div className="flex items-center gap-2 shrink-0">
|
||||
<div
|
||||
className="w-10 h-10 rounded-full flex items-center justify-center text-white font-bold"
|
||||
style={{ background: "#0089c3" }}
|
||||
>
|
||||
✚
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
className="text-[10px] font-bold uppercase leading-tight"
|
||||
style={{ color: "#53514e" }}
|
||||
>
|
||||
Клиника<br />ухо, горло, нос
|
||||
</div>
|
||||
<div className="text-[8px] leading-tight" style={{ color: "#9ca3af" }}>
|
||||
им. проф. Е.Н.Оленевой
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center shrink-0">
|
||||
<img
|
||||
src="/logo/logo-main.png"
|
||||
alt="Клиника ухо, горло, нос"
|
||||
className="h-12 w-auto"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Адрес и соцсети */}
|
||||
{/* Адреса и соцсети */}
|
||||
<div className="text-center space-y-2">
|
||||
<p className="text-xs" style={{ color: "#374151" }}>
|
||||
Мы находимся по адресу: Пермь, ул. Г. Звезда, 31а
|
||||
</p>
|
||||
<div className="text-xs space-y-0.5" style={{ color: "#374151" }}>
|
||||
<p>Мы находимся по адресам:</p>
|
||||
<p>г. Пермь, ул. Клары Цеткин, 9</p>
|
||||
<p>г. Пермь, ул. Газеты Звезда, 31А</p>
|
||||
</div>
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
{["VK", "OK", "YT", "TG"].map((s) => (
|
||||
{["VK", "YT", "TG", "OK", "Дзен"].map((s) => (
|
||||
<a
|
||||
key={s}
|
||||
href="#"
|
||||
@@ -104,14 +107,21 @@ export function FooterBlock() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Часы работы */}
|
||||
<div className="text-right text-xs space-y-1" style={{ color: "#374151" }}>
|
||||
<p className="font-semibold text-xs mb-1" style={{ color: "#111827" }}>
|
||||
Часы работы:
|
||||
{/* Часы работы — два филиала */}
|
||||
<div className="text-right text-xs space-y-2" style={{ color: "#374151" }}>
|
||||
<p className="font-semibold text-xs" style={{ color: "#111827" }}>
|
||||
Время работы клиники:
|
||||
</p>
|
||||
<p>Пн–пт: 9:00–21:00</p>
|
||||
<p>Сб: 9:00–18:00</p>
|
||||
<p>Вс: выходной</p>
|
||||
<div>
|
||||
<p className="font-medium" style={{ color: "#111827" }}>Газеты Звезда 31а</p>
|
||||
<p>пн – пт: с 09.00 до 21.00</p>
|
||||
<p>сб – вс: с 09:00 до 19:00</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium" style={{ color: "#111827" }}>Клары Цеткин 9</p>
|
||||
<p>пн – сб: с 09.00 до 17.00</p>
|
||||
<p>вс – выходной</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -75,26 +75,17 @@ export function HeroBlock() {
|
||||
</div>
|
||||
|
||||
{/* Под баннером: соцсети + просмотры */}
|
||||
<div className="flex items-center gap-3 pt-1">
|
||||
<span className="text-xs" style={{ color: "#9ca3af" }}>
|
||||
Поделиться:
|
||||
</span>
|
||||
{["VK", "FB", "TW"].map((s) => (
|
||||
<button
|
||||
key={s}
|
||||
className="text-xs px-2 py-1 rounded"
|
||||
style={{
|
||||
background: "#f9fafb",
|
||||
border: "1px solid #e5e7eb",
|
||||
color: "#9ca3af",
|
||||
}}
|
||||
>
|
||||
{s}
|
||||
</button>
|
||||
))}
|
||||
<span className="text-xs ml-2" style={{ color: "#9ca3af" }}>
|
||||
👁 98 573 просмотра
|
||||
</span>
|
||||
<div className="flex items-center gap-2 pt-1">
|
||||
<button
|
||||
className="text-xs px-3 py-1.5 rounded"
|
||||
style={{
|
||||
background: "#f9fafb",
|
||||
border: "1px solid #e5e7eb",
|
||||
color: "#9ca3af",
|
||||
}}
|
||||
>
|
||||
Поделиться ✉ 98572
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,81 +1,93 @@
|
||||
export const NAV_ITEMS = [
|
||||
"Клиника",
|
||||
"ЛОР врачи",
|
||||
"Заболевания",
|
||||
"Вопрос-ответ",
|
||||
"ЛОР-операции",
|
||||
"Сурдология",
|
||||
"Цены",
|
||||
"Контакты",
|
||||
];
|
||||
"use client";
|
||||
|
||||
import { NAV_ITEMS } from "./navData";
|
||||
export { NAV_ITEMS };
|
||||
|
||||
function NavItem({ item, isActive }: { item: (typeof NAV_ITEMS)[number]; isActive: boolean }) {
|
||||
const hasSubmenu = item.submenu.length > 0;
|
||||
|
||||
return (
|
||||
<div 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}
|
||||
{hasSubmenu && (
|
||||
<span className="text-xs" style={{ color: "#9ca3af", textDecoration: "none", display: "inline-block" }}>▾</span>
|
||||
)}
|
||||
</a>
|
||||
{hasSubmenu && (
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
export function NavigationBlock() {
|
||||
return (
|
||||
<div
|
||||
className="overflow-hidden"
|
||||
style={{ border: "1px solid #e5e7eb", boxShadow: "0 1px 4px rgba(0,0,0,0.06)" }}
|
||||
>
|
||||
{/* Топ-бар */}
|
||||
<div
|
||||
className="flex items-center justify-between px-6 py-2 text-xs border-b"
|
||||
style={{ background: "#fff", borderColor: "#e5e7eb", color: "#6b7280" }}
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<span>📍 Б. Цитная, 3</span>
|
||||
<a href="#" style={{ color: "#0089c3" }}>
|
||||
Клиника ухо горло нос и аллергия
|
||||
<div className="bg-white relative">
|
||||
{/* Верхняя панель: три столбца — логотип | ссылки | телефон+кнопка */}
|
||||
<div className="flex items-center px-6 py-4">
|
||||
{/* Столбец 1: Логотип */}
|
||||
<div className="shrink-0">
|
||||
<img
|
||||
src="/logo/logo-main.png"
|
||||
alt="Клиника ухо, горло, нос"
|
||||
className="h-20 w-auto"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Столбец 2: Три ссылки вертикально — прижат к логотипу */}
|
||||
<div className="flex flex-col gap-1.5 ml-6">
|
||||
<a href="#" className="flex items-center gap-1.5 text-sm" style={{ color: "#9ca3af", textDecoration: "none" }}>
|
||||
<span style={{ color: "#9ca3af" }}>📍</span>
|
||||
<span style={{ color: "#52b4bd", textDecoration: "underline" }}>К. Цеткин, 9</span>
|
||||
</a>
|
||||
<a href="#" style={{ color: "#0089c3" }}>
|
||||
Центр аллергологии и пульмонологии
|
||||
<a href="#" className="flex items-center gap-1.5 text-sm" style={{ color: "#9ca3af", textDecoration: "none" }}>
|
||||
<span style={{ color: "#9ca3af" }}>📍</span>
|
||||
<span style={{ color: "#52b4bd", textDecoration: "underline" }}>Клиника лечения кашля и аллергии</span>
|
||||
</a>
|
||||
<a href="#" className="flex items-center gap-1.5 text-sm" style={{ color: "#9ca3af", textDecoration: "none" }}>
|
||||
<span style={{ color: "#9ca3af" }}>📍</span>
|
||||
<span style={{ color: "#52b4bd", textDecoration: "underline" }}>Центр диагностики и реабилитации</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="font-bold text-sm" style={{ color: "#111827" }}>
|
||||
|
||||
{/* Столбец 3: Телефон + кнопка вертикально — прижат вправо */}
|
||||
<div className="flex flex-col items-end gap-2 shrink-0 ml-auto">
|
||||
<span className="font-bold" style={{ color: "#000", fontSize: 25 }}>
|
||||
/342/ 255-53-84
|
||||
</span>
|
||||
<button className="bb-btn bb-btn-sm bb-btn-pill">Заказать звонок</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Логотип */}
|
||||
<div className="flex items-center px-6 py-3 bg-white">
|
||||
<div className="flex items-center gap-3">
|
||||
<div
|
||||
className="w-10 h-10 rounded-full flex items-center justify-center text-white font-bold text-lg shrink-0"
|
||||
style={{ background: "#0089c3" }}
|
||||
>
|
||||
✚
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
className="text-[11px] font-bold leading-tight uppercase tracking-wide"
|
||||
style={{ color: "#53514e" }}
|
||||
>
|
||||
Клиника<br />ухо, горло, нос
|
||||
</div>
|
||||
<div className="text-[9px] leading-tight mt-0.5" style={{ color: "#9ca3af" }}>
|
||||
им. проф. Е.Н.Оленевой
|
||||
</div>
|
||||
</div>
|
||||
<button className="bb-btn bb-btn-md bb-btn-pill">Заказать звонок</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Главное меню */}
|
||||
<nav className="flex border-t bg-white" style={{ borderColor: "#e5e7eb" }}>
|
||||
<nav className="flex bg-white">
|
||||
{NAV_ITEMS.map((item, i) => (
|
||||
<a
|
||||
key={item}
|
||||
href="#"
|
||||
className="px-4 py-3 text-sm whitespace-nowrap"
|
||||
style={{
|
||||
color: i === 0 ? "#0089c3" : "#53514e",
|
||||
borderRight: "1px solid #f3f4f6",
|
||||
fontWeight: i === 0 ? 500 : 400,
|
||||
textDecoration: "none",
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</a>
|
||||
<NavItem key={item.label} item={item} isActive={i === 0} />
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
export const NAV_ITEMS = [
|
||||
{
|
||||
label: "Клиника",
|
||||
submenu: [
|
||||
"О клинике", "Официальная информация", "История", "Оборудование",
|
||||
"Новости", "Отзывы", "ЛОР конференции", "Вакансии", "Доверенность",
|
||||
"Клиника лечения кашля и аллергии", "Налоговый вычет",
|
||||
],
|
||||
},
|
||||
{ label: "ЛОР врачи", submenu: [] as string[] },
|
||||
{
|
||||
label: "Заболевания",
|
||||
submenu: ["Горло", "Ухо", "Нос", "У детей", "У беременных", "Диагностика"],
|
||||
},
|
||||
{
|
||||
label: "Вопрос-ответ",
|
||||
submenu: [
|
||||
"Вопросы по заболеваниям уха", "Вопросы по заболеваниям горла",
|
||||
"Вопросы по заболеваниям носа", "Вопросы по детским заболеваниям",
|
||||
"Вопросы по операциям", "Задать свой вопрос?",
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "ЛОР операции",
|
||||
submenu: [
|
||||
"Аденотомия", "Вазотомия", "Мастоидэктомия", "Тимпанопластика 1 типа",
|
||||
"Тимпанопластика 2 типа", "Оссикулопластика", "Септопластика",
|
||||
"Стапедопластика", "Тонзиллотомия", "Полипотомия", "Микрогайморотомия",
|
||||
],
|
||||
},
|
||||
{ label: "Сурдология", submenu: [] as string[] },
|
||||
{ label: "Цены", submenu: [] as string[] },
|
||||
{ label: "Контакты", submenu: [] as string[] },
|
||||
];
|
||||
@@ -37,6 +37,7 @@ export function BlockMetaBar({ path, defaultVersion, defaultIsInPreview, default
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [versionInput, setVersionInput] = useState(defaultVersion);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [savingVersion, setSavingVersion] = useState<false | 'saving' | 'done'>(false);
|
||||
const [togglingPreview, setTogglingPreview] = useState(false);
|
||||
const [apiDown, setApiDown] = useState(false);
|
||||
const [localPreview, setLocalPreview] = useState(defaultIsInPreview);
|
||||
@@ -79,6 +80,22 @@ export function BlockMetaBar({ path, defaultVersion, defaultIsInPreview, default
|
||||
}
|
||||
}
|
||||
|
||||
async function saveFullVersion() {
|
||||
if (apiDown) return;
|
||||
setSavingVersion('saving');
|
||||
try {
|
||||
const updated = await patch({ version: defaultVersion, changelog: defaultChangelog });
|
||||
if (updated) {
|
||||
setMeta(updated);
|
||||
setVersionInput(updated.version);
|
||||
}
|
||||
setSavingVersion('done');
|
||||
setTimeout(() => setSavingVersion(false), 1500);
|
||||
} catch {
|
||||
setSavingVersion(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function togglePreview() {
|
||||
if (apiDown) {
|
||||
const newVal = !localPreview;
|
||||
@@ -180,6 +197,30 @@ export function BlockMetaBar({ path, defaultVersion, defaultIsInPreview, default
|
||||
: "Не в превью"}
|
||||
</button>
|
||||
|
||||
<span style={{ color: "var(--bb-border)" }}>·</span>
|
||||
|
||||
{/* Save version button */}
|
||||
<button
|
||||
onClick={saveFullVersion}
|
||||
disabled={apiDown || savingVersion === 'saving'}
|
||||
title={apiDown ? 'API недоступен' : 'Сохранить текущую версию и changelog в БД'}
|
||||
className="px-2.5 py-1 rounded font-medium transition-colors"
|
||||
style={savingVersion === 'done' ? {
|
||||
background: "#dcfce7",
|
||||
color: "#16a34a",
|
||||
border: "1px solid #86efac",
|
||||
cursor: "default",
|
||||
} : {
|
||||
background: "var(--bb-sidebar-bg)",
|
||||
color: apiDown ? "var(--bb-text-muted)" : "var(--brand-053m)",
|
||||
border: "1px solid var(--bb-border)",
|
||||
cursor: apiDown ? "default" : "pointer",
|
||||
opacity: apiDown ? 0.5 : 1,
|
||||
}}
|
||||
>
|
||||
{savingVersion === 'saving' ? '...' : savingVersion === 'done' ? 'Сохранено' : 'Сохранить версию'}
|
||||
</button>
|
||||
|
||||
{/* Subtle offline dot instead of "API офлайн" text */}
|
||||
{apiDown && (
|
||||
<span
|
||||
|
||||
Reference in New Issue
Block a user