Files
Kunst_Gegen_Bares_Kimaschine/src/features/event/api/eventService.ts
2026-01-05 16:03:44 +01:00

436 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
};