🐛 fix(templates): Corrige les numéros de RC Pro et une faute de frappe
Corrige le numéro de RC Pro dans les CGV et corrige une faute de frappe sur la page d'accueil de réservation. ```
This commit is contained in:
BIN
public/provider/video/vidéo finale site.mp4
Normal file
BIN
public/provider/video/vidéo finale site.mp4
Normal file
Binary file not shown.
@@ -7,6 +7,8 @@ use App\Entity\AccountResetPasswordRequest;
|
||||
use App\Form\RequestPasswordConfirmType;
|
||||
use App\Form\RequestPasswordRequestType;
|
||||
use App\Logger\AppLogger;
|
||||
use App\Repository\ProductRepository;
|
||||
use App\Service\Mailer\Mailer;
|
||||
use App\Service\ResetPassword\Event\ResetPasswordConfirmEvent;
|
||||
use App\Service\ResetPassword\Event\ResetPasswordEvent;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
@@ -14,9 +16,13 @@ use Fkrzski\RobotsTxt\RobotsTxt;
|
||||
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Mailer\MailerInterface;
|
||||
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||
@@ -41,14 +47,61 @@ class ReserverController extends AbstractController
|
||||
]);
|
||||
}
|
||||
#[Route('/reservation', name: 'reservation')]
|
||||
public function revervation()
|
||||
public function revervation(ProductRepository $productRepository): Response
|
||||
{
|
||||
return $this->render('revervation/home.twig');
|
||||
$products =$productRepository->findBy([], ['updatedAt' => 'DESC']);
|
||||
return $this->render('revervation/home.twig',[
|
||||
'products' => $products
|
||||
]);
|
||||
}
|
||||
#[Route('/reservation/contact', name: 'reservation_contact')]
|
||||
public function revervationContact()
|
||||
public function revervationContact(Request $request, Mailer $mailer): Response
|
||||
{
|
||||
return $this->render('revervation/home.twig');
|
||||
$form = $this->createFormBuilder()
|
||||
->add('name', TextType::class, [
|
||||
'label' => 'Nom',
|
||||
'required' => true,
|
||||
])
|
||||
->add('surname', TextType::class, [
|
||||
'label' => 'Prenom',
|
||||
'required' => true,
|
||||
])
|
||||
->add('email', EmailType::class, [
|
||||
'label' => 'Email',
|
||||
'required' => true,
|
||||
])
|
||||
->add('phone', TextType::class, [
|
||||
'label' => 'Telephone',
|
||||
'required' => true,
|
||||
])
|
||||
->add('message', TextareaType::class, [
|
||||
'label' => 'Message',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$formObject = $form->getForm();
|
||||
$formObject->handleRequest($request);
|
||||
|
||||
if ($formObject->isSubmitted() && $formObject->isValid()) {
|
||||
$data = $formObject->getData();
|
||||
|
||||
$mailer->send(
|
||||
'lilian@ludikevent.fr',
|
||||
"Ludikevent",
|
||||
"[Ludikevent] - Demande de contact via la plateforme de reservation",
|
||||
"mails/reserve/contact.twig",
|
||||
$data
|
||||
);
|
||||
|
||||
// Ajout du message flash de succès
|
||||
$this->addFlash('success', 'Votre message a bien été envoyé ! Notre équipe vous répondra dans les plus brefs délais.');
|
||||
|
||||
return $this->redirectToRoute('reservation_contact');
|
||||
}
|
||||
|
||||
return $this->render('revervation/contact.twig', [
|
||||
'form' => $formObject->createView()
|
||||
]);
|
||||
}
|
||||
#[Route('/reservation/recherche', name: 'reservation_search')]
|
||||
public function recherche()
|
||||
|
||||
@@ -16,12 +16,8 @@ use Twig\Environment;
|
||||
#[AsEventListener(event: ResponseEvent::class,method: 'onResponse')]
|
||||
class RedirecListener
|
||||
{
|
||||
private Environment $twig;
|
||||
|
||||
public function __construct(Environment $twig)
|
||||
{
|
||||
$this->twig = $twig;
|
||||
}
|
||||
|
||||
|
||||
public function onResponse(ResponseEvent $event): void
|
||||
{
|
||||
|
||||
46
templates/mails/reserve/contact.twig
Normal file
46
templates/mails/reserve/contact.twig
Normal file
@@ -0,0 +1,46 @@
|
||||
{% extends 'mails/base.twig' %}
|
||||
{% block content %}
|
||||
<mj-section background-color="#ffffff" padding-bottom="0px">
|
||||
<mj-column width="100%">
|
||||
<mj-text font-size="22px" font-weight="900" color="#0f172a" text-transform="uppercase" font-style="italic" align="center">
|
||||
Nouveau <span style="color:#2563eb">Message</span>
|
||||
</mj-text>
|
||||
<mj-divider border-width="1px" border-color="#f1f5f9" padding-top="20px" padding-bottom="20px" />
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
|
||||
<mj-section background-color="#ffffff" padding-top="0px">
|
||||
<mj-column width="100%">
|
||||
<mj-text padding-bottom="0px" font-size="10px" font-weight="900" color="#94a3b8" text-transform="uppercase" letter-spacing="1px">
|
||||
Expéditeur
|
||||
</mj-text>
|
||||
<mj-text font-size="18px" font-weight="700" color="#1e293b" padding-top="5px">
|
||||
{{ datas.surname }} {{ datas.name|upper }}
|
||||
</mj-text>
|
||||
|
||||
<mj-text padding-top="15px" padding-bottom="0px" font-size="10px" font-weight="900" color="#94a3b8" text-transform="uppercase" letter-spacing="1px">
|
||||
Coordonnées
|
||||
</mj-text>
|
||||
<mj-text font-size="15px" color="#0f172a" padding-top="5px">
|
||||
<b>Tél :</b> {{ datas.phone }} <br/>
|
||||
<b>Email :</b> <span style="color:#2563eb; font-weight:700;">{{ datas.email }}</span>
|
||||
</mj-text>
|
||||
|
||||
<mj-text padding-top="25px" padding-bottom="0px" font-size="10px" font-weight="900" color="#94a3b8" text-transform="uppercase" letter-spacing="1px">
|
||||
Contenu du message
|
||||
</mj-text>
|
||||
</mj-column>
|
||||
|
||||
<mj-column width="100%" background-color="#f8fafc" border-radius="20px">
|
||||
<mj-text font-style="italic" color="#334155" line-height="1.6" padding="20px">
|
||||
"{{ datas.message|nl2br }}"
|
||||
</mj-text>
|
||||
</mj-column>
|
||||
|
||||
<mj-column width="100%">
|
||||
<mj-button background-color="#2563eb" color="#ffffff" font-size="14px" font-weight="900" text-transform="uppercase" border-radius="16px" padding-top="30px" inner-padding="18px 30px" href="mailto:{{ datas.email }}">
|
||||
Répondre au client ⚡
|
||||
</mj-button>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
{% endblock %}
|
||||
@@ -146,6 +146,38 @@
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
{# --- GESTION DES MESSAGES FLASH --- #}
|
||||
{% for label, messages in app.flashes %}
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-4">
|
||||
{% for message in messages %}
|
||||
<div class="flex items-center justify-between p-4 rounded-[2rem] shadow-lg border animate-in fade-in slide-in-from-top-4 duration-500
|
||||
{% if label == 'success' %}
|
||||
bg-emerald-50 border-emerald-100 text-emerald-800
|
||||
{% elseif label == 'error' or label == 'danger' %}
|
||||
bg-red-50 border-red-100 text-red-800
|
||||
{% else %}
|
||||
bg-blue-50 border-blue-100 text-blue-800
|
||||
{% endif %}">
|
||||
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="text-xl">
|
||||
{% if label == 'success' %} ✅
|
||||
{% elseif label == 'error' or label == 'danger' %} ❌
|
||||
{% else %} ℹ️ {% endif %}
|
||||
</span>
|
||||
<p class="text-sm font-black italic uppercase tracking-tight">{{ message }}</p>
|
||||
</div>
|
||||
|
||||
{# Bouton pour fermer le message #}
|
||||
<button onclick="this.parentElement.parentElement.remove()" class="p-2 hover:opacity-50 transition-opacity">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{# --- CONTENU --- #}
|
||||
<main class="flex-grow">
|
||||
|
||||
117
templates/revervation/contact.twig
Normal file
117
templates/revervation/contact.twig
Normal file
@@ -0,0 +1,117 @@
|
||||
{% extends 'revervation/base.twig' %}
|
||||
|
||||
{% block title %}Contactez l'expert - Ludik Event{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="min-h-screen bg-gray-50/50 font-sans antialiased pb-20">
|
||||
|
||||
{# --- HEADER --- #}
|
||||
<div class="max-w-6xl mx-auto pt-16 pb-12 px-4">
|
||||
<div class="flex flex-col md:flex-row items-end justify-between gap-6 border-b border-slate-200 pb-8">
|
||||
<div>
|
||||
<h1 class="text-5xl md:text-7xl font-black text-slate-900 uppercase tracking-tighter italic leading-none">
|
||||
Parlons <span class="text-blue-600">Ensemble</span>
|
||||
</h1>
|
||||
<p class="mt-4 text-slate-500 font-medium italic">Une question ? Un devis ? Notre équipe d'experts vous répond.</p>
|
||||
</div>
|
||||
<div class="hidden md:block text-right">
|
||||
<p class="text-[10px] font-black text-slate-400 uppercase tracking-[0.3em] mb-1">Délai de réponse</p>
|
||||
<p class="text-sm font-bold text-slate-900 italic">Moins de 2 heures</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="max-w-6xl mx-auto px-4">
|
||||
<div class="grid grid-cols-1 md:grid-cols-12 gap-6">
|
||||
|
||||
{# 1. FORMULAIRE (Bento Large) #}
|
||||
<div class="md:col-span-8 bg-white p-8 md:p-12 rounded-[3rem] shadow-sm border border-slate-100">
|
||||
<h2 class="text-2xl font-black text-slate-900 uppercase italic mb-8 tracking-tight">Envoyer un <span class="text-blue-600">Message</span></h2>
|
||||
|
||||
{{ form_start(form, {'attr': {'class': 'space-y-6'}}) }}
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div class="space-y-2">
|
||||
<label class="text-[10px] font-black uppercase tracking-widest text-slate-400 ml-2">Votre Nom</label>
|
||||
{{ form_widget(form.name, {'attr': {'class': 'w-full bg-slate-50 border-none rounded-2xl px-6 py-4 focus:ring-2 focus:ring-blue-500 transition-all font-medium', 'placeholder': 'Ex: Dupont'}}) }}
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="text-[10px] font-black uppercase tracking-widest text-slate-400 ml-2">Votre Prénom</label>
|
||||
{{ form_widget(form.surname, {'attr': {'class': 'w-full bg-slate-50 border-none rounded-2xl px-6 py-4 focus:ring-2 focus:ring-blue-500 transition-all font-medium', 'placeholder': 'Ex: Jean'}}) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div class="space-y-2">
|
||||
<label class="text-[10px] font-black uppercase tracking-widest text-slate-400 ml-2">Téléphone</label>
|
||||
{{ form_widget(form.phone, {'attr': {'class': 'w-full bg-slate-50 border-none rounded-2xl px-6 py-4 focus:ring-2 focus:ring-blue-500 transition-all font-medium', 'placeholder': '06 .. .. .. ..'}}) }}
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="text-[10px] font-black uppercase tracking-widest text-slate-400 ml-2">Email</label>
|
||||
{{ form_widget(form.email, {'attr': {'class': 'w-full bg-slate-50 border-none rounded-2xl px-6 py-4 focus:ring-2 focus:ring-blue-500 transition-all font-medium', 'placeholder': 'jean@exemple.fr'}}) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label class="text-[10px] font-black uppercase tracking-widest text-slate-400 ml-2">Votre projet / Question</label>
|
||||
{{ form_widget(form.message, {'attr': {'class': 'w-full bg-slate-50 border-none rounded-3xl px-6 py-4 focus:ring-2 focus:ring-blue-500 transition-all font-medium h-40', 'placeholder': 'Dites-nous tout sur votre événement...'}}) }}
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full md:w-auto px-12 py-5 bg-blue-600 text-white rounded-2xl font-black uppercase tracking-widest hover:bg-slate-900 hover:-translate-y-1 transition-all shadow-xl shadow-blue-100">
|
||||
Envoyer ma demande ⚡
|
||||
</button>
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
|
||||
{# 2. INFOS DE CONTACT (Bento Side) #}
|
||||
<div class="md:col-span-4 space-y-6">
|
||||
|
||||
{# Tuile Téléphone #}
|
||||
<div class="bg-blue-600 p-8 rounded-[2.5rem] shadow-xl text-white relative overflow-hidden group">
|
||||
<div class="absolute -right-4 -bottom-4 text-7xl opacity-10 group-hover:scale-110 transition-transform">📞</div>
|
||||
<p class="text-[10px] font-black uppercase tracking-widest mb-4 opacity-80">Appel direct</p>
|
||||
<a href="tel:0614172447" class="text-2xl font-black italic hover:text-amber-300 transition-colors tracking-tighter">06 14 17 24 47</a>
|
||||
</div>
|
||||
|
||||
{# Tuile Email #}
|
||||
<div class="bg-slate-900 p-8 rounded-[2.5rem] shadow-xl text-white relative overflow-hidden group border border-slate-800">
|
||||
<div class="absolute -right-4 -bottom-4 text-7xl opacity-10 group-hover:scale-110 transition-transform">✉️</div>
|
||||
<p class="text-[10px] font-black uppercase tracking-widest mb-4 opacity-60">Par écrit</p>
|
||||
<a href="mailto:lilian@ludikevent.fr" class="text-lg font-bold italic hover:text-blue-400 transition-colors break-words">lilian@ludikevent.fr</a>
|
||||
</div>
|
||||
|
||||
{# Tuile Services #}
|
||||
<div class="bg-white p-8 rounded-[2.5rem] border border-slate-100 shadow-sm">
|
||||
<h3 class="text-[10px] font-black uppercase tracking-widest mb-6 text-slate-400 italic">À votre service</h3>
|
||||
<ul class="space-y-4">
|
||||
<li class="flex items-center gap-3">
|
||||
<span class="text-blue-600 font-bold">✓</span>
|
||||
<span class="text-sm font-bold text-slate-700 italic">Expertise technique</span>
|
||||
</li>
|
||||
<li class="flex items-center gap-3">
|
||||
<span class="text-blue-600 font-bold">✓</span>
|
||||
<span class="text-sm font-bold text-slate-700 italic">Livraison flexible</span>
|
||||
</li>
|
||||
<li class="flex items-center gap-3">
|
||||
<span class="text-blue-600 font-bold">✓</span>
|
||||
<span class="text-sm font-bold text-slate-700 italic">Large choix de structures</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{# Tuile Localisation #}
|
||||
<div class="bg-amber-400 p-8 rounded-[2.5rem] shadow-sm flex flex-col justify-between">
|
||||
<div>
|
||||
<p class="text-[10px] font-black text-amber-900 uppercase tracking-widest mb-2">Secteur d'intervention</p>
|
||||
<p class="text-sm font-black text-amber-900 italic">Aisne (02) & Hauts-de-France</p>
|
||||
</div>
|
||||
<div class="mt-4 flex gap-1">
|
||||
<div class="h-1 w-12 bg-amber-900/20 rounded-full"></div>
|
||||
<div class="h-1 w-4 bg-amber-900/20 rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,43 +1,44 @@
|
||||
{% extends 'revervation/base.twig' %}
|
||||
|
||||
{% block body %}
|
||||
<div class="space-y-20 pb-20">
|
||||
{% block title %}Location de Châteaux Gonflables - Ludik Event{% endblock %}
|
||||
|
||||
{# --- SECTION HERO : L'accroche visuelle --- #}
|
||||
{% block body %}
|
||||
<div class="space-y-20 pb-20 bg-gray-50/50">
|
||||
|
||||
{# --- SECTION HERO --- #}
|
||||
<section class="relative overflow-hidden pt-16 pb-8 lg:pt-24">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="lg:grid lg:grid-cols-12 lg:gap-8 items-center">
|
||||
<div class="sm:text-center md:max-w-2xl md:mx-auto lg:col-span-6 lg:text-left">
|
||||
<span class="inline-flex items-center px-4 py-1.5 rounded-full text-sm font-semibold bg-blue-100 text-blue-700 mb-6">
|
||||
🎉 Nouveau : Châteaux Jungle disponibles
|
||||
</span>
|
||||
<h1 class="text-5xl md:text-7xl font-black tracking-tight text-gray-900 leading-[1.1]">
|
||||
<h1 class="text-5xl md:text-7xl font-black tracking-tight text-gray-900 leading-[1.1] uppercase italic">
|
||||
Louez le <span class="text-blue-600">Bonheur</span> <br>
|
||||
<span class="text-amber-500 underline decoration-blue-600/20">en un clic.</span>
|
||||
</h1>
|
||||
<p class="mt-6 text-lg text-gray-600 leading-relaxed">
|
||||
Ludikevent simplifie vos événements. Des structures certifiées, une livraison rapide et des souvenirs inoubliables pour les petits et les grands.
|
||||
<p class="mt-6 text-lg text-gray-600 leading-relaxed italic">
|
||||
Ludik Event simplifie vos événements. Des structures certifiées, une livraison rapide et des souvenirs inoubliables pour les petits et les grands.
|
||||
</p>
|
||||
<div class="mt-10 flex flex-col sm:flex-row gap-4 sm:justify-center lg:justify-start">
|
||||
<a href="#catalogue" class="px-8 py-4 bg-blue-600 text-white rounded-2xl font-bold text-lg shadow-xl shadow-blue-200 hover:bg-blue-700 transition-all hover:-translate-y-1 text-center">
|
||||
<a href="#catalogue" class="px-8 py-4 bg-blue-600 text-white rounded-2xl font-bold text-lg shadow-xl shadow-blue-200 hover:bg-blue-700 transition-all hover:-translate-y-1 text-center uppercase tracking-tighter">
|
||||
Voir le catalogue
|
||||
</a>
|
||||
<a href="tel:0614172447" class="px-8 py-4 bg-white text-gray-700 border border-gray-200 rounded-2xl font-bold text-lg hover:bg-gray-50 transition-all text-center">
|
||||
Nous appeler
|
||||
<a href="tel:0614172447" class="px-8 py-4 bg-white text-gray-700 border border-gray-200 rounded-2xl font-bold text-lg hover:bg-gray-50 transition-all text-center uppercase tracking-tighter">
|
||||
📞 06 14 17 24 47
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Image Hero avec effet de profondeur #}
|
||||
{# Vidéo Hero #}
|
||||
<div class="mt-12 lg:mt-0 lg:col-span-6 relative">
|
||||
<div class="relative mx-auto w-full rounded-3xl overflow-hidden shadow-2xl rotate-2 hover:rotate-0 transition-transform duration-500">
|
||||
<img src="https://fastly.picsum.photos/id/891/900/900.jpg?hmac=wrVmh5uJ2iYgYxcBahf7RQIe8z6AAPGIJg8AmMqUuE4" alt="Château gonflable Ludikevent" class="w-full h-full object-cover aspect-[4/3]">
|
||||
<div class="relative mx-auto w-full rounded-[3rem] overflow-hidden shadow-2xl rotate-2 hover:rotate-0 transition-transform duration-500 border-8 border-white">
|
||||
<video autoplay muted loop playsinline src="{{ asset('provider/video/vidéo finale site.mp4') }}" class="w-full h-full object-cover aspect-[4/3]">
|
||||
</video>
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-black/20 to-transparent"></div>
|
||||
</div>
|
||||
{# Badge flottant #}
|
||||
<div class="absolute -bottom-6 -left-6 bg-white p-6 rounded-3xl shadow-xl hidden md:block">
|
||||
<div class="absolute -bottom-6 -left-6 bg-white p-6 rounded-3xl shadow-xl hidden md:block border border-gray-100">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="p-3 bg-amber-100 rounded-2xl text-amber-600 uppercase font-black text-xs">Top Qualité</div>
|
||||
<div class="p-3 bg-amber-100 rounded-2xl text-amber-600 uppercase font-black text-xs tracking-widest">
|
||||
⭐ Top Qualité
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -45,52 +46,100 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{# --- SECTION CATALOGUE : Les produits --- #}
|
||||
<section id="catalogue" class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between items-end mb-12">
|
||||
<div>
|
||||
<h2 class="text-3xl font-black text-gray-900">Nos Best-Sellers</h2>
|
||||
<p class="text-gray-500 mt-2">Les structures préférées de nos clients.</p>
|
||||
{# --- SECTION SERVICES (Nouveauté) --- #}
|
||||
<section class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<div class="flex items-center gap-6 p-8 bg-white rounded-[2.5rem] border border-gray-100 shadow-sm">
|
||||
<div class="w-14 h-14 bg-blue-50 rounded-2xl flex items-center justify-center text-2xl shrink-0">💬</div>
|
||||
<div>
|
||||
<h4 class="font-black text-gray-900 uppercase italic text-sm">Service Client Expert</h4>
|
||||
<p class="text-xs text-gray-500 mt-1 italic">Une équipe à votre écoute pour un événement sur mesure.</p>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ path('reservation_contact') }}" class="text-blue-600 font-bold hover:underline flex items-center gap-2">
|
||||
Tout voir
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M14 5l7 7m0 0l-7 7m7-7H3"/></svg>
|
||||
<div class="flex items-center gap-6 p-8 bg-white rounded-[2.5rem] border border-gray-100 shadow-sm">
|
||||
<div class="w-14 h-14 bg-amber-50 rounded-2xl flex items-center justify-center text-2xl shrink-0">🚚</div>
|
||||
<div>
|
||||
<h4 class="font-black text-gray-900 uppercase italic text-sm">Livraison Possible</h4>
|
||||
<p class="text-xs text-gray-500 mt-1 italic">Nous livrons vos structures directement sur le lieu de fête.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-6 p-8 bg-white rounded-[2.5rem] border border-gray-100 shadow-sm">
|
||||
<div class="w-14 h-14 bg-indigo-50 rounded-2xl flex items-center justify-center text-2xl shrink-0">🎡</div>
|
||||
<div>
|
||||
<h4 class="font-black text-gray-900 uppercase italic text-sm">Large Choix</h4>
|
||||
<p class="text-xs text-gray-500 mt-1 italic">Un catalogue varié pour satisfaire toutes les envies.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{# --- SECTION CATALOGUE --- #}
|
||||
<section id="catalogue" class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex flex-col md:flex-row justify-between items-end mb-12 gap-4">
|
||||
<div>
|
||||
<h2 class="text-4xl font-black text-gray-900 uppercase italic tracking-tighter">Nos <span class="text-blue-600">Best-Sellers</span></h2>
|
||||
<p class="text-gray-500 mt-2 italic">Sélectionnés pour le succès de vos fêtes.</p>
|
||||
</div>
|
||||
<a href="{{ path('reservation_contact') }}" class="group text-blue-600 font-bold flex items-center gap-2 uppercase text-xs tracking-[0.2em] bg-blue-50 px-6 py-3 rounded-full hover:bg-blue-600 hover:text-white transition-all">
|
||||
Tout l'univers
|
||||
<svg class="w-4 h-4 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M14 5l7 7m0 0l-7 7m7-7H3"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{# Exemple de carte produit répétable #}
|
||||
{% for i in 1..3 %}
|
||||
<div class="group bg-white rounded-[2.5rem] p-4 border border-gray-100 shadow-sm hover:shadow-xl transition-all duration-500">
|
||||
<div class="relative overflow-hidden rounded-[2rem] aspect-[4/5]">
|
||||
<img src="https://fastly.picsum.photos/id/33/500/900.jpg?hmac=GIlXM3iIDVzeqRySjChrdtU_Npf794Nbf6XcxaCiff8" class="w-full h-full object-cover transform group-hover:scale-110 transition-transform duration-700">
|
||||
<div class="absolute top-4 left-4 bg-white/90 backdrop-blur-md px-4 py-2 rounded-2xl shadow-sm">
|
||||
<span class="text-blue-600 font-black text-sm uppercase">Dès 120€</span>
|
||||
{% for product in products %}
|
||||
<div class="group bg-white rounded-[3rem] p-4 border border-gray-100 shadow-sm hover:shadow-2xl transition-all duration-500 flex flex-col">
|
||||
|
||||
{# Conteneur Image #}
|
||||
<div class="relative overflow-hidden rounded-[2.5rem] aspect-[4/5] bg-slate-50 flex items-center justify-center">
|
||||
|
||||
{% if product.imageName and product.imageName != "" %}
|
||||
<img src="{{ vich_uploader_asset(product,'imageFile') | imagine_filter('webp') }}"
|
||||
alt="{{ product.name }}"
|
||||
class="w-full h-full object-cover transform group-hover:scale-110 transition-transform duration-700">
|
||||
{% else %}
|
||||
{# FALLBACK : Image par défaut si vide #}
|
||||
<div class="flex flex-col items-center justify-center p-12 text-center">
|
||||
<img src="{{ asset('provider/images/favicon.png') }}"
|
||||
alt="Ludik Event"
|
||||
class="w-20 h-20 object-contain opacity-20 group-hover:opacity-100 group-hover:scale-110 transition-all duration-500 grayscale group-hover:grayscale-0">
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Badge Prix flottant #}
|
||||
<div class="absolute top-5 left-5 bg-white/90 backdrop-blur-md px-4 py-2 rounded-2xl shadow-sm border border-white/50">
|
||||
<p class="text-[9px] font-black text-gray-400 uppercase tracking-widest mb-0.5">Location / Jour</p>
|
||||
<p class="text-blue-600 font-black text-sm uppercase leading-none">
|
||||
Dès {{ product.priceDay|format_currency('EUR') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6 px-2 pb-2">
|
||||
<h3 class="text-xl font-bold text-gray-900">Le Royaume Magique</h3>
|
||||
<div class="mt-3 flex items-center gap-4 text-gray-400 text-sm font-medium">
|
||||
<span class="flex items-center gap-1.5">
|
||||
<svg class="w-4 h-4 text-amber-500" fill="currentColor" viewBox="0 0 20 20"><path d="M13 6a3 3 0 11-6 0 3 3 0 016 0zM18 8a2 2 0 11-4 0 2 2 0 014 0zM6 8a2 2 0 11-4 0 2 2 0 014 0zM11 18a4 4 0 00-8 0 4 4 0 008 0zM19 18a4 4 0 00-8 0 4 4 0 008 0z"/></svg>
|
||||
10 Enfants
|
||||
</span>
|
||||
<span class="flex items-center gap-1.5">
|
||||
<svg class="w-4 h-4 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"/></svg>
|
||||
25 m²
|
||||
</span>
|
||||
|
||||
{# Infos Produit #}
|
||||
<div class="mt-6 px-2 pb-2 flex-grow flex flex-col justify-between">
|
||||
<div>
|
||||
<span class="text-[10px] font-black text-blue-500 uppercase tracking-widest italic mb-1 block">
|
||||
Réf: {{ product.ref }}
|
||||
</span>
|
||||
<h3 class="text-2xl font-black text-gray-900 group-hover:text-blue-600 transition-colors leading-tight italic uppercase">
|
||||
{{ product.name }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="mt-8 flex gap-3">
|
||||
<a href="#" class="flex-grow py-4 bg-gray-900 text-white text-center rounded-2xl font-bold hover:bg-blue-600 transition-colors">
|
||||
Réserver
|
||||
|
||||
<div class="mt-8">
|
||||
<a href="#" class="block w-full py-4 bg-gray-900 text-white text-center rounded-[1.5rem] font-black uppercase text-sm tracking-widest hover:bg-blue-600 transition-all shadow-xl hover:shadow-blue-200 active:scale-95">
|
||||
Réserver ce bonheur
|
||||
</a>
|
||||
<button class="p-4 bg-gray-50 text-gray-400 rounded-2xl hover:text-blue-600 transition-colors">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
{# Message si aucun produit n'est trouvé #}
|
||||
<div class="col-span-full py-20 text-center bg-white rounded-[3rem] border-2 border-dashed border-gray-200">
|
||||
<p class="text-gray-400 font-bold italic uppercase tracking-widest">Le catalogue est en cours de mise à jour...</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user