"use client"; import { useMemo, useState } from "react"; import { useRouter } from "next/navigation"; import Link from "next/link"; import { apiGet, apiPostFormData, apiPostJson, ApiError } from "@/lib/api/client"; import { validateSolicitacaoPayload } from "@/lib/validation/solicitacao"; import { Field } from "@/components/forms/Field"; type Meta = { cargos: Array<{ codigo: string; nome: string }>; secoes: Array<{ codigo: string; descricao: string }>; coligadas: Array<{ codigo: number; nome: string }>; tipos: Array<{ value: string; label: string; precisa_colaborador: boolean }>; }; type Colaborador = { id: string | null; matricula: string | null; nome: string | null; cargo: string | null; setor: string | null; }; type FormState = Record; export default function NovaSolicitacaoPage() { const router = useRouter(); const [meta, setMeta] = useState(null); const [tipo, setTipo] = useState(""); const [busca, setBusca] = useState(""); const [colaboradores, setColaboradores] = useState([]); const [funcionarioId, setFuncionarioId] = useState(""); const [arquivoPedido, setArquivoPedido] = useState(null); const [form, setForm] = useState({}); const [errors, setErrors] = useState>({}); const [loading, setLoading] = useState(false); const [feedback, setFeedback] = useState(""); const selectedTipo = useMemo( () => meta?.tipos.find((t) => t.value === tipo) || null, [meta, tipo] ); async function ensureMeta() { if (meta) return meta; const loaded = await apiGet("/api/nova-solicitacao/metadata/"); setMeta(loaded); return loaded; } async function buscarColaboradores() { if (!tipo) return; setLoading(true); setFeedback(""); try { await ensureMeta(); const query = new URLSearchParams(); if (busca.trim()) query.set("q", busca.trim()); if (tipo === "ADM_SUBSTITUICAO") query.set("tipo", "substituicao"); const res = await apiGet<{ colaboradores: Colaborador[] }>( `/api/colaboradores/?${query.toString()}` ); setColaboradores(res.colaboradores); } catch (error) { setFeedback(error instanceof Error ? error.message : "Erro ao buscar colaboradores."); } finally { setLoading(false); } } async function handleSubmit() { const payload: Record = { ...form, tipo }; if (selectedTipo?.precisa_colaborador) payload.funcionario_id = funcionarioId; if (tipo === "DESLIGAMENTO") { payload.data_prevista_desligamento = form.data_prevista_desligamento || ""; } const validation = validateSolicitacaoPayload(payload); setErrors(validation); if (Object.keys(validation).length > 0) return; setLoading(true); setFeedback(""); try { if (tipo === "DESLIGAMENTO" && arquivoPedido) { const fd = new FormData(); Object.entries(payload).forEach(([k, v]) => { if (typeof v === "boolean") fd.append(k, v ? "true" : "false"); else fd.append(k, String(v ?? "")); }); fd.append("arquivo_pedido", arquivoPedido); const result = await apiPostFormData<{ redirect: string }>( "/api/solicitacoes/", fd ); router.push(result.redirect); return; } const result = await apiPostJson<{ redirect: string }>( "/api/solicitacoes/", payload ); router.push(result.redirect); } catch (error) { if (error instanceof ApiError) { setFeedback(error.message); } else { setFeedback("Erro ao criar solicitação."); } } finally { setLoading(false); } } return (

Nova Solicitação

Crie e envie solicitações sem sair do Next.

Voltar ao dashboard
{selectedTipo?.precisa_colaborador && (

Selecionar colaborador

setBusca(e.target.value)} />

Para substituição, serão listados colaboradores desligados.

)} {tipo === "DESLIGAMENTO" && (
setForm((f) => ({ ...f, tipo_desligamento: e.target.value }))} /> setForm((f) => ({ ...f, aviso_previo: e.target.value }))} /> setForm((f) => ({ ...f, data_prevista_desligamento: e.target.value }))} /> setArquivoPedido(e.target.files?.[0] || null)} />