/* ============================================================ RESTO SUITE — PITCH SUMMARY DASHBOARD (step 03) READ-ONLY. Synthesizes plan.idea + plan.financials into a one-page investor/lender summary. Collects no inputs, writes nothing. Never crashes on partial data. ============================================================ */ function PitchMeta({ items }) { const parts = items.filter(Boolean); if (!parts.length) return null; return (
{parts.map((p, i) => ( {i > 0 && ·} {p} ))}
); } function PitchEmpty({ missing, setActive }) { const { t } = useLang(); return (
{t("pitch.almostThere")}

{t("pitch.emptyBase")} {missing === "both" ? t("pitch.emptyBoth") : missing === "idea" ? t("pitch.emptyIdea") : t("pitch.emptyFin")}

{(missing === "both" || missing === "idea") && } {missing === "fin" && }
); } function PitchPnlRow({ label, value, sub, strong, tone, indent }) { const col = tone === "green" ? "var(--green)" : tone === "red" ? "var(--red)" : "var(--ink)"; return (
{label} {sub && {sub}} {value}
); } function PitchDashboard({ plan, setActive, openIE }) { const { t, lang } = useLang(); const ol = (v) => optLabel(lang, v); const idea = plan.idea || IDEA_DEFAULTS; const fin = plan.financials || FIN_DEFAULTS; const live = computeFin(fin, t); const check = computeIdea(idea, t, lang); const ideaReady = !!(idea.conceptName || idea.category || idea.usp || check.readiness >= 25); const finReady = live.sales > 0 && live.investment > 0; if (!ideaReady || !finReady) { return ( ); } const v = live.verdict; const dash = (s) => (s && String(s).trim() ? s : null); const mix = idea.channelMix || { dineIn: 0, delivery: 0, takeaway: 0 }; const seats = (idea.format || {}).seats || 0; const sqm = (idea.format || {}).sqm || 0; const who = (idea.targetCustomer || []).map(ol).join(", "); const neg = (n) => `${n < 0 ? "−" : ""}${fmtBaht(Math.abs(n))}`; const conceptLines = [ who ? t("pitch.builtFor", { who: who.toLowerCase() }) + (idea.locationType ? t("pitch.inSetting", { loc: ol(idea.locationType).toLowerCase() }) : "") + (idea.priceBand ? t("pitch.atPrices", { band: ol(idea.priceBand).toLowerCase(), range: priceRange(idea.priceBand, lang) }) : "") + "." : null, seats || sqm ? t("pitch.theFormat", { seatsPart: seats ? t("pitch.seatsCount", { n: seats }) : t("pitch.noSeating"), sqmPart: sqm ? t("pitch.onSqm", { n: sqm }) : "", svc: (idea.format || {}).serviceStyle ? `, ${ol(idea.format.serviceStyle).toLowerCase()}` : "", dine: mix.dineIn, del: mix.delivery, take: mix.takeaway, }) : null, ].filter(Boolean); const watchFlags = check.flags.filter((f) => f.tone !== "green").slice(0, 5); return (
{/* a) header */}

{dash(idea.conceptName) || t("pitch.untitledConcept")}

{dash(idea.tagline) &&
“{idea.tagline}”
}
{t("pitch.investmentVerdict")}
{v.label}
{t("pitch.fromAfterTaxMargin")}
{/* b) the ask */}
{t("pitch.theAsk")}
= 0 ? "green" : "red"} /> = 0.12 ? "green" : live.netMargin > 0 ? "amber" : "red"} />
{/* c) the concept */} {(conceptLines.length > 0 || dash(idea.usp)) && (

{t("pitch.theConcept")}

{conceptLines.map((l, i) =>

{l}

)} {dash(idea.usp) && (
{t("pitch.theDifferentiator")}
{idea.usp}
)}
)} {/* d) the numbers */}

{t("pitch.theNumbersMonthly")}

= 0 ? "green" : "red"} />
{/* e) what to watch */}

{t("pitch.whatToWatch")}

{t("pitch.whatToWatchDesc")}
{watchFlags.length > 0 ? watchFlags.map((f, i) => ) : }
{check.riskiest && (
{t("pitch.testFirst")} {check.riskiest.text}
)}
{t("pitch.disclaimer")}
{/* f) actions */}
); } Object.assign(window, { PitchDashboard });