From 213eaf7c4e10a2298d7423319bf8d539059cb944 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Wed, 9 Oct 2024 21:21:05 +0200 Subject: [PATCH 01/22] - added Album component and css --- src/App.jsx | 6 +++++- src/components/Album.jsx | 9 +++++++++ src/index.css | 16 ++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/components/Album.jsx diff --git a/src/App.jsx b/src/App.jsx index a13f8faf..082a63bf 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,7 +1,11 @@ import data from "./data.json"; +import { Album } from "./components/Album" console.log(data); export const App = () => { - return
Find me in src/app.jsx!
; + return ( + <> + + ) }; diff --git a/src/components/Album.jsx b/src/components/Album.jsx new file mode 100644 index 00000000..79adc91c --- /dev/null +++ b/src/components/Album.jsx @@ -0,0 +1,9 @@ + +// Album +export const Album = () => { + return ( +
+
card
+
+ ) +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index 4558f538..01275071 100644 --- a/src/index.css +++ b/src/index.css @@ -5,9 +5,25 @@ sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + background-color: black; } code { font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace; } + +.album-container { + background-color: orange; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 3fr)); + gap: 10px; + border: solid, red; +} + +.album-card { + display: flex; + background-color: black; + max-width: 300px; + height: 300px; +} \ No newline at end of file From b769cfa653510e3ea7c18294c95de33d9b0bafa7 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Thu, 10 Oct 2024 09:47:20 +0200 Subject: [PATCH 02/22] - added artist component --- src/components/Album.jsx | 17 ++++++++++++++++- src/components/AlbumName.jsx | 9 +++++++++ src/components/ArtistName.jsx | 12 ++++++++++++ src/index.css | 5 +++++ 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/components/AlbumName.jsx create mode 100644 src/components/ArtistName.jsx diff --git a/src/components/Album.jsx b/src/components/Album.jsx index 79adc91c..07e1362f 100644 --- a/src/components/Album.jsx +++ b/src/components/Album.jsx @@ -1,9 +1,24 @@ +import { albums } from "../data.json" +import { AlbumName } from "./AlbumName" +import { ArtistName } from "./ArtistName"; // Album export const Album = () => { return (
-
card
+ {/* iterating over the album and rendering one card for each album */} + {albums.items.map((album, index) => ( +
+ + + Listen +
+ ))}
) +} + +// Define proptypes +Album.propTypes = { + AlbumName: PropTypes.string.isRequired, } \ No newline at end of file diff --git a/src/components/AlbumName.jsx b/src/components/AlbumName.jsx new file mode 100644 index 00000000..e781f5ac --- /dev/null +++ b/src/components/AlbumName.jsx @@ -0,0 +1,9 @@ + +// Album Name +export const AlbumName = ({ name }) => { + return ( +
+

{name}

