oefenhub_beheerder_11_categorieen_V1_10.html
Korte beschrijving
Mockup van het categoriebeheer voor beheerders binnen OefenHub. Deze pagina ondersteunt het aanmaken, aanpassen en structureren van categorieën die binnen het platform worden gebruikt.
Gerelateerde documentatie
- Bekijk de schermdocumentatie voor meer functionele context.
Bestand
Broncode
/mockups_html/beheerder/oefenhub_beheerder_11_categorieen_V1_10.html
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>OefenHub Beheer - Categorieën beheren</title>
<link href="./oefenhub_shared_logo.css" rel="stylesheet">
<style>
:root {
--blue-1:#8fd0ff; --blue-2:#5bb3ff; --blue-3:#1f82e9; --blue-4:#0d5db8;
--text:#114f95; --muted:#5f7ea5; --line:rgba(17,79,149,.12);
--orange-1:#ffbb4d; --orange-2:#ff9620; --orange-3:#f87400;
--green-1:#8adf67; --green-2:#57ba3c; --green-3:#2c9348;
--yellow-1:#ffd04e; --yellow-2:#f6aa07; --purple-1:#8d6cff; --purple-2:#6248d8;
--red-1:#ff8f8f; --red-2:#df4949;
--shadow:0 12px 28px rgba(35,100,177,.12); --shadow-soft:0 8px 18px rgba(35,100,177,.08);
}
* { box-sizing:border-box; }
html,body { margin:0; padding:0; }
body {
font-family:"Segoe UI", Tahoma, Geneva, Verdana, 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%);
min-height:100vh;
}
.wrap { width:min(1240px, calc(100% - 30px)); 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:10;
}
.header-row { display:grid; grid-template-columns:minmax(220px,1fr) auto minmax(160px,1fr); align-items:center; gap:10px; }
.brand { display:flex; flex-direction:column; align-items:flex-start; min-width:250px; }
.brand img { display:block; height:46px; width:auto; }
.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:10px; white-space:nowrap; }
.nav-item { position:relative; }
.pill { border:0; border-radius:12px; padding:10px 16px; color:#fff; font-size:13px; font-weight:900; box-shadow:var(--shadow-soft); cursor:pointer; }
.pill.blue { background:linear-gradient(180deg, #2f88ea, #176acc); }
.pill.orange { background:linear-gradient(180deg, #ffbb4d, #ff7f12); }
.pill.green { background:linear-gradient(180deg, #8adf67, #58ba3d); }
.pill.has-chevron { display:inline-flex; align-items:center; gap:8px; }
.dropdown-menu {
position:absolute; top:calc(100% + 8px); left:0; width:304px; 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); }
.dropdown-menu.align-right { left:auto; right:0; width:294px; }
.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:9px 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); }
.menu-link:last-child { box-shadow:none; }
.menu-link.no-arrow { grid-template-columns:auto 1fr; }
.menu-link:hover, .menu-link.is-active { background:linear-gradient(180deg, #edf5ff, #dcecff); }
.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.orange { background:linear-gradient(180deg, #ffbb4d, #ff7f12); }
.menu-icon.blue { background:linear-gradient(180deg, #49a4ff, #1f7fe2); }
.menu-icon.green { background:linear-gradient(180deg, #8add68, #4baa35); }
.menu-arrow { color:#18518f; font-size:20px; line-height:1; font-weight:700; }
.header-actions { display:flex; align-items:center; justify-content:flex-end; gap:10px; min-width:120px; }
.mail-btn, .profile-chip { border:0; box-shadow:var(--shadow-soft); cursor:pointer; }
.mail-btn { position:relative; width:40px; height:40px; border-radius:999px; background:linear-gradient(180deg, #ffffff, #eef6ff); color:var(--blue-4); font-size:17px; }
.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; }
.profile-nav { position:relative; }
.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; }
.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); }
main.page-shell { padding:22px 0 30px; }
.breadcrumb { display:flex; align-items:center; gap:9px; flex-wrap:wrap; margin-bottom:14px; color:#34679f; font-size:13px; font-weight:800; }
.breadcrumb strong { color:#0d5db8; }
.crumb-sep { opacity:.55; }
.hero-card, .panel-card, .side-card, .tabs-card, .table-card, .note-card, .detail-card { background:rgba(255,255,255,.92); border:1px solid rgba(17,79,149,.08); border-radius:26px; box-shadow:var(--shadow-soft); }
.hero-card { padding:20px 22px; margin-bottom:18px; }
.hero-title { margin:0 0 10px; font-size:22px; line-height:1.1; color:#0d5db8; }
.hero-text { margin:0; font-size:15px; line-height:1.65; max-width:940px; }
.subnav-note { margin-top:14px; padding-top:14px; border-top:1px solid rgba(17,79,149,.10); display:flex; gap:10px; flex-wrap:wrap; }
.subnav-pill { display:inline-flex; align-items:center; min-height:34px; padding:0 14px; border-radius:999px; background:#eef6ff; color:#1b5ca0; font-size:13px; font-weight:900; }
.subnav-pill.active { background:#174f90; color:#fff; }
.selection-grid { display:grid; grid-template-columns:minmax(0, 1.2fr) minmax(280px, .8fr); gap:18px; align-items:start; }
.panel-card { padding:18px 20px; min-width:0; overflow:hidden; }
.panel-head { display:flex; justify-content:space-between; gap:14px; align-items:flex-start; margin-bottom:14px; }
.panel-title { margin:0; font-size:19px; color:#0d5db8; }
.panel-copy { margin:6px 0 0; font-size:13px; line-height:1.5; color:#6280a3; }
.toolbar { display:flex; gap:10px; flex-wrap:wrap; align-items:center; }
.search-input, .mini-input, .mini-select, .text-input { width:100%; border:1px solid rgba(17,79,149,.14); background:rgba(255,255,255,.98); border-radius:16px; padding:13px 14px; font:inherit; color:#134f92; box-shadow:inset 0 1px 0 rgba(255,255,255,.8); }
.toolbar .search-wrap { flex:1 1 240px; min-width:220px; }
.toolbar .mini-select { width:auto; min-width:180px; }
.overview-list { display:grid; gap:10px; max-height:420px; overflow:auto; padding-right:6px; }
.overview-item { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:14px; align-items:center; padding:14px 15px; border:1px solid rgba(132,186,236,.35); background:linear-gradient(180deg, rgba(246,250,255,.96), rgba(235,244,255,.92)); border-radius:20px; min-width:0; }
.overview-main { min-width:0; }
.overview-head { display:flex; gap:12px; align-items:center; min-width:0; }
.cat-icon { width:44px; height:44px; border-radius:14px; display:grid; place-items:center; color:#fff; font-weight:900; font-size:18px; flex:0 0 44px; }
.cat-copy { min-width:0; }
.cat-copy strong { display:block; font-size:15px; color:#0d5db8; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cat-copy span { display:block; margin-top:4px; font-size:13px; color:#5a7ea6; line-height:1.45; }
.meta-row { display:flex; flex-wrap:wrap; gap:8px; margin-top:10px; }
.tag { display:inline-flex; align-items:center; min-height:26px; padding:0 10px; border-radius:999px; font-size:11px; font-weight:900; }
.tag.blue { background:#dceeff; color:#216ab9; } .tag.green { background:#e3f7ea; color:#23804a; } .tag.orange { background:#fff0d8; color:#c27209; } .tag.grey { background:#edf3f8; color:#6a84a2; }
.btn { border:0; border-radius:15px; min-height:44px; padding:0 16px; font:inherit; font-size:14px; font-weight:900; cursor:pointer; box-shadow:var(--shadow-soft); }
.btn-primary { background:linear-gradient(180deg, #ffbc4b, #ff9621); color:#fff; }
.btn-secondary { background:linear-gradient(180deg, #eef6ff, #dcecff); color:#0d5db8; }
.btn-danger { background:linear-gradient(180deg,#ef6b6b,#cf3e3e); color:#fff; }
.btn-ghost { background:#fff; color:#0d5db8; border:1px solid rgba(17,79,149,.14); box-shadow:none; }
.readonly-grid { display:grid; gap:0px; }
.readonly-row { display:grid; grid-template-columns:1fr auto; gap:10px; align-items:start; padding:10px 0; border-top:1px solid rgba(17,79,149,.08); }
.readonly-row:first-child { border-top:0; padding-top:0; }
.readonly-row span { color:#6381a4; font-size:13px; }
.readonly-row strong { color:#184f90; font-size:14px; text-align:right; }
.quick-history { margin-top:14px; padding-top:14px; border-top:1px solid rgba(17,79,149,.10); max-height:320px; overflow:auto; padding-right:6px; }
.quick-history h3 { margin:0 0 10px; font-size:15px; color:#0d5db8; }
.history-mini-item { padding:10px 12px; border-radius:16px; background:#f7fbff; border:1px solid rgba(17,79,149,.08); margin-bottom:8px; }
.history-mini-item:last-child { margin-bottom:0; }
.history-mini-item strong { display:block; font-size:13px; color:#184f90; }
.history-mini-item span { display:block; margin-top:4px; font-size:12px; color:#6381a4; line-height:1.45; }
.manage-stage { display:none; margin-top:18px; }
.manage-stage.open { display:block; }
.manage-head { display:flex; justify-content:space-between; align-items:center; gap:16px; margin-bottom:14px; }
.top-summary { display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:12px; margin-top:14px; }
.summary-box { border:1px solid #d5e5f7; background:#f8fbff; border-radius:24px; padding:8px 15px; }
.summary-box strong { display:block; color:#1a4f8f; font-size:19px; margin-bottom:8px; }
.summary-box span { color:#5f80a8; font-size:12px; line-height:1.55; display:block; }
.top-summary-two { grid-template-columns:repeat(2, minmax(0,1fr)); }
.meta-card-list { display:grid; grid-template-columns:1fr; gap:12px; margin-top:12px; }
.meta-card {
border:1px solid #d5e5f7; background:#f8fbff; border-radius:24px; padding:8px 15px;
display:grid; gap:4px; align-items:start;
}
.meta-card strong { color:#5374a0; font-size:13px; display:block; }
.meta-card span { color:#1a4f8f; font-size:14px; line-height:1.45; display:block; }
.tabs-card { padding:16px 18px 20px; }
.tab-row { display:flex; align-items:flex-end; gap:6px; flex-wrap:wrap; margin:0px; }
.tab-btn {
border:1px solid rgba(140,197,242,1); border-bottom:0; border-radius:18px 18px 0 0;
background:linear-gradient(180deg, rgba(255,255,255,.94), rgba(245,250,255,.96));
color:#235b99; font-weight:900; font-size:13px; padding:0 20px; min-height:25px;
display:inline-flex; align-items:center; justify-content:center; cursor:pointer; box-shadow:0 -3px 12px rgba(35,100,177,.05);
}
.tab-btn.active { background:linear-gradient(180deg,#4ea5ff,#1f79dc); color:#fff; border-color:#2f88ea; }
.tab-pane {
display:none; background:linear-gradient(180deg, rgba(255,255,255,.94), rgba(245,250,255,.96));
border:1px solid rgb(140 197 242); border-radius:0 24px 24px 24px; padding:18px; box-shadow:var(--shadow-soft); min-height:560px;
}
.tab-pane.active { display:block; }
.tab-layout { display:grid; grid-template-columns:minmax(0,1fr) 320px; gap:18px; align-items:start; }
.intro-box, .form-card, .history-card, .target-card { padding:18px 20px; border-radius:24px; background:#fff; border:1px solid rgba(17,79,149,.08); box-shadow:var(--shadow-soft); }
.target-card { height:520px; display:flex; flex-direction:column; }
.intro-box h3, .form-card h3, .history-card h3, .target-card h3 { margin:0 0 10px; font-size:18px; color:#0d5db8; }
.intro-box p, .form-card p, .history-card p, .target-card p { margin:0; font-size:14px; line-height:1.6; color:#5f7ea5; }
.info-list { display:grid; gap:10px; margin-top:14px; }
.info-item { padding:12px 14px; border-radius:16px; background:#f7fbff; border:1px solid rgba(17,79,149,.08); }
.info-item strong { display:block; color:#184f90; font-size:14px; margin-bottom:4px; }
.info-item span { color:#6381a4; font-size:13px; line-height:1.5; }
.form-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:16px; }
.field, .field-full { display:grid; gap:8px; }
.field-full { grid-column:1 / -1; }
label { font-size:13px; font-weight:900; color:#235790; }
.picker-grid { display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:10px; }
.picker-item { border:1px solid rgba(17,79,149,.12); border-radius:16px; padding:12px 10px; text-align:center; background:#fff; font-size:13px; font-weight:800; color:#20538d; }
.picker-item .swatch { width:30px; height:30px; border-radius:10px; margin:0 auto 8px; }
.inline-note { margin-top:10px; padding:12px 14px; border-radius:16px; background:#fef5e8; border:1px solid rgba(248,116,0,.16); color:#7b5c22; font-size:13px; line-height:1.5; }
.readonly-display { min-height:50px; border:1px solid rgba(17,79,149,.12); border-radius:16px; padding:12px 14px; background:#f5f9ff; display:flex; align-items:center; }
.status-stats { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:12px; margin-top:16px; }
.status-stat { padding:10px 14px; border-radius:18px; border:1px solid rgba(246,170,7,.28); background:linear-gradient(180deg, #fff8df, #ffeeb7); }
.status-stat.good { border-color:rgba(87,186,60,.24); background:linear-gradient(180deg, #eefae9, #dff4d7); }
.status-stat strong { display:block; color:#8a6400; font-size:18px; margin-bottom:4px; }
.status-stat.good strong { color:#246a39; }
.status-stat span { color:#7a6230; font-size:12px; line-height:1.45; display:block; }
.status-stat.good span { color:#3f7b52; }
.actions-row { display:flex; justify-content:space-between; flex-wrap:wrap; margin-top:15px; padding-top:15px; border-top:1px solid rgba(17,79,149,.10); }
.target-layout { display:grid; grid-template-columns:minmax(0, 1fr) 320px; gap:18px; align-items:stretch; }
.target-list-card { height:520px; display:flex; flex-direction:column; }
.target-list { display:block; max-height:none; overflow:auto; padding-right:6px; flex:1 1 auto; }
.target-detail-card { height:520px; display:flex; flex-direction:column; }
.target-item { margin-bottom:10px; }
.target-copy { display:grid; gap:6px; }
.target-copy .target-tags { display:flex; flex-wrap:wrap; gap:8px; align-items:center; }
.target-tags { display:inline-flex; flex-wrap:wrap; gap:8px; align-items:center; }
.mini-tag { display:inline-flex; align-items:center; min-height:24px; padding:0 10px; border-radius:999px; background:#eef5fd; color:#1b5ca0; font-size:11px; font-weight:800; }
.target-item:last-child { margin-bottom:0; }
.target-item { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:12px; align-items:center; padding:12px 14px; border-radius:18px; background:#f8fbff; border:1px solid #dbe8f7; }
.target-item.active { border-color:#5e93d9; box-shadow:0 0 0 3px rgba(88,139,212,.12); background:linear-gradient(180deg,#ffffff 0%,#f3f8fe 100%); }
.target-copy strong { display:block; color:#1c4f8b; font-size:15px; }
.target-copy > span { display:block; color:#607fa6; font-size:13px; margin-top:4px; }
.warning-box { margin-top:14px; padding:14px 16px; border-radius:16px; background:rgba(255,187,77,.18); border:1px solid rgba(246,170,7,.22); color:#6c561a; font-size:13px; line-height:1.55; }
.history-card { height: 520px; display:flex; flex-direction:column; }
.target-card .readonly-grid { margin-top:8px; }
.history-scroll { margin-top:16px; overflow:auto; flex:1 1 auto; }
.history-table { width:100%; border-collapse:separate; border-spacing:0 10px; }
.history-table th { text-align:left; font-size:12px; text-transform:uppercase; letter-spacing:.04em; color:#6a84a2; padding:0 12px 2px; position:sticky; top:0; background:linear-gradient(180deg, rgba(255,255,255,.98), rgba(245,250,255,.98)); z-index:2; }
.history-table td { background:#f8fbff; border-top:1px solid #dce9f8; border-bottom:1px solid #dce9f8; padding:12px; font-size:13px; color:#184f90; vertical-align:top; }
.history-table td:first-child { border-left:1px solid #dce9f8; border-radius:14px 0 0 14px; }
.history-table td:last-child { border-right:1px solid #dce9f8; border-radius:0 14px 14px 0; }
.muted { color:#6a84a2; }
.site-footer { margin-top:24px; padding:24px 0 22px; background:linear-gradient(180deg, rgba(255,255,255,.82), rgba(235,246,255,.92)); border-top:1px solid rgba(170,204,238,.62); border-radius:26px 26px 0 0; box-shadow:0 -10px 24px rgba(35,100,177,.06); }
.footer-grid { width:min(1240px, calc(100% - 30px)); margin:0 auto; display:grid; grid-template-columns:1.3fr 1fr 1fr; gap:22px; }
.footer-col h4 { margin:0 0 8px; font-size:16px; color:#0f4d91; }
.footer-col p { margin:0; color:#5e7ea6; font-size:14px; line-height:1.55; }
.footer-links { display:flex; flex-direction:column; gap:7px; }
.footer-links a { color:#2364a7; text-decoration:none; font-weight:700; font-size:14px; }
.footer-bottom { width:min(1240px, calc(100% - 30px)); margin:18px auto 0; padding-top:14px; border-top:1px solid rgba(170,204,238,.56); color:#6b86aa; font-size:13px; font-weight:700; }
.modal-overlay { position:fixed; inset:0; background:rgba(18,50,88,.34); backdrop-filter:blur(3px); display:none; align-items:center; justify-content:center; padding:24px; z-index:120; }
.modal-overlay.open { display:flex; }
.modal-card { width:min(580px, 100%); background:#fff; border-radius:24px; padding:22px; box-shadow:0 22px 44px rgba(13,56,110,.22); border:1px solid rgba(17,79,149,.1); }
.modal-head { display:flex; justify-content:space-between; gap:16px; align-items:flex-start; margin-bottom:12px; }
.modal-head h3 { margin:0; font-size:20px; color:#0d5db8; }
.modal-close { border:0; background:#eef6ff; color:#0d5db8; width:38px; height:38px; border-radius:999px; cursor:pointer; font-size:20px; font-weight:700; }
.modal-actions { display:flex; justify-content:flex-end; gap:10px; margin-top:16px; }
@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%; }
.selection-grid, .tab-layout, .target-layout { grid-template-columns:1fr; } .footer-grid { grid-template-columns:1fr; gap:24px; } .top-summary { grid-template-columns:repeat(2, minmax(0,1fr)); } .top-summary-two { grid-template-columns:repeat(2, minmax(0,1fr)); }
}
@media (max-width:760px) {
.wrap { width:min(100%, calc(100% - 18px)); } .page-content { padding:18px; } .form-grid, .picker-grid, .top-summary, .top-summary-two { grid-template-columns:1fr; } .overview-item, .target-item { grid-template-columns:1fr; } .readonly-row { grid-template-columns:1fr; } .readonly-row strong { text-align:left; }
.site-footer { padding:20px 18px 16px; } .footer-bottom { justify-content:flex-start; }
}
</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, Noor</div>
</div>
<nav class="nav-pills" aria-label="Hoofdmenu">
<div class="nav-item"><button class="pill orange">Site instellingen</button></div>
<div class="nav-item" id="contentNav">
<button class="pill blue has-chevron" id="contentMenuBtn" aria-expanded="false" aria-haspopup="true">Content <span>▾</span></button>
<div class="dropdown-menu" id="contentMenu">
<div class="menu-list">
<a class="menu-link no-arrow is-active" href="#"><span class="menu-icon blue">C</span><span>Categorieën beheren</span></a>
<a class="menu-link no-arrow" href="#"><span class="menu-icon orange">M</span><span>Modules beheren</span></a>
<a class="menu-link no-arrow" href="#"><span class="menu-icon green">D</span><span>Docent ondersteuning</span></a>
</div>
</div>
</div>
<div class="nav-item"><button class="pill green">Accounts</button></div>
</nav>
<div class="header-actions">
<button class="mail-btn" aria-label="Meldingen">✉<span class="badge">2</span></button>
<div class="profile-nav nav-item">
<button class="profile-chip" aria-haspopup="true" aria-expanded="false"><span class="avatar">N</span></button>
<div class="dropdown-menu align-right">
<div class="menu-list">
<a class="menu-link" href="#"><span class="menu-icon blue">P</span><span>Profiel</span><span class="menu-arrow">›</span></a>
<a class="menu-link" href="#"><span class="menu-icon orange">V</span><span>Voorkeuren</span><span class="menu-arrow">›</span></a>
<a class="menu-link" href="#"><span class="menu-icon green">T</span><span>Toegankelijkheid</span><span class="menu-arrow">›</span></a>
<a class="menu-link" href="#"><span class="menu-icon blue">M</span><span>Meldingen (2)</span><span class="menu-arrow">›</span></a>
<a class="menu-link" href="#"><span class="menu-icon orange">U</span><span>Uitloggen</span><span class="menu-arrow">›</span></a>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
<main class="page-shell">
<div class="wrap">
<div class="breadcrumb"><span>Home</span><span class="crumb-sep">›</span><span>Content</span><span class="crumb-sep">›</span><strong>Categorieën beheren</strong></div>
<section class="hero-card">
<h1 class="hero-title">Categorieën beheren</h1>
<p class="hero-text">Deze beheerpagina is gericht op centrale categorie-identiteit. Je selecteert eerst een categorie, bekijkt de belangrijkste readonly gegevens en opent daarna het beheer om wijzigingen, migratie of historie te bekijken. Migreren en statuswijzigingen zijn bewust gescheiden acties.</p>
</section>
<section class="selection-grid" id="selectionStage">
<div class="panel-card">
<div class="panel-head">
<div>
<h2 class="panel-title">Overzicht</h2>
<p class="panel-copy">Zoek een centrale categorie en selecteer deze om een compact overzicht te bekijken.</p>
</div>
<button class="btn btn-secondary">Nieuwe categorie</button>
</div>
<div class="toolbar" style="margin-bottom:14px;">
<div class="search-wrap"><input class="search-input" type="text" value="rekenen" aria-label="Zoek categorie"/></div>
</div>
<div class="overview-list">
<article class="overview-item">
<div class="overview-main">
<div class="overview-head">
<div class="cat-icon" style="background:linear-gradient(180deg,#5db4ff,#1c7bde);">+</div>
<div class="cat-copy"><strong>Rekenen</strong><span>Centrale categorie voor basisrekenen, sommen en bewerkingen.</span></div>
</div>
<div class="meta-row"><span class="tag blue">Actief</span><span class="tag green">12 docentenniveaus</span><span class="tag orange">46 oefenkoppelingen</span></div>
</div>
<button class="btn btn-primary open-manage">Selecteer</button>
</article>
<article class="overview-item">
<div class="overview-main">
<div class="overview-head">
<div class="cat-icon" style="background:linear-gradient(180deg,#8d6cff,#6248d8);">✎</div>
<div class="cat-copy"><strong>Taal</strong><span>Hoofdcategorie voor spelling, grammatica en taalbegrip.</span></div>
</div>
<div class="meta-row"><span class="tag blue">Actief</span><span class="tag green">9 docentenniveaus</span><span class="tag orange">31 oefenkoppelingen</span></div>
</div>
<button class="btn btn-ghost">Selecteer</button>
</article>
<article class="overview-item">
<div class="overview-main">
<div class="overview-head">
<div class="cat-icon" style="background:linear-gradient(180deg,#7ed56b,#49aa31);">🌍</div>
<div class="cat-copy"><strong>Aardrijkskunde</strong><span>Gebruikt voor topografie, kaartlezen en wereldoriëntatie.</span></div>
</div>
<div class="meta-row"><span class="tag blue">Actief</span><span class="tag green">4 docentenniveaus</span><span class="tag orange">11 oefenkoppelingen</span></div>
</div>
<button class="btn btn-ghost">Selecteer</button>
</article>
<article class="overview-item">
<div class="overview-main">
<div class="overview-head">
<div class="cat-icon" style="background:linear-gradient(180deg,#ffca59,#f08b17);">⌛</div>
<div class="cat-copy"><strong>Hoofdrekenen oud</strong><span>Historische categorie; niet meer bedoeld voor nieuwe koppelingen.</span></div>
</div>
<div class="meta-row"><span class="tag grey">Inactief</span><span class="tag green">0 actieve docentenniveaus</span><span class="tag orange">0 actieve oefenkoppelingen</span></div>
</div>
<button class="btn btn-ghost">Selecteer</button>
</article>
</div>
</div>
<aside class="panel-card">
<div class="panel-head" style="margin-bottom:10px;">
<div>
<h2 class="panel-title">Geselecteerde categorie</h2>
<p class="panel-copy">Compact readonly overzicht. Voor inhoudelijk beheer open je daarna de beheerweergave.</p>
</div>
</div>
<div class="readonly-grid">
<div class="readonly-row"><span>Naam</span><strong>Rekenen</strong></div>
<div class="readonly-row"><span>Status</span><strong>Actief</strong></div>
<div class="readonly-row"><span>Actieve docentenniveaus</span><strong>12</strong></div>
<div class="readonly-row"><span>Onderliggende oefenkoppelingen</span><strong>46</strong></div>
<div class="readonly-row"><span>Aangemaakt door</span><strong>Naomi Beheerder · 14-01-2026</strong></div>
<div class="readonly-row"><span>Laatst gewijzigd</span><strong>Tom Beheerder · 03-04-2026</strong></div>
</div>
<div class="quick-history">
<h3>Recente wijzigingen (laatste 60 dagen)</h3>
<div class="history-mini-item"><strong>Kleur aangepast</strong><span>03-04-2026 · door Tom Beheerder</span></div>
<div class="history-mini-item"><strong>Icoon aangepast</strong><span>17-03-2026 · door Naomi Beheerder</span></div>
</div>
<div class="actions-row" style="border-top:0; padding-top:16px; margin-top:6px;justify-content:center;">
<span></span>
<button class="btn btn-primary open-manage">Open beheer</button>
</div>
</aside>
</section>
<section class="manage-stage" id="manageStage">
<div class="tabs-card">
<div class="manage-head">
<h2 class="panel-title" style="margin:0;font-size:20px;color:#0f4d91;">Categoriebeheer · Rekenen</h2>
<button class="btn btn-danger manage-return" id="closeManage">Terug naar overzicht</button>
</div>
<div class="tab-row">
<button class="tab-btn active" data-tab="intro">Intro / uitleg</button>
<button class="tab-btn" data-tab="categorie">Categorie</button>
<button class="tab-btn" data-tab="migreren">Migreren naar</button>
<button class="tab-btn" data-tab="geschiedenis">Geschiedenis</button>
</div>
<div class="tab-pane active" id="tab-intro">
<div class="tab-layout">
<div class="intro-box">
<h3>Wat kun je hier doen?</h3>
<p>Gebruik deze tabs om de geselecteerde categorie te beheren. In <strong>Categorie</strong> wijzig je naam, icoon en kleur. In <strong>Migreren naar</strong> verplaats je actieve koppelingen eerst naar een andere centrale categorie. In <strong>Geschiedenis</strong> zie je alle acties op categorieniveau, inclusief migraties, kleurwijzigingen en statuswijzigingen.</p>
<div class="info-list">
<div class="info-item"><strong>Statuswijziging pas na migratie</strong><span>De optie om een categorie op inactief te zetten is alleen beschikbaar wanneer er geen actieve koppelingen meer bestaan.</span></div>
<div class="info-item"><strong>Historie blijft zichtbaar</strong><span>Alle acties blijven op categorieniveau herleidbaar. Migraties verschijnen dus als geschiedenisregels binnen deze categorie.</span></div>
<div class="info-item"><strong>Docenten ontvangen systeembericht</strong><span>Bij een migratie worden betrokken docenten aan de bronkant geïnformeerd via een systeembericht.</span></div>
</div>
</div>
<aside class="side-card" style="padding:18px 20px;">
<h2 class="panel-title" style="font-size:18px;">Gebruik & impact</h2>
<div class="top-summary top-summary-two">
<div class="summary-box"><strong>12</strong><span>Actieve docentenniveaus</span></div>
<div class="summary-box"><strong>46</strong><span>Onderliggende oefenkoppelingen</span></div>
</div>
<div class="meta-card-list">
<div class="meta-card"><strong>Aangemaakt</strong><span>14-01-2026 · Naomi Beheerder</span></div>
<div class="meta-card"><strong>Laatst gewijzigd</strong><span>03-04-2026 · Tom Beheerder</span></div>
</div>
</aside>
</div>
</div>
<div class="tab-pane" id="tab-categorie">
<div class="tab-layout">
<div class="form-card">
<h3>Categorie bewerken</h3>
<p>Deze opzet volgt de bekende categorie-inrichting. Een beheerder kan hier naam, icoon en kleur bijwerken. Statuswijziging blijft een aparte beheermogelijkheid met extra restrictie.</p>
<div class="form-grid" style="margin-top:16px;">
<div class="field"><label>Naam categorie</label><input class="text-input" type="text" value="Rekenen"/></div>
<div class="field"><label>Huidige status</label><span class="tag blue">Actief</span></div>
<div class="field-full">
<label>Icoon</label>
<div class="picker-grid">
<div class="picker-item">+<div class="muted">Geselecteerd</div></div>
<div class="picker-item">✎<div class="muted">Taal</div></div>
<div class="picker-item">🌍<div class="muted">Wereld</div></div>
<div class="picker-item">⌛<div class="muted">Historie</div></div>
</div>
</div>
<div class="field-full">
<label>Kleur</label>
<div class="picker-grid">
<div class="picker-item"><div class="swatch" style="background:#1f82e9;"></div>Blauw</div>
<div class="picker-item"><div class="swatch" style="background:#8d6cff;"></div>Paars</div>
<div class="picker-item"><div class="swatch" style="background:#57ba3c;"></div>Groen</div>
<div class="picker-item"><div class="swatch" style="background:#ff9620;"></div>Oranje</div>
</div>
</div>
</div>
<div class="actions-row">
<button class="btn btn-secondary" id="openStatusModal">Status wijzigen</button>
<button class="btn btn-primary" id="openSaveModal">Opslaan</button>
</div>
</div>
<aside class="side-card" style="padding:18px 20px;">
<h2 class="panel-title" style="font-size:18px;">Gebruik & impact</h2>
<div class="status-stats">
<div class="status-stat"><strong>12</strong><span>Actieve docentenniveaus aanwezig</span></div>
<div class="status-stat"><strong>46</strong><span>Actieve oefenkoppelingen aanwezig</span></div>
</div>
<div class="inline-note">De knop om deze categorie op <strong>inactief</strong> te zetten wordt pas beschikbaar wanneer beide waarden <strong>0</strong> zijn. De verwachte volgorde is dus: <strong>eerst migreren, daarna status wijzigen</strong>.</div>
</aside>
</div>
</div>
<div class="tab-pane" id="tab-migreren">
<div class="target-layout">
<div class="form-card target-list-card">
<h3>Migreren naar andere actieve categorie</h3>
<p>De broncategorie staat al vast: <strong>Rekenen</strong>. Zoek hieronder een actieve doelcategorie. Pas na selectie worden de belangrijkste details getoond en kan de migratieactie worden gestart.</p>
<div style="margin:16px 0 14px;"><input class="search-input" type="text" value="hoofd" aria-label="Zoek doelcategorie"/></div>
<div class="target-list">
<div class="target-item active">
<div class="target-copy"><strong>Hoofdrekenen</strong><div class="target-tags"><span class="tag green">8 docentenniveaus</span><span class="tag orange">29 oefenkoppelingen</span></div></div>
<button class="btn btn-ghost">Selecteer</button>
</div>
<div class="target-item">
<div class="target-copy"><strong>Basisvaardigheden rekenen</strong><span class="target-tags"><span class="tag green">12 docentenniveaus</span><span class="tag orange">46 oefenkoppelingen</span></span></div>
<button class="btn btn-ghost">Selecteer</button>
</div>
<div class="target-item">
<div class="target-copy"><strong>Sommen & bewerkingen</strong><span class="target-tags"><span class="tag green">9 docentenniveaus</span><span class="tag orange">31 oefenkoppelingen</span></span></div>
<button class="btn btn-ghost">Selecteer</button>
</div>
</div>
</div>
<aside class="target-card">
<h3>Geselecteerde doelcategorie</h3>
<div class="readonly-grid" style="margin-top:8px;">
<div class="readonly-row"><span>Naam</span><strong>Hoofdrekenen</strong></div>
<div class="readonly-row"><span>Actieve docentenniveaus</span><strong>8</strong></div>
<div class="readonly-row"><span>Onderliggende oefenkoppelingen</span><strong>29</strong></div>
<div class="readonly-row"><span>Aangemaakt</span><strong>Kim Beheerder · 09-12-2025</strong></div>
<div class="readonly-row"><span>Laatst gewijzigd</span><strong>Naomi Beheerder · 26-03-2026</strong></div>
</div>
<div class="warning-box">Betrokken docenten aan de <strong>bronkant</strong> ontvangen na de migratie een systeembericht. Historische runs blijven historisch herleidbaar.</div>
<div class="actions-row">
<span></span>
<button class="btn btn-primary" id="openMigrateModal">Migreer Rekenen naar Hoofdrekenen</button>
</div>
</aside>
</div>
</div>
<div class="tab-pane" id="tab-geschiedenis">
<div class="history-card">
<h3>Geschiedenis van deze categorie</h3>
<p>Alle acties worden op categorieniveau gelogd. Migraties verschijnen dus als gewone geschiedenisregels binnen deze categorie, naast bewerkingen van naam, kleur, icoon en status.</p>
<div class="history-scroll">
<table class="history-table">
<thead>
<tr><th>Datum</th><th>Actie</th><th>Details</th><th>Door</th><th>Reden</th></tr>
</thead>
<tbody>
<tr><td>03-04-2026 14:22</td><td>Kleur aangepast</td><td>Van #2F88EA naar #1F82E9</td><td>Tom Beheerder</td><td>Visuele afstemming op actieve contentkleur</td></tr>
<tr><td>17-03-2026 09:11</td><td>Icoon aangepast</td><td>Van ÷ naar +</td><td>Naomi Beheerder</td><td>Beter herkenbaar voor leerlingen</td></tr>
<tr><td>10-02-2026 16:42</td><td>Migratie uitgevoerd</td><td>3 historische koppelingen overgezet vanuit Rekenen oud naar Rekenen</td><td>Kim Beheerder</td><td>Opschonen dubbele centrale categorie</td></tr>
<tr><td>14-01-2026 11:08</td><td>Aangemaakt</td><td>Categorie aangemaakt als centrale contentcategorie</td><td>Naomi Beheerder</td><td>Initiële contentinrichting</td></tr>
<tr><td>11-01-2026 09:17</td><td>Naam gecontroleerd</td><td>Geen wijziging doorgevoerd na review van centrale inhoud</td><td>Tom Beheerder</td><td>Controle op duplicaatmelding</td></tr>
<tr><td>08-01-2026 13:05</td><td>Kleurvoorstel beoordeeld</td><td>Voorkeurskleur behouden op basis van bestaande herkenbaarheid</td><td>Kim Beheerder</td><td>Afstemming met ontwerp</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
</div>
</div>
</main>
<footer class="site-footer">
<div class="footer-grid">
<div class="footer-col"><h4>OefenHub Beheer</h4><p>Beheer centrale categorieën en migraties vanuit één overzichtelijke omgeving.</p></div>
<div class="footer-col"><h4>Snelle toegang</h4><div class="footer-links"><a href="#">Content</a><a href="#">Site instellingen</a><a href="#">Accounts</a></div></div>
<div class="footer-col"><h4>Ondersteuning</h4><div class="footer-links"><a href="#">Privacybeleid</a><a href="#">Contact</a><a href="#">Uitloggen</a></div></div>
</div>
<div class="footer-bottom">© 2026 OefenHub</div>
</footer>
<div class="modal-overlay" id="saveModal">
<div class="modal-card">
<div class="modal-head"><h3>Wijzigingen opslaan</h3><button class="modal-close" data-close="saveModal">×</button></div>
<p>Weet je zeker dat je de wijzigingen voor <strong>Rekenen</strong> wilt doorvoeren? Geef hieronder de reden van wijziging op.</p>
<label>Reden van wijziging</label>
<textarea class="text-input" style="min-height:120px; margin-top:8px;">Visuele en tekstuele aanscherping van de categorie.</textarea>
<div class="modal-actions"><button class="btn btn-secondary" data-close="saveModal">Annuleren</button><button class="btn btn-primary" data-close="saveModal">Bevestig opslaan</button></div>
</div>
</div>
<div class="modal-overlay" id="migrateModal">
<div class="modal-card">
<div class="modal-head"><h3>Categorie migreren</h3><button class="modal-close" data-close="migrateModal">×</button></div>
<p>Weet je zeker dat je <strong>Rekenen</strong> wilt migreren naar <strong>Hoofdrekenen</strong>? Betrokken docenten aan de bronkant ontvangen hierover een systeembericht.</p>
<label>Reden van migratie</label>
<textarea class="text-input" style="min-height:120px; margin-top:8px;">Dubbele centrale categorie samenvoegen naar eenduidige actieve categorie.</textarea>
<div class="modal-actions"><button class="btn btn-secondary" data-close="migrateModal">Annuleren</button><button class="btn btn-primary" data-close="migrateModal">Bevestig migratie</button></div>
</div>
</div>
<div class="modal-overlay" id="statusModal">
<div class="modal-card">
<div class="modal-head"><h3>Status wijzigen niet beschikbaar</h3><button class="modal-close" data-close="statusModal">×</button></div>
<p>Deze categorie heeft nog actieve koppelingen. Migreer eerst alle actieve docentenniveaus en oefenkoppelingen weg voordat je de status naar <strong>inactief</strong> kunt wijzigen.</p>
<div class="modal-actions"><button class="btn btn-primary" data-close="statusModal">Sluiten</button></div>
</div>
</div>
<script>
const contentNav = document.getElementById('contentNav');
const contentBtn = document.getElementById('contentMenuBtn');
contentBtn.addEventListener('click', (e) => { e.stopPropagation(); contentNav.classList.toggle('open'); contentBtn.setAttribute('aria-expanded', contentNav.classList.contains('open')); });
document.addEventListener('click', (e) => { if (!contentNav.contains(e.target)) { contentNav.classList.remove('open'); contentBtn.setAttribute('aria-expanded', 'false'); } });
const selectionStage = document.getElementById('selectionStage');
const manageStage = document.getElementById('manageStage');
document.querySelectorAll('.open-manage').forEach(btn => btn.addEventListener('click', () => { selectionStage.style.display='none'; manageStage.classList.add('open'); }));
document.getElementById('closeManage').addEventListener('click', () => { manageStage.classList.remove('open'); selectionStage.style.display='grid'; window.scrollTo({top:0, behavior:'smooth'}); });
const tabButtons = document.querySelectorAll('.tab-btn');
const tabPanes = document.querySelectorAll('.tab-pane');
tabButtons.forEach(btn => btn.addEventListener('click', () => {
tabButtons.forEach(b => b.classList.remove('active')); tabPanes.forEach(p => p.classList.remove('active'));
btn.classList.add('active'); document.getElementById('tab-' + btn.dataset.tab).classList.add('active');
}));
const openModal = id => document.getElementById(id).classList.add('open');
const closeModal = id => document.getElementById(id).classList.remove('open');
document.getElementById('openSaveModal').addEventListener('click', () => openModal('saveModal'));
document.getElementById('openMigrateModal').addEventListener('click', () => openModal('migrateModal'));
document.getElementById('openStatusModal').addEventListener('click', () => openModal('statusModal'));
document.querySelectorAll('[data-close]').forEach(btn => btn.addEventListener('click', () => closeModal(btn.dataset.close)));
document.querySelectorAll('.modal-overlay').forEach(overlay => overlay.addEventListener('click', e => { if (e.target === overlay) overlay.classList.remove('open'); }));
</script>
</body>
</html @media (max-width: 760px) {
.tab-layout { grid-template-columns:1fr; }
.top-summary-two { grid-template-columns:1fr; }
}
>