226 lines
8.3 KiB
Vue
226 lines
8.3 KiB
Vue
<script setup>
|
|
import axios from '@axios';
|
|
import {
|
|
requiredValidator
|
|
} from '@validators';
|
|
import { onMounted } from 'vue';
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
const router = useRouter()
|
|
const route = useRoute()
|
|
const errors = ref({
|
|
dob: undefined,
|
|
gender: undefined,
|
|
marital_status: undefined,
|
|
height: undefined,
|
|
weight: undefined,
|
|
|
|
})
|
|
const isTonalSnackbarVisible = ref(false)
|
|
const patientResponse = ref(false)
|
|
const isLoadingVisible = ref(false)
|
|
const infoVForm = ref()
|
|
const dob = ref()
|
|
const gender = ref()
|
|
const martialStatus = ref(null)
|
|
const height = ref(null)
|
|
const weight = ref(null)
|
|
const patientId = ref()
|
|
|
|
const genders = ref([
|
|
{ name: 'Male', abbreviation: 'Male' },
|
|
{ name: 'Female', abbreviation: 'Female' },
|
|
{ name: 'Other', abbreviation: 'Other' },
|
|
]);
|
|
|
|
const maritalStatuses = ref([
|
|
{ name: 'Single', abbreviation: 'Single' },
|
|
{ name: 'Married', abbreviation: 'Married' },
|
|
{ name: 'Divorced', abbreviation: 'Divorced' },
|
|
]);
|
|
|
|
const heights = ref([
|
|
{ name: '5 ft 0 in', abbreviation: '5 ft 0 in' },
|
|
{ name: '5 ft 1 in', abbreviation: '5 ft 1 in' },
|
|
{ name: '5 ft 2 in', abbreviation: '5 ft 2 in' },
|
|
{ name: '5 ft 3 in', abbreviation: '5 ft 3 in' },
|
|
{ name: '5 ft 4 in', abbreviation: '5 ft 4 in' },
|
|
{ name: '5 ft 5 in', abbreviation: '5 ft 5 in' },
|
|
{ name: '5 ft 6 in', abbreviation: '5 ft 6 in' },
|
|
{ name: '5 ft 7 in', abbreviation: '5 ft 7 in' },
|
|
{ name: '5 ft 8 in', abbreviation: '5 ft 8 in' },
|
|
{ name: '5 ft 9 in', abbreviation: '5 ft 9 in' },
|
|
{ name: '5 ft 10 in', abbreviation: '5 ft 10 in' },
|
|
{ name: '5 ft 11 in', abbreviation: '5 ft 11 in' },
|
|
{ name: '6 ft 0 in', abbreviation: '6 ft 0 in' },
|
|
{ name: '6 ft 1 in', abbreviation: '6 ft 1 in' },
|
|
{ name: '6 ft 2 in', abbreviation: '6 ft 2 in' },
|
|
{ name: '6 ft 3 in', abbreviation: '6 ft 3 in' },
|
|
{ name: '6 ft 4 in', abbreviation: '6 ft 4 in' },
|
|
{ name: '6 ft 5 in', abbreviation: '6 ft 5 in' },
|
|
{ name: '6 ft 6 in', abbreviation: '6 ft 6 in' },
|
|
{ name: '6 ft 7 in', abbreviation: '6 ft 7 in' },
|
|
{ name: '6 ft 8 in', abbreviation: '6 ft 8 in' },
|
|
{ name: '6 ft 9 in', abbreviation: '6 ft 9 in' },
|
|
{ name: '6 ft 10 in', abbreviation: '6 ft 10 in' },
|
|
{ name: '6 ft 11 in', abbreviation: '6 ft 11 in' },
|
|
{ name: '7 ft 0 in', abbreviation: '7 ft 0 in' },
|
|
]);
|
|
const isMobile = ref(window.innerWidth <= 768); // Assuming mobile width is less than or equal to 768px
|
|
|
|
const checkIfMobile = () => {
|
|
isMobile.value = window.innerWidth <= 768;
|
|
};
|
|
|
|
// Attach event listener on component mount
|
|
onMounted(async () => {
|
|
window.addEventListener('resize', checkIfMobile);
|
|
await getPatientInfo()
|
|
});
|
|
|
|
// Detach event listener on component unmount
|
|
onUnmounted(() => {
|
|
window.removeEventListener('resize', checkIfMobile);
|
|
});
|
|
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 `${month}-${day}-${year}`;
|
|
};
|
|
const onSubmit = async () => {
|
|
infoVForm.value?.validate().then(async ({ valid: isValid }) => {
|
|
console.log('isValid ', isValid)
|
|
if (isValid)
|
|
await updatePatientDetails()
|
|
})
|
|
}
|
|
const getPatientInfo = async () => {
|
|
const patient_id = localStorage.getItem('patient_id')
|
|
const access_token = localStorage.getItem('access_token');
|
|
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
|
|
patientId.value = patientData.id
|
|
dob.value = patientData.dob;
|
|
gender.value = patientData.gender;
|
|
martialStatus.value = patientData.marital_status;
|
|
height.value = patientData.height;
|
|
weight.value = patientData.weight;
|
|
|
|
|
|
|
|
isLoadingVisible.value = false;
|
|
} else {
|
|
isLoadingVisible.value = false;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
});
|
|
}
|
|
const updatePatientDetails = async () => {
|
|
console.log('updatePatientDetails');
|
|
await axios.post('/api/update-patient/' + patientId.value, {
|
|
|
|
dob: dob.value,
|
|
gender: gender.value,
|
|
marital_status: martialStatus.value,
|
|
height: height.value,
|
|
weight: weight.value,
|
|
|
|
}).then(r => {
|
|
console.log("updated patient ", r.data);
|
|
localStorage.setItem('profileCompleted', '1')
|
|
router.push('/overview');
|
|
isTonalSnackbarVisible.value = true;
|
|
patientResponse.value = r.data.message;
|
|
isLoadingVisible.value = false;
|
|
}).catch(e => {
|
|
console.log(e.response);
|
|
const { errors: formErrors } = e.response.data.errors;
|
|
console.error("Error", e.response.data.errors)
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<VSnackbar v-model="isTonalSnackbarVisible" :timeout="5000" 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>
|
|
<VAlert color="red text-white mb-0">
|
|
<p class="text-white mb-0">Please finish updating your profile.</p>
|
|
</VAlert>
|
|
<VRow>
|
|
<VCol cols="12">
|
|
<VCard class="mt-2">
|
|
<VCardText>
|
|
<h4>Personal Details</h4>
|
|
<VForm class="mt-6" ref="infoVForm" @submit.prevent="onSubmit">
|
|
<VRow>
|
|
<VCol md="4" cols="12">
|
|
<VTextField v-model="dob" :max="getCurrentDate()" label="Date of Birth"
|
|
placeholder="Date of Birth" type="date" :rules="[requiredValidator]" />
|
|
</VCol>
|
|
<VCol md="4" cols="12">
|
|
<v-select v-model="gender" label="Select Gender" :items="genders" item-title="name"
|
|
item-value="abbreviation" :rules="[requiredValidator]"
|
|
:error-messages="errors.gender">
|
|
</v-select>
|
|
</VCol>
|
|
<VCol cols="12" md="4">
|
|
<v-select v-model="martialStatus" label="Select Marital Status" :items="maritalStatuses"
|
|
item-title="name" item-value="abbreviation" :rules="[requiredValidator]"
|
|
:error-messages="errors.martial_status">
|
|
</v-select>
|
|
</VCol>
|
|
<VCol cols="12" md="4">
|
|
<v-select v-model="height" label="Select Height" :items="heights" item-title="name"
|
|
item-value="abbreviation" :rules="[requiredValidator]"
|
|
:error-messages="errors.height">
|
|
</v-select>
|
|
</VCol>
|
|
<VCol cols="12" md="4">
|
|
<VTextField v-model="weight" label="Weight" :rules="[requiredValidator]" />
|
|
</VCol>
|
|
|
|
<!-- 👉 Form Actions -->
|
|
<VCol cols="12" class="d-flex flex-wrap gap-4">
|
|
<VBtn type="submit">Save changes</VBtn>
|
|
|
|
<VBtn color="secondary" variant="tonal" type="reset">
|
|
Reset
|
|
</VBtn>
|
|
</VCol>
|
|
</VRow>
|
|
</VForm>
|
|
</VCardText>
|
|
</VCard>
|
|
</VCol>
|
|
</VRow>
|
|
</template>
|
|
<style>
|
|
.border-r {
|
|
border-right: 1px solid silver;
|
|
}
|
|
</style>
|