feat: add shift management functionality
This commit is contained in:
@@ -1,11 +1,98 @@
|
||||
<script setup>
|
||||
import ClientLayout from '../../../layouts/ClientLayout.vue'
|
||||
import { computed, ref } from 'vue';
|
||||
import Dialog from 'primevue/dialog';
|
||||
import { toast } from 'vue3-toastify';
|
||||
import ClientLayout from '../../../layouts/ClientLayout.vue';
|
||||
import UiCard from '../../../components/ui/UiCard.vue';
|
||||
import UiButton from '../../../components/ui/UiButton.vue';
|
||||
import ShiftCalendar from '../../../components/dashboard/shifts/ShiftCalendar.vue';
|
||||
import { useShiftStore } from '../../../store/Shift';
|
||||
import { convertEnglishToPersian } from '../../../utils/numberUtils';
|
||||
|
||||
const props = defineProps({
|
||||
myShifts: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
openShifts: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const shiftStore = useShiftStore();
|
||||
|
||||
const selectedShift = ref(null);
|
||||
const confirmVisible = ref(false);
|
||||
|
||||
const isMine = computed(() => {
|
||||
return !!selectedShift.value && props.myShifts.data.some((shift) => shift.id === selectedShift.value.id);
|
||||
});
|
||||
|
||||
const shiftLabel = computed(() => {
|
||||
if (!selectedShift.value) return '';
|
||||
const day = selectedShift.value.date ?? selectedShift.value.day_of_week;
|
||||
const time = `${selectedShift.value.start_time} تا ${selectedShift.value.end_time}`;
|
||||
return convertEnglishToPersian(`${day} - ساعت ${time}`);
|
||||
});
|
||||
|
||||
const openConfirm = (shift) => {
|
||||
selectedShift.value = shift;
|
||||
confirmVisible.value = true;
|
||||
};
|
||||
|
||||
const handleConfirm = async () => {
|
||||
try {
|
||||
if (isMine.value) {
|
||||
await shiftStore.release(selectedShift.value.id);
|
||||
toast.success('شیفت با موفقیت لغو شد.');
|
||||
} else {
|
||||
await shiftStore.claim(selectedShift.value.id);
|
||||
toast.success('شیفت با موفقیت به شما اختصاص یافت.');
|
||||
}
|
||||
confirmVisible.value = false;
|
||||
} catch (error) {
|
||||
toast.error(error.message);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientLayout>
|
||||
<h1 class="text-2xl font-bold">
|
||||
Shifts
|
||||
</h1>
|
||||
<UiCard title="برنامه شیفتهای من" variant="default">
|
||||
<ShiftCalendar
|
||||
:my-shifts="myShifts.data"
|
||||
:open-shifts="openShifts.data"
|
||||
@select-shift="openConfirm"
|
||||
/>
|
||||
</UiCard>
|
||||
|
||||
<Dialog v-model:visible="confirmVisible" :modal="true" :closable="true" :dismissableMask="true" :style="{ width: '400px' }" class="fast-request-dialog">
|
||||
<template #header>
|
||||
<div class="w-full flex items-center justify-start">
|
||||
<h2 class="text-[14px] font-[700] text-[#576989]">{{ isMine ? 'لغو شیفت' : 'انتخاب شیفت' }}</h2>
|
||||
</div>
|
||||
</template>
|
||||
<div class="w-full py-4">
|
||||
<p class="text-[12px] font-[600] text-[#3E4C63]">
|
||||
{{ isMine ? 'آیا از لغو این شیفت اطمینان دارید؟' : 'آیا این شیفت به برنامه شما اضافه شود؟' }}
|
||||
</p>
|
||||
<p class="mt-2 text-[11px] font-[600] text-[#7188AD] bg-[#F6F7F9] border border-[#DEE3EB] rounded-lg p-3">
|
||||
{{ shiftLabel }}
|
||||
</p>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="w-full flex items-center justify-end gap-2">
|
||||
<UiButton label="انصراف" size="small" outlined @click="confirmVisible = false" />
|
||||
<UiButton
|
||||
:label="isMine ? 'لغو شیفت' : 'انتخاب شیفت'"
|
||||
size="small"
|
||||
:severity="isMine ? 'danger' : 'success'"
|
||||
:loading="shiftStore.processingId === selectedShift?.id"
|
||||
@click="handleConfirm"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</ClientLayout>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user