← back to Hub

app/api/grant/detail/route.ts

63 lines

import { NextRequest, NextResponse } from 'next/server';
import { verifyAuth } from '@/lib/auth';
import { query } from '@/lib/db';

export const dynamic = 'force-dynamic';

export async function GET(request: NextRequest) {
  const user = verifyAuth(request);
  if (!user) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  }

  try {
    const [
      totalGrants,
      grantsByStatus,
      proposalCount,
      newsCount,
      totalCollabs,
      collabsByType,
      totalFunding,
      upcomingDeadlines,
    ] = await Promise.all([
      query('grant', 'SELECT COUNT(*) as count FROM grants'),
      query('grant', 'SELECT status, COUNT(*) as count FROM grants GROUP BY status ORDER BY count DESC'),
      query('grant', 'SELECT COUNT(*) as count FROM grant_proposals'),
      query('grant', 'SELECT COUNT(*) as count FROM news_items'),
      query('grant', 'SELECT COUNT(*) as count FROM collaborations'),
      query('grant', 'SELECT collab_type, COUNT(*) as count FROM collaborations GROUP BY collab_type ORDER BY count DESC'),
      query('grant', 'SELECT COALESCE(SUM(amount_awarded), 0) as total FROM grants WHERE amount_awarded IS NOT NULL'),
      query('grant', `SELECT id, title, funder, deadline, status FROM grants WHERE deadline IS NOT NULL AND deadline > NOW() ORDER BY deadline ASC LIMIT 5`),
    ]);

    const byStatus: Record<string, number> = {};
    for (const row of grantsByStatus.rows) {
      byStatus[row.status] = parseInt(row.count);
    }

    const byType: Record<string, number> = {};
    for (const row of collabsByType.rows) {
      byType[row.collab_type] = parseInt(row.count);
    }

    return NextResponse.json({
      grants: {
        total: parseInt(totalGrants.rows[0].count),
        byStatus,
      },
      proposals: parseInt(proposalCount.rows[0].count),
      news: parseInt(newsCount.rows[0].count),
      collaborations: {
        total: parseInt(totalCollabs.rows[0].count),
        byType,
      },
      total_funding: parseFloat(totalFunding.rows[0].total) || 0,
      upcomingDeadlines: upcomingDeadlines.rows,
    });
  } catch (err) {
    console.error('[grant/detail] Error:', (err as Error).message);
    return NextResponse.json({ error: 'Failed to fetch Grant data' }, { status: 500 });
  }
}