From e6eda9514aee160f709ee9d0c1cbc6879ddaba99 Mon Sep 17 00:00:00 2001 From: pwc2002 Date: Thu, 28 Aug 2025 02:38:27 +0900 Subject: [PATCH 01/20] =?UTF-8?q?Fix:=20=EC=A0=95=EC=A0=81=EB=B0=B0?= =?UTF-8?q?=ED=8F=AC=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EB=B0=8F=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EB=B9=84?= =?UTF-8?q?=ED=99=9C=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next.config.ts | 1 + .../signin/[social]/callback/page.jsx | 0 src/app/_auth/signin/layout.js | 16 ++ src/app/_auth/signin/page.jsx | 146 ++++++++++++++ src/app/_auth/signup/layout.js | 16 ++ src/app/_auth/signup/page.jsx | 178 ++++++++++++++++++ .../(dashboard)/admin/[id]/page.jsx | 0 .../(dashboard)/admin/page.jsx | 0 .../(dashboard)/my/[id]/page.jsx | 0 .../{study => _study}/(dashboard)/my/page.jsx | 0 src/app/{study => _study}/apply/[id]/page.jsx | 0 src/app/{study => _study}/create/page.jsx | 0 .../{study => _study}/detail/[id]/page.jsx | 0 src/app/{study => _study}/layout.js | 0 src/app/{study => _study}/loading.js | 0 src/app/{study => _study}/page.jsx | 0 src/app/robots.js | 3 + src/app/sitemap.js | 2 + src/hooks/useAuthApi.js | 11 +- src/middleware.ts | 50 ----- .../auth/signin/custom/CustomAuthApi.js | 17 +- yarn.lock | 30 +-- 22 files changed, 382 insertions(+), 88 deletions(-) rename src/app/{auth => _auth}/signin/[social]/callback/page.jsx (100%) create mode 100644 src/app/_auth/signin/layout.js create mode 100644 src/app/_auth/signin/page.jsx create mode 100644 src/app/_auth/signup/layout.js create mode 100644 src/app/_auth/signup/page.jsx rename src/app/{study => _study}/(dashboard)/admin/[id]/page.jsx (100%) rename src/app/{study => _study}/(dashboard)/admin/page.jsx (100%) rename src/app/{study => _study}/(dashboard)/my/[id]/page.jsx (100%) rename src/app/{study => _study}/(dashboard)/my/page.jsx (100%) rename src/app/{study => _study}/apply/[id]/page.jsx (100%) rename src/app/{study => _study}/create/page.jsx (100%) rename src/app/{study => _study}/detail/[id]/page.jsx (100%) rename src/app/{study => _study}/layout.js (100%) rename src/app/{study => _study}/loading.js (100%) rename src/app/{study => _study}/page.jsx (100%) delete mode 100644 src/middleware.ts diff --git a/next.config.ts b/next.config.ts index 53e79c6..045fe10 100644 --- a/next.config.ts +++ b/next.config.ts @@ -5,6 +5,7 @@ const nextConfig: NextConfig = { unoptimized: true, }, trailingSlash: true, + output: 'export', }; export default nextConfig; \ No newline at end of file diff --git a/src/app/auth/signin/[social]/callback/page.jsx b/src/app/_auth/signin/[social]/callback/page.jsx similarity index 100% rename from src/app/auth/signin/[social]/callback/page.jsx rename to src/app/_auth/signin/[social]/callback/page.jsx diff --git a/src/app/_auth/signin/layout.js b/src/app/_auth/signin/layout.js new file mode 100644 index 0000000..e7d2bb0 --- /dev/null +++ b/src/app/_auth/signin/layout.js @@ -0,0 +1,16 @@ +//import { Suspense } from "react"; +import Header2 from '@/components/ui/common/Header2'; + +export const metadata = { + title: "SignIn", + description: "SignIn to your account", +}; + +export default function SignInLayout({ children }) { + return ( +
+ + {children} +
+ ); +} \ No newline at end of file diff --git a/src/app/_auth/signin/page.jsx b/src/app/_auth/signin/page.jsx new file mode 100644 index 0000000..43d60b2 --- /dev/null +++ b/src/app/_auth/signin/page.jsx @@ -0,0 +1,146 @@ +'use client'; + +import { useState } from 'react'; +import { useRouter } from 'next/navigation'; +import Image from 'next/image'; + +import Header2 from '@/components/ui/common/Header2'; +import Loader from '@/components/ui/common/Loader'; + +import AuthLogin from '@/components/auth/screen/AuthLogin'; +import AuthFindId from '@/components/auth/screen/AuthFindId'; +import AuthResetPassword from '@/components/auth/screen/AuthResetPassword'; +import AuthResetRequest from '@/components/auth/screen/AuthResetRequest'; + +import { GoogleLogin } from '@/services/auth/signin/google/GoogleLogin'; +import { login } from '@/services/auth/signin/custom/CustomAuthApi'; + +import { useAuth } from '@/hooks/useAuth'; + +import loginBg from '@public/images/bgimg.png'; + +export default function Page() { + const router = useRouter(); + const { setAccessToken } = useAuth(); + const { handleGoogleLogin } = GoogleLogin(); + + const [password, setPassword] = useState(''); + const [errors, setErrors] = useState([]); + const [isRendering, setIsRendering] = useState(0); + const [loading, setLoading] = useState(false); + + const handleBackToLogin = () => setIsRendering(0); + const handleFindIdClick = () => setIsRendering(1); + const handleResetPasswordClick = () => setIsRendering(2); + const handleBackToResetRequest = () => setIsRendering(2); + const handleResetPasswordNext = () => setIsRendering(3); + + const validatePassword = (password) => { + const newErrors = []; + if (password.length <= 0) { + newErrors.push('비밀번호를 입력해주세요.'); + } + return newErrors; + }; + + const onSubmit = async (e) => { + e.preventDefault(); + + const formData = Object.fromEntries(new FormData(e.currentTarget)); + const passwordErrors = validatePassword(password); + + if (passwordErrors.length > 0) { + setErrors(passwordErrors); + } else { + setErrors([]); + + try { + const { email, password } = formData; + setLoading(true); + const res = await login(email, password); + const { exists, access_token } = res.data.data; + + if (!exists) { + alert('아이디 혹은 비밀번호가 올바르지 않습니다.'); + setLoading(false); + return; + } + + setAccessToken(access_token); + router.push('/main'); + } catch (error) { + console.error('로그인 실패:', error); + alert('로그인 중 오류가 발생했습니다.'); + setLoading(false); + } + } + }; + + return ( + <> + + loginBg +
+ {/* 로그인 화면 */} +
+ +
+ + {/* 아이디 찾기 화면 */} +
+ +
+ + {/* 비밀번호 재설정 화면 1 */} +
+ +
+ + {/* 비밀번호 재설정 화면 2 */} +
+ +
+
+ + ); +} diff --git a/src/app/_auth/signup/layout.js b/src/app/_auth/signup/layout.js new file mode 100644 index 0000000..62a540b --- /dev/null +++ b/src/app/_auth/signup/layout.js @@ -0,0 +1,16 @@ +//import { Suspense } from "react"; +import Header from "@/components/ui/common/Header"; + +export const metadata = { + title: "SignUp", + description: "SignUp to your account", +}; + +export default function SignUpLayout({ children }) { + return ( + <> +
+ {children} + + ); +} \ No newline at end of file diff --git a/src/app/_auth/signup/page.jsx b/src/app/_auth/signup/page.jsx new file mode 100644 index 0000000..d926517 --- /dev/null +++ b/src/app/_auth/signup/page.jsx @@ -0,0 +1,178 @@ +"use client" + +import { useState, useEffect } from "react"; +import { useRouter } from "next/navigation"; +import { Button } from "@nextui-org/react"; + +import ProfileInfoForm from "@/components/auth/signup/ProfileInfoForm"; +import AdditionalInfoForm from "@/components/auth/signup/AdditionalInfoForm"; + +import { useAuthenticatedApi } from '@/hooks/useAuthenticatedApi.js'; +import usePasswordValidation from "@/hooks/usePasswordValidation"; + +export default function Signup() { + const router = useRouter(); + const { apiClient, handLeLogout }= useAuthenticatedApi(); + + const [isLoading, setIsLoading] = useState(true); + + // 사용자 정보 상태 + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); + const [isEmailValid, setIsEmailValid] = useState(false); + const [major, setMajor] = useState(""); + const [studentId, setStudentId] = useState(""); + const [phoneNumber, setPhoneNumber] = useState(""); + + // 애니메이션 상태 + const [isAnimating, setIsAnimating] = useState(false); + const [isRendering, setIsRendering] = useState(false); + + // 필드 비활성화 상태 + const [isNameDisabled, setIsNameDisabled] = useState(false); + const [isEmailDisabled, setIsEmailDisabled] = useState(false); + + // 비밀번호 유효성 검사 훅 사용 + const { errors } = usePasswordValidation(password); + + useEffect(() => { + // localStorage에서 signup_email과 signup_name 값을 확인 + if (typeof window !== 'undefined') { + const storedEmail = localStorage.getItem('signup_email'); + const storedName = localStorage.getItem('signup_name'); + + if (storedEmail) { + setEmail(storedEmail); + setIsEmailDisabled(true); + } + + if (storedName) { + setName(storedName); + setIsNameDisabled(true); + } + } + + setIsLoading(false); + }, []); + + // 첫 번째 화면에서 다음 버튼 클릭 시 처리 + const handleNext = () => { + if (!name || !email || !password || !confirmPassword) { + alert("모든 칸을 채워주세요."); + return; + } + if (password !== confirmPassword) { + alert("비밀번호가 일치하지 않습니다."); + return; + } + if(email === "pwc2002"){ + setIsEmailValid(true); + alert("이미 가입된 이메일입니다."); + return; + } + if(errors.length > 0){ + alert("비밀번호 조건을 만족해주세요."); + return; + } + + // 화면 전환 애니메이션 + setIsRendering(true); + setTimeout(() => { + setIsAnimating(true); + }, 100); + }; + + const setMajorInfo = (value) => { + setMajor(value); + }; + + // 가입하기 버튼 클릭 시 처리 + const handleSignup = async () => { + if (!major || !studentId || !phoneNumber) { + alert("모든 칸을 채워주세요."); + console.log(name,email,password,major,studentId,phoneNumber); + return; + } + + // 회원가입 정보 객체 생성 + const userinfo = { + name: name, + email: email, + password: password, + major: major, + studentId: studentId, + phoneNumber: phoneNumber + } + + try { + const res = await apiClient.post('/auth/signup', userinfo); + console.log(res); + } catch (error) { + console.log(error); + } + + // 홈으로 리디렉션 + router.push("/"); + }; + + // 로딩 상태 처리 + if (isLoading) { + return ( +
+
로딩 중...
+
+ ); + } + + return ( +
+
+

회원가입하기

+ +
+
+ +
+ +
+ +
+
+ + {/* 하단 버튼 영역 */} +
+ +
+
+
+ ); +} diff --git a/src/app/study/(dashboard)/admin/[id]/page.jsx b/src/app/_study/(dashboard)/admin/[id]/page.jsx similarity index 100% rename from src/app/study/(dashboard)/admin/[id]/page.jsx rename to src/app/_study/(dashboard)/admin/[id]/page.jsx diff --git a/src/app/study/(dashboard)/admin/page.jsx b/src/app/_study/(dashboard)/admin/page.jsx similarity index 100% rename from src/app/study/(dashboard)/admin/page.jsx rename to src/app/_study/(dashboard)/admin/page.jsx diff --git a/src/app/study/(dashboard)/my/[id]/page.jsx b/src/app/_study/(dashboard)/my/[id]/page.jsx similarity index 100% rename from src/app/study/(dashboard)/my/[id]/page.jsx rename to src/app/_study/(dashboard)/my/[id]/page.jsx diff --git a/src/app/study/(dashboard)/my/page.jsx b/src/app/_study/(dashboard)/my/page.jsx similarity index 100% rename from src/app/study/(dashboard)/my/page.jsx rename to src/app/_study/(dashboard)/my/page.jsx diff --git a/src/app/study/apply/[id]/page.jsx b/src/app/_study/apply/[id]/page.jsx similarity index 100% rename from src/app/study/apply/[id]/page.jsx rename to src/app/_study/apply/[id]/page.jsx diff --git a/src/app/study/create/page.jsx b/src/app/_study/create/page.jsx similarity index 100% rename from src/app/study/create/page.jsx rename to src/app/_study/create/page.jsx diff --git a/src/app/study/detail/[id]/page.jsx b/src/app/_study/detail/[id]/page.jsx similarity index 100% rename from src/app/study/detail/[id]/page.jsx rename to src/app/_study/detail/[id]/page.jsx diff --git a/src/app/study/layout.js b/src/app/_study/layout.js similarity index 100% rename from src/app/study/layout.js rename to src/app/_study/layout.js diff --git a/src/app/study/loading.js b/src/app/_study/loading.js similarity index 100% rename from src/app/study/loading.js rename to src/app/_study/loading.js diff --git a/src/app/study/page.jsx b/src/app/_study/page.jsx similarity index 100% rename from src/app/study/page.jsx rename to src/app/_study/page.jsx diff --git a/src/app/robots.js b/src/app/robots.js index 452fd98..baa8391 100644 --- a/src/app/robots.js +++ b/src/app/robots.js @@ -1,3 +1,6 @@ +export const dynamic = 'force-static'; + + export default function robots() { return { rules: [ diff --git a/src/app/sitemap.js b/src/app/sitemap.js index 92cc524..073582e 100644 --- a/src/app/sitemap.js +++ b/src/app/sitemap.js @@ -1,3 +1,5 @@ +export const dynamic = 'force-static'; + export default function sitemap() { const baseUrl = 'https://gdgocinha.com'; const currentDate = new Date().toISOString(); diff --git a/src/hooks/useAuthApi.js b/src/hooks/useAuthApi.js index 0d20c9e..85e22a1 100644 --- a/src/hooks/useAuthApi.js +++ b/src/hooks/useAuthApi.js @@ -4,17 +4,15 @@ import axios from 'axios'; import { useAuth } from '@/hooks/useAuth'; const API_AUTH_URL = process.env.NEXT_PUBLIC_BASE_API_URL + '/auth'; -const API_REFRESH_URL = process.env.NEXT_PUBLIC_BASE_API_URL + '/refresh'; -const ROUTE_API_URL = '/api/auth'; export const useAuthApi = () => { const { accessToken } = useAuth(); - // Access Token 갱신 함수 + // Access Token 갱신 const refreshAccessToken = async () => { try { const response = await axios.post( - `${ROUTE_API_URL}/refresh`, + `${API_AUTH_URL}/refresh`, {}, { headers: { 'Content-Type': 'application/json' }, @@ -22,7 +20,6 @@ export const useAuthApi = () => { credentials: 'include', } ); - return response; } catch (error) { if (error.response?.status === 401) { @@ -34,11 +31,11 @@ export const useAuthApi = () => { } }; - // 로그아웃 함수 + // 로그아웃 const logout = async () => { try { await axios.post( - `${ROUTE_API_URL}/signout`, + `${API_AUTH_URL}/logout`, {}, { withCredentials: true, diff --git a/src/middleware.ts b/src/middleware.ts deleted file mode 100644 index b31805d..0000000 --- a/src/middleware.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { NextRequest, NextResponse } from 'next/server'; - -const API_BASE_URL = process.env.NEXT_PUBLIC_BASE_API_URL; - -// 보호된 경로 목록 -const protectedPaths = [ - '/admin', - '/main', - '/study' -]; - -export async function middleware(request: NextRequest) { - const { pathname } = request.nextUrl; - - // 보호된 경로인지 확인 - const isProtectedPath = protectedPaths.some(path => pathname.startsWith(path)); - if (!isProtectedPath) { - return NextResponse.next(); - } - - // 쿠키에서 리프레시 토큰 확인 - const refreshToken = request.cookies.get('refresh_token'); - - // 리프레시 토큰이 없는 경우 로그인 페이지로 리디렉션 - if (!refreshToken) { - return NextResponse.redirect(new URL('/auth/signin', request.url)); - } - - // 리프레시 토큰이 있으면 요청을 계속 진행 - return NextResponse.next(); -} - -// 미들웨어가 실행될 경로 설정 -export const config = { - matcher: [ - /* - * Match all request paths except for the ones starting with: - * - api (API routes) - * - _next/static (static files) - * - _next/image (image optimization files) - * - favicon.ico (favicon file) - * - public (public assets) - * - auth (인증 관련 페이지) - * - robots.txt, sitemap.xml (SEO 관련 파일) - * - error, loading, not-found (Next.js 시스템 페이지) - * - recruit (모집 관련 페이지) - */ - '/((?!api|_next/static|_next/image|favicon.ico|public|auth|robots.txt|sitemap.xml|error|loading|not-found|unauthorized|forbidden|recruit).*)', - ], -}; \ No newline at end of file diff --git a/src/services/auth/signin/custom/CustomAuthApi.js b/src/services/auth/signin/custom/CustomAuthApi.js index d5de5c9..9262055 100644 --- a/src/services/auth/signin/custom/CustomAuthApi.js +++ b/src/services/auth/signin/custom/CustomAuthApi.js @@ -1,26 +1,23 @@ 'use client'; import axios from 'axios'; -// 기존 직접 요청 URL -// const CUSTOM_AUTH_URL = process.env.NEXT_PUBLIC_BASE_API_URL; - -// 새로운 프록시 URL (상대 경로 사용) -const PROXY_AUTH_URL = '/api/auth/signin'; +// 내부 프록시 제거하고, 백엔드 직접 호출 +const LOGIN_URL = process.env.NEXT_PUBLIC_BASE_API_URL + '/auth/login'; export const login = async (email, password) => { try { const response = await axios.post( - PROXY_AUTH_URL, + LOGIN_URL, { email, password }, { headers: { 'Content-Type': 'application/json' }, withCredentials: true, - credentials: "include", + credentials: 'include', } ); return response; } catch (error) { - console.warn('네트워크 오류 또는 서버에 연결할 수 없습니다.'); - alert('네트워크 오류 또는 서버에 연결할 수 없습니다.'); - } + console.warn('네트워크 오류 또는 서버에 연결할 수 없습니다.'); + alert('네트워크 오류 또는 서버에 연결할 수 없습니다.'); + } }; diff --git a/yarn.lock b/yarn.lock index 06265dc..aa766a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -179,17 +179,10 @@ resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== -"@img/sharp-darwin-arm64@0.34.1": +"@img/sharp-win32-x64@0.34.1": version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.1.tgz" - integrity sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A== - optionalDependencies: - "@img/sharp-libvips-darwin-arm64" "1.1.0" - -"@img/sharp-libvips-darwin-arm64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz" - integrity sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA== + resolved "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.1.tgz" + integrity sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw== "@internationalized/date@^3.6.0", "@internationalized/date@^3.8.0", "@internationalized/date@3.8.0": version "3.8.0" @@ -283,10 +276,10 @@ dependencies: fast-glob "3.3.1" -"@next/swc-darwin-arm64@15.3.2": +"@next/swc-win32-x64-msvc@15.3.2": version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.2.tgz" - integrity sha512-2DR6kY/OGcokbnCsjHpNeQblqCZ85/1j6njYSkzRdpLn5At7OkSdmk7WyAmB9G0k25+VgqVZ/u356OSoQZ3z0g== + resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.3.2.tgz" + integrity sha512-aW5B8wOPioJ4mBdMDXkt5f3j8pUr9W8AnlX0Df35uRWNT1Y6RIybxjnSUe+PhM+M1bwgyY8PHLmXZC6zT1o5tA== "@nextui-org/accordion@2.2.7": version "2.2.7" @@ -2549,10 +2542,10 @@ resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== -"@unrs/resolver-binding-darwin-arm64@1.7.2": +"@unrs/resolver-binding-win32-x64-msvc@1.7.2": version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.7.2.tgz" - integrity sha512-vxtBno4xvowwNmO/ASL0Y45TpHqmNkAaDtz4Jqb+clmcVSSl8XCG/PNFFkGsXXXS6AMjP+ja/TtNCFFa1QwLRg== + resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.7.2.tgz" + integrity sha512-friS8NEQfHaDbkThxopGk+LuE5v3iY0StruifjQEt7SLbA46OnfgMO15sOTkbpJkol6RB+1l1TYPXh0sCddpvA== acorn-jsx@^5.3.2: version "5.3.2" @@ -3559,11 +3552,6 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" From 27bc7f753b9ac4b368daac487a7d7b61e0fa70ff Mon Sep 17 00:00:00 2001 From: pwc2002 Date: Fri, 29 Aug 2025 00:25:22 +0900 Subject: [PATCH 02/20] =?UTF-8?q?Feat:=20=EC=A0=95=EC=A0=81=EB=B0=B0?= =?UTF-8?q?=ED=8F=AC=EC=9A=A9=20api=20client=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/admin/layout.js | 11 ++-- src/app/admin/page.jsx | 16 +++--- src/app/main/layout.js | 11 ++-- src/app/test/page.jsx | 79 ++++++++++++++++++++++++++++ src/components/auth/ApiCodeGuard.jsx | 55 +++++++++++++++++++ 5 files changed, 156 insertions(+), 16 deletions(-) create mode 100644 src/app/test/page.jsx create mode 100644 src/components/auth/ApiCodeGuard.jsx diff --git a/src/app/admin/layout.js b/src/app/admin/layout.js index 1c09e26..4ed6bb3 100644 --- a/src/app/admin/layout.js +++ b/src/app/admin/layout.js @@ -2,6 +2,7 @@ import MenuHeader from '@/components/ui/common/MenuHeader'; +import ApiCodeGuard from '@/components/auth/ApiCodeGuard.jsx'; export const metadata = { title: "Admin", @@ -10,9 +11,11 @@ export const metadata = { export default function AdminLayout({ children }) { return ( - <> - - {children} - + + <> + + {children} + + ); } \ No newline at end of file diff --git a/src/app/admin/page.jsx b/src/app/admin/page.jsx index 06de53f..ca6a4ab 100644 --- a/src/app/admin/page.jsx +++ b/src/app/admin/page.jsx @@ -33,16 +33,16 @@ const statusColorMap = { }; export default function Page() { - const [isLoading, setIsLoading] = useState(true); + const [isLoading, setIsLoading] = useState(false); const router = useRouter(); - useEffect(() => { - if(!document.referrer) { - router.push('/') - } else { - setIsLoading(false); - } - }, []); + // useEffect(() => { + // if(!document.referrer) { + // router.push('/') + // } else { + // setIsLoading(false); + // } + // }, []); // 추후 users 를 사용해 데이터를 받아오고, totalUsers를 사용해 페이지네이션 만들 예정 const [page, setPage] = React.useState(1); // 현재 페이지 상태 (추후 페이지 상태에 따라 api 통신으로 데이터 불러오기) diff --git a/src/app/main/layout.js b/src/app/main/layout.js index e8ac328..a46f0f9 100644 --- a/src/app/main/layout.js +++ b/src/app/main/layout.js @@ -1,5 +1,6 @@ //import { Suspense } from "react"; import MenuHeader from "@/components/ui/common/MenuHeader"; +import ApiCodeGuard from '@/components/auth/ApiCodeGuard.jsx'; export const metadata = { title: "Home", @@ -8,9 +9,11 @@ export const metadata = { export default function HomeLayout({ children }) { return ( - <> - - {children} - + + <> + + {children} + + ); } \ No newline at end of file diff --git a/src/app/test/page.jsx b/src/app/test/page.jsx new file mode 100644 index 0000000..d849638 --- /dev/null +++ b/src/app/test/page.jsx @@ -0,0 +1,79 @@ +'use client' + +import { useState, useMemo } from 'react'; +import { useAuthenticatedApi } from '@/hooks/useAuthenticatedApi'; +import { useAuth } from '@/hooks/useAuth'; + +export default function TestAuthPage() { + const { apiClient } = useAuthenticatedApi(); + const { accessToken } = useAuth(); + + const isLoggedIn = Boolean(accessToken); + const maskedToken = useMemo(() => { + if (!accessToken) return '-'; + const head = String(accessToken).slice(0, 8); + const tail = String(accessToken).slice(-6); + return `${head}...${tail}`; + }, [accessToken]); + + const [loading, setLoading] = useState(false); + const [httpStatus, setHttpStatus] = useState(null); + const [payload, setPayload] = useState(null); + const [errorText, setErrorText] = useState(''); + + const handleCallAuthApi = async () => { + setLoading(true); + setErrorText(''); + setPayload(null); + setHttpStatus(null); + try { + const res = await apiClient.get('/recruit/members', { + params: { page: 0, size: 20, sort: 'createdAt', dir: 'DESC' }, + }); + setHttpStatus(res.status); + setPayload(res.data); + } catch (err) { + const status = err?.response?.status ?? 'NETWORK_ERROR'; + setHttpStatus(status); + if (err?.response?.data) setPayload(err.response.data); + setErrorText(String(err?.message || 'request failed')); + } finally { + setLoading(false); + } + }; + + return ( +
+

로그인 테스트

+ +
+
현재 로그인 상태
+
+ {isLoggedIn ? '로그인됨' : '미로그인'} +
+
액세스 토큰: {maskedToken}
+
+ +
+ +
+ +
+
응답
+
HTTP Status: {httpStatus ?? '-'}
+ {errorText && ( +
에러: {errorText}
+ )} +
+{JSON.stringify(payload, null, 2) || '-'}
+        
+
+
+ ); +} \ No newline at end of file diff --git a/src/components/auth/ApiCodeGuard.jsx b/src/components/auth/ApiCodeGuard.jsx new file mode 100644 index 0000000..20e2ce0 --- /dev/null +++ b/src/components/auth/ApiCodeGuard.jsx @@ -0,0 +1,55 @@ +'use client' + +import { useEffect, useState } from 'react'; +import { useRouter } from 'next/navigation'; + +import { useAuthenticatedApi } from '@/hooks/useAuthenticatedApi'; +import Loader from '@/components/ui/common/Loader'; + +export default function ApiCodeGuard({ children }) { + const router = useRouter(); + const { apiClient } = useAuthenticatedApi(); + + const [checking, setChecking] = useState(true); + const [allowed, setAllowed] = useState(false); + + useEffect(() => { + let cancelled = false; + + const verifyAccess = async () => { + try { + const res = await apiClient.get('/recruit/members', { + params: { page: 0, size: 20, sort: 'createdAt', dir: 'DESC' }, + }); + + const code = res?.data?.code; + if (!cancelled) { + if (code === 200) { + setAllowed(true); + } else { + router.replace('/unauthorized'); + } + } + } catch (error) { + if (!cancelled) { + // 인터셉터에서 401/403 처리로 리다이렉트가 발생할 수 있으므로, 보조적으로 차단 + router.replace('/unauthorized'); + } + } finally { + if (!cancelled) { + setChecking(false); + } + } + }; + + verifyAccess(); + + return () => { + cancelled = true; + }; + }, [apiClient, router]); + + if (checking) return ; + if (!allowed) return null; + return children; +} \ No newline at end of file From 7ec8f0b855b6c8bd1cce552f144178a1d1c2c883 Mon Sep 17 00:00:00 2001 From: ThinkMuk Date: Sat, 30 Aug 2025 02:51:53 +0900 Subject: [PATCH 03/20] =?UTF-8?q?Fix:=20MenuHeader=20onPress=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=ED=95=98=EC=97=AC=20=EC=9D=B4=EB=B2=A4?= =?UTF-8?q?=ED=8A=B8=20=ED=95=B8=EB=93=A4=EB=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ui/common/MenuHeader.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/ui/common/MenuHeader.jsx b/src/components/ui/common/MenuHeader.jsx index c714972..b9cd01a 100644 --- a/src/components/ui/common/MenuHeader.jsx +++ b/src/components/ui/common/MenuHeader.jsx @@ -48,17 +48,17 @@ export default function MenuHeader() { - alert('준비중입니다.')}> + alert('준비중입니다.')}> 공지사항 - alert('준비중입니다.')}> + alert('준비중입니다.')}> 프로젝트 - alert('준비중입니다.')}> + alert('준비중입니다.')}> 멤버 @@ -77,7 +77,7 @@ export default function MenuHeader() { className={`w-full text-white ${index === 4 ? "text-red-500 font-bold" : ""}`} href={item.href} size="lg" - onClick={item.onClick} + onPress={item.onClick} > {item.name} From 08f6f360e7ae302689aba495ee3b0ff27f86b18b Mon Sep 17 00:00:00 2001 From: ThinkMuk Date: Sat, 30 Aug 2025 02:57:49 +0900 Subject: [PATCH 04/20] =?UTF-8?q?Refactor:=20Admin=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0=20?= =?UTF-8?q?#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/admin/page.jsx | 132 ++---------------- .../admin/AdminTableBottomContent.jsx | 24 ++++ src/components/admin/AdminTableCell.jsx | 46 ++++++ src/components/admin/AdminTableTopContent.jsx | 53 +++++++ 4 files changed, 135 insertions(+), 120 deletions(-) create mode 100644 src/components/admin/AdminTableBottomContent.jsx create mode 100644 src/components/admin/AdminTableCell.jsx create mode 100644 src/components/admin/AdminTableTopContent.jsx diff --git a/src/app/admin/page.jsx b/src/app/admin/page.jsx index ca6a4ab..2362df4 100644 --- a/src/app/admin/page.jsx +++ b/src/app/admin/page.jsx @@ -2,22 +2,12 @@ import React, { useCallback, useRef, useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; -import { - Table, - TableHeader, - TableColumn, - TableBody, - TableRow, - TableCell, - User, - Chip, - Pagination, - Input, - Spinner, -} from '@nextui-org/react'; -import { IoSearch } from 'react-icons/io5'; +import { Table, TableHeader, TableColumn, TableBody, TableRow, TableCell } from '@nextui-org/react'; import UserDetailsModal from '@/components/admin/UserDetailsModal'; +import AdminTableCell from '@/components/admin/AdminTableCell'; +import AdminTableTopContent from '@/components/admin/AdminTableTopContent'; +import AdminTableBottomContent from '@/components/admin/AdminTableBottomContent'; import { users } from '@/mock/users'; @@ -33,16 +23,8 @@ const statusColorMap = { }; export default function Page() { - const [isLoading, setIsLoading] = useState(false); const router = useRouter(); - // useEffect(() => { - // if(!document.referrer) { - // router.push('/') - // } else { - // setIsLoading(false); - // } - // }, []); // 추후 users 를 사용해 데이터를 받아오고, totalUsers를 사용해 페이지네이션 만들 예정 const [page, setPage] = React.useState(1); // 현재 페이지 상태 (추후 페이지 상태에 따라 api 통신으로 데이터 불러오기) @@ -64,39 +46,9 @@ export default function Page() { const totalPages = React.useMemo(() => Math.ceil(totalUsers / rowsPerPage), [totalUsers, rowsPerPage]); - const renderCell = useCallback((user, columnKey) => { - const cellValue = user.member[columnKey]; - switch (columnKey) { - case 'name': - return ( - - {user.member.email} - - ); - case 'major': - return ( -
-

{user.member.majors.main}

-

{user.member.studentId}

-
- ); - case 'status': - return ( - - {user.member.isPayed ? '입금' : '미입금'} - - ); - default: - return cellValue; - } - }, []); + const renderCell = useCallback((user, columnKey) => + + , []); const handleRowClick = (user) => { if (modalClosing.current) return; // 모달이 닫히는 중에는 클릭 무시 @@ -117,75 +69,17 @@ export default function Page() { }, 300); }; - // isloading 이 false 일때만 렌더링 return ( <> - {isLoading ? ( -
- -
- ) : ( -
- +
0 ? ( -
- setPage(newPage)} - /> -
- ) : null + setPage(newPage)} /> } topContent={ - - } - value={searchValue} - onChange={(e) => setSearchValue(e.target.value)} - onKeyDown={(e) => { - if (e.key === 'Enter' && !e.nativeEvent.isComposing) { - e.preventDefault(); - handleSearch(); // 클릭시 이벤트 발생 (추후 api 연결로 대체) - } - }} - onClear={() => setSearchValue('')} - /> + } > @@ -195,7 +89,6 @@ export default function Page() { )} - {/* 나중에 여기 users 로 변경할 것 */} {(item) => ( - )} + ); - } \ No newline at end of file diff --git a/src/components/admin/AdminTableBottomContent.jsx b/src/components/admin/AdminTableBottomContent.jsx new file mode 100644 index 0000000..71c67bf --- /dev/null +++ b/src/components/admin/AdminTableBottomContent.jsx @@ -0,0 +1,24 @@ +"use client"; + +import React from 'react'; +import { Pagination } from '@nextui-org/react'; + +export default function AdminTableBottomContent({ page, totalPages, onChangePage }) { + if (!totalPages || totalPages <= 0) return null; + + return ( +
+ +
+ ); +} + + diff --git a/src/components/admin/AdminTableCell.jsx b/src/components/admin/AdminTableCell.jsx new file mode 100644 index 0000000..846ac1a --- /dev/null +++ b/src/components/admin/AdminTableCell.jsx @@ -0,0 +1,46 @@ +"use client"; + +import React from 'react'; +import { User, Chip } from '@nextui-org/react'; + +const statusColorMap = { + true: 'success', + false: 'danger', +}; + +export default function AdminTableCell({ user, columnKey }) { + const cellValue = user.member[columnKey]; + + switch (columnKey) { + case 'name': + return ( + + {user.member.email} + + ); + case 'major': + return ( +
+

{user.member.majors.main}

+

{user.member.studentId}

+
+ ); + case 'status': + return ( + + {user.member.isPayed ? '입금' : '미입금'} + + ); + default: + return cellValue; + } +} + + diff --git a/src/components/admin/AdminTableTopContent.jsx b/src/components/admin/AdminTableTopContent.jsx new file mode 100644 index 0000000..d305316 --- /dev/null +++ b/src/components/admin/AdminTableTopContent.jsx @@ -0,0 +1,53 @@ +"use client"; + +import React from 'react'; +import { Input } from '@nextui-org/react'; +import { IoSearch } from 'react-icons/io5'; + +export default function AdminTableTopContent({ searchValue, setSearchValue, onSearch }) { + return ( + + } + value={searchValue} + onChange={(e) => setSearchValue(e.target.value)} + onKeyDown={(e) => { + if (e.key === 'Enter' && !e.nativeEvent.isComposing) { + e.preventDefault(); + onSearch(); + } + }} + onClear={() => setSearchValue('')} + /> + ); +} + + From 9b5377514195ccd2d3f6ab3248e6d66d9b4d4715 Mon Sep 17 00:00:00 2001 From: ThinkMuk Date: Sat, 30 Aug 2025 16:46:57 +0900 Subject: [PATCH 05/20] =?UTF-8?q?Refactor:=20accessToken=20=EA=B0=B1?= =?UTF-8?q?=EC=8B=A0=20=EB=B0=8F=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=ED=95=A8=EC=88=98useCallback=EC=9C=BC=EB=A1=9C=20=EC=B5=9C?= =?UTF-8?q?=EC=A0=81=ED=99=94=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useAuthApi.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/hooks/useAuthApi.js b/src/hooks/useAuthApi.js index 85e22a1..e44d9ed 100644 --- a/src/hooks/useAuthApi.js +++ b/src/hooks/useAuthApi.js @@ -1,6 +1,7 @@ 'use client' import axios from 'axios'; +import { useCallback } from 'react'; import { useAuth } from '@/hooks/useAuth'; const API_AUTH_URL = process.env.NEXT_PUBLIC_BASE_API_URL + '/auth'; @@ -8,8 +9,8 @@ const API_AUTH_URL = process.env.NEXT_PUBLIC_BASE_API_URL + '/auth'; export const useAuthApi = () => { const { accessToken } = useAuth(); - // Access Token 갱신 - const refreshAccessToken = async () => { + // Access Token 갱신 (stable) + const refreshAccessToken = useCallback(async () => { try { const response = await axios.post( `${API_AUTH_URL}/refresh`, @@ -29,10 +30,10 @@ export const useAuthApi = () => { } throw error; } - }; + }, []); // 로그아웃 - const logout = async () => { + const logout = useCallback(async () => { try { await axios.post( `${API_AUTH_URL}/logout`, @@ -48,7 +49,7 @@ export const useAuthApi = () => { console.error('로그아웃 요청 오류 발생:', error); throw error; } - }; + }, [accessToken]); return { refreshAccessToken, logout }; }; \ No newline at end of file From 009095c212813650e30b1ccea9cca575adc7e057 Mon Sep 17 00:00:00 2001 From: ThinkMuk Date: Sat, 30 Aug 2025 18:09:10 +0900 Subject: [PATCH 06/20] =?UTF-8?q?Refactor:=20Admin=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EC=97=90=EC=84=9C=20API=20=ED=98=B8=EC=B6=9C=20?= =?UTF-8?q?=EB=B0=8F=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0,=20=EA=B2=80=EC=83=89?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=ED=99=9C=EC=84=B1=ED=99=94=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/admin/page.jsx | 89 +++++++++++++++++------ src/components/admin/AdminTableCell.jsx | 17 +++-- src/components/admin/UserDetailsModal.jsx | 4 +- 3 files changed, 80 insertions(+), 30 deletions(-) diff --git a/src/app/admin/page.jsx b/src/app/admin/page.jsx index 2362df4..19e670e 100644 --- a/src/app/admin/page.jsx +++ b/src/app/admin/page.jsx @@ -9,12 +9,12 @@ import AdminTableCell from '@/components/admin/AdminTableCell'; import AdminTableTopContent from '@/components/admin/AdminTableTopContent'; import AdminTableBottomContent from '@/components/admin/AdminTableBottomContent'; -import { users } from '@/mock/users'; +import { useAuthenticatedApi } from '@/hooks/useAuthenticatedApi'; const columns = [ { name: 'NAME', uid: 'name' }, { name: 'MAJOR / ID', uid: 'major' }, - { name: 'PAYMENT', uid: 'status' }, + { name: 'PAYMENT', uid: 'isPayed' }, ]; const statusColorMap = { @@ -24,31 +24,63 @@ const statusColorMap = { export default function Page() { const router = useRouter(); + const { apiClient } = useAuthenticatedApi(); - // 추후 users 를 사용해 데이터를 받아오고, totalUsers를 사용해 페이지네이션 만들 예정 - const [page, setPage] = React.useState(1); // 현재 페이지 상태 (추후 페이지 상태에 따라 api 통신으로 데이터 불러오기) + const [page, setPage] = React.useState(1); const [modalOpen, setModalOpen] = React.useState(false); // 모달 열림 상태 const modalClosing = useRef(false); // 모달이 닫히는 상태를 추적 const [selectedUser, setSelectedUser] = React.useState(null); // 선택된 사용자 데이터 const [searchValue, setSearchValue] = React.useState(''); // 검색 입력 상태 + const [query, setQuery] = React.useState(''); // API 호출시 검색 내용 + const [loading, setLoading] = React.useState(false); + const [error, setError] = React.useState(''); + const [currentUsers, setCurrentUsers] = React.useState([]); + const [totalUsers, setTotalUsers] = React.useState(0); + const [totalPages, setTotalPages] = React.useState(0); const rowsPerPage = 10; //한 페이지당 표시될 유저 수 - const totalUsers = 110; //총 유저 수 (총 페이지 표시를 위함) - // 현재 페이지 데이터 계산 (임시) - const currentUsers = React.useMemo(() => { - const startIndex = (page - 1) * rowsPerPage; - const endIndex = startIndex + rowsPerPage; - return users.slice(startIndex, endIndex); - }, [page, rowsPerPage]); - - const totalPages = React.useMemo(() => Math.ceil(totalUsers / rowsPerPage), [totalUsers, rowsPerPage]); - - const renderCell = useCallback((user, columnKey) => - - , []); + const fetchUsers = useCallback(async () => { + setLoading(true); + setError(''); + try { + const params = { + page: page - 1, + size: rowsPerPage, + sort: 'createdAt', + dir: 'DESC', + question: query || undefined, + }; + const res = await apiClient.get('/recruit/members', { params }); + const list = Array.isArray(res?.data?.data) ? res.data.data : []; + const total = res?.data?.meta?.totalElements ?? list.length; + const computedTotalPages = Math.max(1, Math.ceil(total / rowsPerPage)); + + setCurrentUsers(list); + setTotalUsers(total); + setTotalPages(computedTotalPages); + } catch (err) { + setError(String(err?.message || 'failed to load users')); + setCurrentUsers([]); + setTotalUsers(0); + } finally { + setLoading(false); + } + }, [apiClient, page, rowsPerPage, query]); + + const renderCell = useCallback((user, columnKey) => { + const normalizedUser = { + ...user, + name: user?.name ?? '', + major: user?.major ?? '', + studentId: user?.studentId ?? '', + isPayed: typeof user?.isPayed === 'boolean' ? user.isPayed : '', + phoneNumber: user?.phoneNumber ?? '', + }; + return ; + }, []); const handleRowClick = (user) => { if (modalClosing.current) return; // 모달이 닫히는 중에는 클릭 무시 @@ -57,8 +89,8 @@ export default function Page() { }; const handleSearch = () => { - //추후 api 연결 함수로 변경 예정 - console.log(searchValue); //임시 + setPage(1); + setQuery((searchValue || '').trim()); }; const handleCloseModal = () => { @@ -69,6 +101,17 @@ export default function Page() { }, 300); }; + useEffect(() => { + if (searchValue === '' && query !== '') { + setPage(1); + setQuery(''); + } + }, [searchValue, query]); + + useEffect(() => { + fetchUsers(); + }, [fetchUsers]); + return ( <>
@@ -89,11 +132,15 @@ export default function Page() { )} - + {(item) => ( handleRowClick(item)} > {(columnKey) => {renderCell(item, columnKey)}} diff --git a/src/components/admin/AdminTableCell.jsx b/src/components/admin/AdminTableCell.jsx index 846ac1a..ff67e38 100644 --- a/src/components/admin/AdminTableCell.jsx +++ b/src/components/admin/AdminTableCell.jsx @@ -9,7 +9,8 @@ const statusColorMap = { }; export default function AdminTableCell({ user, columnKey }) { - const cellValue = user.member[columnKey]; + + const cellValue = user[columnKey]; switch (columnKey) { case 'name': @@ -19,23 +20,23 @@ export default function AdminTableCell({ user, columnKey }) { avatarProps={{ className: 'w-0 h-0 overflow-hidden', }} - description={user.member.email} + description={user.phoneNumber} name={cellValue} > - {user.member.email} + {user.phoneNumber} ); case 'major': return (
-

{user.member.majors.main}

-

{user.member.studentId}

+

{user.major}

+

{user.studentId}

); - case 'status': + case 'isPayed': return ( - - {user.member.isPayed ? '입금' : '미입금'} + + {user.isPayed ? '입금' : '미입금'} ); default: diff --git a/src/components/admin/UserDetailsModal.jsx b/src/components/admin/UserDetailsModal.jsx index 4c3283c..660c79e 100644 --- a/src/components/admin/UserDetailsModal.jsx +++ b/src/components/admin/UserDetailsModal.jsx @@ -19,6 +19,8 @@ export default function UserDetailsModal({ user, isOpen, onClose, preventClose } if (!isOpen) return null; + const member = user?.member ?? user ?? {}; + const rowStyle = 'border border-[#5b5b6699]'; const cellStyle = 'p-3 font-bold text-gray-300'; const valueStyle = 'p-3'; @@ -28,7 +30,7 @@ export default function UserDetailsModal({ user, isOpen, onClose, preventClose }
User Details
- + {/* User Basic Info */}
From 6c91ae1bc5a5317c39d1d8a686d135c52ab904ae Mon Sep 17 00:00:00 2001 From: ThinkMuk Date: Sat, 30 Aug 2025 20:26:06 +0900 Subject: [PATCH 07/20] =?UTF-8?q?Refactor:=20UserDetailsModal=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=9E=90=20=EC=A0=95=EB=B3=B4=20=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EB=90=9C=20=EC=9D=91=EB=8B=B5=20=EC=8A=A4=ED=82=A4?= =?UTF-8?q?=EB=A7=88=20=EB=B0=98=EC=98=81=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/admin/UserDetailsModal.jsx | 63 ++++++++++------------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/src/components/admin/UserDetailsModal.jsx b/src/components/admin/UserDetailsModal.jsx index 660c79e..62754e5 100644 --- a/src/components/admin/UserDetailsModal.jsx +++ b/src/components/admin/UserDetailsModal.jsx @@ -19,8 +19,6 @@ export default function UserDetailsModal({ user, isOpen, onClose, preventClose } if (!isOpen) return null; - const member = user?.member ?? user ?? {}; - const rowStyle = 'border border-[#5b5b6699]'; const cellStyle = 'p-3 font-bold text-gray-300'; const valueStyle = 'p-3'; @@ -31,53 +29,44 @@ export default function UserDetailsModal({ user, isOpen, onClose, preventClose }
User Details
- {/* User Basic Info */} + {/* User Basic Info (신 응답 스키마에 맞춤) */}
{[ - ['이름', user.member.name], - ['학년', user.member.grade], - ['학번', user.member.studentId], - ['전화번호', user.member.phoneNumber], - ['국적', user.member.nationality === 'etc' ? user.member.nationalityContent : user.member.nationality], - ['Email', user.member.email], - ['성별', user.member.gender], - ['생년월일', user.member.birth], - ['학교', user.member.school], - ['전공', user.member.majors.main], - ['부전공', user.member.majors.second.join(', ') || '없음'], - ['가입 경로', user.member.route], - ['회비 송금 여부', user.member.isPayed ? 'Yes' : 'No'], - ].map(([label, userValue], idx) => ( - - - - - ))} + ['이름', user?.name], + ['전공', user?.major], + ['학번', user?.studentId], + ['회비 송금 여부', typeof user?.isPayed === 'boolean' ? (user.isPayed ? 'Yes' : 'No') : undefined], + ] + .filter(([, val]) => val !== undefined && val !== null && val !== '') + .map(([label, userValue], idx) => ( + + + + + ))}
{label}{userValue}
{label}{userValue}
- {user.answers.map((answer, idx) => { + {(Array.isArray(user?.answers?.answers) ? user.answers.answers : []).map((answer, idx) => { const questionMap = { - 1: '지원 동기', - 2: '진로 경험 & 이야기', - 3: '관심 분야', - 4: 'GDG 기수', - 5: '경로', - 6: '얻어가고 싶은 거', - 7: '기대하는 활동', - 8: '피드백', + APPLY_MOTIVATION: '지원 동기', + LIFE_STORY: '진로 경험 & 이야기', + INTERESTS: '관심 분야', + GDG_PERIOD: 'GDG 기수', + ROUTE_TO_KNOW: '경로', + WANT_TO_GET: '얻어가고 싶은 거', + EXPECTED_ACTIVITY: '기대하는 활동', + FEEDBACK: '피드백', }; - const question = questionMap[answer.questionId]; - //배열일시 전환 - const response = Array.isArray(answer.responseValue) - ? answer.responseValue.join(', ') - : answer.responseValue; + const question = questionMap[answer?.inputType] ?? answer?.inputType ?? '질문'; + const value = answer?.responseValue; + const response = Array.isArray(value) ? value.join(', ') : value; return ( -
+

{question}
{response || '없음'}
From d1d1e81e4cc7a533a83b0eb3a1889fb3670eba78 Mon Sep 17 00:00:00 2001 From: ThinkMuk Date: Sat, 30 Aug 2025 21:58:15 +0900 Subject: [PATCH 08/20] =?UTF-8?q?Feat:=20Admin=20=ED=9A=8C=EB=B9=84=20?= =?UTF-8?q?=EC=A7=80=EB=B6=88=20=EC=97=AC=EB=B6=80=20=ED=86=A0=EA=B8=80=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/admin/page.jsx | 91 ++++++++++++++++++++----- src/components/admin/AdminTableCell.jsx | 16 ++++- 2 files changed, 87 insertions(+), 20 deletions(-) diff --git a/src/app/admin/page.jsx b/src/app/admin/page.jsx index 19e670e..ebf4a66 100644 --- a/src/app/admin/page.jsx +++ b/src/app/admin/page.jsx @@ -15,6 +15,7 @@ const columns = [ { name: 'NAME', uid: 'name' }, { name: 'MAJOR / ID', uid: 'major' }, { name: 'PAYMENT', uid: 'isPayed' }, + { name: 'TOGGLE', uid: 'togglePay' }, ]; const statusColorMap = { @@ -42,6 +43,7 @@ export default function Page() { const rowsPerPage = 10; //한 페이지당 표시될 유저 수 + //유저 데이터 조회 const fetchUsers = useCallback(async () => { setLoading(true); setError(''); @@ -70,22 +72,69 @@ export default function Page() { } }, [apiClient, page, rowsPerPage, query]); - const renderCell = useCallback((user, columnKey) => { - const normalizedUser = { - ...user, - name: user?.name ?? '', - major: user?.major ?? '', - studentId: user?.studentId ?? '', - isPayed: typeof user?.isPayed === 'boolean' ? user.isPayed : '', - phoneNumber: user?.phoneNumber ?? '', - }; - return ; - }, []); - - const handleRowClick = (user) => { + //회비 지불여부 체크박스 + const handleTogglePay = useCallback( + async (userId, nextValue) => { + const getItemId = (user) => user?.id; + const prevUsers = currentUsers; + + setCurrentUsers((prev) => + prev.map((u) => { + if (getItemId(u) === userId) { + const updated = { ...u, isPayed: nextValue }; + return updated; + } + return u; + }) + ); + + try { + await apiClient.patch(`/recruit/members/${userId}/payment`, { isPayed: nextValue }); + } catch (err) { + // rollback + setCurrentUsers(prevUsers); + alert('결제 상태 변경에 실패했습니다. 다시 시도해주세요.'); + } + }, + [apiClient, currentUsers] + ); + + //테이블 요소 + const renderCell = useCallback( + (user, columnKey) => { + const normalizedUser = { + ...user, + name: user?.name ?? '', + major: user?.major ?? '', + studentId: user?.studentId ?? '', + isPayed: typeof user?.isPayed === 'boolean' ? user.isPayed : '', + phoneNumber: user?.phoneNumber ?? '', + id: user?.id ?? user?.member?.id, + memberId: user?.member?.id ?? user?.id, + }; + return ; + }, + [handleTogglePay] + ); + + //유저 상세 정보 + const handleRowClick = async (user) => { if (modalClosing.current) return; // 모달이 닫히는 중에는 클릭 무시 - setSelectedUser(user); - setModalOpen(true); + try { + const memberId = user?.id; + if (!memberId) { + throw new Error('멤버 ID를 확인할 수 없습니다.'); + } + const res = await apiClient.get(`/recruit/members/${memberId}`); + const detail = res?.data?.data ?? null; + if (!detail) { + throw new Error('상세 정보를 불러오지 못했습니다.'); + } + setSelectedUser(detail); + setModalOpen(true); + } catch (e) { + alert('상세 정보를 불러오는 중 오류가 발생했습니다.'); + } }; const handleSearch = () => { @@ -127,7 +176,11 @@ export default function Page() { > {(column) => ( - + {column.name} )} @@ -143,7 +196,11 @@ export default function Page() { key={item.member?.id ?? item.id} onClick={() => handleRowClick(item)} > - {(columnKey) => {renderCell(item, columnKey)}} + {(columnKey) => ( + + {renderCell(item, columnKey)} + + )} )} diff --git a/src/components/admin/AdminTableCell.jsx b/src/components/admin/AdminTableCell.jsx index ff67e38..8f10642 100644 --- a/src/components/admin/AdminTableCell.jsx +++ b/src/components/admin/AdminTableCell.jsx @@ -1,15 +1,14 @@ "use client"; import React from 'react'; -import { User, Chip } from '@nextui-org/react'; +import { User, Chip, Checkbox } from '@nextui-org/react'; const statusColorMap = { true: 'success', false: 'danger', }; -export default function AdminTableCell({ user, columnKey }) { - +export default function AdminTableCell({ user, columnKey, onTogglePay }) { const cellValue = user[columnKey]; switch (columnKey) { @@ -39,6 +38,17 @@ export default function AdminTableCell({ user, columnKey }) { {user.isPayed ? '입금' : '미입금'} ); + case 'togglePay': + return ( +
e.stopPropagation()} className='w-full flex justify-center items-center'> +
+ onTogglePay?.(user.memberId ?? user.id, checked)} + /> +
+
+ ); default: return cellValue; } From f375fc465789972b15c819036bfea5b14bbdac04 Mon Sep 17 00:00:00 2001 From: pwc2002 Date: Sat, 30 Aug 2025 22:00:37 +0900 Subject: [PATCH 09/20] =?UTF-8?q?Fix:deploy=20=EC=84=B8=ED=8C=85=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 106 +++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c69a48a..9d64475 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,64 +1,74 @@ -name: Build Docker and Upload to S3 +name: DEV CI permissions: contents: read on: push: - branches: - - master + branches: [ develop ] + tags: [ 'development-**' ] + workflow_dispatch: + +concurrency: + group: dev-${{ github.ref }} + cancel-in-progress: true jobs: - build-and-upload: + deploy: runs-on: ubuntu-latest + env: + NODE_ENV: production + NEXT_PUBLIC_BASE_API_URL: ${{ secrets.NEXT_PUBLIC_BASE_API_URL }} + NEXT_PUBLIC_GOOGLE_REDIRECT_CLIENT_ID: ${{ secrets.NEXT_PUBLIC_GOOGLE_REDIRECT_CLIENT_ID }} + NEXT_PUBLIC_GOOGLE_REDIRECT_URI: ${{ secrets.NEXT_PUBLIC_GOOGLE_REDIRECT_URI }} steps: - - name: Checkout Code - uses: actions/checkout@v3 - - - name: Create .env file - run: | - echo "DOCKER_HUB_USERNAME=${{ secrets.DOCKER_HUB_USERNAME }}" > .env - echo "NEXT_PUBLIC_BASE_API_URL=${{ secrets.NEXT_PUBLIC_BASE_API_URL }}" >> .env - echo "NEXT_PUBLIC_GOOGLE_REDIRECT_CLIENT_ID=${{secrets.NEXT_PUBLIC_GOOGLE_REDIRECT_CLIENT_ID}}" >> .env - echo "NEXT_PUBLIC_GOOGLE_REDIRECT_URI=${{secrets.NEXT_PUBLIC_GOOGLE_REDIRECT_URI}}" >> .env + - name: Checkout source code + uses: actions/checkout@v4 - - name: Login to DockerHub (Optional) - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'yarn' # yarn.lock 기반 자동 캐시 - - name: Build and Push Docker Image - run: | - docker build -t ${{ secrets.DOCKER_HUB_USERNAME }}/gdgoc-fe-app:latest . - docker run --rm ${{ secrets.DOCKER_HUB_USERNAME }}/gdgoc-fe-app:latest ls -la /app - docker push ${{ secrets.DOCKER_HUB_USERNAME }}/gdgoc-fe-app:latest + - name: Install dependencies + run: yarn install --frozen-lockfile - - name: Create Deployment Package - run: | - cp scripts/deploy.sh ./deploy.sh - zip -r deploy.zip .env docker-compose.yml deploy.sh appspec.yml \ - Dockerfile package.json package-lock.json next.config.ts \ - pages public .next + - name: Build & Export + run: | + yarn build + yarn export - - name: Configure AWS credentials - run: | - aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }} - aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws configure set region ${{ secrets.AWS_REGION }} + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ secrets.AWS_REGION }} - - name: Upload Deployment Package to S3 - run: | - aws s3 cp deploy.zip s3://${{ secrets.AWS_S3_BUCKET }}/main-deploy.zip + # (선택) 캐시 헤더 전략: 해시된 자산은 장기 캐시, HTML은 no-cache + # 프로젝트에 맞게 include/exclude 패턴 조정 + - name: Upload static assets (long cache) + run: | + aws s3 cp ./out s3://${{ secrets.AWS_S3_BUCKET }} \ + --recursive \ + --exclude "*" \ + --include "_next/**" --include "static/**" --include "assets/**" \ + --cache-control "public, max-age=31536000, immutable" \ + --metadata-directive REPLACE + - name: Upload html (no cache) + run: | + aws s3 cp ./out s3://${{ secrets.AWS_S3_BUCKET }} \ + --recursive \ + --exclude "_next/*" --exclude "static/*" --exclude "assets/*" \ + --cache-control "no-cache" \ + --metadata-directive REPLACE + # (단순화 원하면 기존 sync 한 줄 유지 가능) + # - name: Deploy to S3 + # run: aws s3 sync ./out s3://${{ secrets.AWS_S3_BUCKET }} --delete - - name: Trigger CodeDeploy (CLI) - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_REGION: ap-northeast-2 - run: | - aws deploy create-deployment \ - --application-name ${{ secrets.AWS_CODEDEPLOY_APP }} \ - --deployment-group-name ${{ secrets.AWS_CODEDEPLOY_GROUP }} \ - --s3-location bucket=${{ secrets.S3_BUCKET }},bundleType=zip,key=main-deploy.zip \ - --file-exists-behavior OVERWRITE + - name: Invalidate CloudFront Cache + run: | + aws cloudfront create-invalidation \ + --distribution-id ${{ secrets.AWS_DISTRIBUTION_ID }} \ + --paths "/*" From 57d2ff917764cbf60b6f0929ab7c7d15057d12c2 Mon Sep 17 00:00:00 2001 From: pwc2002 Date: Sat, 30 Aug 2025 23:02:20 +0900 Subject: [PATCH 10/20] =?UTF-8?q?Fix:=20webpack=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20export=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 6 +- next.config.ts | 9 ++ package.json | 3 +- yarn.lock | 273 +++++++++++++++++++++++++++++++++++ 4 files changed, 285 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9d64475..fef6f98 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -34,10 +34,8 @@ jobs: - name: Install dependencies run: yarn install --frozen-lockfile - - name: Build & Export - run: | - yarn build - yarn export + - name: Build + run: yarn build - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 diff --git a/next.config.ts b/next.config.ts index 045fe10..d48ed5f 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,4 +1,5 @@ import type { NextConfig } from 'next'; +import path from 'path'; const nextConfig: NextConfig = { images: { @@ -6,6 +7,14 @@ const nextConfig: NextConfig = { }, trailingSlash: true, output: 'export', + webpack: (config) => { + config.resolve.alias = { + ...(config.resolve.alias || {}), + '@': path.resolve(__dirname, 'src'), + '@public': path.resolve(__dirname, 'public'), + }; + return config; + }, }; export default nextConfig; \ No newline at end of file diff --git a/package.json b/package.json index 6335f2f..9ac79aa 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,7 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint", - "export": "next export" + "lint": "next lint" }, "dependencies": { "@heroicons/react": "^2.2.0", diff --git a/yarn.lock b/yarn.lock index aa766a7..eeb5cf9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,6 +12,28 @@ resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz" integrity sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog== +"@emnapi/core@^1.4.0": + version "1.4.3" + resolved "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz" + integrity sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g== + dependencies: + "@emnapi/wasi-threads" "1.0.2" + tslib "^2.4.0" + +"@emnapi/runtime@^1.4.0": + version "1.4.3" + resolved "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz" + integrity sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ== + dependencies: + tslib "^2.4.0" + +"@emnapi/wasi-threads@1.0.2": + version "1.0.2" + resolved "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz" + integrity sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA== + dependencies: + tslib "^2.4.0" + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.7.0": version "4.7.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz" @@ -179,6 +201,119 @@ resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== +"@img/sharp-darwin-arm64@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.1.tgz" + integrity sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A== + optionalDependencies: + "@img/sharp-libvips-darwin-arm64" "1.1.0" + +"@img/sharp-darwin-x64@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.1.tgz" + integrity sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q== + optionalDependencies: + "@img/sharp-libvips-darwin-x64" "1.1.0" + +"@img/sharp-libvips-darwin-arm64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz" + integrity sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA== + +"@img/sharp-libvips-darwin-x64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz" + integrity sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ== + +"@img/sharp-libvips-linux-arm@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz" + integrity sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA== + +"@img/sharp-libvips-linux-arm64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz" + integrity sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew== + +"@img/sharp-libvips-linux-ppc64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz" + integrity sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ== + +"@img/sharp-libvips-linux-s390x@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz" + integrity sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA== + +"@img/sharp-libvips-linux-x64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz" + integrity sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q== + +"@img/sharp-libvips-linuxmusl-arm64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz" + integrity sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w== + +"@img/sharp-libvips-linuxmusl-x64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz" + integrity sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A== + +"@img/sharp-linux-arm@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.1.tgz" + integrity sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA== + optionalDependencies: + "@img/sharp-libvips-linux-arm" "1.1.0" + +"@img/sharp-linux-arm64@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.1.tgz" + integrity sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ== + optionalDependencies: + "@img/sharp-libvips-linux-arm64" "1.1.0" + +"@img/sharp-linux-s390x@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.1.tgz" + integrity sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA== + optionalDependencies: + "@img/sharp-libvips-linux-s390x" "1.1.0" + +"@img/sharp-linux-x64@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.1.tgz" + integrity sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA== + optionalDependencies: + "@img/sharp-libvips-linux-x64" "1.1.0" + +"@img/sharp-linuxmusl-arm64@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.1.tgz" + integrity sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-arm64" "1.1.0" + +"@img/sharp-linuxmusl-x64@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.1.tgz" + integrity sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-x64" "1.1.0" + +"@img/sharp-wasm32@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.1.tgz" + integrity sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg== + dependencies: + "@emnapi/runtime" "^1.4.0" + +"@img/sharp-win32-ia32@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.1.tgz" + integrity sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw== + "@img/sharp-win32-x64@0.34.1": version "0.34.1" resolved "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.1.tgz" @@ -264,6 +399,15 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@napi-rs/wasm-runtime@^0.2.9": + version "0.2.9" + resolved "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.9.tgz" + integrity sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg== + dependencies: + "@emnapi/core" "^1.4.0" + "@emnapi/runtime" "^1.4.0" + "@tybys/wasm-util" "^0.9.0" + "@next/env@15.3.2": version "15.3.2" resolved "https://registry.npmjs.org/@next/env/-/env-15.3.2.tgz" @@ -276,6 +420,41 @@ dependencies: fast-glob "3.3.1" +"@next/swc-darwin-arm64@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.2.tgz" + integrity sha512-2DR6kY/OGcokbnCsjHpNeQblqCZ85/1j6njYSkzRdpLn5At7OkSdmk7WyAmB9G0k25+VgqVZ/u356OSoQZ3z0g== + +"@next/swc-darwin-x64@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.3.2.tgz" + integrity sha512-ro/fdqaZWL6k1S/5CLv1I0DaZfDVJkWNaUU3un8Lg6m0YENWlDulmIWzV96Iou2wEYyEsZq51mwV8+XQXqMp3w== + +"@next/swc-linux-arm64-gnu@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.3.2.tgz" + integrity sha512-covwwtZYhlbRWK2HlYX9835qXum4xYZ3E2Mra1mdQ+0ICGoMiw1+nVAn4d9Bo7R3JqSmK1grMq/va+0cdh7bJA== + +"@next/swc-linux-arm64-musl@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.3.2.tgz" + integrity sha512-KQkMEillvlW5Qk5mtGA/3Yz0/tzpNlSw6/3/ttsV1lNtMuOHcGii3zVeXZyi4EJmmLDKYcTcByV2wVsOhDt/zg== + +"@next/swc-linux-x64-gnu@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.3.2.tgz" + integrity sha512-uRBo6THWei0chz+Y5j37qzx+BtoDRFIkDzZjlpCItBRXyMPIg079eIkOCl3aqr2tkxL4HFyJ4GHDes7W8HuAUg== + +"@next/swc-linux-x64-musl@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.3.2.tgz" + integrity sha512-+uxFlPuCNx/T9PdMClOqeE8USKzj8tVz37KflT3Kdbx/LOlZBRI2yxuIcmx1mPNK8DwSOMNCr4ureSet7eyC0w== + +"@next/swc-win32-arm64-msvc@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.3.2.tgz" + integrity sha512-LLTKmaI5cfD8dVzh5Vt7+OMo+AIOClEdIU/TSKbXXT2iScUTSxOGoBhfuv+FU8R9MLmrkIL1e2fBMkEEjYAtPQ== + "@next/swc-win32-x64-msvc@15.3.2": version "15.3.2" resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.3.2.tgz" @@ -2425,6 +2604,13 @@ resolved "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.11.2.tgz" integrity sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw== +"@tybys/wasm-util@^0.9.0": + version "0.9.0" + resolved "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz" + integrity sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw== + dependencies: + tslib "^2.4.0" + "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" @@ -2542,6 +2728,88 @@ resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== +"@unrs/resolver-binding-darwin-arm64@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.7.2.tgz" + integrity sha512-vxtBno4xvowwNmO/ASL0Y45TpHqmNkAaDtz4Jqb+clmcVSSl8XCG/PNFFkGsXXXS6AMjP+ja/TtNCFFa1QwLRg== + +"@unrs/resolver-binding-darwin-x64@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.7.2.tgz" + integrity sha512-qhVa8ozu92C23Hsmv0BF4+5Dyyd5STT1FolV4whNgbY6mj3kA0qsrGPe35zNR3wAN7eFict3s4Rc2dDTPBTuFQ== + +"@unrs/resolver-binding-freebsd-x64@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.7.2.tgz" + integrity sha512-zKKdm2uMXqLFX6Ac7K5ElnnG5VIXbDlFWzg4WJ8CGUedJryM5A3cTgHuGMw1+P5ziV8CRhnSEgOnurTI4vpHpg== + +"@unrs/resolver-binding-linux-arm-gnueabihf@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.7.2.tgz" + integrity sha512-8N1z1TbPnHH+iDS/42GJ0bMPLiGK+cUqOhNbMKtWJ4oFGzqSJk/zoXFzcQkgtI63qMcUI7wW1tq2usZQSb2jxw== + +"@unrs/resolver-binding-linux-arm-musleabihf@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.7.2.tgz" + integrity sha512-tjYzI9LcAXR9MYd9rO45m1s0B/6bJNuZ6jeOxo1pq1K6OBuRMMmfyvJYval3s9FPPGmrldYA3mi4gWDlWuTFGA== + +"@unrs/resolver-binding-linux-arm64-gnu@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.7.2.tgz" + integrity sha512-jon9M7DKRLGZ9VYSkFMflvNqu9hDtOCEnO2QAryFWgT6o6AXU8du56V7YqnaLKr6rAbZBWYsYpikF226v423QA== + +"@unrs/resolver-binding-linux-arm64-musl@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.7.2.tgz" + integrity sha512-c8Cg4/h+kQ63pL43wBNaVMmOjXI/X62wQmru51qjfTvI7kmCy5uHTJvK/9LrF0G8Jdx8r34d019P1DVJmhXQpA== + +"@unrs/resolver-binding-linux-ppc64-gnu@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.7.2.tgz" + integrity sha512-A+lcwRFyrjeJmv3JJvhz5NbcCkLQL6Mk16kHTNm6/aGNc4FwPHPE4DR9DwuCvCnVHvF5IAd9U4VIs/VvVir5lg== + +"@unrs/resolver-binding-linux-riscv64-gnu@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.7.2.tgz" + integrity sha512-hQQ4TJQrSQW8JlPm7tRpXN8OCNP9ez7PajJNjRD1ZTHQAy685OYqPrKjfaMw/8LiHCt8AZ74rfUVHP9vn0N69Q== + +"@unrs/resolver-binding-linux-riscv64-musl@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.7.2.tgz" + integrity sha512-NoAGbiqrxtY8kVooZ24i70CjLDlUFI7nDj3I9y54U94p+3kPxwd2L692YsdLa+cqQ0VoqMWoehDFp21PKRUoIQ== + +"@unrs/resolver-binding-linux-s390x-gnu@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.7.2.tgz" + integrity sha512-KaZByo8xuQZbUhhreBTW+yUnOIHUsv04P8lKjQ5otiGoSJ17ISGYArc+4vKdLEpGaLbemGzr4ZeUbYQQsLWFjA== + +"@unrs/resolver-binding-linux-x64-gnu@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.7.2.tgz" + integrity sha512-dEidzJDubxxhUCBJ/SHSMJD/9q7JkyfBMT77Px1npl4xpg9t0POLvnWywSk66BgZS/b2Hy9Y1yFaoMTFJUe9yg== + +"@unrs/resolver-binding-linux-x64-musl@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.7.2.tgz" + integrity sha512-RvP+Ux3wDjmnZDT4XWFfNBRVG0fMsc+yVzNFUqOflnDfZ9OYujv6nkh+GOr+watwrW4wdp6ASfG/e7bkDradsw== + +"@unrs/resolver-binding-wasm32-wasi@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.7.2.tgz" + integrity sha512-y797JBmO9IsvXVRCKDXOxjyAE4+CcZpla2GSoBQ33TVb3ILXuFnMrbR/QQZoauBYeOFuu4w3ifWLw52sdHGz6g== + dependencies: + "@napi-rs/wasm-runtime" "^0.2.9" + +"@unrs/resolver-binding-win32-arm64-msvc@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.7.2.tgz" + integrity sha512-gtYTh4/VREVSLA+gHrfbWxaMO/00y+34htY7XpioBTy56YN2eBjkPrY1ML1Zys89X3RJDKVaogzwxlM1qU7egg== + +"@unrs/resolver-binding-win32-ia32-msvc@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.7.2.tgz" + integrity sha512-Ywv20XHvHTDRQs12jd3MY8X5C8KLjDbg/jyaal/QLKx3fAShhJyD4blEANInsjxW3P7isHx1Blt56iUDDJO3jg== + "@unrs/resolver-binding-win32-x64-msvc@1.7.2": version "1.7.2" resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.7.2.tgz" @@ -3552,6 +3820,11 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" From cc45788681292ebe1e399aba7da782d54c6748de Mon Sep 17 00:00:00 2001 From: pwc2002 Date: Sat, 30 Aug 2025 23:07:18 +0900 Subject: [PATCH 11/20] =?UTF-8?q?Fix:=20deploy.yml=EC=97=90=EC=84=9C=20NOD?= =?UTF-8?q?E=5FENV=20=ED=99=98=EA=B2=BD=20=EB=B3=80=EC=88=98=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index fef6f98..4064cd1 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -16,7 +16,6 @@ jobs: deploy: runs-on: ubuntu-latest env: - NODE_ENV: production NEXT_PUBLIC_BASE_API_URL: ${{ secrets.NEXT_PUBLIC_BASE_API_URL }} NEXT_PUBLIC_GOOGLE_REDIRECT_CLIENT_ID: ${{ secrets.NEXT_PUBLIC_GOOGLE_REDIRECT_CLIENT_ID }} NEXT_PUBLIC_GOOGLE_REDIRECT_URI: ${{ secrets.NEXT_PUBLIC_GOOGLE_REDIRECT_URI }} From ce02d8341d7f6a30f834145e2dc85de81cf7d66e Mon Sep 17 00:00:00 2001 From: pwc2002 Date: Sat, 30 Aug 2025 23:12:28 +0900 Subject: [PATCH 12/20] =?UTF-8?q?Feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EC=97=90=20cicd=20=EB=B0=B0=ED=8F=AC=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/test/page.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/test/page.jsx b/src/app/test/page.jsx index d849638..bbecc1b 100644 --- a/src/app/test/page.jsx +++ b/src/app/test/page.jsx @@ -45,6 +45,7 @@ export default function TestAuthPage() { return (

로그인 테스트

+

cicd 배포 테스트 입니다.

현재 로그인 상태
From 6efbf1f2a85ac154faaebcd4f02542b2930bdd18 Mon Sep 17 00:00:00 2001 From: pwc2002 Date: Sun, 31 Aug 2025 03:00:39 +0900 Subject: [PATCH 13/20] =?UTF-8?q?Feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EB=B0=8F=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B0=9C=EC=84=A0,=20=EC=9D=B4=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=20=EC=A4=91=EB=B3=B5=20=EC=B2=B4=ED=81=AC=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/admin/page.jsx | 5 +- src/app/auth/signup/page.jsx | 34 ++- src/components/auth/ApiCodeGuard.jsx | 4 +- src/components/auth/screen/AuthLogin.jsx | 4 +- .../auth/signup/AdditionalInfoForm.jsx | 16 +- .../auth/signup/ProfileInfoForm.jsx | 10 +- src/components/ui/common/MenuHeader.jsx | 16 +- yarn.lock | 273 ------------------ 8 files changed, 65 insertions(+), 297 deletions(-) diff --git a/src/app/admin/page.jsx b/src/app/admin/page.jsx index ebf4a66..12ccff7 100644 --- a/src/app/admin/page.jsx +++ b/src/app/admin/page.jsx @@ -168,7 +168,10 @@ export default function Page() { className='dark py-[30px] px-[96px] mobile:px-[10px]' aria-label='Example table with custom cells' bottomContent={ - setPage(newPage)} /> +
+ setPage(newPage)} /> +
총 가입자 수 : {totalUsers}
+
} topContent={ diff --git a/src/app/auth/signup/page.jsx b/src/app/auth/signup/page.jsx index d926517..cf9014a 100644 --- a/src/app/auth/signup/page.jsx +++ b/src/app/auth/signup/page.jsx @@ -58,7 +58,7 @@ export default function Signup() { }, []); // 첫 번째 화면에서 다음 버튼 클릭 시 처리 - const handleNext = () => { + const handleNext = async () => { if (!name || !email || !password || !confirmPassword) { alert("모든 칸을 채워주세요."); return; @@ -67,11 +67,24 @@ export default function Signup() { alert("비밀번호가 일치하지 않습니다."); return; } - if(email === "pwc2002"){ + + const checkEmail = await apiClient.get('/auth/check', { + params: { + email: email + } + }) + if(checkEmail.data.data.isDuplicated){ setIsEmailValid(true); - alert("이미 가입된 이메일입니다."); return; } + + if(checkEmail.data.code != 200){ + alert("에러가 발생하였습니다."); + return; + } + + + if(errors.length > 0){ alert("비밀번호 조건을 만족해주세요."); return; @@ -109,6 +122,12 @@ export default function Signup() { try { const res = await apiClient.post('/auth/signup', userinfo); console.log(res); + if(res.data.code == 200){ + console.log(res.data.message); + router.push("/auth/signin"); + } else { + alert(res.data.message); + } } catch (error) { console.log(error); } @@ -128,10 +147,10 @@ export default function Signup() { return (
-
-

회원가입하기

+
+ {/*

회원가입하기

*/} -
+
@@ -167,7 +187,7 @@ export default function Signup() { className="text-white bg-[#EA4336] w-full h-[48px] rounded-full" style={{boxShadow: "black 0px -10px 20px 10px"}} onPress={isAnimating ? handleSignup : handleNext} - isDisabled={!isAnimating && (!name || !email || !password || !confirmPassword || errors.length > 0 || password !== confirmPassword)} + isDisabled={!isAnimating && (!name || !email || !password || !confirmPassword || errors.length > 0 || password !== confirmPassword || isEmailValid)} > {isAnimating ? "가입하기" : "다음"} diff --git a/src/components/auth/ApiCodeGuard.jsx b/src/components/auth/ApiCodeGuard.jsx index 20e2ce0..6923b05 100644 --- a/src/components/auth/ApiCodeGuard.jsx +++ b/src/components/auth/ApiCodeGuard.jsx @@ -27,13 +27,13 @@ export default function ApiCodeGuard({ children }) { if (code === 200) { setAllowed(true); } else { - router.replace('/unauthorized'); + router.replace('/auth/signin'); } } } catch (error) { if (!cancelled) { // 인터셉터에서 401/403 처리로 리다이렉트가 발생할 수 있으므로, 보조적으로 차단 - router.replace('/unauthorized'); + router.replace('/auth/signin'); } } finally { if (!cancelled) { diff --git a/src/components/auth/screen/AuthLogin.jsx b/src/components/auth/screen/AuthLogin.jsx index 1d2001a..8e5cc5a 100644 --- a/src/components/auth/screen/AuthLogin.jsx +++ b/src/components/auth/screen/AuthLogin.jsx @@ -100,7 +100,7 @@ export default function AuthLogin({ router, onSubmit, errors, password, setPassw > 회원가입 -
+ {/*

또는

@@ -114,7 +114,7 @@ export default function AuthLogin({ router, onSubmit, errors, password, setPassw height={54} width={54} /> -
+
*/}
); } \ No newline at end of file diff --git a/src/components/auth/signup/AdditionalInfoForm.jsx b/src/components/auth/signup/AdditionalInfoForm.jsx index 34ac3dc..7f5bd2e 100644 --- a/src/components/auth/signup/AdditionalInfoForm.jsx +++ b/src/components/auth/signup/AdditionalInfoForm.jsx @@ -96,8 +96,20 @@ export default function AdditionalInfoForm({ placeholder="전화번호를 입력해주세요 (예: 010-1234-5678)" radius="full" className="w-full" - value={phoneNumber} - onValueChange={setPhoneNumber} + value={phoneNumber} + onChange={(e) => { + const value = e.target.value.replace(/[^0-9]/g, ''); + if (value.length <= 11) { + let formattedNumber = value; + if (value.length > 3) { + formattedNumber = value.slice(0,3) + '-' + value.slice(3); + } + if (value.length > 7) { + formattedNumber = formattedNumber.slice(0,8) + '-' + formattedNumber.slice(8); + } + setPhoneNumber(formattedNumber); + } + }} classNames={{ label: "!pb-[10px] !text-white", inputWrapper: `h-[48px] rounded-full border-2 border-white/50 caret-white bg-transparent !transition !duration-300 !ease-in-out diff --git a/src/components/auth/signup/ProfileInfoForm.jsx b/src/components/auth/signup/ProfileInfoForm.jsx index 26707d7..d81616b 100644 --- a/src/components/auth/signup/ProfileInfoForm.jsx +++ b/src/components/auth/signup/ProfileInfoForm.jsx @@ -8,8 +8,14 @@ export default function ProfileInfoForm({ password, setPassword, confirmPassword, setConfirmPassword, errors, isEmailValid, - isNameDisabled, isEmailDisabled + isNameDisabled, isEmailDisabled, setIsEmailValid }) { + + const emailChange = (e) => { + setEmail(e.target.value); + setIsEmailValid(false); + } + return (
alert('준비중입니다.') }, { name: "공지사항", href: "#", onClick: () => alert('준비중입니다.') }, - { name: "프로젝트", href: "https://solution.gdgocinha.com" }, - { name: "멤버", href: "#", onClick: () => alert('준비중입니다.') }, + { name: "프로젝트", href: "#", onClick: () => alert('준비중입니다.') }, { name: "로그아웃", href: "#", onClick: handleLogout } ]; @@ -43,23 +43,23 @@ export default function MenuHeader() { - - 스터디 + + 멤버관리 alert('준비중입니다.')}> - 공지사항 + 스터디 alert('준비중입니다.')}> - 프로젝트 + 공지사항 alert('준비중입니다.')}> - 멤버 + 프로젝트 diff --git a/yarn.lock b/yarn.lock index eeb5cf9..aa766a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,28 +12,6 @@ resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz" integrity sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog== -"@emnapi/core@^1.4.0": - version "1.4.3" - resolved "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz" - integrity sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g== - dependencies: - "@emnapi/wasi-threads" "1.0.2" - tslib "^2.4.0" - -"@emnapi/runtime@^1.4.0": - version "1.4.3" - resolved "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz" - integrity sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ== - dependencies: - tslib "^2.4.0" - -"@emnapi/wasi-threads@1.0.2": - version "1.0.2" - resolved "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz" - integrity sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA== - dependencies: - tslib "^2.4.0" - "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.7.0": version "4.7.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz" @@ -201,119 +179,6 @@ resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== -"@img/sharp-darwin-arm64@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.1.tgz" - integrity sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A== - optionalDependencies: - "@img/sharp-libvips-darwin-arm64" "1.1.0" - -"@img/sharp-darwin-x64@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.1.tgz" - integrity sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q== - optionalDependencies: - "@img/sharp-libvips-darwin-x64" "1.1.0" - -"@img/sharp-libvips-darwin-arm64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz" - integrity sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA== - -"@img/sharp-libvips-darwin-x64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz" - integrity sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ== - -"@img/sharp-libvips-linux-arm@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz" - integrity sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA== - -"@img/sharp-libvips-linux-arm64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz" - integrity sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew== - -"@img/sharp-libvips-linux-ppc64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz" - integrity sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ== - -"@img/sharp-libvips-linux-s390x@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz" - integrity sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA== - -"@img/sharp-libvips-linux-x64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz" - integrity sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q== - -"@img/sharp-libvips-linuxmusl-arm64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz" - integrity sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w== - -"@img/sharp-libvips-linuxmusl-x64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz" - integrity sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A== - -"@img/sharp-linux-arm@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.1.tgz" - integrity sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA== - optionalDependencies: - "@img/sharp-libvips-linux-arm" "1.1.0" - -"@img/sharp-linux-arm64@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.1.tgz" - integrity sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ== - optionalDependencies: - "@img/sharp-libvips-linux-arm64" "1.1.0" - -"@img/sharp-linux-s390x@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.1.tgz" - integrity sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA== - optionalDependencies: - "@img/sharp-libvips-linux-s390x" "1.1.0" - -"@img/sharp-linux-x64@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.1.tgz" - integrity sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA== - optionalDependencies: - "@img/sharp-libvips-linux-x64" "1.1.0" - -"@img/sharp-linuxmusl-arm64@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.1.tgz" - integrity sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-arm64" "1.1.0" - -"@img/sharp-linuxmusl-x64@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.1.tgz" - integrity sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-x64" "1.1.0" - -"@img/sharp-wasm32@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.1.tgz" - integrity sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg== - dependencies: - "@emnapi/runtime" "^1.4.0" - -"@img/sharp-win32-ia32@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.1.tgz" - integrity sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw== - "@img/sharp-win32-x64@0.34.1": version "0.34.1" resolved "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.1.tgz" @@ -399,15 +264,6 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@napi-rs/wasm-runtime@^0.2.9": - version "0.2.9" - resolved "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.9.tgz" - integrity sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg== - dependencies: - "@emnapi/core" "^1.4.0" - "@emnapi/runtime" "^1.4.0" - "@tybys/wasm-util" "^0.9.0" - "@next/env@15.3.2": version "15.3.2" resolved "https://registry.npmjs.org/@next/env/-/env-15.3.2.tgz" @@ -420,41 +276,6 @@ dependencies: fast-glob "3.3.1" -"@next/swc-darwin-arm64@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.2.tgz" - integrity sha512-2DR6kY/OGcokbnCsjHpNeQblqCZ85/1j6njYSkzRdpLn5At7OkSdmk7WyAmB9G0k25+VgqVZ/u356OSoQZ3z0g== - -"@next/swc-darwin-x64@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.3.2.tgz" - integrity sha512-ro/fdqaZWL6k1S/5CLv1I0DaZfDVJkWNaUU3un8Lg6m0YENWlDulmIWzV96Iou2wEYyEsZq51mwV8+XQXqMp3w== - -"@next/swc-linux-arm64-gnu@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.3.2.tgz" - integrity sha512-covwwtZYhlbRWK2HlYX9835qXum4xYZ3E2Mra1mdQ+0ICGoMiw1+nVAn4d9Bo7R3JqSmK1grMq/va+0cdh7bJA== - -"@next/swc-linux-arm64-musl@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.3.2.tgz" - integrity sha512-KQkMEillvlW5Qk5mtGA/3Yz0/tzpNlSw6/3/ttsV1lNtMuOHcGii3zVeXZyi4EJmmLDKYcTcByV2wVsOhDt/zg== - -"@next/swc-linux-x64-gnu@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.3.2.tgz" - integrity sha512-uRBo6THWei0chz+Y5j37qzx+BtoDRFIkDzZjlpCItBRXyMPIg079eIkOCl3aqr2tkxL4HFyJ4GHDes7W8HuAUg== - -"@next/swc-linux-x64-musl@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.3.2.tgz" - integrity sha512-+uxFlPuCNx/T9PdMClOqeE8USKzj8tVz37KflT3Kdbx/LOlZBRI2yxuIcmx1mPNK8DwSOMNCr4ureSet7eyC0w== - -"@next/swc-win32-arm64-msvc@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.3.2.tgz" - integrity sha512-LLTKmaI5cfD8dVzh5Vt7+OMo+AIOClEdIU/TSKbXXT2iScUTSxOGoBhfuv+FU8R9MLmrkIL1e2fBMkEEjYAtPQ== - "@next/swc-win32-x64-msvc@15.3.2": version "15.3.2" resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.3.2.tgz" @@ -2604,13 +2425,6 @@ resolved "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.11.2.tgz" integrity sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw== -"@tybys/wasm-util@^0.9.0": - version "0.9.0" - resolved "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz" - integrity sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw== - dependencies: - tslib "^2.4.0" - "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" @@ -2728,88 +2542,6 @@ resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== -"@unrs/resolver-binding-darwin-arm64@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.7.2.tgz" - integrity sha512-vxtBno4xvowwNmO/ASL0Y45TpHqmNkAaDtz4Jqb+clmcVSSl8XCG/PNFFkGsXXXS6AMjP+ja/TtNCFFa1QwLRg== - -"@unrs/resolver-binding-darwin-x64@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.7.2.tgz" - integrity sha512-qhVa8ozu92C23Hsmv0BF4+5Dyyd5STT1FolV4whNgbY6mj3kA0qsrGPe35zNR3wAN7eFict3s4Rc2dDTPBTuFQ== - -"@unrs/resolver-binding-freebsd-x64@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.7.2.tgz" - integrity sha512-zKKdm2uMXqLFX6Ac7K5ElnnG5VIXbDlFWzg4WJ8CGUedJryM5A3cTgHuGMw1+P5ziV8CRhnSEgOnurTI4vpHpg== - -"@unrs/resolver-binding-linux-arm-gnueabihf@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.7.2.tgz" - integrity sha512-8N1z1TbPnHH+iDS/42GJ0bMPLiGK+cUqOhNbMKtWJ4oFGzqSJk/zoXFzcQkgtI63qMcUI7wW1tq2usZQSb2jxw== - -"@unrs/resolver-binding-linux-arm-musleabihf@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.7.2.tgz" - integrity sha512-tjYzI9LcAXR9MYd9rO45m1s0B/6bJNuZ6jeOxo1pq1K6OBuRMMmfyvJYval3s9FPPGmrldYA3mi4gWDlWuTFGA== - -"@unrs/resolver-binding-linux-arm64-gnu@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.7.2.tgz" - integrity sha512-jon9M7DKRLGZ9VYSkFMflvNqu9hDtOCEnO2QAryFWgT6o6AXU8du56V7YqnaLKr6rAbZBWYsYpikF226v423QA== - -"@unrs/resolver-binding-linux-arm64-musl@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.7.2.tgz" - integrity sha512-c8Cg4/h+kQ63pL43wBNaVMmOjXI/X62wQmru51qjfTvI7kmCy5uHTJvK/9LrF0G8Jdx8r34d019P1DVJmhXQpA== - -"@unrs/resolver-binding-linux-ppc64-gnu@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.7.2.tgz" - integrity sha512-A+lcwRFyrjeJmv3JJvhz5NbcCkLQL6Mk16kHTNm6/aGNc4FwPHPE4DR9DwuCvCnVHvF5IAd9U4VIs/VvVir5lg== - -"@unrs/resolver-binding-linux-riscv64-gnu@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.7.2.tgz" - integrity sha512-hQQ4TJQrSQW8JlPm7tRpXN8OCNP9ez7PajJNjRD1ZTHQAy685OYqPrKjfaMw/8LiHCt8AZ74rfUVHP9vn0N69Q== - -"@unrs/resolver-binding-linux-riscv64-musl@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.7.2.tgz" - integrity sha512-NoAGbiqrxtY8kVooZ24i70CjLDlUFI7nDj3I9y54U94p+3kPxwd2L692YsdLa+cqQ0VoqMWoehDFp21PKRUoIQ== - -"@unrs/resolver-binding-linux-s390x-gnu@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.7.2.tgz" - integrity sha512-KaZByo8xuQZbUhhreBTW+yUnOIHUsv04P8lKjQ5otiGoSJ17ISGYArc+4vKdLEpGaLbemGzr4ZeUbYQQsLWFjA== - -"@unrs/resolver-binding-linux-x64-gnu@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.7.2.tgz" - integrity sha512-dEidzJDubxxhUCBJ/SHSMJD/9q7JkyfBMT77Px1npl4xpg9t0POLvnWywSk66BgZS/b2Hy9Y1yFaoMTFJUe9yg== - -"@unrs/resolver-binding-linux-x64-musl@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.7.2.tgz" - integrity sha512-RvP+Ux3wDjmnZDT4XWFfNBRVG0fMsc+yVzNFUqOflnDfZ9OYujv6nkh+GOr+watwrW4wdp6ASfG/e7bkDradsw== - -"@unrs/resolver-binding-wasm32-wasi@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.7.2.tgz" - integrity sha512-y797JBmO9IsvXVRCKDXOxjyAE4+CcZpla2GSoBQ33TVb3ILXuFnMrbR/QQZoauBYeOFuu4w3ifWLw52sdHGz6g== - dependencies: - "@napi-rs/wasm-runtime" "^0.2.9" - -"@unrs/resolver-binding-win32-arm64-msvc@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.7.2.tgz" - integrity sha512-gtYTh4/VREVSLA+gHrfbWxaMO/00y+34htY7XpioBTy56YN2eBjkPrY1ML1Zys89X3RJDKVaogzwxlM1qU7egg== - -"@unrs/resolver-binding-win32-ia32-msvc@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.7.2.tgz" - integrity sha512-Ywv20XHvHTDRQs12jd3MY8X5C8KLjDbg/jyaal/QLKx3fAShhJyD4blEANInsjxW3P7isHx1Blt56iUDDJO3jg== - "@unrs/resolver-binding-win32-x64-msvc@1.7.2": version "1.7.2" resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.7.2.tgz" @@ -3820,11 +3552,6 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" From 233ff7fdbe3f56a3936eecf83e96a082d564d00b Mon Sep 17 00:00:00 2001 From: pwc2002 Date: Sun, 31 Aug 2025 03:05:16 +0900 Subject: [PATCH 14/20] =?UTF-8?q?Fix:=20HeroSection=EC=97=90=EC=84=9C=20'2?= =?UTF-8?q?025-1=20Recruitment'=EB=A5=BC=20'2025-2=20Recruitment'=EB=A1=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/landing/HeroSection.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/landing/HeroSection.jsx b/src/components/landing/HeroSection.jsx index f37c160..e7fe18d 100644 --- a/src/components/landing/HeroSection.jsx +++ b/src/components/landing/HeroSection.jsx @@ -79,7 +79,7 @@ export default function HeroSection({ router }) {

- 2025-1 Recruitment + 2025-2 Recruitment

-
25-1 멤버 가입이 완료되었습니다.
+
25-2 멤버 가입이 완료되었습니다.
신규 멤버 초대는 매주 월요일 오후 3시에 일괄 진행됩니다.
diff --git a/src/components/recruit/screen/Recruit2.jsx b/src/components/recruit/screen/Recruit2.jsx index 9d98fc7..e345c06 100644 --- a/src/components/recruit/screen/Recruit2.jsx +++ b/src/components/recruit/screen/Recruit2.jsx @@ -41,11 +41,11 @@ export default function Recruit2({ step, setChecked, updateRecruitData }) { const handleCheckDuplicate = async () => { try { - const response = await axios.get(`${process.env.NEXT_PUBLIC_BASE_API_URL}/check/studentId`, { + const response = await axios.get(`${process.env.NEXT_PUBLIC_BASE_API_URL}/check/student-id`, { params: { studentId }, }); setIsValidButtonClicked(true); - setIsValidStudentId(!response.data.data); + setIsValidStudentId(!response.data.data.isExists); } catch (error) { setIsValidButtonClicked(true); console.log('중복확인 오류 발생:', error); diff --git a/src/components/recruit/screen/Recruit3.jsx b/src/components/recruit/screen/Recruit3.jsx index b0daf80..71acdb5 100644 --- a/src/components/recruit/screen/Recruit3.jsx +++ b/src/components/recruit/screen/Recruit3.jsx @@ -58,11 +58,11 @@ export default function Recruit3({ step, setChecked, updateRecruitData }) { const handleCheckDuplicate = async () => { try { - const response = await axios.get(`${process.env.NEXT_PUBLIC_BASE_API_URL}/check/phoneNumber`, { + const response = await axios.get(`${process.env.NEXT_PUBLIC_BASE_API_URL}/check/phone-number`, { params: { phoneNumber }, }); setIsValidButtonClicked(true); - setIsValidPhoneNumber(!response.data.data); + setIsValidPhoneNumber(!response.data.data.isExists); } catch (error) { setIsValidButtonClicked(true); console.log('중복확인 오류 발생:', error); diff --git a/yarn.lock b/yarn.lock index aa766a7..eeb5cf9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,6 +12,28 @@ resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz" integrity sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog== +"@emnapi/core@^1.4.0": + version "1.4.3" + resolved "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz" + integrity sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g== + dependencies: + "@emnapi/wasi-threads" "1.0.2" + tslib "^2.4.0" + +"@emnapi/runtime@^1.4.0": + version "1.4.3" + resolved "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz" + integrity sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ== + dependencies: + tslib "^2.4.0" + +"@emnapi/wasi-threads@1.0.2": + version "1.0.2" + resolved "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz" + integrity sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA== + dependencies: + tslib "^2.4.0" + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.7.0": version "4.7.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz" @@ -179,6 +201,119 @@ resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== +"@img/sharp-darwin-arm64@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.1.tgz" + integrity sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A== + optionalDependencies: + "@img/sharp-libvips-darwin-arm64" "1.1.0" + +"@img/sharp-darwin-x64@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.1.tgz" + integrity sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q== + optionalDependencies: + "@img/sharp-libvips-darwin-x64" "1.1.0" + +"@img/sharp-libvips-darwin-arm64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz" + integrity sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA== + +"@img/sharp-libvips-darwin-x64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz" + integrity sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ== + +"@img/sharp-libvips-linux-arm@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz" + integrity sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA== + +"@img/sharp-libvips-linux-arm64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz" + integrity sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew== + +"@img/sharp-libvips-linux-ppc64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz" + integrity sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ== + +"@img/sharp-libvips-linux-s390x@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz" + integrity sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA== + +"@img/sharp-libvips-linux-x64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz" + integrity sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q== + +"@img/sharp-libvips-linuxmusl-arm64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz" + integrity sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w== + +"@img/sharp-libvips-linuxmusl-x64@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz" + integrity sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A== + +"@img/sharp-linux-arm@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.1.tgz" + integrity sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA== + optionalDependencies: + "@img/sharp-libvips-linux-arm" "1.1.0" + +"@img/sharp-linux-arm64@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.1.tgz" + integrity sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ== + optionalDependencies: + "@img/sharp-libvips-linux-arm64" "1.1.0" + +"@img/sharp-linux-s390x@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.1.tgz" + integrity sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA== + optionalDependencies: + "@img/sharp-libvips-linux-s390x" "1.1.0" + +"@img/sharp-linux-x64@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.1.tgz" + integrity sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA== + optionalDependencies: + "@img/sharp-libvips-linux-x64" "1.1.0" + +"@img/sharp-linuxmusl-arm64@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.1.tgz" + integrity sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-arm64" "1.1.0" + +"@img/sharp-linuxmusl-x64@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.1.tgz" + integrity sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-x64" "1.1.0" + +"@img/sharp-wasm32@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.1.tgz" + integrity sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg== + dependencies: + "@emnapi/runtime" "^1.4.0" + +"@img/sharp-win32-ia32@0.34.1": + version "0.34.1" + resolved "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.1.tgz" + integrity sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw== + "@img/sharp-win32-x64@0.34.1": version "0.34.1" resolved "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.1.tgz" @@ -264,6 +399,15 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@napi-rs/wasm-runtime@^0.2.9": + version "0.2.9" + resolved "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.9.tgz" + integrity sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg== + dependencies: + "@emnapi/core" "^1.4.0" + "@emnapi/runtime" "^1.4.0" + "@tybys/wasm-util" "^0.9.0" + "@next/env@15.3.2": version "15.3.2" resolved "https://registry.npmjs.org/@next/env/-/env-15.3.2.tgz" @@ -276,6 +420,41 @@ dependencies: fast-glob "3.3.1" +"@next/swc-darwin-arm64@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.2.tgz" + integrity sha512-2DR6kY/OGcokbnCsjHpNeQblqCZ85/1j6njYSkzRdpLn5At7OkSdmk7WyAmB9G0k25+VgqVZ/u356OSoQZ3z0g== + +"@next/swc-darwin-x64@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.3.2.tgz" + integrity sha512-ro/fdqaZWL6k1S/5CLv1I0DaZfDVJkWNaUU3un8Lg6m0YENWlDulmIWzV96Iou2wEYyEsZq51mwV8+XQXqMp3w== + +"@next/swc-linux-arm64-gnu@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.3.2.tgz" + integrity sha512-covwwtZYhlbRWK2HlYX9835qXum4xYZ3E2Mra1mdQ+0ICGoMiw1+nVAn4d9Bo7R3JqSmK1grMq/va+0cdh7bJA== + +"@next/swc-linux-arm64-musl@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.3.2.tgz" + integrity sha512-KQkMEillvlW5Qk5mtGA/3Yz0/tzpNlSw6/3/ttsV1lNtMuOHcGii3zVeXZyi4EJmmLDKYcTcByV2wVsOhDt/zg== + +"@next/swc-linux-x64-gnu@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.3.2.tgz" + integrity sha512-uRBo6THWei0chz+Y5j37qzx+BtoDRFIkDzZjlpCItBRXyMPIg079eIkOCl3aqr2tkxL4HFyJ4GHDes7W8HuAUg== + +"@next/swc-linux-x64-musl@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.3.2.tgz" + integrity sha512-+uxFlPuCNx/T9PdMClOqeE8USKzj8tVz37KflT3Kdbx/LOlZBRI2yxuIcmx1mPNK8DwSOMNCr4ureSet7eyC0w== + +"@next/swc-win32-arm64-msvc@15.3.2": + version "15.3.2" + resolved "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.3.2.tgz" + integrity sha512-LLTKmaI5cfD8dVzh5Vt7+OMo+AIOClEdIU/TSKbXXT2iScUTSxOGoBhfuv+FU8R9MLmrkIL1e2fBMkEEjYAtPQ== + "@next/swc-win32-x64-msvc@15.3.2": version "15.3.2" resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.3.2.tgz" @@ -2425,6 +2604,13 @@ resolved "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.11.2.tgz" integrity sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw== +"@tybys/wasm-util@^0.9.0": + version "0.9.0" + resolved "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz" + integrity sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw== + dependencies: + tslib "^2.4.0" + "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" @@ -2542,6 +2728,88 @@ resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== +"@unrs/resolver-binding-darwin-arm64@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.7.2.tgz" + integrity sha512-vxtBno4xvowwNmO/ASL0Y45TpHqmNkAaDtz4Jqb+clmcVSSl8XCG/PNFFkGsXXXS6AMjP+ja/TtNCFFa1QwLRg== + +"@unrs/resolver-binding-darwin-x64@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.7.2.tgz" + integrity sha512-qhVa8ozu92C23Hsmv0BF4+5Dyyd5STT1FolV4whNgbY6mj3kA0qsrGPe35zNR3wAN7eFict3s4Rc2dDTPBTuFQ== + +"@unrs/resolver-binding-freebsd-x64@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.7.2.tgz" + integrity sha512-zKKdm2uMXqLFX6Ac7K5ElnnG5VIXbDlFWzg4WJ8CGUedJryM5A3cTgHuGMw1+P5ziV8CRhnSEgOnurTI4vpHpg== + +"@unrs/resolver-binding-linux-arm-gnueabihf@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.7.2.tgz" + integrity sha512-8N1z1TbPnHH+iDS/42GJ0bMPLiGK+cUqOhNbMKtWJ4oFGzqSJk/zoXFzcQkgtI63qMcUI7wW1tq2usZQSb2jxw== + +"@unrs/resolver-binding-linux-arm-musleabihf@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.7.2.tgz" + integrity sha512-tjYzI9LcAXR9MYd9rO45m1s0B/6bJNuZ6jeOxo1pq1K6OBuRMMmfyvJYval3s9FPPGmrldYA3mi4gWDlWuTFGA== + +"@unrs/resolver-binding-linux-arm64-gnu@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.7.2.tgz" + integrity sha512-jon9M7DKRLGZ9VYSkFMflvNqu9hDtOCEnO2QAryFWgT6o6AXU8du56V7YqnaLKr6rAbZBWYsYpikF226v423QA== + +"@unrs/resolver-binding-linux-arm64-musl@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.7.2.tgz" + integrity sha512-c8Cg4/h+kQ63pL43wBNaVMmOjXI/X62wQmru51qjfTvI7kmCy5uHTJvK/9LrF0G8Jdx8r34d019P1DVJmhXQpA== + +"@unrs/resolver-binding-linux-ppc64-gnu@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.7.2.tgz" + integrity sha512-A+lcwRFyrjeJmv3JJvhz5NbcCkLQL6Mk16kHTNm6/aGNc4FwPHPE4DR9DwuCvCnVHvF5IAd9U4VIs/VvVir5lg== + +"@unrs/resolver-binding-linux-riscv64-gnu@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.7.2.tgz" + integrity sha512-hQQ4TJQrSQW8JlPm7tRpXN8OCNP9ez7PajJNjRD1ZTHQAy685OYqPrKjfaMw/8LiHCt8AZ74rfUVHP9vn0N69Q== + +"@unrs/resolver-binding-linux-riscv64-musl@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.7.2.tgz" + integrity sha512-NoAGbiqrxtY8kVooZ24i70CjLDlUFI7nDj3I9y54U94p+3kPxwd2L692YsdLa+cqQ0VoqMWoehDFp21PKRUoIQ== + +"@unrs/resolver-binding-linux-s390x-gnu@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.7.2.tgz" + integrity sha512-KaZByo8xuQZbUhhreBTW+yUnOIHUsv04P8lKjQ5otiGoSJ17ISGYArc+4vKdLEpGaLbemGzr4ZeUbYQQsLWFjA== + +"@unrs/resolver-binding-linux-x64-gnu@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.7.2.tgz" + integrity sha512-dEidzJDubxxhUCBJ/SHSMJD/9q7JkyfBMT77Px1npl4xpg9t0POLvnWywSk66BgZS/b2Hy9Y1yFaoMTFJUe9yg== + +"@unrs/resolver-binding-linux-x64-musl@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.7.2.tgz" + integrity sha512-RvP+Ux3wDjmnZDT4XWFfNBRVG0fMsc+yVzNFUqOflnDfZ9OYujv6nkh+GOr+watwrW4wdp6ASfG/e7bkDradsw== + +"@unrs/resolver-binding-wasm32-wasi@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.7.2.tgz" + integrity sha512-y797JBmO9IsvXVRCKDXOxjyAE4+CcZpla2GSoBQ33TVb3ILXuFnMrbR/QQZoauBYeOFuu4w3ifWLw52sdHGz6g== + dependencies: + "@napi-rs/wasm-runtime" "^0.2.9" + +"@unrs/resolver-binding-win32-arm64-msvc@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.7.2.tgz" + integrity sha512-gtYTh4/VREVSLA+gHrfbWxaMO/00y+34htY7XpioBTy56YN2eBjkPrY1ML1Zys89X3RJDKVaogzwxlM1qU7egg== + +"@unrs/resolver-binding-win32-ia32-msvc@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.7.2.tgz" + integrity sha512-Ywv20XHvHTDRQs12jd3MY8X5C8KLjDbg/jyaal/QLKx3fAShhJyD4blEANInsjxW3P7isHx1Blt56iUDDJO3jg== + "@unrs/resolver-binding-win32-x64-msvc@1.7.2": version "1.7.2" resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.7.2.tgz" @@ -3552,6 +3820,11 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" From 216778331c35348ae2a3fa5972988071e0ea0f78 Mon Sep 17 00:00:00 2001 From: ThinkMuk Date: Mon, 1 Sep 2025 22:11:18 +0900 Subject: [PATCH 17/20] =?UTF-8?q?Fix:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=EC=B0=BD=20=ED=99=9C=EC=84=B1=ED=99=94=20?= =?UTF-8?q?=EC=A4=91=20=EA=B2=B0=EC=A0=9C=20=ED=86=A0=EA=B8=80=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=98=A4=EB=A5=98=20=EA=B0=9C=EC=84=A0=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/admin/page.jsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/app/admin/page.jsx b/src/app/admin/page.jsx index 4ee122f..0c48244 100644 --- a/src/app/admin/page.jsx +++ b/src/app/admin/page.jsx @@ -18,11 +18,6 @@ const columns = [ { name: 'TOGGLE', uid: 'togglePay' }, ]; -const statusColorMap = { - true: 'success', - false: 'danger', -}; - export default function Page() { const router = useRouter(); const { apiClient } = useAuthenticatedApi(); @@ -75,6 +70,7 @@ export default function Page() { //회비 지불여부 체크박스 const handleTogglePay = useCallback( async (userId, nextValue) => { + if (modalClosing.current) return; // 모달이 닫히는 중에는 클릭 무시 const getItemId = (user) => user?.id; const prevUsers = currentUsers; @@ -169,8 +165,12 @@ export default function Page() { aria-label='Example table with custom cells' bottomContent={
- setPage(newPage)} /> -
{totalUsers}
+ setPage(newPage)} + />
} topContent={ From 03184f2d1b4de77be59bb0b69c57676aac1ee634 Mon Sep 17 00:00:00 2001 From: ThinkMuk Date: Mon, 1 Sep 2025 22:12:30 +0900 Subject: [PATCH 18/20] =?UTF-8?q?Fix:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=B4=9D=20=EA=B0=80=EC=9E=85=EC=9E=90=20=EC=88=98=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/admin/AdminTableBottomContent.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/admin/AdminTableBottomContent.jsx b/src/components/admin/AdminTableBottomContent.jsx index 71c67bf..2cb2a5d 100644 --- a/src/components/admin/AdminTableBottomContent.jsx +++ b/src/components/admin/AdminTableBottomContent.jsx @@ -3,7 +3,7 @@ import React from 'react'; import { Pagination } from '@nextui-org/react'; -export default function AdminTableBottomContent({ page, totalPages, onChangePage }) { +export default function AdminTableBottomContent({ page, totalPages, totalUsers, onChangePage }) { if (!totalPages || totalPages <= 0) return null; return ( @@ -17,6 +17,7 @@ export default function AdminTableBottomContent({ page, totalPages, onChangePage total={totalPages} onChange={onChangePage} /> +
{totalUsers}
); } From 75d9e3a004ef95a1f903c369888b36696b8b671b Mon Sep 17 00:00:00 2001 From: ThinkMuk Date: Mon, 1 Sep 2025 22:15:01 +0900 Subject: [PATCH 19/20] =?UTF-8?q?Chore:=20yarn.lock=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=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 --- yarn.lock | 261 ------------------------------------------------------ 1 file changed, 261 deletions(-) diff --git a/yarn.lock b/yarn.lock index eeb5cf9..06265dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,28 +12,6 @@ resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz" integrity sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog== -"@emnapi/core@^1.4.0": - version "1.4.3" - resolved "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz" - integrity sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g== - dependencies: - "@emnapi/wasi-threads" "1.0.2" - tslib "^2.4.0" - -"@emnapi/runtime@^1.4.0": - version "1.4.3" - resolved "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz" - integrity sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ== - dependencies: - tslib "^2.4.0" - -"@emnapi/wasi-threads@1.0.2": - version "1.0.2" - resolved "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz" - integrity sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA== - dependencies: - tslib "^2.4.0" - "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.7.0": version "4.7.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz" @@ -208,117 +186,11 @@ optionalDependencies: "@img/sharp-libvips-darwin-arm64" "1.1.0" -"@img/sharp-darwin-x64@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.1.tgz" - integrity sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q== - optionalDependencies: - "@img/sharp-libvips-darwin-x64" "1.1.0" - "@img/sharp-libvips-darwin-arm64@1.1.0": version "1.1.0" resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz" integrity sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA== -"@img/sharp-libvips-darwin-x64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz" - integrity sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ== - -"@img/sharp-libvips-linux-arm@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz" - integrity sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA== - -"@img/sharp-libvips-linux-arm64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz" - integrity sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew== - -"@img/sharp-libvips-linux-ppc64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz" - integrity sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ== - -"@img/sharp-libvips-linux-s390x@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz" - integrity sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA== - -"@img/sharp-libvips-linux-x64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz" - integrity sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q== - -"@img/sharp-libvips-linuxmusl-arm64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz" - integrity sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w== - -"@img/sharp-libvips-linuxmusl-x64@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz" - integrity sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A== - -"@img/sharp-linux-arm@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.1.tgz" - integrity sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA== - optionalDependencies: - "@img/sharp-libvips-linux-arm" "1.1.0" - -"@img/sharp-linux-arm64@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.1.tgz" - integrity sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ== - optionalDependencies: - "@img/sharp-libvips-linux-arm64" "1.1.0" - -"@img/sharp-linux-s390x@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.1.tgz" - integrity sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA== - optionalDependencies: - "@img/sharp-libvips-linux-s390x" "1.1.0" - -"@img/sharp-linux-x64@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.1.tgz" - integrity sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA== - optionalDependencies: - "@img/sharp-libvips-linux-x64" "1.1.0" - -"@img/sharp-linuxmusl-arm64@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.1.tgz" - integrity sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-arm64" "1.1.0" - -"@img/sharp-linuxmusl-x64@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.1.tgz" - integrity sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-x64" "1.1.0" - -"@img/sharp-wasm32@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.1.tgz" - integrity sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg== - dependencies: - "@emnapi/runtime" "^1.4.0" - -"@img/sharp-win32-ia32@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.1.tgz" - integrity sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw== - -"@img/sharp-win32-x64@0.34.1": - version "0.34.1" - resolved "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.1.tgz" - integrity sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw== - "@internationalized/date@^3.6.0", "@internationalized/date@^3.8.0", "@internationalized/date@3.8.0": version "3.8.0" resolved "https://registry.npmjs.org/@internationalized/date/-/date-3.8.0.tgz" @@ -399,15 +271,6 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@napi-rs/wasm-runtime@^0.2.9": - version "0.2.9" - resolved "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.9.tgz" - integrity sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg== - dependencies: - "@emnapi/core" "^1.4.0" - "@emnapi/runtime" "^1.4.0" - "@tybys/wasm-util" "^0.9.0" - "@next/env@15.3.2": version "15.3.2" resolved "https://registry.npmjs.org/@next/env/-/env-15.3.2.tgz" @@ -425,41 +288,6 @@ resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.2.tgz" integrity sha512-2DR6kY/OGcokbnCsjHpNeQblqCZ85/1j6njYSkzRdpLn5At7OkSdmk7WyAmB9G0k25+VgqVZ/u356OSoQZ3z0g== -"@next/swc-darwin-x64@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.3.2.tgz" - integrity sha512-ro/fdqaZWL6k1S/5CLv1I0DaZfDVJkWNaUU3un8Lg6m0YENWlDulmIWzV96Iou2wEYyEsZq51mwV8+XQXqMp3w== - -"@next/swc-linux-arm64-gnu@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.3.2.tgz" - integrity sha512-covwwtZYhlbRWK2HlYX9835qXum4xYZ3E2Mra1mdQ+0ICGoMiw1+nVAn4d9Bo7R3JqSmK1grMq/va+0cdh7bJA== - -"@next/swc-linux-arm64-musl@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.3.2.tgz" - integrity sha512-KQkMEillvlW5Qk5mtGA/3Yz0/tzpNlSw6/3/ttsV1lNtMuOHcGii3zVeXZyi4EJmmLDKYcTcByV2wVsOhDt/zg== - -"@next/swc-linux-x64-gnu@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.3.2.tgz" - integrity sha512-uRBo6THWei0chz+Y5j37qzx+BtoDRFIkDzZjlpCItBRXyMPIg079eIkOCl3aqr2tkxL4HFyJ4GHDes7W8HuAUg== - -"@next/swc-linux-x64-musl@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.3.2.tgz" - integrity sha512-+uxFlPuCNx/T9PdMClOqeE8USKzj8tVz37KflT3Kdbx/LOlZBRI2yxuIcmx1mPNK8DwSOMNCr4ureSet7eyC0w== - -"@next/swc-win32-arm64-msvc@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.3.2.tgz" - integrity sha512-LLTKmaI5cfD8dVzh5Vt7+OMo+AIOClEdIU/TSKbXXT2iScUTSxOGoBhfuv+FU8R9MLmrkIL1e2fBMkEEjYAtPQ== - -"@next/swc-win32-x64-msvc@15.3.2": - version "15.3.2" - resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.3.2.tgz" - integrity sha512-aW5B8wOPioJ4mBdMDXkt5f3j8pUr9W8AnlX0Df35uRWNT1Y6RIybxjnSUe+PhM+M1bwgyY8PHLmXZC6zT1o5tA== - "@nextui-org/accordion@2.2.7": version "2.2.7" resolved "https://registry.npmjs.org/@nextui-org/accordion/-/accordion-2.2.7.tgz" @@ -2604,13 +2432,6 @@ resolved "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.11.2.tgz" integrity sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw== -"@tybys/wasm-util@^0.9.0": - version "0.9.0" - resolved "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz" - integrity sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw== - dependencies: - tslib "^2.4.0" - "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" @@ -2733,88 +2554,6 @@ resolved "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.7.2.tgz" integrity sha512-vxtBno4xvowwNmO/ASL0Y45TpHqmNkAaDtz4Jqb+clmcVSSl8XCG/PNFFkGsXXXS6AMjP+ja/TtNCFFa1QwLRg== -"@unrs/resolver-binding-darwin-x64@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.7.2.tgz" - integrity sha512-qhVa8ozu92C23Hsmv0BF4+5Dyyd5STT1FolV4whNgbY6mj3kA0qsrGPe35zNR3wAN7eFict3s4Rc2dDTPBTuFQ== - -"@unrs/resolver-binding-freebsd-x64@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.7.2.tgz" - integrity sha512-zKKdm2uMXqLFX6Ac7K5ElnnG5VIXbDlFWzg4WJ8CGUedJryM5A3cTgHuGMw1+P5ziV8CRhnSEgOnurTI4vpHpg== - -"@unrs/resolver-binding-linux-arm-gnueabihf@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.7.2.tgz" - integrity sha512-8N1z1TbPnHH+iDS/42GJ0bMPLiGK+cUqOhNbMKtWJ4oFGzqSJk/zoXFzcQkgtI63qMcUI7wW1tq2usZQSb2jxw== - -"@unrs/resolver-binding-linux-arm-musleabihf@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.7.2.tgz" - integrity sha512-tjYzI9LcAXR9MYd9rO45m1s0B/6bJNuZ6jeOxo1pq1K6OBuRMMmfyvJYval3s9FPPGmrldYA3mi4gWDlWuTFGA== - -"@unrs/resolver-binding-linux-arm64-gnu@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.7.2.tgz" - integrity sha512-jon9M7DKRLGZ9VYSkFMflvNqu9hDtOCEnO2QAryFWgT6o6AXU8du56V7YqnaLKr6rAbZBWYsYpikF226v423QA== - -"@unrs/resolver-binding-linux-arm64-musl@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.7.2.tgz" - integrity sha512-c8Cg4/h+kQ63pL43wBNaVMmOjXI/X62wQmru51qjfTvI7kmCy5uHTJvK/9LrF0G8Jdx8r34d019P1DVJmhXQpA== - -"@unrs/resolver-binding-linux-ppc64-gnu@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.7.2.tgz" - integrity sha512-A+lcwRFyrjeJmv3JJvhz5NbcCkLQL6Mk16kHTNm6/aGNc4FwPHPE4DR9DwuCvCnVHvF5IAd9U4VIs/VvVir5lg== - -"@unrs/resolver-binding-linux-riscv64-gnu@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.7.2.tgz" - integrity sha512-hQQ4TJQrSQW8JlPm7tRpXN8OCNP9ez7PajJNjRD1ZTHQAy685OYqPrKjfaMw/8LiHCt8AZ74rfUVHP9vn0N69Q== - -"@unrs/resolver-binding-linux-riscv64-musl@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.7.2.tgz" - integrity sha512-NoAGbiqrxtY8kVooZ24i70CjLDlUFI7nDj3I9y54U94p+3kPxwd2L692YsdLa+cqQ0VoqMWoehDFp21PKRUoIQ== - -"@unrs/resolver-binding-linux-s390x-gnu@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.7.2.tgz" - integrity sha512-KaZByo8xuQZbUhhreBTW+yUnOIHUsv04P8lKjQ5otiGoSJ17ISGYArc+4vKdLEpGaLbemGzr4ZeUbYQQsLWFjA== - -"@unrs/resolver-binding-linux-x64-gnu@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.7.2.tgz" - integrity sha512-dEidzJDubxxhUCBJ/SHSMJD/9q7JkyfBMT77Px1npl4xpg9t0POLvnWywSk66BgZS/b2Hy9Y1yFaoMTFJUe9yg== - -"@unrs/resolver-binding-linux-x64-musl@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.7.2.tgz" - integrity sha512-RvP+Ux3wDjmnZDT4XWFfNBRVG0fMsc+yVzNFUqOflnDfZ9OYujv6nkh+GOr+watwrW4wdp6ASfG/e7bkDradsw== - -"@unrs/resolver-binding-wasm32-wasi@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.7.2.tgz" - integrity sha512-y797JBmO9IsvXVRCKDXOxjyAE4+CcZpla2GSoBQ33TVb3ILXuFnMrbR/QQZoauBYeOFuu4w3ifWLw52sdHGz6g== - dependencies: - "@napi-rs/wasm-runtime" "^0.2.9" - -"@unrs/resolver-binding-win32-arm64-msvc@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.7.2.tgz" - integrity sha512-gtYTh4/VREVSLA+gHrfbWxaMO/00y+34htY7XpioBTy56YN2eBjkPrY1ML1Zys89X3RJDKVaogzwxlM1qU7egg== - -"@unrs/resolver-binding-win32-ia32-msvc@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.7.2.tgz" - integrity sha512-Ywv20XHvHTDRQs12jd3MY8X5C8KLjDbg/jyaal/QLKx3fAShhJyD4blEANInsjxW3P7isHx1Blt56iUDDJO3jg== - -"@unrs/resolver-binding-win32-x64-msvc@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.7.2.tgz" - integrity sha512-friS8NEQfHaDbkThxopGk+LuE5v3iY0StruifjQEt7SLbA46OnfgMO15sOTkbpJkol6RB+1l1TYPXh0sCddpvA== - acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" From c29785bf6190f9ae93dbd968be8d0adfc5f0ebbf Mon Sep 17 00:00:00 2001 From: ThinkMuk Date: Mon, 1 Sep 2025 22:26:44 +0900 Subject: [PATCH 20/20] =?UTF-8?q?Feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=9E=85=EA=B8=88=20=EC=83=81=ED=83=9C=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EC=8B=9C=20=ED=99=95=EC=9D=B8=20=EB=AA=A8=EB=8B=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/admin/page.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/admin/page.jsx b/src/app/admin/page.jsx index 0c48244..59c75dc 100644 --- a/src/app/admin/page.jsx +++ b/src/app/admin/page.jsx @@ -71,6 +71,8 @@ export default function Page() { const handleTogglePay = useCallback( async (userId, nextValue) => { if (modalClosing.current) return; // 모달이 닫히는 중에는 클릭 무시 + const confirmed = window.confirm('입금 상태를 수정하시겠습니까?'); + if (!confirmed) return; const getItemId = (user) => user?.id; const prevUsers = currentUsers;