feat(site): Gère l'état en ligne du site avec SEO conditionnel et UI.

This commit is contained in:
Serreau Jovann
2026-02-06 17:46:30 +01:00
parent 4462e880f2
commit c650b8fa20
8 changed files with 126 additions and 6 deletions

View File

@@ -34,3 +34,11 @@ services:
App\Command\MaintenanceCommand:
arguments:
$projectDir: '%kernel.project_dir%'
App\Event\Seo\SeoBlockerSubscriber:
arguments:
$projectDir: '%kernel.project_dir%'
App\Twig\OnlineExtension:
arguments:
$projectDir: '%kernel.project_dir%'

View File

@@ -182,11 +182,20 @@ class ReserverController extends AbstractController
public function index(Request $request): Response
{
$robots = new RobotsTxt();
if (!file_exists($this->kernel->getProjectDir() . '/var/.online')) {
$robots->disallow('/');
} else {
$robots->disallow('/signature');
$robots->disallow('/payment');
$robots->disallow('/paiment');
$robots->disallow('/intranet');
$robots->disallow('/crm');
$robots->disallow('/etl');
$robots->crawlDelay(60);
$robots->allow('/reservation');
$robots->sitemap($request->getSchemeAndHttpHost().'/seo/sitemap.xml');
}
return new Response($robots->toString(), Response::HTTP_OK, [
'Content-Type' => 'text/plain'

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Event\Seo;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class SeoBlockerSubscriber implements EventSubscriberInterface
{
private string $projectDir;
public function __construct(string $projectDir)
{
$this->projectDir = $projectDir;
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::RESPONSE => 'onKernelResponse',
];
}
public function onKernelResponse(ResponseEvent $event): void
{
$request = $event->getRequest();
$path = $request->getPathInfo();
$blockedPaths = ['/intranet', '/signature', '/paiment', '/payment', '/crm', '/etl'];
foreach ($blockedPaths as $blockedPath) {
if (str_starts_with($path, $blockedPath)) {
$event->getResponse()->headers->set('X-Robots-Tag', 'noindex, nofollow');
return;
}
}
// Check if var/.online exists
if (!file_exists($this->projectDir . '/var/.online')) {
$event->getResponse()->headers->set('X-Robots-Tag', 'noindex, nofollow');
}
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
class OnlineExtension extends AbstractExtension
{
private string $projectDir;
public function __construct(string $projectDir)
{
$this->projectDir = $projectDir;
}
public function getFunctions(): array
{
return [
new TwigFunction('is_online', [$this, 'isOnline']),
];
}
public function isOnline(): bool
{
return file_exists($this->projectDir . '/var/.online');
}
}

View File

@@ -7,7 +7,6 @@
<title>Ludikevent | {% block title %}Accueil{% endblock %}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<meta name="robots" content="noindex, nofollow">
{{ vite_asset('app.js', []) }}
{% if app.environment != 'dev'%}

View File

@@ -12,6 +12,12 @@
</head>
<body class="bg-[#0f172a] text-slate-200 antialiased overflow-hidden font-sans">
{% if not is_online() %}
<div class="bg-red-600 text-white text-center py-2 px-4 font-bold text-sm sticky top-0 z-[60]">
Votre site internet n'est actuellement pas en ligne. Aucun référencement n'est possible. Pour demander sa mise en ligne, rendez-vous dans votre intranet pour effectuer la demande d'activation.
</div>
{% endif %}
<div class="flex h-screen overflow-hidden">
{# SIDEBAR #}

View File

@@ -44,6 +44,27 @@
{% block body %}
<div class="min-h-screen p-4 md:p-8 space-y-10">
{# --- ACTIVATION SECTION (OFFLINE ONLY) --- #}
{% if not is_online() %}
<section class="group relative w-full" aria-label="Activation du site">
<div class="absolute inset-0 bg-gradient-to-r from-red-600/10 via-transparent to-orange-600/10 blur-3xl opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div class="relative overflow-hidden backdrop-blur-2xl bg-white/5 border border-red-500/30 rounded-[3rem] p-10 flex flex-col md:flex-row items-center justify-between gap-8">
<div class="flex-1">
<p class="text-[10px] font-black text-red-400 uppercase tracking-[0.4em] mb-2 italic">Mise en ligne</p>
<h2 class="text-3xl font-black text-white uppercase tracking-tighter mb-4">Activation du site internet</h2>
<p class="text-sm font-medium text-slate-300 leading-relaxed max-w-3xl">
Une fois la demande faite, vous serez invité à signer le certificat de mise en ligne. En le signant, vous reconnaissez que la fin du développement de l'intranet est conforme au cahier des charges établi. Une fois signé, toute modification sera facturée.
</p>
</div>
<div class="flex-shrink-0">
<button disabled data-turbo="false" class="px-8 py-4 bg-slate-700/50 text-slate-400 font-bold uppercase tracking-widest rounded-2xl border border-slate-600 cursor-not-allowed opacity-75 hover:bg-slate-700/50 transition-colors shadow-lg">
Demander l'activation
</button>
</div>
</div>
</section>
{% endif %}
{# --- HEADER STATS (GLASS PILLS) --- #}
<section class="flex flex-wrap gap-4 items-center mb-8" aria-label="Statistiques rapides">
<div class="flex flex-col md:flex-row md:items-center gap-4 w-full md:w-auto">

View File

@@ -83,6 +83,12 @@
<body class="bg-gray-50 text-gray-900 font-sans antialiased min-h-screen flex flex-col">
{% if not is_online() %}
<div class="bg-red-600 text-white text-center py-2 px-4 font-bold text-sm sticky top-0 z-[60]">
Votre site internet n'est actuellement pas en ligne. Aucun référencement n'est possible. Pour demander sa mise en ligne, rendez-vous dans votre intranet pour effectuer la demande d'activation.
</div>
{% endif %}
{% if is_granted('ROLE_USER') %}
<utm-account id="{{ app.user.id }}" email="{{ app.user.email }}" name="{{ app.user.name }} {{ app.user.surname }}"></utm-account>
{% endif %}