diff options
author | polwex <polwex@sortug.com> | 2025-05-15 10:13:00 +0700 |
---|---|---|
committer | polwex <polwex@sortug.com> | 2025-05-15 10:13:00 +0700 |
commit | d56594d3289002566f4653d607f0837befd65109 (patch) | |
tree | f69685b458419566a78727ce6a8cecd0cdc269a5 /src/components/Login.tsx | |
parent | 04509d9207603d9055cf022051763ec05c9214d6 (diff) |
wtf man
Diffstat (limited to 'src/components/Login.tsx')
-rw-r--r-- | src/components/Login.tsx | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/src/components/Login.tsx b/src/components/Login.tsx new file mode 100644 index 0000000..5747d06 --- /dev/null +++ b/src/components/Login.tsx @@ -0,0 +1,305 @@ +"use client"; + +import { postLogin, postRegister } from "@/actions/login"; +import { cn } from "@/lib/utils"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; + +import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; +import { + Card, + CardHeader, + CardDescription, + CardContent, + CardFooter, + CardTitle, +} from "@/components/ui/card"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +import { useActionState } from "react"; + +const FormSchema = z.object({ + username: z.string().min(2, { + message: "Username must be at least 2 characters.", + }), + password: z.string().min(2, { + message: "Password must be at least 2 characters.", + }), +}); +export default function AuthScreen() { + return <OOldform />; +} + +function OOldform() { + const [state, formAction, isPending] = useActionState< + { msg: string }, + FormData + >(postLogin, { msg: "init" }); + return ( + <form action={formAction}> + {state.msg} + <label> + Username + <input type="text" placeholder="shadcn" name="username" /> + </label> + <label className="flex justify-between"> + <span>Password</span> + <a + href="#" + className="ml-auto text-sm underline-offset-4 hover:underline" + > + Forgot your password? + </a> + <input type="password" placeholder="..." name="password" /> + </label> + <button type="submit" className="w-full"> + Login + </button> + <div className="text-center text-sm"> + Don't have an account?{" "} + <a href="#" className="underline underline-offset-4"> + Sign up + </a> + </div> + </form> + ); +} +function Oldform() { + const [state, formAction, isPending] = useActionState< + { msg: string }, + FormData + >(postLogin, { msg: "init" }); + return ( + <form action={formAction}> + {state.msg} + <div className="flex flex-col gap-6"> + <Card> + <CardHeader className="text-center"> + <CardTitle className="text-xl">Welcome back</CardTitle> + <CardDescription>Login to Sorlang</CardDescription> + <p>{state.msg}</p> + </CardHeader> + <CardContent> + <div className="grid gap-6"> + <div className="grid gap-6"> + <Label> + Username + <Input placeholder="shadcn" name="username" /> + </Label> + <Label className="flex justify-between"> + <span>Password</span> + <a + href="#" + className="ml-auto text-sm underline-offset-4 hover:underline" + > + Forgot your password? + </a> + <Input type="password" placeholder="..." name="password" /> + </Label> + </div> + <Button type="submit" className="w-full"> + Login + </Button> + <div className="text-center text-sm"> + Don't have an account?{" "} + <a href="#" className="underline underline-offset-4"> + Sign up + </a> + </div> + </div> + </CardContent> + </Card> + <div className="text-balance text-center text-xs text-muted-foreground [&_a]:underline [&_a]:underline-offset-4 [&_a]:hover:text-primary "> + By clicking continue, you agree to our{" "} + <a href="#">Terms of Service</a> and <a href="#">Privacy Policy</a>. + </div> + </div> + </form> + ); +} + +function Register({ setRegister }: { setRegister: (b: boolean) => void }) { + const form = useForm<z.infer<typeof FormSchema>>({ + resolver: zodResolver(FormSchema), + defaultValues: { + username: "", + password: "", + }, + }); + + async function onSubmit(data: z.infer<typeof FormSchema>) { + const body = JSON.stringify({ + name: data.username, + creds: data.password, + }); + const opts = { + method: "POST", + headers: { "Content-type": "application/json" }, + body, + }; + const res = await fetch("/api/db/user/new", opts); + const j = await res.json(); + console.log(j); + if ("error" in j) toast(`Error: ${j.error}`); + else { + toast("Register successful"); + } + } + + return ( + <Card> + <CardTitle>Register</CardTitle> + <Form {...form}> + <form + onSubmit={form.handleSubmit(onSubmit)} + className="w-2/3 space-y-6" + > + <CardContent> + <FormField + control={form.control} + name="username" + render={({ field }) => ( + <FormItem> + <FormLabel>Username</FormLabel> + <FormControl> + <Input placeholder="shadcn" {...field} /> + </FormControl> + <FormDescription> + This is your public display name. + </FormDescription> + <FormMessage /> + </FormItem> + )} + /> + <FormField + control={form.control} + name="password" + render={({ field }) => ( + <FormItem> + <FormLabel>Password</FormLabel> + <FormControl> + <Input type="password" placeholder="..." {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + </CardContent> + <CardFooter> + <Button type="submit">Submit</Button> + </CardFooter> + </form> + </Form> + </Card> + ); +} + +function LoginForm({ + className, + ...props +}: React.ComponentPropsWithoutRef<"div">) { + const form = useForm<z.infer<typeof FormSchema>>({ + resolver: zodResolver(FormSchema), + defaultValues: { + username: "", + password: "", + }, + }); + async function onSubmit(data: z.infer<typeof FormSchema>) { + console.log("oh hai"); + const body = JSON.stringify({ + name: data.username, + creds: data.password, + }); + const opts = { + method: "POST", + headers: { "Content-type": "application/json" }, + body, + }; + const res = await fetch("/api/login", opts); + const j = await res.json(); + console.log({ j }); + if ("error" in j) toast(`Error! ${j.error}`); + else { + toast("Login successful"); + } + } + return ( + <div className={cn("flex flex-col gap-6", className)} {...props}> + <Card> + <CardHeader className="text-center"> + <CardTitle className="text-xl">Welcome back</CardTitle> + <CardDescription>Login to Sorlang</CardDescription> + </CardHeader> + <CardContent> + <Form {...form}> + <form onSubmit={form.handleSubmit(onSubmit)}> + <div className="grid gap-6"> + <div className="grid gap-6"> + <FormField + control={form.control} + name="username" + render={({ field }) => ( + <FormItem> + <FormLabel>Username</FormLabel> + <FormControl> + <Input placeholder="shadcn" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + <FormField + control={form.control} + name="password" + render={({ field }) => ( + <FormItem> + <FormLabel className="flex justify-between"> + <span>Password</span> + <a + href="#" + className="ml-auto text-sm underline-offset-4 hover:underline" + > + Forgot your password? + </a> + </FormLabel> + <FormControl> + <Input type="password" placeholder="..." {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + </div> + <Button type="submit" className="w-full"> + Login + </Button> + <div className="text-center text-sm"> + Don't have an account?{" "} + <a href="#" className="underline underline-offset-4"> + Sign up + </a> + </div> + </div> + </form> + </Form> + </CardContent> + </Card> + <div className="text-balance text-center text-xs text-muted-foreground [&_a]:underline [&_a]:underline-offset-4 [&_a]:hover:text-primary "> + By clicking continue, you agree to our <a href="#">Terms of Service</a>{" "} + and <a href="#">Privacy Policy</a>. + </div> + </div> + ); +} |