Herhalingsoefening I
Herhalingsoefening I
Tijdens deze oefensessie bouw je een (klein deel van) een webshop na in React. Tijdens deze les oefen je op alle geziene concepten:
- Componenten
- State
- Lifting state
- Prop drilling
- Routing
- Styling
- Het gebruik van third-party UI libraries
- Het raadplegen van documentatie om relevante informatie te vinden
Merk op dat styling gebruikt wordt als oefening en niet met het doel een productie-klaar resultaat neer te zetten. De styling van de oefening blijft heel beperkt.
We bouwen een webshop pagina met een aantal laptops, waarvan de specificaties automatisch gegenereerd zijn. De website stelt de gebruiker in staat om de beschikbare laptops te filteren op basis van deze specificaties en om een detailpagina te bekijken.
Oefening 0: Voorbereiding
Maak een nieuw project aan, verwijder alle bestanden binnen de src map en maak een lege main.jsx aan. Voeg de startbestanden toe aan het nieuwe project.
Tijdens deze oefeningen maak je opnieuw gebruik van Font Awesome. Ga voor installatie-instructies en voorbeelden kijken in de documentatie of in de oefeningen van les 1
Naast Font Awesome gebruiken we in deze oefeningen ook volgend bibliotheek. Installeer deze.
pnpm add @faker-js/faker
Het UI van de view is als volgt opgebouwd, de werking van de verschillende componenten wordt hieronder uitgelegd.

Oefening 1: Zoek filters
Elke webshop heeft nood aan een manier om de beschikbare producten te filteren. We beginnen hiermee. Een Filter bestaat uit een titel en een aantal opties. Voor de titel "Merk" zijn er bijvoorbeeld de opties "Acer", "Apple", … De filter kan dichtgeklapt worden om de opties te verbergen. Dit dichtklappen programmeer je zelf, maak geen gebruikt van bibliotheken of componenten die dit voor jou doen.
We bouwen de component van onder naar boven uit en beginnen dus met de componenten zonder state en bouwen dan de stateful components die deze eerste componenten gebruiken.
Opties
Maak een nieuwe component FilterItem. Het onderstaande screenshot toont de opties voor de eerste categorie in de array die teruggegeven wordt door de getCategories functie. Elke optie is een FilterItem.

De component bevat geen hardcoded data. Enkel de structuur wordt in deze component gedefinieerd alle effectieve data wordt via properties doorgegeven. Bekijk de API code om de juiste propertynamen te vinden.
Filteren
Maak een nieuwe component Filter, deze component is opgebouwd uit verschillende FilterItems. Daarnaast toont de component ook de titel van de categorie.

Een Filter component heeft twee properties, name en options. De waarden voor deze properties komen uit de API code. Verder wordt de component omringt in een div waaraan via styled-components volgende CSS regel toegekend wordt.
margin-bottom: 1em;
Naast het weergeven van de opties moet de component opengeklapt kunnen worden (standaard open). Hiervoor gebruik je de state van de component Filter. Het pijltje naar beneden wordt door Font Awesome gedefinieerd in het object faCaretDown. Een dichtgeklapte filter gebruikt het faCaretUp icoon en ziet er als volgt uit.

Alle filters
Schrijf een nieuwe component FilterBar die alle filters onder elkaar toont. Daarnaast moet deze component in zijn state de categorieën en bijhorende opties bewaren.
Op basis van de state worden de verschillende Filter componenten gebouwd. Het resultaat:

Filters selecteren
Momenteel kunnen de filters nog niet geselecteerd worden. Dit is natuurlijk niet ideaal. Probeer eerst zelf te zorgen dat de opties binnen elke filter geselecteerd kunnen worden. Als dit niet lukt, kan je de hints hieronder bekijken.
Stappenplan voor het selecteren van een filter
Om een checkbox aan te vinken moet je volgende stappen doorlopen:
- Maak een nieuwe functie aan in de FilterBar component.
- Laat de nieuwe functie de toggleOptionSelected methode van de dataAPI oproepen.
- Laat de nieuwe functie ook de state bijwerken.
- Geef de nieuwe functie door aan elke Filter component via een property.
- Geef tijdens het oproepen van elke FilterItem component een nieuwe lambda (arrow) functie door via properties aan het FilterItem. Deze lambda functie roept de functie die in punt 4 doorgegeven is aan het FilterItem op met de correcte parameter (het id van de optie die weergegeven wordt door het FilterItem en de categorie waarin dit FilterItem zich bevindt).
- Gebruik de in punt 5 aangemaakte functie in het onChange event van de FilterItem component.
Oefening 2: Styling
Installeer Bootstrap en react-bootstrap, zorg er vervolgens voor dat de juiste CSS geïmporteerd wordt.
NavBar
Voeg een navbar toe aan je applicatie. De navbar bevat de links:
- Laptops: '/'
- Smartphones: '/smartphones'
- Keuken: '/kitchen'
- Wasmachines: '/washingmachines'
- About: '/about'
De navbar links moeten nog niet werken.

