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 ':user_id' => $user_id
]); ]);
// all went OK // all went OK
$_SESSION['notice'] = 'Avatar updated successfully!'; $_SESSION['notice'] .= 'Avatar updated successfully. ';
return true; return true;
} catch (Exception $e) { } catch (Exception $e) {
return $e->getMessage(); return $e->getMessage();
} }
} else { } else {
$_SESSION['error'] = 'Error moving the uploaded file.'; $_SESSION['error'] .= 'Error moving the uploaded file. ';
} }
} else { } else {
$_SESSION['error'] = 'Invalid avatar file type.'; $_SESSION['error'] .= 'Invalid avatar file type. ';
} }
} else { } else {
$_SESSION['error'] = 'Error uploading the avatar file.'; $_SESSION['error'] .= 'Error uploading the avatar file. ';
} }
} catch (Exception $e) { } catch (Exception $e) {

View File

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

View File

@ -5,55 +5,31 @@
<p class="h4 card-header">Profile of <?= $userDetails[0]['username'] ?></p> <p class="h4 card-header">Profile of <?= $userDetails[0]['username'] ?></p>
<div class="card-body"> <div class="card-body">
<div class="row"> <form method="POST" action="<?= $app_root ?>?page=profile" enctype="multipart/form-data">
<p class="border rounded bg-light mb-4"><small>edit the profile fields</small></p> <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"> <label for="avatar-upload" class="avatar-btn avatar-btn-select btn btn-primary">
<div> <i class="fas fa-folder" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="select new avatar"></i>
<img class="avatar-img" src="<?= $app_root . htmlspecialchars($avatar) ?>" alt="avatar" /> </label>
<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>
<input type="file" id="avatar-upload" name="avatar_file" accept="image/*" style="display:none;"> <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) { ?> <?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 { ?> <?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 } ?> <?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> </button>
</form> </div>
<!-- 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>
<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="row mb-3">
<div class="col-md-4 text-end"> <div class="col-md-4 text-end">
<label for="username" class="form-label"><small>username:</small></label> <label for="username" class="form-label"><small>username:</small></label>
@ -102,18 +78,45 @@
</div> </div>
<p> <p>
<a href="<?= $app_root ?>?page=profile" class="btn btn-secondary">Cancel</a> <a href="<?= $app_root ?>?page=profile" class="btn btn-secondary">Cancel</a>
<input type="submit" class="btn btn-primary" value="Save" /> <input type="submit" class="btn btn-primary" value="Save" />
</p> </p>
</div> </div>
</form> </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>
</div> </div>
<!-- /user profile --> <!-- /user profile -->
<script> <script>
// Preview the uploaded avatar
document.getElementById('avatar-upload').addEventListener('change', function(event) { document.getElementById('avatar-upload').addEventListener('change', function(event) {
const reader = new FileReader(); const reader = new FileReader();
reader.onload = function() { reader.onload = function() {
@ -122,10 +125,10 @@ document.getElementById('avatar-upload').addEventListener('change', function(eve
reader.readAsDataURL(event.target.files[0]); reader.readAsDataURL(event.target.files[0]);
}); });
const maxFileSize = 500 * 1024; // 500 KB in bytes // Avatar file size and type control
const currentAvatar = '<?= $app_root . htmlspecialchars($avatar) ?>'; // current avatar
document.getElementById('avatar-upload').addEventListener('change', function() { 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]; const file = this.files[0];
if (file) { if (file) {
@ -133,22 +136,15 @@ document.getElementById('avatar-upload').addEventListener('change', function() {
if (file.size > maxFileSize) { if (file.size > maxFileSize) {
alert('File size exceeds 500 KB. Please select a smaller file.'); alert('File size exceeds 500 KB. Please select a smaller file.');
this.value = ''; // Clear the file input 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; 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() { // Submitting the avatar deletion confirmation modal form
// Submit the form when the user confirms deletion document.getElementById('confirm-delete').addEventListener('click', function(event) {
event.preventDefault(); // Prevent the outer form from submitting
document.getElementById('remove-avatar-form').submit(); document.getElementById('remove-avatar-form').submit();
}); });
</script> </script>

View File

@ -47,7 +47,7 @@
<label class="form-label"><small>bio:</small></label> <label class="form-label"><small>bio:</small></label>
</div> </div>
<div class="col-md-8 text-start bg-light"> <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>
</div> </div>

View File

@ -133,7 +133,7 @@
.main-content { .main-content {
flex-grow: 1; flex-grow: 1;
transition: width 0.5s ease; transition: width 0.5s ease;
width: 80%; /* width: 80%;*/
} }
.main-content.expanded { .main-content.expanded {
width: calc(70% + 250px); width: calc(70% + 250px);
@ -170,12 +170,18 @@
resize: none; resize: none;
font-family: inherit; font-family: inherit;
font-size: 14px; font-size: 14px;
user-select: text;
cursor: default;
outline: none;
box-shadow: none;
} }
/* avatar */ /* avatars */
.avatar-container { .avatar-container {
position: relative;
text-align: center; text-align: center;
} }
.avatar-img { .avatar-img {
width: 200px; width: 200px;
height: 200px; height: 200px;
@ -183,6 +189,44 @@
object-fit: cover; /* Ensures proper cropping of image */ object-fit: cover; /* Ensures proper cropping of image */
border: 3px solid #ccc; border: 3px solid #ccc;
} }
.avatar-wrapper {
position: relative;
display: inline-block;
}
.avatar-btn { .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;
}