Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/TripPlace_Accommodation: 페이지 동적 경로 설정 및 storage 재수정 사항 반영 #75

Merged
merged 9 commits into from
Mar 11, 2024
2 changes: 1 addition & 1 deletion src/components/common/DefaultImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const DefaultImage = ({
className={`flex justify-center align-middle min-w-14 ${width} ${heigth} rounded-xl bg-[#EFF2F6]`}
>
<Image
src="svg/default-image.svg"
src="/svg/default-image.svg"
alt="기본 이미지"
width={10}
height={10}
Expand Down
17 changes: 11 additions & 6 deletions src/components/common/SelectDateInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
type SelectDateInfoProps = {
totalNumber?: number;
import { DatesStore } from "@/store/DatesStore";

type SelectDateInfoType = {
tripDate?: number;
};

const SelectDateInfo = ({ totalNumber = 0 }: SelectDateInfoProps) => {
const SelectDateInfo = ({ tripDate = 0 }: SelectDateInfoType) => {
const { tripDates } = DatesStore();
return (
<div className="flex gap-[0.625rem] items-end">
<span className="text-2xl text-content font-bold">{totalNumber}</span>
<span className="text-2xl text-content font-bold">
{tripDates?.length || 0}
</span>
<div className="flex gap-[0.125rem] min-w-fit text-sm">
<span className="font-medium text-[#2966E3]">n일</span>
<span className="font-medium text-[#2966E3]">{tripDate}일</span>
<span aria-hidden>/</span>
<span>n일</span>
<span>{tripDates?.length || 0}일</span>
</div>
</div>
);
Expand Down
24 changes: 18 additions & 6 deletions src/components/tripaccommodation/LocalAccommodationItem.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,40 @@
import { useEffect, useState } from "react";
import { BsFillPlusCircleFill } from "react-icons/bs";
import { FaCheckCircle } from "react-icons/fa";
import DefaultImage from "@/components/common/DefaultImage";
import { SelectAccommodationsStore } from "@/store/AccommodationsStore";

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

const LocalAccommodationItem = ({
id,
index,
title,
addr,
imgSrc,
}: LocalAccommodationItemProps) => {
const { selectedAccommodations, setSelectedAccommodations } =
SelectAccommodationsStore();
const isSelected = Boolean(
selectedAccommodations?.filter(
(accommodation) => accommodation.contentid == id,
).length,
);
const [isSelected, SetIsSelected] = useState<boolean>(false);

useEffect(() => {
if (selectedAccommodations && selectedAccommodations[index]) {
const i = selectedAccommodations[index].findIndex(
(place) => place.contentid == id,
);
if (i > -1) {
SetIsSelected(true);
} else {
SetIsSelected(false);
}
}
}, [selectedAccommodations]);

return (
<li className="group flex gap-3 p-3 items-center w-full bg-white rounded-xl">
Expand All @@ -38,7 +50,7 @@ const LocalAccommodationItem = ({
<button
type="button"
onClick={() => {
setSelectedAccommodations(id);
setSelectedAccommodations(index, id);
}}
>
{isSelected ? (
Expand Down
2 changes: 1 addition & 1 deletion src/components/tripaccommodation/TripAccommodationsMap.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect, useRef, useState } from "react";
import { TOUR_BASE_ACCOMMODATION } from "@/lib/tour/tour";
import { RegionStore } from "@/store/RegionStore";
import { AccommodationsStore } from "@/store/AccommodationsStore";
import { LocationAccommodationsStore } from "@/store/AccommodationsStore";

declare global {
interface Window {
Expand Down
29 changes: 24 additions & 5 deletions src/components/tripplace/LocalPlaceItem.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useEffect, useState } from "react";
import { BsFillPlusCircleFill } from "react-icons/bs";
import { FaCheckCircle } from "react-icons/fa";
import DefaultImage from "@/components/common/DefaultImage";
Expand All @@ -8,13 +9,31 @@ type LocalPlaceItemProps = {
title: string;
addr: string;
imgSrc: string;
index: number;
};

const LocalPlaceItem = ({ id, title, addr, imgSrc }: LocalPlaceItemProps) => {
const LocalPlaceItem = ({
id,
title,
addr,
imgSrc,
index,
}: LocalPlaceItemProps) => {
const { selectedPlaces, setSelctedPlaces } = SelectPlacesStore();
const isSelected = Boolean(
selectedPlaces?.filter((place) => place.contentid == id).length,
);
const [isSelected, SetIsSelected] = useState<boolean>(false);

useEffect(() => {
if (selectedPlaces && selectedPlaces[index]) {
const i = selectedPlaces[index].findIndex(
(place) => place.contentid == id,
);
if (i > -1) {
SetIsSelected(true);
} else {
SetIsSelected(false);
}
}
}, [selectedPlaces]);

return (
<li className="group flex gap-3 p-3 items-center w-full bg-white rounded-xl">
Expand All @@ -30,7 +49,7 @@ const LocalPlaceItem = ({ id, title, addr, imgSrc }: LocalPlaceItemProps) => {
<button
type="button"
onClick={() => {
setSelctedPlaces(id);
setSelctedPlaces(index, id);
}}
>
{isSelected ? (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useParams } from "next/navigation";
import { useEffect, useState } from "react";
import TripAccommodationLayout from "@/layout/tripaccommodation/layout";
import HeaderTripSelect from "@/components/header/HeaderTripSelect";
import TripAccommodationsMap from "@/components/tripaccommodation/TripAccommodationsMap";
Expand All @@ -7,17 +9,30 @@ import DefaultImage from "@/components/common/DefaultImage";
import SelectItem from "@/components/common/SelectItem";
import LocalAccommodationItem from "@/components/tripaccommodation/LocalAccommodationItem";
import ButtonLarge from "@/components/common/ButtonLarge";
import { DatesStore } from "@/store/DatesStore";
import {
LocationAccommodationsStore,
SelectAccommodationsStore,
} from "@/store/AccommodationsStore";

function TripAccommodationPage() {
const params = useParams();
const { tripDates } = DatesStore();
const { locationAccommodations } = LocationAccommodationsStore();
const { selectedAccommodations, resetSelectedAccommodations } =
const { selectedAccommodations, setTripAccommodationsRange } =
SelectAccommodationsStore();
const isSelected = Boolean(selectedAccommodations);
const totalNumberText = selectedAccommodations!.length;

const date = Number(params?.tripdate);
const dateIndex = date - 1;

const [isSelected, SetIsSelected] = useState<boolean>(false);

useEffect(() => {
if (selectedAccommodations && selectedAccommodations[dateIndex]) {
const length = selectedAccommodations[dateIndex].length;
SetIsSelected(Boolean(length));
}
}, [selectedAccommodations]);

return (
<TripAccommodationLayout>
Expand All @@ -26,10 +41,10 @@ function TripAccommodationPage() {
<TripRegionDaysEdit />
<section className="flex flex-col gap-5 w-full p-5">
<div className="flex justify-between">
<SelectDateInfo totalNumber={totalNumberText} />
<SelectDateInfo tripDate={date} />
<button
type="button"
onClick={resetSelectedAccommodations}
onClick={() => setTripAccommodationsRange(tripDates!.length)}
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"
>
초기화
Expand All @@ -39,16 +54,15 @@ function TripAccommodationPage() {
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 ? (
/* selectedAccommodations!.map((accommodation, index) => (
selectedAccommodations![dateIndex].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}
/>
)) */
<SelectItem />
))
) : (
<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">
Expand All @@ -72,6 +86,7 @@ function TripAccommodationPage() {
<LocalAccommodationItem
key={index}
id={location.contentid}
index={dateIndex}
title={location.title}
addr={`${location.addr2 ? location.addr1 + " " + location.addr2 : location.addr1}`}
imgSrc={location.firstimage || location.firstimage2}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
import { useParams } from "next/navigation";
import TripPlaceLayout from "@/layout/tripplace/layout";
import HeaderTripSelect from "@/components/header/HeaderTripSelect";
import TripPlacesMap from "@/components/tripplace/TripPlacesMap";
import TripRegionDaysEdit from "@/components/common/TripRegionDaysEdit";
import SelectDateInfo from "@/components/common/SelectDateInfo";
import SelectItem from "@/components/common/SelectItem";
import ButtonLarge from "@/components/common/ButtonLarge";
import { LocationPlacesStore, SelectPlacesStore } from "@/store/PlacesStore";
import DefaultImage from "@/components/common/DefaultImage";
import LocalPlaceItem from "@/components/tripplace/LocalPlaceItem";
import { useRouter } from "next/router";
import { DatesStore } from "@/store/DatesStore";
import { LocationPlacesStore, SelectPlacesStore } from "@/store/PlacesStore";
import { useEffect, useState } from "react";

const TripPlacePage = ({ params }: { params: { index: number } }) => {
const TripPlacePage = () => {
const params = useParams();
const { locationPlaces } = LocationPlacesStore();
const { selectedPlaces, resetSelectedPlaces } = SelectPlacesStore();
const router = useRouter();
const { index } = router.query;
const isSelected = Boolean(selectedPlaces);
const totalNumberText = selectedPlaces!.length;
const { tripDates } = DatesStore();
const { selectedPlaces, setTripPlacesRange } = SelectPlacesStore();

const date = Number(params?.tripdate);
const dateIndex = date - 1;

const [isSelected, SetIsSelected] = useState<boolean>(false);

useEffect(() => {
if (selectedPlaces && selectedPlaces[dateIndex]) {
const length = selectedPlaces[dateIndex].length;
SetIsSelected(Boolean(length));
}
}, [selectedPlaces]);

return (
<TripPlaceLayout>
Expand All @@ -25,10 +37,10 @@ const TripPlacePage = ({ params }: { params: { index: number } }) => {
<TripRegionDaysEdit />
<section className="flex flex-col gap-5 w-full p-5">
<div className="flex justify-between">
<SelectDateInfo totalNumber={totalNumberText} />
<SelectDateInfo tripDate={date} />
<button
type="button"
onClick={resetSelectedPlaces}
onClick={() => setTripPlacesRange(tripDates!.length)}
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"
>
초기화
Expand All @@ -38,16 +50,15 @@ const TripPlacePage = ({ params }: { params: { index: number } }) => {
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 ? (
/* selectedPlaces!.map((place, index) => (
selectedPlaces![dateIndex].map((place, index) => (
<SelectItem
key={place.contentid}
index={index + 1}
title={place.title}
addr={`${place.addr2 ? place.addr1 + " " + place.addr2 : place.addr1}`}
imgSrc={place.firstimage || place.firstimage2}
/>
)) */
<SelectItem />
))
) : (
<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">
Expand All @@ -71,6 +82,7 @@ const TripPlacePage = ({ params }: { params: { index: number } }) => {
<LocalPlaceItem
key={index}
id={place.contentid}
index={dateIndex}
title={place.title}
addr={`${place.addr2 ? place.addr1 + " " + place.addr2 : place.addr1}`}
imgSrc={place.firstimage || place.firstimage2}
Expand Down
49 changes: 27 additions & 22 deletions src/store/AccommodationsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ type LocationAccommodationsStoreType = {
type SelectAccommodationsStoreType = {
selectedAccommodations: PlaceDataType[][] | null;
setTripAccommodationsRange: (range: number) => void;
// setSelectedAccommodations: (id: number) => void;
resetSelectedAccommodations: () => void;
setSelectedAccommodations: (date: number, id: number) => void;
};

export const LocationAccommodationsStore =
Expand All @@ -28,30 +27,36 @@ export const SelectAccommodationsStore = create(
selectedAccommodations: null,
setTripAccommodationsRange: (range: number) =>
set({ selectedAccommodations: setTripRange(range) }),
/* setSelectedAccommodations: (id: number) =>
setSelectedAccommodations: (date: number, id: number) =>
set((state) => {
if (
...state.locationAccommodations!.filter(
(location) => location.contentid == id,
),
],
}
: {
selectedAccommodations: [
...state.locationAccommodations!.filter(
(location) => location.contentid == id,
),
],
};
!state.selectedAccommodations ||
!state.selectedAccommodations[date]
) {
state.selectedAccommodations = [];
state.selectedAccommodations[date] = [];
}

const locationAccommodations =
LocationAccommodationsStore.getState().locationAccommodations;
const index = state.selectedAccommodations[date].findIndex(
(accommodation) => accommodation.contentid === id,
);

if (index == -1) {
const selectAccommodation = locationAccommodations!.find(
(accommodation) => accommodation.contentid === id,
);
if (selectAccommodation) {
state.selectedAccommodations[date].push(selectAccommodation);
}
} else {
return {
selectedAccommodations: state.selectedAccommodations?.filter(
(sa) => sa.contentid != id,
),
};
state.selectedAccommodations[date].splice(index, 1);
}
}), */
resetSelectedAccommodations: () => set({ selectedAccommodations: null }),
return {
selectedAccommodations: [...state.selectedAccommodations],
};
}),
}),
{
name: "tripAccommodationStorage",
Expand Down
Loading