Skip to content

Commit

Permalink
Feat: TripAccommodation 페이지 - 1차 기능 구현 완료
Browse files Browse the repository at this point in the history
- LocalItem: Tour API Read 데이터(위치기반 숙소정보)
- SelectItem: 선택된 숙소 정보
- 그 외 AccommodationStore 내 selectedAccommodation(선택된 숙소 정보 storage) 이용한 정보 렌더링

Related to WeonTrip-WonT#55
  • Loading branch information
uniS2 committed Mar 8, 2024
1 parent fa82f6b commit 8100e01
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 30 deletions.
46 changes: 34 additions & 12 deletions src/components/common/DefaultImage.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
import Image from "next/image";

type DefaultImageProps = {
size?: string;
width?: string;
heigth?: string;
title?: string;
src?: string;
};

const DefaultImage = ({ size }: DefaultImageProps) => {
return (
<div
className={`flex justify-center align-middle w-[${size}] h-[${size}] rounded-[0.625rem] bg-[#EFF2F6]roun`}
>
const DefaultImage = ({
width = "w-14",
heigth = "h-14",
title,
src,
}: DefaultImageProps) => {
if (src) {
return (
<Image
src="svg/default-image.svg"
alt="기본 이미지"
width={10}
height={10}
src={src}
alt={title!}
width="700"
height="425"
className="w-14 h-14 object-cover rounded-xl group-hover:sm:w-40 group-hover:sm:h-40"
//TODO@uniS2: 모바일 touch 처리 예정
// https://ykwan0714.github.io/%ED%84%B0%EC%B9%98-%EB%94%94%EB%B0%94%EC%9D%B4%EC%8A%A4-%EB%AA%A8%EB%B0%94%EC%9D%BC%EC%97%90%EC%84%9C-hover-%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B8%B0/
/>
</div>
);
);
} else {
return (
<div
className={`flex justify-center align-middle min-w-14 ${width} ${heigth} rounded-xl bg-[#EFF2F6]`}
>
<Image
src="svg/default-image.svg"
alt="기본 이미지"
width={10}
height={10}
/>
</div>
);
}
};

export default DefaultImage;
57 changes: 57 additions & 0 deletions src/components/tripselect/LocalItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { BsFillPlusCircleFill } from "react-icons/bs";
import { FaCheckCircle } from "react-icons/fa";
import DefaultImage from "@/components/common/DefaultImage";
import { AccommodationStore } from "@/store/AccommodationStore";

type LocalItemProps = {
id: number;
title: string;
addr: string;
imgSrc: string;
};

const LocalItem = ({ id, title, addr, imgSrc }: LocalItemProps) => {
const { selectedAccommodation, setToggleAccommodation } =
AccommodationStore();
const isSelected = Boolean(
selectedAccommodation?.filter(
(accommodation) => accommodation.contentid == id,
).length,
);

return (
<li className="group flex gap-3 p-3 items-center w-full bg-white rounded-xl">
<DefaultImage src={imgSrc} />
<div className="w-full">
<p className="text-sm group-hover:sm:text-base group-hover:sm:font-semibold text-contentSecondary">
{title || "장소 이름이 정확하지 않습니다."}
</p>
<p className="text-xs group-hover:sm:text-sm text-point">
{addr || "주소가 정확하지 않습니다."}
</p>
</div>
<button
type="button"
onClick={() => {
setToggleAccommodation(id);
}}
>
{isSelected ? (
<FaCheckCircle
size="1.5625rem"
color="#63D4F2"
title="장소 선택 취소하기"
/>
) : (
<BsFillPlusCircleFill
size="1.5625rem"
color="#777777"
title="장소 선택하기"
/>
)}
</button>
</li>
);
};

export default LocalItem;
7 changes: 6 additions & 1 deletion src/components/tripselect/SelectDaysInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { AccommodationStore } from "@/store/AccommodationStore";

const SelectDaysInfo = () => {
const { selectedAccommodation } = AccommodationStore();
const totalNumber = selectedAccommodation ? selectedAccommodation.length : 0;

return (
<div className="flex gap-[0.625rem] items-end">
<span className="text-2xl text-content font-bold">0</span>
<span className="text-2xl text-content font-bold">{totalNumber}</span>
<div className="flex gap-[0.125rem] min-w-fit text-sm">
<span className="font-medium text-[#2966E3]">n일</span>
<span aria-hidden>/</span>
Expand Down
28 changes: 18 additions & 10 deletions src/components/tripselect/SelectItem.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
import DefaultImage from "@/components/common/DefaultImage";

type SelectItemProps = {
isSelected?: boolean;
index?: number;
imgSrc?: string;
title?: string;
addr?: string;
};

const SelectItem = ({ isSelected = false }: SelectItemProps) => {
const SelectItem = ({ index, imgSrc, title, addr }: SelectItemProps) => {
return (
<li className="flex gap-5 pl-5 items-center justify-start w-full min-h-[4.0625rem]">
<span
className={`w-5 h-5 rounded-full ${isSelected ? "bg-primary" : "bg-[#D0CFD7]"} text-center text-[#F3F5F5] leading-5`}
>
n
<li className="flex gap-5 pl-5 items-center justify-start w-full">
<span className="min-w-5 w-5 h-5 rounded-full bg-primary text-center text-[#F3F5F5] leading-5">
{index}
</span>
<div className="flex gap-[0.625rem] items-center w-full p-[0.625rem] rounded-[0.625rem] bg-white">
<DefaultImage size={"45px"} />
<p className="text-sm text-contentMuted">추가된 장소가 없습니다.</p>
<div className="flex gap-3 items-center w-full p-3 rounded-xl bg-white">
<DefaultImage src={imgSrc} />
<div className="w-full">
<p className="text-sm group-hover:sm:text-base group-hover:sm:font-semibold text-contentSecondary font-semibold">
{title || "장소 이름이 정확하지 않습니다."}
</p>
<p className="text-xs group-hover:sm:text-sm text-point">
{addr || "주소가 정확하지 않습니다."}
</p>
</div>
</div>
</li>
);
Expand Down
5 changes: 1 addition & 4 deletions src/layout/tripaccommodation/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ const TripAccommodationLayout = ({
<meta name="description" content="여행 숙소 선택 페이지입니다." />
<link rel="icon" href="/favicon/favicon.ico" />
</Head>
<section
className="flex flex-col items-center min-w-[22.5rem]
"
>
<section className="flex flex-col items-center min-w-[22.5rem] mb-5">
{children}
</section>
</>
Expand Down
58 changes: 55 additions & 3 deletions src/pages/tripaccommodation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@ import HeaderTripSelect from "@/components/header/HeaderTripSelect";
import TripAccommodationMap from "@/components/tripaccommodation/TripAccommodationMap";
import TripRegionDaysEdit from "@/components/common/TripRegionDaysEdit";
import SelectDaysInfo from "@/components/tripselect/SelectDaysInfo";
import DefaultImage from "@/components/common/DefaultImage";
import SelectItem from "@/components/tripselect/SelectItem";
import LocalItem from "@/components/tripselect/LocalItem";
import ButtonLarge from "@/components/tripselect/ButtonLarge";
import { AccommodationStore } from "@/store/AccommodationStore";

function TripRegionPage() {
const {
locationAccommodation,
selectedAccommodation,
resetSelectedAccommodation,
} = AccommodationStore();
const isSelected = Boolean(selectedAccommodation);

return (
<TripAccommodationLayout>
<HeaderTripSelect isPadding inCloseButton />
Expand All @@ -16,16 +27,57 @@ function TripRegionPage() {
<SelectDaysInfo />
<button
type="button"
onClick={resetSelectedAccommodation}
className="w-20 h-7 rounded-md border border-contentMuted text-sm text-contentMuted hover:bg-secondary hover:border-black hover:text-black hover:font-semibold"
>
초기화
</button>
</div>
<ul className="w-full pl-5 pr-[0.625rem] py-[0.625rem] rounded-[0.625rem] bg-[#E9F0F0]">
{/* AccommodationData.map((item) => {firstimage, title, addr1, mapx, mapy}) */}
<SelectItem />
<ul
className={`grid grid-cols-1 lg:grid-cols-2 gap-3 w-full pr-3 py-3 rounded-xl ${isSelected ? "bg-button" : "bg-[#E9F0F0]"}`}
>
{isSelected ? (
selectedAccommodation!.map((accommodation, index) => (
<SelectItem
key={accommodation.contentid}
index={index + 1}
title={accommodation.title}
addr={`${accommodation.addr2 ? accommodation.addr1 + " " + accommodation.addr2 : accommodation.addr1}`}
imgSrc={accommodation.firstimage || accommodation.firstimage2}
/>
))
) : (
<li className="flex gap-5 pl-5 items-center justify-start w-full">
<span className="w-5 h-5 rounded-full bg-[#D0CFD7] text-center text-[#F3F5F5] leading-5">
1
</span>
<div className="flex gap-3 items-center w-full p-3 rounded-xl bg-white">
<DefaultImage />
<p className="text-sm text-contentMuted">
추가된 장소가 없습니다.
</p>
</div>
</li>
)}
</ul>
<div
className={`pt-5 border-t-4 ${isSelected ? "border-primary" : "border-[#D0CFD7]"}`}
>
<ul className="grid grid-cols-1 lg:grid-cols-2 gap-3 w-full p-3 rounded-xl bg-[#E9F0F0]">
{locationAccommodation &&
locationAccommodation.map((location, index) => (
<LocalItem
key={index}
id={location.contentid}
title={location.title}
addr={`${location.addr2 ? location.addr1 + " " + location.addr2 : location.addr1}`}
imgSrc={location.firstimage || location.firstimage2}
/>
))}
</ul>
</div>
</section>
<ButtonLarge href="/tripeidt" />
</TripAccommodationLayout>
);
}
Expand Down

0 comments on commit 8100e01

Please sign in to comment.