574 lines
17 KiB
TypeScript
574 lines
17 KiB
TypeScript
"use client";
|
|
|
|
import React, { useEffect } from 'react';
|
|
import { usePageTitle } from '@/hooks/usePageTitle';
|
|
import Link from 'next/link';
|
|
import { ArrowLeft, Scale, Calculator } from 'lucide-react';
|
|
import Annexe1Content from './annexe1-data';
|
|
import ClausesCommunesContent from './clauses-communes-data';
|
|
import Annexe2Content from './annexe2-data';
|
|
import Annexe3Content from './annexe3-data';
|
|
import Annexe4Content from './annexe4-data';
|
|
|
|
export default function CCNSVPPage() {
|
|
usePageTitle("Minima CCNSVP");
|
|
|
|
useEffect(() => {
|
|
// Script de gestion des onglets
|
|
const tabs = Array.from(document.querySelectorAll('[role="tab"]'));
|
|
const panels = Array.from(document.querySelectorAll('.ccnsvp-panel'));
|
|
|
|
function activateTab(tab: Element) {
|
|
tabs.forEach((t) => {
|
|
const selected = t === tab;
|
|
t.setAttribute('aria-selected', selected ? 'true' : 'false');
|
|
(t as HTMLElement).tabIndex = selected ? 0 : -1;
|
|
});
|
|
|
|
panels.forEach((p) => {
|
|
const active = p.id === tab.getAttribute('aria-controls');
|
|
p.classList.toggle('active', active);
|
|
if (active) {
|
|
p.removeAttribute('hidden');
|
|
} else {
|
|
p.setAttribute('hidden', '');
|
|
}
|
|
});
|
|
|
|
(tab as HTMLElement).focus({ preventScroll: true });
|
|
}
|
|
|
|
tabs.forEach((tab) => {
|
|
tab.addEventListener('click', () => activateTab(tab));
|
|
});
|
|
|
|
// Navigation clavier
|
|
document.addEventListener('keydown', (e) => {
|
|
const current = document.querySelector('[role="tab"][aria-selected="true"]');
|
|
if (!current) return;
|
|
const i = tabs.indexOf(current);
|
|
if (e.key === 'ArrowRight') {
|
|
e.preventDefault();
|
|
activateTab(tabs[(i + 1) % tabs.length]);
|
|
}
|
|
if (e.key === 'ArrowLeft') {
|
|
e.preventDefault();
|
|
activateTab(tabs[(i - 1 + tabs.length) % tabs.length]);
|
|
}
|
|
if (e.key === 'Home') {
|
|
e.preventDefault();
|
|
activateTab(tabs[0]);
|
|
}
|
|
if (e.key === 'End') {
|
|
e.preventDefault();
|
|
activateTab(tabs[tabs.length - 1]);
|
|
}
|
|
});
|
|
}, []);
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<style jsx global>{`
|
|
.ccnsvp-tabs [role="tablist"] {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.ccnsvp-tabs [role="tab"] {
|
|
appearance: none;
|
|
border: 1px solid #e2e8f0;
|
|
background: white;
|
|
border-radius: 999px;
|
|
padding: 9px 16px;
|
|
cursor: pointer;
|
|
font-weight: 600;
|
|
font-size: 14px;
|
|
color: #475569;
|
|
transition: all 0.2s;
|
|
position: relative;
|
|
}
|
|
|
|
.ccnsvp-tabs [role="tab"]:hover {
|
|
background: #f8fafc;
|
|
border-color: #cbd5e1;
|
|
}
|
|
|
|
.ccnsvp-tabs [role="tab"][aria-selected="true"] {
|
|
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
|
|
border-color: #8b5cf6;
|
|
color: white;
|
|
box-shadow: 0 4px 12px rgba(139, 92, 246, 0.3);
|
|
}
|
|
|
|
.ccnsvp-tabs [role="tab"]:focus-visible {
|
|
outline: 2px solid #6366f1;
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* Tooltips */
|
|
.ccnsvp-tabs [role="tab"][data-tip]::after {
|
|
content: attr(data-tip);
|
|
position: absolute;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
top: calc(100% + 8px);
|
|
background: #0f172a;
|
|
color: white;
|
|
padding: 8px 12px;
|
|
border-radius: 8px;
|
|
font-size: 12px;
|
|
line-height: 1.4;
|
|
white-space: normal;
|
|
max-width: min(72vw, 340px);
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
z-index: 50;
|
|
transition: opacity 0.2s;
|
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
.ccnsvp-tabs [role="tab"][data-tip]::before {
|
|
content: "";
|
|
position: absolute;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
top: calc(100% + 4px);
|
|
border: 6px solid transparent;
|
|
border-bottom-color: #0f172a;
|
|
opacity: 0;
|
|
z-index: 50;
|
|
transition: opacity 0.2s;
|
|
}
|
|
|
|
.ccnsvp-tabs [role="tab"][data-tip]:hover::after,
|
|
.ccnsvp-tabs [role="tab"][data-tip]:hover::before,
|
|
.ccnsvp-tabs [role="tab"][data-tip]:focus-visible::after,
|
|
.ccnsvp-tabs [role="tab"][data-tip]:focus-visible::before {
|
|
opacity: 1;
|
|
}
|
|
|
|
.ccnsvp-panel {
|
|
display: none;
|
|
}
|
|
|
|
.ccnsvp-panel.active {
|
|
display: block;
|
|
}
|
|
|
|
/* Alertes */
|
|
.ccnsvp-alert {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 12px;
|
|
padding: 12px 16px;
|
|
border-radius: 12px;
|
|
border: 1px solid #fed7aa;
|
|
background: #fff7ed;
|
|
color: #9a3412;
|
|
font-size: 13px;
|
|
line-height: 1.5;
|
|
margin-top: 12px;
|
|
}
|
|
|
|
.ccnsvp-alert .icon {
|
|
font-size: 18px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* Tables */
|
|
.ccnsvp-table {
|
|
width: 100%;
|
|
border-collapse: separate;
|
|
border-spacing: 0;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.ccnsvp-table th,
|
|
.ccnsvp-table td {
|
|
border-top: 1px solid #e2e8f0;
|
|
padding: 12px;
|
|
text-align: left;
|
|
vertical-align: top;
|
|
}
|
|
|
|
.ccnsvp-table th {
|
|
background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);
|
|
font-weight: 700;
|
|
color: #475569;
|
|
border-top-color: #c7d2fe;
|
|
}
|
|
|
|
.ccnsvp-table tbody tr:first-child td {
|
|
border-top: 0;
|
|
}
|
|
|
|
.ccnsvp-table tbody tr:hover {
|
|
background: #f8fafc;
|
|
}
|
|
|
|
/* KPIs */
|
|
.ccnsvp-kpi {
|
|
background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);
|
|
border: 1px solid #c7d2fe;
|
|
border-radius: 12px;
|
|
padding: 16px;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.ccnsvp-kpi .lbl {
|
|
font-weight: 700;
|
|
font-size: 14px;
|
|
color: #64748b;
|
|
margin: 0 0 6px 0;
|
|
}
|
|
|
|
.ccnsvp-kpi .num {
|
|
font-size: 24px;
|
|
font-weight: 900;
|
|
color: #1e293b;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.ccnsvp-kpi .muted {
|
|
color: #64748b;
|
|
font-size: 13px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
/* Recherche */
|
|
.ccnsvp-search {
|
|
display: flex;
|
|
gap: 12px;
|
|
align-items: center;
|
|
margin: 16px 0;
|
|
}
|
|
|
|
.ccnsvp-search input {
|
|
flex: 1;
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 12px;
|
|
padding: 12px 16px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.ccnsvp-search input:focus {
|
|
outline: 2px solid #6366f1;
|
|
outline-offset: 0;
|
|
border-color: #6366f1;
|
|
}
|
|
|
|
.ccnsvp-badge {
|
|
display: inline-block;
|
|
background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);
|
|
border: 1px solid #c7d2fe;
|
|
border-radius: 999px;
|
|
padding: 6px 12px;
|
|
font-size: 12px;
|
|
font-weight: 700;
|
|
color: #4f46e5;
|
|
}
|
|
|
|
/* Accordéons */
|
|
.ccnsvp-acc details {
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 12px;
|
|
padding: 12px 16px;
|
|
background: white;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.ccnsvp-acc summary {
|
|
cursor: pointer;
|
|
font-weight: 700;
|
|
color: #1e293b;
|
|
outline: none;
|
|
list-style: none;
|
|
}
|
|
|
|
.ccnsvp-acc summary::-webkit-details-marker {
|
|
display: none;
|
|
}
|
|
|
|
.ccnsvp-acc ul {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 12px 0 0;
|
|
}
|
|
|
|
.ccnsvp-acc li {
|
|
padding: 10px 0;
|
|
border-top: 1px solid #e2e8f0;
|
|
cursor: pointer;
|
|
transition: color 0.2s;
|
|
}
|
|
|
|
.ccnsvp-acc li:first-child {
|
|
border-top: 0;
|
|
}
|
|
|
|
.ccnsvp-acc li:hover {
|
|
color: #6366f1;
|
|
}
|
|
|
|
/* Highlight animation */
|
|
.hl {
|
|
animation: flash 2s ease;
|
|
}
|
|
|
|
@keyframes flash {
|
|
0% { background: #fff7ed; }
|
|
100% { background: transparent; }
|
|
}
|
|
|
|
/* Grille responsive */
|
|
.ccnsvp-grid {
|
|
display: grid;
|
|
gap: 20px;
|
|
}
|
|
|
|
@media (min-width: 900px) {
|
|
.ccnsvp-grid {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
}
|
|
|
|
/* KPI blocks */
|
|
.kpi-blocks {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
|
gap: 12px;
|
|
margin-top: 12px;
|
|
}
|
|
|
|
.kpi-block {
|
|
background: white;
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 10px;
|
|
padding: 12px;
|
|
display: flex;
|
|
align-items: baseline;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
}
|
|
|
|
.kpi-block-label {
|
|
font-weight: 700;
|
|
font-size: 14px;
|
|
color: #475569;
|
|
}
|
|
|
|
.kpi-block-num {
|
|
font-weight: 900;
|
|
font-size: 18px;
|
|
color: #1e293b;
|
|
white-space: nowrap;
|
|
}
|
|
`}</style>
|
|
|
|
{/* Navigation retour */}
|
|
<Link
|
|
href="/minima-ccn"
|
|
className="inline-flex items-center gap-2 text-sm text-slate-600 hover:text-slate-900 transition-colors"
|
|
>
|
|
<ArrowLeft className="w-4 h-4" />
|
|
Retour aux minima CCN
|
|
</Link>
|
|
|
|
{/* En-tête */}
|
|
<section className="rounded-2xl border bg-white p-6">
|
|
<div className="flex items-start gap-3">
|
|
<div className="flex-shrink-0 w-12 h-12 rounded-xl bg-gradient-to-br from-blue-500 to-cyan-600 flex items-center justify-center">
|
|
<Scale className="w-6 h-6 text-white" />
|
|
</div>
|
|
<div className="flex-1 min-w-0">
|
|
<div className="flex items-center gap-2 mb-2">
|
|
<h1 className="text-2xl font-semibold text-slate-900">CCNSVP (IDCC 3090)</h1>
|
|
<span className="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-semibold bg-gradient-to-r from-emerald-500 to-emerald-600 text-white shadow-sm">
|
|
À jour 2025
|
|
</span>
|
|
</div>
|
|
<p className="text-sm text-slate-600 mb-2">
|
|
Spectacle vivant privé - Minima techniciens, artistes et personnels administratifs et commerciaux
|
|
</p>
|
|
<p className="text-xs text-slate-500">
|
|
Données issues de l'accord sur les salaires signé le 25/01/2024, entré en vigueur le 01/02/2024, étendu par arrêté ministériel du 25/03/2024.
|
|
<br />
|
|
Toujours en vigueur au 2e semestre 2025. <strong>Tous les montants sont exprimés bruts.</strong>
|
|
</p>
|
|
<div className="ccnsvp-alert mt-3">
|
|
<span className="icon" aria-hidden="true">⚠️</span>
|
|
<span>
|
|
Les <b>metteurs en scène</b> ne sont pas prévus par la CCNSVP ;
|
|
il convient donc d'appliquer au minimum le <b>SMIC</b> (taux horaire de 11,88€ brut à ce jour).
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Onglets */}
|
|
<section className="rounded-2xl border bg-white p-6 ccnsvp-tabs">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<p className="text-sm text-slate-600">
|
|
Survolez le nom d'une annexe pour connaître son titre exact, cliquez sur l'annexe pour accéder aux détails.
|
|
</p>
|
|
<Link
|
|
href="/simulateur"
|
|
className="inline-flex items-center gap-2 px-4 py-2 rounded-full text-sm font-semibold bg-gradient-to-r from-amber-400 to-amber-500 text-slate-900 hover:from-amber-500 hover:to-amber-600 transition-all shadow-sm"
|
|
>
|
|
<Calculator className="w-4 h-4" />
|
|
Simulateur
|
|
</Link>
|
|
</div>
|
|
|
|
<div role="tablist" aria-label="Onglets CCNSVP">
|
|
<button
|
|
role="tab"
|
|
aria-selected="true"
|
|
aria-controls="ccnsvp-communes"
|
|
tabIndex={0}
|
|
data-tip="Grilles de salaires des emplois administratifs et commerciaux, et des emplois techniques hors annexe"
|
|
>
|
|
Clauses communes
|
|
</button>
|
|
<button
|
|
role="tab"
|
|
aria-selected="false"
|
|
aria-controls="ccnsvp-a1"
|
|
tabIndex={-1}
|
|
data-tip="Annexe 1 — Exploitants de lieux, producteurs ou diffuseurs de spectacles dramatiques, lyriques, chorégraphiques et de musique classique"
|
|
>
|
|
Annexe 1
|
|
</button>
|
|
<button
|
|
role="tab"
|
|
aria-selected="false"
|
|
aria-controls="ccnsvp-a2"
|
|
tabIndex={-1}
|
|
data-tip="Annexe 2 — Exploitants de lieux, producteurs ou diffuseurs de spectacles de chanson, variétés, jazz, musiques actuelles"
|
|
>
|
|
Annexe 2
|
|
</button>
|
|
<button
|
|
role="tab"
|
|
aria-selected="false"
|
|
aria-controls="ccnsvp-a3"
|
|
tabIndex={-1}
|
|
data-tip="Exploitants de lieux, producteurs ou diffuseurs de spectacles de cabarets"
|
|
>
|
|
Annexe 3
|
|
</button>
|
|
<button
|
|
role="tab"
|
|
aria-selected="false"
|
|
aria-controls="ccnsvp-a4"
|
|
tabIndex={-1}
|
|
data-tip="Producteurs ou diffuseurs de spectacles en tournée (à l'exception des cirques et des bals)"
|
|
>
|
|
Annexe 4
|
|
</button>
|
|
<button
|
|
role="tab"
|
|
aria-selected="false"
|
|
aria-controls="ccnsvp-a5"
|
|
tabIndex={-1}
|
|
data-tip="Producteurs, diffuseurs, organisateurs occasionnels (y compris les particuliers) de spectacles de bals avec ou sans orchestre"
|
|
>
|
|
Annexe 5
|
|
</button>
|
|
<button
|
|
role="tab"
|
|
aria-selected="false"
|
|
aria-controls="ccnsvp-a6"
|
|
tabIndex={-1}
|
|
data-tip="Producteurs ou diffuseurs de spectacles de cirque"
|
|
>
|
|
Annexe 6
|
|
</button>
|
|
<button
|
|
role="tab"
|
|
aria-selected="false"
|
|
aria-controls="ccnsvp-indem"
|
|
tabIndex={-1}
|
|
>
|
|
Indemnités
|
|
</button>
|
|
</div>
|
|
|
|
{/* Panneaux */}
|
|
<div id="ccnsvp-communes" className="ccnsvp-panel active" role="tabpanel">
|
|
<ClausesCommunesContent />
|
|
</div>
|
|
|
|
<div id="ccnsvp-a1" className="ccnsvp-panel" role="tabpanel" hidden>
|
|
<Annexe1Content />
|
|
</div>
|
|
|
|
<div id="ccnsvp-a2" className="ccnsvp-panel" role="tabpanel" hidden>
|
|
<Annexe2Content />
|
|
</div>
|
|
|
|
<div id="ccnsvp-a3" className="ccnsvp-panel" role="tabpanel" hidden>
|
|
<Annexe3Content />
|
|
</div>
|
|
|
|
<div id="ccnsvp-a4" className="ccnsvp-panel" role="tabpanel" hidden>
|
|
<Annexe4Content />
|
|
</div>
|
|
|
|
<div id="ccnsvp-a5" className="ccnsvp-panel" role="tabpanel" hidden>
|
|
<div className="text-center py-12">
|
|
<p className="text-slate-500">Contenu de l'Annexe 5 à venir</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="ccnsvp-a6" className="ccnsvp-panel" role="tabpanel" hidden>
|
|
<div className="text-center py-12">
|
|
<p className="text-slate-500">Contenu de l'Annexe 6 à venir</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="ccnsvp-indem" className="ccnsvp-panel" role="tabpanel" hidden>
|
|
<div className="text-center py-12">
|
|
<p className="text-slate-500">Contenu des indemnités à venir</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Note informative */}
|
|
<section className="rounded-xl border border-blue-200 bg-blue-50 p-4">
|
|
<div className="flex items-start gap-3">
|
|
<div className="flex-shrink-0">
|
|
<div className="w-8 h-8 rounded-lg bg-blue-100 flex items-center justify-center">
|
|
<svg
|
|
className="w-5 h-5 text-blue-600"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<div className="flex-1 min-w-0">
|
|
<h3 className="text-sm font-semibold text-blue-900 mb-1">
|
|
Minima conventionnels
|
|
</h3>
|
|
<p className="text-sm text-blue-800">
|
|
Les minima affichés sont issus de la convention collective nationale CCNSVP et sont mis à jour régulièrement.
|
|
Ils constituent une base de référence pour l'établissement des contrats de travail.
|
|
Les tableaux détaillés par annexe seront progressivement intégrés.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|