feat: integrate point management features into the dashboard
- Added a new "Meu Ponto" section for users to register their work hours, breaks, and attendance. - Introduced a "Controle de Ponto" category in the Recursos Humanos section for managing employee time records. - Enhanced the backend schema to support point registration and configuration settings. - Updated various components to improve UI consistency and user experience across the dashboard.
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
<script lang="ts">
|
||||
import { useQuery, useConvexClient } from 'convex-svelte';
|
||||
import { api } from '@sgse-app/backend/convex/_generated/api';
|
||||
import { Clock, Save, CheckCircle2 } from 'lucide-svelte';
|
||||
|
||||
const client = useConvexClient();
|
||||
const configQuery = useQuery(api.configuracaoPonto.obterConfiguracao, {});
|
||||
|
||||
let horarioEntrada = $state('08:00');
|
||||
let horarioSaidaAlmoco = $state('12:00');
|
||||
let horarioRetornoAlmoco = $state('13:00');
|
||||
let horarioSaida = $state('17:00');
|
||||
let toleranciaMinutos = $state(15);
|
||||
let processando = $state(false);
|
||||
let mensagem = $state<{ tipo: 'success' | 'error'; texto: string } | null>(null);
|
||||
|
||||
$effect(() => {
|
||||
if (configQuery?.data) {
|
||||
horarioEntrada = configQuery.data.horarioEntrada;
|
||||
horarioSaidaAlmoco = configQuery.data.horarioSaidaAlmoco;
|
||||
horarioRetornoAlmoco = configQuery.data.horarioRetornoAlmoco;
|
||||
horarioSaida = configQuery.data.horarioSaida;
|
||||
toleranciaMinutos = configQuery.data.toleranciaMinutos;
|
||||
}
|
||||
});
|
||||
|
||||
function mostrarMensagem(tipo: 'success' | 'error', texto: string) {
|
||||
mensagem = { tipo, texto };
|
||||
setTimeout(() => {
|
||||
mensagem = null;
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
async function salvarConfiguracao() {
|
||||
// Validação básica
|
||||
if (!horarioEntrada || !horarioSaidaAlmoco || !horarioRetornoAlmoco || !horarioSaida) {
|
||||
mostrarMensagem('error', 'Preencha todos os horários');
|
||||
return;
|
||||
}
|
||||
|
||||
if (toleranciaMinutos < 0 || toleranciaMinutos > 60) {
|
||||
mostrarMensagem('error', 'Tolerância deve estar entre 0 e 60 minutos');
|
||||
return;
|
||||
}
|
||||
|
||||
processando = true;
|
||||
try {
|
||||
await client.mutation(api.configuracaoPonto.salvarConfiguracao, {
|
||||
horarioEntrada,
|
||||
horarioSaidaAlmoco,
|
||||
horarioRetornoAlmoco,
|
||||
horarioSaida,
|
||||
toleranciaMinutos,
|
||||
});
|
||||
|
||||
mostrarMensagem('success', 'Configuração salva com sucesso!');
|
||||
} catch (error) {
|
||||
console.error('Erro ao salvar configuração:', error);
|
||||
mostrarMensagem('error', error instanceof Error ? error.message : 'Erro ao salvar configuração');
|
||||
} finally {
|
||||
processando = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="container mx-auto px-4 py-6 max-w-4xl">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="p-3 bg-primary/10 rounded-xl">
|
||||
<Clock class="h-8 w-8 text-primary" strokeWidth={2} />
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold text-base-content">Configurações de Ponto</h1>
|
||||
<p class="text-base-content/60 mt-1">Configure os horários de trabalho e tolerâncias</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mensagens -->
|
||||
{#if mensagem}
|
||||
<div
|
||||
class="alert mb-6"
|
||||
class:alert-success={mensagem.tipo === 'success'}
|
||||
class:alert-error={mensagem.tipo === 'error'}
|
||||
>
|
||||
<CheckCircle2 class="h-6 w-6" />
|
||||
<span>{mensagem.texto}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Formulário -->
|
||||
<div class="card bg-base-100 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title mb-4">Horários de Trabalho</h2>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<!-- Entrada -->
|
||||
<div class="form-control">
|
||||
<label class="label" for="horario-entrada">
|
||||
<span class="label-text font-medium">Horário de Entrada *</span>
|
||||
</label>
|
||||
<input
|
||||
id="horario-entrada"
|
||||
type="time"
|
||||
bind:value={horarioEntrada}
|
||||
class="input input-bordered"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Saída para Almoço -->
|
||||
<div class="form-control">
|
||||
<label class="label" for="horario-saida-almoco">
|
||||
<span class="label-text font-medium">Saída para Almoço *</span>
|
||||
</label>
|
||||
<input
|
||||
id="horario-saida-almoco"
|
||||
type="time"
|
||||
bind:value={horarioSaidaAlmoco}
|
||||
class="input input-bordered"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Retorno do Almoço -->
|
||||
<div class="form-control">
|
||||
<label class="label" for="horario-retorno-almoco">
|
||||
<span class="label-text font-medium">Retorno do Almoço *</span>
|
||||
</label>
|
||||
<input
|
||||
id="horario-retorno-almoco"
|
||||
type="time"
|
||||
bind:value={horarioRetornoAlmoco}
|
||||
class="input input-bordered"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Saída -->
|
||||
<div class="form-control">
|
||||
<label class="label" for="horario-saida">
|
||||
<span class="label-text font-medium">Horário de Saída *</span>
|
||||
</label>
|
||||
<input
|
||||
id="horario-saida"
|
||||
type="time"
|
||||
bind:value={horarioSaida}
|
||||
class="input input-bordered"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<!-- Tolerância -->
|
||||
<div class="form-control">
|
||||
<label class="label" for="tolerancia">
|
||||
<span class="label-text font-medium">Tolerância (minutos) *</span>
|
||||
</label>
|
||||
<input
|
||||
id="tolerancia"
|
||||
type="number"
|
||||
bind:value={toleranciaMinutos}
|
||||
min="0"
|
||||
max="60"
|
||||
class="input input-bordered"
|
||||
/>
|
||||
<div class="label">
|
||||
<span class="label-text-alt"
|
||||
>Tempo de tolerância para registros antes ou depois do horário configurado</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ações -->
|
||||
<div class="card-actions justify-end mt-6">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
onclick={salvarConfiguracao}
|
||||
disabled={processando}
|
||||
>
|
||||
{#if processando}
|
||||
<span class="loading loading-spinner loading-sm"></span>
|
||||
{:else}
|
||||
<Save class="h-5 w-5" />
|
||||
{/if}
|
||||
Salvar Configuração
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user