first commit
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
import { auth } from "@/lib/auth";
|
||||
import { createSupabaseServiceRoleClient } from "@/lib/supabase/service-role";
|
||||
import { updateGalleryPhotoPickStatus } from "@/server/admin/gallery-pick";
|
||||
import { NextResponse, type NextRequest } from "next/server";
|
||||
import { z } from "zod";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
const galleryPhotoSelect =
|
||||
"id,unsplash_id,slug,description,alt_description,width,height,color,color_family,likes,urls,user_info,photo_created_at,is_picked,picked_at,picked_by,oss_url,oss_object_key,oss_synced_at,oss_sync_error";
|
||||
|
||||
const patchSchema = z.object({
|
||||
unsplashId: z.string().min(1),
|
||||
isPicked: z.boolean(),
|
||||
});
|
||||
|
||||
async function requireAdminSession() {
|
||||
const session = await auth();
|
||||
|
||||
if (!session) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const session = await requireAdminSession();
|
||||
|
||||
if (!session) {
|
||||
return NextResponse.json(
|
||||
{ ok: false, error: "Unauthorized." },
|
||||
{ status: 401 },
|
||||
);
|
||||
}
|
||||
|
||||
const { searchParams } = new URL(request.url);
|
||||
const page = parseInt(searchParams.get("page") || "1", 10);
|
||||
const perPage = parseInt(searchParams.get("per_page") || "24", 10);
|
||||
const picked = searchParams.get("picked");
|
||||
const colorFamily = searchParams.get("color_family");
|
||||
|
||||
if (page < 1 || perPage < 1 || perPage > 100) {
|
||||
return NextResponse.json(
|
||||
{ ok: false, error: "Invalid pagination parameters." },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const supabase = createSupabaseServiceRoleClient();
|
||||
|
||||
let query = supabase
|
||||
.from("wg_gallery_photos")
|
||||
.select(galleryPhotoSelect, { count: "exact" });
|
||||
|
||||
if (picked === "true") {
|
||||
query = query.eq("is_picked", true);
|
||||
} else if (picked === "false") {
|
||||
query = query.eq("is_picked", false);
|
||||
}
|
||||
|
||||
if (colorFamily && colorFamily !== "all") {
|
||||
query = query.eq("color_family", colorFamily);
|
||||
}
|
||||
|
||||
const { data, error, count } = await query
|
||||
.order("picked_at", { ascending: false, nullsFirst: false })
|
||||
.order("photo_created_at", { ascending: false })
|
||||
.range((page - 1) * perPage, page * perPage - 1);
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
ok: true,
|
||||
data: data ?? [],
|
||||
pagination: {
|
||||
page,
|
||||
perPage,
|
||||
total: count ?? 0,
|
||||
hasMore: (count ?? 0) > page * perPage,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Unknown error.";
|
||||
console.error("[api/admin/gallery-photos] PATCH failed", error);
|
||||
return NextResponse.json(
|
||||
{ ok: false, error: message },
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function PATCH(request: NextRequest) {
|
||||
try {
|
||||
const session = await requireAdminSession();
|
||||
|
||||
if (!session) {
|
||||
return NextResponse.json(
|
||||
{ ok: false, error: "Unauthorized." },
|
||||
{ status: 401 },
|
||||
);
|
||||
}
|
||||
|
||||
const parsed = patchSchema.safeParse(await request.json());
|
||||
|
||||
if (!parsed.success) {
|
||||
return NextResponse.json(
|
||||
{ ok: false, error: "Invalid request body." },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const data = await updateGalleryPhotoPickStatus({
|
||||
isPicked: parsed.data.isPicked,
|
||||
pickedBy:
|
||||
session.user?.email ?? session.user?.id ?? "wallora-admin",
|
||||
unsplashId: parsed.data.unsplashId,
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
ok: true,
|
||||
data,
|
||||
});
|
||||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Unknown error.";
|
||||
return NextResponse.json(
|
||||
{ ok: false, error: message },
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user