widget news fetch 4

This commit is contained in:
Alma 2025-04-13 22:38:19 +02:00
parent 5453b7ef15
commit f099cf0d6c
2 changed files with 74 additions and 93 deletions

View File

@ -1,11 +1,19 @@
import { NextResponse } from 'next/server';
import { Pool } from 'pg';
// Function to clean database host URL
function cleanDatabaseHost(host: string | undefined): string {
if (!host) {
throw new Error('Database host is not defined');
}
return host.replace(/^https?:\/\//, '');
}
// Create a new pool using the environment variables
const pool = new Pool({
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
host: process.env.DB_HOST?.replace('@https://', ''),
host: cleanDatabaseHost(process.env.DB_HOST),
database: process.env.DB_NAME,
ssl: {
rejectUnauthorized: false // Required for some cloud databases
@ -14,11 +22,21 @@ const pool = new Pool({
export async function GET() {
try {
// Log connection attempt
console.log('Attempting database connection with config:', {
user: process.env.DB_USER,
host: process.env.DB_HOST,
database: process.env.DB_NAME,
hasPassword: !!process.env.DB_PASSWORD
});
// Connect to the database
const client = await pool.connect();
console.log('Successfully connected to database');
try {
// Query the news table for the latest 10 news items
console.log('Executing news query...');
const result = await client.query(`
SELECT
id,
@ -37,6 +55,8 @@ export async function GET() {
LIMIT 10
`);
console.log(`Query completed. Found ${result.rows.length} news items.`);
// Format the response
const news = result.rows.map(row => ({
id: row.id,
@ -55,14 +75,34 @@ export async function GET() {
}));
return NextResponse.json({ news });
} catch (queryError: any) {
console.error('Query error:', queryError);
return NextResponse.json(
{ error: 'Database query failed: ' + (queryError?.message || 'Unknown error') },
{ status: 500 }
);
} finally {
// Release the client back to the pool
client.release();
console.log('Database client released');
}
} catch (error) {
} catch (error: any) {
console.error('Database connection error:', error);
// Check if error is due to missing configuration
if (!process.env.DB_USER || !process.env.DB_PASSWORD || !process.env.DB_HOST || !process.env.DB_NAME) {
console.error('Missing database configuration:', {
hasUser: !!process.env.DB_USER,
hasPassword: !!process.env.DB_PASSWORD,
hasHost: !!process.env.DB_HOST,
hasDatabase: !!process.env.DB_NAME
});
return NextResponse.json(
{ error: 'Database configuration is incomplete' },
{ status: 500 }
);
}
return NextResponse.json(
{ error: 'Failed to fetch news' },
{ error: 'Failed to connect to database: ' + (error?.message || 'Unknown error') },
{ status: 500 }
);
}

View File

@ -24,95 +24,54 @@ interface NewsItem {
symbol: string | null;
}
// Mock data for testing - remove this in production
const MOCK_NEWS = [
{
id: 1,
title: "New Project Management Features Released",
url: "#",
date: "2024-03-20",
source: "Internal",
description: "New features added to improve project management workflow",
category: "Update",
sentiment: { score: null, label: null },
symbols: null,
symbol: null
},
{
id: 2,
title: "Team Meeting Schedule Changes",
url: "#",
date: "2024-03-19",
source: "Internal",
description: "Updates to the team meeting schedule",
category: "Announcement",
sentiment: { score: null, label: null },
symbols: null,
symbol: null
},
{
id: 3,
title: "Upcoming Training Sessions",
url: "#",
date: "2024-03-18",
source: "Internal",
description: "Schedule for upcoming training sessions",
category: "Training",
sentiment: { score: null, label: null },
symbols: null,
symbol: null
}
];
export function News() {
console.log('News component mounted');
const [news, setNews] = useState<NewsItem[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [refreshing, setRefreshing] = useState(false);
const [dbStatus, setDbStatus] = useState<'connecting' | 'connected' | 'error'>('connecting');
// Debug info display component
const DebugInfo = () => (
<div className="text-xs text-gray-500 mt-2 p-2 bg-gray-100 rounded">
<p>Status: {dbStatus}</p>
<p>Loading: {loading ? 'true' : 'false'}</p>
<p>Error: {error || 'none'}</p>
<p>News items: {news.length}</p>
</div>
);
const fetchNews = async (isRefresh = false) => {
console.log('Fetching news...');
if (isRefresh) setRefreshing(true);
setLoading(true);
setDbStatus('connecting');
try {
console.log('Making API request to /api/news');
const response = await fetch('/api/news');
console.log('API response status:', response.status);
const response = await fetch('/api/news', {
method: 'GET',
headers: {
'Accept': 'application/json',
},
});
if (!response.ok) {
console.log('API request failed');
throw new Error('Failed to fetch news');
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log('API response data:', data);
if (data.error) {
console.log('API returned error:', data.error);
throw new Error(data.error);
}
// If no news items returned, use mock data for testing
if (!data.news || data.news.length === 0) {
console.log('No news items returned, using mock data');
setNews(MOCK_NEWS);
} else {
console.log('Setting news items from API');
setNews(data.news);
}
setNews(data.news || []);
setError(null);
setDbStatus('connected');
} catch (err) {
console.error('Error details:', err);
setError('Failed to load news. Please try again later.');
const errorMessage = err instanceof Error ? err.message : 'Failed to load news';
setError(errorMessage);
setDbStatus('error');
console.log('Using mock data due to error');
setNews(MOCK_NEWS);
setNews([]);
} finally {
setLoading(false);
setRefreshing(false);
@ -136,33 +95,7 @@ export function News() {
{dbStatus === 'connecting' ? 'Connecting to database...' : 'Loading news...'}
</p>
</div>
</CardContent>
</Card>
);
}
if (error) {
return (
<Card className="w-full">
<CardHeader className="flex flex-row items-center justify-between">
<CardTitle>News</CardTitle>
<Button
variant="ghost"
size="icon"
onClick={() => fetchNews(true)}
disabled={refreshing}
className={`${refreshing ? 'animate-spin' : ''}`}
>
<RefreshCw className="h-4 w-4" />
</Button>
</CardHeader>
<CardContent>
<div className="text-red-500 space-y-2">
<p>{error}</p>
<p className="text-sm text-gray-500">
{dbStatus === 'error' ? 'Database connection error' : 'Failed to fetch news'}
</p>
</div>
<DebugInfo />
</CardContent>
</Card>
);
@ -184,7 +117,14 @@ export function News() {
</CardHeader>
<CardContent>
<div className="space-y-4">
{news.length === 0 ? (
{error ? (
<div className="text-red-500 space-y-2">
<p>{error}</p>
<p className="text-sm text-gray-500">
{dbStatus === 'error' ? 'Database connection error' : 'Failed to fetch news'}
</p>
</div>
) : news.length === 0 ? (
<div className="text-center text-gray-500 py-8">
No news available
</div>
@ -238,6 +178,7 @@ export function News() {
))
)}
</div>
<DebugInfo />
</CardContent>
</Card>
);