изменена верстка
This commit is contained in:
parent
73954d9d5a
commit
ee17998948
2
.gitignore
vendored
2
.gitignore
vendored
@ -13,4 +13,4 @@
|
||||
*.vsix
|
||||
|
||||
node_modules
|
||||
*storybook.log
|
||||
*storybook.log
|
@ -15,4 +15,4 @@
|
||||
5. Валидация форм
|
||||
|
||||
Должен был добавить плеер с воспроизведением песен, но из-за ошибок, про которые я написал выше, не удалось.
|
||||
Пришлось жестко передать объект песни прямо в коде компонента.
|
||||
Пришлось жестко передать объект песни прямо в коде компонента.
|
260
data.json
260
data.json
@ -78,7 +78,7 @@
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "1",
|
||||
"id": "6",
|
||||
"song_name": "Smells Like Poop",
|
||||
"band_id": "1",
|
||||
"band_name": "Nevroz",
|
||||
@ -93,7 +93,7 @@
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"id": "7",
|
||||
"song_name": "Song 3",
|
||||
"band_id": "1",
|
||||
"band_name": "Nevroz",
|
||||
@ -108,7 +108,7 @@
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"id": "8",
|
||||
"song_name": "Ругань из-за Стёпы",
|
||||
"band_id": "2",
|
||||
"band_name": "noizemchik",
|
||||
@ -124,7 +124,7 @@
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"id": "9",
|
||||
"song_name": "Crazy Frog",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
@ -138,126 +138,6 @@
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "6",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "7",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "8",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "9",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "10",
|
||||
"song_name": "Кем я стал",
|
||||
@ -265,14 +145,14 @@
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "source_path",
|
||||
"cover": "https://sun9-11.userapi.com/impg/yfCwuWXI6NkFVC2HvMlegM2qWLlenkeiiRyvNQ/jpH8m1wlLqs.jpg?size=604x604&quality=95&sign=60a1d1877b49631fb6078db88715fc88&c_uniq_tag=UKrig2vg02reyBH_ML0OKeqt5gm_2jpwEXD7NJBUXoQ&type=album",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
},
|
||||
{
|
||||
"id": "11",
|
||||
"song_name": "Кем я стал",
|
||||
@ -280,6 +160,126 @@
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "12",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "13",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "14",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "15",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "18",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "19",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "/src/songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "20",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "source_path",
|
||||
"cover": "https://sun9-11.userapi.com/impg/yfCwuWXI6NkFVC2HvMlegM2qWLlenkeiiRyvNQ/jpH8m1wlLqs.jpg?size=604x604&quality=95&sign=60a1d1877b49631fb6078db88715fc88&c_uniq_tag=UKrig2vg02reyBH_ML0OKeqt5gm_2jpwEXD7NJBUXoQ&type=album",
|
||||
"playlists": [
|
||||
"3"
|
||||
],
|
||||
"genreid": "1",
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "21",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "source_path",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/10129881/f3cf1afc.a.30561322-1/m1000x1000?webp=falseh",
|
||||
"playlists": [
|
||||
@ -289,7 +289,7 @@
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "12",
|
||||
"id": "22",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
@ -304,7 +304,7 @@
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "13",
|
||||
"id": "23",
|
||||
"song_name": "Song 3",
|
||||
"band_id": "1",
|
||||
"band_name": "Nevroz",
|
||||
@ -319,7 +319,7 @@
|
||||
"genre_name": "Rock"
|
||||
},
|
||||
{
|
||||
"id": "14",
|
||||
"id": "24",
|
||||
"song_name": "Song 3",
|
||||
"band_id": "1",
|
||||
"band_name": "Nevroz",
|
||||
|
33
package-lock.json
generated
33
package-lock.json
generated
@ -24,6 +24,7 @@
|
||||
"axios": "^1.7.4",
|
||||
"node-fetch": "^2.6.7",
|
||||
"react": "^18.3.1",
|
||||
"react-audio-player-component": "^1.2.4",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-dotenv": "^0.1.3",
|
||||
"react-google-recaptcha": "^3.1.0",
|
||||
@ -24632,6 +24633,32 @@
|
||||
"react": ">=16.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-audio-player-component": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react-audio-player-component/-/react-audio-player-component-1.2.4.tgz",
|
||||
"integrity": "sha512-bW/mJzFagOzDRJouknPSHEkImwzvKwt0JQBf9nuOQ+tF/MYhwHurNWDoLxAZvhWGGG6dQ9kL2RSFBKsDTa3Irg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"react-audio-visualize": "^1.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.15.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.2.0",
|
||||
"react-dom": ">=16.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-audio-visualize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-audio-visualize/-/react-audio-visualize-1.2.0.tgz",
|
||||
"integrity": "sha512-rfO5nmT0fp23gjU0y2WQT6+ZOq2ZsuPTMphchwX1PCz1Di4oaIr6x7JZII8MLrbHdG7UB0OHfGONTIsWdh67kQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.2.0",
|
||||
"react-dom": ">=16.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-colorful": {
|
||||
"version": "5.6.1",
|
||||
"resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz",
|
||||
@ -27940,9 +27967,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
|
||||
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==",
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz",
|
||||
"integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/tsutils": {
|
||||
|
@ -19,6 +19,7 @@
|
||||
"axios": "^1.7.4",
|
||||
"node-fetch": "^2.6.7",
|
||||
"react": "^18.3.1",
|
||||
"react-audio-player-component": "^1.2.4",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-dotenv": "^0.1.3",
|
||||
"react-google-recaptcha": "^3.1.0",
|
||||
|
@ -90,11 +90,12 @@
|
||||
}
|
||||
|
||||
.song-table-row {
|
||||
|
||||
margin-top: 50px !important;
|
||||
margin-bottom: 50px !important;
|
||||
}
|
||||
|
||||
.song-table-row:hover {
|
||||
outline: #9b9b9b solid 1px !important;
|
||||
outline: #9d0000 solid 3px !important;
|
||||
outline-offset: -1px !important;
|
||||
}
|
||||
|
||||
@ -133,7 +134,6 @@
|
||||
.play-song-button:hover:after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.current-song-cover {
|
||||
object-fit: scale-down;
|
||||
}
|
||||
@ -180,5 +180,5 @@
|
||||
}
|
||||
|
||||
.bg-gradient {
|
||||
background-image: linear-gradient(-45deg, red 0%, yellow 25%, yellow 51%, #ad0000 100%);
|
||||
background-image: linear-gradient(-45deg, red 0%, orange 25%, orange 51%, #ad0000 100%);
|
||||
}
|
36
src/App.tsx
36
src/App.tsx
@ -1,21 +1,6 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { Routes, Route} from 'react-router-dom';
|
||||
|
||||
import logo from './logo.svg';
|
||||
import './App.css';
|
||||
import { Button } from 'antd';
|
||||
import {Track} from './components/songComponents/Track';
|
||||
import {Header} from './components/layoutComponents/Header';
|
||||
import {Playlist} from './components/cardComponents//Playlist';
|
||||
import {Footer} from './components/layoutComponents/Footer';
|
||||
import {CurrentTrack} from './components/songComponents/CurrentTrack';
|
||||
import {SongsBlock} from './components/menuComponents/SongsBlock';
|
||||
import { ISong, IAlbum, IGenre, IBand, IPlaylist, IAdvertisement } from './models/IModels';
|
||||
import axios from 'axios';
|
||||
import { PlaylistsBlock } from './components/menuComponents/PlaylistsBlock';
|
||||
import { MenuBlock } from './components/layoutComponents/MenuBlock';
|
||||
import { getAds, getGenres, getPlaylists, getSongs } from './API/api';
|
||||
import { AdBlock } from './components/layoutComponents/AdBlock';
|
||||
|
||||
import { Homepage } from './pages/Homepage';
|
||||
import { Loginpage } from './pages/Loginpage';
|
||||
@ -28,16 +13,15 @@ function App() {
|
||||
return (
|
||||
|
||||
<div className="App bg-slate-100">
|
||||
<div id="app" className='bg-gradient'>
|
||||
<Routes>
|
||||
<Route path='/' element={<Layout />}>
|
||||
<Route index element={<Homepage />} />
|
||||
<Route path='login' element={<Loginpage />} />
|
||||
<Route path='register' element={<Registerpage />} />
|
||||
<Route path='profile' element={<Profilepage />} />
|
||||
</Route>
|
||||
|
||||
</Routes>
|
||||
<div id="app" className='bg-white'>
|
||||
<Routes>
|
||||
<Route path='/' element={<Layout />}>
|
||||
<Route index element={<Homepage song_id='2'/>} />
|
||||
<Route path='login' element={<Loginpage />} />
|
||||
<Route path='profile' element={<Profilepage />} />
|
||||
</Route>
|
||||
|
||||
</Routes>
|
||||
</div>
|
||||
|
||||
|
||||
@ -46,4 +30,4 @@ function App() {
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App;
|
@ -2,7 +2,7 @@ import { IAdvertisement } from "../../models/IModels";
|
||||
|
||||
export function AdCard({ad}: {ad: IAdvertisement}) {
|
||||
return (
|
||||
<div className="container mx-auto" style={{padding: 10}}>
|
||||
<div className="container mx-auto" style={{paddingTop: 20, paddingBottom: 60, paddingRight: 60, paddingLeft: 60}}>
|
||||
<img src={ad.photo} alt={ad.name} className="h-full w-auto rounded m-auto">
|
||||
</img>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@ import { getAds } from "../../API/api";
|
||||
export function AdBlock({ads}: {ads: IAdvertisement[]}) {
|
||||
|
||||
return (
|
||||
<div className="AdBlock border-solid border-2 border-slate-100" style={{height: 'auto', minHeight: '100%', width: '30%'}}>
|
||||
<div className="AdBlock border-solid border-2 border-slate-100" style={{height: 'auto', minHeight: '100%', width: '35%'}}>
|
||||
{ads.map(ad => <AdCard key={ad.id} ad={ad} />)}
|
||||
</div>
|
||||
);
|
||||
|
@ -3,9 +3,11 @@ import { Tabs } from 'antd';
|
||||
import React from 'react';
|
||||
import { PlaylistsBlock } from '../menuComponents/PlaylistsBlock';
|
||||
import { IAlbum, IGenre, IPlaylist, ISong } from '../../models/IModels';
|
||||
import { SongsBlock } from '../menuComponents/SongsBlock';
|
||||
import { NewSongsBlock } from '../menuComponents/NewSongsBlock';
|
||||
import { FullPlaylistBlock } from '../menuComponents/FullPlaylistBlock';
|
||||
import { width } from '@mui/system';
|
||||
import TabPane from 'antd/es/tabs/TabPane';
|
||||
import { ChartSongsBlock } from '../menuComponents/ChartSongsBlock';
|
||||
|
||||
interface MenuBlockProps {
|
||||
playlists?: IPlaylist[],
|
||||
@ -15,33 +17,41 @@ interface MenuBlockProps {
|
||||
}
|
||||
|
||||
export function MenuBlock({playlists, songs, albums, genres}: MenuBlockProps) {
|
||||
const chartTab = {
|
||||
label: 'Чарт',
|
||||
key: 'Chart',
|
||||
children: songs? <SongsBlock /> : null
|
||||
const newSongsTab = {
|
||||
label: 'Новинки',
|
||||
key: 'New',
|
||||
children: songs? <NewSongsBlock /> : null
|
||||
};
|
||||
const playlistsTab = {
|
||||
label: 'Плейлисты',
|
||||
key: 'Playlists',
|
||||
children: playlists && genres ? <FullPlaylistBlock playlists={playlists} genres={genres}/> : null
|
||||
};
|
||||
const newSongsTab = {
|
||||
label: 'Новинки',
|
||||
key: 'New',
|
||||
children: songs? <SongsBlock /> : null
|
||||
|
||||
const chartTab = {
|
||||
label: 'Чарт',
|
||||
key: 'Chart',
|
||||
children: songs? <ChartSongsBlock /> : null
|
||||
};
|
||||
const tabs = [chartTab, playlistsTab, newSongsTab];
|
||||
|
||||
const recTab = {
|
||||
label: 'Рекомендации',
|
||||
key: 'Recomendations',
|
||||
children: songs? <NewSongsBlock /> : null
|
||||
};
|
||||
const tabs = [recTab, newSongsTab, chartTab, playlistsTab];
|
||||
|
||||
return (
|
||||
<div className="flex" style={{display: 'flex', alignSelf: 'flex-start', width: 'fit-content'}}>
|
||||
<Tabs
|
||||
|
||||
|
||||
type="line"
|
||||
className='container flex justify-start menu-block'
|
||||
defaultActiveKey="Chart"
|
||||
defaultActiveKey="New"
|
||||
items={tabs}
|
||||
style={{padding: '1%'}}
|
||||
/>
|
||||
>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
|
||||
|
45
src/components/menuComponents/ChartSongsBlock.tsx
Normal file
45
src/components/menuComponents/ChartSongsBlock.tsx
Normal file
@ -0,0 +1,45 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { ISong } from '../../models/IModels';
|
||||
import axios from 'axios';
|
||||
import { Table, Button, Empty } from 'antd';
|
||||
import { PlayCircleFilled, PlayCircleOutlined } from '@ant-design/icons';
|
||||
import { getSongs } from '../../API/api';
|
||||
import Title from 'antd/es/typography/Title';
|
||||
import { GetColumns } from './Templates/songsTemplate';
|
||||
import { getColumnsWithNumber } from './Templates/numeredSongsTemplate';
|
||||
|
||||
// Функция для генерации номеров строк
|
||||
const generateRowNumbers = (rows: any[]) =>
|
||||
rows.map((_: any, index: number) => ({ ..._, number: index + 1 }));
|
||||
|
||||
export function ChartSongsBlock() {
|
||||
const [songs, setSongs] = useState<ISong[]>([]);
|
||||
const [numberedSongs, setNumberedSongs] = useState<ISong[]>([]);
|
||||
|
||||
const fetchData = async () => {
|
||||
const response = await getSongs();
|
||||
setSongs(response.data);
|
||||
setNumberedSongs(generateRowNumbers(response.data));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="song-block flex border-slate-100">
|
||||
<Table
|
||||
title={() => <Title level={4}>Чарт</Title>}
|
||||
style={{ width: '100%', backgroundColor: 'transparent' }}
|
||||
className="songs-table menu-block"
|
||||
dataSource={numberedSongs}
|
||||
columns={getColumnsWithNumber(numberedSongs)}
|
||||
showHeader={false}
|
||||
pagination={false}
|
||||
rowClassName={() => 'song-table-row'}
|
||||
rowKey={(record) => record.id}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,14 +1,15 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import {ISong} from '../../models/IModels';
|
||||
import { Track } from '../songComponents/Track';
|
||||
import axios from 'axios';
|
||||
import { Table, Button, Empty } from 'antd';
|
||||
import { PlayCircleFilled, PlayCircleOutlined } from '@ant-design/icons';
|
||||
import { getSongs } from '../../API/api';
|
||||
import Title from 'antd/es/typography/Title';
|
||||
import { GetColumns } from './Templates/songsTemplate';
|
||||
|
||||
|
||||
export function SongsBlock() {
|
||||
export function NewSongsBlock() {
|
||||
|
||||
const [songs, setSongs] = useState<ISong[]>([]);
|
||||
|
||||
@ -20,61 +21,21 @@ export function SongsBlock() {
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'play',
|
||||
key: 'play',
|
||||
width: 100,
|
||||
|
||||
render: (text: string, song: ISong) => (
|
||||
<Button data-content="▷" className='play-song-button rounded' style={{background: 'transparent', display: 'contents'}}>
|
||||
<img
|
||||
className="rounded "
|
||||
src={song.cover}
|
||||
alt={song.song_name}
|
||||
/>
|
||||
</Button>
|
||||
|
||||
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'song_name',
|
||||
key: 'song_name',
|
||||
width: 400
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'band_name',
|
||||
key: 'band_name',
|
||||
width: 400
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'album_name',
|
||||
key: 'album_name',
|
||||
width: 400
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
|
||||
return (
|
||||
<div className="song-block flex border-slate-100">
|
||||
|
||||
<Table
|
||||
title={() => <Title level={4}>Горячие новинки</Title>}
|
||||
style={{width: '100%', backgroundColor: 'transparent'}}
|
||||
className="songs-table menu-block"
|
||||
dataSource={songs.map((s: ISong) => ({...s, play: ''}))}
|
||||
columns={columns}
|
||||
columns={GetColumns(songs)}
|
||||
showHeader={false}
|
||||
pagination={false}
|
||||
rowClassName={() => 'song-table-row'}
|
||||
rowKey={(s: ISong) => s.id}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
};
|
@ -0,0 +1,56 @@
|
||||
import { Button } from "antd";
|
||||
import { ISong } from "../../../models/IModels";
|
||||
import PlayCircleFilled from "@ant-design/icons/lib/icons/PlayCircleFilled";
|
||||
|
||||
export function getColumnsWithNumber(songs: ISong[]) {
|
||||
|
||||
return [
|
||||
{
|
||||
title: '#',
|
||||
dataIndex: 'number',
|
||||
key: 'number',
|
||||
width: 50,
|
||||
render: (value: any, record: ISong, index: number) => {
|
||||
return record.number === 1 ? <span style={{ fontSize: '18px', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>👑</span> :
|
||||
<span style={{ fontSize: '18px', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>{record.number}</span>;
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Play',
|
||||
dataIndex: 'play',
|
||||
key: 'play',
|
||||
width: 100,
|
||||
|
||||
render: (text: string, song: ISong) => (
|
||||
<Button data-content="▷" className='play-song-button rounded' style={{background: 'transparent', display: 'contents'}}>
|
||||
<img
|
||||
className="rounded "
|
||||
src={song.cover}
|
||||
alt={song.song_name}
|
||||
/>
|
||||
</Button>
|
||||
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'song_name',
|
||||
key: 'song_name',
|
||||
width: 350
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'band_name',
|
||||
key: 'band_name',
|
||||
width: 400
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'album_name',
|
||||
key: 'album_name',
|
||||
width: 400
|
||||
}
|
||||
|
||||
]
|
||||
}
|
59
src/components/menuComponents/Templates/songsTemplate.tsx
Normal file
59
src/components/menuComponents/Templates/songsTemplate.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import { Button } from "antd";
|
||||
import { ISong } from "../../../models/IModels";
|
||||
import { useState } from "react";
|
||||
import { PauseCircleFilled, PlayCircleFilled } from "@ant-design/icons";
|
||||
|
||||
const useColumns = (songs: ISong[]) => {
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
|
||||
const handlePlayClick = () => {
|
||||
setIsPlaying(!isPlaying);
|
||||
};
|
||||
|
||||
return [
|
||||
{
|
||||
title: 'Play',
|
||||
dataIndex: 'play',
|
||||
key: 'play',
|
||||
width: 100,
|
||||
|
||||
render: (text: string, song: ISong) => (
|
||||
// Тут в дата-контент вставляется JSON коды иконок
|
||||
<Button data-content={isPlaying ? "\u23EF\uFE0F" : "▷"} className='play-song-button rounded' style={{background: 'transparent', display: 'contents'}} onClick={handlePlayClick}>
|
||||
|
||||
<img
|
||||
className="rounded "
|
||||
src={song.cover}
|
||||
alt={song.song_name}
|
||||
/>
|
||||
</Button>
|
||||
|
||||
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'song_name',
|
||||
key: 'song_name',
|
||||
width: 400
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'band_name',
|
||||
key: 'band_name',
|
||||
width: 400
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'album_name',
|
||||
key: 'album_name',
|
||||
width: 400
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
export function GetColumns(songs: ISong[]) {
|
||||
return useColumns(songs);
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import { BackwardFilled, FastForwardFilled, FastBackwardFilled, PlayCircleFilled
|
||||
import { ISong, SongProps } from '../../models/IModels';
|
||||
import styled from 'styled-components'
|
||||
import useSound from 'use-sound';
|
||||
import { getSongs } from '../../API/api';
|
||||
|
||||
const Song = styled.div`
|
||||
align-items: center;
|
||||
@ -14,33 +13,19 @@ const Song = styled.div`
|
||||
|
||||
type CurrentSongProps = {
|
||||
song: ISong
|
||||
isPlayingVariable: boolean
|
||||
}
|
||||
|
||||
export function CurrentTrack({song, isPlayingVariable}: CurrentSongProps) {
|
||||
export function CurrentTrack({ song }: CurrentSongProps) {
|
||||
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
|
||||
const soundUrl = song?.source || ''; // Пустая строка в случае отсутствия source
|
||||
|
||||
|
||||
song = {
|
||||
"id": "5",
|
||||
"song_name": "Кем я стал",
|
||||
"band_id": "3",
|
||||
"band_name": "DSPD",
|
||||
"albumid": "3",
|
||||
"album_name": "Album 3",
|
||||
"source": "../../songs/DSPD feat. даня хренников - Кем я стал_(audio-lord.ru).mp3",
|
||||
"cover": "https://avatars.yandex.net/get-music-content/6058982/7e431a83.a.23910092-1/m1000x1000?webp=false",
|
||||
"playlists": [
|
||||
"3",
|
||||
],
|
||||
genreid: "1",
|
||||
genre_name: "Rock",
|
||||
|
||||
};
|
||||
|
||||
const [isPlaying, setIsPlaying] = useState(isPlayingVariable);
|
||||
const [play, { pause, duration, sound }] = useSound(song.source, {volume: 0.5});
|
||||
|
||||
|
||||
const [play, { pause, duration, sound }] = useSound(soundUrl, { volume: 0.5 });
|
||||
|
||||
|
||||
const playingButton = () => {
|
||||
if (isPlaying) {
|
||||
pause();
|
||||
@ -50,38 +35,39 @@ export function CurrentTrack({song, isPlayingVariable}: CurrentSongProps) {
|
||||
setIsPlaying(true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (song) {
|
||||
play();
|
||||
setIsPlaying(true);
|
||||
}
|
||||
}, [song]);
|
||||
|
||||
return (
|
||||
<Song >
|
||||
<div className='current-track'>
|
||||
<Row className='w-full h-full bg-white opacity-90 rounded' style={{display: 'flex', alignItems: 'center'}}>
|
||||
<Col span={4} className='flex flex-direction-row justify-center'>
|
||||
<Button type='link' icon={<FastBackwardFilled className='player-button' />}></Button>
|
||||
<Button type="link" icon={isPlaying ? <PauseCircleOutlined className='player-button' onClick={playingButton}/> : <PlayCircleOutlined className='player-button' onClick={playingButton}/>}></Button>
|
||||
<Button type="link" icon={<FastForwardFilled className='player-button' style={{fontSize: 30}} />}></Button>
|
||||
<Song>
|
||||
<div className="current-track">
|
||||
<Row className="w-full h-full bg-white opacity-90 rounded" style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Col span={4} className="flex flex-direction-row justify-center">
|
||||
<Button type="link" icon={<FastBackwardFilled className="player-button" />}></Button>
|
||||
<Button
|
||||
type="link"
|
||||
icon={isPlaying ? <PauseCircleOutlined className="player-button" onClick={playingButton} /> : <PlayCircleOutlined className="player-button" onClick={playingButton} />}
|
||||
></Button>
|
||||
<Button type="link" icon={<FastForwardFilled className="player-button" style={{ fontSize: 30 }} />}></Button>
|
||||
</Col>
|
||||
<Col style={{width: 80}}>
|
||||
<img src={song.cover} alt={song.cover} className='current-song-cover' />
|
||||
|
||||
<Col style={{ width: 80 }}>
|
||||
<img src={song.cover} alt={song.cover} className="current-song-cover" />
|
||||
</Col>
|
||||
<Col span={16}>
|
||||
<Row className='' style={{paddingLeft: 10}}>
|
||||
{song.song_name}
|
||||
</Row>
|
||||
<Row className='' style={{paddingLeft: 10}}>
|
||||
{song.band_name}
|
||||
</Row>
|
||||
<Row style={{ paddingLeft: 10 }}>{song.song_name}</Row>
|
||||
<Row style={{ paddingLeft: 10 }}>{song.band_name}</Row>
|
||||
</Col>
|
||||
<Col>
|
||||
<Button type='link' icon={<HeartOutlined className='current-track-button' />}></Button>
|
||||
<Button type='link' icon={<ShareAltOutlined className='current-track-button' />}></Button>
|
||||
<Button type="link" icon={<HeartOutlined className="current-track-button" />}></Button>
|
||||
<Button type="link" icon={<ShareAltOutlined className="current-track-button" />}></Button>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
</div>
|
||||
|
||||
</Song>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
import { Grid, Col, Row, Button } from 'antd';
|
||||
import { PlayCircleOutlined } from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
import { ISong, SongProps } from '../../models/IModels';
|
||||
|
||||
export function Track({ song }: SongProps) {
|
||||
return (
|
||||
<span className="flex items-center justify-between p-4 px-6 py-2 border-b border-gray-300 ">
|
||||
<Row>
|
||||
<Col span={4}>
|
||||
<Button type="link"><PlayCircleOutlined /></Button>
|
||||
</Col>
|
||||
<Col span={4} className="flex items-center justify-between">
|
||||
<img src={song.cover} alt={song.song_name} className='list-image-none' />
|
||||
</Col>
|
||||
<Col span={8} className="flex items-center justify-between">
|
||||
<p className="text-md">{song.song_name}</p>
|
||||
</Col>
|
||||
<Col span={8} className="flex items-center justify-between">
|
||||
<p className="text-md">{song.band_name}</p>
|
||||
</Col>
|
||||
</Row>
|
||||
</span>
|
||||
)
|
||||
}
|
@ -22,6 +22,7 @@ export interface IGenre {
|
||||
}
|
||||
|
||||
export interface ISong {
|
||||
number: number;
|
||||
id: string
|
||||
song_name: string;
|
||||
band_id: string;
|
||||
|
@ -6,11 +6,10 @@ import { CurrentTrack } from "../components/songComponents/CurrentTrack";
|
||||
import { IPlaylist, ISong, IAlbum, IGenre, IAdvertisement, IBand } from "../models/IModels";
|
||||
|
||||
|
||||
export function Homepage() {
|
||||
export function Homepage({song_id = "0"}) {
|
||||
const [currentSong, setCurrentSong] = useState<ISong | null>(null);
|
||||
|
||||
const [albums, setAlbums] = useState<IAlbum[]>([]);
|
||||
|
||||
const [bands, setBands] = useState<IBand[]>([]);
|
||||
|
||||
const [songs, setSongs] = useState<ISong[]>([]);
|
||||
const [ads, setAds] = useState<IAdvertisement[]>([]);
|
||||
|
||||
@ -39,7 +38,7 @@ export function Homepage() {
|
||||
return (
|
||||
<>
|
||||
<MenuBlock playlists={[]} songs={songs} albums={albums} genres={[]}/><AdBlock ads={ads}/>
|
||||
<CurrentTrack song={songs[0]} isPlayingVariable={false} />
|
||||
</>
|
||||
{currentSong && <CurrentTrack song={currentSong} />}
|
||||
</>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user