photo de profil ajoutée

This commit is contained in:
2026-04-30 12:19:37 +02:00
parent b9f9de19f5
commit fc2e58fe15
14 changed files with 174 additions and 53 deletions

View File

@@ -2,6 +2,21 @@
{% load tags_personnaliser %} {% load tags_personnaliser %}
<div class="col-3 bg-danger d-flex flex-column vh-100 pt-5 sticky-top"> <div class="col-3 bg-danger d-flex flex-column vh-100 pt-5 sticky-top">
<div class="text-center mb-4">
{% if user.employe.photo %}
<img src="{{ user.employe.photo.url }}"
class="rounded-circle"
width="80"
height="80"
style="object-fit:cover;">
{% else %}
<i class="bi bi-person-circle text-white" style="font-size:60px;"></i>
{% endif %}
<div class="text-white mt-2">
{{ user.username }}
</div>
</div>
<a href="{% url 'gestion_employe:mon-profil' %}" class="text-white fw-bold text-decoration-none mb-4" style="font-size:1.4em"> <a href="{% url 'gestion_employe:mon-profil' %}" class="text-white fw-bold text-decoration-none mb-4" style="font-size:1.4em">
<i class="bi bi-person-circle"></i> Mon profil <i class="bi bi-person-circle"></i> Mon profil
</a> </a>

View File

@@ -16,27 +16,31 @@ const tableau_certificat = new Tabulator("#tableau-certificat", {
], ],
ajaxURL: url_certificat, ajaxURL: url_certificat,
}) })
const enregistrerProfil = $("enregistrerProfil"); const enregistrerProfil = $("enregistrerProfil");
enregistrerProfil.addEventListener("click", (e) => { enregistrerProfil.addEventListener("click", (e) => {
const url = $("information-personnelles").dataset.url; const url = $("information-personnelles").dataset.url;
const csrftoken = document.querySelector("[name='csrfmiddlewaretoken']").value; const csrftoken = document.querySelector("[name='csrfmiddlewaretoken']").value;
const formData = new FormData();
formData.append("nom", $("nom").value);
formData.append("prenom", $("prenom").value);
formData.append("email", $("email").value);
formData.append("telephone", $("telephone").value);
formData.append("adresse", $("adresse").value);
formData.append("sexe", $("sexe").value);
formData.append("date_naissance", $("date_naissance").value);
fetch(url, { fetch(url, {
method: 'POST', method: "POST",
headers: { headers: {
'Content-Type': 'application/json', "X-CSRFToken": csrftoken
'X-CSRFToken': csrftoken
}, },
body: JSON.stringify({ body: formData
"nom": $("nom").value,
"prenom": $("prenom").value,
"email": $("email").value,
"telephone": $("telephone").value,
"adresse": $("adresse").value,
"sexe": $("sexe").value,
"date_naissance": $("date_naissance").value,
})
}) })
.then(response => response.json()) .then(response => response.json())
.then(data => alert(data.message)) .then(data => alert(data.message))
}) .catch(error => console.error("Erreur:", error));
});

View File

