"use client"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { toast } from "sonner"; const DEFAULT_BASE = "http://localhost:3100/api/v1"; const PRESETS = [ { name: "채팅 완성", method: "POST", endpoint: "/chat/completions", body: '{"model":"gemini-2.0-flash","messages":[{"role":"user","content":"안녕하세요!"}],"temperature":0.7}' }, { name: "모델 목록", method: "GET", endpoint: "/models", body: "" }, { name: "사용량", method: "GET", endpoint: "/usage", body: "" }, { name: "API 키 목록", method: "GET", endpoint: "/api-keys", body: "" }, ]; export default function AiAssistantApiTestPage() { const [baseUrl, setBaseUrl] = useState( typeof window !== "undefined" ? (process.env.NEXT_PUBLIC_AI_ASSISTANT_API_URL || DEFAULT_BASE) : DEFAULT_BASE ); const [apiKey, setApiKey] = useState(""); const [method, setMethod] = useState("POST"); const [endpoint, setEndpoint] = useState("/chat/completions"); const [body, setBody] = useState(PRESETS[0].body); const [loading, setLoading] = useState(false); const [response, setResponse] = useState<{ status: number; statusText: string; data: unknown } | null>(null); const [responseTime, setResponseTime] = useState(null); const [copied, setCopied] = useState(false); const apply = (p: (typeof PRESETS)[0]) => { setMethod(p.method); setEndpoint(p.endpoint); setBody(p.body); }; const send = async () => { setLoading(true); setResponse(null); setResponseTime(null); const start = Date.now(); try { const headers: Record = { "Content-Type": "application/json" }; if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`; const opt: RequestInit = { method, headers }; if (method !== "GET" && body.trim()) { try { JSON.parse(body); opt.body = body; } catch { toast.error("JSON 형식 오류"); setLoading(false); return; } } const res = await fetch(`${baseUrl}${endpoint}`, opt); const elapsed = Date.now() - start; setResponseTime(elapsed); const ct = res.headers.get("content-type"); const data = ct?.includes("json") ? await res.json() : await res.text(); setResponse({ status: res.status, statusText: res.statusText, data }); toast.success(res.ok ? `성공 ${res.status}` : `실패 ${res.status}`); } catch (e) { setResponseTime(Date.now() - start); setResponse({ status: 0, statusText: "Network Error", data: { error: String(e) } }); toast.error("네트워크 오류"); } finally { setLoading(false); } }; const copyRes = () => { navigator.clipboard.writeText(JSON.stringify(response?.data, null, 2)); setCopied(true); toast.success("복사됨"); setTimeout(() => setCopied(false), 2000); }; const statusV = (s: number) => (s >= 200 && s < 300 ? "success" : s >= 400 ? "destructive" : "secondary"); return (

API 테스트

API를 직접 호출하여 테스트합니다.

API 설정
setBaseUrl(e.target.value)} />
setApiKey(e.target.value)} placeholder="sk-xxx" />
빠른 선택
{PRESETS.map((p, i) => ( ))}
요청
setEndpoint(e.target.value)} className="flex-1" />
{method !== "GET" && (