Claude Code · claude-opus-5-5 · React (TSX)
결과 코드펼치기
import { useState } from "react";
const SCOPES = [
{
title: "운동 기록 읽기",
hint: "날짜, 종목, 세트와 시간을 볼 수 있어요.",
d: "M2.5 8h2l1.5-3 3 6 1.5-3h3",
},
{
title: "새 운동 기록 추가하기",
hint: "추가한 기록은 내가 확인해야 저장돼요.",
d: "M8 3v10M3 8h10",
},
];
export default function AppConnectConsent() {
const [state, setState] = useState<"ask" | "pending-accept" | "pending-deny" | "accepted" | "denied">("ask");
function answer(accept: boolean) {
setState(accept ? "pending-accept" : "pending-deny");
setTimeout(() => setState(accept ? "accepted" : "denied"), 900);
}
const pending = state === "pending-accept" || state === "pending-deny";
return (
<section className="w-full bg-[#0c0c10] px-4 py-16 text-zinc-100 sm:py-24">
<div className="mx-auto max-w-[420px] rounded-[20px] border border-white/10 bg-[#141419] p-8 shadow-2xl shadow-black/50">
<div className="flex items-center justify-center gap-3" aria-hidden>
<span className="flex h-12 w-12 items-center justify-center rounded-2xl bg-gradient-to-br from-sky-400 to-blue-600 text-lg font-bold">D</span>
<span className="flex gap-1">
{[0, 1, 2].map((i) => (
<span key={i} className="h-1.5 w-1.5 rounded-full bg-zinc-600" />
))}
</span>
<span className="flex h-12 w-12 items-center justify-center rounded-2xl bg-gradient-to-br from-orange-400 to-rose-500 text-lg font-bold">F</span>
</div>
{state === "accepted" || state === "denied" ? (
<div role="status" className="mt-6 text-center">
<h1 className="text-xl font-semibold tracking-tight">{state === "accepted" ? "연결했어요" : "연결을 취소했어요"}</h1>
<p className="mt-2 text-sm text-zinc-400">
{state === "accepted" ? "이 창을 닫고 Draftboard로 돌아가세요." : "Draftboard는 Fitlog 기록에 접근할 수 없어요."}
</p>
<button type="button" onClick={() => setState("ask")} className="mt-5 text-xs text-zinc-500 underline-offset-4 hover:text-zinc-300 hover:underline">
처음 화면 다시 보기
</button>
</div>
) : (
<>
<h1 className="mt-6 text-center text-xl font-semibold tracking-tight">
Draftboard이(가) Fitlog에
<br />
연결하려고 합니다
</h1>
<p className="mt-2 text-center text-sm text-zinc-400">
<span className="text-zinc-200">kim@example.com</span> 계정으로 연결합니다.
</p>
<ul className="mt-6 divide-y divide-white/10 rounded-xl border border-white/10">
{SCOPES.map((s) => (
<li key={s.title} className="flex gap-3 px-4 py-3">
<span className="mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-white/[0.06] text-orange-300" aria-hidden>
<svg width="14" height="14" viewBox="0 0 16 16" fill="none">
<path d={s.d} stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</span>
<span>
<span className="block text-sm font-medium">{s.title}</span>
<span className="block text-xs text-zinc-500">{s.hint}</span>
</span>
</li>
))}
</ul>
<p className="mt-4 text-center text-xs text-zinc-500">연결은 Fitlog 설정에서 언제든 끊을 수 있어요.</p>
<div className="mt-6 flex gap-2">
<button
type="button"
disabled={pending}
onClick={() => answer(false)}
className="h-11 flex-1 rounded-xl border border-white/10 bg-white/[0.04] text-sm font-medium transition hover:bg-white/[0.08] disabled:opacity-50"
>
{state === "pending-deny" ? "취소하는 중..." : "거부"}
</button>
<button
type="button"
disabled={pending}
onClick={() => answer(true)}
className="h-11 flex-1 rounded-xl bg-gradient-to-r from-orange-400 to-rose-500 text-sm font-semibold text-white shadow-[0_0_24px_-6px_rgba(251,113,133,0.7)] transition hover:brightness-110 disabled:opacity-50"
>
{state === "pending-accept" ? "연결하는 중..." : "허용"}
</button>
</div>
</>
)}
</div>
</section>
);
}
적용 사이트 0
이 블록이 실제로 쓰인 사이트입니다.
아직 등록된 사이트가 없습니다. 이 블록을 쓴 사이트가 있다면 알려 주세요.
재현 후기
v1 · 0개아직 이 버전의 프롬프트로 직접 만들어 본 사람이 없습니다. 첫 번째로 재현해 보세요.