diff --git a/src/@types/auth.types.ts b/src/@types/auth.types.ts index 98ce9d08..21ad8c97 100644 --- a/src/@types/auth.types.ts +++ b/src/@types/auth.types.ts @@ -23,6 +23,7 @@ export interface EditPassword { export interface EditPasswordProps { password: string; + newPassword: string; } export interface AuthInputBoxProps { diff --git a/src/@types/member.types.ts b/src/@types/member.types.ts index bdb4b699..a7ef7fd7 100644 --- a/src/@types/member.types.ts +++ b/src/@types/member.types.ts @@ -14,15 +14,15 @@ interface MemberInfo { nickname: string; email: string; profileImageUrl: string | null; - ageType: - | 'TEENAGER' - | 'TWENTIES' - | 'THIRTIES' - | 'FOURTIES' - | 'ABOVE_FIFTIES' - | 'DEFATULT' - | null; - genderType: 'MALE' | 'FEMALE' | 'NON_BINARY' | null; + ageType: string | null; + // | 'TEENAGER' + // | 'TWENTIES' + // | 'THIRTIES' + // | 'FOURTIES' + // | 'ABOVE_FIFTIES' + // | 'DEFATULT' + genderType: string | null; + // 'MALE' | 'FEMALE' | 'NON_BINARY' | 'DEFATULT'; survey: Survey | null; } diff --git a/src/api/authClient.ts b/src/api/authClient.ts index 9590a509..132102e2 100644 --- a/src/api/authClient.ts +++ b/src/api/authClient.ts @@ -1,9 +1,8 @@ import { getItem, removeItem, setItem } from '@utils/localStorageFun'; import axios from 'axios'; -import { postLogout } from './auth'; const authClient = axios.create({ - baseURL: import.meta.env.VITE_SERVER_URL, + baseURL: `${import.meta.env.VITE_SERVER_URL}api/`, headers: { 'Content-Type': 'application/json', }, @@ -38,18 +37,16 @@ authClient.interceptors.response.use( return res; }, function (error) { - console.error(error); - if (error.response.status === 401) { // 응답이 401으로 오는 경우 // 1. 엑세스 토큰이 없는 경우(엑세스 토큰이 없습니다.) // 2. 리프레시 토큰이 만료된 경우(리프레시 토큰이 존재하지 않습니다.) // 3. 리프레시 토큰이 없는 경우 // 전부 비로그인으로 처리합니다. - // TODO 서지수 | 로그아웃 요청 console.log('401에러 발생 로그인 페이지로 이동시키면 됩니다.'); - postLogout(); - removeItem('accessToken'); + if (getItem('accessToken')) { + removeItem('accessToken'); + } } return Promise.reject(error); }, diff --git a/src/api/client.ts b/src/api/client.ts index 930438d1..a91224c1 100644 --- a/src/api/client.ts +++ b/src/api/client.ts @@ -1,7 +1,7 @@ import axios from 'axios'; const client = axios.create({ - baseURL: import.meta.env.VITE_SERVER_URL, + baseURL: `${import.meta.env.VITE_SERVER_URL}api/`, headers: { 'Content-Type': 'application/json', }, diff --git a/src/components/Auth/AuthSurvey/AuthSurvey.tsx b/src/components/Auth/AuthSurvey/AuthSurvey.tsx index da9558bb..94811ff6 100644 --- a/src/components/Auth/AuthSurvey/AuthSurvey.tsx +++ b/src/components/Auth/AuthSurvey/AuthSurvey.tsx @@ -43,7 +43,6 @@ const AuthSurvey = ({ path }: Props) => { // newPrevUserInfo.survey = data; // return newPrevUserInfo; // }); - alert('변경되었습니다.'); navigate(path); } } catch (err) { @@ -51,7 +50,6 @@ const AuthSurvey = ({ path }: Props) => { alert('오류가 발생했습니다. 다시 시도해주세요'); } }; - console.log(isDirty); return (
diff --git a/src/components/Auth/Login/AuthButtons/KakaoLoginButton.tsx b/src/components/Auth/Login/AuthButtons/KakaoLoginButton.tsx index aba29b0f..c5227cc7 100644 --- a/src/components/Auth/Login/AuthButtons/KakaoLoginButton.tsx +++ b/src/components/Auth/Login/AuthButtons/KakaoLoginButton.tsx @@ -1,14 +1,10 @@ import { KakaoIcon } from '@components/common/icons/Icons'; const KakaoLoginButton = () => { - const VITE_KAKAO_LOGIN_TEST_API_KEY = import.meta.env - .VITE_KAKAO_LOGIN_TEST_API_KEY; - const REDIRECT_URI = `${window.location.href}/kakao`; - const KAKAO_LOGIN_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${VITE_KAKAO_LOGIN_TEST_API_KEY}&redirect_uri=${REDIRECT_URI}&response_type=code`; - return ( 카카오로 로그인 diff --git a/src/components/Auth/Login/KakaoLogin.tsx b/src/components/Auth/Login/KakaoLogin.tsx new file mode 100644 index 00000000..541ce440 --- /dev/null +++ b/src/components/Auth/Login/KakaoLogin.tsx @@ -0,0 +1,44 @@ +import { UserInfoState } from '@recoil/Auth.atom'; +import { setItem } from '@utils/localStorageFun'; +import { useEffect } from 'react'; +import { useNavigate, useSearchParams } from 'react-router-dom'; +import { useSetRecoilState } from 'recoil'; + +const KakaoLogin = () => { + const setUserInfo = useSetRecoilState(UserInfoState); + const navigate = useNavigate(); + + const [searchParams, _] = useSearchParams(); + const nickname = searchParams.get('nickname'); + const email = searchParams.get('email'); + const gender = searchParams.get('gender'); + const age_range = searchParams.get('age_range'); + const accessToken = searchParams.get('token'); + const profile_image = searchParams.get('profile_image'); + const signup = searchParams.get('signup'); + + useEffect(() => { + if (accessToken) { + setItem('accessToken', accessToken); + setUserInfo({ + nickname: nickname!, + email: email!, + profileImageUrl: profile_image, + ageType: age_range, + genderType: gender, + survey: null, + }); + if (signup) { + navigate('/signup/success'); + } else { + navigate('/'); + } + } else { + alert('로그인에 실패했습니다. 다시 시도해주세요.'); + navigate('/login'); + } + }, []); + return <>카카오 로그인 중입니다.; +}; + +export default KakaoLogin; diff --git a/src/components/Auth/Login/LoginForm.tsx b/src/components/Auth/Login/LoginForm.tsx index b1d42caf..db12f7bc 100644 --- a/src/components/Auth/Login/LoginForm.tsx +++ b/src/components/Auth/Login/LoginForm.tsx @@ -38,7 +38,6 @@ const LoginForm = () => { if (res.data.status === 200) { setItem('accessToken', res.data.data.tokenInfo.accessToken); // setUserInfo(res.data.data.memberDto); - // TODO 서지수 | 로그인 후 어디로 갈지 물어보고 수정 navigate('/'); } } catch (err) { diff --git a/src/components/Auth/Login/index.ts b/src/components/Auth/Login/index.ts index 424a52d4..33ef9f5a 100644 --- a/src/components/Auth/Login/index.ts +++ b/src/components/Auth/Login/index.ts @@ -1,5 +1,6 @@ import LoginLogo from './LoginLogo'; import LoginForm from './LoginForm'; import AuthButtonsWrapper from './AuthButtons/AuthButtonsWrapper'; +import KakaoLogin from './KakaoLogin'; -export { LoginLogo, LoginForm, AuthButtonsWrapper }; +export { LoginLogo, LoginForm, AuthButtonsWrapper, KakaoLogin }; diff --git a/src/components/DetailSectionBottom/DetailReviews.tsx b/src/components/DetailSectionBottom/DetailReviews.tsx index 7eddf34e..fe0e7e83 100644 --- a/src/components/DetailSectionBottom/DetailReviews.tsx +++ b/src/components/DetailSectionBottom/DetailReviews.tsx @@ -25,6 +25,8 @@ import ReviewItem from './ReviewItem'; import ToastPopUp from '@components/common/toastpopup/ToastPopUp'; import EditDelete from '@components/common/modal/children/EditDelete'; import MyAlert from '@components/common/modal/children/MyAlert'; +import { alertTypeState } from '@recoil/modal'; + interface reviewProps { reviewData: any; } @@ -45,6 +47,7 @@ export default function DetailReviews({ reviewData }: reviewProps) { const setIsModifyingReview = useSetRecoilState(isModifyingReviewState); const [toastPopUp, setToastPopUp] = useRecoilState(toastPopUpState); const modalChildren = useRecoilValue(modalChildrenState); + const alertType = useRecoilValue(alertTypeState); const { data: toursReviews, @@ -129,7 +132,7 @@ export default function DetailReviews({ reviewData }: reviewProps) { {reviewDataLength == 0 && (
{Array.from({ length: 5 }, (_, index) => ( @@ -179,9 +182,15 @@ export default function DetailReviews({ reviewData }: reviewProps) { {modalChildren === 'EditDelete' && } - {modalChildren === 'MyAlert' && ( + {modalChildren === 'MyAlert' && alertType === 'DeleteReview' && ( )} + {modalChildren === 'MyAlert' && alertType === 'LoginReview' && ( + + )} ); diff --git a/src/components/DetailSectionBottom/ReviewItem.tsx b/src/components/DetailSectionBottom/ReviewItem.tsx index a8c61a7d..4bc2caec 100644 --- a/src/components/DetailSectionBottom/ReviewItem.tsx +++ b/src/components/DetailSectionBottom/ReviewItem.tsx @@ -111,25 +111,25 @@ const Item: React.FC = (props: ItemProps) => { }; return ( - <> -
-
-
- {!( - authorProfileImageUrl === 'http://asiduheimage.jpg' || - authorProfileImageUrl === null - ) ? ( - 유저 프로필 - ) : ( - - )} -
-
-
{authorNickname}
+
+
+
+ {!( + authorProfileImageUrl === 'http://asiduheimage.jpg' || + authorProfileImageUrl === null + ) ? ( + 유저 프로필 + ) : ( + + )} +
+
+
{authorNickname}
+
{Array.from({ length: 5 }, (_, index) => ( = (props: ItemProps) => { /> ))}
+
+ {formatCreatedTime(createdTime)} +
-
- {formatCreatedTime(createdTime)} +
+ + {isAuthor && ( +
openModal('내 리뷰', reviewId, e)}> +
- {isAuthor && ( + )} +
+ {canTextOverflow ? ( +
+ {content.length > 55 ? `${content.slice(0, 55)}...` : content} +
+ ) : ( +
{content}
+ )} + +
+
+ {!showMoreKeywords && + keywords.slice(0, 2).map((keyword, idx) => ( +
+ {getEmoji(keyword.content)} {keyword.content} +
+ ))} + {keywords.length > 2 && !showMoreKeywords && (
openModal('내 리뷰', reviewId, e)}> - + className="rounded-md bg-gray1 px-2 py-1 text-xs text-gray6" + onClick={(e) => { + handleClickPlusButton(e); + }}> + +{keywords.length - 2}
)}
- {canTextOverflow ? ( -
- {content.length > 75 ? `${content.slice(0, 75)}...` : content} -
- ) : ( -
{content}
- )} - -
-
- {!showMoreKeywords && - keywords.slice(0, 2).map((keyword, idx) => ( +
+ {showMoreKeywords && + Array.from({ length: Math.ceil(keywords.length / 2) }).map( + (_, lineIdx) => (
- {getEmoji(keyword.content)} {keyword.content} + key={lineIdx} + className={`flex gap-2 ${ + lineIdx === Math.ceil(keywords.length / 2) - 1 + ? '' + : ' mb-3' + }`}> + {keywords + .slice(lineIdx * 2, lineIdx * 2 + 2) + .map((keyword, idx) => ( +
+ {getEmoji(keyword.content)} {keyword.content} +
+ ))}
- ))} - {keywords.length > 2 && !showMoreKeywords && ( -
{ - handleClickPlusButton(e); - }}> - +{keywords.length - 2} -
+ ), )} -
-
- {showMoreKeywords && - Array.from({ length: Math.ceil(keywords.length / 2) }).map( - (_, lineIdx) => ( -
- {keywords - .slice(lineIdx * 2, lineIdx * 2 + 2) - .map((keyword, idx) => ( -
- {getEmoji(keyword.content)} {keyword.content} -
- ))} -
- ), - )} -
+
-
- -
{commentCount}
-
+
+ +
{commentCount}
- +
); }; diff --git a/src/components/DetailSectionTop/DetailAddSchedule.tsx b/src/components/DetailSectionTop/DetailAddSchedule.tsx index 136f5ad0..d805968c 100644 --- a/src/components/DetailSectionTop/DetailAddSchedule.tsx +++ b/src/components/DetailSectionTop/DetailAddSchedule.tsx @@ -13,9 +13,9 @@ const DetailAddSchedule = () => { return ( - diff --git a/src/components/DetailSectionTop/DetailToursButtons.tsx b/src/components/DetailSectionTop/DetailToursButtons.tsx index 8947bb35..85a44d0c 100644 --- a/src/components/DetailSectionTop/DetailToursButtons.tsx +++ b/src/components/DetailSectionTop/DetailToursButtons.tsx @@ -1,11 +1,14 @@ import DetailAddSchedule from '@components/DetailSectionTop/DetailAddSchedule'; import { PenIcon } from '@components/common/icons/Icons'; -import { Modal } from '@components/common/modal'; -import MyAlert from '@components/common/modal/children/MyAlert'; -import { isModalOpenState, modalChildrenState } from '@recoil/modal'; +import { + isModalOpenState, + modalChildrenState, + alertTypeState, +} from '@recoil/modal'; import { isModifyingReviewState } from '@recoil/review'; import { useNavigate, useParams } from 'react-router-dom'; -import { useRecoilState, useSetRecoilState } from 'recoil'; +import { useSetRecoilState } from 'recoil'; +import { getItem } from '@utils/localStorageFun'; interface reviewProps { reviewData: any; @@ -17,45 +20,35 @@ export default function DetailTourButtons({ reviewData }: reviewProps) { const tourItemId = Number(params.id); const navigate = useNavigate(); const setIsModifyingReview = useSetRecoilState(isModifyingReviewState); - const [isModalOpen, setIsModalOpen] = useRecoilState(isModalOpenState); - const [modalChildren, setModalChildren] = useRecoilState(modalChildrenState); + const setIsModalOpen = useSetRecoilState(isModalOpenState); + const setModalChildren = useSetRecoilState(modalChildrenState); + const setAlertType = useSetRecoilState(alertTypeState); const handlePostingReivew = () => { - const accessToken = localStorage.getItem('accessToken'); - if (accessToken) { + const token = getItem('accessToken'); + if (token) { navigate(`/reviewPosting/${tourItemId}`, { state: { title, contentTypeId }, }); } else { + setModalChildren('MyAlert'); + setAlertType('LoginReview'); setIsModifyingReview(false); - setModalChildren('EditDelete'); setIsModalOpen(true); } }; - const closeModal = () => { - setIsModalOpen(false); - }; - return ( <>
-
- - {modalChildren === 'MyAlert' && ( - - )} - ); } diff --git a/src/components/Mypage/DeleteMemberButton.tsx b/src/components/Mypage/DeleteMemberButton.tsx index fb359241..8313f23b 100644 --- a/src/components/Mypage/DeleteMemberButton.tsx +++ b/src/components/Mypage/DeleteMemberButton.tsx @@ -1,4 +1,5 @@ import { deleteMember } from '@api/member'; +import Alert from '@components/common/alert/Alert'; import { UserInfoState } from '@recoil/Auth.atom'; import { useNavigate } from 'react-router-dom'; import { useSetRecoilState } from 'recoil'; @@ -6,24 +7,32 @@ import { useSetRecoilState } from 'recoil'; const DeleteMemberButton = () => { const setUserInfo = useSetRecoilState(UserInfoState); const navigate = useNavigate(); - const onDeleteClick = async () => { - if (confirm('정말 탈퇴 하시겠습니까?')) { - try { - const res = await deleteMember(); - if (res.data.status === 200) { - setUserInfo(null); - navigate('/'); - alert('회원 탈퇴되었습니다. 감사합니다.'); - } - } catch (err) { - console.log(err); + + const handleConfirm = async (e: React.MouseEvent) => { + e.stopPropagation(); + try { + const res = await deleteMember(); + if (res.data.status === 200) { + setUserInfo(null); + navigate('/'); + alert('회원 탈퇴되었습니다. 감사합니다.'); } + } catch (err) { + console.log(err); } }; + + const handleCancel = (e: React.MouseEvent) => { + e.stopPropagation(); + }; return ( - + + + ); }; diff --git a/src/components/Mypage/EditPassword/EditPwForm.tsx b/src/components/Mypage/EditPassword/EditPwForm.tsx index 25d5865d..75d3c58f 100644 --- a/src/components/Mypage/EditPassword/EditPwForm.tsx +++ b/src/components/Mypage/EditPassword/EditPwForm.tsx @@ -6,6 +6,7 @@ import { AuthPwInputBox, } from '@components/Auth'; import SubmitBtn from '@components/common/button/SubmitBtn'; +import { AxiosError } from 'axios'; import { SubmitHandler, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; @@ -26,31 +27,26 @@ const EditPwForm = () => { const navigate = useNavigate(); const onEditPwSubmit: SubmitHandler = async (data) => { - const { password } = data; + const { currentPw, password } = data; - // 비밀번호 확인 로직 - // try { - // const res = await getCheckPw(inputValue); - // if (res.status === 200) { try { const res = await putMemberPassword({ - password, + password: currentPw, + newPassword: password, }); if (res.status === 200) { alert('비밀번호가 변경되었습니다.'); navigate('/mypage/info'); } } catch (err) { - alert('오류가 발생했습니다. 다시 시도해주세요'); console.error('비밀번호 수정 요청 중 에러 발생', err); + if (err instanceof AxiosError) { + if (err.response?.data.status === 404) { + resetField('currentPw'); + setError('currentPw', { message: '비밀번호가 올바르지 않습니다.' }); + } + } } - // if (isExist) { - // setError('currentPw', { message: '비밀번호가 올바르지 않습니다.' }); - // } - // } - // } catch (err) { - // console.error(err); - // } }; return ( { const onLogoutClick = async (e: any) => { e.stopPropagation(); + }; + + const handleConfirm = async (e: React.MouseEvent) => { + e.stopPropagation(); try { const res = await postLogout(); if (res.data === 'LOGOUT!') { @@ -19,10 +24,20 @@ const LogoutButton = () => { } }; + const handleCancel = (e: React.MouseEvent) => { + e.stopPropagation(); + }; + return ( - + + + ); }; diff --git a/src/components/Mypage/MypageItem.tsx b/src/components/Mypage/MypageItem.tsx index d0444b4d..c033a568 100644 --- a/src/components/Mypage/MypageItem.tsx +++ b/src/components/Mypage/MypageItem.tsx @@ -1,5 +1,7 @@ +import Alert from '@components/common/alert/Alert'; import { RightIcon } from '@components/common/icons/Icons'; -import { Link } from 'react-router-dom'; +import { getItem } from '@utils/localStorageFun'; +import { Link, useNavigate } from 'react-router-dom'; interface Props { link: string; @@ -7,13 +9,48 @@ interface Props { } const MypageItem = ({ link, children }: Props) => { + const navigate = useNavigate(); + const isLogin = getItem('accessToken'); + + const handleConfirm = async (e: React.MouseEvent) => { + e.stopPropagation(); + if (getItem('accessToken')) { + navigate(link); + } + }; + + const handleCancel = (e: React.MouseEvent) => { + e.stopPropagation(); + }; + return ( - - {children} - - + <> + {isLogin ? ( + + {children} + + + ) : ( + + 조회 시 로그인이 필요합니다. +
+ 로그인 하시겠습니까? + + } + onConfirm={handleConfirm} + onCancel={handleCancel}> + +
+ )} + ); }; diff --git a/src/components/Mypage/MypageList.tsx b/src/components/Mypage/MypageList.tsx index 4d073479..266dad60 100644 --- a/src/components/Mypage/MypageList.tsx +++ b/src/components/Mypage/MypageList.tsx @@ -5,7 +5,7 @@ const MypageList = () => {
나의 여정 나의 관심 여행지 - 나의 리뷰 + 나의 리뷰 나의 여행 취향 설정
); diff --git a/src/components/Review/CommentItem.tsx b/src/components/Review/CommentItem.tsx index 7305ed3f..c4e4d264 100644 --- a/src/components/Review/CommentItem.tsx +++ b/src/components/Review/CommentItem.tsx @@ -56,7 +56,7 @@ const CommentItem: React.FC = (props: ItemProps) => { return (
-
+
{!( authorProfileImageUrl === 'http://asiduheimage.jpg' || @@ -65,15 +65,15 @@ const CommentItem: React.FC = (props: ItemProps) => { 유저 프로필 ) : ( - + )}
{authorNickname}
-
+
{formatCreatedTime(createdTime)}
@@ -85,7 +85,7 @@ const CommentItem: React.FC = (props: ItemProps) => {
)}
-
{content}
+
{content}
); }; diff --git a/src/components/Review/DetailReview.tsx b/src/components/Review/DetailReview.tsx index 9e1db449..8d5539e7 100644 --- a/src/components/Review/DetailReview.tsx +++ b/src/components/Review/DetailReview.tsx @@ -8,21 +8,19 @@ export default function DetailReview() { const { item, tourItemId } = state; return ( -
- -
+ ); } diff --git a/src/components/Review/MyReview.tsx b/src/components/Review/MyReview.tsx index c6cca236..1db45243 100644 --- a/src/components/Review/MyReview.tsx +++ b/src/components/Review/MyReview.tsx @@ -19,6 +19,8 @@ import ReviewItem from '@components/DetailSectionBottom/ReviewItem'; import ToastPopUp from '@components/common/toastpopup/ToastPopUp'; import EditDelete from '@components/common/modal/children/EditDelete'; import MyAlert from '@components/common/modal/children/MyAlert'; +import { alertTypeState } from '@recoil/modal'; +import { PenIcon } from '@components/common/icons/Icons'; export default function MyReview() { const [reviewDataLength, setReviewDataLength] = useState(0); @@ -31,6 +33,8 @@ export default function MyReview() { const setIsModifyingReview = useSetRecoilState(isModifyingReviewState); const [toastPopUp, setToastPopUp] = useRecoilState(toastPopUpState); const modalChildren = useRecoilValue(modalChildrenState); + const [alertType] = useRecoilValue(alertTypeState); + const { data: myReviews, fetchNextPage, @@ -103,9 +107,16 @@ export default function MyReview() { 나의 리뷰{reviewDataLength}
{reviewDataLength == 0 && ( -
-
작성한 리뷰가 없습니다
-
다녀온 여행지의 리뷰를 남겨보세요!
+
+
+ +
+
+ 작성한 리뷰가 없습니다 +
+
+ 다녀온 여행지의 리뷰를 남겨보세요! +
)} {modalChildren === 'EditDelete' && } - {modalChildren === 'MyAlert' && ( + {modalChildren === 'MyAlert' && alertType === 'DeleteReview' && ( )} diff --git a/src/components/Review/ReviewComments.tsx b/src/components/Review/ReviewComments.tsx index fbdc53ae..8cde28ec 100644 --- a/src/components/Review/ReviewComments.tsx +++ b/src/components/Review/ReviewComments.tsx @@ -11,6 +11,7 @@ import InfiniteScroll from 'react-infinite-scroller'; import EditDelete from '@components/common/modal/children/EditDelete'; import MyAlert from '@components/common/modal/children/MyAlert'; import { commentState } from '@recoil/review'; +import { alertTypeState } from '@recoil/modal'; export default function ReviewComments() { const params = useParams(); @@ -21,6 +22,7 @@ export default function ReviewComments() { const [commentDataLength, setCommentDataLength] = useState(0); const modalChildren = useRecoilValue(modalChildrenState); const setComment = useSetRecoilState(commentState); + const alertType = useRecoilValue(alertTypeState); const { data: reviewComments, @@ -46,9 +48,10 @@ export default function ReviewComments() { } const closeModal = () => { - setIsModalOpen(false); setComment(''); + setIsModalOpen(false); }; + useEffect(() => { { reviewComments?.pages.map((group) => { @@ -57,11 +60,12 @@ export default function ReviewComments() { } console.log('reviewComments', reviewComments); }, [reviewComments]); + return ( <> -
+
댓글 - {commentDataLength} + {commentDataLength}
{commentDataLength == 0 && ( @@ -104,9 +108,15 @@ export default function ReviewComments() {
{modalChildren === 'EditDelete' && } - {modalChildren === 'MyAlert' && ( + {modalChildren === 'MyAlert' && alertType === 'DeleteReview' && ( )} + {modalChildren === 'MyAlert' && alertType === 'LoginComment' && ( + + )} ); diff --git a/src/components/common/BackBox/BackBox.tsx b/src/components/common/BackBox/BackBox.tsx index d440deb9..4f724838 100644 --- a/src/components/common/BackBox/BackBox.tsx +++ b/src/components/common/BackBox/BackBox.tsx @@ -1,10 +1,9 @@ -import { useNavigate } from 'react-router-dom'; import { LeftIcon } from '../icons/Icons'; import { ReactNode } from 'react'; interface Props { showBack?: boolean; - // backHandler?: VoidFunction; + backHandler?: VoidFunction; children?: ReactNode; showSkip?: boolean; skipHandler?: VoidFunction; @@ -14,17 +13,15 @@ interface Props { const BackBox = ({ showBack, - // backHandler, + backHandler, children, showSkip, skipHandler, showSave, saveHandler, }: Props) => { - const navigate = useNavigate(); - const onBackClick = () => { - navigate(-1); + backHandler && backHandler(); }; const onSkipClick = () => { skipHandler && skipHandler(); diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx index 52355fba..18f154b1 100644 --- a/src/components/common/icons/Icons.tsx +++ b/src/components/common/icons/Icons.tsx @@ -268,6 +268,7 @@ export const PenIcon: React.FC = ({ size = 25, color = 'black', fill = 'none', + className, }) => { return ( = ({ height={size} viewBox="0 0 21 21" fill={fill} + className={className} xmlns="http://www.w3.org/2000/svg"> diff --git a/src/components/common/modal/children/EditDelete.tsx b/src/components/common/modal/children/EditDelete.tsx index 84754048..28908345 100644 --- a/src/components/common/modal/children/EditDelete.tsx +++ b/src/components/common/modal/children/EditDelete.tsx @@ -4,6 +4,7 @@ import { isModalOpenState, titleState, modalChildrenState, + alertTypeState, } from '@recoil/modal'; import { contentState, @@ -37,7 +38,7 @@ const EditDelete: React.FC = () => { const setIsModalOpen = useSetRecoilState(isModalOpenState); const setModalChildren = useSetRecoilState(modalChildrenState); const setComment = useSetRecoilState(commentState); - + const setAlertType = useSetRecoilState(alertTypeState); const queryClient = useQueryClient(); const handleEdit = () => { @@ -71,6 +72,7 @@ const EditDelete: React.FC = () => { const handleDelete = async () => { if (title === '내 리뷰') { setModalChildren('MyAlert'); + setAlertType('DeleteReview'); } else if (title === '내 댓글') { await deleteCommentMutate(targetCommentId); setIsModalOpen(false); diff --git a/src/components/common/modal/children/MyAlert.tsx b/src/components/common/modal/children/MyAlert.tsx index 4257612a..e5f50f7e 100644 --- a/src/components/common/modal/children/MyAlert.tsx +++ b/src/components/common/modal/children/MyAlert.tsx @@ -5,6 +5,7 @@ import { toastPopUpState, targetReviewIdState, tourItemIdState, + commentState, } from '@recoil/review'; import { useNavigate } from 'react-router-dom'; import { useRecoilValue, useSetRecoilState } from 'recoil'; @@ -21,6 +22,7 @@ const MyAlert: React.FC = ({ title, content }) => { const setIsModalOpen = useSetRecoilState(isModalOpenState); const setToastPopUp = useSetRecoilState(toastPopUpState); const queryClient = useQueryClient(); + const setComment = useSetRecoilState(commentState); const { mutate: deleteReviewMutate } = useMutation({ mutationFn: (targetReviewId: number) => deleteReview(targetReviewId), @@ -52,23 +54,29 @@ const MyAlert: React.FC = ({ title, content }) => { } } } else if (title == '로그인') { + setComment(''); setIsModalOpen(false); navigate(`/login`); } }; + const closeModal = () => { + setComment(''); + setIsModalOpen(false); + }; + return (
{title}
-
- {content} +
+ {content.split('. ').map((sentence, index) => ( +
+ {sentence} +
+ ))}
- { - setIsModalOpen(false); - }} - className="text-sm"> + 취소 diff --git a/src/components/common/nav/InputComment.tsx b/src/components/common/nav/InputComment.tsx index 76fbba1f..eb21cbf6 100644 --- a/src/components/common/nav/InputComment.tsx +++ b/src/components/common/nav/InputComment.tsx @@ -2,10 +2,16 @@ import { KeyboardEvent, ChangeEvent } from 'react'; import { postComments } from '@api/comments'; import { useParams } from 'react-router-dom'; import { commentState } from '@recoil/review'; -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; import { putComments } from '@api/comments'; import { isModifyingCommentState, targetCommentIdState } from '@recoil/review'; import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { getItem } from '@utils/localStorageFun'; +import { + isModalOpenState, + modalChildrenState, + alertTypeState, +} from '@recoil/modal'; interface InputCommentProps { classNameName?: string; @@ -30,6 +36,9 @@ export const InputComment: React.FC = () => { ); const targetCommentId = useRecoilValue(targetCommentIdState); const queryClient = useQueryClient(); + const setIsModalOpen = useSetRecoilState(isModalOpenState); + const setModalChildren = useSetRecoilState(modalChildrenState); + const setAlertType = useSetRecoilState(alertTypeState); const { mutate: postReviewMutate } = useMutation({ mutationFn: ({ comment, reviewId }: PostCommentMutationParams) => @@ -64,13 +73,20 @@ export const InputComment: React.FC = () => { }; const handleSubmit = async () => { - if (isModifyingComment) { - await editReviewMutate({ comment, targetCommentId }); - setIsModifyingComment(false); + const token = getItem('accessToken'); + if (token) { + if (isModifyingComment) { + await editReviewMutate({ comment, targetCommentId }); + setIsModifyingComment(false); + } else { + await postReviewMutate({ comment, reviewId }); + } + setComment(''); } else { - await postReviewMutate({ comment, reviewId }); + setModalChildren('MyAlert'); + setAlertType('LoginComment'); + setIsModalOpen(true); } - setComment(''); }; const handleKeyPress = (event: KeyboardEvent) => { if (event.key === 'Enter') { diff --git a/src/pages/login/login.page.tsx b/src/pages/login/login.page.tsx index 98ffc729..2e4a1ed9 100644 --- a/src/pages/login/login.page.tsx +++ b/src/pages/login/login.page.tsx @@ -4,12 +4,19 @@ import { LoginForm, LoginLogo, } from '@components/Auth/Login'; +import { useNavigate } from 'react-router-dom'; const Login = () => { + const navigate = useNavigate(); return (
- + { + navigate(-1); + }} + />
diff --git a/src/pages/login/loginKakao.page.tsx b/src/pages/login/loginKakao.page.tsx index 3d8ee18a..a3f10231 100644 --- a/src/pages/login/loginKakao.page.tsx +++ b/src/pages/login/loginKakao.page.tsx @@ -1,18 +1,7 @@ -import { useEffect } from 'react'; +import { KakaoLogin } from '@components/Auth/Login'; const LoginKakao = () => { - const code = new URL(window.location.href).searchParams.get('code'); - - useEffect(() => { - console.log(code); - try { - // const res = postKakaoLogin(); - } catch (err) { - console.log('카카오 로그인 중 에러 발생'); - } - }, []); - - return
잠시만 기다려주세요
; + return ; }; export default LoginKakao; diff --git a/src/pages/mypage/editPassword.page.tsx b/src/pages/mypage/editPassword.page.tsx index bc5e73e8..a15f89e6 100644 --- a/src/pages/mypage/editPassword.page.tsx +++ b/src/pages/mypage/editPassword.page.tsx @@ -1,10 +1,18 @@ import EditPwForm from '@components/Mypage/EditPassword/EditPwForm'; import { BackBox } from '@components/common'; +import { useNavigate } from 'react-router-dom'; const EditPassword = () => { + const navigate = useNavigate(); return ( <> - 비밀번호 변경 + { + navigate('/mypage'); + }}> + 비밀번호 변경 + ); diff --git a/src/pages/mypage/editUserInfo.page.tsx b/src/pages/mypage/editUserInfo.page.tsx index 79bf4dfe..eec6457b 100644 --- a/src/pages/mypage/editUserInfo.page.tsx +++ b/src/pages/mypage/editUserInfo.page.tsx @@ -1,11 +1,18 @@ import DeleteMemberButton from '@components/Mypage/DeleteMemberButton'; import { BackBox } from '@components/common'; -import { Link } from 'react-router-dom'; +import { Link, useNavigate } from 'react-router-dom'; const EditUserInfo = () => { + const navigate = useNavigate(); return ( <> - {}}> + { + navigate('/mypage'); + }} + showSave + saveHandler={() => {}}> 회원정보 수정
diff --git a/src/pages/mypage/editUserSurvey.page.tsx b/src/pages/mypage/editUserSurvey.page.tsx index f6551e50..2ec9c382 100644 --- a/src/pages/mypage/editUserSurvey.page.tsx +++ b/src/pages/mypage/editUserSurvey.page.tsx @@ -1,10 +1,19 @@ import AuthSurvey from '@components/Auth/AuthSurvey/AuthSurvey'; import { BackBox } from '@components/common'; +import { useNavigate } from 'react-router-dom'; const EditUserSurvey = () => { + const navigate = useNavigate(); + return ( <> - 나의 여행 취향 설정 + { + navigate('/mypage'); + }}> + 나의 여행 취향 설정 +
diff --git a/src/pages/signup/signup.page.tsx b/src/pages/signup/signup.page.tsx index b24f7d6b..289e5746 100644 --- a/src/pages/signup/signup.page.tsx +++ b/src/pages/signup/signup.page.tsx @@ -1,6 +1,5 @@ import type { SignupFormValue } from '@/@types/auth.types'; import { postSignup } from '@api/auth'; -import authClient from '@api/authClient'; import { AuthTitle, AuthEmailInputBox, @@ -9,6 +8,7 @@ import { } from '@components/Auth'; import { BackBox } from '@components/common'; import SubmitBtn from '@components/common/button/SubmitBtn'; +import { setItem } from '@utils/localStorageFun'; import { SubmitHandler, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; @@ -37,8 +37,7 @@ const Signup = () => { password, }); if (res.status === 200) { - authClient.defaults.headers.common['Authorization'] = - res.data.data.tokenInfo.accessToken; + setItem('accessToken', res.data.data.tokenInfo.accessToken); navigate('/signup/success'); } } catch (err) { @@ -48,7 +47,11 @@ const Signup = () => { return (
- + { + navigate('/login'); + }} + /> diff --git a/src/pages/signup/signupInfo.page.tsx b/src/pages/signup/signupInfo.page.tsx index cf5e2c16..de51184d 100644 --- a/src/pages/signup/signupInfo.page.tsx +++ b/src/pages/signup/signupInfo.page.tsx @@ -77,7 +77,16 @@ const SignupInfo = () => { return (
- + { + navigate('/signup/survey'); + }} + showSkip + skipHandler={() => { + navigate('/'); + }} + /> diff --git a/src/recoil/modal.ts b/src/recoil/modal.ts index eecef4b1..a687f33b 100644 --- a/src/recoil/modal.ts +++ b/src/recoil/modal.ts @@ -14,3 +14,8 @@ export const modalChildrenState = atom({ key: 'modalChildrenState', default: '', }); + +export const alertTypeState = atom({ + key: 'alertTypeState', + default: '', +});