widget news fetch 4
This commit is contained in:
parent
5453b7ef15
commit
f099cf0d6c
@ -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 }
|
||||
);
|
||||
}
|
||||
|
||||
@ -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>
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user