feat: county sync on monitor page + in-app notification system
- GET /api/eterra/counties — distinct county list from GisUat - POST /api/eterra/sync-county — background sync all UATs in a county (TERENURI + CLADIRI + INTRAVILAN), magic mode for enriched UATs, concurrency guard, creates notification on completion - In-app notification service (KeyValueStore, CRUD, unread count) - GET/PATCH /api/notifications/app — list and mark-read endpoints - NotificationBell component in header with popover + polling - Monitor page: county select dropdown + SyncTestButton with customBody Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* GET /api/notifications/app — list recent + unread count
|
||||
* PATCH /api/notifications/app — mark read / mark all read
|
||||
*
|
||||
* Body for PATCH:
|
||||
* { action: "mark-read", id: string }
|
||||
* { action: "mark-all-read" }
|
||||
*/
|
||||
import { NextResponse } from "next/server";
|
||||
import {
|
||||
getAppNotifications,
|
||||
getUnreadCount,
|
||||
markAsRead,
|
||||
markAllAsRead,
|
||||
} from "@/core/notifications/app-notifications";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function GET(req: Request) {
|
||||
try {
|
||||
const url = new URL(req.url);
|
||||
const limit = Math.min(parseInt(url.searchParams.get("limit") ?? "30", 10), 100);
|
||||
|
||||
const [notifications, unreadCount] = await Promise.all([
|
||||
getAppNotifications(limit),
|
||||
getUnreadCount(),
|
||||
]);
|
||||
|
||||
return NextResponse.json({ notifications, unreadCount });
|
||||
} catch (error) {
|
||||
const msg = error instanceof Error ? error.message : "Eroare notificari";
|
||||
return NextResponse.json({ error: msg }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function PATCH(req: Request) {
|
||||
try {
|
||||
const body = (await req.json()) as { action: string; id?: string };
|
||||
|
||||
if (body.action === "mark-read" && body.id) {
|
||||
await markAsRead(body.id);
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
|
||||
if (body.action === "mark-all-read") {
|
||||
await markAllAsRead();
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
|
||||
return NextResponse.json({ error: "Actiune necunoscuta" }, { status: 400 });
|
||||
} catch (error) {
|
||||
const msg = error instanceof Error ? error.message : "Eroare notificari";
|
||||
return NextResponse.json({ error: msg }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user