✨ feat(pages): Ajoute la page e-cosplay avec listing de créateurs.
This commit is contained in:
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use App\Repository\Ag\MainRepository;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
@@ -10,7 +9,14 @@ use Symfony\Component\Routing\Attribute\Route;
|
|||||||
class PagesController extends AbstractController
|
class PagesController extends AbstractController
|
||||||
{
|
{
|
||||||
#[Route(path: '/pages', name: 'app_pages', options: ['sitemap' => false], methods: ['GET','POST'])]
|
#[Route(path: '/pages', name: 'app_pages', options: ['sitemap' => false], methods: ['GET','POST'])]
|
||||||
public function index(MainRepository $mainRepository): Response
|
public function index(): Response
|
||||||
|
{
|
||||||
|
return $this->render('pages.twig',[
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route(path: '/pages/discover', name: 'app_pages_discover', options: ['sitemap' => false], methods: ['GET','POST'])]
|
||||||
|
public function discover(): Response
|
||||||
{
|
{
|
||||||
return $this->render('pages/prestation.twig',[
|
return $this->render('pages/prestation.twig',[
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -51,6 +51,24 @@ class SitemapSubscriber
|
|||||||
}
|
}
|
||||||
$urlContainer->addUrl($decoratedUrlMembers, 'default');
|
$urlContainer->addUrl($decoratedUrlMembers, 'default');
|
||||||
|
|
||||||
|
$urlMembers = new UrlConcrete($urlGenerator->generate('app_pages', [], UrlGeneratorInterface::ABSOLUTE_URL));
|
||||||
|
$decoratedUrlMembers = new GoogleImageUrlDecorator($urlMembers);
|
||||||
|
$decoratedUrlMembers->addImage(new GoogleImage($this->cacheManager->resolve('assets/images/logo.jpg','webp')));
|
||||||
|
$decoratedUrlMembers = new GoogleMultilangUrlDecorator($decoratedUrlMembers);
|
||||||
|
foreach ($langs as $lang) {
|
||||||
|
$decoratedUrlMembers->addLink($urlGenerator->generate('app_pages',['lang'=>$lang], UrlGeneratorInterface::ABSOLUTE_URL), $lang);
|
||||||
|
}
|
||||||
|
$urlContainer->addUrl($decoratedUrlMembers, 'pages');
|
||||||
|
|
||||||
|
$urlMembers = new UrlConcrete($urlGenerator->generate('app_pages_discover', [], UrlGeneratorInterface::ABSOLUTE_URL));
|
||||||
|
$decoratedUrlMembers = new GoogleImageUrlDecorator($urlMembers);
|
||||||
|
$decoratedUrlMembers->addImage(new GoogleImage($this->cacheManager->resolve('assets/images/logo.jpg','webp')));
|
||||||
|
$decoratedUrlMembers = new GoogleMultilangUrlDecorator($decoratedUrlMembers);
|
||||||
|
foreach ($langs as $lang) {
|
||||||
|
$decoratedUrlMembers->addLink($urlGenerator->generate('app_pages_discover',['lang'=>$lang], UrlGeneratorInterface::ABSOLUTE_URL), $lang);
|
||||||
|
}
|
||||||
|
$urlContainer->addUrl($decoratedUrlMembers, 'pages');
|
||||||
|
|
||||||
$urlEvents = new UrlConcrete($urlGenerator->generate('app_events', [], UrlGeneratorInterface::ABSOLUTE_URL));
|
$urlEvents = new UrlConcrete($urlGenerator->generate('app_events', [], UrlGeneratorInterface::ABSOLUTE_URL));
|
||||||
$urlEvents = new GoogleImageUrlDecorator($urlEvents);
|
$urlEvents = new GoogleImageUrlDecorator($urlEvents);
|
||||||
$urlEvents->addImage(new GoogleImage($this->cacheManager->resolve('assets/images/logo.jpg','webp')));
|
$urlEvents->addImage(new GoogleImage($this->cacheManager->resolve('assets/images/logo.jpg','webp')));
|
||||||
|
|||||||
@@ -123,6 +123,7 @@
|
|||||||
{ 'name': 'Accueil'|trans, 'route': 'app_home' },
|
{ 'name': 'Accueil'|trans, 'route': 'app_home' },
|
||||||
{ 'name': 'Qui sommes-nous'|trans, 'route': 'app_about' },
|
{ 'name': 'Qui sommes-nous'|trans, 'route': 'app_about' },
|
||||||
{ 'name': 'Nos membres'|trans, 'route': 'app_members' },
|
{ 'name': 'Nos membres'|trans, 'route': 'app_members' },
|
||||||
|
{ 'name': 'epage_cosplay'|trans, 'route': 'app_pages' },
|
||||||
{ 'name': 'Nos événements'|trans, 'route': 'app_events' },
|
{ 'name': 'Nos événements'|trans, 'route': 'app_events' },
|
||||||
{ 'name': 'Boutiques'|trans, 'route': 'app_shop' },
|
{ 'name': 'Boutiques'|trans, 'route': 'app_shop' },
|
||||||
{ 'name': 'Documents'|trans, 'route': 'app_doc' },
|
{ 'name': 'Documents'|trans, 'route': 'app_doc' },
|
||||||
@@ -130,7 +131,7 @@
|
|||||||
{ 'name': 'Contact'|trans, 'route': 'app_contact' }
|
{ 'name': 'Contact'|trans, 'route': 'app_contact' }
|
||||||
] %}
|
] %}
|
||||||
<header class="bg-white shadow-md sticky top-0 z-40">
|
<header class="bg-white shadow-md sticky top-0 z-40">
|
||||||
<nav class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<nav class="mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div class="flex justify-between items-center h-16">
|
<div class="flex justify-between items-center h-16">
|
||||||
{# LOGO / NOM DU SITE #}
|
{# LOGO / NOM DU SITE #}
|
||||||
|
|
||||||
|
|||||||
131
templates/pages.twig
Normal file
131
templates/pages.twig
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
{% extends 'base.twig' %}
|
||||||
|
|
||||||
|
{# --- METADATA & SCHEMA (Inchangé) --- #}
|
||||||
|
{% block title %}{{'page.title'|trans({})}}{% endblock %}
|
||||||
|
{% block meta_description %}{{'hero.subheading'|trans({})}}{% endblock %}
|
||||||
|
|
||||||
|
{% block canonical_url %}<link rel="canonical" href="{{ url('app_pages') }}" />{% endblock %}
|
||||||
|
{% block breadcrumb_schema %}
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "BreadcrumbList",
|
||||||
|
"itemListElement": [
|
||||||
|
{
|
||||||
|
"@type": "ListItem",
|
||||||
|
"position": 1,
|
||||||
|
"name": "{{ 'breadcrumb.home'|trans }}",
|
||||||
|
"item": "{{ app.request.schemeAndHttpHost }}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "ListItem",
|
||||||
|
"position": 2,
|
||||||
|
"name": "{{ 'page.title'|trans({}) }}",
|
||||||
|
"item": "{{ app.request.schemeAndHttpHost }}{{ app.request.pathInfo }}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{# --- BODY AVEC TAILWIND CSS --- #}
|
||||||
|
{% block body %}
|
||||||
|
{#
|
||||||
|
NOTE: Le bloc de données cosplayers a été retiré.
|
||||||
|
Cette variable 'cosplayers' doit être passée par votre contrôleur PHP.
|
||||||
|
#}
|
||||||
|
{% set cosplayers = cosplayers is defined ? cosplayers : [] %}
|
||||||
|
|
||||||
|
<div class="container mx-auto px-4 py-16">
|
||||||
|
|
||||||
|
{# --- En-tête de la Section Communauté --- #}
|
||||||
|
<div class="text-center mb-12">
|
||||||
|
{# Utilise le filtre trans avec le nombre d'éléments réel et la pluralisation #}
|
||||||
|
<h2 class="text-4xl font-extrabold text-gray-900 sm:text-5xl tracking-tight">
|
||||||
|
{{ 'creators.title_plural'|trans({'%count%': cosplayers|length}) }}
|
||||||
|
</h2>
|
||||||
|
<p class="mt-4 text-xl text-gray-500">
|
||||||
|
{{ 'creators.intro_text'|trans({}) }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# --- Listing des Cartes de Cosplayers --- #}
|
||||||
|
{% if cosplayers|length > 0 %}
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||||
|
|
||||||
|
{% for creator in cosplayers %}
|
||||||
|
<div class="bg-white rounded-xl shadow-2xl overflow-hidden transform hover:scale-[1.02] transition duration-300">
|
||||||
|
|
||||||
|
{# Image du Cosplayer #}
|
||||||
|
<img class="w-full h-80 object-cover"
|
||||||
|
src="{{ creator.image }}"
|
||||||
|
alt="Portrait de {{ creator.pseudo }}"
|
||||||
|
onerror="this.onerror=null;this.src='https://placehold.co/400x600/e5e7eb/4b5563?text=Image+Indisponible';"
|
||||||
|
>
|
||||||
|
|
||||||
|
<div class="p-6">
|
||||||
|
|
||||||
|
{# Pseudo #}
|
||||||
|
<h3 class="text-2xl font-bold text-gray-800 mb-2">{{ creator.pseudo }}</h3>
|
||||||
|
|
||||||
|
{# Description Courte #}
|
||||||
|
<p class="text-gray-600 mb-4 h-16 overflow-hidden">
|
||||||
|
{{ creator.description }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{# Réseaux Sociaux #}
|
||||||
|
<div class="mb-6">
|
||||||
|
<p class="text-sm font-semibold text-indigo-600 mb-2">
|
||||||
|
{{ 'creators.social_label'|trans({}) }}
|
||||||
|
</p>
|
||||||
|
<div class="flex space-x-3">
|
||||||
|
{% for platform, url in creator.social %}
|
||||||
|
<a href="{{ url }}" target="_blank" rel="noopener noreferrer"
|
||||||
|
class="text-gray-500 hover:text-pink-600 transition duration-150"
|
||||||
|
title="{{ 'creators.social_label'|trans({}) }} {{ creator.pseudo }} sur {{ platform|capitalize }}">
|
||||||
|
{# Icône de Réseau Social (Générique) #}
|
||||||
|
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8zM12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6zm0 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# Bouton Voir Plus #}
|
||||||
|
<a href="/cosplayer/{{ creator.pseudo|lower|replace({' ': '-'}) }}"
|
||||||
|
class="w-full inline-flex justify-center items-center px-4 py-3 border border-transparent text-sm font-medium rounded-lg shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition duration-150">
|
||||||
|
{{ 'creators.button'|trans({}) }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
{# Message si la liste est vide (en attendant les données réelles) #}
|
||||||
|
<p class="text-center text-xl text-gray-500 italic mt-8">
|
||||||
|
{{ 'creators.empty_list'|trans({}) }}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{# Fin Listing #}
|
||||||
|
|
||||||
|
{# --- BLOC CTA Cosplayer (Tout en trans) --- #}
|
||||||
|
<div class="mt-20 bg-indigo-50 rounded-xl p-8 md:p-12 shadow-inner text-center">
|
||||||
|
<h2 class="text-3xl font-extrabold text-indigo-900 sm:text-4xl">
|
||||||
|
{{ 'cta_creator.heading'|trans }}
|
||||||
|
</h2>
|
||||||
|
<p class="mt-4 text-xl text-indigo-700">
|
||||||
|
{{ 'cta_creator.subtext'|trans({}) }}
|
||||||
|
</p>
|
||||||
|
<div class="mt-8 flex justify-center">
|
||||||
|
<a href="{{ path('app_pages_discover') }}"
|
||||||
|
class="inline-flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-lg text-white bg-pink-600 shadow-lg hover:bg-pink-700 transform hover:scale-[1.05] transition duration-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-pink-500">
|
||||||
|
{{ 'cta_creator.button'|trans({}) }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -792,4 +792,21 @@ page:
|
|||||||
|
|
||||||
breadcrumb: 'Votre page cosplayer(euse)'
|
breadcrumb: 'Votre page cosplayer(euse)'
|
||||||
|
|
||||||
|
epage_cosplay: 'EPAGE - Cosplayer(euse)'
|
||||||
|
hero:
|
||||||
|
heading: "L'Innovation au Service de Votre Succès"
|
||||||
|
subheading: "Découvrez comment notre expertise peut transformer vos défis en opportunités de croissance durable."
|
||||||
|
cta_main: "Découvrir Nos Solutions"
|
||||||
|
cta_secondary: "Prendre Rendez-vous"
|
||||||
|
page.title: "EPAGE - Cosplayer(euse)"
|
||||||
|
creators:
|
||||||
|
# Pluralisation pour le titre
|
||||||
|
title_plural: "Découvrez notre cosplayer(euse) qui a choisi Epage.|Découvrez nos %count% cosplayers(euses) qui ont choisi Epage."
|
||||||
|
intro_text: "Découvrez les artistes qui ont choisi Epage pour gérer, financer et partager leur passion."
|
||||||
|
social_label: "Réseaux Sociaux"
|
||||||
|
button: "Voir plus"
|
||||||
|
empty_list: "Aucun créateur n'est encore affiché ici"
|
||||||
|
cta_creator:
|
||||||
|
heading: "Êtes-vous cosplayer(euse) ?"
|
||||||
|
subtext: "Vous voulez une page pour présenter vos cosplay et interagir avec vos fans ?"
|
||||||
|
button: "Découvrir Epage pour les Créateurs"
|
||||||
|
|||||||
Reference in New Issue
Block a user