fixes
Build And Push Image / docker (push) Successful in 3m41s Details

This commit is contained in:
Matt 2025-08-13 15:35:53 +02:00
parent 62fb84d25e
commit db19eb2708
4 changed files with 95 additions and 34 deletions

View File

@ -92,10 +92,12 @@
placeholder="Select start date and time"
:enable-time-picker="true"
:is-24="true"
auto-apply
:auto-apply="false"
:action-row="{ showSelect: true, showCancel: true, showNow: false, showPreview: true }"
:clearable="false"
:required="true"
@update:model-value="handleStartDateUpdate"
@closed="onDatePickerClosed"
/>
</div>
</v-col>
@ -113,11 +115,13 @@
placeholder="Select end date and time"
:enable-time-picker="true"
:is-24="true"
auto-apply
:auto-apply="false"
:action-row="{ showSelect: true, showCancel: true, showNow: false, showPreview: true }"
:clearable="false"
:required="true"
:min-date="startDateModel"
@update:model-value="handleEndDateUpdate"
@closed="onDatePickerClosed"
/>
</div>
</v-col>
@ -487,6 +491,11 @@ const handleEndDateUpdate = (date: Date | null) => {
}
};
const onDatePickerClosed = () => {
console.log('[CreateEventDialog] Date picker closed');
// This handler ensures the date picker behaves correctly on mobile and desktop
};
// Methods
const resetForm = () => {
eventData.title = '';

View File

@ -170,7 +170,7 @@
<!-- Error Snackbar -->
<v-snackbar
v-model="showError"
v-model="showErrorSnackbar"
color="error"
:timeout="5000"
>
@ -178,7 +178,7 @@
<template #actions>
<v-btn
variant="text"
@click="showError = false"
@click="showErrorSnackbar = false"
>
Close
</v-btn>
@ -187,7 +187,7 @@
<!-- Success Snackbar -->
<v-snackbar
v-model="showSuccess"
v-model="showSuccessSnackbar"
color="success"
:timeout="3000"
>
@ -195,7 +195,7 @@
<template #actions>
<v-btn
variant="text"
@click="showSuccess = false"
@click="showSuccessSnackbar = false"
>
Close
</v-btn>
@ -244,8 +244,8 @@ const filters = reactive<EventFilters>({
});
// Notification state
const showError = ref(false);
const showSuccess = ref(false);
const showErrorSnackbar = ref(false);
const showSuccessSnackbar = ref(false);
const errorMessage = ref('');
const successMessage = ref('');
@ -378,35 +378,46 @@ const handleDateClick = (dateInfo: any) => {
// Debug: Log the date format being passed
console.log('[Events] Date clicked:', dateInfo);
// Ensure proper ISO format for datetime-local inputs
// Create proper ISO datetime strings (full format)
let formattedDate = '';
let formattedEndDate = '';
if (dateInfo.date) {
// Convert to local datetime-local format: YYYY-MM-DDTHH:mm
// Convert to proper Date object and set default time
const clickedDate = new Date(dateInfo.date);
// Set default time to 6 PM in the user's local timezone
clickedDate.setHours(18, 0, 0, 0); // Default to 6 PM
formattedDate = clickedDate.toISOString().slice(0, 16);
formattedDate = clickedDate.toISOString(); // Full ISO string
// Set end date 2 hours later if not provided
if (dateInfo.endDate) {
formattedEndDate = new Date(dateInfo.endDate).toISOString().slice(0, 16);
const endDate = new Date(dateInfo.endDate);
endDate.setHours(20, 0, 0, 0); // Default to 8 PM for end date
formattedEndDate = endDate.toISOString();
} else {
const endDate = new Date(clickedDate);
endDate.setHours(20, 0, 0, 0); // Default to 8 PM
formattedEndDate = endDate.toISOString().slice(0, 16);
endDate.setHours(20, 0, 0, 0); // Default to 8 PM (2 hours later)
formattedEndDate = endDate.toISOString();
}
}
prefilledDate.value = formattedDate;
prefilledEndDate.value = formattedEndDate;
// Clear previous values first to trigger watchers properly
prefilledDate.value = '';
prefilledEndDate.value = '';
console.log('[Events] Prefilled dates:', {
date: formattedDate,
endDate: formattedEndDate
// Set new values
nextTick(() => {
prefilledDate.value = formattedDate;
prefilledEndDate.value = formattedEndDate;
console.log('[Events] Prefilled dates set:', {
date: formattedDate,
endDate: formattedEndDate
});
showCreateDialog.value = true;
});
showCreateDialog.value = true;
}
};
@ -482,12 +493,12 @@ const subscribeCalendar = async () => {
const showErrorMessage = (message: string) => {
errorMessage.value = message;
showError.value = true;
showErrorSnackbar.value = true;
};
const showSuccessMessage = (message: string) => {
successMessage.value = message;
showSuccess.value = true;
showSuccessSnackbar.value = true;
};
// Lifecycle

View File

@ -34,6 +34,14 @@ export default defineEventHandler(async (event) => {
console.log('[api/events.get] ✅ Valid session found for user:', session.user.email);
console.log('[api/events.get] User tier:', session.user.tier);
// Get member record to find the member_id needed for RSVP lookup
const { getMemberByKeycloakId } = await import('~/server/utils/nocodb');
const member = await getMemberByKeycloakId(session.user.id);
const memberIdentifier = member?.member_id || member?.Id || session.user.id;
console.log('[api/events.get] Using member identifier for RSVP lookup:', memberIdentifier);
console.log('[api/events.get] Member details:', { member_id: member?.member_id, database_id: member?.Id });
const eventsClient = createNocoDBEventsClient();
// Build filters with user role
@ -56,8 +64,8 @@ export default defineEventHandler(async (event) => {
console.log('[api/events.get] Fetching events with filters:', filters);
// Get events from database
const response = await eventsClient.findUserEvents(session.user.id, filters);
// Get events from database using the member identifier (not Keycloak ID)
const response = await eventsClient.findUserEvents(memberIdentifier, filters);
console.log('[api/events.get] ✅ Successfully fetched', response.list.length, 'events');

View File

@ -412,28 +412,61 @@ export function createNocoDBEventsClient() {
},
/**
* Get events for a specific user (simplified version)
* Get events for a specific user with RSVP status loaded
*/
async findUserEvents(memberId: string, filters?: EventFilters) {
console.log('[nocodb-events] Finding events for member:', memberId);
try {
// For now, just get all visible events using the working findAll method
// Remove complex filtering temporarily to fix the 422 errors
// First get all events using the working findAll method
const simpleFilters = {
status: filters?.status,
limit: (filters as any)?.limit,
offset: (filters as any)?.offset
};
console.log('[nocodb-events] Using simplified filters to avoid 422 errors:', simpleFilters);
const events = await this.findAll(simpleFilters);
console.log('[nocodb-events] Using simplified filters:', simpleFilters);
const eventsResponse = await this.findAll(simpleFilters);
if (!eventsResponse.list || eventsResponse.list.length === 0) {
console.log('[nocodb-events] No events found');
return eventsResponse;
}
console.log('[nocodb-events] Found', eventsResponse.list.length, 'events, now loading RSVPs for member:', memberId);
// Load RSVPs for each event for this user
const eventsWithRSVPs = await Promise.all(
eventsResponse.list.map(async (event) => {
try {
// Use event_id if available, otherwise fall back to database Id
const eventIdentifier = event.event_id || event.id || (event as any).Id;
console.log('[nocodb-events] Loading RSVP for event:', event.title, 'identifier:', eventIdentifier);
const userRSVP = await this.findUserRSVP(eventIdentifier, memberId);
if (userRSVP) {
console.log('[nocodb-events] ✅ Found RSVP for event', event.title, ':', userRSVP.rsvp_status);
return {
...event,
user_rsvp: userRSVP
};
} else {
console.log('[nocodb-events] No RSVP found for event:', event.title);
return event;
}
} catch (rsvpError) {
console.log('[nocodb-events] ⚠️ Error loading RSVP for event', event.title, ':', rsvpError);
return event; // Return event without RSVP if lookup fails
}
})
);
console.log('[nocodb-events] ✅ Loaded RSVPs for all events');
// TODO: Add RSVP lookup from separate table
// For now, return events without RSVP status
return {
list: events.list || [],
PageInfo: events.PageInfo
list: eventsWithRSVPs,
PageInfo: eventsResponse.PageInfo
};
} catch (error: any) {
console.error('[nocodb-events] Error finding user events:', error);