diff --git a/app/components/common/NavigateHeader.tsx b/app/components/common/NavigateHeader.tsx index 3188c32..15529bd 100644 --- a/app/components/common/NavigateHeader.tsx +++ b/app/components/common/NavigateHeader.tsx @@ -1,13 +1,17 @@ +import type { ReactNode } from "react"; + type Props = { - title: string; // 텍스트 + title: ReactNode; // 텍스트 onBack?: () => void; //onBack={() => history.back()} 뒤로가기 bgClassName?: string; + titleClassName?: string; }; export default function NavigationHeader({ title, onBack, bgClassName, + titleClassName, }: Props) { const bg = bgClassName ?? "bg-[#FFFFFF]"; @@ -39,7 +43,9 @@ export default function NavigationHeader({
-
{title}
+
+ {title} +
{/* 오른쪽 여백 맞추기 */} diff --git a/app/routes/mypage/likes/likes-content.tsx b/app/routes/mypage/likes/likes-content.tsx index ef5e8a6..cdcb2cb 100644 --- a/app/routes/mypage/likes/likes-content.tsx +++ b/app/routes/mypage/likes/likes-content.tsx @@ -94,11 +94,16 @@ const CAMPAIGN_SORT_PARAM_MAP: Record = { export default function MyPageLikes() { useHideHeader(true); const navigate = useNavigate(); + const DEFAULT_SORT_LABEL = "매칭률 순"; const [activeTab, setActiveTab] = useState<"brand" | "campaign">("brand"); const [isFilterOpen, setIsFilterOpen] = useState(false); - const [brandSortOption, setBrandSortOption] = useState("정렬 필터"); - const [campaignSortOption, setCampaignSortOption] = useState("정렬 필터"); - const [pendingSort, setPendingSort] = useState("정렬 필터"); + const [brandSortOption, setBrandSortOption] = useState(DEFAULT_SORT_LABEL); + const [campaignSortOption, setCampaignSortOption] = useState( + DEFAULT_SORT_LABEL, + ); + const [brandSortApplied, setBrandSortApplied] = useState(false); + const [campaignSortApplied, setCampaignSortApplied] = useState(false); + const [pendingSort, setPendingSort] = useState(DEFAULT_SORT_LABEL); const [loading, setLoading] = useState(false); const [brandLikesApi, setBrandLikesApi] = useState([]); const [campaignLikesApi, setCampaignLikesApi] = useState([]); @@ -107,15 +112,25 @@ export default function MyPageLikes() { const currentSortOption = activeTab === "brand" ? brandSortOption : campaignSortOption; + const currentSortApplied = + activeTab === "brand" ? brandSortApplied : campaignSortApplied; const getSortButtonLabel = () => currentSortOption; - const isFiltered = currentSortOption !== "정렬 필터"; + const isFiltered = currentSortApplied; const brandSortOptions = useMemo( - () => ["매칭률 순", "인기 순", "신규 순"].map((label) => ({ label, value: label })), + () => + ["매칭률 순", "인기 순", "신규 순"].map((label) => ({ + label, + value: label, + })), [], ); const campaignSortOptions = useMemo( - () => ["매칭률 순", "인기 순", "금액 순", "마감 순"].map((label) => ({ label, value: label })), + () => + ["매칭률 순", "인기 순", "금액 순", "마감 순"].map((label) => ({ + label, + value: label, + })), [], ); @@ -124,11 +139,19 @@ export default function MyPageLikes() { setIsFilterOpen(true); }; + useEffect(() => { + if (!isFilterOpen) { + setPendingSort(currentSortOption); + } + }, [currentSortOption, isFilterOpen]); + const applySort = () => { if (activeTab === "brand") { setBrandSortOption(pendingSort); + setBrandSortApplied(true); } else { setCampaignSortOption(pendingSort); + setCampaignSortApplied(true); } setIsFilterOpen(false); }; @@ -202,7 +225,9 @@ export default function MyPageLikes() { "/api/v1/users/me/favorites/campaign", { params: { - sort: CAMPAIGN_SORT_PARAM_MAP[campaignSortOption] ?? "MATCH_SCORE", + sort: + CAMPAIGN_SORT_PARAM_MAP[campaignSortOption] ?? + "MATCH_SCORE", }, }, ); @@ -269,14 +294,18 @@ export default function MyPageLikes() { const toggleCampaignLike = async (campaignId: number) => { setCampaignLikesApi((prev) => - prev.map((c) => (c.id === campaignId ? { ...c, isLiked: !c.isLiked } : c)), + prev.map((c) => + c.id === campaignId ? { ...c, isLiked: !c.isLiked } : c, + ), ); try { await axiosInstance.post(`/api/v1/campaigns/${campaignId}/like`); } catch (error) { console.error("캠페인 좋아요 토글 실패:", error); setCampaignLikesApi((prev) => - prev.map((c) => (c.id === campaignId ? { ...c, isLiked: !c.isLiked } : c)), + prev.map((c) => + c.id === campaignId ? { ...c, isLiked: !c.isLiked } : c, + ), ); } }; @@ -285,7 +314,11 @@ export default function MyPageLikes() {
- navigate(-1)} /> + navigate(-1)} + />
@@ -331,8 +364,8 @@ export default function MyPageLikes() { onClick={openSortSheet} className={`flex items-center w-fit h-7 pl-3 pr-1.5 rounded-full border text-[14px] font-Pretendard ${ isFiltered - ? "border-core-70 text-core-1 bg-core-70" - : "border-core-2 text-gray-2 bg-white text-title3" + ? "border-core-3 text-core-1 bg-core-2" + : "border-core-2 text-text-gray2 bg-white text-title3" }`} > {getSortButtonLabel()} @@ -356,63 +389,63 @@ export default function MyPageLikes() { {loading ? ( ) : ( -
- {activeTab === "brand" - ? brandLikes.length > 0 - ? brandLikes.map((brand) => ( -
-
- {brand.logoUrl ? ( - {brand.name} - ) : ( - brand.name - )} -
+
+ {activeTab === "brand" ? ( + brandLikes.length > 0 ? ( + brandLikes.map((brand) => ( +
+
+ {brand.logoUrl ? ( + {brand.name} + ) : ( + brand.name + )} +
-
-
-
- {brand.name} -
-
-
- - 매칭률 {/*수정*/} - {" "} - - {brand.matchRate}% - +
+
+
+ {brand.name} +
+
+
+ + 매칭률 {/*수정*/} + {" "} + + {brand.matchRate}% + +
+
-
-
-
- {brand.tags.join(" ")} +
+ {brand.tags.join(" ")} +
-
- )) - : ( + )) + ) : (
찜한 브랜드가 없습니다.
) - : campaignLikes.length > 0 - ? campaignLikes.map((campaign) => ( + ) : campaignLikes.length > 0 ? ( + campaignLikes.map((campaign) => (
-
{/*수정*/} +
+ {" "} + {/*수정*/} {campaign.dday} @@ -447,7 +482,7 @@ export default function MyPageLikes() {
- 매칭률 {/*수정*/} + 매칭률 {/*수정*/} {" "} {campaign.matchRate}% @@ -463,21 +498,25 @@ export default function MyPageLikes() {
-
{/*수정*/} +
+ {" "} + {/*수정*/} {campaign.title}
-
{/*수정*/} +
+ {" "} + {/*수정*/} 원고료: {campaign.reward.toLocaleString()}원
)) - : ( -
- 찜한 캠페인이 없습니다. -
- )} -
+ ) : ( +
+ 찜한 캠페인이 없습니다. +
+ )} +
)}
@@ -488,7 +527,9 @@ export default function MyPageLikes() { onChange={setPendingSort} onClose={() => setIsFilterOpen(false)} onApply={applySort} - options={activeTab === "brand" ? brandSortOptions : campaignSortOptions} + options={ + activeTab === "brand" ? brandSortOptions : campaignSortOptions + } title="정렬 필터" applyLabel="적용하기" />