```
✨ feat(membres): Ajoute la page des membres avec les membres du bureau.
```
This commit is contained in:
@@ -25,6 +25,27 @@ class MembersController extends AbstractController
|
||||
#[Route(path: '/membres', name: 'app_members', options: ['sitemap' => true], methods: ['GET'])]
|
||||
public function index(): Response
|
||||
{
|
||||
return $this->render('home.twig');
|
||||
return $this->render('members.twig',[
|
||||
'board_members' => [
|
||||
[
|
||||
'pseudo' => 'Shoko Cosplay',
|
||||
'photo_url' => '/assets/images/shoko.jpg',
|
||||
'role' => 'Président',
|
||||
'cosplayer' => true,
|
||||
'crosscosplayer' => true,
|
||||
'trans' => true,
|
||||
'orientation' => 'pansexual',
|
||||
],
|
||||
[
|
||||
'pseudo' => 'Marta Gator',
|
||||
'photo_url' => '/assets/images/marta.jpg',
|
||||
'role' => 'Secrétaire',
|
||||
'cosplayer' => true,
|
||||
'crosscosplayer' => true,
|
||||
'trans' => false,
|
||||
'orientation' => 'heterosexual',
|
||||
]
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ class SitemapSubscriber
|
||||
$urlMembers = new UrlConcrete($urlGenerator->generate('app_members', [], UrlGeneratorInterface::ABSOLUTE_URL));
|
||||
$decoratedUrlMembers = new GoogleImageUrlDecorator($urlMembers);
|
||||
$decoratedUrlMembers->addImage(new GoogleImage($this->cacheManager->resolve('assets/images/logo.jpg','webp')));
|
||||
$decoratedUrlMembers->addImage(new GoogleImage($this->cacheManager->resolve('assets/images/shoko.jpg','webp')));
|
||||
$decoratedUrlMembers->addImage(new GoogleImage($this->cacheManager->resolve('assets/images/marta.jpg','webp')));
|
||||
$decoratedUrlMembers = new GoogleMultilangUrlDecorator($decoratedUrlMembers);
|
||||
$decoratedUrlMembers->addLink($urlGenerator->generate('app_members',['lang'=>'fr'], UrlGeneratorInterface::ABSOLUTE_URL), 'fr');
|
||||
$decoratedUrlMembers->addLink($urlGenerator->generate('app_members',['lang'=>'en'], UrlGeneratorInterface::ABSOLUTE_URL), 'en');
|
||||
@@ -47,6 +49,8 @@ class SitemapSubscriber
|
||||
$urlEvents->addLink($urlGenerator->generate('app_events',['lang'=>'en'], UrlGeneratorInterface::ABSOLUTE_URL), 'en');
|
||||
$urlContainer->addUrl($urlEvents, 'default');
|
||||
|
||||
|
||||
|
||||
$urlAbout = new UrlConcrete($urlGenerator->generate('app_about', [], UrlGeneratorInterface::ABSOLUTE_URL));
|
||||
$decoratedUrlAbout = new GoogleImageUrlDecorator($urlAbout);
|
||||
$decoratedUrlAbout->addImage(new GoogleImage($this->cacheManager->resolve('assets/images/logo.jpg','webp')));
|
||||
|
||||
209
templates/members.twig
Normal file
209
templates/members.twig
Normal file
@@ -0,0 +1,209 @@
|
||||
{% extends 'base.twig' %}
|
||||
|
||||
{% block title %}{{'members_page.title'|trans}}{% endblock %}
|
||||
|
||||
{% block canonical_url %}<link rel="canonical" href="{{ url('app_members') }}" />{% 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": "{{'members_page.breadcrumb'|trans}}",
|
||||
"item": "{{ app.request.schemeAndHttpHost }}{{ app.request.pathInfo }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="container mx-auto p-4 md:p-8 pt-12">
|
||||
<h1 class="text-4xl font-extrabold text-center mb-12 text-gray-800">
|
||||
{{ 'members_page.title'|trans }}
|
||||
</h1>
|
||||
|
||||
{# --- SECTION 1 : Membres du Bureau --- #}
|
||||
<section class="mb-16">
|
||||
<h2 class="text-3xl font-bold border-b pb-4 mb-8 text-indigo-700">
|
||||
{{ 'members_page.board_title'|trans }}
|
||||
</h2>
|
||||
|
||||
{% if board_members is defined and board_members|length > 0 %}
|
||||
{# Grille de 3 colonnes sur les grands écrans #}
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 gap-8">
|
||||
|
||||
{% for member in board_members %}
|
||||
{# Début de la carte du membre (Bureau) #}
|
||||
<div class="bg-white p-6 rounded-xl shadow-lg border border-gray-100 hover:shadow-xl transition duration-300 transform hover:scale-[1.02] flex flex-col">
|
||||
|
||||
{# Photo et Pseudo #}
|
||||
<div class="text-center mb-4">
|
||||
<img src="{{ member.photo_url|default('placeholder.jpg') }}" alt="Photo de {{ member.pseudo }}" class="w-24 h-24 mx-auto rounded-full object-cover border-4 border-indigo-200 shadow-md">
|
||||
<h3 class="text-xl font-bold mt-3 text-gray-800">{{ member.pseudo }}</h3>
|
||||
</div>
|
||||
|
||||
{# Rôle #}
|
||||
<div class="space-y-3 flex-grow border-t pt-4 mb-3">
|
||||
<p class="text-sm">
|
||||
<strong class="font-semibold text-indigo-600">{{ 'member_card.role'|trans }}:</strong>
|
||||
<span class="text-gray-700">{{ member.role|default('-')|trans }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{# BADGE Cosplayer #}
|
||||
<div class="mb-4">
|
||||
<strong class="text-sm font-semibold text-gray-800 mr-2">{{ 'member_card.cosplay_label'|trans }}:</strong>
|
||||
|
||||
{% if member.cosplayer %}
|
||||
<span class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
|
||||
{{ 'member_card.yes'|trans }}
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-600">
|
||||
{{ 'member_card.no'|trans }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{# BADGES Spécificités #}
|
||||
{# BADGES Spécificités (Mis à jour pour n'afficher que les statuts VRAIS) #}
|
||||
<div class="space-y-2 pt-3 border-t">
|
||||
<p class="text-xs text-gray-500 font-semibold uppercase">{{ 'member_card.specifics'|trans }}</p>
|
||||
|
||||
<div class="flex flex-wrap gap-2">
|
||||
|
||||
{# Badge Crosscosplayer : Affiché uniquement si VRAI #}
|
||||
{% if member.crosscosplayer %}
|
||||
<span class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800">
|
||||
{{ 'member_card.crosscosplay'|trans }}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{# Badge Transgenre : Affiché uniquement si VRAI #}
|
||||
{% if member.trans %}
|
||||
<span class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium bg-pink-100 text-pink-800">
|
||||
{{ 'member_card.trans'|trans }}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{# Badge Orientation (toujours affiché, avec couleur conditionnelle) #}
|
||||
{% set orientation_key = member.orientation ? 'orientation.' ~ member.orientation : null %}
|
||||
{% set orientation_text = orientation_key ? orientation_key|trans : 'member_card.not_specified'|trans %}
|
||||
{% set orientation_color = orientation_key ? 'bg-purple-100 text-purple-800' : 'bg-gray-100 text-gray-600' %}
|
||||
|
||||
<span class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium {{ orientation_color }}">
|
||||
{{ 'member_card.orientation_label'|trans }}: {{ orientation_text }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{# Fin de la carte du membre (Bureau) #}
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-center text-gray-600 p-6 border rounded-lg bg-gray-50">
|
||||
{{ 'members_page.board_empty'|trans }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
{# --- SECTION 2 : Tous les autres Membres --- #}
|
||||
<section>
|
||||
<h2 class="text-3xl font-bold border-b pb-4 mb-8 text-indigo-700">
|
||||
{{ 'members_page.all_title'|trans }}
|
||||
</h2>
|
||||
|
||||
{% if members is defined and members|length > 0 %}
|
||||
{# Grille de 3 colonnes sur les grands écrans #}
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 gap-8">
|
||||
|
||||
{% for member in members %}
|
||||
{# Début de la carte du membre (Général) #}
|
||||
<div class="bg-white p-6 rounded-xl shadow-lg border border-gray-100 hover:shadow-xl transition duration-300 transform hover:scale-[1.02] flex flex-col">
|
||||
|
||||
{# Photo et Pseudo #}
|
||||
<div class="text-center mb-4">
|
||||
<img src="{{ member.photo_url | imagine_filter('filter')}} ) }}" alt="Photo de {{ member.pseudo }}" class="w-24 h-24 mx-auto rounded-full object-cover border-4 border-indigo-200 shadow-md">
|
||||
<h3 class="text-xl font-bold mt-3 text-gray-800">{{ member.pseudo }}</h3>
|
||||
</div>
|
||||
|
||||
{# Rôle #}
|
||||
<div class="space-y-3 flex-grow border-t pt-4 mb-3">
|
||||
<p class="text-sm">
|
||||
<strong class="font-semibold text-indigo-600">{{ 'member_card.role'|trans }}:</strong>
|
||||
<span class="text-gray-700">{{ member.role|default('-')|trans }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{# BADGE Cosplayer #}
|
||||
<div class="mb-4">
|
||||
<strong class="text-sm font-semibold text-gray-800 mr-2">{{ 'member_card.cosplay_label'|trans }}:</strong>
|
||||
|
||||
{% if member.cosplayer %}
|
||||
<span class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
|
||||
{{ 'member_card.yes'|trans }}
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-600">
|
||||
{{ 'member_card.no'|trans }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{# BADGES Spécificités #}
|
||||
{# BADGES Spécificités (Mis à jour pour n'afficher que les statuts VRAIS) #}
|
||||
<div class="space-y-2 pt-3 border-t">
|
||||
<p class="text-xs text-gray-500 font-semibold uppercase">{{ 'member_card.specifics'|trans }}</p>
|
||||
|
||||
<div class="flex flex-wrap gap-2">
|
||||
|
||||
{# Badge Crosscosplayer : Affiché uniquement si VRAI #}
|
||||
{% if member.crosscosplayer %}
|
||||
<span class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800">
|
||||
{{ 'member_card.crosscosplay'|trans }}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{# Badge Transgenre : Affiché uniquement si VRAI #}
|
||||
{% if member.trans %}
|
||||
<span class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium bg-pink-100 text-pink-800">
|
||||
{{ 'member_card.trans'|trans }}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{# Badge Orientation (toujours affiché, avec couleur conditionnelle) #}
|
||||
{% set orientation_key = member.orientation ? 'orientation.' ~ member.orientation : null %}
|
||||
{% set orientation_text = orientation_key ? orientation_key|trans : 'member_card.not_specified'|trans %}
|
||||
{% set orientation_color = orientation_key ? 'bg-purple-100 text-purple-800' : 'bg-gray-100 text-gray-600' %}
|
||||
|
||||
<span class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium {{ orientation_color }}">
|
||||
{{ 'member_card.orientation_label'|trans }}: {{ orientation_text }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{# Fin de la carte du membre (Général) #}
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-center text-gray-600 p-6 border rounded-lg bg-gray-50">
|
||||
{{ 'members_page.all_empty'|trans }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -447,3 +447,35 @@ contact_form.tel.label: "Phone (optional)"
|
||||
contact_form.tel.placeholder: "Ex: 555-123-4567"
|
||||
contact_form.message.label: "Your message"
|
||||
contact_form.message.placeholder: "Type your question or request..."
|
||||
|
||||
members_title: 'Membres'
|
||||
# --- MEMBERS PAGE (members.twig) ---
|
||||
members_page.title: "Our Members & Board"
|
||||
members_page.breadcrumb: "Members"
|
||||
members_page.board_title: "Board Members"
|
||||
members_page.board_empty: "The list of board members will be available soon."
|
||||
members_page.all_title: "All Members"
|
||||
members_page.all_empty: "No members have been found at this time."
|
||||
|
||||
# MEMBER CARD KEYS (Badges and Labels)
|
||||
member_card.role: "Role"
|
||||
member_card.cosplay_label: "Cosplayer"
|
||||
member_card.yes: "Yes"
|
||||
member_card.no: "No"
|
||||
member_card.specifics: "Specifics"
|
||||
member_card.crosscosplay: "Crosscosplayer"
|
||||
member_card.trans: "Transgender"
|
||||
member_card.orientation_label: "Orientation"
|
||||
member_card.not_specified: "Not specified"
|
||||
|
||||
# --- SEXUAL ORIENTATIONS ---
|
||||
orientation.asexual: "Asexual"
|
||||
orientation.bisexual: "Bisexual"
|
||||
orientation.demisexual: "Demisexual"
|
||||
orientation.gay: "Gay"
|
||||
orientation.heterosexual: "Heterosexual"
|
||||
orientation.lesbian: "Lesbian"
|
||||
orientation.pansexual: "Pansexual"
|
||||
orientation.queer: "Queer"
|
||||
orientation.questioning: "Questioning"
|
||||
orientation.other: "Other"
|
||||
|
||||
@@ -440,3 +440,32 @@ contact_form.subject.label: "Sujet"
|
||||
contact_form.tel.label: "Téléphone (facultatif)"
|
||||
contact_form.message.label: "Votre message"
|
||||
form_email_label: "Adresse e-mail"
|
||||
|
||||
|
||||
members_page.title: "Nos Membres & Bureau"
|
||||
members_page.breadcrumb: "Membres"
|
||||
members_page.board_title: "Membres du Bureau"
|
||||
members_page.board_empty: "La liste des membres du bureau sera bientôt disponible."
|
||||
members_page.all_title: "Tous les Membres"
|
||||
members_page.all_empty: "Aucun membre n'a été trouvé pour le moment."
|
||||
members_title: 'Membres'
|
||||
# CLÉS DANS LA FICHE DE MEMBRE (Badges et Labels)
|
||||
member_card.role: "Rôle"
|
||||
member_card.cosplay_label: "Cosplayer"
|
||||
member_card.yes: "Oui"
|
||||
member_card.no: "Non"
|
||||
member_card.specifics: "Spécificités"
|
||||
member_card.crosscosplay: "Crosscosplayer"
|
||||
member_card.trans: "Transgenre"
|
||||
member_card.orientation_label: "Orientation"
|
||||
member_card.not_specified: "Non spécifié"
|
||||
orientation.asexual: "Asexuel(le)"
|
||||
orientation.bisexual: "Bisexuel(le)"
|
||||
orientation.demisexual: "Demisexuel(le)"
|
||||
orientation.gay: "Gay"
|
||||
orientation.heterosexual: "Hétérosexuel(le)"
|
||||
orientation.lesbian: "Lesbienne"
|
||||
orientation.pansexual: "Pansexuel(le)"
|
||||
orientation.queer: "Queer"
|
||||
orientation.questioning: "En questionnement"
|
||||
orientation.other: "Autre"
|
||||
|
||||
Reference in New Issue
Block a user