diff --git a/app/api/news/route.ts b/app/api/news/route.ts index 4520147..47a4a00 100644 --- a/app/api/news/route.ts +++ b/app/api/news/route.ts @@ -1,7 +1,7 @@ import { NextResponse } from 'next/server'; -// FastAPI server configuration -const API_HOST = process.env.API_HOST || 'http://172.16.0.104:8000'; +// FastAPI server configuration - use localhost since both servers are on the same machine +const API_HOST = process.env.API_HOST || 'http://localhost:8000'; // Helper function to clean HTML content function cleanHtmlContent(content: string): string { @@ -16,22 +16,24 @@ function cleanHtmlContent(content: string): string { } // Helper function to format time -function formatDateTime(dateStr: string): { date: string, time: string } { +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 { - date: date.toLocaleDateString('fr-FR', { - day: 'numeric', - month: 'short' - }), - time: date.toLocaleTimeString('fr-FR', { + displayDate: `${day} ${month}`, + timestamp: date.toLocaleString('fr-FR', { + day: '2-digit', + month: 'short', hour: '2-digit', minute: '2-digit', hour12: false }) }; } catch (error) { - return { date: 'N/A', time: 'N/A' }; + return { displayDate: 'N/A', timestamp: 'N/A' }; } } @@ -42,16 +44,36 @@ function truncateText(text: string, maxLength: number): string { return truncated.replace(/[.,!?]$/, '') + '...'; } +// Helper function to format category +function formatCategory(category: string): string { + if (!category) return 'GENERAL'; + // Simplify long category names + return category + .split('-') + .map(part => part.trim().toUpperCase()) + .join(' - '); +} + // Helper function to format source function formatSource(source: string): string { if (!source) return ''; - return source.replace(/^(https?:\/\/)?(www\.)?/i, '').split('.')[0].toLowerCase(); + // 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}...`); + console.log(`Attempting to connect to FastAPI server at ${API_HOST}...`); + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 5000); + const response = await fetch(`${API_HOST}/news?limit=10`, { method: 'GET', headers: { @@ -59,8 +81,12 @@ export async function GET() { 'Accept': 'application/json', }, cache: 'no-store', + signal: controller.signal, + keepalive: true, }); + clearTimeout(timeoutId); + if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP error! status: ${response.status}, body: ${errorText}`); @@ -70,15 +96,15 @@ export async function GET() { // Format and clean the news data const formattedNews = rawNews.map((article: any) => { - const { date, time } = formatDateTime(article.date); + const { displayDate, timestamp } = formatDateTime(article.date); return { id: article.id, title: truncateText(cleanHtmlContent(article.title), 100), description: truncateText(cleanHtmlContent(article.description), 150), - date, - time, + displayDate, + timestamp, source: formatSource(article.source), - category: (article.category || 'GENERAL').toUpperCase(), + category: formatCategory(article.category), url: article.url || '#', }; });