purityselect/resources/js/pages/join-meeting.vue
2024-10-25 01:05:27 +05:00

1312 lines
46 KiB
Vue

<script setup>
import axios from '@axios';
import "@core/utils/external_api";
// import Echo from 'laravel-echo';
import phpUnserialize from 'phpunserialize';
import { ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import videocall from '../views/videocall/videocall.vue';
const router = useRouter()
const route = useRoute()
const api = ref();
const count = ref(5);
const showIframe = ref(true);
const activeTab1 = ref('info');
const overlay = ref(false);
const userAbout = ref('');
const patientName = ref();
const userStatus = ref('active');
const settingsGroup = ref([]);
const twoStepVerification = ref(true);
const picker = ref();
const docpicker = ref();
const isDialogVisible = ref(false)
const isLoadingVisible = ref(false)
const isSuccessVisible = ref(false)
const isTonalSnackbarVisible = ref(false)
const patientUpdatedVisible = ref(false)
const patientResponse = ref(false)
const chooseDate = ref([]);
const selectedDate = ref();
const bookDate = ref();
const selectedtime = ref();
const selectedDoctime = ref();
const docSlotTime = ref();
const doctorList = ref([]);
const selectedDoctor = ref();
const questions = ref([]);
const answers = ref([]);
const refVForm = ref();
const editLocation = ref();
const selectedState = ref(null);
const editAddress = ref();
const editCountry = ref();
const editCity = ref();
const editstate = ref(null);
const editZip = ref();
const labName = ref();
const labAddress = ref();
const labCity = ref();
const labState = ref();
const labLat = ref();
const labLong = ref();
const labDistance = ref();
const labphone = ref();
const showLabInfoTab = ref(false)
const showDatePicker = ref(false)
const showTimeSlots = ref(false)
const confirmSlotDialog = ref(false)
const showLabSpinner = ref(false)
const labBookedDate = ref()
const docBookedDate = ref()
const showBookLabBtn = ref(true)
const showBookDocBtn = ref(false)
const showDocCalender = ref(false)
const showDocRadio = ref(false)
const recordVid = ref(true)
const videoCol = ref(12)
const infoCol = ref('display:none')
const agentId = ref(localStorage.getItem('agent_id'))
const token = ref(localStorage.getItem('agent_meeting_id'))
const isLoadingVisibleDiv = ref(false)
const selectedLab = ref([])
const activeQuestionIndex = ref(null);
const toggleActive = (index) => {
activeQuestionIndex.value = activeQuestionIndex.value === index ? null : index;
};
const isActive = (index) => {
return activeQuestionIndex.value === index;
};
const mobileWidthThreshold = 600; // Adjust this value based on your design needs
const isMobile = ref(window.innerWidth < mobileWidthThreshold);
const handleResize = () => {
isMobile.value = window.innerWidth < mobileWidthThreshold;
};
const errors = ref({
editLocation: undefined,
editAddress: undefined,
editCity: undefined,
})
const labLocations = ref([]);
const microphones = ref([
{
title: "Default Microphone",
id: 1,
index: 1
}, {
title: "Default Microphone 2",
id: 2,
index: 2
}
])
const speakers = ref([
{
title: "Default Speaker",
id: 1,
index: 1
}, {
title: "Default Speaker 2",
id: 2,
index: 2
}
])
const latitude = ref()
const longitude = ref()
const responseUrl = ref(localStorage.getItem('meeting-url'));
onMounted(() => {
window.addEventListener('resize', handleResize);
document.addEventListener('mousemove', handleMouseMove)
const name = "agent";
const domain = "8x8.vc";
isLoadingVisible.value = true;
const patient_id = localStorage.getItem('patient_id');
// window.Pusher = Pusher;
// const key = 'bc8bffbbbc49cfa39818';
// const cluster = 'mt1';
// let echo = new Echo({
// broadcaster: 'pusher',
// key: key,
// cluster: cluster,
// forceTLS: true,
// auth: {
// headers: {
// Authorization: 'Bearer ' + localStorage.getItem('access_token'),
// },
// },
// });
// echo.private('appointment-' + localStorage.getItem('patient_appiontment_id'))
// .listen('AppointmentQuestion', (e) => {
// console.log("Patient AppointmentQuestionPost", e);
// echo.leave('dhkjkiplqe84sdaqf17nqg')
// });
//Get patient Info
axios.post('/agent/api/get-patient-info/' + patient_id)
.then(r => {
console.log("Response", r.data);
patientName.value = r.data.first_name + " " + r.data.last_name + ' (' + r.data.age + 'yrs old)';
editCity.value = r.data.city
editLocation.value = ''
editAddress.value = r.data.address
latitude.value = r.data.lat
longitude.value = r.data.long
editstate.value = r.data.state
editZip.value = r.data.zip_code
editCountry.value = r.data.country
localStorage.setItem('p_city', editCity.value);
localStorage.setItem('p_location', editLocation.value);
localStorage.setItem('p_address', editAddress.value);
}).catch(error => {
console.log("Get Patient", error);
isLoadingVisible.value = false;
});
//Get Doctor List
axios.post('/agent/api/get-doctors-list')
.then(r => {
console.log("Response", r.data);
doctorList.value = r.data;
isLoadingVisible.value = false;
}).catch(error => {
console.log("Get Patient", error);
doctorList.value = [];
isLoadingVisible.value = false;
});
axios.post('/agent/api/patient-recording-switch-get/' + agentId.value)
.then(response => {
console.log('rec ', response.data.recording_switch)
if (response.data.recording_switch == 1)
recordVid.value = true
else
recordVid.value = false
})
.catch(error => {
console.error('error recording ', error.response.data);
});
const access_token = localStorage.getItem('access_token');
const options = {
roomName: 'vpaas-magic-cookie-769c471e6c614755b51aea9447a554fc/' + localStorage.getItem('agent_meeting_id'),
// jwt: "{{ $jassToken }}",
userInfo: {
displayName: name,
},
parentNode: document.querySelector("#jaas-container"),
};
// api.value = new JitsiMeetExternalAPI(domain, options);
// api.value.addEventListener('videoConferenceLeft', (event) => {
// // The user has left the video conference, perform actions accordingly
// console.log('Agent left the Jitsi call:', event);
// const patient_appiontment_id = localStorage.getItem('patient_appiontment_id');
// axios.post('/agent/api/end-call/'+patient_id+'/'+patient_appiontment_id ,{
// headers: {
// 'Content-Type': 'application/json',
// 'Authorization': `Bearer ${access_token}`
// // 'Accept': 'application/json',
// }
// })
// .then(response => {
// console.log("end Call", response.data);
// router.push('/queue-users');
// })
// .catch(error => {
// console.error(error.response.data);
// // isLoadingVisible.value = false;
// });
// });
axios.post('agent/api/questions-list')
.then(r => {
console.log("Question", r.data);
questions.value = r.data;
}).catch(error => {
console.log("ErrorResponse", error);
isLoadingVisible.value = false;
});
});
onBeforeUnmount(() => {
window.removeEventListener('resize', handleResize);
});
onUnmounted(() => {
document.removeEventListener('mousemove', handleMouseMove)
// Clean up the API instance when the component is unmounted
if (api.value) {
api.value.dispose();
}
});
const minDate = new Date(); // Initialize minDate as a Date object
minDate.setHours(0, 0, 0, 0); // Set time to midnight
const maxDate = new Date(new Date().getFullYear() + 1, 11, 31); // Set maxDate to one year from now
const allowedDates = computed(() => {
const dates = [];
const currentDate = new Date(minDate.value);
while (currentDate <= maxDate) {
dates.push(currentDate.toISOString().substr(0, 10));
currentDate.setDate(currentDate.getDate() + 1);
}
return dates;
});
const onSubmit = () => {
refVForm.value?.validate().then(({ valid: isValid }) => {
if (isValid)
updateInfo()
})
}
const updateInfo = () => {
console.log("Zip", editZip.value);
// isLoadingVisible.value = true;
const patient_id = localStorage.getItem('patient_id');
axios.post('/agent/api/update-patient-info/' + patient_id, {
city: editCity.value,
address: editAddress.value,
state: editstate.value,
zip_code: editZip.value,
country: editCountry.value
})
.then(r => {
console.log("patientUpdated", r.data);
isLoadingVisible.value = false;
isTonalSnackbarVisible.value = true;
patientUpdatedVisible.value = true;
patientResponse.value = r.data.message;
editLocation.value = editLocation.value;
activeTab1.value = 'lab_locator';
findLab();
}).catch(error => {
console.log("error", error);
isLoadingVisible.value = false;
});
}
const findLab = async () => {
videoCol.value = 8
activeTab1.value = 'lab_locator';
infoCol.value = 'dispaly:block'
showLabSpinner.value = true
labLocations.value = [];
let completeAddress = (editAddress.value ? editAddress.value + ', ' : '') +
(editCity.value ? editCity.value + ', ' : '') +
(editstate.value ? editstate.value + ' ' : '') +
(editZip.value ? editZip.value + ', ' : '') +
(editCountry.value ? editCountry.value : '');
// Remove trailing comma and space if present
completeAddress = completeAddress.replace(/,\s*$/, '');
axios.post('/api/lab-address', {
address: completeAddress,//'27560 102nd Ave, Donahue IA',//editAddress.value,
city: editCity.value,//'Donahue',//,editCity.value,
state: editstate.value,//'IA' ,// editstate.value,
zip: editZip.value,//'27560',//editZip.value,
lat: latitude.value,
long: longitude.value
}).then((response) => {
console.log('Lab List ', response.data.data.lc_psc_locator.psc_locator_app.settings.labs)
let labs = response.data.data.lc_psc_locator.psc_locator_app.settings.labs
labs.forEach(lab => {
let dataObject = {};
dataObject.lat = lab.address.lat;
dataObject.lng = lab.address.lng;
dataObject.city = lab.address.city;
dataObject.state = lab.address.stateAbbr;
dataObject.locatorId = lab.locatorId;
dataObject.lab_name = lab.name;
dataObject.address = lab.address.street + ',' + lab.address.city + ',' + lab.address.stateAbbr + ',' + lab.address.postalCode;
dataObject.phone = lab.phone
dataObject.distanceFromStartingPoint = lab.distanceFromStartingPoint + ' mi'
console.log('LAb ID', dataObject.locatorId, ' - ', lab.locatorId, dataObject.lat, dataObject.lng)
labLocations.value.push(dataObject);
});
labLocations.value.sort((a, b) => a.distanceFromStartingPoint.localeCompare(b.distanceFromStartingPoint))
showLabSpinner.value = false
console.log('LAb ', labLocations.value)
})
.catch((error) => {
showLabSpinner.value = false
console.error('Error fetching LabCorp locations:', error);
});
};
const editInfo = () => {
// Implement edit info logic
activeTab1.value = 'edit_form';
};
const backToInfo = () => {
// Implement back to info logic
activeTab1.value = 'lab_locator';
};
const saveAnswers = () => {
isLoadingVisible.value = true;
console.log("123", questions.value);
console.log("1231", answers.value);
const patient_id = localStorage.getItem('patient_id');
const appiontment_id = localStorage.getItem('patient_appiontment_id');
let ans = answers.value.map((value, key) => ({
question_id: key,
answer: value,
})).filter(entry => entry.answer); // Filter out entries where 'answer' is empty or falsy
// };
let qaData = Array({ 'patient_id': patient_id, 'answers': ans });
console.log(JSON.stringify(qaData));
// You can send the jsonData to your server or use it as needed
axios.post('/agent/api/question-answer/' + patient_id + '/' + appiontment_id,
{
data: ans
}
)
.then(response => {
console.log('answer api', response.data)
isTonalSnackbarVisible.value = true;
patientResponse.value = response.data.message;
isLoadingVisible.value = false;
// console.log(chooseDate);
// router.push('/queue-users');
})
.catch(error => {
isLoadingVisible.value = false;
console.error(error);
});
};
const backToLabLoc = () => {
// Implement back to lab locator logic
activeTab1.value = 'info';
showLabInfoTab.value = false;
};
const backToLabList = () => {
// Implement back to lab locator logic
activeTab1.value = 'lab_locator';
showLabInfoTab.value = false;
};
const datepick = () => {
isLoadingVisible.value = true;
chooseDate.value = '';
selectedDate.value = '';
if (picker.value) {
const selectedDate = new Date(picker.value);
const year = selectedDate.getFullYear();
const month = (selectedDate.getMonth() + 1).toString().padStart(2, '0'); // Adding 1 because months are zero-indexed
const day = selectedDate.getDate().toString().padStart(2, '0');
const formattedDate = `${year}-${month}-${day}`;
labBookedDate.value = `${month}-${day}-${year}`;
bookDate.value = formattedDate;
console.log("Test", bookDate.value, picker.value);
isLoadingVisible.value = false;
if (formattedDate) {
axios.post('/agent/api/available-slots/' + formattedDate)
.then(response => {
console.log("Data", response.data.available_slots);
chooseDate.value = response.data.available_slots;
isLoadingVisible.value = false;
showTimeSlots.value = true;
showDatePicker.value = false
// console.log(chooseDate);
})
.catch(error => {
console.error(error.response.data);
});
} else {
chooseDate.value = [];
}
}
}
const datePickDoc = () => {
isLoadingVisible.value = true;
chooseDate.value = '';
selectedDate.value = '';
if (docpicker.value) {
const selectedDate = new Date(docpicker.value);
const year = selectedDate.getFullYear();
const month = (selectedDate.getMonth() + 1).toString().padStart(2, '0'); // Adding 1 because months are zero-indexed
const day = selectedDate.getDate().toString().padStart(2, '0');
const formattedDate = `${year}-${month}-${day}`;
docBookedDate.value = `${month}-${day}-${year}`;
bookDate.value = formattedDate;
console.log("Test Date", bookDate.value, docpicker.value);
isLoadingVisible.value = false;
if (formattedDate) {
axios.post('/agent/api/available-slots/' + formattedDate)
.then(response => {
console.log("Data", response.data.available_slots);
chooseDate.value = response.data.available_slots;
isLoadingVisible.value = false;
showDocCalender.value = false;
showDocRadio.value = true
// console.log(chooseDate);
})
.catch(error => {
console.error(error.response.data);
});
} else {
chooseDate.value = [];
}
}
}
const isBookSlotDisabled = computed(() => {
// Check if a date is selected
return !selectedtime.value;
});
const isBookDocSlotDisabled = computed(() => {
// Check if a date is selected
return !selectedDoctime.value;
});
const bookSlot = () => {
// isLoadingVisible.value = true;
confirmSlotDialog.value = false
console.log("selectedData", bookDate.value, selectedtime.value);
if (selectedtime.value && bookDate.value) {
const patient_id = localStorage.getItem('patient_id');
const patient_appiontment_id = localStorage.getItem('patient_appiontment_id');
axios.post('/agent/api/patient-book-lab/post/' + patient_appiontment_id, {
lab_name: labName.value,
lab_address: labAddress.value,
lab_lat: labLat.value,
lab_lang: labLong.value,
lab_city: labCity.value,
lab_state: labState.value,
lab_distance: labDistance.value,
lab_contact_no: labphone.value,
slot_date: bookDate.value,
slot_time: selectedtime.value
})
.then(response => {
console.log(response.data.message);
isTonalSnackbarVisible.value = true;
patientResponse.value = response.data.message;
chooseDate.value = '';
selectedDate.value = '';
// selectedtime.value = '';
isLoadingVisible.value = false;
showLabInfoTab.value = false;
activeTab1.value = 'info';
showBookLabBtn.value = false
showBookDocBtn.value = true
})
.catch(error => {
console.error(error.response.data);
isLoadingVisible.value = false;
});
} else {
isTonalSnackbarVisible.value = true;
patientResponse.value = 'Error in Booking Appiontment';
isLoadingVisible.value = false;
}
}
const bookDocSlot = () => {
isLoadingVisible.value = true;
console.log("selectedData", bookDate.value, selectedDoctime.value);
if (selectedDoctime.value && bookDate.value) {
docSlotTime.value = selectedDoctime.value
const patient_id = localStorage.getItem('patient_id');
const patient_appiontment_id = localStorage.getItem('patient_appiontment_id');
axios.post('/agent/api/book-doc-appointment/post/' + patient_appiontment_id, {
appointment_date: bookDate.value,
appointment_time: selectedDoctime.value,
lab_name: labName.value,
lab_address: labAddress.value,
lab_distance: labDistance.value,
lab_contact_no: labphone.value,
lab_lang: '',
lab_lat: ''
})
.then(response => {
console.log(response.data.message);
isTonalSnackbarVisible.value = true;
patientResponse.value = response.data.message;
chooseDate.value = '';
selectedDate.value = '';
selectedDoctime.value = '';
activeTab1.value = 'info'
isLoadingVisible.value = false;
showBookDocBtn.value = false
})
.catch(error => {
console.error(error.response.data);
isLoadingVisible.value = false;
});
} else {
isTonalSnackbarVisible.value = true;
patientResponse.value = 'Error in Booking Appiontment';
isLoadingVisible.value = false;
}
}
const done = () => {
patientUpdatedVisible.value = false;
}
const x = ref(0)
const y = ref(0)
const dragging = ref(false)
const rect = ref(null)
const style = computed(() => {
return {
transform: `translate(${x.value}px, ${y.value}px)`
}
})
const handleMouseDown = e => {
rect.value = e.currentTarget.getBoundingClientRect()
dragging.value = true
}
const handleMouseMove = e => {
if (!dragging.value) return
x.value = Math.min(Math.max(0, e.clientX - rect.value.left), window.innerWidth - rect.value.width) - 25
y.value = Math.min(Math.max(0, e.clientY - rect.value.top), window.innerHeight - rect.value.height) - 25
}
const getLabInfo = (id, labname = null, distance = null, address = null, phone = null, lat = null, lng = null, city = null, state = null) => {
labName.value = labname;
labAddress.value = address;
labLat.value = lat;
labLong.value = lng;
labCity.value = city;
labState.value = state;
labDistance.value = distance;
labphone.value = phone;
selectedLab.value = id
console.log('Lab Info ', id, labname, distance, address, phone);
showLabInfoTab.value = true;
showDatePicker.value = true
showTimeSlots.value = false;
activeTab1.value = false
}
const backToLabCalender = () => {
showLabInfoTab.value = true;
showDatePicker.value = true
showTimeSlots.value = false;
}
const showConfirmDialog = () => {
confirmSlotDialog.value = true
}
const hideConfirmDialog = () => {
confirmSlotDialog.value = false
}
const showDocDiv = () => {
activeTab1.value = 'doc_appointment'
showDocCalender.value = true
}
const backToDocCalender = () => {
showDocCalender.value = true;
showDocRadio.value = false
}
const backToDocInfo = () => {
activeTab1.value = 'info'
}
const states = ref([
{ name: 'Howland Island', abbreviation: 'UM-84' },
{ name: 'Delaware', abbreviation: 'DE' },
{ name: 'Maryland', abbreviation: 'MD' },
{ name: 'Baker Island', abbreviation: 'UM-81' },
{ name: 'Kingman Reef', abbreviation: 'UM-89' },
{ name: 'New Hampshire', abbreviation: 'NH' },
{ name: 'Wake Island', abbreviation: 'UM-79' },
{ name: 'Kansas', abbreviation: 'KS' },
{ name: 'Texas', abbreviation: 'TX' },
{ name: 'Nebraska', abbreviation: 'NE' },
{ name: 'Vermont', abbreviation: 'VT' },
{ name: 'Jarvis Island', abbreviation: 'UM-86' },
{ name: 'Hawaii', abbreviation: 'HI' },
{ name: 'Guam', abbreviation: 'GU' },
{ name: 'United States Virgin Islands', abbreviation: 'VI' },
{ name: 'Utah', abbreviation: 'UT' },
{ name: 'Oregon', abbreviation: 'OR' },
{ name: 'California', abbreviation: 'CA' },
{ name: 'New Jersey', abbreviation: 'NJ' },
{ name: 'North Dakota', abbreviation: 'ND' },
{ name: 'Kentucky', abbreviation: 'KY' },
{ name: 'Minnesota', abbreviation: 'MN' },
{ name: 'Oklahoma', abbreviation: 'OK' },
{ name: 'Pennsylvania', abbreviation: 'PA' },
{ name: 'New Mexico', abbreviation: 'NM' },
{ name: 'American Samoa', abbreviation: 'AS' },
{ name: 'Illinois', abbreviation: 'IL' },
{ name: 'Michigan', abbreviation: 'MI' },
{ name: 'Virginia', abbreviation: 'VA' },
{ name: 'Johnston Atoll', abbreviation: 'UM-67' },
{ name: 'West Virginia', abbreviation: 'WV' },
{ name: 'Mississippi', abbreviation: 'MS' },
{ name: 'Northern Mariana Islands', abbreviation: 'MP' },
{ name: 'United States Minor Outlying Islands', abbreviation: 'UM' },
{ name: 'Massachusetts', abbreviation: 'MA' },
{ name: 'Connecticut', abbreviation: 'CT' },
{ name: 'Florida', abbreviation: 'FL' },
{ name: 'District of Columbia', abbreviation: 'DC' },
{ name: 'Midway Atoll', abbreviation: 'UM-71' },
{ name: 'Navassa Island', abbreviation: 'UM-76' },
{ name: 'Indiana', abbreviation: 'IN' },
{ name: 'Wisconsin', abbreviation: 'WI' },
{ name: 'Wyoming', abbreviation: 'WY' },
{ name: 'South Carolina', abbreviation: 'SC' },
{ name: 'Arkansas', abbreviation: 'AR' },
{ name: 'South Dakota', abbreviation: 'SD' },
{ name: 'Montana', abbreviation: 'MT' },
{ name: 'North Carolina', abbreviation: 'NC' },
{ name: 'Palmyra Atoll', abbreviation: 'UM-95' },
{ name: 'Puerto Rico', abbreviation: 'PR' },
{ name: 'Colorado', abbreviation: 'CO' },
{ name: 'Missouri', abbreviation: 'MO' },
{ name: 'New York', abbreviation: 'NY' },
{ name: 'Maine', abbreviation: 'ME' },
{ name: 'Tennessee', abbreviation: 'TN' },
{ name: 'Georgia', abbreviation: 'GA' },
{ name: 'Louisiana', abbreviation: 'LA' },
{ name: 'Nevada', abbreviation: 'NV' },
{ name: 'Iowa', abbreviation: 'IA' },
{ name: 'Idaho', abbreviation: 'ID' },
{ name: 'Rhode Island', abbreviation: 'RI' },
{ name: 'Washington', abbreviation: 'WA' },
{ name: 'Ohio', abbreviation: 'OH' },
// ... (add the rest of the states)
]);
const groupedQuestions = computed(() => {
const groups = {};
for (const key in questions.value) {
if (questions.value.hasOwnProperty(key)) {
let groupQuestions = questions.value[key];
groupQuestions.forEach(question => {
const groupId = question.group_id;
if (!groups[groupId]) {
groups[groupId] = {
name: key,
questions: [],
};
}
groups[groupId].questions.push(question);
});
}
}
console.log("groups", groups);
// Convert groups object to an array
return Object.values(groups);
});
const parseOptions = (optionsString) => {
try {
const optionsArray = phpUnserialize(optionsString);
return optionsArray.map((option, index) => ({ key: index, value: option }));
} catch (error) {
console.error('Error parsing options:', error);
return [];
}
};
const transcript = ref([]);
const getTranscript = (transcriptData) => {
// Parse the JSON string
const responseObj = JSON.parse(transcriptData);
// Extract the questions_and_answers array
const questionsAndAnswers = JSON.parse(responseObj.text);
if (Array.isArray(questionsAndAnswers) && questionsAndAnswers.length > 0) {
questions.value.forEach(item => {
const result = findCommonQuestion(item.question, questionsAndAnswers);
if (result.hasCommonQuestion) {
console.log(`Common question found at index ${result.indexInArray2} in array2.`);
answers.value[item.id] = questionsAndAnswers[result.indexInArray2].answer
}
});
// questions.value.forEach(item => {
// if (result.hasCommonQuestion) {
// console.log(`Common question found at index ${result.indexInArray2} in array2.`);
// answers.value[item.question.id] = questionsAndAnswers[result.indexInArray2].answer
// }
// });
// transcript.value.push(questionsAndAnswers);
// console.log('transcript ', transcript.value, hasCommonQuestion(questions.value, questionsAndAnswers))
}
};
function findCommonQuestion(question, arr2) {
for (let j = 0; j < arr2.length; j++) {
if (similar(arr2[j].question, question)) {
return {
hasCommonQuestion: true,
indexInArray2: j
}; // Found a common question
}
}
return { hasCommonQuestion: false, indexInArray2: -1 }; // No common question found
}
const similar = (a, b) => {
var equivalency = 0;
var minLength = (a.length > b.length) ? b.length : a.length;
var maxLength = (a.length < b.length) ? b.length : a.length;
for (var i = 0; i < minLength; i++) {
if (a[i] == b[i]) {
equivalency++;
}
}
var weight = equivalency / maxLength;
return (weight * 100) > 70;
}
</script>
<template>
<VContainer>
<VRow>
<VCol col="12">
<VCard>
<VList>
<v-list-item class="m-0" v-if="patientName">
<span class="text-heading"></span> <strong>{{ patientName }}</strong>
<span class="text-heading"><b> Current address: </b>
<span v-if="editAddress">{{ editAddress }}, </span>
<span v-if="editCity">{{ editCity }}, </span>
<span v-if="editstate">{{ editstate }} &nbsp;</span>
<span v-if="editZip">{{ editZip }}, </span>
<span v-if="editCountry">{{ editCountry }}</span>
</span>
<v-btn v-if="showBookLabBtn && !isMobile" @click="findLab"
class="btn btn-primary waves-effect waves-light float-right">
Book Lab
</v-btn>
</v-list-item>
</VList>
</VCard>
</VCol>
</VRow>
<VRow>
<VSnackbar v-model="isTonalSnackbarVisible" location="top end" variant="flat" color="success">
{{ patientResponse }}
</VSnackbar>
<VDialog v-model="isLoadingVisible" width="110" height="150" color="primary">
<VCardText class="" style="color: white !important;">
<div class="demo-space-x">
<VProgressCircular :size="40" color="primary" indeterminate />
</div>
</VCardText>
</VDialog>
<VDialog v-model="confirmSlotDialog" max-width="600px">
<v-card>
<v-card-title class="headline" v-if="patientName">{{ patientName }}</v-card-title>
<v-card-text class="p-0">
Are you sure you want to book slot with this information?
</v-card-text>
<v-list-item-group v-if="labName || labDistance || labAddress || labphone">
<v-list-item style="border-bottom:1px solid #eee ; padding-bottom: 8px;">
<v-list-item-content class="pt-2 lab_address">
<v-list-item-title v-if="labName">{{ labName }}</v-list-item-title>
<v-list-item-subtitle v-if="labDistance"><v-icon icon="mdi-map-marker" style="font-size: 20px;" />{{
labDistance }} away from your location</v-list-item-subtitle>
<v-list-item-subtitle v-if="labAddress">
<v-icon icon="mdi-home" style="font-size: 20px;" /> {{ labAddress }}</v-list-item-subtitle>
<v-list-item-subtitle v-if="labphone">
<v-icon icon="mdi-phone" style="font-size: 20px;" /> {{ labphone }}</v-list-item-subtitle>
<v-card-title class="headline" style="padding-left: 0px;">Booking Information</v-card-title>
<v-list-item-subtitle v-if="labBookedDate">
<b>Date : {{ labBookedDate }}</b>
</v-list-item-subtitle>
<v-list-item-subtitle v-if="selectedtime" class="mb-4">
<b>Time: {{ selectedtime }}</b>
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
<v-card-actions class="justify-end mt-2">
<v-btn class="green-button text-light" @click="bookSlot">Confirm</v-btn>
<v-btn class="red-button text-light" @click="hideConfirmDialog">Cancel</v-btn>
</v-card-actions>
</v-card>
</VDialog>
<VCol cols="12" :md="videoCol">
<videocall :token="token" :recording="recordVid" @update:transcriptData="getTranscript"></videocall>
</VCol>
<VCol cols="12" md="4" :style="infoCol">
<div style="background-color: white;">
<v-layout v-if="showLabInfoTab" style="height: 555px;">
<v-navigation-drawer location="right" permanent style="width: 100%;">
<v-list-item-group v-if="labName || labDistance || labAddress || labphone">
<v-list-item style="border-bottom:1px solid #eee ; padding-bottom: 8px;">
<v-list-item-content class="pt-2 lab_address">
<v-list-item-title v-if="labName">{{ labName }}</v-list-item-title>
<v-list-item-subtitle v-if="labDistance"><v-icon icon="mdi-map-marker" style="font-size: 20px;" />{{
labDistance }} away from your location</v-list-item-subtitle>
<v-list-item-subtitle v-if="labAddress">
<v-icon icon="mdi-home" style="font-size: 20px;" /> {{ labAddress }}</v-list-item-subtitle>
<v-list-item-subtitle v-if="labphone">
<v-icon icon="mdi-phone" style="font-size: 20px;" /> {{ labphone }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-subtitle v-if="bookDate"><strong>Date: </strong>{{ bookDate }}</v-list-item-subtitle>
</v-list-item>
</v-list-item-group>
<v-divider></v-divider>
<v-list density="compact" nav>
<v-list-item v-if="showDatePicker">
<v-date-picker full-width="true" landscape v-model="picker" :show-week="true" :min="minDate"
:max="maxDate" :allowed-dates="allowedDates" @update:modelValue="datepick"></v-date-picker>
</v-list-item>
<v-list-item v-if="showTimeSlots">
<v-radio-group v-model="selectedtime" @update:modelValue="selectedTimeSlot">
<v-radio :label="choosetimeframes" :value="choosetimeframes"
v-for="(choosetimeframes, index) in chooseDate" :key="index"></v-radio>
</v-radio-group>
</v-list-item>
</v-list>
<template v-slot:append>
<div class="pa-2" v-if="showTimeSlots">
<v-btn block @click=showConfirmDialog() :disabled="isBookSlotDisabled">
Book Slot
</v-btn>
</div>
<div class="pa-2" v-if="showTimeSlots">
<v-btn block @click="backToLabCalender">
Back
</v-btn>
</div>
<div class="pa-2" v-if="showDatePicker">
<v-btn block @click="backToLabList">
Back
</v-btn>
</div>
</template>
</v-navigation-drawer>
<v-main style="height: 100%;min-height: 800px;">
<div class="d-flex justify-center align-center h-100">
</div>
</v-main>
</v-layout>
<div v-if="activeTab1 === 'info' && labName">
<VList>
<v-list-item v-if="labName || labDistance || labAddress || labphone">
<span class="text-heading"><b>Lab Appointment:</b></span>
</v-list-item>
<v-list-item-group v-if="labName || labDistance || labAddress || labphone">
<v-list-item style="border-bottom:1px solid #eee ; padding-bottom: 8px;">
<v-list-item-content class="pt-2 lab_address">
<v-list-item-title v-if="labName">{{ labName }}</v-list-item-title>
<v-list-item-subtitle v-if="labDistance"><v-icon icon="mdi-map-marker" style="font-size: 20px;" />{{
labDistance }} away from your location</v-list-item-subtitle>
<v-list-item-subtitle v-if="labAddress">
<v-icon icon="mdi-home" style="font-size: 20px;" /> {{ labAddress }}</v-list-item-subtitle>
<v-list-item-subtitle v-if="labphone">
<v-icon icon="mdi-phone" style="font-size: 20px;" /> {{ labphone }}</v-list-item-subtitle>
<v-list-item-subtitle v-if="labphone"><b>Date:</b> {{ labBookedDate }}</v-list-item-subtitle>
<v-list-item-subtitle v-if="selectedtime"><b>Time:</b> {{ selectedtime }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item v-if="docSlotTime || docBookedDate">
<span class="text-heading"><b>Doctor Appointment:</b></span>
<v-list-item-subtitle v-if="docBookedDate"><b>Date:</b> {{ docBookedDate }}</v-list-item-subtitle>
<v-list-item-subtitle v-if="docSlotTime"><b>Time:</b> {{ docSlotTime }}</v-list-item-subtitle>
</v-list-item>
<v-list-item v-if="showBookDocBtn">
<v-btn v-if="showBookDocBtn" @click="showDocDiv"
class="btn btn-primary waves-effect waves-light float-right">
Doctor Appointment
</v-btn>
</v-list-item>
</v-list-item-group>
</VList>
<v-list>
</v-list>
<!-- <VRow>
<v-col>
<v-btn @click="editInfo" class="btn btn-primary waves-effect waves-light">
Edit Info
</v-btn>
</v-col>
</VRow> -->
</div>
<div v-else-if="activeTab1 === 'edit_form'" id="edit_form">
<h4 style="padding:15px 10px 15px">Change Address</h4>
<v-form class="change-address" ref="refVForm" @submit.prevent="onSubmit">
<!-- <v-text-field :error-messages="errors.editLocation" class="mb-3" v-model="editLocation" label="Location"
:rules="[requiredLocation]"></v-text-field> -->
<v-text-field :error-messages="errors.editAddress" class="mb-3" v-model="editAddress" label="Address"
:rules="[requiredAddress]"></v-text-field>
<v-text-field :error-messages="errors.editCity" class="mb-3" v-model="editCity" label="City"
:rules="[requiredCity]"></v-text-field>
<!-- <v-text-field :error-messages="errors.editstate" class="mb-3" v-model="editstate" label="State"
:rules="[requiredCity]"></v-text-field> -->
<!-- <v-select v-model="editstate">
<option v-for="state in states" :value="state.abbreviation" :key="state.abbreviation">
{{ state.name }}
</option>
</v-select> -->
<!-- <v-select v-model="editstate" :items="states" :item-text="name" :item-value="abbreviation"
label="Select a State"> -->
<!-- </v-select> -->
<v-select class="mb-3" v-model="editstate" label="Select State" :items="states" item-title="name"
item-value="abbreviation">
</v-select>
<v-text-field type="text" :error-messages="errors.editCountry" class="mb-3" v-model="editCountry"
label="Country"></v-text-field>
<v-text-field type="number" :error-messages="errors.editZip" class="mb-3" v-model="editZip"
label="Zip Code" :rules="[requiredCity]"></v-text-field>
<VRow>
<VCol cols="12" md="6">
<v-btn block @click="backToInfo">Back</v-btn>
</VCol>
<VCol cols="12" md="6">
<v-btn block color="green" type="submit"
class="btn btn-success waves-effect waves-light mr-2">Update</v-btn>
</VCol>
</VRow>
</v-form>
</div>
<div v-else-if="activeTab1 === 'lab_locator'" style="" id="lab_locator">
<h4 class="text-uppercase" style="padding: 15px 10px 5px;">Lab Locate</h4>
<v-row>
<v-col>
<v-list class="lab_locator_inner" style="">
<div class="spinner-container" v-if="showLabSpinner">
<v-progress-circular indeterminate color="primary"></v-progress-circular>
</div>
<v-list-item-group v-if="labLocations.length > 0">
<v-list-item v-for="location in labLocations" :key="location.locatorId"
@click.stop="getLabInfo(location.locatorId, location.lab_name, location.distanceFromStartingPoint, location.address, location.phone, location.lat, location.lng, location.city, location.state)"
style="border-bottom:1px solid #eee ; padding-bottom: 8px;">
<v-list-item-content class="pt-2 lab_address">
<v-list-item-title>{{ location.lab_name }}
<VIcon color="green" icon="mdi-check" v-if="selectedLab == location.locatorId"></VIcon>
</v-list-item-title>
<v-list-item-subtitle><v-icon icon="mdi-map-marker" style="font-size: 15px;" />{{
location.distanceFromStartingPoint }} away from your location</v-list-item-subtitle>
<v-list-item-subtitle><v-icon icon="mdi-home" style="font-size: 15px;" /> {{
location.address
}}</v-list-item-subtitle>
<v-list-item-subtitle><v-icon icon="mdi-phone" style="font-size: 15px;" /> {{ location.phone
}}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
<v-list-item v-else>
<v-list-item-content v-if="!showLabSpinner">No LabCorp locations found.</v-list-item-content>
</v-list-item>
</v-list>
</v-col>
</v-row>
<!-- Leaflet Map goes here -->
<leaftmap></leaftmap>
<!-- <v-btn @click="backToLabLoc" class="mt-2">Back</v-btn> -->
<v-btn block @click="editInfo" class="btn btn-primary waves-effect waves-light float-right mt-2 mb-2">
Change Address
</v-btn>
</div>
<div v-else-if="activeTab1 === 'doc_appointment'">
<div v-if="showDocCalender">
<v-date-picker v-model="docpicker" :show-week="true" :min="minDate" :max="maxDate"
:allowed-dates="allowedDates" @update:modelValue="datePickDoc"></v-date-picker>
<v-btn block color="primary" @click="backToDocInfo">
Back
</v-btn>
</div>
<div v-if="showDocRadio" class="ml-1 mr-1" style="height:557px">
<v-flex xs12 sm6 d-flex>
<div v-if="docBookedDate" style="padding: 15px 10px 5px;">
<b>Date:</b> {{ docBookedDate }}
</div>
<v-radio-group class="custom-scrollbar" v-model="selectedDoctime" @update:modelValue="selectedTimeSlot"
style="overflow-y: auto;height: 394px;margin-left: 10px;">
<v-radio :label="choosetimeframes" :value="choosetimeframes"
v-for="(choosetimeframes, index) in chooseDate" :key="index"></v-radio>
</v-radio-group>
</v-flex>
<div class="text-right mt-5 mb-4">
<v-btn block color="primary" @click=bookDocSlot :disabled="isBookDocSlotDisabled">
Book Slot
</v-btn>
</div>
<div class="text-right mt-5 mb-4">
<v-btn block color="primary" @click="backToDocCalender">
Back
</v-btn>
</div>
</div>
</div>
</div>
</VCol>
<!-- 👉 User Update info -->
<VCol cols="12">
<VRow>
<VCol cols="6" xs="6" lg="12">
<h3>Questionaries</h3>
</VCol>
<VCol cols="6" xs="6" v-if="showBookLabBtn && isMobile">
<v-btn @click="findLab" class="btn btn-primary waves-effect waves-light float-right">
Book Lab
</v-btn>
</VCol>
<VExpansionPanels variant="accordion" class="expansion-panels-width-border">
<VExpansionPanel v-for="(group, groupIndex) in groupedQuestions" :key="groupIndex" :open="group.isOpen">
<VExpansionPanelTitle>
<b>{{ group.name }}</b>
</VExpansionPanelTitle>
<VExpansionPanelText>
<VExpansionPanels>
<VExpansionPanel v-for="(question, questionIndex) in group.questions" :key="questionIndex"
:open="question.isOpen">
<VExpansionPanelTitle>
{{ question.id }}. {{ question.question }} ?
</VExpansionPanelTitle>
<VExpansionPanelText>
<!-- Conditionally render input components based on question type -->
<template v-if="question.type === 'text'">
<VTextField :type="question.type" :id="'question_' + question.id" size="500"
v-model="answers[question.id]" />
</template>
<template v-else-if="question.type === 'radio'">
<VRadioGroup v-model="answers[question.id]">
<VRadio v-for="(option, optionIndex) in parseOptions(question.options)" :key="optionIndex"
:label="option.value" :value="option.value" />
</VRadioGroup>
</template>
<template v-else-if="question.type === 'textarea'">
<VTextarea :type="question.type" :id="'question_' + question.id"
v-model="answers[question.id]" />
</template>
<template v-else-if="question.type === 'checkbox'">
<VCheckboxGroup v-model="answers[question.id]">
<VCheckbox :type="question.type" v-for="(option, optionIndex) in question.options"
:key="optionIndex" :label="option" :value="option" />
</VCheckboxGroup>
</template>
<!-- Add more conditions for other types if needed -->
</VExpansionPanelText>
</VExpansionPanel>
</VExpansionPanels>
</VExpansionPanelText>
</VExpansionPanel>
</VExpansionPanels>
</VRow>
</VCol>
<VCol cols="12">
<VBtn @click="saveAnswers">Save Answers</VBtn>
</VCol>
</VRow>
<!-- <VCol cols="6" v-for="(question, index) in questions">
<label>{{ question.question }}</label>
<VTextField :type="question.type" :id="'question_' + question.id" size="500" v-model="answers[question.id]" />
</VCol>
<VCol cols="12">
<VBtn @click="saveAnswers">Save Answers</VBtn>
</VCol> -->
</VContainer>
</template>
<style>
@media (min-width: 320px) and (max-width: 768px) {
#edit_form {
height: 610px !important;
}
#lab_locator {
height: 100% !important;
max-height: 610px !important;
}
.lab_locator_inner {
height: 100% !important;
max-height: 610px !important;
}
}
button.v-expansion-panel-title {
background-color: rgb(var(--v-theme-yellow)) !important;
color: #fff;
}
button.v-expansion-panel-title.bg-secondary {
background-color: rgb(var(--v-theme-yellow)) !important;
color: #fff;
}
button.v-expansion-panel-title {
background-color: rgb(var(--v-theme-yellow)) !important;
color: #fff;
}
button.v-expansion-panel-title.v-expansion-panel-title--active {
background-color: rgb(var(--v-theme-yellow)) !important;
color: #fff;
}
#edit_form {
height: 555px;
padding: 10px;
}
#lab_locator {
display: block;
height: 555px;
}
.lab_locator_inner {
height: 463px;
}
.change-address div {
margin-bottom: 5px;
}
::-webkit-scrollbar {
width: 20px !important;
}
::-webkit-scrollbar-track {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: #d6dee1;
border-radius: 20px;
border: 6px solid transparent;
background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover {
background-color: #a8bbbf;
}
.v-picker.v-sheet {
width: 100%;
display: block !important;
}
.v-picker-title {
padding-bottom: 5px !important;
}
</style>
<style scoped>
.v-picker-title {
padding-bottom: 5px !important;
}
.small-screen {
background-color: white;
min-height: 150px;
max-width: 24%;
}
.livekit-container {
min-height: 500px;
background-color: black;
position: relative;
}
.v-list-item--density-default.v-list-item--one-line {
min-height: 30px;
}
#jaas-container {
height: 550px;
width: 100%
}
.lab_address div {
margin-top: 5px;
margin-bottom: 5px;
}
.draggable-card {
cursor: move;
position: relative;
}
.box {
position: absolute;
cursor: move;
width: 150px;
height: 150px;
background: #313131;
border-radius: 10px;
margin-left: 10px;
}
.spinner-container {
display: flex;
align-items: center;
justify-content: center;
height: 100px;
/* Set the height as needed */
}
.green-button {
background-color: #16ba16e8;
color: white !important;
/* Optionally set text color */
}
.red-button {
background-color: #ff0000;
color: white !important;
/* Optionally set text color */
}
</style>