Files
purityselect_admin/resources/js/pages/patients/register-patient-step.vue
2024-10-25 19:58:19 +05:00

579 lines
17 KiB
Vue

<script setup>
import { VNodeRenderer } from '@layouts/components/VNodeRenderer';
import { themeConfig } from '@themeConfig';
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
const router = useRouter()
const store = useStore()
definePage({ meta: { layout: 'blank' } })
const states = ref([
{ name: 'Alabama', abbreviation: 'AL' },
{ name: 'Alaska', abbreviation: 'AK' },
{ name: 'Arizona', abbreviation: 'AZ' },
{ name: 'Arkansas', abbreviation: 'AR' },
{ 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: '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 sortedStates = computed(() => {
return states.value.slice().sort((a, b) => {
return a.name.localeCompare(b.name);
});
});
const selectedStateName = (abbreviation) => {
const selectedState = states.value.find(
(s) => s.abbreviation === abbreviation
);
return selectedState ? selectedState.name : abbreviation;
};
const currentStep = ref(0)
const isPasswordVisible = ref(false)
const isConfirmPasswordVisible = ref(false)
const formSave = ref(null)
const formatPhoneNumber = () => {
// Remove non-numeric characters from the input
const numericValue = form.value.phone_no.replace(/\D/g, '');
// Apply formatting logic
if (numericValue.length <= 10) {
form.value.phone_no = numericValue.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
} else {
// Limit the input to a maximum of 14 characters
const truncatedValue = numericValue.slice(0, 10);
form.value.phone_no= truncatedValue.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
}
};
const getCurrentDate = () => {
const today = new Date();
console.log("today", today);
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 radioContent = [
{
title: 'Starter',
desc: 'A simple start for everyone.',
value: '0',
},
{
title: 'Standard',
desc: 'For small to medium businesses.',
value: '99',
},
{
title: 'Enterprise',
desc: 'Solution for big organizations.',
value: '499',
},
]
const items = [
{
title: 'Account',
subtitle: 'Account Details',
},
{
title: 'Shipping Information',
subtitle: 'Enter Information',
}
]
const form = ref({
first_name: '',
last_name: '',
email: '',
password: '',
mobile: '',
pincode: '',
address: '',
landmark: '',
city: '',
dob: '',
phone_no:'',
state: null,
selectedPlan: '0',
cardNumber: '',
cardName: '',
expiryDate: '',
cvv: '',
zip_code: '',
country: 'United States',
gender:''
})
const genders = ref([
{ name: 'Male', abbreviation: 'Male' },
{ name: 'Female', abbreviation: 'Female' },
{ name: 'Other', abbreviation: 'Other' },
]);
const validateStep = async () => {
const { valid } = await formSave.value.validate()
console.log(formSave.value)
return valid
}
const handleNext = async () => {
if (await validateStep()) {
if (currentStep.value < items.length - 1) {
console.log('Age', calculateAge(form.value.dob))
if (calculateAge(form.value.dob) >= 18) {
currentStep.value++
} else {
store.dispatch('updateErrorMessage', 'Patient must be 18+')
}
}
}
}
const handlePrevious = () => {
if (currentStep.value > 0) {
currentStep.value--
}
}
const calculateAge = (dateOfBirth) => {
const today = new Date();
const birthDate = new Date(dateOfBirth);
let age = today.getFullYear() - birthDate.getFullYear();
const monthDiff = today.getMonth() - birthDate.getMonth();
if (
monthDiff < 0 ||
(monthDiff === 0 && today.getDate() < birthDate.getDate())
) {
age--;
}
return age;
};
const onSubmit = async () => {
const { valid } = await formSave.value.validate()
if (valid) {
await store.dispatch('patientAdd',{
first_name: form.value.first_name,
last_name: form.value.last_name,
email: form.value.email,
password: form.value.password,
phone_no: form.value.phone_no,
dob: form.value.dob,
address: form.value.address,
city: form.value.city,
state: form.value.state,
country: form.value.country,
gender: form.value.gender,
zip_code:form.value.zip_code
})
if (!store.getters.getErrorMsg) {
router.push('/admin/patients');
form.value.first_name = null
form.value.last_name = null
form.value.email = null
form.value.password = null
form.value.phone_no = null
form.value.dob = null
form.value.address = null
form.value.city = null
form.value.state = null
form.value.country = null
form.value.zip_code=null
}
}
}
</script>
<template>
<RouterLink to="/">
<div class="auth-logo d-flex align-center gap-x-3">
<VNodeRenderer :nodes="themeConfig.app.logo" />
<h1 class="auth-title">
{{ themeConfig.app.title }}
</h1>
</div>
</RouterLink>
<VRow
no-gutters
class="auth-wrapper"
>
<VCol
cols="12"
md="12"
class="auth-card-v2 d-flex align-center justify-center pa-10"
style="background-color: rgb(var(--v-theme-surface));"
>
<VCard
flat
class="mt-12 mt-sm-0"
>
<AppStepper
v-model:current-step="currentStep"
:items="items"
:direction="$vuetify.display.smAndUp ? 'horizontal' : 'vertical'"
class="mb-12"
/>
<VWindow
v-model="currentStep"
class="disable-tab-transition"
style="max-inline-size: 650px;"
>
<VForm ref="formSave">
<VWindowItem >
<h4 class="text-h4">
Basic Information
</h4>
<p class="mb-5">
Enter Your Account Details
</p>
<VRow>
<VCol
cols="12"
md="6"
>
<VTextField
v-model="form.first_name"
label="First Name"
placeholder="Johndoe"
:rules="[requiredValidator]"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<VTextField
v-model="form.last_name"
label="Last Name"
placeholder="Johndoe"
:rules="[requiredValidator]"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<VTextField
v-model="form.email"
label="Email"
placeholder="johndoe@email.com"
:rules="[requiredValidator, emailValidator]"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<VTextField
v-model="form.password"
label="Password"
placeholder="············"
:type="isPasswordVisible ? 'text' : 'password'"
:append-inner-icon="isPasswordVisible ? 'ri-eye-off-line' : 'ri-eye-line'"
@click:append-inner="isPasswordVisible = !isPasswordVisible"
:rules="[requiredValidator, passwordValidator]"
/>
</VCol>
<VCol cols="12" md="6">
<VTextField v-model="form.phone_no" label="Phone Number" pattern="^\(\d{3}\) \d{3}-\d{4}$"
:rules="[requiredPhone, validUSAPhone]" placeholder="i.e. (000) 000-0000"
@input="formatPhoneNumber" max="14" density="comfortable" />
</VCol>
<VCol cols="12" md="6">
<v-select v-model="form.gender" label="Gender" :items="genders" item-title="name" item-value="abbreviation"
:rules="[requiredValidator]" density="comfortable">
</v-select>
</VCol>
<VCol cols="12" md="6">
<AppDateTimePicker
v-model="form.dob"
label="Date Of Birth"
placeholder="Date Of Birth"
format="MM-dd-yyyy"
:config="{ dateFormat: 'Y-m-d' }"
:max="getCurrentDate()"
:rules="[requiredValidator]"
/>
</VCol>
</VRow>
</VWindowItem>
<VWindowItem >
<h4 class="text-h4">
Shipping Information
</h4>
<p class="mb-5">
Enter Your Shipping Information
</p>
<VRow>
<VCol cols="12">
<VTextField
v-model="form.address"
label="Address"
placeholder="1234 Main St, New York, NY 10001, USA"
:rules="[requiredValidator]"
/>
</VCol>
<VCol cols="12">
<VTextField
v-model="form.zip_code"
label="Zip Code*"
type="number"
:rules="[requiredValidator]"
placeholder="982347"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<VTextField
v-model="form.city"
label="City"
placeholder="New York"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<VAutocomplete
v-model="form.state"
label="States"
:items="sortedStates"
item-title="name" item-value="abbreviation"
placeholder="Select State"
:rules="[requiredState]"
/>
</VCol>
</VRow>
</VWindowItem>
<VWindowItem>
<h4 class="text-h4">
Select Plan
</h4>
<p class="mb-5">
Select plan as per your requirement
</p>
<CustomRadiosWithIcon
v-model:selected-radio="form.selectedPlan"
:radio-content="radioContent"
:grid-column="{ sm: '4', cols: '12' }"
>
<template #default="{ item }">
<div class="text-center">
<h6 class="text-h6 mb-2">
{{ item.title }}
</h6>
<p class="clamp-text text-body-2 mb-2">
{{ item.desc }}
</p>
<div class="d-flex align-center justify-center">
<div class="text-primary mb-2">
$
</div>
<h4 class="text-h4 text-primary">
{{ item.value }}
</h4>
<div class="text-body-2 text-disabled mt-2">
/month
</div>
</div>
</div>
</template>
</CustomRadiosWithIcon>
<h4 class="text-h4 mt-12">
Payment Information
</h4>
<p class="mb-5">
Enter your card information
</p>
<VRow>
<VCol cols="12">
<VTextField
v-model="form.cardNumber"
type="number"
label="Card Number"
placeholder="1234 1234 1234 1234"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<VTextField
v-model="form.cardName"
label="Name on Card"
placeholder="John Doe"
/>
</VCol>
<VCol
cols="6"
md="3"
>
<VTextField
v-model="form.expiryDate"
label="Expiry"
placeholder="MM/YY"
/>
</VCol>
<VCol
cols="6"
md="3"
>
<VTextField
v-model="form.cvv"
type="number"
label="CVV"
placeholder="123"
/>
</VCol>
</VRow>
</VWindowItem>
</VForm>
</VWindow>
<div class="d-flex flex-wrap justify-space-between gap-x-4 gap-y-2 mt-5">
<VBtn
color="secondary"
variant="outlined"
:disabled="currentStep === 0"
@click="currentStep--"
>
<VIcon
icon="ri-arrow-left-line"
start
class="flip-in-rtl"
@click="handlePrevious"
/>
Previous
</VBtn>
<VBtn
v-if="items.length - 1 === currentStep"
color="success"
append-icon="ri-check-line"
@click="onSubmit"
>
submit
</VBtn>
<VBtn
v-else
@click="handleNext(currentStep)"
>
Next
<VIcon
icon="ri-arrow-right-line"
end
class="flip-in-rtl"
/>
</VBtn>
</div>
</VCard>
</VCol>
</VRow>
</template>
<style lang="scss">
@use "@core-scss/template/pages/page-auth.scss";
</style>