348 lines
6.9 KiB
Vue
348 lines
6.9 KiB
Vue
<template>
|
|
<div
|
|
v-motion
|
|
:initial="{ opacity: 0, scale: 0.95 }"
|
|
:enter="{
|
|
opacity: 1,
|
|
scale: 1,
|
|
transition: {
|
|
delay: 600,
|
|
duration: 600,
|
|
type: 'spring',
|
|
stiffness: 200
|
|
}
|
|
}"
|
|
class="payment-card"
|
|
>
|
|
<!-- Card Header -->
|
|
<div class="payment-header">
|
|
<div class="header-left">
|
|
<v-icon color="success" size="20">mdi-credit-card</v-icon>
|
|
<h3 class="payment-title">Payment Status</h3>
|
|
</div>
|
|
<v-chip
|
|
color="success"
|
|
variant="tonal"
|
|
size="small"
|
|
>
|
|
<v-icon start size="14">mdi-check-circle</v-icon>
|
|
Active
|
|
</v-chip>
|
|
</div>
|
|
|
|
<!-- Membership Info -->
|
|
<div
|
|
v-motion
|
|
:initial="{ opacity: 0 }"
|
|
:enter="{
|
|
opacity: 1,
|
|
transition: {
|
|
delay: 700,
|
|
duration: 500
|
|
}
|
|
}"
|
|
class="membership-info"
|
|
>
|
|
<div class="info-row">
|
|
<span class="info-label">Membership Type</span>
|
|
<span class="info-value">{{ membershipType }}</span>
|
|
</div>
|
|
<div class="info-row">
|
|
<span class="info-label">Next Payment</span>
|
|
<span class="info-value">{{ nextPaymentDate }}</span>
|
|
</div>
|
|
<div class="info-row">
|
|
<span class="info-label">Amount</span>
|
|
<span class="info-value amount">${{ membershipAmount }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Payment Method -->
|
|
<div
|
|
v-motion
|
|
:initial="{ opacity: 0, y: 10 }"
|
|
:enter="{
|
|
opacity: 1,
|
|
y: 0,
|
|
transition: {
|
|
delay: 800,
|
|
duration: 500
|
|
}
|
|
}"
|
|
class="payment-method"
|
|
>
|
|
<div class="method-header">
|
|
<span class="method-label">Payment Method</span>
|
|
<v-btn
|
|
variant="text"
|
|
color="error"
|
|
size="x-small"
|
|
@click="$emit('update-payment')"
|
|
>
|
|
Update
|
|
</v-btn>
|
|
</div>
|
|
<div class="method-card">
|
|
<v-icon color="primary" size="20">mdi-credit-card</v-icon>
|
|
<span class="card-number">•••• •••• •••• 4242</span>
|
|
<span class="card-exp">12/25</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recent Payments -->
|
|
<div
|
|
v-motion
|
|
:initial="{ opacity: 0 }"
|
|
:enter="{
|
|
opacity: 1,
|
|
transition: {
|
|
delay: 900,
|
|
duration: 500
|
|
}
|
|
}"
|
|
class="recent-payments"
|
|
>
|
|
<h4 class="payments-title">Recent Payments</h4>
|
|
<div class="payments-list">
|
|
<div
|
|
v-for="(payment, index) in paymentHistory"
|
|
:key="payment.id"
|
|
v-motion
|
|
:initial="{ opacity: 0, x: -10 }"
|
|
:visibleOnce="{
|
|
opacity: 1,
|
|
x: 0,
|
|
transition: {
|
|
delay: 1000 + (index * 50),
|
|
duration: 400
|
|
}
|
|
}"
|
|
class="payment-item"
|
|
>
|
|
<v-icon
|
|
size="16"
|
|
:color="index === 0 ? 'success' : 'grey'"
|
|
>
|
|
mdi-check-circle
|
|
</v-icon>
|
|
<span class="payment-date">{{ payment.date }}</span>
|
|
<span class="payment-amount">${{ payment.amount }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Action Button -->
|
|
<v-btn
|
|
color="error"
|
|
variant="outlined"
|
|
block
|
|
class="mt-4"
|
|
prepend-icon="mdi-history"
|
|
@click="$emit('update-payment')"
|
|
>
|
|
View Payment History
|
|
</v-btn>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
interface Payment {
|
|
id: number;
|
|
date: string;
|
|
amount: string;
|
|
}
|
|
|
|
interface Props {
|
|
membershipType: string;
|
|
nextPaymentDate: string;
|
|
membershipAmount: string;
|
|
paymentHistory: Payment[];
|
|
}
|
|
|
|
defineProps<Props>();
|
|
|
|
defineEmits<{
|
|
'update-payment': [];
|
|
}>();
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.payment-card {
|
|
height: 100%;
|
|
background: linear-gradient(135deg,
|
|
rgba(255, 255, 255, 0.95),
|
|
rgba(255, 255, 255, 0.85)
|
|
);
|
|
backdrop-filter: blur(30px);
|
|
-webkit-backdrop-filter: blur(30px);
|
|
border-radius: 1.25rem;
|
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
box-shadow:
|
|
0 20px 40px rgba(0, 0, 0, 0.08),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.6);
|
|
padding: 1.5rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.payment-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.header-left {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.payment-title {
|
|
font-size: 1.125rem;
|
|
font-weight: 600;
|
|
color: rgb(31, 41, 55);
|
|
margin: 0;
|
|
}
|
|
|
|
.membership-info {
|
|
background: linear-gradient(135deg,
|
|
rgba(34, 197, 94, 0.05),
|
|
rgba(34, 197, 94, 0.02)
|
|
);
|
|
border-radius: 0.75rem;
|
|
padding: 1rem;
|
|
margin-bottom: 1.25rem;
|
|
border: 1px solid rgba(34, 197, 94, 0.1);
|
|
}
|
|
|
|
.info-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 0.375rem 0;
|
|
|
|
&:not(:last-child) {
|
|
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
|
}
|
|
}
|
|
|
|
.info-label {
|
|
font-size: 0.8125rem;
|
|
color: rgb(107, 114, 128);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.info-value {
|
|
font-size: 0.875rem;
|
|
color: rgb(31, 41, 55);
|
|
font-weight: 600;
|
|
|
|
&.amount {
|
|
font-size: 1.125rem;
|
|
background: linear-gradient(135deg, #22c55e, #16a34a);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
background-clip: text;
|
|
}
|
|
}
|
|
|
|
.payment-method {
|
|
background: rgba(255, 255, 255, 0.5);
|
|
border-radius: 0.75rem;
|
|
padding: 1rem;
|
|
margin-bottom: 1.25rem;
|
|
}
|
|
|
|
.method-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 0.75rem;
|
|
}
|
|
|
|
.method-label {
|
|
font-size: 0.8125rem;
|
|
color: rgb(107, 114, 128);
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.05em;
|
|
}
|
|
|
|
.method-card {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75rem;
|
|
padding: 0.75rem;
|
|
background: linear-gradient(135deg,
|
|
rgba(255, 255, 255, 0.9),
|
|
rgba(255, 255, 255, 0.7)
|
|
);
|
|
border-radius: 0.5rem;
|
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.card-number {
|
|
flex: 1;
|
|
font-family: 'Courier New', monospace;
|
|
font-size: 0.875rem;
|
|
color: rgb(31, 41, 55);
|
|
letter-spacing: 0.05em;
|
|
}
|
|
|
|
.card-exp {
|
|
font-size: 0.75rem;
|
|
color: rgb(107, 114, 128);
|
|
}
|
|
|
|
.recent-payments {
|
|
flex: 1;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.payments-title {
|
|
font-size: 0.875rem;
|
|
font-weight: 600;
|
|
color: rgb(31, 41, 55);
|
|
margin: 0 0 0.75rem 0;
|
|
}
|
|
|
|
.payments-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.payment-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.5rem;
|
|
background: rgba(255, 255, 255, 0.3);
|
|
border-radius: 0.5rem;
|
|
transition: all 0.2s ease;
|
|
|
|
&:hover {
|
|
background: rgba(255, 255, 255, 0.5);
|
|
transform: translateX(2px);
|
|
}
|
|
}
|
|
|
|
.payment-date {
|
|
flex: 1;
|
|
font-size: 0.8125rem;
|
|
color: rgb(107, 114, 128);
|
|
}
|
|
|
|
.payment-amount {
|
|
font-size: 0.875rem;
|
|
font-weight: 600;
|
|
color: rgb(31, 41, 55);
|
|
}
|
|
|
|
@media (max-width: 640px) {
|
|
.payment-card {
|
|
padding: 1rem;
|
|
}
|
|
}
|
|
</style> |