This commit is contained in:
devil_1nc 2024-09-20 09:56:32 +04:00
parent 9442dd84a2
commit 19a608b934
18 changed files with 181 additions and 30 deletions

42
package-lock.json generated
View File

@ -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",

View File

@ -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",

View File

@ -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&amp;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>

View File

@ -154,3 +154,8 @@
padding-left: 10px; padding-left: 10px;
padding-right: 10px; padding-right: 10px;
} }
.menu-block {
font-weight: 400;
font-size: 42px;
}

View File

@ -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 />} />
</div> <Route path='profile' element={<Profilepage />} />
</Route>
<Footer /> </Routes>
</div> </div>
</div> </div>
); );
} }

View File

@ -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>

View File

@ -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>
); );

View File

@ -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>
); );
} }

View 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 /></>
);
}

View File

@ -33,11 +33,11 @@ export function MenuBlock({playlists, songs, albums, genres}: MenuBlockProps) {
const tabs = [chartTab, playlistsTab, newSongsTab]; const tabs = [chartTab, playlistsTab, newSongsTab];
return ( 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 <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%'}}

View File

@ -19,7 +19,7 @@ export function SongsBlock({songs}: {songs: ISong[]}) {
render: (text: string, song: ISong) => ( render: (text: string, song: ISong) => (
<Button data-content="▷" className='play-song-button rounded' style={{background: 'transparent', display: 'contents'}}> <Button data-content="▷" className='play-song-button rounded' style={{background: 'transparent', display: 'contents'}}>
<img <img
className="rounded" className="rounded "
src={song.cover} src={song.cover}
alt={song.song_name} alt={song.song_name}
/> />
@ -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}

View File

@ -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 {

View File

@ -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>
<App /> <BrowserRouter>
<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
View 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
View 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>
);
}

View 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>
);
}

View 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>
);
}