feat: implement donation form with payment processing
Add main donate page with TMN and PromptPay flows, donation schema with retry system, SSE integration, heartbeat endpoint, and file-to-data-url utility. Remove unused donate client component.
This commit is contained in:
+8
-3
@@ -88,12 +88,12 @@ export const submissions = artifact.table("submissions", {
|
||||
name: text().notNull(),
|
||||
comment: text().notNull(),
|
||||
char: text()
|
||||
.notNull()
|
||||
// .notNull() // For Special Queue
|
||||
.references(() => characters.name, {
|
||||
onDelete: "cascade",
|
||||
onUpdate: "cascade",
|
||||
}),
|
||||
queue: serial(),
|
||||
queue: serial(), // NULL for Spacial Queue
|
||||
editToken: text().notNull().$defaultFn(uuidv7),
|
||||
edits: integer().notNull().default(0),
|
||||
checked: boolean().notNull().default(false),
|
||||
@@ -348,9 +348,14 @@ export const schDonate = pgSchema("donate");
|
||||
export const donations = schDonate.table("donations", {
|
||||
id: text().primaryKey().$defaultFn(uuidv7),
|
||||
name: text().notNull(),
|
||||
amount: numeric().notNull(),
|
||||
amount: numeric({ mode: "number", precision: 7, scale: 2 }).notNull(),
|
||||
image: bytea(),
|
||||
message: text(),
|
||||
created: timestamp("created_at").defaultNow().notNull(),
|
||||
// The retry system
|
||||
lastPing: timestamp("last_ping").default(new Date("01-01-2000")).notNull(),
|
||||
sent: boolean().default(false).notNull(),
|
||||
uid: text(),
|
||||
});
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -33,9 +33,10 @@ export const sse = sseEndpointMap({
|
||||
},
|
||||
donate: {
|
||||
ping: z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
amount: z.number(),
|
||||
image: z.string(),
|
||||
image: z.string().optional(),
|
||||
message: z.string(),
|
||||
}),
|
||||
// roundtrip SSE system check
|
||||
|
||||
@@ -47,6 +47,11 @@ export function shortestPrefixes(values: readonly string[]) {
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function fileToDataUrl(file: File) {
|
||||
const buffer = Buffer.from(await file.arrayBuffer());
|
||||
return `data:${file.type};base64,${buffer.toString("base64")}`;
|
||||
}
|
||||
|
||||
export function parseSearchNumber(
|
||||
param: string | string[] | undefined,
|
||||
def: number = 0,
|
||||
|
||||
Reference in New Issue
Block a user