Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
62e3ed6
style(frontend): papirhvitt lyst tema, mørkt tema, tekstknapper og te…
Oct 12, 2026
4a6f975
feat(frontend): sett tema før siden tegnes og lang=no
Oct 12, 2026
0c3024d
feat(frontend): legg til tegning i sidefeltet
Oct 12, 2026
d63bbc0
feat(frontend): ThemeToggle for lyst/mørkt tema
Oct 12, 2026
0320db9
feat(frontend): logo følger valgt tema
Oct 12, 2026
bbdbb4d
style(frontend): logo i toppfeltet på smale skjermer
Oct 12, 2026
f8bb8f6
style(frontend): søkefelt med bare linje under
Oct 12, 2026
cc31871
style(frontend): Header i trykk-stil
Oct 12, 2026
0429009
feat(frontend): Header med søk, favoritter og tema
Oct 12, 2026
c4082b8
style(frontend): erstatt Vite-rester med layout for hovedinnholdet
Oct 12, 2026
1f6c131
feat(frontend): bruk Header og vis bare favoritter
Oct 12, 2026
89d4e7d
Merge pull request #52 from IT2810-H26/feat/theme
clemenbe Oct 12, 2026
3a9e925
fix: db-tunnel bug og kommentert ut linje i .env.example
Oct 12, 2026
93f43db
Update ci.yml
albertpl Oct 13, 2026
a75bc18
Update ci.yml
albertpl Oct 13, 2026
f45381f
Update ci.yml
albertpl Oct 13, 2026
f0cf22f
feat(frontend): Apollo-klient mot GraphQL-backend
Oct 13, 2026
e77fb05
feat(frontend): ApolloProvider rundt appen
Oct 13, 2026
336d28c
feat(frontend): spørring for søkeforslag (6 spill, bare navn og år)
Oct 13, 2026
cd839e0
style(frontend): GameSearch med forslagsliste i trykk-stil
Oct 13, 2026
569bee6
feat(frontend): GameSearch med forslag fra serveren (combobox)
Oct 13, 2026
6ea1d93
feat(frontend): bruk GameSearch i Header
Oct 13, 2026
bbc864f
feat(frontend): hovedlista oppdateres bare ved Enter
Oct 13, 2026
bf081ae
Merge pull request #53 from IT2810-H26/feat/search-suggestions
clemenbe Oct 13, 2026
419208f
Merge branch 'feat/cleanup' into feat/list-from-db
Oct 13, 2026
0939bb1
feat: spørring til frontend og databasehenting
Oct 13, 2026
b3c7266
Merge pull request #54 from IT2810-H26/feat/list-from-db
clemenbe Oct 13, 2026
a6cedf8
feat(frontend): legg til tredje visning (utstillingsrad) for spillkort
laspark Oct 13, 2026
02c4a7d
feat(frontend): vis visningsvalget som «visning 1 2 3»
laspark Oct 13, 2026
04ece2b
Merge pull request #58 from IT2810-H26/feature/spillkort
albertpl Oct 13, 2026
9eeef3e
fix: endret package.json for å gjøre klart deploy steg
Oct 15, 2026
e8ada5b
fix: pnpm-lock update
Oct 15, 2026
83eba3f
feature: deploy steg i github actions
Oct 15, 2026
b12eaf2
fix vite.config.ts base path
Oct 15, 2026
c92cf54
Update ci.yml
albertpl Oct 15, 2026
902d36b
Update ci.yml
albertpl Oct 15, 2026
54577cc
formattering på backend
Oct 15, 2026
7ee6e88
Merge pull request #59 from IT2810-H26/backend/format
albertpl Oct 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 76 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,96 @@ on:
branches: [main, dev]
push:
branches: [main, dev]
workflow_dispatch:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: false

jobs:
lint-and-test:
check-and-deploy:
runs-on: self-hosted
strategy:
matrix:
workspace: [frontend, backend]
defaults:
run:
working-directory: ${{ matrix.workspace }}
env:
DEPLOY_DIR: /var/www/project2
SERVICE: project2-backend.service
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 24.21.0

- uses: pnpm/action-setup@v4
with:
version: 11.25.0

- uses: actions/setup-node@v4
- name: Get pnpm store path
id: pnpm-store
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"