@@ -19,17 +19,14 @@
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if not expiration_contrat %}
{% if expiration_contrat %}
{% if contrat_nb_jours_restant %}
<div class="alert alert-danger fade show alert-dismissible mt-2">
<strong>Important :</strong> Votre contrat de travail expire dans {{ contrat_nb_jours_restant }} jours, veuillez contacter les ressources humaines.
</div>
{% endif %}
{% else %}
<div class="alert alert-danger fade show alert-dismissible mt-2"> <div class="alert alert-danger fade show alert-dismissible mt-2">
<strong>Important :</strong> Les informations sur votre contrat n'ont pas été renseignées, veuillez contacter les ressources humaines. <strong>Important :</strong> Les informations sur votre contrat n'ont pas été renseignées, veuillez contacter les ressources humaines.
</div> </div>
{% elif contrat_nb_jours_restant %}
<div class="alert alert-danger fade show alert-dismissible mt-2">
<strong>Important :</strong> Votre contrat de travail expire dans {{ contrat_nb_jours_restant }} jours, veuillez contacter les ressources humaines.
</div>
{% endif %} {% endif %}
<div class="accordion mt-2" id="accordionInformationEmploye"> <div class="accordion mt-2" id="accordionInformationEmploye">
@@ -44,6 +41,13 @@
<div class="row" id="information-personnelles" data-url="{% url 'gestion_employe:modifier-employe' %}"> <div class="row" id="information-personnelles" data-url="{% url 'gestion_employe:modifier-employe' %}">
{% csrf_token %} {% csrf_token %}
<div class="col"> <div class="col">
<div class="form-group mb-2">
<label>photo</label>
{% if employe.photo %}
<span>Fichier actuel : <a href="{{ employe.photo.url }}">{{employe.photo}}</a></span>
{% endif %}
<input type="file" id="photo" name="photo" class="form-control">
</div>
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>Matricule :</label> <label>Matricule :</label>
<input type="text" class="form-control" id="matricule" value="{{ employe.matricule|default:'' }}" readonly> <input type="text" class="form-control" id="matricule" value="{{ employe.matricule|default:'' }}" readonly>
@@ -63,12 +67,13 @@
<option value='f' {% if employe.sexe == 'f' %}selected{% endif %}>Femme</option> <option value='f' {% if employe.sexe == 'f' %}selected{% endif %}>Femme</option>
</select> </select>
</div> </div>
</div>
<div class="col">
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>Date de naissance :</label> <label>Date de naissance :</label>
<input type="date" class="form-control" id="date_naissance" value="{{ employe.date_naissance|date:'Y-m-d' }}"> <input type="date" class="form-control" id="date_naissance" value="{{ employe.date_naissance|date:'Y-m-d' }}">
</div> </div>
</div>
<div class="col">
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>Département :</label> <label>Département :</label>
<input type="text" class="form-control" id="departement" value="{{ employe.departement.nom|default:'' }}" readonly> <input type="text" class="form-control" id="departement" value="{{ employe.departement.nom|default:'' }}" readonly>
@@ -167,6 +172,13 @@
{% csrf_token %} {% csrf_token %}
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="form-group mb-2">
<label>photo</label>
{% if employe.photo %}
<span>Fichier actuel : <a href="{{ employe.photo.url }}">{{employe.photo}}</a></span>
{% endif %}
<input type="file" class="form-control" name="photo">
</div>
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>CV</label> <label>CV</label>
{% if employe.CV %} {% if employe.CV %}

View File

@@ -93,9 +93,6 @@
</h5> </h5>
{% if user|has_group:"ressource_humaine" %} {% if user|has_group:"ressource_humaine" %}
<div> <div>
<button class="btn btn-secondary" disabled>
<i class="bi bi-file-earmark-lock"></i> Contrat actif
</button>
<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#modalContrat{{ item.employe.id }}"> <button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#modalContrat{{ item.employe.id }}">
<i class="bi bi-file-earmark-text"></i> Créer contrat <i class="bi bi-file-earmark-text"></i> Créer contrat
</button> </button>

View File

@@ -204,15 +204,17 @@ def modifier_employer(request):
return JsonResponse({"message": "Profil mis à jour avec succès."}) return JsonResponse({"message": "Profil mis à jour avec succès."})
def enregistrement_document(request): def enregistrement_document(request):
employe = Employe.objects.get(user__username=request.user) employe = Employe.objects.get(user=request.user)
if request.method == "POST": if request.method == "POST":
employe.CV = request.FILES["cv"] if 'cv' in request.FILES else employe.CV if request.FILES.get("photo"):employe.photo = request.FILES["photo"]
employe.diplome = request.FILES["diplome"] if 'diplome' in request.FILES else employe.diplome if "cv" in request.FILES:employe.CV = request.FILES["cv"]
employe.rib = request.FILES["rib"] if 'rib' in request.FILES else employe.rib if "diplome" in request.FILES: employe.diplome = request.FILES["diplome"]
employe.casier_judiciaire = request.FILES["casier_judiciaire"] if 'casier_judiciaire' in request.FILES else employe.casier_judiciaire if "rib" in request.FILES: employe.rib = request.FILES["rib"]
messages.success(request, "Documents enregistrés avec succès.") if "casier_judiciaire" in request.FILES:employe.casier_judiciaire = request.FILES["casier_judiciaire"]
employe.save() employe.save()
messages.success(request, "Documents enregistrés avec succès.")
return redirect("gestion_employe:mon-profil") return redirect("gestion_employe:mon-profil")

