fixes
Build And Push Image / docker (push) Successful in 1m39s Details

This commit is contained in:
Matt 2025-08-15 16:02:14 +02:00
parent 136eb5229e
commit cdacb4a114
1 changed files with 159 additions and 17 deletions

View File

@ -98,34 +98,73 @@
<!-- Mark as Paid Dialog -->
<v-dialog v-model="markAsPaidDialog" max-width="400">
<v-card>
<v-card-title class="text-h6">
<v-icon left color="success">mdi-check-circle</v-icon>
<v-card-title class="text-h6 pa-4">
<v-icon left color="success">mdi-calendar-check</v-icon>
Mark Dues as Paid
</v-card-title>
<v-card-text>
<p>Are you sure you want to mark the dues as paid for this member?</p>
<p class="text-body-2 text-medium-emphasis">
This will remove the payment banner and update the member's status.
</p>
<v-card-text class="pa-4">
<div class="mb-4">
<h4 class="text-subtitle-1 mb-2">
{{ memberData?.FullName || `${memberData?.first_name || ''} ${memberData?.last_name || ''}`.trim() }}
</h4>
<p class="text-body-2 text-medium-emphasis">
Select the date when the dues payment was received:
</p>
</div>
<div class="date-picker-wrapper">
<label class="date-picker-label">Payment Date</label>
<VueDatePicker
v-model="selectedPaymentModel"
:timezone="{
timezone: 'Europe/Monaco',
emitTimezone: 'UTC'
}"
:format="'dd/MM/yyyy (Monaco)'"
:max-date="new Date()"
placeholder="Select payment date"
:enable-time-picker="false"
auto-apply
:clearable="false"
:required="true"
@update:model-value="handleDateUpdate"
/>
<div class="text-caption text-medium-emphasis mt-1">
Select the date when the payment was received
</div>
</div>
<v-alert
v-if="selectedPaymentDate && isDateInFuture"
type="warning"
variant="tonal"
class="mt-2"
density="compact"
>
<v-icon start>mdi-information</v-icon>
Future dates are not allowed. Please select today or an earlier date.
</v-alert>
</v-card-text>
<v-card-actions>
<v-card-actions class="pa-4 pt-0">
<v-spacer />
<v-btn
color="grey"
variant="text"
@click="markAsPaidDialog = false"
@click="cancelPaymentDialog"
>
Cancel
</v-btn>
<v-btn
color="success"
variant="flat"
variant="elevated"
:disabled="!selectedPaymentDate || isDateInFuture"
:loading="updating"
@click="markDuesAsPaid"
>
Mark as Paid
<v-icon start>mdi-check-circle</v-icon>
Confirm Payment
</v-btn>
</v-card-actions>
</v-card>
@ -172,6 +211,10 @@ const config = ref<RegistrationConfig>({
accountHolder: ''
});
// Reactive state for payment date dialog
const selectedPaymentDate = ref('');
const selectedPaymentModel = ref<Date | null>(null);
const snackbar = ref({
show: false,
message: '',
@ -311,6 +354,21 @@ const paymentMessage = computed(() => {
}
});
const todayDate = computed(() => {
return new Date().toISOString().split('T')[0]; // YYYY-MM-DD format
});
const isDateInFuture = computed(() => {
if (!selectedPaymentDate.value) return false;
const selectedDate = new Date(selectedPaymentDate.value);
const today = new Date();
today.setHours(0, 0, 0, 0); // Reset time to start of day
selectedDate.setHours(0, 0, 0, 0); // Reset time to start of day
return selectedDate > today;
});
// Methods
function dismissBanner() {
dismissed.value = true;
@ -325,30 +383,31 @@ function dismissBanner() {
}
async function markDuesAsPaid() {
if (!memberData.value?.Id) return;
if (!memberData.value?.Id || !selectedPaymentDate.value || isDateInFuture.value) return;
updating.value = true;
try {
// Update member's dues status
// Update member's dues status with the selected payment date
await $fetch(`/api/members/${memberData.value.Id}`, {
method: 'PUT',
body: {
current_year_dues_paid: 'true',
membership_date_paid: new Date().toISOString(),
payment_due_date: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString() // Next year
membership_date_paid: selectedPaymentDate.value,
payment_due_date: new Date(new Date(selectedPaymentDate.value).getTime() + 365 * 24 * 60 * 60 * 1000).toISOString() // Next year from payment date
}
});
// Update local member state
if (memberData.value) {
memberData.value.current_year_dues_paid = 'true';
memberData.value.membership_date_paid = new Date().toISOString();
memberData.value.membership_date_paid = selectedPaymentDate.value;
}
// Hide banner
// Hide banner and reset
showBanner.value = false;
markAsPaidDialog.value = false;
selectedPaymentDate.value = '';
// Show success message
snackbar.value = {
@ -369,6 +428,19 @@ async function markDuesAsPaid() {
}
}
// Date picker handler
const handleDateUpdate = (date: Date | null) => {
if (date) {
selectedPaymentDate.value = date.toISOString().split('T')[0];
}
};
const cancelPaymentDialog = () => {
markAsPaidDialog.value = false;
selectedPaymentDate.value = '';
selectedPaymentModel.value = null;
};
// Load member data for the current user from session
async function loadMemberData() {
if (!user.value) return;
@ -460,6 +532,76 @@ onMounted(() => {
border: 1px solid rgba(255, 255, 255, 0.2) !important;
}
/* Date picker styling to match Vuetify */
.date-picker-wrapper {
width: 100%;
}
.date-picker-label {
font-size: 16px;
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
font-weight: 400;
line-height: 1.5;
letter-spacing: 0.009375em;
margin-bottom: 8px;
display: block;
}
/* Style the Vue DatePicker to match Vuetify inputs */
:deep(.dp__input) {
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
border-radius: 4px;
padding: 16px 12px;
padding-right: 48px; /* Make room for calendar icon */
font-size: 16px;
line-height: 1.5;
background: rgb(var(--v-theme-surface));
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
transition: border-color 0.2s cubic-bezier(0.4, 0, 0.2, 1);
width: 100%;
min-height: 56px;
}
:deep(.dp__input:hover) {
border-color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
}
:deep(.dp__input:focus) {
border-color: rgb(var(--v-theme-primary));
border-width: 2px;
outline: none;
}
:deep(.dp__input_readonly) {
cursor: pointer;
}
/* Style the date picker dropdown */
:deep(.dp__menu) {
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
background: rgb(var(--v-theme-surface));
}
/* Primary color theming for the date picker */
:deep(.dp__primary_color) {
background-color: rgb(var(--v-theme-primary));
}
:deep(.dp__primary_text) {
color: rgb(var(--v-theme-primary));
}
:deep(.dp__active_date) {
background-color: rgb(var(--v-theme-primary));
color: rgb(var(--v-theme-on-primary));
}
:deep(.dp__today) {
border: 1px solid rgb(var(--v-theme-primary));
}
/* Mobile responsiveness */
@media (max-width: 600px) {
.banner-content .text-h6 {