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

365 lines
18 KiB
Vue

<script setup>
import StartOverPupup from '@/views/pages/home/StartOverPupup.vue';
import axios from '@axios';
import {
cardNumberValidator,
cvvValidator,
expiryValidator,
requiredValidator
} from '@validators';
import moment from 'moment';
import { onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
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 patient_id = localStorage.getItem('patient_id')
const access_token = store.access_token;
const seetingPlanLogo = ref();
const isLoadingVisible = ref(false)
const paymentForm = ref()
const cardNumber = ref('')
const expiry = ref('')
const cvv = ref('')
const zipcode = ref('')
const firstName = ref('')
const lastName = ref('')
const email = ref('');
const phoneNumber = ref('');
const address = ref('');
const city = ref('');
const state = ref('');
const zip_code = ref('');
const country = ref('');
const dob = ref('')
const gender = ref('')
const marital_status = ref('')
const height = ref('')
const weight = ref('')
const scheduleDate = ref('');
const scheduleTime = ref('');
const timeZone = ref('');
const timeDifference = ref();
const shippingAddress = ref();
const todayDate = ref()
const planName = ref('')
const planAmount = ref('')
const myPlanName = ref(localStorage.getItem('plan_name'))
const myPlanPrice = ref(localStorage.getItem('plan_price'))
const myPlanTitle1 = ref(localStorage.getItem('list_sub_title'))
const myPlanTitle2 = ref(localStorage.getItem('list_one_title'))
const myPlanTitle3 = ref(localStorage.getItem('list_two_title'))
const myPlanImage = ref(localStorage.getItem('plan_image'))
const currentPath = window.location.origin
onBeforeMount(async () => {
store.dispatch('updateIsLoading', true)
store.dispatch('updateCurrentPage', 'process-payment')
localStorage.setItem('currentPage', 'process-payment')
await store.dispatch('getPatientInfo')
await store.dispatch('getPlanInfo')
await store.dispatch('getPatientAppointment')
await store.dispatch('getAdditionalInformation')
planName.value = store.getters.getPatientPlan.plan_name
planAmount.value = store.getters.getPatientPlan.plan_amount
firstName.value = store.getters.getPatient.first_name;
lastName.value = store.getters.getPatient.last_name
email.value = store.getters.getPatient.email
phoneNumber.value = store.getters.getPatient.phone_no
dob.value = store.getters.getPatient.dob
gender.value = store.getters.getPatient.gender
marital_status.value = store.getters.getPatient.marital_status
weight.value = store.getters.getPatient.weight
height.value = store.getters.getPatient.height
address.value = store.getters.getShippingInformation.shipping_address1
city.value = store.getters.getShippingInformation.shipping_city
state.value = store.getters.getShippingInformation.shipping_state
zip_code.value = store.getters.getShippingInformation.shipping_zipcode
country.value = store.getters.getShippingInformation.billing_address1
shippingAddress.value = (address.value ? address.value + ', ' : '') +
(city.value ? city.value + ', ' : '') +
(state.value ? state.value + ' ' : '') +
(zip_code.value ? zip_code.value + ', ' : '') +
(country.value ? country.value : '');
let diffInMinutes = store.getters.getTimeDiff.time_diff;
// scheduleTime.value = appointmentData.appointment_time;
const time = moment(store.getters.getBookedAppointment.appointment_time, 'HH:mm:ss');
// Check if the time is AM or PM
scheduleTime.value = time.format('HH:mm a');
timeZone.value = store.getters.getBookedAppointment.timezone;
timeDifference.value = diffInMinutes;
// console.log(gender.value);
let dateString = store.getters.getPatient.dob
let parts = dateString.split("-");
dob.value = `${parts[1]}-${parts[2]}-${parts[0]}`;
const appointment_date = new Date(store.getters.getBookedAppointment.appointment_date);
const formattedDate = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
}).format(appointment_date);
scheduleDate.value = formattedDate;
store.dispatch('updateIsLoading', false)
})
onMounted(async () => {
todayDate.value = moment().format('MM-DD-YYYY');
window.addEventListener('resize', checkIfMobile);
let setting = await axios.post('/api/settings', {})
console.log(setting.data)
seetingPlanLogo.value = '/assets/logo/' + setting.data.logo
})
// Detach event listener on component unmount
onUnmounted(() => {
window.removeEventListener('resize', checkIfMobile);
});
const checkIfMobile = () => {
isMobile.value = window.innerWidth <= 768;
};
const cardNumberFormat = () => {
cardNumber.value = cardNumber.value.replace(/\D/g, '').substring(0, 16);
}
const formatExpiry = () => {
// Automatically format the input to MM/YY format
expiry.value = expiry.value.replace(/\D/g, '').slice(0, 4).replace(/(\d{2})(\d{2})/, '$1/$2');
}
const handleCVVInput = () => {
// Remove non-digit characters from input
cvv.value = cvv.value.replace(/\D/g, '');
}
const validatePayment = async () => {
const { valid: isValid } = await paymentForm.value?.validate();
console.log('isValid ', isValid);
if (isValid) {
await processPayment()
router.replace(route.query.to && route.query.to != '/process-payment' ? String(route.query.to) : '/thankyou')
}
};
const processPayment = async () => {
await store.dispatch('processPayment')
}
const imageSrc = (src) => {
return `${currentPath}/product/${src}`
};
const backFun = () => {
store.dispatch('updateIsLoading', true)
router.replace(route.query.to && route.query.to != '/process-payment' ? String(route.query.to) : '/checkout')
}
</script>
<template>
<StartOverPupup :showPopup="store.getters.getShowStartOverPupup"></StartOverPupup>
<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="pb-sm-5 pb-2 rounded-top">
<!-- <VContainer> -->
<div class="auth-wrapper d-flex align-center justify-center pa-4 mt-4" style="flex-direction: column;">
<h3 class="mb-8" style="max-width: 600px;width: 100%">Review your treatment and pay</h3>
<VCard class="auth-card pa-2 rounded-3 mt-1 pb-4 pt-4" style="max-width: 600px;width: 100%;">
<p class="mb-0" style="font-family: system-ui;">$0 Due Now - Pay Upon Medical Approval</p>
</VCard>
<h5 class="mt-8" style="max-width: 600px;width: 100%">Your Plan</h5>
<VCard class="auth-card pa-2 rounded-3 mt-1 pb-2" style="max-width: 600px;width: 100%">
<v-row>
<v-col cols="12" md="3">
<v-img :src="imageSrc(myPlanImage)" alt="Selected Item" width="200px" height="150px"></v-img>
</v-col>
<v-col cols="12" md="9">
<v-card-title class="pb-0">
<div style="font-size: 14px;">
<strong>{{ myPlanName }}</strong>
<span class="float-right"><strong>${{ myPlanPrice }}</strong></span>
</div>
</v-card-title>
<v-card-subtitle class="pt-0">0.25mg</v-card-subtitle>
<v-card-text class="pt-0 pb-0">
<p>1ml x 1 Month</p>
</v-card-text>
</v-col>
</v-row>
<v-list dense>
<v-list-item style="border-top: 1px solid #c0c0c075;">
<v-list-item-content>
<v-list-item-title>
<span>{{ myPlanTitle1 }}</span>
<span class="float-right"><b>Included</b></span>
</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item style="border-top: 1px solid #c0c0c075;">
<v-list-item-content>
<v-list-item-title>
<span>{{ myPlanTitle2 }}</span>
<span class="float-right"><b>Included</b></span>
</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item style="border-top: 1px solid #c0c0c075;">
<v-list-item-content>
<v-list-item-title>
<span>{{ myPlanTitle3 }}</span>
</v-list-item-title>
</v-list-item-content>
</v-list-item>
<!-- Add more features as needed -->
</v-list>
</VCard>
<h5 class="mt-8" style="max-width: 600px;width: 100%">Payment</h5>
<VCard class="auth-card pa-2 rounded-3 mt-1 pb-2" style="max-width: 600px;width: 100%">
<h4 class="mb-2 mt-2">
<VIcon>mdi-credit-card</VIcon> Card
</h4>
<VForm ref="paymentForm" @submit.prevent="() => { }">
<VRow>
<VCol cols="12" lg="12" md="12">
<VRow>
<VCol cols="12" lg="12" md="12">
<VTextField v-model="cardNumber" label="Credit Card Number*"
:rules="[requiredValidator, cardNumberValidator]" placeholder="xxxxxxxxxxxxxxxx"
@input="cardNumberFormat" density="comfortable" />
</VCol>
<!-- <VCol cols="12" lg="4" md="4">
<VTextField v-model="zipcode" label="Zipcode*" type="number"
:rules="[requiredValidator]" placeholder="zipcode" density="comfortable"/>
</VCol> -->
<VCol cols="12" lg="6" md="6">
<VTextField v-model="expiry" label="Expiration Date*"
:rules="[requiredValidator, expiryValidator]" placeholder="MM/YY"
@input="formatExpiry" density="comfortable" />
</VCol>
<VCol cols="12" lg="6" md="6">
<VTextField v-model="cvv" :rules="[requiredValidator, cvvValidator]" label="CVV*"
maxlength="3" @input="handleCVVInput" density="comfortable" />
</VCol>
</VRow>
</VCol>
<!-- <VCol cols="12" lg="6" md="6">
<svg v-if="!isMobile" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="auto" height="150"
viewBox="0 0 256 256" xml:space="preserve">
<defs>
</defs>
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;"
transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)">
<path
d="M 81.159 25.776 l -0.9 -10.05 c -0.101 -1.123 -1.092 -1.952 -2.215 -1.851 L 1.86 20.698 c -1.123 0.101 -1.952 1.092 -1.851 2.215 l 4.128 46.09 c 0.101 1.123 1.092 1.952 2.215 1.851 l 3.076 -0.276 L 81.159 25.776 z"
style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(176,182,188); fill-rule: nonzero; opacity: 1;"
transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
<path
d="M 9.428 74.189 c 0 1.074 0.871 1.944 1.944 1.944 h 76.683 c 1.074 0 1.944 -0.871 1.944 -1.944 V 49.73 c -26.255 -4.947 -53.138 -4.734 -80.572 0 V 74.189 z"
style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(64,89,107); fill-rule: nonzero; opacity: 1;"
transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
<path
d="M 88.056 25.776 H 11.372 c -1.074 0 -1.944 0.871 -1.944 1.945 v 7.719 c 26.857 6.175 53.715 6.175 80.572 0 v -7.719 C 90 26.647 89.129 25.776 88.056 25.776 z"
style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(64,89,107); fill-rule: nonzero; opacity: 1;"
transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
<rect x="9.43" y="35.44" rx="0" ry="0" width="80.57" height="14.29"
style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(242,242,242); fill-rule: nonzero; opacity: 1;"
transform=" matrix(1 0 0 1 0 0) " />
<path
d="M 51.045 60.484 H 19.469 c -0.552 0 -1 -0.447 -1 -1 s 0.448 -1 1 -1 h 31.576 c 0.553 0 1 0.447 1 1 S 51.598 60.484 51.045 60.484 z"
style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(242,242,242); fill-rule: nonzero; opacity: 1;"
transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
<path
d="M 37.707 68.001 H 19.469 c -0.552 0 -1 -0.447 -1 -1 s 0.448 -1 1 -1 h 18.238 c 0.552 0 1 0.447 1 1 S 38.259 68.001 37.707 68.001 z"
style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(242,242,242); fill-rule: nonzero; opacity: 1;"
transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
<path
d="M 51.045 68.001 h -8.574 c -0.552 0 -1 -0.447 -1 -1 s 0.448 -1 1 -1 h 8.574 c 0.553 0 1 0.447 1 1 S 51.598 68.001 51.045 68.001 z"
style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(242,242,242); fill-rule: nonzero; opacity: 1;"
transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
<path
d="M 81.153 58.484 H 65.638 c -0.553 0 -1 0.447 -1 1 v 7.517 c 0 0.553 0.447 1 1 1 h 15.516 c 0.553 0 1 -0.447 1 -1 v -7.517 C 82.153 58.932 81.706 58.484 81.153 58.484 z"
style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(242,242,242); fill-rule: nonzero; opacity: 1;"
transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
</g>
</svg>
</VCol> -->
</VRow>
<div class="text-center mb-2 mt-2">
<VBtn type="submit" class="px-4 mt-4 mb-2" color="primary" variant="flat"
@click="validatePayment" style="background-color: rgb(var(--v-theme-yellow)) !important;"
block>
Confirm</VBtn>
<VBtn class="px-4" color="grey" variant="flat" @click="backFun" :class="isMobile ? '' : 'mr-2'"
block>
Back</VBtn>
</div>
</VForm>
</VCard>
</div>
<!-- </VContainer> -->
</div>
</template>
<style lang="scss">
.logo-img {
display: block;
position: relative;
margin: 0 auto;
}
.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: 176px;
}
.no-border {
border: none !important;
}
td {
border: none !important;
}
th {
border: none !important;
}
.cut-text {
white-space: nowrap;
/* Prevents text from wrapping */
overflow: hidden;
/* Hides any content that overflows the container */
text-overflow: ellipsis;
/* Displays an ellipsis (...) to represent the clipped text */
// width: 100px;
text-decoration: line-through;
text-decoration-color: red;
/* Set the color of the line */
text-decoration-thickness: 1px;
/* Adjust the width as needed */
}
</style>../store1.js