diff --git a/README.md b/README.md index 12b6918..9eb7d37 100644 --- a/README.md +++ b/README.md @@ -1,201 +1,224 @@ -# React + TypeScript + Vite -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. +# Dokumentasjon -Currently, two official plugins are available: +Prosjektet er live på: [http://it2810-02.idi.ntnu.no/project1/](http://it2810-02.idi.ntnu.no/project1/) -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs) -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) +## Beskrivelse +_Skriv en beskrivelse her_ -## React Compiler +## oppsett +Vi bruker `fnm` med `pnpm`, og `Node.js` v24. -The React Compiler is enabled on this template. See [this documentation](https://react.dev/learn/react-compiler) for more information. +Installasjon kan gjøres med følgende kommandoer (linux): +``` +# Download and install fnm: +curl -o- https://fnm.vercel.app/install | bash -Note: This will impact Vite dev & build performances. -You can also try [the experimental native React Compiler support in plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md#rust-react-compiler) by using `compiler: true` in the plugin options instead of using the Babel plugin. +# Download and install Node.js: +fnm install 24 -## Expanding the ESLint configuration +# Verify the Node.js version: +node -v # Should print "v24.21.0". -If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: +# Download and install pnpm: +corepack enable pnpm -```js -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... +# Verify pnpm version: +pnpm -v +``` - // Remove tseslint.configs.recommended and replace with this - tseslint.configs.recommendedTypeChecked, - // Alternatively, use this for stricter rules - tseslint.configs.strictTypeChecked, - // Optionally, add this for stylistic rules - tseslint.configs.stylisticTypeChecked, +#### Kjøre prosjektet lokalt for utvikling +1. Klone github repo til maskinen din +2. gå inn i prosjektmappen (default: T02-Project-1) +3. Kjør kommandoene + - `pnpm install` + - `pnpm run dev` - // Other configs... - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]); -``` +#### Bygge prosjektet +Prosjektet kan bygges med kommandoen `pnpm run build`. Dette vil bygge prosjektet og legge det i `/dist` directory under prosjektmappen. -You can also install [eslint-plugin-react-x](https://npmx.dev/package/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://npmx.dev/package/eslint-plugin-react-dom) for React-specific lint rules: - -```js -// eslint.config.js -import reactX from 'eslint-plugin-react-x'; -import reactDom from 'eslint-plugin-react-dom'; - -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - // Enable lint rules for React - reactX.configs['recommended-typescript'], - // Enable lint rules for React DOM - reactDom.configs.recommended, - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]); -``` +#### Test prosjektet +Prosjektet kan testes med kommandoen `pnpm test:run`. -```Dokumentasjon av kode +> [!NOTE] +> Prosjektet forventer en api-token i en lokal `.env`-fil. Se _API_-seksjonen under. -Leona: - Movie_card.tsx + Movie_card.css - Viser ett enkelt filmkort med plakat, tittel, rating og skuespillere. Tar imot movieId, title, posterUrl og rating som props. Henter skuespillerne selv via useMovieCredits(movieId) og viser en "Laster skuespillere..."-tekst mens det henter. De tre første skuespillerne vises kommaseparert. Ratingen ligger som en badge øverst i høyre hjørne, plakaten til venstre og resten av infoen til høyre – med responsiv styling for mobil (@media max-width: 480px). +## vm +Prosjektet er hostet på VM hostet på NTNU sine servere. Oppsettet er gjort i henhold til veiledningen "Komme i gang med virtuell maskin (vm)" på [canvas.ntnu.no](canvas.ntnu.no). - MovieList.tsx + MovieList.css - Tar imot en liste med filmer (movies: Movie[]) og rendrer ett MovieCard per film med .map(). Den vet ingenting om TMDB eller fetching – det ansvaret ligger i hookene og i Section-komponenten (laster/feilhåndtering). Bygger plakat-URL fra TMDB sin poster_path, med fallback til tom streng hvis filmen mangler plakat. Regner om TMDB sin vote_average (0–10) til prosent (0–100). Layouten er et responsivt grid (repeat(auto-fill, minmax(320px, 1fr))) som går til én kolonne på mobil. +På serveren er det opprettet en `cron job` som kjører hvert minutt som kjører følgende deploy-script: +```bash +#!/bin/bash - useMovieCredits.ts - En React Query-hook som henter skuespillerlisten for én bestemt film via fetchMovieCredits i api/tmdb.ts. Caches per movieId i én time (staleTime), slik at samme film ikke hentes på nytt unødvendig når flere kort viser samme data. +FNM_PATH="/home/albertpl/.local/share/fnm" +export PATH="$FNM_PATH:$PATH" +eval "$(fnm env --shell bash)" - bruk av KI: - Movie_card.tsx + Movie_card.css +set -e - KI (Claude, Anthropic) ble brukt til å foreslå strukturen på filmkortet: hvilke props komponenten burde ta imot (movieId, title, posterUrl, rating) versus hva den burde hente selv. Forslaget var at kortet henter skuespillerne sine via useMovieCredits(movieId) internt, i stedet for at forelderen henter og sender ned skuespillerlisten som en egen prop. Dette holder MovieList enkel og fri for ansvar den ikke trenger. +cd /var/www/project - KI ble også brukt til å: +BEFORE=$(git rev-parse HEAD) - - Foreslå lastetilstand ("Laster skuespillere...") mens useMovieCredits henter data, slik at brukeren får tilbakemelding i stedet for et tomt felt - - Generere responsiv styling i Movie_card.css, inkludert plassering av rating-badge, layout med plakat til venstre/info til høyre, og tilpasning under @media (max-width: 480px) +echo "[$(date)] Pulling latest changes..." +git pull origin main - Koden ble gjennomgått og forstått av gruppen før den ble tatt i bruk, og tilpasset til resten av prosjektets struktur (bl.a. typene fra types/tmdb.ts). +AFTER=$(git rev-parse HEAD) - MovieList.tsx + MovieList.css +if [ "$BEFORE" = "$AFTER" ]; then + echo "[$(date)] No changes, skipping build." + exit 0 +fi - KI ble brukt til å foreslå ansvarsdelingen mellom MovieList og resten av appen: MovieList skal kun rendre en liste med MovieCard-komponenter ut fra en ferdig hentet movies-prop, og skal ikke vite noe om TMDB, fetching, lasting eller feilhåndtering — det ansvaret ligger i hookene (useMovies.ts m.fl.) og i Section-komponenten. Denne separasjonen ble foreslått av KI som god praksis for å holde komponentene testbare og gjenbrukbare hver for seg. +echo "[$(date)] Changes detected ($BEFORE -> $AFTER). Installing dependencies..." +pnpm install - KI ble videre brukt til å: +echo "[$(date)] Building..." +pnpm run build - - Generere logikken for å bygge full plakat-URL fra TMDB sin poster_path, inkludert fallback til tom streng når poster_path er null (for å unngå en ødelagt bilde-URL som .../w200null) - - Foreslå omregningen fra TMDB sin vote_average (skala 0–10) til prosent (0–100) som vises i UI - - Sette opp det responsive grid-oppsettet i MovieList.css (repeat(auto-fill, minmax(320px, 1fr))), som går til én kolonne på mobil - - Alle forslag ble vurdert og tilpasset av gruppen, blant annet ved å sjekke at key={movie.id} var satt riktig på listeelementene slik React krever. +echo "[$(date)] Deploy finished." +``` - useMovieCredits.ts +Prosjektet ligger lokalt i mappen `/var/www/project/`, og prosjektet som blir bygget ligger i `/var/www/project/dist/`. Webserveren hoster filene direkte fra `dist` directory gjennom en symlink i `/var/www/html/project1/` som peker til `dist` directory. - KI ble brukt til å sette opp hooken som en TanStack Query-basert wrapper rundt fetchMovieCredits fra api/tmdb.ts, med movieId som en del av queryKey slik at hver film cacher skuespillerdataen sin uavhengig av andre filmer. +## API +Vi bruker The Movie Database (TMDB) sin api i prosjektet vårt. Se tmdb sin egen dokumentasjonen [her](https://developer.themoviedb.org/docs/) - KI foreslo også staleTime: 1000 * 60 * 60 (én time) som en fornuftig cache-varighet, med begrunnelsen at skuespillerlister for en film praktisk talt aldri endrer seg i løpet av en brukerøkt. Dette var spesielt viktig fordi hvert MovieCard gjør sitt eget kall til /credits-endepunktet — uten caching ville samme film blitt hentet på nytt hver gang kortet ble rendret på nytt, noe som kunne gått på bekostning av kravet om å unngå unødvendige API-kall. +#### VITE_TMDB_TOKEN +For autentisering av api-kall mot tmdb sin api kreves det en egen access token. Denne kan etterspørres på under profil-innstillinger på tmdb sin [hjemmeside](https://www.themoviedb.org). - Gruppen vurderte selv om caching-strategien var riktig for prosjektets bruksmønster, og valgte å beholde forslaget som det var. +Etter at man har fyllt ut api-skjema får man to forskjellige API nøkkler: en `API key`, og en `API Read Access Token`. Vi bruker `API Read Access Token`. Denne må kopieres og legges i en lokal `.env.local` fil som skal se slik ut: +``` +VITE_TMDB_TOKEN=[API Read Access Token] +``` -Leona: - Sortering og filtrering av filmer +Når man har lagt inn denne skal prosjektet kunne kjøre lokalt, og api-kall skal fungere. - Hva er implementert +> [!NOTE] +> API token har kun lese-rettigheter, men bør fortsatt ikke være offentlig. +> Filen `.env.local` er derfor lagt til i `.gitignore`. - Brukeren kan sortere filmlistene (populære, nye filmer og søkeresultater) etter: - - Popularitet (TMDB sin standardrekkefølge) - - Vurdering (høyest først) - - Nyeste utgivelsesdato først - - Alfabetisk (tittel) +## testing +_Clemens skriv om testing her_ +_Hva som er testet: hvilke nettlesere, hvilke enheter, og hva de automatiske testene dekker_ - I tillegg kan brukeren sette en minimumsgrense for vurdering (0-10) som filtrerer bort filmer under denne terskelen. +## prosjektstruktur, komponenter, hooks, layout, types - Dette dekker det funksjonelle kravet om at brukeren skal kunne gjøre et valg (filtrering/sortering) som påvirker utvalget av det som presenteres og hvordan det presenteres. +`prosjekt/src`-directory structure: +``` +./src +├── App.css +├── App.tsx +├── main.tsx +├── index.css +| +├── api +│   └── tmdb.ts +├── components +│   ├── FavoriteButton.css +│   ├── FavoriteButton.tsx +│   ├── MovieCard.css +│   ├── MovieCard.tsx +│   ├── MovieDetails.css +│   ├── MovieDetails.tsx +│   ├── MovieList.css +│   ├── MovieList.tsx +│   ├── PersonList.tsx +│   ├── SearchField.css +│   ├── SearchField.tsx +│   ├── Section.css +│   ├── Section.tsx +│   ├── Sidebar.css +│   ├── Sidebar.tsx +│   ├── SortFilterBar.css +│   ├── SortFilterBar.tsx +│   ├── TrendingPreview.css +│   └── TrendingPreview.tsx +├── hooks +│   ├── useDebouncedValue.ts +│   ├── useFavorites.ts +│   ├── useMediaQuery.ts +│   ├── useMovieCredits.ts +│   ├── useMovies.ts +│   ├── usePeople.ts +│   └── useSessionStorage.ts +├── layout +│   ├── FavoritesLayout.tsx +│   ├── MainLayout.tsx +│   └── SearchLayout.tsx +├── test +│   └── setup.ts +├── types +│   └── tmdb.ts +└── utils + ├── sortAndFilterMovies.test.ts + └── sortAndFilterMovies.ts +``` - Hvorfor sessionStorage (og ikke localStorage) +#### components +###### MovieCard.tsx + MovieCard.css +Viser ett enkelt filmkort med plakat, tittel, rating og skuespillere. Tar imot movieId, title, posterUrl og rating som props. Henter skuespillerne selv via useMovieCredits(movieId) og viser en "Laster skuespillere..."-tekst mens det henter. De tre første skuespillerne vises kommaseparert. Ratingen ligger som en badge øverst i høyre hjørne, plakaten til venstre og resten av infoen til høyre – med responsiv styling for mobil (@media max-width: 480px). - Prosjektbeskrivelsen skiller mellom to typer valg som skal huskes: +###### MovieList.tsx + MovieList.css +Tar imot en liste med filmer (movies: Movie[]) og rendrer ett MovieCard per film med .map(). Den vet ingenting om TMDB eller fetching – det ansvaret ligger i hookene og i Section-komponenten (laster/feilhåndtering). Bygger plakat-URL fra TMDB sin poster_path, med fallback til tom streng hvis filmen mangler plakat. Regner om TMDB sin vote_average (0–10) til prosent (0–100). Layouten er et responsivt grid (repeat(auto-fill, minmax(320px, 1fr))) som går til én kolonne på mobil. - - Filter-/sorteringsvalg skal huskes **selv om siden reloades - - Favoritter skal huskes **selv om nettleseren avsluttes og startes igjen +#### hooks +###### useMovieCredits.ts +En React Query-hook som henter skuespillerlisten for én bestemt film via fetchMovieCredits i api/tmdb.ts. Caches per movieId i én time (staleTime), slik at samme film ikke hentes på nytt unødvendig når flere kort viser samme data. - Dette er to forskjellige persistens-behov, og vi har derfor valgt to forskjellige Web Storage-mekanismer med hensikt: +###### useSessionStorage.ts +En generisk, gjenbrukbar hook som fungerer som `useState`, men som leser fra og skriver til `sessionStorage` automatisk. Brukes til både sorteringsvalg og minimumsvurdering, og kan gjenbrukes til andre ting senere ved behov. Lesing og skriving er pakket inn i try/catch i tilfelle storage er utilgjengelig (f.eks. i privat nettlesing), og faller da tilbake til en gitt standardverdi. - - sessionStorage for sortering/filtrering - data overlever en reload av siden, men nullstilles når fanen/nettleseren lukkes. Dette er nøyaktig oppførselen kravet beskriver. - - localStorage for favoritter (implementeres separat) - data overlever at nettleseren lukkes helt. - Ved å bruke begge mekanismene til det de faktisk passer til, dekker vi også det tekniske kravet om bruk av *både* localStorage og sessionStorage, i stedet for å bruke én av dem vilkårlig for alt. +#### layout - Hvordan det er bygget +#### types - src/hooks/useSessionStorage.ts - En generisk, gjenbrukbar hook som fungerer som `useState`, men som leser fra og skriver til `sessionStorage` automatisk. Brukes til både sorteringsvalg og minimumsvurdering, og kan gjenbrukes til andre ting senere ved behov. Lesing og skriving er pakket inn i try/catch i tilfelle storage er utilgjengelig (f.eks. i privat nettlesing), og faller da tilbake til en gitt standardverdi. +###### sortAndFilterMovies.ts +En ren funksjon uten side-effekter som tar inn en liste med filmer, sorteringsvalg og minimumsvurdering, og returnerer en ny, filtrert og sortert liste. Fordi funksjonen er ren (samme input gir alltid samme output, og den endrer ikke noe utenfor seg selv), er den enkel å enhetsteste isolert med Vitest, uten å måtte mocke React eller komponenter. - src/utils/sortAndFilterMovies.ts - En ren funksjon uten side-effekter som tar inn en liste med filmer, sorteringsvalg og minimumsvurdering, og returnerer en ny, filtrert og sortert liste. Fordi funksjonen er ren (samme input gir alltid samme output, og den endrer ikke noe utenfor seg selv), er den enkel å enhetsteste isolert med Vitest, uten å måtte mocke React eller komponenter. +###### SortFilterBar.tsx +En liten, selvutviklet komponent (ingen tredjepartsbibliotek for UI, i tråd med kravet) med en nedtrekksmeny for sortering og en range-slider for minimumsvurdering. Komponenten er "dum" — den mottar verdier og callbacks som props, og eier ingen egen state selv. - src/components/SortFilterBar.tsx - En liten, selvutviklet komponent (ingen tredjepartsbibliotek for UI, i tråd med kravet) med en nedtrekksmeny for sortering og en range-slider for minimumsvurdering. Komponenten er "dum" — den mottar verdier og callbacks som props, og eier ingen egen state selv. +# Vet ikke hvor dette bør stå +## Sortering og filtrering +Brukeren kan sortere filmlistene (populære, nye filmer og søkeresultater) etter: +- Popularitet (TMDB sin standardrekkefølge) +- Vurdering (høyest først) +- Nyeste utgivelsesdato først +- Alfabetisk (tittel) - Kobling i `App.tsx` - `App.tsx` holder sorterings- og filterverdiene via `useSessionStorage`, og sender dem videre til `SortFilterBar` for visning/endring, samt bruker `sortAndFilterMovies(...)` på filmlistene før de sendes videre til `MovieList`. Dermed gjelder valget uansett hvilken liste som vises (populære, nye filmer eller søk). +I tillegg kan brukeren sette en minimumsgrense for vurdering (0-10) som filtrerer bort filmer under denne terskelen. - Kjente begrensninger/mulige forbedringer - - Sortering og filtrering kjøres på nytt ved hver rendring. Med dagens datamengde (10–20 filmer) er dette ubetydelig for ytelsen, men kunne vært optimalisert med `useMemo` dersom datamengden økte betydelig. - - Range-slideren for minimumsvurdering kunne fått `aria-valuetext` for bedre skjermleserstøtte (f.eks. "minst 7 av 10" i stedet for kun tallet). - - sessionStorage-nøklene (`sortBy`, `minRating`) er generiske. Ved videre utvikling av appen kan det være lurt å prefikse dem (f.eks. `movieApp:sortBy`) for å unngå navnekollisjon med annen bruk av sessionStorage. +sessionStorage og localStorage +- Filter-/sorteringsvalg skal huskes **selv om siden reloades +- Favoritter skal huskes **selv om nettleseren avsluttes og startes igjen - Bruk av KI - Løsningen (hook, ren funksjon for sortering/filtrering, UI-komponent og kobling i `App.tsx`) ble utviklet i samarbeid med Claude (Anthropic). KI ble brukt til å foreslå arkitektur (separasjon mellom persistens-hook, ren logikk-funksjon og presentasjonskomponent), generere startkode, og til å vurdere om løsningen faktisk dekket prosjektkravene til filtrering/sortering og bruk av Web Storage API. Koden er gjennomgått og forstått av gruppen før den ble tatt i bruk. -Leona: - Oversikt: Fiks av filtrering/sortering - Problem: Filtrerings- og sorteringskontrollene (dropdown for sortering og slider for min. vurdering) i SortFilterBar oppdaterte state, men påvirket ingen filmlister. Ingenting skjedde når man endret dem. +Kobling i `App.tsx` +`App.tsx` holder sorterings- og filterverdiene via `useSessionStorage`, og sender dem videre til `SortFilterBar` for visning/endring, samt bruker `sortAndFilterMovies(...)` på filmlistene før de sendes videre til `MovieList`. Dermed gjelder valget uansett hvilken liste som vises (populære, nye filmer eller søk). - Årsak: Funksjonen sortAndFilterMovies (i src/utils/sortAndFilterMovies.ts) fantes, men ble aldri kalt noe sted. Importen av den i App.tsx var kommentert ut i en tidligere commit (f8a0241, "fikset vite.config.js og App.tsx slik at prosjektet bygges"), fordi TypeScript feilet på ubrukt import under bygg. I tillegg ble sortBy/minRating aldri sendt videre fra App.tsx til de tre layout-komponentene som faktisk viser filmlister. +Kjente begrensninger/mulige forbedringer +- Sortering og filtrering kjøres på nytt ved hver rendring. Med dagens datamengde (10–20 filmer) er dette ubetydelig for ytelsen, men kunne vært optimalisert med `useMemo` dersom datamengden økte betydelig. +- Range-slideren for minimumsvurdering kunne fått `aria-valuetext` for bedre skjermleserstøtte (f.eks. "minst 7 av 10" i stedet for kun tallet). +- sessionStorage-nøklene (`sortBy`, `minRating`) er generiske. Ved videre utvikling av appen kan det være lurt å prefikse dem (f.eks. `movieApp:sortBy`) for å unngå navnekollisjon med annen bruk av sessionStorage. - Løsning: - Fjernet den utkommenterte importen i src/App.tsx. - sortBy og minRating sendes nå som props fra App.tsx til SearchLayout, MainLayout og FavoritesLayout. - Hver av disse tre komponentene kjører nå sortAndFilterMovies(...) på filmlisten sin før den rendres i MovieList. - Endrede filer: - src/App.tsx - src/layout/SearchLayout.tsx - src/layout/MainLayout.tsx - src/layout/FavoritesLayout.tsx - Ikke endret: TrendingPreview-banneret i MainLayout (viser trending-filmer uavhengig av filter), samt selve sortAndFilterMovies-logikken (den var allerede korrekt, bare ubrukt). +## Bruk av KI +#### Leona +KI (Claude, Anthropic) ble brukt til å foreslå strukturen på filmkortet: hvilke props komponenten burde ta imot (movieId, title, posterUrl, rating) versus hva den burde hente selv. Forslaget var at kortet henter skuespillerne sine via useMovieCredits(movieId) internt, i stedet for at forelderen henter og sender ned skuespillerlisten som en egen prop. Dette holder MovieList enkel og fri for ansvar den ikke trenger. - Bruk av KI - KI (Claude, Anthropic) ble brukt til å finne årsaken til at filtrerings-/sorteringskontrollene ikke hadde noen effekt: ved å spore koden fant KI at importen av sortAndFilterMovies i App.tsx var kommentert ut (fra en tidligere commit som fikset et build-problem forårsaket av at funksjonen på det tidspunktet var ubrukt), og at sortBy/minRating aldri ble sendt videre til layout-komponentene som faktisk viser filmlister. +KI ble brukt til å foreslå ansvarsdelingen mellom MovieList og resten av appen: MovieList skal kun rendre en liste med MovieCard-komponenter ut fra en ferdig hentet movies-prop, og skal ikke vite noe om TMDB, fetching, lasting eller feilhåndtering — det ansvaret ligger i hookene (useMovies.ts m.fl.) og i Section-komponenten. Denne separasjonen ble foreslått av KI som god praksis for å holde komponentene testbare og gjenbrukbare hver for seg. - KI ble videre brukt til å implementere fiksen: gjenopprette importen, legge sortBy og minRating til som props på SearchLayout, MainLayout og FavoritesLayout, og kalle sortAndFilterMovies(...) på riktig filmliste i hver av disse komponentene før den sendes til MovieList. +KI foreslo også staleTime: 1000 * 60 * 60 (én time) som en fornuftig cache-varighet, med begrunnelsen at skuespillerlister for en film praktisk talt aldri endrer seg i løpet av en brukerøkt. Dette var spesielt viktig fordi hvert MovieCard gjør sitt eget kall til /credits-endepunktet — uten caching ville samme film blitt hentet på nytt hver gang kortet ble rendret på nytt, noe som kunne gått på bekostning av kravet om å unngå unødvendige API-kall. - Løsningen ble verifisert med `tsc --noEmit` og `npm run build` (begge grønne), og gjennomgått og forstått av gruppen før den ble tatt i bruk. +Løsningen (hook, ren funksjon for sortering/filtrering, UI-komponent og kobling i `App.tsx`) ble utviklet i samarbeid med Claude (Anthropic). KI ble brukt til å foreslå arkitektur (separasjon mellom persistens-hook, ren logikk-funksjon og presentasjonskomponent), generere startkode, og til å vurdere om løsningen faktisk dekket prosjektkravene til filtrering/sortering og bruk av Web Storage API. Koden er gjennomgått og forstått av gruppen før den ble tatt i bruk. - CSS: - Brukte også claude til å designe CSSen til filter-delen, slik at den matcher med resten av nettsiden. -``` +KI ble også brukt til å: +1. Foreslå lastetilstand ("Laster skuespillere...") mens useMovieCredits henter data, slik at brukeren får tilbakemelding i stedet for et tomt felt +2. Generere responsiv styling i Movie_card.css, inkludert plassering av rating-badge, layout med plakat til venstre/info til høyre, og tilpasning under @media (max-width: 480px) +3. Gjennomgå og forstått av gruppen før den ble tatt i bruk, og tilpasset til resten av prosjektets struktur (bl.a. typene fra types/tmdb.ts). +4. Generere logikken for å bygge full plakat-URL fra TMDB sin poster_path, inkludert fallback til tom streng når poster_path er null (for å unngå en ødelagt bilde-URL som .../w200null) +5. Foreslå omregningen fra TMDB sin vote_average (skala 0–10) til prosent (0–100) som vises i UI +6. Sette opp det responsive grid-oppsettet i MovieList.css (repeat(auto-fill, minmax(320px, 1fr))), som går til én kolonne på mobil \ No newline at end of file diff --git a/info.txt b/info.txt new file mode 100644 index 0000000..181feea --- /dev/null +++ b/info.txt @@ -0,0 +1,61 @@ +Kilden min er prosjektbeskrivelsen du limte inn fra Canvas, pluss dokumentasjonskravene du sendte senere. Jeg har ikke tilgang til Canvas selv, så finnes det en egen rubrikk der som ikke står i den teksten, kjenner jeg ikke til den. + +Eksplisitte krav, direkte sitert + +"Dokumentasjon i form av readme på GitHub som dokumenterer og forklarer valg, dokumenterer hva som er testet." +"Ta utgangspunkt i at dokumentasjonen skal være forklarende for medstudenter og nyttig info for den som skal evaluere." +"I starten av readme-fila skal dere legge inn en lenke til webappen som er installert på vm." +"Alle skal dokumentere bruk av KI enten dere har benyttet det eller ikke. Vi er ute etter hvordan dere har brukt KI, og gjerne en oppsummering av erfaringer." + +Vurderingskriterier som treffer README-en + +"Reproduserbarhet: prosjektet skal være dokumentert og enkelt å installere/kjøre for andre (eksempelvis faglærer)." +"God dokumentasjon som forklarer valg og løsninger, husk å dokumentere bruk av KI." + +Punkt 5 er det eneste kriteriet der README-en alene avgjør om dere består det. Får ikke faglærer kjørt prosjektet fra det som står der, er kriteriet ikke innfridd uansett hvor bra koden er. + +Hva det betyr konkret + +VM-lenke helt øverst, før alt annet +Hva appen gjør og hvilket API den bruker +Installasjon som faktisk fungerer for en som aldri har sett repoet: pnpm install, .env.local med VITE_TMDB_TOKEN, hvor man skaffer tokenet, at det må være v4 og ikke v3, pnpm dev +Kommandoene: dev, build, lint, test, format +Hva som er testet: hvilke nettlesere, hvilke enheter, og hva de automatiske testene dekker +Forklaring av valg og løsninger, ikke bare hva som finnes. "Vi bruker sessionStorage til sortering og localStorage til favoritter, fordi kravene beskriver to ulike varigheter" er en forklaring. "Vi bruker Web Storage" er det ikke. +KI-bruk per person, pluss en oppsummering av erfaringer + +Det som ikke er krav nå + +"Dokumentasjonen skal beskrive hva som er forbedret siden første innlevering" gjelder sluttvurderingen i desember, ikke i morgen. + +Alt dette har du tekst til fra tidligere i dag, bortsett fra VM-lenka og lista over nettlesere og enheter dere faktisk har testet påKilden min er prosjektbeskrivelsen du limte inn fra Canvas, pluss dokumentasjonskravene du sendte senere. Jeg har ikke tilgang til Canvas selv, så finnes det en egen rubrikk der som ikke står i den teksten, kjenner jeg ikke til den. + +Eksplisitte krav, direkte sitert + +"Dokumentasjon i form av readme på GitHub som dokumenterer og forklarer valg, dokumenterer hva som er testet." +"Ta utgangspunkt i at dokumentasjonen skal være forklarende for medstudenter og nyttig info for den som skal evaluere." +"I starten av readme-fila skal dere legge inn en lenke til webappen som er installert på vm." +"Alle skal dokumentere bruk av KI enten dere har benyttet det eller ikke. Vi er ute etter hvordan dere har brukt KI, og gjerne en oppsummering av erfaringer." + +Vurderingskriterier som treffer README-en + +"Reproduserbarhet: prosjektet skal være dokumentert og enkelt å installere/kjøre for andre (eksempelvis faglærer)." +"God dokumentasjon som forklarer valg og løsninger, husk å dokumentere bruk av KI." + +Punkt 5 er det eneste kriteriet der README-en alene avgjør om dere består det. Får ikke faglærer kjørt prosjektet fra det som står der, er kriteriet ikke innfridd uansett hvor bra koden er. + +Hva det betyr konkret + +VM-lenke helt øverst, før alt annet +Hva appen gjør og hvilket API den bruker +Installasjon som faktisk fungerer for en som aldri har sett repoet: pnpm install, .env.local med VITE_TMDB_TOKEN, hvor man skaffer tokenet, at det må være v4 og ikke v3, pnpm dev +Kommandoene: dev, build, lint, test, format +Hva som er testet: hvilke nettlesere, hvilke enheter, og hva de automatiske testene dekker +Forklaring av valg og løsninger, ikke bare hva som finnes. "Vi bruker sessionStorage til sortering og localStorage til favoritter, fordi kravene beskriver to ulike varigheter" er en forklaring. "Vi bruker Web Storage" er det ikke. +KI-bruk per person, pluss en oppsummering av erfaringer + +Det som ikke er krav nå + +"Dokumentasjonen skal beskrive hva som er forbedret siden første innlevering" gjelder sluttvurderingen i desember, ikke i morgen. + +Alt dette har du tekst til fra tidligere i dag, bortsett fra VM-lenka og lista over nettlesere og enheter dere faktisk har testet på..