gendesign/tradein-mvp/frontend/src/components/trade-in/v2/HeroBar.tsx
bot-backend fcb85deab8
All checks were successful
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 1m3s
CI / openapi-codegen-check (pull_request) Successful in 1m59s
refactor(tradein/v2): перенос HUD v2 в tradein-mvp frontend
Прод-/trade-in/* обслуживает tradein-mvp/frontend (basePath=/trade-in,
standalone), а не главный frontend — v2 по ошибке попал в главный, где
прод его не отдаёт. Markup-only порт (fixtures, без API):

- компоненты v2 → tradein-mvp/frontend/src/components/trade-in/v2/
- роут src/app/v2/ (basePath даёт прод-URL /trade-in/v2)
- public/trade-in-v2/building.png
- HeroBar: <img> → next/image (плоский img не префиксит basePath → 404)
- удалён мёртвый v2 из главного frontend

next build (NEXT_PUBLIC_BASE_PATH=/trade-in) зелёный, роут /v2 prerendered.
2026-06-28 13:10:23 +03:00

484 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import Image from "next/image";
import { tokens } from "./tokens";
import { object, report } from "./fixtures";
interface HeroBarProps {
onOpenInfo: () => void;
}
export default function HeroBar({ onOpenInfo }: HeroBarProps) {
return (
<div
style={{
display: "flex",
gap: 30,
padding: "14px 2px 12px",
flex: "0 0 auto",
}}
>
<style>{`
.hero-pdf-btn:hover { border-color: ${tokens.accent}; background: rgba(46,139,255,.07); }
.hero-pdf-btn:active { transform: translateY(1px); }
.hero-calc-btn:hover { border-color: ${tokens.accent}; color: ${tokens.accent}; }
.hero-coef-row:hover { background: rgba(46,139,255,.09); }
@keyframes hero-scanv { 0% { transform: translateY(-100%); } 100% { transform: translateY(900%); } }
`}</style>
{/* LEFT: meta + buttons */}
<div
style={{
flex: 1,
minWidth: 0,
display: "flex",
flexDirection: "column",
justifyContent: "center",
gap: 22,
}}
>
<div style={{ display: "flex", gap: 26, alignItems: "flex-start" }}>
<div>
<div
style={{
fontSize: 9,
letterSpacing: "2px",
color: tokens.muted2,
marginBottom: 6,
}}
>
ОТЧЁТ
</div>
<div
style={{
fontFamily: tokens.font.mono,
fontSize: 14,
color: tokens.ink,
}}
>
{report.id}
</div>
</div>
<div
style={{
borderLeft: `1px solid ${tokens.lineSoft}`,
paddingLeft: 26,
}}
>
<div
style={{
fontSize: 9,
letterSpacing: "2px",
color: tokens.muted2,
marginBottom: 6,
}}
>
ДАТА
</div>
<div
style={{
fontFamily: tokens.font.mono,
fontSize: 14,
color: tokens.ink,
}}
>
{report.date}
</div>
</div>
<div
style={{
borderLeft: `1px solid ${tokens.lineSoft}`,
paddingLeft: 26,
}}
>
<div
style={{
fontSize: 9,
letterSpacing: "2px",
color: tokens.muted2,
marginBottom: 6,
}}
>
ДЕЙСТВИТЕЛЕН ДО
</div>
<div
style={{
fontFamily: tokens.font.mono,
fontSize: 14,
color: tokens.ink,
}}
>
{report.validUntil}
</div>
</div>
</div>
<div style={{ display: "flex", gap: 12, width: "100%", maxWidth: 440 }}>
<button
type="button"
className="hero-pdf-btn"
style={{
flex: 1,
height: 50,
background: tokens.surface.w55,
border: `1px solid ${tokens.line}`,
borderRadius: 7,
display: "flex",
alignItems: "center",
gap: 11,
padding: "0 16px",
cursor: "pointer",
fontFamily: tokens.font.sans,
color: tokens.ink,
transition: "all .15s",
}}
>
<svg width="18" height="20" viewBox="0 0 18 20" fill="none">
<path d="M2 1h9l5 5v13H2z" stroke="#2e8bff" strokeWidth="1.2" />
<path d="M11 1v5h5" stroke="#2e8bff" strokeWidth="1.2" />
<line x1="5" y1="11" x2="13" y2="11" stroke="#6f8195" />
<line x1="5" y1="14" x2="13" y2="14" stroke="#6f8195" />
</svg>
<span
style={{ fontSize: 11, fontWeight: 600, letterSpacing: "1px" }}
>
СКАЧАТЬ PDF-ОТЧЁТ
</span>
</button>
<button
type="button"
className="hero-calc-btn"
style={{
flex: 1,
height: 50,
background: tokens.surface.w40,
border: `1px solid ${tokens.line}`,
borderRadius: 7,
display: "flex",
alignItems: "center",
justifyContent: "center",
cursor: "pointer",
fontFamily: tokens.font.sans,
color: tokens.muted,
fontSize: 11,
fontWeight: 600,
letterSpacing: "1.5px",
transition: "all .15s",
}}
>
КАК РАССЧИТАНО
</button>
</div>
</div>
{/* RIGHT: photo + overlays */}
<div
style={{
position: "relative",
width: 560,
height: 152,
flex: "0 0 auto",
border: `1px solid ${tokens.line3}`,
borderRadius: 6,
overflow: "hidden",
background: tokens.photoBg,
boxShadow: "0 6px 26px rgba(40,80,130,.10)",
}}
>
<Image
src="/trade-in-v2/building.png"
alt=""
fill
sizes="560px"
style={{
objectFit: "contain",
objectPosition: "right center",
filter: "saturate(.9) brightness(1.04)",
}}
/>
<div
style={{
position: "absolute",
inset: 0,
background:
"linear-gradient(90deg,rgba(238,244,250,.96) 0%,rgba(238,244,250,.5) 22%,transparent 40%)",
}}
/>
<div
style={{
position: "absolute",
inset: 0,
background:
"linear-gradient(0deg,rgba(230,240,250,.45),transparent 40%)",
}}
/>
<div
style={{
position: "absolute",
left: 0,
right: 0,
top: "34%",
height: 1,
background:
"linear-gradient(90deg,transparent,rgba(46,139,255,.5),transparent)",
animation: "hero-scanv 6s linear infinite",
}}
/>
{/* address card */}
<div
style={{
position: "absolute",
left: 16,
top: "50%",
transform: "translateY(-50%)",
width: 182,
background: tokens.surface.w72,
backdropFilter: "blur(5px)",
border: `1px solid ${tokens.line}`,
borderRadius: 5,
padding: "11px 13px",
}}
>
<div
style={{
fontSize: 9,
letterSpacing: "2.5px",
color: tokens.muted2,
marginBottom: 3,
}}
>
АДРЕС
</div>
<div style={{ fontSize: 14, fontWeight: 600, lineHeight: 1.3 }}>
{object.address}
<br />
<span
style={{ fontSize: 11, fontWeight: 400, color: tokens.muted }}
>
{object.city}
</span>
</div>
<div
style={{ height: 1, background: tokens.lineSoft, margin: "8px 0" }}
/>
<div
style={{
fontFamily: tokens.font.mono,
fontSize: 9,
color: tokens.muted,
lineHeight: 1.55,
}}
>
{object.streetView}
</div>
<div
style={{ height: 1, background: tokens.lineSoft, margin: "8px 0" }}
/>
<div
className="hero-coef-row"
onClick={onOpenInfo}
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
cursor: "pointer",
borderRadius: 4,
margin: "-3px -5px",
padding: "3px 5px",
transition: "background .15s",
}}
>
<span
style={{
fontSize: "8.5px",
letterSpacing: "1.5px",
color: tokens.muted2,
}}
>
КОЭФ. ЛОКАЦИИ
</span>
<span style={{ display: "flex", alignItems: "center", gap: 6 }}>
<span
style={{
fontFamily: tokens.font.mono,
fontSize: 15,
fontWeight: 500,
color: tokens.accent,
}}
>
{object.locationCoef}
</span>
<span
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
width: 14,
height: 14,
border: `1px solid ${tokens.accent}`,
borderRadius: "50%",
fontSize: "8.5px",
color: tokens.accent,
fontWeight: 600,
}}
>
?
</span>
</span>
</div>
</div>
{/* compass */}
<div
style={{
position: "absolute",
right: 16,
top: 14,
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: 2,
color: tokens.accent,
}}
>
<svg width="22" height="22" viewBox="0 0 22 22" fill="none">
<circle cx="11" cy="11" r="10" stroke="#2e8bff" strokeWidth="1" />
<path d="M11 3 L13 11 L11 9 L9 11 Z" fill="#2e8bff" />
</svg>
<span
style={{
fontFamily: tokens.font.mono,
fontSize: 8,
letterSpacing: ".5px",
color: tokens.muted,
whiteSpace: "nowrap",
}}
>
{object.compass}
</span>
</div>
{/* distance scale */}
<div
style={{
position: "absolute",
left: "50%",
transform: "translateX(-50%)",
bottom: 16,
width: 170,
fontFamily: tokens.font.mono,
}}
>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "flex-end",
height: 8,
borderBottom: "1px solid rgba(46,139,255,.55)",
}}
>
<span
style={{
width: 1,
height: 8,
background: "rgba(46,139,255,.55)",
}}
/>
<span
style={{
width: 1,
height: 5,
background: "rgba(46,139,255,.45)",
}}
/>
<span
style={{
width: 1,
height: 5,
background: "rgba(46,139,255,.45)",
}}
/>
<span
style={{
width: 1,
height: 5,
background: "rgba(46,139,255,.45)",
}}
/>
<span
style={{
width: 1,
height: 8,
background: "rgba(46,139,255,.55)",
}}
/>
</div>
<div
style={{
display: "flex",
justifyContent: "space-between",
fontSize: "7.5px",
color: tokens.muted,
marginTop: 3,
}}
>
<span>0</span>
<span>25</span>
<span>50</span>
<span>75</span>
<span>100м</span>
</div>
</div>
{/* corner brackets */}
<div
style={{
position: "absolute",
left: 8,
top: 8,
width: 14,
height: 14,
borderLeft: `1.5px solid ${tokens.accent}`,
borderTop: `1.5px solid ${tokens.accent}`,
}}
/>
<div
style={{
position: "absolute",
right: 8,
top: 8,
width: 14,
height: 14,
borderRight: `1.5px solid ${tokens.accent}`,
borderTop: `1.5px solid ${tokens.accent}`,
}}
/>
<div
style={{
position: "absolute",
left: 8,
bottom: 8,
width: 14,
height: 14,
borderLeft: `1.5px solid ${tokens.accent}`,
borderBottom: `1.5px solid ${tokens.accent}`,
}}
/>
<div
style={{
position: "absolute",
right: 8,
bottom: 8,
width: 14,
height: 14,
borderRight: `1.5px solid ${tokens.accent}`,
borderBottom: `1.5px solid ${tokens.accent}`,
}}
/>
</div>
</div>
);
}