354 lines
16 KiB
TypeScript
354 lines
16 KiB
TypeScript
'use client';
|
|
|
|
import React, { useState } from 'react';
|
|
import { Card } from 'primereact/card';
|
|
import { InputText } from 'primereact/inputtext';
|
|
import { Dropdown } from 'primereact/dropdown';
|
|
import { InputNumber } from 'primereact/inputnumber';
|
|
import { Calendar } from 'primereact/calendar';
|
|
import { MultiSelect } from 'primereact/multiselect';
|
|
import { Button } from 'primereact/button';
|
|
import { Toast } from 'primereact/toast';
|
|
import { useRouter } from 'next/navigation';
|
|
import { apiClient } from '../../../../services/api-client';
|
|
|
|
interface NouvelEmploye {
|
|
nom: string;
|
|
prenom: string;
|
|
email: string;
|
|
telephone: string;
|
|
metier: string;
|
|
statut: string;
|
|
dateEmbauche: Date | null;
|
|
salaire: number | null;
|
|
competences: string[];
|
|
certifications: string[];
|
|
adresse: string;
|
|
numeroSecu: string;
|
|
niveauExperience: string;
|
|
}
|
|
|
|
const NouvelEmployePage = () => {
|
|
const [employe, setEmploye] = useState<NouvelEmploye>({
|
|
nom: '',
|
|
prenom: '',
|
|
email: '',
|
|
telephone: '',
|
|
metier: '',
|
|
statut: 'ACTIF',
|
|
dateEmbauche: null,
|
|
salaire: null,
|
|
competences: [],
|
|
certifications: [],
|
|
adresse: '',
|
|
numeroSecu: '',
|
|
niveauExperience: 'DEBUTANT'
|
|
});
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
const router = useRouter();
|
|
|
|
const statutOptions = [
|
|
{ label: 'Actif', value: 'ACTIF' },
|
|
{ label: 'Inactif', value: 'INACTIF' },
|
|
{ label: 'Formation', value: 'FORMATION' }
|
|
];
|
|
|
|
const metierOptions = [
|
|
{ label: 'Maçon', value: 'MACON' },
|
|
{ label: 'Électricien', value: 'ELECTRICIEN' },
|
|
{ label: 'Plombier', value: 'PLOMBIER' },
|
|
{ label: 'Charpentier', value: 'CHARPENTIER' },
|
|
{ label: 'Peintre', value: 'PEINTRE' },
|
|
{ label: 'Chef d\'équipe', value: 'CHEF_EQUIPE' },
|
|
{ label: 'Conducteur', value: 'CONDUCTEUR' },
|
|
{ label: 'Couvreur', value: 'COUVREUR' },
|
|
{ label: 'Carreleur', value: 'CARRELEUR' },
|
|
{ label: 'Menuisier', value: 'MENUISIER' }
|
|
];
|
|
|
|
const niveauExperienceOptions = [
|
|
{ label: 'Débutant', value: 'DEBUTANT' },
|
|
{ label: 'Intermédiaire', value: 'INTERMEDIAIRE' },
|
|
{ label: 'Expérimenté', value: 'EXPERIMENTE' },
|
|
{ label: 'Expert', value: 'EXPERT' }
|
|
];
|
|
|
|
const competencesOptions = [
|
|
{ label: 'Maçonnerie', value: 'MACONNERIE' },
|
|
{ label: 'Électricité', value: 'ELECTRICITE' },
|
|
{ label: 'Plomberie', value: 'PLOMBERIE' },
|
|
{ label: 'Charpente', value: 'CHARPENTE' },
|
|
{ label: 'Peinture', value: 'PEINTURE' },
|
|
{ label: 'Carrelage', value: 'CARRELAGE' },
|
|
{ label: 'Menuiserie', value: 'MENUISERIE' },
|
|
{ label: 'Couverture', value: 'COUVERTURE' },
|
|
{ label: 'Isolation', value: 'ISOLATION' },
|
|
{ label: 'Cloisons sèches', value: 'CLOISONS_SECHES' },
|
|
{ label: 'Terrassement', value: 'TERRASSEMENT' },
|
|
{ label: 'Conduite d\'engins', value: 'CONDUITE_ENGINS' }
|
|
];
|
|
|
|
const certificationsOptions = [
|
|
{ label: 'CACES R482', value: 'CACES_R482' },
|
|
{ label: 'CACES R489', value: 'CACES_R489' },
|
|
{ label: 'Habilitation électrique', value: 'HABILITATION_ELECTRIQUE' },
|
|
{ label: 'Travail en hauteur', value: 'TRAVAIL_HAUTEUR' },
|
|
{ label: 'Soudure', value: 'SOUDURE' },
|
|
{ label: 'Échafaudage', value: 'ECHAFAUDAGE' },
|
|
{ label: 'Amiante', value: 'AMIANTE' },
|
|
{ label: 'Plomb', value: 'PLOMB' }
|
|
];
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
|
|
if (!employe.nom || !employe.prenom || !employe.email || !employe.metier) {
|
|
console.error('❌ Champs obligatoires manquants');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
setLoading(true);
|
|
console.log('🔄 Création de l\'employé...', employe);
|
|
|
|
const employeData = {
|
|
...employe,
|
|
dateEmbauche: employe.dateEmbauche?.toISOString().split('T')[0]
|
|
};
|
|
|
|
const response = await apiClient.post('/api/employes', employeData);
|
|
console.log('✅ Employé créé avec succès:', response.data);
|
|
|
|
router.push('/employes');
|
|
} catch (error) {
|
|
console.error('❌ Erreur lors de la création:', error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const handleCancel = () => {
|
|
router.push('/employes');
|
|
};
|
|
|
|
return (
|
|
<div className="grid">
|
|
<div className="col-12">
|
|
<Card title="Nouvel Employé" className="shadow-2">
|
|
<form onSubmit={handleSubmit} className="p-fluid">
|
|
<div className="grid">
|
|
{/* Informations personnelles */}
|
|
<div className="col-12">
|
|
<h3>Informations personnelles</h3>
|
|
</div>
|
|
|
|
<div className="col-12 md:col-6">
|
|
<label htmlFor="nom" className="block text-900 font-medium mb-2">
|
|
Nom *
|
|
</label>
|
|
<InputText
|
|
id="nom"
|
|
value={employe.nom}
|
|
onChange={(e) => setEmploye({...employe, nom: e.target.value})}
|
|
required
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12 md:col-6">
|
|
<label htmlFor="prenom" className="block text-900 font-medium mb-2">
|
|
Prénom *
|
|
</label>
|
|
<InputText
|
|
id="prenom"
|
|
value={employe.prenom}
|
|
onChange={(e) => setEmploye({...employe, prenom: e.target.value})}
|
|
required
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12 md:col-6">
|
|
<label htmlFor="email" className="block text-900 font-medium mb-2">
|
|
Email *
|
|
</label>
|
|
<InputText
|
|
id="email"
|
|
type="email"
|
|
value={employe.email}
|
|
onChange={(e) => setEmploye({...employe, email: e.target.value})}
|
|
required
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12 md:col-6">
|
|
<label htmlFor="telephone" className="block text-900 font-medium mb-2">
|
|
Téléphone
|
|
</label>
|
|
<InputText
|
|
id="telephone"
|
|
value={employe.telephone}
|
|
onChange={(e) => setEmploye({...employe, telephone: e.target.value})}
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12">
|
|
<label htmlFor="adresse" className="block text-900 font-medium mb-2">
|
|
Adresse
|
|
</label>
|
|
<InputText
|
|
id="adresse"
|
|
value={employe.adresse}
|
|
onChange={(e) => setEmploye({...employe, adresse: e.target.value})}
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12 md:col-6">
|
|
<label htmlFor="numeroSecu" className="block text-900 font-medium mb-2">
|
|
Numéro de sécurité sociale
|
|
</label>
|
|
<InputText
|
|
id="numeroSecu"
|
|
value={employe.numeroSecu}
|
|
onChange={(e) => setEmploye({...employe, numeroSecu: e.target.value})}
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
{/* Informations professionnelles */}
|
|
<div className="col-12">
|
|
<h3>Informations professionnelles</h3>
|
|
</div>
|
|
|
|
<div className="col-12 md:col-6">
|
|
<label htmlFor="metier" className="block text-900 font-medium mb-2">
|
|
Métier *
|
|
</label>
|
|
<Dropdown
|
|
id="metier"
|
|
value={employe.metier}
|
|
options={metierOptions}
|
|
onChange={(e) => setEmploye({...employe, metier: e.value})}
|
|
placeholder="Sélectionner un métier"
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12 md:col-6">
|
|
<label htmlFor="niveauExperience" className="block text-900 font-medium mb-2">
|
|
Niveau d'expérience
|
|
</label>
|
|
<Dropdown
|
|
id="niveauExperience"
|
|
value={employe.niveauExperience}
|
|
options={niveauExperienceOptions}
|
|
onChange={(e) => setEmploye({...employe, niveauExperience: e.value})}
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12 md:col-6">
|
|
<label htmlFor="statut" className="block text-900 font-medium mb-2">
|
|
Statut
|
|
</label>
|
|
<Dropdown
|
|
id="statut"
|
|
value={employe.statut}
|
|
options={statutOptions}
|
|
onChange={(e) => setEmploye({...employe, statut: e.value})}
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12 md:col-6">
|
|
<label htmlFor="dateEmbauche" className="block text-900 font-medium mb-2">
|
|
Date d'embauche
|
|
</label>
|
|
<Calendar
|
|
id="dateEmbauche"
|
|
value={employe.dateEmbauche}
|
|
onChange={(e) => setEmploye({...employe, dateEmbauche: e.value as Date})}
|
|
dateFormat="dd/mm/yy"
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12 md:col-6">
|
|
<label htmlFor="salaire" className="block text-900 font-medium mb-2">
|
|
Salaire mensuel (€)
|
|
</label>
|
|
<InputNumber
|
|
id="salaire"
|
|
value={employe.salaire}
|
|
onValueChange={(e) => setEmploye({...employe, salaire: e.value})}
|
|
mode="currency"
|
|
currency="EUR"
|
|
locale="fr-FR"
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12 md:col-6">
|
|
<label htmlFor="competences" className="block text-900 font-medium mb-2">
|
|
Compétences
|
|
</label>
|
|
<MultiSelect
|
|
id="competences"
|
|
value={employe.competences}
|
|
options={competencesOptions}
|
|
onChange={(e) => setEmploye({...employe, competences: e.value})}
|
|
placeholder="Sélectionner les compétences"
|
|
className="w-full"
|
|
display="chip"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12 md:col-6">
|
|
<label htmlFor="certifications" className="block text-900 font-medium mb-2">
|
|
Certifications
|
|
</label>
|
|
<MultiSelect
|
|
id="certifications"
|
|
value={employe.certifications}
|
|
options={certificationsOptions}
|
|
onChange={(e) => setEmploye({...employe, certifications: e.value})}
|
|
placeholder="Sélectionner les certifications"
|
|
className="w-full"
|
|
display="chip"
|
|
/>
|
|
</div>
|
|
|
|
{/* Boutons d'action */}
|
|
<div className="col-12">
|
|
<div className="flex gap-2 justify-content-end">
|
|
<Button
|
|
label="Annuler"
|
|
icon="pi pi-times"
|
|
className="p-button-secondary"
|
|
onClick={handleCancel}
|
|
type="button"
|
|
/>
|
|
<Button
|
|
label="Créer l'employé"
|
|
icon="pi pi-check"
|
|
className="p-button-success"
|
|
loading={loading}
|
|
type="submit"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</Card>
|
|
</div>
|
|
<Toast />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default NouvelEmployePage;
|