fix: suporte completo ao tema claro e escuro nos modais de revisoes e botoes da tabela

This commit is contained in:
Marcos Reifonas
2026-10-07 23:15:28 -03:00
parent c239dffdee
commit 28c23a7324
4 changed files with 158 additions and 166 deletions
+3 -3
View File
@@ -182,13 +182,13 @@ export function PecasTable({
variant="outline" variant="outline"
size="sm" size="sm"
onClick={onOpenPainelRevisoes} onClick={onOpenPainelRevisoes}
className="h-8 border-red-500/60 bg-red-950/20 text-red-400 hover:bg-red-900/40 hover:text-red-200 font-bold flex items-center gap-1.5 transition-all shadow-sm" className="h-8 border-red-500/50 bg-red-500/10 text-red-600 dark:text-red-400 hover:bg-red-500/20 hover:text-red-700 dark:hover:text-red-300 font-bold flex items-center gap-1.5 transition-all shadow-sm"
title="Abrir Registro e Gestão de Revisões da OF" title="Abrir Registro e Gestão de Revisões da OF"
> >
<FileText className="h-3.5 w-3.5 text-red-400" /> <FileText className="h-3.5 w-3.5 text-red-600 dark:text-red-400" />
<span>REG.REVISOES</span> <span>REG.REVISOES</span>
{totalRevisoesOF !== undefined && totalRevisoesOF > 0 && ( {totalRevisoesOF !== undefined && totalRevisoesOF > 0 && (
<span className="ml-1 px-1.5 py-0.2 rounded-full text-[10px] bg-red-500 text-white font-black"> <span className="ml-1 px-1.5 py-0.2 rounded-full text-[10px] bg-red-600 dark:bg-red-500 text-white font-black">
{totalRevisoesOF} {totalRevisoesOF}
</span> </span>
)} )}
@@ -20,16 +20,10 @@ import {
import { import {
FileText, FileText,
Search, Search,
AlertTriangle,
Info,
Clock,
Printer, Printer,
ExternalLink, ExternalLink,
Filter, Filter,
CheckCircle2, RefreshCw
RefreshCw,
Layers,
ArrowRight
} from 'lucide-react'; } from 'lucide-react';
import { useRevisoes, Revisao } from '@/hooks/useRevisoes'; import { useRevisoes, Revisao } from '@/hooks/useRevisoes';
import { Peca } from '@/hooks/usePecas'; import { Peca } from '@/hooks/usePecas';
@@ -105,21 +99,21 @@ export function PainelRevisoesOFModal({
return ( return (
<Dialog open={isOpen} onOpenChange={onClose}> <Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent className="max-w-5xl max-h-[90vh] overflow-y-auto bg-slate-950 border-slate-800 text-slate-100 p-6"> <DialogContent className="max-w-5xl max-h-[90vh] overflow-y-auto bg-background text-foreground border-border p-6 shadow-xl">
<DialogHeader className="border-b border-slate-800 pb-4"> <DialogHeader className="border-b border-border pb-4">
<div className="flex items-center justify-between flex-wrap gap-2"> <div className="flex items-center justify-between flex-wrap gap-2">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-lg bg-red-500/10 border border-red-500/30 flex items-center justify-center text-red-500"> <div className="w-10 h-10 rounded-lg bg-red-500/10 border border-red-500/30 flex items-center justify-center text-red-600 dark:text-red-400">
<FileText className="w-5 h-5" /> <FileText className="w-5 h-5" />
</div> </div>
<div> <div>
<DialogTitle className="text-xl font-bold flex items-center gap-2"> <DialogTitle className="text-xl font-bold flex items-center gap-2">
<span>Registro Geral de Revisões da OF</span> <span>Registro Geral de Revisões da OF</span>
<Badge variant="outline" className="font-mono text-amber-400 border-amber-400/40 bg-amber-500/10 text-sm"> <Badge variant="outline" className="font-mono text-amber-600 dark:text-amber-400 border-amber-400/40 bg-amber-500/10 text-sm">
{ofNumber || 'Geral'} {ofNumber || 'Geral'}
</Badge> </Badge>
</DialogTitle> </DialogTitle>
<DialogDescription className="text-slate-400 text-xs mt-0.5"> <DialogDescription className="text-muted-foreground text-xs mt-0.5">
Rastreabilidade técnica, histórico de modificações simples e críticas nas peças desta Ordem de Fabricação. Rastreabilidade técnica, histórico de modificações simples e críticas nas peças desta Ordem de Fabricação.
</DialogDescription> </DialogDescription>
</div> </div>
@@ -130,9 +124,9 @@ export function PainelRevisoesOFModal({
variant="outline" variant="outline"
size="sm" size="sm"
onClick={() => setVisualizandoRelatorio(!visualizandoRelatorio)} onClick={() => setVisualizandoRelatorio(!visualizandoRelatorio)}
className="border-slate-700 text-slate-200 hover:bg-slate-800 flex items-center gap-1.5 h-8 text-xs" className="border-border text-foreground hover:bg-muted flex items-center gap-1.5 h-8 text-xs"
> >
<Printer className="w-3.5 h-3.5 text-blue-400" /> <Printer className="w-3.5 h-3.5 text-blue-500" />
{visualizandoRelatorio ? 'Voltar para Tabela' : 'Gerar Relatório'} {visualizandoRelatorio ? 'Voltar para Tabela' : 'Gerar Relatório'}
</Button> </Button>
</div> </div>
@@ -142,14 +136,14 @@ export function PainelRevisoesOFModal({
{/* MODO RELATÓRIO IMPRESSÃO */} {/* MODO RELATÓRIO IMPRESSÃO */}
{visualizandoRelatorio ? ( {visualizandoRelatorio ? (
<div className="mt-4 space-y-4"> <div className="mt-4 space-y-4">
<div className="flex items-center justify-between bg-slate-900 p-3 rounded border border-slate-800"> <div className="flex items-center justify-between bg-muted p-3 rounded-lg border border-border">
<span className="text-xs text-slate-300"> <span className="text-xs text-muted-foreground">
Pré-visualização do Relatório Técnico para impressão ou exportação. Pré-visualização do Relatório Técnico para impressão ou exportação.
</span> </span>
<Button <Button
size="sm" size="sm"
onClick={handleImprimirRelatorio} onClick={handleImprimirRelatorio}
className="bg-blue-600 hover:bg-blue-500 text-white text-xs h-7 flex items-center gap-1" className="bg-blue-600 hover:bg-blue-500 text-white text-xs h-7 flex items-center gap-1 shadow-sm"
> >
<Printer className="w-3.5 h-3.5" /> <Printer className="w-3.5 h-3.5" />
Imprimir / Salvar PDF Imprimir / Salvar PDF
@@ -157,7 +151,7 @@ export function PainelRevisoesOFModal({
</div> </div>
{/* Documento A4 Formato Relatório */} {/* Documento A4 Formato Relatório */}
<div className="p-6 bg-white text-slate-900 rounded-lg shadow-lg text-xs space-y-4 font-sans"> <div className="p-6 bg-white text-slate-900 rounded-lg shadow-lg text-xs space-y-4 font-sans border border-slate-200">
{/* Header do Relatório */} {/* Header do Relatório */}
<div className="border-b-2 border-slate-800 pb-3 flex justify-between items-start"> <div className="border-b-2 border-slate-800 pb-3 flex justify-between items-start">
<div> <div>
@@ -209,7 +203,7 @@ export function PainelRevisoesOFModal({
{r.numero_revisao} {r.numero_revisao}
</td> </td>
<td className="border border-slate-300 p-1.5 text-center font-semibold"> <td className="border border-slate-300 p-1.5 text-center font-semibold">
<span className={r.tipo_revisao === 'critica' ? 'text-red-600' : 'text-blue-600'}> <span className={r.tipo_revisao === 'critica' ? 'text-red-600 font-bold' : 'text-blue-600 font-bold'}>
{r.tipo_revisao === 'critica' ? 'CRÍTICA' : 'SIMPLES'} {r.tipo_revisao === 'critica' ? 'CRÍTICA' : 'SIMPLES'}
</span> </span>
</td> </td>
@@ -249,44 +243,44 @@ export function PainelRevisoesOFModal({
<div className="mt-4 space-y-4"> <div className="mt-4 space-y-4">
{/* CARDS DE MÉTRICAS */} {/* CARDS DE MÉTRICAS */}
<div className="grid grid-cols-2 sm:grid-cols-4 gap-3"> <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
<div className="p-3 rounded-lg bg-slate-900 border border-slate-800"> <div className="p-3 rounded-lg bg-card border border-border shadow-sm">
<span className="text-[11px] font-bold uppercase tracking-wider text-slate-400 block"> <span className="text-[11px] font-bold uppercase tracking-wider text-muted-foreground block">
Total de Revisões Total de Revisões
</span> </span>
<span className="text-2xl font-black text-slate-100 mt-1 block"> <span className="text-2xl font-black text-foreground mt-1 block">
{stats.total} {stats.total}
</span> </span>
<span className="text-[10px] text-slate-500">histórico completo</span> <span className="text-[10px] text-muted-foreground">histórico completo</span>
</div> </div>
<div className="p-3 rounded-lg bg-red-950/20 border border-red-500/30"> <div className="p-3 rounded-lg bg-red-500/10 border border-red-500/30 shadow-sm">
<span className="text-[11px] font-bold uppercase tracking-wider text-red-400 block"> <span className="text-[11px] font-bold uppercase tracking-wider text-red-600 dark:text-red-400 block">
Revisões Críticas Revisões Críticas
</span> </span>
<span className="text-2xl font-black text-red-300 mt-1 block"> <span className="text-2xl font-black text-red-700 dark:text-red-300 mt-1 block">
{stats.criticas} {stats.criticas}
</span> </span>
<span className="text-[10px] text-red-400/80">alteraram marca, qtd, peso</span> <span className="text-[10px] text-red-600/80 dark:text-red-400/80">alteraram marca, qtd, peso</span>
</div> </div>
<div className="p-3 rounded-lg bg-blue-950/20 border border-blue-500/30"> <div className="p-3 rounded-lg bg-blue-500/10 border border-blue-500/30 shadow-sm">
<span className="text-[11px] font-bold uppercase tracking-wider text-blue-400 block"> <span className="text-[11px] font-bold uppercase tracking-wider text-blue-600 dark:text-blue-400 block">
Revisões Simples Revisões Simples
</span> </span>
<span className="text-2xl font-black text-blue-300 mt-1 block"> <span className="text-2xl font-black text-blue-700 dark:text-blue-300 mt-1 block">
{stats.simples} {stats.simples}
</span> </span>
<span className="text-[10px] text-blue-400/80">dados informativos</span> <span className="text-[10px] text-blue-600/80 dark:text-blue-400/80">dados informativos</span>
</div> </div>
<div className="p-3 rounded-lg bg-amber-950/20 border border-amber-500/30"> <div className="p-3 rounded-lg bg-amber-500/10 border border-amber-500/30 shadow-sm">
<span className="text-[11px] font-bold uppercase tracking-wider text-amber-400 block"> <span className="text-[11px] font-bold uppercase tracking-wider text-amber-600 dark:text-amber-400 block">
Peças Afetadas Peças Afetadas
</span> </span>
<span className="text-2xl font-black text-amber-300 mt-1 block"> <span className="text-2xl font-black text-amber-700 dark:text-amber-300 mt-1 block">
{stats.pecasUnicas} {stats.pecasUnicas}
</span> </span>
<span className="text-[10px] text-amber-400/80">peças distintas</span> <span className="text-[10px] text-amber-600/80 dark:text-amber-400/80">peças distintas</span>
</div> </div>
</div> </div>
@@ -294,23 +288,23 @@ export function PainelRevisoesOFModal({
<div className="flex items-center justify-between flex-wrap gap-2"> <div className="flex items-center justify-between flex-wrap gap-2">
<div className="flex items-center gap-2 flex-1 min-w-[240px]"> <div className="flex items-center gap-2 flex-1 min-w-[240px]">
<div className="relative flex-1"> <div className="relative flex-1">
<Search className="w-3.5 h-3.5 absolute left-3 top-1/2 -translate-y-1/2 text-slate-500" /> <Search className="w-3.5 h-3.5 absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground" />
<Input <Input
value={busca} value={busca}
onChange={(e) => setBusca(e.target.value)} onChange={(e) => setBusca(e.target.value)}
placeholder="Filtrar por peça, fase, motivo ou autor..." placeholder="Filtrar por peça, fase, motivo ou autor..."
className="pl-8 bg-slate-900 border-slate-800 text-xs h-8" className="pl-8 bg-background border-input text-xs h-8 text-foreground"
/> />
</div> </div>
</div> </div>
<div className="flex items-center gap-1.5 text-xs"> <div className="flex items-center gap-1.5 text-xs">
<Filter className="w-3.5 h-3.5 text-slate-400" /> <Filter className="w-3.5 h-3.5 text-muted-foreground" />
<button <button
type="button" type="button"
onClick={() => setFiltroTipo('todos')} onClick={() => setFiltroTipo('todos')}
className={`px-2.5 py-1 rounded text-xs transition-colors ${ className={`px-2.5 py-1 rounded text-xs transition-colors ${
filtroTipo === 'todos' ? 'bg-slate-700 text-white font-bold' : 'text-slate-400 hover:bg-slate-800' filtroTipo === 'todos' ? 'bg-primary text-primary-foreground font-bold shadow-sm' : 'text-muted-foreground hover:bg-muted'
}`} }`}
> >
Todas ({stats.total}) Todas ({stats.total})
@@ -320,8 +314,8 @@ export function PainelRevisoesOFModal({
onClick={() => setFiltroTipo('critica')} onClick={() => setFiltroTipo('critica')}
className={`px-2.5 py-1 rounded text-xs transition-colors ${ className={`px-2.5 py-1 rounded text-xs transition-colors ${
filtroTipo === 'critica' filtroTipo === 'critica'
? 'bg-red-600 text-white font-bold' ? 'bg-red-600 text-white font-bold shadow-sm'
: 'text-red-400 hover:bg-red-950/40' : 'text-red-600 dark:text-red-400 hover:bg-red-500/10'
}`} }`}
> >
Críticas ({stats.criticas}) Críticas ({stats.criticas})
@@ -331,8 +325,8 @@ export function PainelRevisoesOFModal({
onClick={() => setFiltroTipo('simples')} onClick={() => setFiltroTipo('simples')}
className={`px-2.5 py-1 rounded text-xs transition-colors ${ className={`px-2.5 py-1 rounded text-xs transition-colors ${
filtroTipo === 'simples' filtroTipo === 'simples'
? 'bg-blue-600 text-white font-bold' ? 'bg-blue-600 text-white font-bold shadow-sm'
: 'text-blue-400 hover:bg-blue-950/40' : 'text-blue-600 dark:text-blue-400 hover:bg-blue-500/10'
}`} }`}
> >
Simples ({stats.simples}) Simples ({stats.simples})
@@ -343,7 +337,7 @@ export function PainelRevisoesOFModal({
size="sm" size="sm"
onClick={() => carregarRevisoesOF(ofNumber)} onClick={() => carregarRevisoesOF(ofNumber)}
disabled={loading} disabled={loading}
className="h-8 w-8 p-0 text-slate-400 hover:text-white" className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground"
title="Atualizar lista" title="Atualizar lista"
> >
<RefreshCw className={`w-3.5 h-3.5 ${loading ? 'animate-spin' : ''}`} /> <RefreshCw className={`w-3.5 h-3.5 ${loading ? 'animate-spin' : ''}`} />
@@ -352,31 +346,31 @@ export function PainelRevisoesOFModal({
</div> </div>
{/* TABELA DE REVISÕES */} {/* TABELA DE REVISÕES */}
<div className="rounded-md border border-slate-800 bg-slate-900/60 overflow-hidden"> <div className="rounded-md border border-border bg-card overflow-hidden shadow-sm">
<Table> <Table>
<TableHeader className="bg-slate-900"> <TableHeader className="bg-muted/50">
<TableRow className="border-slate-800 hover:bg-slate-900"> <TableRow className="border-border hover:bg-muted/50">
<TableHead className="text-slate-300 text-xs w-28">Data</TableHead> <TableHead className="text-muted-foreground text-xs w-28">Data</TableHead>
<TableHead className="text-slate-300 text-xs w-20">Peça</TableHead> <TableHead className="text-muted-foreground text-xs w-20">Peça</TableHead>
<TableHead className="text-slate-300 text-xs w-16 text-center">Fase</TableHead> <TableHead className="text-muted-foreground text-xs w-16 text-center">Fase</TableHead>
<TableHead className="text-slate-300 text-xs w-20 text-center">Revisão</TableHead> <TableHead className="text-muted-foreground text-xs w-20 text-center">Revisão</TableHead>
<TableHead className="text-slate-300 text-xs w-20 text-center">Tipo</TableHead> <TableHead className="text-muted-foreground text-xs w-20 text-center">Tipo</TableHead>
<TableHead className="text-slate-300 text-xs">Motivo da Revisão</TableHead> <TableHead className="text-muted-foreground text-xs">Motivo da Revisão</TableHead>
<TableHead className="text-slate-300 text-xs">Campos Alterados</TableHead> <TableHead className="text-muted-foreground text-xs">Campos Alterados</TableHead>
<TableHead className="text-slate-300 text-xs w-28">Autor</TableHead> <TableHead className="text-muted-foreground text-xs w-28">Autor</TableHead>
<TableHead className="text-slate-300 text-xs w-16 text-right">Ação</TableHead> <TableHead className="text-muted-foreground text-xs w-16 text-right">Ação</TableHead>
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody> <TableBody>
{loading ? ( {loading ? (
<TableRow> <TableRow>
<TableCell colSpan={9} className="text-center py-8 text-slate-400 text-xs"> <TableCell colSpan={9} className="text-center py-8 text-muted-foreground text-xs">
Carregando revisões da OF... Carregando revisões da OF...
</TableCell> </TableCell>
</TableRow> </TableRow>
) : revisoesFiltradas.length === 0 ? ( ) : revisoesFiltradas.length === 0 ? (
<TableRow> <TableRow>
<TableCell colSpan={9} className="text-center py-8 text-slate-400 text-xs"> <TableCell colSpan={9} className="text-center py-8 text-muted-foreground text-xs">
{revisoes.length === 0 {revisoes.length === 0
? 'Nenhuma revisão cadastrada nesta OF.' ? 'Nenhuma revisão cadastrada nesta OF.'
: 'Nenhuma revisão encontrada para os filtros selecionados.'} : 'Nenhuma revisão encontrada para os filtros selecionados.'}
@@ -386,23 +380,23 @@ export function PainelRevisoesOFModal({
revisoesFiltradas.map((r) => { revisoesFiltradas.map((r) => {
const pecaCorrespondente = pecas.find((p) => p.id === r.peca_id); const pecaCorrespondente = pecas.find((p) => p.id === r.peca_id);
return ( return (
<TableRow key={r.id} className="border-slate-800 hover:bg-slate-800/50 text-xs"> <TableRow key={r.id} className="border-border hover:bg-muted/40 text-xs">
<TableCell className="font-mono text-slate-400 whitespace-nowrap"> <TableCell className="font-mono text-muted-foreground whitespace-nowrap">
{r.data_revisao ? format(new Date(r.data_revisao), 'dd/MM/yy HH:mm') : '-'} {r.data_revisao ? format(new Date(r.data_revisao), 'dd/MM/yy HH:mm') : '-'}
</TableCell> </TableCell>
<TableCell className="font-mono font-bold text-slate-100"> <TableCell className="font-mono font-bold text-foreground">
{r.peca?.marca || '-'} {r.peca?.marca || '-'}
</TableCell> </TableCell>
<TableCell className="text-center text-slate-300 font-mono"> <TableCell className="text-center text-foreground font-mono">
{r.peca?.etapa_fase || '-'} {r.peca?.etapa_fase || '-'}
</TableCell> </TableCell>
<TableCell className="text-center"> <TableCell className="text-center">
<Badge <Badge
variant="outline" variant="outline"
className="font-mono text-[11px] font-bold bg-amber-500/10 text-amber-400 border-amber-400/40" className="font-mono text-[11px] font-bold bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-400/40"
> >
{r.numero_revisao} {r.numero_revisao}
</Badge> </Badge>
@@ -412,18 +406,18 @@ export function PainelRevisoesOFModal({
<Badge <Badge
className={`text-[10px] font-bold ${ className={`text-[10px] font-bold ${
r.tipo_revisao === 'critica' r.tipo_revisao === 'critica'
? 'bg-red-500/20 text-red-400 border border-red-500/40' ? 'bg-red-500/15 text-red-600 dark:text-red-400 border border-red-500/30'
: 'bg-blue-500/20 text-blue-400 border border-blue-500/40' : 'bg-blue-500/15 text-blue-600 dark:text-blue-400 border border-blue-500/30'
}`} }`}
> >
{r.tipo_revisao === 'critica' ? 'Crítica' : 'Simples'} {r.tipo_revisao === 'critica' ? 'Crítica' : 'Simples'}
</Badge> </Badge>
</TableCell> </TableCell>
<TableCell className="text-slate-200"> <TableCell className="text-foreground">
<span className="font-medium block">{r.descricao_motivo}</span> <span className="font-medium block">{r.descricao_motivo}</span>
{r.observacoes && ( {r.observacoes && (
<span className="text-[10px] text-slate-400 italic block mt-0.5"> <span className="text-[10px] text-muted-foreground italic block mt-0.5">
{r.observacoes} {r.observacoes}
</span> </span>
)} )}
@@ -434,7 +428,7 @@ export function PainelRevisoesOFModal({
{r.campos_alterados?.map((c) => ( {r.campos_alterados?.map((c) => (
<span <span
key={c} key={c}
className="text-[10px] font-mono px-1.5 py-0.5 rounded bg-slate-800 text-slate-300 border border-slate-700" className="text-[10px] font-mono px-1.5 py-0.5 rounded bg-muted text-foreground border border-border"
> >
{c} {c}
</span> </span>
@@ -442,7 +436,7 @@ export function PainelRevisoesOFModal({
</div> </div>
</TableCell> </TableCell>
<TableCell className="text-slate-300 truncate max-w-[120px]"> <TableCell className="text-muted-foreground truncate max-w-[120px]">
{r.usuario_nome || r.usuario_email || 'Sistema'} {r.usuario_nome || r.usuario_email || 'Sistema'}
</TableCell> </TableCell>
@@ -456,12 +450,12 @@ export function PainelRevisoesOFModal({
onOpenRevisaoPeca(pecaCorrespondente); onOpenRevisaoPeca(pecaCorrespondente);
}} }}
title="Abrir CRUD / Histórico da Peça" title="Abrir CRUD / Histórico da Peça"
className="h-6 w-6 p-0 text-amber-400 hover:text-amber-300 hover:bg-amber-950/40" className="h-6 w-6 p-0 text-amber-600 dark:text-amber-400 hover:bg-amber-500/10"
> >
<ExternalLink className="w-3.5 h-3.5" /> <ExternalLink className="w-3.5 h-3.5" />
</Button> </Button>
) : ( ) : (
<span className="text-slate-600 text-[10px]">-</span> <span className="text-muted-foreground text-[10px]">-</span>
)} )}
</TableCell> </TableCell>
</TableRow> </TableRow>
@@ -15,11 +15,9 @@ import { Badge } from '@/components/ui/badge';
import { import {
AlertTriangle, AlertTriangle,
History, History,
CheckCircle2,
ArrowRight, ArrowRight,
TrendingUp, TrendingUp,
TrendingDown, TrendingDown,
Layers,
Save, Save,
Clock, Clock,
User, User,
@@ -148,8 +146,8 @@ export function RevisaoPecaModal({
return ( return (
<Dialog open={isOpen} onOpenChange={onClose}> <Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto bg-slate-950 border-slate-800 text-slate-100 p-6"> <DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto bg-background text-foreground border-border p-6 shadow-xl">
<DialogHeader className="border-b border-slate-800 pb-4"> <DialogHeader className="border-b border-border pb-4">
<div className="flex items-center justify-between flex-wrap gap-2"> <div className="flex items-center justify-between flex-wrap gap-2">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-lg bg-amber-500/10 border border-amber-500/30 flex items-center justify-center text-amber-500"> <div className="w-10 h-10 rounded-lg bg-amber-500/10 border border-amber-500/30 flex items-center justify-center text-amber-500">
@@ -158,17 +156,17 @@ export function RevisaoPecaModal({
<div> <div>
<DialogTitle className="text-xl font-bold flex items-center gap-2"> <DialogTitle className="text-xl font-bold flex items-center gap-2">
<span>Gestão de Revisões da Peça</span> <span>Gestão de Revisões da Peça</span>
<Badge variant="outline" className="font-mono text-amber-400 border-amber-400/40 bg-amber-500/10 text-sm"> <Badge variant="outline" className="font-mono text-amber-600 dark:text-amber-400 border-amber-400/40 bg-amber-500/10 text-sm">
{peca.marca} {peca.marca}
</Badge> </Badge>
{historico.length > 0 && ( {historico.length > 0 && (
<Badge variant="secondary" className="bg-slate-800 text-slate-300 text-xs"> <Badge variant="secondary" className="bg-muted text-muted-foreground text-xs">
{historico.length} {historico.length === 1 ? 'revisão gravada' : 'revisões gravadas'} {historico.length} {historico.length === 1 ? 'revisão gravada' : 'revisões gravadas'}
</Badge> </Badge>
)} )}
</DialogTitle> </DialogTitle>
<DialogDescription className="text-slate-400 text-xs mt-0.5"> <DialogDescription className="text-muted-foreground text-xs mt-0.5">
OF: <strong className="text-slate-200">{peca.of_number}</strong> • Fase: <strong className="text-slate-200">{peca.etapa_fase || 'N/A'}</strong> • Qtd Atual: <strong className="text-slate-200">{peca.quantidade} un</strong> • Peso Atual: <strong className="text-slate-200">{peca.peso_total || (peca.quantidade * peca.peso_unitario)} kg</strong> OF: <strong className="text-foreground">{peca.of_number}</strong> • Fase: <strong className="text-foreground">{peca.etapa_fase || 'N/A'}</strong> • Qtd Atual: <strong className="text-foreground">{peca.quantidade} un</strong> • Peso Atual: <strong className="text-foreground">{peca.peso_total || (peca.quantidade * peca.peso_unitario)} kg</strong>
</DialogDescription> </DialogDescription>
</div> </div>
</div> </div>
@@ -178,8 +176,8 @@ export function RevisaoPecaModal({
variant={tipoEfetivo === 'critica' ? 'destructive' : 'secondary'} variant={tipoEfetivo === 'critica' ? 'destructive' : 'secondary'}
className={`text-xs px-2.5 py-1 font-semibold ${ className={`text-xs px-2.5 py-1 font-semibold ${
tipoEfetivo === 'critica' tipoEfetivo === 'critica'
? 'bg-red-500/20 text-red-400 border border-red-500/40' ? 'bg-red-500/15 text-red-600 dark:text-red-400 border border-red-500/30'
: 'bg-blue-500/20 text-blue-400 border border-blue-500/40' : 'bg-blue-500/15 text-blue-600 dark:text-blue-400 border border-blue-500/30'
}`} }`}
> >
{tipoEfetivo === 'critica' ? '⚠️ Revisão Crítica' : 'ℹ️ Revisão Simples'} {tipoEfetivo === 'critica' ? '⚠️ Revisão Crítica' : 'ℹ️ Revisão Simples'}
@@ -189,12 +187,12 @@ export function RevisaoPecaModal({
</DialogHeader> </DialogHeader>
<Tabs value={activeTab} onValueChange={(v) => setActiveTab(v as any)} className="mt-4"> <Tabs value={activeTab} onValueChange={(v) => setActiveTab(v as any)} className="mt-4">
<TabsList className="grid grid-cols-2 bg-slate-900 border border-slate-800"> <TabsList className="grid grid-cols-2 bg-muted border border-border">
<TabsTrigger value="nova" className="data-[state=active]:bg-amber-600 data-[state=active]:text-white"> <TabsTrigger value="nova" className="data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm font-semibold">
<Edit3 className="w-4 h-4 mr-2" /> <Edit3 className="w-4 h-4 mr-2" />
Nova Revisão (Editar Peça) Nova Revisão (Editar Peça)
</TabsTrigger> </TabsTrigger>
<TabsTrigger value="historico" className="data-[state=active]:bg-slate-800 data-[state=active]:text-white"> <TabsTrigger value="historico" className="data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm font-semibold">
<History className="w-4 h-4 mr-2" /> <History className="w-4 h-4 mr-2" />
Histórico de Revisões ({historico.length}) Histórico de Revisões ({historico.length})
</TabsTrigger> </TabsTrigger>
@@ -204,21 +202,21 @@ export function RevisaoPecaModal({
<TabsContent value="nova" className="mt-4 space-y-4"> <TabsContent value="nova" className="mt-4 space-y-4">
<form onSubmit={handleSalvarRevisao} className="space-y-4"> <form onSubmit={handleSalvarRevisao} className="space-y-4">
{/* Metadados da Revisão */} {/* Metadados da Revisão */}
<div className="p-4 rounded-lg bg-slate-900/80 border border-slate-800 space-y-3"> <div className="p-4 rounded-lg bg-card border border-border space-y-3 shadow-sm">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h4 className="text-xs font-bold uppercase tracking-wider text-slate-400 flex items-center gap-2"> <h4 className="text-xs font-bold uppercase tracking-wider text-muted-foreground flex items-center gap-2">
<Info className="w-3.5 h-3.5 text-amber-500" /> <Info className="w-3.5 h-3.5 text-amber-500" />
Identificação da Revisão Identificação da Revisão
</h4> </h4>
<div className="flex items-center gap-2 text-xs"> <div className="flex items-center gap-2 text-xs">
<span className="text-slate-400">Classificação:</span> <span className="text-muted-foreground">Classificação:</span>
<button <button
type="button" type="button"
onClick={() => setTipoManual('simples')} onClick={() => setTipoManual('simples')}
className={`px-2 py-0.5 rounded text-xs transition-colors ${ className={`px-2.5 py-1 rounded text-xs transition-colors ${
tipoEfetivo === 'simples' tipoEfetivo === 'simples'
? 'bg-blue-600 text-white font-bold' ? 'bg-blue-600 text-white font-bold shadow-sm'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700' : 'bg-muted text-muted-foreground hover:bg-muted/80'
}`} }`}
> >
Simples Simples
@@ -226,10 +224,10 @@ export function RevisaoPecaModal({
<button <button
type="button" type="button"
onClick={() => setTipoManual('critica')} onClick={() => setTipoManual('critica')}
className={`px-2 py-0.5 rounded text-xs transition-colors ${ className={`px-2.5 py-1 rounded text-xs transition-colors ${
tipoEfetivo === 'critica' tipoEfetivo === 'critica'
? 'bg-red-600 text-white font-bold' ? 'bg-red-600 text-white font-bold shadow-sm'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700' : 'bg-muted text-muted-foreground hover:bg-muted/80'
}`} }`}
> >
Crítica Crítica
@@ -239,61 +237,61 @@ export function RevisaoPecaModal({
<div className="grid grid-cols-1 md:grid-cols-3 gap-3"> <div className="grid grid-cols-1 md:grid-cols-3 gap-3">
<div> <div>
<Label className="text-xs text-slate-300">Número da Revisão *</Label> <Label className="text-xs text-foreground">Número da Revisão *</Label>
<Input <Input
value={numeroRevisao} value={numeroRevisao}
onChange={(e) => setNumeroRevisao(e.target.value)} onChange={(e) => setNumeroRevisao(e.target.value)}
placeholder="Ex: Rev 01, Rev 02, Rev A" placeholder="Ex: Rev 01, Rev 02, Rev A"
className="bg-slate-950 border-slate-700 text-slate-100 font-mono text-sm mt-1" className="font-mono text-sm mt-1 bg-background border-input text-foreground"
required required
/> />
</div> </div>
<div className="md:col-span-2"> <div className="md:col-span-2">
<Label className="text-xs text-slate-300">Motivo / Justificativa da Revisão *</Label> <Label className="text-xs text-foreground">Motivo / Justificativa da Revisão *</Label>
<Input <Input
value={motivo} value={motivo}
onChange={(e) => setMotivo(e.target.value)} onChange={(e) => setMotivo(e.target.value)}
placeholder="Ex: Ajuste de projeto, alteração de quantidade pelo cliente..." placeholder="Ex: Ajuste de projeto, alteração de quantidade pelo cliente..."
className="bg-slate-950 border-slate-700 text-slate-100 text-sm mt-1" className="text-sm mt-1 bg-background border-input text-foreground"
required required
/> />
</div> </div>
</div> </div>
<div> <div>
<Label className="text-xs text-slate-300">Observações Adicionais (Opcional)</Label> <Label className="text-xs text-foreground">Observações Adicionais (Opcional)</Label>
<Textarea <Textarea
value={observacoes} value={observacoes}
onChange={(e) => setObservacoes(e.target.value)} onChange={(e) => setObservacoes(e.target.value)}
placeholder="Detalhes adicionais, aprovações de engenharia, notas de fábrica..." placeholder="Detalhes adicionais, aprovações de engenharia, notas de fábrica..."
rows={2} rows={2}
className="bg-slate-950 border-slate-700 text-slate-100 text-xs mt-1" className="text-xs mt-1 bg-background border-input text-foreground"
/> />
</div> </div>
</div> </div>
{/* Formulário CRUD da Peça */} {/* Formulário CRUD da Peça */}
<div className="p-4 rounded-lg bg-slate-900/60 border border-slate-800 space-y-4"> <div className="p-4 rounded-lg bg-card border border-border space-y-4 shadow-sm">
<h4 className="text-xs font-bold uppercase tracking-wider text-slate-400 flex items-center gap-2"> <h4 className="text-xs font-bold uppercase tracking-wider text-muted-foreground flex items-center gap-2">
<Edit3 className="w-3.5 h-3.5 text-blue-400" /> <Edit3 className="w-3.5 h-3.5 text-blue-500" />
Campos da Peça para Revisão Campos da Peça para Revisão
</h4> </h4>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-3"> <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-3">
{/* Marca */} {/* Marca */}
<div> <div>
<Label className="text-xs text-slate-300 flex items-center justify-between"> <Label className="text-xs text-foreground flex items-center justify-between">
<span>Marca / Número da Peça *</span> <span>Marca / Número da Peça *</span>
{formData.marca !== peca.marca && ( {formData.marca !== peca.marca && (
<span className="text-[10px] text-amber-400 font-bold">Alterado!</span> <span className="text-[10px] text-amber-600 dark:text-amber-400 font-bold">Alterado!</span>
)} )}
</Label> </Label>
<Input <Input
value={formData.marca} value={formData.marca}
onChange={(e) => handleInputChange('marca', e.target.value)} onChange={(e) => handleInputChange('marca', e.target.value)}
className={`font-mono text-sm mt-1 bg-slate-950 border-slate-700 ${ className={`font-mono text-sm mt-1 bg-background border-input text-foreground ${
formData.marca !== peca.marca ? 'border-amber-500 bg-amber-950/20 text-amber-200' : '' formData.marca !== peca.marca ? 'border-amber-500 bg-amber-500/10 text-amber-700 dark:text-amber-200' : ''
}`} }`}
required required
/> />
@@ -301,10 +299,10 @@ export function RevisaoPecaModal({
{/* Quantidade */} {/* Quantidade */}
<div> <div>
<Label className="text-xs text-slate-300 flex items-center justify-between"> <Label className="text-xs text-foreground flex items-center justify-between">
<span>Quantidade *</span> <span>Quantidade *</span>
{diffQtd !== 0 && ( {diffQtd !== 0 && (
<span className={`text-[10px] font-bold ${diffQtd > 0 ? 'text-green-400' : 'text-red-400'}`}> <span className={`text-[10px] font-bold ${diffQtd > 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'}`}>
{diffQtd > 0 ? `+${diffQtd}` : `${diffQtd}`} un {diffQtd > 0 ? `+${diffQtd}` : `${diffQtd}`} un
</span> </span>
)} )}
@@ -315,11 +313,11 @@ export function RevisaoPecaModal({
step="1" step="1"
value={formData.quantidade} value={formData.quantidade}
onChange={(e) => handleInputChange('quantidade', Number(e.target.value))} onChange={(e) => handleInputChange('quantidade', Number(e.target.value))}
className={`font-mono text-sm mt-1 bg-slate-950 border-slate-700 ${ className={`font-mono text-sm mt-1 bg-background border-input text-foreground ${
diffQtd !== 0 diffQtd !== 0
? diffQtd > 0 ? diffQtd > 0
? 'border-green-500 bg-green-950/20 text-green-200' ? 'border-green-500 bg-green-500/10 text-green-700 dark:text-green-200'
: 'border-red-500 bg-red-950/20 text-red-200' : 'border-red-500 bg-red-500/10 text-red-700 dark:text-red-200'
: '' : ''
}`} }`}
required required
@@ -328,10 +326,10 @@ export function RevisaoPecaModal({
{/* Peso Unitário */} {/* Peso Unitário */}
<div> <div>
<Label className="text-xs text-slate-300 flex items-center justify-between"> <Label className="text-xs text-foreground flex items-center justify-between">
<span>Peso Unitário (kg) *</span> <span>Peso Unitário (kg) *</span>
{diffPeso !== 0 && ( {diffPeso !== 0 && (
<span className="text-[10px] text-amber-400 font-bold">Alterado</span> <span className="text-[10px] text-amber-600 dark:text-amber-400 font-bold">Alterado</span>
)} )}
</Label> </Label>
<Input <Input
@@ -339,20 +337,20 @@ export function RevisaoPecaModal({
step="0.001" step="0.001"
value={formData.peso_unitario} value={formData.peso_unitario}
onChange={(e) => handleInputChange('peso_unitario', Number(e.target.value))} onChange={(e) => handleInputChange('peso_unitario', Number(e.target.value))}
className="font-mono text-sm mt-1 bg-slate-950 border-slate-700" className="font-mono text-sm mt-1 bg-background border-input text-foreground"
required required
/> />
</div> </div>
{/* Peso Total (calculado) */} {/* Peso Total (calculado) */}
<div> <div>
<Label className="text-xs text-slate-300">Peso Total (kg)</Label> <Label className="text-xs text-foreground">Peso Total (kg)</Label>
<Input <Input
type="number" type="number"
value={formData.peso_total} value={formData.peso_total}
readOnly readOnly
disabled disabled
className="font-mono text-sm mt-1 bg-slate-900 border-slate-800 text-slate-400 cursor-not-allowed" className="font-mono text-sm mt-1 bg-muted border-border text-muted-foreground cursor-not-allowed"
/> />
</div> </div>
</div> </div>
@@ -360,67 +358,67 @@ export function RevisaoPecaModal({
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-3"> <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-3">
{/* Descrição */} {/* Descrição */}
<div className="md:col-span-2"> <div className="md:col-span-2">
<Label className="text-xs text-slate-300">Descrição da Peça</Label> <Label className="text-xs text-foreground">Descrição da Peça</Label>
<Input <Input
value={formData.descricao} value={formData.descricao}
onChange={(e) => handleInputChange('descricao', e.target.value)} onChange={(e) => handleInputChange('descricao', e.target.value)}
placeholder="Ex: Viga I, Pilar Tubular, Perfil Soldado..." placeholder="Ex: Viga I, Pilar Tubular, Perfil Soldado..."
className="text-sm mt-1 bg-slate-950 border-slate-700" className="text-sm mt-1 bg-background border-input text-foreground"
/> />
</div> </div>
{/* Fase / Etapa */} {/* Fase / Etapa */}
<div> <div>
<Label className="text-xs text-slate-300">Fase / Etapa</Label> <Label className="text-xs text-foreground">Fase / Etapa</Label>
<Input <Input
value={formData.etapa_fase} value={formData.etapa_fase}
onChange={(e) => handleInputChange('etapa_fase', e.target.value)} onChange={(e) => handleInputChange('etapa_fase', e.target.value)}
placeholder="Ex: 1, 2, Cobertura..." placeholder="Ex: 1, 2, Cobertura..."
className="text-sm mt-1 bg-slate-950 border-slate-700" className="text-sm mt-1 bg-background border-input text-foreground"
/> />
</div> </div>
{/* Comprimento */} {/* Comprimento */}
<div> <div>
<Label className="text-xs text-slate-300">Comprimento (mm)</Label> <Label className="text-xs text-foreground">Comprimento (mm)</Label>
<Input <Input
type="number" type="number"
value={formData.comprimento} value={formData.comprimento}
onChange={(e) => handleInputChange('comprimento', Number(e.target.value))} onChange={(e) => handleInputChange('comprimento', Number(e.target.value))}
placeholder="Ex: 6000" placeholder="Ex: 6000"
className="text-sm mt-1 bg-slate-950 border-slate-700 font-mono" className="text-sm mt-1 bg-background border-input text-foreground font-mono"
/> />
</div> </div>
</div> </div>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3"> <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
<div> <div>
<Label className="text-xs text-slate-300">Material / Aço</Label> <Label className="text-xs text-foreground">Material / Aço</Label>
<Input <Input
value={formData.material} value={formData.material}
onChange={(e) => handleInputChange('material', e.target.value)} onChange={(e) => handleInputChange('material', e.target.value)}
placeholder="Ex: ASTM A36, A572 GR50" placeholder="Ex: ASTM A36, A572 GR50"
className="text-sm mt-1 bg-slate-950 border-slate-700" className="text-sm mt-1 bg-background border-input text-foreground"
/> />
</div> </div>
<div> <div>
<Label className="text-xs text-slate-300">Perfil Principal</Label> <Label className="text-xs text-foreground">Perfil Principal</Label>
<Input <Input
value={formData.perfil_principal} value={formData.perfil_principal}
onChange={(e) => handleInputChange('perfil_principal', e.target.value)} onChange={(e) => handleInputChange('perfil_principal', e.target.value)}
placeholder="Ex: W250x32.7, RHS150x6.3" placeholder="Ex: W250x32.7, RHS150x6.3"
className="text-sm mt-1 bg-slate-950 border-slate-700" className="text-sm mt-1 bg-background border-input text-foreground"
/> />
</div> </div>
<div> <div>
<Label className="text-xs text-slate-300">Tratamento Superficial</Label> <Label className="text-xs text-foreground">Tratamento Superficial</Label>
<Input <Input
value={formData.tratamento_superficial} value={formData.tratamento_superficial}
onChange={(e) => handleInputChange('tratamento_superficial', e.target.value)} onChange={(e) => handleInputChange('tratamento_superficial', e.target.value)}
placeholder="Ex: Pintura Epóxi, Galvanizado" placeholder="Ex: Pintura Epóxi, Galvanizado"
className="text-sm mt-1 bg-slate-950 border-slate-700" className="text-sm mt-1 bg-background border-input text-foreground"
/> />
</div> </div>
</div> </div>
@@ -428,14 +426,14 @@ export function RevisaoPecaModal({
{/* CARD DE IMPACTO OPERACIONAL / REGRAS DE NEGÓCIO */} {/* CARD DE IMPACTO OPERACIONAL / REGRAS DE NEGÓCIO */}
{analise.camposAlterados.length > 0 && ( {analise.camposAlterados.length > 0 && (
<div className={`p-4 rounded-lg border ${ <div className={`p-4 rounded-lg border shadow-sm ${
tipoEfetivo === 'critica' tipoEfetivo === 'critica'
? 'bg-red-950/20 border-red-500/40 text-red-200' ? 'bg-red-500/10 border-red-500/30 text-red-900 dark:text-red-200'
: 'bg-blue-950/20 border-blue-500/40 text-blue-200' : 'bg-blue-500/10 border-blue-500/30 text-blue-900 dark:text-blue-200'
}`}> }`}>
<div className="flex items-start gap-3"> <div className="flex items-start gap-3">
<ShieldAlert className={`w-5 h-5 mt-0.5 shrink-0 ${ <ShieldAlert className={`w-5 h-5 mt-0.5 shrink-0 ${
tipoEfetivo === 'critica' ? 'text-red-400' : 'text-blue-400' tipoEfetivo === 'critica' ? 'text-red-600 dark:text-red-400' : 'text-blue-600 dark:text-blue-400'
}`} /> }`} />
<div className="space-y-2 text-xs"> <div className="space-y-2 text-xs">
<div className="font-bold uppercase tracking-wider"> <div className="font-bold uppercase tracking-wider">
@@ -446,7 +444,7 @@ export function RevisaoPecaModal({
<div className="space-y-1"> <div className="space-y-1">
{diffQtd > 0 && ( {diffQtd > 0 && (
<div className="flex items-center gap-1.5 text-emerald-400 font-medium"> <div className="flex items-center gap-1.5 text-emerald-700 dark:text-emerald-400 font-medium">
<TrendingUp className="w-4 h-4 shrink-0" /> <TrendingUp className="w-4 h-4 shrink-0" />
<span> <span>
<strong>Aumento de quantidade (+{diffQtd} un):</strong> A diferença excedente de {diffQtd} un nascerá automaticamente no 1º processo de fabricação (Corte/Detalhamento) para novos apontamentos. <strong>Aumento de quantidade (+{diffQtd} un):</strong> A diferença excedente de {diffQtd} un nascerá automaticamente no 1º processo de fabricação (Corte/Detalhamento) para novos apontamentos.
@@ -455,7 +453,7 @@ export function RevisaoPecaModal({
)} )}
{diffQtd < 0 && ( {diffQtd < 0 && (
<div className="flex items-center gap-1.5 text-rose-400 font-medium"> <div className="flex items-center gap-1.5 text-rose-700 dark:text-rose-400 font-medium">
<TrendingDown className="w-4 h-4 shrink-0" /> <TrendingDown className="w-4 h-4 shrink-0" />
<span> <span>
<strong>Redução de quantidade ({diffQtd} un):</strong> O novo total será de {formData.quantidade} un. Os processos que possuírem apontamentos superiores a {formData.quantidade} un serão revisados automaticamente para o novo teto. <strong>Redução de quantidade ({diffQtd} un):</strong> O novo total será de {formData.quantidade} un. Os processos que possuírem apontamentos superiores a {formData.quantidade} un serão revisados automaticamente para o novo teto.
@@ -464,7 +462,7 @@ export function RevisaoPecaModal({
)} )}
{formData.marca !== peca.marca && ( {formData.marca !== peca.marca && (
<div className="flex items-center gap-1.5 text-amber-300 font-medium"> <div className="flex items-center gap-1.5 text-amber-700 dark:text-amber-300 font-medium">
<ArrowRight className="w-4 h-4 shrink-0" /> <ArrowRight className="w-4 h-4 shrink-0" />
<span> <span>
<strong>Alteração de marca/código ({peca.marca} ➔ {formData.marca}):</strong> A rastreabilidade da peça será atualizada e preservada em apontamentos e romaneios de expedição. <strong>Alteração de marca/código ({peca.marca} ➔ {formData.marca}):</strong> A rastreabilidade da peça será atualizada e preservada em apontamentos e romaneios de expedição.
@@ -473,7 +471,7 @@ export function RevisaoPecaModal({
)} )}
{analise.detalhes.map((det, idx) => ( {analise.detalhes.map((det, idx) => (
<div key={idx} className="text-slate-300"> <div key={idx} className="text-foreground/80">
• {det} • {det}
</div> </div>
))} ))}
@@ -489,7 +487,7 @@ export function RevisaoPecaModal({
type="button" type="button"
variant="outline" variant="outline"
onClick={onClose} onClick={onClose}
className="border-slate-700 text-slate-300 hover:bg-slate-800" className="border-border text-foreground hover:bg-muted"
> >
Cancelar Cancelar
</Button> </Button>
@@ -497,7 +495,7 @@ export function RevisaoPecaModal({
<Button <Button
type="submit" type="submit"
disabled={loading || !motivo.trim() || analise.camposAlterados.length === 0} disabled={loading || !motivo.trim() || analise.camposAlterados.length === 0}
className="bg-amber-600 hover:bg-amber-500 text-white font-semibold flex items-center gap-2" className="bg-amber-600 hover:bg-amber-500 text-white font-semibold flex items-center gap-2 shadow-sm"
> >
<Save className="w-4 h-4" /> <Save className="w-4 h-4" />
{loading ? 'Processando Revisão...' : 'Salvar Revisão e Atualizar Peça'} {loading ? 'Processando Revisão...' : 'Salvar Revisão e Atualizar Peça'}
@@ -509,14 +507,14 @@ export function RevisaoPecaModal({
{/* ABA 2: HISTÓRICO DE REVISÕES */} {/* ABA 2: HISTÓRICO DE REVISÕES */}
<TabsContent value="historico" className="mt-4 space-y-3"> <TabsContent value="historico" className="mt-4 space-y-3">
{loadingHistorico ? ( {loadingHistorico ? (
<div className="p-8 text-center text-slate-400"> <div className="p-8 text-center text-muted-foreground">
Carregando histórico de revisões... Carregando histórico de revisões...
</div> </div>
) : historico.length === 0 ? ( ) : historico.length === 0 ? (
<div className="p-8 text-center border border-dashed border-slate-800 rounded-lg text-slate-400"> <div className="p-8 text-center border border-dashed border-border rounded-lg text-muted-foreground bg-card/50">
<History className="w-8 h-8 mx-auto mb-2 text-slate-600" /> <History className="w-8 h-8 mx-auto mb-2 text-muted-foreground/60" />
<p className="font-medium">Nenhuma revisão registrada para esta peça até o momento.</p> <p className="font-medium">Nenhuma revisão registrada para esta peça até o momento.</p>
<p className="text-xs text-slate-500 mt-1"> <p className="text-xs text-muted-foreground mt-1">
Ao realizar a primeira alteração pela aba &quot;Nova Revisão&quot;, o histórico completo será guardado aqui. Ao realizar a primeira alteração pela aba &quot;Nova Revisão&quot;, o histórico completo será guardado aqui.
</p> </p>
</div> </div>
@@ -525,23 +523,23 @@ export function RevisaoPecaModal({
{historico.map((rev) => ( {historico.map((rev) => (
<div <div
key={rev.id} key={rev.id}
className="p-4 rounded-lg bg-slate-900 border border-slate-800 hover:border-slate-700 transition-colors space-y-2.5" className="p-4 rounded-lg bg-card border border-border hover:border-primary/40 transition-colors space-y-2.5 shadow-sm"
> >
<div className="flex items-center justify-between flex-wrap gap-2"> <div className="flex items-center justify-between flex-wrap gap-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Badge variant="outline" className="font-mono font-bold bg-amber-500/10 text-amber-400 border-amber-400/40"> <Badge variant="outline" className="font-mono font-bold bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-400/40">
{rev.numero_revisao} {rev.numero_revisao}
</Badge> </Badge>
<Badge <Badge
className={`text-xs ${ className={`text-xs ${
rev.tipo_revisao === 'critica' rev.tipo_revisao === 'critica'
? 'bg-red-500/20 text-red-300 border-red-500/30' ? 'bg-red-500/15 text-red-600 dark:text-red-400 border border-red-500/30'
: 'bg-blue-500/20 text-blue-300 border-blue-500/30' : 'bg-blue-500/15 text-blue-600 dark:text-blue-400 border border-blue-500/30'
}`} }`}
> >
{rev.tipo_revisao === 'critica' ? 'Crítica' : 'Simples'} {rev.tipo_revisao === 'critica' ? 'Crítica' : 'Simples'}
</Badge> </Badge>
<span className="text-xs text-slate-400 flex items-center gap-1"> <span className="text-xs text-muted-foreground flex items-center gap-1">
<Clock className="w-3.5 h-3.5" /> <Clock className="w-3.5 h-3.5" />
{rev.data_revisao {rev.data_revisao
? format(new Date(rev.data_revisao), "dd/MM/yyyy 'às' HH:mm", { locale: ptBR }) ? format(new Date(rev.data_revisao), "dd/MM/yyyy 'às' HH:mm", { locale: ptBR })
@@ -549,27 +547,27 @@ export function RevisaoPecaModal({
</span> </span>
</div> </div>
<div className="text-xs text-slate-400 flex items-center gap-1.5"> <div className="text-xs text-muted-foreground flex items-center gap-1.5">
<User className="w-3.5 h-3.5 text-slate-500" /> <User className="w-3.5 h-3.5" />
<span>{rev.usuario_nome || rev.usuario_email || 'Usuário'}</span> <span>{rev.usuario_nome || rev.usuario_email || 'Usuário'}</span>
</div> </div>
</div> </div>
{/* Motivo */} {/* Motivo */}
<div className="text-sm font-medium text-slate-200"> <div className="text-sm font-medium text-foreground">
<strong>Motivo:</strong> {rev.descricao_motivo} <strong>Motivo:</strong> {rev.descricao_motivo}
</div> </div>
{rev.observacoes && ( {rev.observacoes && (
<div className="text-xs text-slate-400 italic"> <div className="text-xs text-muted-foreground italic">
<strong>Obs:</strong> {rev.observacoes} <strong>Obs:</strong> {rev.observacoes}
</div> </div>
)} )}
{/* Comparativo de Campos Alterados */} {/* Comparativo de Campos Alterados */}
{rev.campos_alterados && rev.campos_alterados.length > 0 && ( {rev.campos_alterados && rev.campos_alterados.length > 0 && (
<div className="p-2.5 rounded bg-slate-950/80 border border-slate-850 text-xs space-y-1"> <div className="p-2.5 rounded bg-muted/60 border border-border text-xs space-y-1">
<div className="font-semibold text-slate-400 text-[11px] uppercase tracking-wider mb-1"> <div className="font-semibold text-muted-foreground text-[11px] uppercase tracking-wider mb-1">
Modificações Realizadas: Modificações Realizadas:
</div> </div>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-2"> <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-2">
@@ -577,16 +575,16 @@ export function RevisaoPecaModal({
const ant = rev.dados_anteriores?.[campo]; const ant = rev.dados_anteriores?.[campo];
const nov = rev.dados_novos?.[campo]; const nov = rev.dados_novos?.[campo];
return ( return (
<div key={campo} className="p-1.5 rounded bg-slate-900 border border-slate-800"> <div key={campo} className="p-1.5 rounded bg-background border border-border">
<span className="text-slate-400 font-mono text-[10px] block uppercase"> <span className="text-muted-foreground font-mono text-[10px] block uppercase">
{campo} {campo}
</span> </span>
<div className="flex items-center gap-1.5 text-xs font-mono mt-0.5"> <div className="flex items-center gap-1.5 text-xs font-mono mt-0.5">
<span className="text-rose-400 line-through truncate max-w-[80px]"> <span className="text-rose-600 dark:text-rose-400 line-through truncate max-w-[80px]">
{String(ant ?? '-')} {String(ant ?? '-')}
</span> </span>
<ArrowRight className="w-3 h-3 text-slate-500 shrink-0" /> <ArrowRight className="w-3 h-3 text-muted-foreground shrink-0" />
<span className="text-emerald-400 font-bold truncate max-w-[80px]"> <span className="text-emerald-600 dark:text-emerald-400 font-bold truncate max-w-[80px]">
{String(nov ?? '-')} {String(nov ?? '-')}
</span> </span>
</div> </div>
@@ -599,8 +597,8 @@ export function RevisaoPecaModal({
{/* Impacto em Apontamentos */} {/* Impacto em Apontamentos */}
{rev.impacto_processos && rev.impacto_processos.resumo && rev.impacto_processos.resumo.length > 0 && ( {rev.impacto_processos && rev.impacto_processos.resumo && rev.impacto_processos.resumo.length > 0 && (
<div className="p-2 rounded bg-amber-950/20 border border-amber-900/40 text-[11px] text-amber-300/90 space-y-0.5"> <div className="p-2 rounded bg-amber-500/10 border border-amber-500/20 text-[11px] text-amber-800 dark:text-amber-300 space-y-0.5">
<div className="font-bold flex items-center gap-1 text-amber-400"> <div className="font-bold flex items-center gap-1 text-amber-600 dark:text-amber-400">
<AlertTriangle className="w-3 h-3" /> <AlertTriangle className="w-3 h-3" />
Ajustes de Produção Aplicados: Ajustes de Produção Aplicados:
</div> </div>
+3 -3
View File
@@ -102,10 +102,10 @@ export function TableRow({
e.stopPropagation(); e.stopPropagation();
onOpenRevisao?.(); onOpenRevisao?.();
}} }}
className="cursor-pointer inline-flex items-center gap-0.5 text-[10px] bg-amber-500/20 text-amber-400 hover:bg-amber-500/30 border border-amber-500/40 px-1.5 py-0.5 rounded-full font-bold transition-all shadow-sm animate-pulse" className="cursor-pointer inline-flex items-center gap-0.5 text-[10px] bg-amber-500/15 text-amber-700 dark:text-amber-400 hover:bg-amber-500/25 border border-amber-500/40 px-1.5 py-0.5 rounded-full font-bold transition-all shadow-sm animate-pulse"
title={`Peça possui ${peca.qtd_revisoes || 1} revisão(ões) registrada(s) (${peca.revisao_atual || 'Rev'}). Clique para consultar.`} title={`Peça possui ${peca.qtd_revisoes || 1} revisão(ões) registrada(s) (${peca.revisao_atual || 'Rev'}). Clique para consultar.`}
> >
<AlertTriangle className="h-2.5 w-2.5 text-amber-400" /> <AlertTriangle className="h-2.5 w-2.5 text-amber-600 dark:text-amber-400" />
<span>{peca.revisao_atual || '!'}</span> <span>{peca.revisao_atual || '!'}</span>
</button> </button>
)} )}
@@ -192,7 +192,7 @@ export function TableRow({
size="sm" size="sm"
onClick={onOpenRevisao} onClick={onOpenRevisao}
title="Gestão e Histórico de Revisões da Peça" title="Gestão e Histórico de Revisões da Peça"
className="h-6 w-6 p-0 text-amber-500 hover:text-amber-400 hover:bg-amber-950/40" className="h-6 w-6 p-0 text-amber-600 dark:text-amber-400 hover:text-amber-700 dark:hover:text-amber-300 hover:bg-amber-500/10"
> >
<FileText className="h-3 w-3" /> <FileText className="h-3 w-3" />
</Button> </Button>