From 320ef6473e53a7055989459c9e4245e542786487 Mon Sep 17 00:00:00 2001 From: Johannes Bergslid Date: Sun, 13 Sep 2026 13:43:33 +0200 Subject: [PATCH 1/8] Created draft of song card design. --- webdev-prosjekt1/src/App.css | 11 +++++- webdev-prosjekt1/src/App.tsx | 4 ++ webdev-prosjekt1/src/components/Card.css | 5 +++ webdev-prosjekt1/src/components/Card.tsx | 14 +++++++ webdev-prosjekt1/src/components/SongCard.css | 41 ++++++++++++++++++++ webdev-prosjekt1/src/components/SongCard.tsx | 16 ++++++++ 6 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 webdev-prosjekt1/src/components/Card.css create mode 100644 webdev-prosjekt1/src/components/Card.tsx create mode 100644 webdev-prosjekt1/src/components/SongCard.css create mode 100644 webdev-prosjekt1/src/components/SongCard.tsx diff --git a/webdev-prosjekt1/src/App.css b/webdev-prosjekt1/src/App.css index 7bb7cc9..01f6df3 100644 --- a/webdev-prosjekt1/src/App.css +++ b/webdev-prosjekt1/src/App.css @@ -50,8 +50,8 @@ body { min-width: 320px; } position: relative; max-width: 1240px; margin: 0 auto; - display: grid; - grid-template-columns: 0.9fr 1.1fr; + display: flex; + flex-direction: column; padding: 30px 48px 70px; } @@ -145,4 +145,11 @@ body { min-width: 320px; } border-radius: 50%; background: rgba(226, 157, 38, 0.13); filter: blur(45px); +} + +.testlist { + width: 50%; + list-style: none; + padding: 0; + margin: 0; } \ No newline at end of file diff --git a/webdev-prosjekt1/src/App.tsx b/webdev-prosjekt1/src/App.tsx index 2493cb3..6837b4b 100644 --- a/webdev-prosjekt1/src/App.tsx +++ b/webdev-prosjekt1/src/App.tsx @@ -1,6 +1,7 @@ import './App.css'; import { Button } from './components/Button'; import { Searchbar } from './components/Searchbar'; +import { ArtistCard } from './components/SongCard'; import filterIcon from './assets/filter.png'; import musicWizImage from './assets/musicwiz.png'; import { searchTrack, searchAlbum, searchArtist } from "./api/spotify" @@ -27,6 +28,9 @@ function App() {
A musical wizard
+ diff --git a/webdev-prosjekt1/src/components/Card.css b/webdev-prosjekt1/src/components/Card.css new file mode 100644 index 0000000..6b31a75 --- /dev/null +++ b/webdev-prosjekt1/src/components/Card.css @@ -0,0 +1,5 @@ +.search-result-card { + background-color: aliceblue; + display: grid; + grid-template-columns: 1fr 2fr; +} \ No newline at end of file diff --git a/webdev-prosjekt1/src/components/Card.tsx b/webdev-prosjekt1/src/components/Card.tsx new file mode 100644 index 0000000..40ec043 --- /dev/null +++ b/webdev-prosjekt1/src/components/Card.tsx @@ -0,0 +1,14 @@ +import './Card.css'; +import type { ReactNode } from "react"; + +type CardContent = { + content: ReactNode; +} + +export const Card = ({ content }: CardContent) => { + return ( +
  • + {content} +
  • + ) +} \ No newline at end of file diff --git a/webdev-prosjekt1/src/components/SongCard.css b/webdev-prosjekt1/src/components/SongCard.css new file mode 100644 index 0000000..52c71b9 --- /dev/null +++ b/webdev-prosjekt1/src/components/SongCard.css @@ -0,0 +1,41 @@ +.search-result-card { + display: flex; + padding: 0.3rem; + + border-radius: 0.5rem; + + background-color: rgb(43, 43, 43); +} + +.card-image { + aspect-ratio: 1 / 1; + width: 100%; + height: 100%; +} + +.card-image-wrapper { + width: 20%; + border-radius: 0.5rem; + overflow: hidden; +} + +.card-info-container { + display: flex; + flex-direction: column; + gap: 1rem; + + padding: 0.5rem 1rem; +} + +.card-header { + width: 100%; + margin: 0; + + font-size: 1.5rem; +} + +.artist-name { + width: 100%; + + font-size: 1rem; +} diff --git a/webdev-prosjekt1/src/components/SongCard.tsx b/webdev-prosjekt1/src/components/SongCard.tsx new file mode 100644 index 0000000..9e8e940 --- /dev/null +++ b/webdev-prosjekt1/src/components/SongCard.tsx @@ -0,0 +1,16 @@ +import './SongCard.css'; + +export const ArtistCard = () => { + return ( +
  • +
    + +
    + +
    +

    Bæ bæ lille lam

    + JBgamingHD +
    +
  • + ) +} \ No newline at end of file From e538f2ab4f352ce02b89b56daa8d500f1ff657b4 Mon Sep 17 00:00:00 2001 From: Johannes Bergslid Date: Sun, 13 Sep 2026 14:06:43 +0200 Subject: [PATCH 2/8] Added a display for song duration. --- webdev-prosjekt1/src/App.css | 2 +- webdev-prosjekt1/src/components/SongCard.css | 26 ++++++++++++++++---- webdev-prosjekt1/src/components/SongCard.tsx | 9 +++++-- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/webdev-prosjekt1/src/App.css b/webdev-prosjekt1/src/App.css index 01f6df3..3c828af 100644 --- a/webdev-prosjekt1/src/App.css +++ b/webdev-prosjekt1/src/App.css @@ -148,7 +148,7 @@ body { min-width: 320px; } } .testlist { - width: 50%; + width: 100%; list-style: none; padding: 0; margin: 0; diff --git a/webdev-prosjekt1/src/components/SongCard.css b/webdev-prosjekt1/src/components/SongCard.css index 52c71b9..bdfd1af 100644 --- a/webdev-prosjekt1/src/components/SongCard.css +++ b/webdev-prosjekt1/src/components/SongCard.css @@ -2,6 +2,8 @@ display: flex; padding: 0.3rem; + max-width: 400px; + border-radius: 0.5rem; background-color: rgb(43, 43, 43); @@ -14,28 +16,42 @@ } .card-image-wrapper { - width: 20%; + max-width: 60px; border-radius: 0.5rem; overflow: hidden; } .card-info-container { + display: flex; + justify-content: space-between; + width: 100%; + + padding: 0.3rem 1rem; +} + +.title-and-artist { display: flex; flex-direction: column; - gap: 1rem; + justify-content: center; - padding: 0.5rem 1rem; + gap: 0.7rem; } .card-header { width: 100%; margin: 0; - font-size: 1.5rem; + font-size: 1rem; } .artist-name { width: 100%; - font-size: 1rem; + font-size: 0.8rem; +} + +.duration-display-container { + display: flex; + align-items: center; + justify-content: center; } diff --git a/webdev-prosjekt1/src/components/SongCard.tsx b/webdev-prosjekt1/src/components/SongCard.tsx index 9e8e940..2bd782d 100644 --- a/webdev-prosjekt1/src/components/SongCard.tsx +++ b/webdev-prosjekt1/src/components/SongCard.tsx @@ -8,8 +8,13 @@ export const ArtistCard = () => {
    -

    Bæ bæ lille lam

    - JBgamingHD +
    +

    Bæ bæ lille lam

    + JBgamingHD +
    +
    + 4:31 +
    ) From d29ed2765e7444aa57372862263a1586724d30ba Mon Sep 17 00:00:00 2001 From: Martin Sunnset Date: Sun, 13 Sep 2026 14:45:15 +0200 Subject: [PATCH 3/8] Fixed picture not showing --- webdev-prosjekt1/src/App.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/webdev-prosjekt1/src/App.tsx b/webdev-prosjekt1/src/App.tsx index 2179a8f..1ffc85d 100644 --- a/webdev-prosjekt1/src/App.tsx +++ b/webdev-prosjekt1/src/App.tsx @@ -34,13 +34,12 @@ function App() {
    -
    -
    - A musical wizard -
    +
    +
    + A musical wizard
    From 7641d4ef9f8027dd445c09ed36d13585c9836bfb Mon Sep 17 00:00:00 2001 From: Martin Sunnset Date: Sun, 13 Sep 2026 14:53:41 +0200 Subject: [PATCH 4/8] Fixed searchbar responsiveness, and changed Artistcard to Songcard --- webdev-prosjekt1/src/App.css | 12 ++++++------ webdev-prosjekt1/src/App.tsx | 4 ++-- webdev-prosjekt1/src/components/SongCard.tsx | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/webdev-prosjekt1/src/App.css b/webdev-prosjekt1/src/App.css index e81f7bc..a3db0a9 100644 --- a/webdev-prosjekt1/src/App.css +++ b/webdev-prosjekt1/src/App.css @@ -78,12 +78,11 @@ body { display: flex; gap: 10px; - width: calc(100% - 96px); - max-width: 1400px; + width: 100%; + max-width: 1020px; margin: 14px auto 0; - margin-left: 64px; - margin-right: 64px; + padding: 0 24px; } .hero-section { @@ -145,8 +144,9 @@ body { font-size: 40px; } - .search-controls { - width: calc(100% - 48px); + .search-section { + max-width: 100%; + padding: 0 12px; } .hero-section { diff --git a/webdev-prosjekt1/src/App.tsx b/webdev-prosjekt1/src/App.tsx index 1ffc85d..b3622b1 100644 --- a/webdev-prosjekt1/src/App.tsx +++ b/webdev-prosjekt1/src/App.tsx @@ -2,7 +2,7 @@ import './App.css'; import './variables.css'; import { Button } from './components/Button'; import { Searchbar } from './components/Searchbar'; -import { ArtistCard } from './components/SongCard'; +import { SongCard } from './components/SongCard'; import filterIcon from './assets/filter.png'; import musicWizImage from './assets/musicwiz.png'; import logoImage from './assets/music-wiz-logo.png'; @@ -35,7 +35,7 @@ function App() {
      - +
    diff --git a/webdev-prosjekt1/src/components/SongCard.tsx b/webdev-prosjekt1/src/components/SongCard.tsx index 2bd782d..d598d90 100644 --- a/webdev-prosjekt1/src/components/SongCard.tsx +++ b/webdev-prosjekt1/src/components/SongCard.tsx @@ -1,6 +1,6 @@ import './SongCard.css'; -export const ArtistCard = () => { +export const SongCard = () => { return (
  • From 28df7e5a1e59b418c9f28db2c4f73b090cd8a683 Mon Sep 17 00:00:00 2001 From: Martin Sunnset Date: Sun, 13 Sep 2026 15:01:14 +0200 Subject: [PATCH 5/8] Created ArtistCard and AlbumCard, and put them at the bottom of the page --- webdev-prosjekt1/src/App.css | 20 +++++++++++++++++- webdev-prosjekt1/src/App.tsx | 13 +++++++++--- webdev-prosjekt1/src/components/AlbumCard.tsx | 21 +++++++++++++++++++ .../src/components/ArtistCard.css | 3 +++ .../src/components/ArtistCard.tsx | 19 +++++++++++++++++ 5 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 webdev-prosjekt1/src/components/AlbumCard.tsx create mode 100644 webdev-prosjekt1/src/components/ArtistCard.css create mode 100644 webdev-prosjekt1/src/components/ArtistCard.tsx diff --git a/webdev-prosjekt1/src/App.css b/webdev-prosjekt1/src/App.css index a3db0a9..afd4b9f 100644 --- a/webdev-prosjekt1/src/App.css +++ b/webdev-prosjekt1/src/App.css @@ -187,5 +187,23 @@ body { width: 100%; list-style: none; padding: 0; - margin: 0; + margin: 0; + + display: flex; + flex-direction: column; + gap: 12px; +} + +.results-section { + max-width: 1400px; + width: calc(100% - 96px); + + margin: 0 auto; + padding: 20px 0 60px; +} + +@media (max-width: 700px) { + .results-section { + width: calc(100% - 48px); + } } diff --git a/webdev-prosjekt1/src/App.tsx b/webdev-prosjekt1/src/App.tsx index b3622b1..1d0a606 100644 --- a/webdev-prosjekt1/src/App.tsx +++ b/webdev-prosjekt1/src/App.tsx @@ -3,6 +3,8 @@ import './variables.css'; import { Button } from './components/Button'; import { Searchbar } from './components/Searchbar'; import { SongCard } from './components/SongCard'; +import { AlbumCard } from './components/AlbumCard'; +import { ArtistCard } from './components/ArtistCard'; import filterIcon from './assets/filter.png'; import musicWizImage from './assets/musicwiz.png'; import logoImage from './assets/music-wiz-logo.png'; @@ -34,14 +36,19 @@ function App() {
  • -
      - -
    A musical wizard
    + +
    +
      + + + +
    +
    ) diff --git a/webdev-prosjekt1/src/components/AlbumCard.tsx b/webdev-prosjekt1/src/components/AlbumCard.tsx new file mode 100644 index 0000000..9c78ff6 --- /dev/null +++ b/webdev-prosjekt1/src/components/AlbumCard.tsx @@ -0,0 +1,21 @@ +import './SongCard.css'; + +export const AlbumCard = () => { + return ( +
  • +
    + +
    + +
    +
    +

    Bæ bæ lille lam

    + JBgamingHD +
    +
    + 2024 +
    +
    +
  • + ) +} diff --git a/webdev-prosjekt1/src/components/ArtistCard.css b/webdev-prosjekt1/src/components/ArtistCard.css new file mode 100644 index 0000000..76a485f --- /dev/null +++ b/webdev-prosjekt1/src/components/ArtistCard.css @@ -0,0 +1,3 @@ +.artist-image-wrapper { + border-radius: 50%; +} diff --git a/webdev-prosjekt1/src/components/ArtistCard.tsx b/webdev-prosjekt1/src/components/ArtistCard.tsx new file mode 100644 index 0000000..292b689 --- /dev/null +++ b/webdev-prosjekt1/src/components/ArtistCard.tsx @@ -0,0 +1,19 @@ +import './SongCard.css'; +import './ArtistCard.css'; + +export const ArtistCard = () => { + return ( +
  • +
    + +
    + +
    +
    +

    JBgamingHD

    + Artist +
    +
    +
  • + ) +} From e764455370f22e45083d0d294ae8890c4a8e940c Mon Sep 17 00:00:00 2001 From: Martin Sunnset Date: Tue, 15 Sep 2026 10:02:30 +0200 Subject: [PATCH 6/8] Created TrackCard and updated UI to show Tracks, Albums and Artists in Columns --- webdev-prosjekt1/src/App.css | 108 +++++++++--------- webdev-prosjekt1/src/App.tsx | 62 +++++++--- webdev-prosjekt1/src/components/AlbumCard.tsx | 22 +++- .../src/components/ArtistCard.tsx | 16 ++- webdev-prosjekt1/src/components/SongCard.tsx | 21 ---- .../{SongCard.css => TrackCard.css} | 2 +- webdev-prosjekt1/src/components/TrackCard.tsx | 37 ++++++ .../src/components/fallbackImage.ts | 1 + webdev-prosjekt1/src/mockData.ts | 74 ++++++++++++ 9 files changed, 244 insertions(+), 99 deletions(-) delete mode 100644 webdev-prosjekt1/src/components/SongCard.tsx rename webdev-prosjekt1/src/components/{SongCard.css => TrackCard.css} (97%) create mode 100644 webdev-prosjekt1/src/components/TrackCard.tsx create mode 100644 webdev-prosjekt1/src/components/fallbackImage.ts create mode 100644 webdev-prosjekt1/src/mockData.ts diff --git a/webdev-prosjekt1/src/App.css b/webdev-prosjekt1/src/App.css index afd4b9f..a27a2e4 100644 --- a/webdev-prosjekt1/src/App.css +++ b/webdev-prosjekt1/src/App.css @@ -85,6 +85,38 @@ body { padding: 0 24px; } +@media (max-width: 700px) { + .main-header { + padding: 16px 24px 12px; + } + + .app-title-text { + font-size: 40px; + } + + .search-section { + max-width: 100%; + padding: 0 12px; + } + + .hero-section { + width: calc(100% - 48px); + } + + .hero-art { + width: 320px; + min-height: 380px; + } + + .hero-art img { + max-width: 290px; + } + + .art-glow { + width: 230px; + } +} + .hero-section { max-width: 1400px; width: calc(100% - 96px); @@ -134,56 +166,7 @@ body { filter: blur(45px); } - -@media (max-width: 700px) { - .main-header { - padding: 16px 24px 12px; - } - - .app-title-text { - font-size: 40px; - } - - .search-section { - max-width: 100%; - padding: 0 12px; - } - - .hero-section { - width: calc(100% - 48px); - } - - .hero-art { - width: 320px; - min-height: 380px; - } - - .hero-art img { - max-width: 290px; - } - - .art-glow { - width: 230px; - } -} -.hero-art img { - position: relative; - z-index: 1; - width: min(100%, 680px); - max-height: 760px; - object-fit: contain; - filter: drop-shadow(0 20px 25px rgba(0, 0, 0, 0.45)); -} -.art-glow { - position: absolute; - width: 62%; - aspect-ratio: 1; - border-radius: 50%; - background: rgba(226, 157, 38, 0.13); - filter: blur(45px); -} - -.testlist { +.card-list { width: 100%; list-style: none; padding: 0; @@ -198,12 +181,31 @@ body { max-width: 1400px; width: calc(100% - 96px); - margin: 0 auto; - padding: 20px 0 60px; + margin: 20px auto 0; + padding: 0 0 60px; + + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; + align-items: start; } -@media (max-width: 700px) { +@media (max-width: 900px) { .results-section { + grid-template-columns: 1fr; width: calc(100% - 48px); } } + +.results-group { + display: flex; + flex-direction: column; + gap: 14px; +} + +.results-heading { + margin: 0; + color: var(--primary_color); + font-size: 1.4rem; + letter-spacing: 0.04em; +} diff --git a/webdev-prosjekt1/src/App.tsx b/webdev-prosjekt1/src/App.tsx index 1d0a606..2f75ae2 100644 --- a/webdev-prosjekt1/src/App.tsx +++ b/webdev-prosjekt1/src/App.tsx @@ -1,15 +1,26 @@ +import { useState } from 'react'; import './App.css'; import './variables.css'; import { Button } from './components/Button'; import { Searchbar } from './components/Searchbar'; -import { SongCard } from './components/SongCard'; +import { TrackCard } from './components/TrackCard'; import { AlbumCard } from './components/AlbumCard'; import { ArtistCard } from './components/ArtistCard'; +import { mockTracks, mockAlbums, mockArtists } from './mockData'; import filterIcon from './assets/filter.png'; import musicWizImage from './assets/musicwiz.png'; import logoImage from './assets/music-wiz-logo.png'; function App() { + const [query, setQuery] = useState(''); + const [hasSearched, setHasSearched] = useState(false); + + const handleSearch = () => { + if (query.trim()) { + setHasSearched(true); + } + } + return ( <>
    @@ -35,20 +46,43 @@ function App() {
    ) diff --git a/webdev-prosjekt1/src/components/AlbumCard.tsx b/webdev-prosjekt1/src/components/AlbumCard.tsx index 9c78ff6..aa547e5 100644 --- a/webdev-prosjekt1/src/components/AlbumCard.tsx +++ b/webdev-prosjekt1/src/components/AlbumCard.tsx @@ -1,19 +1,29 @@ -import './SongCard.css'; +import './TrackCard.css'; +import type { Album } from '../api/types'; +import { FALLBACK_IMAGE } from './fallbackImage'; + +type AlbumCardProps = { + album: Album; +} + +export const AlbumCard = ({ album }: AlbumCardProps) => { + const image = album.images[0]?.url ?? FALLBACK_IMAGE; + const artistNames = album.artists.map((artist) => artist.name).join(', '); + const year = album.release_date.slice(0, 4); -export const AlbumCard = () => { return (
  • - +
    -

    Bæ bæ lille lam

    - JBgamingHD +

    {album.name}

    + {artistNames}
    - 2024 + {year}
  • diff --git a/webdev-prosjekt1/src/components/ArtistCard.tsx b/webdev-prosjekt1/src/components/ArtistCard.tsx index 292b689..37750fb 100644 --- a/webdev-prosjekt1/src/components/ArtistCard.tsx +++ b/webdev-prosjekt1/src/components/ArtistCard.tsx @@ -1,16 +1,24 @@ -import './SongCard.css'; +import './TrackCard.css'; import './ArtistCard.css'; +import type { Artist } from '../api/types'; +import { FALLBACK_IMAGE } from './fallbackImage'; + +type ArtistCardProps = { + artist: Artist; +} + +export const ArtistCard = ({ artist }: ArtistCardProps) => { + const image = artist.images[0]?.url ?? FALLBACK_IMAGE; -export const ArtistCard = () => { return (
  • - +
    -

    JBgamingHD

    +

    {artist.name}

    Artist
    diff --git a/webdev-prosjekt1/src/components/SongCard.tsx b/webdev-prosjekt1/src/components/SongCard.tsx deleted file mode 100644 index d598d90..0000000 --- a/webdev-prosjekt1/src/components/SongCard.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import './SongCard.css'; - -export const SongCard = () => { - return ( -
  • -
    - -
    - -
    -
    -

    Bæ bæ lille lam

    - JBgamingHD -
    -
    - 4:31 -
    -
    -
  • - ) -} \ No newline at end of file diff --git a/webdev-prosjekt1/src/components/SongCard.css b/webdev-prosjekt1/src/components/TrackCard.css similarity index 97% rename from webdev-prosjekt1/src/components/SongCard.css rename to webdev-prosjekt1/src/components/TrackCard.css index bdfd1af..78f1c74 100644 --- a/webdev-prosjekt1/src/components/SongCard.css +++ b/webdev-prosjekt1/src/components/TrackCard.css @@ -2,7 +2,7 @@ display: flex; padding: 0.3rem; - max-width: 400px; + width: 100%; border-radius: 0.5rem; diff --git a/webdev-prosjekt1/src/components/TrackCard.tsx b/webdev-prosjekt1/src/components/TrackCard.tsx new file mode 100644 index 0000000..84deddf --- /dev/null +++ b/webdev-prosjekt1/src/components/TrackCard.tsx @@ -0,0 +1,37 @@ +import './TrackCard.css'; +import type { Track } from '../api/types'; +import { FALLBACK_IMAGE } from './fallbackImage'; + +type TrackCardProps = { + track: Track; +} + +const formatDuration = (durationMs: number) => { + const totalSeconds = Math.round(durationMs / 1000); + const minutes = Math.floor(totalSeconds / 60); + const seconds = totalSeconds % 60; + return `${minutes}:${seconds.toString().padStart(2, '0')}`; +} + +export const TrackCard = ({ track }: TrackCardProps) => { + const image = track.album.images[0]?.url ?? FALLBACK_IMAGE; + const artistNames = track.artists.map((artist) => artist.name).join(', '); + + return ( +
  • +
    + +
    + +
    +
    +

    {track.name}

    + {artistNames} +
    +
    + {formatDuration(track.duration_ms)} +
    +
    +
  • + ) +} \ No newline at end of file diff --git a/webdev-prosjekt1/src/components/fallbackImage.ts b/webdev-prosjekt1/src/components/fallbackImage.ts new file mode 100644 index 0000000..5b4f044 --- /dev/null +++ b/webdev-prosjekt1/src/components/fallbackImage.ts @@ -0,0 +1 @@ +export const FALLBACK_IMAGE = 'https://placehold.net/6.png'; diff --git a/webdev-prosjekt1/src/mockData.ts b/webdev-prosjekt1/src/mockData.ts new file mode 100644 index 0000000..a48d2d3 --- /dev/null +++ b/webdev-prosjekt1/src/mockData.ts @@ -0,0 +1,74 @@ +// Static placeholder data used to preview the UI without calling the Spotify API. +import type { Album, Artist, Track } from './api/types'; +import { FALLBACK_IMAGE } from './components/fallbackImage'; + +const mockArtistStub = { id: 1, name: 'JBgamingHD', type: 'artist', href: '', uri: '' }; + +const mockAlbum: Album = { + id: 'album-1', + name: 'Bæ bæ lille lam', + album_type: 'album', + artists: [mockArtistStub], + images: [{ url: FALLBACK_IMAGE, height: 300, width: 300 }], + release_date: '2024-01-01', + release_date_precision: 'day', + total_tracks: 10, + uri: '', +}; + +export const mockTracks: Track[] = [ + { + id: 'track-1', + name: 'Bæ bæ lille lam', + type: 'track', + href: '', + artists: [mockArtistStub], + album: mockAlbum, + duration_ms: 4 * 60000 + 31000, + explicit: false, + track_number: 1, + external_ids: { isrc: '' }, + is_playable: true, + uri: '', + }, + { + id: 'track-2', + name: 'Sirkelen er sluttet', + type: 'track', + href: '', + artists: [mockArtistStub], + album: mockAlbum, + duration_ms: 3 * 60000 + 12000, + explicit: false, + track_number: 2, + external_ids: { isrc: '' }, + is_playable: true, + uri: '', + }, + { + id: 'track-3', + name: 'Musikkviking', + type: 'track', + href: '', + artists: [mockArtistStub], + album: mockAlbum, + duration_ms: 2 * 60000 + 58000, + explicit: false, + track_number: 3, + external_ids: { isrc: '' }, + is_playable: true, + uri: '', + }, +]; + +export const mockAlbums: Album[] = [ + mockAlbum, + { ...mockAlbum, id: 'album-2', name: 'Vinterlys', release_date: '2022-06-10' }, + { ...mockAlbum, id: 'album-3', name: 'Nordlys', release_date: '2020-11-20' }, +]; + +export const mockArtists: Artist[] = [ + { id: 1, name: 'JBgamingHD', type: 'artist', href: '', uri: '', images: [{ url: FALLBACK_IMAGE, height: 300, width: 300 }] }, + { id: 2, name: 'Musikkvisdom', type: 'artist', href: '', uri: '', images: [{ url: FALLBACK_IMAGE, height: 300, width: 300 }] }, + { id: 3, name: 'Trollklang', type: 'artist', href: '', uri: '', images: [{ url: FALLBACK_IMAGE, height: 300, width: 300 }] }, +]; From 82d242451ed9790699df3cdf34686351293808b8 Mon Sep 17 00:00:00 2001 From: Martin Sunnset Date: Tue, 15 Sep 2026 10:20:29 +0200 Subject: [PATCH 7/8] Removed fallbackimage.ts and edited to use musicwizimage as a Fallback Image --- webdev-prosjekt1/src/components/AlbumCard.tsx | 4 ++-- webdev-prosjekt1/src/components/ArtistCard.tsx | 4 ++-- webdev-prosjekt1/src/components/TrackCard.tsx | 4 ++-- webdev-prosjekt1/src/components/fallbackImage.ts | 1 - 4 files changed, 6 insertions(+), 7 deletions(-) delete mode 100644 webdev-prosjekt1/src/components/fallbackImage.ts diff --git a/webdev-prosjekt1/src/components/AlbumCard.tsx b/webdev-prosjekt1/src/components/AlbumCard.tsx index aa547e5..84d442d 100644 --- a/webdev-prosjekt1/src/components/AlbumCard.tsx +++ b/webdev-prosjekt1/src/components/AlbumCard.tsx @@ -1,13 +1,13 @@ import './TrackCard.css'; import type { Album } from '../api/types'; -import { FALLBACK_IMAGE } from './fallbackImage'; +import musicwizimage from '../assets/musicwiz.png'; type AlbumCardProps = { album: Album; } export const AlbumCard = ({ album }: AlbumCardProps) => { - const image = album.images[0]?.url ?? FALLBACK_IMAGE; + const image = album.images[0]?.url ?? musicwizimage; const artistNames = album.artists.map((artist) => artist.name).join(', '); const year = album.release_date.slice(0, 4); diff --git a/webdev-prosjekt1/src/components/ArtistCard.tsx b/webdev-prosjekt1/src/components/ArtistCard.tsx index 37750fb..a2a5463 100644 --- a/webdev-prosjekt1/src/components/ArtistCard.tsx +++ b/webdev-prosjekt1/src/components/ArtistCard.tsx @@ -1,14 +1,14 @@ import './TrackCard.css'; import './ArtistCard.css'; import type { Artist } from '../api/types'; -import { FALLBACK_IMAGE } from './fallbackImage'; +import musicwizimage from '../assets/musicwiz.png'; type ArtistCardProps = { artist: Artist; } export const ArtistCard = ({ artist }: ArtistCardProps) => { - const image = artist.images[0]?.url ?? FALLBACK_IMAGE; + const image = artist.images[0]?.url ?? musicwizimage; return (
  • diff --git a/webdev-prosjekt1/src/components/TrackCard.tsx b/webdev-prosjekt1/src/components/TrackCard.tsx index 84deddf..3c3ea05 100644 --- a/webdev-prosjekt1/src/components/TrackCard.tsx +++ b/webdev-prosjekt1/src/components/TrackCard.tsx @@ -1,6 +1,6 @@ import './TrackCard.css'; import type { Track } from '../api/types'; -import { FALLBACK_IMAGE } from './fallbackImage'; +import musicwizimage from '../assets/musicwiz.png'; type TrackCardProps = { track: Track; @@ -14,7 +14,7 @@ const formatDuration = (durationMs: number) => { } export const TrackCard = ({ track }: TrackCardProps) => { - const image = track.album.images[0]?.url ?? FALLBACK_IMAGE; + const image = track.album.images[0]?.url ?? musicwizimage; const artistNames = track.artists.map((artist) => artist.name).join(', '); return ( diff --git a/webdev-prosjekt1/src/components/fallbackImage.ts b/webdev-prosjekt1/src/components/fallbackImage.ts deleted file mode 100644 index 5b4f044..0000000 --- a/webdev-prosjekt1/src/components/fallbackImage.ts +++ /dev/null @@ -1 +0,0 @@ -export const FALLBACK_IMAGE = 'https://placehold.net/6.png'; From 22d40ecbc9e0fe9a39f7b961f5a473314d6f3a3a Mon Sep 17 00:00:00 2001 From: Martin Sunnset Date: Tue, 15 Sep 2026 10:30:53 +0200 Subject: [PATCH 8/8] Removed mockData and made app take in searches from API --- webdev-prosjekt1/src/App.tsx | 7 ++- webdev-prosjekt1/src/mockData.ts | 74 -------------------------------- 2 files changed, 3 insertions(+), 78 deletions(-) delete mode 100644 webdev-prosjekt1/src/mockData.ts diff --git a/webdev-prosjekt1/src/App.tsx b/webdev-prosjekt1/src/App.tsx index 51697b4..e1c10f6 100644 --- a/webdev-prosjekt1/src/App.tsx +++ b/webdev-prosjekt1/src/App.tsx @@ -6,7 +6,6 @@ import { Searchbar } from './components/Searchbar'; import { TrackCard } from './components/TrackCard'; import { AlbumCard } from './components/AlbumCard'; import { ArtistCard } from './components/ArtistCard'; -import { mockTracks, mockAlbums, mockArtists } from './mockData'; import filterIcon from './assets/filter.png'; import musicWizImage from './assets/musicwiz.png'; import logoImage from './assets/music-wiz-logo.png'; @@ -64,7 +63,7 @@ function App() {

    Tracks

      - {mockTracks.map((track) => ( + {results?.tracks.map((track) => ( ))}
    @@ -73,7 +72,7 @@ function App() {

    Albums

      - {mockAlbums.map((album) => ( + {results?.albums.map((album) => ( ))}
    @@ -82,7 +81,7 @@ function App() {

    Artists

      - {mockArtists.map((artist) => ( + {results?.artists.map((artist) => ( ))}
    diff --git a/webdev-prosjekt1/src/mockData.ts b/webdev-prosjekt1/src/mockData.ts deleted file mode 100644 index a48d2d3..0000000 --- a/webdev-prosjekt1/src/mockData.ts +++ /dev/null @@ -1,74 +0,0 @@ -// Static placeholder data used to preview the UI without calling the Spotify API. -import type { Album, Artist, Track } from './api/types'; -import { FALLBACK_IMAGE } from './components/fallbackImage'; - -const mockArtistStub = { id: 1, name: 'JBgamingHD', type: 'artist', href: '', uri: '' }; - -const mockAlbum: Album = { - id: 'album-1', - name: 'Bæ bæ lille lam', - album_type: 'album', - artists: [mockArtistStub], - images: [{ url: FALLBACK_IMAGE, height: 300, width: 300 }], - release_date: '2024-01-01', - release_date_precision: 'day', - total_tracks: 10, - uri: '', -}; - -export const mockTracks: Track[] = [ - { - id: 'track-1', - name: 'Bæ bæ lille lam', - type: 'track', - href: '', - artists: [mockArtistStub], - album: mockAlbum, - duration_ms: 4 * 60000 + 31000, - explicit: false, - track_number: 1, - external_ids: { isrc: '' }, - is_playable: true, - uri: '', - }, - { - id: 'track-2', - name: 'Sirkelen er sluttet', - type: 'track', - href: '', - artists: [mockArtistStub], - album: mockAlbum, - duration_ms: 3 * 60000 + 12000, - explicit: false, - track_number: 2, - external_ids: { isrc: '' }, - is_playable: true, - uri: '', - }, - { - id: 'track-3', - name: 'Musikkviking', - type: 'track', - href: '', - artists: [mockArtistStub], - album: mockAlbum, - duration_ms: 2 * 60000 + 58000, - explicit: false, - track_number: 3, - external_ids: { isrc: '' }, - is_playable: true, - uri: '', - }, -]; - -export const mockAlbums: Album[] = [ - mockAlbum, - { ...mockAlbum, id: 'album-2', name: 'Vinterlys', release_date: '2022-06-10' }, - { ...mockAlbum, id: 'album-3', name: 'Nordlys', release_date: '2020-11-20' }, -]; - -export const mockArtists: Artist[] = [ - { id: 1, name: 'JBgamingHD', type: 'artist', href: '', uri: '', images: [{ url: FALLBACK_IMAGE, height: 300, width: 300 }] }, - { id: 2, name: 'Musikkvisdom', type: 'artist', href: '', uri: '', images: [{ url: FALLBACK_IMAGE, height: 300, width: 300 }] }, - { id: 3, name: 'Trollklang', type: 'artist', href: '', uri: '', images: [{ url: FALLBACK_IMAGE, height: 300, width: 300 }] }, -];