// ESTÚDIO — Páginas A: Dashboard, Perfil Estratégico, Calendário (function () { const { useState } = React; const D = window.DATA; const { PlatRow, PlatIcon, PerfilTag, Chip, EnergiaBadge, Bar, Stars, PageHead, Card, fmtData, daysDiff } = window.UI; const h = React.createElement; function pilar(id) { return D.pilares.find((p) => p.id === id); } // ══════════════════ DASHBOARD ══════════════════ function Dashboard({ initialMarca }) { const [marca, setMarca] = useState(initialMarca || "geral"); const { state } = window.STORE.useStore(); const CONT = state.conteudos; const publicados = CONT.filter((c) => c.status === "Publicado"); function proximos(pid) { return CONT.filter((c) => c.perfis.includes(pid) && c.status !== "Publicado" && c.publicacao) .sort((a, b) => a.publicacao.localeCompare(b.publicacao)); } function atrasados(pid) { return CONT.filter((c) => c.perfis.includes(pid) && c.status !== "Publicado" && c.publicacao && daysDiff(c.publicacao) < 0); } // distribuição REAL dos pilares = % de conteúdos por pilar (calculado dos dados) function pilarReal(perfilId, pilId) { const cont = CONT.filter((c) => c.perfis.includes(perfilId)); const total = cont.length || 1; return Math.round((cont.filter((c) => c.pilar === pilId).length / total) * 100); } function col(p) { const prox = proximos(p.id).filter((c) => daysDiff(c.publicacao) >= 0).slice(0, 4); const atr = atrasados(p.id); const pils = D.pilares.filter((pl) => pl.perfil === p.id); return h(Card, { key: p.id, className: "dash-col" }, h("div", { className: "dash-col-head" }, h("span", { className: "perfil-dot big", style: { background: p.cor } }), h("div", null, h("div", { className: "dash-col-name" }, p.nome), h("div", { className: "dash-col-tipo" }, p.tipo)) ), atr.length > 0 && h("div", { className: "dash-alert" }, "⚠ " + atr.length + " conteúdo(s) atrasado(s): " + atr.map((c) => c.titulo).join(", ")), h("div", { className: "mini-label" }, "Próximos a publicar"), h("div", { className: "dash-next" }, prox.map((c) => h("div", { key: c.id, className: "next-row" }, h("div", { className: "next-date" }, fmtData(c.publicacao)), h("div", { className: "next-body" }, h("div", { className: "next-title" }, c.collab && h("span", { className: "collab-flag" }, "⇄ collab "), c.titulo), h("div", { className: "next-meta" }, h(PlatRow, { plats: c.plats, size: 18 }), h("span", { className: "next-status" }, c.status)) ) ))), h("div", { className: "mini-label" }, "Balanço de pilares — real vs ideal"), h("div", { className: "dash-pilares" }, pils.map((pl) => { const real = pilarReal(p.id, pl.id); const off = Math.abs(real - pl.peso) >= 10; return h("div", { key: pl.id, className: "pilar-row" }, h("div", { className: "pilar-top" }, h("span", null, pl.nome), h("span", { className: off ? "pilar-off" : "pilar-ok" }, real + "% / " + pl.peso + "% ideal")), h(Bar, { value: real, ideal: pl.peso, color: p.cor }) ); })) ); } function hojeBlock() { const HD = window.HOJE_DATA; if (!HD) return null; const sel = HD.hojeSelecao(0); const plats = [["youtube", "YouTube", sel.youtube.titulo], ["instagram", "Instagram", sel.instagram.titulo], ["tiktok", "TikTok", sel.tiktok.titulo]]; return h("div", { className: "dash-hoje" }, h("div", { className: "dash-hoje-head" }, h("div", { className: "dash-hoje-t" }, "⚡ Para hoje", h("span", { style: { fontFamily: "Poppins", fontWeight: 500, fontSize: 12.5, color: "var(--gray)" } }, "1 de cada + stories que vendem")), h("button", { className: "btn-pink sm", onClick: () => { location.hash = "#hoje"; } }, "Abrir Para Hoje →") ), h("div", { className: "dash-hoje-grid" }, plats.map(([pk, nome, txt]) => h("div", { key: pk, className: "dash-hoje-tile" }, h("div", { className: "dh-plat" }, h(window.UI.PlatIcon, { plat: pk, size: 20 }), nome), h("div", { className: "dh-txt" }, txt) )), h("div", { className: "dash-hoje-tile sell" }, h("div", { className: "dh-plat" }, "💰 Stories que vendem"), h("div", { className: "dh-txt" }, "Hoje: " + sel.stories.vende) ) ), h("div", { className: "dash-hoje-membros" }, h("span", { className: "dhm-badge" }, "★ Pra área de membros"), h("span", { className: "dhm-txt" }, h("b", null, sel.membros.fmt + ": "), sel.membros.titulo) ) ); } function objBlock() { const alvosObj = marca === "geral" ? Object.values(D.perfis) : [D.perfis[marca]]; return h("div", { className: "obj-hero" }, h("div", { className: "obj-hero-head" }, h("span", { className: "obj-hero-emoji" }, "🎯"), h("div", null, h("div", { className: "obj-hero-t" }, "Objetivos de " + D.objetivosMes.mes), h("div", { className: "obj-hero-s" }, "O que todo conteúdo do mês deve empurrar"))), h("div", { className: "obj-hero-grid" }, alvosObj.flatMap((p) => (D.objetivosMes[p.id] || []).map((o) => h("div", { key: o.id, className: "obj-tile", style: { borderColor: o.cor + "55" } }, h("div", { className: "obj-tile-top" }, h(PerfilTag, { id: p.id, dot: true }), h("span", { className: "obj-tile-dot", style: { background: o.cor } })), h("div", { className: "obj-tile-txt" }, o.texto) ) ))) ); } const alvos = marca === "geral" ? Object.values(D.perfis) : [D.perfis[marca]]; const sub = (window.hojeLabelBR ? window.hojeLabelBR() : "") + (marca === "geral" ? " · os dois perfis lado a lado" : " · criando para " + D.perfis[marca].nome); return h("div", { className: "page" }, h(PageHead, { titulo: "Dashboard", sub, right: h("div", { className: "seg" }, [["geral", "Visão geral"], ["lore", D.perfis.lore.nome], ["logue", D.perfis.logue.nome]].map(([k, l]) => h("button", { key: k, className: "seg-btn" + (marca === k ? " seg-on" : ""), onClick: () => setMarca(k), style: marca === k && k !== "geral" ? { background: D.perfis[k].cor, color: "#fff" } : undefined }, l)) ) }), marca !== "geral" && (function () { const p = D.perfis[marca]; const ini = (p.nome || "").replace(/^@/, "").charAt(0).toUpperCase(); return h("div", { className: "marca-ctx", style: { background: p.cor + "12", borderColor: p.cor + "3D" } }, h("span", { className: "marca-ctx-bar", style: { background: p.cor } }), h("span", { className: "marca-ctx-mono", style: { background: p.cor } }, ini), h("div", { className: "marca-ctx-body" }, h("div", { className: "marca-ctx-label" }, "Criando agora para"), h("div", { className: "marca-ctx-nome" }, p.nome, p.tipo && h("span", { className: "marca-ctx-tipo" }, p.tipo)) ), h("button", { className: "marca-ctx-btn", style: { color: p.cor, borderColor: p.cor + "55" }, onClick: () => setMarca("geral") }, "Ver os dois lado a lado ", h("span", { "aria-hidden": true }, "→")) ); })(), hojeBlock(), objBlock(), h("div", { className: marca === "geral" ? "dash-grid" : "dash-single" }, alvos.map(col)), h(Card, { className: "dash-full" }, h("div", { className: "mini-label" }, "Publicados recentemente"), h("div", { className: "pub-row" }, publicados.filter((c) => marca === "geral" || c.perfis.includes(marca)).map((c) => h("div", { key: c.id, className: "pub-chip" }, h(PerfilTag, { id: c.perfis[0], dot: true }), c.titulo, h(PlatRow, { plats: c.plats, size: 16 }) ))) ) ); } // ══════════════════ PERFIL ESTRATÉGICO ══════════════════ function Perfil() { const [sel, setSel] = useState("lore"); const p = D.perfis[sel]; const pils = D.pilares.filter((pl) => pl.perfil === sel); const Sec = (t, kids) => h("div", { className: "psec" }, h("div", { className: "psec-t" }, t), kids); // segmentação: rede social → formatos usados (de conteúdos + pautas) const fmtsByPlat = {}; [...D.conteudos, ...D.pautas].filter((x) => x.perfis.includes(sel)).forEach((x) => x.plats.forEach((pl) => { (fmtsByPlat[pl] = fmtsByPlat[pl] || new Set()).add(x.formato); })); const canaisAtivos = p.canais.filter((c) => c.ativo); return h("div", { className: "page" }, h(PageHead, { titulo: "Sistema da Criadora", sub: "Identidade, funcionamento e estratégia de cada perfil", right: h("div", { className: "seg" }, Object.values(D.perfis).map((x) => h("button", { key: x.id, className: "seg-btn" + (sel === x.id ? " seg-on" : ""), onClick: () => setSel(x.id), style: sel === x.id ? { background: x.cor, color: "#fff" } : undefined }, x.nome))) }), h("div", { className: "perfil-hero", style: { borderColor: p.cor } }, h("span", { className: "perfil-dot big", style: { background: p.cor } }), h("div", null, h("h2", { className: "perfil-nome" }, p.nome), h("p", { className: "perfil-bio" }, p.bio)) ), // ── Distribuição por rede social → formato ── h(Card, { className: "seg-card" }, Sec("Distribuição por rede social → formato", h("div", { className: "rede-grid" }, canaisAtivos.map((c) => { const fmts = fmtsByPlat[c.plat] ? [...fmtsByPlat[c.plat]] : []; return h("div", { key: c.plat, className: "rede-item", style: { borderTopColor: D.plataformas[c.plat].cor } }, h("div", { className: "rede-head" }, h(PlatIcon, { plat: c.plat, size: 30 }), h("div", null, h("div", { className: "rede-nome" }, D.plataformas[c.plat].nome), h("div", { className: "rede-handle" }, c.handle))), h("div", { className: "rede-fmts" }, fmts.length ? fmts.map((f) => h("span", { key: f, className: "fmt-chip" }, f)) : h("span", { className: "fmt-empty" }, "sem formato definido")) ); }) ))), h("div", { className: "perfil-grid" }, h(Card, null, Sec("Identidade", h("div", { className: "kv" }, h("div", null, h("b", null, "Missão"), h("p", null, p.missao)), h("div", null, h("b", null, "Visão"), h("p", null, p.visao)), h("div", null, h("b", null, "Valores"), h("ul", { className: "vlist" }, p.valores.map((v, i) => h("li", { key: i }, v)))) ))), h(Card, null, Sec("Tom de voz", h("div", { className: "kv" }, h("div", null, h("b", null, "Como fala"), h("p", null, p.tomDeVoz)), h("div", null, h("b", null, "Aberturas típicas"), h("div", { className: "tagline" }, p.aberturas.map((a, i) => h("span", { key: i, className: "quote-chip" }, "“" + a + "”")))), h("div", null, h("b", null, "Palavras proibidas"), h("div", { className: "tagline" }, p.proibidas.map((a, i) => h("span", { key: i, className: "ban-chip" }, a)))) ))), h(Card, null, Sec("Público-alvo", h("p", { className: "long" }, p.publico))), h(Card, null, Sec("Canais", h("div", { className: "canais" }, p.canais.map((c, i) => h("div", { key: i, className: "canal" + (c.ativo ? "" : " canal-off") }, h(PlatIcon, { plat: c.plat, size: 26 }), h("div", null, h("div", { className: "canal-h" }, c.handle), h("div", { className: "canal-s" }, c.ativo ? "ativo" : "inativo")) ))))), h(Card, { className: "span2" }, Sec("Pilares editoriais — peso ideal vs real do mês", h("div", { className: "perfil-pilares" }, pils.map((pl) => h("div", { key: pl.id, className: "ppilar" }, h("div", { className: "ppilar-head" }, h("b", null, pl.nome), h("span", { className: Math.abs(pl.real - pl.peso) >= 8 ? "pilar-off" : "pilar-ok" }, pl.real + "% real · " + pl.peso + "% ideal")), h("p", { className: "ppilar-desc" }, pl.desc, " — ex: ", h("i", null, pl.ex)), h(Bar, { value: pl.real, ideal: pl.peso, color: p.cor }) ) )))), h(Card, { className: "span2 neuro" }, Sec("Neuroperfil & funcionamento (privado)", h("div", null, h("div", { className: "neuro-tags" }, ["TEA", "TDAH", "AH/SD"].map((t) => h("span", { key: t, className: "neuro-tag" }, t))), h("div", { className: "func-grid" }, h("div", null, h("b", null, "Melhores horários"), h("p", null, "Manhã cedo e após 21h")), h("div", null, h("b", null, "Carga sustentável"), h("p", null, "3-4 conteúdos de alta energia/semana")), h("div", null, h("b", null, "Gatilhos criativos"), h("p", null, "Andar, banho, conversar em voz alta")), h("div", null, h("b", null, "Dias difíceis"), h("p", null, "Só conteúdo de energia baixa (🟢)")) ), h("p", { className: "neuro-note" }, "Estas informações existem apenas para adaptar a organização do sistema. Nunca devem alterar automaticamente a linguagem, o design da interface ou gerar conteúdos sobre esses temas sem decisão explícita da usuária.") ))) ) ); } // ══════════════════ CALENDÁRIO ══════════════════ const MESES_BR = ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"]; function Calendario() { const { state, actions } = window.STORE.useStore(); const hoje = new Date(); hoje.setHours(0, 0, 0, 0); const [modo, setModo] = useState("mes"); const [cur, setCur] = useState({ y: hoje.getFullYear(), m: hoje.getMonth() }); const [fPerfil, setFPerfil] = useState("todos"); const [fPlat, setFPlat] = useState("todas"); const [sel, setSel] = useState(null); const agendados = state.conteudos.filter((c) => c.publicacao) .filter((c) => fPerfil === "todos" || c.perfis.includes(fPerfil)) .filter((c) => fPlat === "todas" || c.plats.includes(fPlat)); const byISO = {}; agendados.forEach((c) => { (byISO[c.publicacao] = byISO[c.publicacao] || []).push(c); }); const iso = (y, m, d) => y + "-" + String(m + 1).padStart(2, "0") + "-" + String(d).padStart(2, "0"); const selC = sel ? state.conteudos.find((x) => x.id === sel) : null; function shift(delta) { setCur((c) => { const dt = new Date(c.y, c.m + delta, 1); return { y: dt.getFullYear(), m: dt.getMonth() }; }); } function evCard(c) { const pc = D.pilarCor[c.pilar] || { bg: "var(--white)", bd: "var(--gray-light)" }; return h("div", { key: c.id, className: "cal-ev", style: { background: pc.bg, borderColor: pc.bd, cursor: "pointer" }, onClick: () => setSel(c.id) }, h("span", { className: "cal-ev-title" }, c.collab && "⇄ ", c.titulo), h(PlatRow, { plats: c.plats, size: 15 }) ); } const firstDow = (new Date(cur.y, cur.m, 1).getDay() + 6) % 7; // Seg=0 const dim = new Date(cur.y, cur.m + 1, 0).getDate(); const cells = []; for (let i = 0; i < firstDow; i++) cells.push(null); for (let d = 1; d <= dim; d++) cells.push(d); const isToday = (d) => d && cur.y === hoje.getFullYear() && cur.m === hoje.getMonth() && d === hoje.getDate(); function semana() { const base = new Date(hoje); base.setDate(hoje.getDate() - ((hoje.getDay() + 6) % 7)); const nomes = ["Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"]; return h("div", { className: "cal-week" }, nomes.map((nm, i) => { const dt = new Date(base); dt.setDate(base.getDate() + i); const key = iso(dt.getFullYear(), dt.getMonth(), dt.getDate()); const hj = dt.getTime() === hoje.getTime(); return h("div", { key: i, className: "week-col" + (hj ? " week-today" : "") }, h("div", { className: "week-head" }, nm, h("span", null, dt.getDate())), h("div", { className: "week-body" }, (byISO[key] || []).map(evCard))); })); } return h("div", { className: "page" }, h(PageHead, { titulo: "Calendário", sub: "Conteúdos reais da produção · clique num card para abrir e alterar", right: h("div", { className: "seg" }, [["mes", "Mês"], ["semana", "Semana"]].map(([k, l]) => h("button", { key: k, className: "seg-btn" + (modo === k ? " seg-on" : ""), onClick: () => setModo(k) }, l))) }), h("div", { className: "cal-filters" }, h("span", { className: "flabel" }, "Perfil:"), h(Chip, { active: fPerfil === "todos", onClick: () => setFPerfil("todos") }, "Todos"), Object.values(D.perfis).map((p) => h(Chip, { key: p.id, active: fPerfil === p.id, onClick: () => setFPerfil(p.id), color: p.cor }, p.nome)), h("span", { className: "flabel", style: { marginLeft: 16 } }, "Plataforma:"), h(Chip, { active: fPlat === "todas", onClick: () => setFPlat("todas") }, "Todas"), Object.entries(D.plataformas).map(([k, v]) => h(Chip, { key: k, active: fPlat === k, onClick: () => setFPlat(k), color: v.cor }, v.nome)) ), modo === "mes" ? h(Card, { className: "cal-card" }, h("div", { className: "cal-nav" }, h("button", { className: "cal-navbtn", onClick: () => shift(-1) }, "‹"), h("div", { className: "cal-title" }, MESES_BR[cur.m] + " " + cur.y), h("button", { className: "cal-navbtn", onClick: () => shift(1) }, "›"), h("button", { className: "cal-hoje-btn", onClick: () => setCur({ y: hoje.getFullYear(), m: hoje.getMonth() }) }, "Hoje") ), h("div", { className: "cal-dow" }, ["Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"].map((d) => h("div", { key: d }, d))), h("div", { className: "cal-grid" }, cells.map((d, i) => h("div", { key: i, className: "cal-cell" + (isToday(d) ? " cal-today" : "") + (d == null ? " cal-empty" : "") }, d && h("div", { className: "cal-num" }, d), d && (byISO[iso(cur.y, cur.m, d)] || []).slice(0, 3).map(evCard) ))) ) : h(Card, { className: "cal-card" }, semana()), selC && h(CalEvModal, { c: selC, onClose: () => setSel(null), onSave: (patch) => { actions.updateConteudo(selC.id, patch); }, onClosed: () => setSel(null) }) ); } function CalEvModal({ c, onClose, onSave }) { const [pub, setPub] = useState(c.publicacao || ""); const [status, setStatus] = useState(c.status); const p = D.pilares.find((x) => x.id === c.pilar); return h("div", { className: "modal-bg", onClick: onClose }, h("div", { className: "modal", style: { maxWidth: 460 }, onClick: (e) => e.stopPropagation() }, h("button", { className: "modal-x", onClick: onClose }, "✕"), h("div", { className: "modal-tags" }, c.perfis.map((id) => h(PerfilTag, { key: id, id })), c.collab && h("span", { className: "collab-flag big" }, "⇄ collab")), h("h2", { className: "modal-title" }, c.titulo), h("div", { className: "modal-sub" }, c.formato, " · ", p && p.nome, " · ", h(PlatRow, { plats: c.plats, size: 18 })), c.resumo && h("div", { className: "modal-ideia" }, h("b", null, "💡 Ideia: "), c.resumo), h("div", { className: "fed-row", style: { marginTop: 6 } }, h("div", null, h("div", { className: "kb-ed-label" }, "Data de publicação"), h("input", { type: "date", className: "fed-select", value: pub, onChange: (e) => setPub(e.target.value) })), h("div", null, h("div", { className: "kb-ed-label" }, "Etapa"), h("select", { className: "fed-select", value: status, onChange: (e) => setStatus(e.target.value) }, D.etapas.map((s) => h("option", { key: s, value: s }, s)))) ), h("div", { className: "fed-actions" }, h("button", { className: "btn-ghost", onClick: onClose }, "Fechar"), h("button", { className: "btn-pink", onClick: () => { onSave({ publicacao: pub, status }); onClose(); } }, "✓ Salvar") ) ) ); } Object.assign(window, { Dashboard, Perfil, Calendario }); })();