Skip to content

Commit

Permalink
🔀merge: merge dev to main
Browse files Browse the repository at this point in the history
merge dev to main
  • Loading branch information
Ryomi-j authored Jul 5, 2023
2 parents b4070cc + 693be7c commit 4e89048
Show file tree
Hide file tree
Showing 21 changed files with 468 additions and 366 deletions.
4 changes: 4 additions & 0 deletions src/components/accommodationDetail/AccommodationInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { IAccommodationDetailResponse } from '../../api/accommodationDetail';
import RatingStars from '../../components/common/RatingStars';

/**
* @param accommodationData: IAccommodationDetailResponse
**/

export const AccommodationInfo = ({
accommodationData
}: {
Expand Down
8 changes: 7 additions & 1 deletion src/components/accommodationDetail/ConfirmModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ interface IConfirmModal {
setModalState: React.Dispatch<React.SetStateAction<boolean>>;
}

/**
* @param data IReservationConfirm;
* @param modalState boolean;
* @param setModalState React.Dispatch<React.SetStateAction<boolean>>;
*/

export const ConfirmModal = ({
data,
modalState,
Expand Down Expand Up @@ -64,7 +70,7 @@ export const ConfirmModal = ({
<div>
<p>
<span className="font-semibold">체크인: </span>
{data.checkOutDate}
{data.checkInDate}
</p>
<p>
<span className="font-semibold">체크아웃</span>:{' '}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
import 'react-responsive-carousel/lib/styles/carousel.min.css';
import { Carousel } from 'react-responsive-carousel';
import './CarouselModal.css';
import './ImageCarouselModal.css';
import { IPicUrlList } from 'api/accommodationDetail';

export interface IModalProps {
export interface IImageCarouselModal {
imgList: IPicUrlList[];
alt: string;
selectedImg: number
selectedImg: number;
}

export const CarouselModal: React.FC<IModalProps> = ({ imgList, alt, selectedImg }) => {
/**
* @param imgList: IPicUrlList[];
* @param alt: string;
* @param selectedImg: number
*/

export const ImageCarouselModal: React.FC<IImageCarouselModal> = ({
imgList,
alt,
selectedImg
}) => {
return (
<>
<input type="checkbox" id="reservationModal" className="modal-toggle" />
<div className="modal">
<div className="modal-box w-11/12 max-w-4xl">
<Carousel selectedItem={selectedImg} showThumbs={imgList.length === 1 ? false : true}>
<Carousel
selectedItem={selectedImg}
showThumbs={imgList.length === 1 ? false : true}
>
{imgList.map((el, idx) => {
return (
<figure key={idx}>
Expand Down
75 changes: 43 additions & 32 deletions src/components/accommodationDetail/Review.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ import { fetchData } from '../../api';
interface IReview {
id: string;
accommodationData: IAccommodationDetailResponse;
setPage: React.Dispatch<React.SetStateAction<number>>;
page: number;
}
/**
* @param id accommodation Id(string),
* @param accommodationData IAccommodationDetailResponse:
*/

export const Review = ({ id, accommodationData }: IReview) => {
const [page, setPage] = useState(0);
const PageSize = 20;

export const Review = ({ id, accommodationData, page, setPage }: IReview) => {
const rateAdj = [
'Terrible',
'Poor',
Expand All @@ -27,6 +32,7 @@ export const Review = ({ id, accommodationData, page, setPage }: IReview) => {
'Outstanding',
'Perfect'
];

const [reviewRes, setReviewRes] = useState<IReviewResponse>({
content: [],
totalElements: 0,
Expand All @@ -36,26 +42,30 @@ export const Review = ({ id, accommodationData, page, setPage }: IReview) => {

const getReview = async (page: number) => {
fetchData
.get(`/accommodation/${id}/review?page=${page}&pagesize=5`)
.then((reviewRes: any) => {
.get(`/accommodation/${id}/review?page=${page}&pagesize=${PageSize}`)
.then((res: any) => {
setReviewRes({
content: reviewRes.data.data.content,
totalElements: reviewRes.data.totalElements || 0,
totalPages: reviewRes.data.totalPages || 0
content: res.data.data.content,
totalElements: res.data.data.totalElements,
totalPages: res.data.data.totalPages
});
setReviewArr((prev) => {
const newReviewArr: IReviewContent[] = [...prev];
newReviewArr[page] = reviewRes.data.data.content;
newReviewArr.push(res.data.data.content);
return newReviewArr;
});
});
})
.catch(() => []);
};

const handleReviewPageButton = (page: number) => {
setPage(page);
if (!reviewArr[page]) getReview(page);
};

useEffect(() => {
(async () => {
if (!reviewArr[page]) getReview(page);
})();
}, [page]);
getReview(page);
}, []);

return (
<>
Expand Down Expand Up @@ -84,34 +94,35 @@ export const Review = ({ id, accommodationData, page, setPage }: IReview) => {
</div>
<div className="divider" />
<div>
{Object.values(reviewArr[page]).map((el, idx) => {
return (
<div
key={idx}
className="flex flex-col gap-3 p-3 border rounded-lg mb-5 text-xs md:text-base"
>
<p className="font-semibold">{el.nickName}</p>
<div className="flex flex-col sm:flex-row gap-4 text-xs md:text-base font-medium">
<div className="flex items-center gap-2 font-semibold">
평점 : <RatingStars rate={el.rating} />
{reviewArr[page] &&
Object.values(reviewArr[page]).map((el, idx) => {
return (
<div
key={idx}
className="flex flex-col gap-3 p-3 border rounded-lg mb-5 text-xs md:text-base"
>
<p className="font-semibold">{el.nickName}</p>
<div className="flex flex-col sm:flex-row gap-4 text-xs md:text-base font-medium">
<div className="flex items-center gap-2 font-semibold">
평점 : <RatingStars rate={el.rating} />
</div>
</div>
<p> {el.description}</p>
</div>
<p> {el.description}</p>
</div>
);
})}
<div className="flex justify-center">
{reviewRes &&
);
})}
<div className="flex justify-center items-center">
{reviewRes.totalPages > 0 &&
new Array(reviewRes.totalPages).fill(0).map((_, idx) => {
return (
<div key={idx} className="join">
<input
aria-label={(idx + 1).toString()}
className="join-item btn btn-square btn-ghost btn-sm mr-1 checked:bg-red-500 checked:text-white border-none important"
className="join-item btn btn-square rounded-md btn-sm mr-1 checked:bg-red-500 checked:text-white border-none important"
type="radio"
name="options"
checked={page === idx}
onChange={() => setPage(idx)}
onChange={() => handleReviewPageButton(idx)}
/>
</div>
);
Expand Down
32 changes: 24 additions & 8 deletions src/components/accommodationDetail/RoomInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,25 @@ import { IReservationConfirm, IRoomResponse } from 'api/accommodationDetail';
import { addCommasToPrice } from '../../helpers';
import { ConfirmModal } from './ConfirmModal';
import { useEffect, useState } from 'react';
import { IModalProps } from './CarouselModal';
import { IImageCarouselModal } from './ImageCarouselModal';
import { useRecoilState } from 'recoil';
import { selectedRoom } from '../../store/atom/comparisonAtom';
import { AlertModal } from '../../components/common/AlertModal';
import { IComparisonBoxProps } from 'components/floatingIcons/comparison/types';
import { getQueryStrData } from '../../utils/handleQueryString';

interface IRoomInfo {
roomInfo: IRoomResponse[];
setModalProps: React.Dispatch<React.SetStateAction<IModalProps>>;
setModalProps: React.Dispatch<React.SetStateAction<IImageCarouselModal>>;
setRoomData: React.Dispatch<React.SetStateAction<IReservationConfirm>>;
roomData: IReservationConfirm;
}
/**
* @param roomInfo: IRoomResponse[];
* @param setModalProps: React.Dispatch<React.SetStateAction<IImageCarouselModal>>;
* @param setRoomData: React.Dispatch<React.SetStateAction<IReservationConfirm>>;
* @param roomData: IReservationConfirm;
*/

export const RoomInfo = ({
roomInfo,
Expand All @@ -22,11 +29,15 @@ export const RoomInfo = ({
roomData
}: IRoomInfo) => {
const [modalContent, setModalContent] = useState('');
const [modalState, setModalState] = useState(false);
const [confirmModalState, setConfirmModalState] = useState(false); // 예약 실행 여부를 확인하는 모달
const [alertModalState, setAlertModalState] = useState(false);
const [selectedRooms, setSelectedRooms] =
useRecoilState<IComparisonBoxProps[]>(selectedRoom);

const { accommodationId, checkInDate, checkOutDate, people } =
getQueryStrData();

// 비교함에 상품을 추가하는 함수
const addRoomComparisonCart = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
item: IRoomResponse
Expand All @@ -39,16 +50,20 @@ export const RoomInfo = ({
} else {
const comparisonData = {
accommodationName: roomData.accommodationName,
accommodationId: roomData.accommodationId,
accommodationId: accommodationId,
roomId: item.id,
checkInDate: checkInDate,
checkOutDate: checkOutDate,
price: item.price,
imgUrl: item.pictureUrlList[0].url
imgUrl: item.pictureUrlList[0].url,
people: people
};

setSelectedRooms((prev) => [...prev, comparisonData]);
}
};

// 4개 이상의 상품이 담기면 alert 모달의 띄움
useEffect(() => {
if (selectedRooms.length > 3) {
setSelectedRooms(selectedRooms.slice(0, 3));
Expand Down Expand Up @@ -110,6 +125,7 @@ export const RoomInfo = ({
</div>
<div className="flex flex-row sm:w-1/3 justify-center">
<div className="flex sm:flex-col gap-3 my-auto items-center">
{/* 가격 버튼을 클릭하면 사용자가 예약을 정말 실행할지 확인하기 위해 ConfirmModal이 띄워짐 */}
<button
className="flex gap-2 btn btn-sm font-semibold w-fit sm:w-full min-w-[80px] md:min-w-[100px] md:btn-md md:text-base bg-red-500 disabled:bg-base-300 hover:bg-red-600 text-white"
onClick={() => {
Expand All @@ -120,7 +136,7 @@ export const RoomInfo = ({
imgUrl: el.pictureUrlList[0].url,
price: el.price.toString()
}));
setModalState(true);
setConfirmModalState(true);
}}
disabled={el.price === null}
>
Expand All @@ -136,8 +152,8 @@ export const RoomInfo = ({
</button>
<ConfirmModal
data={roomData}
modalState={modalState}
setModalState={setModalState}
modalState={confirmModalState}
setModalState={setConfirmModalState}
/>
</div>
</div>
Expand Down
17 changes: 11 additions & 6 deletions src/components/floatingIcons/FloatingIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,23 @@ import { useClickOutside } from '../../hooks/useClickOutside';
export const FloatingIcon = () => {
const selectedAcc = useRecoilValue(selectedAccommodation);
const selectedRooms = useRecoilValue(selectedRoom);

const [comparisonState, setComparisonState] = useState(false);
const [source, setSource] = useState('');

const floatingIconsRef = useRef<HTMLDivElement>(null)
const floatingIconsRef = useRef<HTMLDivElement>(null);

const handleOutsideClick = () => {
setComparisonState(false)
}
setComparisonState(false);
};

useClickOutside(floatingIconsRef, handleOutsideClick);

useClickOutside(floatingIconsRef, handleOutsideClick)
return (
<div ref={floatingIconsRef} className="fixed bottom-[5%] flex flex-col gap-1 md:gap-5 right-1 sm:right-5 md:right-10 z-20">
<div
ref={floatingIconsRef}
className="fixed bottom-[5%] flex flex-col gap-1 md:gap-5 right-1 sm:right-5 md:right-10 z-20"
>
<div className="indicator">
<span className="indicator-item badge bg-red-500 text-white w-4 h-4 md:w-6 md:h-6 right-2 top-3 text-[10px] md:text-base border-none">
{selectedRooms.length}
Expand Down Expand Up @@ -51,7 +56,7 @@ export const FloatingIcon = () => {
onClick={() => {
if (source === 'accommodation') {
setComparisonState(false);
setSource('')
setSource('');
} else {
setComparisonState(true);
setSource('accommodation');
Expand Down
Loading

0 comments on commit 4e89048

Please sign in to comment.