This commit is contained in:
Leo 2024-01-24 15:51:51 +08:00
parent 7e9b6af0ba
commit dae836e49b
12 changed files with 971 additions and 397 deletions

View File

@ -547,3 +547,107 @@ body.one-content-column-version .content thead {
#content-get-api .generate-key-button:hover {
background-color: #45a049; /* Darker green on hover */
}
.delete-key-button {
float: right; /* Align the button to the right */
margin-right: 78%;
margin-top: -40px; /* Adjust the margin-top value based on your layout */
/* Add any additional styling you want for the button */
}
#content-get-api .delete-key-button {
background-color: #af4c4c; /* Green background color */
color: white; /* White text color */
padding: 5px 11px; /* Padding for the button */
border: none; /* Remove button border */
border-radius: 5px; /* Add border-radius for rounded corners */
cursor: pointer; /* Add pointer cursor on hover */
font-size: 14px; /* Font size */
}
#content-get-api .delete-key-button:hover {
background-color: #a04545; /* Darker green on hover */
}
.generate-key-screen {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 30px;
width: 400px; /* Adjust the width as needed */
background-color: #ffffff;
border: 1px solid #eaeaea;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); /* Adjust the shadow as needed */
z-index: 1000;
border-radius: 12px; /* Slightly increased border-radius for a softer look */
overflow: hidden; /* Hide overflow content */
}
.generate-key-screen label {
display: block;
margin-bottom: 8px;
color: #333;
}
.generate-key-screen input {
width: 100%;
padding: 8px;
margin-bottom: 16px;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 4px;
}
.generate-key-screen button {
background-color: #4caf50;
color: #fff;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.generate-key-screen button:hover {
background-color: #45a049;
}
.generate-key-screen button + button {
margin-left: 8px;
background-color: #f44336;
}
.generate-key-screen button + button:hover {
background-color: #d32f2f;
}
.key-input {
display: flex;
align-items: center;
}
.key-input input {
flex: 1;
padding: 8px;
margin-right: 8px;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 4px;
}
.key-input button {
background-color: #4caf50;
color: #fff;
padding: 8px 12px;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.key-input button:hover {
background-color: #45a049;
}

View File

@ -0,0 +1,59 @@
.air-quality-container {
display: flex;
flex-direction: column;
width: 800px;
/* Adjust width as needed */
margin: 0 auto;
position: relative;
}
.chart-container {
background-color: #f5f5f5;
padding: 20px;
position: relative;
}
.button-container {
display: flex;
justify-content: space-between;
margin: 20px 0;
}
#download-container {
display: flex;
align-items: center;
margin-top: 20px; /* Adjust the margin-top for spacing */
}
button {
border: 1px solid #ddd;
border-radius: 5px;
padding: 5px 10px;
font-size: 14px;
cursor: pointer;
}
.data-table {
border-collapse: collapse;
width: 100%;
}
.graphbutton-container {
display: flex;
justify-content: center; /* Center the buttons horizontally */
margin: 20px 0;
}
button#barButton,
button#lineButton {
border: 1px solid #ddd;
border-radius: 5px;
padding: 5px 10px;
font-size: 14px;
cursor: pointer;
margin: 0 10px;
}

View File

@ -100,3 +100,16 @@ body {
background-color: #213f6d;
color: #fff;
}
.custom-btn {
display: inline-block;
padding: 10px 20px; /* Adjust padding as needed */
background-color: #3498db; /* Change background color */
color: #ffffff; /* Change text color */
text-decoration: none;
border-radius: 5px; /* Add rounded corners if desired */
}
.custom-btn:hover {
background-color: #2980b9; /* Change background color on hover */
}

View File

