diff --git a/app/.gitignore b/app/.gitignore index b7bfae0..4de87ab 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1,7 +1,5 @@ .idea - - ###> symfony/framework-bundle ### /.env.local /.env.local.php diff --git a/app/assets/images/logo-dark.svg b/app/assets/images/logo-dark.svg new file mode 100644 index 0000000..847d646 --- /dev/null +++ b/app/assets/images/logo-dark.svg @@ -0,0 +1,79 @@ + + diff --git a/app/assets/images/logo-light.svg b/app/assets/images/logo-light.svg new file mode 100644 index 0000000..b9ddcd1 --- /dev/null +++ b/app/assets/images/logo-light.svg @@ -0,0 +1,79 @@ + + diff --git a/app/assets/styles/maps/index.css b/app/assets/styles/maps/index.css new file mode 100644 index 0000000..a4b3cd1 --- /dev/null +++ b/app/assets/styles/maps/index.css @@ -0,0 +1,66 @@ +/* ════════════════════════════════════════════════════════════════ + Maps Index Styles + ════════════════════════════════════════════════════════════════ */ + +.maps-list { + display: flex; + flex-direction: column; + gap: 1rem; + width: 100%; + margin-top: 1.5rem; +} + +.maps { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + gap: 1rem; + padding: 1rem; + /*background: var(--nav-bg-light);*/ + border: 1px solid var(--border-light); + border-radius: 10px; + transition: background var(--duration-slow) ease, border-color var(--duration-slow) ease, box-shadow var(--duration-slow) ease; +} + +[data-theme="dark"] .maps { + background: var(--nav-bg-dark); + border-color: var(--border-dark); +} + +.maps-name { + font-weight: 600; + font-size: 1rem; + color: var(--text-light); + margin: 0; + transition: color var(--duration-slow) ease; + flex: 1; +} + +[data-theme="dark"] .maps-name { + color: var(--text-dark); +} + +.maps-btn { + display: inline-block; + padding: 0.6rem 1.2rem; + background: var(--violet); + color: white; + text-decoration: none; + border-radius: 8px; + font-weight: 600; + font-size: 0.9rem; + text-align: center; + transition: background var(--duration-normal) ease, transform var(--duration-fast) ease; + white-space: nowrap; + flex-shrink: 0; +} + +.maps-btn:hover { + transform: translateY(-2px); +} + +[data-theme="dark"] .maps-btn { + color: white; +} + diff --git a/app/assets/styles/partials/header.css b/app/assets/styles/partials/header.css index 0554d16..1fe432f 100644 --- a/app/assets/styles/partials/header.css +++ b/app/assets/styles/partials/header.css @@ -43,29 +43,41 @@ header { gap: 0.55rem; text-decoration: none; flex-shrink: 0; + height: 40px; } -.logo-mark { - width: 32px; - height: 32px; - background: var(--violet); - border-radius: 8px; - display: flex; - align-items: center; - justify-content: center; - transition: transform var(--duration-medium) ease, box-shadow var(--duration-medium) ease; + +.logo img { + height: 100%; + width: auto; + transition: opacity var(--duration-slow) ease, display var(--duration-slow) ease; } -.logo:hover .logo-mark { - transform: rotate(-6deg) scale(1.08); - box-shadow: 0 0 18px var(--violet-glow); + +/* Afficher le logo clair par défaut, masquer le logo sombre */ +.logo .logo-light { + opacity: 1; } -.logo-name { - font-weight: 800; - font-size: 1.05rem; - letter-spacing: -0.02em; - color: var(--text-light); - transition: color var(--duration-slow) ease; +.logo .logo-dark { + opacity: 0; + display: none; +} + +/* En mode sombre, afficher le logo sombre et masquer le logo clair */ +[data-theme="dark"] .logo .logo-light { + opacity: 0; + display: none; +} +[data-theme="dark"] .logo .logo-dark { + opacity: 1; + display: block; +} + +/* Hover effect */ +.logo:hover { + transform: scale(1.05); +} +.logo:hover img { + filter: drop-shadow(0 0 8px var(--violet-glow)); } -[data-theme="dark"] .logo-name { color: var(--text-dark); } /* ── NAVIGATION ────────────────────────────────────────────────── */ header nav { diff --git a/app/src/Controller/MapsController.php b/app/src/Controller/MapsController.php new file mode 100644 index 0000000..08ed03d --- /dev/null +++ b/app/src/Controller/MapsController.php @@ -0,0 +1,60 @@ +getParameter('kernel.project_dir') . '/public/uploads/maps'; + + // Créer le répertoire s'il n'existe pas + if (!is_dir($mapsDir)) { + mkdir($mapsDir, 0755, true); + } + + // Récupérer la liste des fichiers + $files = []; + if (is_dir($mapsDir)) { + $scandir = scandir($mapsDir); + foreach ($scandir as $file) { + if ($file !== '.' && $file !== '..' && is_file($mapsDir . '/' . $file)) { + $files[] = [ + 'filename' => $file, + 'display' => pathinfo($file, PATHINFO_FILENAME) + ]; + } + } + } + usort($files, fn($a, $b) => strcmp($a['filename'], $b['filename'])); + + return $this->render('maps/index.html.twig', [ + 'files' => $files, + ]); + } + + #[Route('/download/{filename}', name: 'app_maps_download')] + public function download(string $filename): Response + { + $mapsDir = $this->getParameter('kernel.project_dir') . '/public/uploads/maps'; + $filePath = $mapsDir . '/' . $filename; + + // Vérifier que le fichier existe et est dans le bon répertoire + if (!file_exists($filePath) || !is_file($filePath) || realpath($filePath) === false) { + throw $this->createNotFoundException('Le fichier n\'existe pas.'); + } + + // Vérifier que le chemin réel est bien dans le répertoire uploads/maps + if (strpos(realpath($filePath), realpath($mapsDir)) !== 0) { + throw $this->createAccessDeniedException('Accès refusé.'); + } + + return $this->file($filePath); + } +} diff --git a/app/src/Controller/ModpackController.php b/app/src/Controller/ModpackController.php index 5a2afd1..171974e 100644 --- a/app/src/Controller/ModpackController.php +++ b/app/src/Controller/ModpackController.php @@ -35,6 +35,11 @@ final class ModpackController extends AbstractController $modpack = $modpacks[0] ?? null; } + // Si aucun modpack n'est disponible, afficher le template approprié + if (!$modpack) { + return $this->render('modpack/nomodpack.html.twig'); + } + $form = $this->createForm(ModpackDownloadType::class, $modpack); return $this->render('modpack/index.html.twig', [ diff --git a/app/src/Form/Modpack/ModpackDownloadType.php b/app/src/Form/Modpack/ModpackDownloadType.php index f8674ea..355f4e7 100644 --- a/app/src/Form/Modpack/ModpackDownloadType.php +++ b/app/src/Form/Modpack/ModpackDownloadType.php @@ -15,13 +15,13 @@ class ModpackDownloadType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { - /** @var Modpack $modpack */ - $modpack = $options['data']; + /** @var Modpack|null $modpack */ + $modpack = $options['data'] ?? null; - $optionnels = $modpack->getConstitues() + $optionnels = $modpack?->getConstitues() ->filter(fn(Constitue $c) => $c->isOptionnel()) ->map(fn(Constitue $c) => $c->getMod()) - ->getValues(); + ->getValues() ?? []; $builder ->add('mods_optionnels', EntityType::class, [ diff --git a/app/templates/maps/index.html.twig b/app/templates/maps/index.html.twig new file mode 100644 index 0000000..3744b9e --- /dev/null +++ b/app/templates/maps/index.html.twig @@ -0,0 +1,36 @@ +{% extends 'base.html.twig' %} + +{% block title %} Maps {% endblock %} + +{% block stylesheets %} + {{ parent() }} + + + +{% endblock %} + +{% block main %} +
{{ file.display }}
+ + Télécharger + +Aucune map n'est actuellement disponible au téléchargement.
+ {% endif %} +Aucun modpack n'est actuellement disponible au téléchargement.
+Veuillez réessayer plus tard.
+