874 lines
32 KiB
Vue
874 lines
32 KiB
Vue
<script setup>
|
|
// import LabKit from '@/views/pages/overview/LabKit.vue';
|
|
import UpcomingAppiontment from "@/pages/patient/upcomingAppiontment.vue";
|
|
// import Prescription from '@/views/pages/patient/prescription.vue';
|
|
import Echo from "laravel-echo";
|
|
import { useRouter } from "vue-router";
|
|
const router = useRouter();
|
|
// import moment from 'moment';
|
|
import moment from "moment-timezone";
|
|
import Pusher from "pusher-js";
|
|
import { onMounted } from "vue";
|
|
import { useStore } from "vuex";
|
|
const store = useStore();
|
|
// import HeathCare from '@images/pages/healthcare-wellness-wellbeing-first-aid-box-word-graphic.jpg';
|
|
const isLoadingVisible = ref(false);
|
|
const showTimeBar = ref(false);
|
|
const planName = ref("");
|
|
const planAmount = ref("");
|
|
const loginuser = ref("");
|
|
const email = ref("");
|
|
const phoneNumber = ref("");
|
|
const shippingAddress = ref("");
|
|
const address = ref("");
|
|
const city = ref("");
|
|
const state = ref("");
|
|
const zip_code = ref("");
|
|
const country = ref("");
|
|
const dob = ref("");
|
|
const gender = ref("");
|
|
const height = ref("");
|
|
const weight = ref("");
|
|
const scheduleDate = ref("");
|
|
const scheduleTime = ref("");
|
|
const timeZone = ref("");
|
|
const timeDifference = ref();
|
|
const timeUntilMeeting = ref("");
|
|
const callEnd = ref("");
|
|
const patientId = ref("");
|
|
const appiontmentId = ref("");
|
|
const doctorName = ref("");
|
|
const itemsPrescriptions = ref([]);
|
|
const orders = ref([]);
|
|
const patientLabkit = ref([]);
|
|
const order_id = ref();
|
|
const notifications = ref([]);
|
|
const notes = ref([]);
|
|
const items = ref([]);
|
|
const status = ref();
|
|
const shippingAmmount = ref();
|
|
const appoinmentList = ref([]);
|
|
const upcomingAppoinmentList = ref([]);
|
|
const patientsStats = ref([]);
|
|
onMounted(async () => {
|
|
await fetchApiData();
|
|
await getPatientprescription();
|
|
await orderPtaientList();
|
|
await historyNotes();
|
|
store.dispatch("updateIsLoading", false);
|
|
});
|
|
|
|
const fetchApiData = async () => {
|
|
store.dispatch("updateIsLoading", true);
|
|
await store.dispatch("getPatientInfo");
|
|
await store.dispatch("getPlanInfo");
|
|
await store.dispatch("getPatientAppointment");
|
|
await store.dispatch("getDashboardStats");
|
|
patientsStats.value = store.getters.getPatientsStats;
|
|
// appendItemHistoryToStats(patientsStats.value);
|
|
// console.log("patientsStats", patientsStats.value);
|
|
appoinmentList.value = store.getters.getBookedAppointment;
|
|
upcomingAppoinmentList.value =
|
|
store.getters.getPatientUpcomingAppiontments.upcoming_appointments;
|
|
console.log("final", upcomingAppoinmentList.value);
|
|
loginuser.value =
|
|
store.getters.getPatient.first_name +
|
|
" " +
|
|
store.getters.getPatient.last_name;
|
|
let diffInMinutes = store.getters.getTimeDiff;
|
|
// console.log("diffInMinutes", diffInMinutes);
|
|
timeZone.value = store.getters.getBookedAppointment.timezone;
|
|
order_id.value = store.getters.getBookedAppointment.order_id;
|
|
doctorName.value = store.getters.getBookedAppointment.agent_name;
|
|
status.value = store.getters.getBookedAppointment.status;
|
|
appiontmentId.value = store.getters.getBookedAppointment.appiontmentId;
|
|
console.log("appiontmentId", store.getters.getBookedAppointment);
|
|
const time = store.getters.getBookedAppointment.appointment_time;
|
|
callEnd.value = store.getters.getBookedAppointment.end_time;
|
|
let dateString = store.getters.getPatient.dob;
|
|
let parts = dateString.split("-");
|
|
dob.value = `${parts[1]}-${parts[2]}-${parts[0]}`;
|
|
|
|
let appointmentDate = convertUtcDateTimeToLocal(
|
|
store.getters.getBookedAppointment.appointment_date,
|
|
store.getters.getBookedAppointment.appointment_time,
|
|
"date"
|
|
);
|
|
let appointmentTime = convertUtcDateTimeToLocal(
|
|
store.getters.getBookedAppointment.appointment_date,
|
|
store.getters.getBookedAppointment.appointment_time,
|
|
"time"
|
|
);
|
|
// console.log("appointmentOverview------", appointmentDate, appointmentTime);
|
|
scheduleDate.value = moment(appointmentDate, "YYYY-MM-DD").format(
|
|
"MMMM DD, YYYY"
|
|
);
|
|
scheduleTime.value = moment(appointmentTime, "HH:mm:ss").format("hh:mm A");
|
|
// console.log("scheduleDate------------------", scheduleDate.value, scheduleTime.value);
|
|
timeDifference.value = relativeTimeFromDate(
|
|
appointmentDate,
|
|
appointmentTime
|
|
);
|
|
// console.log("timeDifference--------", timeDifference.value);
|
|
items.value = store.getters.getBookedAppointment.items.items_list;
|
|
shippingAmmount.value = store.getters.getBookedAppointment.items.total;
|
|
// console.log("shippingAmmount", shippingAmmount.value);
|
|
};
|
|
|
|
const upComing = computed(() => {
|
|
appoinmentList.value = store.getters.getBookedAppointment;
|
|
return appoinmentList.value.map((appiontment) => ({
|
|
...appiontment,
|
|
timeZone: appiontment.timezone,
|
|
order_id: appiontment.order_id,
|
|
doctorName: appiontment.agent_name,
|
|
status: appiontment.status,
|
|
appiontmentId: appiontment.appiontmentId,
|
|
// console.log("appiontmentId", store.getters.getBookedAppointment);
|
|
time: appiontment.appointment_time,
|
|
callEnd: appiontment.end_time,
|
|
// let dateString = store.getters.getPatient.dob
|
|
// let parts = dateString.split("-");
|
|
// dob.value = `${parts[1]}-${parts[2]}-${parts[0]}`;
|
|
|
|
appointmentDate: convertUtcDateTimeToLocal(
|
|
appiontment.appointment_date,
|
|
appiontment.appointment_time,
|
|
"date"
|
|
),
|
|
appointmentTime: convertUtcDateTimeToLocal(
|
|
appiontment.appointment_date,
|
|
appiontment.appointment_time,
|
|
"time"
|
|
),
|
|
timeDifference: relativeTimeFromDate(appointmentDate, appointmentTime),
|
|
// scheduleDate.value = moment(appointmentDate, "YYYY-MM-DD").format("MMMM DD, YYYY"),
|
|
// scheduleTime.value = moment(appointmentTime, "HH:mm:ss").format("hh:mm A")
|
|
// items = store.getters.getBookedAppointment.items.items_list,
|
|
// shippingAmmount = store.getters.getBookedAppointment.items.total,
|
|
// console.log("shippingAmmount", shippingAmmount.value);
|
|
}));
|
|
});
|
|
const relativeTimeFromDate = (dateString, timeString) => {
|
|
// Combine the date and time into a full datetime, treated as local time
|
|
const eventDateTime = new Date(dateString + "T" + timeString);
|
|
|
|
// Get the current date and time
|
|
const now = new Date();
|
|
|
|
// Calculate the difference in milliseconds between the event time and now
|
|
const diffMs = eventDateTime - now;
|
|
|
|
// Check if the event time is in the past and log it to the console if it is
|
|
if (diffMs > 0) {
|
|
showTimeBar.value = true;
|
|
console.log("The event time is in the past.");
|
|
}
|
|
|
|
// Convert the difference to an absolute value
|
|
const absDiffMs = Math.abs(diffMs);
|
|
|
|
// Calculate differences in days, hours, and minutes
|
|
const minutes = Math.floor(absDiffMs / 60000) % 60;
|
|
const hours = Math.floor(absDiffMs / 3600000) % 24;
|
|
const days = Math.floor(absDiffMs / 86400000);
|
|
|
|
// Determine the appropriate suffix based on whether the date is in the future or past
|
|
const suffix = diffMs < 0 ? " ago" : " left";
|
|
|
|
// Result formulation based on the above logic
|
|
if (days > 0) {
|
|
return `${days} day${days > 1 ? "s" : ""}${suffix}`;
|
|
} else {
|
|
// Compose hours and minutes
|
|
let result = [];
|
|
if (hours > 0) {
|
|
result.push(`${hours} hour${hours > 1 ? "s" : ""}`);
|
|
}
|
|
if (minutes > 0) {
|
|
result.push(`${minutes} minute${minutes > 1 ? "s" : ""}`);
|
|
}
|
|
if (result.length === 0) {
|
|
return "just now";
|
|
}
|
|
return result.join(" ") + suffix;
|
|
}
|
|
};
|
|
|
|
const historyNotes = async () => {
|
|
// console.log('...........', patientId, appointmentId);
|
|
await store.dispatch("patientsShippingActivity");
|
|
|
|
// notes.value = store.getters.getPatientNotes;
|
|
notifications.value =
|
|
store.getters.getPatientsShippingActivity.item_history;
|
|
console.log("notifications", notifications.value);
|
|
};
|
|
|
|
const orderPtaientList = async () => {
|
|
await store.dispatch("orderPtaientList");
|
|
orders.value = store.getters.getPatientOrderList;
|
|
console.log("orders Test", orders.value);
|
|
// await store.dispatch("getPatientLabKit");
|
|
// patientLabkit.value = store.getters.getPatientLabKit;
|
|
store.dispatch("updateIsLoading", false);
|
|
};
|
|
|
|
const convertUtcDateTimeToLocal = (utcDate, utcTime, type) => {
|
|
const utcDateTime = `${utcDate}T${utcTime}Z`; // Use Z to denote UTC timezone explicitly
|
|
const momentObj = moment.utc(utcDateTime).local(); // Convert UTC to local time
|
|
|
|
if (type === "date") {
|
|
return momentObj.format("YYYY-MM-DD"); // Return local date
|
|
} else if (type === "time") {
|
|
return momentObj.format("HH:mm:ss"); // Return local time
|
|
} else {
|
|
throw new Error("Invalid type specified. Use 'date' or 'time'.");
|
|
}
|
|
};
|
|
const getPatientprescription = async () => {
|
|
// await store.dispatch('getPatientPrescriptions')
|
|
// itemsPrescriptions.value = store.getters.getPrescription
|
|
await store.dispatch("getPatientPrescriptionsByID", {
|
|
appointment_id: appiontmentId.value,
|
|
});
|
|
let prescriptions = store.getters.getPrescriptionList;
|
|
if (prescriptions) {
|
|
// itemsPrescriptions.value = store.getters.getPrescriptionList
|
|
for (let data of prescriptions) {
|
|
let dataObject = {};
|
|
dataObject.brand = data.brand;
|
|
dataObject.direction_one = data.direction_one;
|
|
dataObject.direction_quantity = data.direction_quantity;
|
|
dataObject.direction_two = data.direction_two;
|
|
dataObject.date = formatDateDate(data.created_at);
|
|
dataObject.dosage = data.dosage;
|
|
dataObject.from = data.from;
|
|
dataObject.name = data.name;
|
|
dataObject.quantity = data.quantity;
|
|
dataObject.refill_quantity = data.refill_quantity;
|
|
dataObject.status = data.status;
|
|
dataObject.comments = data.comments;
|
|
itemsPrescriptions.value.push(dataObject);
|
|
}
|
|
itemsPrescriptions.value.sort((a, b) => {
|
|
return b.id - a.id;
|
|
});
|
|
} else {
|
|
itemsPrescriptions.value = "";
|
|
}
|
|
console.log("OverviewItem", itemsPrescriptions.value);
|
|
};
|
|
const formatDateDate = (date) => {
|
|
const messageDate = new Date(date);
|
|
const options = {
|
|
year: "numeric",
|
|
month: "long",
|
|
day: "numeric",
|
|
hour: "2-digit",
|
|
minute: "2-digit",
|
|
};
|
|
return messageDate.toLocaleDateString("en-US", options).replace(/\//g, "-");
|
|
};
|
|
onMounted(() => {
|
|
store.dispatch("updateIsLoading", true);
|
|
window.Pusher = Pusher;
|
|
const key = "bc8bffbbbc49cfa39818";
|
|
const cluster = "mt1";
|
|
let echo = new Echo({
|
|
broadcaster: "pusher",
|
|
|
|
key: key,
|
|
cluster: cluster,
|
|
forceTLS: true,
|
|
auth: {
|
|
headers: {
|
|
Authorization: "Bearer " + localStorage.getItem("access_token"),
|
|
},
|
|
},
|
|
});
|
|
|
|
echo.private(
|
|
"patient-end-call-" + localStorage.getItem("patient_id")
|
|
).listen("AppointmentCallEnded", async (e) => {
|
|
console.log("OverviewAppointmentCallEnded", e);
|
|
fetchApiData();
|
|
});
|
|
|
|
store.dispatch("updateIsLoading", false);
|
|
});
|
|
|
|
const getStatusColor = (status) => {
|
|
switch (status) {
|
|
case "pending":
|
|
return "warning"; // Use Vuetify's warning color (typically yellow)
|
|
case "shipped":
|
|
return "#45B8AC"; // Use Vuetify's primary color (typically blue)
|
|
case "delivered":
|
|
return "green";
|
|
case "returned":
|
|
return "red";
|
|
case "results":
|
|
return "blue";
|
|
default:
|
|
return "grey"; // Use Vuetify's grey color for any other status
|
|
}
|
|
};
|
|
const desserts = [
|
|
{
|
|
dessert: "Blood Test",
|
|
calories: "pending",
|
|
},
|
|
{
|
|
dessert: "Cancer",
|
|
calories: "pending",
|
|
},
|
|
];
|
|
|
|
const viewOrder = (orderId) => {
|
|
router.push({ name: "order-detail", params: { id: orderId } });
|
|
};
|
|
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} `;
|
|
};
|
|
const formatCurrency = (amount) => {
|
|
let formattedAmount = amount.toString();
|
|
|
|
// Remove '.00' if present
|
|
if (formattedAmount.includes(".00")) {
|
|
formattedAmount = formattedAmount.replace(".00", "");
|
|
}
|
|
|
|
// Split into parts for integer and decimal
|
|
let parts = formattedAmount.split(".");
|
|
|
|
// Format integer part with commas
|
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
|
|
// Return formatted number
|
|
return parts.join(".");
|
|
};
|
|
const headers = [
|
|
{
|
|
title: "#Order",
|
|
key: "id",
|
|
},
|
|
{
|
|
title: "Date",
|
|
key: "updated_at",
|
|
},
|
|
|
|
{
|
|
title: "Price",
|
|
key: "total_amount",
|
|
},
|
|
|
|
{
|
|
title: "status",
|
|
key: "status",
|
|
},
|
|
];
|
|
const historyDetail = (history) => {
|
|
console.log("history", history.id);
|
|
// router.push("/patient/complete-appintment-detail/" + history.id);
|
|
router.push("/order-detail/" + history.id);
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<VContainer class="px-0">
|
|
<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>
|
|
|
|
<!-- <VAlert color="rgb(var(--v-theme-yellow))" text-white v-if="showTimeBar">
|
|
<span>
|
|
<p class="text-white mb-0"><b>Remaining Time: </b> {{ timeDifference }}</p>
|
|
</span>
|
|
</VAlert> -->
|
|
<!-- <VAlert type="success" variant="outlined">Password Has been set
|
|
</VAlert> -->
|
|
|
|
<h3 class="text-center mt-3"></h3>
|
|
<VRow class="match-height">
|
|
<!-- 👉 Congratulation John -->
|
|
|
|
<!-- 👉 Ecommerce Transition -->
|
|
<VCol cols="12" md="7" lg="12">
|
|
<VCard>
|
|
<VCardTitle class="pb-0"
|
|
><b> Welcome {{ loginuser }},</b>
|
|
</VCardTitle>
|
|
<VCardText class="m-0">
|
|
<p class="mt-0">
|
|
Here you'll find your order, Appointments, and
|
|
subcriptions from HGH.
|
|
</p>
|
|
</VCardText>
|
|
<VCardText class="pt-6">
|
|
<VRow class="">
|
|
<VCol cols="6" md="3">
|
|
<div class="d-flex align-center gap-4">
|
|
<VAvatar
|
|
color="info"
|
|
variant="tonal"
|
|
size="42"
|
|
>
|
|
<VIcon icon="tabler-chart-pie-2" />
|
|
</VAvatar>
|
|
|
|
<div class="d-flex flex-column">
|
|
<span
|
|
class="text-h5 font-weight-medium"
|
|
>{{
|
|
patientsStats.total_meetings
|
|
}}</span
|
|
>
|
|
<span class="text-sm"> Completed </span>
|
|
</div>
|
|
</div>
|
|
</VCol>
|
|
<VCol cols="6" md="3">
|
|
<div class="d-flex align-center gap-4">
|
|
<VAvatar
|
|
color="primary"
|
|
variant="tonal"
|
|
size="42"
|
|
>
|
|
<VIcon icon="tabler-chart-pie-2" />
|
|
</VAvatar>
|
|
|
|
<div class="d-flex flex-column">
|
|
<span
|
|
class="text-h5 font-weight-medium"
|
|
>{{
|
|
patientsStats.upcoming_meetings
|
|
}}</span
|
|
>
|
|
<span class="text-sm"> Upcoming </span>
|
|
</div>
|
|
</div>
|
|
</VCol>
|
|
<VCol cols="6" md="3">
|
|
<div class="d-flex align-center gap-4">
|
|
<VAvatar
|
|
color="error"
|
|
variant="tonal"
|
|
size="42"
|
|
>
|
|
<VIcon icon="tabler-shopping-cart" />
|
|
</VAvatar>
|
|
|
|
<div class="d-flex flex-column">
|
|
<span
|
|
class="text-h5 font-weight-medium"
|
|
>{{
|
|
patientsStats.total_orders
|
|
}}</span
|
|
>
|
|
<span class="text-sm"> Orders </span>
|
|
</div>
|
|
</div>
|
|
</VCol>
|
|
<VCol cols="6" md="3">
|
|
<div class="d-flex align-center gap-4">
|
|
<VAvatar
|
|
color="success"
|
|
variant="tonal"
|
|
size="42"
|
|
>
|
|
<VIcon icon="tabler-currency-dollar" />
|
|
</VAvatar>
|
|
|
|
<div class="d-flex flex-column">
|
|
<span
|
|
class="text-h5 font-weight-medium"
|
|
>{{
|
|
patientsStats.total_subscription
|
|
}}</span
|
|
>
|
|
<span class="text-sm">
|
|
Subscription
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</VCol>
|
|
</VRow>
|
|
</VCardText>
|
|
<!-- </VCardText>-->
|
|
</VCard>
|
|
</VCol>
|
|
</VRow>
|
|
|
|
<VRow>
|
|
<VCol cols="12" md="6">
|
|
<!-- <VCardTitle class="text-wrap" color="errors">Lab Kit
|
|
<RouterLink class="text-primary" to="/labs">
|
|
<small style="font-size: 12px; font-weight: normal;">(see all)</small>
|
|
</RouterLink>
|
|
</VCardTitle>
|
|
<LabKit :time="scheduleTime" :timezone="timeZone" :timeDiff="timeDifference" /> -->
|
|
<VCardTitle class="text-wrap"
|
|
><b>Upcoming Appointment</b>
|
|
<RouterLink class="text-primary" to="/complete">
|
|
<small style="font-size: 12px; font-weight: normal">
|
|
(see all)
|
|
</small>
|
|
</RouterLink>
|
|
</VCardTitle>
|
|
<!-- <UpcomingAppiontment /> -->
|
|
<UpcomingAppiontment
|
|
:upcommingAppiontmetns="upcomingAppoinmentList"
|
|
:iscallEnd="callEnd"
|
|
:orderid="order_id"
|
|
:date="scheduleDate"
|
|
:time="scheduleTime"
|
|
:timezone="timeZone"
|
|
:isStatus="status"
|
|
:timeDiff="timeDifference"
|
|
:isShippmentAmmount="shippingAmmount"
|
|
:showShipment="false"
|
|
color="rgb(var(--v-theme-yellow))"
|
|
:isItem="items"
|
|
/>
|
|
</VCol>
|
|
<VCol cols="12" md="6">
|
|
<VCardTitle class="text-wrap"
|
|
><b>Orders</b>
|
|
<RouterLink class="text-primary" to="/orders-list">
|
|
<small style="font-size: 12px; font-weight: normal">
|
|
(see all)
|
|
</small>
|
|
</RouterLink>
|
|
</VCardTitle>
|
|
<template v-if="items && items.length > 0">
|
|
<VCard
|
|
class="rounded-5"
|
|
style="
|
|
min-height: 150px;
|
|
overflow-y: scroll;
|
|
overflow: hidden;
|
|
border-radius: 10px;
|
|
"
|
|
>
|
|
<VDataTable
|
|
:headers="headers"
|
|
:items="orders"
|
|
item-value="id"
|
|
class="text-no-wrap"
|
|
>
|
|
<!-- <template #item.title="{ item }">
|
|
<div class="d-flex gap-x-3">
|
|
<VAvatar size="34" variant="tonal" :image="item.image_url" rounded />
|
|
|
|
<div class="d-flex flex-column align-center">
|
|
<h6 style="margin-bottom: 0px;">
|
|
{{ item.title }}
|
|
</h6>
|
|
|
|
<span class="text-sm text-start align-self-start">
|
|
{{ item.list_sub_title }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</template> -->
|
|
<template #item.id="{ item }">
|
|
<span
|
|
@click="historyDetail(item)"
|
|
style="cursor: pointer"
|
|
><b> {{ item.id }} </b></span
|
|
>
|
|
</template>
|
|
<template #item.total_amount="{ item }">
|
|
<span>
|
|
<b
|
|
>${{
|
|
formatCurrency(item.total_amount)
|
|
}}
|
|
</b></span
|
|
>
|
|
</template>
|
|
|
|
<template #item.updated_at="{ item }">
|
|
<span>{{ formatDate(item.updated_at) }}</span>
|
|
</template>
|
|
<template #item.status="{ item }">
|
|
<span>
|
|
<VChip
|
|
variant="tonal"
|
|
:color="getStatusColor(item.status)"
|
|
size="small"
|
|
>
|
|
{{ item.status }}
|
|
</VChip>
|
|
</span>
|
|
</template>
|
|
|
|
<template #bottom />
|
|
</VDataTable>
|
|
<!-- <VTable class="text-no-wrap">
|
|
<thead>
|
|
<tr>
|
|
<th class="text-uppercase">
|
|
<b>Order ID</b>
|
|
</th>
|
|
<th class="text-uppercase">
|
|
<b>Date</b>
|
|
</th>
|
|
|
|
<th class="text-uppercase">
|
|
<b>Amount</b>
|
|
</th>
|
|
<th class="text-uppercase text-center">
|
|
<b>Status</b>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<tr v-for=" order in orders " :key="order">
|
|
<td>
|
|
<div @click="viewOrder(order.id)">{{ order.id }} </div>
|
|
</td>
|
|
|
|
<td class="text-center">
|
|
{{ formatDate(order.updated_at) }}
|
|
|
|
</td>
|
|
|
|
<td class="text-center">
|
|
${{ formatCurrency(order.total_amount) }}
|
|
</td>
|
|
|
|
<td class="text-center">
|
|
<v-chip x-small class="mr-2" outlined>{{ order.status }} </v-chip>
|
|
</td>
|
|
|
|
</tr>
|
|
</tbody>
|
|
|
|
</VTable>
|
|
<VDivider class="m-0" /> -->
|
|
</VCard>
|
|
</template>
|
|
<template v-else>
|
|
<VAlert border="start" color="rgb(var(--v-theme-yellow))">
|
|
<div class="text-center">No data found</div>
|
|
</VAlert>
|
|
</template>
|
|
|
|
<!-- <VCardTitle class="pt-3">
|
|
<b>
|
|
Lab Kits
|
|
</b>
|
|
</VCardTitle>
|
|
|
|
<template v-if="patientLabkit && patientLabkit.length > 0">
|
|
<VCard class="rounded-5"
|
|
style="min-height:150px; overflow-y:scroll; overflow: hidden; border-radius: 10px; ">
|
|
<VTable class="text-no-wrap">
|
|
<thead>
|
|
<tr>
|
|
<th class="text-uppercase">
|
|
<b>Name</b>
|
|
</th>
|
|
<th class="text-uppercase text-center">
|
|
<b>Status</b>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<tr v-for=" item in patientLabkit " :key="item.id">
|
|
<td>
|
|
{{ item.name }}
|
|
</td>
|
|
<td class="text-center">
|
|
|
|
<VChip variant="tonal" :color="getStatusColor(item.status)" size="small">
|
|
{{ item.status }}
|
|
</VChip>
|
|
|
|
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</VTable>
|
|
|
|
</VCard>
|
|
</template>
|
|
<template v-else>
|
|
|
|
<VAlert border="start" color="rgb(var(--v-theme-yellow))" variant="tonal">
|
|
<div class="text-center">No data found</div>
|
|
</VAlert>
|
|
|
|
|
|
</template> -->
|
|
|
|
<!-- <VTimeline truncate-line="both" align="start" side="end" line-inset="10" line-color="primary"
|
|
density="compact" class="v-timeline-density-compact">
|
|
<template v-if="historyNotes">
|
|
<VTimelineItem dot-color="primary" size="x-small" v-for="(p_note, index) of notes" :key="index">
|
|
<div class="d-flex justify-space-between align-center mb-3">
|
|
<span class="app-timeline-title">{{ p_note.note }}</span>
|
|
<span class="app-timeline-meta">{{ p_note.date }}</span>
|
|
</div>
|
|
<VDivider />
|
|
</VTimelineItem>
|
|
</template>
|
|
<template v-else>
|
|
<VCard>
|
|
<VAlert border="start" color="rgb(var(--v-theme-yellow))" variant="tonal">
|
|
<div class="text-center">No data found</div>
|
|
</VAlert>
|
|
</VCard>
|
|
|
|
</template>
|
|
</VTimeline> -->
|
|
<!-- </VCardText> -->
|
|
<!-- </VCard> -->
|
|
|
|
<!-- <template v-else>
|
|
<VCard>
|
|
<VAlert border="start" color="rgb(var(--v-theme-yellow))" variant="tonal">
|
|
<div class="text-center">No data found</div>
|
|
</VAlert>
|
|
|
|
</VCard>
|
|
|
|
</template> -->
|
|
</VCol>
|
|
</VRow>
|
|
</VContainer>
|
|
</template>
|
|
|
|
<style lang="scss">
|
|
button.v-expansion-panel-title {
|
|
background-color: rgb(var(--v-theme-yellow)) !important;
|
|
color: #fff;
|
|
}
|
|
|
|
button.v-expansion-panel-title.bg-secondary {
|
|
background-color: rgb(var(--v-theme-yellow)) !important;
|
|
color: #fff;
|
|
}
|
|
|
|
button.v-expansion-panel-title {
|
|
background-color: rgb(var(--v-theme-yellow)) !important;
|
|
color: #fff;
|
|
}
|
|
|
|
button.v-expansion-panel-title.v-expansion-panel-title--active {
|
|
background-color: rgb(var(--v-theme-yellow)) !important;
|
|
color: #fff;
|
|
}
|
|
|
|
span.v-expansion-panel-title__icon {
|
|
color: #fff;
|
|
display: none !important;
|
|
}
|
|
|
|
.v-expansion-panel {
|
|
background-color: #fff;
|
|
border-radius: 10px;
|
|
box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1);
|
|
margin-bottom: 10px;
|
|
overflow: hidden;
|
|
transition: box-shadow 0.3s ease;
|
|
}
|
|
|
|
.v-expansion-panel:hover {
|
|
box-shadow: 0px 6px 16px rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
.v-expansion-panel-title {
|
|
padding: 15px;
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
color: #333;
|
|
cursor: pointer;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
transition: background-color 0.3s ease, color 0.3s ease;
|
|
}
|
|
|
|
.v-expansion-panel-title.pt-0 {
|
|
padding-top: 0;
|
|
}
|
|
|
|
// .v-expansion-panel-title:hover {
|
|
// background-color: #f9f9f9;
|
|
// color: #222;
|
|
// }
|
|
|
|
.v-expansion-panel-title .mdi {
|
|
font-size: 20px;
|
|
color: #666;
|
|
transition: transform 0.3s ease, color 0.3s ease;
|
|
}
|
|
|
|
.v-expansion-panel-title.v-expansion-panel-title--active .mdi {
|
|
transform: rotate(180deg);
|
|
color: #222;
|
|
}
|
|
|
|
.v-expansion-panel-text {
|
|
padding: 10px 15px;
|
|
font-size: 13px;
|
|
color: #555;
|
|
border-top: 1px solid #eee;
|
|
}
|
|
|
|
.v-expansion-panel-text .d-flex {
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.v-expansion-panel-text .d-flex > div {
|
|
flex: 1;
|
|
}
|
|
|
|
.v-expansion-panel-text p {
|
|
margin-bottom: 16px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.v-expansion-panel-text h3 {
|
|
font-size: 20px;
|
|
font-weight: 600;
|
|
margin-bottom: 16px;
|
|
color: #333;
|
|
}
|
|
|
|
.bg-primary {
|
|
background-color: rgb(var(--v-theme-yellow-theme-button)) !important;
|
|
}
|
|
</style>
|