Streamlines the avatar management
parent
da5e5ec4ae
commit
6a48b54320
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
|
||||||
case 'remove':
|
|
||||||
$result = $userObject->removeAvatar($user_id, $config['avatars_path'].$userDetails[0]['avatar']);
|
$result = $userObject->removeAvatar($user_id, $config['avatars_path'].$userDetails[0]['avatar']);
|
||||||
if ($result === true) {
|
if ($result === true) {
|
||||||
$_SESSION['notice'] = "Avatar for user \"{$user}\" is removed.";
|
$_SESSION['notice'] .= "Avatar for user \"{$user}\" is removed. ";
|
||||||
} else {
|
} else {
|
||||||
$_SESSION['error'] = "Removing the avatar failed. Error: $result";
|
$_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");
|
||||||
|
|
|
@ -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">
|
||||||
|
|
||||||
|
<form method="POST" action="<?= $app_root ?>?page=profile" enctype="multipart/form-data">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<p class="border rounded bg-light mb-4"><small>edit the profile fields</small></p>
|
<p class="border rounded bg-light mb-4"><small>edit the profile fields</small></p>
|
||||||
|
|
||||||
<div class="col-md-4 avatar-container">
|
<div class="col-md-4 avatar-container">
|
||||||
<div>
|
<div class="avatar-wrapper">
|
||||||
<img class="avatar-img" src="<?= $app_root . htmlspecialchars($avatar) ?>" alt="avatar" />
|
<img class="avatar-img" src="<?= $app_root . htmlspecialchars($avatar) ?>" alt="avatar" />
|
||||||
|
<div class="avatar-btn-container">
|
||||||
|
|
||||||
<form method="POST" action="<?= $app_root ?>?page=profile&action=edit&item=avatar" enctype="multipart/form-data">
|
<label for="avatar-upload" class="avatar-btn avatar-btn-select btn btn-primary">
|
||||||
<label for="avatar-upload" class="avatar-btn btn btn-primary"><small>select new</small></label>
|
<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="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>
|
|
||||||
<!-- 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>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
|
|
||||||
<form method="POST" action="<?= $app_root ?>?page=profile">
|
|
||||||
|
|
||||||
<!--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>
|
||||||
|
@ -109,11 +85,38 @@
|
||||||
|
|
||||||
</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]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Avatar file size and type control
|
||||||
|
document.getElementById('avatar-upload').addEventListener('change', function() {
|
||||||
const maxFileSize = 500 * 1024; // 500 KB in bytes
|
const maxFileSize = 500 * 1024; // 500 KB in bytes
|
||||||
const currentAvatar = '<?= $app_root . htmlspecialchars($avatar) ?>'; // current avatar
|
const currentAvatar = '<?= $app_root . htmlspecialchars($avatar) ?>'; // current avatar
|
||||||
document.getElementById('avatar-upload').addEventListener('change', function() {
|
|
||||||
const uploadButton = document.getElementById('avatar-upload-button');
|
|
||||||
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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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-btn {
|
|
||||||
margin-top: 10px;
|
.avatar-wrapper {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.avatar-btn {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue