diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 9495a90..bd67ad9 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -4,7 +4,7 @@ import { GameList } from './components/GameList/GameList'; import { Header } from './components/Header/Header'; import { GAMES } from './graphql/games'; import type { Suggestion } from './graphql/searchSuggestions'; -import type { GameSummary } from './types/game'; +import type { GameSummary, GameView } from './types/game'; import './App.css'; /** @@ -13,7 +13,7 @@ import './App.css'; */ function App() { const [favorites, setFavorites] = useState>(new Set()); - const [view, setView] = useState<'list' | 'grid'>('list'); + const [view, setView] = useState('list'); const [showFavorites, setShowFavorites] = useState(false); // Søket i hovedlista. Settes først når brukeren trykker Enter, ikke for hver bokstav @@ -70,23 +70,37 @@ function App() {

{showFavorites ? 'Favoritter' : 'Søkeresultater'}

- {/* Bytter mellom visning 1 (liste) og visning 2 (rutenett) */} -
+
+ +
diff --git a/frontend/src/components/GameCard/GameCard.css b/frontend/src/components/GameCard/GameCard.css index 781fc6f..fe798b4 100644 --- a/frontend/src/components/GameCard/GameCard.css +++ b/frontend/src/components/GameCard/GameCard.css @@ -169,3 +169,60 @@ margin-top: 6px; } } + + /* ===== Visning 3: utstillingsrad (1 per rad, stort bilde til venstre) ===== */ +.game-card--showcase { + grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); + gap: 28px; + padding: 28px 0; +} + +.game-card--showcase .game-card__body { + gap: 6px; + padding-right: 0; /* knappen ligger nederst her, ikke ved tittelen */ +} + +.game-card--showcase .game-card__title { + font-size: 26px; +} + +/* Store tall med små etiketter over, som i trykk */ +.game-card--showcase .game-card__scores { + gap: 32px; + margin: 16px 0; +} + +.game-card--showcase .game-card__scores div { + flex-direction: column; + gap: 2px; +} + +.game-card--showcase .game-card__scores dt { + font-family: var(--mono); + font-size: 12px; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.game-card--showcase .game-card__scores dd { + font-size: 28px; + line-height: 1.1; +} + +/* Favoritt-knappen nederst i tekstkolonnen i stedet for oppe i hjørnet */ +.game-card--showcase .game-card__favorite { + position: relative; + top: auto; + right: auto; + align-self: flex-start; + margin-top: auto; +} + +/* Smal skjerm: bildet over teksten */ +@media (max-width: 640px) { + .game-card--showcase { + grid-template-columns: 1fr; + gap: 14px; + } +} + diff --git a/frontend/src/components/GameCard/GameCard.tsx b/frontend/src/components/GameCard/GameCard.tsx index 690148d..c921645 100644 --- a/frontend/src/components/GameCard/GameCard.tsx +++ b/frontend/src/components/GameCard/GameCard.tsx @@ -1,4 +1,4 @@ -import type { GameSummary } from '../../types/game'; +import type { GameSummary, GameView } from '../../types/game'; import './GameCard.css'; interface GameCardProps { @@ -6,16 +6,17 @@ interface GameCardProps { isFavorite: boolean; onToggleFavorite: (id: string) => void; /** 'list' = visning 1 (rad), 'grid' = visning 2 (oppsummert rute) */ - view?: 'list' | 'grid'; + view?: GameView; } //Viser ett spill i resultatlista. Lenken i tittelen dekker hele kortet (via CSS), så hele kortet er klikkbart, men skjermlesere hører bare én lenke per kort. export function GameCard({ game, isFavorite, onToggleFavorite, view = 'list' }: GameCardProps) { const year = game.released?.slice(0, 4) ?? null; - const meta = [year, game.genres.slice(0, view === 'grid' ? 1 : 2).join(', ')] - .filter(Boolean) - .join(' · '); + // Rutenett: 1 sjanger, liste: 2, utstillingsrad: alle (undefined = ingen grense) + const maxGenres = view === 'grid' ? 1 : view === 'list' ? 2 : undefined; + const meta = [year, game.genres.slice(0, maxGenres).join(', ')].filter(Boolean).join(' · '); + return (
@@ -47,7 +48,7 @@ export function GameCard({ game, isFavorite, onToggleFavorite, view = 'list' }:
Rating
{game.rating != null ? `${game.rating.toFixed(1)} / 5` : 'Ingen'}
- {view === 'list' && ( + {view !== 'grid' && (
Metacritic
{game.metacritic ?? 'Ingen'}
diff --git a/frontend/src/components/GameList/GameList.tsx b/frontend/src/components/GameList/GameList.tsx index 2cc8e6f..ef6b944 100644 --- a/frontend/src/components/GameList/GameList.tsx +++ b/frontend/src/components/GameList/GameList.tsx @@ -1,4 +1,4 @@ -import type { GameSummary } from '../../types/game'; +import type { GameSummary, GameView } from '../../types/game'; import { GameCard } from '../GameCard/GameCard'; import './GameList.css'; @@ -6,7 +6,7 @@ interface GameListProps { games: GameSummary[]; favorites: Set; onToggleFavorite: (id: string) => void; - view: 'list' | 'grid'; + view: GameView; } /** diff --git a/frontend/src/types/game.ts b/frontend/src/types/game.ts index 0829d11..62107b8 100644 --- a/frontend/src/types/game.ts +++ b/frontend/src/types/game.ts @@ -11,3 +11,6 @@ export interface GameSummary { metacritic: number | null; genres: string[]; } + +/** 'list' = visning 1 (rad), 'grid' = visning 2 (rute), 'showcase' = visning 3 (utstillingsrad) */ +export type GameView = 'list' | 'grid' | 'showcase';