/* global React */ /* Cosidata Portal · diagnóstico data-driven por e-mail (onboarding_responses) */ const { useState: useStateDg, useEffect: useEffectDg } = React; const DG_SUPABASE_URL = "https://guydmkcqklluhfqtmvnx.supabase.co"; const DG_SUPABASE_ANON_KEY = "sb_publishable_zwjW1d7ey0myfWUj5lgQKA_osGdvTuY"; const DG_OND = { excel: "Excel / Google Sheets", erp: "Sistema ERP", crm: "CRM", sql: "Base SQL / Data Warehouse", arquivos: "Arquivos soltos (PDF, e-mail, WhatsApp)", naosabe: "Não sabe ao certo", outro: "Outro", }; const DG_DASH = { sim: "Sim", nao: "Ainda não", construindo: "Em construção" }; const DG_IA = { sim: "Sim, ativamente", experimentei: "Experimentou, não usa", nao: "Ainda não" }; const DG_FIN = { sim: "Estruturado", parcial: "Parcial", nao: "Não" }; const DG_BUD = { ate50: "até 50", "50-150": "50–150", "150-500": "150–500", "500+": "+500", nd: "a definir" }; const DG_MOEDA = { BRL: "R$", EUR: "€", USD: "$" }; const DG_MAT = { 1: "Tudo no feeling", 2: "Quase tudo na intuição", 3: "Decisões mistas", 4: "Bastante orientada a dados", 5: "100% orientada a dados", }; const DG_TONE = { green: "#16A085", amber: "#D9A400", red: "#D64545", muted: "#5F6175" }; async function fetchOnboardingRow(email, token) { const url = DG_SUPABASE_URL + "/rest/v1/onboarding_responses?select=*&email=eq." + encodeURIComponent(email); const headers = { apikey: DG_SUPABASE_ANON_KEY }; if (token) headers.Authorization = "Bearer " + token; const res = await fetch(url, { headers }); if (!res.ok) throw new Error("Supabase " + res.status + ": " + (await res.text().catch(() => ""))); const rows = await res.json(); return rows && rows.length ? rows[rows.length - 1] : null; } function normalizeOnboarding(r) { if (!r) return null; const onde = (r.onde_dados || []).map(k => k === "outro" ? (r.onde_dados_outro || "Outro") : (DG_OND[k] || k)); const ferramentas = (r.ferramentas || "").split(",").map(s => s.trim()).filter(Boolean); const mat = Number(r.maturidade_dados) || 0; const status = [ { label: "Dashboard de decisão", value: DG_DASH[r.usa_dashboard] || "–", tone: r.usa_dashboard === "sim" ? "green" : "muted" }, { label: "Uso de IA", value: DG_IA[r.usa_ia] || "–", tone: r.usa_ia === "sim" ? "green" : r.usa_ia === "experimentei" ? "amber" : "muted" }, { label: "Controle financeiro", value: DG_FIN[r.controle_financeiro] || "–", tone: r.controle_financeiro === "sim" ? "green" : r.controle_financeiro === "parcial" ? "amber" : "red" }, ]; const temBudget = r.budget_valor && r.budget_valor !== "nd"; const budget = ((DG_MOEDA[r.budget_moeda] || "") + " " + (DG_BUD[r.budget_valor] || "–")).trim() + (temBudget ? " / mês" : ""); function toUrl(raw) { return raw && !raw.startsWith("http") ? "https://" + raw : (raw || ""); } function igHandle(v) { return v.match(/instagram\.com\/([^/?#]+)/)?.[1] || v.replace(/^@/, ""); } function liHandle(v) { return v.match(/linkedin\.com\/(?:in|company)\/([^/?#]+)/)?.[1] || null; } function ytHandle(v) { return v.match(/youtube\.com\/(?:@|c\/|channel\/|user\/)?([^/?#]+)/)?.[1] || v.match(/youtu\.be\/([^/?#]+)/)?.[1] || null; } function fbHandle(v) { return v.match(/facebook\.com\/([^/?#]+)/)?.[1] || null; } function xHandle(v) { return v.match(/(?:twitter|x)\.com\/([^/?#]+)/)?.[1] || v.replace(/^@/, ""); } function ttHandle(v) { return v.match(/tiktok\.com\/@?([^/?#]+)/)?.[1] || v.replace(/^@/, ""); } const presenca = []; if (r.site) presenca.push({ type: "site", label: r.site.replace(/^https?:\/\//, "").replace(/\/$/, ""), url: toUrl(r.site) }); if (r.instagram) presenca.push({ type: "instagram", label: "@" + igHandle(r.instagram), url: r.instagram.startsWith("http") ? r.instagram : "https://instagram.com/" + igHandle(r.instagram) }); if (r.linkedin) presenca.push({ type: "linkedin", label: liHandle(r.linkedin) || "LinkedIn", url: toUrl(r.linkedin) }); if (r.youtube) presenca.push({ type: "youtube", label: (ytHandle(r.youtube) ? "@" + ytHandle(r.youtube) : "YouTube"), url: toUrl(r.youtube) }); if (r.facebook) presenca.push({ type: "facebook", label: fbHandle(r.facebook) || "Facebook", url: toUrl(r.facebook) }); if (r.x_twitter) presenca.push({ type: "x_twitter", label: "@" + xHandle(r.x_twitter), url: r.x_twitter.startsWith("http") ? r.x_twitter : "https://x.com/" + xHandle(r.x_twitter) }); if (r.tiktok) presenca.push({ type: "tiktok", label: "@" + ttHandle(r.tiktok), url: r.tiktok.startsWith("http") ? r.tiktok : "https://tiktok.com/@" + ttHandle(r.tiktok) }); if (r.outras_redes) presenca.push({ type: "other", label: r.outras_redes.replace(/^https?:\/\//, "").replace(/\/$/, ""), url: r.outras_redes.startsWith("http") ? r.outras_redes : "" }); const facts = [ { k: "Negócio", v: r.empresa || "–" }, { k: "Função", v: r.cargo || "–" }, { k: "Setor", v: r.setor || "–" }, { k: "Porte", v: r.tamanho_empresa || "–" }, { k: "Localização", v: r.cidade_pais || "–" }, ]; const firstName = (r.nome || "").trim().split(/\s+/)[0] || ""; return { raw: r, nome: r.nome || "Cliente", firstName, empresa: r.empresa || "", facts, presenca, onde, ferramentas, status, budget, mat, matLabel: DG_MAT[mat] || "–", objetivo: r.objetivo_mentoria || "", prioridade: r.prioridade || "", jaTentou: r.ja_tentou || "", diag: r.diagnostico || null, }; } function DgSecHead({ n, eyebrow, title }) { return (
{n} {eyebrow}

{title}

); } function DgPills({ items, accent }) { return (
{items.length === 0 && } {items.map((p, i) => ( {p} ))}
); } function DgState({ icon, title, sub, children }) { useLucide(); return (

{title}

{sub &&

{sub}

} {children &&
{children}
}
); } function DiagnosticReport({ d, onPrint }) { return (

Diagnóstico

{d.diag ? "Concluído" : "Leitura do onboarding"}
Sessão 00 · {d.empresa || d.nome}

Olá, {d.firstName || d.nome}. Esta é a leitura do seu onboarding — o ponto de partida da sua jornada COSI. Tudo aqui vem das suas próprias respostas.

{d.facts.map((f, i) => (
{f.k}
{f.v}
))}
{d.presenca && d.presenca.length > 0 && (
Presença online
{d.presenca.map((p, i) => { const BRAND = { site: { icon: "globe", color: "#4337A5", bg: "rgba(67,55,165,.10)" }, instagram: { icon: "instagram", color: "#F77737", bg: "rgba(247,119,55,.10)" }, linkedin: { icon: "linkedin", color: "#0A66C2", bg: "rgba(10,102,194,.10)" }, youtube: { icon: "youtube", color: "#FF0000", bg: "rgba(255,0,0,.10)" }, facebook: { icon: "facebook", color: "#1877F2", bg: "rgba(24,119,242,.10)" }, x_twitter: { icon: "twitter", color: "#000000", bg: "rgba(0,0,0,.07)" }, tiktok: { icon: null, color: "#010101", bg: "rgba(0,0,0,.07)" }, other: { icon: "link", color: "#5F6175", bg: "var(--surface-2)" }, }; const b = BRAND[p.type] || BRAND.other; const chipStyle = { display: "inline-flex", alignItems: "center", gap: 7, padding: "8px 16px", borderRadius: 999, background: b.bg, border: "1px solid " + b.color + "33", fontSize: 13.5, fontWeight: 700, color: b.color, textDecoration: "none", transition: "opacity .15s" }; const TikTokSvg = () => ( ); const iconEl = p.type === "tiktok" ? : b.icon ? : null; const inner = {iconEl}{p.label}; return p.url ? {inner} : {inner}; })}
)}
Fontes de dados
Ferramentas do dia a dia
{d.status.map((s, i) => (
{s.label}
{s.value}
))}
Budget p/ ferramentas {d.budget}
{d.mat}
de 5
{[1,2,3,4,5].map(n => (
{n}
))}
Tudo no feelingDecisões 100% em dados

{d.matLabel}. É o ponto de partida — e exatamente onde o método COSI mais acelera.

{d.objetivo && (

"{d.objetivo}"

)}
Prioridade nº 1
{d.prioridade || "–"}
{d.jaTentou && (
Já tentou, sem sucesso

{d.jaTentou}

)}
{d.diag && d.diag.resumo ? (
Síntese
{d.diag.resumo}
{d.diag.focos && d.diag.focos.length > 0 && (
{d.diag.focos.map((f, i) => (
{f.n}
{f.titulo}

{f.texto}

))}
)} {d.diag.metodo && d.diag.metodo.length > 0 && (
O método COSI

Quatro fases, da base à inteligência — nessa ordem.

{d.diag.metodo.map((m, i) => { const atual = i === (d.diag.faseAtual ?? -1); const feita = i < (d.diag.faseAtual ?? -1); return (
{m.letra}
{m.fase} {atual && Você está aqui} {feita && }
{m.sessoes}

{m.t}

); })}
)} {d.diag.proximos && (
Próximo passo · {d.diag.proximos}
)}
) : (
A leitura da Cosidata aparecerá aqui
Depois da sua sessão de diagnóstico, a síntese fica disponível nesta página.
)}
); } function ClientDiagnostic({ user, row: providedRow, diagFallback, onPrint }) { useLucide(); const [st, setSt] = useStateDg(providedRow ? { s: "ok", row: providedRow } : { s: "loading" }); useEffectDg(() => { if (providedRow) { setSt({ s: "ok", row: providedRow }); return; } let alive = true; (async () => { try { const email = user && (user.email || user.mail); const token = user && (user.token || user.access_token); if (!email) { setSt({ s: "error", msg: "Não foi possível identificar o e-mail da sessão." }); return; } const row = await fetchOnboardingRow(email, token); if (!alive) return; setSt(row ? { s: "ok", row } : { s: "empty" }); } catch (e) { if (alive) setSt({ s: "error", msg: e.message }); } })(); return () => { alive = false; }; }, [user, providedRow]); useEffectDg(() => { if (window.lucide) window.lucide.createIcons(); }); const doPrint = onPrint || (() => window.print()); if (st.s === "loading") return ; if (st.s === "error") return ; if (st.s === "empty" && !diagFallback) return ; const row = Object.assign({}, st.s === "empty" ? {} : st.row); if (!row.diagnostico && diagFallback) row.diagnostico = diagFallback; const d = normalizeOnboarding(row); return ; } Object.assign(window, { ClientDiagnostic, normalizeOnboarding, DiagnosticReport, fetchOnboardingRow });