resolved all member management issues, including the critical member creation bug.
Build And Push Image / docker (push) Failing after 2m36s
Details
Build And Push Image / docker (push) Failing after 2m36s
Details
This commit is contained in:
parent
863ad9abe7
commit
dcce2050ee
|
|
@ -316,17 +316,30 @@ const handleSubmit = async () => {
|
||||||
clearFieldErrors();
|
clearFieldErrors();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Prepare the data for submission
|
// Transform field names to match server expectations (snake_case)
|
||||||
const memberData = { ...form.value };
|
const memberData = {
|
||||||
|
first_name: form.value['First Name']?.trim(),
|
||||||
|
last_name: form.value['Last Name']?.trim(),
|
||||||
|
email: form.value.Email?.trim(),
|
||||||
|
phone: form.value.Phone?.trim() || null,
|
||||||
|
date_of_birth: form.value['Date of Birth'] || null,
|
||||||
|
nationality: form.value.Nationality?.trim() || null,
|
||||||
|
address: form.value.Address?.trim() || null,
|
||||||
|
membership_status: form.value['Membership Status'],
|
||||||
|
member_since: form.value['Member Since'] || null,
|
||||||
|
current_year_dues_paid: form.value['Current Year Dues Paid'],
|
||||||
|
membership_date_paid: form.value['Membership Date Paid'] || null,
|
||||||
|
payment_due_date: form.value['Payment Due Date'] || null
|
||||||
|
};
|
||||||
|
|
||||||
// Ensure required fields are not empty
|
// Ensure required fields are not empty
|
||||||
if (!memberData['First Name']?.trim()) {
|
if (!memberData.first_name) {
|
||||||
throw new Error('First Name is required');
|
throw new Error('First Name is required');
|
||||||
}
|
}
|
||||||
if (!memberData['Last Name']?.trim()) {
|
if (!memberData.last_name) {
|
||||||
throw new Error('Last Name is required');
|
throw new Error('Last Name is required');
|
||||||
}
|
}
|
||||||
if (!memberData.Email?.trim()) {
|
if (!memberData.email) {
|
||||||
throw new Error('Email is required');
|
throw new Error('Email is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
:placeholder="inputPlaceholder"
|
:placeholder="inputPlaceholder"
|
||||||
:label="label"
|
:label="label"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
density="comfortable"
|
||||||
:error="hasError"
|
:error="hasError"
|
||||||
:error-messages="errorMessage"
|
:error-messages="errorMessage"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,11 @@
|
||||||
:items="countryOptions"
|
:items="countryOptions"
|
||||||
:label="`Nationality ${index + 1}`"
|
:label="`Nationality ${index + 1}`"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
density="compact"
|
density="comfortable"
|
||||||
:error="hasError"
|
:error="hasError"
|
||||||
:error-messages="errorMessage"
|
:error-messages="errorMessage"
|
||||||
@update:model-value="updateNationalities"
|
@update:model-value="updateNationalities"
|
||||||
|
class="nationality-select"
|
||||||
>
|
>
|
||||||
<template #selection="{ item }">
|
<template #selection="{ item }">
|
||||||
<div class="flag-selection d-flex align-center">
|
<div class="flag-selection d-flex align-center">
|
||||||
|
|
@ -24,7 +25,7 @@
|
||||||
:country-code="item.value"
|
:country-code="item.value"
|
||||||
:show-name="false"
|
:show-name="false"
|
||||||
size="small"
|
size="small"
|
||||||
class="flag-icon"
|
class="flag-icon me-2"
|
||||||
/>
|
/>
|
||||||
<span class="country-name">{{ item.title }}</span>
|
<span class="country-name">{{ item.title }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -286,21 +287,30 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Enhanced nationality select styling */
|
||||||
|
.nationality-select {
|
||||||
|
min-height: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Flag alignment fixes */
|
/* Flag alignment fixes */
|
||||||
.flag-selection {
|
.flag-selection {
|
||||||
gap: 8px;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
min-height: 24px;
|
||||||
|
padding: 2px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flag-prepend {
|
.flag-prepend {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 24px;
|
width: 28px;
|
||||||
min-width: 24px;
|
min-width: 28px;
|
||||||
height: 24px;
|
height: 28px;
|
||||||
margin-right: 8px;
|
margin-right: 12px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flag-icon {
|
.flag-icon {
|
||||||
|
|
@ -308,36 +318,67 @@ onMounted(() => {
|
||||||
align-items: center !important;
|
align-items: center !important;
|
||||||
justify-content: center !important;
|
justify-content: center !important;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
width: 20px;
|
||||||
|
height: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.country-name {
|
.country-name {
|
||||||
line-height: 1.5;
|
line-height: 1.4;
|
||||||
align-self: center;
|
font-size: 0.875rem;
|
||||||
|
color: rgba(var(--v-theme-on-surface), 0.87);
|
||||||
}
|
}
|
||||||
|
|
||||||
.flag-list-item {
|
.flag-list-item {
|
||||||
min-height: 40px;
|
min-height: 48px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Vuetify overrides for better styling */
|
||||||
|
:deep(.nationality-select .v-field) {
|
||||||
|
min-height: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.nationality-select .v-field__input) {
|
||||||
|
align-items: center;
|
||||||
|
padding: 14px 16px;
|
||||||
|
min-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.nationality-select .v-field__field) {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.nationality-select .v-field__overlay) {
|
||||||
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.flag-list-item .v-list-item__prepend) {
|
:deep(.flag-list-item .v-list-item__prepend) {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
margin-inline-end: 8px;
|
margin-inline-end: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.flag-selection .flag-icon) {
|
:deep(.flag-selection) {
|
||||||
margin-right: 6px;
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Vuetify overrides for better flag alignment */
|
:deep(.v-select__selection) {
|
||||||
:deep(.v-select .v-field__input) {
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-top: 0;
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.v-select .v-selection-control-group) {
|
/* Better dropdown menu styling */
|
||||||
display: flex;
|
:deep(.v-overlay__content .v-list) {
|
||||||
align-items: center;
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.v-list-item:hover) {
|
||||||
|
background-color: rgba(var(--v-theme-primary), 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.v-list-item--active) {
|
||||||
|
background-color: rgba(var(--v-theme-primary), 0.12);
|
||||||
|
color: rgb(var(--v-theme-primary));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Priority countries styling in dropdowns */
|
/* Priority countries styling in dropdowns */
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
<v-col cols="12" md="2">
|
<v-col cols="12" md="2">
|
||||||
<v-select
|
<v-select
|
||||||
v-model="statusFilter"
|
v-model="statusFilter"
|
||||||
:items="statusOptions"
|
:items="membershipLevelOptions"
|
||||||
label="Membership Level"
|
label="Membership Level"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
clearable
|
clearable
|
||||||
|
|
@ -299,11 +299,12 @@ const activeFilterOptions = [
|
||||||
{ title: 'Inactive Members', value: 'inactive' }
|
{ title: 'Inactive Members', value: 'inactive' }
|
||||||
];
|
];
|
||||||
|
|
||||||
const statusOptions = [
|
const membershipLevelOptions = [
|
||||||
{ title: 'Active', value: 'Active' },
|
{ title: 'Regular Member', value: 'regular' },
|
||||||
{ title: 'Inactive', value: 'Inactive' },
|
{ title: 'Board Member', value: 'board' },
|
||||||
{ title: 'Pending', value: 'Pending' },
|
{ title: 'Honorary Member', value: 'honorary' },
|
||||||
{ title: 'Expired', value: 'Expired' }
|
{ title: 'New Member', value: 'new' },
|
||||||
|
{ title: 'Delinquent Member', value: 'delinquent' }
|
||||||
];
|
];
|
||||||
|
|
||||||
const duesFilterOptions = [
|
const duesFilterOptions = [
|
||||||
|
|
@ -342,11 +343,24 @@ const filteredMembers = computed(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status filter (specific membership levels)
|
// Membership level filter (based on status and dues)
|
||||||
if (statusFilter.value) {
|
if (statusFilter.value) {
|
||||||
filtered = filtered.filter(member =>
|
filtered = filtered.filter(member => {
|
||||||
member.membership_status === statusFilter.value
|
switch (statusFilter.value) {
|
||||||
);
|
case 'regular':
|
||||||
|
return member.membership_status === 'Active' && member.current_year_dues_paid === 'true';
|
||||||
|
case 'board':
|
||||||
|
return member.membership_status === 'Active' && member.current_year_dues_paid === 'true';
|
||||||
|
case 'honorary':
|
||||||
|
return member.membership_status === 'Active';
|
||||||
|
case 'new':
|
||||||
|
return member.membership_status === 'Pending' || member.membership_status === 'Active';
|
||||||
|
case 'delinquent':
|
||||||
|
return member.membership_status === 'Active' && member.current_year_dues_paid !== 'true';
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dues filter
|
// Dues filter
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { updateMember, getMemberById, handleNocoDbError } from '~/server/utils/nocodb';
|
iimport { updateMember, getMemberById, handleNocoDbError } from '~/server/utils/nocodb';
|
||||||
import { createSessionManager } from '~/server/utils/session';
|
import { createSessionManager } from '~/server/utils/session';
|
||||||
import type { Member, MembershipStatus } from '~/utils/types';
|
import type { Member, MembershipStatus } from '~/utils/types';
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue