const { Card, Input, Select, Textarea, Button, Icon, Checkbox, Switch, Tag, Avatar, SearchField, ChecklistPanel, Badge, PriorityBadge, SectorTag, FileDropzone, Modal, StatusPill } = window.ACRFlowDesignSystem_ba1e9c;
const RECUR_MAP = { "Não recorrente": "none", "Diária": "daily", "Semanal": "weekly", "Mensal": "monthly", "Anual": "yearly", "Personalizada": "custom" };
function NewDemandScreen({ onCancel, onCreate, onToast, user }) {
const D = window.useStore();
const S = window.ACRStore;
const sectors = (D.sectorsCfg || []).filter((s) => s.active !== false);
const companies = (D.companies || []).filter((c) => c.active !== false);
const [enviando, setEnviando] = React.useState(false);
const [sector, setSector] = React.useState((sectors[0] || {}).id);
const [category, setCategory] = React.useState(((sectors[0] || {}).categories || [])[0] || "");
const [title, setTitle] = React.useState("");
const [description, setDescription] = React.useState("");
const [tags, setTags] = React.useState([]);
const [newTag, setNewTag] = React.useState("");
const [addingTag, setAddingTag] = React.useState(false);
const [priority, setPriority] = React.useState("normal");
const [due, setDue] = React.useState("");
const [company, setCompany] = React.useState("");
const [linked, setLinked] = React.useState([]);
const [owner, setOwner] = React.useState("");
const [extras, setExtras] = React.useState([]);
const [personQ, setPersonQ] = React.useState("");
const [recur, setRecur] = React.useState("Não recorrente");
const [recurDay, setRecurDay] = React.useState("25");
const [autoRecur, setAutoRecur] = React.useState(true);
const [anexos, setAnexos] = React.useState([]);
const [confirm, setConfirm] = React.useState(false);
const [items, setItems] = React.useState([]);
const current = sectors.find((s) => s.id === sector) || sectors[0] || { id: "", name: "", categories: [] };
React.useEffect(() => { setCategory(current.categories[0] || ""); }, [sector]);
const notRecurring = recur === "Não recorrente";
React.useEffect(() => { if (notRecurring) setAutoRecur(false); }, [recur]);
const sectorExtras = { "departamento-pessoal": ["Colaborador"] }[sector] || [];
const peopleOptions = personQ.trim().length === 0 ? [] : (D.team || []).filter((t) =>
t.active !== false && t.name !== owner && !extras.includes(t.name)
&& t.name.toLowerCase().includes(personQ.trim().toLowerCase()));
const missing = [!title.trim() && "Título", !description.trim() && "Descrição detalhada", !due && "Prazo de entrega", !category && "Atividade", !owner && "Responsável principal"].filter(Boolean);
const valid = missing.length === 0;
const submit = async () => {
const time = D.team || [];
const idDe = (nome) => (time.find((u) => u.name === nome) || {}).id;
const principal = idDe(owner);
const responsaveis = [principal, ...extras.map(idDe)].filter(Boolean);
if (S.online() && responsaveis.length === 0) {
onToast({ tone: "danger", title: "Informe o responsável", message: "Toda demanda precisa de ao menos um responsável cadastrado." });
return;
}
const catId = ((D.catIds || {})[sector] || {})[category];
const empresa = company || undefined;
setEnviando(true);
const r = await S.criarDemanda({
title: title.trim(),
description: description.trim() || undefined,
sectorId: sector,
categoryId: catId,
companyId: empresa,
priorityId: priority,
requester: (user && user.name) || undefined,
deadline: due || undefined,
assigneeIds: responsaveis,
primaryAssigneeId: principal,
tags,
recurrence: { type: RECUR_MAP[recur] || "none", day: Number(recurDay) || undefined, auto: !!autoRecur },
checklist: items.filter((i) => i.text && i.text.trim()).map((i) => ({ text: i.text.trim(), ownerId: idDe(i.owner), dueDate: i.due || undefined })),
});
setEnviando(false);
if (!r.ok) { onToast({ tone: "danger", title: "Não foi possível criar a demanda", message: r.error }); return; }
setConfirm(false);
const num = r.demanda && r.demanda.id ? r.demanda.id : "";
onToast({ tone: "success", title: num ? "Demanda " + num + " criada" : "Demanda criada", message: owner ? owner + " é o responsável principal." : "Registrada com sucesso." });
onCreate();
};
const dueBR = due ? due.split("-").reverse().join("/") : "—";
return (
Nova demanda
O número é gerado automaticamente ao salvar: DEM-2026-000145
Setor *
{sectors.map((s) => (
setSector(s.id)}
style={{ padding: "7px 11px", borderRadius: "var(--radius-sm)", cursor: "pointer", font: "var(--type-caption)", background: sector === s.id ? "var(--surface-sunken)" : "var(--surface-card)", border: "1px solid " + (sector === s.id ? "var(--accent-primary)" : "var(--border-default)"), color: sector === s.id ? "var(--text-brand)" : "var(--text-body)" }}>{s.name}
))}
setCategory(e.target.value)}
options={current.categories.length ? current.categories : ["—"]}
hint="Categorias vêm do cadastro de Áreas e Atividades." />
setTitle(e.target.value)} placeholder="Ex.: Emissão de boleto — Alpha" />
setCompany(e.target.value)}
options={[{ value: "", label: "Selecione a empresa..." }, ...companies.map((c) => ({ value: c.id, label: c.name + " · " + c.purpose }))]} />
{sectorExtras.map((label) => (
{label}
{(window.ACRData.team || []).map((u) => u.name).map((n) => (
setLinked((s) => (s.includes(n) ? s.filter((x) => x !== n) : [...s, n]))}
style={{ padding: 0, border: "none", background: "transparent", cursor: "pointer" }}>
{n}
))}
))}
{company ? Finalidade: {(companies.find((c) => c.id === company) || {}).purpose} · {(companies.find((c) => c.id === company) || {}).doc} : null}
setItems((s) => s.map((i) => (i.id === id ? { ...i, done: !i.done } : i)))}
onAdd={(it) => setItems((s) => [...s, { ...it, id: "c" + Date.now(), done: false }])}
onUpdate={(id, patch) => setItems((s) => s.map((i) => (i.id === id ? { ...i, ...patch } : i)))}
onRemove={(id) => setItems((s) => s.filter((i) => i.id !== id))} />
Prioridade *
{D.priorities.map((p) => (
setPriority(p.id)} style={{ padding: 3, borderRadius: "var(--radius-pill)", border: "1px solid " + (priority === p.id ? "var(--prio-" + p.tone + ")" : "transparent"), background: "transparent", cursor: "pointer" }}>
))}
} hint="Registrada automaticamente na criação." />
setDue(e.target.value)} hint="O sistema alerta 1 dia antes do vencimento." />
{owner
?
:
Nenhum responsável definido — pesquise abaixo.
}
{extras.map((n) => (
setExtras((s) => s.filter((x) => x !== n))}>Remover
))}
setPersonQ(e.target.value)} onClear={() => setPersonQ("")} />
{personQ.trim() ? (
{peopleOptions.length ? peopleOptions.slice(0, 6).map((t) => (
{t.name}
{owner ?
{ setExtras((s) => [...s, t.name]); setPersonQ(""); }}>Adicionar : null}
{ setExtras((s) => [...s.filter((x) => x !== t.name), owner].filter(Boolean)); setOwner(t.name); setPersonQ(""); }}>{owner ? "Tornar principal" : "Definir responsável"}
)) :
{(D.team || []).length === 0 ? "Nenhum colaborador cadastrado — cadastre em Controle de Acesso." : "Nenhum colaborador com esse nome."} }
) : null}
setRecur(e.target.value)}
options={["Não recorrente", "Diária", "Semanal", "Mensal", "Anual", "Personalizada"]} />
{recur === "Mensal" ? setRecurDay(e.target.value)} suffix="dia" /> : null}
setAutoRecur((v) => !v)}
label="Gerar automaticamente a próxima demanda"
description={notRecurring ? "Disponível apenas para demandas recorrentes." : "Preserva o histórico das anteriores."} />
setAnexos((s) => [...s, ...f])}
onRemove={(id) => setAnexos((s) => s.filter((f) => f.id !== id))} />
{valid ? "Tudo pronto — a demanda entra como Aguardando atendimento até a primeira interação do responsável." : "Campos obrigatórios pendentes: " + missing.join(", ") + "."}
Cancelar
} disabled={!valid} onClick={() => setConfirm(true)}>Criar demanda
{confirm ? (
setConfirm(false)}
footer={<> setConfirm(false)}>Voltar e editar } disabled={enviando} onClick={submit}>{enviando ? "Gravando…" : "Confirmar e criar"}>}>
{title}
{[["Atividade", category || "—"], ["Empresa", (companies.find((c) => c.id === company) || {}).name || "—"], ["Prazo de entrega", dueBR], ["Responsável principal", owner || "—"], ["Responsáveis adicionais", extras.length ? extras.join(", ") : "—"], ["Recorrência", notRecurring ? "Não recorrente" : recur + (recur === "Mensal" ? " · dia " + recurDay : "") + (autoRecur ? " · geração automática" : "")], ["Checklist", items.length + " etapas"], ["Anexos", anexos.length ? anexos.length + " arquivo(s)" : "—"]].map(([k, v]) => (
{k}
{v}
))}
) : null}
);
}
Object.assign(window, { NewDemandScreen });