mirror of
https://github.com/JMP-MS/ASPIC.git
synced 2026-10-27 16:07:10 +00:00
V1.22.23 Passage à Claude Code et création du BackOffice
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>ASPIC — BackOffice — Compétences</title>
|
||||
<link rel="icon" href="mevelia-icone.png">
|
||||
<link rel="stylesheet" href="backoffice.css">
|
||||
<style>
|
||||
section{background:#111;border:1px solid #262626;border-radius:6px;padding:16px 18px;margin-bottom:18px;max-width:760px;}
|
||||
section h2{font-size:12px;color:#888;text-transform:uppercase;letter-spacing:.05em;font-weight:normal;margin:0 0 12px;}
|
||||
label{display:block;font-size:11px;color:#999;margin:8px 0 3px;}
|
||||
.grille{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
|
||||
.ligne{padding:8px 0;border-bottom:1px solid #1e1e1e;font-size:13px;display:flex;justify-content:space-between;gap:10px;align-items:center;}
|
||||
.ligne .detail{color:#888;font-size:11px;}
|
||||
.badge{font-size:11px;padding:2px 7px;border-radius:10px;background:#222;color:#999;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="bo-cadre">
|
||||
<div id="bo-corps">
|
||||
<nav id="bo-menu"></nav>
|
||||
<main id="bo-contenu">
|
||||
<h1>Compétences</h1>
|
||||
<p class="sous-titre">Catalogue curaté par Jean-Marc + attribution aux collaborateurs. Une compétence ne produit un effet réel que si elle est câblée dans mission_agent.php.</p>
|
||||
|
||||
<section>
|
||||
<h2>Nouvelle compétence</h2>
|
||||
<label>Code (majuscules/chiffres/underscore, ex. SITE_WEB)</label>
|
||||
<input id="nvCode" placeholder="SITE_WEB">
|
||||
<label>Libellé</label>
|
||||
<input id="nvLibelle" placeholder="Créer et gérer un site web vitrine">
|
||||
<label>Description</label>
|
||||
<textarea id="nvDescription" style="width:100%;min-height:60px;"></textarea>
|
||||
<div style="margin-top:10px;"><button id="btnCreerCompetence" class="principal">Créer</button>
|
||||
<span id="msgCompetence" style="margin-left:10px;font-size:12px;"></span></div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Catalogue</h2>
|
||||
<div id="listeCompetences"></div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Attribuer une compétence</h2>
|
||||
<div class="grille">
|
||||
<div>
|
||||
<label>Collaborateur</label>
|
||||
<select id="selAgent"></select>
|
||||
</div>
|
||||
<div>
|
||||
<label>Compétence</label>
|
||||
<select id="selCompetence"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:10px;"><button id="btnAttribuer" class="principal">Attribuer</button>
|
||||
<span id="msgAttribution" style="margin-left:10px;font-size:12px;"></span></div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Attributions actuelles</h2>
|
||||
<div id="listeAttributions"></div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
<footer id="bo-pied"></footer>
|
||||
</div>
|
||||
<script src="backoffice.js"></script>
|
||||
<script>
|
||||
initBackoffice({ cibleEchap: 'backoffice.html' });
|
||||
|
||||
let competences = [];
|
||||
let agents = [];
|
||||
|
||||
async function chargerCompetences() {
|
||||
const r = await fetch('competences.php');
|
||||
const data = await r.json();
|
||||
competences = data.competences || [];
|
||||
const conteneur = document.getElementById('listeCompetences');
|
||||
conteneur.innerHTML = competences.length ? '' : '<p style="color:#666;font-size:12px;">Aucune compétence dans le catalogue.</p>';
|
||||
competences.forEach(function (c) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'ligne';
|
||||
div.innerHTML = '<div><strong>' + c.CMP_Code + '</strong> — ' + c.CMP_Libelle +
|
||||
'<div class="detail">' + (c.CMP_Description || '') + '</div></div>';
|
||||
conteneur.appendChild(div);
|
||||
});
|
||||
const selCompetence = document.getElementById('selCompetence');
|
||||
selCompetence.innerHTML = '';
|
||||
competences.forEach(function (c) {
|
||||
const option = document.createElement('option');
|
||||
option.value = c.CMP_Code;
|
||||
option.textContent = c.CMP_Libelle + ' (' + c.CMP_Code + ')';
|
||||
selCompetence.appendChild(option);
|
||||
});
|
||||
}
|
||||
|
||||
async function chargerAgents() {
|
||||
const r = await fetch('agents.php');
|
||||
const data = await r.json();
|
||||
agents = data.agents || [];
|
||||
const selAgent = document.getElementById('selAgent');
|
||||
selAgent.innerHTML = '';
|
||||
agents.forEach(function (a) {
|
||||
const option = document.createElement('option');
|
||||
option.value = a.AGN_Incr;
|
||||
option.textContent = a.AGN_Prenom + (a.AGN_Fonction ? ' — ' + a.AGN_Fonction : '');
|
||||
selAgent.appendChild(option);
|
||||
});
|
||||
}
|
||||
|
||||
async function chargerAttributions() {
|
||||
const r = await fetch('agents_competences.php');
|
||||
const data = await r.json();
|
||||
const conteneur = document.getElementById('listeAttributions');
|
||||
const attributions = data.attributions || [];
|
||||
conteneur.innerHTML = attributions.length ? '' : '<p style="color:#666;font-size:12px;">Aucune attribution.</p>';
|
||||
attributions.forEach(function (a) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'ligne';
|
||||
div.innerHTML = '<span>' + a.AGN_Prenom + ' <span class="badge">' + a.CMP_Libelle + '</span></span>';
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'danger';
|
||||
btn.textContent = 'Retirer';
|
||||
btn.addEventListener('click', async function () {
|
||||
btn.disabled = true;
|
||||
await fetch('agents_competences.php', {
|
||||
method: 'DELETE', headers: {'Content-Type':'application/json'},
|
||||
body: JSON.stringify({ AGC_AgentIncr: a.AGC_AgentIncr, AGC_CompetenceCode: a.AGC_CompetenceCode })
|
||||
});
|
||||
chargerAttributions();
|
||||
});
|
||||
div.appendChild(btn);
|
||||
conteneur.appendChild(div);
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('btnCreerCompetence').addEventListener('click', async function () {
|
||||
const code = document.getElementById('nvCode').value.trim().toUpperCase();
|
||||
const libelle = document.getElementById('nvLibelle').value.trim();
|
||||
const description = document.getElementById('nvDescription').value.trim();
|
||||
const msg = document.getElementById('msgCompetence');
|
||||
const r = await fetch('competences.php', {
|
||||
method: 'POST', headers: {'Content-Type':'application/json'},
|
||||
body: JSON.stringify({ CMP_Code: code, CMP_Libelle: libelle, CMP_Description: description })
|
||||
});
|
||||
const data = await r.json();
|
||||
if (!r.ok) { msg.textContent = data.error || 'Erreur'; msg.style.color = '#e14a5c'; return; }
|
||||
msg.textContent = 'Créée.'; msg.style.color = '#7be07b';
|
||||
document.getElementById('nvCode').value = '';
|
||||
document.getElementById('nvLibelle').value = '';
|
||||
document.getElementById('nvDescription').value = '';
|
||||
chargerCompetences();
|
||||
});
|
||||
|
||||
document.getElementById('btnAttribuer').addEventListener('click', async function () {
|
||||
const agentIncr = document.getElementById('selAgent').value;
|
||||
const competenceCode = document.getElementById('selCompetence').value;
|
||||
const msg = document.getElementById('msgAttribution');
|
||||
const r = await fetch('agents_competences.php', {
|
||||
method: 'POST', headers: {'Content-Type':'application/json'},
|
||||
body: JSON.stringify({ AGC_AgentIncr: agentIncr, AGC_CompetenceCode: competenceCode })
|
||||
});
|
||||
const data = await r.json();
|
||||
if (!r.ok) { msg.textContent = data.error || 'Erreur'; msg.style.color = '#e14a5c'; return; }
|
||||
msg.textContent = 'Attribuée.'; msg.style.color = '#7be07b';
|
||||
chargerAttributions();
|
||||
});
|
||||
|
||||
chargerCompetences();
|
||||
chargerAgents();
|
||||
chargerAttributions();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user