60 lines
2.4 KiB
TypeScript
60 lines
2.4 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import Link from "next/link";
|
||
import { useRouter } from "next/navigation";
|
||
import PosterDropzone from "@/components/poster-dropzone";
|
||
import { useRequireLogin } from "@/components/auth-gate";
|
||
import { apiFetch } from "@/lib/api";
|
||
|
||
export default function HomePage() {
|
||
const router = useRouter();
|
||
const requireLogin = useRequireLogin();
|
||
const [file, setFile] = useState<File | null>(null);
|
||
const [name, setName] = useState("");
|
||
const [busy, setBusy] = useState(false);
|
||
const [error, setError] = useState<string | null>(null);
|
||
|
||
const submit = async () => {
|
||
if (!file) return;
|
||
// 여기서 처음으로 로그인이 필요해진다
|
||
if (!requireLogin()) return;
|
||
setBusy(true);
|
||
setError(null);
|
||
try {
|
||
const fd = new FormData();
|
||
fd.append("poster", file);
|
||
fd.append("name", name);
|
||
const { id } = await apiFetch<{ id: string }>("/api/f1/jobs", { method: "POST", body: fd });
|
||
router.push(`/poster/${id}`);
|
||
} catch (e) {
|
||
setError((e as Error).message);
|
||
setBusy(false);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div style={{ display: "flex", flexDirection: "column", alignItems: "center", paddingTop: "0.5rem" }}>
|
||
<Link href="/" className="btn-back" style={{ alignSelf: "flex-start" }}>‹ 시작 방법 고르기</Link>
|
||
<h1 className="page-title" style={{ marginTop: "1.25rem" }}>포스터를 올려주세요</h1>
|
||
<p className="page-subtitle">나레이션·음악·연출까지 자동으로 만들어 9:16 숏폼으로 완성합니다</p>
|
||
|
||
<div style={{ width: "100%", maxWidth: 480, marginTop: "2.5rem", display: "flex", flexDirection: "column", gap: "1rem" }}>
|
||
<PosterDropzone file={file} onFile={setFile} />
|
||
<input
|
||
className="input input--center"
|
||
placeholder="행사 이름을 입력하세요 (비우면 자동 추출)"
|
||
value={name}
|
||
onChange={(e) => setName(e.target.value)}
|
||
/>
|
||
{error && <p style={{ color: "#ff7a7a", fontSize: "var(--text-sm)", textAlign: "center", margin: 0 }}>{error}</p>}
|
||
<button className="btn-cta btn-lg" disabled={!file || busy} onClick={submit}>
|
||
{busy ? "업로드 중…" : "숏폼 만들기"}
|
||
</button>
|
||
<p className="note">공연 상품페이지 주소가 있나요? <Link href="/playreel">상품페이지로 시작하면 캐스팅·일정까지 담깁니다 →</Link></p>
|
||
</div>
|
||
|
||
</div>
|
||
);
|
||
}
|