import { NextResponse } from 'next/server'; // FastAPI server configuration const API_HOST = process.env.API_HOST || 'http://172.16.0.104:8000'; // Helper function to clean HTML content function cleanHtmlContent(content: string): string { if (!content) return ''; return content .replace(/<[^>]*>/g, '') .replace(/ /g, ' ') .replace(/&/g, '&') .replace(/"/g, '"') .replace(/'/g, "'") .trim(); } // Helper function to format time function formatDateTime(dateStr: string): { displayDate: string, timestamp: string } { try { const date = new Date(dateStr); const day = date.getDate(); const month = date.toLocaleString('fr-FR', { month: 'short' }).toLowerCase(); return { displayDate: `${day} ${month}.`, // Added dot for better styling timestamp: date.toLocaleString('fr-FR', { day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit', hour12: false }).replace(',', ' à') // Format: "14 avr. à 15:30" }; } catch (error) { return { displayDate: 'N/A', timestamp: 'N/A' }; } } // Helper function to truncate text function truncateText(text: string, maxLength: number): string { if (!text || text.length <= maxLength) return text; // Find the last space before maxLength to avoid cutting words const lastSpace = text.lastIndexOf(' ', maxLength); const truncated = text.substring(0, lastSpace > 0 ? lastSpace : maxLength).trim(); return truncated.replace(/[.,!?]$/, '') + '...'; } // Helper function to format category function formatCategory(category: string): string { if (!category) return 'GENERAL'; // Make category names shorter and more readable const categoryMap: { [key: string]: string } = { 'GLOBAL ISSUES - WORLD AFFAIRS': 'WORLD', 'UN NEWS - GLOBAL NEWS': 'UN NEWS', 'GLOBAL NEWS': 'WORLD', }; const normalizedCategory = category.toUpperCase(); return categoryMap[normalizedCategory] || normalizedCategory; } // Helper function to format source function formatSource(source: string): string { if (!source) return ''; // Extract domain name without TLD and clean it up const sourceName = source .replace(/^(https?:\/\/)?(www\.)?/i, '') .split('.')[0] .toLowerCase() .replace(/[^a-z0-9]/g, ' ') .trim(); return sourceName.charAt(0).toUpperCase() + sourceName.slice(1); } export async function GET() { try { console.log(`Fetching news from FastAPI server at ${API_HOST}...`); const response = await fetch(`${API_HOST}/news?limit=10`, { method: 'GET', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, cache: 'no-store', }); if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP error! status: ${response.status}, body: ${errorText}`); } const rawNews = await response.json(); // Format and clean the news data const formattedNews = rawNews.map((article: any) => { const { displayDate, timestamp } = formatDateTime(article.date); return { id: article.id, title: truncateText(cleanHtmlContent(article.title), 100), description: truncateText(cleanHtmlContent(article.description), 150), displayDate, timestamp, source: formatSource(article.source), category: formatCategory(article.category), url: article.url || '#', }; }); console.log(`Successfully fetched and formatted ${formattedNews.length} news articles`); return NextResponse.json(formattedNews); } catch (error) { console.error('Error in news API:', { error: error instanceof Error ? error.message : 'Unknown error', apiHost: API_HOST, stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString(), }); return NextResponse.json( { error: 'Failed to fetch news', details: error instanceof Error ? error.message : 'Unknown error', server: API_HOST, timestamp: new Date().toISOString(), }, { status: 500 } ); } }