rejuvallife/resources/js/pages/category-questions.vue
2024-10-25 01:02:11 +05:00

673 lines
25 KiB
Vue

<script setup>
import axios from '@axios';
import previousButton from '@images/svg/previous.svg';
import { onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import phpUnserialize from 'phpunserialize';
import { useStore } from 'vuex';
const store = useStore()
const router = useRouter()
const route = useRoute()
const isMobile = ref(window.innerWidth <= 768); // Assuming mobile width is less than or equal to 768px
const currentDialoagkey = ref('')
const isTonalSnackbarVisible = ref(false)
const patientResponse = ref(false)
const isLoadingVisible = ref(false)
const questionForm = ref()
const answers = ref([]);
const medical_question = ref([]);
const question_length = ref([]);
const isDialogVisible = ref(false)
const selectedQuestion = ref([]);
const previousQid = ref(null)
onBeforeMount(async () => {
await store.dispatch('getMedicalHistoryQuestion')
// medical_question.value.push({ answers: [] });
medical_question.value = store.getters.getMedicalCategoryQuestion.data;
question_length.value = medical_question.value.length;
console.log("medical_question", medical_question.value);
});
const questions = ref([
{
question_key: 'why_interested_hrt',
question: "What aspects of hormone replacement therapy (HRT) intrigue you?",
type: "text",
},
{
question_key: 'goal_loss_weight',
question: "Is your objective with the program to achieve weight loss?",
type: "radio",
options: ["Yes", "No"],
},
{
question_key: 'what_biological_sex',
question: "What is your assigned sex at birth?",
type: "radio",
options: ["Male", "Female"],
},
{
question_key: '3_years_physical_test',
question: "Have you undergone a comprehensive physical examination by a medical professional within the past three years, which included assessments of vital signs such as weight, blood pressure, and heart rate?",
type: "radio",
options: ["Yes", "No"],
},
{
question_key: 'medical_problems',
question: "Did you experience any medical issues? If so, could you please elaborate?",
type: "radio",
options: ["Yes", "No"],
},
{
question_key: 'have_prostate_cancer',
question: "Have you ever received a diagnosis of prostate cancer?",
type: "radio",
options: ["Yes", "No"],
},
// {
// question_key: 'what_height',
// question: "How tall are you?",
// type: "dropdown",
// options: ["5 ft 1 in",
// "5 ft 2 in",
// "5 ft 3 in",
// "5 ft 4 in",
// "5 ft 5 in",
// "5 ft 6 in",
// "5 ft 7 in",
// "5 ft 8 in",
// ],
// },
// {
// question_key: 'whight',
// question: "What is your weight?",
// type: "text",
// },
// {
// question_key: 'birthdate',
// question: "When were you born?",
// type: "date",
// sub_title: 'To proceed with medication, kindly input your accurate date of birth using the format mm/dd/yyyy.'
// },
{
question_key: 'past_harmone_treatments',
question: "Have you been prescribed any hormone treatments currently or in the past?",
type: "radio",
options: ["Thyroid Medication", "Testosterone Treatment", "Estrogen Blocker", "HGH", "Ipamoreline", "Colomipheine", "HCG", "Other", "None"],
},
{
question_key: 'take_medications',
question: "Are you currently using or have you used any over-the-counter or prescription medications, excluding hormone treatments? (Please note that your responses will be cross-checked against prescription and insurance records. Failure to disclose current prescriptions and/or medical conditions may result in disapproval for your safety.)",
type: "radio",
options: ["Yes", "No"],
},
{
question_key: 'have_medications_allegies',
question: "Do you have any allergies to medications?",
type: "radio",
options: ["Yes", "No"],
},
{
question_key: 'plan_children',
question: "Do you intend to have children at some point in the future?",
type: "radio",
options: ["Yes", "No"],
},
{
question_key: 'partner_pregnant',
question: "Is your partner currently pregnant or breastfeeding?",
type: "radio",
options: ["Yes", "No", "Not Applicable"],
},
{
question_key: 'experience_ed',
question: "Are you currently experiencing any erectile dysfunction (ED) issues?",
type: "radio",
options: ["Never", "Almost Never", "Occasionally", "Almost Always", "Always"],
},
{
question_key: 'thyroid_disorders',
question: "Have you ever been diagnosed with thyroid disorders such as hypothyroidism (underactive thyroid), hyperthyroidism (overactive thyroid), Hashimoto's Disease, or Graves' Disease?",
type: "radio",
options: ["Yes", "No"],
},
{
question_key: 'family_history',
question: "Does your family have a history of any of the following disorders?",
type: "radio",
options: ["Drug Alcohol", "Cancer", "Heart Disease", "Thyroid Disease", "Low Testosterone",
"None"],
},
{
question_key: 'patient_concent',
question: "Please read and accept",
linktext: "Patient Content",
type: "signalCheckbox",
},
{
question_key: 'appointment_cancel',
question: "Please read and accept",
linktext: "Appointment Cancel",
type: "signalCheckbox",
},
{
question_key: 'medicare_disclaimer',
question: "Please read and accept",
linktext: "Medicare Disclaimer",
type: "signalCheckbox",
},
{
question_key: 'telehealth_concent',
question: "Please read and accept",
linktext: "Telehealth Concent",
type: "signalCheckbox",
},
{
question_key: 'secondary_contact',
question: "Please read and accept",
linktext: "Secondary Contact Disclosure(optional)",
type: "signalCheckbox",
},
]);
const validateQuestion = async () => {
const { valid: isValid } = await questionForm.value?.validate();
console.log('isValid ', isValid);
if (isValid)
saveAnswers()
};
onMounted(async () => {
window.addEventListener('resize', checkIfMobile);
await getPatientInfo()
})
// Detach event listener on component unmount
onUnmounted(() => {
window.removeEventListener('resize', checkIfMobile);
});
const checkIfMobile = () => {
isMobile.value = window.innerWidth <= 768;
};
const getPatientInfo = async () => {
const patient_id = localStorage.getItem('patient_id')
const access_token = localStorage.getItem('access_token');
console.log()
isLoadingVisible.value = true;
await axios.post('/api/get-patient-detail/' + patient_id, {
headers: {
'Authorization': `Bearer ${access_token}`,
}
})
.then(response => {
console.log('Response:', response.data);
if (response.data) {
let patientData = response.data.patient
isLoadingVisible.value = false;
} else {
isLoadingVisible.value = false;
}
})
.catch(error => {
console.error('Error:', error);
});
}
const saveAnswers = () => {
isLoadingVisible.value = true;
const patient_id = localStorage.getItem('patient_id');
const jsonData = {
questions: questions.value.reduce((accumulator, question, index) => {
const answerValue = answers.value[question.question_key];
if (answerValue !== undefined) {
accumulator.push({
question_key: question.question_key,
type: question.type,
answer: answerValue,
});
}
return accumulator;
}, []),
};
let qaData = Array({ 'answers': jsonData.questions });
console.log('answers ', JSON.stringify(qaData));
// You can send the jsonData to your server or use it as needed
axios.post('/api/medical-history-question-post/' + patient_id,
{
answers: jsonData.questions
}
)
.then(response => {
console.log('answer api', response.data)
// console.log(chooseDate);
isLoadingVisible.value = false;
router.replace(route.query.to && route.query.to != '/additional-information' ? String(route.query.to) : '/shipping-information')
})
.catch(error => {
isLoadingVisible.value = false;
// console.error(error);
});
};
const getCurrentDate = () => {
const today = new Date();
const year = today.getFullYear();
let month = today.getMonth() + 1;
let day = today.getDate();
// Format the date to match the input type="date" format
month = month < 10 ? `0${month}` : month;
day = day < 10 ? `0${day}` : day;
return `${year}-${month}-${day}`;
};
const openDialog = (question_key) => {
currentDialoagkey.value = question_key;
isDialogVisible.value = true;
window.addEventListener('click', closeDialogOnOutsideClick);
};
const closeDialogOnOutsideClick = (event) => {
const dialogElement = refs.myDialog.$el;
if (!dialogElement.contains(event.target)) {
isDialogVisible.value = false;
window.removeEventListener('click', closeDialogOnOutsideClick);
}
};
const handleContinueClick = (currentDialoagkey) => {
isDialogVisible.value = false; // Hide the dialog
answers.value[currentDialoagkey] = true; // Update the answers object
};
const breadcrums = [
{
title: 'Category',
disabled: false,
to: '/category',
},
{
title: localStorage.getItem('category_name'),
disabled: false,
},
];
const radioContent = [
{
title: 'Basic',
subtitle: 'Free',
desc: 'Get 1 project with 1 team member.',
value: 'basic',
},
{
title: 'Premium',
subtitle: '$45.80',
value: 'premium',
desc: 'Get 5 projects with 5 team members.',
},
]
const currentTab = ref(0);
const percentage = ref(0);
const tabItemText = 'hortbread chocolate bar marshmallow bear claw tiramisu chocolate cookie wafer. Gummies sweet brownie brownie marshmallow chocolate cake pastry. Topping macaroon shortbread liquorice dragée macaroon.'
const changeTabOnArrowPress = (event) => {
if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {
currentTab.value = (currentTab.value + 1) % 10;
} else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {
currentTab.value = (currentTab.value - 1 + 10) % 10;
}
};
watchEffect(() => {
window.addEventListener('keydown', changeTabOnArrowPress);
return () => {
window.removeEventListener('keydown', changeTabOnArrowPress);
};
});
const nextTab = (category_id, id, value) => {
// await store.dispatch('saveCategoryAnswer')
previousQid.value = id;
// console.log("nextTabid", previousQid.value);
selectedQuestion.value.push({ id: id, value: value });
// console.log("selectedQuestion", selectedQuestion.value);
store.dispatch('setSelectedQuestionAnswer', {
category_answers: selectedQuestion.value,
})
currentTab.value = currentTab.value + 1;
percentage.value = (currentTab.value / question_length.value) * 100;
// console.log("per", percentage.value);
}
const backTab = (id, indx) => {
let prevIndex = 0;
console.log("backTabid", previousQid.value, id, indx);
const data = store.getters.getSelectedQuestionAnswer;
const entries = Object.entries(data);
console.log("entries", entries[indx]);
for (const [index, [key, value]] of entries.entries()){
console.log("ans", index, value, key);
if(value.id == previousQid.value ){
if(index > 0){
previousQid.value = entries[index - 1][1].id;
console.log("abc",previousQid.value ,value.id, entries[index - 1][1]);
}else{
previousQid.value = entries[0][1].id;
console.log("abc",previousQid.value ,value.id, entries[0][1]);
}
selectedQuestionIndex.value[value.id] = value.value;
}
}
if (currentTab.value == 0) {
} else {
currentTab.value = currentTab.value - 1;
percentage.value = (currentTab.value / question_length.value) * 100;
}
}
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 selectedQuestionIndex = ref(new Array(5).fill(false));
const subquestion1 = ref([
{ title: 'Test 1', key: 'Test 1' },
{ title: 'Test 2', key: 'Test 2' },
{ title: 'Test 3', key: 'Test 3' }
]);
const checked = ref([]);
const visibleQuestion = ref(-1); // Initially, no question is visible
const toggleSubquestion = (index) => {
alert(index);
checked.value[index] = !checked.value[index];
if (checked.value[index]) {
// If the checkbox is checked, set the visibleQuestion index to the next question
visibleQuestion.value = Math.min(index + 1, subquestion1.value.length - 1);
}
};
</script>
<template>
<v-breadcrumbs :items="breadcrums" class="text-primary pt-0 pb-0 mb-5">
<template v-slot:divider style="padding-top:0px; padding-bottom:0px">
<v-icon icon="mdi-chevron-right" style="padding-top:0px;"></v-icon>
</template>
</v-breadcrumbs>
<div class="auth-wrapper d-flex align-center justify-center">
<VDialog v-model="store.getters.getIsLoading" 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>
<div class="auth-card pt-0 rounded-5" max-width="400">
<div class="d-flex align-items-center">
<VProgressLinear v-model="percentage" height="10" width="100" color="success" :rounded="true" />
</div>
<div class="pt-2 pb-3 text-end">{{ currentTab + 1 }}/{{ question_length }}</div>
<VCard max-width="400" class="category-card">
<p style="width: 350px;"></p>
<VCardText class="pt-0 px-0">
<VWindow v-model="currentTab" style="max-width:400px">
<VWindowItem v-for="(item,index) in medical_question" :key="item" :value="item">
<VImg :src="previousButton" width="25" height="25" @click="backTab(item.id, index)"
style="cursor: pointer;">
</VImg>
<div v-if="item.question_type == 'checkbox'">
<h4 class="text-center mt-0 mb-2">{{ item.question }}</h4>
<VCard class="mb-2 selectedCard"
v-for="( option, optionIndex ) in item.question_options" :key="optionIndex"
:value="optionIndex" v-model="answers[item.id]">
<VRow class="text-center pb-2 px-4 pt-4" :class="selectedQuestionIndex[item.id] === option ? 'selected-category-card' : ''" >
<VCol col="auto" class="category-card-option">
<div class="text-center flex-wrap gap-0 pb-2 text-capitalize">
{{ option }}
</div>
</VCol>
</VRow>
</VCard>
<div class="text-center py-2" @click="() => nextTab(item.id, option)">
<VBtn size="small">Submit</VBtn>
</div>
</div>
<div v-if="item.question_type === 'radio'">
<h4 class="text-center mt-0 mb-2">{{ item.question }}</h4>
<VCard class="mb-2 selectedCard" @click="() => nextTab(item.id, option)"
v-for="( option, optionIndex ) in item.question_options" :key="optionIndex"
:value="optionIndex" v-model="answers[item.id]">
<VRow class="text-center pb-2 px-4 pt-4" :class="selectedQuestionIndex[item.id] === option ? 'selected-category-card' : ''" >
<VCol col="auto" class="category-card-option">
<div class="text-center flex-wrap gap-0 pb-2 text-capitalize">
{{ option }}
</div>
</VCol>
</VRow>
</VCard>
</div>
<div v-if="item.question_type == 'text'">
<h4 class="text-center mt-5 mb-2">{{ item.question }}</h4>
<VCard class="mb-2">
<VRow class="text-center pb-0 px-4 pt-4">
<VCol col="12">
<div class="text-center flex-wrap gap-0">
<v-text-field v-model="answers[item.id]"/>
</div>
<div class="text-center py-2" @click="nextTab()">
<VBtn size="small">Submit</VBtn>
</div>
</VCol>
</VRow>
</VCard>
</div>
<div v-if="item.sub_questions" v-for="subquestion in item.sub_questions"
:key="subquestion">
<div v-if="subquestion.question && subquestion.sub_question_type == 'checkbox'">
<h4 class="text-center mt-5 mb-2">{{ subquestion.question }}</h4>
<VCard class="mb-2 selectedCard" @click="() => nextTab(item.id, opt)"
v-for="( opt, optionIndex ) in parseOptions(subquestion.sub_question_options)" :key="optionIndex">
<VRow class=" text-center pb-2 px-4 pt-4 selectedCard">
<VCol col="auto" class="category-card-option selectedCard">
<div class="text-center flex-wrap gap-0 pb-2">
{{ opt.value }}
</div>
</VCol>
</VRow>
</VCard>
</div>
<div v-if="subquestion.question && subquestion.sub_question_type == 'radio'">
<h4 class="text-center mt-5 mb-2">{{ subquestion.question }}</h4>
<VCard class="mb-2 selectedCard" @click="() => nextTab(item.id, opt)"
v-for="( opt, optionIndex ) in parseOptions(subquestion.sub_question_options)" :key="optionIndex">
<VRow class=" text-center pb-2 px-4 pt-4 selectedCard">
<VCol col="auto" class="category-card-option selectedCard">
<div class="text-center flex-wrap gap-0 pb-2">
{{ opt.value }}
</div>
</VCol>
</VRow>
</VCard>
</div>
</div>
<div v-if="item.sub_questions.sub_questions" v-for="sub_subquestion in item.sub_questions.sub_questions"
:key="subquestion">
<div v-if="sub_subquestion.question && subquestion.sub_question_type == 'checkbox'">
<h4 class="text-center mt-5 mb-2">{{ subquestion.question }}</h4>
<VCard class="mb-2 selectedCard"
v-for="( opt, optionIndex ) in parseOptions(sub_subquestion.sub_question_options)" :key="optionIndex">
<VRow class=" text-center pb-2 px-4 pt-4 selectedCard">
<VCol col="auto" class="category-card-option selectedCard">
<div class="text-center flex-wrap gap-0 pb-2">
{{ opt.value }} Test
</div>
</VCol>
</VRow>
</VCard>
</div>
<div v-if="subquestion.question && subquestion.sub_question_type == 'radio'">
<h4 class="text-center mt-5 mb-2">{{ subquestion.question }}</h4>
<VCard class="mb-2 selectedCard" @click="() => nextTab(item.id, opt)"
v-for="( opt, optionIndex ) in parseOptions(subquestion.sub_question_options)" :key="optionIndex">
<VRow class=" text-center pb-2 px-4 pt-4 selectedCard">
<VCol col="auto" class="category-card-option selectedCard">
<div class="text-center flex-wrap gap-0 pb-2">
{{ opt.value }}
</div>
</VCol>
</VRow>
</VCard>
</div>
</div>
</VWindowItem>
</VWindow>
</VCardText>
</VCard>
</div>
</div>
<div>
</div>
</template>
<style lang="scss">
.selectedCard div :hover,
.selectedCard:hover,
.selectedCard h4:hover {
background-color: rgb(105, 108, 255);
color: #fff !important;
cursor: pointer;
}
.category-card-option {
padding: 11px 15px;
}
.selected-category-card{
background-color: rgb(105, 108, 255);
color: #fff !important;
cursor: pointer;
}
// .selectedCard h4:hover {
// color: #fff;
// }
.category-card {
background: none !important;
box-shadow: none !important;
border: none !important;
}
.v-slide-group__next {
display: none !important;
}
.card-title {
font-family: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
}
.v-list-item-title {
white-space: inherit !important;
;
}
.v-list {
min-height: 168px;
}
@media (min-width: 320px) and (max-width: 768px) {
.v-container {
padding: 0px !important;
}
.auth-wrapper {
padding: 0px !important;
}
.input-width {
max-width: 100% !important;
}
}
// .input-width {
// max-width: 50%;
// }
.form-check-input[type=checkbox] {
border-radius: 0.25em;
}
.form-check .form-check-input {
float: left;
margin-right: 0.5em;
}
.form-check-input {
cursor: pointer;
}
.form-check-input {
width: 1.2em;
height: 1.2em;
margin-top: 0.135em;
vertical-align: top;
background-color: #fff;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
border: 2px solid #dbdade;
appearance: none;
}
.form-check .form-check-input:checked,
.form-check .form-check-input[type=checkbox]:indeterminate {
box-shadow: 0 0.125rem 0.25rem rgba(165, 163, 174, 0.3);
}
.form-check-input:checked[type=checkbox] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='13' viewBox='0 0 15 14' fill='none'%3E%3Cpath d='M3.41667 7L6.33333 9.91667L12.1667 4.08333' stroke='%23fff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.form-check-input:checked,
.form-check-input[type=checkbox]:indeterminate {
background-color: #7367f0;
border-color: #7367f0;
}
.form-check-input:checked {
background-color: #7367f0;
border-color: #7367f0;
}
.form-check-input[type=checkbox] {
border-radius: 0.25em;
}
</style>