diff --git a/client/src/components/Card/RecruitCard/RecruitCard.tsx b/client/src/components/Card/RecruitCard/RecruitCard.tsx index bd45f2c..8e96ad0 100644 --- a/client/src/components/Card/RecruitCard/RecruitCard.tsx +++ b/client/src/components/Card/RecruitCard/RecruitCard.tsx @@ -7,9 +7,10 @@ import { timeDifference } from "#utils/cardUtils"; interface RecruitCardProps { data: Recruit; + userIdVisible?: boolean; } -const RecruitCard = ({ data }: RecruitCardProps) => { +const RecruitCard = ({ data, userIdVisible = true }: RecruitCardProps) => { return ( @@ -30,7 +31,7 @@ const RecruitCard = ({ data }: RecruitCardProps) => { CLOCK_ICON {timeDifference(data.startTime)} - {data.userId} + {userIdVisible && data.userId} ); diff --git a/client/src/components/CardList/CourseList/CorseList.tsx b/client/src/components/CardList/CourseList/CorseList.tsx index 917c1bc..5fedcc0 100644 --- a/client/src/components/CardList/CourseList/CorseList.tsx +++ b/client/src/components/CardList/CourseList/CorseList.tsx @@ -21,7 +21,12 @@ const CorseList = ({ distance, query, authorFilter, titleFilter }: CourseListPro const { data, fetchNextPage, hasNextPage } = useCoursesQuery({ distance, query, authorFilter, titleFilter }); return ( - fetchNextPage()} hasMore={hasNextPage} loader={}> + fetchNextPage()} + hasMore={hasNextPage} + loader={} + useWindow={false} + > {data?.pages.map((page, pageIdx) => page?.map((card, idx) => ), diff --git a/client/src/components/CardList/RecruitList/RecruitList.tsx b/client/src/components/CardList/RecruitList/RecruitList.tsx index 3295c45..47c3648 100644 --- a/client/src/components/CardList/RecruitList/RecruitList.tsx +++ b/client/src/components/CardList/RecruitList/RecruitList.tsx @@ -25,6 +25,7 @@ const RecruitList = (props: RecruitListProps) => { } + useWindow={false} > {data?.pages.map((page, pageIdx) => diff --git a/client/src/components/Layout/Layout.styles.ts b/client/src/components/Layout/Layout.styles.ts index 4a0c9af..cc6de10 100644 --- a/client/src/components/Layout/Layout.styles.ts +++ b/client/src/components/Layout/Layout.styles.ts @@ -29,6 +29,8 @@ export const Container = styled.div` > div:last-child { background-color: ${COLOR.WHITE}; position: relative; + height: 100vh; + overflow-y: scroll; } @media screen and (min-width: 480px) { ${flexRowCenter}; @@ -38,8 +40,6 @@ export const Container = styled.div` box-shadow: 2px 0 16px rgba(0, 0, 0, 0.25), -2px 0 16px rgba(0, 0, 0, 0.25); width: 390px; min-width: 390px; - height: 100%; - overflow-y: scroll; -ms-overflow-style: none; scrollbar-width: none; ::-webkit-scrollbar { diff --git a/client/src/hooks/queries/useCoursesQuery.ts b/client/src/hooks/queries/useCoursesQuery.ts index d21b6bd..d9fc94a 100644 --- a/client/src/hooks/queries/useCoursesQuery.ts +++ b/client/src/hooks/queries/useCoursesQuery.ts @@ -26,7 +26,11 @@ const useCoursesQuery = ({ distance, query, authorFilter, titleFilter }: CourseL ["courses", distance?.min, distance?.max, authorFilter, titleFilter, query], ({ pageParam = 1 }) => get("/course", courseQueryParams(pageParam)).then((res) => res.data), { - getNextPageParam: (lastPage, allPages) => (lastPage ? lastPage?.length > 0 && allPages.length + 1 : 1), + getNextPageParam: (lastPage, allPages) => { + if (!lastPage) return 1; + if (lastPage?.length > 0) return allPages.length + 1; + else return undefined; + }, suspense: true, }, ); diff --git a/client/src/hooks/queries/useRecruitsQuery.ts b/client/src/hooks/queries/useRecruitsQuery.ts index 8efddb5..14f07f5 100644 --- a/client/src/hooks/queries/useRecruitsQuery.ts +++ b/client/src/hooks/queries/useRecruitsQuery.ts @@ -18,18 +18,24 @@ const useRecruitsQuery = ({ distance, query, availFilter, authorFilter, titleFil param.maxLen = (distance.max * 1000).toString(); param.minLen = (distance.min * 1000).toString(); } - if (time) { - param.time = time.max.toString(); + + if (time?.max) { + param.hour = time.max.toString(); } + param.page = page; return param; }; return useInfiniteQuery( - ["recruits", distance?.min, distance?.max, authorFilter, titleFilter, query], + ["recruits", distance?.min, distance?.max, authorFilter, titleFilter, query, time], ({ pageParam = 1 }) => get("/recruit", recruitQueryParams(pageParam)).then((res) => res.data), { - getNextPageParam: (lastPage, allPages) => (lastPage ? lastPage?.length > 0 && allPages.length + 1 : 1), + getNextPageParam: (lastPage, allPages) => { + if (!lastPage) return 1; + if (lastPage?.length > 0) return allPages.length + 1; + else return undefined; + }, suspense: true, }, ); diff --git a/client/src/pages/Courses/Courses.tsx b/client/src/pages/Courses/Courses.tsx index d001bbe..702fd97 100644 --- a/client/src/pages/Courses/Courses.tsx +++ b/client/src/pages/Courses/Courses.tsx @@ -1,4 +1,4 @@ -import React, { useState, FormEventHandler, Suspense } from "react"; +import React, { useState, Suspense, ChangeEvent } from "react"; import Header from "#components/Header/Header"; import SearchBar from "#components/SearchBar/SearchBar"; import FilterBar from "#components/FilterBar/FilterBar"; @@ -11,6 +11,7 @@ import { LOCATION_ICON } from "#assets/icons"; import PlusButton from "#components/PlusButton/PlusButton"; import CourseList from "#components/CardList/CourseList/CorseList"; import CardListLoader from "#components/CardList/CardList.loader"; +import { debounce } from "#utils/timerUtils"; const Courses = () => { const [currentDistanceFilter, setCurrentDistanceFilter] = useFilter({ text: "3-5KM", min: 3, max: 5 }); @@ -18,9 +19,9 @@ const Courses = () => { const [authorFilter, toggleAuthorFilter] = useOnOffFilter(false); const [searchContent, setSearchContent] = useState(""); - const handleSearchContentChange: FormEventHandler = (e) => { - setSearchContent(e.currentTarget.value); - }; + const handleSearchContentChange = debounce((e: ChangeEvent) => { + setSearchContent(e.target.value); + }, 200); return ( <> @@ -45,6 +46,7 @@ const Courses = () => { filterIcon={LOCATION_ICON} filterState={currentDistanceFilter} filterOptions={[ + { text: "5KM 이상", min: 5, max: Number.MAX_SAFE_INTEGER }, { text: "3-5KM", min: 3, max: 5 }, { text: "1-3KM", min: 1, max: 3 }, { text: "1KM 이내", min: 0, max: 1 }, diff --git a/client/src/pages/MyPage/MyPageRecruits.tsx b/client/src/pages/MyPage/MyPageRecruits.tsx index 3c83ce6..4abcc67 100644 --- a/client/src/pages/MyPage/MyPageRecruits.tsx +++ b/client/src/pages/MyPage/MyPageRecruits.tsx @@ -55,7 +55,9 @@ const MyPageRecruits = ({ MyPageOption }: MyPageProps) => { if (!pastRecruitsToggled) filteredRecruit = filterPastRecruits(filteredRecruit); if (myRecruitsToggled) filteredRecruit = filterMyRecruits(filteredRecruit); - return filteredRecruit.map((r: Recruit, idx: number) => ); + return filteredRecruit.map((r: Recruit, idx: number) => ( + + )); }; return ( diff --git a/client/src/pages/Recruits/Recruits.tsx b/client/src/pages/Recruits/Recruits.tsx index 61abffd..0b80c1c 100644 --- a/client/src/pages/Recruits/Recruits.tsx +++ b/client/src/pages/Recruits/Recruits.tsx @@ -1,4 +1,4 @@ -import React, { Suspense, useState } from "react"; +import React, { ChangeEvent, Suspense, useState } from "react"; import Header from "#components/Header/Header"; import SearchBar from "#components/SearchBar/SearchBar"; import FilterBar from "#components/FilterBar/FilterBar"; @@ -11,6 +11,7 @@ import { LOCATION_ICON, CLOCK_ICON } from "#assets/icons"; import PlusButton from "#components/PlusButton/PlusButton"; import RecruitList from "#components/CardList/RecruitList/RecruitList"; import CardListLoader from "#components/CardList/CardList.loader"; +import { debounce } from "#utils/timerUtils"; const Recruits = () => { const [currentDistanceFilter, setCurrentDistanceFilter] = useFilter({ text: "3-5KM", min: 3, max: 5 }); @@ -20,9 +21,9 @@ const Recruits = () => { const [availFilter, toggleAvailFilter] = useOnOffFilter(false); const [searchContent, setSearchContent] = useState(""); - const handleSearchContentChange = (e: React.FormEvent) => { - setSearchContent(e.currentTarget.value); - }; + const handleSearchContentChange = debounce((e: ChangeEvent) => { + setSearchContent(e.target.value); + }, 200); return ( <> @@ -52,6 +53,7 @@ const Recruits = () => { filterIcon={LOCATION_ICON} filterState={currentDistanceFilter} filterOptions={[ + { text: "5KM 이상", min: 5, max: Number.MAX_SAFE_INTEGER }, { text: "3-5KM", min: 3, max: 5 }, { text: "1-3KM", min: 1, max: 3 }, { text: "1KM 이내", min: 0, max: 1 }, @@ -63,6 +65,7 @@ const Recruits = () => { filterIcon={CLOCK_ICON} filterState={currentTimeFilter} filterOptions={[ + { text: "상관 없음", min: 0, max: 0 }, { text: "5시간 이내", min: 0, max: 5 }, { text: "3시간 이내", min: 0, max: 3 }, { text: "1시간 이내", min: 0, max: 1 }, diff --git a/noti-server/src/app.service.ts b/noti-server/src/app.service.ts index e0fd559..a14816a 100644 --- a/noti-server/src/app.service.ts +++ b/noti-server/src/app.service.ts @@ -27,11 +27,11 @@ export class AppService { // 30분 전 시작 알림 createRecruitMessage(body: any) { - const { recruitId, user, title, hDong, startTime, pathLength } = body; + const { recruitId, author, title, hDong, startTime, pathLength } = body; const result = {}; result['type'] = 'recruit'; - result['email'] = user.email; // 이메일 하나 + result['email'] = author.email; // 이메일 하나 result['data'] = { title, hName: hDong.name, diff --git a/server/src/common/repositories/course.repository.ts b/server/src/common/repositories/course.repository.ts index e8050f4..97a3fb7 100644 --- a/server/src/common/repositories/course.repository.ts +++ b/server/src/common/repositories/course.repository.ts @@ -56,6 +56,7 @@ export class CourseRepository extends Repository { ]) .offset((page - 1) * pageSize) .limit(pageSize) + .orderBy("course.id", "DESC") .getMany(); } async findOneById(id: number): Promise { diff --git a/server/src/common/repositories/recruit.repository.ts b/server/src/common/repositories/recruit.repository.ts index 3f95ce3..cf49cbc 100644 --- a/server/src/common/repositories/recruit.repository.ts +++ b/server/src/common/repositories/recruit.repository.ts @@ -39,6 +39,7 @@ export class RecruitRepository extends Repository { "h_dong.name", ]) .where("recruit.id = :recruitId", { recruitId }) + .orderBy("recruit.id", "DESC") .getRawOne(); } @@ -94,6 +95,7 @@ export class RecruitRepository extends Repository { .groupBy("recruit.id") .offset((page - 1) * pageSize) .limit(pageSize) + .orderBy("recruit.id", "DESC") .getRawMany(); }