add messeges, add posts in profile

This commit is contained in:
2025-04-09 16:38:45 +03:00
parent f63e5774d8
commit 0696c10a32
7 changed files with 319 additions and 8 deletions

View File

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

View File

@@ -15,7 +15,10 @@ const Header = ({ isAuthenticated, onLogout }) => {
</div>
{!isAuthenticated && <Link to="/register" className={styles.registerLink}>Зарегистрироваться</Link>}
{isAuthenticated && (
<button className={styles.logoutButton} onClick={onLogout}>Выйти</button>
<>
<Link to="/messages" className={styles.messagesLink}>Перейти к сообщениям</Link>
<button className={styles.logoutButton} onClick={onLogout}>Выйти</button>
</>
)}
</header>
);

View File

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

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

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

View File

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

View File

@@ -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; /* Тёмная оранжевая кнопка при наведении */
}