Добавление описания профиля и отступа.
Добавлено модальное окно для добавления описание профиля с счётчиком символов и размером до 500 символов, добавлен отступ между изменением пароля и выходом из аккаунта, перекрашена кнопка удаления аккаунта.
This commit is contained in:
107
src/Profile.js
107
src/Profile.js
@@ -19,6 +19,10 @@ const Profile = () => {
|
||||
const [new_password, setnew_password] = useState('');
|
||||
const [new_password_confirm, setnew_password_confirm] = useState('');
|
||||
const [passwordError, setPasswordError] = useState('');
|
||||
const [showDescriptionModal, setShowDescriptionModal] = useState(false);
|
||||
const [profileDescription, setProfileDescription] = useState('');
|
||||
const [descriptionError, setDescriptionError] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
const checkSession = async () => {
|
||||
try {
|
||||
@@ -117,6 +121,36 @@ const Profile = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const saveProfileDescription = async (e) => {
|
||||
e.preventDefault();
|
||||
setDescriptionError('');
|
||||
|
||||
try {
|
||||
await axios.put('/api/users/change_description',
|
||||
{ new_description: profileDescription },
|
||||
{ withCredentials: true }
|
||||
);
|
||||
try {
|
||||
const response = await axios.get('/api/users/me');
|
||||
setUser(response.data.display_name);
|
||||
setUserName(response.data.username);
|
||||
// Обновляем описание, если оно есть в ответе
|
||||
if (response.data.description) {
|
||||
setProfileDescription(response.data.description);
|
||||
}
|
||||
} catch (err) {
|
||||
setError('Ошибка обновления данных профиля');
|
||||
}
|
||||
|
||||
setShowDescriptionModal(false); // Закрываем модальное окно
|
||||
|
||||
} catch (err) {
|
||||
setDescriptionError(
|
||||
err.response?.data?.detail || 'Ошибка при сохранении описания'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const OpenWindowDelete = () => {
|
||||
setShowConfirm(true); // Показываем окно подтверждения
|
||||
@@ -141,7 +175,23 @@ const Profile = () => {
|
||||
const closeWindowUserName = () => {
|
||||
setShowConfirmUserName(false); // Показываем окно подтверждения
|
||||
};
|
||||
|
||||
|
||||
const openDescriptionModal = async () => {
|
||||
setDescriptionError('');
|
||||
try {
|
||||
const response = await axios.get('/api/users/me');
|
||||
setProfileDescription(response.data.description || '');
|
||||
setShowDescriptionModal(true);
|
||||
} catch (err) {
|
||||
setError('Не удалось загрузить данные профиля');
|
||||
console.error('Ошибка загрузки данных пользователя:', err);
|
||||
}
|
||||
};
|
||||
|
||||
const closeDescriptionModal = () => {
|
||||
setShowDescriptionModal(false);
|
||||
setDescriptionError('');
|
||||
};
|
||||
const deleteAccount = async () => {
|
||||
try {
|
||||
await axios.delete('/api/users/me', { withCredentials: true });
|
||||
@@ -171,6 +221,13 @@ const Profile = () => {
|
||||
<div className="frame"><p>{user}</p></div>
|
||||
<button onClick={OpenWindowName}>✎</button>
|
||||
</div>
|
||||
<p>Описание профиля</p>
|
||||
<div className="com">
|
||||
Добавьте краткое описание о себе, которое увидят другие пользователи.
|
||||
</div>
|
||||
<button onClick={openDescriptionModal} className="button-small">
|
||||
{profileDescription ? 'Редактировать описание' : 'Добавить описание'}
|
||||
</button>
|
||||
<div className="com">Логин</div>
|
||||
<div className="buttonName">
|
||||
<div className="frame"><p>{userName}</p></div>
|
||||
@@ -178,9 +235,9 @@ const Profile = () => {
|
||||
</div>
|
||||
<p>Изменить пароль</p>
|
||||
<div className="com">В целях безопасности мы рекомендуем выбрать пароль, который ещё не использовался вами в других учётных записях.</div>
|
||||
<button onClick={() => setShowChangePassword(true)}className="button-small">Изменить пароль</button>
|
||||
<button onClick={handleLogout}>Выйти из аккаунта</button>
|
||||
<button onClick={OpenWindowDelete}>Удалить аккаунт</button>
|
||||
<button onClick={() => setShowChangePassword(true)} className="button-small">Изменить пароль</button>
|
||||
<button onClick={handleLogout} className="margin-top-large">Выйти из аккаунта</button>
|
||||
<button className="Important-button" onClick={OpenWindowDelete}>Удалить аккаунт</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -284,6 +341,48 @@ const Profile = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showDescriptionModal && (
|
||||
<div className="confirm-modal">
|
||||
<div className="modal-content">
|
||||
<h3>{profileDescription ? 'Редактировать описание профиля' : 'Добавить описание профиля'}</h3>
|
||||
|
||||
{descriptionError && (
|
||||
<div className="error" style={{ color: 'red' }}>
|
||||
{descriptionError}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form onSubmit={saveProfileDescription}>
|
||||
<div className="form-group">
|
||||
<label>Описание:</label>
|
||||
<textarea
|
||||
className="description-textarea"
|
||||
value={profileDescription}
|
||||
onChange={(e) => setProfileDescription(e.target.value)}
|
||||
placeholder="Расскажите о себе, своих интересах или профессиональных навыках..."
|
||||
rows={6}
|
||||
maxLength={500}
|
||||
required
|
||||
/>
|
||||
<div className="char-counter">
|
||||
{profileDescription.length}/500 символов
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="modal-buttons">
|
||||
<button type="submit">Сохранить описание</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={closeDescriptionModal}
|
||||
>
|
||||
Отменить
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Всплывающее окно подтверждения */}
|
||||
{showConfirm && (
|
||||
<div className="confirm-modal">
|
||||
|
||||
@@ -191,7 +191,7 @@ input[type="password"] {
|
||||
.Important-button {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
margin: 8px;
|
||||
margin: 10px auto;
|
||||
background-color: #e30000;
|
||||
color: white;
|
||||
border: none;
|
||||
@@ -278,6 +278,7 @@ button:disabled {
|
||||
width: 30%;
|
||||
min-width: auto;
|
||||
height: auto;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
.user-info p {
|
||||
@@ -313,3 +314,32 @@ h3 {
|
||||
color: #CAD1D8;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.description-textarea {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
font-family: inherit;
|
||||
resize: vertical;
|
||||
min-height: 120px;
|
||||
max-height: 200px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.description-textarea:focus {
|
||||
outline: none;
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
|
||||
}
|
||||
|
||||
.char-counter {
|
||||
text-align: right;
|
||||
color: #6c757d;
|
||||
font-size: 0.875rem;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.margin-top-large {
|
||||
margin-top: 10em;
|
||||
}
|
||||
Reference in New Issue
Block a user