add messeges, add posts in profile
This commit is contained in:
@@ -7,6 +7,7 @@ import Footer from './components/Footer';
|
||||
import Register from './components/Register';
|
||||
import Login from './components/Login';
|
||||
import Profile from './components/Profile';
|
||||
import Messages from './components/Messages';
|
||||
import styles from './App.module.css';
|
||||
|
||||
const App = () => {
|
||||
@@ -29,6 +30,7 @@ const App = () => {
|
||||
<Route path="/register" element={<Register />} />
|
||||
<Route path="/login" element={!isAuthenticated ? <Login onLogin={handleLogin} /> : <Navigate to="/profile" />} />
|
||||
<Route path="/profile" element={isAuthenticated ? <Profile /> : <Navigate to="/login" />} />
|
||||
<Route path="/messages" element={isAuthenticated ? <Messages /> : <Navigate to="/login" />} />
|
||||
<Route path="/" element={<Home />} /> {/* Главная страница */}
|
||||
</Routes>
|
||||
</main>
|
||||
|
||||
@@ -15,7 +15,10 @@ const Header = ({ isAuthenticated, onLogout }) => {
|
||||
</div>
|
||||
{!isAuthenticated && <Link to="/register" className={styles.registerLink}>Зарегистрироваться</Link>}
|
||||
{isAuthenticated && (
|
||||
<>
|
||||
<Link to="/messages" className={styles.messagesLink}>Перейти к сообщениям</Link>
|
||||
<button className={styles.logoutButton} onClick={onLogout}>Выйти</button>
|
||||
</>
|
||||
)}
|
||||
</header>
|
||||
);
|
||||
|
||||
@@ -30,6 +30,16 @@
|
||||
text-decoration: underline; /* Подчеркивание при наведении */
|
||||
}
|
||||
|
||||
.messagesLink {
|
||||
color: #ff4500; /* Оранжевый цвет ссылки */
|
||||
text-decoration: none;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.messagesLink:hover {
|
||||
text-decoration: underline; /* Подчеркивание при наведении */
|
||||
}
|
||||
|
||||
.logoutButton {
|
||||
background-color: #ff4500; /* Оранжевая кнопка */
|
||||
color: #ffffff;
|
||||
|
||||
15
src/components/Messages.js
Normal file
15
src/components/Messages.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// src/components/Messages.js
|
||||
|
||||
import React from 'react';
|
||||
import styles from './Messages.module.css';
|
||||
|
||||
const Messages = () => {
|
||||
return (
|
||||
<div className={styles.messagesContainer}>
|
||||
<h2>Сообщения</h2>
|
||||
<p>Здесь будут ваши сообщения.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Messages;
|
||||
20
src/components/Messages.module.css
Normal file
20
src/components/Messages.module.css
Normal file
@@ -0,0 +1,20 @@
|
||||
/* src/components/Messages.module.css */
|
||||
|
||||
.messagesContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #1a1a1a; /* Темный фон */
|
||||
color: #ffffff; /* Белый текст */
|
||||
padding: 16px; /* Добавляем отступы */
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.messagesContainer h2 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.messagesContainer p {
|
||||
font-size: 18px;
|
||||
}
|
||||
@@ -1,13 +1,128 @@
|
||||
// src/components/Profile.js
|
||||
|
||||
import React from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import styles from './Profile.module.css';
|
||||
|
||||
const Profile = () => {
|
||||
const [profilePicture, setProfilePicture] = useState(null);
|
||||
const [posts, setPosts] = useState([]);
|
||||
const [newPostText, setNewPostText] = useState('');
|
||||
const [newPostMusic, setNewPostMusic] = useState(null);
|
||||
const [newPostImage, setNewPostImage] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Загружаем посты из localStorage при монтировании компонента
|
||||
const savedPosts = JSON.parse(localStorage.getItem('posts')) || [];
|
||||
setPosts(savedPosts);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// Сохраняем посты в localStorage при изменении
|
||||
localStorage.setItem('posts', JSON.stringify(posts));
|
||||
}, [posts]);
|
||||
|
||||
const handleProfilePictureChange = (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => {
|
||||
setProfilePicture(reader.result);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNewPostMusicChange = (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => {
|
||||
setNewPostMusic(reader.result);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNewPostImageChange = (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => {
|
||||
setNewPostImage(reader.result);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
const addPost = () => {
|
||||
if (!newPostText || !newPostMusic) {
|
||||
alert('Пожалуйста, заполните текст и добавьте музыку.');
|
||||
return;
|
||||
}
|
||||
|
||||
const newPost = {
|
||||
id: posts.length + 1,
|
||||
musicUrl: newPostMusic,
|
||||
text: newPostText,
|
||||
image: newPostImage
|
||||
};
|
||||
|
||||
setPosts([...posts, newPost]);
|
||||
setNewPostText('');
|
||||
setNewPostMusic(null);
|
||||
setNewPostImage(null);
|
||||
};
|
||||
|
||||
const deletePost = (id) => {
|
||||
const updatedPosts = posts.filter(post => post.id !== id);
|
||||
setPosts(updatedPosts);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.profileContainer}>
|
||||
<h2>Профиль</h2>
|
||||
<p>Добро пожаловать в ваш профиль!</p>
|
||||
<div className={styles.profileHeader}>
|
||||
<div className={styles.profilePicture}>
|
||||
{profilePicture ? (
|
||||
<img src={profilePicture} alt="Profile" />
|
||||
) : (
|
||||
<div className={styles.defaultPicture}>
|
||||
<span>Фото</span>
|
||||
</div>
|
||||
)}
|
||||
<input type="file" accept="image/*" onChange={handleProfilePictureChange} className={styles.fileInput} />
|
||||
</div>
|
||||
<div className={styles.profileInfo}>
|
||||
<h2>Имя Пользователя</h2>
|
||||
<button className={styles.editButton}>Редактировать профиль</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.postsContainer}>
|
||||
<h3>Посты</h3>
|
||||
<div className={styles.newPostForm}>
|
||||
<textarea
|
||||
value={newPostText}
|
||||
onChange={(e) => setNewPostText(e.target.value)}
|
||||
placeholder="Введите текст поста"
|
||||
className={styles.postTextarea}
|
||||
/>
|
||||
<div className={styles.fileInputs}>
|
||||
<input type="file" accept="audio/*" onChange={handleNewPostMusicChange} className={styles.fileInput} />
|
||||
<input type="file" accept="image/*" onChange={handleNewPostImageChange} className={styles.fileInput} />
|
||||
</div>
|
||||
<button className={styles.addPostButton} onClick={addPost}>Добавить пост</button>
|
||||
</div>
|
||||
{posts.map((post) => (
|
||||
<div key={post.id} className={styles.post}>
|
||||
{post.image && <img src={post.image} alt={`Post ${post.id}`} />}
|
||||
<audio controls>
|
||||
<source src={post.musicUrl} type="audio/mpeg" />
|
||||
Ваш браузер не поддерживает воспроизведение аудио.
|
||||
</audio>
|
||||
<p>{post.text}</p>
|
||||
<button className={styles.deletePostButton} onClick={() => deletePost(post.id)}>Удалить пост</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,16 +5,162 @@
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
background-color: #1a1a1a; /* Темный фон */
|
||||
color: #ffffff; /* Белый текст */
|
||||
padding: 16px; /* Добавляем отступы */
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.profileContainer h2 {
|
||||
.profileHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.profilePicture {
|
||||
position: relative;
|
||||
margin-right: 32px;
|
||||
}
|
||||
|
||||
.profilePicture img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.profilePicture .defaultPicture {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50%;
|
||||
background-color: #444;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.profilePicture .fileInput {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.profileInfo h2 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.editButton {
|
||||
background-color: #ff4500; /* Оранжевая кнопка */
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.editButton:hover {
|
||||
background-color: #e63900; /* Тёмная оранжевая кнопка при наведении */
|
||||
}
|
||||
|
||||
.postsContainer {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.postsContainer h3 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.profileContainer p {
|
||||
font-size: 18px;
|
||||
.newPostForm {
|
||||
background-color: #282828; /* Средний темный фон */
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.postTextarea {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
padding: 8px;
|
||||
border: 1px solid #444;
|
||||
border-radius: 4px;
|
||||
background-color: #1a1a1a; /* Темный фон для инпутов */
|
||||
color: #ffffff; /* Белый текст */
|
||||
margin-bottom: 16px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.fileInputs {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.fileInput {
|
||||
background-color: #ff4500; /* Оранжевая кнопка */
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.fileInput:hover {
|
||||
background-color: #e63900; /* Тёмная оранжевая кнопка при наведении */
|
||||
}
|
||||
|
||||
.addPostButton {
|
||||
background-color: #ff4500; /* Оранжевая кнопка */
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.addPostButton:hover {
|
||||
background-color: #e63900; /* Тёмная оранжевая кнопка при наведении */
|
||||
}
|
||||
|
||||
.post {
|
||||
background-color: #282828; /* Средний темный фон */
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.post img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.post audio {
|
||||
width: 100%;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.post p {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.deletePostButton {
|
||||
background-color: #ff4500; /* Оранжевая кнопка */
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.deletePostButton:hover {
|
||||
background-color: #e63900; /* Тёмная оранжевая кнопка при наведении */
|
||||
}
|
||||
Reference in New Issue
Block a user