chore: commit pending changes — logo, base template, scratch designs, changelog

- favicon.svg: pending logo tweaks
- base.html: pending template changes
- CHANGELOG.md: add waitlist mode and logo redesign entries missed in prior commits
- scratch/: add design prototype HTML/JSX files, remove old markdown notes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Deeman
2026-02-19 23:45:42 +01:00
parent a1933eb2ba
commit bc7fbcd595
12 changed files with 3870 additions and 206 deletions

View File

@@ -0,0 +1,855 @@
import { useState } from "react";
const COLORS = {
bg: "#0A0F1C",
surface: "#111827",
surfaceLight: "#1A2236",
surfaceHover: "#1F2A40",
border: "#2A3550",
borderLight: "#354263",
accent: "#22D3A7",
accentDim: "rgba(34,211,167,0.12)",
accentGlow: "rgba(34,211,167,0.25)",
warning: "#F59E0B",
warningDim: "rgba(245,158,11,0.12)",
hot: "#EF4444",
hotDim: "rgba(239,68,68,0.12)",
blue: "#3B82F6",
blueDim: "rgba(59,130,246,0.12)",
purple: "#A78BFA",
purpleDim: "rgba(167,139,250,0.12)",
text: "#F1F5F9",
textMuted: "#94A3B8",
textDim: "#64748B",
};
const tabs = [
{ id: "dashboard", label: "Dashboard", icon: "◐" },
{ id: "leads", label: "Lead Feed", icon: "◉" },
{ id: "listing", label: "My Listing", icon: "◧" },
{ id: "boost", label: "Boost & Upsells", icon: "△" },
];
const mockLeads = [
{
id: 1,
type: "Indoor Padel Center",
courts: 6,
region: "Lower Saxony, Germany",
budget: "€400K €600K",
timeline: "Q3 2026",
specs: ["Indoor steel hall", "LED lighting", "Panoramic glass walls", "Pro-grade turf"],
posted: "2 hours ago",
heat: "hot",
credits: 25,
unlocked: false,
bidders: 1,
},
{
id: 2,
type: "Outdoor Padel Courts",
courts: 4,
region: "Bavaria, Germany",
budget: "€180K €280K",
timeline: "Q2 2026",
specs: ["Outdoor installation", "Drainage system", "Windbreak fencing", "Night lighting"],
posted: "5 hours ago",
heat: "warm",
credits: 15,
unlocked: false,
bidders: 3,
},
{
id: 3,
type: "Indoor Padel & Fitness Complex",
courts: 10,
region: "North Rhine-Westphalia, Germany",
budget: "€800K €1.2M",
timeline: "Q1 2027",
specs: ["Mixed-use facility", "Padel + gym + café", "Climate control", "Spectator area"],
posted: "1 day ago",
heat: "hot",
credits: 40,
unlocked: false,
bidders: 0,
},
{
id: 4,
type: "Padel Court Addition",
courts: 2,
region: "Hesse, Germany",
budget: "€80K €140K",
timeline: "Q4 2026",
specs: ["Tennis club conversion", "2 courts", "Basic lighting", "Standard glass"],
posted: "2 days ago",
heat: "cool",
credits: 8,
unlocked: true,
bidders: 5,
contact: { name: "Thomas M.", org: "TC Wiesbaden e.V.", email: "t.m***@tc-wiesbaden.de", phone: "+49 611 ***" },
},
{
id: 5,
type: "Commercial Padel Venue",
courts: 8,
region: "Hamburg, Germany",
budget: "€500K €750K",
timeline: "Q2 2026",
specs: ["Standalone commercial", "Bar/lounge area", "Premium courts", "Booking system integration"],
posted: "3 days ago",
heat: "warm",
credits: 30,
unlocked: false,
bidders: 2,
},
];
const upsells = [
{
id: "logo",
label: "Show Company Logo",
desc: "Display your logo next to your listing name",
price: 29,
period: "/mo",
boost: "+40% more clicks",
preselected: true,
active: true,
},
{
id: "highlight",
label: "Highlight Listing",
desc: "Yellow background to stand out in search results",
price: 39,
period: "/mo",
boost: "+65% more views",
preselected: true,
active: true,
},
{
id: "brandcolor",
label: "Custom Brand Color",
desc: "Use your brand color instead of yellow",
price: 59,
period: "/mo",
boost: "+80% brand recognition",
preselected: false,
active: false,
},
{
id: "verified",
label: "Verified Badge ✓",
desc: "Trusted supplier badge on your profile",
price: 49,
period: "/mo",
boost: "+55% more inquiries",
preselected: true,
active: true,
},
{
id: "sticky_week",
label: "Sticky Top 1 Week",
desc: "Pinned to the top of your category for 7 days",
price: 79,
period: "one-time",
boost: "2× more views",
preselected: false,
active: false,
},
{
id: "sticky_month",
label: "Sticky Top 1 Month",
desc: "Pinned to the top of your category for 30 days",
price: 199,
period: "one-time",
boost: "6× more views",
preselected: false,
active: false,
},
{
id: "newsletter",
label: "Featured in Newsletter",
desc: "Included in weekly email to 2,400+ project planners",
price: 99,
period: "/mo",
boost: "+120 targeted impressions/week",
preselected: false,
active: false,
},
{
id: "leadaccess",
label: "Lead Feed Access",
desc: "Browse & unlock leads in your categories",
price: 199,
period: "/mo",
boost: "Direct customer contact",
preselected: true,
active: true,
},
];
function HeatBadge({ heat }) {
const conf = {
hot: { bg: COLORS.hotDim, color: COLORS.hot, label: "🔥 Hot", border: "rgba(239,68,68,0.3)" },
warm: { bg: COLORS.warningDim, color: COLORS.warning, label: "◐ Warm", border: "rgba(245,158,11,0.3)" },
cool: { bg: COLORS.blueDim, color: COLORS.blue, label: "○ Cool", border: "rgba(59,130,246,0.3)" },
}[heat];
return (
<span style={{
background: conf.bg,
color: conf.color,
border: `1px solid ${conf.border}`,
padding: "3px 10px",
borderRadius: 20,
fontSize: 12,
fontWeight: 600,
letterSpacing: 0.3,
}}>{conf.label}</span>
);
}
function StatCard({ label, value, sub, color }) {
return (
<div style={{
background: COLORS.surface,
border: `1px solid ${COLORS.border}`,
borderRadius: 12,
padding: "20px 22px",
flex: 1,
minWidth: 160,
}}>
<div style={{ fontSize: 12, color: COLORS.textDim, textTransform: "uppercase", letterSpacing: 1.2, marginBottom: 8, fontWeight: 600 }}>{label}</div>
<div style={{ fontSize: 28, fontWeight: 700, color: color || COLORS.text, lineHeight: 1.1 }}>{value}</div>
{sub && <div style={{ fontSize: 12, color: COLORS.textMuted, marginTop: 6 }}>{sub}</div>}
</div>
);
}
function DashboardView() {
return (
<div>
<div style={{ marginBottom: 28 }}>
<h2 style={{ fontSize: 22, fontWeight: 700, color: COLORS.text, margin: 0 }}>Welcome back, PadelBau GmbH</h2>
<p style={{ color: COLORS.textMuted, margin: "6px 0 0", fontSize: 14 }}>Your supplier dashboard February 2026</p>
</div>
<div style={{ display: "flex", gap: 14, flexWrap: "wrap", marginBottom: 28 }}>
<StatCard label="Profile Views" value="1,247" sub="↑ 23% vs last month" color={COLORS.accent} />
<StatCard label="Leads Unlocked" value="14" sub="This month" color={COLORS.blue} />
<StatCard label="Credits Balance" value="85" sub="~3 premium leads" color={COLORS.warning} />
<StatCard label="Directory Rank" value="#3" sub="Padel Courts category" color={COLORS.purple} />
</div>
<div style={{
background: `linear-gradient(135deg, ${COLORS.accentDim}, ${COLORS.purpleDim})`,
border: `1px solid ${COLORS.border}`,
borderRadius: 12,
padding: "22px 26px",
marginBottom: 28,
}}>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 12 }}>
<div>
<div style={{ fontSize: 15, fontWeight: 600, color: COLORS.text, marginBottom: 4 }}>🔥 3 new leads match your profile</div>
<div style={{ fontSize: 13, color: COLORS.textMuted }}>Indoor facilities in Lower Saxony, NRW, and Hamburg total project value 1.7M+</div>
</div>
<button style={{
background: COLORS.accent,
color: COLORS.bg,
border: "none",
borderRadius: 8,
padding: "10px 20px",
fontWeight: 700,
fontSize: 13,
cursor: "pointer",
whiteSpace: "nowrap",
}}>View Lead Feed </button>
</div>
</div>
<h3 style={{ fontSize: 15, fontWeight: 600, color: COLORS.text, marginBottom: 14 }}>Recent Activity</h3>
{[
{ time: "2h ago", text: "New lead posted: 6-court indoor center in Lower Saxony (€400K€600K)", dot: COLORS.hot },
{ time: "1d ago", text: "Your listing was viewed 47 times today — 12 from the Padel Courts category", dot: COLORS.accent },
{ time: "2d ago", text: "Lead unlocked: TC Wiesbaden — 2-court addition project. Contact details available.", dot: COLORS.blue },
{ time: "3d ago", text: "Your 'Sticky Top' placement in Padel Courts expired. Renew to stay on top.", dot: COLORS.warning },
{ time: "5d ago", text: "Newsletter sent to 2,400 subscribers — your company was featured", dot: COLORS.purple },
].map((item, i) => (
<div key={i} style={{
display: "flex",
gap: 14,
padding: "12px 0",
borderBottom: i < 4 ? `1px solid ${COLORS.border}` : "none",
alignItems: "flex-start",
}}>
<div style={{ width: 8, height: 8, borderRadius: 4, background: item.dot, marginTop: 6, flexShrink: 0 }} />
<div style={{ flex: 1 }}>
<div style={{ fontSize: 13, color: COLORS.text, lineHeight: 1.5 }}>{item.text}</div>
</div>
<div style={{ fontSize: 12, color: COLORS.textDim, whiteSpace: "nowrap", flexShrink: 0 }}>{item.time}</div>
</div>
))}
</div>
);
}
function LeadFeedView() {
const [leads, setLeads] = useState(mockLeads);
const [filter, setFilter] = useState("all");
const unlock = (id) => {
setLeads(leads.map(l => l.id === id ? {
...l,
unlocked: true,
contact: { name: "Max S.", org: "Padel Invest Nord GmbH", email: "m.s***@padel-invest.de", phone: "+49 40 ***" }
} : l));
};
const filtered = filter === "all" ? leads : leads.filter(l => l.heat === filter);
return (
<div>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 24, flexWrap: "wrap", gap: 12 }}>
<div>
<h2 style={{ fontSize: 22, fontWeight: 700, color: COLORS.text, margin: 0 }}>Lead Feed</h2>
<p style={{ color: COLORS.textMuted, margin: "6px 0 0", fontSize: 14 }}>Browse anonymized project briefs · Spend credits to unlock contact details</p>
</div>
<div style={{
background: COLORS.surface,
border: `1px solid ${COLORS.border}`,
borderRadius: 8,
padding: "8px 14px",
display: "flex",
alignItems: "center",
gap: 8,
}}>
<span style={{ fontSize: 12, color: COLORS.textDim }}>Balance:</span>
<span style={{ fontSize: 16, fontWeight: 700, color: COLORS.warning }}>85 credits</span>
<button style={{
background: COLORS.warningDim,
color: COLORS.warning,
border: `1px solid rgba(245,158,11,0.3)`,
borderRadius: 6,
padding: "4px 10px",
fontSize: 11,
fontWeight: 600,
cursor: "pointer",
marginLeft: 4,
}}>Buy More</button>
</div>
</div>
<div style={{ display: "flex", gap: 8, marginBottom: 20 }}>
{[
{ id: "all", label: "All Leads" },
{ id: "hot", label: "🔥 Hot" },
{ id: "warm", label: "◐ Warm" },
{ id: "cool", label: "○ Cool" },
].map(f => (
<button key={f.id} onClick={() => setFilter(f.id)} style={{
background: filter === f.id ? COLORS.accentDim : "transparent",
color: filter === f.id ? COLORS.accent : COLORS.textMuted,
border: `1px solid ${filter === f.id ? "rgba(34,211,167,0.3)" : COLORS.border}`,
borderRadius: 20,
padding: "6px 16px",
fontSize: 12,
fontWeight: 600,
cursor: "pointer",
}}>{f.label}</button>
))}
</div>
<div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
{filtered.map(lead => (
<div key={lead.id} style={{
background: lead.unlocked ? COLORS.surface : COLORS.surfaceLight,
border: `1px solid ${lead.heat === "hot" ? "rgba(239,68,68,0.2)" : COLORS.border}`,
borderRadius: 12,
padding: "20px 22px",
position: "relative",
overflow: "hidden",
}}>
{lead.heat === "hot" && !lead.unlocked && (
<div style={{
position: "absolute",
top: 0,
left: 0,
right: 0,
height: 2,
background: `linear-gradient(90deg, ${COLORS.hot}, ${COLORS.warning})`,
}} />
)}
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 12, flexWrap: "wrap", gap: 8 }}>
<div>
<div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
<span style={{ fontSize: 16, fontWeight: 700, color: COLORS.text }}>{lead.type}</span>
<HeatBadge heat={lead.heat} />
</div>
<div style={{ display: "flex", gap: 16, flexWrap: "wrap" }}>
<span style={{ fontSize: 13, color: COLORS.textMuted }}>📍 {lead.region}</span>
<span style={{ fontSize: 13, color: COLORS.textMuted }}>🏟 {lead.courts} courts</span>
<span style={{ fontSize: 13, color: COLORS.textMuted }}>💰 {lead.budget}</span>
<span style={{ fontSize: 13, color: COLORS.textMuted }}>📅 {lead.timeline}</span>
</div>
</div>
<div style={{ fontSize: 12, color: COLORS.textDim }}>{lead.posted}</div>
</div>
<div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginBottom: 14 }}>
{lead.specs.map((s, i) => (
<span key={i} style={{
background: COLORS.bg,
color: COLORS.textMuted,
border: `1px solid ${COLORS.border}`,
borderRadius: 6,
padding: "3px 10px",
fontSize: 11,
fontWeight: 500,
}}>{s}</span>
))}
</div>
{lead.unlocked ? (
<div style={{
background: COLORS.accentDim,
border: `1px solid rgba(34,211,167,0.2)`,
borderRadius: 8,
padding: "14px 18px",
}}>
<div style={{ fontSize: 12, color: COLORS.accent, fontWeight: 600, marginBottom: 8, textTransform: "uppercase", letterSpacing: 0.8 }}> Contact Unlocked</div>
<div style={{ display: "flex", gap: 24, flexWrap: "wrap" }}>
<div>
<div style={{ fontSize: 11, color: COLORS.textDim }}>Contact</div>
<div style={{ fontSize: 13, color: COLORS.text, fontWeight: 600 }}>{lead.contact.name}</div>
</div>
<div>
<div style={{ fontSize: 11, color: COLORS.textDim }}>Organization</div>
<div style={{ fontSize: 13, color: COLORS.text, fontWeight: 600 }}>{lead.contact.org}</div>
</div>
<div>
<div style={{ fontSize: 11, color: COLORS.textDim }}>Email</div>
<div style={{ fontSize: 13, color: COLORS.text, fontWeight: 600 }}>{lead.contact.email}</div>
</div>
<div>
<div style={{ fontSize: 11, color: COLORS.textDim }}>Phone</div>
<div style={{ fontSize: 13, color: COLORS.text, fontWeight: 600 }}>{lead.contact.phone}</div>
</div>
</div>
</div>
) : (
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 10 }}>
<div style={{ fontSize: 12, color: COLORS.textDim }}>
{lead.bidders === 0 ? (
<span style={{ color: COLORS.accent, fontWeight: 600 }}> No other suppliers yet be first!</span>
) : (
<span>{lead.bidders} supplier{lead.bidders > 1 ? "s" : ""} already unlocked this lead</span>
)}
</div>
<button onClick={() => unlock(lead.id)} style={{
background: `linear-gradient(135deg, ${COLORS.accent}, #1AAB8A)`,
color: COLORS.bg,
border: "none",
borderRadius: 8,
padding: "10px 20px",
fontWeight: 700,
fontSize: 13,
cursor: "pointer",
display: "flex",
alignItems: "center",
gap: 8,
}}>
<span>Unlock Contact</span>
<span style={{
background: "rgba(0,0,0,0.2)",
borderRadius: 4,
padding: "2px 8px",
fontSize: 12,
}}>{lead.credits} credits</span>
</button>
</div>
)}
</div>
))}
</div>
</div>
);
}
function ListingView() {
return (
<div>
<h2 style={{ fontSize: 22, fontWeight: 700, color: COLORS.text, margin: "0 0 6px" }}>Your Listing Preview</h2>
<p style={{ color: COLORS.textMuted, margin: "0 0 24px", fontSize: 14 }}>This is how your company appears in the directory</p>
{/* Listing card preview */}
<div style={{
background: "linear-gradient(135deg, rgba(245,158,11,0.06), rgba(245,158,11,0.02))",
border: `1px solid rgba(245,158,11,0.25)`,
borderRadius: 14,
padding: "24px 26px",
marginBottom: 28,
position: "relative",
}}>
<div style={{
position: "absolute",
top: 12,
right: 14,
background: COLORS.warningDim,
color: COLORS.warning,
border: `1px solid rgba(245,158,11,0.3)`,
padding: "3px 10px",
borderRadius: 20,
fontSize: 11,
fontWeight: 700,
letterSpacing: 0.5,
}}> PROMOTED</div>
<div style={{ display: "flex", gap: 18, alignItems: "flex-start", marginBottom: 16 }}>
<div style={{
width: 56,
height: 56,
borderRadius: 10,
background: `linear-gradient(135deg, ${COLORS.accent}, ${COLORS.blue})`,
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: 22,
fontWeight: 800,
color: COLORS.bg,
flexShrink: 0,
}}>PB</div>
<div>
<div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 4 }}>
<span style={{ fontSize: 18, fontWeight: 700, color: COLORS.text }}>PadelBau GmbH</span>
<span style={{
background: COLORS.accentDim,
color: COLORS.accent,
border: `1px solid rgba(34,211,167,0.3)`,
padding: "2px 8px",
borderRadius: 4,
fontSize: 10,
fontWeight: 700,
}}> VERIFIED</span>
</div>
<div style={{ fontSize: 13, color: COLORS.textMuted, marginBottom: 8 }}>Premium padel court manufacturer & installer. 150+ courts built across DACH region. Full-service from planning to turnkey delivery.</div>
<div style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
<span style={{ fontSize: 12, color: COLORS.textDim }}>📍 Cologne, Germany</span>
<span style={{ fontSize: 12, color: COLORS.textDim }}>🏟 150+ courts installed</span>
<span style={{ fontSize: 12, color: COLORS.textDim }}> 4.8/5 (23 reviews)</span>
</div>
</div>
</div>
<div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
{["Padel Courts", "Court Construction", "LED Lighting", "Artificial Turf", "Planning & Design"].map((tag, i) => (
<span key={i} style={{
background: COLORS.bg,
color: COLORS.textMuted,
border: `1px solid ${COLORS.border}`,
borderRadius: 6,
padding: "4px 10px",
fontSize: 11,
fontWeight: 500,
}}>{tag}</span>
))}
</div>
</div>
<h3 style={{ fontSize: 15, fontWeight: 600, color: COLORS.text, marginBottom: 14 }}>Active Boosts on Your Listing</h3>
<div style={{ display: "flex", gap: 10, flexWrap: "wrap", marginBottom: 28 }}>
{[
{ label: "Logo Visible", color: COLORS.accent },
{ label: "Yellow Highlight", color: COLORS.warning },
{ label: "Verified Badge", color: COLORS.accent },
{ label: "Lead Feed Access", color: COLORS.blue },
].map((b, i) => (
<span key={i} style={{
background: `${b.color}15`,
color: b.color,
border: `1px solid ${b.color}30`,
padding: "6px 14px",
borderRadius: 8,
fontSize: 12,
fontWeight: 600,
}}> {b.label}</span>
))}
</div>
<h3 style={{ fontSize: 15, fontWeight: 600, color: COLORS.text, marginBottom: 14 }}>Listing Performance (Last 30 Days)</h3>
<div style={{ display: "flex", gap: 14, flexWrap: "wrap" }}>
<StatCard label="Views" value="1,247" sub="From directory search" color={COLORS.accent} />
<StatCard label="Profile Clicks" value="183" sub="14.7% click rate" color={COLORS.blue} />
<StatCard label="Website Clicks" value="67" sub="From your listing" color={COLORS.purple} />
<StatCard label="Contact Requests" value="12" sub="Direct inquiries" color={COLORS.warning} />
</div>
</div>
);
}
function BoostView() {
const [selected, setSelected] = useState(
Object.fromEntries(upsells.map(u => [u.id, u.preselected]))
);
const toggle = (id) => setSelected({ ...selected, [id]: !selected[id] });
const total = upsells.reduce((sum, u) => {
if (!selected[u.id]) return sum;
return sum + u.price;
}, 0);
const monthlyTotal = upsells.reduce((sum, u) => {
if (!selected[u.id] || u.period !== "/mo") return sum;
return sum + u.price;
}, 0);
const viewMultiplier = upsells.reduce((mult, u) => {
if (!selected[u.id]) return mult;
const m = parseFloat(u.boost.match(/[\d.]+/)?.[0] || 0);
if (u.boost.includes("×")) return mult * m;
if (u.boost.includes("%")) return mult * (1 + m / 100);
return mult;
}, 1);
return (
<div>
<h2 style={{ fontSize: 22, fontWeight: 700, color: COLORS.text, margin: "0 0 6px" }}>Boost Your Visibility</h2>
<p style={{ color: COLORS.textMuted, margin: "0 0 24px", fontSize: 14 }}>Select upgrades to stand out · Pre-selected options are our recommendation</p>
<div style={{ display: "flex", gap: 20, flexWrap: "wrap" }}>
{/* Upsell list */}
<div style={{ flex: "1 1 400px", display: "flex", flexDirection: "column", gap: 10 }}>
{upsells.map(u => {
const isOn = selected[u.id];
return (
<div key={u.id} onClick={() => toggle(u.id)} style={{
background: isOn ? COLORS.surfaceLight : COLORS.surface,
border: `1px solid ${isOn ? COLORS.accent + "40" : COLORS.border}`,
borderRadius: 10,
padding: "16px 18px",
cursor: "pointer",
transition: "all 0.15s",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
gap: 14,
}}>
<div style={{ display: "flex", gap: 14, alignItems: "center", flex: 1 }}>
<div style={{
width: 22,
height: 22,
borderRadius: 6,
border: `2px solid ${isOn ? COLORS.accent : COLORS.textDim}`,
background: isOn ? COLORS.accent : "transparent",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: 13,
color: COLORS.bg,
fontWeight: 800,
flexShrink: 0,
}}>{isOn ? "✓" : ""}</div>
<div>
<div style={{ fontSize: 14, fontWeight: 600, color: COLORS.text, marginBottom: 2 }}>{u.label}</div>
<div style={{ fontSize: 12, color: COLORS.textDim }}>{u.desc}</div>
</div>
</div>
<div style={{ textAlign: "right", flexShrink: 0 }}>
<div style={{ fontSize: 16, fontWeight: 700, color: isOn ? COLORS.accent : COLORS.textMuted }}>{u.price}<span style={{ fontSize: 11, fontWeight: 400, color: COLORS.textDim }}>{u.period}</span></div>
<div style={{
fontSize: 11,
color: COLORS.accent,
background: COLORS.accentDim,
borderRadius: 4,
padding: "2px 8px",
marginTop: 4,
display: "inline-block",
fontWeight: 600,
}}>{u.boost}</div>
</div>
</div>
);
})}
</div>
{/* Summary sidebar */}
<div style={{
flex: "0 0 260px",
position: "sticky",
top: 20,
alignSelf: "flex-start",
}}>
<div style={{
background: COLORS.surface,
border: `1px solid ${COLORS.border}`,
borderRadius: 12,
padding: "22px 20px",
}}>
<div style={{ fontSize: 13, color: COLORS.textDim, textTransform: "uppercase", letterSpacing: 1, marginBottom: 16, fontWeight: 600 }}>Your Plan</div>
{upsells.filter(u => selected[u.id]).map(u => (
<div key={u.id} style={{
display: "flex",
justifyContent: "space-between",
fontSize: 13,
color: COLORS.text,
marginBottom: 8,
}}>
<span>{u.label}</span>
<span style={{ color: COLORS.textMuted }}>{u.price}</span>
</div>
))}
<div style={{
borderTop: `1px solid ${COLORS.border}`,
marginTop: 14,
paddingTop: 14,
}}>
<div style={{ display: "flex", justifyContent: "space-between", marginBottom: 4 }}>
<span style={{ fontSize: 14, fontWeight: 700, color: COLORS.text }}>Monthly</span>
<span style={{ fontSize: 18, fontWeight: 700, color: COLORS.accent }}>{monthlyTotal}/mo</span>
</div>
</div>
<div style={{
background: COLORS.accentDim,
borderRadius: 8,
padding: "12px 14px",
marginTop: 16,
textAlign: "center",
}}>
<div style={{ fontSize: 12, color: COLORS.textMuted, marginBottom: 2 }}>Estimated view boost</div>
<div style={{ fontSize: 22, fontWeight: 800, color: COLORS.accent }}>{viewMultiplier.toFixed(1)}×</div>
<div style={{ fontSize: 11, color: COLORS.textDim }}>more visibility vs basic listing</div>
</div>
<button style={{
width: "100%",
background: `linear-gradient(135deg, ${COLORS.accent}, #1AAB8A)`,
color: COLORS.bg,
border: "none",
borderRadius: 8,
padding: "12px 0",
fontWeight: 700,
fontSize: 14,
cursor: "pointer",
marginTop: 16,
}}>Update Plan </button>
<div style={{ fontSize: 11, color: COLORS.textDim, textAlign: "center", marginTop: 10 }}>
Cancel anytime · No lock-in contracts
</div>
</div>
</div>
</div>
</div>
);
}
export default function SupplierDashboard() {
const [activeTab, setActiveTab] = useState("dashboard");
return (
<div style={{
fontFamily: "'DM Sans', 'Manrope', system-ui, sans-serif",
background: COLORS.bg,
color: COLORS.text,
minHeight: "100vh",
display: "flex",
}}>
{/* Sidebar */}
<div style={{
width: 220,
background: COLORS.surface,
borderRight: `1px solid ${COLORS.border}`,
padding: "20px 0",
display: "flex",
flexDirection: "column",
flexShrink: 0,
}}>
<div style={{
padding: "0 20px 20px",
borderBottom: `1px solid ${COLORS.border}`,
marginBottom: 14,
}}>
<div style={{
fontSize: 17,
fontWeight: 800,
color: COLORS.accent,
letterSpacing: -0.5,
}}> PadelConnect</div>
<div style={{ fontSize: 11, color: COLORS.textDim, marginTop: 2 }}>Supplier Portal</div>
</div>
<div style={{ flex: 1 }}>
{tabs.map(tab => (
<button key={tab.id} onClick={() => setActiveTab(tab.id)} style={{
width: "100%",
display: "flex",
alignItems: "center",
gap: 10,
padding: "10px 20px",
border: "none",
background: activeTab === tab.id ? COLORS.accentDim : "transparent",
color: activeTab === tab.id ? COLORS.accent : COLORS.textMuted,
fontSize: 13,
fontWeight: activeTab === tab.id ? 600 : 400,
cursor: "pointer",
textAlign: "left",
borderRight: activeTab === tab.id ? `2px solid ${COLORS.accent}` : "2px solid transparent",
}}>
<span style={{ fontSize: 16 }}>{tab.icon}</span>
{tab.label}
{tab.id === "leads" && (
<span style={{
marginLeft: "auto",
background: COLORS.hotDim,
color: COLORS.hot,
borderRadius: 10,
padding: "1px 7px",
fontSize: 11,
fontWeight: 700,
}}>3</span>
)}
</button>
))}
</div>
<div style={{
padding: "14px 20px",
borderTop: `1px solid ${COLORS.border}`,
}}>
<div style={{ display: "flex", alignItems: "center", gap: 10 }}>
<div style={{
width: 32,
height: 32,
borderRadius: 8,
background: `linear-gradient(135deg, ${COLORS.accent}, ${COLORS.blue})`,
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: 13,
fontWeight: 700,
color: COLORS.bg,
}}>PB</div>
<div>
<div style={{ fontSize: 12, fontWeight: 600, color: COLORS.text }}>PadelBau GmbH</div>
<div style={{ fontSize: 11, color: COLORS.textDim }}>Premium Plan</div>
</div>
</div>
</div>
</div>
{/* Main content */}
<div style={{
flex: 1,
padding: "28px 32px",
overflowY: "auto",
maxHeight: "100vh",
}}>
{activeTab === "dashboard" && <DashboardView />}
{activeTab === "leads" && <LeadFeedView />}
{activeTab === "listing" && <ListingView />}
{activeTab === "boost" && <BoostView />}
</div>
</div>
);
}