Files
Eric Coissac 30b7175702 Make cleaning
2025-11-17 14:18:13 +01:00

207 lines
4.8 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DNA Metabarcoding Learning Server</title>
<style>
body {
margin: 0;
font-family: sans-serif;
display: flex;
height: 100vh;
overflow: hidden;
}
/* Sidebar */
nav {
width: 250px;
background-color: #2c3e50;
color: white;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 20px 0;
overflow-y: auto;
}
nav ul {
list-style: none;
padding-left: 15px;
margin: 0;
}
nav li {
margin: 4px 0;
}
nav a {
color: white;
text-decoration: none;
display: block;
padding: 4px 8px;
border-radius: 4px;
font-weight: 500;
}
nav a:hover {
background-color: #34495e;
}
/* Toggle icons */
.folder {
cursor: pointer;
font-weight: bold;
display: flex;
align-items: center;
}
.folder::before {
content: "▸";
display: inline-block;
margin-right: 6px;
transition: transform 0.2s ease;
}
.folder.open::before {
transform: rotate(90deg);
}
ul.collapsed {
display: none;
}
/* Admin links */
nav .admin-links {
border-top: 1px solid #34495e;
margin-top: 10px;
padding-top: 10px;
}
/* Main content */
main {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
align-items: center;
background-color: #f7f7f7;
}
header img {
width: 100%;
max-width: 1000px;
height: auto;
display: block;
}
iframe#content-frame {
flex: 1;
width: 100%;
border: none;
max-width: 1000px;
background-color: white;
}
nav::-webkit-scrollbar {
width: 8px;
}
nav::-webkit-scrollbar-thumb {
background-color: #34495e;
border-radius: 4px;
}
</style>
</head>
<body>
<nav>
<ul id="nav-menu"></ul>
<ul class="admin-links">
<li><a href="/obidoc/" target="_blank">OBITools 4 Doc</a></li>
<li><a href="/jupyter/" target="_blank">JupyterHub</a></li>
<li><a href="/sftp/" target="_blank">Data Admin</a></li>
</ul>
</nav>
<main>
<header>
<img src="img/welcome_metabar.webp" alt="Welcome Banner">
</header>
<iframe id="content-frame" src=""></iframe>
</main>
<script>
const iframe = document.getElementById("content-frame");
const navMenu = document.getElementById("nav-menu");
/**
* Génère récursivement le menu à partir de l'arborescence JSON
*/
function buildMenu(items, parent) {
items.forEach(item => {
const li = document.createElement("li");
if (item.children) {
const folder = document.createElement("div");
folder.className = "folder";
folder.textContent = item.label;
const subUl = document.createElement("ul");
subUl.classList.add("collapsed");
folder.addEventListener("click", () => {
folder.classList.toggle("open");
subUl.classList.toggle("collapsed");
});
li.appendChild(folder);
li.appendChild(subUl);
parent.appendChild(li);
buildMenu(item.children, subUl);
} else if (item.file) {
const a = document.createElement("a");
a.href = "#";
a.textContent = item.label;
a.addEventListener("click", e => {
e.preventDefault();
iframe.src = "pages/" + item.file;
history.replaceState(null, null, "#" + item.file);
});
li.appendChild(a);
parent.appendChild(li);
}
});
}
fetch('pages/pages.json')
.then(resp => resp.json())
.then(pages => {
buildMenu(pages, navMenu);
// Charger la page par défaut (1ère sans enfants)
let defaultPage = null;
function findFirstFile(items) {
for (const it of items) {
if (it.file) return it.file;
if (it.children) {
const child = findFirstFile(it.children);
if (child) return child;
}
}
return null;
}
defaultPage = findFirstFile(pages);
if (location.hash) {
iframe.src = "pages/" + location.hash.substring(1);
} else if (defaultPage) {
iframe.src = "pages/" + defaultPage;
}
})
.catch(err => {
console.error("Erreur chargement pages.json", err);
iframe.srcdoc = "<p>Impossible de charger le contenu.</p>";
});
</script>
</body>
</html>