oefenhub_leerling_08_gedeelde_oefening_overzicht_v1_4.html
Korte beschrijving
Deze mockup toont het profielonderdeel Gedeelde oefeningen voor ontvangen oefeningen van vrienden.
De pagina is alleen relevant wanneer de leerling gedeelde oefeningen heeft ontvangen en biedt acties om te starten, hervatten, opnieuw te maken, geschiedenis te bekijken of te verwijderen. Gedeelde oefeningen blijven gebaseerd op een historische momentopname van de gedeelde bronrun.
Gerelateerde documentatie
- Bekijk de schermdocumentatie voor meer functionele context.
Bestand
Broncode
/mockups_html/leerling/oefenhub_leerling_08_gedeelde_oefening_overzicht_v1_4.html
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OefenHub - Gedeelde oefeningen</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-2: #57ba3c;
--green-3: #2c9348;
--red-text: #b74d4d;
--shadow: 0 12px 28px rgba(35, 100, 177, 0.12);
--shadow-soft: 0 8px 18px rgba(35, 100, 177, 0.08);
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
min-height: 100vh;
overflow-x: hidden;
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%);
}
.wrap {
width: min(1220px, 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: 30;
}
.header-row {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 16px;
}
.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: 10px;
flex-wrap: nowrap;
white-space: nowrap;
}
.nav-item { position: relative; display: inline-flex; align-items: center; }
.pill {
border: 0;
border-radius: 14px;
padding: 10px 16px;
color: #fff;
font-size: 14px;
font-weight: 900;
box-shadow: var(--shadow-soft);
line-height: 1;
cursor: pointer;
flex: 0 0 auto;
transition: transform .18s ease, filter .18s ease;
}
.pill.orange { background: linear-gradient(180deg, #ffbb4d, #ff7f12); }
.pill.blue { background: linear-gradient(180deg, #2f88ea, #176acc); }
.pill.yellow { background: linear-gradient(180deg, #ffd04d, #f4ab08); }
.pill.green { background: linear-gradient(180deg, #8adf67, #58ba3d); }
.pill.has-chevron { display: inline-flex; align-items: center; gap: 6px; padding-right: 14px; }
.pill-caret { font-size: 12px; line-height: 1; transform: translateY(1px); }
.pill:hover { filter: brightness(1.06); transform: translateY(-1px); }
.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; }
.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, .menu-link.is-active { background: linear-gradient(180deg, #edf5ff, #dcecff); }
.menu-link:hover { 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: 0 6px 12px rgba(35,100,177,.12);
}
.menu-icon.green { background: linear-gradient(180deg, #89da69, #59bb3e); }
.menu-icon.blue { background: linear-gradient(180deg, #67baf4, #2f88ea); }
.menu-icon.yellow { background: linear-gradient(180deg, #ffd45e, #f4ac10); color: #8a5d00; }
.menu-icon.purple { background: linear-gradient(180deg, #9c7af2, #6b49dd); }
.menu-icon.red { background: linear-gradient(180deg, #ff9a9a, #ea6767); }
.menu-arrow { color: #0d5db8; font-size: 24px; line-height: 1; }
.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;
transition: transform .18s ease, background .18s ease;
}
.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-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);
}
.mail-btn:hover,
.profile-chip:hover {
background: linear-gradient(180deg, #ffffff, #e4f1ff);
transform: translateY(-1px);
}
main.wrap { padding: 22px 0 42px; }
.breadcrumb-bar {
display: flex;
align-items: center;
gap: 8px;
margin: 0 0 12px;
color: rgba(17,79,149,.72);
font-size: 13px;
font-weight: 700;
}
.breadcrumb-bar a { color: rgba(17,79,149,.78); text-decoration: none; }
.breadcrumb-bar a:hover { color: var(--blue-4); text-decoration: underline; }
.breadcrumb-bar span { color: rgba(17,79,149,.45); font-weight: 900; }
.breadcrumb-bar strong { color: var(--blue-4); }
.shared-layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 320px;
gap: 18px;
align-items: start;
}
.shared-intro-card,
.shared-side-card,
.shared-table-card {
background: linear-gradient(180deg, rgba(255,255,255,.96), rgba(243,249,255,.96));
border: 1px solid rgba(170,204,238,.62);
border-radius: 26px;
box-shadow: var(--shadow);
min-width: 0;
}
.shared-intro-card { padding: 18px 22px 20px; }
.shared-side-card { padding: 18px 18px 16px; }
.shared-table-card { grid-column: 1 / -1; padding: 18px 20px; }
.shared-title {
margin: 0 0 8px;
font-size: 22px;
line-height: 1.12;
color: #0d5db8;
font-weight: 900;
}
.shared-intro {
margin: 0;
color: #18599e;
font-size: 14px;
line-height: 1.55;
max-width: 860px;
}
.shared-intro strong { color: #114f95; }
.shared-side-top {
display: flex;
justify-content: space-between;
gap: 12px;
align-items: center;
margin-bottom: 12px;
}
.side-card-title {
margin: 0;
font-size: 18px;
color: #0d5db8;
font-weight: 900;
}
.side-toggle {
display: none;
width: 34px;
height: 34px;
border-radius: 12px;
border: 1px solid rgba(17,79,149,.12);
background: rgba(255,255,255,.92);
color: var(--text);
cursor: pointer;
box-shadow: var(--shadow-soft);
place-items: center;
}
.side-toggle svg { width: 18px; height: 18px; transition: transform .18s ease; }
.shared-side-card.is-collapsed .side-toggle svg { transform: rotate(-90deg); }
.shared-side-body { display: grid; gap: 14px; }
.shared-side-card.is-collapsed .shared-side-body { display: none; }
.summary-list { display: grid; gap: 5px; }
.summary-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
font-size: 14px;
color: #285d96;
}
.summary-row:first-child { border-top: 0; padding-top: 0; }
.summary-row strong { color: #0d5db8; text-align: right; }
.compact-list { display: grid; gap: 10px; }
.compact-row { padding: 12px 14px; border-radius: 16px; background: #f6fbff; border: 1px solid rgba(170,204,238,.48); }
.compact-row strong { display: block; margin-bottom: 4px; color: #0d5db8; }
.compact-row span { display: block; color: #5977a6; font-size: 13px; line-height: 1.45; }
.shared-filter-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 12px;
margin-bottom: 14px;
}
.filter-field label {
display: block;
margin-bottom: 6px;
font-size: 12px;
font-weight: 900;
color: #235790;
}
.filter-field select {
width: 100%;
height: 38px;
border-radius: 13px;
border: 1px solid rgba(170,204,238,.82);
padding: 0 11px;
font: inherit;
font-size: 13px;
color: var(--text);
background: linear-gradient(180deg, #ffffff, #f6fbff);
box-shadow: inset 0 1px 0 rgba(255,255,255,.8);
}
.shared-table-shell {
width: 100%;
max-width: 100%;
border: 1px solid rgba(170,204,238,.72);
border-radius: 20px;
overflow: hidden;
background: rgba(255,255,255,.98);
box-shadow: var(--shadow-soft);
}
.shared-table-wrap {
width: 100%;
max-width: 100%;
max-height: 560px;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.shared-table {
width: 100%;
min-width: 1050px;
border-collapse: separate;
border-spacing: 0;
}
.shared-table thead th {
position: sticky;
top: 0;
z-index: 2;
text-align: left;
padding: 12px 14px;
font-size: 12px;
color: #355f9d;
font-weight: 900;
background: linear-gradient(180deg, rgba(242,247,255,.98), rgba(232,241,255,.98));
border-bottom: 1px solid rgba(171,195,233,.95);
white-space: nowrap;
}
.shared-table tbody td {
padding: 11px 14px;
font-size: 14px;
color: #214b8d;
border-bottom: 1px solid rgba(180,201,235,.65);
background: rgba(255,255,255,.96);
white-space: nowrap;
vertical-align: middle;
}
.shared-table tbody tr:last-child td { border-bottom: 0; }
.shared-table tbody tr { cursor: pointer; transition: background .16s ease; }
.shared-table tbody tr:hover td { background: rgba(236,245,255,.98); }
.sort-arrows {
display: inline-flex;
margin-left: 6px;
font-size: 10px;
letter-spacing: -1px;
color: #5c7ea7;
vertical-align: middle;
}
.status-pill {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 118px;
padding: 6px 10px;
border-radius: 999px;
font-size: 11px;
font-weight: 900;
text-transform: uppercase;
letter-spacing: .03em;
}
.status-pill.new { background: #e8f4ff; color: #0d5db8; }
.status-pill.started { background: #fff4dc; color: #9f6700; }
.status-pill.done { background: #e8f7ea; color: #287646; }
.table-actions {
display: flex;
align-items: center;
gap: 10px;
}
.icon-btn {
width: 30px;
height: 30px;
border-radius: 10px;
border: 1px solid rgba(17,79,149,.12);
background: linear-gradient(180deg, #fff, #eef6ff);
display: inline-flex;
align-items: center;
justify-content: center;
color: #18518f;
box-shadow: var(--shadow-soft);
cursor: pointer;
text-decoration: none;
transition: transform .16s ease, box-shadow .16s ease, background .16s ease;
}
.icon-btn:hover { transform: translateY(-1px); box-shadow: 0 10px 18px rgba(35,100,177,.14); background: linear-gradient(180deg, #ffffff, #e6f1ff); }
.icon-btn svg { width: 16px; height: 16px; stroke: currentColor; }
.icon-btn.play { color: #0d5db8; }
.icon-btn.delete { color: #cf4b4b; background: linear-gradient(180deg, #fff, #fff5f5); border-color: rgba(207,75,75,.18); }
.icon-btn.delete:hover { background: linear-gradient(180deg, #fff, #ffecec); }
.icon-btn.is-disabled { color: #9bb2cf; background: linear-gradient(180deg, #f5f8fc, #eef3f9); cursor: not-allowed; box-shadow: none; }
.icon-btn.is-disabled:hover { transform: none; box-shadow: none; background: linear-gradient(180deg, #f5f8fc, #eef3f9); }
.snapshot-text {
margin: 12px 0 0;
color: #5977a6;
font-size: 13px;
line-height: 1.45;
}
.shared-modal-backdrop {
position: fixed;
inset: 0;
background: rgba(10,45,86,.28);
display: none;
align-items: center;
justify-content: center;
padding: 20px;
z-index: 200;
}
.shared-modal-backdrop.is-open { display: flex; }
.shared-modal {
width: min(560px, 100%);
background: linear-gradient(180deg, rgba(255,255,255,.98), rgba(244,250,255,.99));
border: 1px solid rgba(170,204,238,.62);
border-radius: 24px;
box-shadow: 0 18px 34px rgba(17,79,149,.18);
padding: 22px;
}
.shared-modal h3 { margin: 0 0 10px; font-size: 20px; color: #0d5db8; }
.shared-modal p { margin: 0 0 14px; line-height: 1.6; color: #285d96; }
.switch-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 14px 0 16px; padding: 12px 14px; border-radius: 14px; background: #f7fbff; border: 1px solid rgba(170,204,238,.48); }
.mini-switch {
position: relative;
width: 58px;
height: 32px;
border: none;
padding: 0;
border-radius: 999px;
background: #d9e7f7;
cursor: pointer;
box-shadow: inset 0 1px 2px rgba(0,0,0,.08);
}
.mini-switch .knob { position: absolute; top: 4px; left: 4px; width: 24px; height: 24px; border-radius: 50%; background: #fff; box-shadow: 0 4px 10px rgba(0,0,0,.15); transition: left .18s ease; }
.mini-switch.is-random { background: linear-gradient(180deg, #8adf67, #57ba3c); }
.mini-switch.is-random .knob { left: 30px; }
.switch-state { font-size: 13px; font-weight: 800; color: #0d5db8; }
.shared-modal-actions {
display: flex;
justify-content: space-between;
gap: 10px;
margin-top: 18px;
}
.modal-btn {
border: 0;
border-radius: 12px;
padding: 11px 16px;
font-weight: 900;
cursor: pointer;
box-shadow: var(--shadow-soft);
}
.modal-btn.secondary { background: linear-gradient(180deg, #fff, #eef6ff); color: #18518f; }
.modal-btn.primary { background: linear-gradient(180deg, #2f88ea, #176acc); color: #fff; }
.site-footer {
width: 100%;
margin-top: 26px;
background: linear-gradient(180deg, rgba(255,255,255,.86), rgba(255,255,255,.96));
border-top: 1px solid rgba(17,79,149,.10);
box-shadow: var(--shadow);
border-radius: 26px 26px 0 0;
padding: 22px 0 18px;
}
.footer-grid {
display: grid;
grid-template-columns: 1.1fr 1fr 1fr;
gap: 36px;
align-items: start;
}
.footer-col h4 {
margin: 0 0 12px;
font-size: 15px;
color: #0d5db8;
font-weight: 900;
padding-bottom: 8px;
border-bottom: 1px solid rgba(17,79,149,.14);
}
.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(17,79,149,.10);
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: 1120px) {
.header-row { grid-template-columns: 1fr; justify-items: center; gap: 12px; }
.brand { align-items: center; min-width: 0; }
.welcome-text { margin-left: 0; margin-top: -6px; }
.header-actions { min-width: 0; justify-content: center; }
.nav-pills { width: 100%; overflow-x: auto; justify-content: flex-start; padding-bottom: 2px; }
.shared-layout { grid-template-columns: 1fr; }
.shared-side-card { order: 2; }
.shared-table-card { grid-column: auto; order: 3; }
.shared-filter-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.side-toggle { display: grid; }
.shared-side-card.is-collapsed .shared-side-body { display: none; }
.footer-grid { grid-template-columns: 1fr; gap: 20px; }
}
@media (min-width: 1121px) {
.shared-side-card .shared-side-body { display: grid; }
}
@media (max-width: 760px) {
.wrap { width: min(100%, calc(100% - 18px)); }
main.wrap { padding-top: 18px; }
.shared-filter-grid { grid-template-columns: 1fr; }
.shared-title { font-size: 20px; }
.shared-intro-card,
.shared-side-card,
.shared-table-card { border-radius: 22px; }
.site-footer { padding: 20px 0 16px; }
.dropdown-menu { width: min(276px, calc(100vw - 32px)); }
.dropdown-menu.align-right { right: auto; left: 0; }
.dropdown-menu.align-right::before { left: 36px; right: auto; }
.shared-modal-actions { flex-direction: column; }
.modal-btn { width: 100%; }
.switch-row { align-items: flex-start; flex-direction: column; }
}
</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, Emma</div>
</div>
<div class="nav-pills">
<div class="nav-item" data-menu="rekenen-menu-item">
<button class="pill orange has-chevron" type="button" aria-expanded="false" aria-controls="rekenen-menu">🔢 Rekenen <span class="pill-caret">▾</span></button>
<div class="dropdown-menu" id="rekenen-menu">
<div class="menu-list">
<a href="#" class="menu-link is-active"><span class="menu-icon green">+</span><span>Optellen</span><span class="menu-arrow">›</span></a>
<a href="#" class="menu-link"><span class="menu-icon blue">−</span><span>Aftrekken</span></a>
<a href="#" class="menu-link"><span class="menu-icon yellow">×</span><span>Vermenigvuldigen</span></a>
<a href="#" class="menu-link"><span class="menu-icon purple">÷</span><span>Delen</span></a>
</div>
</div>
</div>
<button class="pill blue">📖 Taal</button>
<button class="pill blue">🇬🇧 Engels</button>
<button class="pill yellow">✏️ Spelling</button>
<button class="pill green">🌍 Topografie</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">👥</span><span>Relaties</span><span class="menu-arrow">›</span></a>
<a class="menu-link no-arrow" href="#"><span class="menu-icon blue">🕘</span><span>Geschiedenis</span><span class="menu-arrow">›</span></a>
<a class="menu-link no-arrow is-active" href="#"><span class="menu-icon purple">🤝</span><span>Gedeelde oefeningen</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">
<nav class="breadcrumb-bar" aria-label="Breadcrumb">
<a href="#">Home</a>
<span>›</span>
<a href="#">Profiel</a>
<span>›</span>
<strong>Geschiedenis</strong>
</nav>
<div class="shared-layout">
<section class="shared-intro-card">
<h1 class="shared-title">Gedeelde oefeningen</h1>
<p class="shared-intro">Hier verzamel je <strong>ontvangen gedeelde oefeningen</strong>. Een systeembericht laat weten dat er een gedeelde oefening voor je klaarstaat; op deze pagina kun je hem openen, starten, hervatten of later opnieuw maken. De eerste keer doe je de oefening <strong>exact zoals gedeeld</strong>. Daarna kun je hem opnieuw maken, met dezelfde inhoud maar eventueel in een andere volgorde.</p>
</section>
<aside class="shared-side-card" id="glance-card">
<div class="shared-side-top">
<h2 class="side-card-title">In één oogopslag</h2>
<button class="side-toggle" type="button" aria-expanded="true" aria-label="Toon minder">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M6 9l6 6 6-6" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</button>
</div>
<div class="shared-side-body">
<div class="summary-list">
<div class="summary-row"><span>Nieuw ontvangen</span><strong>4 oefeningen</strong></div>
<div class="summary-row"><span>Al gestart</span><strong>2 oefeningen</strong></div>
<div class="summary-row"><span>Afgerond</span><strong>7 oefeningen</strong></div>
</div>
</div>
</aside>
<section class="shared-table-card">
<div class="shared-filter-grid">
<div class="filter-field">
<label for="statusFilter">Status</label>
<select id="statusFilter"><option selected>Alles</option><option>Nieuw ontvangen</option><option>Al gestart</option><option>Afgerond</option></select>
</div>
<div class="filter-field">
<label for="levelFilter">Niveau</label>
<select id="levelFilter"><option selected>Alle niveaus</option><option>Basisschool – Groep 7</option><option>Basisschool – Groep 8</option></select>
</div>
<div class="filter-field">
<label for="categoryFilter">Categorie</label>
<select id="categoryFilter"><option selected>Alle categorieën</option><option>Rekenen</option><option>Spelling</option><option>Topografie</option></select>
</div>
<div class="filter-field">
<label for="senderFilter">Gedeeld door</label>
<select id="senderFilter"><option selected>Iedereen</option><option>Lotte de Vries</option><option>Milan Hoekstra</option><option>Saar Vermeer</option></select>
</div>
</div>
<div class="shared-table-shell">
<div class="shared-table-wrap">
<table class="shared-table">
<thead>
<tr>
<th>Ontvangen</th>
<th>Gedeeld door <span class="sort-arrows" aria-hidden="true">↑↓</span></th>
<th>Niveau <span class="sort-arrows" aria-hidden="true">↑↓</span></th>
<th>Categorie <span class="sort-arrows" aria-hidden="true">↑↓</span></th>
<th>Subcategorie <span class="sort-arrows" aria-hidden="true">↑↓</span></th>
<th>Status <span class="sort-arrows" aria-hidden="true">↑↓</span></th>
<th>Voortgang</th>
<th>Acties</th>
</tr>
</thead>
<tbody>
<tr>
<td>24-03-2026</td><td>Lotte de Vries</td><td>Basisschool – Groep 7</td><td>Rekenen</td><td>Breuken vergelijken</td><td><span class="status-pill new">Nieuw ontvangen</span></td><td>-</td>
<td><div class="table-actions"><button type="button" class="icon-btn history is-disabled" title="Deze oefening is nog niet eerder afgerond, er is geen geschiedenis van beschikbaar." aria-label="Geen geschiedenis beschikbaar"><svg viewBox="0 0 24 24" fill="none"><path d="M12 8v5l3 2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 12a9 9 0 1 0 3-6.7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 4v4h4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button type="button" class="icon-btn play" data-play-state="first" aria-label="Start gedeelde oefening" title="Start gedeelde oefening"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 6.5v11l9-5.5-9-5.5z"/></svg></button><button type="button" class="icon-btn delete" data-delete="true" aria-label="Verwijder gedeelde oefening" title="Verwijder gedeelde oefening"><svg viewBox="0 0 24 24" fill="none"><path d="M4 7h16" stroke-width="2" stroke-linecap="round"/><path d="M10 11v6M14 11v6" stroke-width="2" stroke-linecap="round"/><path d="M6 7l1 12h10l1-12" stroke-width="2" stroke-linejoin="round"/><path d="M9 7V4h6v3" stroke-width="2" stroke-linejoin="round"/></svg></button></div></td>
</tr>
<tr>
<td>24-03-2026</td><td>Milan Hoekstra</td><td>Basisschool – Groep 7</td><td>Spelling</td><td>Werkwoordspelling</td><td><span class="status-pill started">Al gestart</span></td><td>6 van 15</td>
<td><div class="table-actions"><button type="button" class="icon-btn history is-disabled" title="Deze oefening is nog niet eerder afgerond, er is geen geschiedenis van beschikbaar." aria-label="Geen geschiedenis beschikbaar"><svg viewBox="0 0 24 24" fill="none"><path d="M12 8v5l3 2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 12a9 9 0 1 0 3-6.7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 4v4h4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button type="button" class="icon-btn play" data-play-state="resume" aria-label="Ga verder met gedeelde oefening" title="Ga verder met gedeelde oefening"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 6.5v11l9-5.5-9-5.5z"/></svg></button><button type="button" class="icon-btn delete" data-delete="true" aria-label="Verwijder gedeelde oefening" title="Verwijder gedeelde oefening"><svg viewBox="0 0 24 24" fill="none"><path d="M4 7h16" stroke-width="2" stroke-linecap="round"/><path d="M10 11v6M14 11v6" stroke-width="2" stroke-linecap="round"/><path d="M6 7l1 12h10l1-12" stroke-width="2" stroke-linejoin="round"/><path d="M9 7V4h6v3" stroke-width="2" stroke-linejoin="round"/></svg></button></div></td>
</tr>
<tr>
<td>22-03-2026</td><td>Saar Vermeer</td><td>Basisschool – Groep 8</td><td>Topografie</td><td>Europa – hoofdsteden</td><td><span class="status-pill done">Afgerond</span></td><td>15 van 15</td>
<td><div class="table-actions"><button type="button" class="icon-btn history" aria-label="Bekijk geschiedenis" title="Bekijk geschiedenis"><svg viewBox="0 0 24 24" fill="none"><path d="M12 8v5l3 2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 12a9 9 0 1 0 3-6.7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 4v4h4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button type="button" class="icon-btn play" data-play-state="repeat" aria-label="Start gedeelde oefening opnieuw" title="Start gedeelde oefening opnieuw"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 6.5v11l9-5.5-9-5.5z"/></svg></button><button type="button" class="icon-btn delete" data-delete="true" aria-label="Verwijder gedeelde oefening" title="Verwijder gedeelde oefening"><svg viewBox="0 0 24 24" fill="none"><path d="M4 7h16" stroke-width="2" stroke-linecap="round"/><path d="M10 11v6M14 11v6" stroke-width="2" stroke-linecap="round"/><path d="M6 7l1 12h10l1-12" stroke-width="2" stroke-linejoin="round"/><path d="M9 7V4h6v3" stroke-width="2" stroke-linejoin="round"/></svg></button></div></td>
</tr>
<tr>
<td>20-03-2026</td><td>Milan Hoekstra</td><td>Basisschool – Groep 8</td><td>Engels</td><td>Werkwoorden</td><td><span class="status-pill done">Afgerond</span></td><td>20 van 20</td>
<td><div class="table-actions"><button type="button" class="icon-btn history" aria-label="Bekijk geschiedenis" title="Bekijk geschiedenis"><svg viewBox="0 0 24 24" fill="none"><path d="M12 8v5l3 2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 12a9 9 0 1 0 3-6.7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 4v4h4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button type="button" class="icon-btn play" data-play-state="repeat" aria-label="Start gedeelde oefening opnieuw" title="Start gedeelde oefening opnieuw"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 6.5v11l9-5.5-9-5.5z"/></svg></button><button type="button" class="icon-btn delete" data-delete="true" aria-label="Verwijder gedeelde oefening" title="Verwijder gedeelde oefening"><svg viewBox="0 0 24 24" fill="none"><path d="M4 7h16" stroke-width="2" stroke-linecap="round"/><path d="M10 11v6M14 11v6" stroke-width="2" stroke-linecap="round"/><path d="M6 7l1 12h10l1-12" stroke-width="2" stroke-linejoin="round"/><path d="M9 7V4h6v3" stroke-width="2" stroke-linejoin="round"/></svg></button></div></td>
</tr>
<tr>
<td>19-03-2026</td><td>Saar Vermeer</td><td>Basisschool – Groep 7</td><td>Taal</td><td>Zinsdelen</td><td><span class="status-pill started">Al gestart</span></td><td>4 van 10</td>
<td><div class="table-actions"><button type="button" class="icon-btn history is-disabled" title="Deze oefening is nog niet eerder afgerond, er is geen geschiedenis van beschikbaar." aria-label="Geen geschiedenis beschikbaar"><svg viewBox="0 0 24 24" fill="none"><path d="M12 8v5l3 2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 12a9 9 0 1 0 3-6.7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 4v4h4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button type="button" class="icon-btn play" data-play-state="resume" aria-label="Ga verder met gedeelde oefening" title="Ga verder met gedeelde oefening"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 6.5v11l9-5.5-9-5.5z"/></svg></button><button type="button" class="icon-btn delete" data-delete="true" aria-label="Verwijder gedeelde oefening" title="Verwijder gedeelde oefening"><svg viewBox="0 0 24 24" fill="none"><path d="M4 7h16" stroke-width="2" stroke-linecap="round"/><path d="M10 11v6M14 11v6" stroke-width="2" stroke-linecap="round"/><path d="M6 7l1 12h10l1-12" stroke-width="2" stroke-linejoin="round"/><path d="M9 7V4h6v3" stroke-width="2" stroke-linejoin="round"/></svg></button></div></td>
</tr>
<tr>
<td>18-03-2026</td><td>Lotte de Vries</td><td>Basisschool – Groep 7</td><td>Rekenen</td><td>Optellen</td><td><span class="status-pill done">Afgerond</span></td><td>12 van 12</td>
<td><div class="table-actions"><button type="button" class="icon-btn history" aria-label="Bekijk geschiedenis" title="Bekijk geschiedenis"><svg viewBox="0 0 24 24" fill="none"><path d="M12 8v5l3 2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 12a9 9 0 1 0 3-6.7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 4v4h4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button type="button" class="icon-btn play" data-play-state="repeat" aria-label="Start gedeelde oefening opnieuw" title="Start gedeelde oefening opnieuw"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 6.5v11l9-5.5-9-5.5z"/></svg></button><button type="button" class="icon-btn delete" data-delete="true" aria-label="Verwijder gedeelde oefening" title="Verwijder gedeelde oefening"><svg viewBox="0 0 24 24" fill="none"><path d="M4 7h16" stroke-width="2" stroke-linecap="round"/><path d="M10 11v6M14 11v6" stroke-width="2" stroke-linecap="round"/><path d="M6 7l1 12h10l1-12" stroke-width="2" stroke-linejoin="round"/><path d="M9 7V4h6v3" stroke-width="2" stroke-linejoin="round"/></svg></button></div></td>
</tr>
<tr>
<td>17-03-2026</td><td>Milan Hoekstra</td><td>Basisschool – Groep 8</td><td>Topografie</td><td>Nederland – provincies</td><td><span class="status-pill new">Nieuw ontvangen</span></td><td>-</td>
<td><div class="table-actions"><button type="button" class="icon-btn history is-disabled" title="Deze oefening is nog niet eerder afgerond, er is geen geschiedenis van beschikbaar." aria-label="Geen geschiedenis beschikbaar"><svg viewBox="0 0 24 24" fill="none"><path d="M12 8v5l3 2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 12a9 9 0 1 0 3-6.7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 4v4h4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button type="button" class="icon-btn play" data-play-state="first" aria-label="Start gedeelde oefening" title="Start gedeelde oefening"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 6.5v11l9-5.5-9-5.5z"/></svg></button><button type="button" class="icon-btn delete" data-delete="true" aria-label="Verwijder gedeelde oefening" title="Verwijder gedeelde oefening"><svg viewBox="0 0 24 24" fill="none"><path d="M4 7h16" stroke-width="2" stroke-linecap="round"/><path d="M10 11v6M14 11v6" stroke-width="2" stroke-linecap="round"/><path d="M6 7l1 12h10l1-12" stroke-width="2" stroke-linejoin="round"/><path d="M9 7V4h6v3" stroke-width="2" stroke-linejoin="round"/></svg></button></div></td>
</tr>
</tbody>
</table>
</div>
</div>
<p class="snapshot-text">De teksten van niveau, categorie en subcategorie blijven zichtbaar zoals ze waren op het moment van delen. Ook als namen later worden aangepast, blijft dit overzicht de oorspronkelijke benamingen tonen.</p>
</section>
</div>
</main>
<div class="shared-modal-backdrop" id="playModalBackdrop" aria-hidden="true">
<div class="shared-modal" role="dialog" aria-modal="true" aria-labelledby="playModalTitle">
<h3 id="playModalTitle">Gedeelde oefening starten</h3>
<p id="playModalText"></p>
<div class="switch-row" id="randomRow" hidden>
<div>
<strong style="display:block; margin-bottom:4px; color:#0d5db8;">Volgorde</strong>
<span style="font-size:14px; color:#285d96;">Kies of je de oefening in de gedeelde volgorde of willekeurig wilt doen.</span>
</div>
<div style="display:grid; justify-items:end; gap:6px;">
<button type="button" class="mini-switch" id="randomSwitch" aria-pressed="false" aria-label="Kies volgorde">
<span class="knob"></span>
</button>
<span class="switch-state" id="switchState">Normaal</span>
</div>
</div>
<div class="shared-modal-actions">
<button type="button" class="modal-btn secondary" id="cancelPlayBtn">Annuleren</button>
<button type="button" class="modal-btn primary" id="confirmPlayBtn">Start oefening</button>
</div>
</div>
</div>
<div class="shared-modal-backdrop" id="deleteModalBackdrop" aria-hidden="true">
<div class="shared-modal" role="dialog" aria-modal="true" aria-labelledby="deleteModalTitle">
<h3 id="deleteModalTitle">Gedeelde oefening verwijderen</h3>
<p>Weet je zeker dat je deze gedeelde oefening wilt verwijderen? Reeds uitgevoerde en afgeronde runs blijven toegankelijk via Geschiedenis (alles).</p>
<div class="shared-modal-actions">
<button type="button" class="modal-btn secondary" id="cancelDeleteBtn">Annuleren</button>
<button type="button" class="modal-btn primary" id="confirmDeleteBtn">Verwijderen</button>
</div>
</div>
</div>
<footer class="site-footer">
<div class="wrap">
<div class="footer-grid">
<div class="footer-col">
<h4>OefenHub</h4>
<p>OefenHub helpt kinderen spelenderwijs schoolvakken oefenen, herhalen en beter begrijpen. Alles overzichtelijk op één plek.</p>
</div>
<div class="footer-col">
<h4>Handige Links</h4>
<div class="footer-links">
<a href="#">Over OefenHub</a>
<a href="#">Contact</a>
<a href="#">Privacybeleid</a>
</div>
</div>
<div class="footer-col">
<h4>Snel naar</h4>
<div class="footer-links">
<a href="#">Profiel</a>
<a href="#">Berichten</a>
<a href="#">Meld een probleem</a>
</div>
</div>
</div>
<div class="footer-bottom">
<span>© 2026 OefenHub</span>
</div>
</div>
</footer>
<script>
(function () {
const menuItems = document.querySelectorAll('.nav-item[data-menu]');
menuItems.forEach(function (item) {
const trigger = item.querySelector('button');
if (!trigger) return;
trigger.addEventListener('click', function (event) {
event.preventDefault();
const isOpen = item.classList.contains('open');
menuItems.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) {
menuItems.forEach(function (item) {
if (!item.contains(event.target)) {
item.classList.remove('open');
const btn = item.querySelector('button');
if (btn) btn.setAttribute('aria-expanded', 'false');
}
});
});
const glanceCard = document.getElementById('glance-card');
const glanceToggle = glanceCard ? glanceCard.querySelector('.side-toggle') : null;
const mq = window.matchMedia('(max-width: 1120px)');
function syncGlanceCard() {
if (!glanceCard || !glanceToggle) return;
if (mq.matches) {
glanceCard.classList.add('is-collapsed');
glanceToggle.setAttribute('aria-expanded', 'false');
glanceToggle.setAttribute('aria-label', 'Toon meer');
} else {
glanceCard.classList.remove('is-collapsed');
glanceToggle.setAttribute('aria-expanded', 'true');
glanceToggle.setAttribute('aria-label', 'Toon minder');
}
}
if (glanceToggle) {
glanceToggle.addEventListener('click', function () {
const collapsed = glanceCard.classList.toggle('is-collapsed');
glanceToggle.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
glanceToggle.setAttribute('aria-label', collapsed ? 'Toon meer' : 'Toon minder');
});
}
syncGlanceCard();
if (mq.addEventListener) mq.addEventListener('change', syncGlanceCard);
else if (mq.addListener) mq.addListener(syncGlanceCard);
const playModal = document.getElementById('playModalBackdrop');
const playText = document.getElementById('playModalText');
const randomRow = document.getElementById('randomRow');
const randomSwitch = document.getElementById('randomSwitch');
const switchState = document.getElementById('switchState');
const deleteModal = document.getElementById('deleteModalBackdrop');
let randomOrder = false;
function openModal(modal) {
modal.classList.add('is-open');
modal.setAttribute('aria-hidden', 'false');
}
function closeModal(modal) {
modal.classList.remove('is-open');
modal.setAttribute('aria-hidden', 'true');
}
document.querySelectorAll('[data-play-state]').forEach(function (button) {
button.addEventListener('click', function () {
const state = button.getAttribute('data-play-state');
randomOrder = false;
randomSwitch.classList.remove('is-random');
randomSwitch.setAttribute('aria-pressed', 'false');
switchState.textContent = 'Normaal';
if (state === 'first') {
playText.textContent = 'Je start deze gedeelde oefening voor de eerste keer. De volgorde is exact zoals hij met jou gedeeld is.';
randomRow.hidden = true;
} else if (state === 'resume') {
playText.textContent = 'Je gaat verder waar je gebleven was met deze gedeelde oefening.';
randomRow.hidden = true;
} else {
playText.textContent = 'Je hebt deze gedeelde oefening al afgerond. Je kunt dezelfde inhoud opnieuw oefenen en eventueel de volgorde willekeurig maken.';
randomRow.hidden = false;
}
openModal(playModal);
});
});
randomSwitch.addEventListener('click', function () {
randomOrder = !randomOrder;
randomSwitch.classList.toggle('is-random', randomOrder);
randomSwitch.setAttribute('aria-pressed', String(randomOrder));
switchState.textContent = randomOrder ? 'Willekeurig' : 'Normaal';
});
document.querySelectorAll('[data-delete]').forEach(function (button) {
button.addEventListener('click', function () { openModal(deleteModal); });
});
document.getElementById('cancelPlayBtn').addEventListener('click', function () { closeModal(playModal); });
document.getElementById('confirmPlayBtn').addEventListener('click', function () { closeModal(playModal); });
document.getElementById('cancelDeleteBtn').addEventListener('click', function () { closeModal(deleteModal); });
document.getElementById('confirmDeleteBtn').addEventListener('click', function () { closeModal(deleteModal); });
[playModal, deleteModal].forEach(function (modal) {
modal.addEventListener('click', function (event) {
if (event.target === modal) closeModal(modal);
});
});
})();
</script>
</body>
</html>