feat(donate): add donate UI

- rework form core and migrate all old usages
This commit is contained in:
2026-06-05 15:24:41 +07:00 Unverified
parent 5efc86b6c8
commit 75e711144f
32 changed files with 1710 additions and 244 deletions
+9 -20
View File
@@ -2,7 +2,6 @@ import { desc, eq } from "drizzle-orm";
import { ArrowRight, Save, Trash2 } from "lucide-react";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import type { TypedFormData } from "@/app/(ui)/rubgram/type";
import { CdnChooser } from "@/components/chooser";
import { FormAction, FormInput, FormProvider } from "@/components/form";
import { ModalBase } from "@/components/modal";
@@ -37,17 +36,7 @@ export default async function CharacterEditPage({
if (!char) redirect("/admin/char");
async function submit(
form: TypedFormData<{
name: string;
id: string;
element: (typeof elementEnum.enumValues)[number];
stars: "4" | "5";
image: string;
order: string;
version: string;
weapon: string;
amber: string;
}>,
form: FormData,
) {
"use server";
if (!(await adminCheck())) redirect("/login");
@@ -72,14 +61,14 @@ export default async function CharacterEditPage({
try {
data = {
name: form.get("name")!,
vision: form.get("element")!,
stars: parseInt(form.get("stars") || "0", 10) as 4 | 5,
image: form.get("image")!,
order: parseInt(form.get("order")!, 10),
version: form.get("version")!,
weapon: form.get("weapon")!,
amber: form.get("amber")!,
name: form.get("name") as string,
vision: form.get("element") as string,
stars: parseInt((form.get("stars") as string) || "0", 10) as 4 | 5,
image: form.get("image") as string,
order: parseInt(form.get("order") as string, 10),
version: form.get("version") as string,
weapon: form.get("weapon") as string,
amber: form.get("amber") as string,
};
await db.update(characters).set(data).where(eq(characters.id, charId));
} catch (e) {
+10 -21
View File
@@ -2,7 +2,6 @@ import { desc, sql } from "drizzle-orm";
import { ArrowRight, PlusIcon } from "lucide-react";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import type { TypedFormData } from "@/app/(ui)/rubgram/type";
import { CdnChooser } from "@/components/chooser";
import { FormAction, FormInput, FormProvider } from "@/components/form";
import { ModalBase } from "@/components/modal";
@@ -34,17 +33,7 @@ export default async function CharacterCreatePage() {
]);
async function submit(
form: TypedFormData<{
name: string;
id: string;
element: (typeof elementEnum.enumValues)[number];
stars: "4" | "5";
image: string;
order: string;
version: string;
weapon: string;
amber: string;
}>,
form: FormData,
) {
"use server";
if (!(await adminCheck())) redirect("/login");
@@ -69,15 +58,15 @@ export default async function CharacterCreatePage() {
try {
data = {
id: form.get("id")!,
name: form.get("name")!,
vision: form.get("element")!,
stars: parseInt(form.get("stars") || "0", 10) as 4 | 5,
image: form.get("image")!,
order: parseInt(form.get("order")!, 10),
version: form.get("version")!,
weapon: form.get("weapon")!,
amber: form.get("amber")!,
id: form.get("id") as string,
name: form.get("name") as string,
vision: form.get("element") as string,
stars: parseInt((form.get("stars") as string) || "0", 10) as 4 | 5,
image: form.get("image") as string,
order: parseInt(form.get("order") as string, 10),
version: form.get("version") as string,
weapon: form.get("weapon") as string,
amber: form.get("amber") as string,
};
await db.insert(characters).values(data);
} catch (e) {
+5 -11
View File
@@ -2,7 +2,6 @@ import { eq } from "drizzle-orm";
import { SaveIcon, Trash2 } from "lucide-react";
import { revalidatePath } from "next/cache";
import { notFound, redirect } from "next/navigation";
import type { TypedFormData } from "@/app/(ui)/rubgram/type";
import { CdnChooser } from "@/components/chooser";
import {
FormAction,
@@ -29,12 +28,7 @@ export default async function GuideEditPage({
if (!guide) notFound();
async function submit(
form: TypedFormData<{
name: string;
link: string;
image: string;
order: string;
}>,
form: FormData,
) {
"use server";
if (!(await adminCheck())) redirect("/login");
@@ -49,10 +43,10 @@ export default async function GuideEditPage({
try {
data = {
name: form.get("name")!,
image: form.get("image")!,
link: form.get("link")!,
order: parseInt(form.get("order")!, 10),
name: form.get("name") as string,
image: form.get("image") as string,
link: form.get("link") as string,
order: parseInt(form.get("order") as string, 10),
};
try {
new URL(data.link!);
+5 -11
View File
@@ -2,7 +2,6 @@ import { sql } from "drizzle-orm";
import { PlusIcon } from "lucide-react";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import type { TypedFormData } from "@/app/(ui)/rubgram/type";
import { CdnChooser } from "@/components/chooser";
import {
FormAction,
@@ -29,12 +28,7 @@ export default async function GuideCreatePage() {
})
.from(guides);
async function submit(
form: TypedFormData<{
name: string;
link: string;
image: string;
order: string;
}>,
form: FormData,
) {
"use server";
if (!(await adminCheck())) redirect("/login");
@@ -49,10 +43,10 @@ export default async function GuideCreatePage() {
try {
data = {
name: form.get("name")!,
image: form.get("image")!,
link: form.get("link")!,
order: parseInt(form.get("order")!, 10),
name: form.get("name") as string,
image: form.get("image") as string,
link: form.get("link") as string,
order: parseInt(form.get("order") as string, 10),
};
try {
new URL(data.link);
@@ -3,7 +3,6 @@ import { ArrowRight, PlusIcon, SaveIcon, Trash2 } from "lucide-react";
import { revalidatePath } from "next/cache";
import Link from "next/link";
import { notFound, redirect } from "next/navigation";
import type { TypedFormData } from "@/app/(ui)/rubgram/type";
import { CdnChooser } from "@/components/chooser";
import { DatePicker } from "@/components/date";
import {
@@ -44,15 +43,7 @@ export default async function TlVersionEditPage({
if (!ver) notFound();
async function submit(
form: TypedFormData<{
name: string;
id: string;
order: string;
from: string;
image: string;
disclaimer: string;
deprecates: string;
}>,
form: FormData,
) {
"use server";
if (!(await adminCheck())) redirect("/login");
@@ -73,13 +64,13 @@ export default async function TlVersionEditPage({
try {
data = {
id: form.get("id")!,
name: form.get("name")!,
image: form.get("image")!,
disclaimer: form.get("disclaimer")!,
from: form.get("from")!,
deprecates: form.get("deprecates")!,
order: parseInt(form.get("order")!, 10),
id: form.get("id") as string,
name: form.get("name") as string,
image: form.get("image") as string,
disclaimer: form.get("disclaimer") as string,
from: form.get("from") as string,
deprecates: form.get("deprecates") as string,
order: parseInt(form.get("order") as string, 10),
type: typeId,
};
await db
@@ -3,7 +3,6 @@ import { ArrowRight, PlusIcon } from "lucide-react";
import { revalidatePath } from "next/cache";
import Link from "next/link";
import { notFound, redirect } from "next/navigation";
import type { TypedFormData } from "@/app/(ui)/rubgram/type";
import { CdnChooser } from "@/components/chooser";
import { DatePicker } from "@/components/date";
import {
@@ -59,15 +58,7 @@ export default async function TlVersionCreatePage({
if (!type) notFound();
async function submit(
form: TypedFormData<{
name: string;
id: string;
order: string;
from: string;
image: string;
disclaimer: string;
deprecates: string;
}>,
form: FormData,
) {
"use server";
if (!(await adminCheck())) redirect("/login");
@@ -88,13 +79,13 @@ export default async function TlVersionCreatePage({
try {
data = {
id: form.get("id")!,
name: form.get("name")!,
image: form.get("image")!,
disclaimer: form.get("disclaimer")!,
from: form.get("from")!,
deprecates: form.get("deprecates")!,
order: parseInt(form.get("order")!, 10),
id: form.get("id") as string,
name: form.get("name") as string,
image: form.get("image") as string,
disclaimer: form.get("disclaimer") as string,
from: form.get("from") as string,
deprecates: form.get("deprecates") as string,
order: parseInt(form.get("order") as string, 10),
type: typeId,
};
await db.insert(tierlistVersions).values(data);
@@ -3,7 +3,6 @@ import { eq } from "drizzle-orm";
import { SaveIcon, Trash2 } from "lucide-react";
import { revalidatePath } from "next/cache";
import { notFound, redirect } from "next/navigation";
import type { TypedFormData } from "@/app/(ui)/rubgram/type";
import { CdnChooser } from "@/components/chooser";
import {
FormAction,
@@ -34,13 +33,7 @@ export default async function TlTypeEditPage({
if (!type) notFound();
async function submit(
form: TypedFormData<{
name: string;
id: string;
order: string;
image: string;
mode: string;
}>,
form: FormData,
) {
"use server";
if (!(await adminCheck())) redirect("/login");
@@ -55,11 +48,11 @@ export default async function TlTypeEditPage({
try {
data = {
id: form.get("id")!,
name: form.get("name")!,
image: form.get("image")!,
order: parseInt(form.get("order")!, 10),
mode: form.get("mode")!,
id: form.get("id") as string,
name: form.get("name") as string,
image: form.get("image") as string,
order: parseInt(form.get("order") as string, 10),
mode: form.get("mode") as string,
};
await db
.update(tierlistTypes)
+6 -13
View File
@@ -2,7 +2,6 @@ import { sql } from "drizzle-orm";
import { PlusIcon } from "lucide-react";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import type { TypedFormData } from "@/app/(ui)/rubgram/type";
import { CdnChooser } from "@/components/chooser";
import { FormAction, FormInput, FormProvider } from "@/components/form";
import { ModalBase } from "@/components/modal";
@@ -22,13 +21,7 @@ export default async function TlTypeCreatePage() {
.from(tierlistTypes);
async function submit(
form: TypedFormData<{
name: string;
id: string;
order: string;
image: string;
mode: string;
}>,
form: FormData,
) {
"use server";
if (!(await adminCheck())) redirect("/login");
@@ -43,11 +36,11 @@ export default async function TlTypeCreatePage() {
try {
data = {
id: form.get("id")!,
name: form.get("name")!,
image: form.get("image")!,
mode: form.get("mode")!,
order: parseInt(form.get("order")!, 10),
id: form.get("id") as string,
name: form.get("name") as string,
image: form.get("image") as string,
mode: form.get("mode") as string,
order: parseInt(form.get("order") as string, 10),
};
await db.insert(tierlistTypes).values(data);
} catch (e) {