/__mocks__/mocks.js"
33 | }
34 | };
--------------------------------------------------------------------------------
/jest.tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "esnext",
5 | "esModuleInterop": true,
6 | "jsx": "react",
7 | "sourceMap": false,
8 | "experimentalDecorators": true,
9 | "noImplicitUseStrict": true,
10 | "removeComments": true,
11 | "moduleResolution": "node",
12 | "lib": [
13 | "es2017",
14 | "dom"
15 | ],
16 | "typeRoots": [
17 | "node_modules/@types"
18 | ]
19 | },
20 | "exclude": [
21 | "node_modules",
22 | "out",
23 | ".next"
24 | ]
25 | }
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 | ///
4 |
5 | // NOTE: This file should not be edited
6 | // see https://nextjs.org/docs/basic-features/typescript for more information.
7 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | module.exports = {
3 | reactStrictMode: true,
4 | }
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint",
10 | "test": "jest",
11 | "test:watch": "jest --watch",
12 | "test:coverage": "jest --coverage --detectOpenHandles"
13 | },
14 | "dependencies": {
15 | "@emotion/react": "^11.4.1",
16 | "@emotion/styled": "^11.3.0",
17 | "@mui/icons-material": "^5.0.1",
18 | "@mui/material": "^5.0.2",
19 | "@types/node": "^16.7.7",
20 | "@types/react-dom": "^17.0.9",
21 | "@types/react-redux": "^7.1.18",
22 | "@types/react-transition-group": "^4.4.2",
23 | "axios": "^0.21.1",
24 | "bootstrap": "^5.1.0",
25 | "next": "11.1.0",
26 | "next-redux-wrapper": "^7.0.5",
27 | "node-sass": "^4.14.1",
28 | "react": "17.0.2",
29 | "react-dom": "17.0.2",
30 | "react-redux": "^7.2.4",
31 | "react-transition-group": "^4.4.2",
32 | "redux": "^4.1.1",
33 | "redux-thunk": "^2.3.0",
34 | "tslib": "^2.3.1"
35 | },
36 | "devDependencies": {
37 | "@types/enzyme": "^3.10.9",
38 | "@types/jest": "^27.0.1",
39 | "@types/react": "17.0.19",
40 | "@wojtekmaj/enzyme-adapter-react-17": "^0.6.3",
41 | "babel-core": "^6.26.3",
42 | "babel-jest": "^27.1.0",
43 | "babel-preset-env": "^1.7.0",
44 | "babel-preset-react": "^6.24.1",
45 | "enzyme": "^3.11.0",
46 | "eslint": "7.32.0",
47 | "eslint-config-next": "11.1.0",
48 | "identity-obj-proxy": "^3.0.0",
49 | "jest": "^27.1.0",
50 | "jsdom": "18.0.0",
51 | "jsdom-global": "3.0.2",
52 | "redux-devtools-extension": "^2.13.9",
53 | "ts-jest": "^27.0.5",
54 | "typescript": "4.4.2"
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Error_404:React.FC = () => {
4 | return (
5 |
6 |
This page in not found, try another path
7 |
8 | );
9 | };
10 |
11 | export default Error_404;
--------------------------------------------------------------------------------
/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import "../styles/globals.css";
2 | import type {AppProps} from "next/app";
3 | import Layout from "../components/Layout/Layout";
4 | import React from "react";
5 | import PageTransition from "../components/PageTransition";
6 | import {wrapper} from "../redux/store";
7 | import {ThemeProvider} from "@mui/material";
8 | import {THEME} from "../styles/theme/theme";
9 |
10 | function MyApp({Component, pageProps, router}: AppProps) {
11 | console.warn = () => {};
12 | return (
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | )
21 | }
22 |
23 | export default wrapper.withRedux(MyApp);
24 |
--------------------------------------------------------------------------------
/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {Grid, Typography, Button, Box} from "@mui/material";
3 | import {useRouter} from "next/router";
4 |
5 |
6 | const Index: React.FC = () => {
7 | const router = useRouter();
8 | const start = () => {
9 | router.push("/question/0");
10 | }
11 | const description = "We are the first open-source project that will help you identify your risk group by the most common diseases. 5 minutes to answer questions can not only determine your risk group but also help you live a long and happy life without diseases. Our artificial intelligence algorithms will be able to provide you with the necessary information to maintain and improve your health.";
12 | return (
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Doctorinna
22 |
23 |
24 |
25 |
26 |
27 |
28 | D
29 |
30 |
31 |
32 |
33 |
34 | ctorinna
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | Medical risk factor analyzer
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | {description}
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | );
78 | };
79 |
80 | export default Index;
--------------------------------------------------------------------------------
/pages/overview/[disease].tsx:
--------------------------------------------------------------------------------
1 | import React, {useEffect} from "react";
2 | import {Box, Grid, Typography} from "@mui/material";
3 | import {useRouter} from "next/router";
4 | import {useTypedSelector} from "../../hooks/useTypedSelector";
5 | import {useActions} from "../../hooks/useActions";
6 | import Chart from "../../components/Question/Chart";
7 | import {parseRisk} from "../../utils/risk";
8 |
9 | const Disease: React.FC = () => {
10 | const {query} = useRouter();
11 | const {disease} = query;
12 | const {fetchStatistics} = useActions();
13 | const {results, statistics} = useTypedSelector(state => state.questions);
14 | const index = results.findIndex((v) => v.disease.illness === disease);
15 | const result = results[index];
16 | useEffect(() => {
17 | fetchStatistics(disease as string);
18 | }, []);
19 | return (
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Doctorinna
28 |
29 |
30 |
31 |
32 |
33 | {result?.disease.illness}
34 |
35 |
36 | {"Risk is " + parseRisk(result.risk_factor) + "%"}
37 |
38 |
39 |
40 |
41 | {result.prescription}
42 |
43 |
44 |
45 |
46 |
47 |
48 | {result?.disease.description}
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | );
58 | };
59 |
60 | export default Disease;
61 |
--------------------------------------------------------------------------------
/pages/question/[id].tsx:
--------------------------------------------------------------------------------
1 | import React, {useEffect} from "react";
2 | import {Box, Button, Grid, Typography} from "@mui/material";
3 | import QuestionnaireHoc from "../../components/hoc/QuestionnaireHOC";
4 | import {AnswerType} from "../../redux/types/questions";
5 | import TopNav from "../../components/Layout/TopNav";
6 | import Question from "../../components/Question/Question";
7 | import {useActions} from "../../hooks/useActions";
8 | import {useTypedSelector} from "../../hooks/useTypedSelector";
9 | import {useRouter} from "next/router";
10 |
11 | const QuestionPage: React.FC = () => {
12 | const {fetchQuestions, saveAnswers, fetchCategories, postAnswers, fetchResults} = useActions();
13 | const {query, push} = useRouter();
14 | const id = Number(query.id);
15 | const state = useTypedSelector(state => state.questions);
16 | useEffect(() => {
17 | if (state.categories.length === 0) fetchCategories();
18 | }, []);
19 | useEffect(() => {
20 | fetchQuestions(state.categories[id]?.title);
21 | }, [state.categories, id]);
22 | const questions = state.questions;
23 | let answers: AnswerType[] = questions.map((q) => ({
24 | question: q.id.toString(),
25 | answer: ""
26 | }));
27 | const next = async () => {
28 | let ret = false;
29 | answers.forEach((answer, ind) => {
30 | if (answer.answer === "") {
31 | errors[ind] = true;
32 | ret = true;
33 | }
34 | })
35 | if (ret) return;
36 | saveAnswers(answers);
37 | if (id + 1 == state.categories.length) {
38 | postAnswers();
39 | fetchResults();
40 | push("/question/results");
41 | } else
42 | push("/question/" + (id + 1));
43 | };
44 | let errors = questions.map((q) => false);
45 | return (
46 |
47 |
48 |
49 |
50 |
51 |
52 | {questions.map((val, ind) => (
53 |
54 | {val.description}
55 | {
57 | answers[ind] = answer;
58 | }}
59 | hasError={errors[ind]}
60 | />
61 |
62 | ))}
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | );
78 | };
79 |
80 | export default QuestionPage;
--------------------------------------------------------------------------------
/pages/question/results.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import QuestionnaireHoc from "../../components/hoc/QuestionnaireHOC";
3 | import ResultsComponent from "../../components/Question/Results";
4 | const Results:React.FC = () => {
5 | return (
6 |
7 |
8 |
9 | );
10 | };
11 |
12 | export default Results;
--------------------------------------------------------------------------------
/public/DOCTOR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/DOCTOR.png
--------------------------------------------------------------------------------
/public/LIFE_SUPPORT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/LIFE_SUPPORT.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-01.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-02.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-03.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-04.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-05.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-06.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-07.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-08.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-09.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-10.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-11.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-12.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-13.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-14.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-15.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-16.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-17.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-18.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-19.png
--------------------------------------------------------------------------------
/public/PNG/Drawkit-Vector-Illustration-Medical-20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/PNG/Drawkit-Vector-Illustration-Medical-20.png
--------------------------------------------------------------------------------
/public/Poster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/Poster.png
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-01.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-02.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-03.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-04.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-05.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-06.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-07.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-08.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-09.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-10.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-11.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-12.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-13.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-14.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-15.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-16.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/SVG/Drawkit-Vector-Illustration-Medical-20.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/Vector.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/Vector.png
--------------------------------------------------------------------------------
/public/cardiovascular.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/cardiovascular.png
--------------------------------------------------------------------------------
/public/diabetes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/diabetes.png
--------------------------------------------------------------------------------
/public/stroke.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Doctorinna/frontend/ce6169d13fefdd9d45d2949eee3db7800573b984/public/stroke.png
--------------------------------------------------------------------------------
/redux/action-creators/index.ts:
--------------------------------------------------------------------------------
1 | import * as questions from "./questions";
2 |
3 | export default {
4 | ...questions
5 | }
--------------------------------------------------------------------------------
/redux/action-creators/questions.ts:
--------------------------------------------------------------------------------
1 | import {Dispatch} from "redux";
2 | import axios from "axios";
3 | import {getAllDiseases, getQuestions, getAllCategories, getResults, sendAnswers, getStatistics} from "../api";
4 | import {
5 | AnswerType,
6 | CategoryType,
7 | DiseaseType,
8 | QuestionType,
9 | Recommendation,
10 | Statistics
11 | } from "../types/questions";
12 | import {actions} from "../actions/questions";
13 | import {RootState} from "../reducers";
14 |
15 | export const fetchQuestions = (category: string) => async (dispatch: Dispatch) => {
16 | if(category == undefined)return;
17 | try {
18 | return await axios.get(getQuestions(category)).then(response => {
19 | dispatch(actions.fetchQuestions(response.data));
20 | }
21 | );
22 | } catch
23 | (e: any) {
24 | console.log(e.message)
25 | }
26 | }
27 | export const fetchDiseases = () => async (dispatch: Dispatch) => {
28 | try {
29 | return await axios.get(getAllDiseases()).then(response => {
30 | dispatch(actions.fetchDiseases(response.data));
31 | }
32 | );
33 | } catch
34 | (e: any) {
35 | console.log(e.message)
36 | }
37 | }
38 | export const fetchCategories = () => async (dispatch: Dispatch) => {
39 | try {
40 | return await axios.get(getAllCategories()).then(response => {
41 | dispatch(actions.fetchCategories(response.data));
42 | }
43 | );
44 | } catch
45 | (e: any) {
46 | console.log(e.message)
47 | }
48 | }
49 | export const saveAnswers = (answers: AnswerType[]) => async (dispatch: Dispatch) => {
50 | try {
51 | dispatch(actions.saveAnswers(answers));
52 | } catch
53 | (e: any) {
54 | console.log(e.message)
55 | }
56 | }
57 | export const fetchResults = () => async (dispatch: Dispatch, getState: ()=>RootState) => {
58 | try {
59 | const token = getState().questions.token;
60 | return await axios.get(getResults(token)).then(response => {
61 | dispatch(actions.fetchResults(response.data));
62 | }
63 | );
64 | } catch
65 | (e: any) {
66 | console.log(e.message)
67 | }
68 | }
69 | export const postAnswers = () => async (dispatch: Dispatch, getState: ()=>RootState) => {
70 | try {
71 | const answers = getState().questions.answers;
72 | await axios.post(sendAnswers(), answers).then(res => {
73 | dispatch(actions.saveToken(res.data));
74 | });
75 | } catch
76 | (e: any) {
77 | console.log(e.message)
78 | }
79 | }
80 | export const fetchStatistics = (illness: string) => async(dispatch: Dispatch, getState: ()=>RootState) => {
81 | try {
82 | const token = getState().questions.token
83 | return await axios.get(getStatistics(illness, token)).then(response => {
84 | dispatch(actions.fetchStatistics(response.data));
85 | })
86 | }
87 | catch (e: any) {
88 | console.log(e.message)
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/redux/actions/questions.ts:
--------------------------------------------------------------------------------
1 | import {actionTypes} from "../types/actions";
2 | import {
3 | AnswerType,
4 | CategoryType,
5 | DiseaseType,
6 | QuestionType,
7 | Recommendation,
8 | Statistics
9 | } from "../types/questions";
10 |
11 | export const actions = {
12 | fetchQuestions: (payload: QuestionType[]) => ({
13 | type: actionTypes.FETCH_QUESTIONS,
14 | payload
15 | }),
16 | fetchCategories: (payload: CategoryType[]) => ({
17 | type: actionTypes.FETCH_CATEGORIES,
18 | payload
19 | }),
20 | fetchDiseases: (payload: DiseaseType[]) => ({
21 | type: actionTypes.FETCH_DISEASES,
22 | payload
23 | }),
24 | saveAnswers: (payload: AnswerType[]) => ({
25 | type: actionTypes.SAVE_ANSWERS,
26 | payload
27 | }),
28 | fetchResults: (payload: Recommendation[]) => ({
29 | type: actionTypes.FETCH_RESULTS,
30 | payload
31 | }),
32 | fetchStatistics: (payload: Statistics) => ({
33 | type: actionTypes.FETCH_STATISTICS,
34 | payload
35 | }),
36 | saveToken: (payload: string) => ({
37 | type: actionTypes.SAVE_TOKEN,
38 | payload
39 | })
40 | }
--------------------------------------------------------------------------------
/redux/api.ts:
--------------------------------------------------------------------------------
1 | const urls = {
2 | HOST: "http://18.216.235.168",
3 | mappings: {
4 | API: "api",
5 | RISKS: "risks",
6 | DISEASES: "diseases",
7 | QUESTIONS: "questions",
8 | RESPONSE: "response",
9 | CATEGORIES: "categories",
10 | RESULT: "result",
11 | STATISTICS: "statistics"
12 | }
13 | }
14 | const getQuestions = (category: string) =>
15 | `${urls.HOST}/${urls.mappings.API}/${urls.mappings.RISKS}/${urls.mappings.QUESTIONS}/${category}`;
16 | const getAllDiseases = () =>
17 | `${urls.HOST}/${urls.mappings.API}/${urls.mappings.RISKS}/${urls.mappings.DISEASES}`;
18 | const getAllCategories = () =>
19 | `${urls.HOST}/${urls.mappings.API}/${urls.mappings.RISKS}/${urls.mappings.CATEGORIES}/`;
20 | const sendAnswers = () =>
21 | `${urls.HOST}/${urls.mappings.API}/${urls.mappings.RISKS}/${urls.mappings.RESPONSE}/`;
22 | const getResults = (token: string) =>
23 | `${urls.HOST}/${urls.mappings.API}/${urls.mappings.RISKS}/${urls.mappings.RESULT}/${token}/__all__`;
24 | const getStatistics = (illness: string, token: string) =>
25 | `${urls.HOST}/${urls.mappings.API}/${urls.mappings.RISKS}/${urls.mappings.RESULT}/${urls.mappings.STATISTICS}/${token}/${illness}`;
26 |
27 | export {getAllDiseases, getQuestions, sendAnswers, getAllCategories, getResults, getStatistics};
--------------------------------------------------------------------------------
/redux/reducers/index.ts:
--------------------------------------------------------------------------------
1 | import {reducer as questionsReducer} from "./questions";
2 | import {combineReducers} from "redux";
3 | import {HYDRATE} from "next-redux-wrapper";
4 |
5 | export const rootReducer = combineReducers({
6 | questions: questionsReducer
7 | });
8 |
9 | export type RootState = ReturnType;
10 |
11 | export const reducer = (state: any, action: any) => {
12 | if (action.type === HYDRATE) {
13 | const nextState = {
14 | ...state, // use previous state
15 | ...action.payload, // apply delta from hydration
16 | }
17 | if (state.count) nextState.count = state.count; // preserve count value on client side navigation
18 | return nextState
19 | } else {
20 | return rootReducer(state, action)
21 | }
22 | }
--------------------------------------------------------------------------------
/redux/reducers/questions.ts:
--------------------------------------------------------------------------------
1 | import {actions, actionTypes, questionsState} from "../types/actions";
2 |
3 | const initialState: questionsState = {
4 | questions: [],
5 | answers: [],
6 | results: [],
7 | diseases: [],
8 | categories: [],
9 | statistics: {
10 | country: [],
11 | your_region: []
12 | },
13 | token: ""
14 | }
15 |
16 | export const reducer = (state: questionsState = initialState, action: actions): questionsState => {
17 | switch (action.type) {
18 | case actionTypes.SAVE_TOKEN:
19 | return {...state, token: action.payload};
20 | case actionTypes.FETCH_QUESTIONS:
21 | return {...state, questions: action.payload};
22 | case actionTypes.FETCH_CATEGORIES:
23 | return {...state, categories: action.payload};
24 | case actionTypes.FETCH_DISEASES:
25 | return {...state, diseases: action.payload};
26 | case actionTypes.FETCH_RESULTS:
27 | return {...state, results: action.payload};
28 | case actionTypes.FETCH_STATISTICS:
29 | return {...state, statistics: action.payload};
30 | case actionTypes.SAVE_ANSWERS:
31 | const answers = state.answers.concat(action.payload);
32 | return {...state, answers: answers};
33 | default:
34 | return state;
35 | }
36 | }
--------------------------------------------------------------------------------
/redux/store.ts:
--------------------------------------------------------------------------------
1 | import {createStore, applyMiddleware, compose, Store} from "redux";
2 | import thunk from "redux-thunk";
3 | import {reducer, RootState} from "./reducers";
4 | import {Context, createWrapper} from "next-redux-wrapper";
5 |
6 | let composeEnhancers = compose;
7 |
8 | if(typeof window !== "undefined")
9 | composeEnhancers = (window as any)["__REDUX_DEVTOOLS_EXTENSION_COMPOSE__"] as typeof compose || compose;
10 |
11 | export const makeStore = (context?: Context) => createStore(reducer, undefined, composeEnhancers(applyMiddleware(thunk)));
12 | export const wrapper = createWrapper>(makeStore, {debug: false});
--------------------------------------------------------------------------------
/redux/types/actions.ts:
--------------------------------------------------------------------------------
1 | import {QuestionType, AnswerType, DiseaseType, CategoryType, Recommendation, Statistics} from "./questions";
2 |
3 | export interface questionsState {
4 | questions: QuestionType[],
5 | answers: AnswerType[],
6 | diseases: DiseaseType[],
7 | categories: CategoryType[],
8 | results: Recommendation[],
9 | statistics: Statistics,
10 | token: string
11 | }
12 |
13 | export enum actionTypes {
14 | FETCH_QUESTIONS = "FETCH_QUESTIONS",
15 | SAVE_ANSWERS = "SAVE_ANSWERS",
16 | FETCH_CATEGORIES = "FETCH_CATEGORIES",
17 | FETCH_DISEASES = "FETCH_DISEASES",
18 | FETCH_RESULTS = "FETCH_RESULTS",
19 | FETCH_STATISTICS = "FETCH_STATISTICS",
20 | SAVE_TOKEN = "SAVE_TOKEN"
21 | }
22 |
23 | interface fetchQuestionsAction {
24 | type: actionTypes.FETCH_QUESTIONS,
25 | payload: QuestionType[]
26 | }
27 |
28 | interface fetchStatisticsAction {
29 | type: actionTypes.FETCH_STATISTICS,
30 | payload: Statistics
31 | }
32 |
33 | interface saveAnswersAction {
34 | type: actionTypes.SAVE_ANSWERS,
35 | payload: AnswerType[]
36 | }
37 |
38 | interface fetchCategoriesAction {
39 | type: actionTypes.FETCH_CATEGORIES,
40 | payload: CategoryType[]
41 | }
42 | interface fetchDiseasesAction {
43 | type: actionTypes.FETCH_DISEASES,
44 | payload: DiseaseType[]
45 | }
46 | interface fetchResultsAction {
47 | type: actionTypes.FETCH_RESULTS,
48 | payload: Recommendation[]
49 | }
50 | interface saveTokenAction {
51 | type: actionTypes.SAVE_TOKEN,
52 | payload: string
53 | }
54 |
55 | export type actions = fetchQuestionsAction |
56 | saveAnswersAction |
57 | fetchDiseasesAction |
58 | fetchCategoriesAction |
59 | fetchResultsAction |
60 | fetchStatisticsAction |
61 | saveTokenAction;
--------------------------------------------------------------------------------
/redux/types/questions.ts:
--------------------------------------------------------------------------------
1 | interface Range {
2 | id: number;
3 | min: number;
4 | max: number;
5 | }
6 |
7 | interface Region {
8 | region: string;
9 | avg_factor: number;
10 | }
11 |
12 | interface LocalRegion {
13 | label: string;
14 | count: number;
15 | }
16 |
17 | export interface Option {
18 | id: number;
19 | answer: string;
20 | }
21 |
22 | interface Category {
23 | id: number;
24 | title: string
25 | }
26 | export interface QuestionType{
27 | id: number;
28 | description: string;
29 | category: Category;
30 | range: Range | null;
31 | options: Option[];
32 | }
33 |
34 | export interface DiseaseType {
35 | id: number;
36 | illness: string;
37 | description: string;
38 | }
39 |
40 | export interface CategoryType {
41 | id: number;
42 | title: string;
43 | }
44 |
45 | export interface AnswerType {
46 | question: string;
47 | answer: string;
48 | }
49 | export interface Recommendation {
50 | disease: DiseaseType;
51 | risk_factor: number
52 | prescription: string
53 | }
54 |
55 | export interface Statistics {
56 | country: Region[]
57 | your_region: LocalRegion[]
58 | }
--------------------------------------------------------------------------------
/router/nav.ts:
--------------------------------------------------------------------------------
1 | interface navProps{
2 | name: string,
3 | path: string
4 | }
5 |
6 | export const nav: navProps[] = [
7 | {
8 | name: "Home",
9 | path: "/"
10 | },
11 | {
12 | name: "Questions",
13 | path: "/questions"
14 | }
15 | ]
16 |
17 |
--------------------------------------------------------------------------------
/styles/Router.module.scss:
--------------------------------------------------------------------------------
1 | $timeout: 300ms;
2 | $transition: opacity $timeout ease-in-out, transform $timeout ease-in-out;
3 |
4 | .page-entering {
5 | transition: $transition;
6 | opacity: 1;
7 | transform: translateX(0);
8 | animation: "blink .3s linear 2";
9 | }
10 |
11 | .page-exiting {
12 | transition: $transition;
13 | opacity: 0;
14 | transform: translateX(-50px);
15 | }
16 |
17 | .page-exited {
18 | opacity: 0;
19 | transform: translateX(100%);
20 | }
21 |
22 | .page-entered {
23 | opacity: 0;
24 | transform: translateX(50px);
25 | }
26 |
--------------------------------------------------------------------------------
/styles/globals.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&family=Inter&family=Mulish&family=Rubik&display=swap');
2 |
3 | html,
4 | body {
5 | padding: 0;
6 | margin: 0;
7 | font-family:
8 | -apple-system,
9 | BlinkMacSystemFont,
10 | Segoe UI,
11 | Roboto,
12 | Oxygen,
13 | Ubuntu,
14 | Cantarell,
15 | Fira Sans,
16 | Droid Sans,
17 | Helvetica Neue,
18 | sans-serif;
19 | }
20 |
21 | a {
22 | color: inherit;
23 | text-decoration: none;
24 | }
25 |
26 | * {
27 | box-sizing: border-box;
28 | }
--------------------------------------------------------------------------------
/styles/theme/theme.ts:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {createTheme} from "@mui/material";
3 |
4 | declare module "@mui/material/styles" {
5 | interface TypographyVariants {
6 | home1: React.CSSProperties;
7 | home2: React.CSSProperties;
8 | home3: React.CSSProperties;
9 | home4: React.CSSProperties;
10 | questionTopNav1: React.CSSProperties;
11 | questionTopNav2: React.CSSProperties;
12 | questionTopNav3: React.CSSProperties;
13 | questionSideNav1: React.CSSProperties;
14 | questionSideNav2: React.CSSProperties;
15 | questionSideNav3: React.CSSProperties;
16 | results1: React.CSSProperties;
17 | diseases1: React.CSSProperties;
18 | diseases2: React.CSSProperties;
19 | diseases3: React.CSSProperties;
20 | diseases4: React.CSSProperties;
21 | }
22 |
23 | // allow configuration using `createTheme`
24 | interface TypographyVariantsOptions {
25 | home1?: React.CSSProperties;
26 | home2?: React.CSSProperties;
27 | home3?: React.CSSProperties;
28 | home4?: React.CSSProperties;
29 | questionTopNav1?: React.CSSProperties;
30 | questionTopNav2?: React.CSSProperties;
31 | questionTopNav3?: React.CSSProperties;
32 | questionSideNav1?: React.CSSProperties;
33 | questionSideNav2?: React.CSSProperties;
34 | questionSideNav3?: React.CSSProperties;
35 | results1?: React.CSSProperties;
36 | diseases1?: React.CSSProperties;
37 | diseases2?: React.CSSProperties;
38 | diseases3?: React.CSSProperties;
39 | diseases4?: React.CSSProperties;
40 | }
41 | }
42 |
43 | // Update the Typography's variant prop options
44 | declare module "@mui/material/Typography" {
45 | interface TypographyPropsVariantOverrides {
46 | home1: true;
47 | home2: true;
48 | home3: true;
49 | home4: true;
50 | questionTopNav1: true;
51 | questionTopNav2: true;
52 | questionTopNav3: true;
53 | questionSideNav1: true;
54 | questionSideNav2: true;
55 | questionSideNav3: true;
56 | results1: true;
57 | diseases1: true;
58 | diseases2: true;
59 | diseases3: true;
60 | diseases4: true;
61 | }
62 | }
63 | //1rem == 16px
64 | export const THEME = createTheme({
65 | palette: {
66 | secondary: {
67 | main: "#6562CE"
68 | }
69 | },
70 | typography: {
71 | home1: {
72 | fontFamily: "Mulish",
73 | fontStyle: "normal",
74 | fontWeight: "bold",
75 | fontSize: "2rem",
76 | lineHeight: "2.5rem",
77 | color: "#424242"
78 | },
79 | home2: {
80 | fontFamily: "Mulish",
81 | fontStyle: "normal",
82 | fontWeight: "bold",
83 | fontSize: "4rem",
84 | lineHeight: "5rem",
85 | color: "#5F5F5F"
86 | },
87 | home3: {
88 | fontFamily: "Mulish",
89 | fontStyle: "normal",
90 | fontWeight: "normal",
91 | fontSize: "1.5rem",
92 | lineHeight: "1.875rem",
93 | color: "#5F5F5F"
94 | },
95 | home4: {
96 | fontFamily: "Rubik",
97 | fontStyle: "normal",
98 | fontWeight: "normal",
99 | fontSize: "2rem",
100 | lineHeight: "2.375rem",
101 | color: "#000000"
102 | },
103 | questionTopNav1: {
104 | fontFamily: "Inter",
105 | fontStyle: "normal",
106 | fontWeight: "normal",
107 | fontSize: "1.125rem",
108 | lineHeight: "2rem",
109 | color: "#6562CE"
110 | },
111 | questionTopNav2: {
112 | fontFamily: "Inter",
113 | fontStyle: "normal",
114 | fontWeight: "bold",
115 | fontSize: "1.125rem",
116 | lineHeight: "2rem",
117 | color: "#2D3436"
118 | },
119 | questionTopNav3: {
120 | fontFamily: "Inter",
121 | fontStyle: "normal",
122 | fontWeight: "bold",
123 | fontSize: "1.125rem",
124 | lineHeight: "2rem",
125 | letterSpacing: "0.0125rem",
126 | color: "#EFAF00"
127 | },
128 | questionSideNav1: {
129 | fontFamily: "Mulish",
130 | fontStyle: "normal",
131 | fontWeight: "bold",
132 | fontSize: "2rem",
133 | lineHeight: "2.5rem",
134 | color: "#424242"
135 | },
136 | questionSideNav2: {
137 | fontFamily: "Rubik",
138 | fontStyle: "normal",
139 | fontWeight: "normal",
140 | fontSize: "2rem",
141 | lineHeight: "2.375rem",
142 | color: "#000000"
143 | },
144 | questionSideNav3: {
145 | fontFamily: "Rubik",
146 | fontStyle: "normal",
147 | fontWeight: "normal",
148 | fontSize: "2rem",
149 | lineHeight: "2.375rem",
150 | textDecorationLine: "underline",
151 | color: "#000000"
152 | },
153 | results1: {
154 | fontFamily: "Inter",
155 | fontStyle: "normal",
156 | fontWeight: 800,
157 | fontSize: "1.5rem",
158 | lineHeight: "1.8125rem",
159 | letterSpacing: "0.15625rem",
160 | textTransform: "uppercase",
161 | color: "#2D3436"
162 | },
163 | diseases1: {
164 | fontFamily: "Mulish",
165 | fontStyle: "normal",
166 | fontWeight: "bold",
167 | fontSize: "3.75rem",
168 | lineHeight: "4.5rem"
169 | },
170 | diseases2: {
171 | fontFamily: "Rubik",
172 | fontStyle: "normal",
173 | fontWeight: "bold",
174 | fontSize: "2rem",
175 | lineHeight: "2.375rem",
176 | },
177 | diseases3: {
178 | fontFamily: "Rubik",
179 | fontStyle: "normal",
180 | fontWeight: "normal",
181 | fontSize: "2rem",
182 | lineHeight: "2.375rem",
183 | },
184 | diseases4: {
185 | fontFamily: "IBM Plex Sans",
186 | fontStyle: "normal",
187 | fontWeight: "normal",
188 | fontSize: "1.5rem",
189 | lineHeight: "1rem",
190 | /* identical to box height, or 67% */
191 |
192 | textAlign: "right",
193 | letterSpacing: "0.025rem",
194 | textTransform: "capitalize",
195 |
196 | /* Light Color */
197 |
198 | color: "#FFFFFF"
199 | }
200 | }
201 | })
202 | ;
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "noImplicitAny": true,
17 | "noImplicitThis": true,
18 | "strictNullChecks": true,
19 | "importHelpers": true
20 | },
21 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
22 | "exclude": ["node_modules"]
23 | }
24 |
--------------------------------------------------------------------------------
/utils/risk.ts:
--------------------------------------------------------------------------------
1 | export const parseRisk = (risk: number) => {
2 | return Math.round(risk * 1000) / 10;
3 | };
4 | export const concatInOneString = (str: string) => {
5 | return str.split(" ").reduce((sum,prev) => (sum + prev), "")
6 | };
--------------------------------------------------------------------------------