Search Page
Schrijf een component SearchPage, deze component deelt het scherm op in 2 kolommen, de eerste is 4 breed en bevat de filters, de tweede is 8 breed en bevat momenteel nog niets. Je mag ervan uitgaan dat deze layout voor elk breakpoint hetzelfde is. Gebruik tenslotte de Bootstrap klasse mt-5 om marge boven de SearchPage toe te voegen.
Filter Styling
Pas de tekst "Aanbevolen" aan naar de kleur "success".

Oefening 3: ComputerList
Bouw een component ComputerList, deze component maakt gebruik van een component Computer om een overzicht te tonen van elke computer die voldoet aan de geselecteerde filters.
Elke Computer component is omvat in een kolom die groot is (op elk breakpoint). De container waarin de de Computer components geplaatst worden krijgt een marge via de class 'me-4'. De Computer component is gebouwd met de Card component. De component gebruikt dezelfde afbeelding voor elke computer, deze wordt getoond door middel van het Font Awesome icoon faLaptop. Om het icoon de juiste afmetingen te geven kan je het in een div plaatsen waaraan onderstaande CSS gekoppeld is.
{
font-size: 6rem;
text-align: center;
}
Hieronder zie je twee rijen van computers staan. De namen van de verschillende properties zijn te vinden in de API-code.

Gebruikt de component ComputerList om onderstaand scherm na te bouwen. Het Bootstrap grid komt hierbij van pas.

Oefening 4: Filteren
Je merkte waarschijnlijk al op dat het filteren nog niet werkt. Dit komt omdat de geselecteerde filters bijgehouden worden in de component FilterBar. Je moet dit nog een niveau naar boven verhuizen. Zowel de geselecteerde filters als de computers die hierbij horen moeten in de state van de Search component bijgehouden worden. Zorg dat het filteren werkt.
Oefening 5: Scroll wrapper
Schrijf een component die rond één of meerdere componenten gezet kan worden om deze component(en) in hoogte te beperken tot een bepaald procent van de viewport height, of tot vh als er geen specifieke waarde voor de property meegegeven is. Horizontaal scrollen is niet mogelijk, enkel verticaal scrollen is toegestaan.
{
overflow-x: hidden;
overflow-y: scroll;
height: 100vh;
}
Gebruik de CSS-code hierboven om de ScrollWrapper component via styled-components te implementeren. Ga kijken in de documentatie en geeft de property die de maximale hoogte bepaald door aan de styled-component.
Onderstaande video demonstreert de werking van deze component, ter illustratie is de hoogte van de FilterBar ingesteld op vh en de ComputerList op vh. Verwijder na het testen de ScrollWrapper rond de ComputerList en stel de hoogte voor de andere ScrollWrapper in op vh
Oefening 6: PaginationWrapper
Schrijf een component PaginationWrapper die rond een andere component gezet kan worden en gebruikt kan worden voor pagination. De component is gebouwd met de Pagination component van react-bootstrap. De component PaginationWrapper bestaat is omringt in volgende container.
const FlexContainer = styled.div`
display: flex;
flex-direction: column;
width: 100%;
`
Deze container is opgedeeld in twee delen, het eerste deel is DataContainer die hieronder te vinden is. Binnen deze component wordt de ScrollWrapper geplaatst. Het is opnieuw mogelijk om de hoogte door te geven, via de PaginationWrapper naar de ScrollWrapper. In onderstaande screenshots/video's is een hoogte van vh gebruikt.
const DataContainer = styled.div`
flex-grow: 1;
margin-bottom: 2em;
width: 100%;
`
const PaginationContainer = styled.div`
display: flex;
justify-content: center;
`
Het tweede deel is de PaginationContainer waarvoor volgende richtlijnen gelden:
- De knop om naar de eerste pagina te gaan is altijd zichtbaar.
- De knop om naar de vorige pagina te gaan is altijd zichtbaar.
- Als het aantal pagina's en de huidige pagina groter zijn dan , wordt een ... knop getoond.
- De knoppen voor alle pagina's die in het interval [huidigePagina - , huidigePagina + ] liggen worden getoond.
- Als het aantal pagina's groter is dan en als de huidige pagina minstens 2 verwijderd is van de laatste pagina, wordt een ... knop getoond.
- De knop om naar de volgende pagina te gaan is altijd zichtbaar.
- De knop om naar de laatste pagina te gaan is altijd zichtbaar.
In onderstaande video is een pagina grootte van van items gebruikt.
Oefening 7: Routing
Installeer de nodige pakketten voor routing. Zorg er voor dat de links achter "Small Webshop" en "Laptops" allebei naar de Search component verwijzen.
Voor alle andere pagina's is geen pagina voorzien. Bouw een catch-all route die alle niet gekende paden doorstuurd naar de UnderConstruction component. Deze component bevat onderstaande inhoud. Ook als je de root page van de site open ('/') moet je op de Search component komen.

Oefening 8: RepositoryDetail
Maak een detailpagina aan voor een laptop. Deze pagina is gebouwd met behulp van een Bootstrap Card en gebruikt het Bootstrap grid om twee aparte lijsten naast elkaar weer te geven. De marge tussen twee kolommen weghalen kan door middel van de 'g-0' CSS-klasse.
