Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/entities/home/hooks/homeHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useOAuthStore } from "@/src/features/login/model";
import { HOME_NOTICE_ENDPOINT, HOME_SEARCH_POPULAR_ENDPOINT } from "@/src/shared/api";
import { useHomeMaxTime } from "@/src/features/home/model/homeStore";
import { useDebounce } from "@/src/shared/hooks/useDebounce/useDebounce";
import { ApiCategory, CATEGORY_MAP } from "@/src/features/home/hooks/hooks";
import { ApiCategory, CATEGORY_MAP } from "@/src/features/home/model/model";

export const useNoticeInfinite = () => {
const pinpointId = useOAuthStore(state => state.pinPointId);
Expand Down
1 change: 1 addition & 0 deletions src/entities/listings/hooks/useListingDetailHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ export const useListingFilterDetail = <T>() => {
return useQuery<IResponse<T>, Error, T>({
queryKey: ["pinpoint"],
staleTime: 1000 * 60 * 5,
placeholderData: previousData => previousData,
queryFn: () => PostBasicRequest<T, IResponse<T>, {}, IResponse<T>>(endPoint["pinpoint"], "get"),
select: response => {
if (response.data === undefined) {
Expand Down
66 changes: 38 additions & 28 deletions src/features/home/hooks/hooks.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,8 @@
import { GlobalBuilding } from "@/src/assets/icons/home/globalBuilding";
import { GlobalNoticeIncon } from "@/src/assets/icons/home/globalDoc";
import { GlobalHouse } from "@/src/assets/icons/home/globalHouse";
import { GlobalMapPin } from "@/src/assets/icons/home/globalMappin";
import { GlobalPerson } from "@/src/assets/icons/home/globalPerson";
import {
GlobalListType,
GlobalSearchSection,
SearchCategory,
} from "@/src/entities/home/model/type";
import { ReactNode } from "react";

export const SEARCH_CATEGORY_CONFIG: Record<SearchCategory, { label: string; icon: ReactNode }> = {
notices: { label: "공고명", icon: <GlobalNoticeIncon /> },
complexes: { label: "단지명", icon: <GlobalBuilding /> },
targetGroups: { label: "모집대상", icon: <GlobalPerson /> },
regions: { label: "지역", icon: <GlobalMapPin /> },
houseTypes: { label: "주택유형", icon: <GlobalHouse /> },
};
import { GlobalListType, GlobalSearchSection } from "@/src/entities/home/model/type";
import { useRouter } from "next/navigation";
import { useHomeSheetStore } from "@/src/features/home/model/homeStore";
import { useOAuthStore } from "@/src/features/login/model";
import { PinPointPlace } from "@/src/entities/listings/model/type";

export const useHomeGlobalSearch = (globalData?: GlobalListType): GlobalSearchSection[] => {
if (!globalData) return [];
Expand Down Expand Up @@ -50,13 +36,37 @@ export const useHomeGlobalSearch = (globalData?: GlobalListType): GlobalSearchSe
];
};

export const CATEGORY_MAP = {
notices: "NOTICE",
complexes: "COMPLEX",
targetGroups: "TARGET_GROUP",
regions: "REGION",
houseTypes: "HOUSE_TYPE",
} as const;
export const usePinhouseRouter = () => {
const router = useRouter();
const closeSheet = useHomeSheetStore(s => s.closeSheet);
const replaceRouter = () => {
router.replace("/home");
closeSheet();
};

export type SearchCategoryMap = keyof typeof CATEGORY_MAP;
export type ApiCategory = (typeof CATEGORY_MAP)[SearchCategoryMap];
const handleSetPinpoint = () => {
router.push("/mypage/pinpoints");
};

return {
replaceRouter,
handleSetPinpoint,
};
};

export const usePinpointRowBox = (data: PinPointPlace["pinPoints"] | null) => {
const pinpoints = data ?? null;
const pinPointId = useOAuthStore(s => s.pinPointId);
const setPinPointId = useOAuthStore(s => s.setPinPointId);
const setPinPointName = useOAuthStore(s => s.setPinpointName);
const onChangePinpoint = ({ id, name }: { id: string; name: string }) => {
setPinPointId(id);
setPinPointName(name);
};

return {
pinpoints,
pinPointId,
onChangePinpoint,
};
};
26 changes: 26 additions & 0 deletions src/features/home/model/model.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { SearchCategory } from "@/src/entities/home/model/type";
import { ReactNode } from "react";
import { GlobalNoticeIncon } from "@/src/assets/icons/home/globalDoc";
import { GlobalBuilding } from "@/src/assets/icons/home/globalBuilding";
import { GlobalPerson } from "@/src/assets/icons/home/globalPerson";
import { GlobalMapPin } from "@/src/assets/icons/home/globalMappin";
import { GlobalHouse } from "@/src/assets/icons/home/globalHouse";

export const SEARCH_CATEGORY_CONFIG: Record<SearchCategory, { label: string; icon: ReactNode }> = {
notices: { label: "공고명", icon: <GlobalNoticeIncon /> },
complexes: { label: "단지명", icon: <GlobalBuilding /> },
targetGroups: { label: "모집대상", icon: <GlobalPerson /> },
regions: { label: "지역", icon: <GlobalMapPin /> },
houseTypes: { label: "주택유형", icon: <GlobalHouse /> },
};

export const CATEGORY_MAP = {
notices: "NOTICE",
complexes: "COMPLEX",
targetGroups: "TARGET_GROUP",
regions: "REGION",
houseTypes: "HOUSE_TYPE",
} as const;

export type SearchCategoryMap = keyof typeof CATEGORY_MAP;
export type ApiCategory = (typeof CATEGORY_MAP)[SearchCategoryMap];
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Button } from "@/src/shared/lib/headlessUi";
import { cn } from "@/lib/utils";

type PinpointSelectedButtonType = {
mode: "pinpoints" | "maxTime";
handleSetPinpoint: () => void;
};

export const PinpointSelectedButton = ({ mode, handleSetPinpoint }: PinpointSelectedButtonType) => {
return (
<div className="flex gap-3">
<Button
className={cn(
"flex-1 border-greyscale-grey-100 bg-white text-sm font-medium text-gray-800",
mode === "maxTime" ? "hidden" : "block"
)}
variant="outline"
radius="sm"
onClick={handleSetPinpoint}
>
핀포인트 설정
</Button>
<Button className="flex-1 bg-[#2E2A3B] text-sm font-medium text-white" radius="sm">
저장하기
</Button>
</div>
);
};
58 changes: 26 additions & 32 deletions src/features/home/ui/components/homeFullSheet.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
"use client";
import { homeSheetParseObject } from "@/src/features/listings/model";
import { AnimatePresence, motion } from "framer-motion";
import { useRouter, useSearchParams } from "next/navigation";
import { useSearchParams } from "next/navigation";
import { useHomeSheetStore } from "../../model/homeStore";
import { useMemo } from "react";
import { PinpointRowBox } from "./pinpointRowBoxs";
import { MaxTimeSliderBox } from "./maxTime";
import { Button } from "@/src/shared/lib/headlessUi";
import { cn } from "@/lib/utils";
import { usePinhouseRouter } from "@/src/features/home/hooks/hooks";
import { PinpointSelectedButton } from "@/src/features/home/ui/components/components/pinpointSelectedButton";

export const HomeSheet = () => {
const open = useHomeSheetStore(s => s.open);
const closeSheet = useHomeSheetStore(s => s.closeSheet);
const searchParams = useSearchParams();

const mode = useMemo(() => {
return homeSheetParseObject(searchParams);
}, [searchParams]);
const { replaceRouter, handleSetPinpoint } = usePinhouseRouter();

const router = useRouter();
const replaceRouter = () => {
router.replace("/home");
closeSheet();
};

const handleSetPinpoint = () => {
router.push("/mypage/pinpoints");
};
return (
<AnimatePresence>
{open && (
Expand Down Expand Up @@ -64,26 +56,28 @@ export const HomeSheet = () => {
>
{mode?.key === "pinpoints" && <PinpointRowBox />}
{mode?.key === "maxTime" && <MaxTimeSliderBox />}

<div className="flex gap-3">
<Button
className={cn(
"flex-1 border-greyscale-grey-100 bg-white text-sm font-medium text-gray-800",
mode?.key === "maxTime" ? "hidden" : "block"
)}
variant="outline"
radius="sm"
onClick={handleSetPinpoint}
>
핀포인트 설정
</Button>
<Button
className="flex-1 bg-[#2E2A3B] text-sm font-medium text-white"
radius="sm"
>
저장하기
</Button>
</div>
{!mode ? null : (
<PinpointSelectedButton mode={mode?.key} handleSetPinpoint={handleSetPinpoint} />
)}
{/*<div className="flex gap-3">*/}
{/* <Button*/}
{/* className={cn(*/}
{/* "flex-1 border-greyscale-grey-100 bg-white text-sm font-medium text-gray-800",*/}
{/* mode?.key === "maxTime" ? "hidden" : "block"*/}
{/* )}*/}
{/* variant="outline"*/}
{/* radius="sm"*/}
{/* onClick={handleSetPinpoint}*/}
{/* >*/}
{/* 핀포인트 설정*/}
{/* </Button>*/}
{/* <Button*/}
{/* className="flex-1 bg-[#2E2A3B] text-sm font-medium text-white"*/}
{/* radius="sm"*/}
{/* >*/}
{/* 저장하기*/}
{/* </Button>*/}
{/*</div>*/}
</motion.div>
</div>
</motion.div>
Expand Down
20 changes: 10 additions & 10 deletions src/features/home/ui/components/pinpointRowBoxs.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { useListingFilterDetail } from "@/src/entities/listings/hooks/useListingDetailHooks";
import { PinPointPlace } from "@/src/entities/listings/model/type";
import { useOAuthStore } from "@/src/features/login/model";
import { PinpointItem } from "./components/pinpointId";
import { PinpointRowBoxSkeleton } from "./skeleton/skeleton";
import { usePinpointRowBox } from "@/src/features/home/hooks/hooks";

export const PinpointRowBox = () => {
const { data } = useListingFilterDetail<PinPointPlace>();
const pinpoints = data?.pinPoints;
const pinPointId = useOAuthStore(s => s.pinPointId);
const setPinPointId = useOAuthStore(s => s.setPinPointId);
const setPinPointName = useOAuthStore(s => s.setPinpointName);
const onChangePinpoint = ({ id, name }: { id: string; name: string }) => {
setPinPointId(id);
setPinPointName(name);
};
const { data, isLoading } = useListingFilterDetail<PinPointPlace>();
const pin = data?.pinPoints ?? null;
const { pinpoints, pinPointId, onChangePinpoint } = usePinpointRowBox(pin);

if (!pinpoints) {
return <PinpointRowBoxSkeleton />;
}

return (
<div className="flex flex-col pt-4">
<ul className="flex flex-col divide-y">
Expand Down
21 changes: 21 additions & 0 deletions src/features/home/ui/components/skeleton/skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Skeleton } from "@/src/shared/ui/skeleton/skeleton";

const ITEMS = 3;

export const PinpointRowBoxSkeleton = () => {
return (
<div className="flex flex-col pt-4">
<ul className="flex flex-col divide-y">
{Array.from({ length: ITEMS }).map((_, index) => (
<li key={index} className="p-2">
<div className="mb-1 flex min-h-[22px] items-center gap-2">
<Skeleton className="h-4 w-32" />
<Skeleton className="h-4 w-12 rounded" />
</div>
<Skeleton className="mb-2 h-4 w-3/4" />
</li>
))}
</ul>
</div>
);
};
2 changes: 1 addition & 1 deletion src/features/home/ui/result/homeResultSectionHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SearchCategory } from "@/src/entities/home/model/type";
import { SEARCH_CATEGORY_CONFIG } from "../../hooks/hooks";
import { SEARCH_CATEGORY_CONFIG } from "@/src/features/home/model/model";

interface HomeResultSectionHeaderProps {
category: SearchCategory;
Expand Down
2 changes: 2 additions & 0 deletions src/features/listings/model/listingsModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from "@/src/entities/listings/model/type";
import { PinPoint, PinPointMap } from "@/src/shared/ui/dropDown/deafult/type";
import { SectionLabelMap, SectionMap } from "./filterPanelModel";
import { useMemo } from "react";

export const REGION_CHECKBOX = [
{
Expand Down Expand Up @@ -349,6 +350,7 @@ export const homeSheetParseObject = (searchParams: URLSearchParams): HomeSheetRe
label,
};
};

// 사용처: 검색 결과가 없을 때/빈 검색어 화면에서 추천 태그 클릭 핸들러와 인기 키워드 전달
// - listingsSearchResult/components/searchNoResultView.tsx
// - listingsSearchResult/components/searchEmptyQueryView.tsx
Expand Down