diff --git a/controllers/headerController.js b/controllers/headerController.js index 0594d08..3376342 100644 --- a/controllers/headerController.js +++ b/controllers/headerController.js @@ -172,12 +172,39 @@ exports.update = async (req, res) => { location: parsedData.contactInfo?.location || "", socialLinks: parsedData.socialLinks || [], }; - console.log("✓ Converted to top object:", top); - } catch (e) { - console.error("✗ Error parsing topbarJson:", e.message); - return res.status(400).json({ + + if (logo) { + updateData.logo = logoData; + } + + console.log( + "Preparing to update header with data:", + JSON.stringify(updateData, null, 2), + ); + + const updatedHeader = await Header.findByIdAndUpdate( + headerId, + updateData, + { new: true, runValidators: true }, + ); + + if (!updatedHeader) { + console.error("✗ Header not found with ID:", headerId); + return res.status(404).json({ + success: false, + message: "Header not found", + }); + } + res.json({ + success: true, + message: "Header updated successfully", + data: updatedHeader, + }); + } catch (error) { + console.error("✗ Error updating header:", error); + res.status(400).json({ success: false, - message: "Invalid JSON in topbarJson: " + e.message, + message: error.message, }); } } diff --git a/public/img/favicon.png b/public/img/favicon.png index 207b12b..820c256 100644 Binary files a/public/img/favicon.png and b/public/img/favicon.png differ diff --git a/public/js/password-toggle.js b/public/js/password-toggle.js new file mode 100644 index 0000000..f92d527 --- /dev/null +++ b/public/js/password-toggle.js @@ -0,0 +1,47 @@ +document.addEventListener('DOMContentLoaded', function() { + const toggleButtons = document.querySelectorAll('.password-toggle-btn'); + + toggleButtons.forEach(button => { + // Hover effect logic + button.addEventListener('mouseenter', function() { + this.style.color = 'var(--primary-color)'; + }); + + button.addEventListener('mouseleave', function() { + this.style.color = '#666'; + }); + + button.addEventListener('click', function() { + // Find the input element within the same container + // We assume the structure is container > input + button + // or button is absolutely positioned relative to container + // The safest way is to look for the input in the parent container + const container = this.parentElement; + const input = container.querySelector('input'); + + if (input) { + const type = input.getAttribute('type') === 'password' ? 'text' : 'password'; + input.setAttribute('type', type); + + const icon = this.querySelector('i'); + if (type === 'text') { + icon.classList.remove('fa-eye'); + icon.classList.add('fa-eye-slash'); + this.setAttribute('aria-label', 'Hide password'); + } else { + icon.classList.remove('fa-eye-slash'); + icon.classList.add('fa-eye'); + this.setAttribute('aria-label', 'Show password'); + } + } + }); + + // Add keyboard accessibility + button.addEventListener('keydown', function(e) { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + this.click(); + } + }); + }); +}); diff --git a/routes/auth.js b/routes/auth.js index ade48f2..5abde9f 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -134,22 +134,22 @@ router.post('/register', async (req, res) => { } }); -// Forgot Password Page -router.get('/forgot-password', (req, res) => { - res.render('auth/forgot-password', { - title: 'Forgot Password', +// Change Password Page +router.get('/change-password', (req, res) => { + res.render('auth/change-password', { + title: 'Change Password', layout: false }); }); -// Forgot Password Handle -router.post('/forgot-password', async (req, res) => { +// Change Password Handle +router.post('/change-password', async (req, res) => { const { email } = req.body; try { const user = await User.findOne({ email }); if (!user) { req.flash('error_msg', 'No account with that email address exists.'); - return res.redirect('/auth/forgot-password'); + return res.redirect('/auth/change-password'); } const token = crypto.randomBytes(20).toString('hex'); @@ -166,7 +166,7 @@ router.post('/forgot-password', async (req, res) => { } catch (err) { console.error(err); req.flash('error_msg', 'Error processing request'); - res.redirect('/auth/forgot-password'); + res.redirect('/auth/change-password'); } }); @@ -180,7 +180,7 @@ router.get('/reset-password/:token', async (req, res) => { if (!user) { req.flash('error_msg', 'Password reset token is invalid or has expired.'); - return res.redirect('/auth/forgot-password'); + return res.redirect('/auth/change-password'); } res.render('auth/reset-password', { @@ -190,7 +190,7 @@ router.get('/reset-password/:token', async (req, res) => { }); } catch (err) { console.error(err); - res.redirect('/auth/forgot-password'); + res.redirect('/auth/change-password'); } }); @@ -204,7 +204,7 @@ router.post('/reset-password/:token', async (req, res) => { if (!user) { req.flash('error_msg', 'Password reset token is invalid or has expired.'); - return res.redirect('/auth/forgot-password'); + return res.redirect('/auth/change-password'); } if (req.body.password !== req.body.confirm_password) { diff --git a/views/auth/forgot-password.ejs b/views/auth/change-password.ejs similarity index 97% rename from views/auth/forgot-password.ejs rename to views/auth/change-password.ejs index 5fb2fd9..4bd1571 100644 --- a/views/auth/forgot-password.ejs +++ b/views/auth/change-password.ejs @@ -170,11 +170,11 @@
-

Forgot Password

-

Enter your email to reset password

+

Change Password

+

Enter your email to change password

-
+
@@ -182,7 +182,7 @@
diff --git a/views/auth/login.ejs b/views/auth/login.ejs index cc0bb98..e41436e 100644 --- a/views/auth/login.ejs +++ b/views/auth/login.ejs @@ -170,12 +170,18 @@ @@ -209,6 +215,9 @@ + + + \ No newline at end of file diff --git a/views/auth/register.ejs b/views/auth/register.ejs index 20b99fe..7dc068c 100644 --- a/views/auth/register.ejs +++ b/views/auth/register.ejs @@ -186,13 +186,26 @@
- +
+ + +
- +
+ + +
@@ -251,6 +264,9 @@ } }); + + + \ No newline at end of file diff --git a/views/auth/reset-password.ejs b/views/auth/reset-password.ejs index aff4f58..7f4ac47 100644 --- a/views/auth/reset-password.ejs +++ b/views/auth/reset-password.ejs @@ -176,12 +176,26 @@
- +
+ + +
- +
+ + +
@@ -234,6 +248,9 @@ } }); + + + \ No newline at end of file diff --git a/views/layouts/admin.ejs b/views/layouts/admin.ejs index e05bac5..d566c7e 100644 --- a/views/layouts/admin.ejs +++ b/views/layouts/admin.ejs @@ -131,7 +131,7 @@ } // Automatically clean up on every hide event - document.addEventListener('hidden.bs.modal', function() { + document.addEventListener('hidden.bs.modal', function () { // Wait a tiny bit for the animation to finish setTimeout(forceCleanupModals, 100); }); @@ -146,11 +146,11 @@ } } }, 2000); - + // Clean up on page load window.addEventListener('load', forceCleanupModals); <%- script %> - + \ No newline at end of file