Update CSS, add relationship between sensorModel and locationModel, and remove console.log statements
This commit is contained in:
parent
ba498a4d4b
commit
d38423fa6d
@ -9,13 +9,13 @@ const sequelize = new Sequelize(
|
|||||||
process.env.DB_USER,
|
process.env.DB_USER,
|
||||||
process.env.DB_PASS,
|
process.env.DB_PASS,
|
||||||
{
|
{
|
||||||
host: "mpsqldatabase.mysql.database.azure.com",
|
host: "mpsqldatabasean.mysql.database.azure.com",
|
||||||
dialect: 'mysql',
|
dialect: 'mysql',
|
||||||
// attributeBehavior?: 'escape' | 'throw' | 'unsafe-legacy';
|
// attributeBehavior?: 'escape' | 'throw' | 'unsafe-legacy';
|
||||||
attributeBehavior: 'escape',
|
attributeBehavior: 'escape',
|
||||||
dialectOptions: {
|
dialectOptions: {
|
||||||
ssl: {
|
ssl: {
|
||||||
ca: fs.readFileSync(path.resolve(__dirname, '../cert/DigiCertGlobalRootCA.crt.pem')),
|
ca: fs.readFileSync(path.resolve(__dirname, '../cert/DigiCertGlobalRootCA.crt_3.pem')),
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
|
2
api.MD
2
api.MD
@ -172,4 +172,4 @@ http://localhost/api/v0/sensor-data/data?week=1&sensorid=1&locationid=1&page=2&p
|
|||||||
curl localhost/api/v0/user/register -H "Content-Type: application/json" -X POST -d '{"username": "testuser123", "password": "thisisthesystemuserpasswordnoob", "email": "testuser123@ecosaver.com", "address": "Nanyang Polytechnic 180 Ang Mo Kio Avenue 8 Singapore 569830", "phone": "12345678"}'
|
curl localhost/api/v0/user/register -H "Content-Type: application/json" -X POST -d '{"username": "testuser123", "password": "thisisthesystemuserpasswordnoob", "email": "testuser123@ecosaver.com", "address": "Nanyang Polytechnic 180 Ang Mo Kio Avenue 8 Singapore 569830", "phone": "12345678"}'
|
||||||
|
|
||||||
|
|
||||||
curl localhost:3000/api/v0/token/new -H "Content-Type: application/json" -X POST -d '{"userid": "5", "permission": "canRead"}'
|
curl localhost/api/v0/token/new -H "Content-Type: application/json" -X POST -d '{"userid": "5", "permission": "canRead"}'
|
||||||
|
@ -50,49 +50,48 @@ app.use("/", require("./routes/render"));
|
|||||||
// Catch 404 and forward to error handler. If none of the above routes are
|
// Catch 404 and forward to error handler. If none of the above routes are
|
||||||
// used, this is what will be called.
|
// used, this is what will be called.
|
||||||
app.use(function (req, res, next) {
|
app.use(function (req, res, next) {
|
||||||
//application/json; charset=utf-8
|
//application/json; charset=utf-8
|
||||||
if (req.is("application/json" || "application/json; charset=utf-8")) {
|
var err = new Error("Not Found");
|
||||||
var err = new Error("Not Found");
|
err.message = "Page not found";
|
||||||
err.message = "Page not found";
|
err.status = 404;
|
||||||
err.status = 404;
|
next(err);
|
||||||
next(err);
|
|
||||||
} else {
|
|
||||||
res.status(404).render("404");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Error handler. This is where `next()` will go on error
|
// Error handler. This is where `next()` will go on error
|
||||||
app.use(function (err, req, res, next) {
|
app.use(function (err, req, res, next) {
|
||||||
console.error(err.status || res.status, err.name, req.method, req.url);
|
console.error(err.status || res.status, err.name, req.method, req.url);
|
||||||
if (![404].includes(err.status || res.status)) {
|
|
||||||
console.error(err.message);
|
|
||||||
console.error(err.stack);
|
|
||||||
console.error("=========================================");
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(err.name + " validation error");
|
// Parse key error for Sequilzw
|
||||||
// Parse key error for Sequilzw
|
let keyErrors = {};
|
||||||
let keyErrors = {};
|
if (["SequelizeValidationError"].includes(err.name) && err.errors) {
|
||||||
if (["SequelizeValidationError"].includes(err.name) && err.errors) {
|
for (let item of err.errors) {
|
||||||
for (let item of err.errors) {
|
if (item.path) {
|
||||||
if (item.path) {
|
keyErrors[item.path] = item.message;
|
||||||
keyErrors[item.path] = item.message;
|
}
|
||||||
}
|
}
|
||||||
}
|
res.status = 422;
|
||||||
res.status = 422;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (![404, 422].includes(err.status || res.status)) {
|
if (![404, 401, 422].includes(err.status || res.status)) {
|
||||||
console.error(err.message);
|
console.error(err.message);
|
||||||
console.error(err.stack);
|
console.error(err.stack);
|
||||||
console.error("=========================================");
|
console.error("=========================================");
|
||||||
}
|
}
|
||||||
|
res.status(err.status || 500);
|
||||||
|
// res.status(err.status || 500);
|
||||||
|
|
||||||
|
if (req.get('Content-Type') && req.get('Content-Type').includes("json")) {
|
||||||
res.status(err.status || 500);
|
res.json({
|
||||||
res.json({
|
name: err.name || "Unknown error",
|
||||||
name: err.name || "Unknown error",
|
message: err.message,
|
||||||
message: err.message,
|
keyErrors,
|
||||||
keyErrors,
|
});
|
||||||
});
|
}
|
||||||
});
|
else {
|
||||||
|
res.json({
|
||||||
|
name: err.name || "Unknown error",
|
||||||
|
message: err.message,
|
||||||
|
keyErrors,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -107,4 +107,6 @@ const sensorModel = sequelize.define(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
sensorModel.belongsTo(locationModel);
|
||||||
|
|
||||||
module.exports = { sensorModel };
|
module.exports = { sensorModel };
|
||||||
|
@ -3,7 +3,7 @@ const { Sequelize, DataTypes } = require("sequelize");
|
|||||||
const { sequelize } = require("../mySQL");
|
const { sequelize } = require("../mySQL");
|
||||||
const { userModel } = require("./userModel");
|
const { userModel } = require("./userModel");
|
||||||
|
|
||||||
//sequelize.sync();
|
sequelize.sync();
|
||||||
const tokenModel = sequelize.define(
|
const tokenModel = sequelize.define(
|
||||||
"token",
|
"token",
|
||||||
{
|
{
|
||||||
|
@ -9,13 +9,13 @@ const sequelize = new Sequelize(
|
|||||||
process.env.DB_USER,
|
process.env.DB_USER,
|
||||||
process.env.DB_PASS,
|
process.env.DB_PASS,
|
||||||
{
|
{
|
||||||
host: "mpsqldatabase.mysql.database.azure.com",
|
host: "mpsqldatabasean.mysql.database.azure.com",
|
||||||
dialect: 'mysql',
|
dialect: 'mysql',
|
||||||
// attributeBehavior?: 'escape' | 'throw' | 'unsafe-legacy';
|
// attributeBehavior?: 'escape' | 'throw' | 'unsafe-legacy';
|
||||||
attributeBehavior: 'escape',
|
attributeBehavior: 'escape',
|
||||||
dialectOptions: {
|
dialectOptions: {
|
||||||
ssl: {
|
ssl: {
|
||||||
ca: fs.readFileSync(path.resolve(__dirname, '../cert/DigiCertGlobalRootCA.crt.pem')),
|
ca: fs.readFileSync(path.resolve(__dirname, '../cert/DigiCertGlobalRootCA.crt_3.pem')),
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -1,19 +1,41 @@
|
|||||||
const { hash, compareHash } = require("./bcrypt.js");
|
|
||||||
const { tokenModel } = require("../database/model/tokenModel.js");
|
const { tokenModel } = require("../database/model/tokenModel.js");
|
||||||
|
const { userModel } = require("../database/model/userModel");
|
||||||
|
const { hash, compareHash } = require("./bcrypt.js");
|
||||||
const { generateUUID } = require("./generateUUID.js");
|
const { generateUUID } = require("./generateUUID.js");
|
||||||
|
const { isValid } = require("./isValid");
|
||||||
|
|
||||||
/*
|
async function getTokenByToken(token) {
|
||||||
1) take userid
|
const splitAuthToken = token.split("-");
|
||||||
2) generate random api key
|
const rowid = splitAuthToken[0];
|
||||||
3) hash the api key
|
const suppliedToken = splitAuthToken.slice(1).join("-");
|
||||||
4) append userid with - and api key
|
|
||||||
5) you give the user rowid-uuidv4
|
token = await tokenModel.findByPk(rowid, { include: userModel });
|
||||||
6) store in database
|
|
||||||
*/
|
token.isValid = await compareHash(suppliedToken, token.token); //true
|
||||||
//can be used for api key or token. Both are the same logic
|
console.log("function api getTokenByToken token", token.isValid);
|
||||||
async function addToken(userId, permission , expiry) {
|
token.isValid = token.isValid && isValid(token.expiration);
|
||||||
|
console.log("function api getTokenByToken token", token.isValid);
|
||||||
|
if (!token.isValid) {
|
||||||
|
//add boolean to token table
|
||||||
|
token.destroy();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
console.log(
|
||||||
|
"function api getTokenByToken token",
|
||||||
|
await compareHash(suppliedToken, token.token),
|
||||||
|
isValid("token" , token.expiration)
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
console.log(token.isValid);
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addToken(userId, permission, expiry) {
|
||||||
let uuid = await generateUUID();
|
let uuid = await generateUUID();
|
||||||
let hashtoken = await hash(uuid);
|
let hashtoken = await hash(uuid);
|
||||||
|
//console.log("user id", userId);
|
||||||
|
// return { token: token, userid: userRes.id, username: userRes.username };
|
||||||
|
// let token = await addToken(userRes.id , "canRead" , tokenToLive);
|
||||||
|
|
||||||
let token = await tokenModel.create({
|
let token = await tokenModel.create({
|
||||||
userid: userId,
|
userid: userId,
|
||||||
@ -26,23 +48,4 @@ async function addToken(userId, permission , expiry) {
|
|||||||
return token.id + "-" + uuid;
|
return token.id + "-" + uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkToken(Supplied, rowid) {
|
module.exports = { addToken, getTokenByToken };
|
||||||
try {
|
|
||||||
const retrivedToken = await tokenModel.findOne({
|
|
||||||
raw: true,
|
|
||||||
attributes: ["token", "permission"],
|
|
||||||
where: {
|
|
||||||
id: rowid,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
//console.log(retrivedKey.apikey);
|
|
||||||
if (compareHash(Supplied, retrivedToken.token)) {
|
|
||||||
//return true;
|
|
||||||
return retrivedToken.permission;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { addToken , checkToken };
|
|
||||||
|
@ -1,20 +1,14 @@
|
|||||||
const moment = require("moment");
|
|
||||||
const currentTime = moment().format("YYYY-MM-DD HH:mm:ss");
|
|
||||||
|
|
||||||
//time is taken from the token
|
//time is taken from the token
|
||||||
function isValid(time){
|
function isValid(time) {
|
||||||
const timeDiff = moment(currentTime).diff(time, "minutes");
|
|
||||||
|
|
||||||
if (timeDiff > 1) {
|
|
||||||
console.log(timeDiff);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
Math.floor(new Date(time).getTime() / 1000) <
|
||||||
|
Math.floor(new Date().getTime() / 1000)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = { isValid };
|
||||||
|
|
||||||
|
|
||||||
module.exports = { isValid };
|
|
||||||
|
@ -18,15 +18,19 @@ async function getSensorData() {
|
|||||||
const sensorData = await sensorDataModel.findAll();
|
const sensorData = await sensorDataModel.findAll();
|
||||||
return sensorData;
|
return sensorData;
|
||||||
}
|
}
|
||||||
|
let dataArray = [];
|
||||||
async function addSensorData(id_sensor, id_location, sensordata) {
|
async function addSensorData(id_sensor, id_location, sensordata) {
|
||||||
const sensorData = await sensorDataModel.create({
|
const sensorData = await sensorDataModel.create({
|
||||||
sensorid: id_sensor,
|
sensorid: id_sensor,
|
||||||
locationid: id_location,
|
locationid: id_location ,
|
||||||
measurement: sensordata,
|
measurement: sensordata.measurement,
|
||||||
});
|
});
|
||||||
io().emit('sensorData:new', sensorData)
|
//console.log("sensorData", sensorData);
|
||||||
|
//console.log("sensorData", sensordata);
|
||||||
|
dataArray.push(sensordata);
|
||||||
|
console.log("dataArray", dataArray);
|
||||||
|
|
||||||
|
io().emit('sensorData:new', dataArray)
|
||||||
return sensorData;
|
return sensorData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +65,14 @@ async function getSensorDataById(id) {
|
|||||||
});
|
});
|
||||||
return sensorData;
|
return sensorData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getLatestData() {
|
||||||
|
const sensorData = await sensorDataModel.findAll({
|
||||||
|
limit: 1,
|
||||||
|
order: [["createdAt", "DESC"]],
|
||||||
|
});
|
||||||
|
return sensorData;
|
||||||
|
}
|
||||||
var ormQuery = {};
|
var ormQuery = {};
|
||||||
var whereClause = {};
|
var whereClause = {};
|
||||||
var whereDate = {};
|
var whereDate = {};
|
||||||
@ -724,5 +736,6 @@ module.exports = {
|
|||||||
getSensorDataById,
|
getSensorDataById,
|
||||||
getData,
|
getData,
|
||||||
getDatabyRange,
|
getDatabyRange,
|
||||||
|
getLatestData,
|
||||||
|
|
||||||
};
|
};
|
@ -2,7 +2,6 @@ const { Op } = require('sequelize')
|
|||||||
const { hash, compareHash } = require("./bcrypt.js");
|
const { hash, compareHash } = require("./bcrypt.js");
|
||||||
const { addToken } = require("./api");
|
const { addToken } = require("./api");
|
||||||
const { userModel } = require("../database/model/userModel");
|
const { userModel } = require("../database/model/userModel");
|
||||||
moment = require('moment')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -71,9 +70,11 @@ async function loginUser(user) {
|
|||||||
if (!match) return false;
|
if (!match) return false;
|
||||||
//console.log('loginUser', userRes.id, userRes.username);
|
//console.log('loginUser', userRes.id, userRes.username);
|
||||||
|
|
||||||
//generate token and permission and experiation time
|
//generate token and permission and experiation time + 30 mins
|
||||||
const currentTime = moment().format('YYYY-MM-DD HH:mm:ss');
|
//let tokenToLive = moment().add(30, 'minutes').format();
|
||||||
let token = await addToken(userRes.id , "canRead" , currentTime);
|
let currentDate = new Date();
|
||||||
|
let tokenToLive = new Date(currentDate.getTime() + 30 * 60000);
|
||||||
|
let token = await addToken(userRes.id , "canRead" , tokenToLive);
|
||||||
return { token: token, userid: userRes.id, username: userRes.username };
|
return { token: token, userid: userRes.id, username: userRes.username };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,68 +1,36 @@
|
|||||||
const { tokenModel } = require("../database/model/tokenModel");
|
const { getTokenByToken } = require("../functions/api");
|
||||||
const { userModel } = require("../database/model/userModel");
|
|
||||||
const { compareHash } = require("../functions/bcrypt");
|
|
||||||
const { checkToken } = require("../functions/api");
|
|
||||||
const { isValid } = require("../functions/isValid");
|
|
||||||
|
|
||||||
|
const permissionError = new Error('PermissionError')
|
||||||
|
permissionError.name = "Inadequate Permission Error"
|
||||||
|
permissionError.status = 401
|
||||||
|
permissionError.message = "Inadequate permission to complete this response"
|
||||||
|
|
||||||
async function auth(req, res, next) {
|
async function auth(req, res, next) {
|
||||||
try {
|
try {
|
||||||
const authToken = req.header("auth-token");
|
const token = await getTokenByToken(req.header("auth-token"));
|
||||||
if (!authToken) {
|
|
||||||
const error = new Error("No Token key was supplied. Invalid request");
|
if (!token || !token.isValid){
|
||||||
throw error;
|
throw permissionError;
|
||||||
}
|
}
|
||||||
|
|
||||||
const splitAuthToken = authToken.split("-");
|
|
||||||
const rowid = splitAuthToken[0];
|
|
||||||
const suppliedToken = splitAuthToken.slice(1).join("-");
|
|
||||||
|
|
||||||
const token = await tokenModel.findByPk(rowid, { include: userModel });
|
|
||||||
|
|
||||||
if (!token) {
|
|
||||||
const error = new Error("Token key not found. Invalid request");
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isMatch = await compareHash(suppliedToken, token.token);
|
|
||||||
|
|
||||||
console.log(isMatch);
|
|
||||||
if (!isMatch) {
|
|
||||||
const error = new Error("Token key not found. Invalid request");
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
//if token is a match
|
//if token is a match
|
||||||
req.token = token;
|
req.token = token;
|
||||||
req.user = await token.getUser();
|
req.user = await token.getUser();
|
||||||
const permission = await checkToken(suppliedToken, rowid);
|
|
||||||
|
|
||||||
const route = req.originalUrl.split("?")[0]; // Removing query parameters
|
const route = req.originalUrl.split("?")[0]; // Removing query parameters
|
||||||
//if route is from user/ and permission is canRead allow it to do CRUD
|
//if route is from user/ and permission is canRead allow it to do CRUD
|
||||||
if (route.includes("/user/") && permission === "canRead") {
|
if (route.includes("/user/") && token.permission === "canRead") {
|
||||||
next();
|
return next();
|
||||||
}
|
}
|
||||||
if ((req.method === "GET" && permission === "canRead") || (["GET", "POST", "PUT", "DELETE"].includes(req.method) && permission === "canWrite")) {
|
if ((req.method === "GET" && token.permission === "canRead") || (["GET", "POST", "PUT", "DELETE"].includes(req.method) && token.permission === "canWrite")) {
|
||||||
next();
|
return next();
|
||||||
}
|
|
||||||
|
|
||||||
if (!isValid(token.expiration)){
|
|
||||||
req.token.destroy();
|
|
||||||
throw new Error("Token expired");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw permissionError
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { auth };
|
module.exports = { auth };
|
||||||
|
|
||||||
/*
|
|
||||||
else {
|
|
||||||
const error = new Error("Insufficient permission");
|
|
||||||
error.status = 401;
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
@ -3812,6 +3812,7 @@
|
|||||||
|
|
||||||
.card-text {
|
.card-text {
|
||||||
color: #000000;
|
color: #000000;
|
||||||
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* edit profile */
|
/* edit profile */
|
||||||
|
@ -186,9 +186,7 @@ app.auth = (function (app) {
|
|||||||
function isLoggedIn(callback) {
|
function isLoggedIn(callback) {
|
||||||
|
|
||||||
if (getToken()) {
|
if (getToken()) {
|
||||||
console.log("you shldnt appear at all");
|
|
||||||
return app.api.get("user/me", function (error, data) {
|
return app.api.get("user/me", function (error, data) {
|
||||||
console.log(error, data);
|
|
||||||
if (!error) app.auth.user = data;
|
if (!error) app.auth.user = data;
|
||||||
return callback(error, data);
|
return callback(error, data);
|
||||||
});
|
});
|
||||||
|
@ -18,5 +18,8 @@ router.use('/sensor', [auth, APIlogger], require('./sensor.js'));
|
|||||||
//sensor data route
|
//sensor data route
|
||||||
router.use('/sensor-data', [auth, APIlogger], require('./sensorData.js'));
|
router.use('/sensor-data', [auth, APIlogger], require('./sensorData.js'));
|
||||||
|
|
||||||
|
//latest sensor data to display on dashboard
|
||||||
|
router.use('/latest-sensor-data', [APIlogger], require('./latestsensorData.js'));
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
||||||
|
21
consumerWebsite/routes/latestsensorData.js
Normal file
21
consumerWebsite/routes/latestsensorData.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
const {
|
||||||
|
getLatestData,
|
||||||
|
|
||||||
|
} = require("../functions/sensorData");
|
||||||
|
|
||||||
|
const express = require("express");
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.get("/data", async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
console.log(req.query);
|
||||||
|
const data = await getLatestData();
|
||||||
|
res.status(200).json(data);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
@ -8,7 +8,7 @@ const router = express.Router();
|
|||||||
router.get("/me", async function (req, res, next) {
|
router.get("/me", async function (req, res, next) {
|
||||||
try {
|
try {
|
||||||
let user = await getUserByID(req.user);
|
let user = await getUserByID(req.user);
|
||||||
console.log(user);
|
//console.log(user);
|
||||||
res.json({
|
res.json({
|
||||||
user: user,
|
user: user,
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,17 @@
|
|||||||
<%- include('top') %>
|
<%- include('top') %>
|
||||||
<script>
|
<script>
|
||||||
//call socket.io
|
$(document).ready(async function () {
|
||||||
|
|
||||||
|
app.api.get('latest-sensor-data/data', function (error, data) {
|
||||||
|
//console.log(data[0]);
|
||||||
|
$.scope.LatestSensorData.push(data[0]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//call socket.io to get live data
|
||||||
app.socket.on("sensorData:new", function (data) {
|
app.socket.on("sensorData:new", function (data) {
|
||||||
console.log("new data!!")
|
|
||||||
console.log(data);
|
console.log(data[0]);
|
||||||
|
$.scope.LatestSensorData.update(data[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@ -53,56 +61,56 @@
|
|||||||
</header>
|
</header>
|
||||||
<!-- Page Content -->
|
<!-- Page Content -->
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="services-bar">
|
<div class="services-bar" jq-repeat="LatestSensorData">
|
||||||
<h1 class="my-4">Services</h1>
|
<h1 class="my-4">Services</h1>
|
||||||
<!-- Services Section -->
|
<!-- Services Section -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-3 mb-4">
|
<div class="col-lg-3 mb-4">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h4 class="card-header">Air Quality Index</h4>
|
<h4 class="card-header">Air Quality Index</h4>
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<p class="card-text display-4">15 - 18 PSI</p>
|
<p class="card-text display-4">{{ measurement.psi }} PSI</p>
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="card-footer">
|
||||||
<div class="col-lg-3 mb-4">
|
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
||||||
<div class="card">
|
|
||||||
<h4 class="card-header">Humidity</h4>
|
|
||||||
<div class="card-body text-center">
|
|
||||||
<p class="card-text display-4">70% - 75%</p>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-3 mb-4">
|
</div>
|
||||||
<div class="card">
|
<div class="col-lg-3 mb-4">
|
||||||
<h4 class="card-header">Temperature</h4>
|
<div class="card">
|
||||||
<div class="card-body text-center">
|
<h4 class="card-header">Humidity</h4>
|
||||||
<p class="card-text display-4">30° - 37°</p>
|
<div class="card-body text-center">
|
||||||
</div>
|
<p class="card-text display-4">{{ measurement.humidity }} %</p>
|
||||||
<div class="card-footer">
|
|
||||||
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="card-footer">
|
||||||
<div class="col-lg-3 mb-4">
|
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
||||||
<div class="card">
|
|
||||||
<h4 class="card-header">Another Category</h4>
|
|
||||||
<div class="card-body text-center">
|
|
||||||
<p class="card-text display-4">values</p>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-lg-3 mb-4">
|
||||||
|
<div class="card">
|
||||||
|
<h4 class="card-header">Temperature</h4>
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<p class="card-text display-4">{{ measurement.temperature }}°</p>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-3 mb-4">
|
||||||
|
<div class="card">
|
||||||
|
<h4 class="card-header">Wind Speed</h4>
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<p class="card-text display-4">{{ measurement.windspeed }} Km/h </p>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- /.row -->
|
<!-- /.row -->
|
||||||
</div>
|
</div>
|
||||||
<!-- About Section -->
|
<!-- About Section -->
|
||||||
|
@ -8,10 +8,9 @@
|
|||||||
|
|
||||||
<ul id="sensorDataList">
|
<ul id="sensorDataList">
|
||||||
<li jq-repeat='sensorData'>
|
<li jq-repeat='sensorData'>
|
||||||
rowid: {{ id }}
|
|
||||||
sensorId: {{ sensorid }}
|
sensorId: {{ sensorid }}
|
||||||
created: {{ createdAt }}
|
|
||||||
location: {{ locationid }}
|
location: {{ locationid }}
|
||||||
|
created: {{ createdAt }}
|
||||||
<br />
|
<br />
|
||||||
co: {{ measurement.co }}
|
co: {{ measurement.co }}
|
||||||
humidity: {{ measurement.humidity }}
|
humidity: {{ measurement.humidity }}
|
||||||
@ -30,7 +29,7 @@
|
|||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(async function () {
|
$(document).ready(async function () {
|
||||||
app.api.get('sensor-data/data?order=DESC&limit=40', function(error, data){
|
app.api.get('sensor-data/data?order=DESC&limit=6', function(error, data){
|
||||||
$.scope.sensorData.push(...data);
|
$.scope.sensorData.push(...data);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -57,9 +57,7 @@
|
|||||||
//check if user is logged in
|
//check if user is logged in
|
||||||
app.auth.isLoggedIn(function (error, data) {
|
app.auth.isLoggedIn(function (error, data) {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
console.log(error);
|
|
||||||
$.scope.getUsername.update(data);
|
$.scope.getUsername.update(data);
|
||||||
|
|
||||||
if (location.pathname == "/profile") {
|
if (location.pathname == "/profile") {
|
||||||
$.scope.getUserDetails.update(data);
|
$.scope.getUserDetails.update(data);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user