diff --git a/components/CountryFlag.vue b/components/CountryFlag.vue index b27beee..51bceee 100644 --- a/components/CountryFlag.vue +++ b/components/CountryFlag.vue @@ -1,11 +1,11 @@ @@ -85,8 +64,9 @@ const flagStyle = computed(() => { } /* Ensure proper flag display */ -.fi { - flex-shrink: 0; +:deep(.vue-country-flag) { + border-radius: 2px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); + flex-shrink: 0; } diff --git a/components/EditMemberDialog.vue b/components/EditMemberDialog.vue new file mode 100644 index 0000000..62caee7 --- /dev/null +++ b/components/EditMemberDialog.vue @@ -0,0 +1,468 @@ + + + + + diff --git a/components/MemberCard.vue b/components/MemberCard.vue index 59d7109..81c051c 100644 --- a/components/MemberCard.vue +++ b/components/MemberCard.vue @@ -155,8 +155,8 @@ const memberInitials = computed(() => { }); const avatarColor = computed(() => { - // Generate consistent color based on member ID - const colors = ['primary', 'secondary', 'accent', 'info', 'warning', 'success']; + // Generate consistent color based on member ID using high-contrast colors + const colors = ['red', 'blue', 'green', 'orange', 'purple', 'teal', 'indigo', 'pink', 'brown']; const idNumber = parseInt(props.member.Id) || 0; return colors[idNumber % colors.length]; }); diff --git a/nuxt.config.ts b/nuxt.config.ts index 6494f25..298bf94 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -69,7 +69,6 @@ export default defineNuxtConfig({ ] ], css: [ - 'flag-icons/css/flag-icons.min.css' ], app: { head: { diff --git a/package-lock.json b/package-lock.json index ad8dbaf..5befe2b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "sharp": "^0.34.2", "systeminformation": "^5.27.7", "vue": "latest", + "vue-country-flag-next": "^2.3.2", "vue-router": "latest", "vuetify-nuxt-module": "^0.18.3" }, @@ -17662,6 +17663,18 @@ "integrity": "sha512-uoNZaJ+a1/zppa/Vgmi8zIOP2PHXDN2rT8NyF+zQRK6ZG94lNB9prcV0GdLJbY9i9lrD47JOVIH92SaiA7oJ1A==", "license": "MIT" }, + "node_modules/vue-country-flag-next": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/vue-country-flag-next/-/vue-country-flag-next-2.3.2.tgz", + "integrity": "sha512-Lv12L1VTwlBgizpZ3xPEPO3zuIETaJmeSiPuLOWLLgu2EakwU/o72iKYiKcdZ6BXiSkfss+Ski5fDzjuxZ1DcA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, "node_modules/vue-devtools-stub": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/vue-devtools-stub/-/vue-devtools-stub-0.1.0.tgz", diff --git a/package.json b/package.json index b8b1e25..0d3b4bc 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "sharp": "^0.34.2", "systeminformation": "^5.27.7", "vue": "latest", + "vue-country-flag-next": "^2.3.2", "vue-router": "latest", "vuetify-nuxt-module": "^0.18.3" }, diff --git a/pages/dashboard/member-list.vue b/pages/dashboard/member-list.vue index df997f7..81d3db2 100644 --- a/pages/dashboard/member-list.vue +++ b/pages/dashboard/member-list.vue @@ -15,7 +15,7 @@ - + - - - - - - - - + + + + + mdi-account-search

No members found

- {{ searchTerm || nationalityFilter || statusFilter + {{ searchTerm || statusFilter ? 'Try adjusting your filters to find members.' : 'No members have been added yet.' }}

@@ -267,8 +254,8 @@ const error = ref(''); // Search and filtering const searchTerm = ref(''); -const nationalityFilter = ref(''); const statusFilter = ref(''); +const sortOption = ref('name-asc'); // Dialogs const showAddDialog = ref(false); @@ -290,15 +277,15 @@ const statusOptions = [ { title: 'Expired', value: 'Expired' } ]; -const nationalityOptions = computed(() => { - const countries = getAllCountries(); - return countries.map(country => ({ - title: country.name, - value: country.code, - code: country.code, - name: country.name - })); -}); +// Sort options +const sortOptions = [ + { title: 'Name (A-Z)', value: 'name-asc' }, + { 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 (Z-A)', value: 'nationality-desc' } +]; // Computed properties const filteredMembers = computed(() => { @@ -314,13 +301,6 @@ const filteredMembers = computed(() => { ); } - // Nationality filter - if (nationalityFilter.value) { - filtered = filtered.filter(member => - member.Nationality === nationalityFilter.value - ); - } - // Status filter if (statusFilter.value) { filtered = filtered.filter(member => @@ -328,6 +308,32 @@ const filteredMembers = computed(() => { ); } + // Sorting + if (sortOption.value) { + filtered.sort((a, b) => { + switch (sortOption.value) { + case 'name-asc': + return (a.FullName || '').localeCompare(b.FullName || ''); + case 'name-desc': + 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': + return (a.Nationality || '').localeCompare(b.Nationality || ''); + case 'nationality-desc': + return (b.Nationality || '').localeCompare(a.Nationality || ''); + default: + return 0; + } + }); + } + return filtered; });