This commit is contained in:
Inshal 2024-06-04 03:43:35 +05:00
parent 9f094ad5b0
commit 6e41495bc3
8 changed files with 553 additions and 3 deletions

View File

@ -18,6 +18,10 @@ export const LABS_INFO_API = MAIN_DOMAIN + "/api/admin/labs/"
export const LABS_UPDATE_API = MAIN_DOMAIN + "/api/admin/labs-update/"
export const LABS_DELETE_API = MAIN_DOMAIN + "/api/admin/labs-delete/"
export const MEETING_PRESCREPTIONS_API = MAIN_DOMAIN + "/api/admin/get-patient-prescriptions/"
export const MEETING_NOTES_API = MAIN_DOMAIN + "/api/admin/get-note/"
export const APPOINTMENT_DETAILS_API = MAIN_DOMAIN + "/api/admin/get-appointment/"

View File

@ -0,0 +1,106 @@
<script setup>
import { onMounted, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useStore } from 'vuex';
const store = useStore();
const router = useRouter();
const route = useRoute();
const patientId = route.params.patient_id;
const appointmentId = route.params.id;
const notes = ref([]);
const loadHistoryNotes = async () => {
console.log('Calling loadHistoryNotes');
store.dispatch('updateIsLoading', true);
console.log('Dispatching getHistoryPatientNotes action with', { patient_id: patientId, appointment_id: appointmentId });
// try {
// console.log('Dispatching getHistoryPatientNotes action with', { patient_id: patientId, appointment_id: appointmentId });
await store.dispatch('getHistoryPatientNotes', {
patient_id: patientId,
appointment_id: appointmentId,
});
let notesData = store.getters.getPatientNotes;
if (Array.isArray(notesData)) {
console.log('Fetched notesData:', notesData);
const formattedNotes = notesData
.filter(data => data.note_type === 'Notes')
.map(data => ({
file_url: data.file_url,
note: data.note,
doctor: data.telemedPro.name,
date: formatDateDate(data.created_at),
id: data.id,
}))
.sort((a, b) => b.id - a.id);
notes.value = formattedNotes;
} else {
console.error("getPatientNotes did not return an array", notesData);
}
// } catch (error) {
// console.error("Error loading patient notes:", error);
// } finally {
// store.dispatch('updateIsLoading', false);
// }
};
onMounted(() => {
loadHistoryNotes();
});
const formatDateDate = (date) => {
const messageDate = new Date(date);
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
};
return messageDate.toLocaleDateString('en-US', options).replace(/\//g, '-');
};
const downloadFile = (fileUrl) => {
const link = document.createElement('a');
link.href = fileUrl;
link.download = 'noteFile.png';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
</script>
<template>
<VDialog v-model="store.getters.getIsLoading" width="110" height="150" color="primary">
<VCardText style="color: white !important;">
<div class="demo-space-x">
<VProgressCircular :size="40" color="primary" indeterminate />
</div>
</VCardText>
</VDialog>
<VList class="pb-0" lines="two" v-if="notes.length > 0">
<template v-for="(p_note, index) in notes" :key="index">
<VListItem class="pb-0" border>
<VListItemTitle>
<span class="pb-0">{{ p_note.note }}</span>
<span v-if="p_note.file_url" style="font-size: 12px;float: right;">
<a type="button" @click="downloadFile(p_note.file_url)">
<VIcon>mdi-file-image</VIcon>
</a>
</span>
<p class="text-start fs-5 mb-0 pb-0 text-grey">
<small>{{ p_note.doctor }}</small>
</p>
<p class="text-end fs-5 mb-0 pb-0 text-grey"><small>{{ p_note.date }}</small></p>
</VListItemTitle>
</VListItem>
<VDivider v-if="index !== notes.length - 1" />
</template>
</VList>
<template v-else>
<VCard>
<VAlert border="start" color="#003152" variant="tonal">
<div class="text-center">No data found</div>
</VAlert>
</VCard>
</template>
</template>

View File

@ -0,0 +1,244 @@
<script setup>
import { useRoute, useRouter } from 'vue-router';
import { useStore } from 'vuex';
const store = useStore();
const router = useRouter()
const route = useRoute()
const itemsPrescriptions = ref([]);
const patientId = route.params.patient_id;
const appointmentId = route.params.id;
const prescription = computed(async () => {
console.log('computed=====')
await getprescriptionList()
// await store.dispatch('getHistoryPrescription')
// notes.value = store.getters.getHistoryPrescription;
// console.log("getHistoryPrescription", notes.value);
// store.dispatch('updateIsLoading', false)
});
const getprescriptionList = async () => {
await store.dispatch('getPrescriptions', {
patient_id: patientId,
appointment_id: appointmentId,
})
let prescriptions = store.getters.getPrescriptionList
console.log("BeforeOverviewItem", prescriptions);
// itemsPrescriptions.value = store.getters.getPrescriptionList
for (let data of prescriptions) {
let dataObject = {}
dataObject.brand = data.brand
dataObject.direction_one = data.direction_one
dataObject.direction_quantity = data.direction_quantity
dataObject.direction_two = data.direction_two
dataObject.date = formatDateDate(data.date)
dataObject.dosage = data.dosage
dataObject.from = data.from
dataObject.name = data.name
dataObject.quantity = data.quantity
dataObject.doctor = data.doctor.name
dataObject.refill_quantity = data.refill_quantity
dataObject.status = data.status
dataObject.comments = data.comments
itemsPrescriptions.value.push(dataObject)
}
itemsPrescriptions.value.sort((a, b) => {
return b.id - a.id;
});
console.log("OverviewItem", itemsPrescriptions.value);
};
const formatDateDate = (date) => {
const messageDate = new Date(date);
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
};
return messageDate.toLocaleDateString('en-US', options).replace(/\//g, '-');
};
const getStatusColor = (status) => {
switch (status) {
case 'pending':
return 'warning'; // Use Vuetify's warning color (typically yellow)
case 'shipped':
return '#45B8AC'; // Use Vuetify's primary color (typically blue)
case 'delivered':
return 'green';
case 'returned':
return 'red';
case 'results':
return 'blue';
default:
return 'grey'; // Use Vuetify's grey color for any other status
}
};
</script>
<template>
<template v-if="itemsPrescriptions">
<VExpansionPanels variant="accordion" v-if="prescription">
<VExpansionPanel v-for="item in itemsPrescriptions" :key="item">
<VExpansionPanelTitle collapse-icon="mdi-chevron-down" expand-icon="mdi-chevron-right">
<p class=""><b> {{ item.name }}</b>
<br />
<div class=" pt-2">#{{ appointmentId }} By {{ item.doctor }}</div>
<div class=" pt-2">{{ item.date }}</div>
</p>
<v-row>
</v-row>
<span class="v-expansion-panel-title__icon badge text-warning"
v-if="item.status == null">Pending</span>
<span class="v-expansion-panel-title__icon badge" v-else>
<v-chip :color="getStatusColor(item.status)" label size="small" variant="text">
{{ item.status }}
</v-chip></span>
</VExpansionPanelTitle>
<VExpansionPanelText class="pt-0">
<v-row class='mt-1'>
<v-col cols="12" md="4" sm="6">
<p class='heading'><b>Brand:</b></p>
</v-col>
<v-col cols="12" md="4" sm="6">
<p>{{ item.brand }}</p>
</v-col>
</v-row>
<v-row class='mt-1'>
<v-col cols="12" md="4" sm="6">
<p class='heading'><b>From:</b></p>
</v-col>
<v-col cols="12" md="4" sm="6">
<p>{{ item.from }}</p>
</v-col>
</v-row>
<v-row class='mt-1'>
<v-col cols="12" md="4" sm="6">
<p class='heading'><b>Dosage:</b></p>
</v-col>
<v-col cols="12" md="4" sm="6">
<p>{{ item.dosage }}</p>
</v-col>
</v-row>
<v-row class='mt-1'>
<v-col cols="12" md="4" sm="6">
<p class='heading'><b>Quantity:</b></p>
</v-col>
<v-col cols="12" md="4" sm="6">
<p>{{ item.quantity }}</p>
</v-col>
</v-row>
<v-row class='mt-1'>
<v-col cols="12" md="4" sm="6">
<p class='heading'><b>Direction Quantity:</b></p>
</v-col>
<v-col cols="12" md="8" sm="6">
<p>{{ item.direction_quantity }}</p>
</v-col>
</v-row>
<v-row class='mt-1'>
<v-col cols="12" md="4" sm="6">
<p class='heading'><b>Direction One:</b></p>
</v-col>
<v-col cols="12" md="8" sm="6">
<p>{{ item.direction_one }} </p>
</v-col>
</v-row>
<v-row class='mt-1'>
<v-col cols="12" md="4" sm="6">
<p class='heading'><b>Direction Two:</b></p>
</v-col>
<v-col cols="12" md="8" sm="6">
<p>{{ item.direction_two }} </p>
</v-col>
</v-row>
<v-row class='mt-1'>
<v-col cols="12" md="4" sm="6">
<p class='heading'><b>Refill Quantity:</b></p>
</v-col>
<v-col cols="12" md="8" sm="6">
<p>{{ item.refill_quantity }}</p>
</v-col>
</v-row>
<v-row class='mt-1'>
<v-col cols="12" md="4" sm="6">
<p class='heading'><b>Status:</b></p>
</v-col>
<v-col cols="12" md="8" sm="6">
<p v-if="item.status == null" class="text-warning">Pending</p>
<p v-else>{{ item.status }}</p>
</v-col>
</v-row>
<v-row class='mt-1'>
<v-col cols="12" md="4" sm="6">
<p class='heading'><b>Comments:</b></p>
</v-col>
<v-col cols="12" md="8" sm="8">
<p>{{ item.comments }} </p>
</v-col>
</v-row>
</VExpansionPanelText>
</VExpansionPanel>
</VExpansionPanels>
</template>
<template v-else>
<VCard>
<VAlert border="start" color="#003152" variant="tonal">
<div class="text-center">No data found</div>
</VAlert>
</VCard>
</template>
</template>
<style lang="scss">
button.v-expansion-panel-title {
background-color: #003152 !important;
color: #fff;
}
button.v-expansion-panel-title.bg-secondary {
background-color: #003152 !important;
color: #fff;
}
button.v-expansion-panel-title {
background-color: #003152 !important;
color: #fff;
}
span.v-expansion-panel-title__icon {
color: #fff
}
// button.v-expansion-panel-title.bg-secondary {
// background-color: rgba(var(--v-theme-primary), var(--v-activated-opacity)) !important;
// }
// button.v-expansion-panel-title {
// background-color: rgba(var(--v-theme-primary), var(--v-activated-opacity)) !important;
// }
// button.v-expansion-panel-title.v-expansion-panel-title--active {
// background-color: rgba(var(--v-theme-primary), var(--v-activated-opacity)) !important;
// }
.v-expansion-panel {
background-color: #fff;
border-radius: 16px;
box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1);
margin-bottom: 10px;
overflow: hidden;
transition: box-shadow 0.3s ease;
}
</style>

