Compare commits
No commits in common. "d56103219a5baac6c054e4c7ab697fd1b67a817e" and "fcfc777baae9002e2e9d179f71c35ea1a5909e5f" have entirely different histories.
d56103219a
...
fcfc777baa
3 changed files with 7 additions and 141 deletions
|
|
@ -1,7 +1,6 @@
|
||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { IBM_Plex_Mono, Manrope } from "next/font/google";
|
import { IBM_Plex_Mono, Manrope } from "next/font/google";
|
||||||
|
|
||||||
import { SupportButton } from "@/components/trade-in/v2/SupportButton";
|
|
||||||
import { pageBg } from "@/components/trade-in/v2/tokens";
|
import { pageBg } from "@/components/trade-in/v2/tokens";
|
||||||
|
|
||||||
// Manrope — primary sans typeface of the МЕРА HUD. next/font is bundled
|
// Manrope — primary sans typeface of the МЕРА HUD. next/font is bundled
|
||||||
|
|
@ -42,10 +41,6 @@ export default function TradeInV2Layout({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
{/* Mounted here (not the global app/layout.tsx) — that layout also
|
|
||||||
covers the admin `/scrapers/**` area and `/sale-share`, unrelated
|
|
||||||
products without the МЕРА brand that don't need a support link. */}
|
|
||||||
<SupportButton />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,116 +0,0 @@
|
||||||
"use client";
|
|
||||||
|
|
||||||
// SupportButton — floating link to the МЕРА Telegram support bot.
|
|
||||||
//
|
|
||||||
// WHY: before this, there was no way to reach support from the site.
|
|
||||||
// `LeadForm` (LeadForm.tsx) only mounts once `hasEstimate` is true
|
|
||||||
// (app/v2/page.tsx:1064), so a visitor who hasn't finished (or can't finish)
|
|
||||||
// an estimate has no contact path at all. The only other link anywhere in the
|
|
||||||
// UI is NoAccessScreen.tsx:84, and that only renders on the "access expired"
|
|
||||||
// screen. The support bot itself is already live on the backend (support
|
|
||||||
// bridge, PR #2526) — this button is purely the missing entry point on the
|
|
||||||
// site side. Plain external link, no chat widget / no state / no API calls.
|
|
||||||
//
|
|
||||||
// Portal to document.body (pattern mirrors MapPicker.tsx:104-108 and
|
|
||||||
// BuildingListingsDrawer.tsx): `/v2` renders its HUD inside a fixed
|
|
||||||
// 1536×1024 "artboard" that gets `transform: scale(...)` on narrow viewports
|
|
||||||
// (app/v2/page.tsx:860-871). A `position: fixed` descendant of a
|
|
||||||
// `transform`-ed ancestor is positioned relative to that ancestor, not the
|
|
||||||
// viewport — so without a portal the button would drift/scale with the HUD
|
|
||||||
// instead of staying pinned to the real viewport corner.
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { createPortal } from "react-dom";
|
|
||||||
|
|
||||||
import { tokens } from "./tokens";
|
|
||||||
|
|
||||||
// Same bot as the backend support bridge (PR #2526). A plain module constant
|
|
||||||
// rather than `NEXT_PUBLIC_*`: the URL is public and stable, and env vars are
|
|
||||||
// inlined at build time — swapping the value would need a rebuild for no
|
|
||||||
// benefit over just editing this line.
|
|
||||||
//
|
|
||||||
// Exported: this is the single source of truth for the bot URL. The «Помощь»
|
|
||||||
// item in TopNav.tsx's user menu links to the same bot and imports this
|
|
||||||
// constant rather than duplicating the string.
|
|
||||||
export const SUPPORT_BOT_URL = "https://t.me/MERAsupport_bot";
|
|
||||||
|
|
||||||
const { accent, accentDeep, onAccent, surface, font } = tokens;
|
|
||||||
|
|
||||||
const styles = `
|
|
||||||
.support-btn{background:linear-gradient(90deg,${accentDeep},${accent});transition:box-shadow .18s,transform .18s,background .18s;}
|
|
||||||
.support-btn:hover{background:${accentDeep};box-shadow:0 6px 20px rgba(13,111,214,.4);}
|
|
||||||
.support-btn:active{transform:translateY(1px);}
|
|
||||||
.support-btn:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(46,139,255,.45);}
|
|
||||||
@media (max-width: 480px){
|
|
||||||
.support-btn{right:14px !important;bottom:14px !important;padding:0 14px !important;}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export function SupportButton() {
|
|
||||||
// Portal-mount guard (SSR-safe): `document` only exists after mount
|
|
||||||
// (mirrors MapPicker.tsx:107-108 / BuildingListingsDrawer.tsx:29-30).
|
|
||||||
const [mounted, setMounted] = useState(false);
|
|
||||||
useEffect(() => setMounted(true), []);
|
|
||||||
|
|
||||||
if (!mounted) return null;
|
|
||||||
|
|
||||||
return createPortal(
|
|
||||||
<>
|
|
||||||
<style>{styles}</style>
|
|
||||||
<a
|
|
||||||
href={SUPPORT_BOT_URL}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="support-btn"
|
|
||||||
aria-label="Написать в поддержку МЕРА в Telegram"
|
|
||||||
title="Поддержка МЕРА в Telegram"
|
|
||||||
style={{
|
|
||||||
position: "fixed",
|
|
||||||
right: 20,
|
|
||||||
bottom: 20,
|
|
||||||
// z-index 25 — deliberately BELOW every v2 HUD overlay: SectionOverlay
|
|
||||||
// (29/30), LocationDrawer (40/41), TopNav (50), UserMenu (200), and
|
|
||||||
// the legacy MapPicker dialog (1000). When a modal/drawer is open the
|
|
||||||
// button should disappear under it, not float on top and steal
|
|
||||||
// clicks/tab order. It never collides with TopNav geographically
|
|
||||||
// (top of screen vs. bottom-right corner here), so this only matters
|
|
||||||
// for the bottom-sheet-style overlays.
|
|
||||||
zIndex: 25,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: 8,
|
|
||||||
height: 44,
|
|
||||||
minWidth: 44,
|
|
||||||
boxSizing: "border-box",
|
|
||||||
padding: "0 16px",
|
|
||||||
borderRadius: 999,
|
|
||||||
border: `1px solid ${surface.w40}`,
|
|
||||||
boxShadow: "0 4px 14px rgba(13,111,214,.3)",
|
|
||||||
color: onAccent,
|
|
||||||
fontFamily: font.sans,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: 600,
|
|
||||||
letterSpacing: 0.4,
|
|
||||||
textDecoration: "none",
|
|
||||||
whiteSpace: "nowrap",
|
|
||||||
cursor: "pointer",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
width="18"
|
|
||||||
height="18"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
aria-hidden="true"
|
|
||||||
focusable="false"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M21.05 3.16 2.98 10.42c-1.24.51-1.23 1.22-.23 1.53l4.63 1.45 1.79 5.5c.22.6.37.84.75.84.35 0 .5-.16.7-.35l1.7-1.65 3.63 2.68c.67.37 1.15.18 1.32-.62l2.39-11.27c.26-1.03-.39-1.5-1.61-.87z"
|
|
||||||
fill={onAccent}
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<span>Поддержка</span>
|
|
||||||
</a>
|
|
||||||
</>,
|
|
||||||
document.body,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -12,7 +12,6 @@ import type { CSSProperties } from "react";
|
||||||
|
|
||||||
import { tokens } from "./tokens";
|
import { tokens } from "./tokens";
|
||||||
import { navLabels, version } from "./fixtures";
|
import { navLabels, version } from "./fixtures";
|
||||||
import { SUPPORT_BOT_URL } from "./SupportButton";
|
|
||||||
|
|
||||||
// Real logged-in user identity, derived by the page from useMe()
|
// Real logged-in user identity, derived by the page from useMe()
|
||||||
// ({username, role, brand}). Deliberately excludes `reports` — the «Мои
|
// ({username, role, brand}). Deliberately excludes `reports` — the «Мои
|
||||||
|
|
@ -57,10 +56,8 @@ const menuItemStyle: CSSProperties = {
|
||||||
transition: "background .12s",
|
transition: "background .12s",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Профиль / Настройки have no pages yet — render them dimmed and
|
// Профиль / Настройки / Помощь have no pages yet — render them dimmed and
|
||||||
// non-interactive (no hover class, default cursor) so they read as disabled.
|
// non-interactive (no hover class, default cursor) so they read as disabled.
|
||||||
// «Помощь» used to be in this group too, but now links out to the Telegram
|
|
||||||
// support bot (see SUPPORT_BOT_URL below) — it renders as a live item.
|
|
||||||
const menuItemDisabledStyle: CSSProperties = {
|
const menuItemDisabledStyle: CSSProperties = {
|
||||||
...menuItemStyle,
|
...menuItemStyle,
|
||||||
cursor: "default",
|
cursor: "default",
|
||||||
|
|
@ -377,7 +374,7 @@ export default function TopNav({
|
||||||
|
|
||||||
{/* L5 — `title` gives the dimmed/non-interactive item a hover
|
{/* L5 — `title` gives the dimmed/non-interactive item a hover
|
||||||
tooltip explaining WHY it's disabled, instead of a silent dead
|
tooltip explaining WHY it's disabled, instead of a silent dead
|
||||||
row (mirrored on Настройки below). */}
|
row (mirrored on Настройки/Помощь below). */}
|
||||||
<div
|
<div
|
||||||
style={menuItemDisabledStyle}
|
style={menuItemDisabledStyle}
|
||||||
aria-disabled="true"
|
aria-disabled="true"
|
||||||
|
|
@ -446,20 +443,10 @@ export default function TopNav({
|
||||||
Настройки
|
Настройки
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Live item (issue: two support entry points — the other is
|
<div
|
||||||
SupportButton.tsx's floating button). Same bot, imported
|
style={menuItemDisabledStyle}
|
||||||
constant — single source of truth for the URL. Styled like
|
aria-disabled="true"
|
||||||
the other live row above ("Мои отчёты"), not the dimmed
|
title="Раздел «Помощь» скоро появится"
|
||||||
Профиль/Настройки rows. */}
|
|
||||||
<a
|
|
||||||
href={SUPPORT_BOT_URL}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="tnav-menuitem"
|
|
||||||
style={{ ...menuItemStyle, textDecoration: "none" }}
|
|
||||||
aria-label="Написать в поддержку МЕРА в Telegram"
|
|
||||||
title="Написать в поддержку МЕРА в Telegram"
|
|
||||||
onClick={() => setUserOpen(false)}
|
|
||||||
>
|
>
|
||||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" aria-hidden="true">
|
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" aria-hidden="true">
|
||||||
<circle
|
<circle
|
||||||
|
|
@ -476,7 +463,7 @@ export default function TopNav({
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
Помощь
|
Помощь
|
||||||
</a>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue