SPMS_WEB/react/src/features/service/components/ServiceHeaderCard.tsx
SEAN c872985f96 feat: 서비스 관리 삭제 기능 추가 (#49)
- service.api.ts: deleteService API 함수 추가 (POST /v1/in/service/delete)
- ServiceHeaderCard: 수정하기 버튼 옆 삭제하기 버튼 추가
- ServiceDetailPage: 삭제 확인 모달 및 핸들러 추가 (삭제 후 목록으로 이동)

Closes #49
2026-03-18 12:58:14 +09:00

140 lines
5.3 KiB
TypeScript

import { Link } from "react-router-dom";
import StatusBadge from "@/components/common/StatusBadge";
import CopyButton from "@/components/common/CopyButton";
import PlatformStatusIndicator from "./PlatformStatusIndicator";
import { formatNumber } from "@/utils/format";
import type { ServiceDetail } from "../types";
import { SERVICE_STATUS } from "../types";
interface ServiceHeaderCardProps {
service: ServiceDetail;
onShowApiKey: () => void;
onDelete: () => void;
}
export default function ServiceHeaderCard({
service,
onShowApiKey,
onDelete,
}: ServiceHeaderCardProps) {
return (
<div className="bg-white border border-gray-200 rounded-lg shadow-sm p-6 mb-6">
{/* 상단 행 */}
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<div className="size-14 rounded-xl bg-[#2563EB]/10 flex items-center justify-center">
<span className="material-symbols-outlined text-[#2563EB] text-3xl">
{service.serviceIcon || "hub"}
</span>
</div>
<div className="flex flex-col">
<div className="flex items-center gap-3">
<h2 className="text-2xl font-bold text-[#0f172a]">
{service.serviceName}
</h2>
<StatusBadge
variant={
service.status === SERVICE_STATUS.ACTIVE ? "success" : "error"
}
label={
service.status === SERVICE_STATUS.ACTIVE ? "활성" : "비활성"
}
/>
</div>
<div className="flex items-center gap-4 mt-1.5">
<div className="inline-flex items-center gap-1.5">
<span className="text-sm text-[#64748b] font-mono">
{service.serviceCode}
</span>
<CopyButton text={service.serviceCode} />
</div>
<span className="text-gray-300">|</span>
<button
onClick={onShowApiKey}
className="flex items-center gap-1 text-sm text-[#2563EB] hover:text-[#1d4ed8] transition-colors cursor-pointer"
>
<span
className="material-symbols-outlined"
style={{ fontSize: "14px" }}
>
vpn_key
</span>
<span className="font-medium">API </span>
</button>
</div>
</div>
</div>
<div className="flex items-center gap-2">
<button
onClick={onDelete}
className="border border-red-200 text-red-500 hover:bg-red-50 px-5 py-2.5 rounded text-sm font-medium transition flex items-center gap-2"
>
<span className="material-symbols-outlined text-base">delete</span>
<span></span>
</button>
<Link
to={`/services/${service.serviceCode}/edit`}
className="bg-[#2563EB] hover:bg-[#1d4ed8] text-white px-5 py-2.5 rounded text-sm font-medium transition shadow-sm flex items-center gap-2"
>
<span className="material-symbols-outlined text-base">edit</span>
<span></span>
</Link>
</div>
</div>
{/* 메타 정보 */}
<div className="mt-6 pt-5 border-t border-gray-100 grid grid-cols-2 sm:grid-cols-4 gap-6">
<div className="flex flex-col">
<p className="text-xs text-[#64748b] font-semibold uppercase tracking-wide">
</p>
<div className="flex items-center gap-2.5 mt-1.5">
{service.platforms ? (
<>
<PlatformStatusIndicator
platform="android"
credential={service.platforms.android}
/>
<PlatformStatusIndicator
platform="ios"
credential={service.platforms.ios}
/>
{!service.platforms?.android?.registered &&
!service.platforms?.ios?.registered && (
<span className="text-xs text-gray-400"></span>
)}
</>
) : (
<span className="text-xs text-gray-400"></span>
)}
</div>
</div>
<div className="flex flex-col">
<p className="text-xs text-[#64748b] font-semibold uppercase tracking-wide">
</p>
<p className="text-sm font-semibold text-[#0f172a] mt-1.5">
{formatNumber(service.deviceCount)}
</p>
</div>
<div className="flex flex-col">
<p className="text-xs text-[#64748b] font-semibold uppercase tracking-wide">
</p>
<p className="text-sm font-semibold text-[#0f172a] mt-1.5">
{service.createdAt?.slice(0, 10)}
</p>
</div>
<div className="flex flex-col">
<p className="text-xs text-[#64748b] font-semibold uppercase tracking-wide">
</p>
<p className="text-sm font-semibold text-[#0f172a] mt-1.5">
{service.updatedAt?.slice(0, 10) ?? "-"}
</p>
</div>
</div>
</div>
);
}