View File

@@ -1,4 +1,5 @@
const btnEnregistrerBailleur = document.getElementById('btnEnregistrerBailleur'); const btnEnregistrerBailleur = document.getElementById('btnEnregistrerBailleur');
let table;
btnEnregistrerBailleur.addEventListener('click', function() { btnEnregistrerBailleur.addEventListener('click', function() {
const form = document.getElementById('formBailleur'); const form = document.getElementById('formBailleur');
@@ -21,3 +22,30 @@ btnEnregistrerBailleur.addEventListener('click', function() {
} }
}); });
}); });
document.addEventListener("DOMContentLoaded", function () {
table = new Tabulator("#table-bailleurs", {
ajaxURL: "/gestion-projet/bailleurs/",
layout: "fitColumns",
pagination: "local",
paginationSize: 5,
columns: [
{title: "#", formatter: "rownum", width: 60},
{title: "Organisme", field: "nom_organisme"},
{title: "Contact", field: "contact"},
{title: "Email", field: "email"},
{title: "Pays", field: "pays"},
],
rowDblClick: function(e, row) {
const data = row.getData();
if (confirm(`Voulez-vous vraiment supprimer ${data.nom_organisme} ?`)) {
supprimerBailleur(data.id);
}
}
});
});

View File

@@ -1,20 +1,51 @@
<div class="modal fade" id="modalBailleur" tabindex="-1" aria-labelledby="modalBailleurLabel" aria-hidden="true"> <div class="modal fade" id="modalBailleur" tabindex="-1" aria-labelledby="modalBailleurLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered"> <div class="modal-dialog ">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="modalBailleurLabel">Ajouter un Bailleur</h5> <h5 class="modal-title" id="modalBailleurLabel">Gestion des Bailleurs</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button> <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div> </div>
<div class="modal-body p-4"> <ul class="nav nav-tabs px-3 pt-2" id="bailleurTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="ajouter-tab" data-bs-toggle="tab"
data-bs-target="#ajouter" type="button" role="tab">
Ajouter
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="liste-tab" data-bs-toggle="tab"
data-bs-target="#liste" type="button" role="tab">
Liste
</button>
</li>
</ul>
<div class="modal-body">
<div class="tab-content pt-3">
<div class="tab-pane fade show active" id="ajouter" role="tabpanel">
<form id="formBailleur" method="POST" action="{% url 'gestion_projet:creation-bailleur' %}"> <form id="formBailleur" method="POST" action="{% url 'gestion_projet:creation-bailleur' %}">
{% csrf_token %} {% csrf_token %}
{{ form_ajout_bailleur.as_p }} {{ form_ajout_bailleur.as_p }}
<button type="submit" class="btn btn-success mt-3" id="btnEnregistrerBailleur">
<i class="bi bi-save me-1"></i> Enregistrer
</button>
</form> </form>
</div> </div>
<div class="modal-footer"> <div class="tab-pane fade" id="liste" role="tabpanel">
<button type="submit" id="btnEnregistrerBailleur" class="btn btn-success"><i class="bi bi-save me-1"></i> Enregistrer</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button> <div class="d-flex justify-content-between align-items-center mb-3">
<h6 class="mb-0">Liste des bailleurs</h6>
</div>
<div class="row">
<div class="col">
<div id="table-bailleurs"
data-url="{% url 'gestion_projet:liste-bailleurs' %}">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -19,6 +19,12 @@ urlpatterns = [
views.creation_projet, views.creation_projet,
name='creation-projet' name='creation-projet'
), ),
path(
'bailleurs/',
views.liste_bailleur,
name='liste-bailleurs'
),
path( path(
'projet/modifier/<int:projet_id>/', 'projet/modifier/<int:projet_id>/',
views.modification_projet, views.modification_projet,
@@ -84,6 +90,7 @@ urlpatterns = [
views.liste_activites_projet, views.liste_activites_projet,
name='liste-activites-projet' name='liste-activites-projet'
), ),
# path( # path(
# 'projet/ajout-de-document/', # 'projet/ajout-de-document/',
# views.ajouter_document_projet, # views.ajouter_document_projet,
@@ -119,4 +126,6 @@ urlpatterns = [
views.mises_a_jour_projet, views.mises_a_jour_projet,
name='mises-a-jour-projet' name='mises-a-jour-projet'
) )
] ]

