feat: Ajout mockup hub salarié avec gestion congés/RTT pour régime général

This commit is contained in:
Renaud 2025-11-03 22:56:13 +01:00
parent bea8700104
commit 5b6d9bf9c7
3 changed files with 911 additions and 45 deletions

View file

@ -0,0 +1,874 @@
"use client";
import { useState } from "react";
import {
FileText,
Download,
Upload,
User,
FileSignature,
Calendar,
Bell,
CheckCircle,
Clock,
AlertCircle,
Home,
Briefcase,
CreditCard,
Settings,
LogOut,
ChevronRight,
Eye,
Palmtree,
Plus,
X
} from "lucide-react";
export default function HubSalarieMockup() {
const [activeTab, setActiveTab] = useState<'accueil' | 'contrats' | 'paie' | 'conges' | 'documents' | 'profil'>('accueil');
// Données mockées
const mockEmployee = {
firstName: "Marie",
lastName: "Dupont",
email: "marie.dupont@example.com",
numSecu: "2 85 03 75 123 456 78",
address: "123 rue de la République, 75001 Paris",
phone: "06 12 34 56 78"
};
const mockContracts = [
{
id: 1,
type: "CDDU",
title: "Festival d'été 2025",
organization: "Théâtre National",
startDate: "2025-07-01",
endDate: "2025-07-31",
status: "active",
signedAt: "2025-06-15"
},
{
id: 2,
type: "CDDU",
title: "Production Molière",
organization: "Compagnie ABC",
startDate: "2025-09-10",
endDate: "2025-10-20",
status: "signed",
signedAt: "2025-08-28"
},
{
id: 3,
type: "CDDU",
title: "Tournée régionale",
organization: "Théâtre National",
startDate: "2025-05-01",
endDate: "2025-05-15",
status: "completed",
signedAt: "2025-04-10"
}
];
const mockPayslips = [
{ id: 1, month: "Octobre 2025", amount: "2 450,00", downloadUrl: "#", status: "available" },
{ id: 2, month: "Septembre 2025", amount: "2 680,00", downloadUrl: "#", status: "available" },
{ id: 3, month: "Août 2025", amount: "3 120,00", downloadUrl: "#", status: "available" },
{ id: 4, month: "Juillet 2025", amount: "2 890,00", downloadUrl: "#", status: "available" },
];
const mockDocuments = [
{ id: 1, name: "Attestation Pôle Emploi - Octobre 2025.pdf", date: "2025-11-01", type: "Attestation", size: "245 KB" },
{ id: 2, name: "Certificat de travail - Tournée.pdf", date: "2025-05-16", type: "Certificat", size: "189 KB" },
{ id: 3, name: "RIB.pdf", date: "2025-01-10", type: "Bancaire", size: "78 KB" },
];
const mockPendingSignatures = [
{
id: 1,
title: "Contrat CDDU - Spectacle de Noël",
organization: "Centre Culturel",
dueDate: "2025-11-10",
priority: "high"
}
];
const mockNotifications = [
{ id: 1, type: "success", message: "Votre fiche de paie d'octobre est disponible", date: "Il y a 2 heures" },
{ id: 2, type: "warning", message: "Un nouveau contrat attend votre signature", date: "Il y a 1 jour" },
{ id: 3, type: "info", message: "Pensez à mettre à jour votre RIB si nécessaire", date: "Il y a 3 jours" },
];
// Données mockées pour les congés (RG uniquement)
const mockCongesBalance = {
congesPayes: { acquis: 25, pris: 12, solde: 13 },
rtt: { acquis: 10, pris: 4, solde: 6 },
congesSansSolde: { pris: 0 },
};
const mockCongesHistory = [
{
id: 1,
type: "Congés payés",
startDate: "2025-08-15",
endDate: "2025-08-29",
days: 10,
status: "approved",
approvedBy: "Marie Martin",
approvedAt: "2025-07-20"
},
{
id: 2,
type: "RTT",
startDate: "2025-10-10",
endDate: "2025-10-10",
days: 1,
status: "approved",
approvedBy: "Marie Martin",
approvedAt: "2025-10-01"
},
{
id: 3,
type: "Congés payés",
startDate: "2025-12-23",
endDate: "2025-12-31",
days: 5,
status: "pending",
approvedBy: null,
approvedAt: null
},
];
return (
<div className="min-h-screen bg-slate-50">
{/* Header */}
<header className="bg-white border-b border-slate-200 sticky top-0 z-50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-16">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-indigo-600 rounded-lg flex items-center justify-center">
<span className="text-white font-bold text-lg">O</span>
</div>
<div>
<h1 className="text-lg font-semibold text-slate-900">Espace Paie Salarié</h1>
<p className="text-xs text-slate-500">MOCKUP - Interface de démonstration</p>
</div>
</div>
<div className="flex items-center gap-4">
<button className="relative p-2 text-slate-600 hover:bg-slate-100 rounded-lg transition-colors">
<Bell className="w-5 h-5" />
<span className="absolute top-1 right-1 w-2 h-2 bg-orange-500 rounded-full"></span>
</button>
<div className="flex items-center gap-3 pl-4 border-l border-slate-200">
<div className="text-right">
<p className="text-sm font-medium text-slate-900">{mockEmployee.firstName} {mockEmployee.lastName}</p>
<p className="text-xs text-slate-500">Salarié</p>
</div>
<div className="w-9 h-9 bg-indigo-100 rounded-full flex items-center justify-center">
<User className="w-5 h-5 text-indigo-600" />
</div>
</div>
</div>
</div>
</div>
</header>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
{/* Navigation Tabs */}
<nav className="flex gap-2 mb-8 bg-white p-2 rounded-lg border border-slate-200">
<button
onClick={() => setActiveTab('accueil')}
className={`flex items-center gap-2 px-4 py-2.5 rounded-lg font-medium transition-all ${
activeTab === 'accueil'
? 'bg-indigo-600 text-white'
: 'text-slate-600 hover:bg-slate-100'
}`}
>
<Home className="w-4 h-4" />
Accueil
</button>
<button
onClick={() => setActiveTab('contrats')}
className={`flex items-center gap-2 px-4 py-2.5 rounded-lg font-medium transition-all ${
activeTab === 'contrats'
? 'bg-indigo-600 text-white'
: 'text-slate-600 hover:bg-slate-100'
}`}
>
<Briefcase className="w-4 h-4" />
Mes Contrats
</button>
<button
onClick={() => setActiveTab('paie')}
className={`flex items-center gap-2 px-4 py-2.5 rounded-lg font-medium transition-all ${
activeTab === 'paie'
? 'bg-indigo-600 text-white'
: 'text-slate-600 hover:bg-slate-100'
}`}
>
<CreditCard className="w-4 h-4" />
Mes Paies
</button>
<button
onClick={() => setActiveTab('conges')}
className={`flex items-center gap-2 px-4 py-2.5 rounded-lg font-medium transition-all ${
activeTab === 'conges'
? 'bg-indigo-600 text-white'
: 'text-slate-600 hover:bg-slate-100'
}`}
>
<Palmtree className="w-4 h-4" />
Congés & RTT
</button>
<button
onClick={() => setActiveTab('documents')}
className={`flex items-center gap-2 px-4 py-2.5 rounded-lg font-medium transition-all ${
activeTab === 'documents'
? 'bg-indigo-600 text-white'
: 'text-slate-600 hover:bg-slate-100'
}`}
>
<FileText className="w-4 h-4" />
Mes Documents
</button>
<button
onClick={() => setActiveTab('profil')}
className={`flex items-center gap-2 px-4 py-2.5 rounded-lg font-medium transition-all ${
activeTab === 'profil'
? 'bg-indigo-600 text-white'
: 'text-slate-600 hover:bg-slate-100'
}`}
>
<User className="w-4 h-4" />
Mon Profil
</button>
</nav>
{/* Content */}
{activeTab === 'accueil' && (
<div className="space-y-6">
{/* Welcome Banner */}
<div className="bg-gradient-to-r from-indigo-600 to-indigo-700 rounded-xl p-6 text-white">
<h2 className="text-2xl font-bold mb-2">Bonjour {mockEmployee.firstName} !</h2>
<p className="text-indigo-100">Bienvenue sur votre espace personnel. Gérez vos documents, contrats et informations en toute simplicité.</p>
</div>
{/* Pending Actions */}
{mockPendingSignatures.length > 0 && (
<div className="bg-orange-50 border border-orange-200 rounded-lg p-6">
<div className="flex items-start gap-3">
<AlertCircle className="w-5 h-5 text-orange-600 mt-0.5" />
<div className="flex-1">
<h3 className="font-semibold text-orange-900 mb-3">Actions en attente</h3>
<div className="space-y-3">
{mockPendingSignatures.map(sig => (
<div key={sig.id} className="bg-white rounded-lg p-4 border border-orange-200">
<div className="flex items-center justify-between">
<div className="flex-1">
<p className="font-medium text-slate-900">{sig.title}</p>
<p className="text-sm text-slate-600 mt-1">{sig.organization}</p>
<p className="text-xs text-orange-600 mt-2">À signer avant le {new Date(sig.dueDate).toLocaleDateString('fr-FR')}</p>
</div>
<button className="px-4 py-2 bg-orange-600 text-white rounded-lg hover:bg-orange-700 transition-colors font-medium">
Signer
</button>
</div>
</div>
))}
</div>
</div>
</div>
</div>
)}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* Quick Stats */}
<div className="lg:col-span-2 space-y-6">
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
<div className="bg-white rounded-lg border border-slate-200 p-6">
<div className="flex items-center justify-between mb-2">
<Briefcase className="w-8 h-8 text-indigo-600" />
</div>
<p className="text-3xl font-bold text-slate-900">3</p>
<p className="text-sm text-slate-600 mt-1">Contrats actifs</p>
</div>
<div className="bg-white rounded-lg border border-slate-200 p-6">
<div className="flex items-center justify-between mb-2">
<FileText className="w-8 h-8 text-green-600" />
</div>
<p className="text-3xl font-bold text-slate-900">24</p>
<p className="text-sm text-slate-600 mt-1">Fiches de paie</p>
</div>
<div className="bg-white rounded-lg border border-slate-200 p-6">
<div className="flex items-center justify-between mb-2">
<FileSignature className="w-8 h-8 text-orange-600" />
</div>
<p className="text-3xl font-bold text-slate-900">1</p>
<p className="text-sm text-slate-600 mt-1">À signer</p>
</div>
</div>
{/* Recent Payslips */}
<div className="bg-white rounded-lg border border-slate-200 p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold text-slate-900">Dernières fiches de paie</h3>
<button className="text-sm text-indigo-600 hover:text-indigo-700 font-medium">
Voir tout
</button>
</div>
<div className="space-y-3">
{mockPayslips.slice(0, 3).map(payslip => (
<div key={payslip.id} className="flex items-center justify-between p-3 bg-slate-50 rounded-lg hover:bg-slate-100 transition-colors">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-green-100 rounded-lg flex items-center justify-center">
<FileText className="w-5 h-5 text-green-600" />
</div>
<div>
<p className="font-medium text-slate-900">{payslip.month}</p>
<p className="text-sm text-slate-600">{payslip.amount} </p>
</div>
</div>
<button className="p-2 text-slate-600 hover:bg-white rounded-lg transition-colors">
<Download className="w-5 h-5" />
</button>
</div>
))}
</div>
</div>
</div>
{/* Notifications */}
<div className="bg-white rounded-lg border border-slate-200 p-6">
<h3 className="text-lg font-semibold text-slate-900 mb-4">Notifications</h3>
<div className="space-y-3">
{mockNotifications.map(notif => (
<div key={notif.id} className={`p-3 rounded-lg border ${
notif.type === 'success' ? 'bg-green-50 border-green-200' :
notif.type === 'warning' ? 'bg-orange-50 border-orange-200' :
'bg-blue-50 border-blue-200'
}`}>
<p className="text-sm font-medium text-slate-900">{notif.message}</p>
<p className="text-xs text-slate-600 mt-1">{notif.date}</p>
</div>
))}
</div>
</div>
</div>
</div>
)}
{activeTab === 'contrats' && (
<div className="space-y-6">
<div className="flex items-center justify-between">
<h2 className="text-2xl font-bold text-slate-900">Mes Contrats de Travail</h2>
<div className="flex gap-2">
<button className="px-4 py-2 bg-white border border-slate-200 rounded-lg text-slate-700 hover:bg-slate-50 transition-colors font-medium">
Filtrer
</button>
</div>
</div>
<div className="grid grid-cols-1 gap-4">
{mockContracts.map(contract => (
<div key={contract.id} className="bg-white rounded-lg border border-slate-200 p-6 hover:shadow-md transition-shadow">
<div className="flex items-start justify-between">
<div className="flex-1">
<div className="flex items-center gap-3 mb-3">
<span className={`px-3 py-1 rounded-full text-xs font-medium ${
contract.status === 'active' ? 'bg-green-100 text-green-700' :
contract.status === 'signed' ? 'bg-blue-100 text-blue-700' :
'bg-slate-100 text-slate-700'
}`}>
{contract.status === 'active' ? 'En cours' :
contract.status === 'signed' ? 'Signé' :
'Terminé'}
</span>
<span className="px-3 py-1 bg-indigo-100 text-indigo-700 rounded-full text-xs font-medium">
{contract.type}
</span>
</div>
<h3 className="text-lg font-semibold text-slate-900 mb-2">{contract.title}</h3>
<p className="text-slate-600 mb-3">{contract.organization}</p>
<div className="flex items-center gap-6 text-sm text-slate-600">
<div className="flex items-center gap-2">
<Calendar className="w-4 h-4" />
<span>Du {new Date(contract.startDate).toLocaleDateString('fr-FR')} au {new Date(contract.endDate).toLocaleDateString('fr-FR')}</span>
</div>
<div className="flex items-center gap-2">
<CheckCircle className="w-4 h-4 text-green-600" />
<span>Signé le {new Date(contract.signedAt).toLocaleDateString('fr-FR')}</span>
</div>
</div>
</div>
<div className="flex gap-2">
<button className="p-2 text-indigo-600 hover:bg-indigo-50 rounded-lg transition-colors">
<Eye className="w-5 h-5" />
</button>
<button className="p-2 text-slate-600 hover:bg-slate-100 rounded-lg transition-colors">
<Download className="w-5 h-5" />
</button>
</div>
</div>
</div>
))}
</div>
</div>
)}
{activeTab === 'paie' && (
<div className="space-y-6">
<div className="flex items-center justify-between">
<h2 className="text-2xl font-bold text-slate-900">Mes Fiches de Paie</h2>
<button className="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors font-medium flex items-center gap-2">
<Download className="w-4 h-4" />
Télécharger tout
</button>
</div>
<div className="bg-white rounded-lg border border-slate-200">
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-slate-50 border-b border-slate-200">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-slate-600 uppercase tracking-wider">
Période
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-slate-600 uppercase tracking-wider">
Montant Net
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-slate-600 uppercase tracking-wider">
Statut
</th>
<th className="px-6 py-3 text-right text-xs font-medium text-slate-600 uppercase tracking-wider">
Actions
</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-200">
{mockPayslips.map(payslip => (
<tr key={payslip.id} className="hover:bg-slate-50 transition-colors">
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-green-100 rounded-lg flex items-center justify-center">
<FileText className="w-5 h-5 text-green-600" />
</div>
<span className="font-medium text-slate-900">{payslip.month}</span>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span className="text-lg font-semibold text-slate-900">{payslip.amount} </span>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span className="px-3 py-1 bg-green-100 text-green-700 rounded-full text-xs font-medium">
Disponible
</span>
</td>
<td className="px-6 py-4 whitespace-nowrap text-right">
<div className="flex items-center justify-end gap-2">
<button className="p-2 text-indigo-600 hover:bg-indigo-50 rounded-lg transition-colors">
<Eye className="w-5 h-5" />
</button>
<button className="p-2 text-slate-600 hover:bg-slate-100 rounded-lg transition-colors">
<Download className="w-5 h-5" />
</button>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
)}
{activeTab === 'conges' && (
<div className="space-y-6">
{/* Header with info badge */}
<div className="flex items-start justify-between">
<div>
<h2 className="text-2xl font-bold text-slate-900">Congés & RTT</h2>
<p className="text-sm text-slate-600 mt-1">Gérez vos demandes de congés et consultez vos soldes</p>
</div>
<div className="bg-blue-50 border border-blue-200 rounded-lg px-4 py-2">
<p className="text-xs text-blue-700 font-medium">Réservé au Régime Général uniquement</p>
</div>
</div>
{/* Soldes des congés */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="bg-white rounded-lg border border-slate-200 p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="font-semibold text-slate-900">Congés Payés</h3>
<Palmtree className="w-5 h-5 text-indigo-600" />
</div>
<div className="space-y-3">
<div className="flex justify-between items-center">
<span className="text-sm text-slate-600">Acquis</span>
<span className="text-lg font-bold text-slate-900">{mockCongesBalance.congesPayes.acquis} jours</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-slate-600">Pris</span>
<span className="text-lg font-semibold text-orange-600">{mockCongesBalance.congesPayes.pris} jours</span>
</div>
<div className="pt-3 border-t border-slate-200">
<div className="flex justify-between items-center">
<span className="text-sm font-medium text-slate-900">Solde</span>
<span className="text-2xl font-bold text-indigo-600">{mockCongesBalance.congesPayes.solde} jours</span>
</div>
</div>
</div>
</div>
<div className="bg-white rounded-lg border border-slate-200 p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="font-semibold text-slate-900">RTT</h3>
<Clock className="w-5 h-5 text-green-600" />
</div>
<div className="space-y-3">
<div className="flex justify-between items-center">
<span className="text-sm text-slate-600">Acquis</span>
<span className="text-lg font-bold text-slate-900">{mockCongesBalance.rtt.acquis} jours</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-slate-600">Pris</span>
<span className="text-lg font-semibold text-orange-600">{mockCongesBalance.rtt.pris} jours</span>
</div>
<div className="pt-3 border-t border-slate-200">
<div className="flex justify-between items-center">
<span className="text-sm font-medium text-slate-900">Solde</span>
<span className="text-2xl font-bold text-green-600">{mockCongesBalance.rtt.solde} jours</span>
</div>
</div>
</div>
</div>
<div className="bg-white rounded-lg border border-slate-200 p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="font-semibold text-slate-900">Congés sans solde</h3>
<Calendar className="w-5 h-5 text-slate-600" />
</div>
<div className="space-y-3">
<div className="flex justify-between items-center">
<span className="text-sm text-slate-600">Pris cette année</span>
<span className="text-lg font-bold text-slate-900">{mockCongesBalance.congesSansSolde.pris} jours</span>
</div>
<p className="text-xs text-slate-500 mt-4">Les congés sans solde sont soumis à validation de l'employeur</p>
</div>
</div>
</div>
{/* Nouvelle demande */}
<div className="bg-white rounded-lg border border-slate-200 p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="font-semibold text-slate-900">Faire une nouvelle demande</h3>
<button className="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors font-medium flex items-center gap-2">
<Plus className="w-4 h-4" />
Nouvelle demande
</button>
</div>
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<div>
<label className="block text-sm font-medium text-slate-700 mb-2">Type de congé</label>
<select className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
<option>Congés payés</option>
<option>RTT</option>
<option>Congés sans solde</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-slate-700 mb-2">Date de début</label>
<input
type="date"
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-slate-700 mb-2">Date de fin</label>
<input
type="date"
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-slate-700 mb-2">Nombre de jours</label>
<input
type="number"
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
placeholder="0"
disabled
/>
</div>
</div>
<div className="mt-4">
<label className="block text-sm font-medium text-slate-700 mb-2">Commentaire (optionnel)</label>
<textarea
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
rows={3}
placeholder="Ajoutez un commentaire à votre demande..."
/>
</div>
</div>
{/* Historique des demandes */}
<div className="bg-white rounded-lg border border-slate-200">
<div className="p-6 border-b border-slate-200">
<h3 className="font-semibold text-slate-900">Historique des demandes</h3>
</div>
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-slate-50 border-b border-slate-200">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-slate-600 uppercase tracking-wider">
Type
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-slate-600 uppercase tracking-wider">
Période
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-slate-600 uppercase tracking-wider">
Durée
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-slate-600 uppercase tracking-wider">
Statut
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-slate-600 uppercase tracking-wider">
Validé par
</th>
<th className="px-6 py-3 text-right text-xs font-medium text-slate-600 uppercase tracking-wider">
Actions
</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-200">
{mockCongesHistory.map(conge => (
<tr key={conge.id} className="hover:bg-slate-50 transition-colors">
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center gap-2">
{conge.type === 'Congés payés' ? (
<Palmtree className="w-4 h-4 text-indigo-600" />
) : (
<Clock className="w-4 h-4 text-green-600" />
)}
<span className="font-medium text-slate-900">{conge.type}</span>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span className="text-sm text-slate-900">
{new Date(conge.startDate).toLocaleDateString('fr-FR')} - {new Date(conge.endDate).toLocaleDateString('fr-FR')}
</span>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span className="font-semibold text-slate-900">{conge.days} jour{conge.days > 1 ? 's' : ''}</span>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span className={`px-3 py-1 rounded-full text-xs font-medium ${
conge.status === 'approved' ? 'bg-green-100 text-green-700' :
conge.status === 'pending' ? 'bg-orange-100 text-orange-700' :
'bg-red-100 text-red-700'
}`}>
{conge.status === 'approved' ? 'Validé' :
conge.status === 'pending' ? 'En attente' :
'Refusé'}
</span>
</td>
<td className="px-6 py-4 whitespace-nowrap">
{conge.approvedBy ? (
<div>
<p className="text-sm text-slate-900">{conge.approvedBy}</p>
<p className="text-xs text-slate-500">{conge.approvedAt && new Date(conge.approvedAt).toLocaleDateString('fr-FR')}</p>
</div>
) : (
<span className="text-sm text-slate-500">-</span>
)}
</td>
<td className="px-6 py-4 whitespace-nowrap text-right">
{conge.status === 'pending' && (
<button className="p-2 text-red-600 hover:bg-red-50 rounded-lg transition-colors">
<X className="w-5 h-5" />
</button>
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
)}
{activeTab === 'documents' && (
<div className="space-y-6">
<div className="flex items-center justify-between">
<h2 className="text-2xl font-bold text-slate-900">Mes Documents</h2>
<button className="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors font-medium flex items-center gap-2">
<Upload className="w-4 h-4" />
Charger un document
</button>
</div>
{/* Upload Zone */}
<div className="bg-white rounded-lg border-2 border-dashed border-slate-300 p-8 text-center hover:border-indigo-400 transition-colors cursor-pointer">
<Upload className="w-12 h-12 text-slate-400 mx-auto mb-3" />
<p className="text-slate-700 font-medium mb-1">Glissez vos documents ici</p>
<p className="text-sm text-slate-500">ou cliquez pour sélectionner des fichiers</p>
<p className="text-xs text-slate-400 mt-2">PDF, PNG, JPG jusqu'à 10 MB</p>
</div>
{/* Documents List */}
<div className="bg-white rounded-lg border border-slate-200">
<div className="p-6 border-b border-slate-200">
<h3 className="font-semibold text-slate-900">Documents téléchargés</h3>
</div>
<div className="divide-y divide-slate-200">
{mockDocuments.map(doc => (
<div key={doc.id} className="p-6 hover:bg-slate-50 transition-colors">
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<div className="w-12 h-12 bg-slate-100 rounded-lg flex items-center justify-center">
<FileText className="w-6 h-6 text-slate-600" />
</div>
<div>
<p className="font-medium text-slate-900">{doc.name}</p>
<div className="flex items-center gap-4 mt-1 text-sm text-slate-600">
<span>{doc.type}</span>
<span>{doc.size}</span>
<span>{new Date(doc.date).toLocaleDateString('fr-FR')}</span>
</div>
</div>
</div>
<div className="flex items-center gap-2">
<button className="p-2 text-indigo-600 hover:bg-indigo-50 rounded-lg transition-colors">
<Eye className="w-5 h-5" />
</button>
<button className="p-2 text-slate-600 hover:bg-slate-100 rounded-lg transition-colors">
<Download className="w-5 h-5" />
</button>
</div>
</div>
</div>
))}
</div>
</div>
</div>
)}
{activeTab === 'profil' && (
<div className="space-y-6">
<h2 className="text-2xl font-bold text-slate-900">Mon Profil</h2>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* Profile Photo */}
<div className="bg-white rounded-lg border border-slate-200 p-6">
<h3 className="font-semibold text-slate-900 mb-4">Photo de profil</h3>
<div className="flex flex-col items-center">
<div className="w-32 h-32 bg-indigo-100 rounded-full flex items-center justify-center mb-4">
<User className="w-16 h-16 text-indigo-600" />
</div>
<button className="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors font-medium text-sm">
Modifier la photo
</button>
</div>
</div>
{/* Personal Info */}
<div className="lg:col-span-2 bg-white rounded-lg border border-slate-200 p-6">
<div className="flex items-center justify-between mb-6">
<h3 className="font-semibold text-slate-900">Informations personnelles</h3>
<button className="px-4 py-2 bg-slate-100 text-slate-700 rounded-lg hover:bg-slate-200 transition-colors font-medium text-sm">
Modifier
</button>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
<div>
<label className="block text-sm font-medium text-slate-600 mb-2">Prénom</label>
<p className="text-slate-900 font-medium">{mockEmployee.firstName}</p>
</div>
<div>
<label className="block text-sm font-medium text-slate-600 mb-2">Nom</label>
<p className="text-slate-900 font-medium">{mockEmployee.lastName}</p>
</div>
<div>
<label className="block text-sm font-medium text-slate-600 mb-2">Email</label>
<p className="text-slate-900 font-medium">{mockEmployee.email}</p>
</div>
<div>
<label className="block text-sm font-medium text-slate-600 mb-2">Téléphone</label>
<p className="text-slate-900 font-medium">{mockEmployee.phone}</p>
</div>
<div className="sm:col-span-2">
<label className="block text-sm font-medium text-slate-600 mb-2">Numéro de Sécurité Sociale</label>
<p className="text-slate-900 font-medium">{mockEmployee.numSecu}</p>
</div>
<div className="sm:col-span-2">
<label className="block text-sm font-medium text-slate-600 mb-2">Adresse</label>
<p className="text-slate-900 font-medium">{mockEmployee.address}</p>
</div>
</div>
</div>
</div>
{/* Banking Info */}
<div className="bg-white rounded-lg border border-slate-200 p-6">
<div className="flex items-center justify-between mb-6">
<h3 className="font-semibold text-slate-900">Informations bancaires</h3>
<button className="px-4 py-2 bg-slate-100 text-slate-700 rounded-lg hover:bg-slate-200 transition-colors font-medium text-sm">
Modifier le RIB
</button>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
<div>
<label className="block text-sm font-medium text-slate-600 mb-2">IBAN</label>
<p className="text-slate-900 font-mono">FR76 1234 5678 9012 3456 7890 123</p>
</div>
<div>
<label className="block text-sm font-medium text-slate-600 mb-2">BIC</label>
<p className="text-slate-900 font-mono">BNPAFRPPXXX</p>
</div>
</div>
</div>
{/* Security */}
<div className="bg-white rounded-lg border border-slate-200 p-6">
<h3 className="font-semibold text-slate-900 mb-6">Sécurité</h3>
<div className="space-y-4">
<div className="flex items-center justify-between p-4 bg-slate-50 rounded-lg">
<div>
<p className="font-medium text-slate-900">Mot de passe</p>
<p className="text-sm text-slate-600 mt-1">Dernière modification il y a 3 mois</p>
</div>
<button className="px-4 py-2 bg-slate-100 text-slate-700 rounded-lg hover:bg-slate-200 transition-colors font-medium text-sm">
Modifier
</button>
</div>
<div className="flex items-center justify-between p-4 bg-slate-50 rounded-lg">
<div>
<p className="font-medium text-slate-900">Authentification à deux facteurs</p>
<p className="text-sm text-slate-600 mt-1">Sécurisez votre compte avec 2FA</p>
</div>
<button className="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors font-medium text-sm">
Activer
</button>
</div>
</div>
</div>
</div>
)}
</div>
{/* Footer */}
<footer className="bg-white border-t border-slate-200 mt-12">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
<div className="flex items-center justify-between text-sm text-slate-600">
<p>© 2025 Odentas - Espace Paie</p>
<div className="flex gap-6">
<a href="#" className="hover:text-slate-900 transition-colors">Aide</a>
<a href="#" className="hover:text-slate-900 transition-colors">Confidentialité</a>
<a href="#" className="hover:text-slate-900 transition-colors">CGU</a>
</div>
</div>
</div>
</footer>
</div>
);
}

View file

@ -651,6 +651,21 @@ export default function Sidebar({ clientInfo, isStaff = false, mobile = false, o
</Link>
</div>
{/* Mockups & Tests */}
<div className="mt-3">
<div className="px-3 py-1.5 text-xs font-medium text-slate-500 uppercase tracking-wider">
Mockups & Tests
</div>
<Link href="/staff/mockups/hub-salarie" onClick={() => onNavigate && onNavigate()} className={`block px-3 py-2 rounded-xl text-sm transition truncate ${
isActivePath(pathname, "/staff/mockups/hub-salarie") ? "bg-gradient-to-r from-indigo-200 via-purple-200 to-pink-200 text-slate-700 font-semibold" : "hover:bg-slate-50"
}`} title="Mockup Hub Salarié">
<span className="inline-flex items-center gap-2">
<Users className="w-4 h-4" aria-hidden />
<span>Hub Salarié</span>
</span>
</Link>
</div>
{/* Espace Paie */}
<div className="mt-3">
<div className="px-3 py-1.5 text-xs font-medium text-slate-500 uppercase tracking-wider">

67
package-lock.json generated
View file

@ -2338,7 +2338,6 @@
"integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
"license": "BSD-3-Clause",
"optional": true,
"peer": true,
"dependencies": {
"detect-libc": "^2.0.0",
"https-proxy-agent": "^5.0.0",
@ -4418,6 +4417,7 @@
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.75.1.tgz",
"integrity": "sha512-GEPVBvjQimcMd9z5K1eTKTixTRb6oVbudoLQ9JKqTUJnR6GQdBU4OifFZean1AnHfsQwtri1fop2OWwsMv019w==",
"license": "MIT",
"peer": true,
"dependencies": {
"@supabase/auth-js": "2.75.1",
"@supabase/functions-js": "2.75.1",
@ -4567,6 +4567,7 @@
"integrity": "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==",
"devOptional": true,
"license": "MIT",
"peer": true,
"dependencies": {
"csstype": "^3.0.2"
}
@ -4640,6 +4641,7 @@
"integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.46.1",
"@typescript-eslint/types": "8.46.1",
@ -5176,8 +5178,7 @@
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"license": "ISC",
"optional": true,
"peer": true
"optional": true
},
"node_modules/abs-svg-path": {
"version": "0.1.1",
@ -5191,6 +5192,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@ -5214,7 +5216,6 @@
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"debug": "4"
},
@ -5289,8 +5290,7 @@
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz",
"integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==",
"license": "ISC",
"optional": true,
"peer": true
"optional": true
},
"node_modules/are-we-there-yet": {
"version": "2.0.0",
@ -5299,7 +5299,6 @@
"deprecated": "This package is no longer supported.",
"license": "ISC",
"optional": true,
"peer": true,
"dependencies": {
"delegates": "^1.0.0",
"readable-stream": "^3.6.0"
@ -5796,6 +5795,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.8.9",
"caniuse-lite": "^1.0.30001746",
@ -6140,7 +6140,6 @@
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"license": "ISC",
"optional": true,
"peer": true,
"bin": {
"color-support": "bin.js"
}
@ -6179,8 +6178,7 @@
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
"license": "ISC",
"optional": true,
"peer": true
"optional": true
},
"node_modules/cookie": {
"version": "1.0.2",
@ -6395,8 +6393,7 @@
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
"license": "MIT",
"optional": true,
"peer": true
"optional": true
},
"node_modules/dequal": {
"version": "2.0.3",
@ -6736,6 +6733,7 @@
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@ -6905,6 +6903,7 @@
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.9",
@ -7487,7 +7486,6 @@
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"license": "ISC",
"optional": true,
"peer": true,
"dependencies": {
"minipass": "^3.0.0"
},
@ -7501,7 +7499,6 @@
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"optional": true,
"peer": true,
"dependencies": {
"yallist": "^4.0.0"
},
@ -7578,7 +7575,6 @@
"deprecated": "This package is no longer supported.",
"license": "ISC",
"optional": true,
"peer": true,
"dependencies": {
"aproba": "^1.0.3 || ^2.0.0",
"color-support": "^1.1.2",
@ -7599,8 +7595,7 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"license": "ISC",
"optional": true,
"peer": true
"optional": true
},
"node_modules/generator-function": {
"version": "2.0.1",
@ -7920,8 +7915,7 @@
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
"license": "ISC",
"optional": true,
"peer": true
"optional": true
},
"node_modules/hasown": {
"version": "2.0.2",
@ -7969,7 +7963,6 @@
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"agent-base": "6",
"debug": "4"
@ -8585,6 +8578,7 @@
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"jiti": "bin/jiti.js"
}
@ -8948,7 +8942,6 @@
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"semver": "^6.0.0"
},
@ -8965,7 +8958,6 @@
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"license": "ISC",
"optional": true,
"peer": true,
"bin": {
"semver": "bin/semver.js"
}
@ -9095,7 +9087,6 @@
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
@ -9110,7 +9101,6 @@
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"optional": true,
"peer": true,
"dependencies": {
"yallist": "^4.0.0"
},
@ -9124,7 +9114,6 @@
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"license": "MIT",
"optional": true,
"peer": true,
"bin": {
"mkdirp": "bin/cmd.js"
},
@ -9179,8 +9168,7 @@
"resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz",
"integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==",
"license": "MIT",
"optional": true,
"peer": true
"optional": true
},
"node_modules/nanoid": {
"version": "3.3.11",
@ -9314,7 +9302,6 @@
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"whatwg-url": "^5.0.0"
},
@ -9343,7 +9330,6 @@
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
"license": "ISC",
"optional": true,
"peer": true,
"dependencies": {
"abbrev": "1"
},
@ -9390,7 +9376,6 @@
"deprecated": "This package is no longer supported.",
"license": "ISC",
"optional": true,
"peer": true,
"dependencies": {
"are-we-there-yet": "^2.0.0",
"console-control-strings": "^1.1.0",
@ -9719,7 +9704,6 @@
"integrity": "sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==",
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=8"
}
@ -9828,7 +9812,6 @@
"resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz",
"integrity": "sha512-TdTZPf1trZ8/UFu5Cx/GXB7GZM30LT+wWUNfsi6Bq8ePLnb+woNKtDymI2mxZYBpMbonNFqKmiz684DIfnd8dA==",
"license": "Apache-2.0",
"peer": true,
"engines": {
"node": ">=18"
},
@ -9844,7 +9827,6 @@
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.0",
"nan": "^2.17.0",
@ -9860,7 +9842,6 @@
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"mimic-response": "^2.0.0"
},
@ -9874,7 +9855,6 @@
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=8"
},
@ -9888,7 +9868,6 @@
"integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"decompress-response": "^4.2.0",
"once": "^1.3.1",
@ -9979,6 +9958,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@ -10287,6 +10267,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
@ -10299,6 +10280,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
@ -10455,7 +10437,6 @@
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@ -11008,8 +10989,7 @@
}
],
"license": "MIT",
"optional": true,
"peer": true
"optional": true
},
"node_modules/simple-swizzle": {
"version": "0.2.4",
@ -11533,7 +11513,6 @@
"integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
"license": "ISC",
"optional": true,
"peer": true,
"dependencies": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
@ -11552,7 +11531,6 @@
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"license": "ISC",
"optional": true,
"peer": true,
"engines": {
"node": ">=10"
}
@ -11563,7 +11541,6 @@
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
"license": "ISC",
"optional": true,
"peer": true,
"engines": {
"node": ">=8"
}
@ -11660,6 +11637,7 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@ -11835,6 +11813,7 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -12259,7 +12238,6 @@
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
"license": "ISC",
"optional": true,
"peer": true,
"dependencies": {
"string-width": "^1.0.2 || 2 || 3 || 4"
}
@ -12375,8 +12353,7 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC",
"optional": true,
"peer": true
"optional": true
},
"node_modules/yargs": {
"version": "15.4.1",