From 8bd66ffe46f5740c429bb52116aebb5b7a60b703 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Sun, 3 Aug 2025 10:14:19 +0300 Subject: [PATCH] [frontend]: add zustand --- frontend/package.json | 3 ++- .../features/auth/forms/LoginAccountForm.tsx | 3 +++ .../auth/forms/VerifyAccoiuntForm.tsx | 4 +++- frontend/src/hooks/useAuth.ts | 19 +++++++++++++++++++ frontend/src/store/auth/auth.store.ts | 17 +++++++++++++++++ frontend/src/store/auth/auth.types.ts | 4 ++++ frontend/yarn.lock | 5 +++++ 7 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 frontend/src/hooks/useAuth.ts create mode 100644 frontend/src/store/auth/auth.store.ts create mode 100644 frontend/src/store/auth/auth.types.ts diff --git a/frontend/package.json b/frontend/package.json index ee97116..24f2f82 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -31,7 +31,8 @@ "react-hook-form": "7.61.1", "sonner": "2.0.6", "tailwind-merge": "3.3.1", - "zod": "4.0.14" + "zod": "4.0.14", + "zustand": "5.0.7" }, "devDependencies": { "@eslint/eslintrc": "3.3.1", diff --git a/frontend/src/components/features/auth/forms/LoginAccountForm.tsx b/frontend/src/components/features/auth/forms/LoginAccountForm.tsx index 3e1ef16..1fab8d3 100644 --- a/frontend/src/components/features/auth/forms/LoginAccountForm.tsx +++ b/frontend/src/components/features/auth/forms/LoginAccountForm.tsx @@ -15,6 +15,7 @@ import { import { Input } from '@/components/ui/common/Input'; import { InputOTP, InputOTPGroup, InputOTPSlot } from '@/components/ui/common/InputOTP'; import { useLoginUserMutation } from '@/graphql/generated/output'; +import { useAuth } from '@/hooks/useAuth'; import { loginSchema } from '@/schemas/auth/login.schema'; import AuthWrapper from '../AuthWrapper'; @@ -25,6 +26,7 @@ const LoginAccountForm = () => { const t = useTranslations('auth.login'); const [isShowTwoFactor, setIsShowTwoFactor] = useState(false); const router = useRouter(); + const { auth } = useAuth(); const form = useForm({ resolver: zodResolver(loginSchema), @@ -40,6 +42,7 @@ const LoginAccountForm = () => { if (data.loginUser.message) { setIsShowTwoFactor(true); } else { + auth(); toast.success(t('successMessage')); router.push('/dashboard/settings'); } diff --git a/frontend/src/components/features/auth/forms/VerifyAccoiuntForm.tsx b/frontend/src/components/features/auth/forms/VerifyAccoiuntForm.tsx index a10cfe4..34726b6 100644 --- a/frontend/src/components/features/auth/forms/VerifyAccoiuntForm.tsx +++ b/frontend/src/components/features/auth/forms/VerifyAccoiuntForm.tsx @@ -7,6 +7,7 @@ import { useEffect } from 'react'; import { toast } from 'sonner'; import { useVerifyAccountMutation } from '@/graphql/generated/output'; +import { useAuth } from '@/hooks/useAuth'; import AuthWrapper from '../AuthWrapper'; @@ -16,11 +17,12 @@ type VerifyAccountFormProps = { export const VerifyAccountForm = (props: VerifyAccountFormProps) => { const { token } = props; const t = useTranslations('auth.verify'); - + const { auth } = useAuth(); const router = useRouter(); const [verify] = useVerifyAccountMutation({ onCompleted() { + auth(); toast.success(t('successMessage')); router.push('/dashboard/settings'); }, diff --git a/frontend/src/hooks/useAuth.ts b/frontend/src/hooks/useAuth.ts new file mode 100644 index 0000000..911f9e3 --- /dev/null +++ b/frontend/src/hooks/useAuth.ts @@ -0,0 +1,19 @@ +import { authStore } from '@/store/auth/auth.store'; + +export function useAuth() { + const isAuthenticated = authStore((state) => state.isAuthenticated); + const setIsAuthenticated = authStore((state) => state.setIsAuthenticated); + + const auth = () => { + setIsAuthenticated(true); + }; + const exit = () => { + setIsAuthenticated(false); + }; + + return { + isAuthenticated, + auth, + exit, + }; +} diff --git a/frontend/src/store/auth/auth.store.ts b/frontend/src/store/auth/auth.store.ts new file mode 100644 index 0000000..61c811a --- /dev/null +++ b/frontend/src/store/auth/auth.store.ts @@ -0,0 +1,17 @@ +import { create } from 'zustand'; +import { createJSONStorage, persist } from 'zustand/middleware'; + +import type { AuthStore } from './auth.types'; + +export const authStore = create( + persist( + (set) => ({ + isAuthenticated: false, + setIsAuthenticated: (value: boolean) => { set({ isAuthenticated: value }); }, + }), + { + name: 'auth', + storage: createJSONStorage(() => localStorage), + }, + ), +); diff --git a/frontend/src/store/auth/auth.types.ts b/frontend/src/store/auth/auth.types.ts new file mode 100644 index 0000000..5057309 --- /dev/null +++ b/frontend/src/store/auth/auth.types.ts @@ -0,0 +1,4 @@ +export type AuthStore = { + isAuthenticated: boolean; + setIsAuthenticated: (value: boolean) => void; +}; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index b7db4c2..c397df5 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -6003,3 +6003,8 @@ zod@4.0.14: version "4.0.14" resolved "https://registry.yarnpkg.com/zod/-/zod-4.0.14.tgz#cc3a0a21981e63e0f99c0f4f1decd92ec3be7e9f" integrity sha512-nGFJTnJN6cM2v9kXL+SOBq3AtjQby3Mv5ySGFof5UGRHrRioSJ5iG680cYNjE/yWk671nROcpPj4hAS8nyLhSw== + +zustand@5.0.7: + version "5.0.7" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-5.0.7.tgz#e325364e82c992a84bf386d8445aa7f180c450dc" + integrity sha512-Ot6uqHDW/O2VdYsKLLU8GQu8sCOM1LcoE8RwvLv9uuRT9s6SOHCKs0ZEOhxg+I1Ld+A1Q5lwx+UlKXXUoCZITg==