View File

@@ -143,6 +143,21 @@ def creation_bailleur(request):
return JsonResponse({'success': True}) return JsonResponse({'success': True})
return JsonResponse({'success': False}) return JsonResponse({'success': False})
@login_required
def liste_bailleur(request):
""" Vue pour retourner la liste de tous les bailleurs """
bailleurs = Bailleur.objects.all().order_by('-id')
data = []
for b in bailleurs:
data.append({
"id": b.id,
"nom_organisme": b.nom_organisme,
"contact": b.contact,
"email": b.email,
"pays": b.pays,
})
return JsonResponse(data, safe=False)
@login_required @login_required
def ajouter_financement_projet(request): def ajouter_financement_projet(request):
"""Ajoute un financement à un projet en vérifiant que le total ne dépasse pas 100%""" """Ajoute un financement à un projet en vérifiant que le total ne dépasse pas 100%"""

View File

@@ -56,13 +56,12 @@
{% if appartient_au_departement_informatique %} {% if appartient_au_departement_informatique %}
<button class="btn btn-primary" id="ajoutZoom">Ajout du lien zoom</button> <button class="btn btn-primary" id="ajoutZoom">Ajout du lien zoom</button>
{% endif %} {% endif %}
{% if appartient_direction and reservation.statut == "en_attente" %}
<button class="btn btn-danger" id="refuserReservation" data-lienrefus="{% url 'gestion_salle:refuser-reservation' %}">Refuser</button>
{% endif %}
<button class="btn btn-danger" id="bouton-annuler">Annuler</button>
{% if appartient_direction %} {% if appartient_direction %}
<button class="btn btn-danger" id="refuserReservation" data-lienrefus="{% url 'gestion_salle:refuser-reservation' %}">Refuser</button>
<button class="btn btn-success" id="bouton-valider">Valider</button> <button class="btn btn-success" id="bouton-valider">Valider</button>
{% endif %} {% endif %}
<button class="btn btn-secondary" id="bouton-annuler">Annuler</button>
</div> </div>
</form> </form>
</div> </div>

View File

@@ -18,6 +18,9 @@ def index(request:HttpRequest):
messages.error(request, "Impossible d'accéder au menu 'Reservation de salle' car votre profil Utilisateur n'est lié à aucun profil Employe. Veuillez contacter l'administrateur.") messages.error(request, "Impossible d'accéder au menu 'Reservation de salle' car votre profil Utilisateur n'est lié à aucun profil Employe. Veuillez contacter l'administrateur.")
return redirect('gestion_conges:conge') return redirect('gestion_conges:conge')
nom = request.user.last_name
prenom = request.user.first_name
if request.method == "POST": if request.method == "POST":
form = ReservationForm(request.POST) form = ReservationForm(request.POST)
if form.is_valid(): if form.is_valid():
@@ -42,6 +45,13 @@ def index(request:HttpRequest):
besoin_ordi = besoin_ordi, besoin_ordi = besoin_ordi,
motif_reservation=motif_reservation, motif_reservation=motif_reservation,
) )
if not nom or not prenom or nom.strip() == "" or prenom.strip() == "":
messages.error(
request,
"Vous devez renseigner un nom et un prénom valides pour effectuer une réservation."
)
return redirect('gestion_salle:reservation-salle')
reservation.save() reservation.save()
date_debut = date_debut + timedelta(days=1) date_debut = date_debut + timedelta(days=1)
@@ -117,7 +127,6 @@ def detail_reservation(request:HttpRequest, reservation_id:int):
'besoin_zoom': reservation.besoin_zoom, 'besoin_zoom': reservation.besoin_zoom,
'besoin_ordinateur': reservation.besoin_ordi, 'besoin_ordinateur': reservation.besoin_ordi,
'lien_zoom': reservation.lien_zoom or '', 'lien_zoom': reservation.lien_zoom or '',
'motif_refus': reservation.motif_refus or '',
} }
return JsonResponse(reservation_json, safe=True) return JsonResponse(reservation_json, safe=True)