front_ponto_eletronico/src/components/modals/EditShiftModal.vue
2025-05-06 11:21:31 -03:00

282 lines
8.0 KiB
Vue

<template>
<v-dialog :model-value="isOpen" @update:modelValue="val => $emit('update:modelValue', val)" max-width="600">
<v-card class="pa-4">
<v-btn
icon
class="position-absolute top-2 right-2"
@click="fechar"
>
<v-icon>mdi-close</v-icon>
</v-btn>
<v-card-title class="text-h5 font-weight-bold pt-4">
Editar Escala
</v-card-title>
<v-card-subtitle class="text-body-1 text-grey-darken-1 pb-4">
Preencha os dados da nova escala e clique em adicionar.
</v-card-subtitle>
<v-card-text>
<v-row>
<v-col cols="12" md="6">
<!-- Nome da Escala -->
<div class="mb-3 font-weight-medium">Nome da Escala</div>
<v-text-field
v-model="form.nome"
variant="outlined"
class="mb-4"
hide-details
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<!-- Tolerância -->
<div class="mb-3 font-weight-medium">Tolerância (minutos)</div>
<v-text-field
v-model="form.tolerancia"
type="number"
variant="outlined"
class="mb-4"
hide-details
></v-text-field>
</v-col>
</v-row>
<!-- Descrição -->
<div class="mb-3 font-weight-medium">Descrição</div>
<v-text-field
v-model="form.descricao"
variant="outlined"
class="mb-4"
hide-details
></v-text-field>
<v-row>
<v-col cols="12" md="6">
<!-- Horário de Entrada -->
<div class="mb-3 font-weight-medium">Horário de Entrada</div>
<v-text-field
v-model="form.entrada"
type="time"
variant="outlined"
class="mb-4"
hide-details
prepend-inner-icon="mdi-clock-outline"
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<!-- Saída para Almoço -->
<div class="mb-3 font-weight-medium">Saída para Almoço</div>
<v-text-field
v-model="form.saida_almoco"
type="time"
variant="outlined"
class="mb-4"
hide-details
prepend-inner-icon="mdi-clock-outline"
></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col cols="12" md="6">
<!-- Retorno do Almoço -->
<div class="mb-3 font-weight-medium">Retorno do Almoço</div>
<v-text-field
v-model="form.retorno_almoco"
type="time"
variant="outlined"
class="mb-4"
hide-details
prepend-inner-icon="mdi-clock-outline"
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<!-- Horário de Saída -->
<div class="mb-3 font-weight-medium">Horário de Saída</div>
<v-text-field
v-model="form.saida_final"
type="time"
variant="outlined"
class="mb-4"
hide-details
prepend-inner-icon="mdi-clock-outline"
></v-text-field>
</v-col>
</v-row>
<!-- Dias da Semana -->
<div class="mb-3 font-weight-medium">Dias da Semana</div>
<div class="mb-4">
<v-checkbox
v-model="form.dias_semana"
:value="1"
label="Domingo"
hide-details
class="d-inline-block mr-4"
></v-checkbox>
<v-checkbox
v-model="form.dias_semana"
:value="2"
label="Segunda"
hide-details
class="d-inline-block mr-4"
></v-checkbox>
<v-checkbox
v-model="form.dias_semana"
:value="3"
label="Terça"
hide-details
class="d-inline-block mr-4"
></v-checkbox>
<v-checkbox
v-model="form.dias_semana"
:value="4"
label="Quarta"
hide-details
class="d-inline-block mr-4"
></v-checkbox>
<v-checkbox
v-model="form.dias_semana"
:value="5"
label="Quinta"
hide-details
class="d-inline-block mr-4"
></v-checkbox>
<v-checkbox
v-model="form.dias_semana"
:value="6"
label="Sexta"
hide-details
class="d-inline-block mr-4"
></v-checkbox>
<v-checkbox
v-model="form.dias_semana"
:value="7"
label="Sábado"
hide-details
class="d-inline-block"
></v-checkbox>
</div>
<!-- Almoço Automático -->
<v-checkbox
v-model="form.almoco_automatico"
label="Marcação automática de almoço"
hide-details
class="mb-1"
></v-checkbox>
<div class="text-grey-darken-1 text-body-2 ml-7 mb-4">
Se ativado, o sistema marcará automaticamente a saída e retorno do almoço nos horários definidos
</div>
</v-card-text>
<v-card-actions class="pt-0">
<v-spacer></v-spacer>
<v-btn variant="outlined" class="mr-3" @click="fechar">Cancelar</v-btn>
<v-btn color="primary" variant="elevated" @click="submit" :loading="loading">
Salvar
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script setup>
import { ref, watch } from 'vue';
import { useShiftStore } from '../../stores/shift';
const props = defineProps({
modelValue: Boolean,
shiftData: Object
});
const emit = defineEmits(['update:modelValue', 'save']);
const isOpen = ref(props.modelValue);
const shiftStore = useShiftStore();
const loading = ref(false);
// Formulário reativo
const form = ref({
id: null,
nome: '',
descricao: '',
tolerancia: 15,
entrada: '',
saida_almoco: '',
retorno_almoco: '',
saida_final: '',
dias_semana: [],
almoco_automatico: false
});
// Atualiza isOpen e dialog
watch(() => props.modelValue, (val) => isOpen.value = val);
watch(isOpen, (val) => emit('update:modelValue', val));
// Mapeamento de nomes para valores de dias
const diaSemanaMap = {
'Domingo': 1,
'Segunda-feira': 2,
'Terça-feira': 3,
'Quarta-feira': 4,
'Quinta-feira': 5,
'Sexta-feira': 6,
'Sábado': 7
};
// Atualiza os dados do formulário com shiftData recebido
watch(() => props.shiftData, (newData) => {
if (!newData) return;
form.value = {
id: newData.id || null,
nome: newData.name || '',
descricao: newData.description || '',
tolerancia: newData.tolerance ?? 15,
entrada: newData.start_time || '',
saida_almoco: newData.interval_start || '',
retorno_almoco: newData.interval_end || '',
saida_final: newData.end_time || '',
almoco_automatico: newData.type_interval === 'automatic',
dias_semana: (newData.time_schedules || []).map(d => diaSemanaMap[d.name]).filter(d => d !== undefined)
};
}, { immediate: true });
// Fecha o modal
function fechar() {
isOpen.value = false;
}
// Envia atualização da escala
async function submit() {
try {
loading.value = true;
await shiftStore.updateShift(form.value.id, form.value);
emit('save', form.value); // notifica o pai
fechar();
} catch (error) {
console.error('Erro ao atualizar escala:', error);
} finally {
loading.value = false;
}
}
</script>
<style scoped>
.card-modal {
background-color: #FFFFFF;
border-radius: 16px;
}
.salvar-btn {
background: linear-gradient(to right, #6B4EFF, #2EB6FF);
border-radius: 999px;
text-transform: none;
font-weight: 500;
}
</style>