diff --git a/react/src/api/service.api.ts b/react/src/api/service.api.ts index 2c397ef..8943de6 100644 --- a/react/src/api/service.api.ts +++ b/react/src/api/service.api.ts @@ -79,3 +79,10 @@ export function deleteApns(serviceCode: string) { `/v1/in/service/${serviceCode}/apns/delete`, ); } + +/** 서비스 삭제 */ +export function deleteService(serviceCode: string) { + return apiClient.post>("/v1/in/service/delete", { + service_code: serviceCode, + }); +} diff --git a/react/src/features/service/components/ServiceHeaderCard.tsx b/react/src/features/service/components/ServiceHeaderCard.tsx index 87f9351..d1b0fac 100644 --- a/react/src/features/service/components/ServiceHeaderCard.tsx +++ b/react/src/features/service/components/ServiceHeaderCard.tsx @@ -9,11 +9,13 @@ import { SERVICE_STATUS } from "../types"; interface ServiceHeaderCardProps { service: ServiceDetail; onShowApiKey: () => void; + onDelete: () => void; } export default function ServiceHeaderCard({ service, onShowApiKey, + onDelete, }: ServiceHeaderCardProps) { return (
@@ -62,13 +64,22 @@ export default function ServiceHeaderCard({
- - edit - 수정하기 - +
+ + + edit + 수정하기 + +
{/* 메타 정보 */} diff --git a/react/src/features/service/pages/ServiceDetailPage.tsx b/react/src/features/service/pages/ServiceDetailPage.tsx index f817d1b..4341f89 100644 --- a/react/src/features/service/pages/ServiceDetailPage.tsx +++ b/react/src/features/service/pages/ServiceDetailPage.tsx @@ -1,17 +1,19 @@ import { useState, useEffect, useCallback } from "react"; -import { useParams } from "react-router-dom"; +import { useParams, useNavigate } from "react-router-dom"; +import { toast } from "sonner"; import PageHeader from "@/components/common/PageHeader"; import CopyButton from "@/components/common/CopyButton"; import ServiceHeaderCard from "../components/ServiceHeaderCard"; import ServiceStatsCards from "../components/ServiceStatsCards"; import PlatformManagement from "../components/PlatformManagement"; -import { fetchServiceDetail, fetchApiKey } from "@/api/service.api"; +import { fetchServiceDetail, fetchApiKey, deleteService } from "@/api/service.api"; import { fetchDashboard } from "@/api/dashboard.api"; import type { ServiceDetail } from "../types"; import type { DashboardKpi } from "@/features/dashboard/types"; export default function ServiceDetailPage() { const { id } = useParams<{ id: string }>(); + const navigate = useNavigate(); // 데이터 상태 const [service, setService] = useState(null); @@ -26,6 +28,10 @@ export default function ServiceDetailPage() { const [fullApiKey, setFullApiKey] = useState(null); const [apiKeyLoading, setApiKeyLoading] = useState(false); + // 삭제 모달 상태 + const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); + const [deleting, setDeleting] = useState(false); + // 서비스 상세 + 통계 로드 const loadData = useCallback(async (serviceCode: string) => { setLoading(true); @@ -105,6 +111,21 @@ export default function ServiceDetailPage() { setFullApiKey(null); }; + // 서비스 삭제 + const handleDelete = async () => { + if (!id) return; + setDeleting(true); + try { + await deleteService(id); + toast.success("서비스가 삭제되었습니다."); + navigate("/services"); + } catch { + toast.error("서비스 삭제에 실패했습니다."); + } finally { + setDeleting(false); + } + }; + // 로딩 스켈레톤 if (loading) { return ( @@ -168,6 +189,7 @@ export default function ServiceDetailPage() { setShowDeleteConfirm(true)} /> + {/* 삭제 확인 모달 */} + {showDeleteConfirm && ( +
+
setShowDeleteConfirm(false)} + /> +
+
+
+ + warning + +
+

서비스 삭제

+
+

+ {service.serviceName} 서비스를 삭제하시겠습니까? +

+
+
+ info + 삭제된 서비스는 복구할 수 없습니다. +
+
+ info + 해당 서비스의 모든 기기 및 발송 이력이 비활성화됩니다. +
+
+
+ + +
+
+
+ )} + {/* API 키 확인 모달 */} {showApiKey && (