19 Commits

Author SHA1 Message Date
Pritimay Sarkar
eb975ce11a update app links 2023-11-07 08:26:24 +05:30
Pritimay Sarkar
a3d2bea0cc add incubation time 2023-11-07 05:55:03 +05:30
Pritimay Sarkar
420171d24a add link in qc code 2023-09-30 11:56:08 +05:30
Pritimay Sarkar
dd4ee6d964 add qr code instructions 2023-09-27 02:07:24 +05:30
Pritimay Sarkar
62810fe81b add app installtion page 2023-09-25 01:47:27 +05:30
Pritimay Sarkar
aa08336f5f button css 2023-09-25 01:26:36 +05:30
Pritimay Sarkar
66838b6360 add clearusers api 2023-09-25 01:16:33 +05:30
Pritimay Sarkar
3774972839 add clear button 2023-09-25 00:20:42 +05:30
Pritimay Sarkar
924e48c1f0 add alerts commponents 2023-09-19 15:39:43 +05:30
Pritimay Sarkar
36879b6326 registration name 2023-09-10 09:50:35 +05:30
Pritimay Sarkar
327aa07735 add preprod setup 2023-09-07 11:22:05 +05:30
Pritimay Sarkar
f269b12da1 fix error for hemocube device in select 2023-09-07 11:21:52 +05:30
Pritimay Sarkar
cb0063e286 html tag 2023-09-05 18:44:32 +05:30
Pritimay Sarkar
3e01c94e46 add pdf generation 2023-08-29 16:29:57 +05:30
Pritimay Sarkar
cde2485a60 show user id after user registration 2023-08-28 18:23:39 +05:30
Pritimay Sarkar
9893161684 add user registration 2023-08-28 17:54:20 +05:30
Pritimay Sarkar
eecc6501df add data download page 2023-08-23 21:15:32 +05:30
Pritimay Sarkar
47d348d791 merge 2023-08-23 20:57:33 +05:30
Pritimay Sarkar
16b3f521d4 add sidebar with redux
- add store
	- add routes
	- add page wrapper, mainlayout
	- add nav folder
2023-08-01 15:38:22 +05:30
34 changed files with 4025 additions and 26 deletions

4
.gitignore vendored
View File

@@ -27,3 +27,7 @@ yarn-error.log*
src/components/testData.json src/components/testData.json
public/world-110m.json public/world-110m.json
public/india-states.json public/india-states.json
*.apk
scripts/reports
scripts/data

BIN
logo_nobg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

3007
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,11 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.14.1",
"@mui/material": "^5.14.2",
"@reduxjs/toolkit": "^1.9.5",
"@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",
@@ -14,10 +19,12 @@
"ml-savitzky-golay-generalized": "^4.0.1", "ml-savitzky-golay-generalized": "^4.0.1",
"moment": "^2.29.4", "moment": "^2.29.4",
"react": "^18.2.0", "react": "^18.2.0",
"react-datepicker": "^4.16.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-dropdown": "^1.11.0", "react-dropdown": "^1.11.0",
"react-flip-numbers": "^3.0.8", "react-flip-numbers": "^3.0.8",
"react-icons": "^4.10.1", "react-icons": "^4.10.1",
"react-redux": "^8.1.2",
"react-router-dom": "^6.14.2", "react-router-dom": "^6.14.2",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"react-select": "^5.7.4", "react-select": "^5.7.4",
@@ -49,5 +56,9 @@
"last 1 firefox version", "last 1 firefox version",
"last 1 safari version" "last 1 safari version"
] ]
},
"devDependencies": {
"csv-parser": "^3.0.0",
"html-pdf-node": "^1.0.8"
} }
} }

