305 lines
8.9 KiB
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> |