From eed40e6c513709fb43a9d2a36f3fd4aaa27074ab Mon Sep 17 00:00:00 2001 From: yeahsel Date: Wed, 18 Feb 2026 20:48:27 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A4=91=EA=B0=84=20=EC=9E=91=EC=97=85=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../proposal/sent-campaign-content.tsx | 6 +- .../proposal/sent-proposal-content.tsx | 6 +- .../chat/resuggest/resuggest-content.tsx | 4 +- .../matching/components/ProfileSelector.tsx | 18 ++--- .../components/Bubbles/ProposalMessage.tsx | 72 +++++++++++++++++-- 5 files changed, 80 insertions(+), 26 deletions(-) diff --git a/app/routes/business/proposal/sent-campaign-content.tsx b/app/routes/business/proposal/sent-campaign-content.tsx index abf04c7b..96495823 100644 --- a/app/routes/business/proposal/sent-campaign-content.tsx +++ b/app/routes/business/proposal/sent-campaign-content.tsx @@ -3,10 +3,11 @@ import { useSearchParams, useNavigate } from "react-router-dom"; import { getProposalDetail, type ProposalDetail } from "./api/proposal"; import { axiosInstance } from "../../../api/axios"; import { getBrandSummary, type BrandSummary } from "./api/brand"; -import Header from "../../../components/layout/Header"; import CampaignBrandCard from "../components/CampaignBrandCard"; import LoadingSpinner from "../../../components/common/LoadingSpinner"; import CampaignInfoGroup from "../components/CampaignInfoGroup"; +import { useHideHeader } from "../../../hooks/useHideHeader"; +import NavigationHeader from "../../../components/common/NavigateHeader"; import dropdownIcon from "../../../assets/arrow-down.svg"; import dropupIcon from "../../../assets/arrow-up.svg"; @@ -23,6 +24,7 @@ export default function SentCampaignContent() { const [brandUserId, setBrandUserId] = useState(null); const [brandCategory, setBrandCategory] = useState(null); const [isLoading, setIsLoading] = useState(true); + useHideHeader(true); const proposalId = searchParams.get("proposalId"); @@ -63,7 +65,7 @@ export default function SentCampaignContent() { return (
-
+ navigate(-1)} />
{/* 상단 브랜드 정보 및 채팅 섹션 */} diff --git a/app/routes/business/proposal/sent-proposal-content.tsx b/app/routes/business/proposal/sent-proposal-content.tsx index e81e08a6..69f3e370 100644 --- a/app/routes/business/proposal/sent-proposal-content.tsx +++ b/app/routes/business/proposal/sent-proposal-content.tsx @@ -4,8 +4,9 @@ import { getProposalDetail, type ProposalDetail } from "./api/proposal"; import { getBrandSummary, type BrandSummary } from "./api/brand"; import { getProfileCard, type ProfileCard } from "./api/user"; import { cancelCampaignProposal } from "./api/proposal"; +import { useHideHeader } from "../../../hooks/useHideHeader"; -import Header from "../../../components/layout/Header"; +import NavigationHeader from "../../../components/common/NavigateHeader"; import CampaignBrandCard from "../components/CampaignBrandCard"; import LoadingSpinner from "../../../components/common/LoadingSpinner"; import CampaignInfoGroup from "../components/CampaignInfoGroup"; @@ -20,6 +21,7 @@ export default function ProposalContent() { const [searchParams] = useSearchParams(); const [isContentOpen, setIsContentOpen] = useState(false); const navigate = useNavigate(); + useHideHeader(true); const [data, setData] = useState(null); const [brand, setBrand] = useState(null); @@ -100,7 +102,7 @@ export default function ProposalContent() { return (
-
+ navigate(-1)} />
{/* 브랜드 카드 및 제안 프로필 */} diff --git a/app/routes/chat/resuggest/resuggest-content.tsx b/app/routes/chat/resuggest/resuggest-content.tsx index b43431a0..7cd10ba1 100644 --- a/app/routes/chat/resuggest/resuggest-content.tsx +++ b/app/routes/chat/resuggest/resuggest-content.tsx @@ -199,7 +199,7 @@ export default function ReSuggestContent() { {/* 커스텀 브랜드 카드 디자인 */}
{/* 로고 영역 */} -
+
- + {brandDetail?.name || proposalData?.brandName || ""} diff --git a/app/routes/matching/components/ProfileSelector.tsx b/app/routes/matching/components/ProfileSelector.tsx index d32ed5b6..906afbd1 100644 --- a/app/routes/matching/components/ProfileSelector.tsx +++ b/app/routes/matching/components/ProfileSelector.tsx @@ -14,20 +14,10 @@ export default function ProfileSelector({ className="flex items-center justify-between w-full py-[14px] px-4 gap-2.5 rounded-xl border border-core-70 bg-bluegray-2" >
-
- - - -
+ + + + {username}
(null); const [modalState, setModalState] = useState<"confirm" | "success" | null>(null); + const [acceptFlowStarted, setAcceptFlowStarted] = useState(false); const isAlreadyProcessed = proposalStatus === "MATCHED" || proposalStatus === "REJECTED" || proposalStatus === "CANCELED"; const showButtons = proposalDirection === "BRAND_TO_CREATOR" && !isAlreadyProcessed && !actionDone; const handleAcceptClick = () => { if (isProcessing) return; + setAcceptFlowStarted(true); setModalState("confirm"); }; @@ -65,11 +67,13 @@ export default function ProposalMessage(props: Props) { setActionDone("accepted"); } else { setModalState(null); + setAcceptFlowStarted(false); alert(response.message || "수락 처리 중 오류가 발생했습니다."); } } catch (error) { console.error("제안 수락 실패:", error); setModalState(null); + setAcceptFlowStarted(false); alert("서버와 통신 중 에러가 발생했습니다."); } finally { setIsProcessing(false); @@ -77,11 +81,21 @@ export default function ProposalMessage(props: Props) { }; const handleReject = () => { + if (isProcessing) return; + if (acceptFlowStarted) return; + if (actionDone === "accepted") return; + navigate(`/business/proposal?type=received&proposalId=${proposalId}`, { state: { openReject: true }, }); }; + const closeAcceptModal = () => { + if (isProcessing) return; + setModalState(null); + setAcceptFlowStarted(false); +}; + const AcceptModal = () => { if (!modalState) return null; @@ -89,14 +103,14 @@ export default function ProposalMessage(props: Props) {
!isProcessing && setModalState(null)} + onClick={() => !isProcessing && closeAcceptModal()} />
{modalState === "confirm" && ( ); + if (kind === "APPLY_CARD") { + return ( +
+
+ {timeText ? ( +
+ {timeText} +
+ ) : null} + +
+
+
+ 지원 +
+ +
+
+ 캠페인 명 +
+ +
+
+ {campaignName} +
+ navigate(`/business/proposal?type=sent&proposalId=${proposalId}`)} /> +
+
+
+ +
+
+ 지원 내용 +
+ +
+ {bodyText} +
+
+
+
+
+ ); + } + + if (proposalDirection == "CREATOR_TO_BRAND") { return (
@@ -179,7 +239,7 @@ export default function ProposalMessage(props: Props) {
) : null} -
+
{kind === "RE_PROPOSAL_CARD" ? "재제안" : "제안"} @@ -288,7 +348,7 @@ export default function ProposalMessage(props: Props) {