diff --git a/apps/web/src/lib/auth-client.ts b/apps/web/src/lib/auth-client.ts index 8baa342..f1012dd 100644 --- a/apps/web/src/lib/auth-client.ts +++ b/apps/web/src/lib/auth-client.ts @@ -1,3 +1,3 @@ import { createAuthClient } from "better-auth/react"; -export const authClient = createAuthClient({}); +export const authClient = createAuthClient(); diff --git a/apps/web/src/routeTree.gen.ts b/apps/web/src/routeTree.gen.ts index 84f9305..fb95264 100644 --- a/apps/web/src/routeTree.gen.ts +++ b/apps/web/src/routeTree.gen.ts @@ -10,8 +10,10 @@ import { Route as rootRouteImport } from './routes/__root' import { Route as TermsRouteImport } from './routes/terms' +import { Route as ResetPasswordRouteImport } from './routes/reset-password' import { Route as PrivacyRouteImport } from './routes/privacy' import { Route as LoginRouteImport } from './routes/login' +import { Route as ForgotPasswordRouteImport } from './routes/forgot-password' import { Route as DrinkkaartRouteImport } from './routes/drinkkaart' import { Route as ContactRouteImport } from './routes/contact' import { Route as AccountRouteImport } from './routes/account' @@ -29,6 +31,11 @@ const TermsRoute = TermsRouteImport.update({ path: '/terms', getParentRoute: () => rootRouteImport, } as any) +const ResetPasswordRoute = ResetPasswordRouteImport.update({ + id: '/reset-password', + path: '/reset-password', + getParentRoute: () => rootRouteImport, +} as any) const PrivacyRoute = PrivacyRouteImport.update({ id: '/privacy', path: '/privacy', @@ -39,6 +46,11 @@ const LoginRoute = LoginRouteImport.update({ path: '/login', getParentRoute: () => rootRouteImport, } as any) +const ForgotPasswordRoute = ForgotPasswordRouteImport.update({ + id: '/forgot-password', + path: '/forgot-password', + getParentRoute: () => rootRouteImport, +} as any) const DrinkkaartRoute = DrinkkaartRouteImport.update({ id: '/drinkkaart', path: '/drinkkaart', @@ -100,8 +112,10 @@ export interface FileRoutesByFullPath { '/account': typeof AccountRoute '/contact': typeof ContactRoute '/drinkkaart': typeof DrinkkaartRoute + '/forgot-password': typeof ForgotPasswordRoute '/login': typeof LoginRoute '/privacy': typeof PrivacyRoute + '/reset-password': typeof ResetPasswordRoute '/terms': typeof TermsRoute '/admin/drinkkaart': typeof AdminDrinkkaartRoute '/manage/$token': typeof ManageTokenRoute @@ -116,8 +130,10 @@ export interface FileRoutesByTo { '/account': typeof AccountRoute '/contact': typeof ContactRoute '/drinkkaart': typeof DrinkkaartRoute + '/forgot-password': typeof ForgotPasswordRoute '/login': typeof LoginRoute '/privacy': typeof PrivacyRoute + '/reset-password': typeof ResetPasswordRoute '/terms': typeof TermsRoute '/admin/drinkkaart': typeof AdminDrinkkaartRoute '/manage/$token': typeof ManageTokenRoute @@ -133,8 +149,10 @@ export interface FileRoutesById { '/account': typeof AccountRoute '/contact': typeof ContactRoute '/drinkkaart': typeof DrinkkaartRoute + '/forgot-password': typeof ForgotPasswordRoute '/login': typeof LoginRoute '/privacy': typeof PrivacyRoute + '/reset-password': typeof ResetPasswordRoute '/terms': typeof TermsRoute '/admin/drinkkaart': typeof AdminDrinkkaartRoute '/manage/$token': typeof ManageTokenRoute @@ -151,8 +169,10 @@ export interface FileRouteTypes { | '/account' | '/contact' | '/drinkkaart' + | '/forgot-password' | '/login' | '/privacy' + | '/reset-password' | '/terms' | '/admin/drinkkaart' | '/manage/$token' @@ -167,8 +187,10 @@ export interface FileRouteTypes { | '/account' | '/contact' | '/drinkkaart' + | '/forgot-password' | '/login' | '/privacy' + | '/reset-password' | '/terms' | '/admin/drinkkaart' | '/manage/$token' @@ -183,8 +205,10 @@ export interface FileRouteTypes { | '/account' | '/contact' | '/drinkkaart' + | '/forgot-password' | '/login' | '/privacy' + | '/reset-password' | '/terms' | '/admin/drinkkaart' | '/manage/$token' @@ -200,8 +224,10 @@ export interface RootRouteChildren { AccountRoute: typeof AccountRoute ContactRoute: typeof ContactRoute DrinkkaartRoute: typeof DrinkkaartRoute + ForgotPasswordRoute: typeof ForgotPasswordRoute LoginRoute: typeof LoginRoute PrivacyRoute: typeof PrivacyRoute + ResetPasswordRoute: typeof ResetPasswordRoute TermsRoute: typeof TermsRoute AdminDrinkkaartRoute: typeof AdminDrinkkaartRoute ManageTokenRoute: typeof ManageTokenRoute @@ -221,6 +247,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof TermsRouteImport parentRoute: typeof rootRouteImport } + '/reset-password': { + id: '/reset-password' + path: '/reset-password' + fullPath: '/reset-password' + preLoaderRoute: typeof ResetPasswordRouteImport + parentRoute: typeof rootRouteImport + } '/privacy': { id: '/privacy' path: '/privacy' @@ -235,6 +268,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof LoginRouteImport parentRoute: typeof rootRouteImport } + '/forgot-password': { + id: '/forgot-password' + path: '/forgot-password' + fullPath: '/forgot-password' + preLoaderRoute: typeof ForgotPasswordRouteImport + parentRoute: typeof rootRouteImport + } '/drinkkaart': { id: '/drinkkaart' path: '/drinkkaart' @@ -320,8 +360,10 @@ const rootRouteChildren: RootRouteChildren = { AccountRoute: AccountRoute, ContactRoute: ContactRoute, DrinkkaartRoute: DrinkkaartRoute, + ForgotPasswordRoute: ForgotPasswordRoute, LoginRoute: LoginRoute, PrivacyRoute: PrivacyRoute, + ResetPasswordRoute: ResetPasswordRoute, TermsRoute: TermsRoute, AdminDrinkkaartRoute: AdminDrinkkaartRoute, ManageTokenRoute: ManageTokenRoute, diff --git a/apps/web/src/routes/forgot-password.tsx b/apps/web/src/routes/forgot-password.tsx new file mode 100644 index 0000000..9bfc714 --- /dev/null +++ b/apps/web/src/routes/forgot-password.tsx @@ -0,0 +1,118 @@ +import { useMutation } from "@tanstack/react-query"; +import { createFileRoute, Link } from "@tanstack/react-router"; +import { useState } from "react"; +import { Button } from "@/components/ui/button"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { authClient } from "@/lib/auth-client"; + +export const Route = createFileRoute("/forgot-password")({ + component: ForgotPasswordPage, +}); + +function ForgotPasswordPage() { + const [email, setEmail] = useState(""); + const [sent, setSent] = useState(false); + + const mutation = useMutation({ + mutationFn: async (email: string) => { + const result = await authClient.requestPasswordReset({ + email, + redirectTo: "/reset-password", + }); + if (result.error) { + throw new Error(result.error.message); + } + return result.data; + }, + onSuccess: () => { + setSent(true); + }, + }); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + mutation.mutate(email); + }; + + return ( +
+ Als er een account bestaat voor{" "} + {email}, is er + een e-mail verstuurd met een link om je wachtwoord opnieuw in + te stellen. De link is 1 uur geldig. +
+