fix some errors
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { api } from '@sgse-app/backend/convex/_generated/api';
|
||||
import type { Doc, Id } from '@sgse-app/backend/convex/_generated/dataModel';
|
||||
import type { Doc } from '@sgse-app/backend/convex/_generated/dataModel';
|
||||
import { useConvexClient, useQuery } from 'convex-svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { resolve } from '$app/paths';
|
||||
@@ -14,8 +14,7 @@
|
||||
Trash2,
|
||||
Info,
|
||||
X,
|
||||
Filter,
|
||||
Barcode
|
||||
Filter
|
||||
} from 'lucide-svelte';
|
||||
import BarcodeScanner from '$lib/components/almoxarifado/BarcodeScanner.svelte';
|
||||
|
||||
@@ -36,7 +35,20 @@
|
||||
return [];
|
||||
}
|
||||
});
|
||||
let filtered = $state<Array<Doc<'materiais'>>>([]);
|
||||
let filtered = $derived.by(() => {
|
||||
const busca = filtroBusca.toLowerCase();
|
||||
return materiais.filter((m) => {
|
||||
const okBusca =
|
||||
!busca ||
|
||||
m.codigo.toLowerCase().includes(busca) ||
|
||||
m.nome.toLowerCase().includes(busca) ||
|
||||
(m.codigoBarras && m.codigoBarras.toLowerCase().includes(busca));
|
||||
const okCategoria = !filtroCategoria || m.categoria === filtroCategoria;
|
||||
const okAtivo = filtroAtivo === '' || m.ativo === filtroAtivo;
|
||||
const okEstoqueBaixo = !filtroEstoqueBaixo || m.estoqueAtual <= m.estoqueMinimo;
|
||||
return okBusca && okCategoria && okAtivo && okEstoqueBaixo;
|
||||
});
|
||||
});
|
||||
let filtroBusca = $state('');
|
||||
let filtroCategoria = $state('');
|
||||
let filtroAtivo = $state<boolean | ''>('');
|
||||
@@ -59,21 +71,6 @@
|
||||
Array.from(new Set(materiais.map((m) => m.categoria).filter(Boolean))).sort()
|
||||
);
|
||||
|
||||
function applyFilters() {
|
||||
const busca = filtroBusca.toLowerCase();
|
||||
filtered = materiais.filter((m) => {
|
||||
const okBusca =
|
||||
!busca ||
|
||||
m.codigo.toLowerCase().includes(busca) ||
|
||||
m.nome.toLowerCase().includes(busca) ||
|
||||
(m.codigoBarras && m.codigoBarras.toLowerCase().includes(busca));
|
||||
const okCategoria = !filtroCategoria || m.categoria === filtroCategoria;
|
||||
const okAtivo = filtroAtivo === '' || m.ativo === filtroAtivo;
|
||||
const okEstoqueBaixo = !filtroEstoqueBaixo || m.estoqueAtual <= m.estoqueMinimo;
|
||||
return okBusca && okCategoria && okAtivo && okEstoqueBaixo;
|
||||
});
|
||||
}
|
||||
|
||||
async function buscarPorCodigoBarras(codigo: string) {
|
||||
if (!codigo.trim() || codigo.trim().length < 8) {
|
||||
return;
|
||||
@@ -102,14 +99,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Aplicar filtros sempre que materiais ou filtros mudarem
|
||||
$effect(() => {
|
||||
// Acessar materiais para criar dependência reativa
|
||||
const _ = materiais;
|
||||
// Aplicar filtros
|
||||
applyFilters();
|
||||
});
|
||||
|
||||
function navCadastro() {
|
||||
goto(resolve('/almoxarifado/materiais/cadastro'));
|
||||
}
|
||||
@@ -179,9 +168,6 @@
|
||||
try {
|
||||
excluindo = true;
|
||||
|
||||
// Remover item da lista localmente imediatamente (otimistic update)
|
||||
filtered = filtered.filter((m) => m._id !== materialId);
|
||||
|
||||
await client.mutation(api.almoxarifado.deletarMaterial, {
|
||||
id: materialId
|
||||
});
|
||||
@@ -197,9 +183,6 @@
|
||||
notice = null;
|
||||
}, 5000);
|
||||
} catch (error: unknown) {
|
||||
// Se houver erro, recarregar a lista para garantir consistência
|
||||
applyFilters();
|
||||
|
||||
const message = error instanceof Error ? error.message : 'Erro ao excluir material';
|
||||
|
||||
// Determinar tipo de erro e criar mensagem mais clara
|
||||
@@ -287,13 +270,13 @@
|
||||
<div class="flex flex-col items-start justify-between gap-4 sm:flex-row sm:items-center">
|
||||
<div class="flex items-center gap-4">
|
||||
<div
|
||||
class="from-primary/20 via-primary/10 to-primary/5 border-primary/20 rounded-2xl border bg-gradient-to-br p-4 shadow-lg"
|
||||
class="from-primary/20 via-primary/10 to-primary/5 border-primary/20 rounded-2xl border bg-linear-to-br p-4 shadow-lg"
|
||||
>
|
||||
<Package class="text-primary h-10 w-10" strokeWidth={2.5} />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h1
|
||||
class="from-primary to-primary/70 bg-gradient-to-r bg-clip-text text-4xl font-bold tracking-tight text-transparent"
|
||||
class="from-primary to-primary/70 bg-linear-to-r bg-clip-text text-4xl font-bold tracking-tight text-transparent"
|
||||
>
|
||||
Materiais
|
||||
</h1>
|
||||
@@ -337,7 +320,7 @@
|
||||
</div>
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-4">
|
||||
<div class="form-control">
|
||||
<label class="label pb-2">
|
||||
<label class="label pb-2" for="busca-material">
|
||||
<span class="label-text flex items-center gap-2 font-semibold">
|
||||
<Search class="h-4 w-4" />
|
||||
Buscar
|
||||
@@ -346,6 +329,7 @@
|
||||
<div class="relative">
|
||||
<Search class="text-base-content/40 absolute top-1/2 left-3 h-5 w-5 -translate-y-1/2" />
|
||||
<input
|
||||
id="busca-material"
|
||||
type="text"
|
||||
placeholder="Código, nome ou código de barras..."
|
||||
class="input input-bordered focus:input-primary h-12 w-full pl-10 transition-colors {buscandoPorCodigoBarras
|
||||
@@ -367,25 +351,27 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label pb-2">
|
||||
<label class="label pb-2" for="filtro-categoria">
|
||||
<span class="label-text font-semibold">Categoria</span>
|
||||
</label>
|
||||
<select
|
||||
id="filtro-categoria"
|
||||
class="select select-bordered focus:select-primary h-12 w-full transition-colors"
|
||||
bind:value={filtroCategoria}
|
||||
>
|
||||
<option value="">Todas as categorias</option>
|
||||
{#each categorias as cat}
|
||||
{#each categorias as cat (cat)}
|
||||
<option value={cat}>{cat}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label pb-2">
|
||||
<label class="label pb-2" for="filtro-status">
|
||||
<span class="label-text font-semibold">Status</span>
|
||||
</label>
|
||||
<select
|
||||
id="filtro-status"
|
||||
class="select select-bordered focus:select-primary h-12 w-full transition-colors"
|
||||
bind:value={filtroAtivo}
|
||||
>
|
||||
@@ -396,13 +382,14 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label pb-2">
|
||||
<label class="label pb-2" for="filtro-estoque-baixo">
|
||||
<span class="label-text font-semibold">Filtros Adicionais</span>
|
||||
</label>
|
||||
<label
|
||||
class="label border-base-300 hover:bg-base-200 cursor-pointer justify-start gap-3 rounded-lg border p-3 transition-colors"
|
||||
>
|
||||
<input
|
||||
id="filtro-estoque-baixo"
|
||||
type="checkbox"
|
||||
class="checkbox checkbox-primary"
|
||||
bind:checked={filtroEstoqueBaixo}
|
||||
@@ -453,8 +440,8 @@
|
||||
</td>
|
||||
</tr>
|
||||
{:else}
|
||||
{#each filtered as material}
|
||||
<tr class="hover:bg-base-200/50 transition-colors" key={material._id}>
|
||||
{#each filtered as material (material._id)}
|
||||
<tr class="hover:bg-base-200/50 transition-colors">
|
||||
<td>
|
||||
<div class="text-primary font-mono font-bold">{material.codigo}</div>
|
||||
</td>
|
||||
@@ -499,7 +486,8 @@
|
||||
<button
|
||||
class="btn btn-sm btn-ghost hover:btn-primary transition-all"
|
||||
title="Visualizar detalhes"
|
||||
onclick={() => goto(resolve('/almoxarifado/materiais/' + material._id))}
|
||||
onclick={() =>
|
||||
goto(resolve('/almoxarifado/materiais/' + material._id) as any)}
|
||||
>
|
||||
<Eye class="h-4 w-4" />
|
||||
</button>
|
||||
@@ -507,7 +495,9 @@
|
||||
class="btn btn-sm btn-ghost hover:btn-info transition-all"
|
||||
title="Editar material"
|
||||
onclick={() =>
|
||||
goto(resolve('/almoxarifado/materiais/' + material._id + '/editar'))}
|
||||
goto(
|
||||
resolve('/almoxarifado/materiais/' + material._id + '/editar') as any
|
||||
)}
|
||||
>
|
||||
<Edit class="h-4 w-4" />
|
||||
</button>
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { api } from '@sgse-app/backend/convex/_generated/api';
|
||||
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
|
||||
import type { FunctionReturnType } from 'convex/server';
|
||||
import { useConvexClient, useQuery } from 'convex-svelte';
|
||||
import { resolve } from '$app/paths';
|
||||
import { ArrowLeftRight, ArrowDown, ArrowUp, Settings, History, Package, FileText, User, Building2, AlertCircle } from 'lucide-svelte';
|
||||
import {
|
||||
ArrowLeftRight,
|
||||
ArrowDown,
|
||||
ArrowUp,
|
||||
Settings,
|
||||
History,
|
||||
Package,
|
||||
FileText,
|
||||
User,
|
||||
Building2,
|
||||
AlertCircle
|
||||
} from 'lucide-svelte';
|
||||
import { SvelteMap } from 'svelte/reactivity';
|
||||
import BarcodeScanner from '$lib/components/almoxarifado/BarcodeScanner.svelte';
|
||||
|
||||
const client = useConvexClient();
|
||||
@@ -44,20 +57,26 @@
|
||||
const setoresQuery = useQuery(api.setores.list, {});
|
||||
const movimentacoesQuery = useQuery(api.almoxarifado.listarMovimentacoesComHistorico, {});
|
||||
|
||||
type FuncionariosQueryResult = FunctionReturnType<typeof api.funcionarios.getAll>;
|
||||
type Funcionario = FuncionariosQueryResult[number];
|
||||
|
||||
// Criar mapa de funcionários para lookup eficiente
|
||||
const funcionariosMap = $derived.by(() => {
|
||||
if (!funcionariosQuery.data) return new Map();
|
||||
const map = new Map();
|
||||
const map = new SvelteMap<Id<'funcionarios'>, Funcionario>();
|
||||
if (!funcionariosQuery.data) return map;
|
||||
for (const funcionario of funcionariosQuery.data) {
|
||||
map.set(funcionario._id, funcionario);
|
||||
}
|
||||
return map;
|
||||
});
|
||||
|
||||
type MateriaisQueryResult = FunctionReturnType<typeof api.almoxarifado.listarMateriais>;
|
||||
type Material = MateriaisQueryResult[number];
|
||||
|
||||
// Criar mapa de materiais para lookup eficiente
|
||||
const materiaisMap = $derived.by(() => {
|
||||
if (!materiaisQuery.data) return new Map();
|
||||
const map = new Map();
|
||||
const map = new SvelteMap<Id<'materiais'>, Material>();
|
||||
if (!materiaisQuery.data) return map;
|
||||
for (const material of materiaisQuery.data) {
|
||||
map.set(material._id, material);
|
||||
}
|
||||
@@ -170,9 +189,7 @@
|
||||
materialId: saidaMaterialId as Id<'materiais'>,
|
||||
quantidade: saidaQuantidade,
|
||||
motivo: saidaMotivo.trim(),
|
||||
funcionarioId: saidaFuncionarioId
|
||||
? (saidaFuncionarioId as Id<'funcionarios'>)
|
||||
: undefined,
|
||||
funcionarioId: saidaFuncionarioId ? (saidaFuncionarioId as Id<'funcionarios'>) : undefined,
|
||||
setorId: saidaSetorId ? (saidaSetorId as Id<'setores'>) : undefined,
|
||||
observacoes: saidaObservacoes.trim() || undefined
|
||||
});
|
||||
@@ -235,9 +252,7 @@
|
||||
<div class="breadcrumbs mb-6 text-sm">
|
||||
<ul>
|
||||
<li>
|
||||
<a href={resolve('/almoxarifado')} class="text-primary hover:underline"
|
||||
>Almoxarifado</a
|
||||
>
|
||||
<a href={resolve('/almoxarifado')} class="text-primary hover:underline">Almoxarifado</a>
|
||||
</li>
|
||||
<li>Movimentações</li>
|
||||
</ul>
|
||||
@@ -246,14 +261,20 @@
|
||||
<!-- Cabeçalho -->
|
||||
<div class="mb-8">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="rounded-2xl bg-gradient-to-br from-info/20 via-info/10 to-info/5 p-4 shadow-lg border border-info/20">
|
||||
<ArrowLeftRight class="h-10 w-10 text-info" strokeWidth={2.5} />
|
||||
<div
|
||||
class="from-info/20 via-info/10 to-info/5 border-info/20 rounded-2xl border bg-linear-to-br p-4 shadow-lg"
|
||||
>
|
||||
<ArrowLeftRight class="text-info h-10 w-10" strokeWidth={2.5} />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h1 class="text-4xl font-bold tracking-tight bg-gradient-to-r from-info to-info/70 bg-clip-text text-transparent">
|
||||
<h1
|
||||
class="from-info to-info/70 bg-linear-to-r bg-clip-text text-4xl font-bold tracking-tight text-transparent"
|
||||
>
|
||||
Movimentações de Estoque
|
||||
</h1>
|
||||
<p class="text-base-content/70 text-lg mt-1">Registre entradas, saídas e ajustes de estoque do almoxarifado</p>
|
||||
<p class="text-base-content/70 mt-1 text-lg">
|
||||
Registre entradas, saídas e ajustes de estoque do almoxarifado
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -266,50 +287,55 @@
|
||||
{/if}
|
||||
|
||||
<!-- Abas -->
|
||||
<div class="tabs tabs-boxed mb-8 bg-base-200 shadow-lg rounded-xl p-1">
|
||||
<div class="tabs tabs-boxed bg-base-200 mb-8 rounded-xl p-1 shadow-lg">
|
||||
<button
|
||||
class="tab {abaAtiva === 'entrada' ? 'tab-active' : ''} transition-all font-semibold"
|
||||
class="tab {abaAtiva === 'entrada' ? 'tab-active' : ''} font-semibold transition-all"
|
||||
onclick={() => (abaAtiva = 'entrada')}
|
||||
>
|
||||
<ArrowDown class="h-5 w-5 mr-2" />
|
||||
<ArrowDown class="mr-2 h-5 w-5" />
|
||||
Entrada
|
||||
</button>
|
||||
<button
|
||||
class="tab {abaAtiva === 'saida' ? 'tab-active' : ''} transition-all font-semibold"
|
||||
class="tab {abaAtiva === 'saida' ? 'tab-active' : ''} font-semibold transition-all"
|
||||
onclick={() => (abaAtiva = 'saida')}
|
||||
>
|
||||
<ArrowUp class="h-5 w-5 mr-2" />
|
||||
<ArrowUp class="mr-2 h-5 w-5" />
|
||||
Saída
|
||||
</button>
|
||||
<button
|
||||
class="tab {abaAtiva === 'ajuste' ? 'tab-active' : ''} transition-all font-semibold"
|
||||
class="tab {abaAtiva === 'ajuste' ? 'tab-active' : ''} font-semibold transition-all"
|
||||
onclick={() => (abaAtiva = 'ajuste')}
|
||||
>
|
||||
<Settings class="h-5 w-5 mr-2" />
|
||||
<Settings class="mr-2 h-5 w-5" />
|
||||
Ajuste
|
||||
</button>
|
||||
<button
|
||||
class="tab {abaAtiva === 'historico' ? 'tab-active' : ''} transition-all font-semibold"
|
||||
class="tab {abaAtiva === 'historico' ? 'tab-active' : ''} font-semibold transition-all"
|
||||
onclick={() => (abaAtiva = 'historico')}
|
||||
>
|
||||
<History class="h-5 w-5 mr-2" />
|
||||
<History class="mr-2 h-5 w-5" />
|
||||
Histórico
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Conteúdo das Abas -->
|
||||
{#if abaAtiva === 'entrada'}
|
||||
<div class="card bg-base-100 border border-base-300 shadow-2xl">
|
||||
<div class="card bg-base-100 border-base-300 border shadow-2xl">
|
||||
<div class="card-body p-8">
|
||||
<div class="mb-8 flex items-center gap-3 border-b-2 border-success/20 pb-4">
|
||||
<div class="rounded-lg bg-success/10 p-2.5">
|
||||
<ArrowDown class="h-6 w-6 text-success" strokeWidth={2.5} />
|
||||
<div class="border-success/20 mb-8 flex items-center gap-3 border-b-2 pb-4">
|
||||
<div class="bg-success/10 rounded-lg p-2.5">
|
||||
<ArrowDown class="text-success h-6 w-6" strokeWidth={2.5} />
|
||||
</div>
|
||||
<h2 class="text-2xl font-bold text-base-content">Registrar Entrada de Material</h2>
|
||||
<h2 class="text-base-content text-2xl font-bold">Registrar Entrada de Material</h2>
|
||||
</div>
|
||||
<form onsubmit={(e) => { e.preventDefault(); registrarEntrada(); }}>
|
||||
<form
|
||||
onsubmit={(e) => {
|
||||
e.preventDefault();
|
||||
registrarEntrada();
|
||||
}}
|
||||
>
|
||||
<!-- Leitor de Código de Barras -->
|
||||
<div class="mb-6 rounded-xl border border-base-300 bg-base-200/50 p-4">
|
||||
<div class="border-base-300 bg-base-200/50 mb-6 rounded-xl border p-4">
|
||||
<BarcodeScanner
|
||||
enabled={entradaScannerEnabled}
|
||||
onScan={buscarMaterialPorCodigoBarrasEntrada}
|
||||
@@ -320,8 +346,8 @@
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||
<!-- Material -->
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label pb-2">
|
||||
<span class="label-text font-semibold flex items-center gap-2">
|
||||
<label for="entradaMaterialId" class="label pb-2">
|
||||
<span class="label-text flex items-center gap-2 font-semibold">
|
||||
<Package class="h-4 w-4" />
|
||||
Material <span class="text-error">*</span>
|
||||
{#if entradaBuscandoMaterial}
|
||||
@@ -329,17 +355,24 @@
|
||||
{/if}
|
||||
</span>
|
||||
</label>
|
||||
<select class="select select-bordered w-full focus:select-primary transition-colors h-12 {entradaBuscandoMaterial ? 'input-info' : ''}" bind:value={entradaMaterialId} required>
|
||||
<select
|
||||
id="entradaMaterialId"
|
||||
class="select select-bordered focus:select-primary h-12 w-full transition-colors {entradaBuscandoMaterial
|
||||
? 'input-info'
|
||||
: ''}"
|
||||
bind:value={entradaMaterialId}
|
||||
required
|
||||
>
|
||||
<option value="">Selecione um material</option>
|
||||
{#if materiaisQuery.data}
|
||||
{#each materiaisQuery.data as material}
|
||||
{#each materiaisQuery.data as material (material._id)}
|
||||
<option value={material._id}>
|
||||
{material.codigo} - {material.nome} (Estoque: {material.estoqueAtual}{material.unidadeMedida})
|
||||
</option>
|
||||
{/each}
|
||||
{/if}
|
||||
</select>
|
||||
<label class="label pt-1">
|
||||
<div class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60">
|
||||
{#if entradaBuscandoMaterial}
|
||||
<span class="text-info">Buscando material...</span>
|
||||
@@ -347,17 +380,20 @@
|
||||
Selecione manualmente ou use o leitor de código de barras acima
|
||||
{/if}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quantidade -->
|
||||
<div class="form-control">
|
||||
<label class="label pb-2">
|
||||
<span class="label-text font-semibold">Quantidade <span class="text-error">*</span></span>
|
||||
<label for="entradaQuantidade" class="label pb-2">
|
||||
<span class="label-text font-semibold"
|
||||
>Quantidade <span class="text-error">*</span></span
|
||||
>
|
||||
</label>
|
||||
<input
|
||||
id="entradaQuantidade"
|
||||
type="number"
|
||||
class="input input-bordered w-full focus:input-primary transition-colors h-12"
|
||||
class="input input-bordered focus:input-primary h-12 w-full transition-colors"
|
||||
min="1"
|
||||
step="1"
|
||||
bind:value={entradaQuantidade}
|
||||
@@ -372,54 +408,65 @@
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<label class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60">Quantidade a ser adicionada ao estoque</span>
|
||||
</label>
|
||||
<div class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60"
|
||||
>Quantidade a ser adicionada ao estoque</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Documento -->
|
||||
<div class="form-control">
|
||||
<label class="label pb-2">
|
||||
<span class="label-text font-semibold flex items-center gap-2">
|
||||
<label for="entradaDocumento" class="label pb-2">
|
||||
<span class="label-text flex items-center gap-2 font-semibold">
|
||||
<FileText class="h-4 w-4" />
|
||||
Documento
|
||||
</span>
|
||||
</label>
|
||||
<input
|
||||
id="entradaDocumento"
|
||||
type="text"
|
||||
class="input input-bordered w-full focus:input-primary transition-colors h-12"
|
||||
class="input input-bordered focus:input-primary h-12 w-full transition-colors"
|
||||
placeholder="Número da nota fiscal"
|
||||
bind:value={entradaDocumento}
|
||||
/>
|
||||
<label class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60">NF, nota fiscal ou documento relacionado</span>
|
||||
</label>
|
||||
<div class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60"
|
||||
>NF, nota fiscal ou documento relacionado</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Motivo -->
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label pb-2">
|
||||
<span class="label-text font-semibold">Motivo <span class="text-error">*</span></span>
|
||||
<label for="entradaMotivo" class="label pb-2">
|
||||
<span class="label-text font-semibold"
|
||||
>Motivo <span class="text-error">*</span></span
|
||||
>
|
||||
</label>
|
||||
<input
|
||||
id="entradaMotivo"
|
||||
type="text"
|
||||
class="input input-bordered w-full focus:input-primary transition-colors h-12"
|
||||
class="input input-bordered focus:input-primary h-12 w-full transition-colors"
|
||||
placeholder="Ex: Compra, Doação, Devolução"
|
||||
bind:value={entradaMotivo}
|
||||
required
|
||||
/>
|
||||
<label class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60">Razão da entrada do material no estoque</span>
|
||||
</label>
|
||||
<div class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60"
|
||||
>Razão da entrada do material no estoque</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Observações -->
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label pb-2">
|
||||
<label for="entradaObservacoes" class="label pb-2">
|
||||
<span class="label-text font-semibold">Observações</span>
|
||||
</label>
|
||||
<textarea
|
||||
class="textarea textarea-bordered w-full focus:textarea-primary transition-colors min-h-[100px]"
|
||||
id="entradaObservacoes"
|
||||
class="textarea textarea-bordered focus:textarea-primary min-h-[100px] w-full transition-colors"
|
||||
placeholder="Observações adicionais (opcional)"
|
||||
bind:value={entradaObservacoes}
|
||||
rows="3"
|
||||
@@ -427,8 +474,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-actions mt-8 justify-end gap-4 border-t-2 border-base-300 pt-6">
|
||||
<button type="submit" class="btn btn-success btn-lg min-w-[180px] shadow-lg hover:shadow-xl transition-all" disabled={entradaLoading}>
|
||||
<div class="card-actions border-base-300 mt-8 justify-end gap-4 border-t-2 pt-6">
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-success btn-lg min-w-[180px] shadow-lg transition-all hover:shadow-xl"
|
||||
disabled={entradaLoading}
|
||||
>
|
||||
{#if entradaLoading}
|
||||
<span class="loading loading-spinner loading-sm"></span>
|
||||
Registrando...
|
||||
@@ -442,17 +493,22 @@
|
||||
</div>
|
||||
</div>
|
||||
{:else if abaAtiva === 'saida'}
|
||||
<div class="card bg-base-100 border border-base-300 shadow-2xl">
|
||||
<div class="card bg-base-100 border-base-300 border shadow-2xl">
|
||||
<div class="card-body p-8">
|
||||
<div class="mb-8 flex items-center gap-3 border-b-2 border-error/20 pb-4">
|
||||
<div class="rounded-lg bg-error/10 p-2.5">
|
||||
<ArrowUp class="h-6 w-6 text-error" strokeWidth={2.5} />
|
||||
<div class="border-error/20 mb-8 flex items-center gap-3 border-b-2 pb-4">
|
||||
<div class="bg-error/10 rounded-lg p-2.5">
|
||||
<ArrowUp class="text-error h-6 w-6" strokeWidth={2.5} />
|
||||
</div>
|
||||
<h2 class="text-2xl font-bold text-base-content">Registrar Saída de Material</h2>
|
||||
<h2 class="text-base-content text-2xl font-bold">Registrar Saída de Material</h2>
|
||||
</div>
|
||||
<form onsubmit={(e) => { e.preventDefault(); registrarSaida(); }}>
|
||||
<form
|
||||
onsubmit={(e) => {
|
||||
e.preventDefault();
|
||||
registrarSaida();
|
||||
}}
|
||||
>
|
||||
<!-- Leitor de Código de Barras -->
|
||||
<div class="mb-6 rounded-xl border border-base-300 bg-base-200/50 p-4">
|
||||
<div class="border-base-300 bg-base-200/50 mb-6 rounded-xl border p-4">
|
||||
<BarcodeScanner
|
||||
enabled={saidaScannerEnabled}
|
||||
onScan={buscarMaterialPorCodigoBarrasSaida}
|
||||
@@ -463,8 +519,8 @@
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||
<!-- Material -->
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label pb-2">
|
||||
<span class="label-text font-semibold flex items-center gap-2">
|
||||
<label for="saidaMaterialId" class="label pb-2">
|
||||
<span class="label-text flex items-center gap-2 font-semibold">
|
||||
<Package class="h-4 w-4" />
|
||||
Material <span class="text-error">*</span>
|
||||
{#if saidaBuscandoMaterial}
|
||||
@@ -472,17 +528,24 @@
|
||||
{/if}
|
||||
</span>
|
||||
</label>
|
||||
<select class="select select-bordered w-full focus:select-primary transition-colors h-12 {saidaBuscandoMaterial ? 'input-info' : ''}" bind:value={saidaMaterialId} required>
|
||||
<select
|
||||
id="saidaMaterialId"
|
||||
class="select select-bordered focus:select-primary h-12 w-full transition-colors {saidaBuscandoMaterial
|
||||
? 'input-info'
|
||||
: ''}"
|
||||
bind:value={saidaMaterialId}
|
||||
required
|
||||
>
|
||||
<option value="">Selecione um material</option>
|
||||
{#if materiaisQuery.data}
|
||||
{#each materiaisQuery.data as material}
|
||||
{#each materiaisQuery.data as material (material._id)}
|
||||
<option value={material._id}>
|
||||
{material.codigo} - {material.nome} (Estoque: {material.estoqueAtual}{material.unidadeMedida})
|
||||
</option>
|
||||
{/each}
|
||||
{/if}
|
||||
</select>
|
||||
<label class="label pt-1">
|
||||
<div class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60">
|
||||
{#if saidaBuscandoMaterial}
|
||||
<span class="text-info">Buscando material...</span>
|
||||
@@ -490,17 +553,20 @@
|
||||
Selecione manualmente ou use o leitor de código de barras acima
|
||||
{/if}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quantidade -->
|
||||
<div class="form-control">
|
||||
<label class="label pb-2">
|
||||
<span class="label-text font-semibold">Quantidade <span class="text-error">*</span></span>
|
||||
<label for="saidaQuantidade" class="label pb-2">
|
||||
<span class="label-text font-semibold"
|
||||
>Quantidade <span class="text-error">*</span></span
|
||||
>
|
||||
</label>
|
||||
<input
|
||||
id="saidaQuantidade"
|
||||
type="number"
|
||||
class="input input-bordered w-full focus:input-primary transition-colors h-12"
|
||||
class="input input-bordered focus:input-primary h-12 w-full transition-colors"
|
||||
min="1"
|
||||
step="1"
|
||||
bind:value={saidaQuantidade}
|
||||
@@ -515,77 +581,97 @@
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<label class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60">Quantidade a ser retirada do estoque</span>
|
||||
</label>
|
||||
<div class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60"
|
||||
>Quantidade a ser retirada do estoque</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Funcionário -->
|
||||
<div class="form-control">
|
||||
<label class="label pb-2">
|
||||
<span class="label-text font-semibold flex items-center gap-2">
|
||||
<label for="saidaFuncionarioId" class="label pb-2">
|
||||
<span class="label-text flex items-center gap-2 font-semibold">
|
||||
<User class="h-4 w-4" />
|
||||
Funcionário
|
||||
</span>
|
||||
</label>
|
||||
<select class="select select-bordered w-full focus:select-primary transition-colors h-12" bind:value={saidaFuncionarioId}>
|
||||
<select
|
||||
id="saidaFuncionarioId"
|
||||
class="select select-bordered focus:select-primary h-12 w-full transition-colors"
|
||||
bind:value={saidaFuncionarioId}
|
||||
>
|
||||
<option value="">Selecione (opcional)</option>
|
||||
{#if funcionariosQuery.data}
|
||||
{#each funcionariosQuery.data as funcionario}
|
||||
{#each funcionariosQuery.data as funcionario (funcionario._id)}
|
||||
<option value={funcionario._id}>{funcionario.nome}</option>
|
||||
{/each}
|
||||
{/if}
|
||||
</select>
|
||||
<label class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60">Funcionário que receberá o material</span>
|
||||
</label>
|
||||
<div class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60"
|
||||
>Funcionário que receberá o material</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Setor -->
|
||||
<div class="form-control">
|
||||
<label class="label pb-2">
|
||||
<span class="label-text font-semibold flex items-center gap-2">
|
||||
<label for="saidaSetorId" class="label pb-2">
|
||||
<span class="label-text flex items-center gap-2 font-semibold">
|
||||
<Building2 class="h-4 w-4" />
|
||||
Setor
|
||||
</span>
|
||||
</label>
|
||||
<select class="select select-bordered w-full focus:select-primary transition-colors h-12" bind:value={saidaSetorId}>
|
||||
<select
|
||||
id="saidaSetorId"
|
||||
class="select select-bordered focus:select-primary h-12 w-full transition-colors"
|
||||
bind:value={saidaSetorId}
|
||||
>
|
||||
<option value="">Selecione (opcional)</option>
|
||||
{#if setoresQuery.data}
|
||||
{#each setoresQuery.data as setor}
|
||||
{#each setoresQuery.data as setor (setor._id)}
|
||||
<option value={setor._id}>{setor.nome}</option>
|
||||
{/each}
|
||||
{/if}
|
||||
</select>
|
||||
<label class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60">Setor que receberá o material</span>
|
||||
</label>
|
||||
<div class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60"
|
||||
>Setor que receberá o material</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Motivo -->
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label pb-2">
|
||||
<span class="label-text font-semibold">Motivo <span class="text-error">*</span></span>
|
||||
<label for="saidaMotivo" class="label pb-2">
|
||||
<span class="label-text font-semibold"
|
||||
>Motivo <span class="text-error">*</span></span
|
||||
>
|
||||
</label>
|
||||
<input
|
||||
id="saidaMotivo"
|
||||
type="text"
|
||||
class="input input-bordered w-full focus:input-primary transition-colors h-12"
|
||||
class="input input-bordered focus:input-primary h-12 w-full transition-colors"
|
||||
placeholder="Ex: Uso interno, Empréstimo, Descarte"
|
||||
bind:value={saidaMotivo}
|
||||
required
|
||||
/>
|
||||
<label class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60">Razão da saída do material do estoque</span>
|
||||
</label>
|
||||
<div class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60"
|
||||
>Razão da saída do material do estoque</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Observações -->
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label pb-2">
|
||||
<label for="saidaObservacoes" class="label pb-2">
|
||||
<span class="label-text font-semibold">Observações</span>
|
||||
</label>
|
||||
<textarea
|
||||
class="textarea textarea-bordered w-full focus:textarea-primary transition-colors min-h-[100px]"
|
||||
id="saidaObservacoes"
|
||||
class="textarea textarea-bordered focus:textarea-primary min-h-[100px] w-full transition-colors"
|
||||
placeholder="Observações adicionais (opcional)"
|
||||
bind:value={saidaObservacoes}
|
||||
rows="3"
|
||||
@@ -593,8 +679,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-actions mt-8 justify-end gap-4 border-t-2 border-base-300 pt-6">
|
||||
<button type="submit" class="btn btn-error btn-lg min-w-[180px] shadow-lg hover:shadow-xl transition-all" disabled={saidaLoading}>
|
||||
<div class="card-actions border-base-300 mt-8 justify-end gap-4 border-t-2 pt-6">
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-error btn-lg min-w-[180px] shadow-lg transition-all hover:shadow-xl"
|
||||
disabled={saidaLoading}
|
||||
>
|
||||
{#if saidaLoading}
|
||||
<span class="loading loading-spinner loading-sm"></span>
|
||||
Registrando...
|
||||
@@ -608,32 +698,45 @@
|
||||
</div>
|
||||
</div>
|
||||
{:else if abaAtiva === 'ajuste'}
|
||||
<div class="card bg-base-100 border border-base-300 shadow-2xl">
|
||||
<div class="card bg-base-100 border-base-300 border shadow-2xl">
|
||||
<div class="card-body p-8">
|
||||
<div class="mb-8 flex items-center gap-3 border-b-2 border-warning/20 pb-4">
|
||||
<div class="rounded-lg bg-warning/10 p-2.5">
|
||||
<Settings class="h-6 w-6 text-warning" strokeWidth={2.5} />
|
||||
<div class="border-warning/20 mb-8 flex items-center gap-3 border-b-2 pb-4">
|
||||
<div class="bg-warning/10 rounded-lg p-2.5">
|
||||
<Settings class="text-warning h-6 w-6" strokeWidth={2.5} />
|
||||
</div>
|
||||
<h2 class="text-2xl font-bold text-base-content">Ajustar Estoque</h2>
|
||||
<h2 class="text-base-content text-2xl font-bold">Ajustar Estoque</h2>
|
||||
</div>
|
||||
<div class="alert alert-warning mb-8 shadow-lg border-2 border-warning/30">
|
||||
<div class="alert alert-warning border-warning/30 mb-8 border-2 shadow-lg">
|
||||
<AlertCircle class="h-6 w-6" />
|
||||
<span class="font-semibold">Atenção: Ajustes de estoque devem ser justificados e são registrados permanentemente no histórico.</span>
|
||||
<span class="font-semibold"
|
||||
>Atenção: Ajustes de estoque devem ser justificados e são registrados permanentemente no
|
||||
histórico.</span
|
||||
>
|
||||
</div>
|
||||
<form onsubmit={(e) => { e.preventDefault(); ajustarEstoque(); }}>
|
||||
<form
|
||||
onsubmit={(e) => {
|
||||
e.preventDefault();
|
||||
ajustarEstoque();
|
||||
}}
|
||||
>
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||
<!-- Material -->
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label pb-2">
|
||||
<span class="label-text font-semibold flex items-center gap-2">
|
||||
<label for="ajusteMaterialId" class="label pb-2">
|
||||
<span class="label-text flex items-center gap-2 font-semibold">
|
||||
<Package class="h-4 w-4" />
|
||||
Material <span class="text-error">*</span>
|
||||
</span>
|
||||
</label>
|
||||
<select class="select select-bordered w-full focus:select-primary transition-colors h-12" bind:value={ajusteMaterialId} required>
|
||||
<select
|
||||
id="ajusteMaterialId"
|
||||
class="select select-bordered focus:select-primary h-12 w-full transition-colors"
|
||||
bind:value={ajusteMaterialId}
|
||||
required
|
||||
>
|
||||
<option value="">Selecione um material</option>
|
||||
{#if materiaisQuery.data}
|
||||
{#each materiaisQuery.data as material}
|
||||
{#each materiaisQuery.data as material (material._id)}
|
||||
<option value={material._id}>
|
||||
{material.codigo} - {material.nome} (Atual: {material.estoqueAtual}{material.unidadeMedida})
|
||||
</option>
|
||||
@@ -644,12 +747,15 @@
|
||||
|
||||
<!-- Nova Quantidade -->
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label pb-2">
|
||||
<span class="label-text font-semibold">Nova Quantidade <span class="text-error">*</span></span>
|
||||
<label for="ajusteQuantidadeNova" class="label pb-2">
|
||||
<span class="label-text font-semibold"
|
||||
>Nova Quantidade <span class="text-error">*</span></span
|
||||
>
|
||||
</label>
|
||||
<input
|
||||
id="ajusteQuantidadeNova"
|
||||
type="number"
|
||||
class="input input-bordered w-full focus:input-primary transition-colors h-12"
|
||||
class="input input-bordered focus:input-primary h-12 w-full transition-colors"
|
||||
min="0"
|
||||
step="1"
|
||||
bind:value={ajusteQuantidadeNova}
|
||||
@@ -664,35 +770,43 @@
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<label class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60">Quantidade correta após o ajuste</span>
|
||||
</label>
|
||||
<div class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60"
|
||||
>Quantidade correta após o ajuste</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Justificativa -->
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label pb-2">
|
||||
<span class="label-text font-semibold">Justificativa <span class="text-error">*</span></span>
|
||||
<label for="ajusteMotivo" class="label pb-2">
|
||||
<span class="label-text font-semibold"
|
||||
>Justificativa <span class="text-error">*</span></span
|
||||
>
|
||||
</label>
|
||||
<input
|
||||
id="ajusteMotivo"
|
||||
type="text"
|
||||
class="input input-bordered w-full focus:input-primary transition-colors h-12"
|
||||
class="input input-bordered focus:input-primary h-12 w-full transition-colors"
|
||||
placeholder="Ex: Inventário físico, Correção de erro, Perda"
|
||||
bind:value={ajusteMotivo}
|
||||
required
|
||||
/>
|
||||
<label class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60">Razão para o ajuste de estoque</span>
|
||||
</label>
|
||||
<div class="label pt-1">
|
||||
<span class="label-text-alt text-base-content/60"
|
||||
>Razão para o ajuste de estoque</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Observações -->
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label pb-2">
|
||||
<label for="ajusteObservacoes" class="label pb-2">
|
||||
<span class="label-text font-semibold">Observações</span>
|
||||
</label>
|
||||
<textarea
|
||||
class="textarea textarea-bordered w-full focus:textarea-primary transition-colors min-h-[100px]"
|
||||
id="ajusteObservacoes"
|
||||
class="textarea textarea-bordered focus:textarea-primary min-h-[100px] w-full transition-colors"
|
||||
placeholder="Observações adicionais (opcional)"
|
||||
bind:value={ajusteObservacoes}
|
||||
rows="3"
|
||||
@@ -700,8 +814,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-actions mt-8 justify-end gap-4 border-t-2 border-base-300 pt-6">
|
||||
<button type="submit" class="btn btn-warning btn-lg min-w-[180px] shadow-lg hover:shadow-xl transition-all" disabled={ajusteLoading}>
|
||||
<div class="card-actions border-base-300 mt-8 justify-end gap-4 border-t-2 pt-6">
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-warning btn-lg min-w-[180px] shadow-lg transition-all hover:shadow-xl"
|
||||
disabled={ajusteLoading}
|
||||
>
|
||||
{#if ajusteLoading}
|
||||
<span class="loading loading-spinner loading-sm"></span>
|
||||
Ajustando...
|
||||
@@ -715,34 +833,36 @@
|
||||
</div>
|
||||
</div>
|
||||
{:else if abaAtiva === 'historico'}
|
||||
<div class="card bg-base-100 border border-base-300 shadow-2xl">
|
||||
<div class="card bg-base-100 border-base-300 border shadow-2xl">
|
||||
<div class="card-body p-8">
|
||||
<div class="mb-8 flex items-center gap-3 border-b-2 border-info/20 pb-4">
|
||||
<div class="rounded-lg bg-info/10 p-2.5">
|
||||
<History class="h-6 w-6 text-info" strokeWidth={2.5} />
|
||||
<div class="border-info/20 mb-8 flex items-center gap-3 border-b-2 pb-4">
|
||||
<div class="bg-info/10 rounded-lg p-2.5">
|
||||
<History class="text-info h-6 w-6" strokeWidth={2.5} />
|
||||
</div>
|
||||
<h2 class="text-2xl font-bold text-base-content">Histórico de Movimentações</h2>
|
||||
<h2 class="text-base-content text-2xl font-bold">Histórico de Movimentações</h2>
|
||||
</div>
|
||||
<div class="overflow-x-auto rounded-lg border border-base-300">
|
||||
<table class="table table-zebra">
|
||||
<div class="border-base-300 overflow-x-auto rounded-lg border">
|
||||
<table class="table-zebra table">
|
||||
<thead>
|
||||
<tr class="bg-base-200">
|
||||
<th class="font-bold text-base-content">Data</th>
|
||||
<th class="font-bold text-base-content">Material</th>
|
||||
<th class="font-bold text-base-content">Tipo</th>
|
||||
<th class="font-bold text-base-content">Quantidade</th>
|
||||
<th class="font-bold text-base-content">Anterior</th>
|
||||
<th class="font-bold text-base-content">Nova</th>
|
||||
<th class="font-bold text-base-content">Funcionário</th>
|
||||
<th class="font-bold text-base-content">Usuário</th>
|
||||
<th class="font-bold text-base-content">Motivo</th>
|
||||
<th class="text-base-content font-bold">Data</th>
|
||||
<th class="text-base-content font-bold">Material</th>
|
||||
<th class="text-base-content font-bold">Tipo</th>
|
||||
<th class="text-base-content font-bold">Quantidade</th>
|
||||
<th class="text-base-content font-bold">Anterior</th>
|
||||
<th class="text-base-content font-bold">Nova</th>
|
||||
<th class="text-base-content font-bold">Funcionário</th>
|
||||
<th class="text-base-content font-bold">Usuário</th>
|
||||
<th class="text-base-content font-bold">Motivo</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#if movimentacoesQuery.data && movimentacoesQuery.data.length > 0}
|
||||
{#each movimentacoesQuery.data.slice(0, 100) as item}
|
||||
{#each movimentacoesQuery.data.slice(0, 100) as item (item.id)}
|
||||
{@const material = materiaisMap.get(item.materialId)}
|
||||
{@const funcionario = item.funcionarioId ? funcionariosMap.get(item.funcionarioId) : null}
|
||||
{@const funcionario = item.funcionarioId
|
||||
? funcionariosMap.get(item.funcionarioId)
|
||||
: null}
|
||||
{@const isMovimentacao = item.tipo === 'movimentacao'}
|
||||
{@const isAlteracao = item.tipo === 'alteracao'}
|
||||
<tr class="hover:bg-base-200/50 transition-colors">
|
||||
@@ -751,17 +871,21 @@
|
||||
</td>
|
||||
<td>
|
||||
{#if isAlteracao && item.tipoAlteracao === 'exclusao'}
|
||||
<div class="font-medium text-base-content/60 italic">
|
||||
<div class="text-base-content/60 font-medium italic">
|
||||
Material excluído (ID: {item.materialId})
|
||||
</div>
|
||||
{:else if material}
|
||||
<div class="font-medium">{material.nome}</div>
|
||||
{#if material.codigo}
|
||||
<div class="text-xs text-base-content/50 font-mono">{material.codigo}</div>
|
||||
<div class="text-base-content/50 font-mono text-xs">
|
||||
{material.codigo}
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="font-medium text-base-content/60">Material não encontrado</div>
|
||||
<div class="text-xs text-base-content/50 font-mono">ID: {item.materialId}</div>
|
||||
<div class="text-base-content/60 font-medium">Material não encontrado</div>
|
||||
<div class="text-base-content/50 font-mono text-xs">
|
||||
ID: {item.materialId}
|
||||
</div>
|
||||
{/if}
|
||||
</td>
|
||||
<td>
|
||||
@@ -810,7 +934,9 @@
|
||||
{#if funcionario}
|
||||
<div class="font-medium">{funcionario.nome}</div>
|
||||
{#if funcionario.matricula}
|
||||
<div class="text-xs text-base-content/50">Mat: {funcionario.matricula}</div>
|
||||
<div class="text-base-content/50 text-xs">
|
||||
Mat: {funcionario.matricula}
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<span class="text-base-content/50 text-sm italic">—</span>
|
||||
@@ -820,7 +946,7 @@
|
||||
{#if item.usuarioNome}
|
||||
<div class="font-medium">{item.usuarioNome}</div>
|
||||
{#if isAlteracao}
|
||||
<div class="text-xs text-base-content/50">
|
||||
<div class="text-base-content/50 text-xs">
|
||||
{#if item.tipoAlteracao === 'criacao'}
|
||||
Criou
|
||||
{:else if item.tipoAlteracao === 'edicao'}
|
||||
@@ -843,8 +969,10 @@
|
||||
<tr>
|
||||
<td colspan="9" class="text-center">
|
||||
<div class="py-12">
|
||||
<History class="mx-auto mb-4 h-16 w-16 text-base-content/30" />
|
||||
<p class="text-base-content/70 text-lg font-medium">Nenhuma movimentação registrada</p>
|
||||
<History class="text-base-content/30 mx-auto mb-4 h-16 w-16" />
|
||||
<p class="text-base-content/70 text-lg font-medium">
|
||||
Nenhuma movimentação registrada
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -856,5 +984,3 @@
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user