+
+
+
Relatórios EM
+
Eletromecânico (unificado)
+
+
+ {filtered.length} de {reports.length}
+
+
+
+
+ setSearch(e.target.value)}
+ placeholder="Buscar por cliente, local, tag, número..."
+ className="w-full px-4 py-2.5 bg-gray-950 border border-gray-800 rounded-lg text-white text-sm placeholder-gray-600 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-600"
+ />
+
+
+
+ {filtered.length === 0 ? (
+
+
+
+
+
Nenhum relatório EM encontrado
+
Gere um Megger e salve como EM para começar
+
+ ) : (
+
+ {filtered.map((r) => (
+
+
+
+ {r.header.reportNumber ? `${r.header.reportNumber} · ` : ''}
+ {r.module.toUpperCase()} · {r.header.tag || 'Sem TAG'}
+
+
+ {r.header.client} · {r.header.site} · {formatDate(r.createdAt)}
+
+
+
+
+
+
+
+
+
+ ))}
+
+ )}
+
+
+ );
+};
+
+export default EMReports;
+
diff --git a/src/pages/GenerateReport.tsx b/src/pages/GenerateReport.tsx
index 96c8ccc..6cea329 100644
--- a/src/pages/GenerateReport.tsx
+++ b/src/pages/GenerateReport.tsx
@@ -24,6 +24,7 @@ import { exportCupomPDF } from '../utils/export';
import { exportMeggerExcel } from '../utils/export-excel';
import { dbUtils } from '../db/database';
import { calculateDAI, formatVoltage } from '../utils/units';
+import { emFromIRReport } from '../em';
type InputMode = 'generate' | 'manual';
@@ -246,6 +247,22 @@ const GenerateReport: React.FC = () => {
await dbUtils.saveIRReport(savedReport);
setGeneratedReport(savedReport);
+
+ // Também salva uma versão unificada EM (para o futuro template corporativo)
+ try {
+ const em = emFromIRReport(savedReport, {
+ reportNumber: savedReport.number,
+ client: savedReport.client || 'N/A',
+ site: savedReport.site || 'N/A',
+ tag: savedReport.tag,
+ responsible: { name: savedReport.operator || savedReport.responsible || 'N/A' },
+ observations: savedReport.observations || savedReport.notes,
+ recommendations: savedReport.recommendations,
+ });
+ await dbUtils.saveEMReport(em);
+ } catch (e) {
+ console.warn('Falha ao salvar EM (não bloqueante):', e);
+ }
// Mostrar feedback
showNotificationMessage('success', 'Relatório salvo com sucesso!');
diff --git a/src/types/index.ts b/src/types/index.ts
index 544d067..7bb0568 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -425,3 +425,127 @@ export interface EnvironmentalFactors {
temperature: number; // °C
humidity: number; // %
}
+
+// ==============================
+// === ELETROMECÂNICO (NOVO) ===
+// ==============================
+
+export type EMDiscipline = 'eletrica' | 'mecanica';
+
+export type EMElectricalModule =
+ | 'megger_ir'
+ | 'microhm'
+ | 'hipot'
+ | 'cable'
+ | 'breaker'
+ | 'multiphase_megger';
+
+export type EMMechanicalModule =
+ | 'vibracao'
+ | 'alinhamento'
+ | 'termografia'
+ | 'lubrificacao';
+
+export type EMModule = EMElectricalModule | EMMechanicalModule;
+
+export interface EMResponsible {
+ name: string;
+ crea?: string;
+ role?: string; // ex: Engenheiro Eletricista
+}
+
+export interface EMSignature {
+ label: string; // ex: "Responsável Técnico"
+ signedBy?: string;
+ imageDataUrl?: string; // PNG/JPG data URL (opcional)
+ date?: string; // ISO ou string livre
+}
+
+export interface EMHeaderMeta {
+ reportNumber?: string;
+ date: string; // ISO yyyy-mm-dd
+ client: string;
+ site: string; // obra/local
+ tag?: string;
+ equipmentDescription?: string;
+ responsible: EMResponsible;
+ reviewers?: EMResponsible[];
+ signatures?: EMSignature[];
+ observations?: string;
+ recommendations?: string;
+}
+
+export type EMElectricalPayload =
+ | { module: 'megger_ir'; data: IRReport }
+ | {
+ module: 'microhm';
+ data: {
+ voltage_V: number;
+ current_A: number;
+ reference_Ohm: number;
+ R_Ohm: number;
+ percentDelta: number;
+ status: string;
+ possibleBadContact: boolean;
+ };
+ }
+ | {
+ module: 'hipot';
+ data: {
+ nominalVoltage_V: number;
+ Vteste_V: number;
+ formulaUsed: string;
+ };
+ }
+ | {
+ module: 'cable';
+ data: {
+ power: number;
+ voltage: number;
+ powerFactor: number;
+ systemType: string;
+ distance: number;
+ voltageDropPercent: number;
+ current_A: number;
+ minSection_mm2: number;
+ resistance_Ohm: number;
+ actualDrop: number;
+ status: string;
+ breakerIn?: number;
+ breakerCurve?: string;
+ coordinationOk?: boolean;
+ };
+ }
+ | {
+ module: 'breaker';
+ data: {
+ loadCurrent_A: number;
+ loadType: string;
+ cableMaxCurrent_A: number;
+ In_A: number;
+ curve: string;
+ coordinationOk: boolean;
+ };
+ }
+ | { module: 'multiphase_megger'; data: MultiPhaseReport };
+
+export type EMMechanicalPayload = {
+ module: EMMechanicalModule;
+ // payload mecânico será tipado por módulo quando os módulos forem implementados
+ data: Record