refactor: substituindo tipos genéricos 'any' por tipagem segura em SolicitacaoCompras e VerInconsistencias

This commit is contained in:
2026-08-12 16:01:02 +00:00
parent a7bb224a48
commit 4218d9090f
4 changed files with 20 additions and 19 deletions
@@ -6,11 +6,12 @@ import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { AlertTriangle, Calendar, Hash, TrendingUp, ExternalLink } from 'lucide-react'; import { AlertTriangle, Calendar, Hash, TrendingUp, ExternalLink } from 'lucide-react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { InconsistenciaItem } from '@/hooks/useAuditoriaInconsistencias';
interface InconsistenciaDetalhesModalProps { interface InconsistenciaDetalhesModalProps {
open: boolean; open: boolean;
onOpenChange: (open: boolean) => void; onOpenChange: (open: boolean) => void;
inconsistencia: any; inconsistencia: InconsistenciaItem | null;
} }
export const InconsistenciaDetalhesModal: React.FC<InconsistenciaDetalhesModalProps> = ({ export const InconsistenciaDetalhesModal: React.FC<InconsistenciaDetalhesModalProps> = ({
+2 -2
View File
@@ -3,7 +3,7 @@ import { useState, useCallback } from 'react';
import { supabase } from '@/integrations/supabase/client'; import { supabase } from '@/integrations/supabase/client';
import { naturalSort } from '@/utils/naturalSort'; import { naturalSort } from '@/utils/naturalSort';
interface InconsistenciaItem { export interface InconsistenciaItem {
marca: string; marca: string;
tipo: string; tipo: string;
descricao: string; descricao: string;
@@ -11,7 +11,7 @@ interface InconsistenciaItem {
acaoSugerida?: string; acaoSugerida?: string;
} }
interface ResultadoAuditoria { export interface ResultadoAuditoria {
inconsistencias: { inconsistencias: {
processos: InconsistenciaItem[]; processos: InconsistenciaItem[];
quantidades: InconsistenciaItem[]; quantidades: InconsistenciaItem[];
+11 -11
View File
@@ -5,7 +5,7 @@ import { StandardCard } from '@/components/layout/StandardCard';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import { Plus, Printer, Edit, Trash2, Eye, RefreshCw, Check, ShoppingCart } from 'lucide-react'; import { Plus, Printer, Edit, Trash2, Eye, RefreshCw, Check, ShoppingCart } from 'lucide-react';
import { useSolicitacoesCompra } from '@/hooks/useSolicitacoesCompra'; import { useSolicitacoesCompra, SolicitacaoCompra, ItemSolicitacao } from '@/hooks/useSolicitacoesCompra';
import { useUserFunction } from '@/hooks/useUserFunction'; import { useUserFunction } from '@/hooks/useUserFunction';
import { SolicitacaoComprasModal } from '@/components/solicitacao-compras/SolicitacaoComprasModal'; import { SolicitacaoComprasModal } from '@/components/solicitacao-compras/SolicitacaoComprasModal';
import { SolicitacaoComprasPreviewModal } from '@/components/solicitacao-compras/SolicitacaoComprasPreviewModal'; import { SolicitacaoComprasPreviewModal } from '@/components/solicitacao-compras/SolicitacaoComprasPreviewModal';
@@ -25,7 +25,7 @@ const statusColors = {
export default function SolicitacaoCompras() { export default function SolicitacaoCompras() {
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const [isPreviewOpen, setIsPreviewOpen] = useState(false); const [isPreviewOpen, setIsPreviewOpen] = useState(false);
const [selectedSolicitacao, setSelectedSolicitacao] = useState(null); const [selectedSolicitacao, setSelectedSolicitacao] = useState<SolicitacaoCompra | null>(null);
const { isComprador } = useUserFunction(); const { isComprador } = useUserFunction();
const { const {
solicitacoes, solicitacoes,
@@ -44,7 +44,7 @@ export default function SolicitacaoCompras() {
isComprandoDireto isComprandoDireto
} = useSolicitacoesCompra(); } = useSolicitacoesCompra();
const handlePrint = (solicitacao: any) => { const handlePrint = (solicitacao: SolicitacaoCompra) => {
try { try {
const printContent = ` const printContent = `
<!DOCTYPE html> <!DOCTYPE html>
@@ -129,7 +129,7 @@ export default function SolicitacaoCompras() {
</tr> </tr>
</thead> </thead>
<tbody class="bg-white divide-y divide-gray-200"> <tbody class="bg-white divide-y divide-gray-200">
${solicitacao.itens.map((item: any, index: number) => ` ${solicitacao.itens.map((item: ItemSolicitacao, index: number) => `
<tr${index % 2 === 1 ? ' class="hover:bg-gray-50"' : ''}> <tr${index % 2 === 1 ? ' class="hover:bg-gray-50"' : ''}>
<td class="px-4 py-3 text-xs font-medium text-gray-800 break-words">${item.material?.descricao || 'Material não encontrado'}</td> <td class="px-4 py-3 text-xs font-medium text-gray-800 break-words">${item.material?.descricao || 'Material não encontrado'}</td>
<td class="px-4 py-3 whitespace-nowrap text-center text-gray-600 text-xs">${item.material?.unidade || 'UN'}</td> <td class="px-4 py-3 whitespace-nowrap text-center text-gray-600 text-xs">${item.material?.unidade || 'UN'}</td>
@@ -180,7 +180,7 @@ export default function SolicitacaoCompras() {
} }
}; };
const handleEdit = (solicitacao: any) => { const handleEdit = (solicitacao: SolicitacaoCompra) => {
if (!canEdit(solicitacao)) { if (!canEdit(solicitacao)) {
alert('Você só pode editar suas próprias solicitações.'); alert('Você só pode editar suas próprias solicitações.');
return; return;
@@ -189,12 +189,12 @@ export default function SolicitacaoCompras() {
setIsModalOpen(true); setIsModalOpen(true);
}; };
const handlePreview = (solicitacao: any) => { const handlePreview = (solicitacao: SolicitacaoCompra) => {
setSelectedSolicitacao(solicitacao); setSelectedSolicitacao(solicitacao);
setIsPreviewOpen(true); setIsPreviewOpen(true);
}; };
const handleDelete = (solicitacao: any) => { const handleDelete = (solicitacao: SolicitacaoCompra) => {
if (!canDelete(solicitacao)) { if (!canDelete(solicitacao)) {
if (solicitacao.status !== 'Em planejamento') { if (solicitacao.status !== 'Em planejamento') {
alert('⚠️ PERMISSÃO NEGADA\n\nSolicitações com status diferente de "Em planejamento" só podem ser excluídas por compradores.'); alert('⚠️ PERMISSÃO NEGADA\n\nSolicitações com status diferente de "Em planejamento" só podem ser excluídas por compradores.');
@@ -209,25 +209,25 @@ export default function SolicitacaoCompras() {
} }
}; };
const handleRevisar = (solicitacao: any) => { const handleRevisar = (solicitacao: SolicitacaoCompra) => {
if (window.confirm(`Tem certeza que deseja enviar a solicitação ${solicitacao.numero_sc} para revisão?`)) { if (window.confirm(`Tem certeza que deseja enviar a solicitação ${solicitacao.numero_sc} para revisão?`)) {
revisar({ id: solicitacao.id, created_by: solicitacao.created_by }); revisar({ id: solicitacao.id, created_by: solicitacao.created_by });
} }
}; };
const handleAceitar = (solicitacao: any) => { const handleAceitar = (solicitacao: SolicitacaoCompra) => {
if (window.confirm(`Tem certeza que deseja aceitar a solicitação ${solicitacao.numero_sc}?`)) { if (window.confirm(`Tem certeza que deseja aceitar a solicitação ${solicitacao.numero_sc}?`)) {
aceitar({ id: solicitacao.id, created_by: solicitacao.created_by }); aceitar({ id: solicitacao.id, created_by: solicitacao.created_by });
} }
}; };
const handleComprar = (solicitacao: any) => { const handleComprar = (solicitacao: SolicitacaoCompra) => {
if (window.confirm(`Tem certeza que deseja marcar a solicitação ${solicitacao.numero_sc} como comprada?`)) { if (window.confirm(`Tem certeza que deseja marcar a solicitação ${solicitacao.numero_sc} como comprada?`)) {
comprar({ id: solicitacao.id, created_by: solicitacao.created_by }); comprar({ id: solicitacao.id, created_by: solicitacao.created_by });
} }
}; };
const handleComprarDireto = (solicitacao: any) => { const handleComprarDireto = (solicitacao: SolicitacaoCompra) => {
if (window.confirm(`Você deseja passar o status dessa SC ${solicitacao.numero_sc} para "Comprado"?`)) { if (window.confirm(`Você deseja passar o status dessa SC ${solicitacao.numero_sc} para "Comprado"?`)) {
comprarDireto({ id: solicitacao.id, created_by: solicitacao.created_by }); comprarDireto({ id: solicitacao.id, created_by: solicitacao.created_by });
} }
+5 -5
View File
@@ -7,7 +7,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import { Search, Eye, Download, FileText, AlertTriangle, CheckCircle } from 'lucide-react'; import { Search, Eye, Download, FileText, AlertTriangle, CheckCircle } from 'lucide-react';
import { useOFsAtivas } from '@/hooks/useOFsAtivas'; import { useOFsAtivas } from '@/hooks/useOFsAtivas';
import { useAuditoriaInconsistencias } from '@/hooks/useAuditoriaInconsistencias'; import { useAuditoriaInconsistencias, InconsistenciaItem } from '@/hooks/useAuditoriaInconsistencias';
import { InconsistenciaDetalhesModal } from '@/components/auditoria/InconsistenciaDetalhesModal'; import { InconsistenciaDetalhesModal } from '@/components/auditoria/InconsistenciaDetalhesModal';
import { generateProfessionalPDF } from '@/utils/pdfGenerator'; import { generateProfessionalPDF } from '@/utils/pdfGenerator';
import { toast } from '@/hooks/use-toast'; import { toast } from '@/hooks/use-toast';
@@ -18,7 +18,7 @@ const VerInconsistencias = () => {
const [selectedFase, setSelectedFase] = useState<string>(''); const [selectedFase, setSelectedFase] = useState<string>('');
const [selectedProcesso, setSelectedProcesso] = useState<string>('todas'); const [selectedProcesso, setSelectedProcesso] = useState<string>('todas');
const [fasesDaOF, setFasesDaOF] = useState<string[]>([]); const [fasesDaOF, setFasesDaOF] = useState<string[]>([]);
const [detalhesModal, setDetalhesModal] = useState<{ open: boolean; inconsistencia: any }>({ const [detalhesModal, setDetalhesModal] = useState<{ open: boolean; inconsistencia: InconsistenciaItem | null }>({
open: false, open: false,
inconsistencia: null inconsistencia: null
}); });
@@ -113,7 +113,7 @@ const VerInconsistencias = () => {
const getTotalInconsistencias = () => { const getTotalInconsistencias = () => {
if (!resultadoAuditoria) return 0; if (!resultadoAuditoria) return 0;
return Object.values(resultadoAuditoria.inconsistencias).reduce((total, categoria: any) => total + categoria.length, 0); return Object.values(resultadoAuditoria.inconsistencias).reduce((total, categoria: InconsistenciaItem[]) => total + categoria.length, 0);
}; };
return ( return (
@@ -262,7 +262,7 @@ const VerInconsistencias = () => {
<CardTitle className="capitalize"> <CardTitle className="capitalize">
Inconsistências de {categoria} Inconsistências de {categoria}
<Badge variant="secondary" className="ml-2"> <Badge variant="secondary" className="ml-2">
{(inconsistencias as any[]).length} {(inconsistencias as InconsistenciaItem[]).length}
</Badge> </Badge>
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
@@ -274,7 +274,7 @@ const VerInconsistencias = () => {
</div> </div>
) : ( ) : (
<div className="space-y-2"> <div className="space-y-2">
{(inconsistencias as any[]).map((item, index) => ( {(inconsistencias as InconsistenciaItem[]).map((item, index) => (
<div key={index} className="flex items-center justify-between p-3 border rounded-lg"> <div key={index} className="flex items-center justify-between p-3 border rounded-lg">
<div className="flex-1"> <div className="flex-1">
<div className="font-medium">{item.descricao}</div> <div className="font-medium">{item.descricao}</div>