Created
November 10, 2022 11:51
-
-
Save alimuradov/8f3619fe97f0a294e406ca76cfca31df to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div> | |
<div class="flex flex-row justify-end mb-4"> | |
<div class="flex-1"></div> | |
<ClinicDropdown | |
@set-clinic="setClinicCalendar" | |
:clinic_id="clinicId" | |
:inputId="clinicId" | |
class="basis-1/5 justify-end" | |
/> | |
</div> | |
<FullCalendar :options="calendarOptions" ref="calendar" /> | |
<AppointmentDropdown ref="appointmentMenuRef" /> | |
</div> | |
</template> | |
<script setup lang="ts"> | |
import { ref, onMounted, h } from "vue"; | |
import "@fullcalendar/core/vdom"; // solves problem with Vite | |
import FullCalendar from "@fullcalendar/vue3"; | |
import type { | |
DateSelectArg, | |
EventApi, | |
CalendarOptions, | |
} from "@fullcalendar/vue3"; | |
import dayGridPlugin from "@fullcalendar/daygrid"; | |
import timeGridPlugin from "@fullcalendar/timegrid"; | |
import resourceTimeGridPlugin from "@fullcalendar/resource-timegrid"; | |
import resourceDayGridPlugin from "@fullcalendar/resource-daygrid"; | |
import interactionPlugin from "@fullcalendar/interaction"; | |
import ruLocale from "@fullcalendar/core/locales/ru"; | |
import fetchApi from "@/api/appointment"; | |
import fetchUser from "@/api/user"; | |
import { useUserStore } from "@/stores/modules/user"; | |
import { $vfm } from "vue-final-modal"; | |
import AppointmentAddForm from "@/components/Forms/appointment/AppointmentAddForm.vue"; | |
import ClinicDropdown from "@/components/Dropdowns/ClinicDropdown.vue"; | |
import type { AppointmentCreateModal } from "@/api/appointment/model"; | |
import { useToast } from "vue-toastification"; | |
import { createPopper } from '@popperjs/core'; | |
import AppointmentDropdown from "@/components/Dropdowns/appointment/AppointmentDropdown.vue"; | |
const toast = useToast(); | |
const userStore = useUserStore(); | |
const clinicId = ref(userStore.getClinicId); | |
const uniodId = ref<string>(); | |
const appointmentMenuRef = ref(null); | |
const calendar = ref(null); | |
interface DoctorResource { | |
id: string; | |
title: string; | |
eventBackgroundColor: string; | |
} | |
const doctorsResources = ref<DoctorResource[]>([]); | |
const handleAddAppointment = async (value: AppointmentCreateModal) => { | |
await fetchApi | |
.createAppointment(value) | |
.then((res) => { | |
if (res) { | |
calendar.value.calendar.addEvent({ | |
id: res.id, | |
title: "dggfgf", | |
start: res.start, | |
end: res.end, | |
allDay: false, | |
resourceId: res.doctor_id, | |
}); | |
} | |
toast.success("Запись на прием добавлена"); | |
calendar.value.calendar.getEvents(); | |
}) | |
.catch(() => { | |
toast.error("Не удалось добавить запись на прием"); | |
}); | |
}; | |
const handleDateSelect = (selectInfo: DateSelectArg) => { | |
$vfm.show({ | |
component: AppointmentAddForm, | |
bind: { | |
start: selectInfo.start, | |
end: selectInfo.end, | |
clinic_id: clinicId.value, | |
doctor_id: selectInfo.resource?._resource.id, | |
}, | |
on: { | |
"add-appointment": handleAddAppointment, | |
}, | |
}); | |
const calendarApi = selectInfo.view.calendar; | |
calendarApi.unselect(); // clear date selection | |
}; | |
const setClinicCalendar = (clinic_Id: string, union_id: string) => { | |
if (clinic_Id) { | |
clinicId.value = clinic_Id; | |
calendar.value.calendar.refetchEvents(); | |
} | |
if (union_id) { | |
uniodId.value = union_id; | |
calendar.value.calendar.refetchEvents(); | |
} | |
}; | |
function isNotEmpty(str: string | undefined) { | |
if (str == undefined) return false; | |
if (str.trim() == "") return false; | |
return true; | |
} | |
function getIconFromstatus(status: number) { | |
if (status == 0) { | |
return "<i class='fa-regular fa-clock'></i>"; | |
} else if (status == 1) { | |
return "<i class='fa-solid fa-check'></i>"; | |
} else if (status == 2) { | |
return "<i class='fa-solid fa-ban'></i>"; | |
} | |
} | |
onMounted(async () => { | |
const params = { | |
role: "doctor", | |
clinic_id: clinicId.value, | |
}; | |
await fetchUser | |
.getUsers(params) | |
.then((res) => { | |
if (res.status == 200 && res.data.items.length > 0) { | |
Array.prototype.forEach.call(res.data.items, function (ell) { | |
doctorsResources.value.push({ | |
id: ell.id, | |
title: ell.first_name + " " + ell.last_name, | |
eventBackgroundColor: ell.color, | |
}); | |
}); | |
} | |
}) | |
.catch((er) => { | |
console.log(er); | |
}); | |
}); | |
const calendarOptions = { | |
locale: ruLocale, | |
schedulerLicenseKey: "CC-Attribution-NonCommercial-NoDerivatives", | |
allDaySlot: false, | |
plugins: [ | |
dayGridPlugin, | |
interactionPlugin, | |
timeGridPlugin, | |
resourceTimeGridPlugin, | |
], | |
headerToolbar: { | |
left: "prev,next today addAppointment", | |
center: "title", | |
right: "dayGridMonth,timeGridWeek,timeGridDay,resourceTimeGridPlugin", | |
}, | |
views: { | |
resourceTimeGridPlugin: { | |
type: "resourceTimeGridDay", | |
duration: { days: 1 }, | |
buttonText: "По врачам", | |
}, | |
}, | |
resources: doctorsResources.value, | |
initialView: "timeGridWeek", | |
slotMinTime: "08:00:00", | |
slotMaxTime: "21:00:00", | |
editable: true, | |
selectable: true, | |
select: handleDateSelect, | |
customButtons: { | |
addAppointment: { | |
text: "Добавить прием", | |
click: function () { | |
$vfm.show({ component: AppointmentAddForm }); | |
}, | |
}, | |
}, | |
events: function (info, successCallback, failureCallback) { | |
// const userStore = useUserStore(); | |
fetchApi | |
.eventsFeed({ | |
start: info.start, | |
end: info.end, | |
clinic_id: clinicId.value, | |
}) | |
.then((res) => { | |
successCallback( | |
Array.prototype.slice.call(res.data).map(function (eventEl) { | |
return { | |
resourceId: eventEl["doctor_id"], | |
title: | |
(isNotEmpty(eventEl["patient"]["last_name"]) | |
? eventEl["patient"]["last_name"] | |
: "") + | |
" " + | |
(isNotEmpty(eventEl["patient"]["first_name"]) | |
? eventEl["patient"]["first_name"] | |
: "") + | |
(isNotEmpty(eventEl["patient"]["patronymic"]) | |
? " " + eventEl["patient"]["patronymic"][0] + "." | |
: ""), | |
start: eventEl["start"], | |
end: eventEl["end"], | |
extendedProps: { | |
id: eventEl["id"], | |
status: eventEl["status"], | |
}, | |
}; | |
}) | |
); | |
}) | |
.catch((err) => failureCallback(err)); | |
}, | |
eventResize: async function (info) { | |
await fetchApi | |
.updateAppointment({ | |
id: info.event.extendedProps["id"], | |
start: info.event.start.toISOString(), | |
end: info.event.end.toISOString(), | |
}) | |
.catch(() => { | |
toast.warning("Не удалось изменить диапазон"); | |
}); | |
}, | |
eventDrop: async (info) => { | |
await fetchApi | |
.updateAppointment({ | |
id: info.event.extendedProps["id"], | |
start: info.event.start.toISOString(), | |
end: info.event.end.toISOString(), | |
}) | |
.catch(() => { | |
toast.warning("Не удалось изменить диапазон"); | |
}); | |
}, | |
eventClick: function(info) { | |
info.jsEvent.preventDefault(); | |
console.log(this); | |
createPopper(info.el, this.$refs.appointmentMenuRef, { | |
placement: 'bottom', | |
}); | |
}, | |
eventContent: function (args) { | |
const status = args.event._def.extendedProps.status; | |
let text = getIconFromstatus(status) + " "; | |
text = text + args.event.title + "</br>"; | |
text = text + args.timeText; | |
return { | |
html: text, | |
}; | |
}, | |
} as CalendarOptions; | |
</script> | |
<style> | |
.fc-license-message { | |
display: none !important; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment