34 lines
1.3 KiB
TypeScript
34 lines
1.3 KiB
TypeScript
"use client";
|
|
import useSWR from "swr";
|
|
|
|
const fetcher = (url: string) => fetch(url).then((r) => r.json());
|
|
|
|
export default function CouponsPage() {
|
|
const { data, mutate } = useSWR<{ coupons: { id: string; code: string; title: string; description?: string; stock: number; maxPerUser: number; expiresAt?: string; used: number }[] }>("/api/coupons", fetcher);
|
|
async function redeem(code: string) {
|
|
await fetch("/api/coupons/redeem", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ code }) });
|
|
mutate();
|
|
}
|
|
return (
|
|
<div>
|
|
<h1>무료쿠폰</h1>
|
|
<ul style={{ display: "flex", flexDirection: "column", gap: 8 }}>
|
|
{(data?.coupons ?? []).map((c) => (
|
|
<li key={c.id} style={{ border: "1px solid #eee", borderRadius: 8, padding: 12 }}>
|
|
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
|
<div>
|
|
<strong>{c.title}</strong>
|
|
<div style={{ opacity: 0.8 }}>{c.description}</div>
|
|
<div style={{ fontSize: 12, opacity: 0.7 }}>코드: {c.code} · 소진: {c.used}/{c.stock || "∞"}</div>
|
|
</div>
|
|
<button onClick={() => redeem(c.code)}>사용하기</button>
|
|
</div>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
|