diff --git a/app.py b/app.py index c3ac5dc..77a800e 100644 --- a/app.py +++ b/app.py @@ -146,6 +146,7 @@ def index(): "Friday": "Freitag", "Saturday": "Samstag", "Sunday": "Sonntag"} date = datetime.datetime.now().strftime("%d.%m.%Y %H:%M ") + days[datetime.datetime.now().strftime("%A")] + color = '255, 0, 255' return render_template( 'index.html', @@ -154,6 +155,7 @@ def index(): habit_lists=habit_lists, heatmap_values=heatmap_values, day=day, + color=color, errors={} ) @@ -573,7 +575,7 @@ def check_habit(): "percentage": habit.percentage, "streak": habit.streak, "heatmap": heatmap_values, - "day": day + "day": day, } diff --git a/static/script/script-index.js b/static/script/script-index.js index b8863ad..4f2f16a 100644 --- a/static/script/script-index.js +++ b/static/script/script-index.js @@ -1,6 +1,6 @@ // Funktion zum Erstellen der Heatmap -function createHeatmap(data, day) { +function createHeatmap(data, day, color) { const heatmapContainer = document.getElementById('heatmap'); const days = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'] @@ -21,17 +21,8 @@ function createHeatmap(data, day) { if (data[i * 7 + j]) { const dayElement = document.createElement('div'); dayElement.classList.add('day'); - dayElement.style.backgroundColor = `rgba(0, 255, 0, ${opacity})`; - if (day == i * 7 + j){ - dayElement.style.borderColor = `rgba(255, 0, 0)`; - dayElement.style.borderWidth = "2px"; - } - heatmapContainer.appendChild(dayElement); - } else { - const dayElement = document.createElement('div'); - dayElement.classList.add('day'); - dayElement.style.backgroundColor = `rgba(0, 255, 0, ${opacity})`; - if (day == i * 7 + j){ + dayElement.style.backgroundColor = `rgba(${color}, ${opacity})`; + if (day === i * 7 + j){ dayElement.style.borderColor = `rgba(255, 0, 0)`; dayElement.style.borderWidth = "2px"; } @@ -92,7 +83,7 @@ function sendPostRequest(checkboxId) { const heatmapValues = response.data.heatmap; deleteHeatmap() - createHeatmap(heatmapValues, day) + createHeatmap(heatmapValues, day, color) }).catch(function (error) { // Handle the error if needed @@ -142,7 +133,7 @@ function deleteList(listId) { }); } -document.addEventListener('DOMContentLoaded', (event) => { +document.addEventListener('DOMContentLoaded', () => { const elements = document.querySelectorAll('.task-list').values() // loop through the elements @@ -174,7 +165,6 @@ $(function () { $('[data-toggle="tooltip"]').tooltip() }) -console.log(activityData, day) // Erstelle die Heatmap mit den simulierten Daten -createHeatmap(activityData, day); +createHeatmap(activityData, day, color); diff --git a/static/script/script-profile.js b/static/script/script-profile.js new file mode 100644 index 0000000..42c58c3 --- /dev/null +++ b/static/script/script-profile.js @@ -0,0 +1,183 @@ +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; + } + +}); \ No newline at end of file diff --git a/templates/components/heatmap.html b/templates/components/heatmap.html index 542bc1c..90f16c3 100644 --- a/templates/components/heatmap.html +++ b/templates/components/heatmap.html @@ -10,4 +10,5 @@ // Generates activity based on the Values given by the Backend const activityData = {{ heatmap_values }}; const day = {{ day }}; + const color = "{{ color }}"; \ No newline at end of file diff --git a/templates/profile.html b/templates/profile.html index 19f9602..66a9de7 100644 --- a/templates/profile.html +++ b/templates/profile.html @@ -100,191 +100,6 @@ - - + {% endblock %} \ No newline at end of file