diff --git a/Caddyfile b/Caddyfile index 7911a163..ea7ecbb3 100644 --- a/Caddyfile +++ b/Caddyfile @@ -91,6 +91,15 @@ gendsgn.ru { } } + # gendsgn.ru/sale-share — короткий адрес standalone-продукта «Поиск домов». + # Next basePath=/trade-in → редиректим на канонический /trade-in/sale-share + # (тот же tradein-frontend контейнер; query-string сохраняется). True vanity-URL + # в адресной строке требует отдельного Next-app с basePath=/sale-share. + @saleshare path /sale-share /sale-share/ + handle @saleshare { + redir /trade-in/sale-share permanent + } + # Matcher `path /trade-in /trade-in/*` ловит И /trade-in (без слеша), # И /trade-in/ + /trade-in/anything. Без обоих случаев `handle /trade-in/*` # пропускал /trade-in без слеша → попадал в общий frontend → пустой ответ. diff --git a/tradein-mvp/frontend/src/app/sale-share/layout.tsx b/tradein-mvp/frontend/src/app/sale-share/layout.tsx new file mode 100644 index 00000000..c0c3e6b9 --- /dev/null +++ b/tradein-mvp/frontend/src/app/sale-share/layout.tsx @@ -0,0 +1,18 @@ +import type { Metadata } from "next"; + +// Route-level metadata override: /sale-share — самостоятельный продукт «Поиск +// домов», без бренда «Мера». Next app-router мержит это поверх root metadata +// (src/app/layout.tsx) только для этого сегмента. Server component (no "use +// client") — metadata экспортируется лишь из серверных модулей. +export const metadata: Metadata = { + title: "Поиск домов — gendsgn", + description: "Поиск вторичных домов с высокой долей квартир в продаже", +}; + +export default function SaleShareLayout({ + children, +}: { + children: React.ReactNode; +}) { + return <>{children}; +} diff --git a/tradein-mvp/frontend/src/app/sale-share/page.tsx b/tradein-mvp/frontend/src/app/sale-share/page.tsx index 9c7b7bfd..032f0cd3 100644 --- a/tradein-mvp/frontend/src/app/sale-share/page.tsx +++ b/tradein-mvp/frontend/src/app/sale-share/page.tsx @@ -11,7 +11,7 @@ import { useCallback, useMemo, useRef, useState } from "react"; import dynamic from "next/dynamic"; import "@/components/trade-in/trade-in.css"; -import { Topbar } from "@/components/trade-in/Topbar"; +import { SaleShareHeader } from "@/components/trade-in/SaleShareHeader"; import { SaleShareControls } from "@/components/trade-in/SaleShareControls"; import { SaleShareList } from "@/components/trade-in/SaleShareList"; import { BuildingListingsDrawer } from "@/components/trade-in/BuildingListingsDrawer"; @@ -105,11 +105,12 @@ export default function SaleSharePage() { return ( <> - +
- Главная Мера Доля квартир в продаже + Главная Поиск домов Доля квартир + в продаже
@@ -209,7 +210,7 @@ export default function SaleSharePage() {
- Мера · MVP ·{" "} + Поиск домов ·{" "} доля квартир в продаже · вторичный рынок ЕКБ
diff --git a/tradein-mvp/frontend/src/components/trade-in/SaleShareHeader.tsx b/tradein-mvp/frontend/src/components/trade-in/SaleShareHeader.tsx new file mode 100644 index 00000000..4c630ce6 --- /dev/null +++ b/tradein-mvp/frontend/src/components/trade-in/SaleShareHeader.tsx @@ -0,0 +1,65 @@ +"use client"; + +/** + * SaleShareHeader — топбар самостоятельного продукта «Поиск домов». + * + * В отличие от `Topbar.tsx` (бренд «Мера» + табы оценки/истории/скраперов) + * это минимальная шапка БЕЗ марки «Мера» и без продуктовых табов: только + * название продукта слева и личный кабинет (UserMenu) справа, чтобы + * login/logout продолжали работать. Layout/токены переиспользуются из + * `trade-in.css` (`.topbar` / `.topbar-inner` / `.brand` / `.top-nav`), + * глиф-бейдж `.brand-mark` нейтральный (домик), не Mera-специфичный. + */ + +import { UserMenu } from "@/components/auth/UserMenu"; + +/** Нейтральный глиф «дом» для бейджа продукта (currentColor, в стиле + .brand-mark-svg — тёмный фон даёт CSS-бейдж .brand-mark). */ +function HouseMark() { + return ( + + ); +} + +export function SaleShareHeader() { + return ( +
+
+
+ + + + Поиск домов +
+ {/* Только личный кабинет — никакой Mera-навигации. `.top-nav` + переиспользуется ради margin-left:auto. В dev (401) или до /me + UserMenu сам рендерит null. */} +
+ +
+
+
+ ); +}