View File

@ -0,0 +1,79 @@
<script setup>
import Notes from '@/pages/pages/patient-meetings/notes.vue';
import Prescription from '@/pages/pages/patient-meetings/prescription.vue';
import moment from 'moment';
import { onMounted, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useStore } from 'vuex';
const store = useStore();
const router = useRouter();
const route = useRoute();
const patientId = route.params.patient_id;
const appointmentId = route.params.id;
const currentTab = ref(0);
const appointmentID = ref();
const doctorName = ref();
const startTime = ref();
const endTime = ref();
const duration = ref();
const appointmentData = ref(null);
onMounted(async () => {
store.dispatch('updateIsLoading', true);
await store.dispatch('getAppointmentByIdAgent', {
patient_id: patientId,
appointment_id: appointmentId,
});
appointmentData.value = store.getters.getSinglePatientAppointment;
appointmentID.value = appointmentId;
doctorName.value = appointmentData.value.agent_name;
startTime.value = appointmentData.value.start_time;
endTime.value = appointmentData.value.end_time;
duration.value = totalCallDuration(startTime.value, endTime.value);
localStorage.setItem('meetingPatientAppointmentId', appointmentID.value);
store.dispatch('updateIsLoading', false);
});
const totalCallDuration = (start_time, end_time) => {
const startMoment = moment(start_time);
const endMoment = moment(end_time);
const duration = moment.duration(endMoment.diff(startMoment));
const hours = duration.hours();
const minutes = duration.minutes();
const seconds = duration.seconds();
return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
};
</script>
<template>
<VCard>
<VCardText>
<h3 v-if="appointmentID"> #{{ appointmentID }} By {{ doctorName }} </h3>
<span> Meeting duration: <b>{{ duration }}</b></span>
</VCardText>
<div class="d-flex">
<div>
<VTabs v-model="currentTab" direction="vertical">
<VTab>
<VIcon start icon="tabler-edit" />
Notes
</VTab>
<VTab>
<VIcon start icon="tabler-lock" />
Prescriptions
</VTab>
</VTabs>
</div>
<VCardText>
<VWindow v-model="currentTab" class="ms-3">
<VWindowItem>
<Notes />
</VWindowItem>
<VWindowItem>
<Prescription />
</VWindowItem>
</VWindow>
</VCardText>
</div>
</VCard>
</template>

