diff --git a/src/pages/LandingPage/DriverHome/DriverTab/index.jsx b/src/pages/LandingPage/DriverHome/DriverTab/index.jsx deleted file mode 100644 index 686519aa..00000000 --- a/src/pages/LandingPage/DriverHome/DriverTab/index.jsx +++ /dev/null @@ -1,26 +0,0 @@ -function DriverTab({ tab, setTab }) { - return ( -
- - - -
- ); -} - -export default DriverTab; diff --git a/src/pages/LandingPage/DriverHome/DriverTab/index.tsx b/src/pages/LandingPage/DriverHome/DriverTab/index.tsx new file mode 100644 index 00000000..c77e699a --- /dev/null +++ b/src/pages/LandingPage/DriverHome/DriverTab/index.tsx @@ -0,0 +1,43 @@ +import { Dispatch, memo, SetStateAction } from "react"; +import clsx from "clsx"; + +interface Props { + tab: number; + setTab: Dispatch>; +} + +function DriverTab({ tab, setTab }: Props) { + return ( +
+ + + +
+ ); +} + +export default memo(DriverTab); diff --git a/src/pages/LandingPage/DriverHome/PartyList/NoParty/index.jsx b/src/pages/LandingPage/DriverHome/PartyList/NoParty/index.tsx similarity index 81% rename from src/pages/LandingPage/DriverHome/PartyList/NoParty/index.jsx rename to src/pages/LandingPage/DriverHome/PartyList/NoParty/index.tsx index 3dd10e0b..7f307e00 100644 --- a/src/pages/LandingPage/DriverHome/PartyList/NoParty/index.jsx +++ b/src/pages/LandingPage/DriverHome/PartyList/NoParty/index.tsx @@ -1,3 +1,5 @@ +import { memo } from "react"; + function NoParty() { return (
@@ -10,4 +12,4 @@ function NoParty() { ); } -export default NoParty; +export default memo(NoParty); diff --git a/src/pages/LandingPage/DriverHome/PartyList/index.jsx b/src/pages/LandingPage/DriverHome/PartyList/index.tsx similarity index 69% rename from src/pages/LandingPage/DriverHome/PartyList/index.jsx rename to src/pages/LandingPage/DriverHome/PartyList/index.tsx index b633a178..854f04df 100644 --- a/src/pages/LandingPage/DriverHome/PartyList/index.jsx +++ b/src/pages/LandingPage/DriverHome/PartyList/index.tsx @@ -1,13 +1,18 @@ -import { useEffect, useState } from "react"; +import { memo, useCallback, useEffect, useMemo, useState } from "react"; import { getMyDriverParty } from "../../../../api/party"; +import { HeartParty } from "../../../../types"; import PartyBox from "../../PartyList/PartyBox"; import NoParty from "./NoParty"; -function PartyList({ tab }) { - const [partyData, setPartyData] = useState([]); +interface Props { + tab: number; +} + +function PartyList({ tab }: Props) { + const [partyData, setPartyData] = useState([]); const [loading, setLoading] = useState(true); - const filterParty = () => { + const filterParty: HeartParty[] = useMemo(() => { if (!partyData) return []; if (tab === 0) return partyData.filter( @@ -24,9 +29,10 @@ function PartyList({ tab }) { return partyData.filter( (party) => party.status === "WAITING_DRIVER_APPROVAL" ); - }; + return []; + }, [partyData, tab]); - const getPartyData = async () => { + const getPartyData = useCallback(async () => { try { const result = await getMyDriverParty(); setPartyData(result.payload); @@ -35,21 +41,21 @@ function PartyList({ tab }) { } finally { setLoading(false); } - }; + }, []); useEffect(() => { getPartyData(); }, []); if (loading) return null; - if (filterParty().length === 0) return ; + if (filterParty.length === 0) return ; return (
- {filterParty().map((item) => ( + {filterParty.map((item) => ( ))}
); } -export default PartyList; +export default memo(PartyList); diff --git a/src/pages/LandingPage/DriverHome/index.jsx b/src/pages/LandingPage/DriverHome/index.tsx similarity index 80% rename from src/pages/LandingPage/DriverHome/index.jsx rename to src/pages/LandingPage/DriverHome/index.tsx index a395f4c4..6cb07139 100644 --- a/src/pages/LandingPage/DriverHome/index.jsx +++ b/src/pages/LandingPage/DriverHome/index.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { memo, useState } from "react"; import DriverTab from "./DriverTab"; import PartyList from "./PartyList"; @@ -13,4 +13,4 @@ function DriverHome() { ); } -export default DriverHome; +export default memo(DriverHome); diff --git a/src/pages/LandingPage/DriverMenu/index.jsx b/src/pages/LandingPage/DriverMenu/index.jsx deleted file mode 100644 index 54d92035..00000000 --- a/src/pages/LandingPage/DriverMenu/index.jsx +++ /dev/null @@ -1,25 +0,0 @@ -import { useSelector } from "react-redux"; - -function DriverMenu({ driverMenu, setDriverMenu }) { - const user = useSelector((state) => state.user); - - if (user.role !== "ROLE_DRIVER") return null; - return ( -
- - -
- ); -} - -export default DriverMenu; diff --git a/src/pages/LandingPage/DriverMenu/index.tsx b/src/pages/LandingPage/DriverMenu/index.tsx new file mode 100644 index 00000000..2173034d --- /dev/null +++ b/src/pages/LandingPage/DriverMenu/index.tsx @@ -0,0 +1,39 @@ +import { Dispatch, memo, SetStateAction } from "react"; +import { useSelector } from "react-redux"; +import { RootState } from "../../../redux/store"; +import clsx from "clsx"; + +interface Props { + driverMenu: "driver" | "user"; + setDriverMenu: Dispatch>; +} + +function DriverMenu({ driverMenu, setDriverMenu }: Props) { + const user = useSelector((state: RootState) => state.user); + + if (user.role !== "ROLE_DRIVER") return null; + return ( +
+ + +
+ ); +} + +export default memo(DriverMenu); diff --git a/src/pages/LandingPage/KakaoButton/index.jsx b/src/pages/LandingPage/KakaoButton/index.tsx similarity index 87% rename from src/pages/LandingPage/KakaoButton/index.jsx rename to src/pages/LandingPage/KakaoButton/index.tsx index 1a49ffad..00c1fac8 100644 --- a/src/pages/LandingPage/KakaoButton/index.jsx +++ b/src/pages/LandingPage/KakaoButton/index.tsx @@ -1,3 +1,4 @@ +import { memo } from "react"; import { Link } from "react-router-dom"; import kakaoIcon from "../../../assets/svg/kakao-icon.svg"; @@ -13,4 +14,4 @@ function KakaoButton() { ); } -export default KakaoButton; +export default memo(KakaoButton); diff --git a/src/pages/LandingPage/MyPartyList/PartyList/NoParty/index.jsx b/src/pages/LandingPage/MyPartyList/PartyList/NoParty/index.tsx similarity index 81% rename from src/pages/LandingPage/MyPartyList/PartyList/NoParty/index.jsx rename to src/pages/LandingPage/MyPartyList/PartyList/NoParty/index.tsx index 09754f23..58ce5d55 100644 --- a/src/pages/LandingPage/MyPartyList/PartyList/NoParty/index.jsx +++ b/src/pages/LandingPage/MyPartyList/PartyList/NoParty/index.tsx @@ -1,3 +1,5 @@ +import { memo } from "react"; + function NoParty() { return (
@@ -10,4 +12,4 @@ function NoParty() { ); } -export default NoParty; +export default memo(NoParty); diff --git a/src/pages/LandingPage/MyPartyList/PartyList/index.jsx b/src/pages/LandingPage/MyPartyList/PartyList/index.tsx similarity index 68% rename from src/pages/LandingPage/MyPartyList/PartyList/index.jsx rename to src/pages/LandingPage/MyPartyList/PartyList/index.tsx index 55b98093..60baac82 100644 --- a/src/pages/LandingPage/MyPartyList/PartyList/index.jsx +++ b/src/pages/LandingPage/MyPartyList/PartyList/index.tsx @@ -1,13 +1,18 @@ -import { useEffect, useState } from "react"; +import { memo, useCallback, useEffect, useMemo, useState } from "react"; import { getMyParty } from "../../../../api/party"; +import { HeartParty } from "../../../../types"; import PartyBox from "../../PartyList/PartyBox"; import NoParty from "./NoParty"; -function PartyList({ tab }) { - const [partyData, setPartyData] = useState([]); +interface Props { + tab: number; +} + +function PartyList({ tab }: Props) { + const [partyData, setPartyData] = useState([]); const [loading, setLoading] = useState(true); - const filterParty = () => { + const filterParty: HeartParty[] = useMemo(() => { if (tab === 0) return partyData.filter( (party) => party.status === "SEALED" || party.status === "DAY_OF_TRAVEL" @@ -23,9 +28,10 @@ function PartyList({ tab }) { return partyData.filter( (party) => party.status === "WAITING_DRIVER_APPROVAL" ); - }; + return []; + }, [partyData, tab]); - const getPartyData = async () => { + const getPartyData = useCallback(async () => { try { const result = await getMyParty(); setPartyData(result.payload); @@ -34,21 +40,21 @@ function PartyList({ tab }) { } finally { setLoading(false); } - }; + }, []); useEffect(() => { getPartyData(); }, []); if (loading) return null; - if (filterParty().length === 0) return ; + if (filterParty.length === 0) return ; return (
- {filterParty().map((item) => ( + {filterParty.map((item) => ( ))}
); } -export default PartyList; +export default memo(PartyList); diff --git a/src/pages/LandingPage/MyPartyList/UserTab/index.jsx b/src/pages/LandingPage/MyPartyList/UserTab/index.jsx deleted file mode 100644 index 53ed50e3..00000000 --- a/src/pages/LandingPage/MyPartyList/UserTab/index.jsx +++ /dev/null @@ -1,26 +0,0 @@ -function UserTab({ tab, setTab }) { - return ( -
- - - -
- ); -} - -export default UserTab; diff --git a/src/pages/LandingPage/MyPartyList/UserTab/index.tsx b/src/pages/LandingPage/MyPartyList/UserTab/index.tsx new file mode 100644 index 00000000..0b945979 --- /dev/null +++ b/src/pages/LandingPage/MyPartyList/UserTab/index.tsx @@ -0,0 +1,43 @@ +import { Dispatch, memo, SetStateAction } from "react"; +import clsx from "clsx"; + +interface Props { + tab: number; + setTab: Dispatch>; +} + +function UserTab({ tab, setTab }: Props) { + return ( +
+ + + +
+ ); +} + +export default memo(UserTab); diff --git a/src/pages/LandingPage/MyPartyList/index.jsx b/src/pages/LandingPage/MyPartyList/index.tsx similarity index 78% rename from src/pages/LandingPage/MyPartyList/index.jsx rename to src/pages/LandingPage/MyPartyList/index.tsx index e002aa53..c540e014 100644 --- a/src/pages/LandingPage/MyPartyList/index.jsx +++ b/src/pages/LandingPage/MyPartyList/index.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { memo, useState } from "react"; import UserTab from "./UserTab"; import PartyList from "./PartyList"; @@ -13,4 +13,4 @@ function MyPartyList() { ); } -export default MyPartyList; +export default memo(MyPartyList); diff --git a/src/pages/LandingPage/NewMyParty/index.jsx b/src/pages/LandingPage/NewMyParty/index.tsx similarity index 78% rename from src/pages/LandingPage/NewMyParty/index.jsx rename to src/pages/LandingPage/NewMyParty/index.tsx index f116a0ad..0e1f561e 100644 --- a/src/pages/LandingPage/NewMyParty/index.jsx +++ b/src/pages/LandingPage/NewMyParty/index.tsx @@ -1,18 +1,24 @@ +import { Dispatch, memo, SetStateAction, useCallback } from "react"; import { useNavigate } from "react-router-dom"; import { useSelector } from "react-redux"; +import { RootState } from "../../../redux/store"; import mallangtripLogo from "../../../assets/svg/mallangtrip-logo-grey.svg"; -function NewMyParty({ setShowLoginModal }) { +interface Props { + setShowLoginModal: Dispatch>; +} + +function NewMyParty({ setShowLoginModal }: Props) { const navigation = useNavigate(); - const user = useSelector((state) => state.user); + const user = useSelector((state: RootState) => state.user); - const clickHandler = () => { + const clickHandler = useCallback(() => { if (user.auth) navigation( `/party/new/1?region=${null}&member=${null}&date=${null}&driverId=${null}` ); else setShowLoginModal(true); - }; + }, [user]); return (
@@ -43,4 +49,4 @@ function NewMyParty({ setShowLoginModal }) { ); } -export default NewMyParty; +export default memo(NewMyParty); diff --git a/src/pages/LandingPage/PartyFilter/DateModal/index.jsx b/src/pages/LandingPage/PartyFilter/DateModal/index.tsx similarity index 64% rename from src/pages/LandingPage/PartyFilter/DateModal/index.jsx rename to src/pages/LandingPage/PartyFilter/DateModal/index.tsx index 872c09b9..c5d67ba0 100644 --- a/src/pages/LandingPage/PartyFilter/DateModal/index.jsx +++ b/src/pages/LandingPage/PartyFilter/DateModal/index.tsx @@ -1,38 +1,60 @@ -import { useEffect, useRef, useState } from "react"; +import { + Dispatch, + memo, + MouseEvent, + SetStateAction, + useCallback, + useEffect, + useRef, + useState, +} from "react"; import { createPortal } from "react-dom"; import { useDispatch, useSelector } from "react-redux"; +import { RootState } from "../../../../redux/store"; import { setNowDate } from "../../../../redux/modules/partyFilterSlice"; import Calendar from "react-calendar"; +import clsx from "clsx"; import "./index.css"; -function DateModal({ showModal, setShowModal }) { +interface Props { + showModal: boolean; + setShowModal: Dispatch>; +} + +function DateModal({ showModal, setShowModal }: Props) { const dispatch = useDispatch(); - const nowDate = useSelector((state) => state.partyFilter.nowDate); - const modalRef = useRef(); - const confirmButtonRef = useRef(); - const [date, setDate] = useState(nowDate); + const nowDate = useSelector((state: RootState) => state.partyFilter.nowDate); + const modalRef = useRef(null); + const confirmButtonRef = useRef(null); + const [date, setDate] = useState(nowDate); - const closeModal = () => setShowModal(false); + const closeModal = useCallback(() => setShowModal(false), []); - const modalOutSideClick = (e) => { - if (modalRef.current === e.target) closeModal(); - }; + const modalOutSideClick = useCallback( + (event: MouseEvent) => { + if (modalRef.current === event.target) closeModal(); + }, + [modalRef] + ); - const allDateHandler = () => { + const allDateHandler = useCallback(() => { setDate([]); dispatch(setNowDate([])); setShowModal(false); - }; + }, []); - const confirmHandler = () => { + const confirmHandler = useCallback(() => { dispatch(setNowDate(date)); setShowModal(false); - }; + }, [date]); - const handleKeyPress = (event) => { - if (event.key === "Escape") closeModal(); - else if (event.key === "Enter") confirmButtonRef.current.click(); - }; + const handleKeyPress = useCallback( + (event: KeyboardEvent) => { + if (event.key === "Escape") closeModal(); + else if (event.key === "Enter") confirmButtonRef.current?.click(); + }, + [confirmButtonRef] + ); useEffect(() => { if (!showModal) return document.body.classList.remove("overflow-hidden"); @@ -48,16 +70,18 @@ function DateModal({ showModal, setShowModal }) { return createPortal(
modalOutSideClick(e)} + onClick={modalOutSideClick} >

가능한 일정

@@ -87,9 +111,7 @@ function DateModal({ showModal, setShowModal }) { - date.toLocaleString("en", { day: "numeric" }) - } + formatDay={(_, date) => date.toLocaleString("en", { day: "numeric" })} minDate={new Date()} selectRange={true} calendarType="gregory" @@ -124,4 +146,4 @@ function DateModal({ showModal, setShowModal }) { ); } -export default DateModal; +export default memo(DateModal); diff --git a/src/pages/LandingPage/PartyFilter/Filter/DateFilter/index.jsx b/src/pages/LandingPage/PartyFilter/Filter/DateFilter/index.tsx similarity index 63% rename from src/pages/LandingPage/PartyFilter/Filter/DateFilter/index.jsx rename to src/pages/LandingPage/PartyFilter/Filter/DateFilter/index.tsx index 8100f219..588b5d9b 100644 --- a/src/pages/LandingPage/PartyFilter/Filter/DateFilter/index.jsx +++ b/src/pages/LandingPage/PartyFilter/Filter/DateFilter/index.tsx @@ -1,7 +1,14 @@ +import { Dispatch, memo, SetStateAction } from "react"; import { useSelector } from "react-redux"; +import { RootState } from "../../../../../redux/store"; +import clsx from "clsx"; -function DateFilter({ setShowDateModal }) { - const nowDate = useSelector((state) => state.partyFilter.nowDate); +interface Props { + setShowDateModal: Dispatch>; +} + +function DateFilter({ setShowDateModal }: Props) { + const nowDate = useSelector((state: RootState) => state.partyFilter.nowDate); return (
{num}
- ); -} - -export default PeopleMobileFilter; diff --git a/src/pages/LandingPage/PartyFilter/Filter/PeopleMobileFilter/index.tsx b/src/pages/LandingPage/PartyFilter/Filter/PeopleMobileFilter/index.tsx new file mode 100644 index 00000000..aabbd36b --- /dev/null +++ b/src/pages/LandingPage/PartyFilter/Filter/PeopleMobileFilter/index.tsx @@ -0,0 +1,27 @@ +import { Dispatch, memo, SetStateAction } from "react"; +import { useSelector } from "react-redux"; +import { RootState } from "../../../../../redux/store"; +import partyFilterPeople from "../../../../../assets/svg/party_filter_people.svg"; +import clsx from "clsx"; + +interface Props { + setShowPeopleModal: Dispatch>; +} + +function PeopleMobileFilter({ setShowPeopleModal }: Props) { + const num = useSelector((state: RootState) => state.partyFilter.num); + + return ( + + ); +} + +export default memo(PeopleMobileFilter); diff --git a/src/pages/LandingPage/PartyFilter/Filter/PriceFilter/index.jsx b/src/pages/LandingPage/PartyFilter/Filter/PriceFilter/index.jsx deleted file mode 100644 index 258529cf..00000000 --- a/src/pages/LandingPage/PartyFilter/Filter/PriceFilter/index.jsx +++ /dev/null @@ -1,25 +0,0 @@ -import { useSelector } from "react-redux"; - -function PriceFilter({ setShowPriceModal }) { - const price = useSelector((state) => state.partyFilter.price); - - return ( - - ); -} - -export default PriceFilter; diff --git a/src/pages/LandingPage/PartyFilter/Filter/PriceFilter/index.tsx b/src/pages/LandingPage/PartyFilter/Filter/PriceFilter/index.tsx new file mode 100644 index 00000000..bc7e6702 --- /dev/null +++ b/src/pages/LandingPage/PartyFilter/Filter/PriceFilter/index.tsx @@ -0,0 +1,37 @@ +import { Dispatch, memo, SetStateAction, useMemo } from "react"; +import { useSelector } from "react-redux"; +import { RootState } from "../../../../../redux/store"; +import clsx from "clsx"; + +interface Props { + setShowPriceModal: Dispatch>; +} + +function PriceFilter({ setShowPriceModal }: Props) { + const price = useSelector((state: RootState) => state.partyFilter.price); + const nowPrice = useMemo( + () => (typeof price === "string" ? parseInt(price) : price), + [price] + ); + + return ( + + ); +} + +export default memo(PriceFilter); diff --git a/src/pages/LandingPage/PartyFilter/Filter/PriceMobileFilter/index.jsx b/src/pages/LandingPage/PartyFilter/Filter/PriceMobileFilter/index.jsx deleted file mode 100644 index 1953f54f..00000000 --- a/src/pages/LandingPage/PartyFilter/Filter/PriceMobileFilter/index.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import { useSelector } from "react-redux"; -import partyFilterPrice from "../../../../../assets/svg/party_filter_price.svg"; - -function PriceMobileFilter({ setShowPriceModal }) { - const price = useSelector((state) => state.partyFilter.price); - - return ( - - ); -} - -export default PriceMobileFilter; diff --git a/src/pages/LandingPage/PartyFilter/Filter/PriceMobileFilter/index.tsx b/src/pages/LandingPage/PartyFilter/Filter/PriceMobileFilter/index.tsx new file mode 100644 index 00000000..bd5d3a87 --- /dev/null +++ b/src/pages/LandingPage/PartyFilter/Filter/PriceMobileFilter/index.tsx @@ -0,0 +1,33 @@ +import { Dispatch, memo, SetStateAction, useMemo } from "react"; +import { useSelector } from "react-redux"; +import { RootState } from "../../../../../redux/store"; +import partyFilterPrice from "../../../../../assets/svg/party_filter_price.svg"; +import clsx from "clsx"; + +interface Props { + setShowPriceModal: Dispatch>; +} + +function PriceMobileFilter({ setShowPriceModal }: Props) { + const price = useSelector((state: RootState) => state.partyFilter.price); + const nowPrice = useMemo( + () => (typeof price === "string" ? parseInt(price) : price), + [price] + ); + + return ( + + ); +} + +export default memo(PriceMobileFilter); diff --git a/src/pages/LandingPage/PartyFilter/Filter/RegionFilter/index.jsx b/src/pages/LandingPage/PartyFilter/Filter/RegionFilter/index.jsx deleted file mode 100644 index 5a7db622..00000000 --- a/src/pages/LandingPage/PartyFilter/Filter/RegionFilter/index.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import { useSelector } from "react-redux"; - -function RegionFilter({ setShowRegionModal }) { - const region = useSelector((state) => state.partyFilter.region); - - return ( - - ); -} - -export default RegionFilter; diff --git a/src/pages/LandingPage/PartyFilter/Filter/RegionFilter/index.tsx b/src/pages/LandingPage/PartyFilter/Filter/RegionFilter/index.tsx new file mode 100644 index 00000000..08880eda --- /dev/null +++ b/src/pages/LandingPage/PartyFilter/Filter/RegionFilter/index.tsx @@ -0,0 +1,31 @@ +import { Dispatch, memo, SetStateAction } from "react"; +import { useSelector } from "react-redux"; +import { RootState } from "../../../../../redux/store"; +import clsx from "clsx"; + +interface Props { + setShowRegionModal: Dispatch>; +} + +function RegionFilter({ setShowRegionModal }: Props) { + const region = useSelector((state: RootState) => state.partyFilter.region); + + return ( + + ); +} + +export default memo(RegionFilter); diff --git a/src/pages/LandingPage/PartyFilter/Filter/RegionMobileFilter/index.jsx b/src/pages/LandingPage/PartyFilter/Filter/RegionMobileFilter/index.jsx deleted file mode 100644 index bc2e736c..00000000 --- a/src/pages/LandingPage/PartyFilter/Filter/RegionMobileFilter/index.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import { useSelector } from "react-redux"; -import partyFilterRegion from "../../../../../assets/svg/party_filter_region.svg"; - -function RegionMobileFilter({ setShowRegionModal }) { - const region = useSelector((state) => state.partyFilter.region); - - return ( - - ); -} - -export default RegionMobileFilter; diff --git a/src/pages/LandingPage/PartyFilter/Filter/RegionMobileFilter/index.tsx b/src/pages/LandingPage/PartyFilter/Filter/RegionMobileFilter/index.tsx new file mode 100644 index 00000000..b3522fc7 --- /dev/null +++ b/src/pages/LandingPage/PartyFilter/Filter/RegionMobileFilter/index.tsx @@ -0,0 +1,31 @@ +import { Dispatch, memo, SetStateAction } from "react"; +import { useSelector } from "react-redux"; +import { RootState } from "../../../../../redux/store"; +import partyFilterRegion from "../../../../../assets/svg/party_filter_region.svg"; +import clsx from "clsx"; + +interface Props { + setShowRegionModal: Dispatch>; +} + +function RegionMobileFilter({ setShowRegionModal }: Props) { + const region = useSelector((state: RootState) => state.partyFilter.region); + + return ( + + ); +} + +export default memo(RegionMobileFilter); diff --git a/src/pages/LandingPage/PartyFilter/Filter/index.jsx b/src/pages/LandingPage/PartyFilter/Filter/index.tsx similarity index 77% rename from src/pages/LandingPage/PartyFilter/Filter/index.jsx rename to src/pages/LandingPage/PartyFilter/Filter/index.tsx index 9c5f9c87..ac8dac69 100644 --- a/src/pages/LandingPage/PartyFilter/Filter/index.jsx +++ b/src/pages/LandingPage/PartyFilter/Filter/index.tsx @@ -1,3 +1,4 @@ +import { Dispatch, memo, SetStateAction } from "react"; import RegionFilter from "./RegionFilter"; import DateFilter from "./DateFilter"; import PeopleFilter from "./PeopleFilter"; @@ -8,13 +9,21 @@ import PeopleMobileFilter from "./PeopleMobileFilter"; import PriceMobileFilter from "./PriceMobileFilter"; import NewPartyMobile from "./NewPartyMobile"; +interface Props { + setShowRegionModal: Dispatch>; + setShowDateModal: Dispatch>; + setShowPeopleModal: Dispatch>; + setShowPriceModal: Dispatch>; + setShowLoginModal: Dispatch>; +} + function Filter({ setShowRegionModal, setShowDateModal, setShowPeopleModal, setShowPriceModal, setShowLoginModal, -}) { +}: Props) { return ( <>
@@ -34,4 +43,4 @@ function Filter({ ); } -export default Filter; +export default memo(Filter); diff --git a/src/pages/LandingPage/PartyFilter/PeopleModal/index.jsx b/src/pages/LandingPage/PartyFilter/PeopleModal/index.tsx similarity index 68% rename from src/pages/LandingPage/PartyFilter/PeopleModal/index.jsx rename to src/pages/LandingPage/PartyFilter/PeopleModal/index.tsx index ef5ec1d6..d7643bb8 100644 --- a/src/pages/LandingPage/PartyFilter/PeopleModal/index.jsx +++ b/src/pages/LandingPage/PartyFilter/PeopleModal/index.tsx @@ -1,29 +1,48 @@ -import { useEffect, useRef, useState } from "react"; +import { + Dispatch, + memo, + MouseEvent, + SetStateAction, + useCallback, + useEffect, + useRef, + useState, +} from "react"; import { createPortal } from "react-dom"; import { useDispatch, useSelector } from "react-redux"; +import { RootState } from "../../../../redux/store"; import { setNum } from "../../../../redux/modules/partyFilterSlice"; import minusGray from "../../../../assets/svg/people_minus_gray.svg"; import minusPrimary from "../../../../assets/svg/people_minus_primary.svg"; import plusgray from "../../../../assets/svg/people_plus_gray.svg"; import plusPrimary from "../../../../assets/svg/people_plus_primary.svg"; +import clsx from "clsx"; -function PeopleModal({ showModal, setShowModal }) { +interface Props { + showModal: boolean; + setShowModal: Dispatch>; +} + +function PeopleModal({ showModal, setShowModal }: Props) { const dispatch = useDispatch(); - const modalRef = useRef(); - const num = useSelector((state) => state.partyFilter.num); + const modalRef = useRef(null); + const num = useSelector((state: RootState) => state.partyFilter.num); const [modalNum, setModalNum] = useState(1); - const setIncrease = () => setModalNum(modalNum + 1); - const setDecrease = () => setModalNum(modalNum - 1); + const setIncrease = useCallback(() => setModalNum(modalNum + 1), [modalNum]); + const setDecrease = useCallback(() => setModalNum(modalNum - 1), [modalNum]); - const closeModal = () => { + const closeModal = useCallback(() => { dispatch(setNum(modalNum)); setShowModal(false); - }; + }, [modalNum]); - const modalOutSideClick = (e) => { - if (modalRef.current === e.target) setShowModal(false); - }; + const modalOutSideClick = useCallback( + (event: MouseEvent) => { + if (modalRef.current === event.target) setShowModal(false); + }, + [modalRef] + ); useEffect(() => { if (!showModal) return document.body.classList.remove("overflow-hidden"); @@ -34,16 +53,18 @@ function PeopleModal({ showModal, setShowModal }) { return createPortal(
modalOutSideClick(e)} + onClick={modalOutSideClick} >
@@ -74,29 +95,32 @@ function PeopleModal({ showModal, setShowModal }) {
{modalNum}
- {user.role === "ROLE_USER" && ( - - )} -
- ); -} - -export default UserMenu; diff --git a/src/pages/LandingPage/UserMenu/index.tsx b/src/pages/LandingPage/UserMenu/index.tsx new file mode 100644 index 00000000..099838c2 --- /dev/null +++ b/src/pages/LandingPage/UserMenu/index.tsx @@ -0,0 +1,42 @@ +import { Dispatch, memo, SetStateAction } from "react"; +import { useSelector } from "react-redux"; +import { RootState } from "../../../redux/store"; +import clsx from "clsx"; + +interface Props { + userMenu: "recommend" | "myParty"; + setUserMenu: Dispatch>; +} + +function UserMenu({ userMenu, setUserMenu }: Props) { + const user = useSelector((state: RootState) => state.user); + + return ( +
+ + {user.role === "ROLE_USER" && ( + + )} +
+ ); +} + +export default memo(UserMenu); diff --git a/src/pages/LandingPage/index.jsx b/src/pages/LandingPage/index.tsx similarity index 83% rename from src/pages/LandingPage/index.jsx rename to src/pages/LandingPage/index.tsx index be6e11e1..bc98d937 100644 --- a/src/pages/LandingPage/index.jsx +++ b/src/pages/LandingPage/index.tsx @@ -1,6 +1,7 @@ -import { useEffect, useState } from "react"; +import { memo, useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { useSelector } from "react-redux"; +import { RootState } from "../../redux/store"; import CheckModal from "../../components/CheckModal"; import Title from "../../components/Title"; import PartyFilter from "./PartyFilter"; @@ -14,9 +15,11 @@ import NewMyParty from "./NewMyParty"; function LandingPage() { const navigation = useNavigate(); - const user = useSelector((state) => state.user); - const [driverMenu, setDriverMenu] = useState("driver"); - const [userMenu, setUserMenu] = useState("recommend"); + const user = useSelector((state: RootState) => state.user); + const [driverMenu, setDriverMenu] = useState<"driver" | "user">("driver"); + const [userMenu, setUserMenu] = useState<"recommend" | "myParty">( + "recommend" + ); const [showLoginModal, setShowLoginModal] = useState(false); useEffect(() => { @@ -57,4 +60,4 @@ function LandingPage() { ); } -export default LandingPage; +export default memo(LandingPage);