purityselect/resources/js/pages/provider/orders-list-new.vue
2024-10-25 01:05:27 +05:00

603 lines
22 KiB
Vue

<script setup>
import moment from "moment";
import { computed, onMounted, ref } from "vue";
import { useDisplay } from "vuetify";
import { useStore } from "vuex";
const router = useRouter();
const store = useStore();
const ordersList = ref([]);
const widgetData = ref([
{
title: "Pending Payment",
value: 56,
icon: "ri-calendar-2-line",
},
{
title: "Completed",
value: 12689,
icon: "ri-check-double-line",
},
{
title: "Refunded",
value: 124,
icon: "ri-wallet-3-line",
},
{
title: "Failed",
value: 32,
icon: "ri-error-warning-line",
},
]);
const searchQuery = ref("");
// Data table options
const itemsPerPage = ref(10);
const page = ref(1);
const sortBy = ref();
const orderBy = ref();
const { smAndDown } = useDisplay();
const options = ref({
page: 1,
itemsPerPage: 5,
sortBy: [""],
sortDesc: [false],
});
const isLoading = ref(true);
// Data table Headers
const headers = [
{
title: "Order",
key: "id",
},
// {
// title: 'Order Date',
// key: 'date',
// },
{
title: "Patient",
key: "patient_name",
},
{
title: "Meeting Date",
key: "appointment_date",
},
{
title: "Meeting Time",
key: "appointment_time",
},
{
title: "Perscrption Status",
key: "status",
},
{
title: "Meeting status",
key: "appointment_status",
},
{
title: "Actions",
key: "actions",
sortable: false,
},
];
const updateOptions = (options) => {
page.value = options.page;
sortBy.value = options.sortBy[0]?.key;
orderBy.value = options.sortBy[0]?.order;
};
const resolvePaymentStatus = (status) => {
if (status === 1)
return {
text: "Paid",
color: "success",
};
if (status === 2)
return {
text: "Pending",
color: "warning",
};
if (status === 3)
return {
text: "Cancelled",
color: "secondary",
};
if (status === 4)
return {
text: "Failed",
color: "error",
};
};
const resolveStatusVariant = (status) => {
switch (status.toLowerCase()) {
case "completed":
return { color: "success", text: "Completed" };
case "scheduled":
return { color: "primary", text: "Scheduled" };
case "cancelled":
return { color: "error", text: "Cancelled" };
default:
return { color: "warning", text: "Pending" };
}
};
const formatDateDa = (date) => {
const messageDate = new Date(date);
const options = {
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "2-digit",
hour12: false,
};
const formattedDate = messageDate
.toLocaleString("en-US", options)
.replace(/\//g, "-")
.replace(",", "");
return `${formattedDate}`;
};
function totalCallDuration(start_time, end_time) {
console.log(start_time, end_time);
const startMoment = moment(start_time);
const endMoment = moment(end_time);
// Calculate the duration
const duration = moment.duration(endMoment.diff(startMoment));
const hours = duration.hours();
const thours = `${String(hours).padStart(2, "0")}`;
const minutes = duration.minutes();
const tminutes = `${String(minutes).padStart(2, "0")}`;
const seconds = duration.seconds();
const tsecond = `${String(seconds).padStart(2, "0")}`;
let durationText;
if (hours === 0 && minutes === 0) {
//for second
durationText = ` 00:00:${tsecond}`;
} else if (hours === 0 && minutes > 0) {
//for minutes
durationText = `00:${tminutes}:${tsecond}`;
} else if (hours > 0) {
//for hours
durationText = `${thours}:${tminutes}:${tsecond}`;
}
const totalDuration = durationText;
console.log("Duration:", durationText);
// You may need to adjust this function based on your actual data structure
// For example, if you have separate first name and last name properties in each appointment object
return totalDuration; // For now, just return the first name
}
const ordersGetList = computed(() => {
return ordersList.value.map((history) => ({
...history,
// appointment_date: getConvertedDate(convertUtcTime(history.appointment_time, history.appointment_date, history.timezone)),
//appointment_time: getConvertedTime(convertUtcTime(history.appointment_time, history.appointment_date, history.timezone)),
// appointment_date: changeFormat(history.appointment_date),
// appointment_time: convertUtcDateTimeToLocal(history.appointment_date, history.appointment_time, 'time'),
// start_time: changeDateFormat(history.start_time),
// end_time: changeDateFormat(history.end_time),
// duration: totalCallDuration(history.start_time, history.end_time),
}));
// isLoading.value - false
// ordersList.value.sort((a, b) => {
// return b.id - a.id;
// });
// return ordersList.value
});
onMounted(async () => {
store.dispatch("updateIsLoading", true);
await store.dispatch("orderAgentList");
ordersList.value = store.getters.getPatientOrderList;
console.log("ordersList", ordersList.value);
isLoading.value = false;
});
const convertUtcTime = (time, date, timezone) => {
const timezones = {
EST: "America/New_York",
CST: "America/Chicago",
MST: "America/Denver",
PST: "America/Los_Angeles",
// Add more mappings as needed
};
// Get the IANA timezone identifier from the abbreviation
const ianaTimeZone = timezones[timezone];
if (!ianaTimeZone) {
throw new Error(`Unknown timezone abbreviation: ${timezone}`);
}
// Combine date and time into a single string
const dateTimeString = `${date}T${time}Z`; // Assuming the input date and time are in UTC
// Create a Date object from the combined string
const dateObj = new Date(dateTimeString);
// Options for the formatter
const options = {
timeZone: ianaTimeZone,
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
};
// Create the formatter
const formatter = new Intl.DateTimeFormat("en-US", options);
// Format the date
const convertedDateTime = formatter.format(dateObj);
return convertedDateTime;
};
const getConvertedTime = (inputDate) => {
// Split the input date string into date and time components
const [datePart, timePart] = inputDate.split(", ");
// Split the time component into hours, minutes, and seconds
let [hours, minutes, seconds] = timePart.split(":");
// Convert the hours to an integer
hours = parseInt(hours);
// Determine the period (AM/PM) and adjust the hours if necessary
const period = hours >= 12 ? "PM" : "AM";
hours = hours % 12 || 12; // Convert 0 and 12 to 12, and other hours to 1-11
// Format the time as desired
const formattedTime = `${hours
.toString()
.padStart(2, "0")}:${minutes}${period}`;
return formattedTime;
};
const getConvertedDate = (inputDate) => {
// Split the input date string into date and time components
const [datePart, timePart] = inputDate.split(", ");
// Split the date component into month, day, and year
const [month, day, year] = datePart.split("/");
// Create a new Date object from the parsed components
const dateObject = new Date(`${year}-${month}-${day}T${timePart}`);
// Define an array of month names
const monthNames = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
// Format the date as desired
const formattedDate = `${
monthNames[dateObject.getMonth()]
} ${day}, ${year}`;
return formattedDate;
};
const formatDate = (date) => {
const messageDate = new Date(date);
const options = {
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric", // Change from '2-digit' to 'numeric'
minute: "2-digit",
hour12: true, // Add hour12: true to get 12-hour format with AM/PM
};
const formattedDate = messageDate
.toLocaleString("en-US", options)
.replace(/\//g, "-")
.replace(",", ""); // Remove the comma
return formattedDate.trim();
};
const viewOrder = (orderId) => {
router.push({ name: "provider-order-detail", params: { id: orderId } });
};
function changeFormat(dateFormat) {
const dateParts = dateFormat.split("-"); // Assuming date is in yyyy-mm-dd format
const year = parseInt(dateParts[0]);
const month = String(dateParts[1]).padStart(2, "0"); // Pad single-digit months with leading zero
const day = String(dateParts[2]).padStart(2, "0"); // Pad single-digit days with leading zero
// Create a new Date object with the parsed values
const date = new Date(year, month - 1, day); // Month is zero-based in JavaScript Date object
// Format the date as mm-dd-yyyy
const formattedDate = month + "-" + day + "-" + date.getFullYear();
return formattedDate;
}
const getStatusColor = (status) => {
switch (status) {
case "pending":
return "orange";
case "Shipped":
return "blue";
case "Delivered":
return "green";
case "Cancelled":
return "red";
default:
return "gray";
}
};
</script>
<template>
<div>
<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>
<VCard class="mb-6" style="display: none">
<VCardText class="px-2">
<VRow>
<template v-for="(data, index) in widgetData" :key="index">
<VCol cols="12" sm="6" md="3" class="px-6">
<div
class="d-flex justify-space-between"
:class="
$vuetify.display.xs
? 'product-widget'
: $vuetify.display.sm
? index < 2
? 'product-widget'
: ''
: ''
"
>
<div class="d-flex flex-column gap-y-1">
<h4 class="text-h4">
{{ data.value }}
</h4>
<span class="text-base text-capitalize">
{{ data.title }}
</span>
</div>
<VAvatar variant="tonal" rounded size="42">
<VIcon :icon="data.icon" size="26" />
</VAvatar>
</div>
</VCol>
<VDivider
v-if="
$vuetify.display.mdAndUp
? index !== widgetData.length - 1
: $vuetify.display.smAndUp
? index % 2 === 0
: false
"
vertical
inset
length="100"
/>
</template>
</VRow>
</VCardText>
</VCard>
<VRow>
<VCol cols="12" md="12">
<VCard title="Prescriptions">
<VCardText>
<div
class="d-flex justify-sm-space-between align-center justify-start flex-wrap gap-4"
>
<VTextField
v-model="searchQuery"
placeholder="Search Order"
density="compact"
style="
max-inline-size: 200px;
min-inline-size: 200px;
"
/>
</div>
</VCardText>
<VCardText>
<v-data-table
:loading="isLoading"
:headers="headers"
:items="ordersGetList"
:search="searchQuery"
>
<!-- full name -->
<template #item.id="{ item }">
<RouterLink
:to="{
name: 'provider-order-detail',
params: { id: item.id },
}"
>
#{{ item.id }}
</RouterLink>
</template>
<template #item.patient_name="{ item }">
<div class="d-flex align-center">
<VAvatar
size="32"
:color="
item.profile_picture
? ''
: 'primary'
"
:class="
item.profile_picture
? ''
: 'v-avatar-light-bg primary--text'
"
:variant="
!item.profile_picture
? 'tonal'
: undefined
"
>
<VImg
v-if="item.profile_picture"
:src="item.profile_picture"
/>
<span v-else>{{
item.patient_name.charAt(0)
}}</span>
</VAvatar>
<div class="d-flex flex-column ms-3">
<RouterLink
:to="{
name: 'provider-patient-profile-detail',
params: { id: item.patient_id },
}"
>
<div class="font-weight-medium">
{{ item.patient_name }}
</div>
</RouterLink>
<small>{{ item.patient_email }}</small>
</div>
</div>
</template>
<template #item.appointment_date="{ item }">
{{
getConvertedDate(
convertUtcTime(
item.appointment_time,
item.appointment_date,
item.timezone
)
)
}}
</template>
<template #item.appointment_time="{ item }">
{{
getConvertedTime(
convertUtcTime(
item.appointment_time,
item.appointment_date,
item.timezone
)
)
}}
</template>
<template #item.status="{ item }">
<span>
<VChip
variant="tonal"
:color="getStatusColor(item.status)"
size="small"
>
{{ item.status }}
</VChip>
</span>
</template>
<!-- status -->
<template #item.appointment_status="{ item }">
<VChip
:color="
resolveStatusVariant(
item.appointment_status
).color
"
class="font-weight-medium"
size="small"
:class="{
'blink-status':
item.appointment_status.toLowerCase() !==
'completed',
}"
>
{{
resolveStatusVariant(
item.appointment_status
).text
}}
</VChip>
</template>
<template #item.actions="{ item }">
<IconBtn size="small">
<VIcon icon="ri-more-2-line" />
<VMenu activator="parent">
<VList>
<VListItem value="view">
<RouterLink
:to="{
name: 'provider-order-detail',
params: { id: item.id },
}"
class="text-high-emphasis"
>
View
</RouterLink>
</VListItem>
<VListItem
value="complete"
v-if="
item.appointment_status.toLowerCase() !==
'completed'
"
>
<span
@click="
markAsCompleted(item)
"
class="text-high-emphasis cursor-pointer"
>
Mark as Complete
</span>
</VListItem>
</VList>
</VMenu>
</IconBtn>
</template>
</v-data-table>
</VCardText>
</VCard>
</VCol>
</VRow>
</div>
</template>
<style lang="scss" scoped>
#customer-link {
&:hover {
color: "#000" !important;
}
}
.product-widget {
border-block-end: 1px solid
rgba(var(--v-theme-on-surface), var(--v-border-opacity));
padding-block-end: 1rem;
}
</style>