From e52597c34979b5ae881963f43d7a2e9d0121eac8 Mon Sep 17 00:00:00 2001 From: Derock Date: Fri, 12 Apr 2024 21:23:04 -0400 Subject: [PATCH] ref: use react hook form for setup --- src/app/(auth)/login/page.tsx | 14 +++++ src/app/(auth)/setup/SetupForm.tsx | 98 ++++++++++++++---------------- src/app/layout.tsx | 2 - src/hooks/forms.tsx | 6 +- tailwind.config.ts | 14 +++++ 5 files changed, 78 insertions(+), 56 deletions(-) diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx index db170d8..ab0ada7 100644 --- a/src/app/(auth)/login/page.tsx +++ b/src/app/(auth)/login/page.tsx @@ -1,4 +1,6 @@ import { redirect } from "next/navigation"; +import { db } from "~/server/db"; +import { users } from "~/server/db/schema"; import { api } from "~/trpc/server"; import LoginForm from "./Login"; @@ -6,5 +8,17 @@ export default async function LoginPage() { const loggedIn = await api.auth.me.query().catch(() => null); if (loggedIn) return redirect("/"); + // check if instance is set up or not + const isSetup = await db + .select({ id: users.id }) + .from(users) + .limit(1) + .execute() + .then((users) => users.length > 0); + + if (!isSetup) { + return redirect("/setup"); + } + return ; } diff --git a/src/app/(auth)/setup/SetupForm.tsx b/src/app/(auth)/setup/SetupForm.tsx index 880f466..10861d6 100644 --- a/src/app/(auth)/setup/SetupForm.tsx +++ b/src/app/(auth)/setup/SetupForm.tsx @@ -1,21 +1,20 @@ "use client"; -import { useForm } from "@mantine/form"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { toast } from "sonner"; +import { z } from "zod"; import { Button } from "~/components/ui/button"; import { Card, + CardContent, + CardDescription, + CardFooter, CardHeader, CardTitle, - CardDescription, - CardContent, - CardFooter, } from "~/components/ui/card"; -import { Input } from "~/components/ui/input"; -import { Label } from "~/components/ui/label"; -import { Required } from "~/components/ui/required"; +import { Form } from "~/components/ui/form"; +import { SimpleFormField, useForm } from "~/hooks/forms"; import { api } from "~/trpc/react"; export function SetupForm() { @@ -27,7 +26,7 @@ export function SetupForm() { >(); const setupInstance = api.setup.setup.useMutation({ onSuccess: () => { - router.push("/dashboard"); + router.push("/login"); toast.success("Successfully setup instance!", { id: toastLoading }); }, @@ -36,22 +35,19 @@ export function SetupForm() { }, }); - const form = useForm({ - initialValues: { - username: "", - password: "", - }, - - validate: { - password: (value) => value.length === 0 && "Password is required", - username: (value) => value.length === 0 && "Username is required", - }, - }); + const form = useForm( + z.object({ + username: z.string().min(3), + password: z.string().min(3), + }), + ); return ( - Setup Hostforge 🚀 + + Setup Hostforge 🚀 + Welcome to Hostforge — a modern self-hosted platform for deploying and managing your own applications. @@ -61,43 +57,41 @@ export function SetupForm() { -
{ - setToastLoading(toast.loading("Setting up instance...")); - setupInstance.mutate(data); - })} - > -
- - - {form.errors.username && ( -
{form.errors.username}
- )} -
+ + { + setToastLoading(toast.loading("Setting up instance...")); + await setupInstance.mutateAsync(data); + })} + > + -
- - - {form.errors.password && ( -
{form.errors.password}
- )} -
- + +
- diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 8033f25..d8e1106 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -25,8 +25,6 @@ export default function RootLayout({ }: { children: React.ReactNode; }) { - console.log(outfit); - return ( diff --git a/src/hooks/forms.tsx b/src/hooks/forms.tsx index 9bcbd1a..2d79746 100644 --- a/src/hooks/forms.tsx +++ b/src/hooks/forms.tsx @@ -1,6 +1,6 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { AnimatePresence, motion } from "framer-motion"; -import { type ReactNode } from "react"; +import { type PropsWithChildren, type ReactNode } from "react"; import { useForm as useFormHook, useFormState, @@ -80,8 +80,10 @@ export function SimpleFormField< required?: boolean; render?: ControllerProps["render"]; className?: string; + type?: PropsWithChildren["type"]; }) { - const render = props.render ?? (({ field }) => ); + const render = + props.render ?? (({ field }) => ); return (