From 93e4b221c89e5d0f55d7c864a39be41cdd3590e3 Mon Sep 17 00:00:00 2001 From: jtgi Date: Tue, 20 Feb 2024 17:53:50 +0900 Subject: [PATCH] gm' --- app/routes/~.channels.new.tsx | 364 ++++++++++++++++++ .../20240219053602_gm/migration.sql | 16 + 2 files changed, 380 insertions(+) create mode 100644 app/routes/~.channels.new.tsx create mode 100644 prisma/migrations/20240219053602_gm/migration.sql diff --git a/app/routes/~.channels.new.tsx b/app/routes/~.channels.new.tsx new file mode 100644 index 0000000..a1b0cd2 --- /dev/null +++ b/app/routes/~.channels.new.tsx @@ -0,0 +1,364 @@ +/* eslint-disable react/no-unescaped-entities */ +import { + Control, + Controller, + FormProvider, + UseFormRegister, + UseFormWatch, + useFieldArray, + useForm, + useFormContext, +} from "react-hook-form"; +import { typedjson, useTypedLoaderData } from "remix-typedjson"; +import { LoaderFunctionArgs } from "@remix-run/node"; +import { Button } from "~/components/ui/button"; +import { getSharedEnv, requireUser } from "~/lib/utils.server"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "~/components/ui/select"; +import { + Action, + Rule, + RuleDefinition, + RuleName, + ruleDefinitions, + ruleNames, +} from "~/lib/validations.server"; +import { Input } from "~/components/ui/input"; +import { FieldLabel } from "~/components/ui/fields"; +import { Checkbox } from "~/components/ui/checkbox"; +import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card"; + +export async function loader({ request }: LoaderFunctionArgs) { + const user = await requireUser({ request }); + const env = getSharedEnv(); + + return typedjson({ + user, + ruleDefinitions, + ruleNames, + env: getSharedEnv(), + }); +} + +export default function FrameConfig() { + const { user, env, ruleNames, ruleDefinitions } = + useTypedLoaderData(); + + return ( +
+

New Moderation

+ +
+ ); +} + +type FormValues = { + id?: string; + banThreshold?: number; + ruleSets: Array<{ + id?: string; + ruleParsed: Array; + actionsParsed: Array; + }>; +}; + +export function ChannelForm(props: { + ruleDefinitions: typeof ruleDefinitions; + ruleNames: readonly RuleName[]; + defaultValues: FormValues; +}) { + const methods = useForm({ + defaultValues: props.defaultValues, + }); + + const { + register, + control, + handleSubmit, + watch, + formState: { isSubmitting }, + } = methods; + + const { fields, append, remove } = useFieldArray({ + control, + name: "ruleSets", + }); + + const onSubmit = (data: FormValues) => { + console.log(data); + }; + + const value = watch(); + + return ( +
+ +
+
+ {fields.map((ruleSetField, ruleSetIndex) => ( + + +
+ Rule Set {ruleSetIndex + 1} + +
+
+ + + + +
+ ))} + + +
+ +
+
+
{JSON.stringify(value, null, 2)}
+
+ ); +} + +function RuleSetEditor(props: { + ruleDefinitions: typeof ruleDefinitions; + rulesNames: readonly RuleName[]; + ruleSetIndex: number; + control: Control; + register: UseFormRegister; + watch: UseFormWatch; +}) { + const { rulesNames, ruleSetIndex, control } = props; + const { + fields: ruleFields, + remove: removeRule, + append: appendRule, + } = useFieldArray({ + control, + // @ts-ignore + name: `ruleSets.${ruleSetIndex}.ruleParsed`, + }); + + const { + fields: actionFields, + append: appendAction, + remove: removeAction, + } = useFieldArray({ + control, + // @ts-ignore + name: `ruleSets.${ruleSetIndex}.actionsParsed`, + }); + + return ( +
+
+

Rules

+
+ {ruleFields.map((ruleField, ruleIndex) => { + const ruleName = props.watch( + `ruleSets.${ruleSetIndex}.ruleParsed.${ruleIndex}.name` + ); + + return ( + + + + {props.ruleDefinitions[ruleName].friendlyName} + + + + ( + + )} + /> + + + + + ); + })} +
+ +
+ +
+

Actions

+ {/* Actions */} + {actionFields.map((actionField, actionIndex) => ( +
+ {/* Action inputs */} + +
+ ))} + +
+
+ ); +} + +function RuleArgs(props: { + ruleDefinition: RuleDefinition; + ruleName: RuleName; + ruleIndex: number; + ruleSetIndex: number; +}) { + const { register, control } = useFormContext(); + const ruleDef = props.ruleDefinition; + + return ( +
+ {Object.entries(ruleDef.args).map(([argName, argDef]) => { + if (argDef.type === "number") { + return ( + + + + ); + } + if (argDef.type === "string") { + return ( + + + + ); + } + if (argDef.type === "boolean") { + return ( + + ( + + )} + /> + + ); + } + })} +
+ ); +} diff --git a/prisma/migrations/20240219053602_gm/migration.sql b/prisma/migrations/20240219053602_gm/migration.sql new file mode 100644 index 0000000..63478d2 --- /dev/null +++ b/prisma/migrations/20240219053602_gm/migration.sql @@ -0,0 +1,16 @@ +-- RedefineTables +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_User" ( + "id" TEXT NOT NULL PRIMARY KEY, + "email" TEXT, + "plan" TEXT NOT NULL DEFAULT 'basic', + "role" TEXT NOT NULL DEFAULT 'admin', + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL +); +INSERT INTO "new_User" ("createdAt", "email", "id", "plan", "updatedAt") SELECT "createdAt", "email", "id", "plan", "updatedAt" FROM "User"; +DROP TABLE "User"; +ALTER TABLE "new_User" RENAME TO "User"; +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); +PRAGMA foreign_key_check; +PRAGMA foreign_keys=ON;