281
scripts/pdf.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -2,11 +2,27 @@ import './App.css';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import moment from 'moment'; import moment from 'moment';
import { BrowserRouter, Route, Routes } from "react-router-dom";
import MainLayout from "./components/MainLayout";
import { routes } from "./routes";
import { collection, onSnapshot, query } from "firebase/firestore"; import { collection, onSnapshot, query } from "firebase/firestore";
import Card from './components/Card'; import Card from './components/Card';
import db from './firebase'; import db from './firebase';
function App() { function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<MainLayout />}>
{routes}
</Route>
</Routes>
</BrowserRouter>
);
}
function App1() {
const [totalScreened, setTotalScreened] = useState(0); const [totalScreened, setTotalScreened] = useState(0);
const [males, setMales] = useState(0); const [males, setMales] = useState(0);
const [females, setFemales] = useState(0); const [females, setFemales] = useState(0);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

39
src/components/Alerts.js Normal file
View File

@@ -0,0 +1,39 @@
import React, { useEffect, useState, useRef } from 'react';
import { query, collection, onSnapshot } from 'firebase/firestore';
import './Alerts.css';
import db from '../firebase';
const Alerts = () => {
const [alerts, setAlerts] = useState([]);
useEffect(() => {
if (!allTests) {
const q = query(collection(db, "alerts"));
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);
});
const groups = [...testDevices];
// setDevices(groups);
setAlerts(hposTests);
});
return () => unsub;
}
}, []);
return (
<div>
{alerts.length}
</div>
)
}
export default Alerts;

View File

@@ -0,0 +1,4 @@
.app-qrcode {
height: 250px;
width: 250px;
}

View File

@@ -0,0 +1,35 @@
import React, { useEffect, useState, useRef } from 'react';
import { query, collection, onSnapshot } from 'firebase/firestore';
import './AppInstallation.css';
import db from '../firebase';
const AppInstallation = () => {
const [alerts, setAlerts] = useState([]);
useEffect(() => {
}, []);
return (
<div>
<div>
<div>Testing 2.1.27 (Preprod - 07-11-2023)</div>
<a href="https://www.dropbox.com/scl/fi/v0hux8qrby54rjns8mhum/hpos-testing_preprod_2.1.27.apk?rlkey=ias0fe0zq72avy01rk4cvzmvp&dl=1">
<img className="app-qrcode" src={require('../assets/hpos-testing_preprod.png')} alt='icon'></img>
</a>
</div>
<div>
<p>Steps to install:</p>
<p>
<ul>
<li>use an QR code scanner app to download the app</li>
<li>if the phone browser prompts an warning, select download anyway</li>
<li>install the downloaded apk and give permissions</li>
</ul>
</p>
</div>
</div>
)
}
export default AppInstallation;

View File

