kios-webapp/astro/src/components/LoginForm.tsx

143 lines
3.5 KiB
TypeScript

import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { Button } from "@/components/ui/Button"
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import axios from "axios";
import { setAuthCookie } from "@/utils/authUtils"
import { API_URL } from "@/utils/hooks"
const headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Credentials": "true"
}
const loginFetch = async (email: string, password: string) => {
try {
const response = await fetch(`${API_URL}/api/users/login`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: email,
password: password
}),
})
} catch (err) {
console.log(err)
}
};
interface LoginFormProps {
setAuthToken: (token: string) => void;
authToken: string;
}
export function LoginForm(props: LoginFormProps) {
const login = async (email: string, password: string) => {
try {
const response = await axios.post(`${API_URL}/api/users/login`, {
email: email,
password: password
}, {
withCredentials: true, // include cookies in the request
headers: headers
});
const data = response.data;
if (response.status !== 200) {
throw Error("Login failed")
}
setAuthCookie(data.token, 30);
props.setAuthToken(data.token)
return
} catch (error) {
window.alert(error)
}
};
const formSchema = z.object({
email: z.string().email({
message: "Email must be valid"
}),
password: z.string().min(1, {
}),
})
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
email: "",
password: "",
},
})
function onSubmit(values: z.infer<typeof formSchema>) {
login(values.email, values.password)
}
return (
<div className="flex justify-center">
{props.authToken ? <p>Login successful</p>
:
<div>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input type="email" {...field} />
</FormControl>
<FormDescription>
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>Password</FormLabel>
<FormControl>
<Input type="password" placeholder="" {...field} />
</FormControl>
<FormDescription>
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button variant={"kios"} type="submit">Login</Button>
</form>
</Form>
</div>
}
</div>
)
}