+
+ ) +} \ No newline at end of file diff --git a/src/components/ArtistName.jsx b/src/components/ArtistName.jsx new file mode 100644 index 00000000..a7d65e02 --- /dev/null +++ b/src/components/ArtistName.jsx @@ -0,0 +1,12 @@ +// Artist Name +export const ArtistName = ({ artists }) => { + return ( +
+ {artists.map((artist, index) => ( +

+ {artist.name} +

+ ))} +
+ ) +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index 01275071..0ca8484e 100644 --- a/src/index.css +++ b/src/index.css @@ -26,4 +26,9 @@ code { background-color: black; max-width: 300px; height: 300px; + color: white; +} + +album-name { + color: aliceblue; } \ No newline at end of file From aa7bf93003a33b5e66d3aefc98c0a74dca6e56cb Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Thu, 10 Oct 2024 10:37:06 +0200 Subject: [PATCH 03/22] - added component cover image --- package.json | 1 + src/components/Album.jsx | 11 ++++------- src/components/AlbumName.jsx | 8 +++++++- src/components/ArtistName.jsx | 17 +++++++++++++++-- src/components/CoverImage.jsx | 15 +++++++++++++++ src/index.css | 9 +++++++-- 6 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 src/components/CoverImage.jsx diff --git a/package.json b/package.json index a3bd4ec3..da354b48 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/src/components/Album.jsx b/src/components/Album.jsx index 07e1362f..c4e6d31f 100644 --- a/src/components/Album.jsx +++ b/src/components/Album.jsx @@ -1,14 +1,16 @@ import { albums } from "../data.json" import { AlbumName } from "./AlbumName" -import { ArtistName } from "./ArtistName"; +import { ArtistName } from "./ArtistName" +import { CoverImage } from "./CoverImage" // Album export const Album = () => { return (
{/* iterating over the album and rendering one card for each album */} - {albums.items.map((album, index) => ( + {albums.items.map((album) => (
+ 0 ? album.images[0].url : 'fallback-image-url.jpg'} /> Listen @@ -16,9 +18,4 @@ export const Album = () => { ))}
) -} - -// Define proptypes -Album.propTypes = { - AlbumName: PropTypes.string.isRequired, } \ No newline at end of file diff --git a/src/components/AlbumName.jsx b/src/components/AlbumName.jsx index e781f5ac..77586c53 100644 --- a/src/components/AlbumName.jsx +++ b/src/components/AlbumName.jsx @@ -1,3 +1,4 @@ +import PropTypes from 'prop-types' // Album Name export const AlbumName = ({ name }) => { @@ -6,4 +7,9 @@ export const AlbumName = ({ name }) => {

{name}

) -} \ No newline at end of file +} + +// Define PropTypes for AlbumName +AlbumName.propTypes = { + name: PropTypes.string.isRequired, +}; diff --git a/src/components/ArtistName.jsx b/src/components/ArtistName.jsx index a7d65e02..87dd1c79 100644 --- a/src/components/ArtistName.jsx +++ b/src/components/ArtistName.jsx @@ -1,12 +1,25 @@ +import PropTypes from 'prop-types' + // Artist Name export const ArtistName = ({ artists }) => { return (
- {artists.map((artist, index) => ( + {artists.map((artist) => (

{artist.name}

))}
) -} \ No newline at end of file +} + +// Define PropTypes for ArtistName +ArtistName.propTypes = { + artists: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + // You can add more validations for other properties if necessary + }) + ).isRequired, // Indicate that the artists prop is required +}; \ No newline at end of file diff --git a/src/components/CoverImage.jsx b/src/components/CoverImage.jsx new file mode 100644 index 00000000..3e3a7413 --- /dev/null +++ b/src/components/CoverImage.jsx @@ -0,0 +1,15 @@ +import PropTypes from "prop-types" + +export const CoverImage = ({ coverImg }) => { + return ( +
+
+ +
+
+ ) +} + +CoverImage.propTypes = { + coverImg: PropTypes.string.isRequired +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index 0ca8484e..c51215f5 100644 --- a/src/index.css +++ b/src/index.css @@ -23,12 +23,17 @@ code { .album-card { display: flex; + flex-direction: column; background-color: black; max-width: 300px; height: 300px; color: white; } -album-name { - color: aliceblue; +.cover-image-container { + width: 100%; +} + +.cover-image { + width: 100%; } \ No newline at end of file From f762f06bd7145733253d6e3102b8146f4472932c Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Thu, 10 Oct 2024 12:55:03 +0200 Subject: [PATCH 04/22] - added the icons --- src/components/Album.jsx | 10 ++++-- src/components/CoverImage.jsx | 26 ++++++++++++++- src/index.css | 59 ++++++++++++++++++++++++++++++++++- 3 files changed, 90 insertions(+), 5 deletions(-) diff --git a/src/components/Album.jsx b/src/components/Album.jsx index c4e6d31f..71f76fba 100644 --- a/src/components/Album.jsx +++ b/src/components/Album.jsx @@ -11,9 +11,13 @@ export const Album = () => { {albums.items.map((album) => (
0 ? album.images[0].url : 'fallback-image-url.jpg'} /> - - - Listen + +
+ + + {/* Listen */} +
+
))} diff --git a/src/components/CoverImage.jsx b/src/components/CoverImage.jsx index 3e3a7413..249f10d7 100644 --- a/src/components/CoverImage.jsx +++ b/src/components/CoverImage.jsx @@ -1,10 +1,34 @@ import PropTypes from "prop-types" +import heartIcon from "../assets/icons/heart.svg" +import playIcon from "../assets/icons/play.svg" +import dotsIcon from "../assets/icons/dots.svg" export const CoverImage = ({ coverImg }) => { return (
- + Album Cover + + + + + + + + + {/* +
) diff --git a/src/index.css b/src/index.css index c51215f5..fc04319e 100644 --- a/src/index.css +++ b/src/index.css @@ -26,14 +26,71 @@ code { flex-direction: column; background-color: black; max-width: 300px; - height: 300px; color: white; + padding: 5px; } .cover-image-container { width: 100%; + display: flex; + justify-content: center; } .cover-image { + width: 280px; + height: 280px; + overflow: hidden; + border: solid, red; +} + +.cover-image-img { width: 100%; + height: auto; + object-fit: cover; +} + +.icon-container { + display: flex; + justify-content: center; + z-index: 1; + position: absolute; + width: 300px; + top: 10px; + /* opacity: 0; */ + top: 20%; + gap: 10px; + border: solid, orange; +} + +.heart-icon, +.play-icon, +.dots-icon { + width: 30px; + filter: invert(100%) +} + +.heart-button, +.play-button, +.dots-button { + border: none; + background-color: transparent; + cursor: pointer; + position: relative +} + +.album-info { + display: flex; + flex-direction: column; + justify-content: flex-start; +} + +h2 { + padding: 5px; + margin: 5px; + border: solid, red; +} + +p { + padding: 5px; + margin: 5px; } \ No newline at end of file From 3a647b7d1f117c4e211450fecbf24b3c3458182c Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Thu, 10 Oct 2024 13:08:25 +0200 Subject: [PATCH 05/22] - css --- src/index.css | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/index.css b/src/index.css index fc04319e..32bb680f 100644 --- a/src/index.css +++ b/src/index.css @@ -14,11 +14,10 @@ code { } .album-container { - background-color: orange; + background-color: black; display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 3fr)); gap: 10px; - border: solid, red; } .album-card { @@ -40,7 +39,6 @@ code { width: 280px; height: 280px; overflow: hidden; - border: solid, red; } .cover-image-img { @@ -55,11 +53,8 @@ code { z-index: 1; position: absolute; width: 300px; - top: 10px; /* opacity: 0; */ - top: 20%; gap: 10px; - border: solid, orange; } .heart-icon, @@ -87,7 +82,7 @@ code { h2 { padding: 5px; margin: 5px; - border: solid, red; + font-size: 18px; } p { From 6d66c76fc94b3242fecebed185dd34a03048bd3e Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Thu, 10 Oct 2024 13:18:51 +0200 Subject: [PATCH 06/22] - css --- src/index.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/index.css b/src/index.css index 32bb680f..aa70ebb5 100644 --- a/src/index.css +++ b/src/index.css @@ -33,6 +33,7 @@ code { width: 100%; display: flex; justify-content: center; + position: relative; } .cover-image { @@ -52,6 +53,7 @@ code { justify-content: center; z-index: 1; position: absolute; + top: 120px; width: 300px; /* opacity: 0; */ gap: 10px; @@ -60,7 +62,7 @@ code { .heart-icon, .play-icon, .dots-icon { - width: 30px; + width: 40px; filter: invert(100%) } From 8e5662df9f671d886e34d31205c514ae730c0980 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Thu, 10 Oct 2024 14:04:44 +0200 Subject: [PATCH 07/22] - defractured: dotsbutton, heartbutton and playbutton --- src/App.jsx | 8 ++++---- src/components/Album.jsx | 15 ++++++++++++--- src/components/CoverImage.jsx | 23 ----------------------- src/components/DotsButton.jsx | 11 +++++++++++ src/components/HeartButton.jsx | 11 +++++++++++ src/components/PlayButton.jsx | 11 +++++++++++ src/index.css | 1 + 7 files changed, 50 insertions(+), 30 deletions(-) create mode 100644 src/components/DotsButton.jsx create mode 100644 src/components/HeartButton.jsx create mode 100644 src/components/PlayButton.jsx diff --git a/src/App.jsx b/src/App.jsx index 082a63bf..55c2f7d0 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -4,8 +4,8 @@ import { Album } from "./components/Album" console.log(data); export const App = () => { - return ( - <> - - ) + return ( + <> + + ) }; diff --git a/src/components/Album.jsx b/src/components/Album.jsx index 71f76fba..91f48e75 100644 --- a/src/components/Album.jsx +++ b/src/components/Album.jsx @@ -2,6 +2,9 @@ import { albums } from "../data.json" import { AlbumName } from "./AlbumName" import { ArtistName } from "./ArtistName" import { CoverImage } from "./CoverImage" +import { DotsButton } from "./DotsButton" +import { HeartButton } from "./HeartButton" +import { PlayButton } from "./PlayButton" // Album export const Album = () => { @@ -11,6 +14,11 @@ export const Album = () => { {albums.items.map((album) => (
0 ? album.images[0].url : 'fallback-image-url.jpg'} /> +
+ + + +
@@ -19,7 +27,8 @@ export const Album = () => {
- ))} - + )) + } + ) -} \ No newline at end of file +} diff --git a/src/components/CoverImage.jsx b/src/components/CoverImage.jsx index 249f10d7..98b0fcb3 100644 --- a/src/components/CoverImage.jsx +++ b/src/components/CoverImage.jsx @@ -1,34 +1,11 @@ import PropTypes from "prop-types" -import heartIcon from "../assets/icons/heart.svg" -import playIcon from "../assets/icons/play.svg" -import dotsIcon from "../assets/icons/dots.svg" export const CoverImage = ({ coverImg }) => { return (
Album Cover - - - - - - - - {/* -
) diff --git a/src/components/DotsButton.jsx b/src/components/DotsButton.jsx new file mode 100644 index 00000000..03d6c615 --- /dev/null +++ b/src/components/DotsButton.jsx @@ -0,0 +1,11 @@ +import dotsIcon from "../assets/icons/dots.svg" + +export const DotsButton = () => { + return ( + + + + ) +} \ No newline at end of file diff --git a/src/components/HeartButton.jsx b/src/components/HeartButton.jsx new file mode 100644 index 00000000..330053f4 --- /dev/null +++ b/src/components/HeartButton.jsx @@ -0,0 +1,11 @@ +import heartIcon from "../assets/icons/heart.svg" + +export const HeartButton = () => { + return ( + + + + ) +} diff --git a/src/components/PlayButton.jsx b/src/components/PlayButton.jsx new file mode 100644 index 00000000..4653b367 --- /dev/null +++ b/src/components/PlayButton.jsx @@ -0,0 +1,11 @@ +import playIcon from "../assets/icons/play.svg" + +export const PlayButton = () => { + return ( + + + + ) +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index aa70ebb5..2de8c4c8 100644 --- a/src/index.css +++ b/src/index.css @@ -57,6 +57,7 @@ code { width: 300px; /* opacity: 0; */ gap: 10px; + border: solid, green; } .heart-icon, From f87a1d4a0d377c1cd1e38d0c320f6561ca32fe79 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Thu, 10 Oct 2024 14:08:53 +0200 Subject: [PATCH 08/22] - CSS --- src/index.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.css b/src/index.css index 2de8c4c8..e412513a 100644 --- a/src/index.css +++ b/src/index.css @@ -27,6 +27,7 @@ code { max-width: 300px; color: white; padding: 5px; + position: relative; } .cover-image-container { From 14947916334906c69864d07649514c60727e07a4 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Thu, 10 Oct 2024 14:34:29 +0200 Subject: [PATCH 09/22] - hover effect --- src/index.css | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/index.css b/src/index.css index e412513a..730d368b 100644 --- a/src/index.css +++ b/src/index.css @@ -37,6 +37,10 @@ code { position: relative; } +:hover.cover-image-container { + filter: brightness(40%); +} + .cover-image { width: 280px; height: 280px; @@ -52,22 +56,32 @@ code { .icon-container { display: flex; justify-content: center; + align-items: center; z-index: 1; position: absolute; top: 120px; width: 300px; /* opacity: 0; */ - gap: 10px; - border: solid, green; + gap: 20px; + height: 100px; + width: 100%; } .heart-icon, .play-icon, .dots-icon { - width: 40px; + width: 30px; filter: invert(100%) } +.play-icon { + width: 40px; +} + +:hover.play-icon { + width: 60px; +} + .heart-button, .play-button, .dots-button { From 3fde8bf1d3ae784d77d018664ca92b766e642ad5 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Fri, 11 Oct 2024 11:19:51 +0200 Subject: [PATCH 10/22] - hover effect of images and buttons --- src/components/HeartButton.jsx | 2 +- src/components/PlayButton.jsx | 2 +- src/index.css | 36 ++++++++++++++++++++++------------ 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/components/HeartButton.jsx b/src/components/HeartButton.jsx index 330053f4..f3ea72c9 100644 --- a/src/components/HeartButton.jsx +++ b/src/components/HeartButton.jsx @@ -2,7 +2,7 @@ import heartIcon from "../assets/icons/heart.svg" export const HeartButton = () => { return ( - + diff --git a/src/components/PlayButton.jsx b/src/components/PlayButton.jsx index 4653b367..03ddfd3c 100644 --- a/src/components/PlayButton.jsx +++ b/src/components/PlayButton.jsx @@ -2,7 +2,7 @@ import playIcon from "../assets/icons/play.svg" export const PlayButton = () => { return ( - + diff --git a/src/index.css b/src/index.css index 730d368b..c279c42a 100644 --- a/src/index.css +++ b/src/index.css @@ -37,10 +37,6 @@ code { position: relative; } -:hover.cover-image-container { - filter: brightness(40%); -} - .cover-image { width: 280px; height: 280px; @@ -57,30 +53,34 @@ code { display: flex; justify-content: center; align-items: center; - z-index: 1; + z-index: 0; position: absolute; top: 120px; width: 300px; - /* opacity: 0; */ - gap: 20px; + opacity: 0; + gap: 10px; height: 100px; width: 100%; } +.play-button-container { + display: flex; + justify-content: center; + width: 80px; +} + .heart-icon, .play-icon, .dots-icon { width: 30px; - filter: invert(100%) + filter: invert(100%); + z-index: 5; } .play-icon { - width: 40px; + width: 50px; } -:hover.play-icon { - width: 60px; -} .heart-button, .play-button, @@ -91,6 +91,18 @@ code { position: relative } +.album-card:hover .cover-image-container { + filter: brightness(30%) +} + +.album-card:hover .icon-container { + opacity: 1; +} + +.play-icon:hover { + width: 70px; +} + .album-info { display: flex; flex-direction: column; From 25ac5ffbeb2995cdfce04b0a056824acb5b65606 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Fri, 11 Oct 2024 13:04:01 +0200 Subject: [PATCH 11/22] - linked album with external url --- src/components/Album.jsx | 25 ++++++++++++++----------- src/components/AlbumName.jsx | 12 +++++++++--- src/components/CoverImage.jsx | 19 +++++++++++++++---- src/index.css | 2 +- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/components/Album.jsx b/src/components/Album.jsx index 91f48e75..55f2a26f 100644 --- a/src/components/Album.jsx +++ b/src/components/Album.jsx @@ -2,9 +2,6 @@ import { albums } from "../data.json" import { AlbumName } from "./AlbumName" import { ArtistName } from "./ArtistName" import { CoverImage } from "./CoverImage" -import { DotsButton } from "./DotsButton" -import { HeartButton } from "./HeartButton" -import { PlayButton } from "./PlayButton" // Album export const Album = () => { @@ -13,17 +10,11 @@ export const Album = () => { {/* iterating over the album and rendering one card for each album */} {albums.items.map((album) => (
- 0 ? album.images[0].url : 'fallback-image-url.jpg'} /> -
- - - -
- + 0 ? album.images[0].url : 'fallback-image-url.jpg'} + albumUrl={album.external_urls.spotify} />
- {/* Listen */}
@@ -32,3 +23,15 @@ export const Album = () => { ) } + + + +{/*
+ */} +{/* 0 ? album.images[0].url : 'fallback-image-url.jpg'} /> +
+ + + +
*/} +{/*
*/ } \ No newline at end of file diff --git a/src/components/AlbumName.jsx b/src/components/AlbumName.jsx index 77586c53..1429bf1b 100644 --- a/src/components/AlbumName.jsx +++ b/src/components/AlbumName.jsx @@ -1,15 +1,21 @@ import PropTypes from 'prop-types' // Album Name -export const AlbumName = ({ name }) => { +export const AlbumName = ({ name, albumUrl }) => { return ( - + ) } // Define PropTypes for AlbumName AlbumName.propTypes = { name: PropTypes.string.isRequired, + albumUrl: PropTypes.string.isRequired }; + diff --git a/src/components/CoverImage.jsx b/src/components/CoverImage.jsx index 98b0fcb3..61afc2de 100644 --- a/src/components/CoverImage.jsx +++ b/src/components/CoverImage.jsx @@ -1,16 +1,27 @@ import PropTypes from "prop-types" +import { DotsButton } from "./DotsButton" +import { HeartButton } from "./HeartButton" +import { PlayButton } from "./PlayButton" -export const CoverImage = ({ coverImg }) => { +export const CoverImage = ({ coverImg, albumUrl }) => { return (
-
- Album Cover + +
+ Album Cover +
+
+
+ + +
) } CoverImage.propTypes = { - coverImg: PropTypes.string.isRequired + coverImg: PropTypes.string.isRequired, + albumUrl: PropTypes.string.isRequired, } \ No newline at end of file diff --git a/src/index.css b/src/index.css index c279c42a..400c25b3 100644 --- a/src/index.css +++ b/src/index.css @@ -91,7 +91,7 @@ code { position: relative } -.album-card:hover .cover-image-container { +.cover-image-container:hover .cover-image { filter: brightness(30%) } From 16b2b474b61f5cc644f8d26e5b94a8d10118913e Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Fri, 11 Oct 2024 14:16:01 +0200 Subject: [PATCH 12/22] - added links artists --- src/components/Album.jsx | 19 +++---------------- src/components/AlbumName.jsx | 16 +++++++++------- src/components/ArtistName.jsx | 20 ++++++++++++-------- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/src/components/Album.jsx b/src/components/Album.jsx index 55f2a26f..042b2bde 100644 --- a/src/components/Album.jsx +++ b/src/components/Album.jsx @@ -13,25 +13,12 @@ export const Album = () => { 0 ? album.images[0].url : 'fallback-image-url.jpg'} albumUrl={album.external_urls.spotify} />
- - + +
-
)) } ) -} - - - -{/*
- */} -{/* 0 ? album.images[0].url : 'fallback-image-url.jpg'} /> -
- - - -
*/} -{/*
*/ } \ No newline at end of file +} \ No newline at end of file diff --git a/src/components/AlbumName.jsx b/src/components/AlbumName.jsx index 1429bf1b..6a16eb63 100644 --- a/src/components/AlbumName.jsx +++ b/src/components/AlbumName.jsx @@ -3,16 +3,18 @@ import PropTypes from 'prop-types' // Album Name export const AlbumName = ({ name, albumUrl }) => { return ( - -

{name}

-
+ ) } + // Define PropTypes for AlbumName AlbumName.propTypes = { name: PropTypes.string.isRequired, diff --git a/src/components/ArtistName.jsx b/src/components/ArtistName.jsx index 87dd1c79..3e2213cd 100644 --- a/src/components/ArtistName.jsx +++ b/src/components/ArtistName.jsx @@ -1,25 +1,29 @@ import PropTypes from 'prop-types' +import { albums } from "../data.json" + // Artist Name export const ArtistName = ({ artists }) => { return (
- {artists.map((artist) => ( -

- {artist.name} -

- ))} + {artists.map((artist, index) => + + +

{(index ? ", " : "") + artist.name}

+
+
+ )}
) } -// Define PropTypes for ArtistName + ArtistName.propTypes = { artists: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.string.isRequired, name: PropTypes.string.isRequired, - // You can add more validations for other properties if necessary }) - ).isRequired, // Indicate that the artists prop is required + ).isRequired, + artistsUrl: PropTypes.string.isRequired }; \ No newline at end of file From 92820d5263a7895c6d99c619a70b68799b73aa00 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Fri, 11 Oct 2024 15:25:33 +0200 Subject: [PATCH 13/22] - worked on CSS --- src/components/AlbumName.jsx | 3 ++- src/components/ArtistName.jsx | 29 ++++++++++++++------- src/index.css | 49 ++++++++++++++++++++++++++--------- 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/components/AlbumName.jsx b/src/components/AlbumName.jsx index 6a16eb63..64b64a2d 100644 --- a/src/components/AlbumName.jsx +++ b/src/components/AlbumName.jsx @@ -7,7 +7,8 @@ export const AlbumName = ({ name, albumUrl }) => { + rel="noopener noreferrer" + className='album-name-a'>

