front_ponto_eletronico/src/components/modals/HolidayModal.vue

227 lines
6.1 KiB
Vue

<template>
<v-dialog v-model="dialogVisible" max-width="600px">
<v-card class="pa-6 rounded-xl elevation-2 card-modal">
<v-card-title class="pb-1">
<span class="modal-title">Editar Feriado</span>
</v-card-title>
<v-card-subtitle class="modal-subtitle mb-6">
Altere os dados desejados e clique em salvar.
</v-card-subtitle>
<v-card-text>
<v-container>
<v-row>
<v-col cols="12">
<div class="form-group">
<label class="form-label">Nome do Feriado</label>
<v-text-field v-model="localHoliday.name" variant="outlined" hide-details="auto" clearable />
</div>
</v-col>
<v-col cols="12">
<div class="form-group">
<label class="form-label">Data</label>
<v-text-field v-model="localHoliday.date" type="date" variant="outlined" hide-details="auto" :rules="[rules.required]" clearable />
</div>
</v-col>
<v-col cols="12" md="6">
<div class="form-group">
<label class="form-label">Tipo</label>
<v-select v-model="localHoliday.type" :items="['Nacional', 'Estadual', 'Ponto Facultativo', 'Outro']" variant="outlined" hide-details="auto" />
</div>
</v-col>
<v-col cols="12" md="6">
<div class="form-group">
<label class="form-label">Adicional Hora Extra</label>
<v-select v-model="localHoliday.adicional_he" :items="['0%', '25%','50%','75%', '100%']" variant="outlined" hide-details="auto" />
</div>
</v-col>
<v-col cols="12">
<v-checkbox v-model="localHoliday.recorrente" label="Feriado recorrente (repete todos os anos)" color="primary" />
</v-col>
</v-row>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn text class="cancel-btn" @click="$emit('cancel')">Cancelar</v-btn>
<v-btn class="add-btn" @click="handleSave" :loading="holidayStore.loading">
Salvar
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue';
import { useHolidayStore } from '../../stores/holiday';
import { useAuthStore } from '../../stores/auth';
const props = defineProps({
modalValue: Boolean,
holiday: Object
});
const emit = defineEmits(['update:modalValue', 'save']);
const rules = {
required: (value) => !!value || 'Campo obrigatório'
};
const holidayStore = useHolidayStore();
const authStore = useAuthStore();
const dialogVisible = ref(false);
const localHoliday = ref({
name: '',
type: '',
date: '',
recorrente: true,
adicional_he: 0,
parent_id: authStore.userId,
service_instance_id: authStore.service_instance_id || 2
});
const loadHolidayData = async () => {
try {
if (!props.holiday || !props.holiday.id) return;
const holidayData = await holidayStore.fetchHolidayById(props.holiday.id);
if (holidayData) {
localHoliday.value = {
id: holidayData.id,
name: holidayData.name || '',
type: holidayData.type || '',
date: holidayData.date ? new Date(holidayData.date).toISOString().split('T')[0] : '',
recorrente: holidayData.recorrente ?? true,
adicional_he: Number(holidayData.adicional_he) || 0,
parent_id: holidayData.parent_id || authStore.userId,
service_instance_id: holidayData.service_instance_id || authStore.service_instance_id
};
}
} catch (error) {
console.error('Erro ao carregar feriado:', error);
}
};
watch(() => props.modalValue, async (newVal) => {
dialogVisible.value = newVal;
if (newVal) await loadHolidayData();
});
watch(() => props.holiday, (newVal) => {
if (newVal && newVal.id) loadHolidayData();
}, { deep: true });
watch(dialogVisible, (newVal) => {
if (props.modalValue !== newVal) emit('update:modalValue', newVal);
});
const closeModal = () => {
dialogVisible.value = false;
emit('update:modalValue', false);
};
const handleSave = async () => {
try {
const data = {
...localHoliday.value,
adicional_he: parseInt(localHoliday.value.adicional_he) || 0,
parent_id: authStore.userId,
service_instance_id: authStore.service_instance_id
};
await holidayStore.updateHoliday(data.id, data);
emit('save', data);
closeModal();
} catch (error) {
console.error('Erro ao salvar feriado:', error);
}
};
onMounted(() => {
dialogVisible.value = props.modalValue;
if (props.modalValue && props.holiday?.id) loadHolidayData();
});
</script>
<style scoped>
.card-modal {
background-color: #ffffff;
border-radius: 16px;
max-height: 70 vh;
overflow-y: auto;
}
.v-card-text {
padding-bottom: 0px !important; /* ou 0px */
}
.salvar-btn {
background: linear-gradient(to right, #6b4eff, #2eb6ff);
border-radius: 999px;
text-transform: none;
font-weight: 500;
}
.modal-title {
font-size: 25px;
font-weight: 600;
color: #1e293b;
}
.modal-subtitle {
font-size: 14px;
color: #64748b;
}
.form-group {
display: flex;
flex-direction: column;
margin-bottom: 16px;
}
.form-label {
display: block;
font-size: 18px;
font-weight: 500;
color: #1e293b;
margin-bottom: 4px;
margin-left: 4px;
}
.card-modal {
background-color: #ffffff;
border-radius: 16px;
max-height: 70 vh;
overflow-y: auto;
}
.cancel-btn {
border-radius: 8px;
font-weight: 500;
padding: 0 20px;
height: 44px;
color: #1e293b;
border: 1px solid #d1d5db;
background-color: #fff;
}
/* Borda azul ao passar o mouse */
::v-deep(.v-field.v-field--variant-outlined:hover) {
border-color: #2eb6ff79 !important;
box-shadow: 0 0 0 1px #54d2ff6b !important;
}
.add-btn {
border-radius: 8px;
font-weight: 500;
padding: 0 20px;
height: 44px;
color: white;
background-color: #2563eb;
}
</style>