98 lines
3.7 KiB
TypeScript
98 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { GAME_META, GAMES, GameId } from "@/lib/levels";
|
|
import { GAME_RULES } from "@/lib/rules";
|
|
|
|
function GameSection({ game }: { game: GameId }) {
|
|
const { name, accent, symbol } = GAME_META[game];
|
|
const rules = GAME_RULES[game];
|
|
|
|
return (
|
|
<div className="bg-white rounded-2xl border border-gray-100 p-5 flex flex-col gap-4">
|
|
<div className="flex items-center gap-3">
|
|
<span
|
|
className="w-10 h-10 rounded-xl flex items-center justify-center text-lg font-bold shrink-0"
|
|
style={{ background: `${accent}18`, color: accent }}
|
|
aria-hidden
|
|
>
|
|
{symbol}
|
|
</span>
|
|
<div>
|
|
<h2 className="text-base font-bold text-gray-900">{name}</h2>
|
|
<div className="flex items-center gap-2 mt-0.5">
|
|
<p className="text-xs text-gray-400">{rules.subtitle}</p>
|
|
<span className="text-[10px] text-gray-300">·</span>
|
|
<p className="text-xs text-gray-400">{rules.duration}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex flex-col gap-2">
|
|
{rules.howToPlay.map((rule, i) => (
|
|
<div key={i} className="flex items-start gap-3">
|
|
<span
|
|
className="w-5 h-5 rounded-full flex items-center justify-center text-[10px] font-bold shrink-0 mt-0.5"
|
|
style={{ background: `${accent}18`, color: accent }}
|
|
>
|
|
{i + 1}
|
|
</span>
|
|
<p className="text-sm text-gray-700 leading-snug">{rule}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{rules.tip && (
|
|
<div className="flex items-start gap-2.5 px-3 py-2.5 rounded-xl" style={{ background: `${accent}0d` }}>
|
|
<span className="text-sm shrink-0 mt-px">💡</span>
|
|
<p className="text-xs text-gray-600 leading-snug">{rules.tip}</p>
|
|
</div>
|
|
)}
|
|
|
|
<Link
|
|
href={`/${game}`}
|
|
className="flex items-center justify-center gap-2 py-2.5 rounded-xl text-white text-sm font-semibold transition-opacity hover:opacity-90"
|
|
style={{ background: accent }}
|
|
>
|
|
Jouer à {name}
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2.5} strokeLinecap="round"><polyline points="9 18 15 12 9 6"/></svg>
|
|
</Link>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default function HowToPlayPage() {
|
|
return (
|
|
<div className="flex flex-col gap-6 max-w-sm mx-auto py-4 px-4">
|
|
{/* Header */}
|
|
<div className="flex items-center gap-3">
|
|
<Link href="/" className="text-gray-400 hover:text-gray-600 transition-colors">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round"><polyline points="15 18 9 12 15 6"/></svg>
|
|
</Link>
|
|
<div>
|
|
<h1 className="text-xl font-bold text-gray-900 tracking-tight">Comment jouer</h1>
|
|
<p className="text-xs text-gray-400 mt-0.5">Les règles de chaque puzzle</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Intro */}
|
|
<div className="bg-gray-50 rounded-2xl p-4 text-sm text-gray-600 leading-relaxed">
|
|
<p>
|
|
Puzzle Trainer propose 5 puzzles logiques renouvelés chaque jour. Chaque puzzle peut aussi être pratiqué
|
|
en mode entraînement avec 100 niveaux de difficulté progressive.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Per-game sections */}
|
|
<div className="flex flex-col gap-4">
|
|
{GAMES.map(game => (
|
|
<GameSection key={game} game={game} />
|
|
))}
|
|
</div>
|
|
|
|
<Link href="/" className="text-xs text-gray-400 hover:text-gray-600 transition-colors text-center pb-2">
|
|
← Retour aux puzzles du jour
|
|
</Link>
|
|
</div>
|
|
);
|
|
}
|