@ -0,0 +1,98 @@
function generateKey() {
// Create the overlay dynamically
var overlay = document.createElement('div');
overlay.className = 'overlay';
// Create the small screen dynamically
var generateKeyScreen = document.createElement('div');
generateKeyScreen.className = 'generate-key-screen';
// Generate random public and private keys
var publicKey = generateRandomKey();
var privateKey = generateRandomKey();
// Add input fields for Name, Public Key, Private Key, Key Type, and Created
generateKeyScreen.innerHTML = `
<label for="name">Name:</label>
<input type="text" id="name" name="name" required><br>
<label for="publicKey">Public Key:</label>
<input type="text" id="publicKey" name="publicKey" value="${publicKey}" readonly>
<button onclick="copyToClipboard('publicKey')">Copy</button><br>
<label for="privateKey">Private Key:</label>
<input type="text" id="privateKey" name="privateKey" value="${privateKey}" readonly>
<button onclick="copyToClipboard('privateKey')">Copy</button><br>
<label for="created">Created:</label>
<input type="text" id="created" name="created" value="${getCurrentDate()}" readonly><br>
<button onclick="saveKey()">Save Key</button>
<button onclick="closeGenerateKey()">Close</button>
`;
// Append the overlay and small screen to the body
document.body.appendChild(overlay);
document.body.appendChild(generateKeyScreen);
// Display the overlay and small screen
overlay.style.display = 'block';
generateKeyScreen.style.display = 'block';
}
function generateRandomKey() {
// Generate a random string as a key (you might want to use a more robust key generation method)
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
}
function getCurrentDate() {
// Get the current date and format it as 'YYYY-MM-DD'
return new Date().toISOString().split('T')[0];
}
function copyToClipboard(elementId) {
// Copy the text from the specified input field to the clipboard
var element = document.getElementById(elementId);
element.select();
document.execCommand('copy');
// Optionally, you can provide feedback to the user (e.g., display a tooltip)
alert('Copied to clipboard: ' + element.value);
}
function saveKey() {
// Retrieve values from input fields
var name = document.getElementById('name').value;
var publicKey = document.getElementById('publicKey').value;
var privateKey = document.getElementById('privateKey').value;
var created = document.getElementById('created').value;
// Create a new table row with the key information
var newRow = document.createElement('tr');
newRow.innerHTML = `
<td>${name}</td>
<td>${publicKey}</td>
<td>${privateKey}</td>
<td>${created}</td>
`;
// Append the new row to the table body
var tableBody = document.querySelector('#content-get-api tbody');
tableBody.appendChild(newRow);
// Optionally, you can close the small screen
closeGenerateKey();
}
function closeGenerateKey() {
var overlay = document.querySelector('.overlay');
var generateKeyScreen = document.querySelector('.generate-key-screen');
// Hide and remove the overlay and small screen from the DOM
overlay.style.display = 'none';
generateKeyScreen.style.display = 'none';
document.body.removeChild(overlay);
document.body.removeChild(generateKeyScreen);
}

View File

