Création de la gestion des catégorie
This commit is contained in:
31
migrations/Version20260213134522.php
Normal file
31
migrations/Version20260213134522.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20260213134522 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TABLE category (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY (id))');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP TABLE category');
|
||||||
|
}
|
||||||
|
}
|
||||||
92
src/Controller/Dashboard/CategoryController.php
Normal file
92
src/Controller/Dashboard/CategoryController.php
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Dashboard;
|
||||||
|
|
||||||
|
use App\Entity\Category;
|
||||||
|
use App\Entity\Customer;
|
||||||
|
use App\Entity\CustomerAddress;
|
||||||
|
use App\Form\CategoryType;
|
||||||
|
use App\Form\CustomerAddAddressType;
|
||||||
|
use App\Form\CustomerAddType;
|
||||||
|
use App\Form\CustomerType;
|
||||||
|
use App\Logger\AppLogger;
|
||||||
|
use App\Repository\CategoryRepository;
|
||||||
|
use App\Repository\ContratsRepository;
|
||||||
|
use App\Repository\CustomerAddressRepository;
|
||||||
|
use App\Repository\CustomerRepository;
|
||||||
|
use App\Repository\DevisRepository;
|
||||||
|
use App\Service\Stripe\Client as StripeClient;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Knp\Component\Pager\PaginatorInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
#[Route('/crm/category')]
|
||||||
|
class CategoryController extends AbstractController
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly EntityManagerInterface $em,
|
||||||
|
private readonly AppLogger $appLogger,
|
||||||
|
private readonly EventDispatcherInterface $eventDispatcher
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
#[Route('', name: 'app_crm_category', options: ['sitemap' => false], methods: ['GET'])]
|
||||||
|
public function index(
|
||||||
|
CategoryRepository $categoryRepository,
|
||||||
|
PaginatorInterface $paginator,
|
||||||
|
Request $request
|
||||||
|
): Response {
|
||||||
|
$this->appLogger->record('VIEW', 'Consultation de la page de catégorie');
|
||||||
|
|
||||||
|
foreach (['2-7 Ans','3-15 Ans','3-99 Ans','Barnums','Alimentaire','Options'] as $catName) {
|
||||||
|
$cat = $categoryRepository->findOneBy(['name'=>$catName]);
|
||||||
|
if(!$cat instanceof Category) {
|
||||||
|
$cat = new Category();
|
||||||
|
$cat->setName($catName);
|
||||||
|
$this->em->persist($cat);
|
||||||
|
}
|
||||||
|
$this->em->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('dashboard/category/list.twig', [
|
||||||
|
'categorys' => $categoryRepository->findAll(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/add', name: 'app_crm_category_add', options: ['sitemap' => false], methods: ['GET', 'POST'])]
|
||||||
|
public function add(Request $request, CategoryRepository $categoryRepository): Response
|
||||||
|
{
|
||||||
|
$this->appLogger->record('VIEW', 'Consultation de la page de création catégorie');
|
||||||
|
|
||||||
|
$category = new Category();
|
||||||
|
$form = $this->createForm(CategoryType::class, $category);
|
||||||
|
$form->handleRequest($request);
|
||||||
|
if($form->isSubmitted() && $form->isValid()) {
|
||||||
|
$this->appLogger->record('VIEW', 'Création d\'une catégorie');
|
||||||
|
$this->em->persist($category);
|
||||||
|
$this->em->flush();
|
||||||
|
return $this->redirectToRoute('app_crm_category');
|
||||||
|
}
|
||||||
|
return $this->render('dashboard/category/add.twig', [
|
||||||
|
'form' => $form->createView(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/delete/{id}', name: 'app_crm_category_delete', options: ['sitemap' => false], methods: ['GET'])]
|
||||||
|
public function delete(
|
||||||
|
?Category $category,
|
||||||
|
PaginatorInterface $paginator,
|
||||||
|
Request $request
|
||||||
|
): Response {
|
||||||
|
$this->appLogger->record('VIEW', 'Suppression de la catégorie '.$category->getName());
|
||||||
|
|
||||||
|
$this->em->remove($category);
|
||||||
|
$this->em->flush();
|
||||||
|
return $this->redirectToRoute('app_crm_category');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ use App\Entity\Product;
|
|||||||
use App\Entity\ProductReserve;
|
use App\Entity\ProductReserve;
|
||||||
use App\Entity\Promotion;
|
use App\Entity\Promotion;
|
||||||
use App\Entity\SitePerformance;
|
use App\Entity\SitePerformance;
|
||||||
|
use App\Repository\CategoryRepository;
|
||||||
use App\Repository\CustomerRepository;
|
use App\Repository\CustomerRepository;
|
||||||
use App\Repository\CustomerTrackingRepository;
|
use App\Repository\CustomerTrackingRepository;
|
||||||
use App\Repository\FormulesRepository;
|
use App\Repository\FormulesRepository;
|
||||||
@@ -848,10 +849,11 @@ class ReserverController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/catalogue', name: 'reservation_catalogue')]
|
#[Route('/catalogue', name: 'reservation_catalogue')]
|
||||||
public function revervationCatalogue(ProductRepository $productRepository): Response
|
public function revervationCatalogue(CategoryRepository $categoryRepository,ProductRepository $productRepository): Response
|
||||||
{
|
{
|
||||||
return $this->render('revervation/catalogue.twig', [
|
return $this->render('revervation/catalogue.twig', [
|
||||||
'products' => $productRepository->findBy(['isPublish' => true]),
|
'products' => $productRepository->findBy(['isPublish' => true]),
|
||||||
|
'categories' => $categoryRepository->findBy([],['id' => 'ASC']),
|
||||||
'tvaEnabled' => $this->isTvaEnabled(),
|
'tvaEnabled' => $this->isTvaEnabled(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -883,11 +885,6 @@ class ReserverController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/comment-reserver', name: 'reservation_workflow')]
|
|
||||||
public function revervationWorkfkow(): Response
|
|
||||||
{
|
|
||||||
return $this->render('revervation/workflow.twig');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[Route('/options/{id}', name: 'reservation_options_show')]
|
#[Route('/options/{id}', name: 'reservation_options_show')]
|
||||||
public function revervationShowOpitons(string $id, ProductRepository $productRepository): Response
|
public function revervationShowOpitons(string $id, ProductRepository $productRepository): Response
|
||||||
|
|||||||
35
src/Entity/Category.php
Normal file
35
src/Entity/Category.php
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\CategoryRepository;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: CategoryRepository::class)]
|
||||||
|
class Category
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $name = null;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): ?string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setName(string $name): static
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/Form/CategoryType.php
Normal file
33
src/Form/CategoryType.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Form;
|
||||||
|
|
||||||
|
use App\Entity\Category;
|
||||||
|
use App\Entity\Customer;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CountryType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TelType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class CategoryType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('name', TextType::class, [
|
||||||
|
'label' => 'Nom de la categorie',
|
||||||
|
])
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'data_class' => Category::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ namespace App\Form;
|
|||||||
|
|
||||||
use App\Entity\Customer;
|
use App\Entity\Customer;
|
||||||
use App\Entity\Product;
|
use App\Entity\Product;
|
||||||
|
use App\Repository\CategoryRepository;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||||
@@ -17,8 +18,18 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
|||||||
|
|
||||||
class ProductType extends AbstractType
|
class ProductType extends AbstractType
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public function __construct(private readonly CategoryRepository $categoryRepository)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
{
|
{
|
||||||
|
$categoryList = [];
|
||||||
|
foreach ($this->categoryRepository->findAll() as $category) {
|
||||||
|
$categoryList[$category->getName()] = $category->getName();
|
||||||
|
}
|
||||||
$builder
|
$builder
|
||||||
->add('name',TextType::class,[
|
->add('name',TextType::class,[
|
||||||
'label' => 'Nom du produit',
|
'label' => 'Nom du produit',
|
||||||
@@ -35,14 +46,7 @@ class ProductType extends AbstractType
|
|||||||
->add('category',ChoiceType::class,[
|
->add('category',ChoiceType::class,[
|
||||||
'label' => 'Catégorie du produit',
|
'label' => 'Catégorie du produit',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'choices' => [
|
'choices' => $categoryList,
|
||||||
'2-7 Ans' =>'2-7 ans',
|
|
||||||
'3-15 Ans' =>'3-15 ans',
|
|
||||||
'3-99 Ans' =>'3-99 ans',
|
|
||||||
'Barnums' =>'barnums',
|
|
||||||
'Alimentaire' =>'alimentaire',
|
|
||||||
'Options' =>'options',
|
|
||||||
]
|
|
||||||
])
|
])
|
||||||
->add('caution',NumberType::class,[
|
->add('caution',NumberType::class,[
|
||||||
'label' => 'Caution du produit',
|
'label' => 'Caution du produit',
|
||||||
|
|||||||
43
src/Repository/CategoryRepository.php
Normal file
43
src/Repository/CategoryRepository.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\Category;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends ServiceEntityRepository<Category>
|
||||||
|
*/
|
||||||
|
class CategoryRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct($registry, Category::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @return Category[] Returns an array of Category objects
|
||||||
|
// */
|
||||||
|
// public function findByExampleField($value): array
|
||||||
|
// {
|
||||||
|
// return $this->createQueryBuilder('c')
|
||||||
|
// ->andWhere('c.exampleField = :val')
|
||||||
|
// ->setParameter('val', $value)
|
||||||
|
// ->orderBy('c.id', 'ASC')
|
||||||
|
// ->setMaxResults(10)
|
||||||
|
// ->getQuery()
|
||||||
|
// ->getResult()
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public function findOneBySomeField($value): ?Category
|
||||||
|
// {
|
||||||
|
// return $this->createQueryBuilder('c')
|
||||||
|
// ->andWhere('c.exampleField = :val')
|
||||||
|
// ->setParameter('val', $value)
|
||||||
|
// ->getQuery()
|
||||||
|
// ->getOneOrNullResult()
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -52,7 +52,7 @@ class RedirecListener
|
|||||||
|
|
||||||
if ($pathInfo === "/") {
|
if ($pathInfo === "/") {
|
||||||
if ($host === "prestataire.ludikevent.fr") {
|
if ($host === "prestataire.ludikevent.fr") {
|
||||||
$redirect = new RedirectResponse("https://etl.ludikevent.fr/etl");
|
$redirect = new RedirectResponse("https://prestataire.ludikevent.fr/etl");
|
||||||
$event->setResponse($redirect);
|
$event->setResponse($redirect);
|
||||||
$event->stopPropagation();
|
$event->stopPropagation();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -103,9 +103,7 @@ class SiteMapListener implements EventSubscriberInterface
|
|||||||
$catUrl = new UrlConcrete($reservationUrl, $t, UrlConcrete::CHANGEFREQ_DAILY, 0.7);
|
$catUrl = new UrlConcrete($reservationUrl, $t, UrlConcrete::CHANGEFREQ_DAILY, 0.7);
|
||||||
$urlContainer->addUrl($catUrl, 'reservation');
|
$urlContainer->addUrl($catUrl, 'reservation');
|
||||||
|
|
||||||
$reservationUrl = $urlGenerator->generate('reservation_workflow', [], UrlGeneratorInterface::ABSOLUTE_URL);
|
|
||||||
$workFlow = new UrlConcrete($reservationUrl, $t, UrlConcrete::CHANGEFREQ_MONTHLY, 0.5);
|
|
||||||
$urlContainer->addUrl($workFlow, 'reservation');
|
|
||||||
|
|
||||||
foreach ($this->formulesRepository->findBy(['isPublish'=>true]) as $formule) {
|
foreach ($this->formulesRepository->findBy(['isPublish'=>true]) as $formule) {
|
||||||
$formulesUrls = $urlGenerator->generate(
|
$formulesUrls = $urlGenerator->generate(
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
{{ menu.nav_link(path('app_crm_reservation'), 'Planing de réservation', '<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5" />', 'app_crm_reservation') }}
|
{{ menu.nav_link(path('app_crm_reservation'), 'Planing de réservation', '<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5" />', 'app_crm_reservation') }}
|
||||||
{{ menu.nav_link(path('app_template_point_controle_index'), 'Modèles de contrôle', '<path stroke-linecap="round" stroke-linejoin="round" d="M11.35 3.836c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z" />', 'app_template_point_controle_index') }}
|
{{ menu.nav_link(path('app_template_point_controle_index'), 'Modèles de contrôle', '<path stroke-linecap="round" stroke-linejoin="round" d="M11.35 3.836c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z" />', 'app_template_point_controle_index') }}
|
||||||
{{ menu.nav_link(path('app_crm_product'), 'Produits', '<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" />', 'app_crm_product') }}
|
{{ menu.nav_link(path('app_crm_product'), 'Produits', '<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" />', 'app_crm_product') }}
|
||||||
|
{{ menu.nav_link(path('app_crm_category'), 'Categorie', '<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" />', 'app_crm_product') }}
|
||||||
{{ menu.nav_link(path('app_crm_formules'), 'Formules', '<path stroke-linecap="round" stroke-linejoin="round" d="M21 7.5l-9-5.25L3 7.5m18 0l-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9" />', 'app_crm_formules') }}
|
{{ menu.nav_link(path('app_crm_formules'), 'Formules', '<path stroke-linecap="round" stroke-linejoin="round" d="M21 7.5l-9-5.25L3 7.5m18 0l-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9" />', 'app_crm_formules') }}
|
||||||
{{ menu.nav_link(path('app_crm_promotion'), 'Promotions', '<path stroke-linecap="round" stroke-linejoin="round" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />', 'app_crm_promotion') }}
|
{{ menu.nav_link(path('app_crm_promotion'), 'Promotions', '<path stroke-linecap="round" stroke-linejoin="round" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />', 'app_crm_promotion') }}
|
||||||
{{ menu.nav_link(path('app_crm_facture'), 'Facture', '<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />', 'app_crm_facture') }}
|
{{ menu.nav_link(path('app_crm_facture'), 'Facture', '<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />', 'app_crm_facture') }}
|
||||||
|
|||||||
28
templates/dashboard/category/add.twig
Normal file
28
templates/dashboard/category/add.twig
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{% extends 'dashboard/base.twig' %}
|
||||||
|
{% block title %}Nouvelle Catégorie{% endblock %}
|
||||||
|
{% block title_header %}Nouvelle <span class="text-blue-500">Catégorie</span>{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<div class="backdrop-blur-xl bg-[#1e293b]/40 border border-white/5 rounded-[2.5rem] shadow-2xl overflow-hidden">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="p-10">
|
||||||
|
{{ form_start(form, {'attr': {'class': 'space-y-12'}}) }}
|
||||||
|
{{ form_row(form.name) }}
|
||||||
|
{# ACTIONS : Boutons espacés #}
|
||||||
|
<div class="pt-10 border-t border-white/5 flex items-center justify-end">
|
||||||
|
<div class="flex items-center space-x-16"> {# Espace large entre les deux boutons #}
|
||||||
|
<a data-turbo="false" href="{{ path('app_crm_category') }}" class="mr-2 text-[10px] font-black text-slate-300 hover:text-rose-500 uppercase tracking-widest transition-colors">
|
||||||
|
Annuler l'opération
|
||||||
|
</a>
|
||||||
|
<button type="submit" class="p-2 px-16 py-4 bg-blue-600 hover:bg-blue-500 text-white text-[10px] font-black uppercase tracking-[0.2em] rounded-2xl shadow-lg shadow-blue-600/20 transition-all hover:scale-105 active:scale-95">
|
||||||
|
Valider et enregistrer
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ form_end(form) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
64
templates/dashboard/category/list.twig
Normal file
64
templates/dashboard/category/list.twig
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
{% extends 'dashboard/base.twig' %}
|
||||||
|
|
||||||
|
{% block title %}Catégorie{% endblock %}
|
||||||
|
{% block title_header %}Catégorie{% endblock %}
|
||||||
|
|
||||||
|
{% block actions %}
|
||||||
|
<div class="flex items-center space-x-3">
|
||||||
|
<a data-turbo="false" href="{{ path('app_crm_category_add') }}" class="flex items-center space-x-2 px-6 py-3 bg-blue-600 hover:bg-blue-500 text-white text-[10px] font-black uppercase tracking-[0.2em] rounded-xl transition-all shadow-lg shadow-blue-600/20 group">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M12 4v16m8-8H4" />
|
||||||
|
</svg>
|
||||||
|
<span>Nouvelle catégorie</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% block body %}
|
||||||
|
<div class="backdrop-blur-xl bg-[#1e293b]/40 border border-white/5 rounded-[2.5rem] overflow-hidden shadow-2xl animate-in fade-in duration-700">
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="w-full text-left border-collapse">
|
||||||
|
<thead>
|
||||||
|
<tr class="border-b border-white/5 bg-black/20">
|
||||||
|
<th class="px-6 py-5 text-[10px] font-black text-slate-300 uppercase tracking-[0.2em]">Nom</th>
|
||||||
|
<th class="px-6 py-5 text-[10px] font-black text-slate-300 uppercase tracking-[0.2em] text-right">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-white/5">
|
||||||
|
{% for category in categorys %}
|
||||||
|
<tr class="group hover:bg-white/[0.02] transition-colors">
|
||||||
|
|
||||||
|
{# CLIENT #}
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<span class="text-[11px] font-mono font-bold text-blue-500 tracking-wider">
|
||||||
|
{{ category.name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{# ACTIONS #}
|
||||||
|
<td class="px-6 py-4 text-right">
|
||||||
|
<div class="flex items-center justify-end space-x-2">
|
||||||
|
<a data-turbo="false" href="{{ path('app_crm_category_delete', {id: category.id}) }}?_token={{ csrf_token('delete' ~ category.id) }}"
|
||||||
|
data-turbo-method="post"
|
||||||
|
data-turbo-confirm="Confirmer la suppression de la catégorie {{ category.name }} ?"
|
||||||
|
class="p-2 bg-rose-500/10 hover:bg-rose-600 text-rose-500 hover:text-white rounded-xl transition-all border border-rose-500/20">
|
||||||
|
<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="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" /></svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="py-24 text-center">
|
||||||
|
<p class="text-slate-500 italic uppercase tracking-[0.2em] text-[10px] font-black">Aucun devis trouvé</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -133,7 +133,6 @@
|
|||||||
{{ macros.nav_link('reservation_catalogue', 'nav.catalogue') }}
|
{{ macros.nav_link('reservation_catalogue', 'nav.catalogue') }}
|
||||||
{{ macros.nav_link('reservation_formules', 'nav.packages') }}
|
{{ macros.nav_link('reservation_formules', 'nav.packages') }}
|
||||||
{{ macros.nav_link('/images/Catalogue.pdf', 'nav.pdf', true) }}
|
{{ macros.nav_link('/images/Catalogue.pdf', 'nav.pdf', true) }}
|
||||||
{{ macros.nav_link('reservation_workflow', 'nav.how_to_book') }}
|
|
||||||
{{ macros.nav_link('reservation_estimate_delivery', 'Estimer la livraison') }}
|
{{ macros.nav_link('reservation_estimate_delivery', 'Estimer la livraison') }}
|
||||||
{{ macros.nav_link('reservation_contact', 'nav.contact') }}
|
{{ macros.nav_link('reservation_contact', 'nav.contact') }}
|
||||||
|
|
||||||
@@ -190,7 +189,6 @@
|
|||||||
{{ macros.mobile_nav_link('reservation_catalogue', 'Nos structures') }}
|
{{ macros.mobile_nav_link('reservation_catalogue', 'Nos structures') }}
|
||||||
{{ macros.mobile_nav_link('reservation_formules', 'Nos Formules') }}
|
{{ macros.mobile_nav_link('reservation_formules', 'Nos Formules') }}
|
||||||
{{ macros.mobile_nav_link('/provider/Catalogue.pdf', 'Catalogue', true) }}
|
{{ macros.mobile_nav_link('/provider/Catalogue.pdf', 'Catalogue', true) }}
|
||||||
{{ macros.mobile_nav_link('reservation_workflow', 'Comment reserver') }}
|
|
||||||
{{ macros.mobile_nav_link('reservation_estimate_delivery', 'Estimer la livraison') }}
|
{{ macros.mobile_nav_link('reservation_estimate_delivery', 'Estimer la livraison') }}
|
||||||
{{ macros.mobile_nav_link('reservation_search', 'Rechercher') }}
|
{{ macros.mobile_nav_link('reservation_search', 'Rechercher') }}
|
||||||
<a is="flow-reserve" class="block px-3 py-2 text-base font-medium text-gray-700 hover:bg-gray-50 rounded-xl flex items-center justify-between">
|
<a is="flow-reserve" class="block px-3 py-2 text-base font-medium text-gray-700 hover:bg-gray-50 rounded-xl flex items-center justify-between">
|
||||||
|
|||||||
@@ -37,19 +37,10 @@
|
|||||||
{{ 'catalog.filter.all'|trans }}
|
{{ 'catalog.filter.all'|trans }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{% set categories_list = [
|
{% for categorie in categories %}
|
||||||
{'id': '2-7 ans', 'label': 'catalog.filter.cat_2_7'|trans, 'hover': 'hover:border-amber-500 hover:text-amber-600'},
|
<button data-filter="{{ categorie.name }}"
|
||||||
{'id': '3-15 ans', 'label': 'catalog.filter.cat_3_15'|trans, 'hover': 'hover:border-blue-600 hover:text-blue-600'},
|
class="filter-btn px-5 py-2.5 rounded-xl font-black italic text-[9px] tracking-widest transition-all uppercase bg-white text-slate-600 border border-slate-200">
|
||||||
{'id': '3-99 ans', 'label': 'catalog.filter.cat_3_99'|trans, 'hover': 'hover:border-indigo-600 hover:text-indigo-600'},
|
{{ categorie.name }}
|
||||||
{'id': 'barnums', 'label': 'catalog.filter.cat_barnums'|trans, 'hover': 'hover:border-slate-800 hover:text-slate-800'},
|
|
||||||
{'id': 'alimentaire', 'label': 'catalog.filter.cat_food'|trans, 'hover': 'hover:border-rose-500 hover:text-rose-600'},
|
|
||||||
{'id': 'options', 'label': 'catalog.filter.cat_options'|trans, 'hover': 'hover:border-emerald-500 hover:text-emerald-600'}
|
|
||||||
] %}
|
|
||||||
|
|
||||||
{% for cat in categories_list %}
|
|
||||||
<button data-filter="{{ cat.id }}"
|
|
||||||
class="filter-btn px-5 py-2.5 rounded-xl font-black italic text-[9px] tracking-widest transition-all uppercase bg-white text-slate-600 border border-slate-200 {{ cat.hover }}">
|
|
||||||
{{ cat.label }}
|
|
||||||
</button>
|
</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,155 +0,0 @@
|
|||||||
{% extends 'revervation/base.twig' %}
|
|
||||||
|
|
||||||
{% block title %}{{ 'workflow.seo.title'|trans }}{% endblock %}
|
|
||||||
{% block description %}{{ 'workflow.seo.description'|trans }}{% endblock %}
|
|
||||||
|
|
||||||
{% block breadcrumb_json %}
|
|
||||||
,{
|
|
||||||
"@type": "ListItem",
|
|
||||||
"position": 1,
|
|
||||||
"name": "{{ 'workflow.breadcrumb'|trans }}",
|
|
||||||
"item": "{{ url('reservation_workflow') }}"
|
|
||||||
}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block body %}
|
|
||||||
<div class="min-h-screen bg-white font-sans antialiased pb-20">
|
|
||||||
|
|
||||||
{# --- HEADER --- #}
|
|
||||||
<div class="max-w-4xl mx-auto pt-20 pb-16 px-4 text-center">
|
|
||||||
<span class="inline-block bg-blue-100 text-blue-600 px-4 py-1.5 rounded-full text-[10px] font-black uppercase tracking-widest mb-6" data-aos="fade-down">
|
|
||||||
{{ 'workflow.header.badge'|trans }}
|
|
||||||
</span>
|
|
||||||
<h1 class="text-6xl md:text-8xl font-black text-slate-900 uppercase italic tracking-tighter leading-[0.85] mb-6" data-aos="fade-up" data-aos-delay="100">
|
|
||||||
{{ 'workflow.header.title_part1'|trans }} <br><span class="text-blue-600">{{ 'workflow.header.title_part2'|trans }}</span>
|
|
||||||
</h1>
|
|
||||||
<p class="text-xl text-slate-500 font-medium italic leading-relaxed" data-aos="fade-up" data-aos-delay="200">{{ 'workflow.header.subtitle'|trans }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# --- TIMELINE --- #}
|
|
||||||
<div class="max-w-5xl mx-auto px-4 relative">
|
|
||||||
<div class="hidden md:block absolute left-1/2 top-0 bottom-0 w-1 bg-slate-100 -translate-x-1/2 z-0"></div>
|
|
||||||
|
|
||||||
<div class="space-y-24 relative z-10">
|
|
||||||
|
|
||||||
{# 1. SELECTION #}
|
|
||||||
<div class="flex flex-col md:flex-row items-center gap-12 group" data-aos="fade-right">
|
|
||||||
<div class="flex-1 text-center md:text-right order-2 md:order-1">
|
|
||||||
<h2 class="text-3xl font-black text-slate-900 uppercase italic mb-4 group-hover:text-blue-600 transition-colors">{{ 'workflow.step1.title'|trans }}</h2>
|
|
||||||
<p class="text-slate-500 font-medium leading-relaxed">{{ 'workflow.step1.desc'|trans }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="w-24 h-24 bg-blue-600 rounded-[2rem] flex items-center justify-center shadow-xl shadow-blue-200 order-1 md:order-2 shrink-0 transform group-hover:rotate-12 transition-transform">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 hidden md:block order-3"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# 2. DATES #}
|
|
||||||
<div class="flex flex-col md:flex-row items-center gap-12 group" data-aos="fade-left">
|
|
||||||
<div class="flex-1 hidden md:block"></div>
|
|
||||||
<div class="w-24 h-24 bg-amber-500 rounded-[2rem] flex items-center justify-center shadow-xl shadow-amber-200 shrink-0 transform group-hover:-rotate-12 transition-transform">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 00-2 2z" /></svg>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 text-center md:text-left">
|
|
||||||
<h2 class="text-3xl font-black text-slate-900 uppercase italic mb-4 group-hover:text-amber-500 transition-colors">{{ 'workflow.step2.title'|trans }}</h2>
|
|
||||||
<p class="text-slate-500 font-medium leading-relaxed">{{ 'workflow.step2.desc'|trans }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# 3. DETAILS & LIVRAISON #}
|
|
||||||
<div class="flex flex-col md:flex-row items-center gap-12 group" data-aos="fade-right">
|
|
||||||
<div class="flex-1 text-center md:text-right order-2 md:order-1">
|
|
||||||
<h2 class="text-3xl font-black text-slate-900 uppercase italic mb-4 group-hover:text-blue-600 transition-colors">{{ 'workflow.step3.title'|trans }}</h2>
|
|
||||||
<p class="text-slate-500 font-medium leading-relaxed">
|
|
||||||
{{ 'workflow.step3.desc'|trans }}
|
|
||||||
<span class="block mt-2 text-blue-600 font-bold italic">{{ 'workflow.step3.highlight'|trans }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="w-24 h-24 bg-blue-600 rounded-[2rem] flex items-center justify-center shadow-xl shadow-blue-200 order-1 md:order-2 shrink-0 transform group-hover:rotate-12 transition-transform">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /></svg>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 hidden md:block order-3"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# 4. SIGNATURE #}
|
|
||||||
<div class="flex flex-col md:flex-row items-center gap-12 group" data-aos="fade-left">
|
|
||||||
<div class="flex-1 hidden md:block"></div>
|
|
||||||
<div class="w-24 h-24 bg-indigo-600 rounded-[2rem] flex items-center justify-center shadow-xl shadow-indigo-200 shrink-0 transform group-hover:-rotate-12 transition-transform">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" /></svg>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 text-center md:text-left">
|
|
||||||
<h2 class="text-3xl font-black text-slate-900 uppercase italic mb-4 group-hover:text-indigo-600 transition-colors">{{ 'workflow.step4.title'|trans }}</h2>
|
|
||||||
<p class="text-slate-500 font-medium leading-relaxed">{{ 'workflow.step4.desc'|trans }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# 5. ARRHES #}
|
|
||||||
<div class="flex flex-col md:flex-row items-center gap-12 group" data-aos="fade-right">
|
|
||||||
<div class="flex-1 text-center md:text-right order-2 md:order-1">
|
|
||||||
<h2 class="text-3xl font-black text-slate-900 uppercase italic mb-4 group-hover:text-rose-500 transition-colors">{{ 'workflow.step5.title'|trans }}</h2>
|
|
||||||
<p class="text-slate-500 font-medium leading-relaxed">{{ 'workflow.step5.desc'|trans|raw }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="w-24 h-24 bg-rose-500 rounded-[2rem] flex items-center justify-center shadow-xl shadow-rose-200 order-1 md:order-2 shrink-0 transform group-hover:scale-110 transition-transform">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M3 10h18M7 15h1m4 0h1m-7 4h12a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 hidden md:block order-3"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# 6. RAPPEL #}
|
|
||||||
<div class="flex flex-col md:flex-row items-center gap-12 group" data-aos="fade-left">
|
|
||||||
<div class="flex-1 hidden md:block"></div>
|
|
||||||
<div class="w-24 h-24 bg-violet-600 rounded-[2rem] flex items-center justify-center shadow-xl shadow-violet-200 shrink-0 transform group-hover:-rotate-12 transition-transform">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" /></svg>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 text-center md:text-left">
|
|
||||||
<h2 class="text-3xl font-black text-slate-900 uppercase italic mb-4 group-hover:text-violet-600 transition-colors">{{ 'workflow.step6.title'|trans }}</h2>
|
|
||||||
<p class="text-slate-500 font-medium leading-relaxed">{{ 'workflow.step6.desc'|trans|raw }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# 8 & 9. RECEPTION & SOLDE #}
|
|
||||||
<div class="flex flex-col md:flex-row items-center gap-12 group" data-aos="fade-right">
|
|
||||||
<div class="flex-1 text-center md:text-right order-2 md:order-1">
|
|
||||||
<h2 class="text-3xl font-black text-slate-900 uppercase italic mb-4 group-hover:text-emerald-500 transition-colors">{{ 'workflow.step8_9.title'|trans }}</h2>
|
|
||||||
<p class="text-slate-500 font-medium leading-relaxed">
|
|
||||||
{{ 'workflow.step8_9.desc'|trans }}
|
|
||||||
<span class="block mt-2 text-emerald-600 font-bold">{{ 'workflow.step8_9.highlight'|trans }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="w-24 h-24 bg-emerald-500 rounded-[2rem] flex items-center justify-center shadow-xl shadow-emerald-200 order-1 md:order-2 shrink-0 transform group-hover:scale-110 transition-transform">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 hidden md:block order-3"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# 10. POST-LOCATION #}
|
|
||||||
<div class="flex flex-col md:flex-row items-center gap-12 group" data-aos="fade-left">
|
|
||||||
<div class="flex-1 hidden md:block"></div>
|
|
||||||
<div class="w-24 h-24 bg-blue-900 rounded-[2rem] flex items-center justify-center shadow-xl shadow-slate-300 shrink-0 transform group-hover:rotate-12 transition-transform">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-7.714 2.143L11 21l-2.286-6.857L1 12l7.714-2.143L11 3z" /></svg>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 text-center md:text-left">
|
|
||||||
<h2 class="text-3xl font-black text-slate-900 uppercase italic mb-4">{{ 'workflow.step10.title'|trans }}</h2>
|
|
||||||
<p class="text-slate-500 font-medium leading-relaxed">{{ 'workflow.step10.desc'|trans }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# --- CTA FINAL --- #}
|
|
||||||
<div class="max-w-4xl mx-auto mt-32 px-4">
|
|
||||||
<div class="bg-slate-900 rounded-[3rem] p-12 text-center relative overflow-hidden shadow-2xl" data-aos="zoom-in">
|
|
||||||
<div class="relative z-10">
|
|
||||||
<h3 class="text-3xl md:text-5xl font-black text-white uppercase italic mb-8">{{ 'workflow.cta.title'|trans|raw }}</h3>
|
|
||||||
<a href="{{ path('reservation_catalogue') }}" class="inline-flex items-center gap-4 bg-white text-slate-900 px-10 py-5 rounded-2xl font-black uppercase text-xs tracking-widest hover:bg-blue-600 hover:text-white transition-all transform hover:scale-105">
|
|
||||||
{{ 'workflow.cta.button'|trans }}
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M14 5l7 7m0 0l-7 7m7-7H3" /></svg>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="absolute top-0 right-0 -mr-16 -mt-16 w-64 h-64 bg-blue-600/20 rounded-full blur-3xl"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
Reference in New Issue
Block a user