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. | 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", 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, 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}
} +