@ -0,0 +1,184 @@
const buttons = document.querySelectorAll('.button-container button');
const ctx = document.getElementById('dataChart').getContext('2d');
// Initial dataset (AQI)
const initialData = {
labels: ['', 'Jan 22 11:00 PM', '', '', 'Jan 23 2:00 AM', '', '', 'Jan 23 5:00 AM', '', '', 'Jan 23 8:00 AM', '',],
datasets: [{
label: 'AQI',
data: [50, 60, 60, 80, 30, 60, 54, 60, 43, 30, 60, 60],
backgroundColor: 'green',
borderColor: 'green',
}]
};
const chart = new Chart(ctx, {
type: 'bar',
data: initialData,
options: {
responsive: true,
title: {
display: true,
text: 'HISTORICAL'
},
subtitle: {
display: true,
text: 'Historic air quality graph for Singapore'
},
legend: {
display: false
},
tooltips: {
mode: 'index',
intersect: false,
callbacks: {
label: function (tooltipItem, data) {
const label = data.labels[tooltipItem.index];
return label + ': ' + data.datasets[0].data[tooltipItem.index];
}
}
},
scales: {
xAxes: [{
barPercentage: 0.6,
categoryPercentage: 0.7,
ticks: {
autoSkip: true,
},
maxRotation: 0,
minRotation: 0
}],
yAxes: [{
title: {
display: true,
text: 'Value'
}
}]
}
}
});
// Function to update chart data based on the selected button
const updateChart = (data) => {
chart.data = data;
chart.update();
};
// Event listener for button clicks
buttons.forEach(button => {
button.addEventListener('click', () => {
// Implement logic to switch data based on clicked button
const buttonId = button.id.toLowerCase();
let newData;
// Example: Switch data based on button clicked
switch (buttonId) {
case 'aqibutton':
newData = {
labels: ['', 'Jan 22 11:00 PM', '', '', 'Jan 23 2:00 AM', '', '', 'Jan 23 5:00 AM', '', '', 'Jan 23 8:00 AM', '',],
datasets: [{
label: 'AQI',
data: [50, 60, 60, 80, 30, 60, 54, 60, 43, 30, 60, 60],
backgroundColor: 'green',
borderColor: 'green',
}]
};
break;
case 'tempbutton':
newData = {
labels: ['Jan 22 11:00 PM', 'Jan 23 12:00 AM', 'Jan 23 1:00 AM', 'Jan 23 2:00 AM'],
datasets: [{
label: 'Temperature',
data: [25, 30, 40, 35],
backgroundColor: 'green',
borderColor: 'green',
}]
};
break;
case 'humbutton':
newData = {
labels: ['Jan 22 11:00 PM', 'Jan 23 12:00 AM', 'Jan 23 1:00 AM', 'Jan 23 2:00 AM'],
datasets: [{
label: 'Humidity',
data: [25, 30, 40, 35],
backgroundColor: 'green',
borderColor: 'green',
}]
};
break;
case 'pm25button':
newData = {
labels: ['Jan 22 11:00 PM', 'Jan 23 12:00 AM', 'Jan 23 1:00 AM', 'Jan 23 2:00 AM'],
datasets: [{
label: 'PM2.5',
data: [25, 30, 40, 35],
backgroundColor: 'green',
borderColor: 'green',
}]
};
break;
case 'pm10button':
newData = {
labels: ['Jan 22 11:00 PM', 'Jan 23 12:00 AM', 'Jan 23 1:00 AM', 'Jan 23 2:00 AM'],
datasets: [{
label: 'PM10',
data: [25, 30, 40, 35],
backgroundColor: 'green',
borderColor: 'green',
}]
};
break;
case 'o3button':
newData = {
labels: ['Jan 22 11:00 PM', 'Jan 23 12:00 AM', 'Jan 23 1:00 AM', 'Jan 23 2:00 AM'],
datasets: [{
label: 'O3',
data: [25, 30, 40, 35],
backgroundColor: 'green',
borderColor: 'green',
}]
};
break;
case 'no2button':
newData = {
labels: ['Jan 22 11:00 PM', 'Jan 23 12:00 AM', 'Jan 23 1:00 AM', 'Jan 23 2:00 AM'],
datasets: [{
label: 'NO2',
data: [25, 30, 40, 35],
backgroundColor: 'green',
borderColor: 'green',
}]
};
break;
case 'so2button':
newData = {
labels: ['Jan 22 11:00 PM', 'Jan 23 12:00 AM', 'Jan 23 1:00 AM', 'Jan 23 2:00 AM'],
datasets: [{
label: 'SO2',
data: [25, 30, 40, 35],
backgroundColor: 'green',
borderColor: 'green',
}]
};
break;
case 'cobutton':
newData = {
labels: ['Jan 22 11:00 PM', 'Jan 23 12:00 AM', 'Jan 23 1:00 AM', 'Jan 23 2:00 AM'],
datasets: [{
label: 'CO',
data: [25, 30, 40, 35],
backgroundColor: 'green',
borderColor: 'green',
}]
};
break;
default:
newData = initialData; // Default to initial data (AQI)
break;
}
updateChart(newData);
});
});

View File

