new static path
This commit is contained in:
422
src/AppOp.css
Normal file
422
src/AppOp.css
Normal file
@@ -0,0 +1,422 @@
|
||||
body {
|
||||
background-color: rgb(247, 245, 249);
|
||||
}
|
||||
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* ::-webkit-scrollbar {
|
||||
display: none;
|
||||
} */
|
||||
|
||||
.dashboard-title::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
width: 100%;
|
||||
font-family: Arial Black;
|
||||
text-align: center;
|
||||
align-self: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
font-size: xx-large;
|
||||
background-color: rgb(207, 235, 250);
|
||||
}
|
||||
|
||||
.last-update {
|
||||
width: 100%;
|
||||
font-size: small;
|
||||
text-align: center;
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
.developer {
|
||||
font-size: medium;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.dev-logo {
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.nscm-logo {
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.gov-logo {
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.gov-logo-1 {
|
||||
width: 1.79em;
|
||||
}
|
||||
|
||||
.gov-logo-3 {
|
||||
width: 1.79em;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
margin: 0 1em 0 1em;
|
||||
font-size: medium;
|
||||
}
|
||||
|
||||
.numeric-card {
|
||||
height: 30vh;
|
||||
width: 28vw;
|
||||
padding: 20px;
|
||||
box-shadow: 5px 10px 8px 10px #888888;
|
||||
border-radius: 15px;
|
||||
margin: 20px;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 320px) {
|
||||
.numeric-card {
|
||||
height: 200px;
|
||||
width: 300px;
|
||||
padding: 20px;
|
||||
box-shadow: 5px 10px 8px 10px #888888;
|
||||
border-radius: 15px;
|
||||
margin: 20px;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
color: black;
|
||||
font-size: 1em;
|
||||
font-weight: 600;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.card-data {
|
||||
color: black;
|
||||
font-size: 4em;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.cards-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cards-row {
|
||||
margin: 5px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
text-align: center;
|
||||
align-self: center;
|
||||
font-size: xx-large;
|
||||
background-color: rgb(207, 235, 250);
|
||||
}
|
||||
|
||||
.nscm-logo {
|
||||
width: 2em;
|
||||
}
|
||||
|
||||
.gov-logo {
|
||||
width: 2em;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
margin: 0 1em 0 1em;
|
||||
font-size: small;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 500px) {
|
||||
.numeric-card {
|
||||
height: 200px;
|
||||
width: 300px;
|
||||
padding: 20px;
|
||||
box-shadow: 5px 10px 8px 10px #888888;
|
||||
border-radius: 15px;
|
||||
margin: 20px;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
color: black;
|
||||
font-size: 1em;
|
||||
font-weight: 600;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.card-data {
|
||||
color: black;
|
||||
font-size: 8em;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.cards-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cards-row {
|
||||
margin: 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
text-align: center;
|
||||
align-self: center;
|
||||
font-size: xx-large;
|
||||
background-color: rgb(207, 235, 250);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 900px) {
|
||||
.numeric-card {
|
||||
height: 150px;
|
||||
width: 200px;
|
||||
padding: 20px;
|
||||
box-shadow: 5px 10px 8px 10px #888888;
|
||||
border-radius: 15px;
|
||||
margin: 20px;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
color: black;
|
||||
font-size: 1.5em;
|
||||
font-weight: 600;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.card-data {
|
||||
color: black;
|
||||
font-size: 4em;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.cards-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cards-row {
|
||||
margin: 5px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
text-align: center;
|
||||
align-self: center;
|
||||
font-size: xx-large;
|
||||
background-color: rgb(207, 235, 250);
|
||||
}
|
||||
|
||||
.title-text {
|
||||
font-size: x-large;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1200px) {
|
||||
.numeric-card {
|
||||
height: 200px;
|
||||
width: 320px;
|
||||
padding: 20px;
|
||||
box-shadow: 5px 10px 8px 10px #888888;
|
||||
border-radius: 15px;
|
||||
margin: 20px;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
color: black;
|
||||
font-size: 1.6em;
|
||||
font-weight: 600;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.card-data {
|
||||
color: black;
|
||||
font-size: 6em;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.cards-container {
|
||||
height: 90vh;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cards-row {
|
||||
margin: 5px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
height: 10vh;
|
||||
text-align: center;
|
||||
align-self: center;
|
||||
font-size: xx-large;
|
||||
background-color: rgb(207, 235, 250);
|
||||
}
|
||||
|
||||
.title-text {
|
||||
font-size: xx-large;
|
||||
}
|
||||
|
||||
.nscm-logo {
|
||||
width: 2em;
|
||||
}
|
||||
|
||||
.gov-logo {
|
||||
width: 2.5em;
|
||||
}
|
||||
|
||||
.gov-logo-3 {
|
||||
width: 2.5em;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 2560px) {
|
||||
.numeric-card {
|
||||
height: 30vh;
|
||||
width: 28vw;
|
||||
padding: 20px;
|
||||
box-shadow: 5px 10px 8px 10px #888888;
|
||||
border-radius: 15px;
|
||||
margin: 20px;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
color: black;
|
||||
font-size: 6em;
|
||||
font-weight: 600;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.card-data {
|
||||
color: black;
|
||||
font-size: 18em;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.cards-container {
|
||||
height: 90vh;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cards-row {
|
||||
margin: 20px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
text-align: center;
|
||||
align-self: center;
|
||||
background-color: rgb(207, 235, 250);
|
||||
}
|
||||
|
||||
.title-text {
|
||||
font-size: 2vw;
|
||||
}
|
||||
|
||||
.nscm-logo {
|
||||
width: 5em;
|
||||
}
|
||||
|
||||
.gov-logo-1 {
|
||||
width: 4em;
|
||||
}
|
||||
|
||||
.gov-logo {
|
||||
width: 5em;
|
||||
}
|
||||
|
||||
.gov-logo-3 {
|
||||
width: 5em;
|
||||
}
|
||||
}
|
||||
|
||||
div.chart {
|
||||
font-family: sans-serif;
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
div.bar {
|
||||
background-color: DarkRed;
|
||||
color: white;
|
||||
height: 3em;
|
||||
line-height: 3em;
|
||||
padding-right: 1em;
|
||||
margin-bottom: 2px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background-color: rgb(207, 235, 250);
|
||||
color: black;
|
||||
text-align: center;
|
||||
}
|
||||
120
src/AppOp.js
Normal file
120
src/AppOp.js
Normal file
@@ -0,0 +1,120 @@
|
||||
import './AppOp.css';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import { collection, onSnapshot, query } from "firebase/firestore";
|
||||
import Card from './components/Card';
|
||||
import db from './firebase';
|
||||
|
||||
function AppOp() {
|
||||
const [totalScreened, setTotalScreened] = useState(0);
|
||||
const [males, setMales] = useState(0);
|
||||
const [females, setFemales] = useState(0);
|
||||
const [normal, setNormal] = useState(0);
|
||||
// const [positives, setPositives] = useState(0);
|
||||
const [traits, setTraits] = useState(0);
|
||||
const [diseases, setDiseases] = useState(0);
|
||||
const [lastUpdate, setLastUpdate] = useState(moment());
|
||||
const [devMode, setDevMode] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
const q = query(collection(db, "patientData"));
|
||||
|
||||
const unsub = onSnapshot(q, (querySnapshot) => {
|
||||
const patients = [];
|
||||
let maleCount = 0;
|
||||
let femaleCount = 0;
|
||||
querySnapshot.forEach((document) => {
|
||||
const patient = document.data();
|
||||
patients.push(patient);
|
||||
const { gender } = patient;
|
||||
if (gender?.toLowerCase() === 'male') {
|
||||
maleCount++;
|
||||
}
|
||||
if (gender?.toLowerCase() === 'female') {
|
||||
femaleCount++;
|
||||
}
|
||||
});
|
||||
setTotalScreened(patients.length);
|
||||
setMales(maleCount);
|
||||
setFemales(femaleCount);
|
||||
setLastUpdate(moment());
|
||||
});
|
||||
|
||||
return () => unsub;
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const q = query(collection(db, "testData"));
|
||||
|
||||
const unsub = onSnapshot(q, (querySnapshot) => {
|
||||
const hposTests = [];
|
||||
let normalCount = 0;
|
||||
let traitCount = 0;
|
||||
let diseaseCount = 0;
|
||||
querySnapshot.forEach((document) => {
|
||||
const hposTestData = document.data();
|
||||
hposTests.push(hposTestData);
|
||||
const { result } = hposTestData;
|
||||
if (result === "NORMAL") {
|
||||
normalCount++;
|
||||
}
|
||||
if (result === 'SICKLECELLTRAIT') {
|
||||
traitCount++;
|
||||
}
|
||||
if (result === 'SICKLECELLDISEASE') {
|
||||
diseaseCount++;
|
||||
}
|
||||
});
|
||||
setNormal(normalCount);
|
||||
// setPositives(traitCount + diseaseCount);
|
||||
setTraits(traitCount);
|
||||
setDiseases(diseaseCount);
|
||||
setLastUpdate(moment());
|
||||
});
|
||||
|
||||
return () => unsub;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='dashboard-title'>
|
||||
<img className="nscm-logo" src={require('./logo_nobg.png')} alt='img' />
|
||||
<div className='title-text'>HPOS Sickle Cell Test Dashboard</div>
|
||||
<img className="gov-logo-1" src={require('./gov_logo2.png')} alt='img' />
|
||||
<img className="gov-logo" src={require('./gov_logo3.png')} alt='img' />
|
||||
<img className="gov-logo-3" src={require('./gov_logo4.png')} alt='img' />
|
||||
</div>
|
||||
|
||||
<div className='cards-container'>
|
||||
<div className='cards-row'>
|
||||
<Card title={"Total"} counter={"339"} color={'black'} backgroundColor={'rgb(254, 240, 227)'} />
|
||||
<Card title={"Normal"} counter={"211"} backgroundColor={'rgb(234, 240, 230)'} />
|
||||
<Card title={"Sickle Cell Disease HbSS"} counter={"48"} backgroundColor={'rgb(234, 246, 245)'} />
|
||||
</div>
|
||||
|
||||
<div className='cards-row'>
|
||||
<Card title={"Sickle Cell Trait HbAS"} counter={"80"} backgroundColor={'rgb(192,233, 199)'} />
|
||||
<Card title={"Males"} counter={"185"} backgroundColor={'rgb(237, 190, 190)'} />
|
||||
<Card title={"Female"} counter={"154"} backgroundColor={'rgb(249, 195, 195)'} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='footer'>
|
||||
<div className='last-update'>
|
||||
Updated at: {moment(lastUpdate).format("DD-MM-YYYY hh:mm:ss a")}
|
||||
</div>
|
||||
|
||||
<div className='developer' onClick={() => setDevMode(!devMode)}>
|
||||
Developed by <img className="dev-logo" alt='img' src={require('./smi-logo-120x120.webp')} /> ShanMukha
|
||||
</div>
|
||||
|
||||
{/* {devMode &&
|
||||
<div>dev mode is on</div>} */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default AppOp;
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
} from "react-router-dom";
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import AppOp from './AppOp';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
import Devices from './components/Devices';
|
||||
import TestAnalytics from './components/TestAnalytics';
|
||||
@@ -37,7 +38,11 @@ const router = createBrowserRouter([
|
||||
{
|
||||
path: "/calibrations",
|
||||
element: <Calibrations />,
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/op",
|
||||
element: <AppOp />,
|
||||
},
|
||||
]);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user