feat(admin): centralize subscriptions under /admin?tab=subscriptions
Replaced the dedicated /admin/subscriptions page with a redirect to the central admin panel’s subscriptions tab. Removed session checks, imports, and the AdminSubscriptionDashboard since routing and access are now handled centrally. This streamlines admin UX and keeps access control unified.
This commit is contained in:
1 parent
d8e7d5d7e6
commit
62ab5b2608
19 files changed
+3091
-357
No files matched your search
+30
-24
@@ -1,60 +1,66 @@
|
||||
import { NextRequest } from "next/server";
|
||||
import { searchItems } from "@/lib/items-db";
|
||||
import { searchItems, type ItemSort } from "@/lib/prisma/queries/items";
|
||||
import { buildPublicItemImageUrl } from "@/lib/item-images";
|
||||
|
||||
function parseArray(param: string | null): string[] {
|
||||
if (!param) return [];
|
||||
// Suporta formatos: comma-separated (a,b) ou múltiplos parâmetros já combinados
|
||||
return param
|
||||
.split(",")
|
||||
.map((v) => v.trim())
|
||||
.map((value) => value.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
const allowedSorts: ItemSort[] = [
|
||||
"name",
|
||||
"level-asc",
|
||||
"level-desc",
|
||||
"weight-asc",
|
||||
"weight-desc",
|
||||
"category",
|
||||
"updated-desc",
|
||||
];
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(req.url);
|
||||
const q = searchParams.get("q") || undefined;
|
||||
const categories = parseArray(searchParams.get("category"));
|
||||
const rarities = parseArray(searchParams.get("rarity"));
|
||||
const sortParam = (searchParams.get("sort") || "name") as
|
||||
| "name"
|
||||
| "level-asc"
|
||||
| "level-desc"
|
||||
| "weight-asc"
|
||||
| "weight-desc"
|
||||
| "category";
|
||||
const server = searchParams.get("server") || undefined;
|
||||
const sortParamRaw = (searchParams.get("sort") || "name").toLowerCase();
|
||||
const sortParam = (allowedSorts.find((sort) => sort === sortParamRaw) || "name") as ItemSort;
|
||||
const page = Number(searchParams.get("page") || "1");
|
||||
const pageSize = Number(searchParams.get("pageSize") || "24");
|
||||
const voc = searchParams.get("voc") || undefined;
|
||||
|
||||
const { items, total } = searchItems({
|
||||
const { items, total } = await searchItems({
|
||||
q,
|
||||
categories,
|
||||
rarities,
|
||||
category: categories[0],
|
||||
rarity: rarities[0],
|
||||
server,
|
||||
sort: sortParam,
|
||||
vocation: voc,
|
||||
page,
|
||||
pageSize,
|
||||
});
|
||||
|
||||
// Enriquecer com URL pública de imagem quando possível
|
||||
const itemsWithImage = items.map((it: any) => {
|
||||
const img = (it.image || "").toString();
|
||||
// Preferir URL absoluta do banco para teste
|
||||
const itemsWithImage = items.map((item) => {
|
||||
const img = (item.image_url || item.image_local_path || "").toString();
|
||||
if (/^https?:\/\//i.test(img)) {
|
||||
return { ...it, image: img };
|
||||
return { ...item, image_url: img, image: img };
|
||||
}
|
||||
if (img.startsWith("data/")) {
|
||||
return { ...it, image: `/api/images?path=${encodeURIComponent(img)}` };
|
||||
return { ...item, image_url: img, image: `/api/images?path=${encodeURIComponent(img)}` };
|
||||
}
|
||||
const categoryEn = (it.category || "other").toString();
|
||||
return { ...it, image: buildPublicItemImageUrl(categoryEn, img) };
|
||||
const category = item.category || "other";
|
||||
return {
|
||||
...item,
|
||||
image_url: item.image_url,
|
||||
image: buildPublicItemImageUrl(category, img),
|
||||
};
|
||||
});
|
||||
|
||||
const totalPages = Math.max(1, Math.ceil(total / Math.max(1, pageSize)));
|
||||
return Response.json(
|
||||
{ items: itemsWithImage, page, pageSize, total, totalPages },
|
||||
{ items: itemsWithImage, page, pageSize, total, totalPages, sort: sortParam },
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (error: any) {
|
||||
|
||||
Reference in new issue
Block a user