@ -1,21 +1,21 @@
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%";
const pm25 = "10";
const pm10 = "20";
const so2 = "5";
const o3 = "35";
const co = "0.5";
const no2 = "15";
// Replace the following with actual data retrieval based on the region
const aqi = "15";
const temperature = "25°C";
const humidity = "60%";
const pm25 = "10";
const pm10 = "20";
const so2 = "5";
const o3 = "35";
const co = "0.5";
const no2 = "15";
infoContainer.innerHTML = `
infoContainer.innerHTML = `
<div class="additional-info-box">
<h3>Additional Information - ${region}</h3>
<button id="downloadCsvButton">Download CSV</button>
<button id="viewData">View Data</button>
<div class="info-item">
<span class="info-label">Air Quality Index:</span>
<span class="info-value">${aqi}</span>
@ -54,7 +54,13 @@ infoContainer.innerHTML = `
</div>
</div>
`;
var viewDataButton = document.getElementById("viewData");
// Add a click event listener to the button
viewDataButton.addEventListener("click", function () {
// Redirect to the "viewdata.ejs" page
window.location.href = "/viewdata";
});
// Remove the 'active' class from all info-box elements
const infoBoxes = document.querySelectorAll('.info-box');
@ -65,6 +71,8 @@ infoContainer.innerHTML = `
clickedBox.classList.add('active');
}
const defaultRegion = "North";
const defaultBox = document.getElementById(defaultRegion.toLowerCase());
defaultBox.classList.add('active');
@ -117,3 +125,4 @@ document.getElementById("central").addEventListener("click", function () {
updateAdditionalInfo("Central");
});

View File

@ -82,6 +82,11 @@ router.get("/contact", function (req, res, next) {
res.render("contact");
});
//data page
router.get("/viewdata", function (req, res, next) {
res.render("viewdata");
});
//api doc
router.get("/api", function (req, res, next) {
res.render("api");

View File

@ -5,7 +5,7 @@
https://github.com/ticlekiwi/API-Documentation-HTML-Template
!-->
<%- include('top') %>
<%- include('top') %>
<link rel="stylesheet" href="css/api.css" media="all">
<body class="one-content-column-version">
@ -39,12 +39,12 @@
<li class="scroll-to-link active" data-target="content-get-started">
<a>GET STARTED</a>
</li>
<li class="scroll-to-link" data-target="content-get-api">
<a>Generate API</a>
</li>
<li class="scroll-to-link" data-target="content-errors">
<a>Errors</a>
</li>
<li class="scroll-to-link" data-target="content-get-api">
<a>Generate API</a>
</li>
</ul>
</div>
</div>
@ -361,7 +361,10 @@
<div class="overflow-hidden content-section" id="content-get-api">
<div class="api-keys-header">
<h2>API Keys</h2>
<button class="generate-key-button">Generate Key</button>
<div class="button-container">
<button class="generate-key-button" onclick="generateKey()">Generate Key</button>
<button class="delete-key-button" onclick="deleteKeys()">Delete Keys</button>
</div>
<p>
You can generate API Keys here:
</p>
@ -371,7 +374,6 @@
<th>Name</th>
<th>Public Key</th>
<th>Private Key</th>
<th>Key Type</th>
<th>Created</th>
</tr>
</thead>
@ -380,7 +382,6 @@
<td>API Key</td>
<td>GR234-We34</td>
<td>greR-234-fEG</td>
<td>Type</td>
<td>2024-01-22</td>
</tr>
</tbody>
@ -390,9 +391,12 @@
</div>
</div>
</body>
<script src="js/api.js"></script>
<script src="js/apikey.js"></script>
</html>

View File

@ -82,6 +82,9 @@
</div>
</footer>
<script src="js/search.js"></script>
<script src="js/data.js"></script>
</body>
</html>

View File

@ -38,7 +38,11 @@
<br>
<br>
<script src="js/learnmore.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<%- include('bot') %>

View File

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PM2.5 Sub-Index Over Time</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<canvas id="pm25Chart"></canvas>
<script>
const ctx = document.getElementById('pm25Chart').getContext('2d');
const pm25Data = [37, 38, 39, 40, 41, 39, 38];
const timestamps = ["4pm", "7pm", "11pm", "3am", "7am", "11am", "3pm"];
const myChart = new Chart(ctx, {
type: 'line',
data: {
labels: timestamps,
datasets: [{
label: 'PM2.5 Sub-Index',
data: pm25Data,
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgba(255, 99, 132, 1)',
pointRadius: 5,
pointHitRadius: 10,
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'PM2.5 Sub-Index Over Time'
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
</body>
</html>

View File

@ -0,0 +1,43 @@
<%- include('top') %>
<link href="css/data.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<br>
<br>
<br>
<body>
<div class="air-quality-container">
<%#
<div class="graphbutton-container">
<button id="barButton">Bar Graph</button>
<button id="lineButton">Line Graph</button>
</div> %>
<div class="chart-container">
<canvas id="dataChart"></canvas>
</div>
<div class="button-container">
<button id="aqiButton">AQI</button>
<button id="tempButton">Temperature</button>
<button id="humButton">Humidity</button>
<button id="pm25Button">PM2.5</button>
<button id="pm10Button">PM10</button>
<button id="o3Button">O3</button>
<button id="no2Button">NO2</button>
<button id="so2Button">SO2</button>
<button id="coButton">CO</button>
</div>
<div class="download-container">
<p>Download data here:</p>
<button id="downloadCSVButton">Download CSV</button>
</div>
</div>
</body>
<br>
<br>
<%- include('bot') %>