1<!DOCTYPE html> 2<html lang="nl"> 3<head> 4<meta charset="UTF-8"> 5<meta name="viewport" content="width=device-width, initial-scale=1.0"> 6<title>Toolkit 'AI, curriculum en toetsing'</title> 7<style> 8 :root{ 9 --kleur-header:#d3104c; 10 --groen:#bfe6c2; 11 --groen-rand:#7cc684; 12 --geel:#fdeeb3; 13 --geel-rand:#e9cf6a; 14 --rood:#f4c2c4; 15 --rood-rand:#df8c8f; 16 } 17 *{box-sizing:border-box;} 18 html,body{height:100%;} 19 body{ 20 margin:0; 21 font-family:"Segoe UI",Tahoma,Arial,sans-serif; 22 color:#1f1f1f; 23 background:#fff; 24 display:flex; 25 flex-direction:column; 26 height:100vh; 27 overflow:hidden; 28 } 29 30 /* ---------- Header ---------- */ 31 header{ 32 background:var(--kleur-header); 33 color:#fff; 34 padding:7px 12px; 35 display:flex; 36 align-items:center; 37 justify-content:space-between; 38 flex:0 0 auto; 39 box-shadow:0 2px 6px rgba(0,0,0,.2); 40 z-index:50; 41 } 42 header h1{ 43 margin:0; 44 font-size:11px; 45 font-weight:600; 46 letter-spacing:.2px; 47 } 48 .header-actions{ 49 position:relative; 50 display:flex;
51 align-items:center; 52 gap:6px; 53 } 54 .icon-btn{ 55 width:23px;height:23px; 56 border-radius:50%; 57 border:1px solid rgba(255,255,255,.85); 58 background:rgba(255,255,255,.12); 59 color:#fff; 60 font-size:11px; 61 font-weight:700; 62 cursor:pointer; 63 display:flex;align-items:center;justify-content:center; 64 transition:background .15s; 65 } 66 .icon-btn:hover{background:rgba(255,255,255,.28);} 67 68 /* ---------- Settings popover ---------- */ 69 .popover{ 70 position:absolute; 71 top:30px;right:0; 72 background:#fff; 73 color:#1f1f1f; 74 border:1px solid #ddd; 75 border-radius:10px; 76 box-shadow:0 8px 24px rgba(0,0,0,.18); 77 padding:14px 16px; 78 min-width:200px; 79 display:none; 80 z-index:60; 81 } 82 .popover.open{display:block;} 83 .popover h3{margin:0 0 10px;font-size:13px;color:#888;text-transform:uppercase;letter-spacing:.5px;} 84 .popover label{ 85 display:flex;align-items:center;gap:10px; 86 padding:6px 4px;font-size:14px;cursor:pointer;border-radius:6px; 87 } 88 .popover label:hover{background:#f5f5f5;} 89 .popover input[type=checkbox]{width:17px;height:17px;accent-color:var(--kleur-header);cursor:pointer;} 90 91 /* ---------- Toolbar (invoer) ---------- */ 92 .toolbar{ 93 flex:0 0 auto; 94 display:flex; 95 gap:6px; 96 padding:7px 12px; 97 background:#fafafa; 98 border-bottom:1px solid #eee; 99 align-items:center; 100 } 101 .toolbar input{ 102 flex:1; 103 max-width:252px; 104 padding:6px 8px; 105 border:1px solid #ccc; 106 border-radius:6px; 107 font-size:8.5px; 108 outline:none; 109 } 110 .toolbar input:focus{border-color:var(--kleur-header);box-shadow:0 0 0 2px rgba(211,16,76,.15);} 111 .toolbar button{ 112 padding:6px 12px; 113 background:var(--kleur-header); 114 color:#fff; 115 border:none; 116 border-radius:6px; 117 font-size:8.5px;font-weight:600; 118 cursor:pointer; 119 transition:filter .15s; 120 } 121 .toolbar button:hover{filter:brightness(1.08);} 122 .toolbar .hint{font-size:7.5px;color:#999;margin-left:4px;} 123 124 /* ---------- Whiteboard ---------- */ 125 #whiteboard{ 126 position:relative; 127 flex:1 1 auto; 128 overflow:hidden; 129 } 130 .board-grid{ 131 position:absolute; 132 inset:0; 133 display:flex; 134 flex-direction:column; 135 } 136 .grid-row{display:flex;} 137 .grid-row.titles{flex:0 0 auto;} 138 .grid-row.band-row{flex:1 1 0;} 139 /* 'i'-knopje achter een balk-label */ 140 .info-i{ 141 display:inline-flex;align-items:center;justify-content:center; 142 width:18px;height:18px; 143 margin-left:6px; 144 border-radius:50%; 145 border:1px solid #555; 146 background:#fff; 147 color:#333; 148 font-family:Georgia,'Times New Roman',serif; 149 font-style:italic; 150 font-weight:700; 151 font-size:11px; 152 line-height:1; 153 cursor:pointer; 154 vertical-align:middle; 155 padding:0; 156 } 157 .info-i:hover{background:#333;color:#fff;border-color:#333;} 158 /* ---------- Brede modal + inschattingsmatrix ---------- */ 159 .modal.modal-wide{max-width:1140px;} 160 .matrix{ 161 display:flex; 162 margin-top:16px; 163 border:1px solid #cfcfcf; 164 border-radius:8px; 165 overflow:hidden; 166 } 167 .matrix-col{ 168 flex:1 1 0; 169 display:flex; 170 flex-direction:column; 171 border-right:2px solid #fff; 172 min-width:0; 173 } 174 .matrix-col:last-child{border-right:none;} 175 .matrix-head{ 176 background:var(--kleur-header); 177 color:#fff; 178 padding:10px 12px; 179 text-align:center; 180 font-weight:600; 181 font-size:12.5px; 182 line-height:1.35; 183 } 184 .matrix-cell{ 185 flex:1 1 auto; 186 padding:10px 12px; 187 font-size:12px; 188 line-height:1.4; 189 } 190 .matrix-cell ul{margin:0;padding-left:18px;} 191 .matrix-cell li{margin:5px 0;} 192 .matrix-cell p{margin:10px 0 0;} 193 .matrix-foot{ 194 padding:9px 12px; 195 font-size:12px; 196 border-top:2px solid #fff; 197 } 198 .col-groen .matrix-cell,.col-groen .matrix-foot{background:var(--groen);} 199 .col-geel .matrix-cell,.col-geel .matrix-foot{background:var(--geel);} 200 .col-rood .matrix-cell,.col-rood .matrix-foot{background:var(--rood);} 201 .matrix-col.highlight{outline:3px solid #d3104c;outline-offset:-3px;} 202 @media (max-width:720px){ .matrix{flex-direction:column;} .matrix-col{border-right:none;border-bottom:2px solid #fff;} } 203 .cell{ 204 flex:1 1 0; 205 min-width:0; 206 border-right:2px solid #fff; 207 } 208 .cell:last-child{border-right:none;} 209 .cell.title{ 210 text-align:center; 211 font-weight:700; 212 font-size:10.5px; 213 padding:5.5px 3px; 214 background:#f0f0f0; 215 color:#333; 216 }
217 .cell.band.groen{background:var(--groen);} 218 .cell.band.geel{background:var(--geel);} 219 .cell.band.rood{background:var(--rood);} 220 /* horizontale label-balken over de VOLLEDIGE breedte */ 221 .level-label{ 222 flex:0 0 auto; 223 text-align:center; 224 font-weight:600; 225 font-size:12.5px; 226 padding:8px 10px; 227 color:#2a2a2a; 228 border-top:2px solid #fff; 229 border-bottom:1px solid rgba(0,0,0,.12); 230 } 231 .level-label.groen-label{background:#dff0e1;} 232 .level-label.geel-label{background:#fdf3cc;} 233 .level-label.rood-label{background:#f8dadb;} 234 235 /* ---------- Verplaatsbare blokjes ---------- */ 236 .note{ 237 position:absolute; 238 width:85px; 239 z-index:10; 240 user-select:none; 241 } 242 /* status-icoon boven het blokje: geel ?, rood !, groen vinkje */ 243 .note .note-icon{ 244 display:none; 245 width:20px;height:20px; 246 line-height:20px; 247 margin:0 auto 2px; 248 text-align:center; 249 border-radius:50%; 250 font-weight:800; 251 font-size:13px; 252 box-shadow:0 1px 3px rgba(0,0,0,.25); 253 cursor:pointer; 254 } 255 .note .note-icon.active{display:block;} 256 .icon-geel{background:#f1c40f;color:#4a3b00;} 257 .icon-rood{background:#e2342a;color:#fff;} 258 .icon-groen{background:#1e9e54;color:#fff;} 259 .note .body{ 260 background:#fff; 261 border:2px solid #000; 262 border-radius:6px; 263 padding:6px 8px; 264 font-size:11px; 265 line-height:1.2; 266 text-align:center; 267 word-break:break-word; 268 cursor:grab; 269 box-shadow:0 3px 8px rgba(0,0,0,.18); 270 min-height:22px; 271 display:flex;align-items:center;justify-content:center; 272 } 273 .note .body:hover{background:#fafafa;} 274 .note .body:active{cursor:grabbing;} 275 276 /* ---------- Info modal ---------- */ 277 .modal-overlay{ 278 position:fixed;inset:0; 279 background:rgba(0,0,0,.45); 280 display:none; 281 align-items:center;justify-content:center; 282 z-index:100;padding:20px; 283 } 284 .modal-overlay.open{display:flex;} 285 .modal{ 286 background:#fff; 287 border-radius:14px; 288 max-width:560px;width:100%; 289 max-height:85vh;overflow:auto; 290 box-shadow:0 20px 50px rgba(0,0,0,.3); 291 } 292 .modal-header{ 293 background:var(--kleur-header); 294 color:#fff; 295 padding:14px 20px; 296 display:flex;align-items:center;justify-content:space-between; 297 border-radius:14px 14px 0 0; 298 position:sticky;top:0; 299 } 300 .modal-header h2{margin:0;font-size:17px;} 301 .modal-header .close{cursor:pointer;font-size:22px;line-height:1;background:none;border:none;color:#fff;} 302 .modal-body{padding:20px 22px;font-size:14px;line-height:1.55;color:#2a2a2a;} 303 .modal-body h3{margin:18px 0 8px;font-size:14px;color:var(--kleur-header);} 304 .modal-body h3:first-child{margin-top:0;} 305 .legend{display:flex;gap:8px;align-items:center;margin:6px 0;font-size:13px;} 306 .swatch{width:18px;height:18px;border-radius:4px;flex:0 0 auto;border:1px solid rgba(0,0,0,.15);} 307 .icon-legend{width:20px;height:20px;line-height:20px;border-radius:50%;flex:0 0 auto;text-align:center;font-weight:800;font-size:13px;} 308 .modal-body ul{margin:6px 0;padding-left:20px;} 309 .modal-body li{margin:3px 0;} 310 .instructie-box{ 311 margin-top:6px; 312 background:#f6f6f6; 313 border:1px dashed #ccc; 314 border-radius:8px; 315 padding:14px; 316 color:#666; 317 font-style:italic; 318 } 319 320 /* ---------- Toast melding ---------- */ 321 #toast{ 322 position:fixed; 323 bottom:22px;left:50%; 324 transform:translateX(-50%) translateY(20px); 325 background:#333;color:#fff; 326 padding:10px 18px; 327 border-radius:8px; 328 font-size:13px; 329 opacity:0; 330 pointer-events:none; 331 transition:opacity .25s, transform .25s; 332 z-index:200; 333 } 334 #toast.show{opacity:1;transform:translateX(-50%) translateY(0);} 335 336 337 /* ---------- Hoofdnavigatie met vier onderdelen ---------- */ 338 .app-tabs{ 339 flex:0 0 auto; 340 display:grid; 341 grid-template-columns:repeat(4,minmax(0,1fr)); 342 background:#fff; 343 border-bottom:1px solid #d8d8d8; 344 box-shadow:0 2px 8px rgba(0,0,0,.12); 345 position:relative; 346 z-index:300; 347 } 348 .app-tab{ 349 min-width:0; 350 height:45px; 351 min-height:45px; 352 padding:3px 14px; 353 border:0; 354 border-right:1px solid #ddd; 355 border-bottom:4px solid transparent; 356 background:#f5f5f5; 357 color:#292929; 358 font:600 14px/1.15 "Segoe UI",Tahoma,Arial,sans-serif; 359 text-align:center; 360 cursor:pointer; 361 transition:background .15s,color .15s,border-color .15s; 362 } 363 .app-tab:last-child{border-right:0;} 364 .app-tab:hover{background:#fff;} 365 .app-tab:focus-visible{outline:3px solid rgba(211,16,76,.3);outline-offset:-3px;} 366 .app-tab[aria-selected="true"]{ 367 background:var(--kleur-header); 368 border-bottom-color:var(--kleur-header); 369 color:#fff; 370 } 371 .app-panels{ 372 flex:1 1 auto; 373 min-height:0; 374 position:relative; 375 overflow:hidden; 376 } 377 .app-panel{ 378 position:absolute; 379 inset:0; 380 min-width:0; 381 min-height:0; 382 display:none; 383 background:#fff; 384 } 385 .app-panel.active{display:flex;} 386 #panel-scan{flex-direction:column;overflow:hidden;} 387 #panel-toolkit, 388 #panel-flowchart{overflow:hidden;} 389 .embedded-page{ 390 display:block; 391 width:100%; 392 height:100%; 393 border:0; 394 background:#fff; 395 } 396 #panel-cards{ 397 overflow:auto; 398 background:#f7f7f7; 399 color:#111; 400 padding:22px clamp(18px,4vw,64px) 20px; 401 } 402 .cards-shell{ 403 width:min(1120px,100%); 404 min-height:100%; 405 margin:auto; 406 display:flex; 407 flex-direction:column;
408 align-items:stretch; 409 gap:14px; 410 } 411 .cards-header{ 412 display:block; 413 flex:0 0 auto; 414 padding:0; 415 background:transparent; 416 color:#111; 417 box-shadow:none; 418 position:static; 419 z-index:auto; 420 } 421 .cards-header h2{ 422 margin:0 0 14px; 423 color:#111; 424 font-size:28px; 425 line-height:1.1; 426 font-weight:800; 427 font-style:normal; 428 text-align:center; 429 } 430 .card-categories{ 431 display:grid; 432 grid-template-columns:repeat(3,minmax(0,1fr)); 433 gap:12px; 434 } 435 .card-category{ 436 min-height:48px; 437 padding:9px 14px; 438 border:2px solid #d8d8d8; 439 border-radius:9px; 440 background:#fff; 441 color:#292929; 442 font:700 14px/1.25 "Segoe UI",Tahoma,Arial,sans-serif; 443 cursor:pointer; 444 transition:background .15s,color .15s,border-color .15s,box-shadow .15s; 445 } 446 .card-category:hover{ 447 border-color:var(--kleur-header); 448 box-shadow:0 2px 8px rgba(0,0,0,.08); 449 } 450 .card-category:focus-visible{ 451 outline:3px solid rgba(211,16,76,.25); 452 outline-offset:2px; 453 } 454 .card-category[aria-selected="true"]{ 455 background:var(--kleur-header); 456 border-color:var(--kleur-header); 457 color:#fff; 458 } 459 .conversation-card{ 460 position:relative; 461 flex:1 1 330px; 462 min-height:330px; 463 max-height:470px; 464 display:flex;
465 align-items:center; 466 justify-content:center; 467 padding:52px clamp(28px,7vw,90px) 62px; 468 background:#fff; 469 border:2px solid #ddd; 470 border-radius:14px; 471 box-shadow:0 7px 20px rgba(0,0,0,.09); 472 } 473 .card-warning{ 474 padding:13px 18px; 475 border:1px solid #e0c16b; 476 border-radius:5px; 477 background:#fff1c9; 478 color:#29230f; 479 font-size:15px; 480 line-height:1.45; 481 } 482 .card-warning[hidden]{display:none;} 483 .card-content{ 484 width:100%; 485 max-width:930px; 486 text-align:center; 487 } 488 .card-kicker{ 489 margin-bottom:26px; 490 color:#999; 491 font-size:12px; 492 font-weight:500; 493 letter-spacing:1.2px; 494 } 495 #cardQuestion{ 496 margin:0; 497 color:#003b49; 498 font-size:clamp(21px,2.15vw,29px); 499 line-height:1.42; 500 font-weight:800; 501 } 502 #cardSubtext{ 503 max-width:900px; 504 margin:16px auto 0; 505 color:#4e4e4e; 506 font-size:clamp(13px,1.3vw,16px); 507 line-height:1.55; 508 font-style:italic; 509 font-weight:400; 510 } 511 #cardSubtext[hidden]{display:none;} 512 .card-counter{ 513 position:absolute; 514 left:0; 515 right:0; 516 bottom:25px; 517 color:#aaa; 518 font-size:14px; 519 text-align:center; 520 } 521 .card-navigation{ 522 display:flex; 523 justify-content:center; 524 gap:12px; 525 } 526 .card-navigation button{ 527 min-width:122px; 528 min-height:42px; 529 padding:9px 18px; 530 border:0; 531 border-radius:8px; 532 background:#003b49; 533 color:#fff; 534 font:700 14px/1.2 "Segoe UI",Tahoma,Arial,sans-serif; 535 cursor:pointer; 536 transition:background .15s,transform .05s; 537 } 538 .card-navigation button:hover{background:#005467;} 539 .card-navigation button:active{transform:translateY(1px);} 540 .card-navigation button:focus-visible{ 541 outline:3px solid rgba(0,59,73,.25); 542 outline-offset:2px; 543 } 544 545 /* Scanbediening: invoer en vier acties in één balk */ 546 #panel-scan .header-actions{ 547 flex:0 0 auto; 548 gap:10px; 549 margin-left:auto; 550 } 551 #panel-scan .icon-btn{ 552 width:38px; 553 height:38px; 554 font-size:18px; 555 border-color:var(--kleur-header); 556 background:var(--kleur-header); 557 color:#fff; 558 } 559 #panel-scan .icon-btn:hover{background:#b90e42;} 560 #panel-scan .popover{top:50px;} 561 #panel-scan > .toolbar{ 562 gap:10px; 563 padding:12px 20px; 564 min-width:0; 565 } 566 #panel-scan > .toolbar input{ 567 max-width:420px; 568 padding:10px 14px; 569 border-radius:10px; 570 font-size:14px; 571 } 572 #panel-scan > .toolbar button{ 573 padding:10px 20px; 574 border-radius:10px; 575 font-size:14px; 576 } 577 #panel-scan > .toolbar .hint{ 578 flex:1 1 auto; 579 min-width:180px; 580 font-size:12.5px; 581 margin-left:7px; 582 } 583 584 @media (max-width:760px){ 585 .app-tab{ 586 height:58px; 587 min-height:58px; 588 padding:4px; 589 } 590 #panel-scan > .toolbar{flex-wrap:wrap;} 591 #panel-scan > .toolbar .hint{order:4;flex-basis:100%;margin-left:0;} 592 #panel-scan .header-actions{margin-left:0;} 593 #panel-cards{padding:16px 12px;} 594 .cards-header h2{font-size:23px;} 595 .card-categories{grid-template-columns:1fr;gap:7px;} 596 .card-category{min-height:40px;padding:7px 10px;font-size:12px;} 597 .conversation-card{ 598 min-height:360px; 599 max-height:none; 600 padding:38px 22px 58px; 601 } 602 .card-kicker{margin-bottom:18px;} 603 #cardQuestion{font-size:20px;line-height:1.35;} 604 #cardSubtext{font-size:13px;line-height:1.45;} 605 } 606 607</style> 608</head> 609<body> 610 <nav class="app-tabs" aria-label="Onderdelen AI, curriculum en toetsing" role="tablist"> 611 <button class="app-tab" id="tab-toolkit" type="button" role="tab" aria-controls="panel-toolkit" aria-selected="false" tabindex="-1">1) Toolkit 'AI, curriculum en toetsing'</button> 612 <button class="app-tab" id="tab-scan" type="button" role="tab" aria-controls="panel-scan" aria-selected="true">2) Scan AI-bewust curriculum- en toetsprogramma</button> 613 <button class="app-tab" id="tab-flowchart" type="button" role="tab" aria-controls="panel-flowchart" aria-selected="false" tabindex="-1">3) Flowchart AI-bewust toetsen</button> 614 <button class="app-tab" id="tab-cards" type="button" role="tab" aria-controls="panel-cards" aria-selected="false" tabindex="-1">4) Gesprekskaarten 'AI, curriculum en toetsing'</button> 615 </nav> 616 617 <main class="app-panels"> 618 <section class="app-panel" id="panel-toolkit" role="tabpanel" aria-labelledby="tab-toolkit" hidden> 619 <iframe class="embedded-page" title="Toolkit AI, curriculum en toetsing" src="https://maken.wikiwijs.nl/223515/Toolkit__AI__curriculum_en_toetsing" loading="eager"></iframe> 620 </section> 621 622 <section class="app-panel active" id="panel-scan" role="tabpanel" aria-labelledby="tab-scan"> 623<!-- ===== Header ===== --> 624 <header> 625 <h1>Scan AI-bewust curriculum- en toetsprogramma</h1> 626 <div class="header-actions"> 627 <button class="icon-btn" id="saveBtn" title="Opslaan">💾</button> 628 <button class="icon-btn" id="loadBtn" title="Laden">📂</button> 629 <button class="icon-btn" id="infoBtn" title="Instructie">i</button> 630 <button class="icon-btn" id="settingsBtn" title="Instellingen">⚙</button> 631 632 <div class="popover" id="settingsMenu"> 633 <h3>Toon jaren</h3> 634 <label><input type="checkbox" data-year="2" checked> Jaar 2 (Vlak 2)</label> 635 <label><input type="checkbox" data-year="3" checked> Jaar 3 (Vlak 3)</label> 636 <label><input type="checkbox" data-year="4" checked> Jaar 4 (Vlak 4)</label> 637 </div> 638 </div> 639 </header> 640 641 <!-- ===== Invoerbalk ===== --> 642 <div class="toolbar"> 643 <input type="text" id="courseInput" placeholder="Cursusnaam"> 644 <button id="addBtn">Voer in</button> 645 <span class="hint">Sleep blokjes met de linkermuisknop ingedrukt | klik op een blokje voor het status-icoon | rechtsklik om te verwijderen</span> 646 </div> 647 648 <!-- ===== Whiteboard ===== --> 649 <div id="whiteboard"> 650 <div class="board-grid" id="board"> 651 <div class="grid-row titles"> 652 <div class="cell title" data-year="1">Jaar 1</div> 653 <div class="cell title" data-year="2">Jaar 2</div> 654 <div class="cell title" data-year="3">
654Jaar 3</div> 655 <div class="cell title" data-year="4">Jaar 4</div> 656 </div> 657 658 <div class="level-label groen-label">De toetsing is AI-bewust. <button class="info-i" data-level="groen" title="Toon de inschattingsmatrix">i</button></div> 659 <div class="grid-row band-row"> 660 <div class="cell band groen" data-year="1"></div> 661 <div class="cell band groen" data-year="2"></div> 662 <div class="cell band groen" data-year="3"></div> 663 <div class="cell band groen" data-year="4"></div> 664 </div> 665 666 <div class="level-label geel-label">Er zijn nog enkele AI-gerelateerde risico’s bij deze toetsing. <button class="info-i" data-level="geel" title="Toon de inschattingsmatrix">i</button></div> 667 <div class="grid-row band-row"> 668 <div class="cell band geel" data-year="1"></div> 669 <div class="cell band geel" data-year="2"></div> 670 <div class="cell band geel" data-year="3"></div> 671 <div class="cell band geel" data-year="4"></div> 672 </div> 673 674 <div class="level-label rood-label">Er zijn veel AI-gerelateerde risico’s bij deze toetsing. <button class="info-i" data-level="rood" title="Toon de inschattingsmatrix">i</button></div> 675 <div class="grid-row band-row"> 676 <div class="cell band rood" data-year="1"></div> 677 <div class="cell band rood" data-year="2"></div> 678 <div class="cell band rood" data-year="3"></div> 679 <div class="cell band rood" data-year="4"></div> 680 </div> 681 </div> 682 <!-- verplaatsbare blokjes worden hier toegevoegd --> 683 </div> 684 685 <!-- ===== Info / instructie modal ===== --> 686 <div class="modal-overlay" id="infoModal"> 687 <div class="modal"> 688 <div class="modal-header"> 689 <h2>Uitleg & instructie</h2> 690 <button class="close" id="closeInfo">×</button> 691 </div> 692 <div class="modal-body"> 693 <h3>De verticale vlakken (jaren)</h3> 694 <p>De pagina is verdeeld in vier verticale vlakken, één per studiejaar:</p> 695 <ul> 696 <li><strong>Vlak 1</strong> – Jaar 1</li> 697 <li><strong>Vlak 2</strong> – Jaar 2</li> 698 <li><strong>Vlak 3</strong> – Jaar 3</li> 699 <li><strong>Vlak 4</strong> – Jaar 4</li> 700 </ul> 701 702 <h3>De horizontale vlakken (AI-bewustzijn van de toetsing)</h3> 703 <div class="legend"><span class="swatch" style="background:var(--groen)"></span> <span><strong>Groen:</strong> De toetsing is AI-bewust.</span></div> 704 <div class="legend"><span class="swatch" style="background:var(--geel)"></span> <span><strong>Geel:</strong> Er zijn nog enkele AI-gerelateerde risico’s bij deze toetsing.</span></div> 705 <div class="legend"><span class="swatch" style="background:var(--rood)"></span> <span><strong>Rood:</strong> Er zijn veel AI-gerelateerde risico’s bij deze toetsing.</span></div> 706 707 <h3>De status-iconen op een blokje</h3> 708 <p>Klik met de linkermuisknop op een cursusblokje of rechtstreeks op het statusicoon om het icoon te wisselen:</p> 709 <div class="legend"><span class="icon-legend icon-geel">?</span> <span>In deze cursus willen we verder uitdenken of en hoe we AI hier een rol in willen geven.</span></div> 710 <div class="legend"><span class="icon-legend icon-rood">!</span> <span>In deze cursus worden de kansen van AI nog niet benut / komt AI nog niet aan bod, terwijl dat wel wenselijk is.</span></div> 711 <div class="legend"><span class="icon-legend icon-groen">✓</span> <span>In deze cursus zijn de kansen van AI benut / komt AI niet aan bod omdat dat niet wenselijk is.</span></div> 712 713 <h3>Cursus verwijderen</h3> 714 <p><strong>Klik met de rechtermuisknop op een cursusblokje om die cursus direct te wissen.</strong></p> 715 716 </div> 717 </div> 718 </div> 719 720 <!-- ===== Inschattingsmatrix modal ===== --> 721 <div class="modal-overlay" id="matrixModal"> 722 <div class="modal modal-wide"> 723 <div class="modal-header"> 724 <h2>Inschattingsmatrix AI-bewust toetsen</h2> 725 <button class="close" id="closeMatrix">×</button> 726 </div> 727 <div class="modal-body"> 728 <p>Deze niveaus van AI-bewustheid zijn geen exacte wetenschap. Elke toets en elk toetsprogramma is immer
728s anders. Elke beroepspraktijk wordt ook weer op andere manieren beïnvloed door generatieve AI. Gebruik onderstaande informatie daarom om een globaal idee te krijgen van waar je toetsen kunt plaatsen in het overzicht. Het gesprek dat daaruit volgt is belangrijker dan de exacte positie van de toetsen.</p> 729 <p><strong>Verificatiemaatregelen</strong> zijn (extra) manieren om te toetsen of studenten de kennis, vaardigheden en attitudes daadwerkelijk <u>zelf</u> bezitten. Voorbeelden hiervan zijn het toevoegen van een mondelinge component of een uitgebreidere verantwoording van brongebruik. Verificatiemaatregelen zijn ook manieren om te controleren of studenten daadwerkelijk bepaald werk hebben uitgevoerd en manieren waarop ze hun AI-gebruik transparant hebben verantwoord. Voorbeelden hiervan zijn het toevoegen van feedback, gesprekken en/of handtekeningen van begeleiders.</p> 730 731 <div class="matrix"> 732 <div class="matrix-col col-groen" data-level="groen"> 733 <div class="matrix-head">AI-bewustheid: Hoog<br>AI-Risico: Laag<br><br>Extra verificatiemaatregelen niet nodig</div> 734 <div class="matrix-cell"> 735 <ul> 736 <li>Mondelinge toetsen zonder bijbehorend product</li> 737 <li>Presentaties zonder bijbehorend product (Live observaties / Performance assessments, waaronder o.a. observaties van beroepshandelingen, stagewerkzaamheden en/of practica)</li> 738 <li>Video-opnames van beroepshandelingen, stagewerkzaamheden en/of practica</li> 739 <li>Toetsen onder toezicht op locatie, waaronder o.a. toetsing met meerkeuzevragen, open vragen, casuïstiek, etc.</li> 740 <li>Beveiligde digitale toetsen via ANS (Met/zonder internet, Met/zonder aangeleverde bronnen, Met/zonder AI.)</li> 741 </ul> 742 </div> 743 <div class="matrix-foot">Hoe kan generatieve AI de toetsing en de voorbereiding erop versterken?</div> 744 </div> 745 746 <div class="matrix-col col-geel" data-level="geel"> 747 <div class="matrix-head">AI-bewustheid: Gemiddeld<br>AI-Risico: Gemiddeld<br><br>Overweeg extra verificatiemaatregelen</div> 748 <div class="matrix-cell"> 749 <ul> 750 <li>Mondelinge toetsen gebaseerd op een bijbehorend product.</li> 751 <li>Presentaties gebaseerd op een bijbehorend product.</li> 752 <li>Criteriumgerichte interviews gebaseerd op een bijbehorend product.</li> 753 </ul> 754 <p>Hierbij is het van belang om te kijken hoe het product tot stand komt en of daar onwenselijk gebruik van generatieve AI kan meespelen.</p> 755 </div> 756 <div class="matrix-foot">Hoe kan generatieve AI de toetsing en de voorbereiding erop versterken?</div> 757 </div> 758 759 <div class="matrix-col col-rood" data-level="rood"> 760 <div class="matrix-head">AI-bewustheid: Laag<br>AI-Risico: Hoog<br><br>Extra verificatiemaatregelen nodig</div> 761 <div class="matrix-cell"> 762 <ul> 763 <li>Alle soorten schriftelijke verslagen zonder verificatiemaatregelen</li> 764 <li>Opgenomen audiopresentaties zonder verificatiemaatregelen</li> 765 <li>Portfolio’s zonder verificatiemaatregelen</li> 766 <li>Scripties zonder verificatiemaatregelen (met name scripties waarin theoretisch onderzoek centraal staat en een praktijkgerichte component ontbreekt of minimaal is)</li> 767 </ul> 768 </div> 769 <div class="matrix-foot">Hoe kan generatieve AI de toetsing en de voorbereiding erop versterken?</div> 770 </div> 771 </div> 772 </div> 773 </div> 774 </div> 775 776 <!-- verborgen bestand-invoer voor het laden van een opgeslagen bestand --> 777 <input type="file" id="fileInput" accept="application/json,.json" style="display:none"> 778 779 <!-- toast melding --> 780 <div id="toast"></div> 781
782<script> 783/* ---------- Gedeelde opslag: alles wat de gebruiker doet blijft lokaal bewaard ---------- */ 784window.toolkitState = (function(){ 785 const KEY = 'toetsscan_ui'; 786 function read(){ 787 try{ return JSON.parse(localStorage.getItem(KEY) || '{}') || {}; } 788 catch(e){ return {}; } 789 } 790 function write(patch){ 791 try{ 792 const state = read(); 793 Object.assign(state, patch); 794 localStorage.setItem(KEY, JSON.stringify(state)); 795 }catch(e){} 796 } 797 return { read: read, write: write }; 798})(); 799</script>
799 800
801<script> 802(function(){ 803 "use strict"; 804 805 const whiteboard = document.getElementById('whiteboard'); 806 const board = document.getElementById('board'); 807 const courseInput = document.getElementById('courseInput'); 808 const addBtn = document.getElementById('addBtn'); 809 const settingsBtn = document.getElementById('settingsBtn'); 810 const settingsMenu = document.getElementById('settingsMenu'); 811 const infoBtn = document.getElementById('infoBtn'); 812 const infoModal = document.getElementById('infoModal'); 813 const closeInfo = document.getElementById('closeInfo'); 814 815 // status-iconen die je doorklikt op een blokje (geel ? -> rood ! -> groen vinkje) 816 const ICONS = [ 817 { sym:'?', cls:'icon-geel', label:'In deze cursus willen we verder uitdenken of en hoe we AI hier een rol in willen geven.' }, 818 { sym:'!', cls:'icon-rood', label:'In deze cursus worden de kansen van AI nog niet benut / komt AI nog niet aan bod, terwijl dat wel wenselijk is.' }, 819 { sym:'â', cls:'icon-groen', label:'In deze cursus zijn de kansen van AI benut / komt AI niet aan bod omdat dat niet wenselijk is.' } 820 ]; 821 822 const LEVELS = ['groen','geel','rood']; 823 let cascade = 0; // verdeelt nieuwe blokjes binnen het eerste vak 824 825 function clamp(value, min, max){ 826 return Math.max(min, Math.min(value, max)); 827 } 828 829 function getBandCell(year, level){ 830 const cell = board.querySelector('.cell.band.'+level+'[data-year="'+year+'"]'); 831 if(!cell) return null; 832 const rect = cell.getBoundingClientRect(); 833 return (rect.width > 0 && rect.height > 0) ? cell : null; 834 } 835 836 function setNoteAnchor(note, year, level, xRatio, yRatio){ 837 note.dataset.year = String(year); 838 note.dataset.level = LEVELS.indexOf(level) >= 0 ? level : 'groen'; 839 note.dataset.xRatio = String(clamp(Number(xRatio) || 0.5, 0, 1)); 840 note.dataset.yRatio = String(clamp(Number(yRatio) || 0.5, 0, 1)); 841 } 842 843 function getNoteAnchor(note){ 844 return { 845 year: note.dataset.year || '1', 846 level: LEVELS.indexOf(note.dataset.level) >= 0 ? note.dataset.level : 'groen', 847 xRatio: clamp(parseFloat(note.dataset.xRatio) || 0.5, 0, 1), 848 yRatio: clamp(parseFloat(note.dataset.yRatio) || 0.5, 0, 1) 849 }; 850 } 851 852 function positionNoteFromAnchor(note){ 853 if(note.dataset.dragging === 'true') return; 854 const anchor = getNoteAnchor(note);
855 const cell = getBandCell(anchor.year, anchor.level); 856 if(!cell){ 857 note.style.display = 'none'; 858 return; 859 } 860 861 note.style.display = ''; 862 const cellRect = cell.getBoundingClientRect(); 863 const boardRect = whiteboard.getBoundingClientRect(); 864 const noteWidth = note.offsetWidth; 865 const noteHeight = note.offsetHeight; 866 867 const minX = cellRect.width > noteWidth ? (noteWidth / 2) / cellRect.width : 0.5; 868 const maxX = cellRect.width > noteWidth ? 1 - minX : 0.5; 869 const minY = cellRect.height > noteHeight ? (noteHeight / 2) / cellRect.height : 0.5; 870 const maxY = cellRect.height > noteHeight ? 1 - minY : 0.5; 871 const xRatio = clamp(anchor.xRatio, minX, maxX); 872 const yRatio = clamp(anchor.yRatio, minY, maxY); 873 874 note.style.left = (cellRect.left - boardRect.left + xRatio * cellRect.width - noteWidth / 2) + 'px'; 875 note.style.top = (cellRect.top - boardRect.top + yRatio * cellRect.height - noteHeight / 2) + 'px'; 876 } 877 878 function nearestBandCell(centerX, centerY){ 879 let nearest = null; 880 let nearestDistance = Infinity; 881 LEVELS.forEach(function(level){ 882 board.querySelectorAll('.cell.band.'+level).forEach(function(cell){ 883 const rect = cell.getBoundingClientRect(); 884 if(rect.width <= 0 || rect.height <= 0) return; 885 const dx = centerX < rect.left ? rect.left - centerX : (centerX > rect.right ? centerX - rect.right : 0); 886 const dy = centerY < rect.top ? rect.top - centerY : (centerY > rect.bottom ? centerY - rect.bottom : 0); 887 const distance = dx * dx + dy * dy; 888 if(distance < nearestDistance){ 889 nearestDistance = distance; 890 nearest = { cell:cell, level:level, rect:rect }; 891 } 892 }); 893 }); 894 return nearest; 895 } 896 897 function anchorNoteToNearestCell(note){ 898 const noteRect = note.getBoundingClientRect(); 899 const centerX = noteRect.left + noteRect.width / 2; 900 const centerY = noteRect.top + noteRect.height / 2; 901 const target = nearestBandCell(centerX, centerY); 902 if(!target) return; 903 904 setNoteAnchor( 905 note, 906 target.cell.getAttribute('data-year') || '1', 907 target.level, 908 (centerX - target.rect.left) / target.rect.width, 909 (centerY - target.rect.top) / target.rect.height 910 ); 911 positionNoteFromAnchor(note); 912 } 913 914 function layoutAllNotes(){ 915 if(whiteboard.clientWidth < 1 || whiteboard.clientHeight < 1) return; 916 whiteboard.querySelectorAll('.note').forEach(positionNoteFromAnchor); 917 } 918 919 let layoutFrame = 0; 920 function scheduleLayout(){ 921 cancelAnimationFrame(layoutFrame); 922 layoutFrame = requestAnimationFrame(layoutAllNotes); 923 } 924 925 /* ---------- Blokje toevoegen ---------- */ 926 function addNote(text, opts){ 927 opts = opts || {}; 928 const note = document.createElement('div'); 929 note.className = 'note'; 930 note.dataset.text = text; 931 932 const icon = document.createElement('div'); 933 icon.className = 'note-icon'; 934 935 const body = document.createElement('div'); 936 body.className = 'body'; 937 body.textContent = text; 938 body.title = 'Sleep met de linkermuisknop ingedrukt · klik om het icoon te wisselen · rechtsklik om te verwijderen'; 939 940 note.appendChild(icon); 941 note.appendChild(body); 942 943 whiteboard.appendChild(note); 944 945 // ----- Status-icoon ----- 946 // bij toevoegen staat het eerste icoon (geel ?) meteen zichtbaar; 947 // links klikken loopt door: geel ? -> rood ! -> groen vinkje -> geel ? ... 948 let state = (typeof opts.state === 'number') ? (((opts.state % 3) + 3) % 3) : 0; 949 950 function renderIcon(){ 951 const ic = ICONS[state]; 952 icon.textContent = ic.sym; 953 icon.className = 'note-icon active ' + ic.cls; 954 icon.title = ic.label + ' Klik om het volgende statusicoon te tonen.'; 955 note.dataset.state = state; // staat onthouden voor opslaan 956 } 957 958 renderIcon(); // toon direct het eerste icoon bij toevoegen 959 960 // Nieuwe opslag gebruikt een vast vak (jaar + niveau) en een relatieve 961 // positie binnen dat vak. Oude pixelposities worden eenmalig gemigreerd. 962 const hasAnchor = opts.year && LEVELS.indexOf(opts.level) >= 0 && 963 typeof opts.xRatio === 'number' && typeof opts.yRatio === 'number'; 964 if(hasAnchor){ 965 setNoteAnchor(note, opts.year, opts.level, opts.xRatio, opts.yRatio); 966 positionNoteFromAnchor(note); 967 }else if(typeof opts.left === 'number' && typeof opts.top === 'number'){ 968 note.style.left = opts.left + 'px'; 969 note.style.top = opts.top + 'px'; 970 anchorNoteToNearestCell(note); 971 }else{ 972 const slot = cascade++; 973 const xSlots = [0.20, 0.50, 0.80]; 974 const ySlots = [0.28, 0.72]; 975 setNoteAnchor(note, '1', 'groen', xSlots[slot % 3], ySlots[Math.floor(slot / 3) % 2]); 976 positionNoteFromAnchor(note); 977 } 978 979 // ----- Verwijderen via de rechtermuisknop ----- 980 note.addEventListener('contextmenu', function(e){
981 e.preventDefault(); 982 note.remove(); 983 autoSave(); // verwijdering direct opslaan 984 }); 985 986 function cycleStatus(){ 987 state = (state + 1) % 3; 988 renderIcon(); 989 autoSave(); // icoonwijziging direct opslaan 990 } 991 992 // ----- Slepen met de linkermuisknop; een gewone klik wisselt het icoon ----- 993 enableDrag(note, body, cycleStatus); 994 icon.addEventListener('click', function(e){ 995 e.stopPropagation(); 996 cycleStatus(); // klikken op het icoon werkt hetzelfde als klikken op het blokje 997 }); 998 999 autoSave(); // toevoeging direct opslaan 1000 return note; 1001 } 1002 1003 /* ---------- Sleepfunctionaliteit ---------- 1004 Het hele blokje is versleepbaar met de linkermuisknop ingedrukt. 1005 Indrukken en loslaten zonder beweging telt als klik (onTap). */ 1006 function enableDrag(note, surface, onTap){ 1007 let startX, startY, origLeft, origTop, dragging = false, moved = false; 1008 1009 surface.addEventListener('pointerdown', function(e){ 1010 if(e.button !== 0) return; // alleen de linkermuisknop sleept 1011 e.preventDefault(); 1012 dragging = true; 1013 moved = false; 1014 startX = e.clientX; 1015 startY = e.clientY; 1016 origLeft = note.offsetLeft; 1017 origTop = note.offsetTop; 1018 note.style.zIndex = 1000; 1019 note.dataset.dragging = 'true'; 1020 surface.setPointerCapture(e.pointerId); 1021 }); 1022 1023 surface.addEventListener('pointermove', function(e){ 1024 if(!dragging) return; 1025 const dx = e.clientX - startX; 1026 const dy = e.clientY - startY; 1027 if(!moved && (Math.abs(dx) > 3 || Math.abs(dy) > 3)){ moved = true; } 1028 if(!moved) return; 1029 1030 let newLeft = origLeft + dx; 1031 let newTop = origTop + dy; 1032 1033 // binnen het whiteboard houden 1034 const maxLeft = whiteboard.clientWidth - note.offsetWidth; 1035 const maxTop = whiteboard.clientHeight - note.offsetHeight; 1036 newLeft = Math.max(0, Math.min(newLeft, maxLeft)); 1037 newTop = Math.max(0, Math.min(newTop, maxTop)); 1038 1039 note.style.left = newLeft + 'px'; 1040 note.style.top = newTop + 'px'; 1041 }); 1042 1043 function endDrag(e){ 1044 if(!dragging) return; 1045 dragging = false; 1046 note.style.zIndex = 10; 1047 try{ surface.releasePointerCapture(e.pointerId); }catch(_){} 1048 if(!moved){ 1049 if(typeof onTap === 'function'){ onTap(); } // gewone klik -> icoon wisselen 1050 }else{ 1051 note.dataset.dragging = 'false'; 1052 anchorNoteToNearestCell(note); // vastzetten in één van de 12 vakken 1053 autoSave(); // verplaatsing direct opslaan 1054 } 1055 note.dataset.dragging = 'false'; 1056 } 1057 surface.addEventListener('pointerup', endDrag); 1058 surface.addEventListener('pointercancel', endDrag); 1059 } 1060 1061 /* ---------- Invoer afhandelen ---------- */ 1062 function handleAdd(){ 1063 const text = courseInput.value.trim(); 1064 if(!text) { courseInput.focus(); return; } 1065 addNote(text); 1066 courseInput.value = ''; 1067 window.toolkitState.write({ courseInput: '' }); 1068 courseInput.focus(); 1069 } 1070 courseInput.addEventListener('input', function(){ 1071 window.toolkitState.write({ courseInput: courseInput.value }); 1072 }); 1073 1074 addBtn.addEventListener('click', handleAdd); 1075 courseInput.addEventListener('keydown', function(e){ 1076 if(e.key === 'Enter') handleAdd(); 1077 }); 1078 1079 /* ---------- Instellingen: jaren tonen/verbergen ---------- */ 1080 settingsBtn.addEventListener('click', function(e){ 1081 e.stopPropagation(); 1082 settingsMenu.classList.toggle('open'); 1083 }); 1084 settingsMenu.addEventListener('click', function(e){ e.stopPropagation(); }); 1085 document.addEventListener('click', function(){ settingsMenu.classList.remove('open'); }); 1086 1087 const yearBoxes = Array.prototype.slice.call(settingsMenu.querySelectorAll('input[type=checkbox]')); 1088 1089 function applyYear(cb){ 1090 const year = cb.getAttribute('data-year'); 1091 board.querySelectorAll('[data-year="'+year+'"]').forEach(function(c){ 1092 c.style.display = cb.checked ? '' : 'none'; 1093 });
1094 } 1095 1096 function saveYears(){ 1097 const years = {}; 1098 yearBoxes.forEach(function(cb){ years[cb.getAttribute('data-year')] = cb.checked; }); 1099 window.toolkitState.write({ years: years }); 1100 } 1101 1102 function restoreYears(){ 1103 const years = window.toolkitState.read().years; 1104 if(!years) return; 1105 yearBoxes.forEach(function(cb){ 1106 const year = cb.getAttribute('data-year'); 1107 if(typeof years[year] === 'boolean') cb.checked = years[year]; 1108 applyYear(cb); 1109 }); 1110 } 1111 1112 yearBoxes.forEach(function(cb){ 1113 cb.addEventListener('change', function(){ 1114 applyYear(cb); 1115 saveYears(); 1116 scheduleLayout(); 1117 }); 1118 }); 1119 1120 /* ---------- Opslaan & laden via een bestand op de harde schijf ---------- */ 1121 const saveBtn = document.getElementById('saveBtn'); 1122 const loadBtn = document.getElementById('loadBtn'); 1123 const fileInput = document.getElementById('fileInput'); 1124 const toast = document.getElementById('toast'); 1125 let toastTimer; 1126 1127 function showToast(msg){ 1128 toast.textContent = msg; 1129 toast.classList.add('show'); 1130 clearTimeout(toastTimer); 1131 toastTimer = setTimeout(function(){ toast.classList.remove('show'); }, 1900); 1132 } 1133 1134 function collectNotes(){ 1135 return Array.prototype.map.call( 1136 whiteboard.querySelectorAll('.note'), 1137 function(n){ 1138 return { 1139 text: n.dataset.text || '', 1140 left: parseInt(n.style.left, 10) || 0, 1141 top: parseInt(n.style.top, 10) || 0, 1142 state: parseInt(n.dataset.state, 10) || 0, 1143 year: n.dataset.year || '1', 1144 level: n.dataset.level || 'groen', 1145 xRatio: parseFloat(n.dataset.xRatio) || 0.5, 1146 yRatio: parseFloat(n.dataset.yRatio) || 0.5 1147 }; 1148 } 1149 ); 1150 } 1151 1152 // ----- Automatisch opslaan (lokaal in de browser) bij elke wijziging ----- 1153 const AUTOSAVE_KEY = 'toetsscan_autosave'; 1154 let suppressSave = false; 1155 1156 function autoSave(){ 1157 if(suppressSave) return; 1158 try{ localStorage.setItem(AUTOSAVE_KEY, JSON.stringify(collectNotes())); }catch(e){} 1159 } 1160 1161 function autoRestore(){ 1162 let raw = null; 1163 try{ raw = localStorage.getItem(AUTOSAVE_KEY); }catch(e){} 1164 if(!raw) return; 1165 let data; 1166 try{ data = JSON.parse(raw); }catch(e){ return; } 1167 if(!Array.isArray(data)) return; 1168 suppressSave = true; 1169 data.forEach(function(d){ 1170 addNote(d.text, { 1171 left:d.left, 1172 top:d.top, 1173 year:d.year, 1174 level:d.level, 1175 xRatio:d.xRatio, 1176 yRatio:d.yRatio, 1177 state:(typeof d.state==='number' ? d.state : d.count) 1178 }); 1179 }); 1180 suppressSave = false; 1181 autoSave(); // migreert oude pixelposities direct naar vakvaste posities 1182 } 1183 1184 function saveBoard(){ 1185 const data = collectNotes(); 1186 const payload = { app:'toetsscan', version:3, positioning:'year-level-relative', notes:data }; 1187 const blob = new Blob([JSON.stringify(payload, null, 2)], { type:'application/json' }); 1188 const url = URL.createObjectURL(blob); 1189 const a = document.createElement('a'); 1190 a.href = url; 1191 a.download = 'toetsscan.json'; 1192 document.body.appendChild(a); 1193 a.click(); 1194 document.body.removeChild(a); 1195 setTimeout(function(){ URL.revokeObjectURL(url); }, 1000); 1196 showToast(data.length + ' blokje(s) opgeslagen naar bestand.'); 1197 } 1198 1199 function loadBoard(){ 1200 fileInput.value = ''; // zodat hetzelfde bestand opnieuw gekozen kan worden 1201 fileInput.click(); 1202 } 1203 1204 fileInput.addEventListener('change', function(){ 1205 const file = fileInput.files && fileInput.files[0]; 1206 if(!file) return; 1207 const reader = new FileReader(); 1208 reader.onload = function(){ 1209 let parsed; 1210 try{ parsed = JSON.parse(reader.result); } 1211 catch(e){ showToast('Laden mislukt: geen geldig bestand.'); return; } 1212 const data = Array.isArray(parsed) ? parsed : ((parsed && parsed.notes) || []); 1213 whiteboard.querySelectorAll('.note').forEach(function(n){ n.remove(); }); 1214 cascade = 0; 1215 suppressSave = true; 1216 data.forEach(function(d){ 1217 addNote(d.text, { 1218 left:d.left, 1219 top:d.top, 1220 year:d.year, 1221 level:d.level, 1222 xRatio:d.xRatio, 1223 yRatio:d.yRatio, 1224 state:(typeof d.state==='number' ? d.state : d.count) 1225 }); 1226 }); 1227 suppressSave = false; 1228 autoSave(); 1229 showToast(data.length + ' blokje(s) geladen.'); 1230 }; 1231 reader.readAsText(file); 1232 }); 1233 1234 saveBtn.addEventListener('click', saveBoard); 1235 loadBtn.addEventListener('click', loadBoard); 1236 1237 /* ---------- Info-modal ---------- */ 1238 infoBtn.addEventListener('click', function(){ infoModal.classList.add('open'); }); 1239 closeInfo.addEventListener('click', function(){ infoModal.classList.remove('open'); }); 1240 infoModal.addEventListener('click', function(e){
1241 if(e.target === infoModal) infoModal.classList.remove('open'); 1242 }); 1243 1244 /* ---------- Inschattingsmatrix-modal (via de 'i' achter de balken) ---------- */ 1245 const matrixModal = document.getElementById('matrixModal'); 1246 const closeMatrix = document.getElementById('closeMatrix'); 1247 1248 document.querySelectorAll('.info-i').forEach(function(btn){ 1249 btn.addEventListener('click', function(e){ 1250 e.stopPropagation(); 1251 const lvl = btn.getAttribute('data-level'); 1252 document.querySelectorAll('.matrix-col').forEach(function(c){ 1253 c.classList.toggle('highlight', c.getAttribute('data-level') === lvl); 1254 }); 1255 matrixModal.classList.add('open'); 1256 }); 1257 }); 1258 closeMatrix.addEventListener('click', function(){ matrixModal.classList.remove('open'); }); 1259 matrixModal.addEventListener('click', function(e){ 1260 if(e.target === matrixModal) matrixModal.classList.remove('open'); 1261 }); 1262 1263 document.addEventListener('keydown', function(e){ 1264 if(e.key === 'Escape'){ 1265 infoModal.classList.remove('open'); 1266 matrixModal.classList.remove('open'); 1267 } 1268 }); 1269 1270 /* ---------- Responsief herpositioneren ---------- 1271 Elk blokje blijft gekoppeld aan hetzelfde jaar en dezelfde kleurzone. 1272 Alleen de pixelpositie wordt opnieuw berekend wanneer het bord verandert. */ 1273 window.addEventListener('resize', scheduleLayout); 1274 window.addEventListener('toetsscan:layout', scheduleLayout); 1275 if(typeof ResizeObserver !== 'undefined'){ 1276 const boardResizeObserver = new ResizeObserver(scheduleLayout); 1277 boardResizeObserver.observe(whiteboard); 1278 boardResizeObserver.observe(board); 1279 } 1280 1281 /* ---------- Automatisch herstellen van de laatst opgeslagen staat ---------- */ 1282 restoreYears(); 1283 const savedCourseInput = window.toolkitState.read().courseInput; 1284 if(typeof savedCourseInput === 'string') courseInput.value = savedCourseInput; 1285 autoRestore(); 1286 scheduleLayout(); 1287 1288})(); 1289</script>
1289 1290 </section> 1291 1292 <section class="app-panel" id="panel-flowchart" role="tabpanel" aria-labelledby="tab-flowchart" hidden> 1293 <iframe class="embedded-page" title="Flowchart AI, curriculum en toetsing" srcdoc="<!DOCTYPE html> 1294<html lang="nl"> 1295<head> 1296<meta charset="UTF-8"> 1297<meta name="viewport" content="width=device-width, initial-scale=1.0"> 1298<title>Toolkit 'AI, curriculum en toetsing' â Flowchart AI-bewust toetsen</title> 1299<style> 1300 :root{ 1301 --brand:#E2004B; 1302 --brand-dark:#C50040; 1303 --ink:#1a1a1a; 1304 --line:#d0d0d0; 1305 --triangle:#7a7a7a; 1306 --box-border:#f3b9cd; 1307 --bg:#ffffff; 1308 --warn:#f6b500; 1309 } 1310 *{box-sizing:border-box;} 1311 html{ -webkit-text-size-adjust:100%; } 1312 body{ 1313 margin:0; 1314 font-family:"Segoe UI","Nunito",Verdana,Arial,sans-serif; 1315 color:var(--ink); 1316 background:#eef0f2; 1317 line-height:1.4; 1318 } 1319 .sheet{ 1320 max-width:1180px; 1321 margin:24px auto; 1322 background:var(--bg); 1323 padding:28px 32px 40px; 1324 box-shadow:0 2px 14px rgba(0,0,0,.12); 1325 border-radius:6px; 1326 } 1327 1328 /* ---------- Header ---------- */ 1329 .top{ 1330 display:flex; 1331 justify-content:space-between; 1332 align-items:flex-start; 1333 gap:24px; 1334 } 1335 h1{ 1336 font-size:24px; 1337 margin:0 0 14px; 1338 font-weight:800; 1339 color:var(--brand); 1340 } 1341 h1 .black{ color:var(--ink); } 1342 .logo{ 1343 flex:0 0 auto; 1344 width:66px;height:66px; 1345 } 1346 .logo svg{ width:100%; height:100%; display:block; } 1347 .logo .lg-bg{ fill:var(--brand); } 1348 .intro{ font-size:14.5px; margin:0 0 16px; max-width:960px; } 1349 .intro strong{ font-weight:800; } 1350 1351 .warn{ 1352 display:flex; gap:10px; align-items:flex-start; 1353 font-size:12px; color:#444; 1354 border-left:4px solid var(--warn); 1355 background:#fffbe9; 1356 padding:10px 14px; 1357 border-radius:4px; 1358 margin-bottom:22px; 1359 max-width:960px; 1360 } 1361 .warn .ico{ font-size:18px; line-height:1; } 1362 1363 /* ---------- Rows ---------- */ 1364 .grid{ border:1px solid var(--line); border-radius:6px; overflow:hidden; } 1365 .row{ 1366 display:flex;
1367 align-items:stretch; 1368 gap:16px; 1369 padding:18px 16px; 1370 border-bottom:1px solid var(--line); 1371 } 1372 .row:last-child{ border-bottom:none; } 1373 1374 /* number + triangle column */ 1375 .stepcol{ flex:0 0 190px; display:flex; gap:8px; align-items:flex-start; } 1376 .stepno{ 1377 flex:0 0 auto; 1378 width:34px;height:34px;border-radius:50%; 1379 border:1px solid #bbb; background:#f3f3f3; 1380 display:flex;align-items:center;justify-content:center; 1381 font-weight:700; font-size:15px; 1382 } 1383 .triangle{ flex:1 1 auto; } 1384 .triangle svg{ width:100%; height:auto; display:block; } 1385 1386 /* the flow lane */ 1387 .flow{ 1388 flex:1 1 auto; 1389 display:flex; 1390 flex-wrap:wrap; 1391 align-items:center; 1392 gap:10px; 1393 } 1394 .box{ 1395 flex:1 1 160px; 1396 min-width:150px; 1397 border:1.5px solid var(--box-border); 1398 border-radius:14px; 1399 padding:12px 14px; 1400 font-size:12.5px; 1401 background:#fff; 1402 text-align:center; 1403 align-self:center; 1404 } 1405 .box.tight{ flex:1 1 150px; } 1406 .box strong{ font-weight:800; } 1407 .box .brandtext{ color:var(--brand); font-weight:800; } 1408 .box ol{ margin:6px 0 0; padding-left:18px; text-align:left; } 1409 .box ol li{ margin:2px 0; } 1410 1411 /* vertical stacks & branches */ 1412 .stack, .branch{ display:flex; flex-direction:column; gap:8px; flex:1 1 220px; min-width:180px; align-self:center; } 1413 /* inside a column, reset the row-oriented flex so children size to content */ 1414 .stack > .box, .stack > a.btn{ flex:0 0 auto; } 1415 .branch-row{ display:flex; align-items:stretch; gap:8px; } 1416 .branch-row .box, .branch-row a.btn{ flex:1 1 auto; } 1417 1418 /* buttons / links */ 1419 a.btn{ 1420 display:flex;
1421 align-items:center; 1422 justify-content:center; 1423 gap:8px; 1424 flex:1 1 170px; 1425 min-width:150px; 1426 text-decoration:none; 1427 background:var(--brand); 1428 color:#fff; 1429 font-weight:700; 1430 font-size:12.5px; 1431 text-align:center; 1432 border-radius:14px; 1433 padding:13px 14px; 1434 transition:background .15s ease, transform .05s ease; 1435 align-self:center; 1436 } 1437 a.btn{ 1438 cursor:pointer; 1439 position:relative; 1440 box-shadow:0 3px 8px rgba(226,0,75,.16); 1441 transition:background .15s ease,transform .15s ease,box-shadow .15s ease,outline-color .15s ease; 1442 } 1443 a.btn:hover{ 1444 background:var(--brand-dark); 1445 transform:translateY(-4px) scale(1.018); 1446 box-shadow:0 11px 24px rgba(197,0,64,.28); 1447 outline:3px solid rgba(226,0,75,.18); 1448 outline-offset:3px; 1449 } 1450 a.btn:focus-visible{ 1451 outline:4px solid rgba(226,0,75,.28); 1452 outline-offset:3px; 1453 } 1454 a.btn .chev{ 1455 display:inline-block; 1456 transition:transform .15s ease; 1457 } 1458 a.btn:hover .chev{transform:translateX(5px);} 1459 a.btn::before, 1460 a.box.toolkit-route::before{ 1461 content:'KLIK'; 1462 position:absolute; 1463 top:7px; 1464 right:9px; 1465 padding:3px 6px; 1466 border-radius:8px; 1467 font-size:9px; 1468 font-weight:900; 1469 letter-spacing:.5px; 1470 line-height:1; 1471 opacity:0; 1472 transform:translateY(-5px); 1473 transition:opacity .15s ease,transform .15s ease; 1474 pointer-events:none; 1475 } 1476 a.btn::before{ 1477 background:#fff; 1478 color:var(--brand); 1479 } 1480 a.box.toolkit-route::before{ 1481 background:var(--brand); 1482 color:#fff; 1483 } 1484 a.btn:hover::before, 1485 a.box.toolkit-route:hover::before{ 1486 opacity:1; 1487 transform:translateY(0); 1488 } 1489 a.box.toolkit-route{ 1490 color:var(--ink); 1491 text-decoration:none; 1492 cursor:pointer; 1493 position:relative; 1494 box-shadow:0 2px 6px rgba(0,0,0,.05); 1495 transition:border-color .15s ease,box-shadow .15s ease,background .15s ease,transform .15s ease; 1496 } 1497 a.box.toolkit-route:hover{ 1498 border-color:var(--brand); 1499 background:#fff8fb; 1500 transform:translateY(-4px) scale(1.018); 1501 box-shadow:0 11px 24px rgba(197,0,64,.2); 1502 outline:3px solid rgba(226,0,75,.16); 1503 outline-offset:3px; 1504 } 1505 a.box.toolkit-route:focus-visible{ 1506 outline:4px solid rgba(226,0,75,.28); 1507 outline-offset:3px; 1508 } 1509 a.btn:active{ transform:translateY(1px); } 1510 a.btn .chev{ font-weight:900; } 1511 1512 /* arrows */ 1513 .arr{ flex:0 0 auto; display:flex; align-items:center; } 1514 .arr.r{ } 1515 .arr.r .stem{ width:14px;height:9px;background:var(--brand); } 1516 .arr.r .head{ 1517 width:0;height:0; 1518 border-top:11px solid transparent; 1519 border-bottom:11px solid transparent; 1520 border-left:16px solid var(--brand); 1521 } 1522 .arr.d{ flex-direction:column; align-self:center; margin:0 auto; } 1523 .arr.d .stem{ width:9px;height:12px;background:var(--brand); } 1524 .arr.d .head{ 1525 width:0;height:0; 1526 border-left:11px solid transparent; 1527 border-right:11px solid transparent; 1528 border-top:16px solid var(--brand); 1529 } 1530 1531 /* ---------- Verbeterde driehoekdiagrammen ---------- */ 1532 .sheet{position:relative;} 1533 .intro{ 1534 max-width:none; 1535 padding-right:0; 1536 min-height:0; 1537 padding-top:0; 1538 } 1539 .stepcol{ 1540 flex:0 0 220px; 1541 position:relative; 1542 display:flex;
1543 align-items:center; 1544 justify-content:center; 1545 padding:0 6px 0 40px; 1546 min-height:170px; 1547 } 1548 .stepno{ 1549 position:absolute; 1550 left:0; 1551 top:0; 1552 } 1553 .triangle{ 1554 flex:0 0 174px; 1555 width:174px; 1556 max-width:174px; 1557 } 1558 .triangle svg{ 1559 width:174px; 1560 height:auto; 1561 overflow:visible; 1562 } 1563 .diagram-label text{ 1564 fill:#333; 1565 font-family:"Segoe UI","Nunito",Verdana,Arial,sans-serif; 1566 font-size:16px; 1567 font-weight:600; 1568 text-anchor:middle; 1569 } 1570 .diagram-label rect{ 1571 fill:#fff; 1572 stroke:transparent; 1573 stroke-width:3; 1574 } 1575 .diagram-label.selected rect{stroke:var(--brand);} 1576 .diagram-label.selected text{ 1577 fill:#222; 1578 font-weight:800; 1579 } 1580 1581 /* ---------- Responsive ---------- */ 1582 @media (max-width:860px){ 1583 .sheet{ padding:20px 16px 28px; } 1584 .intro{padding-right:0;} 1585 .row{ flex-direction:column; } 1586 .stepcol{ flex-basis:auto; align-self:center; } 1587 .triangle{ max-width:220px; } 1588 .flow{ flex-direction:column; align-items:stretch; } 1589 .box, a.btn{ flex-basis:auto; } 1590 .branch, .stack{ flex-basis:auto; } 1591 .arr.r{ transform:rotate(90deg); align-self:center; } 1592 } 1593 @media print{ 1594 body{ background:#fff; } 1595 .sheet{ box-shadow:none; margin:0; max-width:100%; } 1596 a.btn{ -webkit-print-color-adjust:exact; print-color-adjust:exact; } 1597 } 1598</style> 1599</head> 1600<body> 1601<div class="sheet"> 1602 1603 1604 1605 <p class="intro"> 1606 Het doel van deze flowchart is om je curriculum en toetsing AI-bewuster te maken. Deze flowchart start vanuit het perspectief van een <strong>individuele cursus</strong>. 1607 Bij het gebruik van de flowchart zul je echter ook naar de positionering van de cursus binnen een leerlijn of volledig curriculum moeten kijken. 1608 </p> 1609 1610 <div class="warn"> 1611 <span class="ico">â ï¸</span> 1612 <span><strong>Let op:</strong> Informatie die je in een generatieve AI-chatbot plaatst kan door training van nieuwe modellen openbaar gemaakt worden. Voer daarom nooit beschermde of geheime informatie, zoals tentamenvragen, in. Bekijk ook kritisch de Generatieve AI Doâs en Donâts van Hogeschool Rotterdam (zie toolkit).</span> 1613 </div> 1614 1615 <div class="grid"> 1616 1617 <!-- ================= ROW 1 : Leerdoelen ================= --> 1618 <div class="row"> 1619 <div class="stepcol"> 1620 <div class="stepno">1</div> 1621 <div class="triangle"> 1622 1623 <svg viewBox="0 0 260 205" role="img" aria-label="Driehoek met Leerdoelen omcirkeld"> 1624 <polygon points="130,50 42,158 218,158" fill="none" stroke="var(--triangle)" stroke-width="2.5"/> 1625 <g class="diagram-label selected"> 1626 <rect x="75" y="6" width="110" height="32" rx="16"/> 1627 <text x="130" y="27">Leerdoelen</text> 1628 </g> 1629 <g class="diagram-label"> 1630 <text x="47" y="190">Leeractiviteiten</text> 1631 </g> 1632 <g class="diagram-label"> 1633 <text x="215" y="190">Toetsing</text> 1634 </g> 1635 </svg> 1636 </div> 1637 </div> 1638 1639 <div class="flow"> 1640 <div class="box"> 1641 Noteer de leerdoelen van de cursus. Noteer ook de leerdoelen van vergelijkbare cursussen die <strong>voor</strong> of <strong>na</strong> deze cursus komen. 1642 Analyseer welke onderdelen concentrisch zijn (herhalend en verdiepend terugkomen). 1643 </div> 1644 1645 <div class="arr r"><span class="stem"></span><span class="head"></span></div> 1646 1647 <div class="box"> 1648 Analyseer de leerdoelen van je cursus. Moeten er vanwege generatieve AI 1649 <ol type="A"> 1650 <li>leerdoelen verdwijnen?</li> 1651 <li>leerdoelen worden aangepast?</li> 1652 <li>leerdoelen worden toegevoegd?</li> 1653 </ol> 1654 </div> 1655 1656 <div class="arr r"><span class="stem"></span><span class="head"></span></div> 1657 1658 <div class="stack"> 1659 <div class="box"> 1660 <strong>Let op:</strong> Als je leerdoelen verwijdert, aanpast of toevoegt, heeft dit gevolgen voor de toetsing en leeractiviteiten én voor eerdere of latere cursussen. 1661 </div> 1662 <div class="arr d"><span class="stem"></span><span class="head"></span></div> 1663 <a class="btn" href="#" data-open-card-category="0"> 1664 Ga met betrokken collegaâs in gesprek. Open de gesprekskaarten: <span class="chev">âº</span> 1665 </a> 1666 </div> 1667 </div> 1668 </div> 1669 1670 <!-- ================= ROW 2 : Toetsing ================= --> 1671 <div class="row"> 1672 <div class="stepcol"> 1673 <div class="stepno">2</div> 1674 <div class="triangle"> 1675 1676 <svg viewBox="0 0 260 205" role="img" aria-label="Driehoek met Toetsing omcirkeld"> 1677 <polygon points="130,50 42,158 218,158" fill="none" stroke="var(--triangle)" stroke-width="2.5"/> 1678 <g class="diagram-label"> 1679 <text x="130" y="27">Leerdoelen</text> 1680 </g> 1681 <g class="diagram-label"> 1682 <text x="47" y="190">Leeractiviteiten</text> 1683 </g> 1684 <g class="diagram-label selected"> 1685 <rect x="174" y="165" width="82" height="32" rx="16"/> 1686 <text x="215" y="187">Toetsing</text> 1687 </g> 1688 </svg> 1689 </div> 1690 </div> 1691 1692 <div class="flow"> 1693 <div class="box tight"> 1694 Stap in de schoenen van je student die de toetsing van je cursus moet doorlopen. Probeer de toetsing zoveel mogelijk door generatieve AI te laten doen. 1695 <div style="margin-top:8px;">â ï¸ <strong>Wat valt je op?</strong></div> 1696 </div> 1697 1698 <div class="arr r"><span class="stem"></span><span class="head"></span></div> 1699 1700 <div class="branch"> 1701 <div class="branch-row"> 1702 <div class="box"> 1703 Er zijn <span class="brandtext">onbenutte kansen</span> om generatieve AI in te zetten bij deze toetsing. 1704 </div> 1705 <div class="arr r"><span class="stem"></span><span class="head"></span></div> 1706 <a class="btn" href="#" data-open-card-category="1"> 1707 Ga met betrokken collegaâs in gesprek. Open de gesprekskaarten: <span class="chev">âº</span> 1708 </a> 1709 </div> 1710 1711 <div class="branch-row"> 1712 <div class="box"> 1713 Er zijn <span class="brandtext">risicoâs</span> dat je student door onverantwoord gebruik van generatieve AI de kennis, vaardigheden en attitudes niet zelf heeft verworven. 1714 </div> 1715 <div class="arr r"><span class="stem"></span><span class="head"></span></div> 1716 <a class="btn" href="#" data-open-card-category="2"> 1717 Ga met betrokken collegaâs in gesprek. Open de gesprekskaarten: <span class="chev">âº</span> 1718 </a> 1719 </div> 1720 </div> 1721 </div> 1722 </div> 1723 1724 <!-- ================= ROW 3 : Leeractiviteiten ================= --> 1725 <div class="row"> 1726 <div class="stepcol"> 1727 <div class="stepno">3</div> 1728 <div class="triangle"> 1729 1730 <svg viewBox="0 0 260 205" role="img" aria-label="Driehoek met Leeractiviteiten omcirkeld"> 1731 <polygon points="130,50 42,158 218,158" fill="none" stroke="var(--triangle)" stroke-width="2.5"/> 1732 <g class="diagram-label"> 1733 <text x="130" y="27">Leerdoelen</text> 1734 </g> 1735 <g class="diagram-label selected"> 1736 <rect x="2" y="165" width="116" height="32" rx="16"/> 1737 <text x="60" y="187">Leeractiviteiten</text> 1738 </g> 1739 <g class="diagram-label"> 1740 <text x="215" y="190">Toetsing</text> 1741 </g> 1742 </svg> 1743 </div> 1744 </div> 1745 1746 <div class="flow"> 1747 <div class="box"> 1748 Bedenk welke leeractiviteiten goed passen bij de kennis, vaardigheden en attitudes die je studenten moeten verwerven. 1749 Kijk of ze goed aansluiten bij de leerdoelen en toetsing van de cursus. 1750 </div> 1751 1752 <div class="arr r"><span class="stem"></span><span class="head"></span></div> 1753 1754 <div class="box"> 1755 Bedenk op welke manier je generatieve AI kunt gebruiken in leeractiviteiten <strong>voor</strong>, <strong>tijdens</strong> en <strong>na</strong> het lesmoment. 1756 Bespreek na de leeractiviteiten de (on)mogelijkheden en (on)wenselijkheden van generatieve AI. 1757 </div> 1758 1759 <div class="arr r"><span class="stem"></span><span class="head"></span></div> 1760 1761 <div class="stack"> 1762 <a class="box toolkit-route" href="#" data-open-toolkit-page="https://maken.wikiwijs.nl/223515/Toolkit__AI__curriculum_en_toetsing_#!page-8674017"> 1763 Je kunt een generatieve AI-chatbot vragen om inspirerende werkvormen met AI, óf: 1764 </a> 1765 <div class="arr d"><span class="stem"></span><span class="head"></span></div> 1766 <a class="btn" href="#" data-open-toolkit-page="https://maken.wikiwijs.nl/223515/Toolkit__AI__curriculum_en_toetsing_#!page-8674019"> 1767 Bekijk ons boekje â60 laagdrempelige werkvormen met AIâ <span class="chev">âº</span> 1768 </a> 1769 </div> 1770 </div> 1771 </div> 1772 1773 </div><!-- /grid --> 1774</div><!-- /sheet --> 1775<script> 1776 document.querySelectorAll('[data-open-card-category]').forEach(function(link){ 1777 link.addEventListener('click', function(event){ 1778 event.preventDefault(); 1779 parent.postMessage({ 1780 source:'toetsscan-flowchart', 1781 action:'open-card-category', 1782 category:Number(link.getAttribute('data-open-card-category')) 1783 }, '*'); 1784 });
1785 }); 1786 document.querySelectorAll('[data-open-toolkit-page]').forEach(function(link){ 1787 link.addEventListener('click', function(event){ 1788 event.preventDefault(); 1789 parent.postMessage({ 1790 source:'toetsscan-flowchart', 1791 action:'open-toolkit-page', 1792 url:link.getAttribute('data-open-toolkit-page') 1793 }, '*'); 1794 }); 1795 }); 1796</script> 1797</body> 1798</html> 1799"></iframe> 1800 </section> 1801 1802 <section class="app-panel" id="panel-cards" role="tabpanel" aria-labelledby="tab-cards" hidden> 1803 <div class="cards-shell"> 1804 <header class="cards-header"> 1805 <h2>Gesprekskaarten</h2> 1806 <div class="card-categories" role="tablist" aria-label="Categorieën gesprekskaarten"> 1807 <button class="card-category" type="button" role="tab" aria-selected="true">Leerdoelen herzien</button> 1808 <button class="card-category" type="button" role="tab" aria-selected="false" tabindex="-1">Kansen van generatieve AI benutten</button> 1809 <button class="card-category" type="button" role="tab" aria-selected="false" tabindex="-1">Toetsing herzien</button> 1810 </div> 1811 </header> 1812 1813 <div class="card-warning" id="cardWarning" role="note" hidden> 1814 Houd goed in de gaten dat onderwijs en toetsing haalbaar, uitvoerbaar, betaalbaar, organiseerbaar en studeerbaar moeten blijven. 1815 </div> 1816 1817 <article class="conversation-card" aria-live="polite" aria-atomic="true"> 1818 <div class="card-content"> 1819 <div class="card-kicker">GESPREKSKAART</div> 1820 <h3 id="cardQuestion"></h3> 1821 <p id="cardSubtext" hidden></p> 1822 </div> 1823 <div class="card-counter" id="cardCounter"></div> 1824 </article> 1825 1826 <nav class="card-navigation" aria-label="Navigatie door gesprekskaarten"> 1827 <button id="previousCard" type="button"><span aria-hidden="true">â</span> Vorige</button> 1828 <button id="nextCard" type="button">Volgende <span aria-hidden="true">â</span></button> 1829 </nav> 1830 </div> 1831 </section> 1832 </main> 1833 1834
1835<script> 1836(function(){ 1837 "use strict"; 1838 const scanHeader = document.querySelector('#panel-scan > header'); 1839 const scanToolbar = document.querySelector('#panel-scan > .toolbar'); 1840 if(scanHeader && scanToolbar){ 1841 const scanActions = scanHeader.querySelector('.header-actions'); 1842 if(scanActions) scanToolbar.appendChild(scanActions); 1843 scanHeader.remove(); 1844 } 1845 1846 const tabs = Array.prototype.slice.call(document.querySelectorAll('.app-tab')); 1847 const panels = Array.prototype.slice.call(document.querySelectorAll('.app-panel')); 1848 const conversationCards = [{"title":"Leerdoelen herzien","cards":[{"question":"Welke aspecten van de beroepspraktijk die deze cursus raken worden niet beïnvloed door (generatieve) AI?"},{"question":"Welke aspecten van deze cursus moeten AI-vrij blijven (en kun je dat onderbouwen op meer dan alleen intuïtie)?"},{"question":"Welke aspecten van de beroepspraktijk die deze cursus raken veranderen volledig door de mogelijkheden die (generatieve) AI biedt?"},{"question":"Welke aspecten van de beroepspraktijk die deze cursus raken veranderen deels door de mogelijkheden die (generatieve) AI biedt?"},{"question":"Hoe verhouden de nieuwe mogelijkheden van (generatieve) AI zich tot de leerdoelen van deze cursus en verwante eerdere en latere cursussen in je curriculum?"},{"question":"In welke mate moeten je studenten (generatieve) AI leren gebruiken als een hulpmiddel binnen hun vakgebied? Wat moeten ze dan kunnen met (generatieve) AI?"},{"question":"Welke ethische vraagstukken rondom het gebruik van (generatieve) AI zijn relevant voor de beroepspraktijk van je studenten? Hoe kun je daarop inspelen in je onderwijs?"},{"question":"Wat betekent de inzet van (generatieve) AI voor de creatieve en innovatieve vaardigheden van je studenten? Hoe stimuleren we hun eigen denkwerk ondanks AI-mogelijkheden?"},{"question":"Je onderwijs, curriculum en toetsing afstemmen op de hu
1848idige beroepspraktijk maakt je onderwijs toekomstbestendig. Hoe kun je als opleiding ook (deels) toekomstbepalend zijn? De toekomstige beroepspraktijk kijkt immers ook naar nieuwe generaties voor innovatie."}]},{"title":"Kansen van generatieve AI benutten","cards":[{"question":"Waar zie je een toegevoegde waarde van generatieve AI in de beroepspraktijk van je student? Hoe kun je jouw studenten daar in deze cursus (inclusief toetsing) al kritisch kennis mee laten maken? Wat is daarvoor nodig?"},{"question":"Welke kennis, vaardigheden en attitudes hebben je studenten nodig om de output en inzet van generatieve AI in hun beroep op waarde te kunnen schatten? Wat is daarvan relevant voor deze cursus?"},{"question":"Op welke manier kan generatieve AI je student helpen om de kennis, vaardigheden en attitudes van deze cursus te verwerven?"},{"question":"Met welke werkvormen kun je studenten laten werken aan de kennis, vaardigheden en attitudes van deze cursus?","subtext":"Tip: Boekje â60 laagdrempelige werkvormen met AIâ"},{"question":"Hoe kun jij als docent het goede voorbeeld geven met generatieve AI?"},{"question":"Hoe kun je jouw studenten helpen om de risico's van de inzet van generatieve AI bij het onderwerp van deze cursus te managen?"},{"question":"Weet jij hoe je collega's studenten helpen om de kansen van generatieve AI te benutten?"}]},{"title":"Toetsing herzien","cards":[{"question":"Kunnen de kennis, vaardigheden en attitudes van je cursus via een âPerformance assessmentâ worden getoetst?","subtext":"Een performance assessment is een manier van toetsen waarin je student de kennis, vaardigheden en attitudes in een echte of gesimuleerde (beroeps)situatie aantoont."},{"question":"Is er een mogelijkheid om de leerdoelen te toetsen met een toets onder toezicht op locatie?","subtext":"Via digitale toetsplatformen ANS en Schoolyear is het mogelijk om uitgebreide casuïstiek aan te bieden waarin zowel internet als (generatieve) AI (deels) worden aangezet of uitgezet. Je kunt dan ook meerdere (PDF) bestanden aanleveren waar studenten veilig digitaal mee aan de slag moeten. Enkel toegang tot PubMed of Google Scholar is ook een optie."},{"question":"Zijn er mogelijkheden om de beoordeling meer te richten op het proces dan nu gebeurt?"},{"question":"Op welke formatieve manier kan er in deze toetsing verder gekeken worden naar het proces in plaats van naar het eindproduct?"},{"question":"Is het mogelijk en/of wenselijk om een criteriumgericht interview of een mondelinge component toe te voegen aan de toetsing?"},{"question":"Is het een mogelijkheid dat de beoordeling van deze toets (deels) door een extern iemand (werkplekbegeleider / stagebegeleider) wordt gedaan? Kan een werkplekbegeleider of stagebegeleider verifiëren dat bepaalde acties, beweringen en/of bewijsvoering waar zijn?","subtext":"Als een werkplekbegeleider een deel van de beoordeling uitvoert en daarmee een summatieve rol heeft, moet deze worden aangewezen als externe examinator. Wanneer de werkplekbegeleider uitsluitend een verificatierol heeft, wordt deze formatief ingezet en is er geen sprake van een beoordelaarsrol in de zin van examinator."},{"question":"Hoe kun je studenten verplichten om expliciete evaluaties te maken van gebruikte bronnen, waardoor kritische reflectie op AI-gegenereerde inhoud noodzakelijk wordt?"},{"question":"Op welke manier zou je gebruik kunnen maken van video-opnames in de toetsing van deze opdracht?"},{"question":"Hoe is deze toets gepositioneerd in een eventuele leerlijn of het gehele toetsprogramma?","subtext":"Is het mogelijk om (delen van) de inhoud van deze toets naar een toets die later in het curriculum zit te verplaatsen? De overgebleven onderdelen van deze toets kunnen dan mogelijk op een andere manier getoetst worden."},{"question":"Hoe maak je duidelijk / ga je duidelijk maken hoe studenten generatieve AI mogen gebruiken bij deze cursus?","subtext":"Weet jij wat je collegaâs toestaan of verbieden rondom AI? Weten je studenten dat ook?"}]}]; 1849 const categoryButtons = Array.prototype.slice.call(document.querySelectorAll('.card-category')); 1850 const cardQuestion = document.getElementById('cardQuestion'); 1851 const cardSubtext = document.getElementById('cardSubtext'); 1852 const cardCounter = document.getElementById('cardCounter'); 1853 const cardWarning = document.getElementById('cardWarning'); 1854 const previousCard = document.getElementById('previousCard'); 1855 const nextCard = document.getElementById('nextCard'); 1856 const toolkitFrame = document.querySelector('#panel-toolkit iframe'); 1857 const flowchartFrame = document.querySelector('#panel-flowchart iframe'); 1858 const savedUI = window.toolkitState.read(); 1859 let activeCategory = 0; 1860 let activeCard = 0; 1861 1862 if(Number.isInteger(savedUI.cardCategory) && savedUI.cardCategory >= 0 && savedUI.cardCategory < conversationCards.length){ 1863 activeCategory = savedUI.cardCategory; 1864 } 1865 if(Number.isInteger(savedUI.cardIndex) && savedUI.cardIndex >= 0 && savedUI.cardIndex < conversationCards[activeCategory].cards.length){ 1866 activeCard = savedUI.cardIndex; 1867 } 1868 1869 function renderConversationCard(){ 1870 const category = conversationCards[activeCategory]; 1871 const card = category.cards[activeCard]; 1872 categoryButtons.forEach(function(button, index){ 1873 const selected = index === activeCategory; 1874 button.setAttribute('aria-selected', selected ? 'true' : 'false'); 1875 button.tabIndex = selected ? 0 : -1; 1876 });
1877 cardQuestion.textContent = card.question; 1878 if(card.subtext){ 1879 cardSubtext.textContent = card.subtext; 1880 cardSubtext.hidden = false; 1881 }else{ 1882 cardSubtext.textContent = ''; 1883 cardSubtext.hidden = true; 1884 } 1885 cardCounter.textContent = (activeCard + 1) + ' van ' + category.cards.length; 1886 cardWarning.hidden = activeCategory !== 2; 1887 window.toolkitState.write({ cardCategory: activeCategory, cardIndex: activeCard }); 1888 } 1889 1890 categoryButtons.forEach(function(button, index){ 1891 button.addEventListener('click', function(){ 1892 activeCategory = index; 1893 activeCard = 0; 1894 renderConversationCard(); 1895 }); 1896 button.addEventListener('keydown', function(event){ 1897 if(event.key !== 'ArrowLeft' && event.key !== 'ArrowRight' && event.key !== 'Home' && event.key !== 'End') return; 1898 event.preventDefault(); 1899 let nextCategory = index; 1900 if(event.key === 'ArrowLeft') nextCategory = (index - 1 + categoryButtons.length) % categoryButtons.length; 1901 if(event.key === 'ArrowRight') nextCategory = (index + 1) % categoryButtons.length; 1902 if(event.key === 'Home') nextCategory = 0; 1903 if(event.key === 'End') nextCategory = categoryButtons.length - 1; 1904 activeCategory = nextCategory; 1905 activeCard = 0; 1906 renderConversationCard(); 1907 categoryButtons[nextCategory].focus(); 1908 }); 1909 }); 1910 1911 previousCard.addEventListener('click', function(){ 1912 const total = conversationCards[activeCategory].cards.length; 1913 activeCard = (activeCard - 1 + total) % total; 1914 renderConversationCard(); 1915 }); 1916 1917 nextCard.addEventListener('click', function(){ 1918 const total = conversationCards[activeCategory].cards.length; 1919 activeCard = (activeCard + 1) % total; 1920 renderConversationCard(); 1921 }); 1922 1923 function showPanel(panelId, focusTab){
1924 tabs.forEach(function(tab){ 1925 const active = tab.getAttribute('aria-controls') === panelId; 1926 tab.setAttribute('aria-selected', active ? 'true' : 'false'); 1927 tab.tabIndex = active ? 0 : -1; 1928 if(active && focusTab) tab.focus(); 1929 }); 1930 panels.forEach(function(panel){ 1931 const active = panel.id === panelId; 1932 panel.classList.toggle('active', active); 1933 panel.hidden = !active; 1934 }); 1935 if(panelId === 'panel-scan'){ 1936 window.dispatchEvent(new CustomEvent('toetsscan:layout')); 1937 } 1938 if(panelId === 'panel-cards') renderConversationCard(); 1939 window.toolkitState.write({ panel: panelId }); 1940 } 1941 1942 tabs.forEach(function(tab, index){ 1943 tab.addEventListener('click', function(){ 1944 showPanel(tab.getAttribute('aria-controls'), false); 1945 }); 1946 tab.addEventListener('keydown', function(event){ 1947 if(event.key !== 'ArrowLeft' && event.key !== 'ArrowRight' && event.key !== 'Home' && event.key !== 'End') return; 1948 event.preventDefault(); 1949 let next = index; 1950 if(event.key === 'ArrowLeft') next = (index - 1 + tabs.length) % tabs.length; 1951 if(event.key === 'ArrowRight') next = (index + 1) % tabs.length; 1952 if(event.key === 'Home') next = 0; 1953 if(event.key === 'End') next = tabs.length - 1; 1954 showPanel(tabs[next].getAttribute('aria-controls'), true); 1955 }); 1956 }); 1957 1958 window.addEventListener('message', function(event){ 1959 if(!flowchartFrame || event.source !== flowchartFrame.contentWindow) return; 1960 const message = event.data; 1961 if(!message || message.source !== 'toetsscan-flowchart') return; 1962 1963 if(message.action === 'open-card-category'){ 1964 const category = Number(message.category); 1965 if(!Number.isInteger(category) || category < 0 || category >= conversationCards.length) return; 1966 showPanel('panel-cards', false); 1967 activeCategory = category; 1968 activeCard = 0; 1969 renderConversationCard(); 1970 } 1971 1972 if(message.action === 'open-toolkit-page'){ 1973 const allowedPrefix = 'https://maken.wikiwijs.nl/223515/Toolkit__AI__curriculum_en_toetsing_'; 1974 if(typeof message.url !== 'string' || message.url.indexOf(allowedPrefix) !== 0) return; 1975 toolkitFrame.src = message.url; 1976 window.toolkitState.write({ toolkitUrl: message.url }); 1977 showPanel('panel-toolkit', false); 1978 } 1979 }); 1980 1981 const allowedToolkitPrefix = 'https://maken.wikiwijs.nl/223515/Toolkit__AI__curriculum_en_toetsing'; 1982 if(toolkitFrame && typeof savedUI.toolkitUrl === 'string' && savedUI.toolkitUrl.indexOf(allowedToolkitPrefix) === 0){ 1983 toolkitFrame.src = savedUI.toolkitUrl; 1984 } 1985 1986 renderConversationCard(); 1987 1988 const savedPanel = savedUI.panel; 1989 const knownPanel = panels.some(function(panel){ return panel.id === savedPanel; }); 1990 showPanel(knownPanel ? savedPanel : 'panel-scan', false); 1991})(); 1992</script>
1992 1993</body> 1994</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.