From c9fa5b99a1a62d63034451dcd2a9c5abd7b690d6 Mon Sep 17 00:00:00 2001 From: Clemens Beese Date: Mon, 12 Oct 2026 17:41:04 +0200 Subject: [PATCH 1/4] #28 rating, ratingsCount og playtime i Game-schema --- backend/src/schema.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/src/schema.ts b/backend/src/schema.ts index fa8b1eb..5e1b1c0 100644 --- a/backend/src/schema.ts +++ b/backend/src/schema.ts @@ -30,6 +30,9 @@ export const typeDefs = `#graphql website: String, added: Int!, metacritic: Int, + rating: Float, + ratingsCount: Int!, + playtime: Int, esrbRating: String, dominantColor: String, backgroundImage: String, From 01f041675171ebf723b5274d838804e8e7223538 Mon Sep 17 00:00:00 2001 From: Clemens Beese Date: Mon, 12 Oct 2026 17:41:04 +0200 Subject: [PATCH 2/4] #28 hent rating, ratingsCount og playtime fra databasen --- backend/src/resolvers.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/src/resolvers.ts b/backend/src/resolvers.ts index 9a9e10a..5537c4f 100644 --- a/backend/src/resolvers.ts +++ b/backend/src/resolvers.ts @@ -31,6 +31,9 @@ const GAME_COLS = ` website, added, metacritic, + rating, + ratings_count AS "ratingsCount", + playtime, esrb_rating AS "esrbRating", dominant_color AS "dominantColor", background_image AS "backgroundImage", From 5fb5902ec29f46ba7880de0dcd4315a3eae7b72c Mon Sep 17 00:00:00 2001 From: Clemens Beese Date: Mon, 12 Oct 2026 17:44:17 +0200 Subject: [PATCH 3/4] #28 dokumenter rating, ratingsCount og playtime i backend-api --- backend/backend-api.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/backend-api.md b/backend/backend-api.md index edb1e94..200bef0 100644 --- a/backend/backend-api.md +++ b/backend/backend-api.md @@ -218,6 +218,9 @@ Et spill med detaljer og relasjoner. | `website` | `String` | Offisiell nettside. | | `added` | `Int!` | Antall RAWG-brukere som har lagt spillet til i en liste. Brukes som mål på popularitet. | | `metacritic` | `Int` | Metacritic-score, 0–100. | +| `rating` | `Float` | RAWG-brukernes snittvurdering, 0–5. | +| `ratingsCount` | `Int!` | Antall vurderinger bak `rating`. | +| `playtime` | `Int` | Gjennomsnittlig spilletid i timer. | | `esrbRating` | `String` | Amerikansk aldersgrense, f.eks. `Mature`. | | `dominantColor` | `String` | Hovedfargen i forsidebildet som hex, f.eks. `0f0f0f`. | | `backgroundImage` | `String` | URL til forsidebildet. | From 0939bb194f0b3ad324f02b18ba0cf8aaa1588dbe Mon Sep 17 00:00:00 2001 From: Clemens Beese Date: Tue, 13 Oct 2026 11:48:04 +0200 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20sp=C3=B8rring=20til=20frontend=20og?= =?UTF-8?q?=20databasehenting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.css | 9 +++++++ frontend/src/App.tsx | 43 +++++++++++++++++++++++------- frontend/src/graphql/games.ts | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 frontend/src/graphql/games.ts diff --git a/frontend/src/App.css b/frontend/src/App.css index 8c3aa5c..8a106e5 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -19,3 +19,12 @@ font-family: var(--mono); font-size: 14px; } + +/* Antall treff under overskriften, i samme monospace som menyen */ +.results-count { + min-height: 1.5em; /* holder plassen, så lista ikke hopper når teksten kommer */ + margin: 8px 0 0; + font-family: var(--mono); + font-size: 13px; + color: var(--text); +} \ No newline at end of file diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index a09dfa0..9495a90 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,12 +1,14 @@ import { useState } from 'react'; +import { useQuery } from '@apollo/client/react'; import { GameList } from './components/GameList/GameList'; -import { mockGames } from './mocks/games'; -import type { Suggestion } from './graphql/searchSuggestions'; import { Header } from './components/Header/Header'; +import { GAMES } from './graphql/games'; +import type { Suggestion } from './graphql/searchSuggestions'; +import type { GameSummary } from './types/game'; import './App.css'; /** - * Midlertidig forside: viser spillene med mockdata til GraphQL er klart. + * Forsiden: søk, resultatliste fra databasen og favoritter. * Favoritter og valgt visning ligger bare i minnet her og skal senere inn i state management. */ function App() { @@ -22,12 +24,28 @@ function App() { // Den som lager detaljsiden bytter denne linjen til navigering. const handleSelectGame = (game: Suggestion) => setQuery(game.name); - // MIDLERTIDIG: filtrerer mockdata på klienten for å kunne teste søket. - // Når GraphQL er klart, sendes `query` til backend og filtreres i databasen. - const games = mockGames.filter( - (g) => - g.name.toLowerCase().includes(query.toLowerCase()) && (!showFavorites || favorites.has(g.id)), - ); + // Henter første side fra databasen. Kjøres på nytt bare når `query` endres (ved Enter). + // Tomt søk (null) gir de mest populære spillene. + const { data, previousData, loading, error } = useQuery(GAMES, { + variables: { search: query || null, first: 20 }, + }); + const result = data ?? previousData; // forrige liste vises mens den nye lastes + + // Backend gir sjangre som objekter ({ name }), spillkortet forventer bare navnene + const allGames: GameSummary[] = + result?.games.edges.map(({ node }) => ({ + ...node, + genres: node.genres.map((g) => g.name), + })) ?? []; + + // MIDLERTIDIG: favoritter filtreres blant spillene som er lastet inn. + // Når favoritter lagres i databasen, bør de hentes derfra i stedet. + const games = showFavorites ? allGames.filter((g) => favorites.has(g.id)) : allGames; + + // Teksten over lista. role="status" gjør at skjermlesere leser den opp når den endres + let status = ''; + if (loading && !result) status = 'Laster …'; + else if (result && !showFavorites) status = `${result.games.totalCount.toLocaleString('nb-NO')} treff`; const toggleFavorite = (id: string) => { setFavorites((prev) => { @@ -73,6 +91,11 @@ function App() { +

+ {status} +

+ {error &&

Kunne ikke hente spill: {error.message}

} + = gql` + query Games($search: String, $first: Int) { + games(search: $search, first: $first) { + totalCount + edges { + node { + id + name + released + backgroundImage + rating + metacritic + genres { + name + } + } + } + } + } +`; \ No newline at end of file