diff --git a/qtify/package-lock.json b/qtify/package-lock.json
index 84c0f2767a..c9620aeda4 100644
--- a/qtify/package-lock.json
+++ b/qtify/package-lock.json
@@ -11,6 +11,7 @@
"@emotion/react": "^11.13.0",
"@emotion/styled": "^11.13.0",
"@mui/base": "^5.0.0-beta.40",
+ "@mui/icons-material": "^5.16.6",
"@mui/lab": "^5.0.0-alpha.173",
"@mui/material": "^5.16.6",
"@testing-library/jest-dom": "^5.17.0",
@@ -3677,6 +3678,32 @@
"url": "https://opencollective.com/mui-org"
}
},
+ "node_modules/@mui/icons-material": {
+ "version": "5.16.6",
+ "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.6.tgz",
+ "integrity": "sha512-ceNGjoXheH9wbIFa1JHmSc9QVjJUvh18KvHrR4/FkJCSi9HXJ+9ee1kUhCOEFfuxNF8UB6WWVrIUOUgRd70t0A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.23.9"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui-org"
+ },
+ "peerDependencies": {
+ "@mui/material": "^5.0.0",
+ "@types/react": "^17.0.0 || ^18.0.0",
+ "react": "^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@mui/lab": {
"version": "5.0.0-alpha.173",
"resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.173.tgz",
diff --git a/qtify/package.json b/qtify/package.json
index c4510d778b..dcc24c7bbc 100644
--- a/qtify/package.json
+++ b/qtify/package.json
@@ -6,6 +6,7 @@
"@emotion/react": "^11.13.0",
"@emotion/styled": "^11.13.0",
"@mui/base": "^5.0.0-beta.40",
+ "@mui/icons-material": "^5.16.6",
"@mui/lab": "^5.0.0-alpha.173",
"@mui/material": "^5.16.6",
"@testing-library/jest-dom": "^5.17.0",
diff --git a/qtify/src/App.css b/qtify/src/App.css
index 74b5e05345..e247a5ffe9 100644
--- a/qtify/src/App.css
+++ b/qtify/src/App.css
@@ -36,3 +36,4 @@
transform: rotate(360deg);
}
}
+
diff --git a/qtify/src/App.js b/qtify/src/App.js
index 579b5ef93a..328c1437b5 100644
--- a/qtify/src/App.js
+++ b/qtify/src/App.js
@@ -3,9 +3,25 @@ import Navbar from './components/Navbar/Navbar';
import Hero from './components/Hero/Hero';
import axios from 'axios';
-import { useEffect, useState } from 'react';
+import React, { useEffect, useState } from 'react';
import Section from './components/Section/Section';
import { Stack, Divider } from '@mui/material';
+import { MusicContext } from './MusicContext';
+import MusicBar from './components/MusicBar/MusicBar';
+
+import { Routes, Route } from 'react-router-dom';
+import AlbumDetails from './components/AlbumDetails/AlbumDetails';
+
+
+export const fetchData = async (type) => {
+ try {
+ let res = await axios.get('https://qtify-backend-labs.crio.do/' + type)
+
+ return res.data
+ } catch (e) {
+ console.log(e)
+ }
+}
function App() {
@@ -13,16 +29,13 @@ function App() {
const [topData, setTopData] = useState([])
const [songData, setSongData] = useState([])
const [genreData, setGenreData] = useState([])
+ const [faqData, setFaqData] = useState([])
+
+
+ const [selectedSong, setSelectedSong] = useState(null);
+
- const fetchData = async (type) => {
- try {
- let res = await axios.get('https://qtify-backend-labs.crio.do/' + type)
- return res.data
- } catch (e) {
- console.log(e)
- }
- }
useEffect(() => {
const getData = async () => {
@@ -34,6 +47,8 @@ function App() {
await setSongData(data)
data = await fetchData('genres')
await setGenreData(data.data)
+ data = await fetchData('faq')
+ await setFaqData(data.data)
}
@@ -42,17 +57,29 @@ function App() {
}, [])
+
+
return (
-
-
-
- }>
-
-
-
-
-
-
+
+
+
+
+
+
+ }>
+
+
+
+
+
+
+ >
+ } />
+ } />
+
+
+
);
}
diff --git a/qtify/src/MusicContext.js b/qtify/src/MusicContext.js
new file mode 100644
index 0000000000..aa0f9e88dd
--- /dev/null
+++ b/qtify/src/MusicContext.js
@@ -0,0 +1,4 @@
+import React from 'react';
+
+
+export const MusicContext = React.createContext()
diff --git a/qtify/src/assets/music.mp3 b/qtify/src/assets/music.mp3
new file mode 100644
index 0000000000..edbe9e056b
Binary files /dev/null and b/qtify/src/assets/music.mp3 differ
diff --git a/qtify/src/components/AlbumDetails/AlbumDetails.js b/qtify/src/components/AlbumDetails/AlbumDetails.js
new file mode 100644
index 0000000000..5d33fd8ca2
--- /dev/null
+++ b/qtify/src/components/AlbumDetails/AlbumDetails.js
@@ -0,0 +1,127 @@
+import React, { useEffect, useState } from 'react';
+import { useParams } from 'react-router-dom';
+import MusicBar from '../MusicBar/MusicBar';
+import axios from 'axios';
+import ArrowCircleLeftOutlinedIcon from '@mui/icons-material/ArrowCircleLeftOutlined';
+import { useNavigate } from 'react-router-dom';
+import { Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper } from '@mui/material';
+import Pagination from '@mui/material/Pagination';
+
+import { MusicContext } from "../../MusicContext";
+
+function AlbumDetails() {
+
+ const { id } = useParams();
+ const [album, setAlbum] = useState(null);
+ const [page, setPage] = useState(1);
+
+ const navigate = useNavigate();
+ const { selectedSong, setSelectedSong } = React.useContext(MusicContext)
+
+ const fetchAlbumData = async () => {
+ try {
+ const newData = await axios.get('https://qtify-backend-labs.crio.do/albums/new');
+ const topData = await axios.get('https://qtify-backend-labs.crio.do/albums/top');
+ const allData = [...newData.data, ...topData.data];
+ const foundAlbum = allData.find(item => item.id === id);
+ setAlbum(foundAlbum);
+ } catch (error) {
+ console.error("Error fetching album data:", error);
+ }
+ };
+
+ useEffect(() => {
+ fetchAlbumData();
+ }, [id]);
+
+ const handleChange = (event, value) => {
+ setPage(value);
+ };
+
+ const songsPerPage = 13;
+ const startIndex = (page - 1) * songsPerPage;
+ const endIndex = startIndex + songsPerPage;
+ const currentSongs = album ? album.songs.slice(startIndex, endIndex) : [];
+
+ if (!album) {
+ return Loading...
;
+ }
+
+ function totalDuration() {
+ let durationInMillis = album.songs.reduce((acc, curr) => curr.durationInMs + acc, 0);
+ const minutes = Math.floor(durationInMillis / 60000); // 1 minute = 60,000 milliseconds
+ return `${minutes} min`;
+ }
+
+ return (
+
+
+
+ navigate('/')} style={{ cursor: 'pointer', height: '4%', width: '4%' }} />
+
+
+
+
+
{album.title}
+
+
{album.description}
+
{album.songs.length} songs • {totalDuration()} • {album.follows} Follows
+
+
+
+
+
+
+
+
+
+
+ Title
+ Artist
+ Duration
+
+
+
+ {currentSongs.map((song, index) => (
+ setSelectedSong(song)} style={{ cursor: 'pointer' }}>
+
+
+ {song.title}
+
+ {song.artists.join(', ')}
+ {Math.ceil(song.durationInMs / 60000)} min
+
+ ))}
+
+
+
+
+
+
+
+
+ );
+}
+
+export default AlbumDetails;
diff --git a/qtify/src/components/AlbumDetails/AlbumDetails.module.css b/qtify/src/components/AlbumDetails/AlbumDetails.module.css
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/qtify/src/components/Button/Button.jsx b/qtify/src/components/Button/Button.jsx
index 0b295cbe82..d948dbcf68 100644
--- a/qtify/src/components/Button/Button.jsx
+++ b/qtify/src/components/Button/Button.jsx
@@ -1,9 +1,9 @@
import React from "react";
import styles from "./Button.module.css";
-export default function Button({ children }) {
+export default function CustomButton({ children, onClick }) {
return (
-