espace-paie-odentas/app/(app)/minima-ccn/ccneac/emplois-non-artistiques-data.tsx
2025-10-18 00:29:58 +02:00

344 lines
17 KiB
TypeScript

"use client";
import React, { useState } from 'react';
import { Briefcase, ChevronDown, Search } from 'lucide-react';
const euro = (n: number) => new Intl.NumberFormat('fr-FR', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(n) + '€';
// Données des minima par groupe et échelon
const minimaData = {
'Groupe 1': [3495.87, 3600.75, 3705.62, 3810.50, 3915.37, 4020.25, 4125.13, 4230.00, 4334.88, 4439.75, 4544.63, 4649.51],
'Groupe 2': [2734.91, 2816.96, 2899.00, 2981.05, 3063.10, 3145.15, 3227.19, 3309.24, 3391.29, 3473.34, 3555.38, 3637.43],
'Groupe 3': [2522.44, 2598.11, 2673.79, 2749.46, 2825.13, 2900.81, 2976.48, 3052.15, 3127.83, 3203.50, 3279.17, 3354.85],
'Groupe 4': [2324.51, 2394.25, 2463.98, 2533.72, 2603.45, 2673.19, 2742.92, 2812.66, 2882.39, 2952.13, 3021.86, 3091.60],
'Groupe 5': [1991.44, 2051.18, 2110.93, 2170.67, 2230.41, 2290.16, 2349.90, 2409.64, 2469.39, 2529.13, 2588.87, 2648.62],
'Groupe 6': [1870.99, 1927.12, 1983.25, 2039.38, 2095.51, 2151.64, 2207.77, 2263.90, 2320.03, 2376.16, 2432.29, 2488.42],
'Groupe 7': [1811.69, 1866.04, 1920.39, 1974.74, 2029.09, 2083.44, 2137.79, 2192.14, 2246.50, 2300.85, 2355.20, 2409.55],
'Groupe 8': [1784.42, 1837.95, 1891.49, 1945.02, 1998.55, 2052.08, 2105.62, 2159.15, 2212.68, 2266.21, 2319.75, 2373.28],
'Groupe 9': [1770.58, 1823.70, 1876.81, 1929.93, 1983.05, 2036.17, 2089.28, 2142.40, 2195.52, 2248.64, 2301.75, 2354.87],
};
// Liste des professions et leurs groupes
const professionsData = [
{ profession: "Directeur", groupe: 1 },
{ profession: "Administrateur", groupe: 2 },
{ profession: "Secrétaire Général", groupe: 3 },
{ profession: "Directeur de Production", groupe: 3 },
{ profession: "Conseiller Technique", groupe: 4 },
{ profession: "Responsable d'Administration", groupe: 4 },
{ profession: "Chef Comptable", groupe: 4 },
{ profession: "Collaborateur de Direction", groupe: 4 },
{ profession: "Administrateur de Production", groupe: 4 },
{ profession: "Administrateur de Diffusion", groupe: 4 },
{ profession: "Programmateur Artistique", groupe: 4 },
{ profession: "Secrétaire de Direction", groupe: 5 },
{ profession: "Comptable Principal", groupe: 5 },
{ profession: "Chargé de Production", groupe: 5 },
{ profession: "Chargé de Diffusion", groupe: 5 },
{ profession: "Bibliothécaire Musical", groupe: 5 },
{ profession: "Copiste", groupe: 5 },
{ profession: "Attaché de Programmation", groupe: 6 },
{ profession: "Attaché de Production", groupe: 6 },
{ profession: "Attaché de Diffusion", groupe: 6 },
{ profession: "Attaché d'Administration", groupe: 6 },
{ profession: "Comptable", groupe: 7 },
{ profession: "Secrétaire", groupe: 8 },
{ profession: "Secrétaire-Comptable", groupe: 8 },
{ profession: "Aide-Comptable", groupe: 9 },
{ profession: "Caissier", groupe: 9 },
{ profession: "Standardiste", groupe: 9 },
{ profession: "Employé de Bureau", groupe: 9 },
{ profession: "Agent de Catering", groupe: 9 },
{ profession: "Directeur de la Communication", groupe: 3 },
{ profession: "Directeur des Relations Publiques", groupe: 3 },
{ profession: "Directeur de l'Action Culturelle", groupe: 3 },
{ profession: "Responsable des relations avec la presse", groupe: 4 },
{ profession: "Responsable de Formation", groupe: 4 },
{ profession: "Responsable de l'Action Culturelle", groupe: 4 },
{ profession: "Responsable du secteur de l'information", groupe: 4 },
{ profession: "Chargé du secteur des relations avec le public", groupe: 5 },
{ profession: "Attaché à l'Accueil", groupe: 6 },
{ profession: "Attaché à l'information", groupe: 6 },
{ profession: "Attaché aux relations avec le public", groupe: 6 },
{ profession: "Attaché à l'accompagnement des pratiques artistiques et culturelles", groupe: 6 },
{ profession: "Graphiste ou Infographiste", groupe: 6 },
{ profession: "Documentaliste", groupe: 7 },
{ profession: "Maquettiste PAO", groupe: 7 },
{ profession: "Caissier-hôte d'accueil", groupe: 8 },
{ profession: "Hôte(sse) d'accueil", groupe: 9 },
{ profession: "Contrôleur", groupe: 9 },
{ profession: "Hôte(sse) de salle", groupe: 9 },
{ profession: "Employé de routage", groupe: 9 },
{ profession: "Employé de bar", groupe: 9 },
{ profession: "Directeur technique", groupe: 3 },
{ profession: "Scénographe", groupe: 3 },
{ profession: "Régisseur général", groupe: 4 },
{ profession: "Concepteur", groupe: 4 },
{ profession: "Eclairagiste", groupe: 4 },
{ profession: "Concepteur lumière", groupe: 4 },
{ profession: "Ingénieur du son", groupe: 4 },
{ profession: "Concepteur des costumes", groupe: 4 },
{ profession: "Concepteur des maquillages", groupe: 4 },
{ profession: "Concepteur des perruques", groupe: 4 },
{ profession: "Concepteur des coiffures", groupe: 4 },
{ profession: "Concepteur des artifices", groupe: 4 },
{ profession: "Décorateur", groupe: 4 },
{ profession: "Pyrotechnicien", groupe: 4 },
{ profession: "Concepteur images-vidéo", groupe: 4 },
{ profession: "Concepteur de structure scénique ou acrobatique", groupe: 4 },
{ profession: "Réalisateur des costumes", groupe: 5 },
{ profession: "Réalisateur des chapeaux", groupe: 5 },
{ profession: "Réalisateur des maquillages", groupe: 5 },
{ profession: "Réalisateur des masques", groupe: 5 },
{ profession: "Réalisateur des coiffures", groupe: 5 },
{ profession: "Réalisateur des perruques", groupe: 5 },
{ profession: "Réalisateur son", groupe: 5 },
{ profession: "Réalisateur lumière", groupe: 5 },
{ profession: "Réalisateur pyrotechnique", groupe: 5 },
{ profession: "Réalisateur de décor", groupe: 5 },
{ profession: "Réalisateur de structure scénique ou acrobatique", groupe: 5 },
{ profession: "Réalisateur d'accessoires", groupe: 5 },
{ profession: "Régisseur principal ou de site", groupe: 5 },
{ profession: "Régisseur de structure mobile, acrobatique ou scénique", groupe: 5 },
{ profession: "Régisseur de scène ou de plateau", groupe: 6 },
{ profession: "Régisseur d'orchestre", groupe: 6 },
{ profession: "Régisseur de choeurs", groupe: 6 },
{ profession: "Régisseur lumière", groupe: 6 },
{ profession: "Régisseur son", groupe: 6 },
{ profession: "Régisseur de lieux de répétition", groupe: 6 },
{ profession: "Régisseur audiovisuel-vidéo de spectacle", groupe: 6 },
{ profession: "Régisseur de production", groupe: 6 },
{ profession: "Technicien de réalisation", groupe: 6 },
{ profession: "Tapissier de théâtre", groupe: 6 },
{ profession: "Ensemblier", groupe: 6 },
{ profession: "Menuisier de théâtre", groupe: 6 },
{ profession: "Peintre décorateur", groupe: 6 },
{ profession: "Peintre de théâtre", groupe: 6 },
{ profession: "Sculpteur de théâtre", groupe: 6 },
{ profession: "Serrurier", groupe: 6 },
{ profession: "Serrurier métallier", groupe: 6 },
{ profession: "Staffeur", groupe: 6 },
{ profession: "Chef-machiniste", groupe: 6 },
{ profession: "Dessinateur DAO-CAO", groupe: 7 },
{ profession: "Constructeur", groupe: 7 },
{ profession: "Machiniste", groupe: 7 },
{ profession: "Opérateur projectionniste", groupe: 7 },
{ profession: "Electricien", groupe: 7 },
{ profession: "Technicien hydraulique-de structure", groupe: 7 },
{ profession: "Technicien lumière", groupe: 7 },
{ profession: "Technicien son", groupe: 7 },
{ profession: "Technicien console", groupe: 7 },
{ profession: "Technicien vidéo", groupe: 7 },
{ profession: "Technicien image", groupe: 7 },
{ profession: "Technicien effets spéciaux", groupe: 7 },
{ profession: "Technicien groupe électrogène", groupe: 7 },
{ profession: "Technicien instruments", groupe: 7 },
{ profession: "Technicien de sécurité", groupe: 7 },
{ profession: "Monteur de structure mobile", groupe: 8 },
{ profession: "Monteur de structure acrobatique ou scénique", groupe: 8 },
{ profession: "Assistant instrument de musique (backline)", groupe: 8 },
{ profession: "Cintrier", groupe: 8 },
{ profession: "Ouvrier professionnel", groupe: 8 },
{ profession: "Ouvrier son", groupe: 8 },
{ profession: "Ouvrier prompteur", groupe: 8 },
{ profession: "Ouvrier lumière-poursuiteur", groupe: 8 },
{ profession: "Ouvrier vidéo-images", groupe: 8 },
{ profession: "Ouvrier accrocheur (rigger)", groupe: 8 },
{ profession: "Perruquier", groupe: 8 },
{ profession: "Chapelier", groupe: 8 },
{ profession: "Bottier", groupe: 8 },
{ profession: "Maquilleur", groupe: 8 },
{ profession: "Posticheur", groupe: 8 },
{ profession: "Coiffeur", groupe: 8 },
{ profession: "Habilleur", groupe: 8 },
{ profession: "Armurier", groupe: 8 },
{ profession: "Artificier", groupe: 8 },
{ profession: "Accessoiriste", groupe: 8 },
{ profession: "Lingère", groupe: 8 },
{ profession: "Repasseur·se", groupe: 8 },
{ profession: "Retoucheur·se", groupe: 8 },
{ profession: "Chauffeur-coursier", groupe: 9 },
{ profession: "Employé de nettoyage", groupe: 9 },
{ profession: "Gardien", groupe: 9 },
{ profession: "Employé polyvalent", groupe: 9 },
];
export default function EmploisNonArtistiquesContent() {
const [selectedGroupe, setSelectedGroupe] = useState<string>('Groupe 1');
const [searchTerm, setSearchTerm] = useState<string>('');
const [searchResults, setSearchResults] = useState<typeof professionsData>([]);
const [selectedProfession, setSelectedProfession] = useState<string>('');
const handleSearch = (term: string) => {
setSearchTerm(term);
if (term.trim() === '') {
setSearchResults([]);
return;
}
const results = professionsData.filter(item =>
item.profession.toLowerCase().includes(term.toLowerCase())
);
setSearchResults(results);
};
const selectProfession = (profession: string, groupe: number) => {
setSelectedGroupe(`Groupe ${groupe}`);
setSelectedProfession(profession);
setSearchTerm('');
setSearchResults([]);
};
return (
<div className="space-y-6">
{/* En-tête */}
<div className="rounded-xl border bg-gradient-to-br from-slate-50 to-gray-50 p-4">
<h2 className="text-lg font-semibold text-slate-900 mb-1">
Emplois non artistiques
</h2>
<p className="text-sm text-slate-700">
Minima mensuels conventionnels pour les emplois administratifs, techniques et commerciaux
</p>
<p className="text-xs text-slate-600 mt-2">
Grille de salaires applicable au 1er juin 2024
</p>
</div>
{/* Recherche et sélection côte à côte */}
<div className="rounded-xl border bg-white p-5">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
{/* Moteur de recherche de profession */}
<div>
<label htmlFor="profession-search" className="block text-sm font-semibold text-slate-900 mb-3 flex items-center gap-2">
<Search className="w-4 h-4" />
Rechercher une profession
</label>
<div className="relative">
<input
id="profession-search"
type="text"
value={searchTerm}
onChange={(e) => handleSearch(e.target.value)}
placeholder="Tapez le nom d'une profession..."
className="w-full px-4 py-3 pl-10 rounded-lg border-2 border-slate-200 bg-white text-slate-900 placeholder:text-slate-400 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 transition-all"
/>
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
</div>
{/* Résultats de recherche */}
{searchResults.length > 0 && (
<div className="mt-3 border border-slate-200 rounded-lg divide-y divide-slate-100 max-h-60 overflow-y-auto shadow-lg">
{searchResults.map((result, index) => (
<button
key={index}
onClick={() => selectProfession(result.profession, result.groupe)}
className="w-full px-4 py-3 text-left hover:bg-indigo-50 transition-colors flex items-center justify-between group"
>
<span className="text-sm text-slate-900 font-medium">{result.profession}</span>
<span className="text-xs font-bold text-indigo-600 bg-indigo-100 px-2 py-1 rounded group-hover:bg-indigo-200">
Groupe {result.groupe}
</span>
</button>
))}
</div>
)}
{searchTerm && searchResults.length === 0 && (
<div className="mt-3 p-4 bg-amber-50 border border-amber-200 rounded-lg">
<p className="text-sm text-amber-800">
Aucune profession trouvée pour "{searchTerm}".
</p>
</div>
)}
{/* Profession sélectionnée */}
{selectedProfession && (
<div className="mt-3 p-3 bg-green-50 border border-green-200 rounded-lg">
<p className="text-xs text-green-700 font-medium mb-1">Profession sélectionnée :</p>
<p className="text-sm text-green-900 font-bold">{selectedProfession}</p>
</div>
)}
</div>
{/* Sélecteur de groupe */}
<div>
<label htmlFor="groupe-select" className="block text-sm font-semibold text-slate-900 mb-3">
Ou sélectionnez directement un groupe :
</label>
<div className="relative">
<select
id="groupe-select"
value={selectedGroupe}
onChange={(e) => {
setSelectedGroupe(e.target.value);
setSelectedProfession('');
}}
className="w-full appearance-none px-4 py-3 pr-10 rounded-lg border-2 border-slate-200 bg-white text-slate-900 font-semibold focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 transition-all cursor-pointer"
>
{Object.keys(minimaData).map((groupe) => (
<option key={groupe} value={groupe}>
{groupe}
</option>
))}
</select>
<ChevronDown className="absolute right-3 top-1/2 -translate-y-1/2 w-5 h-5 text-slate-400 pointer-events-none" />
</div>
</div>
</div>
</div>
{/* Tableau des minima pour le groupe sélectionné */}
<div className="rounded-xl border bg-white p-5">
<h3 className="text-base font-bold text-indigo-900 mb-4 flex items-center gap-2">
<Briefcase className="w-5 h-5" />
Minima mensuels - {selectedGroupe}
</h3>
<div className="overflow-x-auto">
<table className="w-full text-xs border-collapse">
<thead>
<tr className="bg-indigo-50">
<th className="text-left p-3 text-indigo-900 font-bold border border-indigo-200"></th>
{Array.from({ length: 12 }, (_, i) => (
<th key={i + 1} className="text-center p-3 text-indigo-900 font-bold border border-indigo-200">
Échelon {i + 1}
</th>
))}
</tr>
</thead>
<tbody>
<tr className="hover:bg-indigo-50/30">
<td className="p-3 border border-indigo-200 font-semibold text-indigo-900">Mensuel</td>
{minimaData[selectedGroupe as keyof typeof minimaData].map((montant, index) => (
<td key={index} className="text-center p-3 font-bold text-indigo-900 border border-indigo-200 bg-indigo-50/50">
{euro(montant)}
</td>
))}
</tr>
<tr className="hover:bg-indigo-50/30">
<td className="p-3 border border-indigo-200 font-semibold text-indigo-900">Taux horaire</td>
{minimaData[selectedGroupe as keyof typeof minimaData].map((montant, index) => (
<td key={index} className="text-center p-3 font-semibold text-indigo-700 border border-indigo-200">
{euro(montant / 151.4)}
</td>
))}
</tr>
</tbody>
</table>
</div>
{/* Note explicative */}
<div className="mt-4 p-3 bg-blue-50 border border-blue-200 rounded-lg">
<p className="text-xs text-blue-900">
<span className="font-semibold">💡 Note :</span> Ces montants correspondent aux salaires mensuels minimaux bruts
pour les emplois non artistiques selon la classification conventionnelle CCNEAC.
Chaque groupe comporte 12 échelons représentant une progression salariale.
</p>
</div>
</div>
</div>
);
}