updated member list with improved filtering system and enhanced editing capabilities.
Build And Push Image / docker (push) Successful in 2m53s Details

This commit is contained in:
Matt 2025-08-07 22:34:51 +02:00
parent 024eca02ac
commit 9202509c9c
1 changed files with 69 additions and 27 deletions

View File

@ -15,7 +15,7 @@
<!-- Search and Filter Controls --> <!-- Search and Filter Controls -->
<v-row class="mb-4"> <v-row class="mb-4">
<v-col cols="12" md="3"> <v-col cols="12" md="2">
<v-text-field <v-text-field
v-model="searchTerm" v-model="searchTerm"
label="Search members..." label="Search members..."
@ -26,18 +26,40 @@
/> />
</v-col> </v-col>
<v-col cols="12" md="3"> <v-col cols="12" md="2">
<v-select <v-select
v-model="statusFilter" v-model="activeFilter"
:items="statusOptions" :items="activeFilterOptions"
label="Membership Status" label="Member Status"
variant="outlined" variant="outlined"
clearable clearable
@update:model-value="filterMembers" prepend-inner-icon="mdi-account-check"
/> />
</v-col> </v-col>
<v-col cols="12" md="3"> <v-col cols="12" md="2">
<v-select
v-model="statusFilter"
:items="statusOptions"
label="Membership Level"
variant="outlined"
clearable
prepend-inner-icon="mdi-shield-account"
/>
</v-col>
<v-col cols="12" md="2">
<v-select
v-model="duesFilter"
:items="duesFilterOptions"
label="Dues Status"
variant="outlined"
clearable
prepend-inner-icon="mdi-cash"
/>
</v-col>
<v-col cols="12" md="2">
<v-select <v-select
v-model="sortOption" v-model="sortOption"
:items="sortOptions" :items="sortOptions"
@ -47,7 +69,7 @@
/> />
</v-col> </v-col>
<v-col cols="12" md="3"> <v-col cols="12" md="2">
<v-btn <v-btn
color="primary" color="primary"
block block
@ -254,7 +276,9 @@ const error = ref('');
// Search and filtering // Search and filtering
const searchTerm = ref(''); const searchTerm = ref('');
const activeFilter = ref('');
const statusFilter = ref(''); const statusFilter = ref('');
const duesFilter = ref('');
const sortOption = ref('name-asc'); const sortOption = ref('name-asc');
// Dialogs // Dialogs
@ -270,6 +294,11 @@ const showSuccess = ref(false);
const successMessage = ref(''); const successMessage = ref('');
// Filter options // Filter options
const activeFilterOptions = [
{ title: 'Active Members', value: 'active' },
{ title: 'Inactive Members', value: 'inactive' }
];
const statusOptions = [ const statusOptions = [
{ title: 'Active', value: 'Active' }, { title: 'Active', value: 'Active' },
{ title: 'Inactive', value: 'Inactive' }, { title: 'Inactive', value: 'Inactive' },
@ -277,12 +306,15 @@ const statusOptions = [
{ title: 'Expired', value: 'Expired' } { title: 'Expired', value: 'Expired' }
]; ];
const duesFilterOptions = [
{ title: 'Dues Paid', value: 'paid' },
{ title: 'Dues Outstanding', value: 'unpaid' }
];
// Sort options // Sort options
const sortOptions = [ const sortOptions = [
{ title: 'Name (A-Z)', value: 'name-asc' }, { title: 'Name (A-Z)', value: 'name-asc' },
{ title: 'Name (Z-A)', value: 'name-desc' }, { title: 'Name (Z-A)', value: 'name-desc' },
{ title: 'Date Paid (Newest First)', value: 'date-desc' },
{ title: 'Date Paid (Oldest First)', value: 'date-asc' },
{ title: 'Nationality (A-Z)', value: 'nationality-asc' }, { title: 'Nationality (A-Z)', value: 'nationality-asc' },
{ title: 'Nationality (Z-A)', value: 'nationality-desc' } { title: 'Nationality (Z-A)', value: 'nationality-desc' }
]; ];
@ -296,18 +328,36 @@ const filteredMembers = computed(() => {
const search = searchTerm.value.toLowerCase(); const search = searchTerm.value.toLowerCase();
filtered = filtered.filter(member => filtered = filtered.filter(member =>
member.FullName?.toLowerCase().includes(search) || member.FullName?.toLowerCase().includes(search) ||
member.Email?.toLowerCase().includes(search) || member.email?.toLowerCase().includes(search) ||
member.Phone?.includes(search) member.phone?.includes(search)
); );
} }
// Status filter // Active/Inactive filter
if (activeFilter.value) {
if (activeFilter.value === 'active') {
filtered = filtered.filter(member => member.membership_status === 'Active');
} else if (activeFilter.value === 'inactive') {
filtered = filtered.filter(member => member.membership_status !== 'Active');
}
}
// Status filter (specific membership levels)
if (statusFilter.value) { if (statusFilter.value) {
filtered = filtered.filter(member => filtered = filtered.filter(member =>
member['Membership Status'] === statusFilter.value member.membership_status === statusFilter.value
); );
} }
// Dues filter
if (duesFilter.value) {
if (duesFilter.value === 'paid') {
filtered = filtered.filter(member => member.current_year_dues_paid === 'true');
} else if (duesFilter.value === 'unpaid') {
filtered = filtered.filter(member => member.current_year_dues_paid !== 'true');
}
}
// Sorting // Sorting
if (sortOption.value) { if (sortOption.value) {
filtered.sort((a, b) => { filtered.sort((a, b) => {
@ -316,18 +366,10 @@ const filteredMembers = computed(() => {
return (a.FullName || '').localeCompare(b.FullName || ''); return (a.FullName || '').localeCompare(b.FullName || '');
case 'name-desc': case 'name-desc':
return (b.FullName || '').localeCompare(a.FullName || ''); return (b.FullName || '').localeCompare(a.FullName || '');
case 'date-desc':
const aDate = a['Membership Date Paid'] || '';
const bDate = b['Membership Date Paid'] || '';
return new Date(bDate).getTime() - new Date(aDate).getTime();
case 'date-asc':
const aDateAsc = a['Membership Date Paid'] || '';
const bDateAsc = b['Membership Date Paid'] || '';
return new Date(aDateAsc).getTime() - new Date(bDateAsc).getTime();
case 'nationality-asc': case 'nationality-asc':
return (a.Nationality || '').localeCompare(b.Nationality || ''); return (a.nationality || '').localeCompare(b.nationality || '');
case 'nationality-desc': case 'nationality-desc':
return (b.Nationality || '').localeCompare(a.Nationality || ''); return (b.nationality || '').localeCompare(a.nationality || '');
default: default:
return 0; return 0;
} }
@ -339,13 +381,13 @@ const filteredMembers = computed(() => {
const totalMembers = computed(() => members.value.length); const totalMembers = computed(() => members.value.length);
const activeMembers = computed(() => const activeMembers = computed(() =>
members.value.filter(m => m['Membership Status'] === 'Active').length members.value.filter(m => m.membership_status === 'Active').length
); );
const paidDuesMembers = computed(() => const paidDuesMembers = computed(() =>
members.value.filter(m => m['Current Year Dues Paid'] === 'true').length members.value.filter(m => m.current_year_dues_paid === 'true').length
); );
const uniqueNationalities = computed(() => { const uniqueNationalities = computed(() => {
const nationalities = new Set(members.value.map(m => m.Nationality).filter(Boolean)); const nationalities = new Set(members.value.map(m => m.nationality).filter(Boolean));
return nationalities.size; return nationalities.size;
}); });