Streamlines the avatar management

main
Yasen Pramatarov 2024-09-10 14:05:38 +03:00
parent da5e5ec4ae
commit 6a48b54320
5 changed files with 120 additions and 84 deletions

View File

@ -137,19 +137,19 @@ class User {
':user_id' => $user_id
]);
// all went OK
$_SESSION['notice'] = 'Avatar updated successfully!';
$_SESSION['notice'] .= 'Avatar updated successfully. ';
return true;
} catch (Exception $e) {
return $e->getMessage();
}
} else {
$_SESSION['error'] = 'Error moving the uploaded file.';
$_SESSION['error'] .= 'Error moving the uploaded file. ';
}
} else {
$_SESSION['error'] = 'Invalid avatar file type.';
$_SESSION['error'] .= 'Invalid avatar file type. ';
}
} else {
$_SESSION['error'] = 'Error uploading the avatar file.';
$_SESSION['error'] .= 'Error uploading the avatar file. ';
}
} catch (Exception $e) {

View File

@ -14,22 +14,13 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$item = $_REQUEST['item'] ?? '';
// avatar editing
if ($item === 'avatar') {
switch ($action) {
case 'remove':
$result = $userObject->removeAvatar($user_id, $config['avatars_path'].$userDetails[0]['avatar']);
if ($result === true) {
$_SESSION['notice'] = "Avatar for user \"{$user}\" is removed.";
} else {
$_SESSION['error'] = "Removing the avatar failed. Error: $result";
}
break;
case 'edit':
$result = $userObject->changeAvatar($user_id, $_FILES['avatar_file'], $config['avatars_path']);
break;
default:
$_SESSION['error'] = "Unspecified avatar editing action.";
// avatar removal
if ($item === 'avatar' && $action === 'remove') {
$result = $userObject->removeAvatar($user_id, $config['avatars_path'].$userDetails[0]['avatar']);
if ($result === true) {
$_SESSION['notice'] .= "Avatar for user \"{$user}\" is removed. ";
} else {
$_SESSION['error'] .= "Removing the avatar failed. Error: $result ";
}
header("Location: $app_root?page=profile");
@ -44,9 +35,14 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
];
$result = $userObject->editUser($user_id, $updatedUser);
if ($result === true) {
$_SESSION['notice'] = "User details for \"{$updatedUser['name']}\" are edited.";
$_SESSION['notice'] .= "User details for \"{$updatedUser['name']}\" are edited. ";
} else {
$_SESSION['error'] = "Editing the user details failed. Error: $result";
$_SESSION['error'] .= "Editing the user details failed. Error: $result ";
}
// update the avatar
if (!empty($_FILES['avatar_file']['tmp_name'])) {
$result = $userObject->changeAvatar($user_id, $_FILES['avatar_file'], $config['avatars_path']);
}
header("Location: $app_root?page=profile");

View File

@ -5,55 +5,31 @@
<p class="h4 card-header">Profile of <?= $userDetails[0]['username'] ?></p>
<div class="card-body">
<div class="row">
<p class="border rounded bg-light mb-4"><small>edit the profile fields</small></p>
<form method="POST" action="<?= $app_root ?>?page=profile" enctype="multipart/form-data">
<div class="row">
<p class="border rounded bg-light mb-4"><small>edit the profile fields</small></p>
<div class="col-md-4 avatar-container">
<div class="avatar-wrapper">
<img class="avatar-img" src="<?= $app_root . htmlspecialchars($avatar) ?>" alt="avatar" />
<div class="avatar-btn-container">
<div class="col-md-4 avatar-container">
<div>
<img class="avatar-img" src="<?= $app_root . htmlspecialchars($avatar) ?>" alt="avatar" />
<form method="POST" action="<?= $app_root ?>?page=profile&action=edit&item=avatar" enctype="multipart/form-data">
<label for="avatar-upload" class="avatar-btn btn btn-primary"><small>select new</small></label>
<label for="avatar-upload" class="avatar-btn avatar-btn-select btn btn-primary">
<i class="fas fa-folder" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="select new avatar"></i>
</label>
<input type="file" id="avatar-upload" name="avatar_file" accept="image/*" style="display:none;">
<input type="submit" id="avatar-upload-button" class="avatar-btn btn btn-secondary" value="upload" disabled>
</form>
<form id="remove-avatar-form" method="POST" action="<?= $app_root ?>?page=profile&action=remove&item=avatar">
<?php if ($default_avatar) { ?>
<button type="button" class="avatar-btn btn btn-secondary" data-toggle="modal" data-target="#confirmDeleteModal" disabled>
<button type="button" class="avatar-btn avatar-btn-remove btn btn-secondary" data-toggle="modal" data-target="#confirmDeleteModal" disabled>
<?php } else { ?>
<button type="button" class="avatar-btn btn btn-danger" data-toggle="modal" data-target="#confirmDeleteModal">
<button type="button" class="avatar-btn avatar-btn-remove btn btn-danger" data-toggle="modal" data-target="#confirmDeleteModal">
<?php } ?>
<small>remove current avatar</small>
<i class="fas fa-trash" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="remove current avatar"></i>
</button>
</form>
<!-- avatar removal moda confirmation -->
<div class="modal fade" id="confirmDeleteModal" tabindex="-1" aria-labelledby="confirmDeleteModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmDeleteModalLabel">Confirm Avatar Deletion</h5>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Are you sure you want to delete your avatar? This action cannot be undone.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger" id="confirm-delete">Delete Avatar</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-8">
<form method="POST" action="<?= $app_root ?>?page=profile">
<div class="col-md-8">
<!--div class="row mb-3">
<div class="col-md-4 text-end">
<label for="username" class="form-label"><small>username:</small></label>
@ -102,18 +78,45 @@
</div>
<p>
<a href="<?= $app_root ?>?page=profile" class="btn btn-secondary">Cancel</a>
<input type="submit" class="btn btn-primary" value="Save" />
</p>
<p>
<a href="<?= $app_root ?>?page=profile" class="btn btn-secondary">Cancel</a>
<input type="submit" class="btn btn-primary" value="Save" />
</p>
</div>
</form>
<!-- avatar removal modal confirmation -->
<div class="modal fade" id="confirmDeleteModal" tabindex="-1" aria-labelledby="confirmDeleteModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmDeleteModalLabel">Confirm Avatar Deletion</h5>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<img class="avatar-img" src="<?= $app_root . htmlspecialchars($avatar) ?>" alt="avatar" />
<br />
Are you sure you want to delete your avatar?
<br />
This action cannot be undone.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<form id="remove-avatar-form" data-action="remove-avatar" method="POST" action="<?= $app_root ?>?page=profile&action=remove&item=avatar">
<button type="button" class="btn btn-danger" id="confirm-delete">Delete Avatar</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /user profile -->
<script>
// Preview the uploaded avatar
document.getElementById('avatar-upload').addEventListener('change', function(event) {
const reader = new FileReader();
reader.onload = function() {
@ -122,10 +125,10 @@ document.getElementById('avatar-upload').addEventListener('change', function(eve
reader.readAsDataURL(event.target.files[0]);
});
const maxFileSize = 500 * 1024; // 500 KB in bytes
const currentAvatar = '<?= $app_root . htmlspecialchars($avatar) ?>'; // current avatar
// Avatar file size and type control
document.getElementById('avatar-upload').addEventListener('change', function() {
const uploadButton = document.getElementById('avatar-upload-button');
const maxFileSize = 500 * 1024; // 500 KB in bytes
const currentAvatar = '<?= $app_root . htmlspecialchars($avatar) ?>'; // current avatar
const file = this.files[0];
if (file) {
@ -133,22 +136,15 @@ document.getElementById('avatar-upload').addEventListener('change', function() {
if (file.size > maxFileSize) {
alert('File size exceeds 500 KB. Please select a smaller file.');
this.value = ''; // Clear the file input
uploadButton.disabled = true; // Keep the upload button disabled
uploadButton.className = 'avatar-btn btn btn-secondary';
document.querySelector('.avatar-img').src = currentAvatar;
} else {
// Enable the upload button if the file size is valid
uploadButton.disabled = false;
uploadButton.className = 'avatar-btn btn btn-success';
}
} else {
uploadButton.disabled = true; // Disable the button if no file is selected
uploadButton.className = 'avatar-btn btn btn-secondary';
}
});
document.getElementById('confirm-delete').addEventListener('click', function() {
// Submit the form when the user confirms deletion
// Submitting the avatar deletion confirmation modal form
document.getElementById('confirm-delete').addEventListener('click', function(event) {
event.preventDefault(); // Prevent the outer form from submitting
document.getElementById('remove-avatar-form').submit();
});
</script>

View File

@ -47,7 +47,7 @@
<label class="form-label"><small>bio:</small></label>
</div>
<div class="col-md-8 text-start bg-light">
<textarea class="scroll-box" rows="10"><?= $userDetails[0]['bio'] ?? '' ?></textarea>
<textarea class="scroll-box" rows="10" readonly><?= $userDetails[0]['bio'] ?? '' ?></textarea>
</div>
</div>

View File

@ -133,7 +133,7 @@
.main-content {
flex-grow: 1;
transition: width 0.5s ease;
width: 80%;
/* width: 80%;*/
}
.main-content.expanded {
width: calc(70% + 250px);
@ -170,12 +170,18 @@
resize: none;
font-family: inherit;
font-size: 14px;
user-select: text;
cursor: default;
outline: none;
box-shadow: none;
}
/* avatar */
/* avatars */
.avatar-container {
position: relative;
text-align: center;
}
.avatar-img {
width: 200px;
height: 200px;
@ -183,6 +189,44 @@
object-fit: cover; /* Ensures proper cropping of image */
border: 3px solid #ccc;
}
.avatar-wrapper {
position: relative;
display: inline-block;
}
.avatar-btn {
margin-top: 10px;
}
position: absolute;
bottom: 10px; /* Adjust this value as needed */
/* background: rgba(0, 0, 0, 0.5); /* Semi-transparent background */
color: white;
border: none;
border-radius: 4px;
padding: 10px;
}
.avatar-btn-container {
position: absolute;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 10px; /* Space between buttons */
}
.avatar-btn-select,
.avatar-btn-remove {
/* background: rgba(0, 0, 0, 0.5); /* Semi-transparent background */
color: white;
border: none;
border-radius: 4px;
padding: 10px;
}
.avatar-btn-select {
width: 50px;
left: -55px;
}
.avatar-btn-remove {
width: 50px;
left: 5px;
}