Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
"format": "prettier --write ."
},
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@mui/material": "^5.15.2",
"@react-google-maps/api": "^2.19.2",
"@tanstack/react-query": "^5.8.7",
"@tanstack/react-query-devtools": "^5.8.7",
Expand Down
47 changes: 39 additions & 8 deletions src/components/template/mypage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,49 @@ import ReservationList from './reservationList';
import { ErrorBoundary } from 'react-error-boundary';
import { useQueryErrorResetBoundary } from '@tanstack/react-query';
import { Error } from './error';
// import WishList from './wishList';
import ReviewList from './reviewList';
import { Suspense, useState } from 'react';
import WishList from './wishList';
import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
import Box from '@mui/material/Box';

const MypageContainer = () => {
const { reset } = useQueryErrorResetBoundary();

const [activeTab, setActiveTab] = useState(0);

const handleTabChange = (_event: React.ChangeEvent<{}>, newValue: number) => {
setActiveTab(newValue);
};

return (
<>
<ErrorBoundary FallbackComponent={Error} onError={reset}>
<StyledTitle>마이페이지</StyledTitle>
<ReservationList />
{/* <WishList /> */}
</ErrorBoundary>
</>
<ErrorBoundary FallbackComponent={Error} onError={reset}>
<Suspense>
<StyledTitle $mt="1.5rem">마이페이지</StyledTitle>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<Tabs
value={activeTab}
onChange={handleTabChange}
variant="fullWidth"
sx={{
'.MuiTabs-indicator': {
backgroundColor: '#de2f5f', // 인디케이터 색상 변경
},
'.Mui-selected': {
color: '#de2f5f !important', // 활성화된 탭의 텍스트 색상
},
}}>
<Tab label="예약내역" style={{ fontSize: '1.2rem' }} />
<Tab label="리뷰" style={{ fontSize: '1.2rem' }} />
<Tab label="찜리스트" style={{ fontSize: '1.2rem' }} />
</Tabs>
</Box>
{activeTab === 0 && <ReservationList />}
{activeTab === 1 && <ReviewList />}
{activeTab === 2 && <WishList />}
</Suspense>
</ErrorBoundary>
);
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/template/mypage/reservationCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const ReservationCard: React.FC<ReservationCardProps> = ({ data }) => {

export default ReservationCard;

const StyledReservationContainer = styled(StyledFlexContainer)`
export const StyledReservationContainer = styled(StyledFlexContainer)`
&:hover {
background-color: #eeeeee;
}
Expand Down
12 changes: 6 additions & 6 deletions src/components/template/mypage/reservationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const ReservationList = () => {
<StyledSubTitle
$mt="2rem"
style={{ paddingInline: '5rem', fontSize: '1.2rem' }}>
예약내역
총 {reservationData?.length}건의 예약내역
</StyledSubTitle>
<StyledWrapper
style={{
Expand Down Expand Up @@ -90,13 +90,13 @@ const ReservationList = () => {

export default ReservationList;

const PaginationContainer = styled.div`
export const PaginationContainer = styled.div`
display: flex;
justify-content: center;
padding: 1rem;
`;

const PageButton = styled.button`
export const PageButton = styled.button`
border: none;
background-color: #f0f0f0;
margin: 0 5px;
Expand All @@ -115,17 +115,17 @@ const PageButton = styled.button`
}
`;

const fadeIn = keyframes`
export const fadeIn = keyframes`
from { opacity: 0; }
to { opacity: 1; }
`;

const fadeOut = keyframes`
export const fadeOut = keyframes`
from { opacity: 1; }
to { opacity: 0; }
`;

const StyledReservationList = styled.div.withConfig({
export const StyledReservationList = styled.div.withConfig({
shouldForwardProp: (prop) => !['isFadingOut'].includes(prop),
})<StyledReservationListProps>`
animation: ${(props) => (props.isFadingOut ? fadeOut : fadeIn)} 300ms
Expand Down
144 changes: 144 additions & 0 deletions src/components/template/mypage/reviewList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import {
StyledWrap,
StyledH2Text,
StyledTextBox,
StyledBold,
} from '@/style/products/productsStyle';
import {
StyledFlexContainer,
StyledImageContainer,
StyledText,
StyledTitle,
StyledSubTitle,
StyledWrapper,
} from '@/style/payment/paymentStyle';
import { ProductReviewResponse } from '@/interfaces/interface';
import { reviewStar } from '@/util/reviewUtilities';
import {
StyleReviewContainer,
StyleReviewItem,
StyledStar,
} from '@/style/products/reviewStyle';
import { useState } from 'react';
import {
PaginationContainer,
PageButton,
StyledReservationList,
} from './reservationList';

import { useGetReview } from '@/hooks/useGetReview';

const itemsPerPage = 5;

const ReviewList = () => {
const data = useGetReview();
const reviews = data?.content || [];
const totalElements = data?.totalElements || 0;
console.log(data);

const [currentPage, setCurrentPage] = useState(1);
const [isFadingOut, setIsFadingOut] = useState(false);

const indexOfLastItem = currentPage * itemsPerPage;
const indexOfFirstItem = indexOfLastItem - itemsPerPage;
const currentItems = reviews.slice(indexOfFirstItem, indexOfLastItem);

const pageNumbers = [];
for (let i = 1; i <= Math.ceil(reviews.length / itemsPerPage); i++) {
pageNumbers.push(i);
}

const handlerPageChange = (pageNumber: number) => {
setIsFadingOut(true);
setTimeout(() => {
setCurrentPage(pageNumber);
setIsFadingOut(false);
}, 300);
};

const noReviewMessage = ` 에 대한 리뷰가 없습니다. 방문 후 리뷰를 남겨주세요 😊`;

return (
<>
{/* <StyledFlexContainer>
<StyledTextBox>
<select value={sort} onChange={handleSortChange}>
<option value="reviewDate,DESC">최신순</option>
<option value="reviewDate,ASC">오래된순</option>
<option value="score,DESC">평점 높은순</option>
<option value="score,ASC">평점 낮은순</option>
</select>
</StyledTextBox>
</StyledFlexContainer> */}
<StyledSubTitle
$mt="2rem"
style={{ paddingInline: '5rem', fontSize: '1.2rem' }}>
총 {data?.numberOfElements}개의 리뷰
</StyledSubTitle>
<StyledWrapper
style={{
paddingInline: '5rem',
fontFamily:
'Pretendard, system-ui, Avenir, Helvetica, Arial, sans-serif',
overflowY: 'auto',
height: '60vh',
}}>
<StyledReservationList isFadingOut={isFadingOut}>
{totalElements > 0 ? (
currentItems.map((review) => (
<StyleReviewItem
$mt="0"
$mb="1rem"
key={review.reviewId}
style={{ display: 'flex' }}>
<StyledImageContainer $w="auto" style={{ overflow: 'unset' }}>
<img
src={`${review.productDetails.productImage}`}
style={{
width: '124px',
height: '100%',
objectFit: 'cover',
borderRadius: '0.5rem',
}}
/>
</StyledImageContainer>
<StyledFlexContainer
style={{ width: '100%', height: '100%' }}
$flexDirection="column"
$alignItems="flex-start">
<StyledTitle $mt="0" $mb="0">
{`${review.accommodationDetails.accommodationName}`}
</StyledTitle>
<StyledSubTitle>
{`${review.productDetails.productName}`}
</StyledSubTitle>
<div style={{ display: 'flex' }}>
<StyledStar>{reviewStar(review.score)}</StyledStar>
{review.reviewDate}
{review.content}
</div>
</StyledFlexContainer>
</StyleReviewItem>
))
) : (
<StyleReviewItem $mt="0" $mb="0" $padding="1.2rem 1rem">
{noReviewMessage}
</StyleReviewItem>
)}
</StyledReservationList>
<PaginationContainer>
{pageNumbers.map((number) => (
<PageButton
key={number}
className={number === currentPage ? 'active' : ''}
onClick={() => handlerPageChange(number)}>
{number}
</PageButton>
))}
</PaginationContainer>
</StyledWrapper>
</>
);
};

export default ReviewList;
27 changes: 6 additions & 21 deletions src/components/template/mypage/reviewWriteModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,11 @@ import { StyledButton } from '@/style/payment/paymentStyle';
import { StyledTitle, StyledFlexContainer } from '@/style/payment/paymentStyle';
import { FaStar } from 'react-icons/fa';
import { useState, useEffect, useRef } from 'react';
import {
postReviews,
getReviews,
putReviews,
deleteReviews,
} from '@/api/service';
import {
useSuspenseQuery,
useQueryClient,
useMutation,
} from '@tanstack/react-query';
import { postReviews, putReviews, deleteReviews } from '@/api/service';
import { useQueryClient, useMutation } from '@tanstack/react-query';
import { AxiosResponse, AxiosError } from 'axios';
import { findMyReview } from '@/util/util';
import { useGetReview } from '@/hooks/useGetReview';

const ReviewWriteModal = ({
setShowModal,
Expand All @@ -34,18 +26,11 @@ const ReviewWriteModal = ({
const [score, setScore] = useState(0);
const [hover, setHover] = useState(0);

const { data } = useSuspenseQuery({
queryKey: ['accommodation'],
queryFn: () => getReviews(),
staleTime: 60000,
});
const data = useGetReview();

useEffect(() => {
if (data?.data && orderDetailData?.orderItemId) {
const myReview = findMyReview(
data.data.content,
orderDetailData.orderItemId,
);
if (data && orderDetailData?.orderItemId) {
const myReview = findMyReview(data.content, orderDetailData.orderItemId);
if (myReview && reviewTextRef.current) {
reviewTextRef.current.value = myReview.content;
setScore(myReview.score);
Expand Down
12 changes: 12 additions & 0 deletions src/hooks/useGetReview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useSuspenseQuery } from '@tanstack/react-query';
import { getReviews } from '@/api/service';

export const useGetReview = () => {
const { data } = useSuspenseQuery({
queryKey: ['accommodation'],
queryFn: () => getReviews(),
staleTime: 60000,
});

return data.data;
};
Loading