{name}

diff --git a/src/components/ArtistName.jsx b/src/components/ArtistName.jsx index 3e2213cd..3490b7dd 100644 --- a/src/components/ArtistName.jsx +++ b/src/components/ArtistName.jsx @@ -1,18 +1,29 @@ import PropTypes from 'prop-types' -import { albums } from "../data.json" // Artist Name export const ArtistName = ({ artists }) => { return ( -
- {artists.map((artist, index) => - - -

{(index ? ", " : "") + artist.name}

-
-
- )} +
+ {artists.map((artist, index) => { + let separator = ", "; + if (artists.length === 2 && index === 0) { + separator = " & "; + } else if (index === artists.length - 2) { + separator = " & "; + } else if (index === artists.length - 1) { + separator = ""; + } + + + return ( + + +

{artist.name + separator}

+
+
+ ) + })}
) } diff --git a/src/index.css b/src/index.css index 400c25b3..35ff24a7 100644 --- a/src/index.css +++ b/src/index.css @@ -91,16 +91,13 @@ code { position: relative } -.cover-image-container:hover .cover-image { +.album-card:hover .cover-image { filter: brightness(30%) } .album-card:hover .icon-container { opacity: 1; -} - -.play-icon:hover { - width: 70px; + filter: brightness(70%); } .album-info { @@ -109,13 +106,41 @@ code { justify-content: flex-start; } -h2 { - padding: 5px; - margin: 5px; - font-size: 18px; +.play-button:hover .play-icon { + width: 70px; + filter: invert(100%); + transition: all 0.3s ease; } -p { - padding: 5px; - margin: 5px; +.artists-container { + display: flex; +} + + +.artist-name, +.album-name { + padding-left: 5px; + margin: 2px; + color: white; + text-decoration: none; +} + +.artist-name { + filter: brightness(70%); + text-decoration: none; +} + +.artist-name:hover, +.album-name:hover { + text-decoration: underline; +} + +.artist-name-a, +.album-name-a { + text-decoration: none; +} + +.artist-name-a:hover, +.album-name-a:hover { + text-decoration: underline; } \ No newline at end of file From b52558144aea4694f44dc874259a070be0f6835b Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Fri, 11 Oct 2024 19:34:18 +0200 Subject: [PATCH 14/22] - added url to play button with onClick; deleted link of coverimage --- src/components/CoverImage.jsx | 20 ++++++++++---------- src/components/PlayButton.jsx | 12 ++++++++++-- src/index.css | 6 +++--- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/components/CoverImage.jsx b/src/components/CoverImage.jsx index 61afc2de..eb6a4ab2 100644 --- a/src/components/CoverImage.jsx +++ b/src/components/CoverImage.jsx @@ -3,20 +3,19 @@ import { DotsButton } from "./DotsButton" import { HeartButton } from "./HeartButton" import { PlayButton } from "./PlayButton" + export const CoverImage = ({ coverImg, albumUrl }) => { return (
- -
- Album Cover - +
+ Album Cover +
+ + +
-
-
- - -
+
) } @@ -24,4 +23,5 @@ export const CoverImage = ({ coverImg, albumUrl }) => { CoverImage.propTypes = { coverImg: PropTypes.string.isRequired, albumUrl: PropTypes.string.isRequired, -} \ No newline at end of file +} + diff --git a/src/components/PlayButton.jsx b/src/components/PlayButton.jsx index 03ddfd3c..00b815b1 100644 --- a/src/components/PlayButton.jsx +++ b/src/components/PlayButton.jsx @@ -1,11 +1,19 @@ import playIcon from "../assets/icons/play.svg" +import PropTypes from "prop-types" -export const PlayButton = () => { +export const PlayButton = ({ albumUrl }) => { + const handlePlayClick = () => { + window.open(albumUrl, "_blank", "noopener,noreferrer") + } return ( - ) +} + +PlayButton.propTypes = { + albumUrl: PropTypes.string.isRequired, } \ No newline at end of file diff --git a/src/index.css b/src/index.css index 35ff24a7..e7badf9b 100644 --- a/src/index.css +++ b/src/index.css @@ -24,7 +24,7 @@ code { display: flex; flex-direction: column; background-color: black; - max-width: 300px; + min-width: 300px; color: white; padding: 5px; position: relative; @@ -38,8 +38,8 @@ code { } .cover-image { - width: 280px; - height: 280px; + width: 100%; + overflow: hidden; } From 9bce540779fae265b23302e666b48959c7ae0fb1 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Fri, 11 Oct 2024 19:51:54 +0200 Subject: [PATCH 15/22] - css --- src/index.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/index.css b/src/index.css index e7badf9b..1449742b 100644 --- a/src/index.css +++ b/src/index.css @@ -91,13 +91,15 @@ code { position: relative } +/* hover effects */ + .album-card:hover .cover-image { filter: brightness(30%) } .album-card:hover .icon-container { opacity: 1; - filter: brightness(70%); + filter: brightness(100%); } .album-info { From 2f5c8969a9d12f1cf0527a25a5ab0fff29e46de4 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Sat, 12 Oct 2024 22:42:27 +0200 Subject: [PATCH 16/22] - css --- src/components/Album.jsx | 30 +++++++++++++---------- src/components/Header.jsx | 11 +++++++++ src/index.css | 50 +++++++++++++++++++++++---------------- 3 files changed, 58 insertions(+), 33 deletions(-) create mode 100644 src/components/Header.jsx diff --git a/src/components/Album.jsx b/src/components/Album.jsx index 042b2bde..d2ddc5d9 100644 --- a/src/components/Album.jsx +++ b/src/components/Album.jsx @@ -2,23 +2,27 @@ import { albums } from "../data.json" import { AlbumName } from "./AlbumName" import { ArtistName } from "./ArtistName" import { CoverImage } from "./CoverImage" +import { Header } from "./Header" // Album export const Album = () => { return ( -
- {/* iterating over the album and rendering one card for each album */} - {albums.items.map((album) => ( -
- 0 ? album.images[0].url : 'fallback-image-url.jpg'} - albumUrl={album.external_urls.spotify} /> -
- - + <> +
+
+ {/* iterating over the album and rendering one card for each album */} + {albums.items.map((album) => ( +
+ 0 ? album.images[0].url : 'fallback-image-url.jpg'} + albumUrl={album.external_urls.spotify} /> +
+ + +
-
- )) - } -
+ )) + } +
+ ) } \ No newline at end of file diff --git a/src/components/Header.jsx b/src/components/Header.jsx new file mode 100644 index 00000000..75de4106 --- /dev/null +++ b/src/components/Header.jsx @@ -0,0 +1,11 @@ + + +export const Header = () => { + return ( +
+

+ New Vibes +

+
+ ) +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index 1449742b..287f6343 100644 --- a/src/index.css +++ b/src/index.css @@ -13,6 +13,17 @@ code { monospace; } +header { + height: 10%; + display: flex; + justify-content: center; +} + +h1 { + color: greenyellow; + +} + .album-container { background-color: black; display: grid; @@ -39,8 +50,8 @@ code { .cover-image { width: 100%; - overflow: hidden; + padding: 15px; } .cover-image-img { @@ -74,7 +85,7 @@ code { .dots-icon { width: 30px; filter: invert(100%); - z-index: 5; + /* z-index: 5; */ } .play-icon { @@ -91,40 +102,23 @@ code { position: relative } -/* hover effects */ - -.album-card:hover .cover-image { - filter: brightness(30%) -} - -.album-card:hover .icon-container { - opacity: 1; - filter: brightness(100%); -} - .album-info { display: flex; flex-direction: column; justify-content: flex-start; } -.play-button:hover .play-icon { - width: 70px; - filter: invert(100%); - transition: all 0.3s ease; -} - .artists-container { display: flex; } - .artist-name, .album-name { padding-left: 5px; margin: 2px; color: white; text-decoration: none; + font-size: medium; } .artist-name { @@ -145,4 +139,20 @@ code { .artist-name-a:hover, .album-name-a:hover { text-decoration: underline; +} + +/* hover effects */ + +.album-card:hover .cover-image-container .cover-image-img { + filter: brightness(30%); +} + +.album-card:hover .icon-container { + opacity: 1; +} + +.play-button:hover .play-icon { + width: 70px; + filter: invert(100%); + transition: all 0.3s ease; } \ No newline at end of file From 4b5076475602f78d6aefea89b90adf2540d39e5d Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Sun, 13 Oct 2024 11:34:55 +0200 Subject: [PATCH 17/22] - added sidebar --- src/App.jsx | 2 + src/components/Album.jsx | 34 +++++++++------- src/components/Sidebar.jsx | 18 +++++++++ src/components/SidebarAlbum.jsx | 16 ++++++++ src/index.css | 72 ++++++++++++++++++++++++++++++--- 5 files changed, 122 insertions(+), 20 deletions(-) create mode 100644 src/components/Sidebar.jsx create mode 100644 src/components/SidebarAlbum.jsx diff --git a/src/App.jsx b/src/App.jsx index 55c2f7d0..9e218327 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,7 +1,9 @@ import data from "./data.json"; +import stretchgoals from "./stretch-goal.json" import { Album } from "./components/Album" console.log(data); +console.log(stretchgoals) export const App = () => { return ( diff --git a/src/components/Album.jsx b/src/components/Album.jsx index d2ddc5d9..47e82779 100644 --- a/src/components/Album.jsx +++ b/src/components/Album.jsx @@ -3,26 +3,30 @@ import { AlbumName } from "./AlbumName" import { ArtistName } from "./ArtistName" import { CoverImage } from "./CoverImage" import { Header } from "./Header" +import { Sidebar } from "./Sidebar" // Album export const Album = () => { return ( <>
-
- {/* iterating over the album and rendering one card for each album */} - {albums.items.map((album) => ( -
- 0 ? album.images[0].url : 'fallback-image-url.jpg'} - albumUrl={album.external_urls.spotify} /> -
- - +
+
+ {albums.items.map((album) => ( +
+ 0 ? album.images[0].url : 'fallback-image-url.jpg'} + albumUrl={album.external_urls.spotify} + /> +
+ + +
-
- )) - } -
+ ))} +
+ +
- ) -} \ No newline at end of file + ); +}; \ No newline at end of file diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx new file mode 100644 index 00000000..7c4ab3ed --- /dev/null +++ b/src/components/Sidebar.jsx @@ -0,0 +1,18 @@ +import { playlists } from "../stretch-goal.json" +import { SidebarAlbum } from "./SidebarAlbum"; + +export const Sidebar = () => { + return ( +
+

Editor's Picks

+
+ {playlists.items.map((item) => ( + 0 ? item.images[0].url : 'fallback-image-url.jpg'} + /> + ))} +
+
+ ); +}; diff --git a/src/components/SidebarAlbum.jsx b/src/components/SidebarAlbum.jsx new file mode 100644 index 00000000..c8cec4d1 --- /dev/null +++ b/src/components/SidebarAlbum.jsx @@ -0,0 +1,16 @@ +import PropTypes from "prop-types" +export const SidebarAlbum = ({ sidebarImg }) => { + return ( + <> +
+
+ Single Cover +
+
+ + ) +} + +SidebarAlbum.propTypes = { + sidebarImg: PropTypes.string.isRequired, +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index 287f6343..2d03ef16 100644 --- a/src/index.css +++ b/src/index.css @@ -24,18 +24,28 @@ h1 { } +.main-container { + display: grid; + grid-template-columns: repeat(1, 1fr); +} + .album-container { background-color: black; display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 3fr)); + grid-template-columns: repeat(auto-fit, minmax(250px, 3fr)); gap: 10px; } +.sidebar { + display: none; +} + + .album-card { display: flex; flex-direction: column; background-color: black; - min-width: 300px; + min-width: 250px; color: white; padding: 5px; position: relative; @@ -116,13 +126,18 @@ h1 { .album-name { padding-left: 5px; margin: 2px; - color: white; text-decoration: none; - font-size: medium; + font-family: Helvetica; +} + +.album-name { + font-size: 14px; + color: #ffffff; } .artist-name { - filter: brightness(70%); + font-size: 12px; + color: #a0a0a0; text-decoration: none; } @@ -155,4 +170,51 @@ h1 { width: 70px; filter: invert(100%); transition: all 0.3s ease; +} + + + +@media (min-width: 1024px) { + .main-container { + display: grid; + grid-template-columns: 1fr 300px; + } + + .album-container { + grid-template-columns: repeat(auto-fit, minmax(240px, 3fr)); + } + + /* sidebar */ + .sidebar { + background-color: black; + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + height: 100vh; + overflow-y: auto; + position: sticky; + top: 0; + } + + .sidebar-header, + .sidebar-sub-header { + color: greenyellow; + } + + .sidebar-album-container { + display: flex; + width: 200px; + justify-content: center; + } + + .cover-image-sidebar { + width: 100%; + padding: 20px; + } + + .cover-image-sidebar-img { + width: 100%; + } + } \ No newline at end of file From 0cac192572deac74a028e0804ff4060080dea2c5 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Sun, 13 Oct 2024 11:42:09 +0200 Subject: [PATCH 18/22] - added live view link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 38807b33..bb881711 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Describe how you approached to problem, and what tools and techniques you used t ### View it live -Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. +https://gittes-music-release.netlify.app ## Instructions From 5a3cd2e7ef161468d45ff4c64bc6de4810cc6a0c Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Sun, 10 Nov 2024 18:41:32 +0100 Subject: [PATCH 19/22] - cleaned the code --- src/App.jsx | 13 +++---- src/components/Album.jsx | 44 ++++++++++++------------ src/components/AlbumName.jsx | 27 +++++++-------- src/components/ArtistName.jsx | 61 ++++++++++++++++----------------- src/components/CoverImage.jsx | 29 ++++++++-------- src/components/DotsButton.jsx | 14 ++++---- src/components/Header.jsx | 16 ++++----- src/components/HeartButton.jsx | 16 ++++----- src/components/PlayButton.jsx | 22 ++++++------ src/components/Sidebar.jsx | 30 ++++++++-------- src/components/SidebarAlbum.jsx | 21 ++++++------ 11 files changed, 144 insertions(+), 149 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 9e218327..07650a7b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,4 +1,4 @@ -import data from "./data.json"; +import data from "./data.json" import stretchgoals from "./stretch-goal.json" import { Album } from "./components/Album" @@ -6,8 +6,9 @@ console.log(data); console.log(stretchgoals) export const App = () => { - return ( - <> - - ) -}; + return ( + <> + + + ) +} diff --git a/src/components/Album.jsx b/src/components/Album.jsx index 47e82779..2cecc5ac 100644 --- a/src/components/Album.jsx +++ b/src/components/Album.jsx @@ -7,26 +7,26 @@ import { Sidebar } from "./Sidebar" // Album export const Album = () => { - return ( - <> -
-
-
- {albums.items.map((album) => ( -
- 0 ? album.images[0].url : 'fallback-image-url.jpg'} - albumUrl={album.external_urls.spotify} - /> -
- - -
-
- ))} -
- + return ( + <> +
+
+
+ {albums.items.map((album) => ( +
+ 0 ? album.images[0].url : 'fallback-image-url.jpg'} + albumUrl={album.external_urls.spotify} + /> +
+ + +
- - ); -}; \ No newline at end of file + ))} +
+ +
+ + ) +} \ No newline at end of file diff --git a/src/components/AlbumName.jsx b/src/components/AlbumName.jsx index 64b64a2d..60297f9e 100644 --- a/src/components/AlbumName.jsx +++ b/src/components/AlbumName.jsx @@ -2,23 +2,22 @@ import PropTypes from 'prop-types' // Album Name export const AlbumName = ({ name, albumUrl }) => { - return ( - - ) + return ( + + ) } - // Define PropTypes for AlbumName AlbumName.propTypes = { - name: PropTypes.string.isRequired, - albumUrl: PropTypes.string.isRequired + name: PropTypes.string.isRequired, + albumUrl: PropTypes.string.isRequired }; diff --git a/src/components/ArtistName.jsx b/src/components/ArtistName.jsx index 3490b7dd..2ab01937 100644 --- a/src/components/ArtistName.jsx +++ b/src/components/ArtistName.jsx @@ -1,40 +1,37 @@ import PropTypes from 'prop-types' - // Artist Name export const ArtistName = ({ artists }) => { - return ( -
- {artists.map((artist, index) => { - let separator = ", "; - if (artists.length === 2 && index === 0) { - separator = " & "; - } else if (index === artists.length - 2) { - separator = " & "; - } else if (index === artists.length - 1) { - separator = ""; - } - + return ( +
+ {artists.map((artist, index) => { + let separator = ", "; + if (artists.length === 2 && index === 0) { + separator = " & "; + } else if (index === artists.length - 2) { + separator = " & "; + } else if (index === artists.length - 1) { + separator = ""; + } - return ( - - -

{artist.name + separator}

-
-
- ) - })} -
- ) + return ( + + +

{artist.name + separator}

+
+
+ ) + })} +
+ ) } - ArtistName.propTypes = { - artists: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - }) - ).isRequired, - artistsUrl: PropTypes.string.isRequired -}; \ No newline at end of file + artists: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + }) + ).isRequired, + artistsUrl: PropTypes.string.isRequired +} \ No newline at end of file diff --git a/src/components/CoverImage.jsx b/src/components/CoverImage.jsx index eb6a4ab2..bd814d14 100644 --- a/src/components/CoverImage.jsx +++ b/src/components/CoverImage.jsx @@ -3,25 +3,24 @@ import { DotsButton } from "./DotsButton" import { HeartButton } from "./HeartButton" import { PlayButton } from "./PlayButton" - export const CoverImage = ({ coverImg, albumUrl }) => { - return ( -
-
- Album Cover -
- - - -
-
- + return ( +
+
+ Album Cover +
+ + +
- ) +
+ +
+ ) } CoverImage.propTypes = { - coverImg: PropTypes.string.isRequired, - albumUrl: PropTypes.string.isRequired, + coverImg: PropTypes.string.isRequired, + albumUrl: PropTypes.string.isRequired, } diff --git a/src/components/DotsButton.jsx b/src/components/DotsButton.jsx index 03d6c615..4695ab6e 100644 --- a/src/components/DotsButton.jsx +++ b/src/components/DotsButton.jsx @@ -1,11 +1,11 @@ import dotsIcon from "../assets/icons/dots.svg" export const DotsButton = () => { - return ( - - - - ) + return ( + + + + ) } \ No newline at end of file diff --git a/src/components/Header.jsx b/src/components/Header.jsx index 75de4106..dc20cd2d 100644 --- a/src/components/Header.jsx +++ b/src/components/Header.jsx @@ -1,11 +1,9 @@ - - export const Header = () => { - return ( -
-

- New Vibes -

-
- ) + return ( +
+

+ New Vibes +

+
+ ) } \ No newline at end of file diff --git a/src/components/HeartButton.jsx b/src/components/HeartButton.jsx index f3ea72c9..e242db03 100644 --- a/src/components/HeartButton.jsx +++ b/src/components/HeartButton.jsx @@ -1,11 +1,11 @@ import heartIcon from "../assets/icons/heart.svg" export const HeartButton = () => { - return ( - - - - ) -} + return ( + + + + ) +} \ No newline at end of file diff --git a/src/components/PlayButton.jsx b/src/components/PlayButton.jsx index 00b815b1..3b4c6c5b 100644 --- a/src/components/PlayButton.jsx +++ b/src/components/PlayButton.jsx @@ -2,18 +2,18 @@ import playIcon from "../assets/icons/play.svg" import PropTypes from "prop-types" export const PlayButton = ({ albumUrl }) => { - const handlePlayClick = () => { - window.open(albumUrl, "_blank", "noopener,noreferrer") - } - return ( - - - - ) + const handlePlayClick = () => { + window.open(albumUrl, "_blank", "noopener,noreferrer") + } + return ( + + + + ) } PlayButton.propTypes = { - albumUrl: PropTypes.string.isRequired, + albumUrl: PropTypes.string.isRequired, } \ No newline at end of file diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx index 7c4ab3ed..91c4000c 100644 --- a/src/components/Sidebar.jsx +++ b/src/components/Sidebar.jsx @@ -1,18 +1,18 @@ import { playlists } from "../stretch-goal.json" -import { SidebarAlbum } from "./SidebarAlbum"; +import { SidebarAlbum } from "./SidebarAlbum" export const Sidebar = () => { - return ( -
-

Editor's Picks

-
- {playlists.items.map((item) => ( - 0 ? item.images[0].url : 'fallback-image-url.jpg'} - /> - ))} -
-
- ); -}; + return ( +
+

Editor's Picks

+
+ {playlists.items.map((item) => ( + 0 ? item.images[0].url : 'fallback-image-url.jpg'} + /> + ))} +
+
+ ) +} diff --git a/src/components/SidebarAlbum.jsx b/src/components/SidebarAlbum.jsx index c8cec4d1..809481e1 100644 --- a/src/components/SidebarAlbum.jsx +++ b/src/components/SidebarAlbum.jsx @@ -1,16 +1,17 @@ import PropTypes from "prop-types" + export const SidebarAlbum = ({ sidebarImg }) => { - return ( - <> -
-
- Single Cover -
-
- - ) + return ( + <> +
+
+ Single Cover +
+
+ + ) } SidebarAlbum.propTypes = { - sidebarImg: PropTypes.string.isRequired, + sidebarImg: PropTypes.string.isRequired, } \ No newline at end of file From c1f449750303f80f4b2116adda8d6af5f1c0c47d Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Fri, 22 Nov 2024 11:45:14 +0100 Subject: [PATCH 20/22] - cleaned code and added README --- README.md | 61 +++++++++++++++------------------ index.html | 24 +++++++------ src/App.jsx | 9 ++--- src/components/Album.jsx | 14 ++++---- src/components/AlbumName.jsx | 7 ++-- src/components/ArtistName.jsx | 8 ++--- src/components/CoverImage.jsx | 12 +++---- src/components/DotsButton.jsx | 2 +- src/components/Header.jsx | 14 ++++---- src/components/HeartButton.jsx | 2 +- src/components/PlayButton.jsx | 4 +-- src/components/Sidebar.jsx | 8 ++--- src/components/SidebarAlbum.jsx | 2 +- src/index.css | 8 ----- src/main.jsx | 2 +- 15 files changed, 79 insertions(+), 98 deletions(-) diff --git a/README.md b/README.md index bb881711..dbeeea31 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,32 @@ -