View File

@ -99,6 +99,10 @@ onMounted(async () => {
await getPatientMeetingList();
});
onUnmounted(() => {});
const historyDetail = (item) => {
console.log('item', item)
router.push('/admin/patient/meeting-details/' + route.params.id + '/' + item.id);
}
</script>
<template>
@ -133,7 +137,8 @@ onUnmounted(() => {});
<!-- Actions -->
<template #item.actions="{ item }">
<div class="d-flex gap-1">
<!-- Your action buttons go here -->
<VBtn class="text-capitalize text-white" @click="historyDetail(item)"> Detail
</VBtn>
</div>
</template>
</v-data-table>

View File

@ -48,6 +48,11 @@ export const routes = [
name: 'admin-patient-meeitngs',
component: () => import('@/pages/patients/meetings.vue'),
},
{
path: '/admin/patient/meeting-details/:patient_id/:id',
name: 'admin-patient-meeitng-details',
component: () => import('@/pages/patients/meeting-details.vue'),
},
{
path: '/admin/providers',
name: 'admin-providers',

View File

@ -2,9 +2,12 @@ import axios from 'axios';
import { createStore } from 'vuex';
import {
APPOINTMENT_DETAILS_API,
LABS_DELETE_API,
LABS_LIST_API,
LABS_UPDATE_API,
MEETING_NOTES_API,
MEETING_PRESCREPTIONS_API,
PATIENT_DELETE_API,
PATIENT_LIST_API,
PATIENT_MEETING_LIST_API,
@ -22,7 +25,10 @@ export default createStore({
patientList:[],
patientMeetingList:[],
providersList:[],
labsList:[]
labsList:[],
singlePatientAppointment: null,
patientPrescription:null,
patientNotes: null,
},
mutations: {
setLoading(state, payload) {
@ -40,7 +46,17 @@ export default createStore({
},
setLabsList(state, payload) {
state.labsList = payload
}
},
setPrescription(state, payload) {
state.patientPrescription = payload
},
setSinglePatientAppointment(state, payload) {
state.singlePatientAppointment = payload
},
setPatientNotes(state, payload) {
state.patientNotes = payload
},
},
actions: {
@ -276,6 +292,85 @@ export default createStore({
console.error('Error:', error);
});
},
async getAppointmentByIdAgent ({commit,state},payload){
commit('setLoading', true)
await axios.post(APPOINTMENT_DETAILS_API+payload.patient_id + '/' + payload.appointment_id, {}, {
headers: {
'Authorization': `Bearer ${localStorage.getItem('admin_access_token')}`,
}
}) .then(response => {
commit('setLoading', false)
console.log('Response Notes:', response.data.data);
commit('setSinglePatientAppointment',response.data.data)
})
.catch(error => {
commit('setLoading', false)
console.error('Error:', error);
});
},
async getPrescriptions ({commit,state},payload){
commit('setLoading', true)
await axios.post(MEETING_PRESCREPTIONS_API+payload.patient_id + '/' + payload.appointment_id, {}, {
headers: {
'Authorization': `Bearer ${localStorage.getItem('admin_access_token')}`,
}
}) .then(response => {
commit('setLoading', false)
let doctor={}
let itemsPrescriptions=[]
for (let data of response.data) {
let dataObject = {}
dataObject.first_name = data.patient.first_name
dataObject.last_name = data.patient.last_name
dataObject.gender = data.patient.gender
dataObject.dob = data.patient.dob
dataObject.patient_address = data.patient.address+' '+ data.patient.city+' '+ data.patient.state +' ' +data.patient.country
dataObject.name = data.prescription.name
dataObject.brand = data.prescription.brand
dataObject.from = data.prescription.from
dataObject.direction_quantity = data.prescription.direction_quantity
dataObject.dosage = data.prescription.dosage
dataObject.quantity = data.prescription.quantity
dataObject.refill_quantity = data.prescription.refill_quantity
dataObject.actions = ''
dataObject.id = data.prescription.id
dataObject.comments = data.comments
dataObject.direction_one = data.direction_one
dataObject.direction_two = data.direction_two
dataObject.doctor = data.telemedPro
dataObject.status = data.status
dataObject.date = data.created_at
dataObject.agent_sign = data.telemedPro.name
dataObject.medical_license_number = data.telemedPro.medical_license_number
itemsPrescriptions.push(dataObject)
}
console.log('Response Notes:', response.data);
commit('setPrescription',itemsPrescriptions)
})
.catch(error => {
commit('setLoading', false)
commit('setPrescription',null)
console.error('Error:', error);
});
},
async getHistoryPatientNotes ({commit,state},payload){
commit('setLoading', true)
await axios.post(MEETING_NOTES_API+payload.patient_id + '/' + payload.appointment_id, {}, {
headers: {
'Authorization': `Bearer ${localStorage.getItem('admin_access_token')}`,
}
}) .then(response => {
commit('setLoading', false)
console.log('Response Notes:', response.data.data);
commit('setPatientNotes',response.data.data)
})
.catch(error => {
commit('setLoading', false)
console.error('Error:', error);
});
},
},
getters: {
getIsLoading(state){
@ -294,5 +389,14 @@ export default createStore({
getLabsList(state){
return state.labsList
},
getSinglePatientAppointment(state){
return state.singlePatientAppointment
},
getPrescriptionList(state){
return state.patientPrescription
},
getPatientNotes(state){
return state.patientNotes
},
}
})

3
typed-router.d.ts vendored
View File

@ -147,9 +147,12 @@ declare module 'vue-router/auto/routes' {
'pages-icons': RouteRecordInfo<'pages-icons', '/pages/icons', Record<never, never>, Record<never, never>>,
'pages-misc-coming-soon': RouteRecordInfo<'pages-misc-coming-soon', '/pages/misc/coming-soon', Record<never, never>, Record<never, never>>,
'pages-misc-under-maintenance': RouteRecordInfo<'pages-misc-under-maintenance', '/pages/misc/under-maintenance', Record<never, never>, Record<never, never>>,
'pages-patient-meetings-notes': RouteRecordInfo<'pages-patient-meetings-notes', '/pages/patient-meetings/notes', Record<never, never>, Record<never, never>>,
'pages-patient-meetings-prescription': RouteRecordInfo<'pages-patient-meetings-prescription', '/pages/patient-meetings/prescription', Record<never, never>, Record<never, never>>,
'pages-pricing': RouteRecordInfo<'pages-pricing', '/pages/pricing', Record<never, never>, Record<never, never>>,
'pages-typography': RouteRecordInfo<'pages-typography', '/pages/typography', Record<never, never>, Record<never, never>>,
'pages-user-profile-tab': RouteRecordInfo<'pages-user-profile-tab', '/pages/user-profile/:tab', { tab: ParamValue<true> }, { tab: ParamValue<false> }>,
'patients-meeting-details': RouteRecordInfo<'patients-meeting-details', '/patients/meeting-details', Record<never, never>, Record<never, never>>,
'patients-meetings': RouteRecordInfo<'patients-meetings', '/patients/meetings', Record<never, never>, Record<never, never>>,
'patients-patients': RouteRecordInfo<'patients-patients', '/patients/patients', Record<never, never>, Record<never, never>>,
'providers-providers': RouteRecordInfo<'providers-providers', '/providers/providers', Record<never, never>, Record<never, never>>,