add test graphs with device, date and test filters

This commit is contained in:
prisar
2023-07-21 03:56:24 +05:30
parent 37dd99a18b
commit 0f955c4c4a
10 changed files with 449 additions and 165 deletions

88
package-lock.json generated
View File

@@ -11,12 +11,15 @@
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"axios": "^1.4.0",
"d3": "^7.8.5", "d3": "^7.8.5",
"d3-selection": "^3.0.0", "d3-selection": "^3.0.0",
"firebase": "^9.23.0", "firebase": "^9.23.0",
"lodash": "^4.17.21",
"moment": "^2.29.4", "moment": "^2.29.4",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-dropdown": "^1.11.0",
"react-flip-numbers": "^3.0.8", "react-flip-numbers": "^3.0.8",
"react-router-dom": "^6.14.2", "react-router-dom": "^6.14.2",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
@@ -6126,6 +6129,29 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/axios": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axios/node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/axobject-query": { "node_modules/axobject-query": {
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
@@ -6794,6 +6820,11 @@
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz",
"integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ=="
}, },
"node_modules/classnames": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"node_modules/clean-css": { "node_modules/clean-css": {
"version": "5.3.2", "version": "5.3.2",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz",
@@ -15566,6 +15597,11 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/psl": { "node_modules/psl": {
"version": "1.9.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
@@ -15839,6 +15875,18 @@
"react": "^18.2.0" "react": "^18.2.0"
} }
}, },
"node_modules/react-dropdown": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/react-dropdown/-/react-dropdown-1.11.0.tgz",
"integrity": "sha512-E2UWetRPxNdIhQahXw6b984ME7WmcgDj9AEAjrtS/oyLCFVo+2qkCfcS06C22JR0Zj+YLnygwv0Ozf6VKKDq7g==",
"dependencies": {
"classnames": "^2.2.3"
},
"peerDependencies": {
"react": "^0.14.7 || ^15.0.0-0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^0.14.7 || ^15.0.0-0 || ^16.0.0 || ^17.0.0|| ^18.0.0"
}
},
"node_modules/react-error-overlay": { "node_modules/react-error-overlay": {
"version": "6.0.11", "version": "6.0.11",
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
@@ -23246,6 +23294,28 @@
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz",
"integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==" "integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g=="
}, },
"axios": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
"requires": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
},
"dependencies": {
"form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
}
}
},
"axobject-query": { "axobject-query": {
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
@@ -23735,6 +23805,11 @@
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz",
"integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ=="
}, },
"classnames": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"clean-css": { "clean-css": {
"version": "5.3.2", "version": "5.3.2",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz",
@@ -29904,6 +29979,11 @@
} }
} }
}, },
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"psl": { "psl": {
"version": "1.9.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
@@ -30100,6 +30180,14 @@
"scheduler": "^0.23.0" "scheduler": "^0.23.0"
} }
}, },
"react-dropdown": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/react-dropdown/-/react-dropdown-1.11.0.tgz",
"integrity": "sha512-E2UWetRPxNdIhQahXw6b984ME7WmcgDj9AEAjrtS/oyLCFVo+2qkCfcS06C22JR0Zj+YLnygwv0Ozf6VKKDq7g==",
"requires": {
"classnames": "^2.2.3"
}
},
"react-error-overlay": { "react-error-overlay": {
"version": "6.0.11", "version": "6.0.11",
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",

View File

@@ -6,12 +6,15 @@
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"axios": "^1.4.0",
"d3": "^7.8.5", "d3": "^7.8.5",
"d3-selection": "^3.0.0", "d3-selection": "^3.0.0",
"firebase": "^9.23.0", "firebase": "^9.23.0",
"lodash": "^4.17.21",
"moment": "^2.29.4", "moment": "^2.29.4",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-dropdown": "^1.11.0",
"react-flip-numbers": "^3.0.8", "react-flip-numbers": "^3.0.8",
"react-router-dom": "^6.14.2", "react-router-dom": "^6.14.2",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",

View File

@@ -3,39 +3,9 @@ import './App.css';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import moment from 'moment'; import moment from 'moment';
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
import { getFirestore, collection, getDocs, doc, onSnapshot, query } from "firebase/firestore"; import { getFirestore, collection, getDocs, doc, onSnapshot, query } from "firebase/firestore";
import Card from './components/Card'; import Card from './components/Card';
import db from './firebase';
/* dev and test */
const firebaseConfig = {
apiKey: "AIzaSyBFl_YkJ5PMIvMY3G70313SyrqemjFnUv8",
authDomain: "hpos-af3cc.firebaseapp.com",
projectId: "hpos-af3cc",
storageBucket: "hpos-af3cc.appspot.com",
messagingSenderId: "650071678820",
appId: "1:650071678820:web:ce50538bf46632d46c6471",
measurementId: "G-6JHQ47S9DD"
};
// /* prod */
// const firebaseConfig = {
// apiKey: "AIzaSyBF4pLZReAedU4dWX1eRJNFNIaOIz2xk4s",
// authDomain: "hpos-prod.firebaseapp.com",
// projectId: "hpos-prod",
// storageBucket: "hpos-prod.appspot.com",
// messagingSenderId: "1012719870714",
// appId: "1:1012719870714:web:fcd00acef93f6612de5f43",
// measurementId: "G-B0NZ7DEF69"
// };
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
const db = getFirestore(app);
function App() { function App() {
const [mtests, setMtests] = useState([]); const [mtests, setMtests] = useState([]);
@@ -46,7 +16,7 @@ function App() {
const [positives, setPositives] = useState(0); const [positives, setPositives] = useState(0);
const [traits, setTraits] = useState(0); const [traits, setTraits] = useState(0);
const [diseases, setDiseases] = useState(0); const [diseases, setDiseases] = useState(0);
const [lastUpdate, setLastUpdate] = useState(''); const [lastUpdate, setLastUpdate] = useState(moment());
useEffect(() => { useEffect(() => {
@@ -143,7 +113,7 @@ function App() {
<div className='footer'> <div className='footer'>
<div className='last-update'> <div className='last-update'>
Updated at: {moment(lastUpdate).format("DD-MM-YYYY HH:mm:ss a")} Updated at: {moment(lastUpdate).format("DD-MM-YYYY hh:mm:ss a")}
</div> </div>
<div className='developer'> <div className='developer'>

View File

@@ -0,0 +1,111 @@
import React, { Component } from 'react';
import * as d3 from 'd3';
import './DeviceGraph.css';
import axios from 'axios';
class AbsorbanceGraph extends Component {
constructor(props) {
super(props);
this.state = { url: this.props.url };
}
componentDidMount() {
this.drawChart(this.props.url);
}
drawChart(url) {
if (!url) return;
var margin = { top: 20, right: 20, bottom: 30, left: 50 },
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
// define the line
var valueline = d3.line()
.x(function (d) { return x(d.wavelength); })
.y(function (d) { return y(d.calculation); });
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("#wavelength-graph").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g").attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
axios({
method: 'get',
url: url,
withCredentials: false,
secure: false,
responseType: 'blob',
headers: {
"Content-Type": "application/octet-stream"
},
})
.then(response => response.data.text())
.then((text) => {
const testData = d3.csvParse(text.replaceAll('"', '')).filter(x => { if (x.NM > 390 && x.NM < 650) return x; });;
testData.forEach(function (d) {
d.wavelength = d.NM;
d.calculation = +d.CA;
});
x.domain(d3.extent(testData, function (d) { return d.wavelength; }));
y.domain([0, d3.max(testData, function (d) { return d.calculation; })]);
svg.append("path")
.data([testData])
.attr("class", "line")
.attr("d", valueline);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
svg.append("g")
.call(d3.axisLeft(y));
});
// /* test graph */
// const testData = require('./testData.json').filter(x => { if (x.NM > 397 && x.NM < 580) return x; });
// testData.forEach(function (d) {
// d.wavelength = d.NM;
// d.calculation = +d.CA;
// });
// x.domain(d3.extent(testData, function (d) { return d.wavelength; }));
// y.domain([0, d3.max(testData, function (d) { return d.calculation; })]);
// svg.append("path")
// .data([testData])
// .attr("class", "line")
// .attr("d", valueline);
// svg.append("g")
// .attr("transform", "translate(0," + height + ")")
// .call(d3.axisBottom(x));
// svg.append("g")
// .call(d3.axisLeft(y));
}
render() {
return (
<div>
<div className='graph-card'>
<div id="wavelength-graph" style={{ margin: '1em' }}>
</div>
<div className='graph-title'>wavelength vs absorbance</div>
</div>
</div>
)
};
}
export default AbsorbanceGraph;

View File

@@ -7,8 +7,10 @@
.graph-card { .graph-card {
width: 80vw; width: 80vw;
background-color: white; background-color: white;
margin: 10px;
} }
.graph-title { .graph-title {
text-align: center; text-align: center;
font-weight: 600;
} }

View File

@@ -1,130 +1,70 @@
import React, { Component } from 'react'; import React, { useEffect, useState } from 'react';
import * as d3 from 'd3'; import * as d3 from 'd3';
import axios from 'axios';
import { query, collection, onSnapshot, getDocs } from 'firebase/firestore';
import './DeviceGraph.css'; import './DeviceGraph.css';
import AbsorbanceGraph from './AbsorbanceGraph';
import db from '../firebase';
class DeviceGraph extends Component { function DeviceGraph({url}) {
const [devices, setDevices] = useState([]);
const [hposTests, setHposTests] = useState(null);
componentDidMount() { async function getTests() {
this.drawChart(); try {
const testDataCol = collection(db, 'testData');
const testDataSnapshot = await getDocs(testDataCol);
const testDataList = testDataSnapshot.docs.map(doc => doc.data());
console.log(testDataList);
// setHposTests(testDataList);
return testDataList;
} catch (err) {
// log error
}
} }
drawChart() { // useEffect(() => {
var margin = { top: 20, right: 20, bottom: 30, left: 50 }, // const q = query(collection(db, "testData"));
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// set the ranges // const unsub = onSnapshot(q, (querySnapshot) => {
var x = d3.scaleTime().range([0, width]); // const testDevices = [];
var y = d3.scaleLinear().range([height, 0]); // querySnapshot.forEach((document) => {
// const hposTestData = document.data();
// // testDevices.push(hposTestData);
// // const { deviceSerialNo } = hposTestData;
// // console.log(document.data());
// });
// // setDevices(testDevices);
// });
// define the line // return () => unsub;
var valueline = d3.line() // }, []);
.x(function (d) { return x(d.wavelength); })
.y(function (d) { return y(d.calculation); });
// append the svg obgect to the body of the page // useEffect(() => {
// appends a 'group' element to 'svg' // // const q = query(collection(db, "testData"));
// moves the 'group' element to the top left margin
var svg = d3.select("#wavelength-graph").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g").attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// d3.csv("https://thingproxy.freeboard.io/fetch/https://firebasestorage.googleapis.com/v0/b/hpos-af3cc.appspot.com/o/255668896558B%204DDG%2FHPOSSC_255668896558B%204DDG.csv?alt=media&token=d63d0e5f-0845-4cb6-98c6-cbfb6904cfd7", function (error, data) { // // const unsub = onSnapshot(q, (querySnapshot) => {
// alert(data.length) // // const testDevices = [];
// // var data = [ // // querySnapshot.forEach((document) => {
// // { // // const hposTestData = document.data();
// // "year": 2006, // // // testDevices.push(hposTestData);
// // "population": 40 // // // const { deviceSerialNo } = hposTestData;
// // }, // // console.log(document.data());
// // { // // });
// // "year": 2008, // // setDevices(testDevices);
// // "population": 45 // // });
// // },
// // {
// // "year": 2010,
// // "population": 48
// // },
// // {
// // "year": 2012,
// // "population": 51
// // },
// // {
// // "year": 2014,
// // "population": 53
// // },
// // {
// // "year": 2016,
// // "population": 57
// // },
// // {
// // "year": 2017,
// // "population": 62
// // }
// // ];
// // console.log(data);
// // // if (error) throw error;
// // // format the data
// // data.forEach(function (d) {
// // d.year = d.year;
// // d.population = +d.population;
// // });
// // // Scale the range of the data // if (hposTests !== null) {
// // x.domain(d3.extent(data, function (d) { return d.year; })); // const result = getTests();
// // y.domain([0, d3.max(data, function (d) { return d.population; })]); // setHposTests(result);
// }
// }, []);
// // // Add the valueline path. return (
// // svg.append("path") <div>
// // .data([data]) <AbsorbanceGraph url={url} />
// // .attr("class", "line") </div>
// // .attr("d", valueline); );
// // // Add the X Axis
// // svg.append("g")
// // .attr("transform", "translate(0," + height + ")")
// // .call(d3.axisBottom(x));
// // // Add the Y Axis
// // svg.append("g")
// // .call(d3.axisLeft(y));
// });
/* test graph */
const testData = require('./testData.json').filter(x => { if (x.NM > 397 && x.NM < 580) return x; });
testData.forEach(function (d) {
d.wavelength = d.NM;
d.calculation = +d.CA;
});
x.domain(d3.extent(testData, function (d) { return d.wavelength; }));
y.domain([0, d3.max(testData, function (d) { return d.calculation; })]);
svg.append("path")
.data([testData])
.attr("class", "line")
.attr("d", valueline);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
svg.append("g")
.call(d3.axisLeft(y));
}
render() {
return (<div>
<div className='graph-card'>
<div id="wavelength-graph" style={{ margin: '1em' }}>
</div>
<div className='graph-title'>wavelength vs absorbance</div>
</div>
</div>);
}
} }
export default DeviceGraph; export default DeviceGraph;

View File

@@ -0,0 +1,49 @@
.device-dropdown {
width: 15vw;
margin: 5px;
font-weight: 600;
}
.day-dropdown {
width: 15vw;
margin: 5px;
font-weight: 600;
}
.test-dropdown {
width: 20vw;
margin: 5px;
font-weight: 600;
}
.dropdown-group {
display: flex;
flex-direction: row;
margin: 10px;
}
.person-details {
margin: 15px;
font-weight: 600;
font-size: larger;
}
.graph-person-conatiner {
display: flex;
flex-direction: row;
width: 100vw;
}
.refresh-graph-message {
margin: 15px;
font-weight: 600;
font-size: larger;
}
.clear-button {
background-color: aquamarine;
width: 5vw;
height: 5vh;
margin: 5px;
border-radius: 50%;
}

103
src/components/Devices.js Normal file
View File

@@ -0,0 +1,103 @@
import React, { useEffect, useState } from 'react';
import { query, collection, onSnapshot, getDocs } from 'firebase/firestore';
import * as _ from 'lodash';
import Dropdown from 'react-dropdown';
import 'react-dropdown/style.css';
import moment from 'moment';
import DeviceGraph from "./DeviceGraph";
import db from '../firebase';
import './Devices.css';
const Devices = () => {
const [device, setDevice] = useState("Select a device");
const [testDate, setTestDate] = useState("Select a test date");
const [curTest, setCurTest] = useState("Select a test");
const [curTestData, setCurTestData] = useState(null);
const [devices, setDevices] = useState([]);
const [days, setDays] = useState([]);
const [tests, setTests] = useState([]);
const [allTests, setAllTests] = useState(null);
const changeDevice = ({ value }) => {
console.log(value);
setDevice(value);
setDays([...new Set(allTests
.filter((x) => {
if (x.deviceSerialNumber === device) return x;
})
.map(x => moment(x.testTime).format("YYYY-MM-DD")))]);
// setTests(allTests
// .filter((x) => {
// if (x.deviceSerialNumber === device && x.testTime === ) return x;
// })
// .map(x => x.testTime));
}
const changeTestDate = ({ value }) => {
setTestDate(value);
setCurTest(null);
setCurTestData(null);
setTests(allTests
.filter((x) => {
if (x.deviceSerialNumber === device && moment(x.testTime).isBetween(moment(testDate).startOf('day'), moment(testDate).endOf('day'))) return x;
})
.map(x => x._id));
}
const changeTest = ({ value }) => {
setCurTest(null); setCurTestData(null);
if (curTest) alert('Click clear button first');
setCurTest(value);
setCurTestData(allTests.find(x => x._id === value));
}
useEffect(() => {
const q = query(collection(db, "testData"));
const unsub = onSnapshot(q, (querySnapshot) => {
const testDevices = new Set();
const hposTests = [];
querySnapshot.forEach((document) => {
const hposTestData = document.data();
hposTests.push(hposTestData);
const { deviceSerialNumber } = hposTestData;
testDevices.add(deviceSerialNumber);
// console.log(document.data());
});
const groups = [...testDevices];
// console.log(groups);
setDevices(groups);
setAllTests(hposTests);
});
return () => unsub;
}, [curTestData, curTest]);
return (
<div>
<div className='dropdown-group'>
<Dropdown className='device-dropdown' options={devices} onChange={changeDevice} value={device} placeholder="Select an option" />
<Dropdown className='day-dropdown' options={days} onChange={changeTestDate} value={testDate} placeholder="Select an option" />
<Dropdown className='test-dropdown' options={tests} onChange={changeTest} value={curTest} placeholder="Select an option" />
<button className='clear-button' onClick={() => { setCurTest(null); setCurTestData(null); }}>Clear</button>
</div>
<div className='graph-person-conatiner'>
{!curTestData && <div className='refresh-graph-message'>Select test device, date and person to get the detailed graph. Then, refresh or click clear button to render another entry.</div>}
{curTestData?.csvPath && <DeviceGraph url={curTestData?.csvPath} />}
{curTestData && <div className='person-details'>
deviceid: {curTestData?.deviceId},
kit serial: {curTestData?.kitSerial},
test time: {curTestData?.testTime},
result: {curTestData?.result}
<img src={curTestData?.userImageURL} width={100} height={150} />
</div>}
</div>
</div>
)
}
export default Devices;

View File

@@ -1,16 +1,35 @@
import firebase from "firebase"; import { getFirestore, collection, getDocs, doc, onSnapshot, query } from "firebase/firestore";
const firebaseConfig = { import { initializeApp } from "firebase/app";
apiKey: "AIzaSyBFl_YkJ5PMIvMY3G70313SyrqemjFnUv8", import { getAnalytics } from "firebase/analytics";
authDomain: "hpos-af3cc.firebaseapp.com",
projectId: "hpos-af3cc",
storageBucket: "hpos-af3cc.appspot.com",
messagingSenderId: "650071678820",
appId: "1:650071678820:web:ce50538bf46632d46c6471",
measurementId: "G-6JHQ47S9DD"
};
const firebaseApp = firebase.initializeApp(firebaseConfig); // /* dev and test */
const db = firebase.firestore(); // const firebaseConfig = {
// apiKey: "AIzaSyBFl_YkJ5PMIvMY3G70313SyrqemjFnUv8",
// authDomain: "hpos-af3cc.firebaseapp.com",
// projectId: "hpos-af3cc",
// storageBucket: "hpos-af3cc.appspot.com",
// messagingSenderId: "650071678820",
// appId: "1:650071678820:web:ce50538bf46632d46c6471",
// measurementId: "G-6JHQ47S9DD"
// };
/* prod */
const firebaseConfig = {
apiKey: "AIzaSyBF4pLZReAedU4dWX1eRJNFNIaOIz2xk4s",
authDomain: "hpos-prod.firebaseapp.com",
projectId: "hpos-prod",
storageBucket: "hpos-prod.appspot.com",
messagingSenderId: "1012719870714",
appId: "1:1012719870714:web:fcd00acef93f6612de5f43",
measurementId: "G-B0NZ7DEF69"
};
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
const db = getFirestore(app);
export default db; export default db;

View File

@@ -7,8 +7,7 @@ import {
import './index.css'; import './index.css';
import App from './App'; import App from './App';
import reportWebVitals from './reportWebVitals'; import reportWebVitals from './reportWebVitals';
import RegistraionChart from './RegistraionChart'; import Devices from './components/Devices';
import DeviceGraph from './components/DeviceGraph';
const router = createBrowserRouter([ const router = createBrowserRouter([
{ {
@@ -16,8 +15,8 @@ const router = createBrowserRouter([
element: <App />, element: <App />,
}, },
{ {
path: "/absorbance", path: "/testgraphs",
element: <DeviceGraph />, element: <Devices />,
} }
]); ]);