import { NextRequest, NextResponse } from "next/server"; import { prisma } from "@/lib/db"; import { Prisma } from "@prisma/client"; export async function GET(req: NextRequest) { try { const { searchParams } = new URL(req.url); const page = Math.max(1, Number(searchParams.get("page") || 1)); const perPage = Math.min(100, Math.max(10, Number(searchParams.get("perPage") || 50))); const search = searchParams.get("search") || ""; const sortBy = searchParams.get("sortBy") || "capturedAt"; const sortDir = (searchParams.get("sortDir") || "desc") as "asc" | "desc"; const hasEmail = searchParams.get("hasEmail"); // "yes" | "no" | null const capturedFrom = searchParams.get("capturedFrom"); const capturedTo = searchParams.get("capturedTo"); const statuses = searchParams.getAll("status"); const sourceTabs = searchParams.getAll("sourceTab"); const priorities = searchParams.getAll("priority"); const tags = searchParams.getAll("tags"); const searchTerms = searchParams.getAll("searchTerm"); const contacted = searchParams.get("contacted"); const favorite = searchParams.get("favorite"); const where: Prisma.LeadWhereInput = {}; if (search) { where.OR = [ { domain: { contains: search } }, { companyName: { contains: search } }, { contactName: { contains: search } }, { email: { contains: search } }, { notes: { contains: search } }, { sourceTerm: { contains: search } }, ]; } if (statuses.length > 0) where.status = { in: statuses }; if (sourceTabs.length > 0) where.sourceTab = { in: sourceTabs }; if (priorities.length > 0) where.priority = { in: priorities }; if (hasEmail === "yes") where.email = { not: null }; else if (hasEmail === "no") where.email = null; if (capturedFrom || capturedTo) { where.capturedAt = {}; if (capturedFrom) where.capturedAt.gte = new Date(capturedFrom); if (capturedTo) where.capturedAt.lte = new Date(capturedTo); } if (searchTerms.length > 0) { where.sourceTerm = { in: searchTerms }; } if (contacted === "yes") { where.tags = { contains: "kontaktiert" }; } if (favorite === "yes") { where.tags = { contains: "favorit" }; } if (tags.length > 0) { // SQLite JSON contains — search for each tag in the JSON string where.AND = tags.map(tag => ({ tags: { contains: tag }, })); } const validSortFields: Record = { capturedAt: true, status: true, priority: true, companyName: true, domain: true, email: true, contactName: true, }; const orderByField = validSortFields[sortBy] ? sortBy : "capturedAt"; const [total, leads] = await Promise.all([ prisma.lead.count({ where }), prisma.lead.findMany({ where, orderBy: { [orderByField]: sortDir }, skip: (page - 1) * perPage, take: perPage, }), ]); return NextResponse.json({ leads, total, page, pages: Math.ceil(total / perPage), perPage, }); } catch (err) { console.error("GET /api/leads error:", err); return NextResponse.json({ error: "Failed to fetch leads" }, { status: 500 }); } }