Compare commits

...

2 Commits

Author SHA1 Message Date
e0592c916c aba de configurações 2025-05-06 17:11:06 -03:00
374ebe8ac6 pagina escala completa 2025-05-06 11:21:31 -03:00
4 changed files with 802 additions and 27 deletions

View File

@ -112,49 +112,49 @@
<div class="mb-4">
<v-checkbox
v-model="form.dias_semana"
:value="0"
:value="1"
label="Domingo"
hide-details
class="d-inline-block mr-4"
></v-checkbox>
<v-checkbox
v-model="form.dias_semana"
:value="1"
:value="2"
label="Segunda"
hide-details
class="d-inline-block mr-4"
></v-checkbox>
<v-checkbox
v-model="form.dias_semana"
:value="2"
:value="3"
label="Terça"
hide-details
class="d-inline-block mr-4"
></v-checkbox>
<v-checkbox
v-model="form.dias_semana"
:value="3"
:value="4"
label="Quarta"
hide-details
class="d-inline-block mr-4"
></v-checkbox>
<v-checkbox
v-model="form.dias_semana"
:value="4"
:value="5"
label="Quinta"
hide-details
class="d-inline-block mr-4"
></v-checkbox>
<v-checkbox
v-model="form.dias_semana"
:value="5"
:value="6"
label="Sexta"
hide-details
class="d-inline-block mr-4"
></v-checkbox>
<v-checkbox
v-model="form.dias_semana"
:value="6"
:value="7"
label="Sábado"
hide-details
class="d-inline-block"

View File