- - Project Banner Image - -

- # Music Releases - -Replace this readme with your own information about your project. - -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. - -## Getting Started with the Project - -### Dependency Installation & Startup Development Server - -Once cloned, navigate to the project's root directory and this project uses npm (Node Package Manager) to manage its dependencies. - -The command below is a combination of installing dependencies, opening up the project on VS Code and it will run a development server on your terminal. - -```bash -npm i && code . && npm run dev -``` - -### The Problem - -Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? +This project is a web application designed to display a collection of albums, with additional features like album details, a play button to launch albums in Spotify, and a sidebar showcasing editor’s picks. It pulls data from a Spotify API and uses that information to render album covers, names, and artist details. The app is structured using React components, each serving a specific purpose to ensure modularity and reusability. + +# Key Features +Album List: +The main section of the app displays a list of albums fetched from the Spotify API. Each album card contains: +Album Cover: Displays the album’s artwork. +Album Name: Links to the album's Spotify page. +Artist Name: Shows the name of the artist(s) associated with the album. +Play Button: Opens the album's Spotify page when clicked, enabling users to listen to the album directly in Spotify. +Sidebar with Editor’s Picks: Displays a list of curated playlists called "Editor's Picks." + +# Tech Stack +React: Used to create reusable components and manage application state. +PropTypes: For type-checking component props to ensure the correct data is passed to components. +Spotify API: To fetch album data (album details, cover images, artist names, etc.). +CSS: Custom styling to match the given design, ensuring that the album cards, play buttons, and sidebar look cohesive and visually appealing. + +Challenges & Solutions: +Design Consistency: One of the main challenges in this project was adhering to the design specifications provided. To address this, I followed a structured approach: + +I built reusable components to maintain consistency in the layout and UI elements (e.g., album card components, play button, sidebar components). +The app’s CSS was structured in a way that each component was easily styled, and custom media queries were used for responsive design. +API Data Handling: Handling asynchronous data fetching from the Spotify API required ensuring that the album data was properly loaded before rendering the components. I used the map() function to iterate through the album and playlist data and render the appropriate content. + +# Future Enhancements +Album Search: Implement a search feature that allows users to search for albums by name, artist, or genre. +Album Details Page: Expand the functionality by adding an album details page that includes track listings, release date, and additional information. +User Authentication: Integrate Spotify’s OAuth to allow users to log in and personalize their album lists. ### View it live - https://gittes-music-release.netlify.app - -## Instructions - - - See instructions of this project - diff --git a/index.html b/index.html index 3e0bcb75..6a22189f 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,15 @@ - - - - - Music Releases - - -
- - - + + + + + Music Releases + + + +
+ + + + \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index 07650a7b..23d90cf9 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,9 +1,4 @@ -import data from "./data.json" -import stretchgoals from "./stretch-goal.json" -import { Album } from "./components/Album" - -console.log(data); -console.log(stretchgoals) +import { Album } from "./components/Album"; export const App = () => { return ( @@ -11,4 +6,4 @@ export const App = () => { ) -} +} \ No newline at end of file diff --git a/src/components/Album.jsx b/src/components/Album.jsx index 2cecc5ac..1376b2f0 100644 --- a/src/components/Album.jsx +++ b/src/components/Album.jsx @@ -1,9 +1,9 @@ -import { albums } from "../data.json" -import { AlbumName } from "./AlbumName" -import { ArtistName } from "./ArtistName" -import { CoverImage } from "./CoverImage" -import { Header } from "./Header" -import { Sidebar } from "./Sidebar" +import { albums } from "../data.json"; +import { AlbumName } from "./AlbumName"; +import { ArtistName } from "./ArtistName"; +import { CoverImage } from "./CoverImage"; +import { Header } from "./Header"; +import { Sidebar } from "./Sidebar"; // Album export const Album = () => { @@ -15,7 +15,7 @@ export const Album = () => { {albums.items.map((album) => (
0 ? album.images[0].url : 'fallback-image-url.jpg'} + coverImg={album.images.length > 0 ? album.images[0].url : "fallback-image-url.jpg"} albumUrl={album.external_urls.spotify} />
diff --git a/src/components/AlbumName.jsx b/src/components/AlbumName.jsx index 60297f9e..6a83f4e5 100644 --- a/src/components/AlbumName.jsx +++ b/src/components/AlbumName.jsx @@ -1,4 +1,4 @@ -import PropTypes from 'prop-types' +import PropTypes from "prop-types"; // Album Name export const AlbumName = ({ name, albumUrl }) => { @@ -8,7 +8,7 @@ export const AlbumName = ({ name, albumUrl }) => { href={albumUrl} target="_blank" rel="noopener noreferrer" - className='album-name-a'> + className="album-name-a">

