Se alle prosjekter

Klimakampen

Screenshot av klimakalkulatorens første spørsmål og flere valg brukeren kan velge mellom for å svare

Kode på GitHub

Eksamen i Rammeverk gikk ut på å lage et nettsted som skulle inspirere og hjelpe folk å ta enkle grep for klimaet. Nettstedet skulle ha tre hovedfunksjonaliteter:

  1. Klimatiltak: På forsiden får brukeren tips til enkle klimatiltak man kan ta i hverdagen for å senke klimautslippene sine. 
  2. Klimaverstinger: På denne siden får brukeren to grafiske framstillinger av klimautslippene til de 20 landene med høyest CO2-utslipp per innbygger.
  3. Klimakalkulator: I kalkulatoren kan brukeren svare på en rekke spørsmål og få utslippene sine regnet ut. Resultatet viser hvordan brukeren gjør det sammenlignet med gjennomsnittet.

Nettstedet er utviklet med React og Next.js, Typescript og Tailwind. Zustand er brukt for lagring av data og state.

Hvordan gikk jeg fram?

En enkel side for å formidle enkle grep

Siden nettstedet skulle hjelpe brukere å ta enkle grep, fokuserte jeg på at brukeropplevelsen og designet skulle være enkelt, og med en velfungerende funksjonalitet. Derfor er det en enkel navigasjon, og lite innhold for å ikke distrahere fra budskapet. 

Jeg lot ChatGPT generere tekstinnholdet for nettstedet, slik at jeg kunne fokusere på kodingen. Språkmodellen har også hjulpet meg med dataen for kalkulatoren, ettersom dette er avanserte kalkuleringer som jeg verken har kunnskap om eller tid til å gjennomføre selv. Derfor vil jeg presisere at dataen som blir brukt ikke er kvalitetssikret, og er brukt for å ha data å jobbe med.

En gjenbrukbar og ryddig datastruktur

Dataen for klimaverstingene ville jeg strukturere på en måte at både tabellen og stolpediagrammet kunne bruke det, slik at jeg kunne importere datasettet i begge React-komponentene. Først lagde jeg tabellen og utformet datasettet til å passe på dette. Da jeg startet på stolpediagrammet fra Plotly, innså jeg at dataen ikke ville passe. For å løse dette, mappet jeg over arrayet med land for å hente ut navn på landene til X-aksen, og CO2-utslippene til Y-aksen.

Dynamisk routing og URL-parametre

For å lenke kortene på forsiden til artiklene som hører til temaet, altså at ved å trykke på et kort får brukeren mer informasjon om temaet, brukte jeg dynamisk routing. Det vil si at fra Card.tsx lenkes det til artiklene med slug-en som parameter i URL-en. Om ingen artikkel har en slug som matcher det jeg sender inn, får brukeren en feilmelding. Slik havner ikke brukeren på en side som ikke eksisterer. Først prøvde jeg å bruke id-en som er i cardContent og articleContent, ettersom det er veldig lett å sammenligne tall. Men, jeg ville heller at URL-en skulle ha en slug som ligner på tittelen, for å gjøre det tydeligere for brukeren hvilken artikkel det er basert på URL-en. Denne løsningen ble jeg veldig fornøyd med.

Viser URL-en på siden som samsvarer med tittelen på artikkelen

Vise spørsmål, lagre brukervalg, kalkulere resultat og sammenligne med annen data

Dataen for kalkulatoren er utformet som et array med et objekt for hvert spørsmål, hvor alt har sin type. Spørsmålene har en id, selve spørsmålet, så et array med alternativer som er objekter med id, label og utslipp, og til slutt en “average” som henter id-en til det alternativet som tilsvarer gjennomsnittssvaret for en nordmann.

Datastrukturen til spørsmålene

For å vise et og et spørsmål brukte jeg først useState, som øker og minker state. Etterhvert ville jeg ha en knapp som lar brukeren ta kalkulatoren på nytt, flyttet jeg state inn i en Zustand-store (store/store.ts). Det gjorde det enklere å holde oversikt og kontrollere state når alt var sammen. Jeg satte currentCard til 1, slik at den kan bruke id-en fra spørsmålene i arrayet og hente ut spørsmål med id 1. For å navigere mellom spørsmålene satte jeg en onClick på knappene i calculatorCard som oppdaterer currentCard med -1 og +1 for å gå fram og tilbake. Hvis brukeren er på første spørsmål, er det ikke mulig å gå lengre bak: “Forrige”-knappen blir disabled og onClick fjernes fra den.

En grå "forrige"-knapp og en grønn "neste"-knapp

Om brukeren er på siste spørsmål, som vil være length på arrayet, er det ikke mulig å gå lengre, og “Neste”-knappen blir en knapp for å sende inn svarene.

En grønn "forrige"-knapp og en mørkegrønn "ferdig"-knapp


For å lagre svarene til brukeren, lagres id-en til spørsmålet og alternativet brukeren valgte i store. Jeg kunne valgt å lagre stringen til spørsmålet, da det hadde gjort det enklere å hente fram senere uten å bruke find og map, men jeg brukte id slik at det ikke er risiko for at noen bokstaver eller tegn er feil, og dermed ikke vil vise riktig.

Det jeg synes er vanskeligst med React og Next er hvor jeg skal plassere logikken min. Ofte starter jeg i ei fil for å se at det funker, og så deler jeg opp i mindre biter, slik at jeg kan finne ut hvor koden hører mest hjemme for å sikre gjenbrukbarhet og ryddighet.

Hva ble resultatet?

  1. Klimatiltak
  • Ved å trykke på et klimatiltak, oppdateres URL-en med slug, og viser da en artikkel som utdyper mer om temaet brukeren trykket på. 
Forsiden: hero-tekst med informasjon om nettstedet, og flere kort med klimatiltak


  1. Klimaverstinger
  • Brukeren kan toggle mellom to ulike framvisninger av topp 20 klimaverstinger. Begge komponentene bruker samme datasett.
Stolpediagram over de 20 landene med mest utslippTabellvisning av de 20 landene med mest utslipp


  1. Klimakalkulator
  • Brukeren svarer på spørsmålene, og får se sitt midlertidige resultat underveis sammenlignet med gjennomsnittet. Brukeren kan gå fram og tilbake mellom spørsmålene, uten at svaret deres forsvinner, siden svarene er lagret i Zustand.
  • Når brukeren sender inn svarene sine får de en grafisk framvisning av sitt resultat sammenlignet med gjennomsnittet, og en melding ut ifra om de er bedre, lik eller dårligere enn gjennomsnittet. Brukeren kan også velge å ta kalkulatoren på nytt.
Siste spørsmål i klimakalkulatorenResultatet fra kalkulatoren: en melding om resultatet, et stolpediagram, og en tabell som sammenligner brukerens svar med gjennomsnittet.



Det jeg er mest fornøyd med på dette prosjektet er Zustand-store. Her har jeg fått lagt inn masse funksjonalitet som tilhører kalkulatoren, og dermed er det enkelt å kontrollere state og bruke det som lagres der. I tillegg er jeg fornøyd med hvordan jeg har løst dynamisk routing, og at URL-en oppdateres til riktig tema.

Kode på GitHub