mirror of
https://github.com/Xevion/linkpulse.git
synced 2025-12-06 15:15:34 -06:00
126 lines
3.6 KiB
TypeScript
126 lines
3.6 KiB
TypeScript
import { Icons } from "@/components/icons";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Label } from "@/components/ui/label";
|
|
import { login } from "@/lib/auth";
|
|
import { useUserStore } from "@/lib/state";
|
|
import { cn } from "@/lib/utils";
|
|
import { Link } from "@tanstack/react-router";
|
|
import { HTMLAttributes, SyntheticEvent, useState } from "react";
|
|
|
|
interface UserAuthFormProps extends HTMLAttributes<HTMLDivElement> {}
|
|
|
|
export function RegisterForm({ className, ...props }: UserAuthFormProps) {
|
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
|
|
async function onSubmit(event: SyntheticEvent) {
|
|
event.preventDefault();
|
|
|
|
setIsLoading(true);
|
|
// await login()
|
|
setIsLoading(false);
|
|
}
|
|
|
|
return (
|
|
<div className={cn("grid gap-6", className)} {...props}>
|
|
<form onSubmit={onSubmit}>
|
|
<div className="grid gap-2">
|
|
<div className="grid gap-1">
|
|
<Label className="sr-only" htmlFor="email">
|
|
Email
|
|
</Label>
|
|
<Input
|
|
id="email"
|
|
placeholder="name@example.com"
|
|
type="email"
|
|
autoCapitalize="none"
|
|
autoComplete="email"
|
|
autoCorrect="off"
|
|
disabled={isLoading}
|
|
/>
|
|
</div>
|
|
<Button disabled={isLoading || true}>
|
|
{isLoading && (
|
|
<Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
|
|
)}
|
|
Create Account
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function LoginForm({ className, ...props }: UserAuthFormProps) {
|
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
const { setUser } = useUserStore();
|
|
|
|
async function onSubmit(event: SyntheticEvent) {
|
|
event.preventDefault();
|
|
|
|
const email = (event.target as HTMLFormElement).email.value;
|
|
const password = (event.target as HTMLFormElement).password.value;
|
|
|
|
setIsLoading(true);
|
|
const result = await login(email, password);
|
|
if (result.isOk) {
|
|
setUser(result.value);
|
|
} else {
|
|
alert("Login failed");
|
|
}
|
|
setIsLoading(false);
|
|
}
|
|
|
|
return (
|
|
<div className={cn("grid gap-6", className)} {...props}>
|
|
<form onSubmit={onSubmit}>
|
|
<div className="grid gap-2">
|
|
<div className="grid gap-1">
|
|
<Label htmlFor="email">Email</Label>
|
|
<Input
|
|
id="email"
|
|
type="email"
|
|
autoCapitalize="none"
|
|
autoComplete="email"
|
|
autoCorrect="off"
|
|
disabled={isLoading}
|
|
/>
|
|
</div>
|
|
<div className="grid gap-1">
|
|
<Label htmlFor="email">Password</Label>
|
|
<Input
|
|
id="password"
|
|
type="password"
|
|
autoCapitalize="none"
|
|
autoComplete="current-password"
|
|
autoCorrect="off"
|
|
disabled={isLoading}
|
|
/>
|
|
</div>
|
|
<Button disabled={isLoading}>
|
|
{isLoading && (
|
|
<Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
|
|
)}
|
|
Login
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
<p className="text-center text-sm text-muted-foreground">
|
|
<Link
|
|
to="/register"
|
|
className="underline underline-offset-4 hover:text-primary"
|
|
>
|
|
Register
|
|
</Link>{" "}
|
|
or{" "}
|
|
<Link
|
|
href="/forgot-password"
|
|
className="underline underline-offset-4 hover:text-primary"
|
|
>
|
|
Forgot Password
|
|
</Link>
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|