refactor(db): migrate app pages and APIs from Prisma facade to Drizzle (4)
Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
580972c0a0
commit
9aa4f331bf
40 files changed
+1259
-927
No files matched your search
@@ -1,10 +1,21 @@
|
||||
import {
|
||||
and,
|
||||
asc,
|
||||
count,
|
||||
desc,
|
||||
eq,
|
||||
inArray,
|
||||
like,
|
||||
or,
|
||||
type SQL,
|
||||
} from "drizzle-orm";
|
||||
import { redirect } from "next/navigation";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { StatusCard } from "@/components/admin/dashboard";
|
||||
import { calcPagination, parseListParams } from "@/lib/admin-helpers";
|
||||
import { db, User, WebsitePaypalTransactions } from "@/lib/db";
|
||||
import { formatDate } from "@/lib/format-date";
|
||||
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { type TransactionRow, TransactionsTable } from "./transactions-table";
|
||||
|
||||
const PAID_STATUS = ["completed", "paid", "success", "approved"] as const;
|
||||
@@ -33,15 +44,6 @@ function formatAmount(amount: number, currency: string): string {
|
||||
return `${value} ${currency}`;
|
||||
}
|
||||
|
||||
const SORT_MAP: Record<string, any> = {
|
||||
id: { id: "desc" },
|
||||
amount: { amount: "desc" },
|
||||
date: { createdAt: "desc" },
|
||||
status: { status: "desc" },
|
||||
package: { description: "desc" },
|
||||
payer: { userId: "desc" },
|
||||
};
|
||||
|
||||
export default async function AdminTransactions({
|
||||
searchParams,
|
||||
}: {
|
||||
@@ -57,14 +59,20 @@ export default async function AdminTransactions({
|
||||
const parsed = parseListParams(new URLSearchParams(raw));
|
||||
const statusFilter = raw.filter_status ?? "";
|
||||
|
||||
const where: any = {};
|
||||
const conditions: SQL[] = [];
|
||||
|
||||
if (statusFilter === "paid") {
|
||||
where.status = { in: [...PAID_STATUS] };
|
||||
conditions.push(
|
||||
inArray(WebsitePaypalTransactions.status, [...PAID_STATUS]),
|
||||
);
|
||||
} else if (statusFilter === "failed") {
|
||||
where.status = { in: [...FAILED_STATUS] };
|
||||
conditions.push(
|
||||
inArray(WebsitePaypalTransactions.status, [...FAILED_STATUS]),
|
||||
);
|
||||
} else if (statusFilter === "pending") {
|
||||
where.status = { in: [...PENDING_STATUS] };
|
||||
conditions.push(
|
||||
inArray(WebsitePaypalTransactions.status, [...PENDING_STATUS]),
|
||||
);
|
||||
}
|
||||
|
||||
if (parsed.search.trim()) {
|
||||
@@ -72,55 +80,67 @@ export default async function AdminTransactions({
|
||||
const asId = Number(q);
|
||||
let userIds: number[] = [];
|
||||
try {
|
||||
const users = await prisma.user.findMany({
|
||||
where: { username: { contains: q } },
|
||||
select: { id: true },
|
||||
take: 50,
|
||||
});
|
||||
const users = await db
|
||||
.select({ id: User.id })
|
||||
.from(User)
|
||||
.where(like(User.username, `%${q}%`))
|
||||
.limit(50);
|
||||
userIds = users.map((u) => u.id);
|
||||
} catch {
|
||||
userIds = [];
|
||||
}
|
||||
|
||||
where.AND = [
|
||||
...(where.status ? [{ status: where.status }] : []),
|
||||
{
|
||||
OR: [
|
||||
{ transactionId: { contains: q } },
|
||||
{ description: { contains: q } },
|
||||
...(Number.isFinite(asId) && asId > 0 ? [{ userId: asId }] : []),
|
||||
...(userIds.length ? [{ userId: { in: userIds } }] : []),
|
||||
],
|
||||
},
|
||||
];
|
||||
delete where.status;
|
||||
conditions.push(
|
||||
or(
|
||||
like(WebsitePaypalTransactions.transactionId, `%${q}%`),
|
||||
like(WebsitePaypalTransactions.description, `%${q}%`),
|
||||
...(Number.isFinite(asId) && asId > 0
|
||||
? [eq(WebsitePaypalTransactions.userId, asId)]
|
||||
: []),
|
||||
...(userIds.length
|
||||
? [inArray(WebsitePaypalTransactions.userId, userIds)]
|
||||
: []),
|
||||
)!,
|
||||
);
|
||||
}
|
||||
|
||||
const where = conditions.length > 0 ? and(...conditions) : undefined;
|
||||
|
||||
let total = 0;
|
||||
try {
|
||||
total = await prisma.websitePaypalTransactions.count({ where });
|
||||
const [totalRow] = await db
|
||||
.select({ total: count() })
|
||||
.from(WebsitePaypalTransactions)
|
||||
.where(where);
|
||||
total = Number(totalRow?.total ?? 0);
|
||||
} catch {
|
||||
total = 0;
|
||||
}
|
||||
|
||||
const pagination = calcPagination(total, parsed.page, parsed.perPage);
|
||||
const sortKey = parsed.sort ?? "id";
|
||||
const baseOrder = SORT_MAP[sortKey] ?? { id: "desc" as const };
|
||||
const orderField = Object.keys(baseOrder)[0] as keyof typeof baseOrder;
|
||||
const orderBy = {
|
||||
[orderField]: parsed.order,
|
||||
} as any;
|
||||
const orderCol =
|
||||
parsed.sort === "amount"
|
||||
? WebsitePaypalTransactions.amount
|
||||
: parsed.sort === "date"
|
||||
? WebsitePaypalTransactions.createdAt
|
||||
: parsed.sort === "status"
|
||||
? WebsitePaypalTransactions.status
|
||||
: parsed.sort === "package"
|
||||
? WebsitePaypalTransactions.description
|
||||
: parsed.sort === "payer"
|
||||
? WebsitePaypalTransactions.userId
|
||||
: WebsitePaypalTransactions.id;
|
||||
const orderBy = parsed.order === "asc" ? asc(orderCol) : desc(orderCol);
|
||||
|
||||
let transactions: Awaited<
|
||||
ReturnType<typeof prisma.websitePaypalTransactions.findMany>
|
||||
> = [];
|
||||
let transactions: (typeof WebsitePaypalTransactions.$inferSelect)[] = [];
|
||||
try {
|
||||
transactions = await prisma.websitePaypalTransactions.findMany({
|
||||
where,
|
||||
orderBy,
|
||||
skip: pagination.offset,
|
||||
take: pagination.perPage,
|
||||
});
|
||||
transactions = await db
|
||||
.select()
|
||||
.from(WebsitePaypalTransactions)
|
||||
.where(where)
|
||||
.orderBy(orderBy)
|
||||
.limit(pagination.perPage)
|
||||
.offset(pagination.offset);
|
||||
} catch {
|
||||
transactions = [];
|
||||
}
|
||||
@@ -129,10 +149,10 @@ export default async function AdminTransactions({
|
||||
let names = new Map<number, string>();
|
||||
if (userIds.length > 0) {
|
||||
try {
|
||||
const users = await prisma.user.findMany({
|
||||
where: { id: { in: userIds } },
|
||||
select: { id: true, username: true },
|
||||
});
|
||||
const users = await db
|
||||
.select({ id: User.id, username: User.username })
|
||||
.from(User)
|
||||
.where(inArray(User.id, userIds));
|
||||
names = new Map(users.map((u) => [u.id, u.username]));
|
||||
} catch {
|
||||
names = new Map();
|
||||
|
||||
Reference in new issue
Block a user