Files
BoursePython/app/templates/gestion_societes.html
T

413 lines
15 KiB
HTML
Raw Normal View History

2026-07-23 10:51:11 +02:00
{% extends "base.html" %} {% block title %}Gestion des sociétés - Bolsa{%
endblock %} {% block header_title %}Gestion sociétés{% endblock %} {% block
content %}
<div class="flex flex-col items-center justify-center py-6 relative">
<!-- Système de Toasts (Notifications flottantes centrées) -->
<div
id="toast-container"
class="fixed top-6 left-1/2 transform -translate-x-1/2 z-50 space-y-3 w-full max-w-md px-4 pointer-events-none"
>
{% set messages = get_flashed_messages(with_categories=true) %} {% if
messages %} {% for category, message in messages %}
<div
class="toast-message pointer-events-auto flex items-center justify-center px-4 py-3 rounded-xl shadow-2xl text-white text-sm font-medium transition-all duration-300 transform translate-y-0 opacity-100 text-center {% if category == 'success' %} bg-emerald-600 border border-emerald-500 {% elif category == 'warning' %} bg-amber-600 border border-amber-500 {% else %} bg-rose-600 border border-rose-500 {% endif %}"
>
<span>{{ message }}</span>
</div>
{% endfor %} {% endif %}
</div>
<!-- Box centrée principale -->
<div
class="bg-gray-900 border border-gray-800 p-8 rounded-2xl shadow-2xl w-full max-w-6xl"
>
<!-- En-tête de section -->
<div
class="flex justify-between items-center mb-6 border-b border-gray-800 pb-4"
>
<div>
<h2 class="text-2xl font-extrabold text-white">
Administration des sociétés
</h2>
<p class="text-gray-400 text-sm">
Gérez les informations légales et coordonnées des sociétés.
</p>
</div>
<a
href="{{ url_for('main.menu') }}"
class="px-4 py-2 bg-gray-800 hover:bg-gray-700 text-gray-200 text-sm font-medium rounded-lg transition duration-200"
>
Retour au menu
</a>
</div>
<!-- Grille principale -->
<div class="grid grid-cols-1 md:grid-cols-12 gap-8 py-4">
<!-- COLONNE GAUCHE : Liste des sociétés -->
<div
class="md:col-span-4 bg-gray-950 border border-gray-800 rounded-xl p-4 flex flex-col h-[560px]"
>
<h3
class="text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3 px-2"
>
Sociétés enregistrées
</h3>
<!-- Liste scrollable -->
<div class="overflow-y-auto flex-1 space-y-1 pr-1">
{% for s in societes %}
<div
onclick="selectionnerSociete('{{ s.id }}', '{{ s.Nom | e }}', '{{ s.Forme | e }}', '{{ s.Capital }}', '{{ s.siren }}', '{{ s.siret }}', '{{ s.RCS | e }}', '{{ s.TVA | e }}', '{{ s.NAF | e }}', '{{ s.Tel | e }}', '{{ s.Web | e }}', '{{ s.Mail | e }}')"
class="societe-item cursor-pointer px-3 py-2.5 rounded-lg {% if loop.first %}bg-blue-600 text-white{% else %}hover:bg-gray-800 text-gray-300{% endif %} font-medium text-sm transition flex justify-between items-center"
data-id="{{ s.id }}"
>
<span class="truncate pr-2 font-semibold">{{ s.Nom }}</span>
<span
class="text-xs {% if loop.first %}bg-blue-800{% else %}bg-gray-800 text-gray-400{% endif %} px-2 py-0.5 rounded whitespace-nowrap"
>
{{ s.Forme or 'N/A' }}
</span>
</div>
{% endfor %}
</div>
</div>
<!-- COLONNE DROITE : Formulaire -->
<div
class="md:col-span-8 bg-gray-950 border border-gray-800 rounded-xl p-6 flex flex-col justify-between"
>
<form
id="societe-form"
method="POST"
action=""
class="space-y-4 flex-1 flex flex-col justify-between"
>
<!-- ID technique caché -->
<input type="hidden" id="field-id" name="id" />
<div class="space-y-4">
<h3
class="text-sm font-semibold text-gray-300 uppercase tracking-wider mb-2"
>
Détails de la société
</h3>
<!-- Ligne 1 : Nom (50%), Forme (25%), Capital (25%) -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
<div class="md:col-span-2">
<label class="block text-xs font-medium text-gray-400 mb-1"
>Nom</label
>
<input
type="text"
id="field-nom"
name="Nom"
required
maxlength="60"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
<div class="md:col-span-1">
<label class="block text-xs font-medium text-gray-400 mb-1"
>Forme</label
>
<input
type="text"
id="field-forme"
name="Forme"
required
maxlength="10"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
<div class="md:col-span-1">
<label class="block text-xs font-medium text-gray-400 mb-1"
>Capital (€)</label
>
<input
type="number"
id="field-capital"
name="Capital"
required
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
</div>
<!-- Toutes les autres lignes sur 2 colonnes -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<!-- SIREN -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>SIREN</label
>
<input
type="text"
id="field-siren"
name="siren"
required
maxlength="14"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
<!-- SIRET -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>SIRET</label
>
<input
type="text"
id="field-siret"
name="siret"
required
maxlength="14"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
<!-- RCS -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>RCS</label
>
<input
type="text"
id="field-rcs"
name="RCS"
required
maxlength="50"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
<!-- TVA Intra. -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>TVA Intra.</label
>
<input
type="text"
id="field-tva"
name="TVA"
required
maxlength="50"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
<!-- Code NAF -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>Code NAF</label
>
<input
type="text"
id="field-naf"
name="NAF"
required
maxlength="10"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
<!-- Téléphone -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>Téléphone</label
>
<input
type="text"
id="field-tel"
name="Tel"
required
maxlength="30"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
<!-- Site Web -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>Site Web</label
>
<input
type="text"
id="field-web"
name="Web"
required
maxlength="100"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
<!-- Email -->
<div>
<label class="block text-xs font-medium text-gray-400 mb-1"
>Email</label
>
<input
type="email"
id="field-mail"
name="Mail"
required
maxlength="100"
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500"
/>
</div>
</div>
</div>
<!-- Bas : Boutons -->
<div
class="flex items-center justify-end space-x-3 pt-6 border-t border-gray-800 mt-6"
>
<button
type="button"
onclick="preparerCreation()"
class="px-4 py-2 bg-gray-800 hover:bg-gray-700 text-gray-300 text-sm font-medium rounded-lg transition duration-200"
>
Nouveau / Vider
</button>
<button
type="button"
onclick="annulerAction()"
class="px-4 py-2 bg-gray-800 hover:bg-gray-700 text-gray-300 text-sm font-medium rounded-lg transition duration-200"
>
Annuler
</button>
<button
type="submit"
name="action"
value="creer"
class="px-4 py-2 bg-emerald-600 hover:bg-emerald-500 text-white text-sm font-medium rounded-lg transition duration-200"
>
Créer
</button>
<button
type="submit"
name="action"
value="modifier"
class="px-4 py-2 bg-blue-600 hover:bg-blue-500 text-white text-sm font-medium rounded-lg transition duration-200"
>
Modifier
</button>
</div>
</form>
</div>
</div>
<!-- Pied de page sécurisé centré -->
<div
class="border-t border-gray-800 pt-4 mt-6 text-xs text-gray-400 italic text-center w-full"
>
Positions en bourse : Accès sécurisé. Veillez à fermer votre session après
chaque utilisation.
</div>
</div>
</div>
<script>
// Disparition automatique des Toasts au bout de 4 secondes
document.addEventListener("DOMContentLoaded", () => {
const toasts = document.querySelectorAll(".toast-message");
toasts.forEach((toast) => {
setTimeout(() => {
toast.style.opacity = "0";
toast.style.transform = "translateY(-10px)";
setTimeout(() => toast.remove(), 300);
}, 4000);
});
const premiereSociete = document.querySelector(".societe-item");
if (premiereSociete) {
premiereSociete.click();
}
});
function selectionnerSociete(
id,
nom,
forme,
capital,
siren,
siret,
rcs,
tva,
naf,
tel,
web,
mail,
) {
document.getElementById("field-id").value = id;
document.getElementById("field-nom").value = nom;
document.getElementById("field-forme").value = forme;
document.getElementById("field-capital").value = capital;
document.getElementById("field-siren").value = siren;
document.getElementById("field-siret").value = siret;
document.getElementById("field-rcs").value = rcs;
document.getElementById("field-tva").value = tva;
document.getElementById("field-naf").value = naf;
document.getElementById("field-tel").value = tel;
document.getElementById("field-web").value = web;
document.getElementById("field-mail").value = mail;
document.querySelectorAll(".societe-item").forEach((el) => {
el.classList.remove("bg-blue-600", "text-white");
el.classList.add("hover:bg-gray-800", "text-gray-300");
const badge = el.querySelector("span:last-child");
if (badge) {
badge.classList.remove("bg-blue-800");
badge.classList.add("bg-gray-800", "text-gray-400");
}
});
const selectedEl = document.querySelector(`[data-id="${id}"]`);
if (selectedEl) {
selectedEl.classList.remove("hover:bg-gray-800", "text-gray-300");
selectedEl.classList.add("bg-blue-600", "text-white");
const badge = selectedEl.querySelector("span:last-child");
if (badge) {
badge.classList.remove("bg-gray-800", "text-gray-400");
badge.classList.add("bg-blue-800");
}
selectedEl.scrollIntoView({ block: "nearest" });
}
}
// Fonction pour vider le formulaire pour une création propre
function preparerCreation() {
document.getElementById("field-id").value = "";
document.getElementById("field-nom").value = "";
document.getElementById("field-forme").value = "";
document.getElementById("field-capital").value = "";
document.getElementById("field-siren").value = "";
document.getElementById("field-siret").value = "";
document.getElementById("field-rcs").value = "";
document.getElementById("field-tva").value = "";
document.getElementById("field-naf").value = "";
document.getElementById("field-tel").value = "";
document.getElementById("field-web").value = "";
document.getElementById("field-mail").value = "";
// Retirer la surbrillance de la liste
document.querySelectorAll(".societe-item").forEach((el) => {
el.classList.remove("bg-blue-600", "text-white");
el.classList.add("hover:bg-gray-800", "text-gray-300");
const badge = el.querySelector("span:last-child");
if (badge) {
badge.classList.remove("bg-blue-800");
badge.classList.add("bg-gray-800", "text-gray-400");
}
});
}
function annulerAction() {
const premiereSociete = document.querySelector(".societe-item");
if (premiereSociete) {
premiereSociete.click();
}
}
</script>
{% endblock %}