Herhalingsoefeningen
Herhalingsoefeningen
Op deze pagina worden extra oefeningen aangeboden die je kan gebruiken om je voor te bereiden op het examen. Kijk zeker ook naar voorbeeldexamen.
Startbestanden
Secret Santa
Voeg drie nieuwe pagina's toe aan de startbestanden, een homepagina, een pagina voor de deelnemers en een pagina waar een trekking gemaakt kan worden voor Secret Santa (of iets soortgelijks). Gebruik hiervoor onderstaande HTML-code.
Zorg er verder ook voor dat de cards of de home pagina de gebruiker doorverwijzen naar de juiste pagina.
<div class="container vh-100 d-flex flex-column justify-content-center align-items-center">
<h1 class="mb-5">Secret Santa</h1>
<div class="d-flex gap-4 mt-5">
<div class="card" style="cursor: pointer;">
<div class="card-body">
<h5 class="card-title">Deelnemers</h5>
<p class="card-text">Beheer de personen die deelnemen aan de trekking.</p>
</div>
</div>
<div class="card" style="cursor: pointer;">
<div class="card-body">
<h5 class="card-title">Trekkingen</h5>
<p class="card-text">Bekijk historische trekkingen of maak een nieuwe trekking aan.</p>
</div>
</div>
</div>
</div><div class="container my-5">
<h1>Deelnemers</h1>
<div class="d-flex gap-4">
<input class="form-control flex-grow-1" placeholder="Naam">
<button class="btn btn-primary" id="addPersonButton" style="min-width: 12rem">Voeg toe</button>
</div>
<div id="participants" class="mt-4 d-grid gap-4 justify-content-between"
style="grid-template-columns: repeat(auto-fill, 18rem)">
</div>
</div><div class="d-flex">
<custom-sidebar></custom-sidebar>
<div class="container my-5">
<h1>Nieuwe Trekking</h1>
<div class="d-flex gap-4">
<select class="form-select" id="participantsSelect">
<option>-- Selecteer personen --</option>
</select>
<button class="btn btn-primary" id="addButton" style="min-width: 12rem">Voeg toe</button>
</div>
<div>
<h4 class="mt-4">Toegevoegde personen</h4>
<div id="participants" class="d-grid gap-1 justify-content-between"
style="grid-template-columns: repeat(auto-fill, 10rem)">
</div>
</div>
<div class="d-grid my-2">
<button class="btn btn-danger">Maak trekking</button>
</div>
<ul id="draw">
</ul>
</div>
</div>Sidebar
Schrijf een nieuw custom element <custom-sidebar> dat een navigatiebalk weergeeft met links naar de verschillende pagina's, hiervoor gebruik je onderstaande HTML-code. Voeg de component toe aan de deelnemers en trekkingen pagina's en zorg ervoor dat de links werken.
<div class="border-end border-2 min-vh-100" style="width: 8rem">
<div class="pt-5 border-bottom border-2"></div>
<button class="btn btn-link">Secret Santa</button>
<button class="btn btn-link">Deelnemers</button>
<button class="btn btn-link">Trekkingen</button>
</div>
Deelnemers pagina
Zorg ervoor dat het formulier op de deelnemerspagina werkt en dat de deelnemers bewaard worden in local storage (via de LocalStoragePersistenceProvider).
Schrijf vervolgens een custom element <participant-card> dat een deelnemer weergeeft. Gebruik daarvoor onderstaande HTML-code, zorg er tenslotte voor dat de delete en update functionaliteiten werken. Als er op de edit knop gedrukt wordt moet de naam bewerkbaar worden en moet er een save en delete knop getoond worden, de UI hiervoor is al voorzien in de HTML-code.
<div class="card" style="width: 18rem;">
<div class="card-body d-flex flex-column gap-2" id="edit-body">
<input class="form-control" placeholder="Name">
<div class="d-flex gap-2 justify-content-end">
<button class="btn btn-outline-danger">Cancel</button>
<button class="btn btn-outline-primary">Save</button>
</div>
</div>
<div class="card-body" id="read-body">
<h5 class="card-title">Name</h5>
<div class="d-flex gap-2 justify-content-end">
<button class="btn btn-outline-danger">Delete</button>
<button class="btn btn-outline-primary">Edit</button>
</div>
</div>
</div>Trekkingen pagina
Vul de dropdown op de trekkingen pagina op met de deelnemers die je op de vorige pagina toegevoegd hebt. De geselecteerde deelnemers moeten persistent blijven als je tussen pagina's wisselt, maar niet als de pagina herladen wordt, je gebruikt hiervoor dus de MemoryPersistenceProvider. Het is, afhankelijk van je implementatie, mogelijk dat je een kleine aanpassingen moet maken aan de MemoryPersistenceProvider, dit is geen probleem.
Via de "Voeg toe" knop moet een deelnemer toegevoegd worden aan de huidige trekking, gebruik een nieuw custom element om de geselecteerde deelnemers weer te geven. Dit custom element moet algemeen bruikbaar zijn, je mag hier dus geen PersistenceProvider oproepen, maar moet een custom event opgooien als er op de deleteknop wordt gedrukt. Je kan onderstaande UI gebruiken.
<div class="border rounded d-flex justify-content-between align-items-center flex-grow-0 gap-1"
style="max-width: 10rem; padding: 0.25rem">
<div id="label" class="text-truncate"></div>
<button class="btn btn-danger p-0" id="delete-btn" style="width: 2rem; height: 2rem">X</button>
</div>De dropdown mag enkel deelnemers tonen die nog niet geselecteerd zijn. Zodra een deelnemer verwijderd wordt uit de lijst van geselecteerde deelnemers moet deze weer in de dropdown getoond.
Trekking maken
Als er op de "Maak trekking" knop gedrukt wordt, moet een willekeurige verdeling gemaakt worden van de geselecteerde deelnemers. Het is vanzelfsprekend dat niemand gekoppeld mag zijn aan zichzelf en dat iedereen slechts voor één andere persoon een cadeau mag kopen. Daarnaast geldt de bijkomende regel dat twee personen geen cadeau voor elkaar mogen kopen als er een oneven aantal deelnemers zijn (anders kan er een oneindige lus gegenereerd wordt omdat de laatste persoon enkel nog aan zichzelf een cadeau kan geven).
Zorg er tenslotte voor dat de "Maak trekking" knop enkel beschikbaar is als er minstens 3 deelnemers zijn. Verder moet het formulier ook terug leeg gemaakt worden als de trekking gemaakt is.
Uitdagend, moeilijker dan het examen Smurfen
Smurfen is een denkspelletje dat op een vierkant rooster gespeeld wordt. Bij het begin van het spel bevat het rooster blauwe bollen (de smurfen) die een nummer bevatten, rood-witte bollen (paddenstoelen) en lege vakjes. De bedoeling van het spel is om elk leeg vakje op te vullen met een smurf (zonder nummer) of een paddenstoel.
De spelregels zijn als volgt:
- Smurfen zien elkaar wanneer ze in dezelfde rij of kolom staan.
- Paddenstoelen zijn obstakels die het zicht van een smurf blokkeren.
- De smurfen in de startconfiguratie bevatten een nummer dat aangeeft hoeveel andere smurfen zij moeten zien.
- Elke smurf moet minsten één andere smurf zien.
- Alle cellen op het spelbord moeten opgevuld zijn.
Home pagina renderen
Deze applicatie bestaat slechts uit één pagina, zorgt ervoor dat deze gerenderd wordt zodat je onderstaand resultaat bekomt. Zorg er verder ook voor dat het CSS-bestand ingeladen wordt.

