test redesign gesthub

This commit is contained in:
lnino
2025-12-16 01:31:23 +01:00
parent 4c7bb77890
commit e0883b04f6
5 changed files with 331 additions and 312 deletions

View File

@@ -1,153 +1,155 @@
// ... (Garde tout ton code existant pour le Dark mode, Menu, Contact, etc.) ...
// mode dark pour les gens qui ne sortent pas de chez eux voir la lumiere du jours
document.getElementById("toggle-darkmode").onclick = () => {
document.body.classList.toggle("dark");
};
// profil
document.querySelector(".profile-menu").addEventListener("click", (e) => {
e.stopPropagation();
document.querySelector(".profile-menu").classList.toggle("active");
});
// notif
document.querySelector(".notification").addEventListener("click", (e) => {
e.stopPropagation();
document.querySelector(".notification").classList.toggle("active");
});
// syteme contact
const contactOptions = document.querySelectorAll('.contact-option:not(.expandable)');
const contactModal = document.getElementById('contactModal');
const recipientName = document.getElementById('recipient-name');
const cancelBtn = document.getElementById('cancel-message');
const sendBtn = document.getElementById('send-message');
const dropdown = document.querySelector('.dropdown');
const nestedDropdowns = document.querySelectorAll('.nested-dropdown');
//menu princ
dropdown.addEventListener('click', (e) => {
e.stopPropagation();
const content = dropdown.querySelector('.dropdown-content');
content.style.display = content.style.display === 'block' ? 'none' : 'block';
});
// Gestion des sous-menus
nestedDropdowns.forEach(dropdown => {
dropdown.addEventListener('click', (e) => {
e.stopPropagation();
const nestedContent = dropdown.querySelector('.nested-content');
nestedContent.style.display = nestedContent.style.display === 'block' ? 'none' : 'block';
});
});
// Fermer les menus quand on clique ailleurs
document.addEventListener('click', () => {
document.querySelector('.dropdown-content').style.display = 'none';
document.querySelectorAll('.nested-content').forEach(el => {
el.style.display = 'none';
});
});
contactOptions.forEach(option => {
option.addEventListener('click', (e) => {
e.preventDefault();
if (option.dataset.role) {
recipientName.textContent = option.dataset.role;
contactModal.style.display = 'block';
}
});
});
document.querySelector('.close-modal').addEventListener('click', () => {
contactModal.style.display = 'none';
});
cancelBtn.addEventListener('click', () => {
contactModal.style.display = 'none';
});
sendBtn.addEventListener('click', () => {
const message = document.getElementById('message-content').value;
if (message.trim() !== '') {
contactModal.style.display = 'none';
document.getElementById('message-content').value = '';
}
});
// Fermer la modale si on clique en dehors
window.addEventListener('click', (e) => {
if (e.target === contactModal) {
contactModal.style.display = 'none';
}
});
// --- GESTION DU LAYOUT DYNAMIQUE ---
// Gestion des annonces
let isPageAdmin = false;
let isAdmin = false;
fetch("/api/is_admin")
.then(res => res.json())
.then(data => {
isAdmin = data.admin;
if (isAdmin) {
document.getElementById("admin-tools").style.display = "block";
}
});
fetch("/api/annonces")
.then(res => res.json())
.then(data => {
const container = document.getElementById("annonces-container");
container.innerHTML = "";
data.forEach(item => {
const div = document.createElement("div");
div.className = "postit";
div.dataset.id = item.id;
div.innerHTML = `
<span class="annonce-text">${item.text}</span>
<br><small>${item.author}</small>
`;
if (isAdmin) {
const editBtn = document.createElement("button");
editBtn.textContent = "✏️";
editBtn.onclick = () => editAnnonce(item.id, item.text);
div.appendChild(editBtn);
const delBtn = document.createElement("button");
delBtn.textContent = "🗑️";
delBtn.onclick = () => deleteAnnonce(item.id);
div.appendChild(delBtn);
}
container.appendChild(div);
});
});
function submitAnnonce() {
const txt = document.getElementById("annonce-text").value;
fetch("/api/annonces", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text: txt })
}).then(() => location.reload());
}
function deleteAnnonce(id) {
fetch(`/api/annonces/${id}`, {
method: "DELETE"
}).then(() => location.reload());
}
function editAnnonce(id, oldText) {
const newText = prompt("Modifier l'annonce :", oldText);
if (newText && newText !== oldText) {
fetch(`/api/annonces/${id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text: newText })
}).then(() => location.reload());
// 1. Vérification Admin et Initialisation
fetch("/api/is_admin")
.then(res => res.json())
.then(data => {
isPageAdmin = data.admin;
if (isPageAdmin) {
document.getElementById("admin-panel").style.display = "block";
document.body.classList.add('admin-active');
initDragAndDrop();
// Afficher aussi les outils d'annonces si tu veux garder ça
const tools = document.getElementById("admin-tools");
if(tools) tools.style.display = "block";
}
}
loadLayout(); // Charger les blocs
});
// 2. Chargement des blocs depuis l'API
function loadLayout() {
fetch('/api/layout')
.then(res => res.json())
.then(blocks => {
// Vider les colonnes
['left', 'center', 'right'].forEach(id => document.getElementById(id).innerHTML = '');
// Remettre le titre au centre (optionnel si tu veux qu'il soit un bloc aussi)
document.getElementById('center').innerHTML = '<h1 class="main-title">Gesthub</h1>';
blocks.forEach(block => {
const col = document.getElementById(block.column);
if (col) {
const el = createBlockElement(block);
col.appendChild(el);
}
});
});
}
// 3. Création du HTML d'un bloc
function createBlockElement(block) {
const div = document.createElement('div');
div.className = 'draggable-item';
div.dataset.id = block.id;
div.style.marginBottom = "1rem";
div.style.background = block.type === 'buttons' ? 'transparent' : '';
// Barre de drag (visible seulement en admin via CSS)
let html = `<div class="drag-handle">:: Deplacer :: <span onclick="deleteBlock(${block.id})" style="color:red;cursor:pointer;float:right">✖</span></div>`;
if (block.type === 'iframe') {
html += `
<div class="trello" style="padding: 10px; height: auto;">
${block.data.title ? `<h3>${block.data.title}</h3>` : ''}
<iframe src="${block.data.url}" width="100%" height="${block.data.height || 400}" frameborder="0"></iframe>
</div>
`;
} else if (block.type === 'buttons') {
// block.data.links doit être un tableau d'objets {label, url}
let btns = '';
if(block.data.links) {
block.data.links.forEach(link => {
btns += `<button class="simple-btn" onclick="window.open('${link.url}', '_blank')">${link.label}</button>`;
});
}
html += `<div class="button-container">${btns}</div>`;
} else if (block.type === 'html') {
html += `<div class="postit">${block.data.content}</div>`;
}
div.innerHTML = html;
return div;
}
// 4. Initialisation Drag & Drop (SortableJS)
function initDragAndDrop() {
const containers = [document.getElementById('left'), document.getElementById('center'), document.getElementById('right')];
containers.forEach(container => {
new Sortable(container, {
group: 'shared', // Permet de déplacer entre les colonnes
handle: '.drag-handle', // On ne peut attraper que par la poignée
animation: 150,
onEnd: function (evt) {
saveLayoutPosition();
}
});
});
}
// 5. Sauvegarde de la position
function saveLayoutPosition() {
const layout = [];
['left', 'center', 'right'].forEach(colId => {
const col = document.getElementById(colId);
const items = col.querySelectorAll('.draggable-item');
items.forEach((item, index) => {
layout.push({
id: item.dataset.id,
column: colId,
position: index
});
});
});
fetch('/api/layout/save', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(layout)
});
}
// 6. Ajouter un Widget (Logique simple pour l'instant)
window.addNewWidget = function(type) {
let data = {};
if (type === 'iframe') {
const url = prompt("URL de l'iframe (Mattermost/Trello) :");
const height = prompt("Hauteur (ex: 400) :", "400");
if (!url) return;
data = { url: url, height: height, title: "Nouveau Widget" };
} else if (type === 'buttons') {
// Pour faire simple, on ajoute un bouton par défaut, tu pourras éditer plus tard
data = {
links: [
{ label: "Nouveau Bouton", url: "https://google.com" }
]
};
} else if (type === 'html') {
const text = prompt("Texte du Post-it :");
data = { content: text };
}
fetch('/api/block/add', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: type, column: 'center', data: data })
})
.then(res => res.json())
.then(block => {
location.reload(); // Recharge pour afficher le nouveau bloc proprement
});
}
window.deleteBlock = function(id) {
if(confirm("Supprimer ce bloc ?")) {
fetch(`/api/block/${id}`, { method: 'DELETE' })
.then(() => location.reload());
}
}