Fix RSVP API calls and compact MemberCard UI design
Build And Push Image / docker (push) Successful in 4m2s Details

This commit is contained in:
Matt 2025-08-13 14:02:29 +02:00
parent d215dfedc7
commit 3620bd8b53
5 changed files with 92 additions and 84 deletions

View File

@ -452,7 +452,11 @@ const submitRSVP = async (status: 'confirmed' | 'declined') => {
rsvpLoading.value = true; rsvpLoading.value = true;
try { try {
await rsvpToEvent(props.event.id, { // Use the database ID for RSVP API calls
const databaseId = (props.event as any).extendedProps?.database_id || props.event.id;
console.log('[EventDetailsDialog] Using database ID for RSVP:', databaseId, 'from event:', props.event);
await rsvpToEvent(databaseId, {
member_id: '', // This will be filled by the composable member_id: '', // This will be filled by the composable
rsvp_status: status, rsvp_status: status,
rsvp_notes: rsvpNotes.value rsvp_notes: rsvpNotes.value

View File

@ -60,20 +60,20 @@
</div> </div>
<!-- Card Content --> <!-- Card Content -->
<v-card-text class="pb-4"> <v-card-text class="pb-4 pt-3">
<div class="d-flex align-center mb-3"> <div class="d-flex align-center mb-2">
<v-avatar <v-avatar
:color="avatarColor" :color="avatarColor"
size="48" size="40"
class="mr-3" class="mr-3"
> >
<span class="text-white font-weight-bold text-h6"> <span class="text-white font-weight-bold">
{{ memberInitials }} {{ memberInitials }}
</span> </span>
</v-avatar> </v-avatar>
<div class="flex-grow-1"> <div class="flex-grow-1">
<h3 class="text-h6 font-weight-bold mb-1"> <h3 class="text-subtitle-1 font-weight-bold mb-1">
{{ member.FullName || `${member.first_name} ${member.last_name}` }} {{ member.FullName || `${member.first_name} ${member.last_name}` }}
</h3> </h3>
<div class="nationality-display"> <div class="nationality-display">
@ -92,14 +92,14 @@
</div> </div>
<!-- Display country names --> <!-- Display country names -->
<div class="country-names"> <div class="country-names">
<span class="text-body-2 text-medium-emphasis"> <span class="text-caption text-medium-emphasis">
{{ nationalitiesArray.map(n => getCountryName(n)).join(', ') }} {{ nationalitiesArray.map(n => getCountryName(n)).join(', ') }}
</span> </span>
</div> </div>
</div> </div>
</template> </template>
<template v-else> <template v-else>
<span class="text-body-2 text-medium-emphasis"> <span class="text-caption text-medium-emphasis">
Unknown Unknown
</span> </span>
</template> </template>
@ -107,83 +107,81 @@
</div> </div>
</div> </div>
<!-- Member Info --> <!-- Member Info - More Compact -->
<div class="member-info"> <div class="member-info mb-2">
<div class="info-row mb-2"> <div class="info-row mb-1" v-if="member.email">
<v-icon size="16" class="mr-2 text-medium-emphasis">mdi-email</v-icon> <v-icon size="14" class="mr-2 text-medium-emphasis">mdi-email</v-icon>
<span class="text-body-2">{{ member.email || 'No email' }}</span> <span class="text-caption">{{ member.email }}</span>
</div> </div>
<div class="info-row mb-2" v-if="member.phone"> <div class="info-row mb-1" v-if="member.phone">
<v-icon size="16" class="mr-2 text-medium-emphasis">mdi-phone</v-icon> <v-icon size="14" class="mr-2 text-medium-emphasis">mdi-phone</v-icon>
<span class="text-body-2">{{ member.FormattedPhone || member.phone }}</span> <span class="text-caption">{{ member.FormattedPhone || member.phone }}</span>
</div> </div>
<div class="info-row mb-2" v-if="member.member_since"> <div class="info-row mb-1" v-if="member.member_since">
<v-icon size="16" class="mr-2 text-medium-emphasis">mdi-calendar</v-icon> <v-icon size="14" class="mr-2 text-medium-emphasis">mdi-calendar</v-icon>
<span class="text-body-2">Member since {{ formatDate(member.member_since) }}</span> <span class="text-caption">Since {{ formatDate(member.member_since) }}</span>
</div> </div>
</div> </div>
<!-- Dues Status --> <!-- Status Section - Reorganized -->
<div class="dues-status mt-3"> <div class="status-section">
<v-chip <!-- Primary Status (Dues) -->
:color="duesColor" <div class="d-flex align-center justify-space-between mb-2">
:variant="duesVariant" <v-chip
size="small" :color="duesColor"
class="mr-2" :variant="duesVariant"
> size="small"
<v-icon start size="14">{{ duesIcon }}</v-icon> class="flex-grow-1 mr-1"
{{ duesText }} >
</v-chip> <v-icon start size="12">{{ duesIcon }}</v-icon>
{{ duesText }}
</v-chip>
<!-- Portal Status - Compact -->
<v-tooltip
:text="member.keycloak_id ? 'Portal Account Active' : 'No Portal Account'"
location="top"
>
<template #activator="{ props }">
<v-chip
v-bind="props"
:color="member.keycloak_id ? 'success' : 'grey'"
variant="tonal"
size="x-small"
class="ml-1"
>
<v-icon size="12">{{ member.keycloak_id ? 'mdi-account-check' : 'mdi-account-off' }}</v-icon>
</v-chip>
</template>
</v-tooltip>
</div>
<!-- Dues Coming Due Warning --> <!-- Secondary Status (Due Dates) - Only show if relevant -->
<v-chip <div v-if="isDuesComingDue || (member.payment_due_date && !isDuesComingDue && isOverdue)" class="d-flex">
v-if="isDuesComingDue" <v-chip
color="orange" v-if="isDuesComingDue"
variant="flat" color="orange"
size="small" variant="flat"
class="mr-2" size="x-small"
> class="flex-grow-1"
<v-icon start size="14">mdi-clock-alert</v-icon> >
Due {{ formatDate(nextDuesDate) }} <v-icon start size="10">mdi-clock-alert</v-icon>
</v-chip> Due {{ formatDate(nextDuesDate) }}
</v-chip>
<v-chip
v-if="member.payment_due_date && !isDuesComingDue" <v-chip
color="warning" v-else-if="member.payment_due_date && !isDuesComingDue && isOverdue"
variant="tonal" color="error"
size="small" variant="flat"
:class="{ 'text-error': isOverdue }" size="x-small"
> class="flex-grow-1"
<v-icon start size="14">mdi-calendar-alert</v-icon> >
{{ isOverdue ? 'Overdue' : `Due ${formatDate(member.payment_due_date)}` }} <v-icon start size="10">mdi-calendar-alert</v-icon>
</v-chip> Overdue
</div> </v-chip>
</div>
<!-- Portal Account Status -->
<div class="portal-status mt-3">
<v-chip
v-if="member.keycloak_id"
color="success"
variant="tonal"
size="small"
class="mr-2"
>
<v-icon start size="14">mdi-account-check</v-icon>
Portal Account Active
</v-chip>
<v-chip
v-else
color="grey"
variant="tonal"
size="small"
class="mr-2"
>
<v-icon start size="14">mdi-account-off</v-icon>
No Portal Account
</v-chip>
</div> </div>
</v-card-text> </v-card-text>
@ -481,7 +479,7 @@ const formatDate = (dateString: string): string => {
} }
.member-info { .member-info {
min-height: 80px; min-height: 60px;
} }
.info-row { .info-row {

View File

@ -123,8 +123,13 @@ export const useEvents = () => {
}); });
if (response.success) { if (response.success) {
// Update local event data // Update local event data - match by database ID (stored in Id field or as fallback)
const eventIndex = events.value.findIndex(e => e.id === eventId); const eventIndex = events.value.findIndex(e =>
(e as any).Id === eventId || e.id === eventId
);
console.log('[useEvents] Looking for event with database ID:', eventId, 'found at index:', eventIndex);
if (eventIndex !== -1) { if (eventIndex !== -1) {
events.value[eventIndex].user_rsvp = response.data; events.value[eventIndex].user_rsvp = response.data;

View File

@ -180,7 +180,7 @@
<!-- Dues Payment Banner --> <!-- Dues Payment Banner -->
<DuesPaymentBanner /> <DuesPaymentBanner />
<v-container fluid class="pa-0"> <v-container fluid>
<slot /> <slot />
</v-container> </v-container>
</v-main> </v-main>

View File

@ -1,5 +1,5 @@
<template> <template>
<v-container fluid> <v-container fluid class="pa-4">
<!-- Dues Payment Banner --> <!-- Dues Payment Banner -->
<DuesPaymentBanner /> <DuesPaymentBanner />
@ -146,8 +146,9 @@
:key="member.Id" :key="member.Id"
cols="12" cols="12"
sm="6" sm="6"
md="4" md="6"
lg="3" lg="4"
xl="3"
> >
<MemberCard <MemberCard
:member="member" :member="member"