react-bootstrap#Fade TypeScript Examples

The following examples show how to use react-bootstrap#Fade. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: landing-page.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 5 votes vote down vote up
LandingPage = (props: any) => {

    const context = React.useContext(AppContext);
    const { t } = useTranslation();

    const { keycloak } = useKeycloak();

    const [isInit, setIsInit] = React.useState(false)
    const [storedLandingDisclaimerShow, setStoredLandingDisclaimerShow] = useLocalStorage('landingDisclaimerShow', true);

    React.useEffect(() => {
        if (context) {
            setIsInit(true);
        }
    }, [context])

    return (!(isInit && context && context.navigation) ? <CwaSpinner /> :
        <Fade appear={true} in={true} >
            <Container className='center-content'>

                <h1 className='mx-auto mb-5 d-flex'>
                    {t('translation:welcome')}
                    {utils.hasRole(keycloak, 'c19_quick_test_admin')
                        ? <DisclamerButton
                            firstTimeShow={props.disclaimerShow}
                            checked={!storedLandingDisclaimerShow}
                            onInit={() => { props.setDisclaimerShow(false) }}
                            onCheckChange={(checked: boolean) => { setStoredLandingDisclaimerShow(!checked) }}
                            disclaimerText={
                                <>
                                    {t('translation:disclaimer-text1-part1')}
                                    <a
                                        href={t('translation:disclaimer-link')}
                                        target='blank'
                                    >
                                        {t('translation:disclaimer-link')}
                                    </a>
                                    {t('translation:disclaimer-text1-part2')}
                                </>
                            }
                        />
                        : <></>
                    }
                </h1>

                {utils.hasRole(keycloak, 'c19_quick_test_counter')
                    ? <Button block className='landing-btn' onClick={context.navigation.toRecordPatient}>{t('translation:record-patient-data')}</Button>
                    : <></>
                }
                {utils.hasRole(keycloak, 'c19_quick_test_lab')
                    ? <Button block className='landing-btn' onClick={context.navigation.toRecordTestResult}>{t('translation:record-result')}</Button>
                    : <></>}
                {utils.hasRole(keycloak, 'c19_quick_test_counter')
                    ? <Button block className='landing-btn' onClick={context.navigation.toQRScan}>{t('translation:record-qr-scan')}</Button>
                    : <></>}
                {utils.hasRole(keycloak, 'c19_quick_test_lab')
                    ? <>
                        <Button block className='landing-btn' onClick={context.navigation.toReports}>{t('translation:failed-report')}</Button>
                        <Button block className='landing-btn' onClick={context.navigation.toStatistics}>{t('translation:statistics-menu-item')}</Button>
                    </>
                    : <></>}
                {utils.hasRole(keycloak, 'c19_quick_test_admin')
                    ? <Button block className='landing-btn' onClick={context.navigation.toUserManagement}>{t('translation:user-management')}</Button>
                    : <></>}
            </Container>
        </Fade >
    )
}
Example #2
Source File: qr-scan.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 5 votes vote down vote up
QrScan = (props: any) => {

    const context = React.useContext(AppContext);
    const { t } = useTranslation();

    const [message, setMessage] = React.useState('');
    const [isInit, setIsInit] = React.useState(false)

    React.useEffect(() => {
        if (context.navigation && context.valueSets)
            setIsInit(true);
    }, [context.navigation, context.valueSets])

    const handleScan = (data: string | null) => {
        if (props.setQuickTest && data) {
            try {
                const scannedPatient = getPersonDataFromScan(data);
                props.setQuickTest(scannedPatient);
                context.navigation!.toRecordPatient();

            } catch (e) {
                setMessage(t('translation:qr-code-no-patient-data'));
            }
        }
    }

    const handleError = (error: any) => {
        if (window.location.protocol === 'http:') {
            setMessage(t('translation:qr-scan-https-only'));
        } else {
            setMessage("Scan Error: " + error);
        }
    }

    var messageHtml = undefined;
    if (message.length > 0) {
        messageHtml = <div className="alert alert-warning">
            {message}
        </div>;
    }

    return (
        !(isInit && context && context.valueSets)
            ? <CwaSpinner />
            : <Fade appear={true} in={true} >
                <Card id='data-card'>
                    <CardHeader title={t('translation:qr-scan')} />

                    {/*
    content area with process number input and radios
    */}
                    <Card.Body id='data-body' className='pt-0'>
                        <QrReader
                            delay={300}
                            onScan={handleScan}
                            onError={handleError}
                        />
                        {messageHtml}
                    </Card.Body>

                    {/*
    footer with cancel and submit button
    */}
                    <Card.Footer id='data-footer'>
                        <Row>
                            <Col sm='6' md='3'>
                                <Button
                                    className='my-1 my-md-0 p-0'
                                    block
                                    onClick={context.navigation!.toLanding}
                                >
                                    {t('translation:cancel')}
                                </Button>
                            </Col>
                        </Row>
                    </Card.Footer>
                </Card>
            </Fade>
    )
}
Example #3
Source File: group-modal.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
GroupModal = (props: any) => {

    const [btnOkDisabled, setBtnOkDisabled] = React.useState(true);
    const { t } = useTranslation();
    const { keycloak } = useKeycloak();

    const [data, setData] = React.useState('');
    const [validated, setValidated] = React.useState(false);
    const [isReady, setIsReady] = React.useState(false);
    const [isNew, setIsNew] = React.useState(true);
    const [options, setOptions] = React.useState<JSX.Element[]>();
    const [dropdownItems, setDropdownItems] = React.useState<JSX.Element[]>();
    const [dropdownList] = React.useState<string[]>(['https://', 'http://']);
    const [selectedDropdownValue, setSelectedDropdownValue] = React.useState<string>(dropdownList[0]);
    const [websiteValue, setWebsiteValue] = React.useState('');
    const [displayOpeningHours, setDisplayOpeningHours] = React.useState('');
    const [errorOpeningHour, setErrorOpeningHour] = React.useState('');

    const groupReloaded = (group: IGroupDetails) => {
        if (group) {
            setData(unpackData(group.pocDetails))
            group.parentGroup = props.parentGroupId;

            if (group.website) {
                let website = '';

                for (const item of dropdownList) {
                    if (group.website.startsWith(item)) {
                        website = group.website.slice(item.length, group.website.length);
                        setSelectedDropdownValue(item);
                    }
                }

                setWebsiteValue(website);
            }
            else {
                setWebsiteValue('');
                setSelectedDropdownValue(dropdownList[0]);
            }
        }
        setBtnOkDisabled(false);
    }

    const [group, updateGroup, setGroup] = useGetGroupDetails(groupReloaded, props.handleError);


    React.useEffect(() => {
        getDropdownItems();
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [])

    React.useEffect(() => {
        if (group) {

            setOptions(getOptions());
            setDisplayOpeningHours(
                group.openingHours?.map(
                    (element: string) => element)
                    .join('\n')
            );

            setIsReady(true);
        }

        setIsNew(!(group && group.id));
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [group])

    React.useEffect(() => {
        setValidated(props.isSuccess)
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [props.isSuccess]);

    React.useEffect(() => {
        if (props.isCreationError) {
            setBtnOkDisabled(false)
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [props.isCreationError]);

    const handleCancel = () => {
        setErrorOpeningHour('');
        props.onCancel();
    }

    const unpackData = (data: string) => {
        if (data) {
            data = data.replaceAll(',', '\n')
        } else {
            data = ''
        }
        return data;
    }

    const packData = (data: string) => {
        if (data) {
            data = data.replaceAll('\n', ',')
        }
        return data;
    }

    const handleOk = () => {
        if (props.handleOk) {
            setBtnOkDisabled(true);
            group.pocDetails = packData(data);
            if (websiteValue
                && (
                    websiteValue.startsWith('www.')
                    || !(
                        websiteValue.startsWith(dropdownList[0])
                        || websiteValue.startsWith(dropdownList[1])
                    )
                )) {
                group.website = selectedDropdownValue + websiteValue;
            }
            else {
                group.website = websiteValue;
            }

            props.handleOk(group);
        }
    }

    const handleEnter = () => {
        if (props.onEnter) {
            props.onEnter();
        }

        setBtnOkDisabled(false);

        if (props.groupId) {
            updateGroup(props.groupId);
        }
        else {
            setGroup({ ...emptyGroup });
            setSelectedDropdownValue(dropdownList[0]);
            setData('');
            setWebsiteValue('');
        }
    }

    const handleExited = () => {
        setIsReady(false);
        props.onExit();
    }

    const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
        const form = event.currentTarget;
        event.preventDefault();
        event.stopPropagation();

        if (errorOpeningHour) {
            document.getElementById('formPocOpeningHours')?.focus();
            return;
        }

        if (form.checkValidity()) {
            handleOk();
        }
    }

    const updateGroupProp = (name: string, value: any) => {
        const ngroup = { ...group, [name]: value };
        setGroup({ ...ngroup });
    }

    const changeOpeningHoursHandler = (name: string, value: string) => {

        setDisplayOpeningHours(value);

        let error = undefined;
        const openingHours = value.split('\n');
        if (openingHours.length > 7) {
            setErrorOpeningHour('opening-hours-to-much-lines-error');
            return;
        }

        error = openingHours.find(element => {
            return !utils.isOpeningHoursValid(element);
        });

        if (error) {
            setErrorOpeningHour('openening-hours-to-long-error');
        } else {
            setErrorOpeningHour('');
            updateGroupProp("openingHours", openingHours);
        }
    }

    const updateSearchPortalConsent = (name: string, value: any) => {
        const ngroup: IGroupDetails = { ...group, [name]: value };

        if (value === false) {
            ngroup.email = '';
            ngroup.website = '';
            ngroup.openingHours = [];
            ngroup.appointmentRequired = false;
        }
        setGroup(ngroup);
    }

    const collectChildren = (idlist: string[], parentNode: IGroup) => {
        if (parentNode) {
            idlist.push(parentNode.id);
            parentNode.children.forEach(child => collectChildren(idlist, child as IGroup));
        }
    }

    const getOptions = (): JSX.Element[] => {
        let result: JSX.Element[] = [];

        if (group && group.id) {

            const node = props.groups.find((groupNode: IGroupNode) => groupNode.group.id === group.id);
            const selfIdOrChildren: string[] = [];

            if (node) {
                collectChildren(selfIdOrChildren, node.group);
            }

            const fList = props.groups.filter((groupNode: IGroupNode) => selfIdOrChildren.indexOf(groupNode.group.id) < 0)

            result = fList.map((groupNode: IGroupNode) =>
                <option key={groupNode.group.id} value={groupNode.group.id}>{"\u00A0\u00A0\u00A0\u00A0".repeat(groupNode.level) + groupNode.group.name}</option>
            );

            // result.push(<option key="empty" value="empty">{t('translation:no-parentgroup-option')}</option>);
        }


        return result;
    }

    const getDropdownItems = () => {
        setDropdownItems(
            dropdownList.map(
                (item: string) =>
                    <Dropdown.Item
                        onSelect={(eventKey: any) => setSelectedDropdownValue(eventKey)}
                        eventKey={item}
                        key={item}
                    >
                        {item}
                    </Dropdown.Item>));
    }

    return (
        <Modal
            contentClassName='data-modal'
            size="lg"
            show={props.show}
            backdrop="static"
            keyboard={false}
            centered
            onEnter={handleEnter}
            onExited={handleExited}
        >
            {!isReady
                ? <CwaSpinner background='#eeeeee' />
                : <Fade appear={true} in={true} >
                    <Form
                        className='form-flex'
                        onSubmit={handleSubmit}
                        validated={validated}
                    >
                        <Modal.Header id='data-header' className='pb-0' >
                            <Modal.Title>{isNew ? t('translation:add-group') : t('translation:edit-group')}</Modal.Title>
                        </Modal.Header>

                        <Modal.Body className='bg-light'>
                            {isNew
                                ? <></>
                                : <>
                                    <FormGroupSelect controlId='formGroupSelect'
                                        title={t('translation:parentgroup')}
                                        placeholder={t('translation:no-parentgroup-option')}
                                        value={group.parentGroup}
                                        onChange={(ent: any) => updateGroupProp('parentGroup', ent.target.value)}
                                        options={options}
                                    />

                                    <hr />
                                </>
                            }

                            < FormGroupInput controlId='formFirstName' title={t('translation:name')}
                                value={group ? group.name : ''}
                                required
                                onChange={(evt: any) => {
                                    updateGroupProp('name', evt.target.value);
                                    props.resetError();
                                }}
                                maxLength={45}
                                isInvalid={props.isCreationError}
                                InvalidText={t('translation:group-conflict-error')}
                            />

                            {/* <hr /> */}

                            < FormGroupTextarea controlId='formAdressData' title={t('translation:address-testcenter')} placeholder={t('translation:address-testcenter-placeholder')}
                                value={data}
                                required
                                onChange={(evt: any) => setData(evt.target.value)}
                                type='textarea'
                                maxLength={300}
                            />

                            {utils.hasRole(keycloak, 'c19_quick_test_poc_nat_admin')
                                ?
                                <FormGroupPermissionCkb controlId='formenablePcr' title={t('translation:enablePcr')}
                                    //label={t('translation:for-counter')}
                                    onChange={(evt: any) => updateSearchPortalConsent('enablePcr', evt.currentTarget.checked)}
                                    type='checkbox'
                                    checked={group.enablePcr}
                                />
                                : <></>
                            }

                            <hr />

                            {/* < FormGroupInput controlId='formBSNRInput' title={t('translation:bsnr')} placeholder={t('translation:bsnr-placeholder')}
                                value={group ? group.bsnr : ''}
                                onChange={(evt: any) => {
                                    updateGroupProp('bsnr', evt.target.value);
                                    props.resetError();
                                }}
                                maxLength={9}
                                prepend='i'
                                tooltip={t('translation:bsnr-tooltip')}
                                pattern={utils.pattern.BSNR}
                            /> */}

                            <FormGroupPermissionCkb controlId='formsearchPortalConsent' title={t('translation:searchPortalConsent')}
                                //label={t('translation:for-counter')}
                                onChange={(evt: any) => updateSearchPortalConsent('searchPortalConsent', evt.currentTarget.checked)}
                                type='checkbox'
                                checked={group.searchPortalConsent}
                            />

                            <Collapse in={group.searchPortalConsent}>
                                <div>
                                    < FormGroupInput controlId='formEmailInput' title={t('translation:email-address')}
                                        value={group?.email ? group.email : ''}
                                        onChange={(evt: any) => {
                                            updateGroupProp('email', evt.target.value);
                                            props.resetError();
                                        }}
                                        type='email'
                                        pattern={utils.pattern.eMail}
                                        minLength={5}
                                        maxLength={255}
                                    />
                                    < FormGroupInput controlId='formPocWebsite' title={t('translation:searchPortalWebsite')} placeholder={t('translation:searchPortalWebsitePlaceholder')}
                                        value={websiteValue}
                                        dropdown={dropdownItems}
                                        dropdownTitle={selectedDropdownValue}
                                        prepend='i'
                                        tooltip={t('translation:searchPortalWebsiteTooltip')}
                                        onChange={(evt: any) => {
                                            setWebsiteValue(evt.target.value);
                                            props.resetError();
                                        }}
                                        maxLength={100}
                                        pattern={utils.pattern.url}
                                    />

                                    < FormGroupTextarea controlId='formPocOpeningHours' title={t('translation:searchPortalOpeningHours')}
                                        value={displayOpeningHours}
                                        onChange={(evt: any) => {
                                            changeOpeningHoursHandler('openingHours', evt.target.value);
                                            props.resetError();
                                        }}
                                        type='textarea'
                                        rows={7}
                                        pattern={utils.pattern.email}
                                        isInvalid={errorOpeningHour}
                                        invalidText={errorOpeningHour && t('translation:' + errorOpeningHour)}
                                    />
                                    <FormGroupPermissionCkb controlId='formAppointmentRequired' title={t('translation:searchPortalAppointmentRequired')}
                                        onChange={(evt: any) => updateGroupProp('appointmentRequired', evt.currentTarget.checked)}
                                        type='checkbox'
                                        checked={group?.appointmentRequired ? group.appointmentRequired : false}
                                    />
                                </div>
                            </Collapse>

                            {!(group && group.pocId)
                                ? <></>
                                : <>
                                    <hr />
                                    < FormGroupInput controlId='formPocId' title={t('translation:poc-id')}
                                        value={group && group.pocId ? group.pocId : ''}
                                        readOnly
                                    />
                                </>
                            }

                        </Modal.Body>

                        <Modal.Footer id='data-footer'>
                            <Container className='p-0'>
                                <Row>
                                    <Col sm='6' lg='4' className='mb-2 mb-sm-0 p-0 pr-sm-2'>
                                        <Button
                                            className='p-0'
                                            block
                                            variant='outline-primary'
                                            onClick={handleCancel}
                                        >
                                            {t('translation:cancel')}
                                        </Button>
                                    </Col>
                                    <Col sm='6' lg='4' className='p-0 pl-sm-2'>
                                        <Button
                                            className='p-0'
                                            block
                                            type='submit'
                                            disabled={btnOkDisabled}
                                        >
                                            {isNew ? t('translation:add') : t('translation:edit')}

                                            <Spinner
                                                as="span"
                                                className='btn-spinner'
                                                animation="border"
                                                hidden={!btnOkDisabled}
                                                size="sm"
                                                role="status"
                                                aria-hidden="true"
                                            />
                                        </Button>
                                    </Col>
                                </Row>
                            </Container>
                        </Modal.Footer>
                    </Form>
                </Fade>
            }
        </Modal>
    )
}
Example #4
Source File: test-result-inputs.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
TestResultInputs = (props: any) => {

    const context = React.useContext(AppContext);
    const { t } = useTranslation();

    const [testResult, setTestResult] = React.useState<TestResult>();

    const [testId, setTestId] = useLocalStorage('testId', '');
    const [testName, setTestName] = useLocalStorage('testName', '');
    const [pcrTestName, setPcrTestName] = useLocalStorage('pcrTestName', '');
    const [testManufacturerId, setTestManufacturerId] = useLocalStorage('testManufacturers', '');
    const [testManufacturerDescription, setTestManufacturerDescription] = React.useState('');
    const [dccConsent, setDccConsent] = React.useState<boolean>();
    const [testType, setTestType] = React.useState<TestType>();

    const tests = useGetTests();

    React.useEffect(() => {
        if (testResult) {
            let result: ITestResult;

            if (testType === TestType.PCR) {
                result = {
                    pcrTestName: pcrTestName,
                    result: testResult
                }
            }
            else {
                result = {
                    testBrandId: dccConsent ? undefined : testId,
                    testBrandName: dccConsent ? undefined : testName,
                    result: testResult,
                    dccTestManufacturerId: dccConsent ? testManufacturerId : undefined,
                    dccTestManufacturerDescription: dccConsent ? testManufacturerDescription : undefined
                }
            }

            props.onChange(result);
        }

        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [testId, testName, testResult, testManufacturerId, testManufacturerDescription, pcrTestName])

    React.useEffect(() => {
        if (testManufacturerId) {
            const desc = getValueSetDisplay(testManufacturerId, context!.valueSets![Value_Sets.TestManufacturer]);
            if (desc) {
                setTestManufacturerDescription(desc);
            }
        }
        else {
            setTestManufacturerDescription('');
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [testManufacturerId])

    React.useEffect(() => {
        if (props.quickTest) {
            setDccConsent(props.quickTest.dccConsent === true);
            setTestType(props.quickTest.testType ?? TestType.RAT);
        }
    }, [props.quickTest])

    const handleTestChange = (evt: any, change: (str: string) => void) => {
        const value = evt.currentTarget.value;

        if (tests && value) {
            const strVal: string = value;
            const splitIndex = strVal.indexOf('-');

            const id = strVal.slice(0, splitIndex - 1);
            const name = strVal.slice(splitIndex + 2);

            const find = tests.find((item) => (strVal.length <= 15 || item.testBrandName === name) && item.testBrandId === id);
            if (find) {
                setTestId(find.testBrandId);
                setTestName(find.testBrandName);
            }
            else {
                change(value)
            }
        }
        else {
            change(value)
        }
    }

    const handleTestIdChange = (evt: any) => {
        handleTestChange(evt, setTestId);
    }
    const handleTestNameChange = (evt: any) => {
        handleTestChange(evt, setTestName);
    }

    // const byId = (a: ITests, b: ITests): number => {
    //     if (a.testBrandId < b.testBrandId) {
    //         return -1;
    //     }
    //     if (a.testBrandId > b.testBrandId) {
    //         return 1;
    //     }

    //     // names must be equal
    //     return 0;
    // }
    // const byName = (a: ITests, b: ITests): number => {
    //     const nameA = a.testBrandName.toUpperCase(); // ignore upper and lowercase
    //     const nameB = b.testBrandName.toUpperCase(); // ignore upper and lowercase
    //     if (nameA < nameB) {
    //         return -1;
    //     }
    //     if (nameA > nameB) {
    //         return 1;
    //     }

    //     // names must be equal
    //     return 0;
    // }


    return (
        <Fade appear={true} in={dccConsent !== undefined}>
            <Container className='form-flex p-0 '>
                {testType === TestType.RAT
                    ? <>
                        {/* test-ID input */}
                        < FormGroupInput controlId='formTestIdInput' title={t('translation:test-id')}
                            value={testId}
                            onChange={handleTestIdChange}
                            required={!dccConsent}
                            hidden={dccConsent}
                            maxLength={15}
                            datalistId='testid-list'
                            datalist={tests ? tests.map((i: ITests) => <option key={i.testBrandId} value={i.testBrandId + ' - ' + i.testBrandName} />) : undefined}
                        />

                        {/* test-name input */}
                        < FormGroupInput controlId='formTestNameInput' title={t('translation:test-name')}
                            value={testName}
                            onChange={handleTestNameChange}
                            required={!dccConsent}
                            hidden={dccConsent}
                            maxLength={200}
                            datalistId='testname-list'
                            datalist={tests ? tests.map((i: ITests) => <option key={i.testBrandId} value={i.testBrandId + ' - ' + i.testBrandName} />) : undefined}
                        />

                        {/* combobox testManufacturers */}
                        <FormGroupValueSetSelect controlId='formTestManufactorersInput' title={t('translation:testManufacturers')}
                            infoText={<>{t('translation:RAT-list-info')}  <a className='rat-list-info-link' href={t('translation:RAT-list-info-link')} target='blank'>{t('translation:RAT-list-info-link-text')}</a></>}
                            value={testManufacturerId}
                            required={dccConsent}
                            hidden={!dccConsent}
                            onChange={(evt: any) => setTestManufacturerId(evt.target.value)}
                            valueSet={context!.valueSets![Value_Sets.TestManufacturer]}
                        />
                    </>

                    : < FormGroupInput controlId='formpcrTestNameInput' title={t('translation:pcrTestManufacturers')}
                        value={pcrTestName}
                        required
                        maxLength={80}
                        onChange={(evt: any) => setPcrTestName(evt.target.value)}
                    />
                }

                <hr />

                {/* test result radio */}
                < FormGroupRadio controlId='result-radio1' title={t('translation:result-positive')}
                    checked={testResult === TestResult.POSITIVE || testResult === TestResult.PCR_POSITIVE}
                    onChange={() => { testType === TestType.RAT ? setTestResult(TestResult.POSITIVE) : setTestResult(TestResult.PCR_POSITIVE) }}
                    name="result-radios"
                    required
                />
                <hr />
                {/* test result radio */}
                < FormGroupRadio controlId='result-radio2' title={t('translation:result-negative')}
                    checked={testResult === TestResult.NEGATIVE || testResult === TestResult.PCR_NEGATIVE}
                    onChange={() => { testType === TestType.RAT ? setTestResult(TestResult.NEGATIVE) : setTestResult(TestResult.PCR_NEGATIVE) }}
                    name="result-radios"
                    required
                />
                <hr />
                {/* test result radio */}
                < FormGroupRadio controlId='result-radio3' title={t('translation:result-failed')}
                    checked={testResult === TestResult.INVALID || testResult === TestResult.PCR_INVALID}
                    onChange={() => { testType === TestType.RAT ? setTestResult(TestResult.INVALID) : setTestResult(TestResult.PCR_INVALID) }}
                    name="result-radios"
                    required
                />
            </Container>
        </Fade>
    )
}
Example #5
Source File: record-patient-data.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
RecordPatientData = (props: any) => {

    const context = React.useContext(AppContext);
    const { t } = useTranslation();

    const { keycloak } = useKeycloak();

    const [isInit, setIsInit] = React.useState(false)
    const [uuIdHash, setUuIdHash] = React.useState('');

    const [isBack, setIsBack] = React.useState(true);
    const isBackRef = React.useRef(isBack);
    isBackRef.current = isBack;

    const [processId, setProcessId] = React.useState('');
    const processIdRef = React.useRef(processId);
    processIdRef.current = processId;

    const [person, setPerson] = React.useState<IPersonData>();
    const [address, setAddress] = React.useState<IAddressData>();

    const [pcrEnabled, setPcrEnabled] = React.useState(false);
    const [testType, setTestType] = React.useState(TestType.RAT);

    const [phoneNumber, setPhoneNumber] = React.useState('');
    const [emailAddress, setEmailAddress] = React.useState('');
    const [additionalInfo, setAdditionalInfo] = React.useState('');
    const [consent, setConsent] = React.useState(false);
    const [dccConsent, setDccConsent] = React.useState(false);
    const [dccNoConsent, setDccNoConsent] = React.useState(false);
    const [persDataInQR, setIncludePersData] = React.useState(false)
    const [privacyAgreement, setPrivacyAgreement] = React.useState(false)
    const [validated, setValidated] = React.useState(false);



    const handleError = (error: any) => {
        let msg = '';

        if (error) {
            msg = error.message
        }

        if (error && error.message && (error.message as string).includes('412')) {
            msg = t('translation:no-group-error');
        }
        props.setError({ error: error, message: msg, onCancel: context.navigation!.toLanding });
    }

    const handleDelete = () => { deleteQuicktest(processIdRef.current); }
    const [uuid, deleteQuicktest] = useGetUuid(props?.quickTest?.uuId, undefined, handleError);
    useOnUnload(() => handleDelete);


    React.useEffect(() => {
        return () => {
            if (isBackRef.current) {
                handleDelete();
            }
        };
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [])

    React.useEffect(() => {

        if (keycloak.idTokenParsed) {
            setPcrEnabled(!!(keycloak.idTokenParsed as any).pcr_enabled);
        }

    }, [keycloak])

    // set values from props or new uuid on mount
    React.useEffect(() => {
        if (props.quickTest) {
            const p = props.quickTest;

            setConsent(p.processingConsens);
            setIncludePersData(p.includePersData);
            setPrivacyAgreement(p.privacyAgreement);
            setPhoneNumber(p.phoneNumber);
            if (p.emailAddress) {
                setEmailAddress(p.emailAddress);
            }
            if (p.additionalInfo) {
                setAdditionalInfo(p.additionalInfo);
            }
            setDccConsent(p.dccConsent);
            setDccNoConsent(!p.dccConsent);
            setTestType(p.testType);
        }

        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [props.quickTest]);

    // set hash from uuid
    React.useEffect(() => {
        if (uuid) {
            setUuIdHash(sha256(uuid).toString());
        }
    }, [uuid]);

    // set process id from hash
    React.useEffect(() => {
        setProcessId(utils.shortHash(uuIdHash));
    }, [uuIdHash]);

    // set ready state for spinner
    React.useEffect(() => {
        if (processId && context.navigation && context.valueSets) {
            setIsInit(true);
        }
    }, [processId, context.navigation, context.valueSets])

    const handleDccConsentChange = (evt: any) => {
        setDccConsent(true)
        setDccNoConsent(false);
    }

    const handleDccNoConsentChange = (evt: any) => {
        setDccConsent(false)
        setDccNoConsent(true);
    }

    const handleConsentChange = (evt: any) => {
        setConsent(!consent)
        setIncludePersData(false);
    }

    const handlePersDataInQRChange = (evt: any) => {
        setIncludePersData(!persDataInQR);
        setConsent(false);
    }

    const handleCancel = () => {
        props.setQuickTest(undefined);
        context.navigation!.toLanding();
    }

    const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
        const form = event.currentTarget;

        event.preventDefault();
        event.stopPropagation();

        setValidated(true);
        setIsBack(false);

        if (form.checkValidity() && person) {
            props.setQuickTest({
                personData: person,
                addressData: address,
                processingConsens: consent,
                uuId: uuid,
                includePersData: persDataInQR,
                privacyAgreement: privacyAgreement,
                phoneNumber: phoneNumber,
                emailAddress: emailAddress || undefined,
                dccConsent: dccConsent,
                additionalInfo: additionalInfo || undefined,
                testType: testType
            })
            setTimeout(context.navigation!.toShowRecordPatient, 200);
        }

    }

    return (
        !(isInit && context && context.valueSets)
            ? <CwaSpinner />
            : <Fade appear={true} in={true} >
                <Container className='form-flex p-0 '>
                    <Row id='process-row'>
                        <span className='font-weight-bold mr-2'>{t('translation:process')}</span>
                        <span>{processId}</span>
                    </Row>
                    <Card id='data-card'>

                        <Form className='form-flex' onSubmit={handleSubmit} validated={validated}>

                            {/*
                            header with title and id card query
                            */}
                            <CardHeader idCard={true} title={t('translation:record-result2')} />

                            {/*
                            content area with patient inputs and check box
                            */}
                            <Card.Body id='data-body' className='pt-0'>

                                {/* dccConsent */}
                                <Row className='yellow'>
                                    <Col className='p-0' xs='5' sm='3'>
                                        <Row className='m-0 mb-2'>
                                            <Col className='p-0' xs='auto'>
                                                <Form.Label className='input-label pl-1'>
                                                    {t('translation:testZertifikat')}*
                                                </Form.Label>
                                            </Col>
                                            <Col className='p-0 jcc-xs-jcfs-lg ml-lg-2 d-flex'>
                                                <Image className="eu-flag" src={eu_logo} />
                                            </Col>
                                        </Row>
                                    </Col>
                                    <Col xs='7' sm='9'>
                                        <Row className='m-0'>
                                            <Form.Label className='input-label m-0'>{t('translation:dccConsent')}</Form.Label>
                                        </Row>
                                        <Collapse in={dccConsent}>
                                            <Row className='m-0 my-1'>
                                                <Form.Label className='input-label text-justify m-0'>
                                                    <Form.Label className='input-label mb-0 mr-2'>
                                                        &#xf071;
                                                    </Form.Label>
                                                    {t('translation:dccConsent-cwa-only')}
                                                </Form.Label>
                                            </Row>
                                        </Collapse>
                                        <Row className='m-0 mb-2'>
                                            <FormGroupDccConsentRadio controlId='dccConsent-radio1' name="dccConsent-radios" title={t('translation:ja')}
                                                checked={dccConsent}
                                                onChange={handleDccConsentChange}
                                                required={true}
                                            />

                                            <FormGroupDccConsentRadio controlId='dccConsent-radio2' name="dccConsent-radios" title={t('translation:nein')}
                                                checked={dccNoConsent}
                                                onChange={handleDccNoConsentChange}
                                                required={true}
                                            />
                                        </Row>
                                    </Col>
                                </Row>

                                <hr />
                                {!pcrEnabled
                                    ? <></>
                                    : <>
                                        <Row>
                                            <Form.Label className='input-label txt-no-wrap' column xs='5' sm='3'>{t('translation:test-type') + '*'}</Form.Label>

                                            <Col xs='7' sm='9' className='d-flex'>
                                                <Row>
                                                    <FormGroupInlineRadio controlId='test-type1' name="test-type-radios" title={t(`translation:${TestType.RAT}`)} sm='6'
                                                        checked={testType === TestType.RAT}
                                                        onChange={() => setTestType(TestType.RAT)}
                                                    />

                                                    <FormGroupInlineRadio controlId='test-type2' name="test-type-radios" title={t(`translation:${TestType.PCR}`)} sm='6'
                                                        checked={testType === TestType.PCR}
                                                        onChange={() => setTestType(TestType.PCR)}
                                                        required={true}
                                                    />
                                                </Row>
                                            </Col>
                                        </Row>
                                        <hr />
                                    </>
                                }

                                <PersonInputs quickTest={props.quickTest} onChange={setPerson} dccConsent={dccConsent} onDccChanged={setDccConsent} />

                                <hr />

                                {/* address input */}
                                <AddressInputs quickTest={props.quickTest} onChange={setAddress} />

                                <hr />

                                {/* phone number input */}

                                < FormGroupInput controlId='formPhoneInput' title={t('translation:phone-number')}
                                    value={phoneNumber}
                                    onChange={(evt: any) => setPhoneNumber(evt.target.value)}
                                    type='tel'
                                    required
                                    pattern={utils.pattern.tel}
                                    maxLength={79}
                                />

                                < FormGroupInput controlId='formEmailInput' title={t('translation:email-address')}
                                    value={emailAddress}
                                    onChange={(evt: any) => setEmailAddress(evt.target.value)}
                                    type='email'
                                    pattern={utils.pattern.eMail}
                                    minLength={5}
                                    maxLength={255}
                                />

                                < FormGroupInput controlId='formAdditionalInfo' title={t('translation:additional-info')}
                                    value={additionalInfo}
                                    onChange={(evt: any) => setAdditionalInfo(evt.target.value)}
                                    type='text'
                                    minLength={1}
                                    maxLength={250}
                                    prepend='i'
                                    tooltip={t('translation:additional-info-tooltip')}
                                />

                                <hr />
                                {/* processing consent check box */}
                                <FormGroupConsentCkb controlId='formConsentCheckbox' title={t('translation:processing-consent-title')}
                                    accordion={t('translation:processing-consent')}
                                    onClick={handleConsentChange}
                                    onChange={handleConsentChange}
                                    type='radio'
                                    name="check-radios"
                                    checked={consent}
                                    required={dccConsent}
                                />
                                <FormGroupConsentCkb controlId='formKeepPrivateCheckbox' title={t('translation:patientdata-exclude-title')}
                                    accordion={t('translation:patientdata-exclude')}
                                    onClick={handlePersDataInQRChange}
                                    onChange={handlePersDataInQRChange}
                                    type='radio'
                                    name="check-radios"
                                    checked={persDataInQR}
                                    required={dccConsent}
                                />
                                <FormGroupConsentCkb controlId='formDataPrivacyCheckbox' title={t('translation:data-privacy-approve')}
                                    onChange={(evt: any) => setPrivacyAgreement(evt.currentTarget.checked)}
                                    type='checkbox'
                                    checked={privacyAgreement}
                                    required
                                />
                            </Card.Body>

                            {/*
    footer with clear and nex button
    */}
                            <CardFooter handleCancel={handleCancel} />

                        </Form>
                    </Card>
                </Container>
            </Fade>
    )
}
Example #6
Source File: record-test-result.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
RecordTestResult = (props: any) => {

    const context = React.useContext(AppContext);
    const { t } = useTranslation();

    const [processNo, setProcessNo] = React.useState('');
    const [processNoForModal, setProcessNoForModal] = React.useState('');
    const [testResult, setTestResult] = React.useState<ITestResult>();
    const [testResultToPost, setTestResultToPost] = React.useState<ITestResult>();

    const [validated, setValidated] = React.useState(false);
    const [isInit, setIsInit] = React.useState(false)
    const [showProcessIdInputModal, setShowProcessIdInputModal] = React.useState(true)
    const [postInProgress, setPostInProgress] = React.useState(false);



    React.useEffect(() => {
        if (context.navigation && context.valueSets)
            setIsInit(true);
    }, [context.navigation, context.valueSets])

    const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
        const form = event.currentTarget;

        event.preventDefault();
        event.stopPropagation();

        setValidated(true);

        if (form.checkValidity()) {
            setPostInProgress(true);
            setTestResultToPost(testResult);
        }
    }

    const finishProcess = () => {
        props.setNotificationShow(true);
        context.navigation!.toLanding();
        setPostInProgress(false);
    }

    const handleCancel = () => {
        context.navigation?.toLanding();
    }

    const handleError = (error: any) => {
        let msg = '';

        if (error) {
            msg = error.message
        }
        if (error && error.message && (error.message as string).includes('412')) {
            msg = t('translation:no-group-error');
        }
        props.setError({ error: error, message: msg, onCancel: context.navigation!.toLanding });
    }

    const handleProcessIdInputCancel = () => {
        if (!processNo) {
            context.navigation!.toLanding();
        }
    }

    const handleProcessIdInputHide = () => {
        setShowProcessIdInputModal(false);
    }

    const handleProcessIdInputClick = () => {
        setShowProcessIdInputModal(true);
        setProcessNo('');
    }

    const handleProcessIdInputChange = (processNo: string) => {
        setProcessNo(processNo);
        setProcessNoForModal(processNo);
    }

    usePostTestResult(testResultToPost, processNo, finishProcess, handleError);
    const quickTest: IQuickTestDccAPIResponseModel | undefined = useGetQuicktest(processNo, handleProcessIdInputHide, (error: any) => props.setError({ error: '', message: t('translation:error-processId-data-load'), onCancel: context.navigation!.toLanding }));

    return (<>{
        !(isInit && context && context.valueSets && processNo && !showProcessIdInputModal)
            ? <CwaSpinner />
            : <Fade appear={true} in={true} >
                <Card id='data-card'>

                    <Form className='form-flex' onSubmit={handleSubmit} validated={validated}>

                        <CardHeader title={t('translation:record-result2')} />

                        {/*
    content area with process number input and radios
    */}
                        <Card.Body id='data-body' className='pt-0'>
                            {/* process number input */}
                            < FormGroupInput controlId='formProcessInput' title={t('translation:process-number')}
                                value={processNo}
                                onChange={(evt: any) => setProcessNo(evt.currentTarget.value)}
                                onClick={handleProcessIdInputClick}
                                readOnly
                                required
                                min={utils.shortHashLen}
                                maxLength={utils.shortHashLen}
                                pattern={utils.pattern.processNo}
                            />
                            <hr />

                            <TestResultInputs
                                quickTest={quickTest}
                                hidden={quickTest === undefined}
                                onChange={setTestResult}
                            />
                        </Card.Body>

                        {/*
    footer with cancel and submit button
    */}
                        <CardFooter
                            okText={t('translation:data-submit')}
                            handleCancel={handleCancel}
                            disabled={postInProgress}
                        />
                    </Form>

                </Card>
            </Fade>
    }
        <ProcessIdInput
            show={showProcessIdInputModal}
            processNo={processNoForModal}
            handleError={handleError}
            onHide={() => { }}
            onCancel={handleProcessIdInputCancel}
            onChange={handleProcessIdInputChange}
        />
    </>
    )
}
Example #7
Source File: reports.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
Reports = (props: any) => {

    const context = React.useContext(AppContext);
    const { t } = useTranslation();

    const [isInit, setIsInit] = React.useState(false)
    const [filterComplete, setFilterComplete] = React.useState(false)
    const [startDate, setStartDate] = React.useState<Date | undefined>();
    const [endDate, setEndDate] = React.useState<Date | undefined>(new Date());
    const [selectedHash, setSelectedHash] = React.useState<string>();
    const [filterTestResult, setFilterTestResult] = React.useState<TestResult>();

    const parentRef = React.useRef<HTMLDivElement>(null);

    React.useEffect(() => {
        if (context.navigation && context.valueSets)
            setIsInit(true);
    }, [context.navigation, context.valueSets])

    const handleError = (error: any) => {
        let msg = '';

        if (error) {
            msg = error.message
        }

        if (error && error.message && (error.message as string).includes('412')) {
            msg = t('translation:no-group-error');
        }
        props.setError({ error: error, message: msg, onCancel: context.navigation!.toLanding });
    }

    const qtArchive = useGetPositiveForTimeRange(filterTestResult, startDate, endDate, undefined, handleError);
    const pdf = useGetPDF(selectedHash);

    const handleDateChange = (evt: Date | [Date, Date] | null, change: (date: Date | undefined) => void, hour: number) => {
        let date: Date | undefined;

        if (evt instanceof Date) {
            date = new Date(evt);
            // date = evt;
        }
        else if (evt != null) {
            date = evt[0];
        }

        if (date) {
            date.setHours(hour);
        }

        setFilterTestResult(undefined);
        change(date);

    }

    const handleStartDateChange = (evt: Date | [Date, Date] | null) => {
        handleDateChange(evt, setStartDate, 0);
        handleDateChange(evt, setEndDate, 24);
    }

    React.useEffect(() => {
        if (startDate && endDate)
            setFilterComplete(true)
        else {
            setFilterComplete(false);
            setSelectedHash('');
        }
    }, [startDate, endDate])

    React.useEffect(() => {
        if (selectedHash) {
            setSelectedHash(undefined);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [filterTestResult])


    return (
        !(isInit && context && context.valueSets)
            ? <CwaSpinner />
            : <Fade appear={true} in={true} >
                <Card id='data-card'>
                    <CardHeader title={t('translation:failed-report')} />

                    {/*
    content area
    */}
                    <Card.Body id='data-header' className='qt-frame-card '>
                        {/* date of filter input */}
                        <Form.Group as={Row} className='mb-1'>
                            <Form.Label className='input-label txt-no-wrap' column xs='5' sm='3'>{t('translation:timerange')}</Form.Label>

                            <Col xs='7' sm='9' className='d-flex'>
                                <Row >
                                    <Col xs='12' sm='12' className='d-flex'>
                                        <DatePicker
                                            selected={startDate}
                                            onChange={handleStartDateChange}
                                            locale='de'
                                            dateFormat='dd. MM. yyyy'
                                            isClearable
                                            placeholderText={t('translation:from')}
                                            className='qt-input form-control mb-2 mb-sm-0'
                                            wrapperClassName='align-self-center'
                                            showMonthDropdown
                                            showYearDropdown
                                            dropdownMode="select"
                                            maxDate={new Date()}
                                            minDate={new Date(1900, 0, 1, 12)}
                                            required
                                        />
                                    </Col>
                                </Row>
                            </Col>
                        </Form.Group>
                        <hr />
                        <Row>
                            <Form.Label className='input-label txt-no-wrap' column xs='5' sm='3'>{t('translation:filter-record-result')}</Form.Label>

                            <Col xs='7' sm='9' className='d-flex'>
                                <Row>
                                    <FormGroupInlineRadio controlId='filterTestResult-radio1' name="filterTestResult-radios" sm='6' md='3'
                                        title={t('translation:filter-none')}
                                        checked={filterTestResult === undefined}
                                        onChange={() => setFilterTestResult(undefined)}
                                    />
                                    <FormGroupInlineRadio controlId='filterTestResult-radio2' name="filterTestResult-radios" sm='6' md='3'
                                        title={t('translation:result-positive')}
                                        checked={filterTestResult === TestResult.POSITIVE}
                                        onChange={() => setFilterTestResult(TestResult.POSITIVE)}
                                    />
                                    <FormGroupInlineRadio controlId='filterTestResult-radio3' name="filterTestResult-radios" sm='6' md='3'
                                        title={t('translation:result-negative')}
                                        checked={filterTestResult === TestResult.NEGATIVE}
                                        onChange={() => setFilterTestResult(TestResult.NEGATIVE)}
                                    />
                                    <FormGroupInlineRadio controlId='filterTestResult-radio4' name="filterTestResult-radios" sm='6' md='3'
                                        title={t('translation:result-failed')}
                                        checked={filterTestResult === TestResult.INVALID}
                                        onChange={() => setFilterTestResult(TestResult.INVALID)}
                                    />
                                </Row>
                            </Col>
                        </Row>

                        <hr />


                        {!filterComplete ? <></> :
                            (qtArchive === undefined)
                                ? <CwaSpinner background='inherit' />
                                : <Row className='flex-fill'>
                                    <Col md='3'>
                                        <PagedList data={qtArchive} onSelected={setSelectedHash} />
                                    </Col>
                                    <Col md='9' ref={parentRef}>
                                        {!pdf ? <></> : <>
                                            <iframe title='qt-IFrame' src={pdf} className='qt-IFrame' /></>
                                        }
                                    </Col>
                                </Row>
                        }
                    </Card.Body>

                    {/*
    footer
    */}
                    <Card.Footer id='data-footer'>
                        <Row>
                            <Col sm='6' md='3' className='pr-md-0'>
                                <Button
                                    className='my-1 my-md-0 p-0'
                                    block
                                    onClick={context.navigation!.toLanding}
                                >
                                    {t('translation:cancel')}
                                </Button>
                            </Col>
                        </Row>
                    </Card.Footer>
                </Card>
            </Fade>
    )
}
Example #8
Source File: show-patient-data.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
ShowPatientData = (props: any) => {

    const context = React.useContext(AppContext);
    const { t } = useTranslation();

    const [isInit, setIsInit] = React.useState(false)
    const [quickTest, setQuickTest] = React.useState<IQuickTest>();
    const [quickTestToPost, setQuickTestToPost] = React.useState<IQuickTest>();
    const [qrCodeValue, setQrCodeValue] = React.useState<string[]>();
    const [uuIdHash, setUuIdHash] = React.useState('');
    const [processId, setProcessId] = React.useState('');
    const [postInProgress, setPostInProgress] = React.useState(false);

    // set quickTest data on mount and set hash from uuid
    React.useEffect(() => {
        if (isInit) {
            if (props.quickTest) {
                setQuickTest(props.quickTest)
            }
            else
                props.setError({ error: '', message: t('translation:error-patient-data-load'), onCancel: context.navigation!.toLanding });
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [isInit])

    React.useEffect(() => {
        if (quickTest && quickTest.personData && quickTest.uuId) {

            setUuIdHash(sha256(quickTest.uuId).toString());

            if (quickTest.includePersData) {

                setQrCodeValue(getQrCodeValueString(quickTest.uuId, quickTest.dccConsent, quickTest.testType, quickTest.personData.givenName, quickTest.personData.familyName, quickTest.personData.dateOfBirth));
            }
            if (quickTest.processingConsens) {
                setQrCodeValue(getQrCodeValueString(quickTest.uuId, quickTest.dccConsent, quickTest.testType));
            }
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [quickTest])

    // set process id from hash
    React.useEffect(() => {
        if (uuIdHash) {
            setProcessId(utils.shortHash(uuIdHash));
        }
    }, [uuIdHash]);


    React.useEffect(() => {
        if (qrCodeValue && qrCodeValue.length > 1) {
            // console.log(qrCodeValue);
            quickTest!.testResultHash = qrCodeValue[1];
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [qrCodeValue]);

    // set ready state for spinner
    React.useEffect(() => {
        if (context.navigation && context.valueSets)
            setIsInit(true);
    }, [context.navigation, context.valueSets])

    const finishProcess = () => {
        props.setQuickTest(undefined);
        props.setNotificationShow(true);
        context.navigation!.toLanding();
        setPostInProgress(false);
    }

    const handleError = (error: any) => {
        let msg = '';

        if (error) {
            msg = error.message
        }
        props.setError({ error: error, message: msg, onCancel: context.navigation!.toLanding });
    }

    usePostQuickTest(quickTestToPost, processId, finishProcess, handleError);

    const handlePost = () => {
        setPostInProgress(true);
        setQuickTestToPost(quickTest);
    }

    return (
        !(isInit && context && context.valueSets && quickTest && quickTest.personData && quickTest.addressData)
            ? <CwaSpinner />
            : <Fade appear={true} in={true} >
                <Container className='form-flex p-0 '>
                    <Row id='process-row'>
                        <span className='font-weight-bold mr-2'>{t('translation:process')}</span>
                        <span>{processId}</span>
                    </Row>
                    <Card id='data-card'>

                        {/*
    content area with patient inputs and check box
    */}
                        <Card.Body id='data-header'>
                            <Row>
                                <Col sm='5'>
                                    <Card.Title className='m-sm-0 jcc-xs-jcfs-sm' as={'h2'}>{t('translation:qr-code')}</Card.Title>
                                    <hr />

                                    <Card.Text className='input-label font-weight-bold mt-4 jcc-xs-jcfs-sm' >
                                        {t('translation:patient-data')}
                                    </Card.Text>

                                    <Card.Text className='input-label jcc-xs-jcfs-sm mb-0' >
                                        {quickTest.personData.givenName + ' ' + quickTest.personData.familyName}
                                    </Card.Text>

                                    <Moment className='input-label mb-3 jcc-xs-jcfs-sm' locale='de' format={utils.momentDateFormat} >
                                        {quickTest.personData.dateOfBirth as Date}
                                    </Moment>

                                    <Card.Text className='input-label jcc-xs-jcfs-sm' >
                                        {quickTest.personData.sex === Sex.MALE
                                            ? t('translation:male')
                                            : quickTest.personData.sex === Sex.FEMALE
                                                ? t('translation:female')
                                                : t('translation:diverse')}
                                    </Card.Text>

                                    <Card.Text className='input-label jcc-xs-jcfs-sm mb-0' >
                                        {quickTest.addressData.street}
                                    </Card.Text>

                                    {/* <Card.Text className='input-label jcc-xs-jcfs-sm mb-0' >{quickTest?.addressData.street + ' ' + quickTest?.addressData.houseNumber}</Card.Text> */}
                                    <Card.Text className='input-label jcc-xs-jcfs-sm' >
                                        {quickTest.addressData.zip + ' ' + quickTest.addressData.city}
                                    </Card.Text>

                                    <Card.Text className='input-label jcc-xs-jcfs-sm mb-0' >
                                        {quickTest.phoneNumber}
                                    </Card.Text>

                                    <Card.Text className='input-label jcc-xs-jcfs-sm' >
                                        {quickTest.emailAddress}
                                    </Card.Text>

                                    <Card.Text className='input-label jcc-xs-jcfs-sm' >
                                        {quickTest.testId}
                                    </Card.Text>
                                </Col>
                                <Col sm='7' className='px-4'>
                                    <Container id='qr-code-container'>
                                        {qrCodeValue ? <><QRCode id='qr-code' size={256} renderAs='svg' value={qrCodeValue[0]} />
                                        </> : <></>}
                                    </Container>
                                </Col>
                            </Row>
                        </Card.Body>

                        {/*
    footer with correction and finish button
    */}

                        <CardFooter
                            cancelText={t('translation:patient-data-correction')}
                            okText={t('translation:process-finish')}
                            handleCancel={context.navigation!.toRecordPatient}
                            handleOk={() => handlePost()}
                            disabled={postInProgress}
                        />

                    </Card>
                </Container>
            </Fade>
    )
}
Example #9
Source File: statistics.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
Statistics = (props: any) => {

    const context = React.useContext(AppContext);
    const { t } = useTranslation();
    const { keycloak } = useKeycloak();

    const handleError = (error: any) => {
        let msg = '';

        if (error) {
            msg = error.message
        }

        if (error && error.message && (error.message as string).includes('412')) {
            msg = t('translation:no-group-error');
        }
        props.setError({ error: error, message: msg, onCancel: context.navigation!.toLanding });
    }

    const [pcrEnabled, setPcrEnabled] = React.useState(false);
    const [statisticData,
        thisWeekStatisticData,
        thisMonthStatisticData] = useStatistics(undefined, handleError);
    const [statisticsResult,
        getStatisticsFromTo] = useGetStatisticsFromTo(undefined, handleError);
    const [isInit, setIsInit] = React.useState(false);
    const [statisticRows, setStatisticRows] = React.useState<any[]>([]);
    const [dateValidFrom, setDateValidFrom] = React.useState<Date>();
    const [dateValidTo, setDateValidTo] = React.useState<Date>();

    React.useEffect(() => {

        if (keycloak.idTokenParsed) {
            setPcrEnabled(!!(keycloak.idTokenParsed as any).pcr_enabled);
        }

    }, [keycloak])

    React.useEffect(() => {
        if (context.navigation && context.valueSets && statisticData && thisWeekStatisticData && thisMonthStatisticData) {
            setStatisticRows([
                { ...statisticData, label: t('translation:today'), key: Math.random() },
                { ...thisWeekStatisticData, label: t('translation:thisWeek'), key: Math.random() },
                { ...thisMonthStatisticData, label: t('translation:thisMonth'), key: Math.random() }
            ])
            setIsInit(true);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [context.navigation, context.valueSets, statisticData, thisWeekStatisticData, thisMonthStatisticData])

    React.useEffect(() => {
        if (dateValidFrom || (dateValidFrom && dateValidTo)) {

            let startDate = new Date(dateValidFrom);
            let endDate: Date;

            startDate.setUTCHours(0, 0, 0, 0);

            if (dateValidTo) {
                endDate = new Date(dateValidTo);
                endDate.setUTCHours(0, 0, 0, 0);
                let day = endDate.getDate() + 1;
                endDate.setDate(day);
            } else {
                let fromDate = new Date(startDate);
                let day = fromDate.getDate() + 1;
                endDate = new Date(fromDate.setDate(day));
            }

            getStatisticsFromTo(startDate, endDate);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [dateValidFrom, dateValidTo])

    React.useEffect(() => {
        if (statisticsResult) {

            let newLabel: string | undefined = dateValidFrom ? format(dateValidFrom, utils.pickerDateFormat) : undefined;
            if (newLabel && dateValidTo) {
                newLabel += ' - ' + format(dateValidTo, utils.pickerDateFormat);
            }

            setStatisticRows([...statisticRows, { ...statisticsResult, label: newLabel, key: Math.random() }]);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [statisticsResult])

    const handleNewStatisticRow = (dateValidFrom: Date, dateValidTo: Date) => {
        setDateValidFrom(dateValidFrom);
        setDateValidTo(dateValidTo);
    }

    const handleDeleteStatisticRow = (key: number) => {
        setStatisticRows((prevStatisticRows) => {
            return prevStatisticRows.filter((row) => {
                return row.key !== key
            });
        })
    }

    return (
        !(isInit && context && context.valueSets && statisticData && thisWeekStatisticData && thisMonthStatisticData)
            ? <CwaSpinner />
            : <Fade appear={true} in={true} >
                <Card id='data-card'>
                    <CardHeader title={t('translation:statistics')} />

                    {/*
    content area with patient inputs and check box
    */}
                    <Card.Body id='data-header'>
                        <StatisticDateSelectionRow addRow={handleNewStatisticRow} />
                        <hr />
                        <StatisticDataRow statisticData={statisticRows} pcrEnabled={pcrEnabled} deleteRow={handleDeleteStatisticRow} />
                    </Card.Body>

                    {/*
    footer with correction and finish button
    */}
                    <Card.Footer id='data-footer'>
                        <Row>
                            <Col sm='6' md='3' className='pr-md-0'>
                                <Button
                                    className='my-1 my-md-0 p-0'
                                    block
                                    onClick={context.navigation!.toLanding}
                                >
                                    {t('translation:back')}
                                </Button>
                            </Col>
                        </Row>
                    </Card.Footer>
                </Card>
            </Fade>
    )
}
Example #10
Source File: user-management.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
UserManagement = (props: any) => {
    const context = React.useContext(AppContext);
    const { t } = useTranslation();

    const [isInit, setIsInit] = React.useState(true);
    const [groupNodes, setGroupNodes] = React.useState<IGroupNode[]>();
    const [userReload, setUserReload] = React.useState(false);
    const [storedUserManagementDisclaimerShow, setStoredUserManagementDisclaimerShow] = useLocalStorage('userManagementDisclaimerShow', true);


    const handleError = (error: any, message?: string, onCancel?: () => void) => {
        let msg = '';

        if (error) {
            msg = error.message;
        }
        if (message) {
            msg = message;
        }

        props.setError({ error: error, message: msg, onCancel: onCancel ?? context.navigation!.toLanding });
    }

    React.useEffect(() => {
        //setIsInit(!!(bGroups && bUsers));
        setIsInit(!!(context && context.navigation, context.valueSets));
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [context.navigation, context.valueSets]);


    return (
        !(isInit && context && context.valueSets)
            ? <CwaSpinner />
            : <Fade appear={true} in={true} >
                <Card id='data-card'>

                    <CardHeader
                        title={t('translation:user-management')}
                        firstTimeShow={props.disclaimerShow}
                        checked={!storedUserManagementDisclaimerShow}
                        onInit={() => { props.setDisclaimerShow(false) }}
                        onCheckChange={(checked: boolean) => { setStoredUserManagementDisclaimerShow(!checked) }}
                        disclaimerText={
                            <>
                                {t('translation:disclaimer-text2-part1')}
                                <a
                                    href={t('translation:disclaimer-link')}
                                    target='blank'
                                >
                                    {t('translation:disclaimer-link')}
                                </a>
                                {t('translation:disclaimer-text2-part2')}
                            </>
                        }
                    />

                    <Card.Body id='data-body' className='pt-0' >

                        <h4>{t('translation:groups')}</h4>

                        <GroupTable
                            groupNodes={groupNodes}
                            setGroupNodes={setGroupNodes}
                            setUserReload={setUserReload}
                            handleError={handleError}
                        />

                        <hr />

                        <h4>{t('translation:user')}</h4>

                        <UserTable
                            groupNodes={groupNodes}
                            handleError={handleError}
                            setUserReload={setUserReload}
                            userReload={userReload}
                        />

                    </Card.Body>

                    <Card.Footer id='data-footer'>
                        <Row className='justify-content-end'>
                            <Col sm='6' md='3' className='p-0'>
                                <Button
                                    className='my-md-0 p-0'
                                    variant='primary'
                                    block
                                    onClick={() => context.navigation!.toLanding()}
                                >
                                    {t('translation:back')}
                                </Button>
                            </Col>
                        </Row>
                    </Card.Footer>

                </Card>
            </Fade>
    );

}