{name}

@@ -19,5 +19,4 @@ export const AlbumName = ({ name, albumUrl }) => { AlbumName.propTypes = { name: PropTypes.string.isRequired, albumUrl: PropTypes.string.isRequired -}; - +}; \ No newline at end of file diff --git a/src/components/ArtistName.jsx b/src/components/ArtistName.jsx index 2ab01937..6b0dd27f 100644 --- a/src/components/ArtistName.jsx +++ b/src/components/ArtistName.jsx @@ -1,9 +1,9 @@ -import PropTypes from 'prop-types' +import PropTypes from "prop-types"; // Artist Name export const ArtistName = ({ artists }) => { return ( -
+
{artists.map((artist, index) => { let separator = ", "; if (artists.length === 2 && index === 0) { @@ -16,8 +16,8 @@ export const ArtistName = ({ artists }) => { return ( - -

{artist.name + separator}

+
+

{artist.name + separator}

) diff --git a/src/components/CoverImage.jsx b/src/components/CoverImage.jsx index bd814d14..4538f222 100644 --- a/src/components/CoverImage.jsx +++ b/src/components/CoverImage.jsx @@ -1,7 +1,7 @@ -import PropTypes from "prop-types" -import { DotsButton } from "./DotsButton" -import { HeartButton } from "./HeartButton" -import { PlayButton } from "./PlayButton" +import PropTypes from "prop-types"; +import { DotsButton } from "./DotsButton"; +import { HeartButton } from "./HeartButton"; +import { PlayButton } from "./PlayButton"; export const CoverImage = ({ coverImg, albumUrl }) => { return ( @@ -14,7 +14,6 @@ export const CoverImage = ({ coverImg, albumUrl }) => {
-
) } @@ -22,5 +21,4 @@ export const CoverImage = ({ coverImg, albumUrl }) => { CoverImage.propTypes = { coverImg: PropTypes.string.isRequired, albumUrl: PropTypes.string.isRequired, -} - +} \ No newline at end of file diff --git a/src/components/DotsButton.jsx b/src/components/DotsButton.jsx index 4695ab6e..6276eb6b 100644 --- a/src/components/DotsButton.jsx +++ b/src/components/DotsButton.jsx @@ -1,4 +1,4 @@ -import dotsIcon from "../assets/icons/dots.svg" +import dotsIcon from "../assets/icons/dots.svg"; export const DotsButton = () => { return ( diff --git a/src/components/Header.jsx b/src/components/Header.jsx index dc20cd2d..76717c75 100644 --- a/src/components/Header.jsx +++ b/src/components/Header.jsx @@ -1,9 +1,9 @@ export const Header = () => { - return ( -
-

- New Vibes -

-
- ) + return ( +
+

+ New Vibes +

+
+ ) } \ No newline at end of file diff --git a/src/components/HeartButton.jsx b/src/components/HeartButton.jsx index e242db03..353ec73f 100644 --- a/src/components/HeartButton.jsx +++ b/src/components/HeartButton.jsx @@ -1,4 +1,4 @@ -import heartIcon from "../assets/icons/heart.svg" +import heartIcon from "../assets/icons/heart.svg"; export const HeartButton = () => { return ( diff --git a/src/components/PlayButton.jsx b/src/components/PlayButton.jsx index 3b4c6c5b..3b6d7211 100644 --- a/src/components/PlayButton.jsx +++ b/src/components/PlayButton.jsx @@ -1,5 +1,5 @@ -import playIcon from "../assets/icons/play.svg" -import PropTypes from "prop-types" +import playIcon from "../assets/icons/play.svg"; +import PropTypes from "prop-types"; export const PlayButton = ({ albumUrl }) => { const handlePlayClick = () => { diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx index 91c4000c..98d09cc5 100644 --- a/src/components/Sidebar.jsx +++ b/src/components/Sidebar.jsx @@ -1,5 +1,5 @@ -import { playlists } from "../stretch-goal.json" -import { SidebarAlbum } from "./SidebarAlbum" +import { playlists } from "../stretch-goal.json"; +import { SidebarAlbum } from "./SidebarAlbum"; export const Sidebar = () => { return ( @@ -9,10 +9,10 @@ export const Sidebar = () => { {playlists.items.map((item) => ( 0 ? item.images[0].url : 'fallback-image-url.jpg'} + sidebarImg={item.images.length > 0 ? item.images[0].url : "fallback-image-url.jpg"} /> ))}
) -} +} \ No newline at end of file diff --git a/src/components/SidebarAlbum.jsx b/src/components/SidebarAlbum.jsx index 809481e1..906ce09b 100644 --- a/src/components/SidebarAlbum.jsx +++ b/src/components/SidebarAlbum.jsx @@ -1,4 +1,4 @@ -import PropTypes from "prop-types" +import PropTypes from "prop-types"; export const SidebarAlbum = ({ sidebarImg }) => { return ( diff --git a/src/index.css b/src/index.css index 2d03ef16..1a25e9ec 100644 --- a/src/index.css +++ b/src/index.css @@ -21,7 +21,6 @@ header { h1 { color: greenyellow; - } .main-container { @@ -40,7 +39,6 @@ h1 { display: none; } - .album-card { display: flex; flex-direction: column; @@ -95,14 +93,12 @@ h1 { .dots-icon { width: 30px; filter: invert(100%); - /* z-index: 5; */ } .play-icon { width: 50px; } - .heart-button, .play-button, .dots-button { @@ -157,7 +153,6 @@ h1 { } /* hover effects */ - .album-card:hover .cover-image-container .cover-image-img { filter: brightness(30%); } @@ -172,8 +167,6 @@ h1 { transition: all 0.3s ease; } - - @media (min-width: 1024px) { .main-container { display: grid; @@ -216,5 +209,4 @@ h1 { .cover-image-sidebar-img { width: 100%; } - } \ No newline at end of file diff --git a/src/main.jsx b/src/main.jsx index 51294f39..a2fb6f6a 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -7,4 +7,4 @@ ReactDOM.createRoot(document.getElementById("root")).render( -); +); \ No newline at end of file From de83afe751e0264d7b013240d4faa829f893cc57 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Fri, 22 Nov 2024 12:28:17 +0100 Subject: [PATCH 21/22] - updated README --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index dbeeea31..6d60db72 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,22 @@ This project is a web application designed to display a collection of albums, wi # Key Features Album List: The main section of the app displays a list of albums fetched from the Spotify API. Each album card contains: + Album Cover: Displays the album’s artwork. + Album Name: Links to the album's Spotify page. + Artist Name: Shows the name of the artist(s) associated with the album. + Play Button: Opens the album's Spotify page when clicked, enabling users to listen to the album directly in Spotify. + Sidebar with Editor’s Picks: Displays a list of curated playlists called "Editor's Picks." # Tech Stack React: Used to create reusable components and manage application state. + PropTypes: For type-checking component props to ensure the correct data is passed to components. + Spotify API: To fetch album data (album details, cover images, artist names, etc.). CSS: Custom styling to match the given design, ensuring that the album cards, play buttons, and sidebar look cohesive and visually appealing. @@ -21,11 +28,14 @@ Design Consistency: One of the main challenges in this project was adhering to t I built reusable components to maintain consistency in the layout and UI elements (e.g., album card components, play button, sidebar components). The app’s CSS was structured in a way that each component was easily styled, and custom media queries were used for responsive design. + API Data Handling: Handling asynchronous data fetching from the Spotify API required ensuring that the album data was properly loaded before rendering the components. I used the map() function to iterate through the album and playlist data and render the appropriate content. # Future Enhancements Album Search: Implement a search feature that allows users to search for albums by name, artist, or genre. + Album Details Page: Expand the functionality by adding an album details page that includes track listings, release date, and additional information. + User Authentication: Integrate Spotify’s OAuth to allow users to log in and personalize their album lists. ### View it live From 4968f3b5554f48bb1a372374427e0fda106ca6d2 Mon Sep 17 00:00:00 2001 From: Gitte Beckmann Date: Fri, 22 Nov 2024 12:29:23 +0100 Subject: [PATCH 22/22] - updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d60db72..6cc6b420 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ PropTypes: For type-checking component props to ensure the correct data is passe Spotify API: To fetch album data (album details, cover images, artist names, etc.). CSS: Custom styling to match the given design, ensuring that the album cards, play buttons, and sidebar look cohesive and visually appealing. -Challenges & Solutions: +# Challenges & Solutions Design Consistency: One of the main challenges in this project was adhering to the design specifications provided. To address this, I followed a structured approach: I built reusable components to maintain consistency in the layout and UI elements (e.g., album card components, play button, sidebar components).