@ -112,7 +112,7 @@ export const useShiftStore = defineStore('shifts', {
end_time: shiftData.end_time,
interval_start: shiftData.interval_start,
interval_end: shiftData.interval_end,
type_interval: shiftData.type_interval || 'manual', // "manual" ou "automatic" dependendo da checkbox
type_interval: shiftData.type_interval, // "manual" ou "automatic" dependendo da checkbox
description: shiftData.description || '',
tolerance: shiftData.tolerance || 0,
service_instance_id: authStore.service_instance_id,
@ -166,7 +166,7 @@ export const useShiftStore = defineStore('shifts', {
end_time: shiftData.saida_final,
interval_start: shiftData.saida_almoco,
interval_end: shiftData.retorno_almoco,
type_interval: shiftData.almoco_automatico ? 'Automatico' : 'Manual', // "manual" ou "automatic" dependendo da checkbox
type_interval: shiftData.almoco_automatico ? 'automatic' : 'Manual', // "manual" ou "automatic" dependendo da checkbox
description: shiftData.descricao || '',
tolerance: shiftData.tolerancia || 0,
service_instance_id: authStore.service_instance_id,

View File

@ -1,10 +1,781 @@
<template>
<v-container>
<h1>Settings</h1>
<p>Configurações do usuário.</p>
</v-container>
</template>
<script setup>
</script>
<template>
<v-container class="tab">
<div class="header-container">
<div class="header-left">
<div class="icon-wrapper">
<v-icon color="primary" size="32">mdi-clock-outline</v-icon>
</div>
<div class="header-title">
<h1>Sistema de Ponto | Admin</h1>
</div>
</div>
<div class="header-right">
<v-btn variant="text" prepend-icon="mdi-arrow-left" class="back-button" to="/dashboard">
Voltar para Dashboard
</v-btn>
<v-badge dot color="error" class="notification-badge">
<v-icon>mdi-bell</v-icon>
</v-badge>
<div class="admin-profile">
<v-avatar class="mr-2" color="primary" size="40">
<v-img src="/api/placeholder/40/40" alt="Administrador"></v-img>
</v-avatar>
<div class="admin-info">
<span class="admin-name">Administrador</span>
<span class="admin-role">Gestor</span>
</div>
<v-icon>mdi-chevron-down</v-icon>
</div>
</div>
</div>
<!-- Título e descrição da seção -->
<div class="section-header">
<h2>Configurações do Sistema</h2>
<p class="section-description">Defina os parâmetros de funcionamento do sistema de ponto</p>
</div>
<!-- Abas -->
<v-tabs v-model="selectedTab" class="custom-tabs" align-tabs="start">
<v-tab
v-for="tab in tabs"
:key="tab.value"
:value="tab.value"
:class="selectedTab === tab.value ? 'active-tab' : ''"
>
{{ tab.label }}
</v-tab>
</v-tabs>
<v-window v-model="selectedTab">
<!-- Aba: Geral -->
<v-window-item value="geral">
<v-card class="pa-6">
<h3 class="section-title">Configurações Gerais</h3>
<p class="section-description">Configure os parametros gerais de funcionamento do sistema de ponto</p>
<v-row class="mb-6">
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Tolerância para Entrada (minutos)</div>
<v-text-field
v-model="form.tolerancia_entrada"
type="number"
variant="outlined"
class="mb-4"
hide-details />
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Tolerância para Saída(minutos)</div>
<v-text-field
v-model="form.tolerancia_saida"
type="number"
variant="outlined"
class="mb-4"
hide-details
/>
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Limite Diário de Horas Extras</div>
<v-text-field
v-model="form.limite_diario_he"
type="number"
variant="outlined"
class="mb-4"
hide-details
/>
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Limite Mensal de Horas Extras</div>
<v-text-field
v-model="form.limite_mensal_he"
type="number"
variant="outlined"
class="mb-4"
hide-details/>
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Limite Banco de Horas Positivo</div>
<v-text-field
v-model="form.banco_horas_positivo"
type="number"
variant="outlined"
class="mb-4"
hide-details />
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Limite Banco de Horas Negativo</div>
<v-text-field
v-model="form.banco_horas_negativo"
type="number"
variant="outlined"
class="mb-4"
hide-details
/>
</v-col>
<v-col cols="12" md="6">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Validação Facial Obrigatória</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.validacao_facial"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12" md="6">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Permitir Registro Remoto</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.registro_remoto"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12" md="6">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Permitir Ajuste pelo Colaborador</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.ajuste_colaborador"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Dias para Aprovação Automática</div>
<v-text-field
v-model="form.dias_aprovacao"
type="number"
variant="outlined"
class="mb-4"
hide-details/>
<small > Dias após os quais as soliticações são aprovadas automaticamente (0=nunca)</small>
</v-col>
</v-row>
</v-card>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" @click="salvarConfiguracoes" class="add-btn">Salvar Configurações</v-btn>
</v-card-actions>
</v-window-item>
<!-- Outras abas virão depois -->
</v-window>
<v-window v-model="selectedTab">
<v-window-item value="calculo">
<v-card class="pa-6">
<h3 class="section-title">Configurações de Cálculo de Horas</h3>
<p class="section-description">Configure os parametros para cálculo de horas trabalhados, extras e noturnoas</p>
<v-row class="mb-6">
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Jornada Diária (horas)</div>
<v-text-field
v-model="form.jornada_diaria"
type="number"
variant="outlined"
class="mb-4"
hide-details />
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Jornada Semanal (horas)</div>
<v-text-field
v-model="form.jornada_semanal"
type="number"
variant="outlined"
class="mb-4"
hide-details
/>
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Início Período Noturno</div>
<v-text-field
v-model="form.periodo_noturno_inicio"
type="time"
variant="outlined"
class="mb-4"
hide-details
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Fim do Período Noturno</div>
<v-text-field
v-model="form.periodo_noturno_inicio"
type="time"
variant="outlined"
class="mb-4"
hide-details
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Aplicar Redução de Hora Noturna</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.hora_noturna"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Adicional Noturno (%)</div>
<v-text-field
v-model="form.adicional_noturno"
type="number"
variant="outlined"
class="mb-4"
hide-details
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Adicional Hora Extra Normal (%)</div>
<v-text-field
v-model="form.adicional_hora_normal"
type="number"
variant="outlined"
class="mb-4"
hide-details
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Adicional Hora Extra Feriado (%)</div>
<v-text-field
v-model="form.hora_extra_feriado"
type="number"
variant="outlined"
class="mb-4"
hide-details
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Descontar Atrasos Automaticamente</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.descontar_atrasos"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12" md="6">
<div class="mb-3 font-weight-medium">Tolerância para Descontos (minutos)</div>
<v-text-field
v-model="form.tolerancia_desconto"
type="number"
variant="outlined"
class="mb-4"
hide-details />
</v-col>
<v-col cols="12" md="12">
<div class="mb-3 font-weight-medium">Arredondamento de Minutos</div>
<v-text-field
v-model="form.arredondamento_registro"
type="number"
variant="outlined"
class="mb-4"
hide-details
/>
<small>Arredondamento aplicado aos registros de ponto</small>
</v-col>
</v-row>
</v-card>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" @click="salvarConfiguracoes" class="add-btn">Salvar Configurações</v-btn>
</v-card-actions>
</v-window-item>
</v-window>
<v-window v-model="selectedTab">
<v-window-item value="notificacoes">
<v-card class="pa-6">
<h3 class="section-title">Configurações Notificações</h3>
<p class="section-description">Configure as notificações do sistema para colaboradores e gestores</p>
<v-row class="mb-6">
<v-col cols="12">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Notificar Esquecimento de Ponto</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.esquecimento_ponto_notificacao"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Notificar Horas Extras</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.horas_extras_notificacao"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Notificar Solicitações Pendentes</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.solictacao_pendente_notificacao"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Notificar Banco de Horas</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.banco_horas_notificacao"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Notificar Gestor sobre Ajustes</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.banco_horas_notificacao"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
</v-row>
<v-divider class="my-4 mx-auto custom-divider"></v-divider>
<v-row class ="mb-6">
<v-col cols="12">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Relatórios por E-mail</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.relatorio_email"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Relatórios Díario para Gestores</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.relatorio_gestores"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Relatórios Semanal para Colaboradores</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.relatorio_colaboradores"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
</v-row>
</v-card>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" @click="salvarConfiguracoes" class="add-btn">Salvar Configurações</v-btn>
</v-card-actions>
</v-window-item>
<!-- Outras abas virão depois -->
</v-window>
<v-window v-model="selectedTab">
<v-window-item value="integracoes">
<v-card class="pa-6">
<h3 class="section-title">Configurações de Integrações</h3>
<p class="section-description">Configure as integrações com outros sistemas</p>
<v-row class="mb-6">
<v-col cols="12">
<v-row class="align-center justify-space-between ">
<v-col cols="auto">
<span class="font-weight-medium">Integrar com Folha de Pagamento</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.integrar_folha_pagamento"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
</v-row>
<v-divider class="my-4 mx-auto custom-divider"></v-divider>
<v-row class ="mb-6">
<v-col cols="12">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Exportação de Dados</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.exportacao_dados"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Permitir Exportação CSV</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.exportacao_csv"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Permitir Exportação PDF</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.exportacao_pdf"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
<v-col cols="12">
<v-row class="align-center justify-space-between">
<v-col cols="auto">
<span class="font-weight-medium">Integrar com Calendário</span>
</v-col>
<v-col cols="auto">
<v-switch
v-model="form.banco_horas_notificacao"
color="#2563eb"
hide-details
inset
/>
</v-col>
</v-row>
</v-col>
</v-row>
</v-card>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" @click="salvarConfiguracoes" class="add-btn">Salvar Configurações</v-btn>
</v-card-actions>
</v-window-item>
<!-- Outras abas virão depois -->
</v-window>
</v-container>
</template>
<script setup>
import { ref } from 'vue';
const selectedTab = ref('geral');
const tabs = [
{ value: 'geral', label: 'Geral' },
{ value: 'calculo', label: 'Cálculo de Horas' },
{ value: 'notificacoes', label: 'Notificações' },
{ value: 'integracoes', label: 'Integrações' }
];
const form = ref({
tolerancia_entrada: '15',
tolerancia_saida: '15',
limite_diario_he: '2',
limite_mensal_he: '40',
banco_horas_positivo: '40',
banco_horas_negativo: '10',
validacao_facial: true,
registro_remoto: true,
ajuste_colaborador: false,
dias_aprovacao: '7'
});
const salvarConfiguracoes = () => {
console.log('Configurações salvas:', form.value);
// Chamada à API futura aqui
};
</script>
<style scoped>
.custom-divider {
width: 85%; /* ou qualquer valor: 300px, 80%, etc */
}
.mb-6 {
margin-bottom: 32px !important;
}
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding: 0 0 20px 0;
border-bottom: 1px solid #eaecef;
}
.header-left {
display: flex;
align-items: center;
}
.icon-wrapper {
background-color: #e3f2fd;
border-radius: 8px;
padding: 12px;
margin-right: 12px;
}
.header-title h1 {
font-size: 18px;
font-weight: 600;
margin: 0;
color: #1e293b;
}
.header-right {
display: flex;
align-items: center;
gap: 16px;
}
.back-button {
color: #1976d2;
}
.new-holiday-btn {
background-color: #1976d2;
color: white;
}
.admin-profile {
display: flex;
align-items: center;
margin-left: 16px;
cursor: pointer;
}
.admin-info {
display: flex;
flex-direction: column;
margin: 0 8px;
}
.admin-name {
font-size: 14px;
font-weight: 500;
color: #1e293b;
}
.admin-role {
font-size: 12px;
color: #64748b;
}
.notification-badge {
margin: 0 8px;
}
/* Estilo da seção de título */
.section-header {
margin-bottom: 24px;
}
.section-header h2 {
font-size: 24px;
font-weight: 600;
margin: 0 0 8px 0;
color: #1e293b;
}
.section-description {
color: #64748b;
font-size: 14px;
margin: 1;
padding-bottom: 2%;
}
.main-title {
font-size: 28px;
font-weight: 600;
margin-bottom: 8px;
color: #333;
}
.subtitle {
color: #666;
font-size: 16px;
}
.image-wrapper {
display: flex;
justify-content: flex-end;
}
.top-image {
max-width: 180px;
height: auto;
}
.v-card {
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
overflow: hidden;
}
.custom-tabs {
background-color: #e6edf700;
border-radius: 8px;
padding: 4px;
}
.v-tab {
border-radius: 8px;
min-width: 140px;
text-transform: none;
font-weight: 500;
color: #475569;
}
.v-tab.active-tab {
background-color: #ffffff !important;
color: #1e293b !important;
}
.add-btn {
border-radius: 8px;
font-weight: 500;
padding: 0 20px ;
height: 44px;
color: white !important;
background-color: #2563eb;
}
</style>

View File

@ -65,8 +65,9 @@
</div>
</template>
<template v-slot:item.almoco_type="{ item }">
{{ item.type_interval === 'automatic' ? 'Automatico' : 'Manual' }}
{{ item.almoco_type }}
</template>
<template v-slot:item.actions="{ item }">
<v-icon size="small" class="mr-2" @click="openEditShiftDialog(item.id)">mdi-pencil</v-icon>
<v-icon size="small" @click="confirmDelete('shift', item)">mdi-delete</v-icon>
@ -175,8 +176,11 @@ export default {
shifts.value = data.map(shift => ({
...shift,
formatted_days: formatDays(shift.time_schedules),
horarios: formatFullSchedule(shift)
horarios: formatFullSchedule(shift),
almoco_type: shift.type_interval?.toLowerCase() === 'automatic' ? 'Automático' : 'Manual'
}));
} catch {
showNotification('Erro ao carregar escalas', 'error');
} finally {
@ -229,13 +233,13 @@ export default {
};
const handleCreatedShift = async () => {
await shiftStore.fetchShifts(); // função que carrega os turnos da API
await fetchShifts();
showNotification('Escala criada com sucesso!');
dialogs.value.createShift = false;
};
const handleEditedShift = async () => {
await shiftStore.fetchShifts(); // 🔁 recarrega os dados atualizados da API
dialogs.value.editShift = false; // fecha o modal
await fetchShifts();
dialogs.value.editShift = false;
showNotification('Escala atualizada com sucesso!');
};
@ -273,16 +277,16 @@ export default {
};
</script>
<style scoped>
.header-container {
display: flex;
background-color: #ffffff;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding: 20px;
border-bottom: 1px solid #ffffff;
padding: 0 0 20px 0;
border-bottom: 1px solid #eaecef;
}
.header-left {