- uses: actions/cache@v4
with:
node-version: 24.21.0
cache: pnpm
cache-dependency-path: ${{ matrix.workspace }}/pnpm-lock.yaml
path: ${{ steps.pnpm-store.outputs.path }}
key: pnpm-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: pnpm-${{ runner.os }}-

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Lint
run: pnpm run lint
- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Format
run: pnpm format:check

- name: Lint frontend
if: ${{ !cancelled() }}
run: pnpm --filter frontend lint

- name: Lint backend
if: ${{ !cancelled() }}
run: pnpm --filter backend lint

- name: Build frontend
if: ${{ !cancelled() }}
run: pnpm --filter frontend build

- name: Build backend
if: ${{ !cancelled() }}
run: pnpm --filter backend build

- name: Test frontend
if: ${{ !cancelled() }}
run: pnpm --filter frontend --if-present run test

- name: Test backend
if: ${{ !cancelled() }}
run: pnpm --filter backend --if-present run test

- name: Deploy frontend
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
run: rsync -a --delete frontend/dist/ "$DEPLOY_DIR/frontend/"

- name: Typecheck
run: pnpm run --if-present typecheck
- name: Deploy backend
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
run: |
rm -rf "$DEPLOY_DIR/backend.new" "$DEPLOY_DIR/backend.old"
pnpm --filter backend deploy --prod "$DEPLOY_DIR/backend.new"
if [ -d "$DEPLOY_DIR/backend" ]; then mv "$DEPLOY_DIR/backend" "$DEPLOY_DIR/backend.old"; fi
mv "$DEPLOY_DIR/backend.new" "$DEPLOY_DIR/backend"
sudo -n /usr/bin/systemctl restart "$SERVICE"
rm -rf "$DEPLOY_DIR/backend.old"
- name: Test
run: pnpm run --if-present test --run
- name: Check backend
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
run: |
for i in $(seq 1 10); do
if curl -sf -X POST -H 'Content-Type: application/json' \
-d '{"query":"{ genres { id } }"}' http://localhost:3001/ > /dev/null; then
echo "Backend is up"
exit 0
fi
sleep 2
done
echo "Backend did not respond"
systemctl status "$SERVICE" --no-pager || true
exit 1
50 changes: 50 additions & 0 deletions .github/workflows/ci.yml.bak
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: CI

on:
pull_request:
branches: [main, dev]
push:
branches: [main, dev]

jobs:
lint-and-test:
runs-on: self-hosted
strategy:
fail-fast: false
matrix:
workspace: [frontend, backend]
defaults:
run:
working-directory: ${{ matrix.workspace }}
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 24.21.0

- uses: pnpm/action-setup@v4
with:
version: 11.25.0

- name: Get pnpm store path
id: pnpm-store
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"

- uses: actions/cache@v4
with:
path: ${{ steps.pnpm-store.outputs.path }}
key: pnpm-${{ runner.os }}-${{ matrix.workspace }}-${{ hashFiles(format('{0}/pnpm-lock.yaml', matrix.workspace)) }}
restore-keys: pnpm-${{ runner.os }}-${{ matrix.workspace }}-

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Lint
run: pnpm run lint

- name: Typecheck
run: pnpm run --if-present typecheck

- name: Test
run: pnpm run --if-present test --run
2 changes: 1 addition & 1 deletion backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ TUNNEL_PORT=5433
# backend server env vars
DATABASE_URL=postgresql://webapp:<PASSORD>@localhost:5433/gamesdb
PORT=3001
JWT_TOKEN=<server-rand-token>
#JWT_TOKEN=<server-rand-token>
123 changes: 71 additions & 52 deletions backend/backend-api.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Backend-API

## Queries

### game

