Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xings music libary #95

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@

# 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.
This week, we will practice React and creating components that will use data from Spotify, which then transfer to its children's components using props. The task is to build a page that shows new albums and single releases.

## Getting Started with the Project
Step 1: Install Node.js
Step 2: Verify Node.js Installation Path on Windows
Step 3: Restart Git Bash in VS Code and then the setup is done

### Dependency Installation & Startup Development Server

Expand All @@ -24,7 +25,9 @@ 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?
The #1 problem is how to get start with npm which took me some effort to identify the install of Node.js and set the right "Environment Variables" on my PC of the windows system.



### View it live

Expand Down
26 changes: 15 additions & 11 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Music Releases</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>

<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Xings Spotify Music Releases</title>
<!-- https://xingsmusiclibary.netlify.app -->
</head>

<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>

</html>
5 changes: 2 additions & 3 deletions pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
## Netlify link
Add your Netlify link here.
PS. Don't forget to add it in your readme as well.
https://xingsmusiclibary.netlify.app

## Collaborators
Add any collaborators here, as well as in the title of the PR.
chatGpt :>
15 changes: 14 additions & 1 deletion src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import data from "./data.json";
import Header from "./components/Header";
import Footer from "./components/Footer";
import { AlbumList } from "./components/AlbumList";


import './index.css';


console.log(data);

export const App = () => {
return <div>Find me in src/app.jsx!</div>;
return (
<div className="App">
<Header />
<AlbumList albums={data.albums.items}/>
<Footer />
</div>
);
};
2 changes: 1 addition & 1 deletion src/assets/icons/dots.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/assets/icons/heart.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/assets/icons/play.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/icons/spotify.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions src/components/Album.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import PropTypes from 'prop-types';
import { ArtistName } from './ArtistName';
import { CoverImage } from './CoverImage';
import { AlbumName } from './AlbumName';

export const Album = ({ album }) => {
return (
<div className="album-card">
<CoverImage imageUrl={album.images[0].url} />
<div className="album-info">
<div className="album-name">
<AlbumName name={album.name} url={album.external_urls.spotify} />
</div>
<div className="artist-name">
{album.artists.map((artist, index) => (
<ArtistName
key={artist.id}
name={artist.name}
url={artist.external_urls.spotify}
isLast={index === album.artists.length - 1}
/>
))}
</div>
</div>
</div>
);
};

Album.propTypes = {
album: PropTypes.shape({
name: PropTypes.string.isRequired,
images: PropTypes.arrayOf(
PropTypes.shape({
url: PropTypes.string.isRequired,
})
).isRequired,
external_urls: PropTypes.shape({
spotify: PropTypes.string.isRequired,
}).isRequired,
artists: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
external_urls: PropTypes.shape({
spotify: PropTypes.string.isRequired,
}).isRequired,
})
).isRequired,
}).isRequired,
};
Comment on lines +29 to +49

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you understand this part? We have not gone through it. It's important that you understand the code, even though you've gotten help from your collaborator. :)


16 changes: 16 additions & 0 deletions src/components/AlbumList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import PropTypes from 'prop-types';
import { Album } from './Album';

export const AlbumList = ({ albums }) => {
return (
<div className="album-container">
{albums.map((album) => (
<Album key={album.id} album={album} />
))}
</div>
);
};

AlbumList.propTypes = {
albums: PropTypes.arrayOf(PropTypes.object).isRequired,
};
Comment on lines +14 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, prop types is nice to understand. But we haven't really gone thru it yet.

20 changes: 20 additions & 0 deletions src/components/AlbumName.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import PropTypes from 'prop-types';

export const AlbumName = ({ name, url }) => {
return (
<a
href={url}
target="_blank"
rel="noopener noreferrer"
className="album-name"
>
{name}
</a>
);
};

AlbumName.propTypes = {
name: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
};

23 changes: 23 additions & 0 deletions src/components/ArtistName.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import PropTypes from 'prop-types';

export const ArtistName = ({ name, url, isLast }) => {
return (
<>
<a
href={url}
target="_blank"
rel="noopener noreferrer"
className="artist-name"
>
{name}
</a>
{!isLast && ', '}
</>
);
};

ArtistName.propTypes = {
name: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
isLast: PropTypes.bool.isRequired,
};
28 changes: 28 additions & 0 deletions src/components/CoverImage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import PropTypes from 'prop-types';
import dotsIcon from '../assets/icons/dots.svg';
import heartIcon from '../assets/icons/heart.svg';
import playIcon from '../assets/icons/play.svg';

export const CoverImage = ({ imageUrl }) => {
return (
<div className="cover-image-wrapper">
<img src={imageUrl} alt="Album cover" className="cover-image" />
<div className="hover-buttons">
<button className="hover-button">
<img src={heartIcon} alt="Favorite" className="heartIcon" />
</button>
<button className="hover-button">
<img src={playIcon} alt="Play" className="playIcon" />
</button>
<button className="hover-button">
<img src={dotsIcon} alt="More options" className="dotsIcon" />
</button>
</div>
</div>
);
};

CoverImage.propTypes = {
imageUrl: PropTypes.string.isRequired,
};

10 changes: 10 additions & 0 deletions src/components/Footer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const Footer = () => {
return (
<footer>
<p>&copy; 2024 XingS Music APP. All rights reserved.</p>
<p>Source from Spotify API</p>
</footer>
);
};

export default Footer;
15 changes: 15 additions & 0 deletions src/components/Header.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import spotifyIcon from '../assets/icons/spotify.svg';

const Header = () => {
return (
<header>
<h1 className="header">
<img src={spotifyIcon} alt="Spotify Logo" className="spotifyIcon" />
New albums and single releases
</h1>
<p>Find you next Favorite</p>
</header>
);
};

export default Header;
Loading