diff --git a/apps/api/prisma/seed.ts b/apps/api/prisma/seed.ts
index fd874e0..7d60ac2 100644
--- a/apps/api/prisma/seed.ts
+++ b/apps/api/prisma/seed.ts
@@ -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 колонки ссылок, адрес, часы работы'] },
],
},
diff --git a/apps/web/app/blocks/ceo/page.tsx b/apps/web/app/blocks/ceo/page.tsx
index c35fa59..298e9a9 100644
--- a/apps/web/app/blocks/ceo/page.tsx
+++ b/apps/web/app/blocks/ceo/page.tsx
@@ -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 (
@@ -63,7 +75,7 @@ export default function CeoPage() {
Вводный текст (CEO-блок)
-
+
Блок после hero-баннера на perm.oclinica.ru/lor. Описание специализации клиники
+ вопросы-стимулы для пациентов.
@@ -152,7 +164,7 @@ export default function CeoPage() {
{/* LLM блок */}
-
+
Формы записи
-
+
Два блока форм с perm.oclinica.ru/lor — запись на приём и запрос стоимости операции.
@@ -126,7 +134,7 @@ export default function ContactFormsPage() {
{/* LLM блок */}
-
+
@@ -84,7 +101,7 @@ export default function ContactFooterPage() {
Подвал (Footer)
-
+
Подвал сайта с perm.oclinica.ru — 4 колонки ссылок, логотип, адрес, часы работы, соцсети.
@@ -122,7 +139,7 @@ export default function ContactFooterPage() {
{/* LLM блок */}
-
+
Hero-баннер
-
+
Главный баннер страницы раздела ЛОР — perm.oclinica.ru/lor. Двухколоночный блок, единый светло-кремовый фон{" "}
#f9f4e7 .
@@ -161,7 +169,7 @@ export default function HeroPage() {
{/* LLM блок */}
-
+
@@ -58,7 +93,7 @@ export default function NavigationPage() {
Шапка и навигация
-
+
Точное воспроизведение шапки с perm.oclinica.ru/lor. Три зоны: топ-бар, логотип, главное меню.
@@ -69,7 +104,7 @@ export default function NavigationPage() {
Живой пример
-
+
@@ -79,28 +114,19 @@ export default function NavigationPage() {
Анатомия шапки
-
+
{[
{
- zone: "1. Топ-бар",
+ zone: "1. Верхняя панель",
bg: "#f0f9ff",
- height: "~40px",
- color: "Фон: #fff",
- desc: "Адрес, ссылки на разделы клиники, телефон, кнопка «Заказать звонок» (pill)",
- },
- {
- zone: "2. Логотип",
- bg: "#f0fdf4",
- height: "~64px",
- color: "Фон: #fff",
- desc: "Иконка-кружок (#0089c3) + название клиники двумя строками + подпись мелким",
+ desc: "Три столбца: логотип (logo-main.png) | три ссылки вертикально с 📍 (К. Цеткин 9, Клиника кашля, Центр диагностики) | телефон 25px + кнопка «Заказать звонок» (pill)",
+ details: "Фон: #fff · Без рамок · Ссылки: #52b4bd, подчёркнутые",
},
{
- 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) => (
- H: {z.height} · {z.color}
+ {z.details}
))}
@@ -127,29 +153,49 @@ export default function NavigationPage() {
Пункты главного меню
-
- {NAV_ITEMS.map((item, i) => (
-
- {item}
- {i === 0 && (
-
- (активный)
-
- )}
-
- ))}
+
+
+ {NAV_ITEMS.map((item, i) => (
+
+ ))}
+
- Порядок пунктов фиксирован. Hover и активный пункт — цвет #0089c3 (--brand-053m).
+ Порядок фиксирован. Все пункты чёрные (#000), подчёркнуты. Hover — бежевый фон #f5f0e6. ▾ — выпадающее подменю при наведении.
@@ -161,9 +207,13 @@ export default function NavigationPage() {
{[
{ 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) => (
{/* LLM блок */}
-
+
@@ -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", "—"],
diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css
index da33c22..9c3db49 100644
--- a/apps/web/app/globals.css
+++ b/apps/web/app/globals.css
@@ -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,
diff --git a/apps/web/components/blocks/CeoBlock.tsx b/apps/web/components/blocks/CeoBlock.tsx
index f89e279..1fd71ff 100644
--- a/apps/web/components/blocks/CeoBlock.tsx
+++ b/apps/web/components/blocks/CeoBlock.tsx
@@ -20,10 +20,10 @@ export function CeoBlock() {
>
Клиника ухо, нос специализируется на оториноларингологии – лечении взрослых и детей
- с ЛОР заболеваниями. ЛОР клиника представлена на двух адресах:{" "}
- ул. Цитная, 9 ,{" "}
- ул. Г. Звезда, 31а .{" "}
- Это Клиника лечения кашля и аллергии .
+ с ЛОР заболеваниями. ЛОР клиника ухо, горло, нос в Перми представлена по двум адресам:{" "}
+ ул. Клары Цеткин, 9 |{" "}
+ ул. Г. Звезда, 31а .{" "}
+ Это Клиника лечения кашля и аллергии .
diff --git a/apps/web/components/blocks/ContactFormsBlock.tsx b/apps/web/components/blocks/ContactFormsBlock.tsx
index c748952..48daf83 100644
--- a/apps/web/components/blocks/ContactFormsBlock.tsx
+++ b/apps/web/components/blocks/ContactFormsBlock.tsx
@@ -36,7 +36,7 @@ export function ContactFormsBlock() {
Отправляя данные, я даю согласие на обработку персональных данных
-
+
Запишите меня!
@@ -74,7 +74,7 @@ export function ContactFormsBlock() {
Отправляя данные, я даю согласие на обработку персональных данных
-
+
Перезвоните мне
diff --git a/apps/web/components/blocks/FooterBlock.tsx b/apps/web/components/blocks/FooterBlock.tsx
index 085fbea..7233c64 100644
--- a/apps/web/components/blocks/FooterBlock.tsx
+++ b/apps/web/components/blocks/FooterBlock.tsx
@@ -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() {
{link}
@@ -61,33 +74,23 @@ export function FooterBlock() {
style={{ background: "#fff" }}
>
{/* Логотип */}
-
-
- ✚
-
-
-
- Клиника ухо, горло, нос
-
-
- им. проф. Е.Н.Оленевой
-
-
+
+
- {/* Адрес и соцсети */}
+ {/* Адреса и соцсети */}
-
- Мы находимся по адресу: Пермь, ул. Г. Звезда, 31а
-
+
+
Мы находимся по адресам:
+
г. Пермь, ул. Клары Цеткин, 9
+
г. Пермь, ул. Газеты Звезда, 31А
+
- {["VK", "OK", "YT", "TG"].map((s) => (
+ {["VK", "YT", "TG", "OK", "Дзен"].map((s) => (
- {/* Часы работы */}
-
-
- Часы работы:
+ {/* Часы работы — два филиала */}
+
+
+ Время работы клиники:
-
Пн–пт: 9:00–21:00
-
Сб: 9:00–18:00
-
Вс: выходной
+
+
Газеты Звезда 31а
+
пн – пт: с 09.00 до 21.00
+
сб – вс: с 09:00 до 19:00
+
+
+
Клары Цеткин 9
+
пн – сб: с 09.00 до 17.00
+
вс – выходной
+
diff --git a/apps/web/components/blocks/HeroBlock.tsx b/apps/web/components/blocks/HeroBlock.tsx
index 3ef9fec..cccda9b 100644
--- a/apps/web/components/blocks/HeroBlock.tsx
+++ b/apps/web/components/blocks/HeroBlock.tsx
@@ -75,26 +75,17 @@ export function HeroBlock() {
{/* Под баннером: соцсети + просмотры */}
-
-
- Поделиться:
-
- {["VK", "FB", "TW"].map((s) => (
-
- {s}
-
- ))}
-
- 👁 98 573 просмотра
-
+
+
+ Поделиться ✉ 98572
+
);
diff --git a/apps/web/components/blocks/NavigationBlock.tsx b/apps/web/components/blocks/NavigationBlock.tsx
index 336d1d9..a3a6cf3 100644
--- a/apps/web/components/blocks/NavigationBlock.tsx
+++ b/apps/web/components/blocks/NavigationBlock.tsx
@@ -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;
-export function NavigationBlock() {
return (
-
- {/* Топ-бар */}
-
+
-
+ );
+}
+
+export function NavigationBlock() {
+ return (
+
+ {/* Верхняя панель: три столбца — логотип | ссылки | телефон+кнопка */}
+
+ {/* Столбец 1: Логотип */}
+
+
+
+
+ {/* Столбец 2: Три ссылки вертикально — прижат к логотипу */}
+
-
-
+
+ {/* Столбец 3: Телефон + кнопка вертикально — прижат вправо */}
+
+
/342/ 255-53-84
- Заказать звонок
-
-
-
- {/* Логотип */}
-
-
-
- ✚
-
-
-
- Клиника ухо, горло, нос
-
-
- им. проф. Е.Н.Оленевой
-
-
+
Заказать звонок
{/* Главное меню */}
-
+
{NAV_ITEMS.map((item, i) => (
-
- {item}
-
+
))}
diff --git a/apps/web/components/blocks/navData.ts b/apps/web/components/blocks/navData.ts
new file mode 100644
index 0000000..eae8c8f
--- /dev/null
+++ b/apps/web/components/blocks/navData.ts
@@ -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[] },
+];
diff --git a/apps/web/components/ui/BlockMetaBar.tsx b/apps/web/components/ui/BlockMetaBar.tsx
index 3c8b6e1..493f68d 100644
--- a/apps/web/components/ui/BlockMetaBar.tsx
+++ b/apps/web/components/ui/BlockMetaBar.tsx
@@ -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);
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
: "Не в превью"}
+ ·
+
+ {/* Save version button */}
+
+ {savingVersion === 'saving' ? '...' : savingVersion === 'done' ? 'Сохранено' : 'Сохранить версию'}
+
+
{/* Subtle offline dot instead of "API офлайн" text */}
{apiDown && (