Add live/sandbox environment switcher on /api/doc

- Toggle switch (Sandbox orange / Live green) in header section
- Switches update in real-time: base URL, description, all endpoint path prefixes
- Sandbox: /api/sandbox (orange), Live: /api/live (green)
- Auth endpoints (/api/auth/*) are not affected by the toggle
- No page reload needed, pure JS DOM updates

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-03-23 18:59:46 +01:00
parent 2e01f1f4c0
commit 419c7f0a19

View File

@@ -26,21 +26,26 @@
</div>
</div>
<div class="mt-8 grid grid-cols-1 sm:grid-cols-2 gap-4">
{% for env in environments %}
<div class="border-2 border-gray-700 bg-gray-800 p-4">
<div class="flex items-center gap-2 mb-2">
<span class="{{ env.badgeColor }} text-white text-[10px] font-black uppercase tracking-widest px-2 py-0.5">{{ env.badge }}</span>
<span class="font-black text-sm uppercase tracking-tighter">{{ env.name }}</span>
<div class="mt-8">
<div class="flex items-center gap-4">
<p class="text-[10px] font-black uppercase tracking-widest text-gray-500">Environnement</p>
<div class="flex border-2 border-gray-600 overflow-hidden" id="env-switcher">
<button type="button" data-env="sandbox" class="env-btn px-5 py-2 font-black uppercase text-xs tracking-widest transition-all cursor-pointer bg-orange-500 text-white">
Sandbox
</button>
<button type="button" data-env="live" class="env-btn px-5 py-2 font-black uppercase text-xs tracking-widest transition-all cursor-pointer bg-gray-800 text-gray-400 hover:text-white">
Live
</button>
</div>
<p class="font-mono font-bold text-sm text-[#fabf04] mb-2">https://ticket.e-cosplay.fr{{ env.baseUrl }}</p>
<p class="text-xs font-bold text-gray-400">{{ env.description }}</p>
</div>
{% endfor %}
<div class="mt-3 border-2 border-gray-700 bg-gray-800 px-4 py-3 flex items-center gap-3">
<p class="text-[10px] font-black uppercase tracking-widest text-gray-500">Base URL</p>
<p class="font-mono font-bold text-sm text-[#fabf04]" id="env-base-url">https://ticket.e-cosplay.fr/api/sandbox</p>
</div>
<p class="mt-2 text-xs font-bold text-gray-400" id="env-description">Environnement de test. Les donnees ne sont pas modifiees.</p>
<p class="mt-2 text-xs font-bold text-gray-500">L'authentification (<span class="font-mono">/api/auth/login</span>) est commune aux deux environnements.</p>
</div>
<p class="mt-4 text-xs font-bold text-gray-400">L'authentification (<span class="font-mono">/api/auth/login</span>) est commune aux deux environnements : <span class="font-mono text-[#fabf04]">https://ticket.e-cosplay.fr/api/auth/login</span></p>
<div class="mt-8">
<a href="{{ path('app_api_doc_json') }}" target="_blank" class="inline-flex items-center gap-2 px-6 py-3 border-4 border-[#fabf04] bg-[#fabf04] text-gray-900 font-black uppercase text-xs tracking-widest shadow-[6px_6px_0px_rgba(0,0,0,1)] hover:shadow-[8px_8px_0px_rgba(0,0,0,1)] hover:translate-y-[-2px] transition-all">
<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="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/></svg>
@@ -141,11 +146,11 @@
<div class="{{ method_colors[endpoint.method] ?? 'bg-gray-600' }} text-white px-4 py-3 flex items-center min-w-[80px] justify-center">
<span class="font-black text-xs tracking-widest">{{ endpoint.method }}</span>
</div>
<div class="flex-1 bg-gray-900 text-white px-4 py-3 flex items-center gap-2 flex-wrap">
<div class="flex-1 bg-gray-900 text-white px-4 py-3 flex items-center">
{% if endpoint.path starts with '/api/auth' %}
<code class="font-mono font-bold text-sm">{{ endpoint.path }}</code>
{% else %}
<code class="font-mono font-bold text-sm"><span class="text-orange-400">/api/sandbox</span><span class="text-gray-500">|</span><span class="text-green-400">/api/live</span>{{ endpoint.path|replace({'/api': ''}) }}</code>
<code class="font-mono font-bold text-sm"><span class="api-env-prefix text-orange-400">/api/sandbox</span>{{ endpoint.path|replace({'/api': ''}) }}</code>
{% endif %}
</div>
</div>
@@ -273,4 +278,43 @@
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const envs = {
sandbox: { prefix: '/api/sandbox', baseUrl: 'https://ticket.e-cosplay.fr/api/sandbox', color: 'text-orange-400', btnBg: 'bg-orange-500', desc: 'Environnement de test. Les donnees ne sont pas modifiees.' },
live: { prefix: '/api/live', baseUrl: 'https://ticket.e-cosplay.fr/api/live', color: 'text-green-400', btnBg: 'bg-green-600', desc: 'Environnement de production. Les donnees sont reelles.' },
}
let current = 'sandbox'
const buttons = document.querySelectorAll('.env-btn')
const baseUrlEl = document.getElementById('env-base-url')
const descEl = document.getElementById('env-description')
const prefixes = document.querySelectorAll('.api-env-prefix')
function switchEnv(env) {
current = env
const config = envs[env]
buttons.forEach(btn => {
const isActive = btn.dataset.env === env
btn.className = 'env-btn px-5 py-2 font-black uppercase text-xs tracking-widest transition-all cursor-pointer ' +
(isActive ? config.btnBg + ' text-white' : 'bg-gray-800 text-gray-400 hover:text-white')
})
baseUrlEl.textContent = config.baseUrl
descEl.textContent = config.desc
prefixes.forEach(el => {
el.textContent = config.prefix
el.className = 'api-env-prefix ' + config.color
})
}
buttons.forEach(btn => {
btn.addEventListener('click', () => switchEnv(btn.dataset.env))
})
})
</script>
{% endblock %}