front_ponto_eletronico/src/components/modals/ShiftModal.vue

305 lines
8.9 KiB
Vue

<template>
<v-dialog v-model="isOpen" max-width="1200px" persistent>
<v-card class="pa-6 rounded-xl elevation-2 card-modal">
<v-card-title class="text-h5 font-weight-bold pb-0">
Cadastrar escala
</v-card-title>
<v-card-subtitle class="text-body-1 text-grey-darken-1 pb-4">
Insira os detalhes da sua escala
</v-card-subtitle>
<v-card-text>
<v-row class="mb-4">
<v-col cols="12">
<v-text-field
v-model="formData.shiftName"
label="Nome da escala"
placeholder="Ex: Escala Semana A"
outlined
rounded
density="comfortable"
class="mb-4"
/>
<v-radio-group v-model="formData.shiftType" inline>
<v-radio label="Semanal" value="Semanal"></v-radio>
<v-radio label="Por jornada" value="Por jornada"></v-radio>
</v-radio-group>
<v-row class="pa-0 ma-0">
<v-col cols="12" class="d-flex align-center gap-2 pa-0 ma-0">
<v-checkbox
v-model="formData.abonar"
label="Abonar intervalo"
density="compact"
hide-details
class="ma-0"
/>
<v-checkbox
v-model="formData.autoInterval"
label="Marcar intervalo automático"
density="compact"
hide-details
class="ma-0"
/>
</v-col>
</v-row>
</v-col>
</v-row>
<v-row>
<v-col cols="12" class="d-flex justify-end">
<v-menu>
<template #activator="{ props }">
<v-btn
v-bind="props"
color="primary"
variant="outlined"
:disabled="diasExcluidos.length === 0"
>
Restaurar dia
</v-btn>
</template>
<v-list>
<v-list-item
v-for="(dia, index) in diasExcluidos"
:key="index"
@click="restaurarDia(dia)"
>
<v-list-item-title>{{ dia }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-col>
</v-row>
<v-table>
<thead>
<tr>
<th>Folga</th>
<th>Dias da semana</th>
<th>Entrada</th>
<th>Saída</th>
<th>Intervalo</th>
<th>Total</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="(dia, index) in diasSemana" :key="index">
<td>
<v-checkbox v-model="dia.folga" />
</td>
<td>
<v-select
v-model="dia.nome"
:items="diasDaSemana"
label="Dia"
item-title="label"
item-value="value"
dense
rounded
/>
</td>
<td>
<v-text-field v-model="dia.entrada" type="time" rounded />
</td>
<td>
<v-text-field v-model="dia.saida" type="time" rounded />
</td>
<td>
<v-row no-gutters>
<v-col cols="6">
<v-text-field v-model="dia.intervaloInicio" type="time" label="de..." rounded />
</v-col>
<v-col cols="6">
<v-text-field v-model="dia.intervaloFim" type="time" label="até..." rounded />
</v-col>
</v-row>
</td>
<td>09:00</td>
<td>
<v-btn icon @click="removeDia(index)">
<v-icon @click="removerDia(dia.nome)" color="red" class="cursor-pointer">mdi-close</v-icon>
</v-btn>
</td>
</tr>
</tbody>
</v-table>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn text @click="close">Cancelar</v-btn>
<v-btn
@click="submit"
class="text-white salvar-btn"
>
+ Salvar Escala
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script setup>
import { ref, computed, watch, onMounted } from 'vue';
import { useAuthStore } from '../../stores/auth';
import {useShiftStore} from '../../stores/shift';
const props = defineProps({
modelValue: Boolean,
shift: {
type: Object,
default: () => ({
id: '',
tipo: 'Semanal',
abonar: true,
autoIntervalo: true,
diasSemana: [
{ nome: 'Segunda-feira', entrada: '08:00', saida: '17:00', intervaloInicio: '12:00', intervaloFim: '13:00', folga: false },
{ nome: 'Terça-feira', entrada: '08:00', saida: '17:00', intervaloInicio: '12:00', intervaloFim: '13:00', folga: false },
{ nome: 'Quarta-feira', entrada: '08:00', saida: '17:00', intervaloInicio: '12:00', intervaloFim: '13:00', folga: false },
{ nome: 'Quinta-feira', entrada: '08:00', saida: '17:00', intervaloInicio: '12:00', intervaloFim: '13:00', folga: false },
{ nome: 'Sexta-feira', entrada: '08:00', saida: '17:00', intervaloInicio: '12:00', intervaloFim: '13:00', folga: false },
{ nome: 'Sábado', entrada: '', saida: '', intervaloInicio: '', intervaloFim: '', folga: true },
{ nome: 'Domingo', entrada: '', saida: '', intervaloInicio: '', intervaloFim: '', folga: true }
]
})
},
isEditMode: {
type: Boolean,
default: false
}
});
const emit = defineEmits(['update:modelValue', 'save']);
const authStore = useAuthStore();
const shiftStore = useShiftStore();
const isOpen = computed({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value)
});
const diasDaSemana = [
{ label: 'Segunda-feira', value: 'Segunda-feira' },
{ label: 'Terça-feira', value: 'Terça-feira' },
{ label: 'Quarta-feira', value: 'Quarta-feira' },
{ label: 'Quinta-feira', value: 'Quinta-feira' },
{ label: 'Sexta-feira', value: 'Sexta-feira' },
{ label: 'Sábado', value: 'Sábado' },
{ label: 'Domingo', value: 'Domingo' }
];
const formData = ref({
shiftName: '',
shiftType: 'Semanal',
abonar: true,
autoInterval: true,
service_instance_id: authStore.service_instance_id || null
});
const diasSemana = ref([]);
const diasExcluidos = ref([]);
const montarDiasPadrao = () => {
diasSemana.value = diasDaSemana.map((dia) => ({
nome: dia.value,
entrada: '08:00',
saida: '17:00',
intervaloInicio: '12:00',
intervaloFim: '13:00',
folga: true
}));
};
const removerDia = (diaNome) => {
const index = diasSemana.value.findIndex((d) => d.nome === diaNome);
if (index !== -1) {
diasExcluidos.value.push(diasSemana.value[index].nome);
diasSemana.value.splice(index, 1);
}
};
const restaurarDia = (diaNome) => {
diasSemana.value.push({
nome: diaNome,
entrada: '08:00',
saida: '17:00',
intervaloInicio: '12:00',
intervaloFim: '13:00',
folga: true
});
diasExcluidos.value = diasExcluidos.value.filter((d) => d !== diaNome);
};
const resetForm = () => {
formData.value = {
shiftType: 'Semanal',
abonar: true,
autoInterval: true,
service_instance_id: authStore.service_instance_id || null
};
diasExcluidos.value = [];
montarDiasPadrao();
};
const submit = async () => {
try {
for (const dia of diasSemana.value) {
const payload = {
day: dia.nome,
start_time: dia.entrada,
end_time: dia.saida,
interval_start: dia.intervaloInicio,
interval_end: dia.intervaloFim,
type_interval: formData.value.abonar ? 'abonado' : 'normal',
service_instance_id: formData.value.service_instance_id,
name: formData.value.shiftName
};
await shiftStore.createShift(payload);
console.log('Enviado com sucesso:', payload);
}
emit('save');
close();
} catch (error) {
console.error('Erro ao enviar escala:', error);
}
};
const close = () => {
isOpen.value = false;
resetForm();
};
onMounted(() => {
montarDiasPadrao();
});
watch(
() => props.modelValue,
(val) => {
if (val) {
resetForm();
}
}
);
</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>