merge: master into codex/bark-battle
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,137 @@
|
||||
import { Loader2, Sparkles } from 'lucide-react';
|
||||
|
||||
export type PuzzleOnboardingPhase = 'input' | 'generating' | 'generated';
|
||||
|
||||
type PuzzleOnboardingViewProps = {
|
||||
prompt: string;
|
||||
phase: PuzzleOnboardingPhase;
|
||||
error: string | null;
|
||||
copy: string;
|
||||
onPromptChange: (value: string) => void;
|
||||
onSubmit: () => void;
|
||||
onSkip: () => void;
|
||||
};
|
||||
|
||||
export function PuzzleOnboardingView({
|
||||
prompt,
|
||||
phase,
|
||||
error,
|
||||
copy,
|
||||
onPromptChange,
|
||||
onSubmit,
|
||||
onSkip,
|
||||
}: PuzzleOnboardingViewProps) {
|
||||
const isGenerating = phase === 'generating';
|
||||
const isGenerated = phase === 'generated';
|
||||
const canSubmit = Boolean(prompt.trim()) && !isGenerating && !isGenerated;
|
||||
|
||||
return (
|
||||
<div className="relative flex min-h-screen items-center justify-center overflow-hidden bg-[radial-gradient(circle_at_30%_15%,rgba(251,191,36,0.22),transparent_30%),linear-gradient(135deg,#0f172a,#111827_46%,#1e1b4b)] px-4 py-8 text-white">
|
||||
<div className="absolute inset-0 bg-[linear-gradient(rgba(255,255,255,0.045)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.04)_1px,transparent_1px)] bg-[length:38px_38px] opacity-30" />
|
||||
<button
|
||||
type="button"
|
||||
disabled={isGenerating}
|
||||
onClick={onSkip}
|
||||
className="absolute right-4 top-4 z-10 inline-flex min-h-10 items-center justify-center rounded-full border border-white/14 bg-black/24 px-4 text-sm font-black text-white/86 shadow-[0_12px_28px_rgba(0,0,0,0.22)] backdrop-blur transition hover:border-amber-200/45 hover:text-amber-100 disabled:cursor-not-allowed disabled:opacity-45 sm:right-6 sm:top-6"
|
||||
>
|
||||
跳过
|
||||
</button>
|
||||
<section className="relative flex w-full max-w-[34rem] flex-col items-center gap-5 text-center">
|
||||
<div className="grid h-14 w-14 place-items-center rounded-[1.2rem] border border-amber-200/32 bg-amber-200/14 text-amber-100 shadow-[0_18px_48px_rgba(251,191,36,0.18)]">
|
||||
{isGenerating ? (
|
||||
<Loader2 className="h-6 w-6 animate-spin" />
|
||||
) : (
|
||||
<Sparkles className="h-6 w-6" />
|
||||
)}
|
||||
</div>
|
||||
<h1 className="text-[2rem] font-black leading-tight sm:text-[2.85rem]">
|
||||
{copy}
|
||||
</h1>
|
||||
<form
|
||||
className="flex w-full flex-col gap-3"
|
||||
onSubmit={(event) => {
|
||||
event.preventDefault();
|
||||
onSubmit();
|
||||
}}
|
||||
>
|
||||
<textarea
|
||||
value={prompt}
|
||||
disabled={isGenerating || isGenerated}
|
||||
onChange={(event) => onPromptChange(event.target.value)}
|
||||
placeholder="把你的梦讲给我听吧"
|
||||
rows={4}
|
||||
className="min-h-32 w-full resize-none rounded-[1.25rem] border border-white/14 bg-black/28 px-4 py-4 text-base font-semibold leading-7 text-white shadow-[0_18px_50px_rgba(0,0,0,0.24)] outline-none backdrop-blur placeholder:text-white/42 focus:border-amber-200/70 focus:ring-2 focus:ring-amber-200/20 disabled:opacity-70"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!canSubmit}
|
||||
className="inline-flex min-h-12 items-center justify-center gap-2 rounded-[1rem] bg-amber-200 px-5 text-sm font-black text-slate-950 transition hover:bg-amber-100 disabled:cursor-not-allowed disabled:opacity-45"
|
||||
>
|
||||
{isGenerating ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
生成
|
||||
</>
|
||||
) : (
|
||||
'生成'
|
||||
)}
|
||||
</button>
|
||||
</form>
|
||||
{error ? (
|
||||
<div className="w-full rounded-[1rem] border border-red-300/30 bg-red-500/14 px-4 py-3 text-sm font-semibold text-red-50">
|
||||
{error}
|
||||
</div>
|
||||
) : null}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type PuzzleOnboardingLoginOverlayProps = {
|
||||
isSaving: boolean;
|
||||
error: string | null;
|
||||
copy: string;
|
||||
onLogin: () => void;
|
||||
};
|
||||
|
||||
export function PuzzleOnboardingLoginOverlay({
|
||||
isSaving,
|
||||
error,
|
||||
copy,
|
||||
onLogin,
|
||||
}: PuzzleOnboardingLoginOverlayProps) {
|
||||
return (
|
||||
<div className="fixed inset-0 z-[110] flex items-center justify-center bg-slate-950/72 px-4 py-6 text-white backdrop-blur-md">
|
||||
<section className="flex w-full max-w-[24rem] flex-col items-center gap-5 rounded-[1.35rem] border border-white/14 bg-slate-950/94 px-5 py-6 text-center shadow-[0_28px_90px_rgba(0,0,0,0.5)]">
|
||||
<div className="grid h-12 w-12 place-items-center rounded-[1rem] bg-amber-200 text-slate-950">
|
||||
{isSaving ? (
|
||||
<Loader2 className="h-5 w-5 animate-spin" />
|
||||
) : (
|
||||
<Sparkles className="h-5 w-5" />
|
||||
)}
|
||||
</div>
|
||||
<h2 className="text-2xl font-black leading-tight">{copy}</h2>
|
||||
<button
|
||||
type="button"
|
||||
disabled={isSaving}
|
||||
onClick={onLogin}
|
||||
className="inline-flex min-h-12 w-full items-center justify-center gap-2 rounded-[1rem] bg-amber-200 px-5 text-sm font-black text-slate-950 transition hover:bg-amber-100 disabled:cursor-not-allowed disabled:opacity-45"
|
||||
>
|
||||
{isSaving ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
注册账号 / 登录
|
||||
</>
|
||||
) : (
|
||||
'注册账号 / 登录'
|
||||
)}
|
||||
</button>
|
||||
{error ? (
|
||||
<div className="w-full rounded-[1rem] border border-red-300/30 bg-red-500/14 px-4 py-3 text-sm font-semibold text-red-50">
|
||||
{error}
|
||||
</div>
|
||||
) : null}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user