From 03dabfa3e9100d72d5db72d2f0197a2e512884e6 Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Tue, 18 Feb 2025 14:44:33 +0900 Subject: [PATCH 01/41] =?UTF-8?q?refactor=20:=20=ED=82=A4=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B3=B5=ED=86=B5?= =?UTF-8?q?=EB=82=B4=EC=9A=A9=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../template/ApiKeys/ApiKeyInfo.tsx | 23 +++++++ src/components/template/ApiKeys/Issued.tsx | 60 +++++++++---------- src/components/template/ApiKeys/NotIssued.tsx | 12 +--- src/components/template/ApiKeys/Separator.tsx | 7 +++ 4 files changed, 61 insertions(+), 41 deletions(-) create mode 100644 src/components/template/ApiKeys/ApiKeyInfo.tsx create mode 100644 src/components/template/ApiKeys/Separator.tsx diff --git a/src/components/template/ApiKeys/ApiKeyInfo.tsx b/src/components/template/ApiKeys/ApiKeyInfo.tsx new file mode 100644 index 0000000..672a4e8 --- /dev/null +++ b/src/components/template/ApiKeys/ApiKeyInfo.tsx @@ -0,0 +1,23 @@ +import { Link } from 'react-router-dom'; + +const ApiKeyInfo = () => { + return ( +
+

+ 한 계정당 키는 한개만 발급가능합니다 +

+

+ 갱신하면 새로운 키가 발급되어 기존의 키는 사용할 수 없습니다 +

+ + API 사용방법 + +
+ ); +}; + +export default ApiKeyInfo; diff --git a/src/components/template/ApiKeys/Issued.tsx b/src/components/template/ApiKeys/Issued.tsx index 8f63896..ee5fb0c 100644 --- a/src/components/template/ApiKeys/Issued.tsx +++ b/src/components/template/ApiKeys/Issued.tsx @@ -1,43 +1,39 @@ import { Button } from '@components/ui/button'; +import ApiKeyInfo from './ApiKeyInfo'; +import Separator from './Separator'; +import { createToastSuccess } from '@lib/toast'; const Issued = () => { + const handleCopy = () => { + const apiKey = document.getElementById('api-key')!.textContent!; + navigator.clipboard.writeText(apiKey).then(() => { + createToastSuccess('', 'API 키를 복사하였습니다.'); + }); + }; + return (
-

+

20241231-1234567890

-
- -
-

- 생성일시 : 2024-12-31 14:41:28 -

-

- 만료일시 : 2025-03-31 14:41:28 -

-
- -
-

- 한 계정당 키는 한 개만 발급 가능합니다 -

-

- 키의 유효기간은 3개월입니다 -

-

- 갱신하면 새로운 키가 발급되어 기존의 키는 사용할 수 없습니다 -

-

- 갱신은 만료기한 일주일전부터 가능합니다 -

-
- -
- - +

+ 복사하기 +

+ + + + + + + +
); }; diff --git a/src/components/template/ApiKeys/NotIssued.tsx b/src/components/template/ApiKeys/NotIssued.tsx index 13dbf22..172c7d5 100644 --- a/src/components/template/ApiKeys/NotIssued.tsx +++ b/src/components/template/ApiKeys/NotIssued.tsx @@ -1,20 +1,14 @@ import { Button } from '@components/ui/button'; +import ApiKeyInfo from './ApiKeyInfo'; const NotIssued = () => { return (
-

+

키 발급하기

-
-

- 한 계정당 키는 한개만 발급가능합니다 -

-

- 키의 유효기간은 3개월입니다 -

-
+
diff --git a/src/components/template/ApiKeys/Separator.tsx b/src/components/template/ApiKeys/Separator.tsx new file mode 100644 index 0000000..5d4c278 --- /dev/null +++ b/src/components/template/ApiKeys/Separator.tsx @@ -0,0 +1,7 @@ +const Separator = () => { + return ( +
+ ); +}; + +export default Separator; From dd823eefa099d9d02c252616b733d6d072e5df1f Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Tue, 18 Feb 2025 14:59:01 +0900 Subject: [PATCH 02/41] =?UTF-8?q?feat=20:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8/?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=97=94=ED=84=B0=ED=82=A4=EB=A1=9C=20submit=20=20?= =?UTF-8?q?=EA=B0=80=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/template/ApiKeys/Issued.tsx | 2 +- src/pages/LoginPage.tsx | 8 ++++++++ src/pages/SignupPage.tsx | 10 ++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/components/template/ApiKeys/Issued.tsx b/src/components/template/ApiKeys/Issued.tsx index ee5fb0c..0d53c50 100644 --- a/src/components/template/ApiKeys/Issued.tsx +++ b/src/components/template/ApiKeys/Issued.tsx @@ -21,7 +21,7 @@ const Issued = () => {

복사하기 diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index f2cd0b9..3c98818 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -32,6 +32,12 @@ const LoginPage = () => { } }; + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + handleLogin(); + } + }; + return (

@@ -40,6 +46,7 @@ const LoginPage = () => { className='h-12 rounded-xl' value={email} onChange={(e) => setEmail(e.target.value)} + onKeyDown={handleKeyDown} /> {errors.email && (

{errors.email}

@@ -52,6 +59,7 @@ const LoginPage = () => { className='h-12 rounded-xl' value={password} onChange={(e) => setPassword(e.target.value)} + onKeyDown={handleKeyDown} /> {errors.password && (

{errors.password}

diff --git a/src/pages/SignupPage.tsx b/src/pages/SignupPage.tsx index 0c9c3bf..59ba9ef 100644 --- a/src/pages/SignupPage.tsx +++ b/src/pages/SignupPage.tsx @@ -46,6 +46,12 @@ const SignupPage = () => { } }; + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + handleSignup(); + } + }; + return (
@@ -55,6 +61,7 @@ const SignupPage = () => { className='h-12 rounded-xl' value={formData.email} onChange={handleChange} + onKeyDown={handleKeyDown} /> {errors.email && (

{errors.email}

@@ -69,6 +76,7 @@ const SignupPage = () => { className='h-12 rounded-xl' value={formData.password} onChange={handleChange} + onKeyDown={handleKeyDown} /> {errors.password && (

{errors.password}

@@ -83,6 +91,7 @@ const SignupPage = () => { className='h-12 rounded-xl' value={formData.passwordConfirm} onChange={handleChange} + onKeyDown={handleKeyDown} /> {errors.passwordConfirm && (

{errors.passwordConfirm}

@@ -96,6 +105,7 @@ const SignupPage = () => { className='h-12 rounded-xl' value={formData.name} onChange={handleChange} + onKeyDown={handleKeyDown} /> {errors.name && (

{errors.name}

From 84678935b6e10757639b550f8bf461621869f58e Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Tue, 18 Feb 2025 16:00:03 +0900 Subject: [PATCH 03/41] =?UTF-8?q?feat=20:=20ProtectedRoute=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20&=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=9B=84=20?= =?UTF-8?q?=EC=9D=B4=EC=A0=84=ED=8E=98=EC=9D=B4=EC=A7=80=EB=A1=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../template/auth/ProtectedRoute.tsx | 17 +++++++++++++++++ src/hooks/useAuth.ts | 10 +++++++--- src/pages/LoginPage.tsx | 2 -- src/router.tsx | 19 ++++++++++++++++--- src/store/authStore.ts | 7 ++++++- 5 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 src/components/template/auth/ProtectedRoute.tsx diff --git a/src/components/template/auth/ProtectedRoute.tsx b/src/components/template/auth/ProtectedRoute.tsx new file mode 100644 index 0000000..0d18749 --- /dev/null +++ b/src/components/template/auth/ProtectedRoute.tsx @@ -0,0 +1,17 @@ +import { useAuthStore } from '@store/authStore'; +import { Navigate, useLocation } from 'react-router-dom'; + +interface ProtectedRouteProps { + children: React.ReactNode; +} + +export const ProtectedRoute = ({ children }: ProtectedRouteProps) => { + const { auth } = useAuthStore(); + const location = useLocation(); + + if (!auth) { + return ; + } + + return <>{children}; +}; diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts index 7c41061..3b48dc9 100644 --- a/src/hooks/useAuth.ts +++ b/src/hooks/useAuth.ts @@ -3,20 +3,24 @@ import { apiClient } from '@lib/api/apiClient'; import { API_ENDPOINTS } from '@constants/apiEndpoints'; import type { LoginReq, LoginRes, SignupReq } from '@type/auth'; import { createToastSuccess, createToastError } from '@lib/toast'; -import { useNavigate } from 'react-router-dom'; +import { useNavigate, useLocation } from 'react-router-dom'; import { useAuthStore } from '@store/authStore'; export const useLogin = () => { const navigate = useNavigate(); const setAuth = useAuthStore((state) => state.setAuth); + const location = useLocation(); return useMutation({ mutationFn: (data: LoginReq) => apiClient.post(API_ENDPOINTS.LOGIN, data), onSuccess: (response: LoginRes) => { setAuth(response.data); - createToastSuccess('로그인 성공', '메인 페이지로 이동합니다'); - navigate('/'); + sessionStorage.setItem('auth', JSON.stringify(response.data)); + createToastSuccess('', '로그인되었습니다'); + + const from = location.state?.from?.pathname || '/'; + navigate(from); }, onError: createToastError('로그인 실패'), }); diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index 3c98818..c774b47 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -22,8 +22,6 @@ const LoginPage = () => { const credentials = { email, password }; login(credentials); - // TODO: zustand로 인증 상태관리 (useLogin 훅에서 처리) - // TODO: 메인페이지로 리다이렉트 (useLogin 훅에서 처리) } catch (error) { if (error instanceof ZodError) { const formattedErrors = formatZodErrors(error); diff --git a/src/router.tsx b/src/router.tsx index 721da36..cd38d99 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -1,6 +1,7 @@ import Layout from '@components/template/Layout'; import { lazy } from 'react'; import { createBrowserRouter } from 'react-router-dom'; +import { ProtectedRoute } from '@components/template/auth/ProtectedRoute'; const MainPage = lazy(() => import('@pages/MainPage').then((module) => ({ default: module.default })), @@ -35,15 +36,27 @@ const routes = [ children: [ { path: '/', - element: , + element: ( + + + + ), }, { path: '/transactions', - element: , + element: ( + + + + ), }, { path: '/api-keys', - element: , + element: ( + + + + ), }, ], }, diff --git a/src/store/authStore.ts b/src/store/authStore.ts index 0f235f8..a3ffdb7 100644 --- a/src/store/authStore.ts +++ b/src/store/authStore.ts @@ -1,7 +1,12 @@ import { create } from 'zustand'; import type { AuthState } from '@type/zustand'; +const getStoredAuth = () => { + const storedAuth = sessionStorage.getItem('auth'); + return storedAuth ? JSON.parse(storedAuth) : null; +}; + export const useAuthStore = create((set) => ({ - auth: null, + auth: getStoredAuth(), setAuth: (auth) => set({ auth }), })); From e78801996ce428eb5b19002634e8222b21560748 Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Tue, 18 Feb 2025 16:24:15 +0900 Subject: [PATCH 04/41] =?UTF-8?q?refactor=20:=20=EC=9D=B8=EC=A6=9D?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?(=EC=84=B8=EC=85=98=EC=8A=A4=ED=86=A0=EB=A6=AC=EC=A7=80=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=ED=9B=84=20zustand=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=B5=9C=EC=B4=88=201=ED=9A=8C=EB=A7=8C=20=EC=B2=B4=ED=81=AC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useAuth.ts | 2 +- src/store/authStore.ts | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts index 3b48dc9..ea361e2 100644 --- a/src/hooks/useAuth.ts +++ b/src/hooks/useAuth.ts @@ -15,8 +15,8 @@ export const useLogin = () => { mutationFn: (data: LoginReq) => apiClient.post(API_ENDPOINTS.LOGIN, data), onSuccess: (response: LoginRes) => { - setAuth(response.data); sessionStorage.setItem('auth', JSON.stringify(response.data)); + setAuth(response.data); createToastSuccess('', '로그인되었습니다'); const from = location.state?.from?.pathname || '/'; diff --git a/src/store/authStore.ts b/src/store/authStore.ts index a3ffdb7..3dcef9f 100644 --- a/src/store/authStore.ts +++ b/src/store/authStore.ts @@ -7,6 +7,15 @@ const getStoredAuth = () => { }; export const useAuthStore = create((set) => ({ - auth: getStoredAuth(), + auth: null, setAuth: (auth) => set({ auth }), })); + +const initializeAuth = () => { + const auth = getStoredAuth(); + if (auth) { + useAuthStore.getState().setAuth(auth); + } +}; + +initializeAuth(); From fc6c0f8d237e57d087921479b0ee95ced296364e Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Tue, 18 Feb 2025 16:25:52 +0900 Subject: [PATCH 05/41] =?UTF-8?q?refactor=20:=20API=20=ED=98=B8=EC=B6=9C?= =?UTF-8?q?=20hook=20=EC=9C=84=EC=B9=98=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/{ => api}/useAuth.ts | 0 src/hooks/{ => api}/useKey.ts | 0 src/hooks/{ => api}/useTransaction.ts | 0 src/pages/LoginPage.tsx | 2 +- src/pages/SignupPage.tsx | 2 +- src/pages/TransactionsPage.tsx | 2 +- 6 files changed, 3 insertions(+), 3 deletions(-) rename src/hooks/{ => api}/useAuth.ts (100%) rename src/hooks/{ => api}/useKey.ts (100%) rename src/hooks/{ => api}/useTransaction.ts (100%) diff --git a/src/hooks/useAuth.ts b/src/hooks/api/useAuth.ts similarity index 100% rename from src/hooks/useAuth.ts rename to src/hooks/api/useAuth.ts diff --git a/src/hooks/useKey.ts b/src/hooks/api/useKey.ts similarity index 100% rename from src/hooks/useKey.ts rename to src/hooks/api/useKey.ts diff --git a/src/hooks/useTransaction.ts b/src/hooks/api/useTransaction.ts similarity index 100% rename from src/hooks/useTransaction.ts rename to src/hooks/api/useTransaction.ts diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index c774b47..cd630e6 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { Button } from '@components/ui/button'; import { Input } from '@components/ui/input'; -import { useLogin } from '@hooks/useAuth'; +import { useLogin } from '@hooks/api/useAuth'; import { ZodError } from 'zod'; import { formatZodErrors } from '@lib/zod'; import type { ZodFormErrors } from '@type/zod'; diff --git a/src/pages/SignupPage.tsx b/src/pages/SignupPage.tsx index 59ba9ef..7a29734 100644 --- a/src/pages/SignupPage.tsx +++ b/src/pages/SignupPage.tsx @@ -5,7 +5,7 @@ import { ZodError } from 'zod'; import { formatZodErrors } from '@lib/zod'; import type { ZodFormErrors } from '@type/zod'; import { signupSchema } from '@schema/auth'; -import { useSignup } from '@hooks/useAuth'; +import { useSignup } from '@hooks/api/useAuth'; import AuthLayout from '@components/template/auth/AuthLayout'; const SignupPage = () => { diff --git a/src/pages/TransactionsPage.tsx b/src/pages/TransactionsPage.tsx index edd1c82..03cd0aa 100644 --- a/src/pages/TransactionsPage.tsx +++ b/src/pages/TransactionsPage.tsx @@ -1,5 +1,5 @@ import Loader from '@components/template/Loader'; -import { useTransactions } from '@hooks/useTransaction'; +import { useTransactions } from '@hooks/api/useTransaction'; import Transactions from '@components/template/Transactions'; import Error from '@components/template/Error'; import { useAuthStore } from '@store/authStore'; From c3a0638e057e2633b08e8db5b3a4cc5ae5419248 Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Wed, 19 Feb 2025 10:18:28 +0900 Subject: [PATCH 06/41] =?UTF-8?q?refactor=20:=20API=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=84=B0=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/template/auth/ProtectedRoute.tsx | 4 ++-- src/constants/routes.ts | 7 +++++++ src/constants/sidebar.ts | 6 +++--- src/hooks/api/useAuth.ts | 3 ++- src/pages/MainPage.tsx | 3 ++- src/pages/TransactionsPage.tsx | 4 +--- src/router.tsx | 14 +++++++------- 7 files changed, 24 insertions(+), 17 deletions(-) create mode 100644 src/constants/routes.ts diff --git a/src/components/template/auth/ProtectedRoute.tsx b/src/components/template/auth/ProtectedRoute.tsx index 0d18749..9922b28 100644 --- a/src/components/template/auth/ProtectedRoute.tsx +++ b/src/components/template/auth/ProtectedRoute.tsx @@ -1,6 +1,6 @@ import { useAuthStore } from '@store/authStore'; import { Navigate, useLocation } from 'react-router-dom'; - +import { ROUTES } from '@constants/routes'; interface ProtectedRouteProps { children: React.ReactNode; } @@ -10,7 +10,7 @@ export const ProtectedRoute = ({ children }: ProtectedRouteProps) => { const location = useLocation(); if (!auth) { - return ; + return ; } return <>{children}; diff --git a/src/constants/routes.ts b/src/constants/routes.ts new file mode 100644 index 0000000..901549c --- /dev/null +++ b/src/constants/routes.ts @@ -0,0 +1,7 @@ +export const ROUTES = { + MAIN: '/', + LOGIN: '/login', + SIGNUP: '/signup', + TRANSACTIONS: '/transactions', + KEY_MANAGEMENT: '/key-management', +}; diff --git a/src/constants/sidebar.ts b/src/constants/sidebar.ts index 446df56..0523f59 100644 --- a/src/constants/sidebar.ts +++ b/src/constants/sidebar.ts @@ -1,5 +1,5 @@ import * as LucideIcons from 'lucide-react'; - +import { ROUTES } from '@constants/routes'; export const sideBarItems: { name: string; icon: keyof typeof LucideIcons; @@ -8,11 +8,11 @@ export const sideBarItems: { { name: '거래내역', icon: 'FileText', - link: '/transactions', + link: ROUTES.TRANSACTIONS, }, { name: '키 관리', icon: 'KeyRound', - link: '/api-keys', + link: ROUTES.KEY_MANAGEMENT, }, ]; diff --git a/src/hooks/api/useAuth.ts b/src/hooks/api/useAuth.ts index ea361e2..70917ee 100644 --- a/src/hooks/api/useAuth.ts +++ b/src/hooks/api/useAuth.ts @@ -5,6 +5,7 @@ import type { LoginReq, LoginRes, SignupReq } from '@type/auth'; import { createToastSuccess, createToastError } from '@lib/toast'; import { useNavigate, useLocation } from 'react-router-dom'; import { useAuthStore } from '@store/authStore'; +import { ROUTES } from '@constants/routes'; export const useLogin = () => { const navigate = useNavigate(); @@ -33,7 +34,7 @@ export const useSignup = () => { mutationFn: (data: SignupReq) => apiClient.post(API_ENDPOINTS.SIGNUP, data), onSuccess: () => { createToastSuccess('회원가입 성공', '로그인 페이지로 이동합니다'); - navigate('/login'); + navigate(ROUTES.LOGIN); }, onError: createToastError('회원가입 실패'), }); diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx index f5d66c6..466f710 100644 --- a/src/pages/MainPage.tsx +++ b/src/pages/MainPage.tsx @@ -1,7 +1,8 @@ import { Navigate } from 'react-router-dom'; +import { ROUTES } from '@constants/routes'; const MainPage = () => { - return ; + return ; }; export default MainPage; diff --git a/src/pages/TransactionsPage.tsx b/src/pages/TransactionsPage.tsx index 03cd0aa..4b33edf 100644 --- a/src/pages/TransactionsPage.tsx +++ b/src/pages/TransactionsPage.tsx @@ -2,11 +2,9 @@ import Loader from '@components/template/Loader'; import { useTransactions } from '@hooks/api/useTransaction'; import Transactions from '@components/template/Transactions'; import Error from '@components/template/Error'; -import { useAuthStore } from '@store/authStore'; + const TransactionsPage = () => { const { data, isLoading, isError } = useTransactions(); - const { auth } = useAuthStore(); - console.log(auth); if (isLoading) return ; else if (isError) return ; diff --git a/src/router.tsx b/src/router.tsx index cd38d99..dd91c7c 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -2,7 +2,7 @@ import Layout from '@components/template/Layout'; import { lazy } from 'react'; import { createBrowserRouter } from 'react-router-dom'; import { ProtectedRoute } from '@components/template/auth/ProtectedRoute'; - +import { ROUTES } from '@constants/routes'; const MainPage = lazy(() => import('@pages/MainPage').then((module) => ({ default: module.default })), ); @@ -23,19 +23,19 @@ const SignupPage = lazy(() => const routes = [ { - path: '/login', + path: ROUTES.LOGIN, element: , }, { - path: '/signup', + path: ROUTES.SIGNUP, element: , }, { - path: '/', + path: ROUTES.MAIN, element: , children: [ { - path: '/', + path: ROUTES.MAIN, element: ( @@ -43,7 +43,7 @@ const routes = [ ), }, { - path: '/transactions', + path: ROUTES.TRANSACTIONS, element: ( @@ -51,7 +51,7 @@ const routes = [ ), }, { - path: '/api-keys', + path: ROUTES.KEY_MANAGEMENT, element: ( From c9b45871a8f6ea6c52b00a31608e2e6cfe6b926d Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Wed, 19 Feb 2025 10:22:49 +0900 Subject: [PATCH 07/41] =?UTF-8?q?refactor=20:=20=ED=82=A4=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/sidebar.ts | 1 + src/pages/{ApiKeysPage.tsx => KeyManagementPage.tsx} | 0 src/router.tsx | 9 ++++++--- 3 files changed, 7 insertions(+), 3 deletions(-) rename src/pages/{ApiKeysPage.tsx => KeyManagementPage.tsx} (100%) diff --git a/src/constants/sidebar.ts b/src/constants/sidebar.ts index 0523f59..15f811c 100644 --- a/src/constants/sidebar.ts +++ b/src/constants/sidebar.ts @@ -1,5 +1,6 @@ import * as LucideIcons from 'lucide-react'; import { ROUTES } from '@constants/routes'; + export const sideBarItems: { name: string; icon: keyof typeof LucideIcons; diff --git a/src/pages/ApiKeysPage.tsx b/src/pages/KeyManagementPage.tsx similarity index 100% rename from src/pages/ApiKeysPage.tsx rename to src/pages/KeyManagementPage.tsx diff --git a/src/router.tsx b/src/router.tsx index dd91c7c..67ba931 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -3,6 +3,7 @@ import { lazy } from 'react'; import { createBrowserRouter } from 'react-router-dom'; import { ProtectedRoute } from '@components/template/auth/ProtectedRoute'; import { ROUTES } from '@constants/routes'; + const MainPage = lazy(() => import('@pages/MainPage').then((module) => ({ default: module.default })), ); @@ -14,8 +15,10 @@ const TransactionsPage = lazy(() => default: module.default, })), ); -const ApiKeysPage = lazy(() => - import('@pages/ApiKeysPage').then((module) => ({ default: module.default })), +const KeyManagementPage = lazy(() => + import('@pages/KeyManagementPage').then((module) => ({ + default: module.default, + })), ); const SignupPage = lazy(() => import('@pages/SignupPage').then((module) => ({ default: module.default })), @@ -54,7 +57,7 @@ const routes = [ path: ROUTES.KEY_MANAGEMENT, element: ( - + ), }, From 82cabba8f44023eb010fa642045ed126bcaf42d0 Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Wed, 19 Feb 2025 12:17:56 +0900 Subject: [PATCH 08/41] =?UTF-8?q?feat=20:=20=ED=82=A4=20=EA=B0=B1=EC=8B=A0?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/template/ApiKeys/Issued.tsx | 25 ++++++++++++++++++++-- src/hooks/api/useKey.ts | 5 +++-- src/types/key.ts | 7 ++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/components/template/ApiKeys/Issued.tsx b/src/components/template/ApiKeys/Issued.tsx index 0d53c50..b081208 100644 --- a/src/components/template/ApiKeys/Issued.tsx +++ b/src/components/template/ApiKeys/Issued.tsx @@ -2,8 +2,15 @@ import { Button } from '@components/ui/button'; import ApiKeyInfo from './ApiKeyInfo'; import Separator from './Separator'; import { createToastSuccess } from '@lib/toast'; +import { useKey } from '@hooks/api/useKey'; +import { useAuthStore } from '@store/authStore'; +import { useState } from 'react'; const Issued = () => { + const [apiKey, setApiKey] = useState('20241231-1234567890'); + const { mutate: renewKey } = useKey(); + const { auth } = useAuthStore(); + const handleCopy = () => { const apiKey = document.getElementById('api-key')!.textContent!; navigator.clipboard.writeText(apiKey).then(() => { @@ -11,13 +18,25 @@ const Issued = () => { }); }; + const handleRenew = () => { + renewKey( + { id: auth!.id }, + { + onSuccess: ({ data }) => { + setApiKey(data.key); + createToastSuccess('', 'API 키가 성공적으로 갱신되었습니다.'); + }, + }, + ); + }; + return (

- 20241231-1234567890 + {apiKey}

{ - +

); }; diff --git a/src/hooks/api/useKey.ts b/src/hooks/api/useKey.ts index 3d0f2be..3e1ea7a 100644 --- a/src/hooks/api/useKey.ts +++ b/src/hooks/api/useKey.ts @@ -1,10 +1,11 @@ import { useMutation } from '@tanstack/react-query'; import { apiClient } from '@lib/api/apiClient'; import { API_ENDPOINTS } from '@constants/apiEndpoints'; -import type { KeyReq } from '@type/key'; +import type { KeyReq, KeyRes } from '@type/key'; export const useKey = () => { return useMutation({ - mutationFn: (data: KeyReq) => apiClient.post(API_ENDPOINTS.KEY, data), + mutationFn: (data: KeyReq) => + apiClient.post(API_ENDPOINTS.KEY, data), }); }; diff --git a/src/types/key.ts b/src/types/key.ts index cd83032..bdfc348 100644 --- a/src/types/key.ts +++ b/src/types/key.ts @@ -1,3 +1,10 @@ export type KeyReq = { id: string; }; + +export type KeyRes = { + ok: boolean; + data: { + key: string; + }; +}; From cdaae1432cb236a460bfbce6e7e33268619412d3 Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Wed, 19 Feb 2025 12:21:04 +0900 Subject: [PATCH 09/41] =?UTF-8?q?refactor=20:=20=ED=82=A4=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=EA=B4=80=EB=A0=A8=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/template/{ApiKeys => Key}/ApiKeyInfo.tsx | 0 src/components/template/{ApiKeys => Key}/Issued.tsx | 0 src/components/template/{ApiKeys => Key}/NotIssued.tsx | 0 src/components/template/{ApiKeys => Key}/Separator.tsx | 0 src/pages/KeyManagementPage.tsx | 4 ++-- 5 files changed, 2 insertions(+), 2 deletions(-) rename src/components/template/{ApiKeys => Key}/ApiKeyInfo.tsx (100%) rename src/components/template/{ApiKeys => Key}/Issued.tsx (100%) rename src/components/template/{ApiKeys => Key}/NotIssued.tsx (100%) rename src/components/template/{ApiKeys => Key}/Separator.tsx (100%) diff --git a/src/components/template/ApiKeys/ApiKeyInfo.tsx b/src/components/template/Key/ApiKeyInfo.tsx similarity index 100% rename from src/components/template/ApiKeys/ApiKeyInfo.tsx rename to src/components/template/Key/ApiKeyInfo.tsx diff --git a/src/components/template/ApiKeys/Issued.tsx b/src/components/template/Key/Issued.tsx similarity index 100% rename from src/components/template/ApiKeys/Issued.tsx rename to src/components/template/Key/Issued.tsx diff --git a/src/components/template/ApiKeys/NotIssued.tsx b/src/components/template/Key/NotIssued.tsx similarity index 100% rename from src/components/template/ApiKeys/NotIssued.tsx rename to src/components/template/Key/NotIssued.tsx diff --git a/src/components/template/ApiKeys/Separator.tsx b/src/components/template/Key/Separator.tsx similarity index 100% rename from src/components/template/ApiKeys/Separator.tsx rename to src/components/template/Key/Separator.tsx diff --git a/src/pages/KeyManagementPage.tsx b/src/pages/KeyManagementPage.tsx index 4f29e46..8b18ca3 100644 --- a/src/pages/KeyManagementPage.tsx +++ b/src/pages/KeyManagementPage.tsx @@ -1,5 +1,5 @@ -import Issued from '@components/template/ApiKeys/Issued'; -import NotIssued from '@components/template/ApiKeys/NotIssued'; +import Issued from '@components/template/Key/Issued'; +import NotIssued from '@components/template/Key/NotIssued'; const KEY_ISSUED = true; From 1cbe0acfb55298ab6e721167bd82eeb51fb2011e Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Wed, 19 Feb 2025 12:22:43 +0900 Subject: [PATCH 10/41] =?UTF-8?q?refactor=20:=20=ED=82=A4=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=EA=B4=80=EB=A0=A8=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/template/Key/{ApiKeyInfo.tsx => Info.tsx} | 0 src/components/template/Key/Issued.tsx | 4 ++-- src/components/template/Key/NotIssued.tsx | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename src/components/template/Key/{ApiKeyInfo.tsx => Info.tsx} (100%) diff --git a/src/components/template/Key/ApiKeyInfo.tsx b/src/components/template/Key/Info.tsx similarity index 100% rename from src/components/template/Key/ApiKeyInfo.tsx rename to src/components/template/Key/Info.tsx diff --git a/src/components/template/Key/Issued.tsx b/src/components/template/Key/Issued.tsx index b081208..7838e50 100644 --- a/src/components/template/Key/Issued.tsx +++ b/src/components/template/Key/Issued.tsx @@ -1,5 +1,5 @@ import { Button } from '@components/ui/button'; -import ApiKeyInfo from './ApiKeyInfo'; +import Info from './Info'; import Separator from './Separator'; import { createToastSuccess } from '@lib/toast'; import { useKey } from '@hooks/api/useKey'; @@ -48,7 +48,7 @@ const Issued = () => { - + diff --git a/src/components/template/Key/NotIssued.tsx b/src/components/template/Key/NotIssued.tsx index 172c7d5..0929d75 100644 --- a/src/components/template/Key/NotIssued.tsx +++ b/src/components/template/Key/NotIssued.tsx @@ -1,5 +1,5 @@ import { Button } from '@components/ui/button'; -import ApiKeyInfo from './ApiKeyInfo'; +import Info from './Info'; const NotIssued = () => { return ( @@ -8,7 +8,7 @@ const NotIssued = () => { 키 발급하기 - +
From 272b8c371fc6daa6cb3c7b5ffab3a834a3d53d16 Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Wed, 19 Feb 2025 13:32:13 +0900 Subject: [PATCH 11/41] =?UTF-8?q?chore=20:=20proxy=20host=20env=EB=A1=9C?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vite.config.ts | 52 ++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index 2c480a6..d763513 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,34 +1,36 @@ -import { defineConfig } from 'vite'; +import { defineConfig, loadEnv } from 'vite'; import react from '@vitejs/plugin-react-swc'; import path from 'path'; // https://vite.dev/config/ -export default defineConfig({ - plugins: [react()], - resolve: { - alias: { - '@api': path.resolve(__dirname, './src/api'), - '@components': path.resolve(__dirname, './src/components'), - '@constants': path.resolve(__dirname, './src/constants'), - '@hooks': path.resolve(__dirname, './src/hooks'), - '@lib': path.resolve(__dirname, './src/lib'), - '@mocks': path.resolve(__dirname, './src/mocks'), - '@pages': path.resolve(__dirname, './src/pages'), - '@type': path.resolve(__dirname, './src/types'), - '@schema': path.resolve(__dirname, './src/schema'), - '@store': path.resolve(__dirname, './src/store'), +export default defineConfig(({ mode }) => { + const env = loadEnv(mode, process.cwd()); + + return { + plugins: [react()], + resolve: { + alias: { + '@api': path.resolve(__dirname, './src/api'), + '@components': path.resolve(__dirname, './src/components'), + '@constants': path.resolve(__dirname, './src/constants'), + '@hooks': path.resolve(__dirname, './src/hooks'), + '@lib': path.resolve(__dirname, './src/lib'), + '@mocks': path.resolve(__dirname, './src/mocks'), + '@pages': path.resolve(__dirname, './src/pages'), + '@type': path.resolve(__dirname, './src/types'), + '@schema': path.resolve(__dirname, './src/schema'), + '@store': path.resolve(__dirname, './src/store'), + }, }, - }, - server: { - proxy: { - '/api': { - target: 'https://backoffice.pay-200.com', - changeOrigin: true, - rewrite: (path) => path.replace(/^\/api/, ''), - secure: false, - ws: true, + server: { + proxy: { + '/api': { + target: env.VITE_API_URL, + changeOrigin: true, + rewrite: (path) => path.replace(/^\/api/, ''), + }, }, }, - }, + }; }); From 48af003b19621ad26af2b75bf251dca8a60617a6 Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Thu, 20 Feb 2025 14:41:17 +0900 Subject: [PATCH 12/41] =?UTF-8?q?feat=20:=20=ED=82=A4=20=EA=B0=B1=EC=8B=A0?= =?UTF-8?q?=20-=20=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8,=20res=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/template/Key/Issued.tsx | 2 +- src/constants/apiEndpoints.ts | 2 +- src/types/key.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/template/Key/Issued.tsx b/src/components/template/Key/Issued.tsx index 7838e50..5464555 100644 --- a/src/components/template/Key/Issued.tsx +++ b/src/components/template/Key/Issued.tsx @@ -23,7 +23,7 @@ const Issued = () => { { id: auth!.id }, { onSuccess: ({ data }) => { - setApiKey(data.key); + setApiKey(data.apiKey); createToastSuccess('', 'API 키가 성공적으로 갱신되었습니다.'); }, }, diff --git a/src/constants/apiEndpoints.ts b/src/constants/apiEndpoints.ts index b11634b..cc0c732 100644 --- a/src/constants/apiEndpoints.ts +++ b/src/constants/apiEndpoints.ts @@ -13,5 +13,5 @@ export const API_ENDPOINTS = { PAYMENTS: getPaymentsEndpoint, TRANSACTIONS: getTransactionEndpoint, }, - KEY: `${BASE_URL}/key`, + KEY: `${BASE_URL}/keys`, } as const; diff --git a/src/types/key.ts b/src/types/key.ts index bdfc348..dcaca40 100644 --- a/src/types/key.ts +++ b/src/types/key.ts @@ -5,6 +5,6 @@ export type KeyReq = { export type KeyRes = { ok: boolean; data: { - key: string; + apiKey: string; }; }; From d6a64d16d082e50d018a72d54cfa49959c22006d Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Thu, 20 Feb 2025 15:19:45 +0900 Subject: [PATCH 13/41] =?UTF-8?q?feat=20:=20=ED=82=A4=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20API=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/template/Key/Issued.tsx | 8 ++++---- src/constants/apiEndpoints.ts | 5 ++++- src/hooks/api/useKey.ts | 11 ----------- src/hooks/api/useKeys.ts | 18 ++++++++++++++++++ src/pages/KeyManagementPage.tsx | 13 ++++++++++--- 5 files changed, 36 insertions(+), 19 deletions(-) delete mode 100644 src/hooks/api/useKey.ts create mode 100644 src/hooks/api/useKeys.ts diff --git a/src/components/template/Key/Issued.tsx b/src/components/template/Key/Issued.tsx index 5464555..f72f558 100644 --- a/src/components/template/Key/Issued.tsx +++ b/src/components/template/Key/Issued.tsx @@ -2,13 +2,13 @@ import { Button } from '@components/ui/button'; import Info from './Info'; import Separator from './Separator'; import { createToastSuccess } from '@lib/toast'; -import { useKey } from '@hooks/api/useKey'; +import { useKeys } from '@hooks/api/useKeys'; import { useAuthStore } from '@store/authStore'; import { useState } from 'react'; -const Issued = () => { - const [apiKey, setApiKey] = useState('20241231-1234567890'); - const { mutate: renewKey } = useKey(); +const Issued = ({ issuedApiKey }: { issuedApiKey: string }) => { + const [apiKey, setApiKey] = useState(issuedApiKey); + const { mutate: renewKey } = useKeys(); const { auth } = useAuthStore(); const handleCopy = () => { diff --git a/src/constants/apiEndpoints.ts b/src/constants/apiEndpoints.ts index cc0c732..dba9f8b 100644 --- a/src/constants/apiEndpoints.ts +++ b/src/constants/apiEndpoints.ts @@ -13,5 +13,8 @@ export const API_ENDPOINTS = { PAYMENTS: getPaymentsEndpoint, TRANSACTIONS: getTransactionEndpoint, }, - KEY: `${BASE_URL}/keys`, + MANAGEMENT: { + KEYS: `${BASE_URL}/keys`, + ID: (id: string) => `${BASE_URL}/keys/${id}`, + }, } as const; diff --git a/src/hooks/api/useKey.ts b/src/hooks/api/useKey.ts deleted file mode 100644 index 3e1ea7a..0000000 --- a/src/hooks/api/useKey.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { useMutation } from '@tanstack/react-query'; -import { apiClient } from '@lib/api/apiClient'; -import { API_ENDPOINTS } from '@constants/apiEndpoints'; -import type { KeyReq, KeyRes } from '@type/key'; - -export const useKey = () => { - return useMutation({ - mutationFn: (data: KeyReq) => - apiClient.post(API_ENDPOINTS.KEY, data), - }); -}; diff --git a/src/hooks/api/useKeys.ts b/src/hooks/api/useKeys.ts new file mode 100644 index 0000000..a2df1b0 --- /dev/null +++ b/src/hooks/api/useKeys.ts @@ -0,0 +1,18 @@ +import { useMutation, useQuery } from '@tanstack/react-query'; +import { apiClient } from '@lib/api/apiClient'; +import { API_ENDPOINTS } from '@constants/apiEndpoints'; +import type { KeyReq, KeyRes } from '@type/key'; + +export const useKeys = () => { + return useMutation({ + mutationFn: (data: KeyReq) => + apiClient.post(API_ENDPOINTS.MANAGEMENT.KEYS, data), + }); +}; + +export const useKeysId = (id: string) => { + return useQuery({ + queryKey: ['get-key'], + queryFn: () => apiClient.get(API_ENDPOINTS.MANAGEMENT.ID(id)), + }); +}; diff --git a/src/pages/KeyManagementPage.tsx b/src/pages/KeyManagementPage.tsx index 8b18ca3..7ab7ade 100644 --- a/src/pages/KeyManagementPage.tsx +++ b/src/pages/KeyManagementPage.tsx @@ -1,10 +1,17 @@ import Issued from '@components/template/Key/Issued'; import NotIssued from '@components/template/Key/NotIssued'; - -const KEY_ISSUED = true; +import Loader from '@components/template/Loader'; +import { useKeysId } from '@hooks/api/useKeys'; +import { useAuthStore } from '@store/authStore'; const ApiKeysPage = () => { - return KEY_ISSUED ? : ; + const { auth } = useAuthStore(); + const { data, isLoading } = useKeysId(auth!.id); + + if (isLoading) return ; + else { + return data ? : ; + } }; export default ApiKeysPage; From 96957cd2e29c3214b3e716e9bf379620bf570941 Mon Sep 17 00:00:00 2001 From: happyboyhj-redtable Date: Thu, 20 Feb 2025 15:41:36 +0900 Subject: [PATCH 14/41] =?UTF-8?q?feat=20:=20NotIssed=20=EC=A7=84=ED=96=89?= =?UTF-8?q?=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/template/Key/NotIssued.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/template/Key/NotIssued.tsx b/src/components/template/Key/NotIssued.tsx index 0929d75..f66b6a2 100644 --- a/src/components/template/Key/NotIssued.tsx +++ b/src/components/template/Key/NotIssued.tsx @@ -2,6 +2,11 @@ import { Button } from '@components/ui/button'; import Info from './Info'; const NotIssued = () => { + // const handleIssue = () => { + // // TODO: 키 발급 API 호출 + // // TODO: 성공 후 Issued 컴포넌트로 이동 => 컴포넌트 렌더를 결정하는 변수가 상위 컴포넌트에 있음 + // }; + return (

From 078ce623c15ef8777a1b56e86e7029488323bce7 Mon Sep 17 00:00:00 2001 From: h-genie Date: Thu, 20 Feb 2025 16:32:05 +0900 Subject: [PATCH 15/41] =?UTF-8?q?refactor=20:=20NotIssued=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/template/Key/NotIssued.tsx | 31 ++++++++++++++++++----- src/pages/KeyManagementPage.tsx | 25 +++++++++++++++--- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/components/template/Key/NotIssued.tsx b/src/components/template/Key/NotIssued.tsx index f66b6a2..700a389 100644 --- a/src/components/template/Key/NotIssued.tsx +++ b/src/components/template/Key/NotIssued.tsx @@ -1,11 +1,28 @@ import { Button } from '@components/ui/button'; import Info from './Info'; +import { useAuthStore } from '@store/authStore'; +import { useKeys } from '@hooks/api/useKeys'; +import { createToastSuccess } from '@lib/toast'; -const NotIssued = () => { - // const handleIssue = () => { - // // TODO: 키 발급 API 호출 - // // TODO: 성공 후 Issued 컴포넌트로 이동 => 컴포넌트 렌더를 결정하는 변수가 상위 컴포넌트에 있음 - // }; +const NotIssued = ({ + onIssueSuccess, +}: { + onIssueSuccess: (value: string) => void; +}) => { + const { auth } = useAuthStore(); + const { mutate: renewKey } = useKeys(); + + const handleIssue = () => { + renewKey( + { id: auth!.id }, + { + onSuccess: ({ data }) => { + createToastSuccess('', 'API 키가 성공적으로 발급되었습니다.'); + onIssueSuccess(data.apiKey); + }, + }, + ); + }; return (
@@ -15,7 +32,9 @@ const NotIssued = () => { - +
); }; diff --git a/src/pages/KeyManagementPage.tsx b/src/pages/KeyManagementPage.tsx index 7ab7ade..15b86d2 100644 --- a/src/pages/KeyManagementPage.tsx +++ b/src/pages/KeyManagementPage.tsx @@ -1,17 +1,34 @@ +import Error from '@components/template/Error'; import Issued from '@components/template/Key/Issued'; import NotIssued from '@components/template/Key/NotIssued'; import Loader from '@components/template/Loader'; import { useKeysId } from '@hooks/api/useKeys'; import { useAuthStore } from '@store/authStore'; +import { useState, useEffect } from 'react'; const ApiKeysPage = () => { const { auth } = useAuthStore(); - const { data, isLoading } = useKeysId(auth!.id); + const { data, isLoading, isError } = useKeysId(auth!.id); + const [issuedApiKey, setIssuedApiKey] = useState( + null, + ); + + useEffect(() => { + const apiKey = data?.data.apiKey; + if (apiKey) setIssuedApiKey(apiKey); + }, [data]); if (isLoading) return ; - else { - return data ? : ; - } + else if (isError) return ; + return issuedApiKey ? ( + + ) : ( + { + setIssuedApiKey(newApiKey); + }} + /> + ); }; export default ApiKeysPage; From 202f3f86dd2f339d6e2edefa1a9b8d16da47c4c2 Mon Sep 17 00:00:00 2001 From: h-genie Date: Thu, 20 Feb 2025 16:34:13 +0900 Subject: [PATCH 16/41] =?UTF-8?q?feat=20:=20Sidebar=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=EC=9D=B4=EB=A6=84=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/template/SideBar/index.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/template/SideBar/index.tsx b/src/components/template/SideBar/index.tsx index 6d95949..4ac3856 100644 --- a/src/components/template/SideBar/index.tsx +++ b/src/components/template/SideBar/index.tsx @@ -1,15 +1,16 @@ import { sideBarItems } from '@constants/sidebar.ts'; import SideBarItem from './SideBarItem.tsx'; import { useLocation } from 'react-router-dom'; - +import { useAuthStore } from '@store/authStore'; const SideBar = () => { const { pathname } = useLocation(); + const { auth } = useAuthStore(); return (