import { useState } from "react"; import { useNavigate } from "react-router-dom"; import { toast } from "sonner"; import { AxiosError } from "axios"; import PageHeader from "@/components/common/PageHeader"; import CopyButton from "@/components/common/CopyButton"; import PlatformSelector from "../components/PlatformSelector"; import useShake from "@/hooks/useShake"; import { createService } from "@/api/service.api"; import type { ApiError } from "@/types/api"; import type { CreateServiceResponse } from "../types"; export default function ServiceRegisterPage() { const navigate = useNavigate(); // 폼 상태 const [serviceName, setServiceName] = useState(""); const [description, setDescription] = useState(""); const [relatedLink, setRelatedLink] = useState(""); const [androidChecked, setAndroidChecked] = useState(false); const [iosChecked, setIosChecked] = useState(false); const [iosAuthType, setIosAuthType] = useState<"p8" | "p12">("p8"); // 에러 상태 const [nameError, setNameError] = useState(false); const [nameErrorMsg, setNameErrorMsg] = useState("서비스 명을 입력해주세요."); const { triggerShake, cls } = useShake(); // 제출 상태 const [submitting, setSubmitting] = useState(false); // 모달 const [showConfirm, setShowConfirm] = useState(false); // API Key 모달 const [apiKeyResult, setApiKeyResult] = useState(null); const [showApiKeyModal, setShowApiKeyModal] = useState(false); // 등록 버튼 클릭 const handleRegister = () => { const trimmed = serviceName.trim(); if (!trimmed || trimmed.length < 2) { setNameError(true); setNameErrorMsg( !trimmed ? "서비스 명을 입력해주세요." : "서비스 명은 2자 이상이어야 합니다.", ); triggerShake(["name"]); return; } setShowConfirm(true); }; // 등록 확인 const handleConfirm = async () => { setShowConfirm(false); setSubmitting(true); try { const res = await createService({ serviceName: serviceName.trim(), description: description.trim() || null, }); setApiKeyResult(res.data.data); setShowApiKeyModal(true); } catch (err) { const axiosErr = err as AxiosError; const status = axiosErr.response?.status; const msg = axiosErr.response?.data?.msg; if (status === 409) { toast.error(msg ?? "이미 사용 중인 서비스 명입니다."); setNameError(true); setNameErrorMsg(msg ?? "이미 사용 중인 서비스 명입니다."); triggerShake(["name"]); } else { toast.error(msg ?? "서비스 등록에 실패했습니다. 다시 시도해주세요."); } } finally { setSubmitting(false); } }; // API Key 모달 닫기 → 상세 페이지 이동 const handleApiKeyModalClose = () => { setShowApiKeyModal(false); if (apiKeyResult) { navigate(`/services/${apiKeyResult.serviceCode}`); } }; return (
{/* 폼 카드 */}
{/* 1. 서비스 명 */}
{ setServiceName(e.target.value); if (e.target.value.trim()) setNameError(false); }} placeholder="서비스 명을 입력하세요" className={`w-full px-3 py-2.5 bg-white border rounded text-sm focus:outline-none focus:ring-2 focus:ring-[#2563EB] focus:border-transparent transition-shadow placeholder-gray-400 ${ nameError ? "border-red-500 ring-2 ring-red-500/15" : "border-gray-300" } ${cls("name")}`} /> {nameError && (
error {nameErrorMsg}
)}
{/* 2. 플랫폼 선택 */} {/* 4. 설명 */}