← back to Hub

app/api/dashboard/route.ts

112 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 {
    // Query all 4 databases in parallel
    const [sdccData, grantData, pattyData, freddyData] = await Promise.all([
      // SDCC
      Promise.all([
        query('sdcc', 'SELECT COUNT(*) as count FROM drafts'),
        query('sdcc', 'SELECT COUNT(*) as count FROM news_items'),
        query('sdcc', 'SELECT COUNT(*) as count FROM petitions'),
        query('sdcc', 'SELECT COUNT(*) as count FROM collaborations'),
        query('sdcc', 'SELECT COUNT(*) as count FROM partners'),
        query('sdcc', 'SELECT COUNT(*) as count FROM old_leads'),
        query('sdcc', 'SELECT COUNT(*) as count FROM library_items'),
      ]),
      // Grant
      Promise.all([
        query('grant', 'SELECT COUNT(*) as count FROM grants'),
        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 COALESCE(SUM(amount_awarded), 0) as total FROM grants WHERE amount_awarded IS NOT NULL'),
      ]),
      // Patty
      Promise.all([
        query('patty', 'SELECT COUNT(*) as count FROM petitions'),
        query('patty', 'SELECT COALESCE(SUM(signature_count), 0) as total FROM petitions'),
        query('patty', 'SELECT COUNT(*) as count FROM email_campaigns'),
        query('patty', 'SELECT COUNT(*) as count FROM email_subscribers'),
        query('patty', 'SELECT COUNT(*) as count FROM petition_templates'),
      ]),
      // Freddy
      Promise.all([
        query('freddy', 'SELECT COUNT(*) as count FROM causes'),
        query('freddy', 'SELECT COUNT(*) as count FROM organizations'),
        query('freddy', 'SELECT COUNT(*) as count FROM granters'),
        query('freddy', 'SELECT COUNT(*) as count FROM matches'),
        query('freddy', 'SELECT COUNT(*) as count FROM contacts'),
        query('freddy', 'SELECT COALESCE(SUM(commission_amount), 0) as total FROM revenue'),
      ]),
    ]);

    const sdcc = {
      drafts: parseInt(sdccData[0].rows[0].count),
      news: parseInt(sdccData[1].rows[0].count),
      petitions: parseInt(sdccData[2].rows[0].count),
      collaborations: parseInt(sdccData[3].rows[0].count),
      partners: parseInt(sdccData[4].rows[0].count),
      leads: parseInt(sdccData[5].rows[0].count),
      library: parseInt(sdccData[6].rows[0].count),
    };

    const grant = {
      grants: parseInt(grantData[0].rows[0].count),
      proposals: parseInt(grantData[1].rows[0].count),
      news: parseInt(grantData[2].rows[0].count),
      collaborations: parseInt(grantData[3].rows[0].count),
      total_funding: parseFloat(grantData[4].rows[0].total) || 0,
    };

    const patty = {
      petitions: parseInt(pattyData[0].rows[0].count),
      signatures: parseInt(pattyData[1].rows[0].total),
      campaigns: parseInt(pattyData[2].rows[0].count),
      subscribers: parseInt(pattyData[3].rows[0].count),
      templates: parseInt(pattyData[4].rows[0].count),
    };

    const freddy = {
      causes: parseInt(freddyData[0].rows[0].count),
      organizations: parseInt(freddyData[1].rows[0].count),
      granters: parseInt(freddyData[2].rows[0].count),
      matches: parseInt(freddyData[3].rows[0].count),
      contacts: parseInt(freddyData[4].rows[0].count),
      revenue_total: parseFloat(freddyData[5].rows[0].total) || 0,
    };

    const totalRecords =
      sdcc.drafts + sdcc.news + sdcc.petitions + sdcc.collaborations + sdcc.partners + sdcc.leads + sdcc.library +
      grant.grants + grant.proposals + grant.news + grant.collaborations +
      patty.petitions + patty.campaigns + patty.subscribers + patty.templates +
      freddy.causes + freddy.organizations + freddy.granters + freddy.matches + freddy.contacts;

    return NextResponse.json({
      sdcc,
      grant,
      patty,
      freddy,
      system: {
        apps_online: 4,
        total_records: totalRecords,
      },
    });
  } catch (err) {
    console.error('[dashboard] Error:', (err as Error).message);
    return NextResponse.json(
      { error: 'Failed to fetch dashboard data' },
      { status: 500 },
    );
  }
}