예제 소스
장기로 이해하는 규칙 엔진과 평가 함수 탐색 · 파일 59개
page.tsx
"use client";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { KiboListModal } from "@/components/KiboListModal";
import { MoreGames } from "@/components/MoreGames";
import type { GameListItem } from "@/lib/gameTypes";
import { rememberGame } from "@/lib/guest";
export default function HomePage() {
const router = useRouter();
const [showMore, setShowMore] = useState(false);
const [showKibo, setShowKibo] = useState(false);
const openKiboItem = (item: GameListItem) => {
rememberGame(item.code, item.access_key);
router.push(`/play?g=${encodeURIComponent(item.code)}&k=${encodeURIComponent(item.access_key)}`);
};
return (
<main
style={{
minHeight: "100dvh",
display: "flex",
flexDirection: "column",
background:
"radial-gradient(ellipse at 50% 20%, #4a301c 0%, #2b1d12 55%, #1c130c 100%)",
}}
>
<div
style={{
flex: 1,
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
gap: 16,
padding: 24,
textAlign: "center",
}}
>
<p
style={{
margin: 0,
letterSpacing: "0.28em",
color: "#c9a36a",
fontSize: 12,
}}
>
JANGGI
</p>
<h1
style={{
fontFamily: "Cormorant Garamond, Noto Serif KR, serif",
fontSize: 56,
margin: 0,
color: "#f6d7a4",
}}
>
장기
</h1>
<p style={{ color: "#c9a36a", margin: 0, lineHeight: 1.65 }}>
초(楚)와 한(漢). 상·마 배치를 고르고
<br />
사람과 컴퓨터로 대국하세요.
<br />
진행 중 기보가 있으면 저장 시점으로 이어집니다.
</p>
<Link
href="/play"
style={{
marginTop: 8,
padding: "14px 32px",
borderRadius: 10,
background: "linear-gradient(180deg, #a05a28, #8a4b1f)",
color: "#f8ead0",
fontWeight: 600,
textDecoration: "none",
border: "1px solid #c9894a",
}}
>
대국 시작
</Link>
<button
type="button"
onClick={() => setShowKibo(true)}
style={{
padding: "12px 28px",
borderRadius: 10,
background: "transparent",
color: "#f6d7a4",
fontWeight: 600,
border: "1px solid #6a4a2c",
cursor: "pointer",
font: "inherit",
}}
>
기보 보기
</button>
</div>
<nav
style={{
display: "grid",
gridTemplateColumns: "1fr 1fr 1fr 1fr",
borderTop: "1px solid #6a4a2c",
background: "#24180f",
}}
>
<span
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
minHeight: 44,
fontSize: 12,
color: "#f6d7a4",
background: "rgba(201,154,107,0.12)",
}}
>
홈
</span>
<Link
href="/play"
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
minHeight: 44,
fontSize: 12,
color: "#c9a36a",
textDecoration: "none",
}}
>
대국
</Link>
<button
type="button"
onClick={() => setShowKibo(true)}
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
minHeight: 44,
fontSize: 12,
color: "#c9a36a",
background: "none",
border: "none",
cursor: "pointer",
font: "inherit",
}}
>
기보
</button>
<button
type="button"
onClick={() => setShowMore(true)}
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
minHeight: 44,
fontSize: 12,
color: "#c9a36a",
background: "none",
border: "none",
cursor: "pointer",
font: "inherit",
}}
>
다른 게임
</button>
</nav>
<MoreGames open={showMore} onClose={() => setShowMore(false)} excludeId="janggy" />
<KiboListModal open={showKibo} onClose={() => setShowKibo(false)} onSelect={openKiboItem} />
</main>
);
}