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-dom": "^18.3.1",
|
||||
"react-dotenv": "^0.1.3",
|
||||
"react-router-dom": "^6.26.2",
|
||||
"react-scripts": "5.0.1",
|
||||
"styled-components": "^6.1.12",
|
||||
"swiper": "^11.1.10",
|
||||
@ -5397,6 +5398,15 @@
|
||||
"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": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
||||
@ -24953,6 +24963,38 @@
|
||||
"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": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
||||
|
@ -21,6 +21,7 @@
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-dotenv": "^0.1.3",
|
||||
"react-router-dom": "^6.26.2",
|
||||
"react-scripts": "5.0.1",
|
||||
"styled-components": "^6.1.12",
|
||||
"swiper": "^11.1.10",
|
||||
@ -44,7 +45,6 @@
|
||||
"plugin:storybook/recommended"
|
||||
]
|
||||
},
|
||||
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
@ -57,11 +57,11 @@
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
|
||||
"react-dotenv": {
|
||||
"whitelist": ["API_URL"]
|
||||
"whitelist": [
|
||||
"API_URL"
|
||||
]
|
||||
},
|
||||
|
||||
"devDependencies": {
|
||||
"@chromatic-com/storybook": "^1.8.0",
|
||||
"@storybook/addon-essentials": "^8.2.9",
|
||||
|
@ -13,6 +13,14 @@
|
||||
|
||||
<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>
|
||||
<script id="react-dotenv" src="./env.js"></script>
|
||||
</head>
|
||||
|
@ -153,4 +153,9 @@
|
||||
font-size: 24px !important;
|
||||
padding-left: 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 { 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/mainComponents/Header';
|
||||
import {Header} from './components/layoutComponents/Header';
|
||||
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 {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/mainComponents/MenuBlock';
|
||||
import { MenuBlock } from './components/layoutComponents/MenuBlock';
|
||||
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() {
|
||||
const [songs, setSongs] = React.useState<ISong[]>([]);
|
||||
@ -54,17 +61,20 @@ function App() {
|
||||
|
||||
<div className="App bg-slate-100">
|
||||
<div id="app" className='bg-white'>
|
||||
<Header />
|
||||
<div id='main-content'>
|
||||
<MenuBlock playlists={playlists} songs={songs} albums={albums} genres={genres}/>
|
||||
<AdBlock ads={ads} />
|
||||
<CurrentTrack />
|
||||
</div>
|
||||
<Routes>
|
||||
<Route path='/' element={<Layout />}>
|
||||
<Route index element={<Homepage playlists={playlists} songs={songs} genres={genres} albums={albums} ads={ads} />} />
|
||||
<Route path='login' element={<Loginpage />} />
|
||||
<Route path='register' element={<Registerpage />} />
|
||||
<Route path='profile' element={<Profilepage />} />
|
||||
</Route>
|
||||
|
||||
<Footer />
|
||||
</Routes>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { IAdvertisement } from "../../models/IModels";
|
||||
|
||||
export function AdCard({ad}: {ad: IAdvertisement}) {
|
||||
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>
|
||||
</div>
|
||||
|
@ -4,8 +4,7 @@ import { AdCard } from "../cardComponents/AdCard";
|
||||
export function AdBlock({ads}: {ads: any[]}) {
|
||||
return (
|
||||
<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} />)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,14 +1,15 @@
|
||||
import React from 'react';
|
||||
import { Button } from 'antd';
|
||||
import { UserOutlined } from '@ant-design/icons';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export function Header() {
|
||||
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">
|
||||
<h1 className="text-3xl font-bold">😈 DEVIL music</h1>
|
||||
<Button href="/login" style={{ width: 30, height: 30 }}>
|
||||
<Link to='/' className="text-3xl" style={{ fontFamily: 'Permanent Marker' }}>😈 DEVIL music</Link>
|
||||
<Link to="/login" style={{ width: 30, height: 30 }}>
|
||||
<UserOutlined />
|
||||
</Button>
|
||||
</Link>
|
||||
</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 /></>
|
||||
);
|
||||
}
|
@ -33,11 +33,11 @@ export function MenuBlock({playlists, songs, albums, genres}: MenuBlockProps) {
|
||||
const tabs = [chartTab, playlistsTab, newSongsTab];
|
||||
|
||||
return (
|
||||
<div className="flex " style={{display: 'flex', alignSelf: 'flex-start', width: 'fit-content'}}>
|
||||
<div className="flex" style={{display: 'flex', alignSelf: 'flex-start', width: 'fit-content'}}>
|
||||
<Tabs
|
||||
|
||||
type="line"
|
||||
className='container flex justify-start '
|
||||
className='container flex justify-start menu-block'
|
||||
defaultActiveKey="Chart"
|
||||
items={tabs}
|
||||
style={{padding: '1%'}}
|
@ -19,7 +19,7 @@ export function SongsBlock({songs}: {songs: ISong[]}) {
|
||||
render: (text: string, song: ISong) => (
|
||||
<Button data-content="▷" className='play-song-button rounded' style={{background: 'transparent', display: 'contents'}}>
|
||||
<img
|
||||
className="rounded"
|
||||
className="rounded "
|
||||
src={song.cover}
|
||||
alt={song.song_name}
|
||||
/>
|
||||
@ -54,7 +54,7 @@ export function SongsBlock({songs}: {songs: ISong[]}) {
|
||||
|
||||
<Table
|
||||
style={{width: '100%' }}
|
||||
className="songs-table"
|
||||
className="songs-table menu-block"
|
||||
dataSource={songs.map((s: ISong) => ({...s, play: ''}))}
|
||||
columns={columns}
|
||||
showHeader={false}
|
||||
|
@ -9,6 +9,10 @@ body {
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-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 {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
@ -9,11 +10,11 @@ const root = ReactDOM.createRoot(
|
||||
);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
|
||||
</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