Henter informasjon om ett enkelt spill ved ID.
Expand All @@ -25,7 +27,9 @@ game(id: ID!): Game
game(id: "3498") {
name
esrbRating
genres { name }
genres {
name
}
}
}
```
Expand Down Expand Up @@ -54,11 +58,11 @@ games(search: String, filter: GameFilter, first: Int = 20): GameConnection!

#### Argumenter

| Navn | Type | Default | Beskrivelse |
| -------- | --------------------------- | ------- | --------------------------------------------------------------------------------------------- |
| Navn | Type | Default | Beskrivelse |
| -------- | --------------------------- | ------- | --------------------------------------------------------------------------------------------------------- |
| `search` | `String` | — | Søk i tittel og alternative navn. Skiller ikke mellom store og små bokstaver, og matcher deler av navnet. |
| `filter` | [`GameFilter`](#gamefilter) | — | Filtrering på sjanger, plattform og utgivelsesår. |
| `first` | `Int` | `20` | Antall spill på siden. Begrenset til 1–50. |
| `filter` | [`GameFilter`](#gamefilter) | — | Filtrering på sjanger, plattform og utgivelsesår. |
| `first` | `Int` | `20` | Antall spill på siden. Begrenset til 1–50. |

Alle argumenter er valgfrie og kan kombineres.

Expand All @@ -72,7 +76,11 @@ Alle argumenter er valgfrie og kan kombineres.
{
games(search: "zelda", first: 3) {
totalCount
edges { node { name } }
edges {
node {
name
}
}
}
}
```
Expand Down Expand Up @@ -103,7 +111,12 @@ Action- og RPG-spill på PC, utgitt 2015–2020:
first: 3
) {
totalCount
edges { node { name released } }
edges {
node {
name
released
}
}
}
}
```
Expand Down Expand Up @@ -145,7 +158,10 @@ Liste med [`Facet`](#facet).

```graphql
{
genres { id name }
genres {
id
name
}
}
```

Expand Down Expand Up @@ -185,7 +201,10 @@ Merk: ID-ene her er plattformfamilier og er ikke de samme som ID-ene i `Game.pla

```graphql
{
platforms { id name }
platforms {
id
name
}
}
```

Expand All @@ -202,36 +221,38 @@ Merk: ID-ene her er plattformfamilier og er ikke de samme som ID-ene i `Game.pla
```

## Mutations

> Dette skal legges til når funksjonalitet for brukere blir lagt til
## Types

### Game

Et spill med detaljer og relasjoner.