@@ -24,7 +24,7 @@ const Devices = () => {
setTestDate(null); setTestDate(null);
setCurTest(null); setCurTest(null);
setDays([...new Set(allTests setDays([...new Set(allTests
.filter((x) => x.deviceSerialNumber === value) .filter((x) => x.deviceSerialNumber === value || x.deviceId === value)
.map(x => moment(x.testTime).format("YYYY-MM-DD")))] .map(x => moment(x.testTime).format("YYYY-MM-DD")))]
.sort() .sort()
.reverse()); .reverse());
@@ -36,7 +36,7 @@ const Devices = () => {
setCurTestData(null); setCurTestData(null);
setShowGraph(false); setShowGraph(false);
setTests(allTests setTests(allTests
.filter((x) => x.deviceSerialNumber === device && moment(x.testTime).isBetween(moment(value).startOf('day'), moment(value).endOf('day'))) .filter((x) => (x.deviceSerialNumber === device || x.deviceId === device) && moment(x.testTime).isBetween(moment(value).startOf('day'), moment(value).endOf('day')))
.map(x => x._id) .map(x => x._id)
.sort()); .sort());
} }
@@ -70,8 +70,13 @@ const Devices = () => {
querySnapshot.forEach((document) => { querySnapshot.forEach((document) => {
const hposTestData = document.data(); const hposTestData = document.data();
hposTests.push(hposTestData); hposTests.push(hposTestData);
const { deviceSerialNumber } = hposTestData; const { deviceType, deviceId, deviceSerialNumber } = hposTestData;
testDevices.add(deviceSerialNumber); if (deviceType === 'HEMOCUBE' && deviceId) {
testDevices.add(deviceId);
}
if (deviceType !== 'HEMOCUBE' && deviceSerialNumber) {
testDevices.add(deviceSerialNumber);
}
}); });
const groups = [...testDevices]; const groups = [...testDevices];
setDevices(groups); setDevices(groups);

View File

@@ -0,0 +1,29 @@
.button {
background-color: #4CAF50;
/* Green */
border: none;
color: white;
/* padding: 15px 32px; */
padding: 5px 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 15px;
}
.dates {
flex-direction: row;
display: flex;
justify-content: center;
align-items: center;
margin: 1.5rem;
}
.start-date {
margin: 10px;
}
.end-date {
margin: 10px;
}

View File

@@ -0,0 +1,32 @@
import React, { useState } from 'react';
import DatePicker from "react-datepicker";
import moment from 'moment';
import "react-datepicker/dist/react-datepicker.css";
import './ExportData.css';
function ExportData({ url, show }) {
const [startDate, setStartDate] = useState("");
const [endDate, setEndDate] = useState("");
const fetchFile = (start_date, end_date) => {
window.location.href = `https://asia-south1-hpos-preprod.cloudfunctions.net/consolidation?start_date=${moment(startDate).format("YYYY-MM-DD")}&end_date=${moment(endDate).format("YYYY-MM-DD")}`;
}
return (
<div>
<div className='dates'>
<div className='start-date'>
<DatePicker selected={startDate} onChange={(date) => setStartDate(date)} placeholderText='start date' />
</div>
<div className='end-date'>
<DatePicker selected={endDate} onChange={(date) => setEndDate(date)} placeholderText='end date' />
</div>
<div className='button' onClick={() => fetchFile(startDate, endDate)}>Download Excel</div>
</div>
</div>
);
}
export default ExportData;

View File

@@ -0,0 +1,9 @@
import React from 'react';
const HomePage = (props) => {
return (
<div>HomePage</div>
);
};
export default HomePage;

View File

@@ -0,0 +1,38 @@
import { Outlet } from "react-router-dom";
import { Box, Toolbar } from "@mui/material";
import colorConfigs from "../configs/colorConfigs";
import sizeConfigs from "../configs/sizeConfigs";
import Sidebar from "./nav/Sidebar";
import Topbar from "./nav/Topbar";
const MainLayout = () => {
return (
<Box sx={{ display: "flex" }}>
<Topbar />
<Box
component="nav"
sx={{
width: sizeConfigs.sidebar.width,
flexShrink: 0
}}
>
<Sidebar />
</Box>
<Box
component="main"
sx={{
flexGrow: 1,
p: 3,
width: `calc(100% - ${sizeConfigs.sidebar.width})`,
minHeight: "100vh",
backgroundColor: colorConfigs.mainBg
}}
>
<Toolbar />
<Outlet />
</Box>
</Box>
);
};
export default MainLayout;

View File

@@ -0,0 +1,19 @@
import { useEffect } from "react";
import { useDispatch } from "react-redux";
import { setAppState } from "../store/appStateSlice";
const PageWrapper = (props) => {
const dispatch = useDispatch();
useEffect(() => {
if (props.state) {
dispatch(setAppState(props.state));
}
}, [dispatch, props]);
return (
<>{props.children}</>
);
};
export default PageWrapper;

View File

@@ -0,0 +1,28 @@
.message {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 80vw;
height: 50px;
background-color: rgb(187, 218, 174);
}
.user-creation {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.clear-users-button {
background-color: #b62200;
border: none;
color: white;
padding: 5px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 5px;
}

View File

@@ -0,0 +1,106 @@
import React, { useState } from 'react';
import moment from 'moment';
import axios from 'axios';
import './Registration.css';
function Registration() {
const [userId, setUserId] = useState("2808202300103SMIBLR");
const [counter, setCounter] = useState(0);
const [message, setMessage] = useState("");
const [name, setName] = useState("");
const createUser = () => {
setMessage("");
const id = moment().unix() + counter + "SMIBLR";
setCounter(counter + 1);
axios({
method: 'post',
url: "https://asia-south1-hpos-preprod.cloudfunctions.net/registerUser",
data: {
"_id": id,
"aadharId": "2808202300001",
"abhaId": "12434949797979",
"birthYear": "2000",
"bloodGroup": "",
"careOf": "",
"caste": "",
"city": "Bengaluru",
"district": "Bengaluru",
"gender": "Male",
"house": "42",
"maritalStatus": "Single",
"name": name ? name : "Web",
"phoneNumber": "9123456789",
"pinCode": "560060",
"registeredBy": "admin",
"registrationCenterName": "SMI",
"sickleCellHistory": null,
"state": "Karnataka",
"subCaste": "",
"testStatus": false,
"incubationTime": moment().subtract('15', 'minutes').utcOffset("+05:30").format("YYYY-MM-DD HH:mm:ss"),
"underMedication": false,
"underTransfusion": false,
"userImageURL": "https://hpos-prod.web.app/logo.png"
},
withCredentials: false,
secure: false,
headers: {
"Content-Type": "application/json",
"x-client": "e16a1bd15af2ee640f5a7a18c8d8333f5f01f7c66e003bbc21ee52870f1bce27",
},
})
.then(response => response.data)
.then((data) => {
setMessage(`${id} is being created`);
})
.catch((err) => {
console.log(err);
setMessage(`error: ${err?.message}`);
});
}
const clearsUsers = () => {
setMessage("");
axios({
method: 'get',
url: "https://asia-south1-hpos-preprod.cloudfunctions.net/clearUsers",
withCredentials: false,
secure: false,
headers: {
"Content-Type": "application/json",
// "x-client": "e16a1bd15af2ee640f5a7a18c8d8333f5f01f7c66e003bbc21ee52870f1bce27",
},
})
.then(response => response.data)
.then((data) => {
setMessage(`${data}`);
})
.catch((err) => {
console.log(err);
setMessage(`error: ${err?.message}`);
});
}
const onNameChange = (event) => {
setName(event.target.value);
}
return (
<div className="user-creation">
<label>
name:
<input name="name" value={name} placeholder="350umol kmon04" onChange={onNameChange} />
</label>
<div className='dates'>
<div className='button' onClick={() => createUser()}>Create User</div>
</div>
<div className='dates'>
<div className='clear-users-button' onClick={() => clearsUsers()}>Clear</div>
</div>
<div>{message && <div className='message'>{message}</div>}</div>
</div>
);
}
export default Registration;

View File

@@ -25,9 +25,9 @@ class TestAnalyticsGraph extends Component {
data.reverse(); data.reverse();
var margin = { top: 60, right: 20, bottom: 30, left: 50 }, var margin = { top: 30, right: 20, bottom: 50, left: 15 },
width = 520 - margin.left - margin.right, width = 1500 - margin.left - margin.right,
height = 220 - margin.top - margin.bottom; height = 180 - margin.top - margin.bottom;
var svg = d3.select("#tests-count-graph").append('svg') var svg = d3.select("#tests-count-graph").append('svg')
.attr("width", width + margin.left + margin.right) .attr("width", width + margin.left + margin.right)

View File

@@ -0,0 +1,50 @@
import { Avatar, Drawer, List, Stack, Toolbar } from "@mui/material";
// import assets from "../../assets";
import colorConfigs from "../../configs/colorConfigs";
import sizeConfigs from "../../configs/sizeConfigs";
import appRoutes from "../../routes/appRoutes";
import SidebarItem from "./SidebarItem";
import SidebarItemCollapse from "./SidebarItemCollapse";
const Sidebar = () => {
return (
<Drawer
variant="permanent"
sx={{
width: sizeConfigs.sidebar.width,
flexShrink: 0,
"& .MuiDrawer-paper": {
width: sizeConfigs.sidebar.width,
boxSizing: "border-box",
borderRight: "0px",
backgroundColor: colorConfigs.sidebar.bg,
color: colorConfigs.sidebar.color
}
}}
>
<List disablePadding>
<Toolbar sx={{ marginBottom: "20px" }}>
<Stack
sx={{ width: "100%" }}
direction="row"
justifyContent="center"
>
<Avatar src={require('../../smi-logo-120x120.webp')} />
</Stack>
</Toolbar>
{appRoutes.map((route, index) => (
route.sidebarProps ? (
route.child ? (
<SidebarItemCollapse item={route} key={index} />
) : (
<SidebarItem item={route} key={index} />
)
) : null
))}
</List>
</Drawer>
);
};
export default Sidebar;

View File

@@ -0,0 +1,34 @@
import { ListItemButton, ListItemIcon } from "@mui/material";
import { useSelector } from "react-redux";
import { Link } from "react-router-dom";
import colorConfigs from "../../configs/colorConfigs";
const SidebarItem = ({ item }) => {
const { appState } = useSelector((state) => state.appState);
return (
item.sidebarProps && item.path ? (
<ListItemButton
component={Link}
to={item.path}
sx={{
"&: hover": {
backgroundColor: colorConfigs.sidebar.hoverBg
},
backgroundColor: appState === item.state ? colorConfigs.sidebar.activeBg : "unset",
paddingY: "12px",
paddingX: "24px"
}}
>
<ListItemIcon sx={{
color: colorConfigs.sidebar.color
}}>
{item.sidebarProps.icon && item.sidebarProps.icon}
</ListItemIcon>
{item.sidebarProps.displayText}
</ListItemButton>
) : null
);
};
export default SidebarItem;

View File

@@ -0,0 +1,66 @@
import { Collapse, List, ListItemButton, ListItemIcon, ListItemText, Typography } from "@mui/material";
import { useEffect, useState } from "react";
import colorConfigs from "../../configs/colorConfigs";
import ExpandLessOutlinedIcon from '@mui/icons-material/ExpandLessOutlined';
import ExpandMoreOutlinedIcon from '@mui/icons-material/ExpandMoreOutlined';
import SidebarItem from "./SidebarItem";
import { useSelector } from "react-redux";
const SidebarItemCollapse = ({ item }) => {
const [open, setOpen] = useState(false);
const { appState } = useSelector((state) => state.appState);
useEffect(() => {
if (appState.includes(item.state)) {
setOpen(true);
}
}, [appState, item]);
return (
item.sidebarProps ? (
<>
<ListItemButton
onClick={() => setOpen(!open)}
sx={{
"&: hover": {
backgroundColor: colorConfigs.sidebar.hoverBg
},
paddingY: "12px",
paddingX: "24px"
}}
>
<ListItemIcon sx={{
color: colorConfigs.sidebar.color
}}>
{item.sidebarProps.icon && item.sidebarProps.icon}
</ListItemIcon>
<ListItemText
disableTypography
primary={
<Typography>
{item.sidebarProps.displayText}
</Typography>
}
/>
{open ? <ExpandLessOutlinedIcon /> : <ExpandMoreOutlinedIcon />}
</ListItemButton>
<Collapse in={open} timeout="auto">
<List>
{item.child?.map((route, index) => (
route.sidebarProps ? (
route.child ? (
<SidebarItemCollapse item={route} key={index} />
) : (
<SidebarItem item={route} key={index} />
)
) : null
))}
</List>
</Collapse>
</>
) : null
);
};
export default SidebarItemCollapse;

View File

@@ -0,0 +1,26 @@
import { AppBar, Toolbar, Typography } from "@mui/material";
import colorConfigs from "../../configs/colorConfigs";
import sizeConfigs from "../../configs/sizeConfigs";
const Topbar = () => {
return (
<AppBar
position="fixed"
sx={{
width: `calc(100% - ${sizeConfigs.sidebar.width})`,
ml: sizeConfigs.sidebar.width,
boxShadow: "unset",
backgroundColor: colorConfigs.topbar.bg,
color: colorConfigs.topbar.color
}}
>
<Toolbar>
<Typography variant="h6">
HPOS dashboard
</Typography>
</Toolbar>
</AppBar>
);
};
export default Topbar;

View File

@@ -0,0 +1,17 @@
import { colors } from "@mui/material";
const colorConfigs = {
sidebar: {
bg: "#233044",
color: "#eeeeee",
hoverBg: "#1e293a",
activeBg: "#1e253a"
},
topbar: {
bg: "#fff",
color: "#000"
},
mainBg: colors.grey["100"]
};
export default colorConfigs;

View File

@@ -0,0 +1,7 @@
const sizeConfigs = {
sidebar: {
width: "300px"
}
};
export default sizeConfigs;

View File

@@ -14,17 +14,28 @@ import { getAnalytics } from "firebase/analytics";
// measurementId: "G-6JHQ47S9DD" // measurementId: "G-6JHQ47S9DD"
// }; // };
/* preprod */
const firebaseConfig = {
apiKey: "AIzaSyB2-suWmKh2PgQbRmx7rzPjYhgoovQIsQ8",
authDomain: "hpos-preprod.firebaseapp.com",
projectId: "hpos-preprod",
storageBucket: "hpos-preprod.appspot.com",
messagingSenderId: "121176529204",
appId: "1:121176529204:web:6c0db8e642992192bbed61",
measurementId: "G-GYM6LRQ8KR"
};
/* prod */ // /* prod */
const firebaseConfig = { // const firebaseConfig = {
apiKey: "AIzaSyBF4pLZReAedU4dWX1eRJNFNIaOIz2xk4s", // apiKey: "AIzaSyBF4pLZReAedU4dWX1eRJNFNIaOIz2xk4s",
authDomain: "hpos-prod.firebaseapp.com", // authDomain: "hpos-prod.firebaseapp.com",
projectId: "hpos-prod", // projectId: "hpos-prod",
storageBucket: "hpos-prod.appspot.com", // storageBucket: "hpos-prod.appspot.com",
messagingSenderId: "1012719870714", // messagingSenderId: "1012719870714",
appId: "1:1012719870714:web:fcd00acef93f6612de5f43", // appId: "1:1012719870714:web:fcd00acef93f6612de5f43",
measurementId: "G-B0NZ7DEF69" // measurementId: "G-B0NZ7DEF69"
}; // };
const app = initializeApp(firebaseConfig); const app = initializeApp(firebaseConfig);

View File

@@ -4,6 +4,9 @@ import {
createBrowserRouter, createBrowserRouter,
RouterProvider, RouterProvider,
} from "react-router-dom"; } from "react-router-dom";
import { Provider } from 'react-redux';
import { store } from './store/store';
import './index.css'; import './index.css';
import App from './App'; import App from './App';
import reportWebVitals from './reportWebVitals'; import reportWebVitals from './reportWebVitals';
@@ -11,6 +14,7 @@ import Devices from './components/Devices';
import TestAnalytics from './components/TestAnalytics'; import TestAnalytics from './components/TestAnalytics';
import WorldMap from './components/WorldMap'; import WorldMap from './components/WorldMap';
import RegistraionChart from './RegistraionChart'; import RegistraionChart from './RegistraionChart';
import TestAnalyticsGraph from './components/TestAnalyticsGraph';
const router = createBrowserRouter([ const router = createBrowserRouter([
{ {
@@ -29,6 +33,10 @@ const router = createBrowserRouter([
path: "/analytics", path: "/analytics",
element: <TestAnalytics />, element: <TestAnalytics />,
}, },
{
path: "/hposdata",
element: <TestAnalyticsGraph />,
},
{ {
path: "/map", path: "/map",
element: <RegistraionChart />, element: <RegistraionChart />,
@@ -38,7 +46,11 @@ const router = createBrowserRouter([
const root = ReactDOM.createRoot(document.getElementById('root')); const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( root.render(
<RouterProvider router={router} /> <Provider store={store}>
{/* <CssBaseline /> */}
{/* <RouterProvider router={router} /> */}
<App />
</Provider>
); );
// If you want to start measuring performance in your app, pass a function // If you want to start measuring performance in your app, pass a function

66
src/routes/appRoutes.js Normal file
View File

@@ -0,0 +1,66 @@
import DashboardOutlinedIcon from '@mui/icons-material/DashboardOutlined';
import AppsOutlinedIcon from '@mui/icons-material/AppsOutlined';
import TestAnalytics from "../components/TestAnalytics";
import HomePage from '../components/HomePage';
import Devices from '../components/Devices';
import { Download } from '@mui/icons-material';
import ExportData from '../components/ExportData';
import Registration from '../components/Registration';
import { FaAndroid, FaPhone, FaUser } from 'react-icons/fa';
import AppInstallation from '../components/AppInstallation';
const appRoutes = [
{
index: true,
element: <HomePage />,
state: "home"
},
{
path: "/analytics",
element: <TestAnalytics />,
state: "analytics",
sidebarProps: {
displayText: "Analytics",
icon: <DashboardOutlinedIcon />
}
},
{
path: "/tests/insights",
element: <Devices />,
state: "insights",
sidebarProps: {
displayText: "Insights",
icon: <AppsOutlinedIcon />
}
},
{
path: "/downloaddata",
element: <ExportData />,
state: "downloaddata",
sidebarProps: {
displayText: "Data Download",
icon: <Download />
}
},
{
path: "/registration",
element: <Registration />,
state: "registration",
sidebarProps: {
displayText: "Registration",
icon: <FaUser />
}
},
{
path: "/appinstallation",
element: <AppInstallation />,
state: "appinstallation",
sidebarProps: {
displayText: "App Installation",
icon: <FaAndroid />
}
},
]
export default appRoutes;

34
src/routes/index.js Normal file
View File

@@ -0,0 +1,34 @@
import { Route } from "react-router-dom";
import PageWrapper from "../components/PageWrapper";
import appRoutes from "./appRoutes";
const generateRoute = (routes) => {
return routes.map((route, index) => (
route.index ? (
<Route
index
path={route.path}
element={<PageWrapper state={route.state}>
{route.element}
</PageWrapper>}
key={index}
/>
) : (
<Route
path={route.path}
element={
<PageWrapper state={route.child ? undefined : route.state}>
{route.element}
</PageWrapper>
}
key={index}
>
{route.child && (
generateRoute(route.child)
)}
</Route>
)
));
};
export const routes = generateRoute(appRoutes);

View File

@@ -0,0 +1,21 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
const initialState = {
appState: ""
};
export const appStateSlice = createSlice({
name: "appState",
initialState,
reducers: {
setAppState: (state, action) => {
state.appState = action.payload;
}
}
});
export const {
setAppState
} = appStateSlice.actions;
export default appStateSlice.reducer;

8
src/store/store.js Normal file
View File

@@ -0,0 +1,8 @@
import { configureStore } from "@reduxjs/toolkit";
import appStateSlice from "./appStateSlice";
export const store = configureStore({
reducer: {
appState: appStateSlice
}
});