/** * Directus API Client (REST-based, no SDK dependencies) */ const DIRECTUS_URL = process.env.DIRECTUS_URL || 'https://cms.dk0.dev'; const DIRECTUS_TOKEN = process.env.DIRECTUS_STATIC_TOKEN || ''; // Mapping: next-intl locale → Directus language code const localeToDirectus: Record = { en: 'en-US', de: 'de-DE', }; function toDirectusLocale(locale: string): string { return localeToDirectus[locale] || locale; } interface FetchOptions { method?: 'GET' | 'POST' | 'PATCH' | 'DELETE'; body?: any; } async function directusRequest( endpoint: string, options: FetchOptions = {} ): Promise { // Wenn kein Token gesetzt, skip Directus (nutze JSON fallback) if (!DIRECTUS_TOKEN || DIRECTUS_TOKEN === '') { return null; } const url = `${DIRECTUS_URL}/graphql`; try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${DIRECTUS_TOKEN}`, }, body: JSON.stringify(options.body || {}), // Timeout nach 2 Sekunden signal: AbortSignal.timeout(2000), }); if (!response.ok) { // Collection noch nicht erstellt? Stille fallback zu JSON const text = await response.text(); if (text.includes('GRAPHQL_VALIDATION') || text.includes('Cannot query field')) { // Stille: Collection existiert noch nicht return null; } console.error(`Directus error: ${response.status}`, text); return null; } const data = await response.json(); // Prüfe auf GraphQL errors if (data?.errors) { // Stille: Collection noch nicht ready return null; } return data?.data || null; } catch (error: any) { // Timeout oder Network Error - stille fallback if (error?.name === 'TimeoutError' || error?.name === 'AbortError') { return null; } // Andere Errors nur in dev loggen if (process.env.NODE_ENV === 'development') { console.error('Directus request failed:', error); } return null; } } export async function getMessage(key: string, locale: string): Promise { const directusLocale = toDirectusLocale(locale); // GraphQL Query für Directus Native Translations // Hole alle translations, filter client-side da GraphQL filter komplex ist const query = ` query { messages(filter: {key: {_eq: "${key}"}}, limit: 1) { key translations { value languages_code { code } } } } `; try { const result = await directusRequest( '', { body: { query } } ); const messages = (result as any)?.messages; if (!messages || messages.length === 0) { return null; } // Hole die Translation für die gewünschte Locale (client-side filter) const translations = messages[0]?.translations || []; const translation = translations.find((t: any) => t.languages_code?.code === directusLocale ); return translation?.value || null; } catch (error) { console.error(`Failed to fetch message ${key} (${locale}):`, error); return null; } } export async function getContentPage( slug: string, locale: string ): Promise { const directusLocale = toDirectusLocale(locale); const query = ` query { content_pages(filter: {slug: {_eq: "${slug}"}, locale: {_eq: "${directusLocale}"}}, limit: 1) { id slug locale title content } } `; try { const result = await directusRequest( '', { body: { query } } ); const pages = (result as any)?.content_pages; return pages?.[0] || null; } catch (error) { console.error(`Failed to fetch content page ${slug} (${locale}):`, error); return null; } }