oefenhub_docent_03_nieuwe_oefening_v1_22.html
Korte beschrijving
Mockup van de subcategorie-view waarin een docent een verdiepende laag van het oefenaanbod en de onderliggende oefeningen bekijkt of beheert.
Gerelateerde documentatie
- Bekijk de schermdocumentatie voor meer functionele context.
Bestand
Broncode
/mockups_html/docent/oefenhub_docent_03_nieuwe_oefening_v1_22.html
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OefenHub - Nieuwe Oefening</title>
<link href="./oefenhub_shared_logo.css" rel="stylesheet">
<style>
:root{
--line:#c7d7ea;
--text:#174f9a;
--muted:#5d7ea8;
--accent:#1e5aa8;
--accent-2:#2f79db;
--shadow:0 12px 28px rgba(25,70,130,.08);
--blue-4:#0d5db8;
--shadow-soft:0 8px 18px rgba(35,100,177,.08);
}
*{box-sizing:border-box}
html, body { margin:0; padding:0; }
body{
overflow-x:hidden;
min-height:100vh;
font-family:"Segoe UI", Tahoma, sans-serif;
color:var(--text);
background:
radial-gradient(circle at 8% 14%, rgba(255,255,255,.68) 0 12%, transparent 13%),
radial-gradient(circle at 18% 10%, rgba(255,255,255,.45) 0 9%, transparent 10%),
radial-gradient(circle at 86% 17%, rgba(255,255,255,.58) 0 11%, transparent 12%),
linear-gradient(180deg, #7ec2f8 0%, #bfe2fd 15%, #edf7ff 34%, #f7fbff 100%);
}
.wrap, .footer-wrap { width: min(1220px, calc(100% - 48px)); margin: 0 auto; }
.header {
padding: 10px 0 12px;
background: linear-gradient(180deg, rgba(100,171,238,.92), rgba(120,192,248,.85));
border-bottom: 1px solid rgba(255,255,255,.38);
box-shadow: 0 8px 20px rgba(28, 100, 177, .08);
position: relative;
z-index: 1;
}
.header-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 10px; }
.brand { display: flex; flex-direction: column; align-items: flex-start; min-width: 250px; }
.welcome-text { font-size: 12px; color: rgba(17,79,149,.82); font-weight: 700; margin-top: -10px; margin-left: 53px; }
.nav-pills { display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: nowrap; white-space: nowrap; }
.pill { border: 0; border-radius: 12px; padding: 9px 14px; color: #fff; font-size: 13px; font-weight: 900; box-shadow: var(--shadow-soft); line-height: 1; cursor: pointer; flex: 0 0 auto; }
.pill.blue { background: linear-gradient(180deg, #2f88ea, #176acc); }
.pill.green { background: linear-gradient(180deg, #8adf67, #58ba3d); }
.pill.purple { background: linear-gradient(180deg, #BF67DF, #863DBA); }
.header-actions { display: flex; align-items: center; justify-content: flex-end; gap: 10px; min-width: 120px; }
.mail-btn { position: relative; width: 40px; height: 40px; border-radius: 999px; background: linear-gradient(180deg, #ffffff, #eef6ff); font-size: 17px; border:0; box-shadow: var(--shadow-soft); cursor:pointer; color:var(--blue-4); }
.badge { position: absolute; right: -2px; bottom: -2px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: #e23838; color: #fff; font-size: 11px; font-weight: 800; display: flex; align-items: center; justify-content: center; border: 2px solid #fff; }
.nav-item { position: relative; display: inline-flex; align-items: center; }
.profile-chip { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 999px; background: linear-gradient(180deg, #ffffff, #edf6ff); padding: 0; border:0; box-shadow: var(--shadow-soft); cursor:pointer; }
.avatar { width: 28px; height: 28px; border-radius: 999px; display: grid; place-items: center; color: #fff; font-size: 13px; font-weight: 900; background: linear-gradient(180deg, #ffb247, #ff8120); }
.dropdown-menu { position: absolute; top: calc(100% + 8px); left: 0; width: 306px; background: linear-gradient(180deg, rgba(255,255,255,.97), rgba(244,250,255,.98)); border-radius: 20px; box-shadow: 0 12px 24px rgba(35,100,177,.16); border: 1px solid rgba(170, 204, 238, .55); padding: 10px 12px; z-index: 40; opacity: 0; visibility: hidden; transform: translateY(-4px); transition: opacity .18s ease, transform .18s ease, visibility .18s ease; }
.dropdown-menu::before { content: ""; position: absolute; top: -10px; left: 36px; border-left: 10px solid transparent; border-right: 10px solid transparent; border-bottom: 10px solid rgba(255,255,255,.97); filter: drop-shadow(0 -1px 0 rgba(170, 204, 238, .45)); }
.dropdown-menu.align-right { left: auto; right: 0; width: 306px; }
.dropdown-menu.align-right::before { left: auto; right: 20px; }
.nav-item:hover .dropdown-menu, .nav-item:focus-within .dropdown-menu, .nav-item.open .dropdown-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.menu-list { display: flex; flex-direction: column; gap: 0; }
.menu-link { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 9px; padding: 8px 11px; border-radius: 13px; text-decoration: none; color: #18518f; font-size: 15px; font-weight: 900; box-shadow: inset 0 -1px 0 rgba(17,79,149,.10); transition: background .18s ease, transform .18s ease; }
.menu-link:last-child { box-shadow: none; }
.menu-link:hover { background: linear-gradient(180deg, #edf5ff, #dcecff); transform: translateX(2px); }
.menu-link.no-arrow { grid-template-columns: auto 1fr; }
.menu-link.no-arrow .menu-arrow { display: none; }
.menu-icon { width: 23px; height: 23px; border-radius: 7px; display: grid; place-items: center; color: #fff; font-size: 14px; font-weight: 900; box-shadow: inset 0 1px 1px rgba(255,255,255,.35), 0 4px 8px rgba(0,0,0,.10); }
.menu-icon.green { background: linear-gradient(180deg, #8add68, #4baa35); }
.menu-icon.blue { background: linear-gradient(180deg, #49a4ff, #1f7fe2); }
.menu-icon.yellow { background: linear-gradient(180deg, #ffd45a, #f0b000); color: #8a5d00; }
.menu-icon.purple { background: linear-gradient(180deg, #8d6cff, #6147d8); }
.menu-icon.red { background: linear-gradient(180deg, #ff9a9a, #ea6767); }
.menu-arrow { color: #18518f; font-size: 22px; line-height: 1; font-weight: 700; }
main.wrap { padding: 0; }
.page-shell{ background:transparent; border-radius:0; box-shadow:none; overflow:visible; }
.page-content{ padding:22px 0 0; }
.panel, .intro, .selection-panel{ background: rgba(255,255,255,.92); border: 1px solid rgba(170,204,238,.62); border-radius: 24px; box-shadow: 0 8px 18px rgba(35,100,177,.08); }
.page-breadcrumb{ display:flex; align-items:center; gap:8px; margin:0 0 14px; font-size:13px; line-height:1.35; font-weight:800; color:#6d86a7; }
.page-breadcrumb a{ color:#4d79ac; text-decoration:none; }
.page-breadcrumb a:hover{ text-decoration:underline; }
.page-breadcrumb .sep{ color:#90a8c4; font-weight:900; }
.intro{ margin:0 0 18px; padding:24px 28px 22px; }
h1{ margin:0 0 10px; font-size:26px; line-height:1.12; color:#0d5db8; font-weight:900; }
.lead{ font-size:16px; line-height:1.55; color:#55789f; max-width:1100px; margin:0; }
.selection-panel{ margin:0; padding:24px; }
.section-title{ display:flex; align-items:center; justify-content:space-between; gap:20px; margin-bottom:12px; }
.section-title h2{ margin:0; font-size:22px; color:#0d5db8; }
.section-sub{ margin:0 0 18px; color:#55789f; font-size:16px; line-height:1.45; max-width:1000px; }
.module-grid{ display:grid; grid-template-columns:minmax(280px,320px) minmax(0,1fr); gap:18px; align-items:stretch; }
.module-list,.module-detail{ background:rgba(255,255,255,.72); border:1px solid rgba(170,204,238,.62); border-radius:26px; padding:18px; min-height:0; min-width:0; }
.module-list h3,.module-detail h3{ margin:0 0 8px; font-size:18px; color:#0d5db8; }
.small-text{ color:#55789f; font-size:14px; line-height:1.45; }
.module-scroll{ margin-top:14px; max-height:405px; overflow:auto; padding-right:6px; }
.module-item{ width:100%; text-align:left; border:1px solid rgba(170,204,238,.62); background:#fff; border-radius:18px; padding:12px 14px; margin-bottom:10px; cursor:pointer; color:var(--text); }
.module-item.active{ border-color:#8db8ef; background:#eef5fe; box-shadow:0 0 0 2px rgba(56,125,213,.08) inset; }
.module-item .tech{ display:block; font-size:14px; font-weight:800; margin-bottom:3px; }
.module-item .display{ display:block; color:#597da8; font-size:14px; }
.detail-card{ background:#fff; border:1px solid rgba(170,204,238,.62); border-radius:22px; padding:20px; min-height:405px; }
.detail-card h4{ margin:0 0 10px; font-size:18px; color:#0d5db8; }
.detail-card p{ color:#55789f; font-size:16px; line-height:1.6; margin:0 0 14px; }
.cta-row{ display:flex; justify-content:center; margin-top:18px; }
.btn{ border:none; border-radius:18px; padding:16px 28px; font-size:18px; font-weight:900; color:#fff; background:linear-gradient(180deg, var(--accent-2), var(--accent)); cursor:pointer; box-shadow:0 10px 20px rgba(31,90,168,.16); }
.btn.small{ padding:10px 16px; font-size:14px; border-radius:14px; }
.btn.danger{ background:linear-gradient(180deg, #f28a8a, #da5656); box-shadow:0 10px 20px rgba(179,72,72,.16); }
.module-config{ margin-top:22px; }
.module-config[hidden]{ display:none !important; }
.modal{ background:#f9fbfe; border:1px solid rgba(170,204,238,.62); border-radius:30px; box-shadow:0 22px 48px rgba(21,58,109,.18); overflow:hidden; }
.modal-header{ padding:22px 26px 16px; }
.modal-header-top{ display:flex; align-items:flex-start; justify-content:space-between; gap:16px; }
.modal-title{ font-size:22px; line-height:1.15; margin:0; color:#0d5db8; font-weight:900; }
.config-top-actions{ margin:0; display:flex; justify-content:flex-end; flex:0 0 auto; }
.modal-body{ padding:22px; min-height:640px; display:flex; align-items:center; justify-content:center; }
.technical-placeholder{ width:100%; text-align:center; color:#55789f; font-size:30px; line-height:1.35; font-style:italic; font-weight:700; }
.site-footer { margin-top: 26px; background: linear-gradient(180deg, rgba(255,255,255,.86), rgba(255,255,255,.96)); border-top: 1px solid rgba(170,204,238,.62); box-shadow: var(--shadow); border-radius: 26px 26px 0 0; overflow: visible; }
.site-footer .footer-wrap { padding: 22px 28px 18px; }
.footer-grid { display: grid; grid-template-columns: 1.1fr 1fr 1fr; gap: 36px; align-items: start; padding: 0; }
.footer-col h4 { margin: 0 0 12px; font-size: 15px; color: #0d5db8; font-weight: 900; padding-bottom: 8px; border-bottom: 1px solid rgba(170,204,238,.62); }
.footer-col p { margin: 0; font-size: 13px; line-height: 1.55; color: var(--muted); font-weight: 600; }
.footer-links { display: flex; flex-direction: column; gap: 10px; }
.footer-links a { color: #18518f; text-decoration: none; font-size: 13px; font-weight: 700; transition: color .18s ease; }
.footer-links a:hover { color: var(--blue-4); text-decoration: underline; }
.footer-bottom { margin-top: 18px; padding-top: 14px; border-top: 1px solid rgba(170,204,238,.62); display: flex; justify-content: space-between; gap: 12px; align-items: center; flex-wrap: wrap; font-size: 12px; color: var(--muted); font-weight: 600; }
@media (max-width:1100px){
.header-row { grid-template-columns: 1fr; gap: 14px; }
.brand { justify-self: center; align-items: center; min-width: 0; }
.welcome-text { margin-left: 0; margin-top: -6px; }
.header-actions { justify-content: center; }
.nav-pills { overflow-x: auto; justify-content: flex-start; padding-bottom: 2px; width: 100%; }
.module-grid { grid-template-columns:1fr; }
.footer-grid { grid-template-columns:1fr; gap:24px; }
}
@media (max-width:700px){
.wrap, .footer-wrap { width: min(100%, calc(100% - 18px)); }
.page-content { padding:18px; }
.dropdown-menu { width:276px; }
.dropdown-menu.align-right { width:286px; }
.site-footer .footer-wrap { padding:20px 18px 16px; }
.footer-bottom { justify-content:flex-start; }
.btn { width:100%; }
.config-top-actions .btn { width:auto; }
.technical-placeholder{ font-size:24px; }
}
</style>
</head>
<body>
<header class="header">
<div class="wrap">
<div class="header-row">
<div class="brand">
<div class="brand-logo" aria-label="OefenHub logo" role="img"></div>
<div class="welcome-text">Welkom terug, Eva</div>
</div>
<div class="nav-pills teacher-nav">
<button class="pill purple long">🧩 Oefenaanbod</button>
<button class="pill blue long">👥 Leerlingen</button>
<button class="pill green long">🟢 Online</button>
</div>
<div class="header-actions">
<button class="mail-btn" aria-label="Berichten">✉️<span class="badge">3</span></button>
<div class="nav-item profile-nav" data-menu="profielmenu">
<button class="profile-chip" type="button" aria-label="Gebruikersmenu" aria-haspopup="true" aria-expanded="false">
<span class="avatar">E</span>
</button>
<div class="dropdown-menu align-right" role="menu" aria-label="Gebruikersmenu">
<div class="menu-list">
<a class="menu-link no-arrow" href="#"><span class="menu-icon blue">👤</span><span>Profiel</span><span class="menu-arrow">›</span></a>
<a class="menu-link no-arrow" href="#"><span class="menu-icon green">⚙</span><span>Voorkeuren</span><span class="menu-arrow">›</span></a>
<a class="menu-link no-arrow" href="#"><span class="menu-icon yellow">Aa</span><span>Toegankelijkheid</span><span class="menu-arrow">›</span></a>
<a class="menu-link no-arrow" href="#"><span class="menu-icon purple" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path class="stroke-current" d="M16 19v-1a4 4 0 0 0-4-4H7a4 4 0 0 0-4 4v1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><circle class="stroke-current" cx="9.5" cy="7" r="3" stroke-width="2"/><path class="stroke-current" d="M21 19v-1a4 4 0 0 0-3-3.87" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path class="stroke-current" d="M16 4.13a4 4 0 0 1 0 7.75" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span><span>Relaties</span><span class="menu-arrow">›</span></a>
<a class="menu-link no-arrow" href="#"><span class="menu-icon red">!</span><span>Meld een probleem</span><span class="menu-arrow">›</span></a>
<a class="menu-link no-arrow" href="#"><span class="menu-icon blue">↪</span><span>Uitloggen</span><span class="menu-arrow">›</span></a>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
<main class="wrap">
<section class="page-shell">
<div class="page-content">
<nav class="page-breadcrumb" aria-label="Breadcrumb">
<a href="#">Home</a>
<span class="sep">></span>
<a href="#">Oefenaanbod</a>
<span class="sep">></span>
<span aria-current="page">Nieuwe oefening</span>
</nav>
<section class="intro panel">
<h1>Nieuwe oefening toevoegen</h1>
<p class="lead">Kies eerst een technische module die door beheer beschikbaar is gesteld. Bekijk daarna de beschrijving van de module en open de configuratie om een concrete oefening samen te stellen voor jouw leerlingen.</p>
</section>
<section class="selection-panel panel" id="moduleSelection">
<div class="section-title"><h2>Selecteer een technische module</h2></div>
<p class="section-sub">Links staat de lijst met technisch beschikbare modules. Rechts zie je detailinformatie van de geselecteerde module. De beschrijving wordt geladen vanuit de bijbehorende library en niet vanuit de database.</p>
<div class="module-grid">
<div class="module-list">
<h3>Beschikbare modules</h3>
<div class="small-text">Technische weergavenaam en referentie zoals door beheer beschikbaar gesteld.</div>
<div class="module-scroll">
<button class="module-item active"><span class="tech">OptellenAftrekken_Simple_v1</span><span class="display">Optellen & Aftrekken (simpel)</span></button>
<button class="module-item"><span class="tech">MultiplyBasic_Grid_v2</span><span class="display">Vermenigvuldigen basis</span></button>
<button class="module-item"><span class="tech">DivisionSimple_Ladder_v1</span><span class="display">Delen zonder rest</span></button>
<button class="module-item"><span class="tech">FractionsCompare_Core_v3</span><span class="display">Breuken vergelijken</span></button>
<button class="module-item"><span class="tech">TimeClock_Basics_v1</span><span class="display">Klokkijken basis</span></button>
<button class="module-item"><span class="tech">PercentagesIntro_L1</span><span class="display">Procenten introductie</span></button>
<button class="module-item"><span class="tech">Topography_Europe_Country_v4</span><span class="display">Topografie Europa landen</span></button>
<button class="module-item"><span class="tech">Spelling_DoubleConsonants_v2</span><span class="display">Spelling dubbele medeklinkers</span></button>
<button class="module-item"><span class="tech">Grammar_Woordsoorten_v1</span><span class="display">Woordsoorten herkennen</span></button>
<button class="module-item"><span class="tech">Reading_Comprehension_Short_v2</span><span class="display">Begrijpend lezen kort</span></button>
</div>
</div>
<div class="module-detail">
<h3>Detailoverzicht geselecteerde module</h3>
<div class="small-text">Dit detailoverzicht wordt gevuld zodra een docent een module selecteert.</div>
<div class="detail-card" style="margin-top:14px;">
<h4>Optellen & Aftrekken (simpel)</h4>
<p>Deze module is in staat om sommen te genereren waarbij twee getallen bij elkaar opgeteld of van elkaar afgetrokken moeten worden. Je kunt een minimale en/of maximale waarde per getal en uitkomst opgeven. Het is zelfs mogelijk om de getallen te beperken tot specifieke getallen.</p>
<p>De concrete beschrijving, beschikbare configuraties en modal-opbouw worden via een strategy pattern opgehaald uit de gekozen library. De opmaak en inhoud van de beschrijvingscomponent komen dus niet uit de database.</p>
<div class="cta-row"><button class="btn" id="openModuleConfig" type="button">Selecteer en configureer</button></div>
</div>
</div>
</div>
</section>
<div class="module-config" id="moduleConfig" hidden>
<div class="modal">
<div class="modal-header">
<div class="modal-header-top">
<h2 class="modal-title">Module configureren</h2>
<div class="config-top-actions"><button class="btn danger small" id="closeModuleConfigTop" type="button">Terug naar overzicht</button></div>
</div>
</div>
<div class="modal-body placeholder-body">
<div class="technical-placeholder">{Placeholder voor technische oefen modules}</div>
</div>
</div>
</div>
</div>
</section>
</main>
<footer class="site-footer">
<div class="footer-wrap">
<div class="footer-grid">
<div class="footer-col">
<h4>OefenHub</h4>
<p>Docentomgeving voor het beheren van niveaus, categorieën, subcategorieën en de leerlingen die daar toegang toe hebben.</p>
</div>
<div class="footer-col">
<h4>Snelle links</h4>
<div class="footer-links">
<a href="#">Oefenaanbod</a>
<a href="#">Leerlingen</a>
<a href="#">Online</a>
</div>
</div>
<div class="footer-col">
<h4>Ondersteuning</h4>
<div class="footer-links">
<a href="#">Handleiding voor docenten</a>
<a href="#">Meld een probleem</a>
<a href="#">Privacy & veiligheid</a>
</div>
</div>
</div>
<div class="footer-bottom">
<span>© 2026 OefenHub</span>
</div>
</div>
</footer>
<script>
(function () {
const navItems = document.querySelectorAll('.nav-item[data-menu]');
navItems.forEach(function (item) {
const trigger = item.querySelector('button');
if (!trigger) return;
trigger.addEventListener('click', function (event) {
event.preventDefault();
const isOpen = item.classList.contains('open');
navItems.forEach(function (other) {
other.classList.remove('open');
const btn = other.querySelector('button');
if (btn) btn.setAttribute('aria-expanded', 'false');
});
if (!isOpen) {
item.classList.add('open');
trigger.setAttribute('aria-expanded', 'true');
}
});
});
document.addEventListener('click', function (event) {
navItems.forEach(function (item) {
if (!item.contains(event.target)) {
item.classList.remove('open');
const btn = item.querySelector('button');
if (btn) btn.setAttribute('aria-expanded', 'false');
}
});
});
var openBtn = document.getElementById('openModuleConfig');
var closeTop = document.getElementById('closeModuleConfigTop');
var config = document.getElementById('moduleConfig');
var selection = document.getElementById('moduleSelection');
function openConfig() {
if (!config) return;
config.hidden = false;
if (selection) selection.hidden = true;
config.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
function closeConfig() {
if (!config) return;
config.hidden = true;
if (selection) selection.hidden = false;
if (selection) selection.scrollIntoView({ behavior: 'smooth', block: 'start' });
else if (openBtn) openBtn.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
if (openBtn) openBtn.addEventListener('click', openConfig);
if (closeTop) closeTop.addEventListener('click', closeConfig);
})();
</script>
</body>
</html>