import { useEffect, useRef, useState } from 'react'; import { router } from '@inertiajs/react'; import { control, button } from '@/pages/management/shared'; import { valueText } from '@/lib/value-text'; type Classification = { target_type: string; purpose: string; requested_state: string; disclosure: string; criteria?: string; justification?: string; source_reference?: string; citation?: string; authority_id?: string | null; document_id?: string | null; external_status?: string; external_act_reference?: string; production_stage?: string; valid_from?: string | null; valid_until?: string | null; }; export type ClassificationRelation = { related_id: string; relation_type: string; classification?: Classification; [key: string]: unknown; }; export type ClassificationOptions = { dimensions: Record; types: Record; purposes: Record; targets: Record< string, { id: string | number; label: string; code?: string; level?: number | null; path?: { id: string; code: string; label: string }[]; source_version?: string | null; edition?: string | null; }[] >; externalStates: string[]; }; const typeLabels: Record = { park: 'Parque industrial — organização produtiva', corridor: 'Corredor', location: 'Localização', cluster: 'Cluster', project: 'Projeto âncora', chain: 'Cadeia de valor', zone: 'Zona ou parque', sector: 'Setor', activity: 'Subsector ou atividade', }; export const classificationStates: Record = { draft: 'Rascunho', preliminary: 'Preliminar', in_validation: 'Em validação', confirmed: 'Confirmado', rejected: 'Rejeitado', archived: 'Arquivado', revoked: 'Revogado', }; const externalLabels: Record = { not_assessed: 'Não determinado', pending: 'Pendente', documented_granted: 'Ato de concessão documentado', documented_denied: 'Ato de recusa documentado', expired: 'Caducado', }; const help = 'Indique relações com corredores, clusters, projectos âncora, zonas, parques, cadeias e actividades, quando aplicáveis. Cada associação tem finalidade, fonte e estado próprios. A implantação, a abrangência e a proximidade são diferentes: estar num distrito não comprova pertença a um cluster, parque ou regime especial. Associação, publicação e acto externo são decisões separadas; dados ausentes permanecem por determinar.'; export function ClassificationEditor({ rows, onChange, options, documents, authorities, errors = {}, }: { rows: ClassificationRelation[]; onChange: (rows: ClassificationRelation[]) => void; options: ClassificationOptions; documents: { id: string; payload: { title?: string }; file?: { file_name: string }; }[]; authorities: { id: string; label_pt_mz: string }[]; errors?: Record; }) { const container = useRef(null); useEffect(() => { const key = Object.keys(errors).find((k) => k.startsWith('canonical.relations.'), ); const index = key?.match(/^canonical\.relations\.(\d+)/)?.[1]; if (index) container.current ?.querySelector( `[data-association-index="${index}"]`, ) ?.focus(); }, [errors]); const patch = ( index: number, fields: Partial, related?: string, ) => onChange( rows.map((row, i) => i === index ? { ...row, related_id: related ?? row.related_id, classification: { ...row.classification!, ...fields }, } : row, ), ); return (

Associações territoriais e produtivas

Inclui relações territoriais, produtivas, regulatórias e de actividade. Não repita aqui o endereço nem a hierarquia dos locais. Pode preparar relações preliminares; confirmação e publicação seguem as verificações já existentes de fonte, citação e revisão.

{help}

{Object.entries(options.dimensions).map(([dimension, label]) => (
{label} {rows.map((row, index) => row.classification && options.types[row.classification.target_type] === dimension ? (
Associação {index + 1}
{( [ 'criteria', 'justification', 'source_reference', 'citation', 'external_act_reference', 'production_stage', ] as const ).map((key) => (