- feat(rubgram): add webhook for submission

- fix(rubgram): return to register page after timer expire
- fix(rubgram): hydration warning fix
This commit is contained in:
2026-02-08 16:14:25 +07:00 Unverified
parent 2bd0329c27
commit 3fe84d0c5c
6 changed files with 124 additions and 6 deletions
+1 -1
View File
@@ -187,7 +187,7 @@ export function CharacterChooser({
</span>
</div>
<center>ออกจากเกมเพื่อให้ข้อมูลอัพเดท แล้วกดรีโหลด</center>
<AlertDialogFooter>
<AlertDialogFooter suppressHydrationWarning>
<AlertDialogCancel>ปิดหน้าต่าง</AlertDialogCancel>
<Countdown
time={cacheTtl}
+10 -3
View File
@@ -216,7 +216,10 @@ export async function submitEndgame(formData: EndgameFormData) {
})
.returning({ queue: endgameSubmissions.queue, id: endgameSubmissions.id });
revalidatePath("/rubgram/admin");
ps.publish({}, { topic: "rubgram", event: "update" });
ps.publish(
{ type: "submit", sub: queue.id },
{ topic: "rubgram", event: "update" },
);
return queue;
}
@@ -286,7 +289,11 @@ export async function submitEndgamePayment(formData: EndgamePaymentFormData) {
.where(eq(endgameSubmissions.id, sid));
});
revalidatePath("/rubgram/admin");
ps.publish({}, { topic: "rubgram", event: "update" });
if (Array.isArray(queue))
ps.publish(
{ type: "paid", sub: queue[0].id },
{ topic: "rubgram", event: "update" },
);
return Array.isArray(queue) ? queue[0] : queue;
}
@@ -401,7 +408,7 @@ export async function cancel(sid: string) {
await removeExpiredSubmissions();
ps.publish({}, { topic: "rubgram", event: "update" });
ps.publish({ type: "cancel" }, { topic: "rubgram", event: "update" });
revalidatePath("/rubgram");
}
+12
View File
@@ -1,6 +1,7 @@
"use client";
import { ArrowRight, Check, Download, LogIn, ScrollText } from "lucide-react";
import { useRouter } from "next/navigation";
import { type ReactNode, useEffect, useRef, useState } from "react";
import { toast } from "sonner";
import { Blocker } from "@/components/blocker";
@@ -185,11 +186,22 @@ export function DownloadButton() {
export function Countdown({
time,
render = String,
refreshWhenOver = false,
}: {
time: Date;
render?: (time: string | null) => ReactNode;
refreshWhenOver?: boolean;
}) {
const [now, setNow] = useState(new Date());
const router = useRouter();
useEffect(() => {
if (!refreshWhenOver) return;
const wait = time.getTime() - Date.now();
if (wait < 0) return;
const timeout = setTimeout(() => router.refresh(), wait);
return () => clearTimeout(timeout);
}, [time, router, refreshWhenOver]);
useEffect(() => {
const interval = setInterval(() => setNow(new Date()), 1000);
+2 -2
View File
@@ -175,8 +175,8 @@ export default async function EndgamePage() {
<span className="font-bold text-lg">
ยอดชำระ {q.price} บาท{" "}
{q.expires && (
<Kbd>
<Countdown time={q.expires} />
<Kbd suppressHydrationWarning>
<Countdown time={q.expires} refreshWhenOver />
</Kbd>
)}
</span>