fix login flow

This commit is contained in:
2024-08-15 17:36:24 +02:00
parent 0d32ec6d97
commit 171539eacf
5 changed files with 94 additions and 99 deletions

View File

@@ -9,17 +9,17 @@ import { useMeQuery } from "@/services"
export const AuthRedirect: FC<{ children: ReactNode }> = ({ children }) => {
const router = useRouter()
const { data: user, isLoading } = useMeQuery()
const { data: user, isPending } = useMeQuery()
const isAuthPage =
router.pathname === "/login" || router.pathname === "/sign-up"
useEffect(() => {
if (!isLoading && !user && !isAuthPage) {
if (!isPending && !user && !isAuthPage) {
router.push("/login")
}
}, [user, isLoading, isAuthPage, router])
}, [user, isPending, isAuthPage, router])
if (isLoading || (!user && !isAuthPage)) {
if (isPending || (!user && !isAuthPage)) {
return (
<div className={"h-screen"}>
<Loader />

View File

@@ -7,40 +7,59 @@ import { AuthRedirect, Button } from "@/components"
import { ModeToggle } from "@/components/mode-toggle"
import { ThemeProvider } from "@/components/theme-provider"
import { useLogoutMutation } from "@/services"
import Link from "next/link"
import { useRouter } from "next/router"
const queryClient = new QueryClient()
const MyApp: AppType = ({ Component, pageProps }) => {
return (
<QueryClientProvider client={queryClient}>
<AuthRedirect>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
<Header />
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
<Header />
<AuthRedirect>
<Component {...pageProps} />
</ThemeProvider>
</AuthRedirect>
</AuthRedirect>
</ThemeProvider>
</QueryClientProvider>
)
}
function Header() {
const router = useRouter()
const { mutate: logout } = useLogoutMutation()
const handleLogout = () => {
logout()
}
const isLoginPage = router.pathname === "/login"
const isSignUpPage = router.pathname === "/sign-up"
const isOtherPage = !isLoginPage && !isSignUpPage
return (
<header className={"flex items-center justify-between p-4"}>
<h1 className={"text-3xl"}>Tasks</h1>
<Link href={"/"} className={"text-3xl"}>
Tasks
</Link>
<div className={"flex gap-4"}>
<ModeToggle />
<Button onClick={handleLogout} variant={"outline"}>
Logout
</Button>
{isOtherPage && (
<Button onClick={logout} variant={"outline"}>
Logout
</Button>
)}
{isLoginPage && (
<Button variant={"outline"} asChild>
<Link href={"/sign-up"}>Sign up</Link>
</Button>
)}
{isSignUpPage && (
<Button variant={"outline"} asChild>
<Link href={"/login"}>Sign In</Link>
</Button>
)}
</div>
</header>
)

View File

@@ -1,68 +1,40 @@
import type { ChangeEvent } from "react"
import React, { useState } from "react"
import type { FormEvent } from "react"
import React from "react"
import type { NextPage } from "next"
import { Button, Input } from "@/components"
import { Label } from "@/components/ui/label"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { useLoginMutation } from "@/services"
const Login: NextPage = () => {
const { mutate: login } = useLoginMutation()
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
const [remember, setRemember] = useState(true)
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)
const handlePasswordChange = (e: ChangeEvent<HTMLInputElement>) => {
setPassword(e.target.value)
}
const handleEmailChange = (e: ChangeEvent<HTMLInputElement>) => {
setEmail(e.target.value)
}
const handleRememberChange = (e: ChangeEvent<HTMLInputElement>) => {
setRemember(e.target.checked)
}
const handleSubmit = () => {
login({
email,
password,
rememberMe: remember,
})
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
const values = Object.fromEntries(formData) as any
login(values)
}
return (
<div className={"flex h-full items-center justify-center"}>
<div className={"flex w-52 flex-col gap-3"}>
<Input
value={email}
onChange={handleEmailChange}
type="email"
label={"Email"}
/>
<Input
type="password"
label={"Password"}
value={password}
onChange={handlePasswordChange}
/>
<Label className={"flex items-center gap-2"}>
<input
type={"checkbox"}
checked={remember}
onChange={handleRememberChange}
/>
Remember me
</Label>
<Button className={"w-full"} onClick={handleSubmit}>
Login
</Button>
</div>
<Card className={"w-96"}>
<CardHeader>
<CardTitle>Sign In</CardTitle>
</CardHeader>
<CardContent>
<form className={"flex flex-col gap-3"} onSubmit={handleSubmit}>
<Input type="email" name={"email"} label={"Email"} />
<Input type="password" name={"password"} label={"Password"} />
<Button className={"w-full"} type={"submit"}>
Sign in
</Button>
</form>
</CardContent>
</Card>
</div>
)
}

View File

@@ -4,6 +4,7 @@ import React from "react"
import type { NextPage } from "next"
import { Button, Input } from "@/components"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { useSignUpMutation } from "@/services"
const Login: NextPage = () => {
@@ -19,30 +20,33 @@ const Login: NextPage = () => {
}
return (
<div className={"flex h-screen items-center justify-center"}>
<form
className={"flex w-96 flex-col gap-3 rounded-md border p-6"}
onSubmit={handleSubmit}
>
<h1 className={"font-bold text-2xl"}>Sign up</h1>
<label className={"flex flex-col gap-1"}>
Username (optional)
<Input name={"username"} type="text" />
</label>
<label className={"flex flex-col gap-1"}>
Email
<Input name={"email"} type="email" />
</label>
<div className={"flex h-full items-center justify-center"}>
<Card className={"w-96"}>
<CardHeader>
<CardTitle>Sign up</CardTitle>
</CardHeader>
<CardContent>
<form className={"flex flex-col gap-3"} onSubmit={handleSubmit}>
<label className={"flex flex-col gap-1"}>
Username (optional)
<Input name={"username"} type="text" />
</label>
<label className={"flex flex-col gap-1"}>
Email
<Input name={"email"} type="email" />
</label>
<label className={"flex flex-col gap-1"}>
Password
<Input type="password" name={"password"} />
</label>
<label className={"flex flex-col gap-1"}>
Password
<Input type="password" name={"password"} />
</label>
<Button className={"w-full"} type={"submit"}>
Login
</Button>
</form>
<Button className={"w-full"} type={"submit"}>
Sign Up
</Button>
</form>
</CardContent>
</Card>
</div>
)
}

View File

@@ -29,14 +29,14 @@ export const useLoginMutation = () => {
export const useLogoutMutation = () => {
const queryClient = useQueryClient()
const router = useRouter()
return useMutation({
mutationFn: AuthApi.logout,
onSuccess: async () => {
return {
mutate: async () => {
localStorage.removeItem("accessToken")
localStorage.removeItem("refreshToken")
await queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.ME] })
await router.push(ROUTES.LOGIN)
},
})
}
}
export const useSignUpMutation = () => {