Skip to content

Commit ae4e16b

Browse files
authored
✨ Feat: API 테스트 폼 컴포넌트 추가 (#57)
* feat: 모니터링 페이지 내 API 테스트 기능 추가 * chore: GET 요청 제외 DB 반영 경고 표시 추가 * chore: GNB 한글로 변경
1 parent 8e85bcf commit ae4e16b

3 files changed

Lines changed: 97 additions & 5 deletions

File tree

src/components/GNB/Header.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@ const Header = () => {
2020
<div className="rounded-[8px] overflow-hidden">
2121
<img src={logo} alt="링크드아웃 로고" width={40} />
2222
</div>
23-
<h1 className="text-white text-2xl">Linked Out Admin Page</h1>
23+
<h1 className="text-white text-2xl">링크드아웃 관리자 페이지</h1>
2424
</div>
2525
<div className="flex gap-[15px] items-center">
2626
{isLogin ? (
2727
<>
28-
<div className="text-white">My Page</div>
2928
<Button
3029
className="text-white"
3130
variant="ghost"
@@ -35,19 +34,19 @@ const Header = () => {
3534
navigate(`/auth/${AuthPaths.LOGIN}`);
3635
}}
3736
>
38-
Logout
37+
로그아웃
3938
</Button>
4039
</>
4140
) : (
4241
<>
4342
<Link to={`/auth/${AuthPaths.LOGIN}`}>
4443
<Button className="text-white" variant="ghost">
45-
LOGIN
44+
로그인
4645
</Button>
4746
</Link>
4847
<Link to={`/auth/${AuthPaths.REGISTER}`}>
4948
<Button className="text-white" variant="ghost">
50-
REGISTER
49+
회원가입
5150
</Button>
5251
</Link>
5352
</>
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { Button } from "../../components/ui/button";
2+
import { Textarea } from "../../components/ui/textarea";
3+
import fetchData from "../../api/fetchData";
4+
import { useState } from "react";
5+
6+
type MethodType = "GET" | "POST" | "PUT" | "DELETE";
7+
8+
export default function ApiTestForm() {
9+
const [url, setUrl] = useState("");
10+
const [method, setMethod] = useState<MethodType>("GET");
11+
const [body, setBody] = useState("{}");
12+
13+
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
14+
e.preventDefault();
15+
16+
if (method !== "GET") {
17+
const confirmChange = window.confirm(
18+
"⚠️ 이 요청은 실제 DB에 영향을 줄 수 있습니다. 진행하시겠습니까?"
19+
);
20+
if (!confirmChange) {
21+
console.log("%c요청이 취소되었습니다.", "color: orange;");
22+
return;
23+
}
24+
}
25+
26+
try {
27+
const parsedBody = body ? JSON.parse(body) : undefined;
28+
29+
console.log(
30+
"%cAPI 요청 정보:\n",
31+
"background: #006980; color: white; padding: 4px; border-radius: 4px;",
32+
{ url, method, parsedBody }
33+
);
34+
const res = await fetchData({
35+
url,
36+
method,
37+
body: parsedBody,
38+
});
39+
40+
console.log(
41+
"%cAPI 요청 결과:\n",
42+
"background: green; color: white; padding: 4px; border-radius: 4px;",
43+
res
44+
);
45+
} catch (err) {
46+
console.log("에러 발생:", err);
47+
}
48+
};
49+
50+
return (
51+
<form onSubmit={handleSubmit} className="flex flex-col gap-[10px]">
52+
<div>
53+
<label className="block font-semibold mb-2">URL</label>
54+
<input
55+
type="text"
56+
value={url}
57+
onChange={(e) => setUrl(e.target.value)}
58+
className="w-full p-2 border rounded"
59+
placeholder="/api 이하의 엔드포인트를 전부 입력해주세요(예: /admin-support/releases?page=0&perPage=10)"
60+
required
61+
/>
62+
</div>
63+
<div>
64+
<label className="block font-semibold mb-2">HTTP Method</label>
65+
<select
66+
value={method}
67+
onChange={(e) => setMethod(e.target.value as MethodType)}
68+
className="w-full p-2 border rounded"
69+
>
70+
<option value="GET">GET</option>
71+
<option value="POST">POST</option>
72+
<option value="PUT">PUT</option>
73+
<option value="DELETE">DELETE</option>
74+
</select>
75+
</div>
76+
<div>
77+
<label className="block font-semibold mb-2">Body (JSON)</label>
78+
<Textarea
79+
value={body}
80+
onChange={(e) => setBody(e.target.value)}
81+
className="w-full p-2 border rounded"
82+
rows={5}
83+
placeholder='json 형식으로 입력해주세요 {"key": "value"}'
84+
disabled={method === "GET" || method === "DELETE"}
85+
/>
86+
</div>
87+
<Button type="submit">API 보내기</Button>
88+
</form>
89+
);
90+
}

src/pages/monitoring/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Metric, onCLS, onFCP, onINP, onLCP, onTTFB } from "web-vitals";
22
import { useEffect, useState } from "react";
33

4+
import ApiTestForm from "./ApiTestForm";
45
import ServerStatus from "./ServerStatus";
56
import { cn } from "../../lib/utils";
67

@@ -47,6 +48,8 @@ export default function Monitoring() {
4748
<WebVitalItem key={key} label={key} value={value} />
4849
))}
4950
</ul>
51+
<h4 className="text-2xl">API 테스트: 결과 콘솔 확인(F12)</h4>
52+
<ApiTestForm />
5053
</div>
5154
);
5255
}

0 commit comments

Comments
 (0)