fixes
Build And Push Image / docker (push) Successful in 1m28s
Details
Build And Push Image / docker (push) Successful in 1m28s
Details
This commit is contained in:
parent
cde48de9ff
commit
c6edd6d25d
|
|
@ -159,6 +159,8 @@
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
:error="hasFieldError('Membership Date Paid')"
|
:error="hasFieldError('Membership Date Paid')"
|
||||||
:error-messages="getFieldError('Membership Date Paid')"
|
:error-messages="getFieldError('Membership Date Paid')"
|
||||||
|
hint="Enter the actual date when dues were paid (can be historical)"
|
||||||
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
|
|
@ -170,8 +172,29 @@
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
:error="hasFieldError('Payment Due Date')"
|
:error="hasFieldError('Payment Due Date')"
|
||||||
:error-messages="getFieldError('Payment Due Date')"
|
:error-messages="getFieldError('Payment Due Date')"
|
||||||
|
hint="Enter when payment is due (for new members in grace period)"
|
||||||
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
|
<!-- Dues Status Preview -->
|
||||||
|
<v-col cols="12" v-if="duesPaid && form['Membership Date Paid']">
|
||||||
|
<v-card variant="tonal" :color="calculatedDuesStatus.color" class="pa-3">
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<v-icon :color="calculatedDuesStatus.color" class="mr-2">
|
||||||
|
{{ calculatedDuesStatus.icon }}
|
||||||
|
</v-icon>
|
||||||
|
<div>
|
||||||
|
<div class="text-subtitle-2 font-weight-bold">
|
||||||
|
Calculated Dues Status: {{ calculatedDuesStatus.text }}
|
||||||
|
</div>
|
||||||
|
<div class="text-caption">
|
||||||
|
{{ calculatedDuesStatus.message }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-form>
|
</v-form>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
|
|
@ -202,6 +225,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Member } from '~/utils/types';
|
import type { Member } from '~/utils/types';
|
||||||
import { formatBooleanAsString } from '~/utils/client-utils';
|
import { formatBooleanAsString } from '~/utils/client-utils';
|
||||||
|
import { isPaymentOverOneYear, isDuesActuallyCurrent, calculateOverdueDays } from '~/utils/dues-calculations';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: boolean;
|
modelValue: boolean;
|
||||||
|
|
@ -243,23 +267,69 @@ const phoneData = ref(null);
|
||||||
// Error handling
|
// Error handling
|
||||||
const fieldErrors = ref<Record<string, string>>({});
|
const fieldErrors = ref<Record<string, string>>({});
|
||||||
|
|
||||||
|
// Computed dues status calculation
|
||||||
|
const calculatedDuesStatus = computed(() => {
|
||||||
|
if (!duesPaid.value || !form.value['Membership Date Paid']) {
|
||||||
|
return {
|
||||||
|
color: 'grey',
|
||||||
|
icon: 'mdi-help',
|
||||||
|
text: 'Unknown',
|
||||||
|
message: 'Please enter payment date to calculate status'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a mock member object with form data to use calculation functions
|
||||||
|
const mockMember = {
|
||||||
|
current_year_dues_paid: 'true',
|
||||||
|
membership_date_paid: form.value['Membership Date Paid'],
|
||||||
|
payment_due_date: form.value['Payment Due Date'],
|
||||||
|
member_since: form.value['Member Since']
|
||||||
|
} as Member;
|
||||||
|
|
||||||
|
const isOverdue = !isDuesActuallyCurrent(mockMember);
|
||||||
|
const paymentTooOld = isPaymentOverOneYear(mockMember);
|
||||||
|
|
||||||
|
if (isOverdue && paymentTooOld) {
|
||||||
|
const overdueDays = calculateOverdueDays(mockMember);
|
||||||
|
return {
|
||||||
|
color: 'error',
|
||||||
|
icon: 'mdi-alert-circle',
|
||||||
|
text: 'Overdue',
|
||||||
|
message: `Payment is ${overdueDays} days overdue (more than 1 year since payment)`
|
||||||
|
};
|
||||||
|
} else if (isOverdue) {
|
||||||
|
return {
|
||||||
|
color: 'warning',
|
||||||
|
icon: 'mdi-clock-alert',
|
||||||
|
text: 'Due Soon',
|
||||||
|
message: 'Dues will be due soon based on payment date'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const paymentDate = new Date(form.value['Membership Date Paid']);
|
||||||
|
const nextDue = new Date(paymentDate);
|
||||||
|
nextDue.setFullYear(nextDue.getFullYear() + 1);
|
||||||
|
const nextDueFormatted = nextDue.toLocaleDateString('en-US', {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric'
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
color: 'success',
|
||||||
|
icon: 'mdi-check-circle',
|
||||||
|
text: 'Current',
|
||||||
|
message: `Dues are current. Next payment due: ${nextDueFormatted}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Watch dues paid switch
|
// Watch dues paid switch
|
||||||
watch(duesPaid, (newValue) => {
|
watch(duesPaid, (newValue) => {
|
||||||
form.value['Current Year Dues Paid'] = formatBooleanAsString(newValue);
|
form.value['Current Year Dues Paid'] = formatBooleanAsString(newValue);
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
form.value['Payment Due Date'] = '';
|
form.value['Payment Due Date'] = '';
|
||||||
if (!form.value['Membership Date Paid']) {
|
|
||||||
form.value['Membership Date Paid'] = new Date().toISOString().split('T')[0];
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
form.value['Membership Date Paid'] = '';
|
form.value['Membership Date Paid'] = '';
|
||||||
if (!form.value['Payment Due Date']) {
|
|
||||||
// Set due date to one month from member since date or today
|
|
||||||
const memberSince = form.value['Member Since'] || new Date().toISOString().split('T')[0];
|
|
||||||
const dueDate = new Date(memberSince);
|
|
||||||
dueDate.setMonth(dueDate.getMonth() + 1);
|
|
||||||
form.value['Payment Due Date'] = dueDate.toISOString().split('T')[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,8 @@
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
:error="hasFieldError('membership_date_paid')"
|
:error="hasFieldError('membership_date_paid')"
|
||||||
:error-messages="getFieldError('membership_date_paid')"
|
:error-messages="getFieldError('membership_date_paid')"
|
||||||
|
hint="Enter the actual date when dues were paid (can be historical)"
|
||||||
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
|
|
@ -183,9 +185,30 @@
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
:error="hasFieldError('payment_due_date')"
|
:error="hasFieldError('payment_due_date')"
|
||||||
:error-messages="getFieldError('payment_due_date')"
|
:error-messages="getFieldError('payment_due_date')"
|
||||||
|
hint="Enter when payment is due (for members in grace period)"
|
||||||
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
|
<!-- Dues Status Preview -->
|
||||||
|
<v-col cols="12" v-if="duesPaid && form.membership_date_paid">
|
||||||
|
<v-card variant="tonal" :color="calculatedDuesStatus.color" class="pa-3">
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<v-icon :color="calculatedDuesStatus.color" class="mr-2">
|
||||||
|
{{ calculatedDuesStatus.icon }}
|
||||||
|
</v-icon>
|
||||||
|
<div>
|
||||||
|
<div class="text-subtitle-2 font-weight-bold">
|
||||||
|
Calculated Dues Status: {{ calculatedDuesStatus.text }}
|
||||||
|
</div>
|
||||||
|
<div class="text-caption">
|
||||||
|
{{ calculatedDuesStatus.message }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
<!-- Portal Access Control Section (Admin Only) -->
|
<!-- Portal Access Control Section (Admin Only) -->
|
||||||
<template v-if="isAdmin && member?.keycloak_id">
|
<template v-if="isAdmin && member?.keycloak_id">
|
||||||
<v-col cols="12">
|
<v-col cols="12">
|
||||||
|
|
@ -292,6 +315,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Member } from '~/utils/types';
|
import type { Member } from '~/utils/types';
|
||||||
|
import { isPaymentOverOneYear, isDuesActuallyCurrent, calculateOverdueDays } from '~/utils/dues-calculations';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: boolean;
|
modelValue: boolean;
|
||||||
|
|
@ -339,6 +363,62 @@ const phoneData = ref(null);
|
||||||
// Error handling
|
// Error handling
|
||||||
const fieldErrors = ref<Record<string, string>>({});
|
const fieldErrors = ref<Record<string, string>>({});
|
||||||
|
|
||||||
|
// Computed dues status calculation
|
||||||
|
const calculatedDuesStatus = computed(() => {
|
||||||
|
if (!duesPaid.value || !form.value.membership_date_paid) {
|
||||||
|
return {
|
||||||
|
color: 'grey',
|
||||||
|
icon: 'mdi-help',
|
||||||
|
text: 'Unknown',
|
||||||
|
message: 'Please enter payment date to calculate status'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a mock member object with form data to use calculation functions
|
||||||
|
const mockMember = {
|
||||||
|
current_year_dues_paid: 'true',
|
||||||
|
membership_date_paid: form.value.membership_date_paid,
|
||||||
|
payment_due_date: form.value.payment_due_date,
|
||||||
|
member_since: form.value.member_since
|
||||||
|
} as Member;
|
||||||
|
|
||||||
|
const isOverdue = !isDuesActuallyCurrent(mockMember);
|
||||||
|
const paymentTooOld = isPaymentOverOneYear(mockMember);
|
||||||
|
|
||||||
|
if (isOverdue && paymentTooOld) {
|
||||||
|
const overdueDays = calculateOverdueDays(mockMember);
|
||||||
|
return {
|
||||||
|
color: 'error',
|
||||||
|
icon: 'mdi-alert-circle',
|
||||||
|
text: 'Overdue',
|
||||||
|
message: `Payment is ${overdueDays} days overdue (more than 1 year since payment)`
|
||||||
|
};
|
||||||
|
} else if (isOverdue) {
|
||||||
|
return {
|
||||||
|
color: 'warning',
|
||||||
|
icon: 'mdi-clock-alert',
|
||||||
|
text: 'Due Soon',
|
||||||
|
message: 'Dues will be due soon based on payment date'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const paymentDate = new Date(form.value.membership_date_paid);
|
||||||
|
const nextDue = new Date(paymentDate);
|
||||||
|
nextDue.setFullYear(nextDue.getFullYear() + 1);
|
||||||
|
const nextDueFormatted = nextDue.toLocaleDateString('en-US', {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric'
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
color: 'success',
|
||||||
|
icon: 'mdi-check-circle',
|
||||||
|
text: 'Current',
|
||||||
|
message: `Dues are current. Next payment due: ${nextDueFormatted}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Auth state
|
// Auth state
|
||||||
const { user, isAdmin } = useAuth();
|
const { user, isAdmin } = useAuth();
|
||||||
|
|
||||||
|
|
@ -409,18 +489,8 @@ watch(duesPaid, (newValue) => {
|
||||||
form.value.current_year_dues_paid = newValue ? 'true' : 'false';
|
form.value.current_year_dues_paid = newValue ? 'true' : 'false';
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
form.value.payment_due_date = '';
|
form.value.payment_due_date = '';
|
||||||
if (!form.value.membership_date_paid) {
|
|
||||||
form.value.membership_date_paid = new Date().toISOString().split('T')[0];
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
form.value.membership_date_paid = '';
|
form.value.membership_date_paid = '';
|
||||||
if (!form.value.payment_due_date) {
|
|
||||||
// Set due date to one month from member since date or today
|
|
||||||
const memberSince = form.value.member_since || new Date().toISOString().split('T')[0];
|
|
||||||
const dueDate = new Date(memberSince);
|
|
||||||
dueDate.setMonth(dueDate.getMonth() + 1);
|
|
||||||
form.value.payment_due_date = dueDate.toISOString().split('T')[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue