Initial commit
This commit is contained in:
353
app/(main)/employes/nouveau/page.tsx
Normal file
353
app/(main)/employes/nouveau/page.tsx
Normal file
@@ -0,0 +1,353 @@
|
||||
'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;
|
||||
Reference in New Issue
Block a user