rejuvallife/resources/js/pages/patient/subscription.vue
2024-10-25 01:02:11 +05:00

390 lines
14 KiB
Vue

<script setup>
import { computed, onMounted, reactive, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useStore } from "vuex";
const route = useRoute();
const router = useRouter();
const store = useStore();
const statusOptions = ["Active", "Cancelled"];
let filters = reactive({
status: [],
})
let foundText = ref('')
const subscriptions = ref([]);
const search = ref("");
const filteredSubscriptions = computed(() => {
let subscriptionList = store.getters.getsubscriptionList;
// Check if subscriptionList is null or undefined
if (!subscriptionList) {
return [];
}
subscriptions.value = subscriptionList;
if (filters.status.length > 0) {
foundText.value = filters.status.join(', ')
subscriptionList = subscriptionList.filter((order) =>
filters.status.includes(order.status)
);
}
console.log('subscriptionList', subscriptionList)
const searchLower = search.value.toLowerCase();
console.log(searchLower)
return subscriptionList.filter(
(sub) =>
(sub.order_number && String(sub.order_number).toLowerCase().includes(searchLower)) ||
(sub.product_title && String(sub.product_title).toLowerCase().includes(searchLower))
);
});
const formatDate = (date) => {
const messageDate = new Date(date);
const options = {
year: "numeric",
month: "numeric",
day: "numeric",
};
const formattedDate = messageDate
.toLocaleString("en-US", options)
.replace(/\//g, "-");
return `${formattedDate} `;
};
const getStatusColor = (status) => {
if (status === "Active") return "green";
if (status === "Cancelled") return "orange";
return "red";
};
const getStatusIcon = (status) => {
switch (status.toLowerCase()) {
case 'active':
return 'mdi-check-circle';
case 'pending':
return 'mdi-clock-outline';
case 'cancelled':
return 'mdi-cancel';
case 'expired':
return 'mdi-alert-circle-outline';
default:
return 'mdi-help-circle-outline';
}
}
const viewDetails = (subscription) => {
// Implement view details logic here
console.log("View details for subscription:", subscription.id);
router.push("/subscriptions-detail/" + subscription.id);
};
const subscriptionList = computed(() => {
let filtered = store.getters.getsubscriptionList;
subscriptions.value = store.getters.getsubscriptionList;
return subscriptions.value;
});
onMounted(async () => {
store.dispatch("updateIsLoading", true);
await store.dispatch("subscriptionList");
});
const getPlanIcon = (plan) => {
switch (plan.toLowerCase()) {
case "basic":
return "mdi-star-outline";
case "premium":
return "mdi-star-half";
case "pro":
return "mdi-star";
case "enterprise":
return "mdi-medal";
default:
return "mdi-help-circle";
}
};
const cancelSubscription = async (subscriptionData) => {
// Implement cancellation logic here
store.dispatch("updateIsLoading", true);
await store.dispatch("subscriptionCancel", { id: subscriptionData.subscription_id });
console.log("Cancelling subscription:", subscriptionData.subscription_id);
await store.dispatch("subscriptionList");
await store.getters.getsubscriptionList;
store.dispatch("updateIsLoading", false);
};
</script>
<template>
<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>
<v-container fluid class="subscription-container pa-6">
<v-row justify="center" align="center" class="mb-8" style="display: none;">
<v-col cols="12" md="8">
<h4 class="text-h4 text-center gradient-text mb-4">
Active Subscriptions
</h4>
<v-text-field v-model="search" prepend-inner-icon="mdi-magnify" label="Search subscriptions" outlined
rounded hide-details dense class="search-field"></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col cols="12">
<VCardTitle class="pt-0"><b>Subscriptions </b></VCardTitle>
<v-card>
<v-card-title>
<v-row class="px-0 py-4">
<v-col cols="12" md="4">
<v-text-field v-model="search" prepend-inner-icon="mdi-magnify"
label="Search subscriptions" outlined density="compact" hide-details
class="search-field"></v-text-field>
</v-col>
<v-col cols="12" md="4">
<v-select v-model="filters.status" :items="statusOptions" label="Status" outlined
density="compact" multiple></v-select>
</v-col>
</v-row>
</v-card-title>
</v-card>
</v-col>
</v-row>
<v-row v-if="filteredSubscriptions.length > 0">
<VCol sm="6" cols="12" v-for="subscription in filteredSubscriptions" :key="subscription.order_number"
style="display: none;">
<VCard>
<div class="d-flex justify-space-between flex-wrap flex-md-nowrap flex-column flex-md-row">
<div class="ma-auto pa-5">
<VImg width="137" height="176" :src="subscription.image_url" />
</div>
<VDivider :vertical="$vuetify.display.mdAndUp" />
<div>
<VCardItem>
</VCardItem>
<VCardText>
<h3>{{ subscription }}</h3>
</VCardText>
<VCardText class="text-subtitle-1">
<span>Price :</span> <span class="font-weight-medium">${{
subscription.product_price.amount }}</span>
<span v-if="subscription.subscription_start_date">Start :</span> <span
class="font-weight-medium" v-if="subscription.subscription_start_date">{{
formatDate(subscription.subscription_start_date)
}}</span>
<span v-if="subscription.subscription_renewal_date">Renewal Date :</span> <span
class="font-weight-medium" v-if="subscription.subscription_renewal_date">{{
formatDate(subscription.subscription_renewal_date)
}}</span>
<span>Status :</span> <span class="font-weight-medium">{{
subscription.status }}</span>
</VCardText>
<VCardActions class="justify-space-between">
<VBtn>
<VIcon icon="bx-cart-add" />
<span class="ms-2">Add to cart</span>
</VBtn>
<VBtn color="secondary" icon="bx-share-alt" />
</VCardActions>
</div>
</div>
</VCard>
</VCol>
<v-col v-for="subscription in filteredSubscriptions" :key="subscription.order_number" cols="12" md="4">
<v-hover v-slot:default="{ isHovering }">
<v-card class="subscription-card mx-auto" :elevation="isHovering ? 8 : 2"
:class="{ 'on-hover': isHovering }">
<v-card-title class="text-h5 d-flex flex-column align-center">
<v-avatar size="80" class="mb-3" color="rgb(var(--v-theme-yellow))"
v-if="subscription.image_url">
<v-img :src="subscription.image_url" :alt="subscription.title"></v-img>
</v-avatar>
<v-avatar color="rgb(var(--v-theme-yellow))" size="56" v-if="!subscription.image_url"
class="text-grey-800 text-h6 font-weight-bold mr-4">
#{{ subscription.order_number }}
</v-avatar>
</v-card-title>
<v-card-text>
<h4 class="text-center title">{{ subscription.product_title }}</h4>
<v-list dense class="details-list">
<v-list-item>
<v-row align="center" no-gutters>
<v-col cols="12" md="2">
</v-col>
<v-col cols="12" md="8">
<v-icon color="primary">mdi-cash</v-icon> <span>Price: ${{
subscription.product_price.amount }}</span>
</v-col>
<v-col cols="12" md="2">
</v-col>
</v-row>
</v-list-item>
<v-list-item v-if="subscription.subscription_start_date">
<v-row align="center" no-gutters>
<v-col cols="12" md="2">
</v-col>
<v-col cols="12" md="8">
<v-icon color="primary">mdi-calendar-start</v-icon><span>Start: {{
formatDate(subscription.subscription_start_date) }}</span>
</v-col>
<v-col cols="12" md="2">
</v-col>
</v-row>
</v-list-item>
<v-list-item v-if="subscription.subscription_renewal_date">
<v-row align="center" no-gutters>
<v-col cols="12" md="2">
</v-col>
<v-col cols="12" md="8">
<v-icon color="primary">mdi-calendar-clock</v-icon> <span>Next Billing: {{
formatDate(subscription.subscription_renewal_date) }}</span>
</v-col>
<v-col cols="12" md="2">
</v-col>
</v-row>
</v-list-item>
<v-list-item>
<v-row align="center" no-gutters>
<v-col cols="12" md="2">
</v-col>
<v-col cols="12" md="8">
<v-icon :color="getStatusColor(subscription.status)">
{{ getStatusIcon(subscription.status) }}
</v-icon>
<span>Status: {{ subscription.status }}</span>
</v-col>
<v-col cols="12" md="2">
</v-col>
</v-row>
</v-list-item>
</v-list>
</v-card-text>
<v-card-actions>
<v-btn color="rgb(var(--v-theme-yellow))" @click="cancelSubscription(subscription)"
prepend-icon="mdi-cancel" block>Cancel
Subscription</v-btn>
<v-btn color="primary" block @click="viewDetails(subscription)">
View Details
</v-btn>
</v-card-actions>
</v-card>
</v-hover>
</v-col>
</v-row>
<v-row v-else justify="center" align="center">
<v-col cols="12" class="text-center">
<v-icon size="64" color="grey">mdi-playlist-remove</v-icon>
<h3 class="mt-4">No {{ foundText }} Subscriptions</h3>
<p class="text-subtitle-1">You don't have any {{foundText}} subscriptions at the moment.</p>
</v-col>
</v-row>
</v-container>
</template>
<style scoped>
.subscription-container {
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
}
.subscription-card {
transition: all 0.3s ease;
}
.subscription-card.on-hover {
transform: translateY(-5px);
}
.v-avatar {
background-color: var(--v-primary-base);
}
.subscription-container .v-card .v-card-text {
line-height: 1.25rem;
min-height: 200px;
}
.title {
font-size: 13px;
}
.gradient-text {
background: linear-gradient(45deg, rgb(var(--v-theme-yellow)), #173320);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-weight: bold;
}
.search-field {
max-width: 500px;
margin: 0 auto;
}
.subscription-card {
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
border-radius: 16px;
overflow: hidden;
}
.subscription-card.on-hover {
transform: translateY(-5px);
}
.v-list-item {
min-height: 40px;
}
.details-list .v-list-item {
padding: 0;
}
.details-list .v-row {
align-items: center;
}
.details-list .v-col {
display: flex;
align-items: center;
}
.details-list .v-icon {
margin-right: 0.5rem;
font-size: 1.5rem;
}
.details-list .v-col span {
font-size: 1rem;
font-weight: 500;
color: var(--v-grey-darken1);
}
</style>