68 lines
No EOL
3.3 KiB
TypeScript
68 lines
No EOL
3.3 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { createSbServer } from "@/lib/supabaseServer";
|
|
|
|
export async function GET(req: Request) {
|
|
try {
|
|
const sb = createSbServer();
|
|
const { data: { user } } = await sb.auth.getUser();
|
|
if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
|
|
const { data: me } = await sb.from("staff_users").select("is_staff").eq("user_id", user.id).maybeSingle();
|
|
if (!me?.is_staff) return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
|
|
|
const url = new URL(req.url);
|
|
const q = url.searchParams.get("q");
|
|
const org_id = url.searchParams.get("org_id");
|
|
const period_month = url.searchParams.get("period_month");
|
|
const mode = url.searchParams.get("mode");
|
|
const notification_sent = url.searchParams.get("notification_sent");
|
|
const notification_ok = url.searchParams.get("notification_ok");
|
|
const has_client_wire = url.searchParams.get("has_client_wire");
|
|
const deadline_from = url.searchParams.get("deadline_from");
|
|
const deadline_to = url.searchParams.get("deadline_to");
|
|
const sort = url.searchParams.get("sort") || "period_month";
|
|
const order = (url.searchParams.get("order") || "desc").toLowerCase() === "asc" ? "asc" : "desc";
|
|
const limit = Math.min(500, parseInt(url.searchParams.get("limit") || "100", 10));
|
|
const offset = Math.max(0, parseInt(url.searchParams.get("offset") || "0", 10));
|
|
|
|
// Build base query with organization name
|
|
let query = sb.from("salary_transfers").select(`
|
|
*,
|
|
organizations!org_id(name)
|
|
`, { count: "exact" });
|
|
|
|
if (q) {
|
|
// simple ilike search on period_label, callsheet_url, notes
|
|
query = query.or(`period_label.ilike.%${q}%,callsheet_url.ilike.%${q}%,notes.ilike.%${q}%`);
|
|
}
|
|
if (org_id) query = query.eq("org_id", org_id);
|
|
if (period_month) query = query.eq("period_month", period_month);
|
|
if (mode) query = query.eq("mode", mode);
|
|
if (notification_sent !== null) {
|
|
if (notification_sent === "true") query = query.eq("notification_sent", true);
|
|
if (notification_sent === "false") query = query.eq("notification_sent", false);
|
|
}
|
|
if (notification_ok !== null) {
|
|
if (notification_ok === "true") query = query.eq("notification_ok", true);
|
|
if (notification_ok === "false") query = query.eq("notification_ok", false);
|
|
}
|
|
if (has_client_wire === "true") query = query.not("client_wire_received_at", "is", null);
|
|
if (has_client_wire === "false") query = query.is("client_wire_received_at", null);
|
|
if (deadline_from) query = query.gte("deadline", deadline_from);
|
|
if (deadline_to) query = query.lte("deadline", deadline_to);
|
|
|
|
// allowed sort columns
|
|
const allowedSorts = new Set(["period_month", "deadline", "total_net", "created_at", "updated_at", "client_wire_received_at"]);
|
|
const sortCol = allowedSorts.has(sort) ? sort : "period_month";
|
|
query = query.order(sortCol, { ascending: order === "asc" });
|
|
query = query.range(offset, offset + limit - 1);
|
|
|
|
const { data, error, count } = await query;
|
|
if (error) return NextResponse.json({ error: error.message }, { status: 500 });
|
|
|
|
return NextResponse.json({ rows: data ?? [], count: count ?? (data ? data.length : 0) });
|
|
} catch (err: any) {
|
|
console.error(err);
|
|
return NextResponse.json({ error: "Internal" }, { status: 500 });
|
|
}
|
|
} |