github.com/lauslim12/expert-systems@v0.0.0-20221115131159-018513aad29c/web/src/components/Tuberculosis.tsx (about)

     1  import { Button, Text, useToast, VStack } from '@chakra-ui/react';
     2  import { lazy, memo, Suspense, useState } from 'react';
     3  import { useTranslation } from 'react-i18next';
     4  
     5  import type Request from '../types/Request';
     6  import type Response from '../types/Response';
     7  import type { StateCertaintyWeight } from '../types/UserCertaintyWeight';
     8  import request from '../utils/request';
     9  import FailedToast from './FailedToast';
    10  import AnswerInput from './Input/AnswerInput';
    11  
    12  /**
    13   * Lazy-load modal, as it is not displayed right away.
    14   */
    15  const ResultModal = lazy(() => import('../components/Modal/ResultModal'));
    16  
    17  /**
    18   * Tuberculosis component to infer, render, and handle user inputs about this disease.
    19   *
    20   * @returns React Functional Component
    21   */
    22  const Tuberculosis = () => {
    23    const [isLoading, setIsLoading] = useState(false);
    24    const [openResult, setOpenResult] = useState(false);
    25    const [result, setResult] = useState({} as Response);
    26    const [fever, setFever] = useState(null as StateCertaintyWeight);
    27    const [coughBlood, setCoughBlood] = useState(null as StateCertaintyWeight);
    28    const [spBloody, setSpBloody] = useState(null as StateCertaintyWeight);
    29    const [nightSweat, setNightSweat] = useState(null as StateCertaintyWeight);
    30    const [chestPain, setChestPain] = useState(null as StateCertaintyWeight);
    31    const [backPain, setBackPain] = useState(null as StateCertaintyWeight);
    32    const [shortBreath, setShortBreath] = useState(null as StateCertaintyWeight);
    33    const [weightLoss, setWeightLoss] = useState(null as StateCertaintyWeight);
    34    const [bodyTired, setBodyTired] = useState(null as StateCertaintyWeight);
    35    const [lumps, setLumps] = useState(null as StateCertaintyWeight);
    36    const [coughing, setCoughing] = useState(null as StateCertaintyWeight);
    37    const [swollen, setSwollen] = useState(null as StateCertaintyWeight);
    38    const [lossApetite, setLossApetite] = useState(null as StateCertaintyWeight);
    39    const toast = useToast();
    40    const { t, i18n } = useTranslation();
    41  
    42    const submitResult = () => {
    43      // Not '!' as 0 equals false as well. We need that literal 0 value.
    44      if (
    45        fever === null ||
    46        coughBlood === null ||
    47        spBloody === null ||
    48        nightSweat === null ||
    49        chestPain === null ||
    50        backPain === null ||
    51        shortBreath === null ||
    52        weightLoss === null ||
    53        bodyTired === null ||
    54        lumps === null ||
    55        coughing === null ||
    56        swollen === null ||
    57        lossApetite === null
    58      ) {
    59        FailedToast(toast, t('general.notComplete'));
    60        return;
    61      }
    62  
    63      const requestBody: Request = {
    64        diseaseId: 'D01',
    65        locale: i18n.language as 'en' | 'id',
    66        symptoms: [
    67          {
    68            symptomId: 'S1',
    69            weight: fever,
    70          },
    71          {
    72            symptomId: 'S2',
    73            weight: coughBlood,
    74          },
    75          {
    76            symptomId: 'S3',
    77            weight: spBloody,
    78          },
    79          {
    80            symptomId: 'S4',
    81            weight: nightSweat,
    82          },
    83          {
    84            symptomId: 'S5',
    85            weight: chestPain,
    86          },
    87          {
    88            symptomId: 'S6',
    89            weight: backPain,
    90          },
    91          {
    92            symptomId: 'S7',
    93            weight: shortBreath,
    94          },
    95          {
    96            symptomId: 'S8',
    97            weight: weightLoss,
    98          },
    99          {
   100            symptomId: 'S9',
   101            weight: bodyTired,
   102          },
   103          {
   104            symptomId: 'S10',
   105            weight: lumps,
   106          },
   107          {
   108            symptomId: 'S11',
   109            weight: coughBlood,
   110          },
   111          {
   112            symptomId: 'S12',
   113            weight: swollen,
   114          },
   115          {
   116            symptomId: 'S13',
   117            weight: lossApetite,
   118          },
   119        ],
   120      };
   121  
   122      setIsLoading(true);
   123      request('/api/v1', requestBody, 'POST')
   124        .then((data: Response) => setResult(data))
   125        .then(() => setOpenResult(true))
   126        .catch((err) => FailedToast(toast, err.message))
   127        .finally(() => setIsLoading(false));
   128    };
   129  
   130    return (
   131      <>
   132        <Suspense fallback={null}>
   133          <ResultModal
   134            isOpen={openResult}
   135            onClose={() => setOpenResult(false)}
   136            results={result}
   137          />
   138        </Suspense>
   139  
   140        <VStack as="form" w={['full', '70vw']} spacing={5}>
   141          <AnswerInput
   142            state={fever}
   143            setState={setFever}
   144            title={t('tbSymptoms.symptomOne')}
   145          />
   146  
   147          <AnswerInput
   148            state={coughBlood}
   149            setState={setCoughBlood}
   150            title={t('tbSymptoms.symptomTwo')}
   151          />
   152  
   153          <AnswerInput
   154            state={spBloody}
   155            setState={setSpBloody}
   156            title={t('tbSymptoms.symptomThree')}
   157          />
   158  
   159          <AnswerInput
   160            state={nightSweat}
   161            setState={setNightSweat}
   162            title={t('tbSymptoms.symptomFour')}
   163          />
   164  
   165          <AnswerInput
   166            state={chestPain}
   167            setState={setChestPain}
   168            title={t('tbSymptoms.symptomFive')}
   169          />
   170  
   171          <AnswerInput
   172            state={backPain}
   173            setState={setBackPain}
   174            title={t('tbSymptoms.symptomSix')}
   175          />
   176  
   177          <AnswerInput
   178            state={shortBreath}
   179            setState={setShortBreath}
   180            title={t('tbSymptoms.symptomSeven')}
   181          />
   182  
   183          <AnswerInput
   184            state={weightLoss}
   185            setState={setWeightLoss}
   186            title={t('tbSymptoms.symptomEight')}
   187          />
   188  
   189          <AnswerInput
   190            state={bodyTired}
   191            setState={setBodyTired}
   192            title={t('tbSymptoms.symptomNine')}
   193          />
   194  
   195          <AnswerInput
   196            state={lumps}
   197            setState={setLumps}
   198            title={t('tbSymptoms.symptomTen')}
   199          />
   200  
   201          <AnswerInput
   202            state={coughing}
   203            setState={setCoughing}
   204            title={t('tbSymptoms.symptomEleven')}
   205          />
   206  
   207          <AnswerInput
   208            state={swollen}
   209            setState={setSwollen}
   210            title={t('tbSymptoms.symptomTwelve')}
   211          />
   212  
   213          <AnswerInput
   214            state={lossApetite}
   215            setState={setLossApetite}
   216            title={t('tbSymptoms.symptomThirteen')}
   217          />
   218  
   219          <VStack w="full" align="start">
   220            <Text fontWeight="bold">{t('general.analyze')}</Text>
   221  
   222            <Button
   223              colorScheme="pink"
   224              w="full"
   225              variant="solid"
   226              onClick={submitResult}
   227              isLoading={isLoading}
   228            >
   229              {t('general.results')}
   230            </Button>
   231          </VStack>
   232        </VStack>
   233      </>
   234    );
   235  };
   236  
   237  export default memo(Tuberculosis);