-
+
diff --git a/src/components/Review/Review.module.scss b/src/components/Review/Review.module.scss
new file mode 100644
index 00000000..7b74f1d8
--- /dev/null
+++ b/src/components/Review/Review.module.scss
@@ -0,0 +1,47 @@
+@use "@/sass" as *;
+
+.container {
+ display: flex;
+ gap: 8px;
+ padding: 24px 20px;
+ border-bottom: 1px solid $neutral100;
+
+ &__contentsBox {
+ width: 100%;
+
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+
+ &__name {
+ @include typography(button);
+ }
+
+ &__secondItems {
+ display: flex;
+ align-items: center;
+
+ &__star {
+ display: inline;
+ font-size: 1.6rem;
+ color: $etc0;
+ }
+
+ &__point {
+ margin-left: 2px;
+ @include typography(captionSmall);
+ }
+
+ &__visitedAt {
+ margin-left: 9px;
+ color: $primary300;
+ @include typography(captionSmall);
+ }
+ }
+
+ &__content {
+ @include typography(bodySmall);
+ text-overflow: ellipsis;
+ }
+ }
+}
diff --git a/src/components/Review/Review.tsx b/src/components/Review/Review.tsx
new file mode 100644
index 00000000..dae9dccc
--- /dev/null
+++ b/src/components/Review/Review.tsx
@@ -0,0 +1,52 @@
+import { Avatar } from "@chakra-ui/react";
+import { GoStarFill } from "react-icons/go";
+
+import styles from "./Review.module.scss";
+
+import ReviewImageSlider from "./ReviewImageSlider/ReviewImageSlider";
+
+import { ReviewPropsTypes } from "@/types/detail";
+
+function Review({
+ name,
+ isGoogle = false,
+ point,
+ visitedAt,
+ content,
+ images,
+}: ReviewPropsTypes) {
+ return (
+
+
+
+
+ {name}
+ {isGoogle && 구글}
+
+
+
+
+ {point}
+
+
+ {visitedAt}
+
+
+
{content}
+ {images &&
}
+
+
+ );
+}
+
+export default Review;
diff --git a/src/components/Review/ReviewImageSlider/ReviewImageSlider.module.scss b/src/components/Review/ReviewImageSlider/ReviewImageSlider.module.scss
new file mode 100644
index 00000000..0f7c7303
--- /dev/null
+++ b/src/components/Review/ReviewImageSlider/ReviewImageSlider.module.scss
@@ -0,0 +1,56 @@
+.container {
+ overflow: hidden;
+ position: relative;
+
+ &__imgWrapper {
+ position: relative;
+ display: flex;
+ gap: 8px;
+
+ transition: all 1s;
+ img {
+ width: 7.6rem;
+ height: 7.6rem;
+ }
+ }
+
+ &__leftBtn {
+ position: absolute;
+ top: 50%;
+ left: 10px;
+ transform: translate(-10px, -50%);
+
+ width: 2.4rem;
+ height: 2.2rem;
+ border-radius: 1.2rem;
+
+ background-color: #ffffff;
+ z-index: 2;
+ &__icon {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ }
+ }
+
+ &__rightBtn {
+ position: absolute;
+ top: 50%;
+ right: 10px;
+ transform: translate(-10px, -50%);
+
+ width: 2.4rem;
+ height: 2.4rem;
+ border-radius: 1.2rem;
+
+ background-color: #ffffff;
+ z-index: 2;
+ &__icon {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ }
+ }
+}
diff --git a/src/components/Review/ReviewImageSlider/ReviewImageSlider.tsx b/src/components/Review/ReviewImageSlider/ReviewImageSlider.tsx
new file mode 100644
index 00000000..07db63a9
--- /dev/null
+++ b/src/components/Review/ReviewImageSlider/ReviewImageSlider.tsx
@@ -0,0 +1,50 @@
+import { useState } from "react";
+import { AiOutlineLeft, AiOutlineRight } from "react-icons/ai";
+
+import styles from "./ReviewImageSlider.module.scss";
+
+import useComponentSize from "@/hooks/useComponetSize";
+
+function ReviewImageSlider({ images }: { images: string[] }) {
+ const [slideLocation, setSlideLocation] = useState
(0);
+ const [componentRef, size] = useComponentSize();
+
+ return (
+
+
{
+ setSlideLocation(slideLocation + 84);
+ }}
+ >
+
+
+
= 84 * images.length - 1 - size.width
+ ? "none"
+ : "block",
+ }}
+ onClick={() => {
+ setSlideLocation(slideLocation - 84);
+ }}
+ >
+
+
+
+ {images.map((data) => (
+
![]({data})
+ ))}
+
+
+ );
+}
+
+export default ReviewImageSlider;
diff --git a/src/components/SearchFromHome/SearchBar/SearchBar.module.scss b/src/components/SearchFromHome/SearchBar/SearchBar.module.scss
new file mode 100644
index 00000000..c0da7272
--- /dev/null
+++ b/src/components/SearchFromHome/SearchBar/SearchBar.module.scss
@@ -0,0 +1,66 @@
+@use "@/sass" as *;
+
+@mixin icon {
+ position: absolute;
+ top: calc(50% - 1.5px);
+
+ width: 24px;
+ height: 24px;
+
+ font-size: 24px;
+
+ transform: translateY(-50%);
+}
+
+.container {
+ width: 100%;
+ height: 4.8rem;
+
+ padding: 0 20px 8px 20px;
+
+ .search_container {
+ position: relative;
+
+ padding: 5px 32px 8px 32px;
+
+ .bottom_line {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+
+ width: 100%;
+ height: 2px;
+
+ background-color: $primary300;
+ }
+ }
+
+ .searchBar {
+ position: relative;
+
+ width: 100%;
+ height: 100%;
+
+ @include typography(subTitle);
+
+ &__input {
+ width: 100%;
+ &:focus {
+ outline: none;
+ }
+ }
+ }
+
+ .return {
+ left: 0;
+
+ @include icon;
+ }
+ .enter {
+ right: 0;
+
+ @include icon;
+
+ cursor: pointer;
+ }
+}
diff --git a/src/components/SearchFromHome/SearchBar/SearchBar.tsx b/src/components/SearchFromHome/SearchBar/SearchBar.tsx
new file mode 100644
index 00000000..86e0017f
--- /dev/null
+++ b/src/components/SearchFromHome/SearchBar/SearchBar.tsx
@@ -0,0 +1,79 @@
+import { useEffect, useState } from "react";
+import { Link } from "react-router-dom";
+
+import styles from "./SearchBar.module.scss";
+
+interface PropsType {
+ set: React.Dispatch>;
+ keyword: string | undefined;
+}
+
+function SearchBar({ set, keyword }: PropsType) {
+ const [inputValue, setInputValue] = useState("");
+
+ useEffect(() => {
+ if (keyword) {
+ setInputValue(keyword);
+ }
+ }, [keyword]);
+
+ function handleInputValue(e: React.ChangeEvent) {
+ setInputValue(e.target.value);
+ }
+
+ function search() {
+ set(inputValue);
+ }
+
+ return (
+
+
+
+ {
+ if (e.key === "Enter") {
+ search();
+ }
+ }}
+ />
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default SearchBar;
diff --git a/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.module.scss b/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.module.scss
new file mode 100644
index 00000000..ab073fac
--- /dev/null
+++ b/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.module.scss
@@ -0,0 +1,25 @@
+@use "@/sass" as *;
+
+.container {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+
+ img {
+ max-width: 10.6rem;
+ max-height: 10.6rem;
+
+ border-radius: 1.6rem;
+ }
+ .text_box {
+ display: flex;
+ flex-direction: column;
+ }
+ .title {
+ @include typography(button);
+ }
+ .location {
+ color: $neutral400;
+ @include typography(captionSmall);
+ }
+}
diff --git a/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.tsx b/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.tsx
new file mode 100644
index 00000000..55a67f4d
--- /dev/null
+++ b/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.tsx
@@ -0,0 +1,23 @@
+import { Link } from "react-router-dom";
+
+import styles from "./HotItem.module.scss";
+
+import { SearchHotItemType } from "@/types/home";
+
+interface PropsData {
+ data: SearchHotItemType;
+}
+
+function HotItem({ data }: PropsData) {
+ return (
+
+
+
+ {data.title}
+ {data.location}
+
+
+ );
+}
+
+export default HotItem;
diff --git a/src/components/SearchFromHome/SearchHome/HotItems/HotItems.module.scss b/src/components/SearchFromHome/SearchHome/HotItems/HotItems.module.scss
new file mode 100644
index 00000000..ba1ada99
--- /dev/null
+++ b/src/components/SearchFromHome/SearchHome/HotItems/HotItems.module.scss
@@ -0,0 +1,10 @@
+@use "@/sass" as *;
+
+.container {
+ @include slide_button_container;
+
+ .slide_box {
+ @include slide_list_container;
+ gap: 8px;
+ }
+}
diff --git a/src/components/SearchFromHome/SearchHome/HotItems/HotItems.tsx b/src/components/SearchFromHome/SearchHome/HotItems/HotItems.tsx
new file mode 100644
index 00000000..fcb7c47f
--- /dev/null
+++ b/src/components/SearchFromHome/SearchHome/HotItems/HotItems.tsx
@@ -0,0 +1,55 @@
+import { useEffect, useState } from "react";
+
+import styles from "./HotItems.module.scss";
+
+import useComponentSize from "@/hooks/useComponetSize";
+
+import SlideButton from "@/components/SlideButton/SlideButton";
+
+import { getData } from "@/mocks/handlers/home";
+
+import HotItem from "./HotItem/HotItem";
+
+import { SearchHotItemType } from "@/types/home";
+
+interface PropsType {
+ type: string;
+}
+
+function HotItems({ type }: PropsType) {
+ const [data, setData] = useState();
+ const [slideLocation, setSlideLocation] = useState(0);
+ const [componentRef, size] = useComponentSize();
+
+ useEffect(() => {
+ getData(`home/search/hot${type}`, setData);
+ }, [type]);
+
+ return (
+
+ {data && (
+
+ )}
+
+ {data &&
+ data.map((data, i) => )}
+
+
+ );
+}
+
+export default HotItems;
diff --git a/src/components/SearchFromHome/SearchHome/SearchHome.module.scss b/src/components/SearchFromHome/SearchHome/SearchHome.module.scss
new file mode 100644
index 00000000..6e9732e5
--- /dev/null
+++ b/src/components/SearchFromHome/SearchHome/SearchHome.module.scss
@@ -0,0 +1,26 @@
+@use "@/sass" as *;
+
+.lists_box {
+ display: flex;
+ flex-direction: column;
+ gap: 48px;
+
+ .title {
+ @include typography(titleMedium);
+ color: #1d2433;
+
+ padding: 8px 20px;
+ }
+
+ .column_4px {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ }
+
+ .column_8px {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ }
+}
diff --git a/src/components/SearchFromHome/SearchHome/SearchHome.tsx b/src/components/SearchFromHome/SearchHome/SearchHome.tsx
new file mode 100644
index 00000000..85c1784c
--- /dev/null
+++ b/src/components/SearchFromHome/SearchHome/SearchHome.tsx
@@ -0,0 +1,29 @@
+import styles from "./SearchHome.module.scss";
+
+import HotItems from "./HotItems/HotItems";
+import SearchKeyword from "./SearchKeyword/SearchKeyword";
+
+interface PropsType {
+ set: React.Dispatch>;
+}
+
+function SearchHome({ set }: PropsType) {
+ return (
+
+ );
+}
+
+export default SearchHome;
diff --git a/src/components/SearchFromHome/SearchHome/SearchKeyword/SearchKeyword.module.scss b/src/components/SearchFromHome/SearchHome/SearchKeyword/SearchKeyword.module.scss
new file mode 100644
index 00000000..e50c9a10
--- /dev/null
+++ b/src/components/SearchFromHome/SearchHome/SearchKeyword/SearchKeyword.module.scss
@@ -0,0 +1,27 @@
+@use "@/sass" as *;
+
+.container {
+ @include slide_button_container;
+
+ .slide_box {
+ @include slide_list_container;
+ gap: 8px;
+
+ p {
+ height: 3.8rem;
+
+ padding: 8px 16px;
+
+ border-radius: 48px;
+
+ color: $primary300;
+ background-color: $primary100;
+
+ white-space: nowrap;
+
+ cursor: pointer;
+
+ @include typography(button);
+ }
+ }
+}
diff --git a/src/components/SearchFromHome/SearchHome/SearchKeyword/SearchKeyword.tsx b/src/components/SearchFromHome/SearchHome/SearchKeyword/SearchKeyword.tsx
new file mode 100644
index 00000000..4e84c883
--- /dev/null
+++ b/src/components/SearchFromHome/SearchHome/SearchKeyword/SearchKeyword.tsx
@@ -0,0 +1,89 @@
+import { useEffect, useState } from "react";
+
+import styles from "./SearchKeyword.module.scss";
+
+import useComponentSize from "@/hooks/useComponetSize";
+
+import SlideButton from "@/components/SlideButton/SlideButton";
+
+import { getData } from "@/mocks/handlers/home";
+
+interface PropsType {
+ set: React.Dispatch>;
+}
+
+function SearchKeyword({ set }: PropsType) {
+ const [data, setData] = useState();
+ const [listWidth, setListWidth] = useState(0);
+ const [slideLocation, setSlideLocation] = useState(0);
+ const [componentRef, size] = useComponentSize();
+
+ useEffect(() => {
+ getData("home/search/keyword", setData);
+ }, []);
+
+ // 각 키워드의 너비를 모두 더한 값을 구함
+ useEffect(() => {
+ // 정확한 이유를 찾지 못하였으나 setTimeout을 걸지 않으면 각 p태그의 width가 실제보다 다소 큰 수가 반영됨
+ setTimeout(() => {
+ if (
+ data &&
+ componentRef.current &&
+ componentRef.current?.childNodes.length === data.length
+ ) {
+ const pTags = componentRef.current.querySelectorAll("p");
+ const widths = Array.from(pTags).map((pTag) => {
+ const rect = pTag.getBoundingClientRect();
+ return rect.width;
+ });
+ const width = widths.reduce((acc, width) => acc + width, 0);
+ setListWidth(width);
+ }
+ }, 100);
+ }, [data, componentRef]);
+
+ function searchKeyword(keyword: string) {
+ set(keyword);
+ }
+
+ return (
+
+ {data && (
+
+ )}
+
+ {data ? (
+ data.map((keyword, i) => (
+
{
+ searchKeyword(keyword);
+ }}
+ >
+ {keyword}
+
+ ))
+ ) : (
+
키워드가 없습니다.
+ )}
+
+
+ );
+}
+
+export default SearchKeyword;
diff --git a/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.module.scss b/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.module.scss
new file mode 100644
index 00000000..e90ca855
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.module.scss
@@ -0,0 +1,20 @@
+@use "@/sass" as *;
+
+.container {
+ width: 7.9rem;
+ height: 2.4rem;
+
+ display: flex;
+ align-items: center;
+
+ padding: 4px 8px;
+
+ cursor: pointer;
+
+ @include typography(button);
+
+ .icon {
+ width: 2.4rem;
+ height: 2.4rem;
+ }
+}
diff --git a/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.tsx b/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.tsx
new file mode 100644
index 00000000..ccae0fe7
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.tsx
@@ -0,0 +1,14 @@
+import { BsFilterLeft } from "react-icons/bs";
+
+import styles from "./DateFilter.module.scss";
+
+function DateFilter() {
+ return (
+
+
+ 등록순
+
+ );
+}
+
+export default DateFilter;
diff --git a/src/components/SearchFromHome/SearchList/LocationFilter/LocationFilter.module.scss b/src/components/SearchFromHome/SearchList/LocationFilter/LocationFilter.module.scss
new file mode 100644
index 00000000..036adae2
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/LocationFilter/LocationFilter.module.scss
@@ -0,0 +1,28 @@
+@use "@/sass" as *;
+
+.container {
+ width: 9.1rem;
+ height: 3rem;
+
+ display: flex;
+ align-items: center;
+ gap: 2px;
+
+ padding: 4px 4px 4px 10px;
+
+ border: 1px solid $neutral300;
+ border-radius: 16px;
+
+ @include typography(tabLabel);
+
+ cursor: pointer;
+
+ .icon {
+ width: 2rem;
+ height: 2rem;
+
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+}
diff --git a/src/components/SearchFromHome/SearchList/LocationFilter/LocationFilter.tsx b/src/components/SearchFromHome/SearchList/LocationFilter/LocationFilter.tsx
new file mode 100644
index 00000000..e4b8e946
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/LocationFilter/LocationFilter.tsx
@@ -0,0 +1,14 @@
+import { MdOutlineKeyboardArrowDown } from "react-icons/md";
+
+import styles from "./LocationFilter.module.scss";
+
+function LocationFilter() {
+ return (
+
+ 전체 지역
+
+
+ );
+}
+
+export default LocationFilter;
diff --git a/src/components/SearchFromHome/SearchList/MapButton/MapButton.module.scss b/src/components/SearchFromHome/SearchList/MapButton/MapButton.module.scss
new file mode 100644
index 00000000..e7ef1ead
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/MapButton/MapButton.module.scss
@@ -0,0 +1,34 @@
+@use "@/sass" as *;
+
+.container {
+ position: fixed;
+ left: 50%;
+ bottom: 24px;
+ transform: translateX(-50%);
+
+ width: 18.3rem;
+ height: 5.4rem;
+
+ padding: 12px 32px;
+
+ border-radius: 4.8rem;
+
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ background-color: $primary300;
+ color: $neutral0;
+
+ @include typography(button);
+
+ .text {
+ display: flex;
+ gap: 4px;
+
+ .icon {
+ width: 2rem;
+ height: 2rem;
+ }
+ }
+}
diff --git a/src/components/SearchFromHome/SearchList/MapButton/MapButton.tsx b/src/components/SearchFromHome/SearchList/MapButton/MapButton.tsx
new file mode 100644
index 00000000..73539784
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/MapButton/MapButton.tsx
@@ -0,0 +1,16 @@
+import { MdOutlineMap } from "react-icons/md";
+
+import styles from "./MapButton.module.scss";
+
+function MapButton() {
+ return (
+
+ );
+}
+
+export default MapButton;
diff --git a/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.module.scss b/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.module.scss
new file mode 100644
index 00000000..0018e0d9
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.module.scss
@@ -0,0 +1,32 @@
+@use "@/sass" as *;
+
+.container {
+ width: 100%;
+ max-height: 70px;
+
+ display: flex;
+ gap: 12px;
+
+ padding: 16px 0;
+
+ img {
+ width: 4rem;
+ height: 4rem;
+
+ border-radius: 0.8rem;
+ }
+
+ .text {
+ display: flex;
+ flex-direction: column;
+
+ .title {
+ @include typography(titleSmall);
+ }
+ .info {
+ color: $neutral400;
+
+ @include typography(captionSmall);
+ }
+ }
+}
diff --git a/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.tsx b/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.tsx
new file mode 100644
index 00000000..e23fae02
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.tsx
@@ -0,0 +1,25 @@
+import { Link } from "react-router-dom";
+
+import styles from "./SearchItem.module.scss";
+
+import { SearchItemType } from "@/types/home";
+
+interface PropsType {
+ data: SearchItemType;
+}
+
+function SearchItem({ data }: PropsType) {
+ return (
+
+
+
+ {data.title}
+
+ {data.category}·{data.location}
+
+
+
+ );
+}
+
+export default SearchItem;
diff --git a/src/components/SearchFromHome/SearchList/SearchList.module.scss b/src/components/SearchFromHome/SearchList/SearchList.module.scss
new file mode 100644
index 00000000..74ab4d7b
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/SearchList.module.scss
@@ -0,0 +1,22 @@
+@use "@/sass" as *;
+
+.container {
+ width: 100%;
+
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+
+ @include typography(button);
+
+ .filter {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ padding: 0 20px;
+ }
+ ul {
+ padding: 0 20px;
+ }
+}
diff --git a/src/components/SearchFromHome/SearchList/SearchList.tsx b/src/components/SearchFromHome/SearchList/SearchList.tsx
new file mode 100644
index 00000000..d60829ac
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/SearchList.tsx
@@ -0,0 +1,52 @@
+import { useEffect, useState } from "react";
+
+import styles from "./SearchList.module.scss";
+
+import { getData } from "@/mocks/handlers/home";
+
+import DateFilter from "./DateFilter/DateFilter";
+import LocationFilter from "./LocationFilter/LocationFilter";
+import MapButton from "./MapButton/MapButton";
+import SearchItem from "./SearchItem/SearchItem";
+import Tabs from "./Tabs/Tabs";
+
+import { SearchItemType } from "@/types/home";
+
+function SearchList({ keyword }: { keyword: string }) {
+ const [data, setData] = useState();
+ const [filterData, setFilterData] = useState();
+ const [category, setCategory] = useState("전체");
+
+ useEffect(() => {
+ setCategory("전체");
+ getData("home/search/search", setData);
+ }, [keyword]);
+
+ useEffect(() => {
+ if (data && category !== "전체") {
+ const filterData = data.filter((data) => data.category === category);
+ setFilterData(filterData);
+ } else {
+ setFilterData(data);
+ }
+ }, [data, category]);
+
+ return (
+
+
+
+
+
+
+
+ {filterData &&
+ filterData.map((data, i) => (
+
+ ))}
+
+
+
+ );
+}
+
+export default SearchList;
diff --git a/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.module.scss b/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.module.scss
new file mode 100644
index 00000000..08882f61
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.module.scss
@@ -0,0 +1,13 @@
+@use "@/sass" as *;
+.container {
+ min-width: 90px;
+ height: 33px;
+
+ transition: 0.5s color;
+
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ cursor: pointer;
+}
diff --git a/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.tsx b/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.tsx
new file mode 100644
index 00000000..7946fa0a
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.tsx
@@ -0,0 +1,31 @@
+import styles from "./Tab.module.scss";
+
+interface PropsType {
+ set: React.Dispatch>;
+ category: string;
+ thisCategory: string;
+}
+
+function Tab({ set, category, thisCategory }: PropsType) {
+ function handleCategory(key: string) {
+ set(key);
+ }
+
+ return (
+ {
+ handleCategory(thisCategory);
+ }}
+ >
+ {thisCategory}
+
+ );
+}
+
+export default Tab;
diff --git a/src/components/SearchFromHome/SearchList/Tabs/Tabs.module.scss b/src/components/SearchFromHome/SearchList/Tabs/Tabs.module.scss
new file mode 100644
index 00000000..909e2ec1
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/Tabs/Tabs.module.scss
@@ -0,0 +1,11 @@
+@use "@/sass" as *;
+
+.container {
+ color: $neutral300;
+
+ @include slide_button_container;
+
+ .tabs {
+ @include slide_list_container;
+ }
+}
diff --git a/src/components/SearchFromHome/SearchList/Tabs/Tabs.tsx b/src/components/SearchFromHome/SearchList/Tabs/Tabs.tsx
new file mode 100644
index 00000000..67eedf15
--- /dev/null
+++ b/src/components/SearchFromHome/SearchList/Tabs/Tabs.tsx
@@ -0,0 +1,61 @@
+import { useState } from "react";
+
+import styles from "./Tabs.module.scss";
+
+import useComponentSize from "@/hooks/useComponetSize";
+
+import SlideButton from "@/components/SlideButton/SlideButton";
+
+import Tab from "./Tab/Tab";
+
+interface PropsType {
+ set: React.Dispatch>;
+ category: string;
+}
+
+function Tabs({ set, category }: PropsType) {
+ const [slideLocation, setSlideLocation] = useState(0);
+ const [componentRef, size] = useComponentSize();
+ const thisCategory = [
+ "전체",
+ "맛집",
+ "숙소",
+ "관광지",
+ "문화시설",
+ "레포츠",
+ "쇼핑",
+ ];
+
+ return (
+
+
+
+ {thisCategory.map((thisCategory) => (
+
+ ))}
+
+
+ );
+}
+
+export default Tabs;
diff --git a/src/components/SlideButton/LeftButton/LeftButton.tsx b/src/components/SlideButton/LeftButton/LeftButton.tsx
index 02693d78..71790084 100644
--- a/src/components/SlideButton/LeftButton/LeftButton.tsx
+++ b/src/components/SlideButton/LeftButton/LeftButton.tsx
@@ -9,7 +9,11 @@ function LeftButton({
setSlideLocation,
itemWidth,
flexGap,
+ buttonSize,
}: LeftButtonPropsType) {
+ const buttonsSize = buttonSize ? buttonSize : 40;
+ const iconSize = buttonSize ? buttonSize / 3 : undefined;
+
function handleButton() {
if (-itemWidth < slideLocation) {
setSlideLocation(0);
@@ -21,7 +25,12 @@ function LeftButton({
return (
);
diff --git a/src/components/Vote/VoteCandidateItem/VoteCandidateItem.module.scss b/src/components/Vote/VoteCandidateItem/VoteCandidateItem.module.scss
new file mode 100644
index 00000000..e8bdbddb
--- /dev/null
+++ b/src/components/Vote/VoteCandidateItem/VoteCandidateItem.module.scss
@@ -0,0 +1,80 @@
+@use "@/sass" as *;
+
+.container {
+ width: 100%; //335?
+ height: 14.4rem;
+ padding: 15px 20px;
+
+ border-radius: 16px;
+ border: 2px solid $neutral200;
+ box-shadow: $shadow100;
+
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+}
+
+.main {
+ width: 100%;
+
+ display: flex;
+ justify-content: space-between;
+
+ &__contextBox {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+
+ &__name {
+ @include typography(titleMedium);
+ color: $neutral900;
+ }
+ &__category {
+ @include typography(captionSmall);
+ color: $neutral400;
+ }
+ &__addDay {
+ @include typography(captionSmall);
+ color: $neutral800;
+ }
+ }
+ &__voteBox {
+ @include typography(bodySmall);
+ color: $neutral800;
+
+ width: 5.8rem;
+ height: 8rem;
+
+ padding: 10px;
+
+ border-radius: 10px;
+ border: 2px solid $neutral200;
+
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ gap: 4px;
+
+ &__star {
+ font-size: 2.4rem;
+ }
+ }
+}
+
+.comment {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+
+ &__text {
+ height: 2.2rem;
+ @include typography(bodySmall);
+ color: $neutral900;
+ background-color: $neutral100;
+
+ padding: 0 17px;
+ border-radius: 7px;
+ }
+}
diff --git a/src/components/Vote/VoteCandidateItem/VoteCandidateItem.tsx b/src/components/Vote/VoteCandidateItem/VoteCandidateItem.tsx
new file mode 100644
index 00000000..47cc2a24
--- /dev/null
+++ b/src/components/Vote/VoteCandidateItem/VoteCandidateItem.tsx
@@ -0,0 +1,26 @@
+import { Avatar } from "@chakra-ui/react";
+
+import styles from "./VoteCandidateItem.module.scss";
+
+const VoteCandidateItem = () => {
+ return (
+
+
+
+
대전 성심당 {">"}
+
카페
+
+ 일정에 추가
+
+
+
+
+
+ );
+};
+
+export default VoteCandidateItem;
diff --git a/src/components/Vote/VoteDetailsBottomButton/VoteDetailsBottomButton.module.scss b/src/components/Vote/VoteDetailsBottomButton/VoteDetailsBottomButton.module.scss
new file mode 100644
index 00000000..f6afe520
--- /dev/null
+++ b/src/components/Vote/VoteDetailsBottomButton/VoteDetailsBottomButton.module.scss
@@ -0,0 +1,6 @@
+@use "@/sass" as *;
+
+// .bottomButton {
+// @include vote-common-button !important;
+// @include typography(button) !important;
+// }
diff --git a/src/components/Vote/VoteDetailsBottomButton/VoteDetailsBottomButton.tsx b/src/components/Vote/VoteDetailsBottomButton/VoteDetailsBottomButton.tsx
new file mode 100644
index 00000000..e3aba6bf
--- /dev/null
+++ b/src/components/Vote/VoteDetailsBottomButton/VoteDetailsBottomButton.tsx
@@ -0,0 +1,13 @@
+import { Button } from "@chakra-ui/react";
+
+//import styles from "./VoteDetailsBottomButton.module.scss";
+
+const VoteDetailsBottomButton = () => {
+ return (
+
+
+
+ );
+};
+
+export default VoteDetailsBottomButton;
diff --git a/src/components/Vote/VoteDetailsField/VoteDetailsField.module.scss b/src/components/Vote/VoteDetailsField/VoteDetailsField.module.scss
new file mode 100644
index 00000000..fa7c3a1f
--- /dev/null
+++ b/src/components/Vote/VoteDetailsField/VoteDetailsField.module.scss
@@ -0,0 +1,32 @@
+@use "@/sass" as *;
+
+.container {
+ width: 100%;
+ padding: 20px;
+
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+
+ &__stateBar {
+ margin-bottom: 15px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ &__state {
+ @include typography(captionSmall);
+ color: $primary200;
+ //color:$neutral400;
+ }
+ &__addCandidate {
+ @include typography(button);
+ color: $neutral900;
+ }
+ }
+ &__candidateList {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ }
+}
diff --git a/src/components/Vote/VoteDetailsField/VoteDetailsField.tsx b/src/components/Vote/VoteDetailsField/VoteDetailsField.tsx
new file mode 100644
index 00000000..d4076471
--- /dev/null
+++ b/src/components/Vote/VoteDetailsField/VoteDetailsField.tsx
@@ -0,0 +1,35 @@
+import { Icon } from "@chakra-ui/react";
+import { GoDotFill } from "react-icons/go";
+
+import styles from "./VoteDetailsField.module.scss";
+
+import VoteCandidateItem from "../VoteCandidateItem/VoteCandidateItem";
+
+// import VoteDetailsFieldZero from "../VoteDetailsFieldZero/VoteDetailsFieldZero";
+
+const VoteDetailsField = () => {
+ // if(CandidateList.length===0) {
+ // //지도 색 neutral300
+ // return
+ // }
+
+ return (
+
+
+
+
+ 진행 중
+
+
+ + 후보 추가(1/15)
+
+
+
+
+
+
+
+
+ );
+};
+export default VoteDetailsField;
diff --git a/src/components/Vote/VoteDetailsFieldZero/VoteDetailsFieldZero.module.scss b/src/components/Vote/VoteDetailsFieldZero/VoteDetailsFieldZero.module.scss
new file mode 100644
index 00000000..3cc2caba
--- /dev/null
+++ b/src/components/Vote/VoteDetailsFieldZero/VoteDetailsFieldZero.module.scss
@@ -0,0 +1,20 @@
+@use "@/sass" as *;
+
+.container {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+
+ &__zeroTextBox {
+ text-align: center;
+ margin-top: 25vh;
+ &__title {
+ @include typography(titleSmall);
+ color: $neutral400;
+ }
+ &__text {
+ @include typography(captionSmall);
+ color: $neutral300;
+ }
+ }
+}
diff --git a/src/components/Vote/VoteDetailsFieldZero/VoteDetailsFieldZero.tsx b/src/components/Vote/VoteDetailsFieldZero/VoteDetailsFieldZero.tsx
new file mode 100644
index 00000000..9f1d2d40
--- /dev/null
+++ b/src/components/Vote/VoteDetailsFieldZero/VoteDetailsFieldZero.tsx
@@ -0,0 +1,18 @@
+import styles from "./VoteDetailsFieldZero.module.scss";
+
+const VoteDetailsFieldZero = () => {
+ return (
+
+
+
+ 투표 후보가 없습니다.
+
+
+ 하단 버튼을 눌러 후보를 추가해보세요!
+
+
+
+ );
+};
+
+export default VoteDetailsFieldZero;
diff --git a/src/components/Vote/VoteDetailsHeader/VoteDetailsHeader.module.scss b/src/components/Vote/VoteDetailsHeader/VoteDetailsHeader.module.scss
new file mode 100644
index 00000000..58776061
--- /dev/null
+++ b/src/components/Vote/VoteDetailsHeader/VoteDetailsHeader.module.scss
@@ -0,0 +1,36 @@
+@use "@/sass" as *;
+
+.container {
+ height: 4rem;
+ width: 45rem;
+ min-width: 36rem;
+ position: fixed;
+ top: 0;
+ left: 50%;
+ transform: translateX(-50%);
+
+ padding: 0 16px;
+
+ background-color: $neutral0;
+
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ font-size: 2.4rem;
+
+ z-index: 100;
+}
+
+.title {
+ @include typography(tabLabel);
+ height: 2.2rem;
+ margin-left: 40px;
+}
+
+.iconBox {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 16px;
+}
diff --git a/src/components/Vote/VoteDetailsHeader/VoteDetailsHeader.tsx b/src/components/Vote/VoteDetailsHeader/VoteDetailsHeader.tsx
new file mode 100644
index 00000000..0eecd11b
--- /dev/null
+++ b/src/components/Vote/VoteDetailsHeader/VoteDetailsHeader.tsx
@@ -0,0 +1,28 @@
+import { BsThreeDots } from "react-icons/bs";
+import { FaRegMap } from "react-icons/fa";
+import { MdOutlineArrowBackIosNew } from "react-icons/md";
+
+import styles from "./VoteDetailsHeader.module.scss";
+
+const VoteDetailsHeader = () => {
+ const voteTitle = "카페 어디로 갈래?";
+
+ //상태에 따른 아이콘 disabled
+ // 또는 없애기
+
+ return (
+
+
+
+
+
{voteTitle}
+
+
+
+
+
+
+ );
+};
+
+export default VoteDetailsHeader;
diff --git a/src/mocks/handlers/home.ts b/src/mocks/handlers/home.ts
index a6b64c09..1b797ece 100644
--- a/src/mocks/handlers/home.ts
+++ b/src/mocks/handlers/home.ts
@@ -3,6 +3,7 @@ import { http, HttpResponse } from "msw";
import { Dispatch } from "react";
const recommendedItem = [
+ // 홈
[
{
title: "호텔 loft",
@@ -175,28 +176,27 @@ const recommendedLocation = [
"https://img-cf.kurly.com/shop/data/goodsview/20210218/gv30000159355_1.jpg",
},
];
-
const userVoteData = [
{
title: "부산, 여수 여행",
date: "1.17-1.19",
profile: "https://avatars.githubusercontent.com/u/154430298?s=48&v=4",
discussion: "첫째 날 카페 어디갈래?",
- voteURL: "/voteDetail",
+ voteURL: "/vote",
},
{
title: "부산, 여수 여행",
date: "1.17-1.19",
profile: "https://avatars.githubusercontent.com/u/154430298?s=48&v=4",
discussion: "둘째 날 카페 어디갈래?",
- voteURL: "/voteDetail",
+ voteURL: "/vote",
},
{
title: "부산, 여수 여행",
date: "1.17-1.19",
profile: "https://avatars.githubusercontent.com/u/154430298?s=48&v=4",
discussion: "셋째 날 카페 어디갈래?",
- voteURL: "/voteDetail",
+ voteURL: "/vote",
},
];
const tripSpaceData = [
@@ -222,8 +222,215 @@ const tripSpaceData = [
dDay: "D-34",
},
];
+// 홈 검색
+const searchKeywordData = [
+ "감자",
+ "강릉 감자",
+ "강릉 감자유원지",
+ "부산",
+ "울산 맛집",
+ "해운대 카페",
+ "광안리 횟집",
+ "깡통시장 깡돼후",
+];
+const hotPlaces = [
+ {
+ title: "대전 성심당",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "맛집 · 대전",
+ id: "1",
+ },
+ {
+ title: "대전 성심당",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "맛집 · 대전",
+ id: "1",
+ },
+ {
+ title: "대전 성심당",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "맛집 · 대전",
+ id: "1",
+ },
+ {
+ title: "대전 성심당",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "맛집 · 대전",
+ id: "1",
+ },
+ {
+ title: "대전 성심당",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "맛집 · 대전",
+ id: "1",
+ },
+ {
+ title: "대전 성심당",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "맛집 · 대전",
+ id: "1",
+ },
+];
+const hotHotels = [
+ {
+ title: "호텔 loft",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "호텔 · 제주",
+ id: "1",
+ },
+ {
+ title: "호텔 loft",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "호텔 · 제주",
+ id: "1",
+ },
+ {
+ title: "호텔 loft",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "호텔 · 제주",
+ id: "1",
+ },
+ {
+ title: "호텔 loft",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "호텔 · 제주",
+ id: "1",
+ },
+ {
+ title: "호텔 loft",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "호텔 · 제주",
+ id: "1",
+ },
+ {
+ title: "호텔 loft",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "호텔 · 제주",
+ id: "1",
+ },
+];
+const searchItemData = [
+ {
+ title: "아시안 누들 서비스",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "맛집",
+ },
+ {
+ title: "더 타코부스",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "맛집",
+ },
+ {
+ title: "콴안다오",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "맛집",
+ },
+ {
+ title: "신라호텔",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "숙소",
+ },
+ {
+ title: "조선호텔",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "숙소",
+ },
+ {
+ title: "그랜드하얏트",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "숙소",
+ },
+ {
+ title: "더 현대",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "관광지",
+ },
+ {
+ title: "서울숲",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "관광지",
+ },
+ {
+ title: "롯데월드",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "관광지",
+ },
+ {
+ title: "국립중앙박물관",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "문화시설",
+ },
+ {
+ title: "디큐브아트센터",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "문화시설",
+ },
+ {
+ title: "인사아트프로젝트",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "문화시설",
+ },
+ {
+ title: "한강 레저",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "레포츠",
+ },
+ {
+ title: "서울 레이스 파크",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "레포츠",
+ },
+ {
+ title: "남산 케이블카",
+ imageURL:
+ "https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg",
+ location: "서울",
+ category: "레포츠",
+ },
+];
export const home = [
+ // 홈
http.get("/api/home/recommendedItem/1", () => {
return HttpResponse.json(recommendedItem[0], {
status: 200,
@@ -249,6 +456,27 @@ export const home = [
status: 200,
});
}),
+ // 홈 검색
+ http.get("/api/home/search/keyword", () => {
+ return HttpResponse.json(searchKeywordData, {
+ status: 200,
+ });
+ }),
+ http.get("/api/home/search/hotplace", () => {
+ return HttpResponse.json(hotPlaces, {
+ status: 200,
+ });
+ }),
+ http.get("/api/home/search/hothotel", () => {
+ return HttpResponse.json(hotHotels, {
+ status: 200,
+ });
+ }),
+ http.get("/api/home/search/search", () => {
+ return HttpResponse.json(searchItemData, {
+ status: 200,
+ });
+ }),
];
// 추후 api폴더가 생기면 함수를 옮기겠습니다.
diff --git a/src/pages/SearchFromHome/SearchFromHome.module.scss b/src/pages/SearchFromHome/SearchFromHome.module.scss
new file mode 100644
index 00000000..39ebfd03
--- /dev/null
+++ b/src/pages/SearchFromHome/SearchFromHome.module.scss
@@ -0,0 +1,21 @@
+@use "@/sass" as *;
+
+.container {
+ width: 100%;
+
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+
+ padding-top: 16px;
+
+ font-family: "suit", sans-serif;
+
+ color: $neutral900;
+
+ -ms-overflow-style: none;
+ scrollbar-width: none;
+ ::-webkit-scrollbar {
+ display: none;
+ }
+}
diff --git a/src/pages/SearchFromHome/SearchFromHome.tsx b/src/pages/SearchFromHome/SearchFromHome.tsx
new file mode 100644
index 00000000..25faaa8f
--- /dev/null
+++ b/src/pages/SearchFromHome/SearchFromHome.tsx
@@ -0,0 +1,24 @@
+import { useState } from "react";
+
+import styles from "./SearchFromHome.module.scss";
+
+import SearchBar from "@/components/SearchFromHome/SearchBar/SearchBar";
+import SearchHome from "@/components/SearchFromHome/SearchHome/SearchHome";
+import SearchList from "@/components/SearchFromHome/SearchList/SearchList";
+
+function SearchFromHome() {
+ const [keyword, setKeyword] = useState
();
+
+ return (
+
+
+ {!keyword ? (
+
+ ) : (
+
+ )}
+
+ );
+}
+
+export default SearchFromHome;
diff --git a/src/pages/Trip/Trip.tsx b/src/pages/Trip/Trip.tsx
index 5d17f70a..b2c36612 100644
--- a/src/pages/Trip/Trip.tsx
+++ b/src/pages/Trip/Trip.tsx
@@ -39,7 +39,6 @@ function Trip() {
onOpen: onBottomSlideOpen,
onClose: onBottomSlideClose,
} = useDisclosure();
-
const {
isOpen: isSlideBarOpen,
onOpen: onSlideBarOpen,
diff --git a/src/pages/VoteDetail/VoteDetail.module.scss b/src/pages/VoteDetail/VoteDetail.module.scss
new file mode 100644
index 00000000..e1ddeb1b
--- /dev/null
+++ b/src/pages/VoteDetail/VoteDetail.module.scss
@@ -0,0 +1,11 @@
+@use "@/sass" as *;
+
+.container {
+ height: 100vh;
+ width: 100%;
+ margin-top: 4rem;
+
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
diff --git a/src/pages/VoteDetail/VoteDetail.tsx b/src/pages/VoteDetail/VoteDetail.tsx
new file mode 100644
index 00000000..78c5bbf6
--- /dev/null
+++ b/src/pages/VoteDetail/VoteDetail.tsx
@@ -0,0 +1,21 @@
+import styles from "./VoteDetail.module.scss";
+
+// import CreatVoteTitleModal from "@/components/Vote/CreatVoteTitleModal/CreatVoteTitleModal";
+import VoteDetailsBottomButton from "@/components/Vote/VoteDetailsBottomButton/VoteDetailsBottomButton";
+import VoteDetailsField from "@/components/Vote/VoteDetailsField/VoteDetailsField";
+import VoteDetailsHeader from "@/components/Vote/VoteDetailsHeader/VoteDetailsHeader";
+
+const VoteDetail = () => {
+ return (
+
+
+
+
+ {/* 나중에 여행스페이스 메인에 옮겨야함 */}
+ {/* */}
+
+
+ );
+};
+
+export default VoteDetail;
diff --git a/src/routes/MainRouter/MainRouter.tsx b/src/routes/MainRouter/MainRouter.tsx
index 7e7002d2..e7f1f1e7 100644
--- a/src/routes/MainRouter/MainRouter.tsx
+++ b/src/routes/MainRouter/MainRouter.tsx
@@ -1,14 +1,15 @@
import { Route, Routes } from "react-router-dom";
-import Login from "@/pages/Login/Login";
import Alarm from "@/pages/Alarm/Alarm";
import Detail from "@/pages/Detail/Detail";
import Home from "@/pages/Home/Home";
+import Login from "@/pages/Login/Login";
+import SearchFromHome from "@/pages/SearchFromHome/SearchFromHome";
import AgreePrivacy from "@/pages/Signup/Agree/AgreePrivacy";
import AgreeService from "@/pages/Signup/Agree/AgreeService";
-import Dashboard from "@/routes/Dashboard/Dashboard";
-import Vote from "@/pages/Vote/Vote";
import Trip from "@/pages/Trip/Trip";
+import Vote from "@/pages/Vote/Vote";
+import Dashboard from "@/routes/Dashboard/Dashboard";
function MainRouter() {
return (
@@ -25,6 +26,7 @@ function MainRouter() {
} />
} />
} />
+ } />
);
}
diff --git a/src/types/home.ts b/src/types/home.ts
index 1bd496f2..e03e6600 100644
--- a/src/types/home.ts
+++ b/src/types/home.ts
@@ -1,3 +1,5 @@
+// 홈 타입
+
export interface RecommendedItemDataType {
title: string;
imageURL: string;
@@ -32,6 +34,7 @@ export interface LeftButtonPropsType {
setSlideLocation: React.Dispatch>;
itemWidth: number;
flexGap: number;
+ buttonSize?: number;
}
interface ComponentSize {
@@ -43,3 +46,18 @@ export interface SlideButtonPropsType extends LeftButtonPropsType {
slideSize: ComponentSize;
itemNumber: number;
}
+
+// 홈 검색 타입
+export interface SearchHotItemType {
+ title: string;
+ imageURL: string;
+ location: string;
+ id: number;
+}
+
+export interface SearchItemType {
+ title: string;
+ imageURL: string;
+ location: string;
+ category: string;
+}