From 34ff4701d4f5b936f7cf6502b64fcf89b353ee25 Mon Sep 17 00:00:00 2001 From: imsoohyeok Date: Fri, 14 Jun 2024 15:20:54 +0900 Subject: [PATCH 01/11] =?UTF-8?q?fix:=20=EC=9E=98=EB=AA=BB=20=EA=B1=B4?= =?UTF-8?q?=EB=93=9C=EB=A6=B0=20=EA=B2=83=20=EC=9B=90=EB=9E=98=EB=8C=80?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/users/apiUsers.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/users/apiUsers.tsx b/src/api/users/apiUsers.tsx index f80bb4d..d1e1c06 100644 --- a/src/api/users/apiUsers.tsx +++ b/src/api/users/apiUsers.tsx @@ -43,7 +43,7 @@ export async function apiInquireMyInfo(): Promise { // 내 정보 수정 api export async function apiEditMyInfo( - body: EditMyInfoBody, + body: EditMyInfoBody ): Promise { const res = await instance.put('/users/me', body); return handleResponse(res); @@ -51,7 +51,7 @@ export async function apiEditMyInfo( // 프로필 이미지 업로드 api export async function apiUploadImage( - body: UploadImage, + body: UploadImage ): Promise { const res = await instance.post('/users/me/image', body); return handleResponse(res); From 2458d18f26eea370ea506c9f3e1987d49287af40 Mon Sep 17 00:00:00 2001 From: imsoohyeok Date: Sat, 15 Jun 2024 23:41:14 +0900 Subject: [PATCH 02/11] =?UTF-8?q?fix:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=8B=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 8 ++-- src/api/axiosInstance.tsx | 14 ++++++ src/api/users/apiUsers.tsx | 5 +- src/contexts/UserContext.tsx | 23 +++------- .../components/utils/constants.ts | 11 ----- .../components/utils/useLoginFrom.ts | 39 ++++++++++++++-- .../components/utils/useSignUpForm.ts | 46 +++++++++++++++++-- 7 files changed, 103 insertions(+), 43 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 7d64cb8..15f2fe0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -21,6 +21,8 @@ function AppLayout() { } /> } /> } /> + } /> + } /> ); } @@ -30,17 +32,15 @@ function App() { } /> - } /> - } /> - )} + } /> diff --git a/src/api/axiosInstance.tsx b/src/api/axiosInstance.tsx index 261f111..ae98538 100644 --- a/src/api/axiosInstance.tsx +++ b/src/api/axiosInstance.tsx @@ -12,4 +12,18 @@ const instance = axios.create({ }, }); +// 요청 인터셉터를 추가하여 매 요청 시마다 토큰을 헤더에 추가 +instance.interceptors.request.use( + (config) => { + const token = localStorage.getItem('Token'); + if (token) { + config.headers['Authorization'] = `Bearer ${token}`; + } + return config; + }, + (error) => { + return Promise.reject(error); + } +); + export default instance; diff --git a/src/api/users/apiUsers.tsx b/src/api/users/apiUsers.tsx index 51c914a..0fdc606 100644 --- a/src/api/users/apiUsers.tsx +++ b/src/api/users/apiUsers.tsx @@ -47,12 +47,13 @@ export async function apiEditMyInfo( // 프로필 이미지 업로드 api export async function apiUploadImage( - body: FormData, // FormData로 받아오도록 + body: FormData, ): Promise { + const token = localStorage.getItem('Token'); // 저장된 토큰을 가져옴 const res = await instance.post('/users/me/image', body, { headers: { 'Content-Type': 'multipart/form-data', - Authorization: `Bearer ${localStorage.getItem('Token')}`, // 토큰 설정 추가 + Authorization: `Bearer ${token}`, // 토큰 사용 }, }); return handleResponse(res); diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx index 48bbb4b..5853260 100644 --- a/src/contexts/UserContext.tsx +++ b/src/contexts/UserContext.tsx @@ -1,10 +1,4 @@ -import { - createContext, - useState, - useEffect, - ReactNode, - useMemo, -} from 'react'; +import { createContext, useState, useEffect, ReactNode, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import { apiInquireMyInfo } from '../api/apiModule'; @@ -44,6 +38,10 @@ export function UserProvider({ children }: UserProviderProps) { useEffect(() => { const fetchUserInfo = async () => { + if (window.location.pathname === '/signup') { + return; // 회원가입 페이지에서는 사용자 정보를 가져오지 않음 + } + try { const Info = await apiInquireMyInfo(); setUserInfo(Info); @@ -56,14 +54,7 @@ export function UserProvider({ children }: UserProviderProps) { fetchUserInfo(); }, [navigate]); - const value = useMemo( - () => ({ userInfo, setUserInfo }), - [userInfo], - ); + const value = useMemo(() => ({ userInfo, setUserInfo }), [userInfo]); - return ( - - {children} - - ); + return {children}; } diff --git a/src/pages/login-signup/components/utils/constants.ts b/src/pages/login-signup/components/utils/constants.ts index 46d1647..dc439eb 100644 --- a/src/pages/login-signup/components/utils/constants.ts +++ b/src/pages/login-signup/components/utils/constants.ts @@ -5,14 +5,3 @@ export enum InputType { Email = 'email', Password = 'password', } - -// User 타입 선언 => useUser에 타입 적용 => API요청 setUser(response.user ?? null) -// useLoginForm 에서 사용 -export interface User { - id: number; - email: string; - nickname: string; - profileImageUrl?: string | undefined; - createdAt: string; - updatedAt: string; -} diff --git a/src/pages/login-signup/components/utils/useLoginFrom.ts b/src/pages/login-signup/components/utils/useLoginFrom.ts index 7581559..d7aa020 100644 --- a/src/pages/login-signup/components/utils/useLoginFrom.ts +++ b/src/pages/login-signup/components/utils/useLoginFrom.ts @@ -1,7 +1,7 @@ -import { useState } from 'react'; +import { useState, useContext } from 'react'; +import { UserContext } from '../../../../contexts/UserContext'; import { useNavigate } from 'react-router-dom'; -import { apiLoginRequest } from '../../../../api/apiModule'; -import { User } from './constants'; +import { apiLoginRequest, apiInquireMyInfo } from '../../../../api/apiModule'; // 로그인 폼 제출 기능을 수행하는 함수입니다. // useNavigate를 사용하여 폼 제출 시 다른 페이지로 이동하도록 구현했습니다. @@ -28,7 +28,6 @@ function useLoginForm() { // 이외의 상태 관리 const [loading, setLoading] = useState(false); const [, setError] = useState(null); - const [, setUser] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const navigate = useNavigate(); @@ -37,6 +36,13 @@ function useLoginForm() { setIsModalOpen(false); }; + const userContext = useContext(UserContext); + if (!userContext) { + throw new Error('반드시 DashboardProvider 안에서 사용해야 합니다.'); + } + const { setUserInfo } = userContext; + + // 로그인 버튼 시 실행 const handleSubmit = async (e: { preventDefault: () => void }) => { e.preventDefault(); setLoading(true); // 로그인 시도 중에는 버튼 비활성화 @@ -46,7 +52,30 @@ function useLoginForm() { try { const response = await apiLoginRequest({ email, password }); - setUser(response.user ?? null); + + // 로그인 후 토큰을 로컬 스토리지에 저장 + const token = response.accessToken; + if (token) { + localStorage.setItem('Token', token); + // 이후 API 요청은 저장된 토큰을 사용할 수 있습니다. + } else { + throw new Error('로그인 응답에 토큰이 없습니다.'); + } + + const userInfo = await apiInquireMyInfo(); + + const profileImageUrlWithTimestamp = `${ + userInfo.profileImageUrl + }?timestamp=${new Date().getTime()}`; + setUserInfo({ + ...userInfo, + profileImageUrl: profileImageUrlWithTimestamp, + }); + localStorage.setItem('profileImageUrl', profileImageUrlWithTimestamp); + + // 페이지를 강제로 리로드하여 이미지 변경 반영 + window.location.reload(); + navigate('/mydashboard'); // 로그인 성공 시 mydashboard 페이지로 이동 } catch (error) { setIsModalOpen(true); // 로그인 실패 시 모달 창 띄우기 diff --git a/src/pages/login-signup/components/utils/useSignUpForm.ts b/src/pages/login-signup/components/utils/useSignUpForm.ts index 021ae8f..e620cdb 100644 --- a/src/pages/login-signup/components/utils/useSignUpForm.ts +++ b/src/pages/login-signup/components/utils/useSignUpForm.ts @@ -1,9 +1,11 @@ -import { useState } from 'react'; +import { useState, useContext } from 'react'; +import { UserContext } from '../../../../contexts/UserContext'; import { useNavigate } from 'react-router-dom'; import { apiSignUp, - apiLoginRequest, apiUploadImage, + apiInquireMyInfo, + apiLoginRequest, // 임시 로그인 요청을 위해 추가 } from '../../../../api/apiModule'; import defaultProfileImg from '../../../../../public/img/default.png'; @@ -12,6 +14,7 @@ import defaultProfileImg from '../../../../../public/img/default.png'; // 회원가입 시도 시 모달 창이 띄워지도록 useState를 사용하여 구현했습니다. // 성공, 이메일 중복으로 실패, 그 밖의 에러 세 가지 경우로 나눠서 모달이 뜨도록 했습니다. // 회원가입 중에는 버튼이 비활성화 되도록 useState를 사용하여 구현했습니다.(loading) +// 회원가입 시 기본 이미지가 프로필 이미지로 설정됩니다. // SignUpForm 컴포넌트에서 사용됩니다. // 타입 정의 @@ -46,6 +49,12 @@ function useSignUpForm() { // 변경 성공 시 모달을 닫으면 자동으로 로그인 페이지로 이동 const closeSuccessModalAndReload = () => { setIsModalOpen(false); + setValues({ + email: '', + nickname: '', + password: '', + passwordCheck: '', + }); // 폼 값을 초기화 navigate('/login'); // 회원가입 성공 시 로그인 페이지로 이동 }; @@ -56,6 +65,12 @@ function useSignUpForm() { return blob; }; + const userContext = useContext(UserContext); + if (!userContext) { + throw new Error('반드시 DashboardProvider 안에서 사용해야 합니다.'); + } + const { setUserInfo } = userContext; + // 회원가입 폼 제출 const handleSubmit = async (e: { preventDefault: () => void }) => { e.preventDefault(); @@ -70,15 +85,36 @@ function useSignUpForm() { password, }); // 회원가입 API 호출 - // 회원가입 후 바로 로그인 - await apiLoginRequest({ email, password }); + // 회원가입 후 임시 로그인 요청 + const loginResponse = await apiLoginRequest({ email, password }); + const token = loginResponse.accessToken; + if (token) { + localStorage.setItem('Token', token); // 받은 토큰을 로컬 스토리지에 저장 + } else { + throw new Error('로그인 응답에 토큰이 없습니다.'); + } // 기본 이미지를 Blob으로 변환하여 업로드 const defaultImageBlob = await getDefaultImageBlob(); const formData = new FormData(); formData.append('image', defaultImageBlob, 'default.png'); - await apiUploadImage(formData); // 기본 프로필 이미지 업로드 + // 기본 프로필 이미지 업로드 + const uploadImageResponse = await apiUploadImage(formData); + + // 이미지 URL 저장 + const newProfileImageUrl = uploadImageResponse.profileImageUrl; + localStorage.setItem('profileImageUrl', newProfileImageUrl); + + // UserContext의 사용자 정보 업데이트 + const updatedUserInfo = await apiInquireMyInfo(); + setUserInfo({ + ...updatedUserInfo, + profileImageUrl: `${newProfileImageUrl}?timestamp=${new Date().getTime()}`, // 캐시 우회 + }); + + // 토큰을 삭제하여 자동 로그인 방지 + localStorage.removeItem('Token'); setIsModalOpen(true); // 성공 시 모달 창 띄우기 } catch (error) { From 7bb220df880daa9cbbdef5427e1585c7adeb98ae Mon Sep 17 00:00:00 2001 From: imsoohyeok Date: Sat, 15 Jun 2024 23:47:45 +0900 Subject: [PATCH 03/11] =?UTF-8?q?fix:lint=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 4 ++-- src/api/axiosInstance.tsx | 12 ++++++------ src/contexts/UserContext.tsx | 4 +++- .../login-signup/components/Input/InputPassword.tsx | 2 +- .../login-signup/components/LoginForm/LoginForm.tsx | 2 +- .../components/SignUpForm/SignUpForm.tsx | 2 +- src/pages/login-signup/components/utils/constants.ts | 4 +++- .../login-signup/components/utils/useLoginFrom.ts | 2 +- .../login-signup/components/utils/useSignUpForm.ts | 2 +- 9 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 15f2fe0..685f7ef 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -34,13 +34,13 @@ function App() { } /> - } + )} /> diff --git a/src/api/axiosInstance.tsx b/src/api/axiosInstance.tsx index ae98538..9c5dcdf 100644 --- a/src/api/axiosInstance.tsx +++ b/src/api/axiosInstance.tsx @@ -15,15 +15,15 @@ const instance = axios.create({ // 요청 인터셉터를 추가하여 매 요청 시마다 토큰을 헤더에 추가 instance.interceptors.request.use( (config) => { - const token = localStorage.getItem('Token'); + const newConfig = Object.assign({}, config); // 기존 config 객체를 복사 if (token) { - config.headers['Authorization'] = `Bearer ${token}`; + newConfig.headers = Object.assign({}, config.headers, { + Authorization: `Bearer ${token}`, // Authorization 필드 추가 + }); } - return config; + return newConfig; }, - (error) => { - return Promise.reject(error); - } + (error) => Promise.reject(error) ); export default instance; diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx index 5853260..89e1d9b 100644 --- a/src/contexts/UserContext.tsx +++ b/src/contexts/UserContext.tsx @@ -1,4 +1,6 @@ -import { createContext, useState, useEffect, ReactNode, useMemo } from 'react'; +import { + createContext, useState, useEffect, ReactNode, useMemo, +} from 'react'; import { useNavigate } from 'react-router-dom'; import { apiInquireMyInfo } from '../api/apiModule'; diff --git a/src/pages/login-signup/components/Input/InputPassword.tsx b/src/pages/login-signup/components/Input/InputPassword.tsx index ac557fb..f31e2be 100644 --- a/src/pages/login-signup/components/Input/InputPassword.tsx +++ b/src/pages/login-signup/components/Input/InputPassword.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import classNames from 'classnames'; import styles from './Input.module.scss'; -import { InputType } from '../utils/constants'; +import InputType from '../utils/constants'; import EyeOn from '../../../../../public/icon/eye_on.svg'; import EyeOff from '../../../../../public/icon/eye_off.svg'; diff --git a/src/pages/login-signup/components/LoginForm/LoginForm.tsx b/src/pages/login-signup/components/LoginForm/LoginForm.tsx index 2202d13..8f8db5b 100644 --- a/src/pages/login-signup/components/LoginForm/LoginForm.tsx +++ b/src/pages/login-signup/components/LoginForm/LoginForm.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import styles from './LoginForm.module.scss'; import { useCombinedLoginForm } from '../utils/useCombinedForm'; import AlertModal from '../../../modal/AlertModal/AlertModal'; -import { InputType } from '../utils/constants'; +import InputType from '../utils/constants'; import InputEmail from '../Input/InputEmail'; import InputPassword from '../Input/InputPassword'; import Button from '../Button/Button'; diff --git a/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx b/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx index fa23011..cfe6da0 100644 --- a/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx +++ b/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx @@ -1,6 +1,6 @@ import styles from './SignUpForm.module.scss'; import AlertModal from '../../../modal/AlertModal/AlertModal'; -import { InputType } from '../utils/constants'; +import InputType from '../utils/constants'; import InputEmail from '../Input/InputEmail'; import InputPassword from '../Input/InputPassword'; import Checkbox from '../CheckBox/CheckBox'; diff --git a/src/pages/login-signup/components/utils/constants.ts b/src/pages/login-signup/components/utils/constants.ts index dc439eb..7a5c13c 100644 --- a/src/pages/login-signup/components/utils/constants.ts +++ b/src/pages/login-signup/components/utils/constants.ts @@ -1,7 +1,9 @@ // InputType enum으로 따로 선언 // LoginForm, SignUpForm 컴포넌트에서 사용 -export enum InputType { +enum InputType { Text = 'text', Email = 'email', Password = 'password', } + +export default InputType; diff --git a/src/pages/login-signup/components/utils/useLoginFrom.ts b/src/pages/login-signup/components/utils/useLoginFrom.ts index d7aa020..a493c70 100644 --- a/src/pages/login-signup/components/utils/useLoginFrom.ts +++ b/src/pages/login-signup/components/utils/useLoginFrom.ts @@ -1,6 +1,6 @@ import { useState, useContext } from 'react'; -import { UserContext } from '../../../../contexts/UserContext'; import { useNavigate } from 'react-router-dom'; +import { UserContext } from '../../../../contexts/UserContext'; import { apiLoginRequest, apiInquireMyInfo } from '../../../../api/apiModule'; // 로그인 폼 제출 기능을 수행하는 함수입니다. diff --git a/src/pages/login-signup/components/utils/useSignUpForm.ts b/src/pages/login-signup/components/utils/useSignUpForm.ts index e620cdb..4f82505 100644 --- a/src/pages/login-signup/components/utils/useSignUpForm.ts +++ b/src/pages/login-signup/components/utils/useSignUpForm.ts @@ -1,6 +1,6 @@ import { useState, useContext } from 'react'; -import { UserContext } from '../../../../contexts/UserContext'; import { useNavigate } from 'react-router-dom'; +import { UserContext } from '../../../../contexts/UserContext'; import { apiSignUp, apiUploadImage, From ed30f6ac93f8da52fa33afe8ddd0b9b7d09ea30a Mon Sep 17 00:00:00 2001 From: imsoohyeok Date: Sat, 15 Jun 2024 23:55:59 +0900 Subject: [PATCH 04/11] fix: lint --- .eslintrc.cjs | 19 ++++++++++++------- src/api/axiosInstance.tsx | 9 +++------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index bc07b5f..1ed794a 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -24,10 +24,15 @@ module.exports = { 'import/no-absolute-path': 'off', // jsx-a11y label-has-associated-control 규칙 설정 - "jsx-a11y/label-has-associated-control": [ 2, { - "some": [ "nesting", "id" ] - }], - } - } - ] -} + 'jsx-a11y/label-has-associated-control': [ + 2, + { + some: ['nesting', 'id'], + }, + ], + + 'no-param-reassign': ['error', { props: false }], + }, + }, + ], +}; diff --git a/src/api/axiosInstance.tsx b/src/api/axiosInstance.tsx index 9c5dcdf..d5a10ba 100644 --- a/src/api/axiosInstance.tsx +++ b/src/api/axiosInstance.tsx @@ -15,15 +15,12 @@ const instance = axios.create({ // 요청 인터셉터를 추가하여 매 요청 시마다 토큰을 헤더에 추가 instance.interceptors.request.use( (config) => { - const newConfig = Object.assign({}, config); // 기존 config 객체를 복사 if (token) { - newConfig.headers = Object.assign({}, config.headers, { - Authorization: `Bearer ${token}`, // Authorization 필드 추가 - }); + config.headers.Authorization = `Bearer ${token}`; } - return newConfig; + return config; }, - (error) => Promise.reject(error) + (error) => Promise.reject(error), ); export default instance; From 6401e7715bf067d827f859379e41bb0bae336b5b Mon Sep 17 00:00:00 2001 From: Park Sumin Date: Sun, 16 Jun 2024 00:11:54 +0900 Subject: [PATCH 05/11] Test : pull test --- public/img/Avatar.png | Bin 0 -> 1386 bytes src/contexts/UserContext.tsx | 13 ++++++++-- .../components/utils/useSignUpForm.ts | 24 ++++++------------ .../DashboardList/DashboardList.module.scss | 3 ++- src/pages/myDashboard/index.module.scss | 2 +- src/utils/defaultProfileImgMaker.tsx | 4 +-- 6 files changed, 24 insertions(+), 22 deletions(-) create mode 100644 public/img/Avatar.png diff --git a/public/img/Avatar.png b/public/img/Avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..9089de5bce3354e3f7165c8de66dd87d9b3cf848 GIT binary patch literal 1386 zcmV-w1(o`VP)XLK>(p_s9Xmcw9e&cqM9fw&RszeYBfM+SWYLg@RW| zY(gZhTa>iS3tF$SI%0`0ZD@y}lU%{_qXF7GW{co8Kg#>k>Cz&$4>QlMGCShhgKX!F z;1wLVd2k$evq8+|(sTzOs}INVjF(PXSggAZ6R3VCw$h7^tcCZ{Ab-j|zp`nLOJpj5 zO)P9zK0_!&ab3y2Hze!5o9{C#1eqV!$mD7SLHh>ZodSh3_ z=49R!{dDd8b8j$v?nwHMOJ~W2gd%v0|A__L$ov^f&~5*IeQwb_D44?6x6S!3UTqm` zE3n24EFQyS;1-mi*gM1dVkzRxCV*Fa`R8p^UI6A2`%f%b%)AW+D3X>c3Q9jBl=n38I3ZaC6)ie=E@aUQ%O6uxc;*QX=-d<<=T3a)Ko z1}c|zX`wP=6DY6&krO0VZPKM{=RK|{OQD+Xs6;H-M@<-XvWy03BbQYKyQZOUCuk#n z<+`+sc}Yf_P!a43OiNx7m8LPlS6W&Pqu>ZNagEpYipeU6#m(m?TVvM6C1nF%!iRCF zovpg&PFk23T?UH%XLO#eG3xjBO`o#pSa9ulN(;M|aLm5S1T>!K62{*uu9nDYXRIKY zFg46V5p+-2Je{WKd*xVg(vfuQ3lyM*T~?-*D4OGQp75p_n{5>Fb^;Z+#?8x}IX)@; z|L?N}g3$qTQCtr*m;TVP51v9OP-b;RH>ag(sT(|fk>=-J^7GbJnZ3uVJ%B@DjJ)ukQ1f^+vhJKejg4WWOnVjmWM2nE8gP^ zBZ9+YX9P2v{cM42*F{`;*R_SoSpaxw_C~a`3|EeUxUzFnE2?ZP(S*cnY46b`+ zUka%tm^{X~-)YBQu2W7u5{)aZ^ePJ`c25XJ_i-_V((W$u3cx~w6P{pv%QG(JV>yJ@ zstZ3MQ{RLojZc;CYb>B2yHvid`nGLa2jrw5%GU{MmVd> sEVcV^zls;XhG%Q!kr$V^nt2uP7b(${2G4=Z;Q#;t07*qoM6N<$f>Gp!@Bjb+ literal 0 HcmV?d00001 diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx index 046a40e..bb904ce 100644 --- a/src/contexts/UserContext.tsx +++ b/src/contexts/UserContext.tsx @@ -7,6 +7,7 @@ import { } from 'react'; import { useNavigate, useLocation } from 'react-router-dom'; import { apiInquireMyInfo } from '../api/apiModule'; +import DefaultImg from '/img/Avatar.png'; // 이미지를 import /* 현재 로그인된 유저의 정보를 가져오는 Context입니다. @@ -28,6 +29,8 @@ export interface UserInfo { interface UserContextProps { userInfo: UserInfo | null; setUserInfo: (info: UserInfo | null) => void; + userProfile: string; + setUserProfile: (url: string) => void; } interface UserProviderProps { @@ -40,6 +43,7 @@ export const UserContext = createContext(null); // UserProvider 컴포넌트 export function UserProvider({ children }: UserProviderProps) { const [userInfo, setUserInfo] = useState(null); + const [userProfile, setUserProfile] = useState(DefaultImg); // DefaultImg를 초기값으로 설정 const navigate = useNavigate(); const location = useLocation(); @@ -63,6 +67,11 @@ export function UserProvider({ children }: UserProviderProps) { try { const info = await apiInquireMyInfo(); setUserInfo(info); + if (info.profileImageUrl === null) { + setUserProfile(DefaultImg); + } else { + setUserProfile(info.profileImageUrl); + } } catch (error) { navigate('/login'); } @@ -73,8 +82,8 @@ export function UserProvider({ children }: UserProviderProps) { }, [location.pathname, userInfo, navigate]); const value = useMemo( - () => ({ userInfo, setUserInfo }), - [userInfo], + () => ({ userInfo, setUserInfo, userProfile, setUserProfile }), // userProfile과 setUserProfile 추가 + [userInfo, userProfile], ); return ( diff --git a/src/pages/login-signup/components/utils/useSignUpForm.ts b/src/pages/login-signup/components/utils/useSignUpForm.ts index 11c70e6..9d70154 100644 --- a/src/pages/login-signup/components/utils/useSignUpForm.ts +++ b/src/pages/login-signup/components/utils/useSignUpForm.ts @@ -34,19 +34,6 @@ function useSignUpForm() { const [isErrorModalOpen, setIsErrorModalOpen] = useState(false); const navigate = useNavigate(); - // 모달 창 닫는 함수 - const closeModal = () => { - setIsModalOpen(false); - setIsErrorModalOpen(false); - }; - - // 변경 성공 시 모달을 닫으면 자동으로 로그인 페이지로 이동 - const closeSuccessModalAndReload = () => { - setIsModalOpen(false); - navigate('/login'); // 회원가입 성공 시 로그인 페이지로 이동 - }; - - // 회원가입 폼 제출 const handleSubmit = async (e: { preventDefault: () => void }) => { e.preventDefault(); setLoading(true); // 회원가입 시도 중에는 버튼 비활성화 @@ -57,9 +44,9 @@ function useSignUpForm() { try { await apiSignUp({ email, nickname, password }); // 회원가입 API 호출 - defaultProfileImgMaker({ name: nickname }); // 프로필 이미지 생성 - + const profileImgUrl = defaultProfileImgMaker({ name: nickname }); // 프로필 이미지 생성 setIsModalOpen(true); // 성공 시 모달 창 띄우기 + navigate('/login'); // 회원가입 성공 시 로그인 페이지로 이동 } catch (error) { setIsErrorModalOpen(true); setError('중복된 이메일입니다.'); @@ -68,6 +55,12 @@ function useSignUpForm() { } }; + // 모달 창 닫는 함수 + const closeModal = () => { + setIsModalOpen(false); + setIsErrorModalOpen(false); + }; + // 사용할 값 리턴 return { values, @@ -79,7 +72,6 @@ function useSignUpForm() { closeModal, setIsModalOpen, setIsErrorModalOpen, - closeSuccessModalAndReload, }; } diff --git a/src/pages/myDashboard/components/DashboardList/DashboardList.module.scss b/src/pages/myDashboard/components/DashboardList/DashboardList.module.scss index b3a2cf0..805e97b 100644 --- a/src/pages/myDashboard/components/DashboardList/DashboardList.module.scss +++ b/src/pages/myDashboard/components/DashboardList/DashboardList.module.scss @@ -2,7 +2,8 @@ @use '/src/styles/media.scss' as *; .container { - width: 1024px; + width: auto; + max-width: 1024px; } .dashboardList { diff --git a/src/pages/myDashboard/index.module.scss b/src/pages/myDashboard/index.module.scss index 078491a..4a956dd 100644 --- a/src/pages/myDashboard/index.module.scss +++ b/src/pages/myDashboard/index.module.scss @@ -35,7 +35,7 @@ overflow-x: auto; @include mobile { - margin: 40px; + margin-left: 8px; } } } diff --git a/src/utils/defaultProfileImgMaker.tsx b/src/utils/defaultProfileImgMaker.tsx index 7af6c36..dbb6b90 100644 --- a/src/utils/defaultProfileImgMaker.tsx +++ b/src/utils/defaultProfileImgMaker.tsx @@ -51,7 +51,7 @@ export function RandomColorPicker() { // 현재 프로젝트에서 사용할 수 있도록 만든 프로필 이미지 생성기입니다. // 이름(전체), size(필수 아님)을 prop으로 받습니다. // 약 0.6kb정도의 svg 이미지 url이 나옵니다. -function defaultProfileImgMaker({ name, size = 50 }: SvgMakerProps) { +function defaultProfileImgMaker({ name, size = 38 }: SvgMakerProps) { // 이름 첫글자 const initial = name.charAt(0).toUpperCase(); @@ -60,7 +60,7 @@ function defaultProfileImgMaker({ name, size = 50 }: SvgMakerProps) { // 이미지 Url 생성 const ImgUrl = toSvgImg({ initial, size, color }); - + return ImgUrl; } From 48824e5156eabf281284071d93c8b9ccbf2f0dcf Mon Sep 17 00:00:00 2001 From: imsoohyeok Date: Sun, 16 Jun 2024 01:30:45 +0900 Subject: [PATCH 06/11] =?UTF-8?q?fix:=20=EC=9B=90=EB=9E=98=EB=8C=80?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.cjs | 2 - src/api/axiosInstance.tsx | 11 ----- src/contexts/UserContext.tsx | 4 -- .../components/Input/InputPassword.tsx | 2 +- .../components/LoginForm/LoginForm.tsx | 2 +- .../components/SignUpForm/SignUpForm.tsx | 2 +- .../components/utils/constants.ts | 13 ++++- .../components/utils/useLoginFrom.ts | 42 ++++------------ .../components/utils/useSignUpForm.ts | 48 +------------------ src/pages/mypage/utils/useProfileChange.ts | 9 ++++ 10 files changed, 33 insertions(+), 102 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 1ed794a..7a0b53b 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -30,8 +30,6 @@ module.exports = { some: ['nesting', 'id'], }, ], - - 'no-param-reassign': ['error', { props: false }], }, }, ], diff --git a/src/api/axiosInstance.tsx b/src/api/axiosInstance.tsx index d5a10ba..261f111 100644 --- a/src/api/axiosInstance.tsx +++ b/src/api/axiosInstance.tsx @@ -12,15 +12,4 @@ const instance = axios.create({ }, }); -// 요청 인터셉터를 추가하여 매 요청 시마다 토큰을 헤더에 추가 -instance.interceptors.request.use( - (config) => { - if (token) { - config.headers.Authorization = `Bearer ${token}`; - } - return config; - }, - (error) => Promise.reject(error), -); - export default instance; diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx index 89e1d9b..5e2ff5b 100644 --- a/src/contexts/UserContext.tsx +++ b/src/contexts/UserContext.tsx @@ -40,10 +40,6 @@ export function UserProvider({ children }: UserProviderProps) { useEffect(() => { const fetchUserInfo = async () => { - if (window.location.pathname === '/signup') { - return; // 회원가입 페이지에서는 사용자 정보를 가져오지 않음 - } - try { const Info = await apiInquireMyInfo(); setUserInfo(Info); diff --git a/src/pages/login-signup/components/Input/InputPassword.tsx b/src/pages/login-signup/components/Input/InputPassword.tsx index f31e2be..ac557fb 100644 --- a/src/pages/login-signup/components/Input/InputPassword.tsx +++ b/src/pages/login-signup/components/Input/InputPassword.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import classNames from 'classnames'; import styles from './Input.module.scss'; -import InputType from '../utils/constants'; +import { InputType } from '../utils/constants'; import EyeOn from '../../../../../public/icon/eye_on.svg'; import EyeOff from '../../../../../public/icon/eye_off.svg'; diff --git a/src/pages/login-signup/components/LoginForm/LoginForm.tsx b/src/pages/login-signup/components/LoginForm/LoginForm.tsx index 8f8db5b..2202d13 100644 --- a/src/pages/login-signup/components/LoginForm/LoginForm.tsx +++ b/src/pages/login-signup/components/LoginForm/LoginForm.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import styles from './LoginForm.module.scss'; import { useCombinedLoginForm } from '../utils/useCombinedForm'; import AlertModal from '../../../modal/AlertModal/AlertModal'; -import InputType from '../utils/constants'; +import { InputType } from '../utils/constants'; import InputEmail from '../Input/InputEmail'; import InputPassword from '../Input/InputPassword'; import Button from '../Button/Button'; diff --git a/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx b/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx index cfe6da0..fa23011 100644 --- a/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx +++ b/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx @@ -1,6 +1,6 @@ import styles from './SignUpForm.module.scss'; import AlertModal from '../../../modal/AlertModal/AlertModal'; -import InputType from '../utils/constants'; +import { InputType } from '../utils/constants'; import InputEmail from '../Input/InputEmail'; import InputPassword from '../Input/InputPassword'; import Checkbox from '../CheckBox/CheckBox'; diff --git a/src/pages/login-signup/components/utils/constants.ts b/src/pages/login-signup/components/utils/constants.ts index 7a5c13c..46d1647 100644 --- a/src/pages/login-signup/components/utils/constants.ts +++ b/src/pages/login-signup/components/utils/constants.ts @@ -1,9 +1,18 @@ // InputType enum으로 따로 선언 // LoginForm, SignUpForm 컴포넌트에서 사용 -enum InputType { +export enum InputType { Text = 'text', Email = 'email', Password = 'password', } -export default InputType; +// User 타입 선언 => useUser에 타입 적용 => API요청 setUser(response.user ?? null) +// useLoginForm 에서 사용 +export interface User { + id: number; + email: string; + nickname: string; + profileImageUrl?: string | undefined; + createdAt: string; + updatedAt: string; +} diff --git a/src/pages/login-signup/components/utils/useLoginFrom.ts b/src/pages/login-signup/components/utils/useLoginFrom.ts index a493c70..dc74c8e 100644 --- a/src/pages/login-signup/components/utils/useLoginFrom.ts +++ b/src/pages/login-signup/components/utils/useLoginFrom.ts @@ -1,7 +1,7 @@ -import { useState, useContext } from 'react'; +import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { UserContext } from '../../../../contexts/UserContext'; -import { apiLoginRequest, apiInquireMyInfo } from '../../../../api/apiModule'; +import { apiLoginRequest } from '../../../../api/apiModule'; +import { User } from './constants'; // 로그인 폼 제출 기능을 수행하는 함수입니다. // useNavigate를 사용하여 폼 제출 시 다른 페이지로 이동하도록 구현했습니다. @@ -16,6 +16,7 @@ interface LoginFormInputs { password: string; passwordCheck: string; } + function useLoginForm() { // Input value 값 상태 관리 const [values, setValues] = useState({ @@ -28,6 +29,7 @@ function useLoginForm() { // 이외의 상태 관리 const [loading, setLoading] = useState(false); const [, setError] = useState(null); + const [, setUser] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const navigate = useNavigate(); @@ -36,13 +38,7 @@ function useLoginForm() { setIsModalOpen(false); }; - const userContext = useContext(UserContext); - if (!userContext) { - throw new Error('반드시 DashboardProvider 안에서 사용해야 합니다.'); - } - const { setUserInfo } = userContext; - - // 로그인 버튼 시 실행 + // 로그인 버튼 클릭 시 실행 const handleSubmit = async (e: { preventDefault: () => void }) => { e.preventDefault(); setLoading(true); // 로그인 시도 중에는 버튼 비활성화 @@ -52,31 +48,11 @@ function useLoginForm() { try { const response = await apiLoginRequest({ email, password }); + setUser(response.user ?? null); + navigate('/mydashboard'); // 로그인 성공 시 mydashboard 페이지로 이동 - // 로그인 후 토큰을 로컬 스토리지에 저장 - const token = response.accessToken; - if (token) { - localStorage.setItem('Token', token); - // 이후 API 요청은 저장된 토큰을 사용할 수 있습니다. - } else { - throw new Error('로그인 응답에 토큰이 없습니다.'); - } - - const userInfo = await apiInquireMyInfo(); - - const profileImageUrlWithTimestamp = `${ - userInfo.profileImageUrl - }?timestamp=${new Date().getTime()}`; - setUserInfo({ - ...userInfo, - profileImageUrl: profileImageUrlWithTimestamp, - }); - localStorage.setItem('profileImageUrl', profileImageUrlWithTimestamp); - - // 페이지를 강제로 리로드하여 이미지 변경 반영 + // 페이지 새로고침 window.location.reload(); - - navigate('/mydashboard'); // 로그인 성공 시 mydashboard 페이지로 이동 } catch (error) { setIsModalOpen(true); // 로그인 실패 시 모달 창 띄우기 } finally { diff --git a/src/pages/login-signup/components/utils/useSignUpForm.ts b/src/pages/login-signup/components/utils/useSignUpForm.ts index 4f82505..8958354 100644 --- a/src/pages/login-signup/components/utils/useSignUpForm.ts +++ b/src/pages/login-signup/components/utils/useSignUpForm.ts @@ -1,20 +1,13 @@ import { useState, useContext } from 'react'; import { useNavigate } from 'react-router-dom'; import { UserContext } from '../../../../contexts/UserContext'; -import { - apiSignUp, - apiUploadImage, - apiInquireMyInfo, - apiLoginRequest, // 임시 로그인 요청을 위해 추가 -} from '../../../../api/apiModule'; -import defaultProfileImg from '../../../../../public/img/default.png'; +import { apiSignUp } from '../../../../api/apiModule'; // 회원가입 폼 제출 기능을 수행하는 함수입니다. // useNavigate를 사용하여 폼 제출 시 다른 페이지로 이동하도록 구현했습니다. // 회원가입 시도 시 모달 창이 띄워지도록 useState를 사용하여 구현했습니다. // 성공, 이메일 중복으로 실패, 그 밖의 에러 세 가지 경우로 나눠서 모달이 뜨도록 했습니다. // 회원가입 중에는 버튼이 비활성화 되도록 useState를 사용하여 구현했습니다.(loading) -// 회원가입 시 기본 이미지가 프로필 이미지로 설정됩니다. // SignUpForm 컴포넌트에서 사용됩니다. // 타입 정의 @@ -58,18 +51,10 @@ function useSignUpForm() { navigate('/login'); // 회원가입 성공 시 로그인 페이지로 이동 }; - // 기본 이미지를 Blob으로 변환하는 함수 - const getDefaultImageBlob = async (): Promise => { - const response = await fetch(defaultProfileImg); - const blob = await response.blob(); - return blob; - }; - const userContext = useContext(UserContext); if (!userContext) { throw new Error('반드시 DashboardProvider 안에서 사용해야 합니다.'); } - const { setUserInfo } = userContext; // 회원가입 폼 제출 const handleSubmit = async (e: { preventDefault: () => void }) => { @@ -85,37 +70,6 @@ function useSignUpForm() { password, }); // 회원가입 API 호출 - // 회원가입 후 임시 로그인 요청 - const loginResponse = await apiLoginRequest({ email, password }); - const token = loginResponse.accessToken; - if (token) { - localStorage.setItem('Token', token); // 받은 토큰을 로컬 스토리지에 저장 - } else { - throw new Error('로그인 응답에 토큰이 없습니다.'); - } - - // 기본 이미지를 Blob으로 변환하여 업로드 - const defaultImageBlob = await getDefaultImageBlob(); - const formData = new FormData(); - formData.append('image', defaultImageBlob, 'default.png'); - - // 기본 프로필 이미지 업로드 - const uploadImageResponse = await apiUploadImage(formData); - - // 이미지 URL 저장 - const newProfileImageUrl = uploadImageResponse.profileImageUrl; - localStorage.setItem('profileImageUrl', newProfileImageUrl); - - // UserContext의 사용자 정보 업데이트 - const updatedUserInfo = await apiInquireMyInfo(); - setUserInfo({ - ...updatedUserInfo, - profileImageUrl: `${newProfileImageUrl}?timestamp=${new Date().getTime()}`, // 캐시 우회 - }); - - // 토큰을 삭제하여 자동 로그인 방지 - localStorage.removeItem('Token'); - setIsModalOpen(true); // 성공 시 모달 창 띄우기 } catch (error) { setIsErrorModalOpen(true); diff --git a/src/pages/mypage/utils/useProfileChange.ts b/src/pages/mypage/utils/useProfileChange.ts index 18fc887..143ceea 100644 --- a/src/pages/mypage/utils/useProfileChange.ts +++ b/src/pages/mypage/utils/useProfileChange.ts @@ -66,6 +66,15 @@ function useProfileChange() { const file = e.target.files[0]; setProfileImage(file); + // 파일 형식 검사 + const validImageTypes = ['image/jpeg', 'image/png', 'image/svg+xml']; + if (!validImageTypes.includes(file.type)) { + alert('Unsupported file type. Only JPEG, PNG, and SVG are allowed.'); + return; + } + + setProfileImage(file); + // URL.createObjectURL을 사용하여 새로운 이미지 URL 생성 const imageUrl = URL.createObjectURL(file); setProfileImageUrl(imageUrl); From e3677ea2063db7cd7fb482d6c850d4c4fee2329d Mon Sep 17 00:00:00 2001 From: Park Sumin Date: Sun, 16 Jun 2024 01:36:04 +0900 Subject: [PATCH 07/11] =?UTF-8?q?Feat=20:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=97=86=EC=9D=84=EC=8B=9C=20=EA=B8=B0=EB=B3=B8=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UserProfileImg/UserProfileImg.tsx | 18 ++++++++++-------- .../components/Members/Members.tsx | 2 -- .../components/utils/useSignUpForm.ts | 3 +-- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/components/UserProfileImg/UserProfileImg.tsx b/src/components/UserProfileImg/UserProfileImg.tsx index 93832d4..472b884 100644 --- a/src/components/UserProfileImg/UserProfileImg.tsx +++ b/src/components/UserProfileImg/UserProfileImg.tsx @@ -1,4 +1,5 @@ import styles from './UserProfileImg.module.scss'; +import DefaultImg from '/img/Avatar.png'; /* 유저의 프로필 이미지 컴포넌트입니다. 프로필 이미지를 설정하지 않은 유저는 프로필 이미지가 없으므로, @@ -34,12 +35,13 @@ function UserProfileImg({ } // 대시보드 멤버들 표현에 사용되는 프로필 이미지 +interface MembersProfileImgprops { + profileImageUrl : string | null; +} export function MembersProfileImg({ - isImg, - profileImageUrl, - nickname, -}: UserProfileImgProps) { + profileImageUrl +}: MembersProfileImgprops) { return (
- {isImg ? ( + {profileImageUrl ? ( 프로필 이미지 ) : ( -
{nickname?.[0].toUpperCase()}
+ 프로필 기본 이미지 )}
); @@ -62,13 +64,13 @@ svg 생성기가 있으면, 사용할 프로필 이미지 컴포넌트 props로 url 하나만 받아옵니다. */ interface UserProfileImgSvgProps { - profileImageUrl: string | undefined; + profileImageUrl?: string | null; } export function UserProfileImgSvg({ profileImageUrl }: UserProfileImgSvgProps) { return ( 프로필 이미지 diff --git a/src/pages/dashboard.{dashboardid}/components/Members/Members.tsx b/src/pages/dashboard.{dashboardid}/components/Members/Members.tsx index e44c0fe..5255a81 100644 --- a/src/pages/dashboard.{dashboardid}/components/Members/Members.tsx +++ b/src/pages/dashboard.{dashboardid}/components/Members/Members.tsx @@ -106,8 +106,6 @@ function Members({ dashboardId }: { dashboardId: number | undefined }) { {members.slice(0, maxMembersToShow).map((member) => ( ))} diff --git a/src/pages/login-signup/components/utils/useSignUpForm.ts b/src/pages/login-signup/components/utils/useSignUpForm.ts index 79a169a..34e0eed 100644 --- a/src/pages/login-signup/components/utils/useSignUpForm.ts +++ b/src/pages/login-signup/components/utils/useSignUpForm.ts @@ -117,7 +117,6 @@ function useSignUpForm() { localStorage.removeItem('Token'); setIsModalOpen(true); // 성공 시 모달 창 띄우기 - navigate('/login'); // 회원가입 성공 시 로그인 페이지로 이동 } catch (error) { setIsErrorModalOpen(true); } finally { @@ -140,4 +139,4 @@ function useSignUpForm() { }; } -export default useSignUpForm; +export default useSignUpForm; \ No newline at end of file From 4112e86a6f302fdcf991af15e0acfe0253a7306f Mon Sep 17 00:00:00 2001 From: Park Sumin Date: Sun, 16 Jun 2024 01:40:27 +0900 Subject: [PATCH 08/11] PULL TEST --- src/pages/login-signup/components/SignUpForm/SignUpForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx b/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx index fa23011..c7aee5a 100644 --- a/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx +++ b/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx @@ -150,4 +150,4 @@ function SignUpForm() { ); } -export default SignUpForm; +export default SignUpForm; \ No newline at end of file From 98aa376ead20be4b07830e46747601318542ed53 Mon Sep 17 00:00:00 2001 From: Park Sumin Date: Sun, 16 Jun 2024 01:46:50 +0900 Subject: [PATCH 09/11] =?UTF-8?q?Fix=20:=20=EB=A6=B0=ED=8A=B8=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/UserProfileImg/UserProfileImg.tsx | 6 +++--- src/contexts/UserContext.tsx | 4 +++- src/pages/login-signup/components/SignUpForm/SignUpForm.tsx | 2 +- src/pages/login-signup/components/utils/useSignUpForm.ts | 2 +- src/pages/mypage/utils/useProfileChange.ts | 2 +- src/utils/defaultProfileImgMaker.tsx | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/components/UserProfileImg/UserProfileImg.tsx b/src/components/UserProfileImg/UserProfileImg.tsx index 472b884..7a387da 100644 --- a/src/components/UserProfileImg/UserProfileImg.tsx +++ b/src/components/UserProfileImg/UserProfileImg.tsx @@ -40,7 +40,7 @@ interface MembersProfileImgprops { } export function MembersProfileImg({ - profileImageUrl + profileImageUrl, }: MembersProfileImgprops) { return (
({ userInfo, setUserInfo, userProfile, setUserProfile }), // userProfile과 setUserProfile 추가 + () => ({ + userInfo, setUserInfo, userProfile, setUserProfile, + }), // userProfile과 setUserProfile 추가 [userInfo, userProfile], ); diff --git a/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx b/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx index c7aee5a..fa23011 100644 --- a/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx +++ b/src/pages/login-signup/components/SignUpForm/SignUpForm.tsx @@ -150,4 +150,4 @@ function SignUpForm() { ); } -export default SignUpForm; \ No newline at end of file +export default SignUpForm; diff --git a/src/pages/login-signup/components/utils/useSignUpForm.ts b/src/pages/login-signup/components/utils/useSignUpForm.ts index 392d569..8958354 100644 --- a/src/pages/login-signup/components/utils/useSignUpForm.ts +++ b/src/pages/login-signup/components/utils/useSignUpForm.ts @@ -93,4 +93,4 @@ function useSignUpForm() { }; } -export default useSignUpForm; \ No newline at end of file +export default useSignUpForm; diff --git a/src/pages/mypage/utils/useProfileChange.ts b/src/pages/mypage/utils/useProfileChange.ts index 143ceea..38ba908 100644 --- a/src/pages/mypage/utils/useProfileChange.ts +++ b/src/pages/mypage/utils/useProfileChange.ts @@ -69,7 +69,7 @@ function useProfileChange() { // 파일 형식 검사 const validImageTypes = ['image/jpeg', 'image/png', 'image/svg+xml']; if (!validImageTypes.includes(file.type)) { - alert('Unsupported file type. Only JPEG, PNG, and SVG are allowed.'); + // alert('Unsupported file type. Only JPEG, PNG, and SVG are allowed.'); return; } diff --git a/src/utils/defaultProfileImgMaker.tsx b/src/utils/defaultProfileImgMaker.tsx index dbb6b90..18393e7 100644 --- a/src/utils/defaultProfileImgMaker.tsx +++ b/src/utils/defaultProfileImgMaker.tsx @@ -60,7 +60,7 @@ function defaultProfileImgMaker({ name, size = 38 }: SvgMakerProps) { // 이미지 Url 생성 const ImgUrl = toSvgImg({ initial, size, color }); - + return ImgUrl; } From b5d3701fafadf68b866e1d382e76aca599170d62 Mon Sep 17 00:00:00 2001 From: imsoohyeok Date: Sun, 16 Jun 2024 01:54:28 +0900 Subject: [PATCH 10/11] =?UTF-8?q?fix:=20=EA=B8=B0=EB=B3=B8=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/mypage/utils/useProfileChange.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/mypage/utils/useProfileChange.ts b/src/pages/mypage/utils/useProfileChange.ts index 38ba908..f4d9198 100644 --- a/src/pages/mypage/utils/useProfileChange.ts +++ b/src/pages/mypage/utils/useProfileChange.ts @@ -1,7 +1,7 @@ import { useContext, useState, useEffect } from 'react'; import { UserContext } from '../../../contexts/UserContext'; import { apiEditMyInfo, apiUploadImage } from '../../../api/apiModule'; -import defaultProfileImg from '../../../../public/img/test_img.png'; +import defaultProfileImg from '../../../../public/img/Avatar.png'; // 닉네임과 프로필을 변경하는 함수입니다. // 닉네임은 기존 값을 먼저 보여주며, 변경하고 변경 버튼을 누르면 닉네임이 변경됩니다. @@ -28,7 +28,7 @@ function useProfileChange() { const [nickname, setNickname] = useState(''); const [profileImage, setProfileImage] = useState(null); const [profileImageUrl, setProfileImageUrl] = useState( - userInfo?.profileImageUrl || defaultProfileImg, + userInfo?.profileImageUrl || defaultProfileImg ); // 모달 상태 관리 From 4ab7416a231dbcfe73149c2863a0917b7d224adb Mon Sep 17 00:00:00 2001 From: imsoohyeok Date: Sun, 16 Jun 2024 01:56:22 +0900 Subject: [PATCH 11/11] fix: lint --- src/api/users/apiUsers.tsx | 6 +----- src/pages/mypage/utils/useProfileChange.ts | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/api/users/apiUsers.tsx b/src/api/users/apiUsers.tsx index f17f23d..0fdc606 100644 --- a/src/api/users/apiUsers.tsx +++ b/src/api/users/apiUsers.tsx @@ -39,7 +39,7 @@ export async function apiInquireMyInfo(): Promise { // 내 정보 수정 api export async function apiEditMyInfo( - body: EditMyInfoBody + body: EditMyInfoBody, ): Promise { const res = await instance.put('/users/me', body); return handleResponse(res); @@ -47,11 +47,7 @@ export async function apiEditMyInfo( // 프로필 이미지 업로드 api export async function apiUploadImage( -<<<<<<< HEAD - body: FormData // FormData로 받아오도록 -======= body: FormData, ->>>>>>> 9ca940bfde7c5cef0d3201940e2ebed752c92d74 ): Promise { const token = localStorage.getItem('Token'); // 저장된 토큰을 가져옴 const res = await instance.post('/users/me/image', body, { diff --git a/src/pages/mypage/utils/useProfileChange.ts b/src/pages/mypage/utils/useProfileChange.ts index f4d9198..867c382 100644 --- a/src/pages/mypage/utils/useProfileChange.ts +++ b/src/pages/mypage/utils/useProfileChange.ts @@ -28,7 +28,7 @@ function useProfileChange() { const [nickname, setNickname] = useState(''); const [profileImage, setProfileImage] = useState(null); const [profileImageUrl, setProfileImageUrl] = useState( - userInfo?.profileImageUrl || defaultProfileImg + userInfo?.profileImageUrl || defaultProfileImg, ); // 모달 상태 관리