Replace all mock data in admin and board pages with real data
All checks were successful
Build And Push Image / docker (push) Successful in 1m56s

- Admin members page now loads real member data from NocoDB API
- Admin users page fetches actual users from Keycloak with tier determination
- Board members page uses real member data with proper transformations
- Admin payments page generates payment records from dues tracking data
- Created new /api/admin/users endpoint for Keycloak user management
- All stats cards now calculate from real data instead of hardcoded values
- Removed all mock/placeholder data arrays from production pages

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-08-31 18:43:04 +02:00
parent 1aef356d78
commit 70e79d2618
8 changed files with 601 additions and 508 deletions

View File

@@ -339,10 +339,10 @@ const membershipFilter = ref(null);
// Stats
const stats = ref({
total: 156,
active: 142,
newThisMonth: 8,
renewalDue: 23
total: 0,
active: 0,
newThisMonth: 0,
renewalDue: 0
});
// Form data
@@ -368,42 +368,8 @@ const headers = [
{ title: 'Actions', key: 'actions', sortable: false, align: 'end' }
];
// Mock data
const members = ref<Member[]>([
{
member_id: '1',
first_name: 'John',
last_name: 'Smith',
email: 'john.smith@example.com',
membership_type: 'Premium',
status: 'active',
dues_status: 'Paid',
join_date: '2023-01-15',
phone: '555-0100'
},
{
member_id: '2',
first_name: 'Sarah',
last_name: 'Johnson',
email: 'sarah.j@example.com',
membership_type: 'Standard',
status: 'active',
dues_status: 'Due',
join_date: '2023-03-22',
phone: '555-0101'
},
{
member_id: '3',
first_name: 'Michael',
last_name: 'Williams',
email: 'michael.w@example.com',
membership_type: 'VIP',
status: 'active',
dues_status: 'Paid',
join_date: '2022-11-08',
phone: '555-0102'
}
]);
// Real data from API
const members = ref<Member[]>([]);
// Computed
const filteredMembers = computed(() => {
@@ -496,12 +462,51 @@ const saveMember = () => {
showCreateDialog.value = false;
};
// Load real members data from API
const loadMembers = async () => {
loading.value = true;
try {
// Fetch members from API
const { data } = await $fetch('/api/members');
if (data?.members) {
// Transform the data to match our interface
members.value = data.members.map((member: any) => ({
member_id: member.Id || member.id,
first_name: member.first_name,
last_name: member.last_name,
email: member.email,
membership_type: member.membership_type || 'Standard',
status: member.membership_status === 'Active' ? 'active' : 'inactive',
dues_status: member.dues_status || 'Unknown',
join_date: member.member_since || member.created_at,
phone: member.phone_number || member.phone || ''
}));
// Calculate stats from real data
const now = new Date();
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
stats.value = {
total: members.value.length,
active: members.value.filter(m => m.status === 'active').length,
newThisMonth: members.value.filter(m => {
const joinDate = new Date(m.join_date);
return joinDate >= startOfMonth;
}).length,
renewalDue: members.value.filter(m => m.dues_status === 'Due' || m.dues_status === 'Overdue').length
};
}
} catch (error) {
console.error('Error loading members:', error);
// Keep empty array if load fails
} finally {
loading.value = false;
}
};
// Load data on mount
onMounted(async () => {
loading.value = true;
// Fetch members from API
setTimeout(() => {
loading.value = false;
}, 1000);
await loadMembers();
});
</script>