2
This commit is contained in:
parent
9442dd84a2
commit
19a608b934
42
package-lock.json
generated
42
package-lock.json
generated
@ -26,6 +26,7 @@
|
|||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-dotenv": "^0.1.3",
|
"react-dotenv": "^0.1.3",
|
||||||
|
"react-router-dom": "^6.26.2",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"styled-components": "^6.1.12",
|
"styled-components": "^6.1.12",
|
||||||
"swiper": "^11.1.10",
|
"swiper": "^11.1.10",
|
||||||
@ -5397,6 +5398,15 @@
|
|||||||
"react-dom": ">=16.9.0"
|
"react-dom": ">=16.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@remix-run/router": {
|
||||||
|
"version": "1.19.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz",
|
||||||
|
"integrity": "sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rollup/plugin-babel": {
|
"node_modules/@rollup/plugin-babel": {
|
||||||
"version": "5.3.1",
|
"version": "5.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
||||||
@ -24953,6 +24963,38 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-router": {
|
||||||
|
"version": "6.26.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.2.tgz",
|
||||||
|
"integrity": "sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@remix-run/router": "1.19.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-router-dom": {
|
||||||
|
"version": "6.26.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.2.tgz",
|
||||||
|
"integrity": "sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@remix-run/router": "1.19.2",
|
||||||
|
"react-router": "6.26.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8",
|
||||||
|
"react-dom": ">=16.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-scripts": {
|
"node_modules/react-scripts": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-dotenv": "^0.1.3",
|
"react-dotenv": "^0.1.3",
|
||||||
|
"react-router-dom": "^6.26.2",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"styled-components": "^6.1.12",
|
"styled-components": "^6.1.12",
|
||||||
"swiper": "^11.1.10",
|
"swiper": "^11.1.10",
|
||||||
@ -44,7 +45,6 @@
|
|||||||
"plugin:storybook/recommended"
|
"plugin:storybook/recommended"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
">0.2%",
|
">0.2%",
|
||||||
@ -57,11 +57,11 @@
|
|||||||
"last 1 safari version"
|
"last 1 safari version"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
"react-dotenv": {
|
"react-dotenv": {
|
||||||
"whitelist": ["API_URL"]
|
"whitelist": [
|
||||||
|
"API_URL"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@chromatic-com/storybook": "^1.8.0",
|
"@chromatic-com/storybook": "^1.8.0",
|
||||||
"@storybook/addon-essentials": "^8.2.9",
|
"@storybook/addon-essentials": "^8.2.9",
|
||||||
|
@ -13,6 +13,14 @@
|
|||||||
|
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="" />
|
||||||
|
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Permanent+Marker&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
|
||||||
<title>React App</title>
|
<title>React App</title>
|
||||||
<script id="react-dotenv" src="./env.js"></script>
|
<script id="react-dotenv" src="./env.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
@ -154,3 +154,8 @@
|
|||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu-block {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 42px;
|
||||||
|
}
|
32
src/App.tsx
32
src/App.tsx
@ -1,20 +1,27 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
import { Routes, Route} from 'react-router-dom';
|
||||||
|
|
||||||
import logo from './logo.svg';
|
import logo from './logo.svg';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
import { Button } from 'antd';
|
import { Button } from 'antd';
|
||||||
import {Track} from './components/songComponents/Track';
|
import {Track} from './components/songComponents/Track';
|
||||||
import {Header} from './components/mainComponents/Header';
|
import {Header} from './components/layoutComponents/Header';
|
||||||
import {Playlist} from './components/cardComponents//Playlist';
|
import {Playlist} from './components/cardComponents//Playlist';
|
||||||
import {Footer} from './components/mainComponents/Footer';
|
import {Footer} from './components/layoutComponents/Footer';
|
||||||
import {CurrentTrack} from './components/songComponents/CurrentTrack';
|
import {CurrentTrack} from './components/songComponents/CurrentTrack';
|
||||||
import {SongsBlock} from './components/menuComponents/SongsBlock';
|
import {SongsBlock} from './components/menuComponents/SongsBlock';
|
||||||
import { ISong, IAlbum, IGenre, IBand, IPlaylist, IAdvertisement } from './models/IModels';
|
import { ISong, IAlbum, IGenre, IBand, IPlaylist, IAdvertisement } from './models/IModels';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { PlaylistsBlock } from './components/menuComponents/PlaylistsBlock';
|
import { PlaylistsBlock } from './components/menuComponents/PlaylistsBlock';
|
||||||
import { MenuBlock } from './components/mainComponents/MenuBlock';
|
import { MenuBlock } from './components/layoutComponents/MenuBlock';
|
||||||
import { getAds, getGenres, getPlaylists, getSongs } from './API/api';
|
import { getAds, getGenres, getPlaylists, getSongs } from './API/api';
|
||||||
import { AdBlock } from './components/mainComponents/AdBlock';
|
import { AdBlock } from './components/layoutComponents/AdBlock';
|
||||||
|
|
||||||
|
import { Homepage } from './pages/Homepage';
|
||||||
|
import { Loginpage } from './pages/Loginpage';
|
||||||
|
import { Registerpage } from './pages/Registerpage';
|
||||||
|
import { Profilepage } from './pages/Profilepage';
|
||||||
|
import { Layout } from './components/layoutComponents/Layout';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [songs, setSongs] = React.useState<ISong[]>([]);
|
const [songs, setSongs] = React.useState<ISong[]>([]);
|
||||||
@ -54,17 +61,20 @@ function App() {
|
|||||||
|
|
||||||
<div className="App bg-slate-100">
|
<div className="App bg-slate-100">
|
||||||
<div id="app" className='bg-white'>
|
<div id="app" className='bg-white'>
|
||||||
<Header />
|
<Routes>
|
||||||
<div id='main-content'>
|
<Route path='/' element={<Layout />}>
|
||||||
<MenuBlock playlists={playlists} songs={songs} albums={albums} genres={genres}/>
|
<Route index element={<Homepage playlists={playlists} songs={songs} genres={genres} albums={albums} ads={ads} />} />
|
||||||
<AdBlock ads={ads} />
|
<Route path='login' element={<Loginpage />} />
|
||||||
<CurrentTrack />
|
<Route path='register' element={<Registerpage />} />
|
||||||
|
<Route path='profile' element={<Profilepage />} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Footer />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { IAdvertisement } from "../../models/IModels";
|
|||||||
|
|
||||||
export function AdCard({ad}: {ad: IAdvertisement}) {
|
export function AdCard({ad}: {ad: IAdvertisement}) {
|
||||||
return (
|
return (
|
||||||
<div className="container mx-auto" style={{}}>
|
<div className="container mx-auto" style={{padding: 10}}>
|
||||||
<img src={ad.photo} alt={ad.name} className="h-full w-auto rounded m-auto">
|
<img src={ad.photo} alt={ad.name} className="h-full w-auto rounded m-auto">
|
||||||
</img>
|
</img>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,6 @@ import { AdCard } from "../cardComponents/AdCard";
|
|||||||
export function AdBlock({ads}: {ads: any[]}) {
|
export function AdBlock({ads}: {ads: any[]}) {
|
||||||
return (
|
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: '30%'}}>
|
||||||
<p>Реклама</p>
|
|
||||||
{ads.map(ad => <AdCard key={ad.id} ad={ad} />)}
|
{ads.map(ad => <AdCard key={ad.id} ad={ad} />)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
@ -1,14 +1,15 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Button } from 'antd';
|
import { Button } from 'antd';
|
||||||
import { UserOutlined } from '@ant-design/icons';
|
import { UserOutlined } from '@ant-design/icons';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
export function Header() {
|
export function Header() {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-between p-4 border-b bg-gradient-to-bl from-red-900 to-red-600 border-solid border-2 border-slate-100">
|
<div className="flex items-center justify-between p-4 border-b bg-gradient-to-bl from-red-900 to-red-600 border-solid border-2 border-slate-100">
|
||||||
<h1 className="text-3xl font-bold">😈 DEVIL music</h1>
|
<Link to='/' className="text-3xl" style={{ fontFamily: 'Permanent Marker' }}>😈 DEVIL music</Link>
|
||||||
<Button href="/login" style={{ width: 30, height: 30 }}>
|
<Link to="/login" style={{ width: 30, height: 30 }}>
|
||||||
<UserOutlined />
|
<UserOutlined />
|
||||||
</Button>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
20
src/components/layoutComponents/Layout.tsx
Normal file
20
src/components/layoutComponents/Layout.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Button } from 'antd';
|
||||||
|
import { UserOutlined } from '@ant-design/icons';
|
||||||
|
import { Link, Outlet } from 'react-router-dom';
|
||||||
|
import { IPlaylist, ISong, IAlbum, IGenre, IAdvertisement } from '../../models/IModels';
|
||||||
|
import { CurrentTrack } from '../songComponents/CurrentTrack';
|
||||||
|
import { AdBlock } from './AdBlock';
|
||||||
|
import { Footer } from './Footer';
|
||||||
|
import { Header } from './Header';
|
||||||
|
import { MenuBlock } from './MenuBlock';
|
||||||
|
|
||||||
|
export function Layout() {
|
||||||
|
return (
|
||||||
|
<><Header />
|
||||||
|
<div id='main-content'>
|
||||||
|
<Outlet />
|
||||||
|
</div>
|
||||||
|
<Footer /></>
|
||||||
|
);
|
||||||
|
}
|
@ -37,7 +37,7 @@ export function MenuBlock({playlists, songs, albums, genres}: MenuBlockProps) {
|
|||||||
<Tabs
|
<Tabs
|
||||||
|
|
||||||
type="line"
|
type="line"
|
||||||
className='container flex justify-start '
|
className='container flex justify-start menu-block'
|
||||||
defaultActiveKey="Chart"
|
defaultActiveKey="Chart"
|
||||||
items={tabs}
|
items={tabs}
|
||||||
style={{padding: '1%'}}
|
style={{padding: '1%'}}
|
@ -54,7 +54,7 @@ export function SongsBlock({songs}: {songs: ISong[]}) {
|
|||||||
|
|
||||||
<Table
|
<Table
|
||||||
style={{width: '100%' }}
|
style={{width: '100%' }}
|
||||||
className="songs-table"
|
className="songs-table menu-block"
|
||||||
dataSource={songs.map((s: ISong) => ({...s, play: ''}))}
|
dataSource={songs.map((s: ISong) => ({...s, play: ''}))}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
showHeader={false}
|
showHeader={false}
|
||||||
|
@ -9,6 +9,10 @@ body {
|
|||||||
sans-serif;
|
sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
|
background-image: url('https://www.fonstola.ru/images/201301/fonstola.ru_86743.jpg');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import reportWebVitals from './reportWebVitals';
|
import reportWebVitals from './reportWebVitals';
|
||||||
@ -9,11 +10,11 @@ const root = ReactDOM.createRoot(
|
|||||||
);
|
);
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
|
<BrowserRouter>
|
||||||
<App />
|
<App />
|
||||||
|
</BrowserRouter>
|
||||||
|
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
|
||||||
// If you want to start measuring performance in your app, pass a function
|
|
||||||
// to log results (for example: reportWebVitals(console.log))
|
|
||||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
|
||||||
reportWebVitals();
|
reportWebVitals();
|
10
src/pages/Homepage.tsx
Normal file
10
src/pages/Homepage.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { AdBlock } from "../components/layoutComponents/AdBlock";
|
||||||
|
import { MenuBlock } from "../components/layoutComponents/MenuBlock";
|
||||||
|
import { CurrentTrack } from "../components/songComponents/CurrentTrack";
|
||||||
|
import { IPlaylist, ISong, IAlbum, IGenre, IAdvertisement } from "../models/IModels";
|
||||||
|
|
||||||
|
export function Homepage({playlists, songs, genres, albums, ads}: {playlists: IPlaylist[], songs: ISong[], genres: IGenre[], albums: IAlbum[], ads: IAdvertisement[]}) {
|
||||||
|
return (
|
||||||
|
<><MenuBlock playlists={playlists} songs={songs} albums={albums} genres={genres} /><AdBlock ads={ads} /><CurrentTrack /></>
|
||||||
|
);
|
||||||
|
}
|
37
src/pages/Loginpage.tsx
Normal file
37
src/pages/Loginpage.tsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { Form } from 'antd'
|
||||||
|
|
||||||
|
export function Loginpage() {
|
||||||
|
return (
|
||||||
|
<div className="container mx-auto" style={{height: 'auto', width: '100%', display: 'flex', justifyContent: 'center', backgroundImage: "url('https://www.google.com/url?sa=i&url=https%3A%2F%2Fwallpapers.99px.ru%2Fwallpapers%2F32630%2F&psig=AOvVaw1t52LawgmuRVrJhHsKhhe8&ust=1726831156597000&source=images&cd=vfe&opi=89978449&ved=0CBQQjRxqFwoTCNC43L7xzogDFQAAAAAdAAAAABAE')"}}>
|
||||||
|
<div className='sb-login rounded bg-black'>
|
||||||
|
|
||||||
|
<Form>
|
||||||
|
<p>Вход</p>
|
||||||
|
<Form.Item style={{margin: '140px'}}>
|
||||||
|
<Form.Item
|
||||||
|
name="username"
|
||||||
|
rules={[{ required: true, message: 'Please input your username!' }]}
|
||||||
|
style={{padding: '20px'}}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Username"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="password"
|
||||||
|
rules={[{ required: true, message: 'Please input your password!' }]}
|
||||||
|
style={{padding: '20px'}}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
placeholder="Password"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
7
src/pages/Profilepage.tsx
Normal file
7
src/pages/Profilepage.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export function Profilepage() {
|
||||||
|
return (
|
||||||
|
<div className="container mx-auto bg-slate-300" style={{height: 300, width: '75%'}}>
|
||||||
|
<p>Страница профиля</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
7
src/pages/Registerpage.tsx
Normal file
7
src/pages/Registerpage.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export function Registerpage() {
|
||||||
|
return (
|
||||||
|
<div className="container mx-auto bg-slate-300" style={{height: 300, width: '75%'}}>
|
||||||
|
<p>Регистрация</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user