| Felt | Type | Beskrivelse |
| --------------------------- | ------------------- | ----------------------------------------------------------------- |
| `id` | `ID!` | ID til spillet. |
| `name` | `String!` | Tittel. |
| `description` | `String` | Beskrivelse i ren tekst. |
| `released` | `String` | Utgivelsesdato, `YYYY-MM-DD`. |
| `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. |
| `backgroundImageAdditional` | `String` | URL til et ekstra bilde. |
| `screenshots` | `[String!]!` | URL-er til skjermbilder. Tom liste hvis ingen. |
| `genres` | [`[Facet!]!`](#facet) | Sjangre. |
| `platforms` | [`[Facet!]!`](#facet) | Enkeltkonsoller, f.eks. PlayStation 4. |
| `stores` | [`[Facet!]!`](#facet) | Butikker spillet selges i. |
| `developers` | [`[Facet!]!`](#facet) | Utviklere. |
| `publishers` | [`[Facet!]!`](#facet) | Utgivere. |
| `tags` | [`[Facet!]!`](#facet) | Tagger fra RAWG, f.eks. Open World. |
| Felt | Type | Beskrivelse |
| --------------------------- | --------------------- | --------------------------------------------------------------------------------------- |
| `id` | `ID!` | ID til spillet. |
| `name` | `String!` | Tittel. |
| `description` | `String` | Beskrivelse i ren tekst. |
| `released` | `String` | Utgivelsesdato, `YYYY-MM-DD`. |
| `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. |
| `backgroundImageAdditional` | `String` | URL til et ekstra bilde. |
| `screenshots` | `[String!]!` | URL-er til skjermbilder. Tom liste hvis ingen. |
| `genres` | [`[Facet!]!`](#facet) | Sjangre. |
| `platforms` | [`[Facet!]!`](#facet) | Enkeltkonsoller, f.eks. PlayStation 4. |
| `stores` | [`[Facet!]!`](#facet) | Butikker spillet selges i. |
| `developers` | [`[Facet!]!`](#facet) | Utviklere. |
| `publishers` | [`[Facet!]!`](#facet) | Utgivere. |
| `tags` | [`[Facet!]!`](#facet) | Tagger fra RAWG, f.eks. Open World. |

Relasjonene returnerer en tom liste hvis spillet ikke har noen.

Expand All @@ -252,30 +273,30 @@ Felles type for sjangre, plattformer, butikker, utviklere, utgivere og tagger.

Resultatet av [`games`](#games). Følger Relay-mønsteret for paginering (se [dokumentasjon](https://graphql.org/learn/pagination/)).

| Felt | Type | Beskrivelse |
| ------------ | --------------------------- | --------------------------------------------------- |
| `edges` | [`[GameEdge!]!`](#gameedge) | Spillene på denne siden. |
| `pageInfo` | [`PageInfo!`](#pageinfo) | Informasjon for å hente neste side. |
| `totalCount` | `Int!` | Totalt antall spill som matcher søk og filtre. |
| Felt | Type | Beskrivelse |
| ------------ | --------------------------- | ---------------------------------------------- |
| `edges` | [`[GameEdge!]!`](#gameedge) | Spillene på denne siden. |
| `pageInfo` | [`PageInfo!`](#pageinfo) | Informasjon for å hente neste side. |
| `totalCount` | `Int!` | Totalt antall spill som matcher søk og filtre. |

---

### GameEdge

Ett spill i en [`GameConnection`](#gameconnection).

| Felt | Type | Beskrivelse |
| -------- | -------------------- | ------------------------------------ |
| `node` | [`Game!`](#game-1) | Spillet. |
| `cursor` | `String!` | Posisjonen til spillet i listen. |
| Felt | Type | Beskrivelse |
| -------- | ------------------ | -------------------------------- |
| `node` | [`Game!`](#game-1) | Spillet. |
| `cursor` | `String!` | Posisjonen til spillet i listen. |

---

### PageInfo

| Felt | Type | Beskrivelse |
| ------------- | ---------- | ------------------------------------------------------------- |
| `hasNextPage` | `Boolean!` | `true` hvis det finnes flere spill etter denne siden. |
| Felt | Type | Beskrivelse |
| ------------- | ---------- | ------------------------------------------------------------------- |
| `hasNextPage` | `Boolean!` | `true` hvis det finnes flere spill etter denne siden. |
| `endCursor` | `String` | Cursor til siste spill på siden. Sendes som `after` for neste side. |

---
Expand All @@ -284,13 +305,11 @@ Ett spill i en [`GameConnection`](#gameconnection).

Input-type for filtrering i [`games`](#games). Alle felt er valgfrie.

| Felt | Type | Beskrivelse |
| -------------- | -------- | ------------------------------------------------------------------------------ |
| `genreIds` | `[ID!]` | Spill som har **alle** de valgte sjangrene. ID-er fra [`genres`](#genres). |
| `platformIds` | `[ID!]` | Spill på **minst én** av de valgte plattformfamiliene. ID-er fra [`platforms`](#platforms). |
| `releasedFrom` | `Int` | Utgitt dette året eller senere, f.eks. `2015`. |
| `releasedTo` | `Int` | Utgitt dette året eller tidligere, f.eks. `2020`. |
| Felt | Type | Beskrivelse |
| -------------- | ------- | ------------------------------------------------------------------------------------------- |
| `genreIds` | `[ID!]` | Spill som har **alle** de valgte sjangrene. ID-er fra [`genres`](#genres). |
| `platformIds` | `[ID!]` | Spill på **minst én** av de valgte plattformfamiliene. ID-er fra [`platforms`](#platforms). |
| `releasedFrom` | `Int` | Utgitt dette året eller senere, f.eks. `2015`. |
| `releasedTo` | `Int` | Utgitt dette året eller tidligere, f.eks. `2020`. |

Merk: Spill uten utgivelsesdato utelates når `releasedFrom` eller `releasedTo` er satt. ID-er som ikke er tall ignoreres.


3 changes: 3 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
"start": "pnpm run build && node dist/index.js",
"lint": "eslint ."
},
"files": [
"dist"
],
"keywords": [],
"author": "",
"license": "ISC",
Expand Down
3 changes: 1 addition & 2 deletions backend/src/auth.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@

// server jwt secret
// const secret = process.env.JWT_SECRET;
// const secret = process.env.JWT_SECRET;
Loading