first commit

This commit is contained in:
martin
2026-01-05 16:03:44 +01:00
commit 9805c18dd5
223 changed files with 24265 additions and 0 deletions

View File

@@ -0,0 +1,435 @@
import { getWebhookUrl } from '@/lib/config';
export interface Event {
id?: string | number;
user_id?: number;
name?: string;
title?: string; // neuer Titel-Name vom Timeline-Endpoint
description?: string;
location?: string;
url?: string;
image?: string;
manager_name?: string;
manager_email?: string;
guests?: any;
begin_date?: string; // ISO date string (YYYY-MM-DD)
end_date?: string; // ISO date string (YYYY-MM-DD)
eventDate?: string; // ISO date string (YYYY-MM-DD) vom Timeline-Endpoint (camelCase)
event_date?: string; // ISO date string (YYYY-MM-DD) direkt aus SQL-Query
status?: 'PENDING' | 'ON_AIR'; // aggregierter Status für Timeline
overall_status?: 'PENDING' | 'ON_AIR'; // Alias-Name aus SQL-Query
creation_date?: number;
last_update?: number;
}
// Payload-Struktur für den neuen Event-Endpunkt
interface CreateEventPayload {
title: string;
description?: string;
eventDate: string; // YYYY-MM-DD
promotionStartDate?: string; // YYYY-MM-DD
coverMediaUrl?: string;
ticketUrl?: string;
admissionTimes?: string;
ticketPrice?: string;
promotionSlots: Array<{
slotIndex: number;
slotType: 'EVENT_MAIN' | 'ARTIST';
promoDate: string; // YYYY-MM-DD
artistName?: string;
artistInstagram?: string;
}>;
}
export interface EventDetail extends CreateEventPayload {
id: string | number;
}
export const createEvent = async (payload: CreateEventPayload): Promise<any> => {
try {
const { apiFetch } = await import('@/utils/apiFetch');
const response = await apiFetch(`${getWebhookUrl()}/events/new`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
return result;
} catch (error) {
console.error('Error creating event manually:', error);
throw error;
}
};
export interface ArtistCollabUpdateByOpPayload {
eventId: string | number;
slotId?: string | number;
slotIndex?: number;
artistDescription?: string;
artistInstagram?: string;
artistFacebook?: string;
artistLinkedin?: string;
artistTiktok?: string;
artistYoutube?: string;
}
export const updateArtistCollabDataByOp = async (
payload: ArtistCollabUpdateByOpPayload
): Promise<{ success: boolean; message?: string }> => {
try {
const { apiFetch } = await import('@/utils/apiFetch');
const response = await apiFetch(`${getWebhookUrl()}/events/update_artist_data_byop`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const raw = await response.json();
const data = Array.isArray(raw) ? raw[0] ?? {} : raw ?? {};
return {
success: data.success !== false,
message: data.message,
};
} catch (error) {
console.error('Error updating artist collab data by op:', error);
return { success: false, message: error instanceof Error ? error.message : 'Unknown error' };
}
};
export const getEventInfoFromUrl = async (url: string): Promise<any> => {
try {
const { apiFetch } = await import('@/utils/apiFetch');
const response = await apiFetch(`${getWebhookUrl()}/events/getinfofromurl`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ url }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Error getting event info from URL:', error);
throw error;
}
};
export const fetchCurrentEvents = async (apiFetch: Function): Promise<Event[]> => {
const webhookUrl = `${getWebhookUrl()}/events/get_current`;
try {
const response = await apiFetch(webhookUrl, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
});
if (!response.ok) throw new Error('Failed to fetch events');
const raw = await response.json();
// n8n kann die Liste ggf. als String-JSON zurückgeben
const data =
typeof raw === 'string'
? (() => {
try {
return JSON.parse(raw);
} catch {
return raw;
}
})()
: raw;
return Array.isArray(data) ? data : data ? [data] : [];
} catch (error) {
console.error('Error fetching events:', error);
throw error;
}
}
export interface ArtistCollabUpdatePayload {
token: string;
slotId?: string | number;
eventId?: string | number;
artistDescription?: string;
artistInstagram?: string;
artistFacebook?: string;
artistLinkedin?: string;
artistTiktok?: string;
artistYoutube?: string;
}
export const updateArtistCollabData = async (
payload: ArtistCollabUpdatePayload
): Promise<{ success: boolean; message?: string }> => {
try {
const { apiFetch } = await import('@/utils/apiFetch');
const response = await apiFetch(`${getWebhookUrl()}/events/update_artist_data`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const raw = await response.json();
const data = Array.isArray(raw) ? raw[0] ?? {} : raw ?? {};
return {
success: data.success !== false,
message: data.message,
};
} catch (error) {
console.error('Error updating artist collab data:', error);
return { success: false, message: error instanceof Error ? error.message : 'Unknown error' };
}
};
export const fetchEventById = async (
apiFetch: Function,
id: string | number
): Promise<EventDetail> => {
const webhookUrl = `${getWebhookUrl()}/events/getbyid?id=${id}`;
const response = await apiFetch(webhookUrl, {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
});
if (!response.ok) throw new Error('Failed to fetch event');
const raw = await response.json();
// n8n kann entweder ein Objekt, ein Array mit einem Objekt
// oder einen JSON-String zurückgeben hier alles abfangen.
const data =
typeof raw === 'string'
? (() => {
try {
return JSON.parse(raw);
} catch {
return raw;
}
})()
: raw;
if (Array.isArray(data)) {
return (data[0] || {}) as EventDetail;
}
return data as EventDetail;
};
export const updateEvent = async (
id: string | number,
payload: CreateEventPayload
): Promise<any> => {
try {
const { apiFetch } = await import('@/utils/apiFetch');
const response = await apiFetch(`${getWebhookUrl()}/events/update`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ id, ...payload }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
return result;
} catch (error) {
console.error('Error updating event:', error);
throw error;
}
};
export const fetchEvents = async (apiFetch: Function): Promise<Event[]> => {
const webhookUrl = `${getWebhookUrl()}/events`;
try {
const response = await apiFetch(webhookUrl, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
});
if (!response.ok) throw new Error('Failed to fetch events');
const data = await response.json();
return Array.isArray(data) ? data : data ? [data] : [];
} catch (error) {
console.error('Error fetching events:', error);
throw error;
}
}
export const createEventFromUrl = async (url: string): Promise<any> => {
try {
const { apiFetch } = await import('@/utils/apiFetch');
const response = await apiFetch(`${getWebhookUrl()}/event/new_fromurl`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
url,
command: 'eventmodus_extract_from_url'
}),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.message_from_ai || data;
} catch (error) {
console.error('Error creating event from URL:', error);
throw error;
}
};
// Helper function to format dates to YYYY-MM-DD
export const formatDateForInput = (dateString: string): string => {
if (!dateString) return '';
const date = new Date(dateString);
return date.toISOString().split('T')[0];
};
export interface CollabLinkResponse {
token: string;
url?: string;
[key: string]: any;
}
export const generateCollabLink = async (
eventId: string | number,
slotIndex: number,
artistName?: string,
artistInstagram?: string
): Promise<CollabLinkResponse> => {
try {
const { apiFetch } = await import('@/utils/apiFetch');
const response = await apiFetch(`${getWebhookUrl()}/events/generate_collab_link`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ eventId, slotIndex, artistName, artistInstagram }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = (await response.json()) as CollabLinkResponse;
return data;
} catch (error) {
console.error('Error generating collaboration link:', error);
throw error;
}
};
export interface CollabMediaItem {
id: string;
url: string;
type?: string;
}
export interface CollabInfo {
eventTitle: string;
promoDate?: string;
artistName?: string;
artistDescription?: string;
artistMediaUrl?: string;
artistInstagram?: string;
slotId?: string | number;
eventId?: string | number;
media?: CollabMediaItem[];
}
export const fetchArtistSlotByToken = async (token: string): Promise<CollabInfo | null> => {
try {
const { apiFetch } = await import('@/utils/apiFetch');
const response = await apiFetch(`${getWebhookUrl()}/events/slots/getartistsslot`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ token }),
});
if (response.status === 401 || response.status === 403 || response.status === 404) {
// Token ungültig, abgelaufen oder Slot nicht gefunden
return null;
}
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const raw = await response.json();
const data: any = (() => {
if (!raw) return null;
if (Array.isArray(raw)) return raw[0] ?? null;
if (typeof raw === 'string') {
try {
const parsed = JSON.parse(raw);
return Array.isArray(parsed) ? parsed[0] ?? null : parsed;
} catch {
return null;
}
}
return raw as any;
})();
if (!data) return null;
return {
eventTitle: data.eventTitle ?? data.event_title ?? data.title ?? '',
promoDate: data.promoDate ?? data.promo_date,
artistName: data.artistName ?? data.artist_name,
artistDescription: data.artistDescription ?? data.artist_description,
artistMediaUrl: data.artistMediaUrl ?? data.artist_media_url,
artistInstagram: data.artistInstagram ?? data.artist_instagram,
slotId: data.id ?? data.slot_id,
eventId: data.event_id ?? data.eventId,
media: Array.isArray(data.media)
? data.media.map((m: any) => ({
id: String(m.id),
url: m.url || m.file_url,
type: m.type || m.file_type,
}))
: [],
};
} catch (error) {
console.error('Error fetching artist slot by token:', error);
throw error;
}
};