290 lines
14 KiB
HTML
290 lines
14 KiB
HTML
{% extends 'layouts/main.html' %}
|
|
|
|
{% block content %}
|
|
|
|
<div class="container mt-5">
|
|
<h1 class="mb-4">Account Einstellungen👤</h1>
|
|
|
|
<!-- Account information fields -->
|
|
<div class="card mb-4">
|
|
<div class="card-body d-flex">
|
|
<div>
|
|
<h5 class="card-title">Profilbild</h5>
|
|
<div class="mb-3 profile-image-container" id="profileImageContainer">
|
|
<img src="{{ profile_image_url }}" alt="Profile Image" class="profile-image" id="profileImage">
|
|
<div class="profile-image-overlay" id="profileImageOverlay">
|
|
<span>Profilbild aktualisieren</span>
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<form id="uploadForm" action="/upload" method="POST" enctype="multipart/form-data">
|
|
<input type="file" class="form-control-file" id="profileImageInput" name="file" style="display: none;">
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="ml-5" style="margin-left: 50px;">
|
|
<h5 class="card-title">Name</h5>
|
|
<p>{{ name }}</p>
|
|
<h5 class="card-title">Email</h5>
|
|
<p>{{ email }}</p>
|
|
<button type="button" class="btn btn-primary" id="editButton" data-toggle="modal" data-target="#editModal">
|
|
Bearbeiten
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Password change fields -->
|
|
<div class="card mb-4">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Passwort ändern</h5>
|
|
<form id="editPasswordForm" action="/password" method="POST">
|
|
<div class="form-group mb-3">
|
|
<label for="oldPassword">Altes Passwort:</label>
|
|
<input type="password" class="form-control" id="oldPassword" name="oldPassword" autocomplete="current-password">
|
|
<div class="invalid-feedback" id="oldPasswordFeedback"></div>
|
|
</div>
|
|
<div class="form-group mb-3">
|
|
<label for="newPassword">Neues Passwort:</label>
|
|
<input type="password" class="form-control" id="newPassword" name="newPassword" autocomplete="new-password">
|
|
<div class="invalid-feedback" id="newPasswordFeedback"></div>
|
|
</div>
|
|
<div class="form-group mb-3">
|
|
<label for="confirmPassword">Neues Passwort bestätigen:</label>
|
|
<input type="password" class="form-control" id="confirmPassword" name="confirmPassword" autocomplete="new-password">
|
|
<div class="invalid-feedback" id="confirmPasswordFeedback"></div>
|
|
</div>
|
|
</form>
|
|
<button type="button" class="btn btn-primary" id="submitPasswordChange">Änderungen speichern</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- Edit Modal -->
|
|
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="editModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="editModalLabel">Bearbeiten</h5>
|
|
<span class="close-icon" data-bs-dismiss="modal" aria-label="Close">
|
|
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 72 72" class="close-icon">
|
|
<path d="M 19 15 C 17.977 15 16.951875 15.390875 16.171875 16.171875 C 14.609875 17.733875 14.609875 20.266125 16.171875 21.828125 L 30.34375 36 L 16.171875 50.171875 C 14.609875 51.733875 14.609875 54.266125 16.171875 55.828125 C 16.951875 56.608125 17.977 57 19 57 C 20.023 57 21.048125 56.609125 21.828125 55.828125 L 36 41.65625 L 50.171875 55.828125 C 51.731875 57.390125 54.267125 57.390125 55.828125 55.828125 C 57.391125 54.265125 57.391125 51.734875 55.828125 50.171875 L 41.65625 36 L 55.828125 21.828125 C 57.390125 20.266125 57.390125 17.733875 55.828125 16.171875 C 54.268125 14.610875 51.731875 14.609875 50.171875 16.171875 L 36 30.34375 L 21.828125 16.171875 C 21.048125 15.391875 20.023 15 19 15 z" stroke="none"></path>
|
|
</svg>
|
|
</span>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form id="editForm" action="/profile" method="POST">
|
|
<div class="form-group">
|
|
<label for="newName">Neuer Name:</label>
|
|
<input type="text" class="form-control" id="newName" name="newName" value="{{name}}" autocomplete="username">
|
|
<div class="invalid-feedback" id="nameFeedback"></div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="newEmail">Neue E-Mail:</label>
|
|
<input type="email" class="form-control" id="newEmail" name="newEmail" value="{{email}}" autocomplete="username">
|
|
<div class="invalid-feedback" id="emailFeedback"></div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="password">Passwort:</label>
|
|
<input type="password" class="form-control" id="password" name="password" autocomplete="current-password">
|
|
<div class="invalid-feedback" id="passwordFeedback"></div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
|
<button type="button" class="btn btn-primary" id="saveChangesButton">Änderungen speichern</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
// Get elements
|
|
const profileImage = document.getElementById("profileImage");
|
|
const profileImageOverlay = document.getElementById("profileImageOverlay");
|
|
const profileImageInput = document.getElementById("profileImageInput");
|
|
const uploadForm = document.getElementById("uploadForm");
|
|
|
|
const editButton = document.getElementById("editButton");
|
|
const saveChangesButton = document.getElementById("saveChangesButton");
|
|
const editForm = document.getElementById("editForm");
|
|
const editModal = new bootstrap.Modal(document.getElementById('editModal'));
|
|
|
|
const submitPasswordChangeButton = document.getElementById("submitPasswordChange");
|
|
|
|
// Open file input when profile image is clicked
|
|
profileImageOverlay.addEventListener("click", function() {
|
|
profileImageInput.click();
|
|
});
|
|
|
|
// Change profile image when a new file is selected
|
|
profileImageInput.addEventListener("change", function() {
|
|
const file = this.files[0];
|
|
const reader = new FileReader();
|
|
|
|
reader.onload = function(e) {
|
|
profileImage.src = e.target.result;
|
|
};
|
|
|
|
reader.readAsDataURL(file);
|
|
|
|
// Submit the form
|
|
uploadForm.submit();
|
|
});
|
|
|
|
// Add event listener to edit button to open modal
|
|
editButton.addEventListener("click", function() {
|
|
editModal.show();
|
|
document.getElementById("newName").value = "{{ name }}";
|
|
document.getElementById("newEmail").value = "{{ email }}";
|
|
document.getElementById("password").value = "";
|
|
});
|
|
|
|
// Add event listener to save changes button to submit form
|
|
saveChangesButton.addEventListener("click", function() {
|
|
// Perform client-side validation before submitting the form
|
|
validateForm()
|
|
.then(isValid => {
|
|
if (isValid) {
|
|
console.log("Validated 2");
|
|
editForm.submit();
|
|
}
|
|
})
|
|
.catch(error => {
|
|
// Handle validation error
|
|
console.log("Account Form validation failed", error);
|
|
});
|
|
});
|
|
|
|
// Function to perform client-side validation
|
|
async function validateForm() {
|
|
let isValid = true;
|
|
|
|
isValid = validateInput("newName", "nameFeedback", "Bitte geben Sie einen neuen Namen ein.") && isValid;
|
|
isValid = validateEmail("newEmail", "emailFeedback", "Bitte geben Sie eine gültige E-Mail-Adresse ein.") && isValid;
|
|
|
|
try {
|
|
const passwordValid = await validatePassword("password", "passwordFeedback", "Bitte geben Sie Ihr Passwort ein.");
|
|
isValid = passwordValid && isValid;
|
|
} catch (error) {
|
|
isValid = false;
|
|
}
|
|
|
|
return isValid;
|
|
}
|
|
|
|
// Function to validate input fields
|
|
function validateInput(inputId, feedbackId, errorMessage) {
|
|
const input = document.getElementById(inputId);
|
|
const feedback = document.getElementById(feedbackId);
|
|
if (!input.value.trim()) {
|
|
feedback.textContent = errorMessage;
|
|
input.classList.add("is-invalid");
|
|
return false;
|
|
} else {
|
|
feedback.textContent = "";
|
|
input.classList.remove("is-invalid");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Function to validate email
|
|
function validateEmail(emailId, feedbackId, errorMessage) {
|
|
const input = document.getElementById(emailId);
|
|
const feedback = document.getElementById(feedbackId);
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; // Regular expression for email validation
|
|
if (!input.value.trim()) {
|
|
feedback.textContent = "Bitte geben Sie eine neue E-Mail-Adresse ein.";
|
|
input.classList.add("is-invalid");
|
|
return false;
|
|
} else if (!emailRegex.test(input.value.trim())) {
|
|
feedback.textContent = errorMessage;
|
|
input.classList.add("is-invalid");
|
|
return false;
|
|
} else {
|
|
feedback.textContent = "";
|
|
input.classList.remove("is-invalid");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Function to validate password
|
|
function validatePassword(passwordId, passwordFeedbackId, errorMessage) {
|
|
return new Promise((resolve, reject) => {
|
|
const passwordInput = document.getElementById(passwordId);
|
|
const passwordFeedback = document.getElementById(passwordFeedbackId);
|
|
const password = passwordInput.value.trim(); // Get the password entered by the user
|
|
if (!passwordInput.value.trim()) {
|
|
passwordFeedback.textContent = errorMessage;
|
|
passwordInput.classList.add("is-invalid");
|
|
reject(false);
|
|
} else {
|
|
axios.post('/check_password', { password: password })
|
|
.then(response => {
|
|
if (!response.data.valid) {
|
|
passwordFeedback.textContent = "Falsches Passwort.";
|
|
passwordInput.classList.add("is-invalid");
|
|
passwordInput.value = "";
|
|
reject(false);
|
|
} else {
|
|
passwordInput.classList.remove("is-invalid");
|
|
resolve(true);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error checking password:', error);
|
|
reject(false);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
submitPasswordChangeButton.addEventListener("click", function() {
|
|
// Perform client-side validation before submitting the form
|
|
validatePasswordChangeForm()
|
|
.then(isValid => {
|
|
if (isValid) {
|
|
document.getElementById("editPasswordForm").submit();
|
|
}
|
|
})
|
|
.catch(error => {
|
|
// Handle validation error
|
|
console.log("Password change form validation failed", error);
|
|
});
|
|
});
|
|
|
|
async function validatePasswordChangeForm() {
|
|
let isValid = true;
|
|
|
|
try {
|
|
const passwordValid = await validatePassword("oldPassword", "oldPasswordFeedback", "Bitte geben Sie Ihr altes Passwort ein.");
|
|
isValid = passwordValid && isValid;
|
|
} catch (error) {
|
|
isValid = false;
|
|
}
|
|
isValid = validateInput("newPassword", "newPasswordFeedback", "Bitte geben Sie Ihr neues Passwort ein.") && isValid;
|
|
isValid = validateInput("confirmPassword", "confirmPasswordFeedback", "Bitte bestätigen Sie Ihr neues Passwort.") && isValid;
|
|
|
|
// Check if new password matches confirm password
|
|
const newPassword = document.getElementById("newPassword").value.trim();
|
|
const confirmPassword = document.getElementById("confirmPassword").value.trim();
|
|
if (newPassword !== confirmPassword) {
|
|
document.getElementById("confirmPasswordFeedback").textContent = "Die Passwörter stimmen nicht überein.";
|
|
document.getElementById("confirmPassword").classList.add("is-invalid");
|
|
isValid = false;
|
|
} else {
|
|
document.getElementById("confirmPasswordFeedback").textContent = "";
|
|
document.getElementById("confirmPassword").classList.remove("is-invalid");
|
|
}
|
|
|
|
return isValid;
|
|
}
|
|
|
|
});
|
|
</script>
|
|
|
|
|
|
{% endblock %} |