Files
Puechberty Arthur 2de4261631 first commit
2026-03-30 23:26:19 +02:00

127 lines
4.4 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useState, useCallback, useEffect } from "react";
import { Difficulty, getDifficultyLabel, generateSudokus, SudokuPuzzle } from "./lib/sudoku";
import SudokuGrid from "./components/SudokuGrid";
const DIFFICULTIES: Difficulty[] = ["facile", "moyen", "difficile", "expert"];
const SUDOKU_COUNT = 6;
export default function Home() {
const [difficulty, setDifficulty] = useState<Difficulty>("moyen");
const [puzzles, setPuzzles] = useState<SudokuPuzzle[] | null>(null);
const [generating, setGenerating] = useState(false);
// Générer automatiquement des sudoku "Moyen" au chargement
useEffect(() => {
setGenerating(true);
setTimeout(() => {
const generated = generateSudokus("moyen", SUDOKU_COUNT);
setPuzzles(generated);
setGenerating(false);
}, 50);
}, []);
const handleGenerate = useCallback((diff: Difficulty) => {
setDifficulty(diff);
setGenerating(true);
// Use setTimeout to let UI update before heavy computation
setTimeout(() => {
const generated = generateSudokus(diff, SUDOKU_COUNT);
setPuzzles(generated);
setGenerating(false);
}, 50);
}, []);
const handlePrint = useCallback(() => {
if (!puzzles) {
setGenerating(true);
setTimeout(() => {
const generated = generateSudokus(difficulty, SUDOKU_COUNT);
setPuzzles(generated);
setGenerating(false);
setTimeout(() => window.print(), 100);
}, 50);
} else {
window.print();
}
}, [puzzles, difficulty]);
const label = getDifficultyLabel(difficulty);
return (
<div className="app-container">
{/* Controls - hidden when printing */}
<header className="controls no-print" role="banner">
<h1 className="app-title">🧩 Générateur de Sudoku</h1>
<p className="app-subtitle">
Choisissez une difficulté pour générer {SUDOKU_COUNT} sudoku sur une feuille A4 avec leurs solutions.
</p>
<nav className="button-group" role="navigation" aria-label="Choix de difficulté">
{DIFFICULTIES.map((diff) => (
<button
key={diff}
onClick={() => handleGenerate(diff)}
disabled={generating}
aria-pressed={difficulty === diff && !!puzzles}
className={`btn-difficulty ${difficulty === diff && puzzles ? "btn-active" : ""}`}
>
{getDifficultyLabel(diff)}
</button>
))}
<button
onClick={handlePrint}
disabled={generating || !puzzles}
className="btn-print"
aria-label="Imprimer les grilles de sudoku"
>
🖨 Imprimer
</button>
</nav>
{generating && (
<p className="generating-text" role="status" aria-live="polite">Génération en cours</p>
)}
</header>
{/* SEO content - visible to crawlers, visually subtle */}
<section className="seo-content no-print" aria-label="À propos">
<h2>Générateur de Sudoku gratuit à imprimer</h2>
<p>
Créez et imprimez des grilles de Sudoku gratuitement. Notre générateur produit des puzzles
valides et solvables avec 4 niveaux de difficulté : facile, moyen, difficile et expert.
Chaque feuille A4 contient 6 grilles 9×9 accompagnées de leurs solutions sur une page séparée.
Idéal pour s&apos;entraîner, jouer en famille ou en classe.
</p>
</section>
{/* Printable content */}
{puzzles && (
<main className="print-area" role="main">
{/* Page 1: Puzzles */}
<section className="print-page" aria-label={`Grilles de sudoku niveau ${label}`}>
<h2 className="page-title">Sudoku Niveau {label}</h2>
<div className="sudoku-grid-container">
{puzzles.map((p, i) => (
<SudokuGrid key={`puzzle-${i}`} grid={p.puzzle} index={i} />
))}
</div>
</section>
{/* Page 2: Solutions */}
<section className="print-page" aria-label={`Solutions niveau ${label}`}>
<h2 className="page-title">Solutions Niveau {label}</h2>
<div className="sudoku-grid-container">
{puzzles.map((p, i) => (
<SudokuGrid key={`solution-${i}`} grid={p.solution} index={i} isSolution />
))}
</div>
</section>
</main>
)}
</div>
);
}