diff --git a/src/api/mypageApi.ts b/src/api/mypageApi.ts index 745a51c..614e4c6 100644 --- a/src/api/mypageApi.ts +++ b/src/api/mypageApi.ts @@ -1,5 +1,14 @@ import axiosInstance from './axiosInstance'; +export type RefundType = { + productName: string; + quantity: number; + price: number; + url: string; + paymentStatus: string; + postId: number; +}; + export type MyPostType = { availableNumber: number; category: string; @@ -136,3 +145,11 @@ export const putEditProfile = async (file: File) => { return response.data; }; + +export const putChangeNickname = async (nickname: string) => { + const response = await axiosInstance.put( + `/api/mypage/change_nickname?nickName=${nickname}` + ); + + return response.data; +}; diff --git a/src/components/common/Header.tsx b/src/components/common/Header.tsx index 40a3b25..5f3e3ca 100644 --- a/src/components/common/Header.tsx +++ b/src/components/common/Header.tsx @@ -14,16 +14,6 @@ const Header = () => { setIsMobileMenuOpen(!isMobileMenuOpen); }; - const handleCommunityClick = ( - e: React.MouseEvent - ) => { - if (!isLoggedIn && !isAdmin) { - e.preventDefault(); - alert('로그인 후 이용할 수 있는 페이지입니다.'); - setIsMobileMenuOpen(!isMobileMenuOpen); - } - }; - return ( @@ -57,7 +47,7 @@ const Header = () => { - + Community @@ -65,7 +55,13 @@ const Header = () => { {isLoggedIn && ( ) => { + if (isAdmin) { + e.preventDefault(); // Admin일 경우 링크 동작 차단 + } else { + toggleMobileMenu(); + } + }} > {isAdmin ? 'Admin Page' : 'My Page'} @@ -96,7 +92,10 @@ const Header = () => { - + 장바구니 아이콘 diff --git a/src/components/pages/Payment/PaymentFailPage.tsx b/src/components/pages/Payment/PaymentFailPage.tsx index dffe762..16b2b76 100644 --- a/src/components/pages/Payment/PaymentFailPage.tsx +++ b/src/components/pages/Payment/PaymentFailPage.tsx @@ -11,7 +11,7 @@ const PaymentFailPage = () => { const productId = Number(id); const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); - const amount = urlParams.get('totalAmount'); + const price = urlParams.get('price'); const { data: product, isLoading, isError } = useProductQuery(productId); if (!product) { @@ -33,7 +33,7 @@ const PaymentFailPage = () => { - {amount} 원 + {price} 원 diff --git a/src/components/pages/Payment/PaymentSuccessPage.tsx b/src/components/pages/Payment/PaymentSuccessPage.tsx index aa61298..6c0927c 100644 --- a/src/components/pages/Payment/PaymentSuccessPage.tsx +++ b/src/components/pages/Payment/PaymentSuccessPage.tsx @@ -12,7 +12,7 @@ const PaymentSuccessPage = () => { const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); - const amount = urlParams.get('totalAmount'); + const price = urlParams.get('price'); const { data: product, isLoading, isError } = useProductQuery(productId); @@ -34,7 +34,7 @@ const PaymentSuccessPage = () => { - {amount}원 + {price}원 diff --git a/src/components/pages/ProductDetailPage/ProductDetail.tsx b/src/components/pages/ProductDetailPage/ProductDetail.tsx index 16dad50..d3060c0 100644 --- a/src/components/pages/ProductDetailPage/ProductDetail.tsx +++ b/src/components/pages/ProductDetailPage/ProductDetail.tsx @@ -24,7 +24,7 @@ const ProductDetail: React.FC = () => { const { quantity, setQuantity } = useQuantity(); const [remainingTime, setRemainingTime] = useState(''); const navigate = useNavigate(); - const isOutOfStock = product ? product.now >= product.currentStock : false; + const isOutOfStock = product ? product.currentStock < 0 : false; const isDeadlinePassed = remainingTime === '마감되었습니다.'; const isButtonDisabled = isOutOfStock || isDeadlinePassed; useEffect(() => { @@ -209,7 +209,7 @@ const Stars = styled.div` position: absolute; font-size: 20px; color: #ffaa00; - bottom: 80px; + bottom: 13%; right: 2%; @media (min-width: 768px) and (max-width: 1024px) { diff --git a/src/components/pages/ProductPage/ProductComponent.tsx b/src/components/pages/ProductPage/ProductComponent.tsx index 956292a..85ba5b6 100644 --- a/src/components/pages/ProductPage/ProductComponent.tsx +++ b/src/components/pages/ProductPage/ProductComponent.tsx @@ -27,7 +27,7 @@ const ProductComponent: React.FC = ({ const filteredProducts = selectedText === '마감 상품' ? products.filter( - (p) => p.available === false && new Date(p.deadline) < new Date() + (p) => p.available === false || new Date(p.deadline) < new Date() ) : products.filter( (p) => p.available === true && new Date(p.deadline) > new Date() diff --git a/src/components/pages/login/FindPasswordPage.tsx b/src/components/pages/login/FindPasswordPage.tsx index db21f40..9706098 100644 --- a/src/components/pages/login/FindPasswordPage.tsx +++ b/src/components/pages/login/FindPasswordPage.tsx @@ -18,7 +18,7 @@ const FindPasswordPage = () => { style={{ width: '100%', height: '100%', - objectFit: 'contain', + objectFit: 'cover', }} /> diff --git a/src/components/pages/login/LoginCompletePage.tsx b/src/components/pages/login/LoginCompletePage.tsx index cd784ba..e3a7960 100644 --- a/src/components/pages/login/LoginCompletePage.tsx +++ b/src/components/pages/login/LoginCompletePage.tsx @@ -14,7 +14,7 @@ const LoginCompletePage = () => { style={{ width: '100%', height: '100%', - objectFit: 'contain', + objectFit: 'cover', }} /> diff --git a/src/components/pages/login/ResetPasswordPage.tsx b/src/components/pages/login/ResetPasswordPage.tsx index b6b9ec5..8a0b99f 100644 --- a/src/components/pages/login/ResetPasswordPage.tsx +++ b/src/components/pages/login/ResetPasswordPage.tsx @@ -31,7 +31,7 @@ const ResetPasswordPage = () => { style={{ width: '100%', height: '100%', - objectFit: 'contain', + objectFit: 'cover', }} /> diff --git a/src/components/pages/login/SetLocationPage.tsx b/src/components/pages/login/SetLocationPage.tsx index 2f1df7f..a485a37 100644 --- a/src/components/pages/login/SetLocationPage.tsx +++ b/src/components/pages/login/SetLocationPage.tsx @@ -29,8 +29,10 @@ function SetLocationPage() { // eslint-disable-next-line @typescript-eslint/no-explicit-any (result: any, status: any) => { if (status === window.kakao.maps.services.Status.OK) { - const primaryRegion = result[0]?.region_3depth_name || ''; - setRegion(primaryRegion); + const fullRegion = `${result[0]?.region_1depth_name || ''} ${ + result[0]?.region_2depth_name || '' + } ${result[0]?.region_3depth_name || ''}`; + setRegion(fullRegion); setCalled(true); } else { console.error('주소를 가져오지 못했습니다.'); diff --git a/src/components/pages/login/SetNicknamePage.tsx b/src/components/pages/login/SetNicknamePage.tsx index 69cba2b..25f384f 100644 --- a/src/components/pages/login/SetNicknamePage.tsx +++ b/src/components/pages/login/SetNicknamePage.tsx @@ -1,3 +1,4 @@ +import axios from 'axios'; import React, { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { styled } from 'styled-components'; @@ -29,7 +30,7 @@ const SetNicknamePage = () => { style={{ width: '100%', height: '100%', - objectFit: 'contain', + objectFit: 'cover', }} /> @@ -53,14 +54,27 @@ const SetNicknamePage = () => { { if (isValidLength && isValidFormat) { - const response = await postSignUpNickname({ nickname: nickname }); + try { + const response = await postSignUpNickname({ + nickname: nickname, + }); - if (response.message === '닉네임 중복 확인 완료') { - localStorage.setItem('nickname', nickname); + if (response.message === '닉네임 중복 확인 완료') { + localStorage.setItem('nickname', nickname); - navigate('/setprofile'); - } else { - alert('닉네임이 중복입니다.'); + navigate('/setprofile'); + } else { + alert('닉네임이 중복입니다.'); + } + } catch (err) { + if ( + axios.isAxiosError(err) && + err.response && + err.response.data && + err.response.data.error + ) { + alert(err.response.data.error); + } } } else { alert('닉네임 조건을 만족시켜 주세요.'); diff --git a/src/components/pages/login/SetProfilePage.tsx b/src/components/pages/login/SetProfilePage.tsx index 76bedb9..ffb9e68 100644 --- a/src/components/pages/login/SetProfilePage.tsx +++ b/src/components/pages/login/SetProfilePage.tsx @@ -29,7 +29,7 @@ const SetProfilePage = () => { style={{ width: '100%', height: '100%', - objectFit: 'contain', + objectFit: 'cover', }} /> diff --git a/src/components/pages/login/SignInPage.tsx b/src/components/pages/login/SignInPage.tsx index 92c8426..c26d690 100644 --- a/src/components/pages/login/SignInPage.tsx +++ b/src/components/pages/login/SignInPage.tsx @@ -1,14 +1,25 @@ -import React, { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; +import React, { useEffect, useState } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; import { styled } from 'styled-components'; import { postSignIn } from '../../../api/loginApi'; import { useAuth } from '../../../context/AuthContext'; const SignInPage = () => { const navigate = useNavigate(); + const location = useLocation(); const [email, setEmail] = useState(''); const [pw, setPw] = useState(''); const { login } = useAuth(); + + useEffect(() => { + const searchParams = new URLSearchParams(location.search); + const accessToken = searchParams.get('accessToken'); + if (accessToken) { + localStorage.setItem('token', accessToken); + navigate('/'); + } + }, [location, navigate]); + return ( diff --git a/src/components/pages/login/SignUpPage.tsx b/src/components/pages/login/SignUpPage.tsx index 001b500..81d8a5e 100644 --- a/src/components/pages/login/SignUpPage.tsx +++ b/src/components/pages/login/SignUpPage.tsx @@ -1,3 +1,4 @@ +import axios from 'axios'; import React, { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { styled } from 'styled-components'; @@ -20,7 +21,7 @@ function SignUpPage() { style={{ width: '100%', height: '100%', - objectFit: 'contain', + objectFit: 'cover', }} /> @@ -71,24 +72,35 @@ function SignUpPage() { if (pw !== cpw) { alert('비밀번호가 일치하지 않습니다.'); } else { - const response = await postSignUp({ - email: email, - password: pw, - password_confirm: cpw, - name: name, - phone: phone, - }); + try { + const response = await postSignUp({ + email: email, + password: pw, + password_confirm: cpw, + name: name, + phone: phone, + }); - if (response.message === '이메일, 전화번호 중복 확인 완료') { - localStorage.setItem('email', email); - localStorage.setItem('password', pw); - localStorage.setItem('password_confirm', cpw); - localStorage.setItem('name', name); - localStorage.setItem('phone', phone); + if (response.message === '이메일, 전화번호 중복 확인 완료') { + localStorage.setItem('email', email); + localStorage.setItem('password', pw); + localStorage.setItem('password_confirm', cpw); + localStorage.setItem('name', name); + localStorage.setItem('phone', phone); - navigate('/termsandservice'); - } else { - alert('이메일 또는 전화번호가 중복 되었습니다.'); + navigate('/termsandservice'); + } else { + alert('이메일 또는 전화번호가 중복 되었습니다.'); + } + } catch (err) { + if ( + axios.isAxiosError(err) && + err.response && + err.response.data && + err.response.data.error + ) { + alert(err.response.data.error); + } } } }} diff --git a/src/components/pages/login/TermsPage.tsx b/src/components/pages/login/TermsPage.tsx index 11429d4..89a7d86 100644 --- a/src/components/pages/login/TermsPage.tsx +++ b/src/components/pages/login/TermsPage.tsx @@ -73,7 +73,7 @@ const TermsPage = () => { style={{ width: '100%', height: '100%', - objectFit: 'contain', + objectFit: 'cover', }} /> diff --git a/src/components/pages/myPage/LocationPage.tsx b/src/components/pages/myPage/LocationPage.tsx index 822ad11..07eb974 100644 --- a/src/components/pages/myPage/LocationPage.tsx +++ b/src/components/pages/myPage/LocationPage.tsx @@ -29,8 +29,10 @@ function LocationPage() { // eslint-disable-next-line @typescript-eslint/no-explicit-any (result: any, status: any) => { if (status === window.kakao.maps.services.Status.OK) { - const primaryRegion = result[0]?.region_3depth_name || ''; - setRegion(primaryRegion); + const fullRegion = `${result[0]?.region_1depth_name || ''} ${ + result[0]?.region_2depth_name || '' + } ${result[0]?.region_3depth_name || ''}`; + setRegion(fullRegion); setCalled(true); } else { console.error('주소를 가져오지 못했습니다.'); diff --git a/src/components/pages/myPage/OrderListComponents/OrderHistory.tsx b/src/components/pages/myPage/OrderListComponents/OrderHistory.tsx index 119ab66..0b55586 100644 --- a/src/components/pages/myPage/OrderListComponents/OrderHistory.tsx +++ b/src/components/pages/myPage/OrderListComponents/OrderHistory.tsx @@ -36,7 +36,7 @@ const OrderHistory = () => { return '결제 완료'; case 'FAILED': return '결제 실패'; - case 'CANCELD': + case 'CANCELED': return '결제 취소'; case 'PARTIAL_CANCELED': return '부분 취소'; @@ -78,18 +78,24 @@ const OrderHistory = () => { > 상품 페이지 이동 - { - handleCancelClick(); - if (order.payment_key) { - setPk(order.payment_key); - } - }} - > - 주문 취소/환불 - {order.paymentStatus === 'DONE' && ( - + { + handleCancelClick(); + if (order.payment_key) { + setPk(order.payment_key); + } + }} + > + 주문 취소/환불 + + )} + {order.paymentStatus === 'DONE' && ( + { + navigate(`/products/${order.postId}`); + }} + > 리뷰 작성하기 diff --git a/src/components/pages/myPage/OrderListComponents/RefundHistory.tsx b/src/components/pages/myPage/OrderListComponents/RefundHistory.tsx index 1f6de75..3273868 100644 --- a/src/components/pages/myPage/OrderListComponents/RefundHistory.tsx +++ b/src/components/pages/myPage/OrderListComponents/RefundHistory.tsx @@ -1,37 +1,46 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; import styled from 'styled-components'; -import { getRefundList } from '../../../../api/mypageApi'; -import { refundHistoryData } from '../mockData'; +import { getRefundList, RefundType } from '../../../../api/mypageApi'; const RefundHistory = () => { + const [refundList, setRefundList] = useState([]); + const navigate = useNavigate(); + useEffect(() => { const fetchOrderList = async () => { const response = await getRefundList(); - console.log(response); + setRefundList(response); }; fetchOrderList(); }, []); return ( - {refundHistoryData.map((refund) => ( - + {refundList.map((refund, idx) => ( + - {refund.name} + {refund.productName} Quantity: {refund.quantity} - - {refund.status} + + {refund.paymentStatus === 'CANCELED' ? '취소' : '대기 중'} - {refund.price} + {refund.price}원 - 상품 페이지 이동 + { + navigate(`/products/${refund.postId}`); + }} + > + 상품 페이지 이동 + ))} diff --git a/src/components/pages/myPage/SettingPage.tsx b/src/components/pages/myPage/SettingPage.tsx index 5acc8c1..b95a061 100644 --- a/src/components/pages/myPage/SettingPage.tsx +++ b/src/components/pages/myPage/SettingPage.tsx @@ -7,7 +7,11 @@ import PasswordModal from './Modal/PasswordModal'; import LogoutModal from './Modal/LogoutModal'; import WithdrawModal from './Modal/WithdrawModal'; import { useDaumPostcodePopup } from 'react-daum-postcode'; -import { getUser, putEditProfile } from '../../../api/mypageApi'; +import { + getUser, + putChangeNickname, + putEditProfile, +} from '../../../api/mypageApi'; const SettingPage = () => { const [addressList, setAddressList] = useState(SettingPageData.addressList); @@ -21,6 +25,7 @@ const SettingPage = () => { const [phoneLast, setPhoneLast] = useState(''); const [isAddingNewAddress, setIsAddingNewAddress] = useState(false); const [profileImage, setProfileImage] = useState(null); + const [nickname, setNickname] = useState(''); const postcodeScriptUrl = 'https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js'; @@ -127,8 +132,21 @@ const SettingPage = () => { 닉네임 변경 - - 변경하기 + ) => { + setNickname(e.target.value); + }} + placeholder="최소 2자 이상 ~ 15자 이내, 띄어쓰기 및 특수문자 사용 불가" + /> + { + await putChangeNickname(nickname); + setNickname(''); + }} + > + 변경하기 + 배송지 주소 변경