diff --git a/src/components/expedicao/PecasRomaneioExpandido.tsx b/src/components/expedicao/PecasRomaneioExpandido.tsx index cd3978b..1acc478 100644 --- a/src/components/expedicao/PecasRomaneioExpandido.tsx +++ b/src/components/expedicao/PecasRomaneioExpandido.tsx @@ -1,9 +1,10 @@ import React, { useState, useEffect } from 'react'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; import { Badge } from '@/components/ui/badge'; import { ScrollArea } from '@/components/ui/scroll-area'; -import { Edit2, Trash2, X } from 'lucide-react'; +import { Edit2, Trash2, Check, X, Package } from 'lucide-react'; import { supabase } from '@/integrations/supabase/client'; import { toast } from 'sonner'; import { RomaneioExpedicao } from '@/hooks/useRomaneios'; @@ -20,6 +21,7 @@ interface ItemRomaneioPeca { id: string; peca_id: string; quantidade_expedida: number; + quantidade_max_peca?: number; peso_unitario: number; peso_total: number; comprimento?: number | null; @@ -39,13 +41,16 @@ export const PecasRomaneioExpandido: React.FC = ({ const [itensPeca, setItensPeca] = useState([]); const [loading, setLoading] = useState(false); + const [editingItemId, setEditingItemId] = useState(null); + const [editQuantidade, setEditQuantidade] = useState(''); + const [savingEdit, setSavingEdit] = useState(false); const carregarItensPecas = async () => { setLoading(true); try { const { data, error } = await supabase .from('itens_romaneio_pecas') - .select('*, pecas(comprimento)') + .select('*, pecas(comprimento, prioridade, quantidade)') .eq('romaneio_id', romaneio.id) .order('marca'); @@ -56,13 +61,14 @@ export const PecasRomaneioExpandido: React.FC = ({ id: item.id, peca_id: item.peca_id, quantidade_expedida: item.quantidade_expedida, + quantidade_max_peca: item.pecas?.quantidade || undefined, peso_unitario: item.peso_unitario, peso_total: item.peso_total, comprimento: item.pecas?.comprimento || item.comprimento || null, marca: item.marca, descricao: item.descricao || '', fase: item.fase || '', - prioridade: 'P4' + prioridade: item.pecas?.prioridade || 'P4' })); setItensPeca(itensFormatados); } @@ -76,8 +82,10 @@ export const PecasRomaneioExpandido: React.FC = ({ useEffect(() => { if (isOpen) { + setEditingItemId(null); carregarItensPecas(); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isOpen, romaneio.id]); const handleRemoverItem = async (itemId: string) => { @@ -99,16 +107,59 @@ export const PecasRomaneioExpandido: React.FC = ({ }; const handleEditarItem = (item: ItemRomaneioPeca) => { - // Funcionalidade de edição pode ser implementada aqui - toast.info('Funcionalidade de edição em desenvolvimento'); + setEditingItemId(item.id); + setEditQuantidade(String(item.quantidade_expedida)); + }; + + const handleCancelarEdicao = () => { + setEditingItemId(null); + setEditQuantidade(''); + }; + + const handleSalvarEdicao = async (item: ItemRomaneioPeca) => { + const novaQtd = parseInt(editQuantidade, 10); + if (isNaN(novaQtd) || novaQtd <= 0) { + toast.error('Informe uma quantidade válida maior que zero'); + return; + } + + if (item.quantidade_max_peca && novaQtd > item.quantidade_max_peca) { + toast.error(`A quantidade não pode exceder o total da peça na OF (${item.quantidade_max_peca} un)`); + return; + } + + try { + setSavingEdit(true); + const novoPesoTotal = novaQtd * item.peso_unitario; + const { error } = await supabase + .from('itens_romaneio_pecas') + .update({ + quantidade_expedida: novaQtd, + peso_total: novoPesoTotal + }) + .eq('id', item.id); + + if (error) throw error; + + toast.success(`Quantidade da peça ${item.marca} atualizada para ${novaQtd} un`); + setEditingItemId(null); + setEditQuantidade(''); + carregarItensPecas(); + onRefresh(); + } catch (error) { + console.error('Erro ao atualizar item:', error); + toast.error('Erro ao atualizar quantidade da peça'); + } finally { + setSavingEdit(false); + } }; const getPrioridadeColor = (prioridade: string) => { switch (prioridade) { - case 'P1': return 'bg-red-100 text-red-800'; - case 'P2': return 'bg-orange-100 text-orange-800'; - case 'P3': return 'bg-blue-100 text-blue-800'; - default: return 'bg-gray-100 text-gray-800'; + case 'P1': return 'bg-red-100 text-red-800 border-red-200 dark:bg-red-950/60 dark:text-red-300 dark:border-red-800'; + case 'P2': return 'bg-orange-100 text-orange-800 border-orange-200 dark:bg-orange-950/60 dark:text-orange-300 dark:border-orange-800'; + case 'P3': return 'bg-blue-100 text-blue-800 border-blue-200 dark:bg-blue-950/60 dark:text-blue-300 dark:border-blue-800'; + default: return 'bg-slate-100 text-slate-800 border-slate-200 dark:bg-slate-800 dark:text-slate-300 dark:border-slate-700'; } }; @@ -122,32 +173,35 @@ export const PecasRomaneioExpandido: React.FC = ({ ? 'w-[95vw] max-w-none h-[95vh] m-2' : isTablet ? 'w-[90vw] max-w-5xl h-[90vh]' - : 'max-w-6xl h-[95vh]' + : 'max-w-6xl h-[90vh]' } - bg-slate-900 text-white border-slate-700 overflow-hidden flex flex-col + bg-background text-foreground border-border shadow-xl overflow-hidden flex flex-col `}> - +
- + + Peças do Romaneio {romaneio.numero_romaneio} - OF: {romaneio.of_number} -
- + Qtd Total: {qtdTotal} - + Peso Total: {pesoTotal.toFixed(2)} kg
@@ -156,13 +210,13 @@ export const PecasRomaneioExpandido: React.FC = ({
{loading ? (
-
+
Carregando...
) : itensPeca.length === 0 ? (
-
+
Nenhuma peça encontrada no romaneio
@@ -171,7 +225,7 @@ export const PecasRomaneioExpandido: React.FC = ({
{/* Cabeçalho da tabela - Desktop/Tablet */} {!isMobile && ( -
Marca
@@ -190,120 +244,209 @@ export const PecasRomaneioExpandido: React.FC = ({ {itensPeca.map((item, index) => { const limite = romaneio.comprimento_maximo_veiculo || 12000; const naoCabe = Boolean(item.comprimento && item.comprimento > limite); + const isEditing = editingItemId === item.id; return (
{isMobile ? ( // Layout mobile - card style -
-
+
{item.marca} {naoCabe && ( - + Excede Veículo )}
-
{item.fase}
+
Fase {item.fase}
- - + {isEditing ? ( + <> + + + + ) : ( + <> + + + + )}
-
+
{item.descricao}
-
+
-
Comp:
-
+
Comp:
+
{item.comprimento ? `${item.comprimento}mm` : '-'}
-
Qtd:
-
{item.quantidade_expedida}
+
Qtd:
+ {isEditing ? ( + setEditQuantidade(e.target.value)} + className="h-7 w-16 text-center text-xs px-1" + autoFocus + /> + ) : ( +
{item.quantidade_expedida}
+ )}
-
Peso Unit:
-
{item.peso_unitario.toFixed(2)} kg
+
Peso Unit:
+
{item.peso_unitario.toFixed(2)} kg
-
Peso Total:
-
{item.peso_total.toFixed(2)} kg
+
Peso Total:
+
{item.peso_total.toFixed(2)} kg
) : ( // Layout desktop/tablet - table style -
-
+
+
{item.marca} - {naoCabe && ⚠️} + {naoCabe && ⚠️}
-
{item.fase}
-
+
{item.fase}
+
{item.descricao}
-
+
{item.comprimento ? `${item.comprimento}` : '-'}
-
- {item.quantidade_expedida} +
+ {isEditing ? ( + setEditQuantidade(e.target.value)} + onKeyDown={(e) => { + if (e.key === 'Enter') handleSalvarEdicao(item); + if (e.key === 'Escape') handleCancelarEdicao(); + }} + className="h-7 w-20 text-center text-xs px-1" + autoFocus + /> + ) : ( + item.quantidade_expedida + )}
-
+
{item.peso_unitario.toFixed(2)} kg
-
+
{item.peso_total.toFixed(2)} kg
{!isTablet && (
- + {item.prioridade}
)}
- - + {isEditing ? ( + <> + + + + ) : ( + <> + + + + )}
)} @@ -315,11 +458,11 @@ export const PecasRomaneioExpandido: React.FC = ({ )}
-
+