update
This commit is contained in:
parent
47aaf71d10
commit
60c132d9ea
@ -1,4 +1,4 @@
|
|||||||
const mysql = require("mysql2");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
require('dotenv').config({ path: path.resolve(__dirname, '../.env') })
|
require('dotenv').config({ path: path.resolve(__dirname, '../.env') })
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const express = require("express");
|
const express = require("express");
|
||||||
const session = require("express-session");
|
const session = require("express-session");
|
||||||
const rateLimit = require('express-rate-limit');
|
const rateLimit = require('express-rate-limit');
|
||||||
const mysql2 = require('mysql2');
|
|
||||||
const bodyParser = require("body-parser");
|
const bodyParser = require("body-parser");
|
||||||
const bcrypt = require("bcrypt");
|
const bcrypt = require("bcrypt");
|
||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
@ -13,7 +13,7 @@ const { format } = require('date-fns');
|
|||||||
|
|
||||||
const { Sequelize } = require('sequelize');
|
const { Sequelize } = require('sequelize');
|
||||||
const { transporter } = require("./modules/nodeMailer");
|
const { transporter } = require("./modules/nodeMailer");
|
||||||
const { connection } = require("./modules/mysql");
|
|
||||||
const { sequelize, User } = require("./modules/mysql");
|
const { sequelize, User } = require("./modules/mysql");
|
||||||
const userLogs= require('./models/userLogs')(sequelize); // Adjust the path based on your project structure
|
const userLogs= require('./models/userLogs')(sequelize); // Adjust the path based on your project structure
|
||||||
const app = express();
|
const app = express();
|
||||||
@ -80,8 +80,6 @@ app.get("/login", (req, res) => {
|
|||||||
res.render("login", { error: null });
|
res.render("login", { error: null });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const limiter = rateLimit({
|
const limiter = rateLimit({
|
||||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||||
max: 5, // limit each IP to 3 requests per windowMs
|
max: 5, // limit each IP to 3 requests per windowMs
|
||||||
@ -168,7 +166,7 @@ app.post("/verify-otp", [
|
|||||||
const errors = validationResult(req);
|
const errors = validationResult(req);
|
||||||
|
|
||||||
if (!errors.isEmpty()) {
|
if (!errors.isEmpty()) {
|
||||||
return res.render('otp', { error: 'Invalid OTP. Please try again.', username: req.body.username, csrfToken: req.session.csrfToken });
|
return res.render('otp', { error: 'Invalid OTP. Please try again.'});
|
||||||
}
|
}
|
||||||
|
|
||||||
const enteredOTP = req.body.otp;
|
const enteredOTP = req.body.otp;
|
||||||
@ -223,12 +221,7 @@ app.post("/verify-otp", [
|
|||||||
|
|
||||||
app.get("/logout", async (req, res) => {
|
app.get("/logout", async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const username = req.session.username || "Unknown User";
|
const username = req.session.username ;
|
||||||
|
|
||||||
// Log the logout activity using Sequelize
|
|
||||||
await userLogs.create({ username, activity: "User logged out. Session destroyed." });
|
|
||||||
|
|
||||||
|
|
||||||
// Log the user out by clearing the session
|
// Log the user out by clearing the session
|
||||||
req.session.destroy(async (err) => {
|
req.session.destroy(async (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -238,7 +231,8 @@ app.post("/verify-otp", [
|
|||||||
await userLogs.create({ username, activity: "User logged out unsuccessfully. Session not destroyed." });
|
await userLogs.create({ username, activity: "User logged out unsuccessfully. Session not destroyed." });
|
||||||
} else {
|
} else {
|
||||||
console.log("Session destroyed.");
|
console.log("Session destroyed.");
|
||||||
|
// Log the logout activity using Sequelize
|
||||||
|
await userLogs.create({ username, activity: "User logged out. Session destroyed." });
|
||||||
// Clear the session token cookie
|
// Clear the session token cookie
|
||||||
res.clearCookie('sessionToken');
|
res.clearCookie('sessionToken');
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,102 @@
|
|||||||
img {
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
#map {
|
||||||
display: block;
|
display: block;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 100vh;
|
max-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#map-container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#north {
|
||||||
|
top: 25%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#south {
|
||||||
|
top: 60%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#east {
|
||||||
|
top: 50%;
|
||||||
|
left: 60%;
|
||||||
|
transform: translateX(-50%) translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#west {
|
||||||
|
top: 50%;
|
||||||
|
left: 40%;
|
||||||
|
transform: translateX(-50%) translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#central {
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%) translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box {
|
||||||
|
position: absolute;
|
||||||
|
background-color: rgba(255, 255, 255, 0.8);
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#north h3 {
|
||||||
|
color: #34d0db;
|
||||||
|
}
|
||||||
|
|
||||||
|
#south h3 {
|
||||||
|
color: #2ecc71;
|
||||||
|
}
|
||||||
|
|
||||||
|
#east h3 {
|
||||||
|
color: #3498db;
|
||||||
|
}
|
||||||
|
|
||||||
|
#west h3 {
|
||||||
|
color: #e74c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.additional-info-box {
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 20px auto; /* Center horizontally */
|
||||||
|
max-width: 300px auto; /* Adjust the maximum width as needed */
|
||||||
|
text-align: center; /* Center text horizontally */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-label {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-value {
|
||||||
|
color: #007bff; /* Adjust the color as needed */
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box.active {
|
||||||
|
background-color: #213f6d;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
0
consumerWebsite/public/documentation.html
Normal file
0
consumerWebsite/public/documentation.html
Normal file
87
consumerWebsite/public/js/learnmore.js
Normal file
87
consumerWebsite/public/js/learnmore.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
function updateAdditionalInfo(region) {
|
||||||
|
const infoContainer = document.getElementById("additional-info");
|
||||||
|
// Replace the following with actual data retrieval based on the region
|
||||||
|
const aqi = "15";
|
||||||
|
const temperature = "25°C";
|
||||||
|
const humidity = "60%";
|
||||||
|
|
||||||
|
infoContainer.innerHTML = `
|
||||||
|
<div class="additional-info-box">
|
||||||
|
<h3>Additional Information - ${region}</h3>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="info-label">Air Quality Index:</span>
|
||||||
|
<span class="info-value">${aqi}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="info-label">Temperature:</span>
|
||||||
|
<span class="info-value">${temperature}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="info-label">Humidity:</span>
|
||||||
|
<span class="info-value">${humidity}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Remove the 'active' class from all info-box elements
|
||||||
|
const infoBoxes = document.querySelectorAll('.info-box');
|
||||||
|
infoBoxes.forEach(box => box.classList.remove('active'));
|
||||||
|
|
||||||
|
// Add the 'active' class to the clicked info-box
|
||||||
|
const clickedBox = document.getElementById(region.toLowerCase());
|
||||||
|
clickedBox.classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultRegion = "North";
|
||||||
|
const defaultBox = document.getElementById(defaultRegion.toLowerCase());
|
||||||
|
defaultBox.classList.add('active');
|
||||||
|
const defaultAqi = "--"; // Replace with actual data retrieval
|
||||||
|
updateAdditionalInfo(defaultRegion, defaultAqi);
|
||||||
|
|
||||||
|
// Event listeners for each region's info-box
|
||||||
|
document.getElementById("north").addEventListener("click", function () {
|
||||||
|
const northAqi = "--"; // Replace with actual data retrieval
|
||||||
|
updateAdditionalInfo("North", northAqi);
|
||||||
|
});
|
||||||
|
document.getElementById("south").addEventListener("click", function () {
|
||||||
|
const southAqi = "--";
|
||||||
|
updateAdditionalInfo("South", southAqi);
|
||||||
|
});
|
||||||
|
document.getElementById("east").addEventListener("click", function () {
|
||||||
|
const eastAqi = "--";
|
||||||
|
updateAdditionalInfo("East", eastAqi);
|
||||||
|
});
|
||||||
|
document.getElementById("west").addEventListener("click", function () {
|
||||||
|
const westAqi = "--";
|
||||||
|
updateAdditionalInfo("West", westAqi);
|
||||||
|
});
|
||||||
|
document.getElementById("central").addEventListener("click", function () {
|
||||||
|
const centralAqi = "--";
|
||||||
|
updateAdditionalInfo("Central", centralAqi);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Event listeners for each region's info-box
|
||||||
|
document.getElementById("north").addEventListener("click", function () {
|
||||||
|
updateAdditionalInfo("North");
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("south").addEventListener("click", function () {
|
||||||
|
updateAdditionalInfo("South");
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("east").addEventListener("click", function () {
|
||||||
|
updateAdditionalInfo("East");
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("west").addEventListener("click", function () {
|
||||||
|
updateAdditionalInfo("West");
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("central").addEventListener("click", function () {
|
||||||
|
updateAdditionalInfo("Central");
|
||||||
|
});
|
||||||
|
|
19
consumerWebsite/public/js/search.js
Normal file
19
consumerWebsite/public/js/search.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
function searchFunction() {
|
||||||
|
// Get the search input value
|
||||||
|
var searchTerm = document.getElementById('searchInput').value.toLowerCase();
|
||||||
|
|
||||||
|
// Get all blog entries
|
||||||
|
var blogEntries = document.getElementById('blogEntries').getElementsByClassName('card');
|
||||||
|
|
||||||
|
// Loop through each blog entry and hide/show based on the search term
|
||||||
|
for (var i = 0; i < blogEntries.length; i++) {
|
||||||
|
var title = blogEntries[i].getElementsByClassName('card-title')[0].innerText.toLowerCase();
|
||||||
|
var text = blogEntries[i].getElementsByClassName('card-text')[0].innerText.toLowerCase();
|
||||||
|
|
||||||
|
if (title.includes(searchTerm) || text.includes(searchTerm)) {
|
||||||
|
blogEntries[i].style.display = 'block';
|
||||||
|
} else {
|
||||||
|
blogEntries[i].style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -54,10 +54,37 @@
|
|||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<div class="map">
|
<div id="map-container">
|
||||||
<img src="images/map.png" alt="Map Image">
|
<img src="images/map.png" alt="Singapore Map" id="map">
|
||||||
|
|
||||||
|
<!-- Information boxes for each region -->
|
||||||
|
<div class="info-box" id="north">
|
||||||
|
<h3>North</h3>
|
||||||
|
<p>Air Quality Index: 15 <span id="north-aqi"></span></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="info-box" id="south">
|
||||||
|
<h3>South</h3>
|
||||||
|
<p>Air Quality Index: 16 <span id="south-aqi"></span></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-box" id="east">
|
||||||
|
<h3>East</h3>
|
||||||
|
<p>Air Quality Index: 16 <span id="east-aqi"></span></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-box" id="west">
|
||||||
|
<h3>West</h3>
|
||||||
|
<p>Air Quality Index: 18 <span id="west-aqi"></span></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-box" id="central">
|
||||||
|
<h3>Central</h3>
|
||||||
|
<p>Air Quality Index: 17 <span id="central-aqi"></span></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div id="additional-info"></div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
@ -148,6 +175,7 @@
|
|||||||
<!-- Bootstrap core JavaScript -->
|
<!-- Bootstrap core JavaScript -->
|
||||||
<script src="vendor/jquery/jquery.min.js"></script>
|
<script src="vendor/jquery/jquery.min.js"></script>
|
||||||
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script src="js/learnmore.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
Loading…
x
Reference in New Issue
Block a user