From 9f5044046b81c0e5b791c61039d1f2b0b46615b9 Mon Sep 17 00:00:00 2001 From: YermIm Date: Thu, 26 Mar 2026 23:26:37 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=EC=83=81=EB=8B=A8=EC=97=90=20?= =?UTF-8?q?=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/icon/chevron/chervon-left.svg | 2 +- src/pages/ads/list/CampaignDetail.tsx | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/assets/icon/chevron/chervon-left.svg b/src/assets/icon/chevron/chervon-left.svg index dc7b444e..eca1cf74 100644 --- a/src/assets/icon/chevron/chervon-left.svg +++ b/src/assets/icon/chevron/chervon-left.svg @@ -1,3 +1,3 @@ - + diff --git a/src/pages/ads/list/CampaignDetail.tsx b/src/pages/ads/list/CampaignDetail.tsx index 1e545975..a18aa4b0 100644 --- a/src/pages/ads/list/CampaignDetail.tsx +++ b/src/pages/ads/list/CampaignDetail.tsx @@ -1,4 +1,4 @@ -import { useParams } from "react-router-dom"; +import { useNavigate, useParams } from "react-router-dom"; import type { TPlatform } from "@/types/ads/campaign"; @@ -15,6 +15,7 @@ import Modal from "@/components/common/modal/Modal"; import ModalContent from "@/components/common/modal/ModalContent"; import { updateCampaignStatus } from "@/api/ads/ads"; +import LeftChevronIcon from "@/assets/icon/chevron/chervon-left.svg?react"; import WarnCircleIcon from "@/assets/icon/common/warn-circle.svg?react"; export default function CampaignDetail() { @@ -29,6 +30,8 @@ export default function CampaignDetail() { projectId ? Number(projectId) : null, ); + const navigate = useNavigate(); + const stopControl = useControlModal({ successMessage: "해당 캠페인의 모든 광고 운영이 중단되었습니다.", errorMessage: "중단 처리에 실패하였습니다.", @@ -67,10 +70,17 @@ export default function CampaignDetail() { return (
-
+
{/* header */}
+

{data.name}

Date: Fri, 27 Mar 2026 19:42:47 +0900 Subject: [PATCH 2/7] =?UTF-8?q?refactor:=20=EC=BA=A0=ED=8E=98=EC=9D=B8=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EC=A0=95=EB=B3=B4=20=EB=B0=B0=EC=B9=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ads/list/CampaignDetail.tsx | 86 +++++++++++++++++++-------- 1 file changed, 60 insertions(+), 26 deletions(-) diff --git a/src/pages/ads/list/CampaignDetail.tsx b/src/pages/ads/list/CampaignDetail.tsx index a18aa4b0..a2c37e32 100644 --- a/src/pages/ads/list/CampaignDetail.tsx +++ b/src/pages/ads/list/CampaignDetail.tsx @@ -1,3 +1,4 @@ +import React from "react"; import { useNavigate, useParams } from "react-router-dom"; import type { TPlatform } from "@/types/ads/campaign"; @@ -7,8 +8,6 @@ import { useCampaignDetail } from "@/hooks/ads/useCampaignDetail"; import { useControlModal } from "@/hooks/ads/useControlModal"; import AdListTable from "@/components/ads/AdListTable"; -import CampaignInfoCard from "@/components/ads/CampaignInfoCard"; -import PlatformCard from "@/components/ads/PlatformCard"; import Badge from "@/components/common/badge/Badge"; import ControlBox from "@/components/common/controlbox/ControlBox"; import Modal from "@/components/common/modal/Modal"; @@ -17,6 +16,15 @@ import ModalContent from "@/components/common/modal/ModalContent"; import { updateCampaignStatus } from "@/api/ads/ads"; import LeftChevronIcon from "@/assets/icon/chevron/chervon-left.svg?react"; import WarnCircleIcon from "@/assets/icon/common/warn-circle.svg?react"; +import GoogleLogo from "@/assets/logo/social-logo/circle/google-circle.svg?react"; +import KakaoLogo from "@/assets/logo/social-logo/circle/kakao-circle.svg?react"; +import NaverLogo from "@/assets/logo/social-logo/circle/naver-circle.svg?react"; + +const LogoMap: Record = { + kakao: , + google: , + naver: , +}; export default function CampaignDetail() { const { orgId, projectId } = useParams<{ @@ -81,42 +89,68 @@ export default function CampaignDetail() { 광고 운영 관리 -
-

{data.name}

- - {data.status === "ON_GOING" - ? "운영 중" - : data.status === "PAUSED" - ? "중단" - : "종료"} - -
- {data.description && ( -
-

- {data.description} -

+ +
+
+
+

{data.name}

+ + {data.status === "ON_GOING" + ? "운영 중" + : data.status === "PAUSED" + ? "중단" + : "종료"} + +
+ + {data.createdAt.replaceAll("-", ".")} 등록 +
- )} + +
+ 예산 {data.budget.toLocaleString()}원 + · +
+ {data.providers.map((provider) => { + const platform = provider.toLowerCase() as TPlatform; + return ( +
+ {LogoMap[platform] || null} +
+ ); + })} +
+
+ + {data.description && ( +
+

+ {data.description} +

+
+ )} +
{/* card section */} -
+ {/*
p.toLowerCase() as TPlatform, - )} + platforms={data.providers.map((p) => p.toLowerCase() as TPlatform)} className="flex-1 min-w-[320px] w-full" /> -
+
*/}
{/* ads list */} From f6b9d000f27160f7f04ffb34ed6c66a53177389d Mon Sep 17 00:00:00 2001 From: YermIm Date: Fri, 27 Mar 2026 19:45:15 +0900 Subject: [PATCH 3/7] =?UTF-8?q?refactor:=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ads/list/CampaignDetail.tsx | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/pages/ads/list/CampaignDetail.tsx b/src/pages/ads/list/CampaignDetail.tsx index a2c37e32..0782f6f1 100644 --- a/src/pages/ads/list/CampaignDetail.tsx +++ b/src/pages/ads/list/CampaignDetail.tsx @@ -139,19 +139,6 @@ export default function CampaignDetail() {
- {/* card section */} - {/*
- - p.toLowerCase() as TPlatform)} - className="flex-1 min-w-[320px] w-full" - /> -
*/} -
{/* ads list */} {isAdLoading ? ( From 57c1d3a0db1e40d0b44980a872e54762b795233b Mon Sep 17 00:00:00 2001 From: YermIm Date: Fri, 27 Mar 2026 20:50:04 +0900 Subject: [PATCH 4/7] =?UTF-8?q?refactor:=20=EA=B4=91=EA=B3=A0=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=EC=A0=95=EB=B3=B4=20UI=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ads/AdDetailContent.tsx | 32 +++++++++++++++----------- src/components/ads/AdRow.tsx | 16 ++++++------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/components/ads/AdDetailContent.tsx b/src/components/ads/AdDetailContent.tsx index 93c68d33..2c40cb6e 100644 --- a/src/components/ads/AdDetailContent.tsx +++ b/src/components/ads/AdDetailContent.tsx @@ -75,17 +75,19 @@ export default function AdDetailContent({ }; return ( -
-
-
- -
- {/* description */} +
+
+ {/* description */} +
+ 광고 소재

{ad.description}

+
- {/* tags */} + {/* tags */} +
+ 타겟
{tags.length > 0 ? ( tags.map((tag, idx) => ( @@ -93,7 +95,7 @@ export default function AdDetailContent({ key={idx} variant="running" size="sm" - className="border border-bg-text-sub bg-bg-surface text-text-sub font-normal px-3" + className="border border-bg-disabled bg-white text-text-sub px-3" > #{tag} @@ -104,10 +106,13 @@ export default function AdDetailContent({ )}
+
- {/* link */} -
-
+ {/* link */} +
+ 랜딩 URL +
+
{ad.landingUrl} @@ -126,9 +131,8 @@ export default function AdDetailContent({
-
-
-
+
+
{/* status badge */} -
+
- {/* title */} -
- {name} -
- {/* platform */} -
+
{LogoMap[platform]}
+ {/* title */} +
+ {name} +
+ {/* chevron */} -
+
Date: Fri, 27 Mar 2026 22:57:56 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20controlBox=20=EB=82=B4=EC=9A=A9=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ads/AdDetailContent.tsx | 79 +++++++------------- src/components/common/modal/ModalContent.tsx | 2 +- 2 files changed, 28 insertions(+), 53 deletions(-) diff --git a/src/components/ads/AdDetailContent.tsx b/src/components/ads/AdDetailContent.tsx index 2c40cb6e..63452183 100644 --- a/src/components/ads/AdDetailContent.tsx +++ b/src/components/ads/AdDetailContent.tsx @@ -39,14 +39,8 @@ export default function AdDetailContent({ }); const trackControl = useControlModal({ - successMessage: "트래킹이 활성화되었습니다.", - errorMessage: "트래킹 활성화에 실패했습니다.", - onSuccess: refetchAds, - }); - - const stopTrackControl = useControlModal({ - successMessage: "트래킹이 중단되었습니다.", - errorMessage: "트래킹 중단에 실패했습니다.", + successMessage: "트래킹 링크가 발급되었습니다.", + errorMessage: "트래킹 링크 발급에 실패했습니다.", onSuccess: refetchAds, }); @@ -76,7 +70,7 @@ export default function AdDetailContent({ return (
-
+
{/* description */}
광고 소재 @@ -131,34 +125,33 @@ export default function AdDetailContent({
-
+
handleCopy(ad.trackingUrl!) : trackControl.openModal } buttonDisabled={false} - containerClassName={`${isTrackingActive ? "bg-status-red/7 border-status-red" : "bg-chart-3/7 border-chart-3"} px-6 py-4 tablet:flex-col tablet:items-start tablet:gap-4`} - titleClassName={`${isTrackingActive ? "text-status-red" : "text-chart-3"} font-heading3`} + containerClassName="bg-status-blue/7 border-status-blue px-6 py-4" + titleClassName="text-status-blue font-heading4 -mb-1" descriptionClassName="font-caption text-text-sub" - buttonSize="big" - buttonClassName={`${ - isTrackingActive ? "bg-status-red" : "bg-chart-3" - } font-body1 tablet:w-full `} + buttonSize="small" + buttonClassName="bg-status-blue font-body2 tablet:w-full" /> +
- {/* 트래킹 활성화 */} + {/* 트래킹 링크 발급 */} } - title="트래킹을 활성화하시겠습니까?" + title="트래킹 링크를 발급하시겠습니까?" description={ <> - 실시간 광고 성과 데이터를 수집하여 + 발급된 링크를 복사하여 광고 플랫폼에 등록하면
- 분석 리포트에 즉시 반영합니다. + 트래킹을 활성화할 수 있습니다. } - buttonText="시작하기" + buttonText="발급하기" onConfirm={() => trackControl.handleConfirm(async () => { if (!ad.landingUrl) { + toast.error( + "광고에 등록된 랜딩 URL이 없어 발급이 불가능합니다.", + ); throw new Error("랜딩 URL이 없습니다."); } await createTrackingUrl(Number(orgId), ad.id, ad.landingUrl); @@ -224,27 +220,6 @@ export default function AdDetailContent({ />
- {/* 트래킹 중단 */} - - } - title="트래킹을 중단하시겠습니까?" - description="데이터 수집이 중단되어 분석 리포트에 공백이 생길 수 있습니다." - buttonText="중단하기" - onConfirm={() => - stopTrackControl.handleConfirm(async () => { - /* API 호출 */ - }) - } - isLoading={stopTrackControl.isLoading} - variant="danger" - /> - - {/* 광고 소재 중단 */} {isLoading ? "처리 중.." : buttonText} From 9562c5b41ca0db6d39ee066525b0426ac5fa2876 Mon Sep 17 00:00:00 2001 From: YermIm Date: Fri, 27 Mar 2026 23:14:15 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20=EB=A0=88=EC=9D=B4=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ads/AdRow.tsx | 4 ++-- src/pages/ads/list/CampaignDetail.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/ads/AdRow.tsx b/src/components/ads/AdRow.tsx index a73e6d5e..b5d647a0 100644 --- a/src/components/ads/AdRow.tsx +++ b/src/components/ads/AdRow.tsx @@ -42,7 +42,7 @@ export default function AdRow({ } > {/* status badge */} -
+
{/* platform */} -
+
{LogoMap[platform]}
diff --git a/src/pages/ads/list/CampaignDetail.tsx b/src/pages/ads/list/CampaignDetail.tsx index 0782f6f1..336f024a 100644 --- a/src/pages/ads/list/CampaignDetail.tsx +++ b/src/pages/ads/list/CampaignDetail.tsx @@ -91,7 +91,7 @@ export default function CampaignDetail() {
-
+

{data.name}

Date: Sat, 28 Mar 2026 00:17:24 +0900 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0?= =?UTF-8?q?=20=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ads/list/CampaignDetail.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ads/list/CampaignDetail.tsx b/src/pages/ads/list/CampaignDetail.tsx index 336f024a..02dfd716 100644 --- a/src/pages/ads/list/CampaignDetail.tsx +++ b/src/pages/ads/list/CampaignDetail.tsx @@ -83,7 +83,7 @@ export default function CampaignDetail() { {/* header */}