Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/app/login/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"use server"

import { getUser } from "@/utils/apis/user"
import { cookies } from "next/headers"
import { redirect } from "next/navigation"

export const loginUser = async (user_id: string, password: string, redirect_url: string) => {
return getUser(user_id, password).then((token) => {
cookies().set("token", token)

return redirect(redirect_url)
})
}
60 changes: 60 additions & 0 deletions src/app/login/components/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"use client"
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { loginUser } from "../actions"
import { Button } from "@/components/ui/button"

type LoginFormSubmitEventType = z.infer<typeof formSchema>

const formSchema = z.object({
user_id: z.string(),
password: z.string(),
})

export function LoginForm({ redirect }: { redirect: string }){
const form = useForm<LoginFormSubmitEventType>({
resolver: zodResolver(formSchema),
defaultValues: {
user_id: "",
password: "",
}
})

const handleSubmit = async (data: LoginFormSubmitEventType) => {
await loginUser(data.user_id, data.password, redirect).catch((err) => {
console.error(err)
form.setError("root", {
type: "server",
message: "Feil brukernavn eller passord"
})
})
}

return (
<Form {...form}>
<form onSubmit={form.handleSubmit(handleSubmit)}>
<FormField control={form.control} name="user_id" render={({ field}) => (
<FormItem>
<FormLabel>Brukernavn</FormLabel>
<FormControl>
<Input placeholder="brukernavn" {...field} />
</FormControl>
</FormItem>
)} />
<FormField control={form.control} name="password" render={({ field}) => (
<FormItem>
<FormLabel>Passord</FormLabel>
<FormControl>
<Input placeholder="passord" type="password" {...field} />
</FormControl>
</FormItem>
)} />
{form.formState.errors.root && <FormMessage className="my-2">{form.formState.errors.root.message}</FormMessage>}
<Button className="w-full" type="submit">Login</Button>
</form>
</Form>
)
}
21 changes: 21 additions & 0 deletions src/app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { LoginForm } from "./components/LoginForm";

export default function Page({ searchParams }: { searchParams?: { redirect?: string }}){
const redirect_url = searchParams?.redirect ?? "/"
const isLoggedin = Boolean(cookies().get("token"))
if(isLoggedin) redirect(redirect_url)

return <div className="max-w-page mx-auto h-screen flex flex-col justify-center items-center">
<Card className="w-80">
<CardHeader>
<CardTitle className="text-center">Login</CardTitle>
</CardHeader>
<CardContent>
<LoginForm redirect={redirect_url} />
</CardContent>
</Card>
</div>
}
9 changes: 9 additions & 0 deletions src/utils/apis/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { IFetch } from "./fetch"

const baseUrl = process.env.NEXT_PUBLIC_API_URL ?? '';

export const getUser = (user_id: string, password: string) => {
return IFetch<string>({ url: `${baseUrl}/auth/login`, config: { method: "POST", body: JSON.stringify({user_id, password}), headers: {
"Content-Type": "application/json"
}}})
}