Spelbord downloaden
Het spelbord kan gedownload worden in verschillende configuraties en is beschikbaar in groottes van 6x6, 7x7 en 8x8. Standaard wordt een 6x6 bord gebruikt, via de dropdown kan de grootte aangepast worden, dit mag echter pas gebeuren als de gebruiker op de "Start nieuw spel" knop drukt.
Gebruik een fetch request om de configuratie te downloaden van onderstaande URL, je voorziet natuurlijk ook de nodige TypeScript types om het bord te beschrijven. De configuratie bevat slechts informatie over sommige vakken, de rest van de velden zijn leeg bij de start van het spel.
https://vaolhgulafwfxgrqpngy.supabase.co/functions/v1/smurfen?boardSize=6
Spelbord renderen
Het spelbord is opgebouwd uit rijen en cellen. Elke rij is een <div> met de CSS-klasse d-flex, elke cel is een <button> met de CSS-klassen cell. Afhankelijk van het type cel krijgt deze ook de CSS-klasse empty, smurf of paddenstoel. Voor een cell die een waarde heeft, moet deze getoond worden als content van de button.
De gedownloade configuratie bevat enkel informatie over de cellen in de startconfiguratie, alle andere cellen zijn aanvankelijk leeg.

Spel spelen
Als de gebruiker op een cel klikt moet het volgende gebeuren
- Als er op een cel uit de startconfiguratie geklikt wordt, moet er niets gebeuren.
- Als er op een lege cel geklikt wordt, moet deze omgevormd worden in een smurf.
- Als er op een smurf geklikt wordt, moet deze omgevormd worden in een paddenstoel.
- Als er op een paddenstoel geklikt wordt, moet deze omgevormd worden in een lege cel.
De reset knop moet het spelbord resetten naar de startconfiguratie.
Timer
Als de applicatie start, en als de gebruiker op de "Start nieuw spel" knop drukt, moet er een timer starten. Deze blijft lopen tot de gebruiker het spel opgelost heeft, of tot er opnieuw op de "Start nieuw spel" knop gedrukt wordt. Implementeer de timer via de setInterval en clearInterval functies. Zorg er voor dat eventuele lopende timers geannuleerd worden voordat een nieuwe timer gestart wordt.
Aangezien de timer heel veel renders nodig heeft (elke seconde), pas je de timer aan buiten de render-functie.
Scoreboard
Maak gebruik van de RestPersistenceProvider en de API uit de startbestanden om de highscores te bewaren. De API ondersteunt alle CRUD operaties op het /highscores endpoint.
Er zijn twee situaties te onderscheiden. Als er nog geen data aanwezig is in de API wordt de tekst 'Geen info' getoond in het scorebord.

Als er wel data aanwezig is, wordt deze informatie uitgelezen en getoond, om dit te testen kan je volgende code in /src/data/highscores.json plaatsen in de API.
[
{
"name": "Test Gebruiker",
"time": "00:24",
"size": 6
}
]
Controleer
Via de knop 'Controleer' kan de gebruiker nakijken of de oplossing correct is. Ga terug kijken naar de spelregels voor de vereisten voor een correcte oplossing. Als de oplossing niet correct is, wordt onderstaande boodschap getoond.

Indien de oplossing wel correct is, wordt de gebruiker gevraagd om een naam in te geven. Deze wordt vervolgens samen met de verstreken tijd en de grootte van het spelbord bewaard in highscores.

Voorbeeldexamen
Bekijk ook zeker het voorbeeldexamen voor meer oefeningen.