react-bootstrap#Button TypeScript Examples

The following examples show how to use react-bootstrap#Button. 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: CommunitiesView.tsx    From 3Speak-app with GNU General Public License v3.0 6 votes vote down vote up
export function CommunitiesView() {
  const [data, setData] = useState([])

  const generate = async () => {
    const res = await client.call('bridge', 'list_communities', {
      last: '',
      limit: 100,
    })
    setData(res)
  }
  useEffect(() => {
    document.title = '3Speak - Tokenised video communities'
    generate()
  }, [])
  return (
    <Container fluid>
      <Row>
        <div className="col-12">
          <h3 style={{ display: 'inline-block' }}>Communities</h3>
          <span className="float-right mb-3">
            <Button id="communityCreate" variant="primary" disabled>
              Create +
            </Button>
          </span>
        </div>
      </Row>
      <Row>
        {data.map((value) => (
          <CommunityTile key={value.name} reflink={`hive:${value.name}`} info={value} />
        ))}
      </Row>
    </Container>
  )
}
Example #2
Source File: NetworkErrPage.tsx    From devex with GNU General Public License v3.0 6 votes vote down vote up
NetworkErrPage: React.FC = () => {
  
  const networkUrl = useNetworkUrl()

  return <>
    <Card className='error-card'>
      <Card.Body>
        <h4 className='mb-3'>
          Sorry! Could not connect to network. Try again later!
        </h4>
        <h5>
          <strong>{networkUrl}</strong>
        </h5>
        <Button id='error-btn' onClick={() => window.location.reload()} className='mt-4'>
          <span>
            Retry Connection
          </span>
        </Button>
      </Card.Body>
    </Card>
  </>
}
Example #3
Source File: QuestEnemy.tsx    From apps with MIT License 6 votes vote down vote up
function EnemyNpcDescription(props: {
    region: Region;
    enemyLookUp: EnemyLookUp;
    deck?: QuestEnemy.DeckType;
    npcId?: number;
    hash?: string;
    handleNavigateEnemyHash?: (hash: string) => void;
}) {
    const hash = props.hash ?? `${props.deck}-${props.npcId}`;
    const enemy = props.enemyLookUp.get(hash);
    if (enemy !== undefined) {
        return (
            <Button variant="link" className="move-button" onClick={() => props.handleNavigateEnemyHash?.(hash)}>
                {enemy.deckId}. <ClassIcon className={enemy.svt.className} rarity={enemy.svt.rarity} />{" "}
                <FaceIcon
                    type={enemy.svt.type}
                    rarity={enemy.svt.rarity}
                    location={enemy.svt.face}
                    mightNotExist={true}
                />{" "}
                {enemy.name} Lv. {enemy.lv}
            </Button>
        );
    } else {
        return <>Enemy {props.npcId}</>;
    }
}
Example #4
Source File: card-footer.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 6 votes vote down vote up
CardFooter = (props: any) => {

    const { t } = useTranslation();

    return (!props ? <></> :
        <Card.Footer id='data-footer'>
            <Row>
                <Col sm='6' md='3' className=''>
                    <Button
                        className='my-1 my-md-0 p-0'
                        variant='outline-primary'
                        block
                        onClick={props.handleCancel}
                    >
                        {props.cancelText
                            ? props.cancelText
                            : t('translation:cancel')}
                    </Button>
                </Col>
                <Col sm='6' md='3' className='pr-md-0'>
                    <Button
                        className='my-1 my-md-0 p-0'
                        block
                        type='submit'
                        onClick={props.handleOk}
                        disabled={props.disabled}
                    >
                        {props.okText
                            ? props.okText
                            :t('translation:next')}
                    </Button>
                </Col>
            </Row>
        </Card.Footer>
    )

}
Example #5
Source File: EmptyScreen.tsx    From bada-frame with GNU General Public License v3.0 6 votes vote down vote up
export default function EmptyScreen({ openUploader }) {
    const deduplicateContext = useContext(DeduplicateContext);
    return (
        <Wrapper>
            {deduplicateContext.isOnDeduplicatePage ? (
                <div
                    style={{
                        color: '#a6a6a6',
                        fontSize: '18px',
                    }}>
                    {constants.NO_DUPLICATES_FOUND}
                </div>
            ) : (
                <>
                    <img height={150} src="/images/gallery.png" />
                    <div style={{ color: '#a6a6a6', marginTop: '16px' }}>
                        {constants.UPLOAD_FIRST_PHOTO_DESCRIPTION}
                    </div>
                    <Button
                        variant="outline-success"
                        onClick={openUploader}
                        style={{
                            marginTop: '32px',
                            paddingLeft: '32px',
                            paddingRight: '32px',
                            paddingTop: '12px',
                            paddingBottom: '12px',
                            fontWeight: 900,
                        }}>
                        {constants.UPLOAD_FIRST_PHOTO}
                    </Button>
                </>
            )}
        </Wrapper>
    );
}
Example #6
Source File: pending-button.tsx    From polkabtc-ui with Apache License 2.0 6 votes vote down vote up
ButtonMaybePending = ({
  isPending,
  disabled,
  children,
  ...rest
}: Props & ButtonProps): JSX.Element => (
  <Button
    disabled={isPending || disabled}
    {...rest}>
    {(isPending && <FaHourglass className='inline-block' />) || children}
  </Button>
)
Example #7
Source File: index.tsx    From nouns-monorepo with GNU General Public License v3.0 6 votes vote down vote up
WalletButton: React.FC<{ onClick: () => void; walletType: WALLET_TYPE }> = props => {
  const { onClick, walletType } = props;

  return (
    <Button className={classes.walletButton} onClick={onClick}>
      <img src={logo(walletType)} alt={`${walletType} logo`} />
      {walletType}
    </Button>
  );
}
Example #8
Source File: addQueue.tsx    From remote-office-hours-queue with Apache License 2.0 6 votes vote down vote up
function CancelAddButton (props: CancelAddButtonProps) {
    return (
        <Link to='/manage/'>
            <Button variant='link' className={'text-danger ' + buttonSpacing} aria-label='Cancel' disabled={props.disabled}>
                Cancel
            </Button>
        </Link>
    );
}
Example #9
Source File: BlocklistView.tsx    From 3Speak-app with GNU General Public License v3.0 5 votes vote down vote up
export function BlocklistView(props: any) {
  const [list, setList] = useState([])

  const generate = () => {
    PromiseIpc.send('blocklist.ls', {} as any).then((value: any) => {
      setList(value)
    })
  }

  const handleRemove = async (reflink) => {
    await PromiseIpc.send('blocklist.rm', reflink)
    NotificationManager.success(`Unblocked ${reflink}`)
    generate()
  }

  useEffect(() => {
    document.title = '3Speak - Tokenised video communities'
    generate()
  }, [])

  return (
    <div>
      <Table responsive>
        <thead>
          <tr>
            <th>Reflink</th>
            <th>Reason</th>
            <th>Remove?</th>
          </tr>
        </thead>
        <tbody>
          {list.map((value) => (
            <tr key={value._id}>
              <td>{value._id}</td>
              <td>{value.reason}</td>
              <td>
                <Button variant="danger" onClick={() => handleRemove(value._id)}>
                  X
                </Button>
              </td>
            </tr>
          ))}
        </tbody>
      </Table>
    </div>
  )
}
Example #10
Source File: Login.tsx    From tutorial-cloudflare-bookstore with Apache License 2.0 5 votes vote down vote up
render() {
    if (this.state.redirect) return <Redirect to="/" />;

    return (
      <div className="Login">
        <form onSubmit={this.onLogin}>
          <FormGroup controlId="email" validationState={this.state.emailValid}>
            <ControlLabel>Email</ControlLabel>
            <FormControl
              name="email"
              type="email"
              bsSize="large"
              value={this.state.email}
              onChange={this.onEmailChange}
            />
            <FormControl.Feedback />
          </FormGroup>
          <FormGroup
            controlId="password"
            validationState={this.state.passwordValid}
          >
            <ControlLabel>Password</ControlLabel>
            <FormControl
              name="password"
              type="password"
              bsSize="large"
              value={this.state.password}
              onChange={this.onPasswordChange}
            />
            <FormControl.Feedback />
          </FormGroup>
          <Button
            block
            bsSize="large"
            type="submit"
            disabled={
              this.state.passwordValid !== "success" ||
              this.state.emailValid !== "success"
            }
          >
            {this.state.loading && (
              <Glyphicon glyph="refresh" className="spinning" />
            )}
            Log in
          </Button>
        </form>
      </div>
    );
  }
Example #11
Source File: LabelModal.tsx    From devex with GNU General Public License v3.0 5 votes vote down vote up
LabelModal: React.FC<IProps> = ({ show, handleCloseModal, addLabel }) => {
  const themeContext = useContext(ThemeContext);
  const { theme } = themeContext!;
  const [labelInput, setLabelInput] = useState("");

  const handleSubmit = (e: React.SyntheticEvent) => {
    e.preventDefault();
    setLabelInput("");
    addLabel(labelInput);
  };

  return (
    <Modal
      className={
        theme === "dark"
          ? "custom-modal dark-theme"
          : "custom-modal light-theme"
      }
      show={show}
      onHide={handleCloseModal}
    >
      <div className="modal-header">
        <h6>Add Label</h6>
      </div>
      <Modal.Body>
        <Form onSubmit={handleSubmit}>
          <div className="mb-3">
            <Form.Control
              autoFocus={true}
              required
              type="text"
              value={labelInput}
              maxLength={20}
              onChange={(e) => {
                setLabelInput(sanitizeHtml(e.target.value));
              }}
              placeholder="Label Name"
            />
          </div>
          <div>
            <Button block type="submit">
              Save
            </Button>
          </div>
        </Form>
        <div className="modal-footer">
          <span>Labels can be accessed from the Labels Page</span>
          <br />
          <span>Label data is saved in the local storage of your browser</span>
        </div>
      </Modal.Body>
    </Modal>
  );
}
Example #12
Source File: BgmDescriptor.tsx    From apps with MIT License 5 votes vote down vote up
export default function BgmDescriptor(props: {
    region: Region;
    bgm: Bgm.Bgm;
    showName?: string;
    showLink?: boolean;
    style?: React.CSSProperties;
}) {
    const bgm = props.bgm;
    if (bgm.id === 0) {
        return null;
    } else if (bgm.audioAsset !== undefined) {
        const showName = getBgmName(bgm);
        const toLink = props.showLink ? (
            <>
                <Button variant="primary" as={Link} to={`/${props.region}/bgm/${bgm.id}`}>
                    <FontAwesomeIcon icon={faShare} title={`Go to ${props.region} BGM ${showName}`} />
                </Button>
            </>
        ) : null;
        const downloadButton = bgm.notReleased ? (
            <Button disabled variant="secondary" target="_blank" title={showName}>
                {showName}
            </Button>
        ) : (
            <Button variant={"info"} href={bgm.audioAsset} target="_blank" title={`Download ${showName}`}>
                {props.showName ?? showName}&nbsp;
                <FontAwesomeIcon icon={faFileAudio} />
            </Button>
        );
        return (
            <>
                <ButtonGroup size="sm" style={props.style}>
                    <VoiceLinePlayer audioAssetUrls={[bgm.audioAsset]} delay={[0]} title={bgm.name} />
                    {downloadButton}
                    {toLink}
                </ButtonGroup>
            </>
        );
    } else {
        return (
            <Button variant={"info"} disabled style={props.style}>
                {bgm.name}
            </Button>
        );
    }
}
Example #13
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 #14
Source File: ExportFinished.tsx    From bada-frame with GNU General Public License v3.0 5 votes vote down vote up
export default function ExportFinished(props: Props) {
    const totalFiles = props.exportStats.failed + props.exportStats.success;
    return (
        <>
            <div
                style={{
                    borderBottom: '1px solid #444',
                    marginBottom: '20px',
                    padding: '0 5%',
                }}>
                <Row>
                    <Label width="35%">{constants.LAST_EXPORT_TIME}</Label>
                    <Value width="65%">
                        {formatDateTime(props.lastExportTime)}
                    </Value>
                </Row>
                <Row>
                    <Label width="60%">
                        {constants.SUCCESSFULLY_EXPORTED_FILES}
                    </Label>
                    <Value width="40%">
                        <ComfySpan>
                            {props.exportStats.success} / {totalFiles}
                        </ComfySpan>
                    </Value>
                </Row>
                {props.exportStats.failed > 0 && (
                    <Row>
                        <Label width="60%">
                            {constants.FAILED_EXPORTED_FILES}
                        </Label>
                        <Value width="35%">
                            <ComfySpan>
                                {props.exportStats.failed} / {totalFiles}
                            </ComfySpan>
                        </Value>
                    </Row>
                )}
            </div>
            <div
                style={{
                    width: '100%',
                    display: 'flex',
                    justifyContent: 'space-around',
                }}>
                <Button
                    block
                    variant={'outline-secondary'}
                    onClick={props.onHide}>
                    {constants.CLOSE}
                </Button>
                <div style={{ width: '30px' }} />
                {props.exportStats.failed !== 0 ? (
                    <Button
                        block
                        variant={'outline-danger'}
                        onClick={props.retryFailed}>
                        {constants.RETRY_EXPORT_}
                    </Button>
                ) : (
                    <Button
                        block
                        variant={'outline-success'}
                        onClick={props.exportFiles}>
                        {constants.EXPORT_AGAIN}
                    </Button>
                )}
            </div>
        </>
    );
}
Example #15
Source File: AddYearPopup.tsx    From peterportal-client with MIT License 5 votes vote down vote up
AddYearPopup: FC<AddYearPopupProps> = ({ placeholderYear }) => {
  const dispatch = useAppDispatch();
  const [year, setYear] = useState(placeholderYear);
  const [show, setShow] = useState(false);
  const target = useRef(null);

  useEffect(() => { setYear(placeholderYear) }, [placeholderYear]);

  const handleClick = (event: React.MouseEvent) => {
    setShow(!show);
  };

  return (
    <div>
      <Button variant="light" ref={target} className="add-year-btn" onClick={handleClick}>
        <PlusCircleFill className="add-year-icon" />
        <div className="add-year-text">Add year</div>
      </Button>
      <Overlay show={show} target={target} placement="top">
        <Popover id=''>
          <Popover.Content>
            <Form>
              <Form.Group>
                <Form.Label className="add-year-form-label">
                  Start Year
                </Form.Label>
                <Form.Control
                  type="number"
                  name="year"
                  value={year}
                  onChange={(e) => {
                    setYear(parseInt(e.target.value));
                  }}
                  onKeyDown={(e: React.KeyboardEvent) => {
                    // prevent submitting form (reloads the page)
                    if (e.key === 'Enter') {
                      e.preventDefault();
                    }
                  }}
                  min={1000}
                  max={9999}
                  placeholder={placeholderYear.toString()}
                ></Form.Control>
              </Form.Group>
              <Button
                className="popup-btn"
                onClick={() => {
                  setShow(!show);
                  dispatch(addYear(
                    {
                      yearData: {
                        startYear: year,
                        quarters: ['fall', 'winter', 'spring'].map(quarter => { return { name: quarter, courses: [] } })
                      }
                    }
                  ));
                  setYear(placeholderYear);
                }}
              >
                Add Year
              </Button>
            </Form>
          </Popover.Content>
        </Popover>
      </Overlay>
    </div >
  );
}
Example #16
Source File: table-page-selector.tsx    From polkabtc-ui with Apache License 2.0 5 votes vote down vote up
export default function TablePageSelector({ totalPages, currentPage, setPage }: TablePageSelectorProps): ReactElement {
  const { t } = useTranslation();

  if (totalPages <= 1) totalPages = 1;

  const displayedPages = 5;
  // const displayedPages = Math.min(totalPages, pagesToDisplay);
  const first = Math.max(currentPage - Math.ceil(displayedPages / 2 - 1), 0);
  const last = Math.min(first + displayedPages, totalPages);
  const pages = range(first, last);

  return (
    <Row className='justify-content-between mt-5'>
      <Button
        variant='outline-dark'
        onClick={() => setPage(Math.max(currentPage - 1, 0))}>{t('prev')}
      </Button>
      <Col sm={4}>
        {pages[0] === 0 ? (
          ''
        ) : (
          <>
            <PageLink {...{ page: 0, setPage }} />
            {'\u2026'}&nbsp;
          </>
        )}
        {pages.map(page => (
          <PageLink
            key={page}
            {...{ page, setPage }} />
        ))}
        {pages[pages.length - 1] === totalPages - 1 ? (
          ''
        ) : (
          <>
            {'\u2026'}
            <PageLink {...{ page: totalPages - 1, setPage }} />
          </>
        )}
      </Col>
      <Button
        variant='outline-dark'
        onClick={() => setPage(Math.min(currentPage + 1, totalPages - 1))}>{t('next')}
      </Button>
    </Row>
  );
}
Example #17
Source File: ManageCategories.tsx    From Apni-Dukan-Frontend with MIT License 5 votes vote down vote up
ManageCategories = () => {
  const [categories, setCategories] = useState<Category[]>([]);

  const { _id, token } = isAuthenticated() as JWT;

  const preload = () => {
    getCategories().then((data) => {
      if ((data as CustomError).error) {
        // console.log((data as CustomError).error);
      } else {
        setCategories(data as Category[]);
      }
    });
  };

  const deleteaCategory = (categoryId: string) => {
    deleteCategory(categoryId, _id, token).then((data) => {
      if (data.error) {
        // console.log(data.error);
      } else {
        preload();
      }
    });
  };

  useEffect(() => {
    preload();
  }, []);

  return (
    <Base title="Manage all your categories here!" description="">
      <div className="container bg-info rounded p-2">
        <div className="row">
          {categories.map((category, index) => (
            <div key={index} className="col-12 col-sm-6 col-md-4">
              <Card className="mb-2">
                <Card.Header className="text-dark">{category.name}</Card.Header>
                <Button variant="success" className="p-1 m-1">
                  Update
                </Button>
                <Button
                  onClick={() => deleteaCategory(category._id!)}
                  variant="danger"
                  className="p-1 m-1"
                >
                  Delete
                </Button>
              </Card>
            </div>
          ))}
        </div>
        <div className="m-3">
          <Button variant="light">
            <Link
              style={{ textDecoration: "none", color: "black" }}
              to="/admin/dashboard"
            >
              Go Back
            </Link>
          </Button>
        </div>
      </div>
    </Base>
  );
}
Example #18
Source File: index.tsx    From nouns-monorepo with GNU General Public License v3.0 5 votes vote down vote up
CreateProposalButton = ({
  className,
  isLoading,
  proposalThreshold,
  hasActiveOrPendingProposal,
  hasEnoughVote,
  isFormInvalid,
  handleCreateProposal,
}: {
  className?: string;
  isLoading: boolean;
  proposalThreshold?: number;
  hasActiveOrPendingProposal: boolean;
  hasEnoughVote: boolean;
  isFormInvalid: boolean;
  handleCreateProposal: () => void;
}) => {
  const buttonText = () => {
    if (hasActiveOrPendingProposal) {
      return <Trans>You already have an active or pending proposal</Trans>;
    }
    if (!hasEnoughVote) {
      if (proposalThreshold) {
        return (
          <Trans>
            You must have {i18n.number(proposalThreshold || 0 + 1)} votes to submit a proposal
          </Trans>
        );
      }
      return <Trans>You don't have enough votes to submit a proposal</Trans>;
    }
    return <Trans>Create Proposal</Trans>;
  };

  return (
    <div className="d-grid gap-2">
      <Button
        className={className}
        variant={hasActiveOrPendingProposal || !hasEnoughVote ? 'danger' : 'primary'}
        disabled={isFormInvalid || hasActiveOrPendingProposal || !hasEnoughVote}
        onClick={handleCreateProposal}
      >
        {isLoading ? <Spinner animation="border" /> : buttonText()}
      </Button>
    </div>
  );
}
Example #19
Source File: addQueue.tsx    From remote-office-hours-queue with Apache License 2.0 5 votes vote down vote up
// The 'tab-custom' role is used to override a default 'tab' role that resulted in tab links not being keyboard accessible.
function AddQueueEditor(props: AddQueueEditorProps) {
    return (
        <Tab.Container id='add-queue-editor' defaultActiveKey='general' activeKey={props.activeKey} onSelect={props.onTabSelect}>
            <Row>
                <Col md={3} sm={3}>
                    <Nav variant='pills' className='flex-column mt-5'>
                        <Nav.Item>
                            <Nav.Link eventKey='general' role='tab-custom' tabIndex={0} aria-label='General Tab'>
                                General
                            </Nav.Link>
                        </Nav.Item>
                        <Nav.Item>
                            <Nav.Link eventKey='hosts' role='tab-custom' tabIndex={0} aria-label='Manage Hosts Tab'>
                                Manage Hosts
                            </Nav.Link>
                        </Nav.Item>
                    </Nav>
                </Col>
                <Col md={6} sm={9}>
                    <h1>Add Queue</h1>
                    <Tab.Content aria-live='polite'>
                        <Tab.Pane eventKey='general'>
                            <GeneralEditor {...props} />
                            <div className='mt-4'>
                                <Button
                                    variant='primary'
                                    className={buttonSpacing}
                                    aria-label='Next'
                                    disabled={props.disabled}
                                    onClick={props.onGeneralNextClick}
                                >
                                    Next
                                </Button>
                                <CancelAddButton disabled={props.disabled} />
                            </div>
                        </Tab.Pane>
                        <Tab.Pane eventKey='hosts'>
                            <ManageHostsEditor {...props} />
                            <div className='mt-4'>
                                <Button
                                    variant='primary'
                                    className={buttonSpacing}
                                    aria-label='Back'
                                    disabled={props.disabled}
                                    onClick={props.onBackClick}
                                >
                                    Back
                                </Button>
                                <Button
                                    variant='primary'
                                    className={buttonSpacing}
                                    aria-label='Finish Adding Queue'
                                    disabled={props.disabled}
                                    onClick={props.onFinishClick}
                                >
                                    Finish Adding Queue
                                </Button>
                                <CancelAddButton disabled={props.disabled} />
                            </div>
                        </Tab.Pane>
                    </Tab.Content>
                </Col>
            </Row>
        </Tab.Container>
    );
}
Example #20
Source File: TopNavbar.tsx    From 3Speak-app with GNU General Public License v3.0 4 votes vote down vote up
export function TopNavbar() {
  const [inEdit, setInEdit] = useState(false)
  const urlForm = useRef<any>()
  const [urlSplit, setUrlSplit] = useState([])

  const startEdit = () => {
    setInEdit(true)
  }

  useEffect(() => {
    if (inEdit) {
      urlForm.current?.focus()
    }
  }, [inEdit])

  const exitEdit = () => {
    setInEdit(false)
  }

  const finishEdit = (e) => {
    if (e.keyCode === 13) {
      if (location.hash !== `#${e.target.value}`) {
        location.replace(`#${e.target.value}`)
        location.reload()
      }
      setInEdit(false)
    } else if (e.keyCode === 27) {
      exitEdit()
    }
  }

  const updateUrlSplit = () => {
    const hash = window.location.hash
    const theUrlSplit = hash.split('/')
    theUrlSplit.splice(0, 1)

    if (theUrlSplit[0] === 'watch') {
      const pagePerm = theUrlSplit[1]
      const pagePermSpliced = pagePerm.split(':')
      pagePermSpliced.splice(0, 1)
      theUrlSplit.pop()
      pagePermSpliced.forEach((onePagePerm) => {
        theUrlSplit.push(onePagePerm)
      })

      setUrlSplit(theUrlSplit)
    } else {
      setUrlSplit(theUrlSplit)
    }
  }

  useEffect(() => {
    updateUrlSplit()
  }, [])

  useEffect(() => {
    window.addEventListener('hashchange', function (event) {
      updateUrlSplit()
    })
  }, [])

  const userProfileUrl = useMemo(() => {
    const windowLocationHash = window.location.hash
    const windowLocationSearch = windowLocationHash.search('#')
    const windowLocationHref = windowLocationHash.slice(windowLocationSearch)
    const hrefSegments = windowLocationHref.split('/')
    hrefSegments.splice(0, 1)

    let userProfileUrl = '#/user/'

    if (hrefSegments[0] === 'watch') {
      const userProfileUrlInit = hrefSegments[1]
      const userProfileUrlSpliced = userProfileUrlInit.split(':')
      userProfileUrlSpliced.pop()

      userProfileUrlSpliced.forEach((one) => {
        if (one === userProfileUrlSpliced[0]) {
          userProfileUrl = userProfileUrl + one + ':'
        } else {
          userProfileUrl = userProfileUrl + one
        }
      })
    }

    return userProfileUrl
  }, [])

  return (
    <div>
      <Navbar bg="light" expand="lg">
        <Navbar.Collapse id="basic-navbar-nav">
          <Nav className="mr-auto">
            {!inEdit ? (
              <>
                <Breadcrumb>
                  <Breadcrumb.Item href="#/">Home</Breadcrumb.Item>
                  {urlSplit.map((el) =>
                    el === updateUrlSplit[1] && updateUrlSplit[0] === 'watch' ? (
                      <Breadcrumb.Item href={userProfileUrl} key={el} id={el}>
                        {el}
                      </Breadcrumb.Item>
                    ) : (
                      <Breadcrumb.Item href={'#'} key={el} id={el}>
                        {el}
                      </Breadcrumb.Item>
                    ),
                  )}
                </Breadcrumb>
                <Button
                  className="btn btn-light btn-sm"
                  style={{
                    marginLeft: '5px',
                    width: '40px',
                    height: '40px',
                    padding: '3.5%',
                    verticalAlign: 'baseline',
                  }}
                  onClick={startEdit}
                >
                  <FaEdit style={{ textAlign: 'center', verticalAlign: 'initial' }} />
                </Button>
              </>
            ) : (
              <FormControl
                ref={urlForm}
                defaultValue={(() => {
                  return location.hash.slice(1)
                })()}
                onKeyDown={finishEdit}
                onBlur={exitEdit}
              />
            )}
          </Nav>
          <Dropdown>
            <Dropdown.Toggle variant="secondary" size="lg">
              Options
            </Dropdown.Toggle>

            <Dropdown.Menu>
              <Dropdown.Item onClick={() => copyToClip(window.location.hash)}>
                Copy Current URL{' '}
                <FaCopy size={28} onClick={() => copyToClip(window.location.hash)} />
              </Dropdown.Item>
              <Dropdown.Item onClick={goToClip}>
                Go to Copied URL <FaArrowRight size={28} />
              </Dropdown.Item>
            </Dropdown.Menu>
          </Dropdown>
          <Nav>
            <Nav.Link>
              <FaAngleLeft size={28} onClick={goBack} />
            </Nav.Link>
            <Nav.Link>
              <FaAngleRight size={28} onClick={goForth} />
            </Nav.Link>
          </Nav>
        </Navbar.Collapse>
      </Navbar>
    </div>
  )
}
Example #21
Source File: VieraConfigUI.tsx    From homebridge-vieramatic with Apache License 2.0 4 votes vote down vote up
Body = () => {
  useSingleton(() => void (async (): Promise<void> => await updateGlobalConfig())())
  const state = useState(globalState)

  useEffect(
    () => (state.loading.value ? homebridge.showSpinner() : homebridge.hideSpinner()),
    [state.loading.value]
  )

  const request = async (path: string, body?: unknown) => {
    state.loading.set(true)
    return await homebridge.request(path, body).finally(() => state.loading.set(false))
  }

  const previousConfig = (ip: string): UserConfig | undefined =>
    state.pluginConfig.tvs.value.find((o) => o.ipAddress === ip)

  const backToMain = (form?: IHomebridgeUiFormHelper) => {
    if (form) form.end()
    state.merge({ frontPage: true, selected: none })
  }

  const onEdition = async (raw?: string): Promise<void> => {
    const pair = (challenge: string) => {
      const pinForm = homebridge.createForm(pinRequestSchema, undefined, 'Next', 'Cancel')
      pinForm.onCancel(pinForm.end)
      pinForm.onSubmit(
        async (data) =>
          await request('/pair', { challenge, ip: tv.ipAddress, pin: data.pin })
            .then(async (auth: VieraAuth) => {
              const body = JSON.stringify({ ...tv, appId: auth.appId, encKey: auth.key })
              const specs: VieraSpecs = await request('/specs', body)
              return { auth, specs }
            })
            // eslint-disable-next-line promise/always-return
            .then((payload) => {
              const config = { ...tv, appId: payload.auth.appId, encKey: payload.auth.key }
              state.selected.merge({ config, onHold: false, reachable: true, specs: payload.specs })
            })
            .catch(() => {
              homebridge.toast.error('Wrong PIN...', tv.ipAddress)
              backToMain()
            })
            .finally(pinForm.end)
      )
    }

    if (!raw) {
      state.frontPage.set(false)
      const tvForm = homebridge.createForm(tvAddressSchema, undefined, 'Next', 'Cancel')
      tvForm.onCancel(() => backToMain(tvForm))

      tvForm.onSubmit(async (data) => {
        if (isValidIPv4(data.ipAddress)) {
          if (previousConfig(data.ipAddress))
            homebridge.toast.error('Trying to add an already configured TV set!', data.ipAddress)
          else {
            tvForm.end()
            const config = { hdmiInputs: [], ipAddress: data.ipAddress }
            state.selected.merge({ config, onHold: true })
          }
        } else homebridge.toast.error('Please insert a valid IP address...', data.ipAddress)
      })
    } else
      state.batch((s) => {
        s.selected.merge({ config: JSON.parse(raw), onHold: true }), s.frontPage.set(false)
      })

    while (!state.selected.value?.config) await sleep(250)
    const tv = state.selected.value.config
    await request('/ping', tv.ipAddress).then(async (reachable: boolean) => {
      /* eslint-disable promise/no-nesting*/
      if (!reachable) return state.selected.merge({ onHold: false, reachable })
      return await request('/specs', JSON.stringify(tv))
        .then((specs) => state.selected.merge({ onHold: false, reachable, specs }))
        .catch(async () => await request('/pin', tv.ipAddress).then((challenge) => pair(challenge)))
    })
  }

  const onDeletion = (raw: string) =>
    state.batch((s) => {
      s.frontPage.set(false), s.selected.merge({ config: JSON.parse(raw), onHold: false })
    })

  const FrontPage = () => {
    const flip = () => !state.abnormal.value && state.killSwitch.set((k) => !k)
    const label = `${state.killSwitch.value ? 'deletion' : 'edition'} mode`
    const doIt = (tv: string) => (state.killSwitch.value ? onDeletion(tv) : onEdition(tv))
    const KillBox = () =>
      state.pluginConfig.value.tvs.length === 0 ? (
        <></>
      ) : state.abnormal.value ? (
        <Alert variant="warning" className="d-flex justify-content-center mt-3 mb-5">
          <b>more than one TV with same IP address found: please delete the bogus ones!</b>
        </Alert>
      ) : (
        <Form className="d-flex justify-content-end mt-3 mb-5">
          <Form.Switch onChange={flip} id="kS" label={label} checked={state.killSwitch.value} />
        </Form>
      )
    const style = { height: '4em', width: '10em' }
    const AddNew = () =>
      state.killSwitch.value ? (
        <></>
      ) : (
        <div className="d-flex justify-content-center mt-3 mb-5">
          <Button
            className="my-4"
            variant="primary"
            onClick={async () => await onEdition()}
            style={style}
          >
            <Icon fixedWidth size="sm" icon={faTv} /> <br />
            <Icon fixedWidth size="lg" icon={faCartPlus} />
          </Button>
        </div>
      )
    const Available = () => {
      const variant = state.killSwitch.value ? 'danger' : 'info'
      const onClick = (tv: UserConfig) => doIt(JSON.stringify(tv))
      const tvs = state.pluginConfig.value.tvs.map((tv, index) => (
        <Button variant={variant} style={style} key={index} onClick={() => onClick(tv)}>
          <Icon fixedWidth size="lg" icon={state.killSwitch.value ? faTrash : faTv} />
          <br /> {tv.ipAddress}
        </Button>
      ))
      return <>{tvs}</>
    }

    return (
      <section className="mh-100">
        <KillBox /> <Available /> <AddNew />
      </section>
    )
  }

  const Results = (props: { selected: State<Selected> | undefined }) => {
    if (!props.selected || props.selected.onHold.value) return <></>

    const Offline = (props: { selected: State<Selected> }) => (
      <Alert variant="danger" className="mt-3">
        <Alert.Heading>
          The Viera TV at <b>{props.selected.config.ipAddress.value}</b> could not be edited.
        </Alert.Heading>
        <hr />
        <p className="mb-2">
          Please, do make sure that it is <b>turned on</b> and <b>connected to the network</b>, and
          then try again.
        </p>
        <div className="mt-4 w-75 mx-auto">
          <p className="text-left ">
            Also, <b>if you haven't done it already</b>...
          </p>
          <p className="text-left">
            ...on your TV go to <b>Menu / Network / TV Remote App Settings</b> and make sure that
            the following settings are <b>all</b> turned <b>ON</b>:
            <ul className="mt-2">
              <li>
                <b>TV Remote</b>
              </li>
              <li>
                <b>Powered On by Apps</b>
              </li>
              <li>
                <b>Networked Standby</b>
              </li>
            </ul>
          </p>
        </div>
        <div className="d-flex justify-content-end mt-5">
          <Button onClick={() => backToMain()} variant="primary">
            OK
          </Button>
        </div>
      </Alert>
    )

    const ConfirmDeletion = (props: { selected: State<Selected> }) => {
      const { ipAddress } = props.selected.config.value
      const nxt = rawClone(state.pluginConfig.value.tvs.filter((o) => o.ipAddress !== ipAddress))
      const dropIt = async () =>
        await updateHomebridgeConfig(ipAddress, nxt, actionType.delete).then(() => backToMain())

      return (
        <Alert variant="danger" className="mt-3">
          <Alert.Heading>
            The Viera TV at <b>{ipAddress}</b> is about to be deleted from this Homebridge.
          </Alert.Heading>
          <hr />
          <div className="d-flex justify-content-center">
            <div className="w-75">
              <p className="mb-2">Please, make sure you know what you are doing...</p>
              <hr />
              <pre class="text-monospace text-left bg-light p-2">
                {prettyPrint(props.selected.config.value)}
              </pre>
              <hr />
            </div>
          </div>
          <div className="d-flex justify-content-end mt-1">
            <Button onClick={() => backToMain()} variant="primary">
              Cancel
            </Button>
            <Button onClick={() => dropIt()} variant="danger">
              Delete
            </Button>
          </div>
        </Alert>
      )
    }

    const Editor = (props: { selected: State<Selected> }) => {
      if (props.selected.specs.ornull?.requiresEncryption.value)
        commonFormLayout.splice(1, 0, authLayout)

      const schema = { layout: commonFormLayout, schema: commonSchema }
      const data = rawClone(props.selected.config.value)
      const tvform = homebridge.createForm(schema, data, 'Submit', 'Cancel')
      tvform.onCancel(() => backToMain(tvform))
      tvform.onSubmit(async (submited) => {
        const queued = submited as UserConfig
        state.loading.set(true)
        backToMain(tvform)
        const before = previousConfig(queued.ipAddress)
        let [others, type] = [[] as UserConfig[], actionType.none]

        if (!isSame(before, queued)) {
          const modded = before !== undefined
          const { tvs } = state.pluginConfig.value
          others = modded ? rawClone(tvs.filter((v) => v.ipAddress != queued.ipAddress)) : []
          type = modded ? actionType.update : actionType.create
        }
        await updateHomebridgeConfig(queued.ipAddress, [...others, queued], type).finally(() =>
          state.loading.set(false)
        )
      })
      return <></>
    }

    if (state.killSwitch.value) return <ConfirmDeletion selected={props.selected} />
    if (props.selected.reachable.value) return <Editor selected={props.selected} />
    return <Offline selected={props.selected} />
  }

  return state.frontPage.value ? <FrontPage /> : <Results selected={state.selected.ornull} />
}
Example #22
Source File: Home.tsx    From tutorial-cloudflare-bookstore with Apache License 2.0 4 votes vote down vote up
renderLanding() {
    return (
      <div className="lander">
        <hr />
        <p>
          Welcome to the Edge Commerce Bookstore example app built entirely with
          Cloudflare Workers & Marcometa Global Data Network. It's entirely
          serverless and geo-distributed, which provides a lovely developer
          experience when building it and unparalleled performance.
        </p>
        <p>
          Creating a new user account to access the app will give you the full
          'shopping' experience. If you don't want to take the time to sign up,
          you can access a shared demo account with a single click below (more
          than one person may be logged into the shared account at once, so you
          might see some unexpected behavior).
        </p>
        <p>
          Learn more about the architecture of the app by checking out the
          source code in this{" "}
          <a
            href="https://github.com/Macrometacorp/tutorial-cloudflare-bookstore"
            target="_blank"
          >
            github repository
          </a>
          .
        </p>
        <div className="button-container col-md-12">
          <div style={{ paddingTop: "20px", paddingBottom: "20px" }}>
            <LinkContainer to="/signup">
              <a href="/signup">Create an Edge Commerce Demo Account</a>
            </LinkContainer>
          </div>
          <div style={{ marginLeft: "30%", marginRight: "30%" }}>
            <p
              onClick={(event: any) => {
                this.onLogin(event);
              }}
              className="link-click"
              style={{
                color: "#2eadde",
                fontSize: "14px",
                fontWeight: "bold",
              }}
            >
              {this.state.isLoading && (
                <Glyphicon glyph="refresh" className="spinning" />
              )}
              Log in to shared guest account
            </p>
          </div>
        </div>
        <figure>
          <img
            src={screenshot}
            className="img-fluid full-width screenshot-shadow img-center"
            alt="Screenshot"
          ></img>

          <figcaption style={{ paddingTop: "2px" }}>
            <p style={{ fontSize: "15px" }}>
              This example app is an exact replica of the Amazon Web Services{" "}
              <a href="https://d2h3ljlsmzojxz.cloudfront.net/" target="_blank">
                Amazon Book Store example app
              </a>{" "}
              using Cloudflare and Macrometa instead of AWS.
            </p>
          </figcaption>
        </figure>
        <footer
          style={{
            height: "auto",
            backgroundColor: "#3d3cb1",
            display: "flex",
            flexDirection: "column",
            justifyContent: "center",

            marginTop: "100px",
          }}
        >
          <div
            style={{
              display: "flex",
              justifyContent: "space-around",
              flexDirection: "column",
            }}
          >
            <div
              style={{
                display: "flex",
                justifyContent: "center",
                paddingBottom: "10px",
                paddingTop: "40px",
              }}
            >
              <h4
                style={{
                  color: "white",
                  display: "flex",
                  justifyContent: "center",
                }}
              >
                Get started using Macrometa
              </h4>
            </div>
            <div
              style={{
                display: "flex",
                justifyContent: "center",
                paddingBottom: "40px",
              }}
            >
              <form
                action="https://cloudflare.paas.macrometa.io/signup"
                method="get"
                target="_blank"
              >
                <Button type="submit">
                  {this.state.isLoading && (
                    <Glyphicon glyph="refresh" className="spinning" />
                  )}
                  Sign up for FREE a Developer Account
                </Button>
              </form>
            </div>
          </div>
        </footer>
      </div>
    );
  }
Example #23
Source File: ImportExport.tsx    From devex with GNU General Public License v3.0 4 votes vote down vote up
ImportExport: React.FC<IProps> = ({ type, map, setMapCb, toJson, fromJson }) => {

  const onDrop = useCallback((acceptedFiles: Blob[]) => {
    acceptedFiles.forEach((file: Blob) => {
      const reader = new FileReader()

      reader.onload = () => {
        const parsedFile = JSON.parse(reader.result as string)
        setMapCb(fromJson ? fromJson(parsedFile) : parsedFile)
      }
      reader.readAsText(file)
    })
  }, [setMapCb, fromJson])

  const { getRootProps, getInputProps } = useDropzone({ noDrag: true, onDrop })

  return (
    <>
      <div className='import-export'>
        <span className='mr-1' {...getRootProps()}>
          <input {...getInputProps()} />
          <OverlayTrigger placement='top'
            overlay={<Tooltip id={'import-tt'}>{type === 'labels' ? 'Import Labels' : 'Import Networks'}</Tooltip>}>
            <Button>
              <FontAwesomeIcon
                icon={faDownload}
                size='sm' />
            </Button>
          </OverlayTrigger>
        </span>
        <span className='ml-2'>
          <OverlayTrigger placement='top'
            overlay={<Tooltip id={'export-tt'}>{type === 'labels' ? 'Export Labels' : 'Export Networks'}</Tooltip>}>
            <Button
              onClick={() => {
                exportToJson(type, toJson, map)
              }}>
              <FontAwesomeIcon
                icon={faUpload}
                size='sm' />
            </Button>
          </OverlayTrigger>
        </span>
      </div>
    </>
  )
}
Example #24
Source File: ErrorStatus.tsx    From apps with MIT License 4 votes vote down vote up
render() {
        document.title = "Error - Atlas Academy DB";
        let message: string | JSX.Element;

        const links = [
            <Link to={`/`}>
                <Button variant="primary" style={{ minWidth: "130px" }}>
                    {"DB Home"}
                </Button>
            </Link>,
            <Button variant="primary" style={{ minWidth: "130px" }} onClick={() => window.history.back()}>
                {"Previous Page"}
            </Button>,
        ];

        if (this.props.endpoint !== undefined && this.props.region !== undefined && this.props.id !== undefined) {
            const { region, endpoint, id } = this.props;
            message = "This page does not exist. ";
            const searchResults = fuseEndpoints.search(endpoint);

            if (searchResults.length) {
                const match = searchResults[0].item;

                message = (
                    <>
                        {`This page does not exist.`}
                        <br />
                        {`Maybe you meant to go to `}
                        <Link to={`/${region}/${match}/${id}`}>{`${match}/${id}`}</Link>
                        {" instead?"}
                    </>
                );
            }
        } else if (this.props.endpoint !== undefined && this.props.region !== undefined) {
            message = "This page does not exist.";
            if (this.props.endpoint.length) {
                const endpoint = fuseEndpoints.search(this.props.endpoint)?.[0]?.item ?? "";
                if (endpoint.length) {
                    message += ` Maybe you meant to view all ${getSanitisedEndpoint(endpoint).display}s?`;
                    links.splice(
                        links.length - 1,
                        0,
                        <Link to={`/${this.props.region}/${getSanitisedEndpoint(endpoint).name}s`}>
                            <Button variant="primary" style={{ minWidth: "130px" }}>{`${
                                getSanitisedEndpoint(endpoint).display
                            }s`}</Button>
                        </Link>
                    );
                }
            }
        } else if (this.props.error === undefined || this.props.error.response === undefined) {
            message = "This page does not exist";
        } else if (this.props.error.response.status === 500) {
            message = "Server Error";
        } else if (this.props.error.response.status === 404) {
            message = "Not Found";
        } else {
            message = "Code " + this.props.error.response.status;
        }

        if (
            typeof this.props.error?.response?.data === "object" &&
            this.props.error.response.data !== null &&
            typeof (this.props.error.response.data as any).detail === "string"
        ) {
            const [, , region, rawEndpoint] =
                this.props.error.response.config.url!.match(/\/nice\/(NA|JP|CN|KR|TW)\/.*(?=\/)/)?.[0]?.split("/") ??
                Array(4).fill("");

            if (rawEndpoint) {
                const niceEndpoint = getSanitisedEndpoint(rawEndpoint);

                message = `${niceEndpoint.display} not found.`;

                links.splice(
                    links.length - 1,
                    0,
                    <Link to={`/${region}/${niceEndpoint.name}s`}>
                        <Button variant="primary" style={{ minWidth: "130px" }}>
                            {niceEndpoint.display}
                            {"s"}
                        </Button>
                    </Link>
                );
            }
        }

        const random = Math.floor(Math.random() * images.length),
            image = images[random];

        return (
            <div id={"error-status"} style={{ maxWidth: "1000px", margin: "0 auto" }}>
                <img
                    alt={"Error"}
                    src={image}
                    style={{
                        display: "block",
                        height: 300,
                        margin: "0 auto",
                    }}
                />
                <p style={{ width: "fit-content", margin: "0 auto", padding: "10px" }}>
                    <strong>ERROR: {message}</strong>
                </p>
                <ul
                    style={{
                        width: "fit-content",
                        listStyleType: "none",
                        margin: "0 auto",
                        padding: 0,
                    }}
                >
                    {links.map((link, idx) => (
                        <li key={idx} className="d-inline my-0 mx-1">
                            {link}
                        </li>
                    ))}
                </ul>
            </div>
        );
    }
Example #25
Source File: dataprivacy.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
DataprivacyPage = (props: any) => {

    const { t } = useTranslation();
    const [show, setShow] = React.useState(false);

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

    const handleClose = () => {
        props.setShow(false)
    }

    return (
        <>
            <Modal
                size='lg'
                contentClassName='bg-light'
                scrollable
                show={show}
                aria-labelledby="example-custom-modal-styling-title"
                centered
                onHide={handleClose}

            >
                <Modal.Header id='data-header' closeButton className='pb-0' >
                    <Row>
                        <Col >
                            <Card.Title className='m-0 jcc-xs-jcfs-md' as={'h2'} >{t('translation:dp-title')}</Card.Title>
                        </Col>
                    </Row>
                </Modal.Header>
                    <hr className='mx-3 mb-0' />
                <Modal.Body className='px-3 bg-light'>
                    <Container className='px-1 px-sm-2 px-md-3'>
                        <h5 className='text-justify'>
                            Der Schutz Ihrer persönlichen Daten hat für die T-Systems International GmbH einen hohen Stellenwert. Es ist uns wichtig, Sie darüber zu informieren, welche persönlichen Daten erfasst werden, wie diese verwendet werden und welche Gestaltungsmöglichkeiten Sie dabei haben.
                    </h5>

                        <ol>
                            <li className='text-justify py-3'>
                                <strong>Welche Daten werden erfasst, wie werden sie verwendet und wie lange werden sie gespeichert?</strong>
                                <ol type='a' className='pr-2 pr-md-4'>
                                    <li>
                                        <strong>Technische Merkmale:</strong> <br />
                                        Wenn Sie sich an unserem Schnelltestportal anmelden, verzeichnet der Server Ihren Benutzernamen, die Teststellen-ID, den verwendeten Mandanten (und die von Ihnen ausgeführten Datenbankoperationen (z.B. Eingabe von Patientendaten, Eingabe von Testergebnissen). 
Die protokollierten Daten werden ausschließlich für Zwecke der Datensicherheit, insbesondere zur Abwehr von Angriffsversuchen auf unseren Server verwendet (Art. 6 Abs. 1f DSGVO). Sie werden weder für die Erstellung von individuellen Anwenderprofilen verwendet noch an Dritte weitergegeben und werden nach Ablauf eines Zeitraums von 7 Tagen bis 30 Tagen gelöscht. Die statistische Auswertung anonymisierter Datensätze behalten wir uns vor.<br />
                                    </li>
                                    <li className='py-3'>
                                        <strong>Authentifizierungsdaten:</strong> <br />
                                        Wenn Sie sich an unserem Schnelltest-Portal anmelden, werden erfolgreiche und fehlgeschlagene Anmeldeversuche dokumentiert. Diese Dokumentation umfasst den Benutzernamen, Ihren Vor- und Nachnamen, den Zeitpunkt der Anmeldung, die IP-Adresse, von der aus die Anmeldung durchgeführt wurde und die Session-Dauer. Rechtsgrundlage dieser Verarbeitung ist § 26 Abs. 1 BDSG, soweit Sie als Beschäftigter eines Unternehmens, welches unsere Leistungen in Anspruch nimmt, tätig sind. Sind Sie auf selbständiger Basis für ein Unternehmen tätig, welches unsere Leistungen in Anspruch nimmt, erfolgt die Verarbeitung auf Grund der durch Ihren Auftraggeber eingeholten Einwilligung zur Speicherung.<br />
                                    </li>
                                    <li>
                                        <strong>Archivierung von Testergebnissen:</strong> <br />
                                        Ihr Benutzername wird zusammen mit den Patientendaten des durchgeführten Tests (Name, Vorname, Geburtsdatum, Geschlecht, Adresse, Testhersteller, eingesetzter Test, Tag des Testergebnisses) und dem Testergebnis gemäß gesetzlicher Grundlage archiviert und 10 Jahre aufbewahrt und dann gelöscht.<br />
                                    </li>
                                </ol>
                            </li>
                            <li className='text-justify py-3' >
                                <strong>Wird mein Nutzungsverhalten ausgewertet, z. B. für Werbung oder Tracking?<br /></strong>
                                Es werden nur für die Nutzung des Schnelltest-Portals erforderliche Cookies verwendet. Diese Cookies sind notwendig, damit Sie durch die Seiten navigieren und wesentliche Funktionen nutzen können. Sie ermöglichen die Benutzung des Schnelltestportals. Rechtsgrundlage für diese Cookies ist Art. 6 Abs. 1b DSGVO bzw. bei Drittstaaten Art. 49 Abs. 1b DSGVO.
                             
                            </li>
                            <Table className='my-3'>
                                <thead>
                                    <tr>
                                        <th>Firma</th>
                                        <th>Zweck</th>
                                        <th>Speicherdauer</th>
                                        <th>Land der Verarbeitung</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr>
                                        <td>T-Systems</td>
                                        <td>Login</td>
                                        <td>Session Cookie</td>
                                        <td>Deutschland</td>
                                    </tr>
                                </tbody>
                            </Table>
                            <li className='text-justify py-3' >
                                <strong>Wo finde ich die Informationen, die für mich wichtig sind?</strong><br />
                                Dieser <strong>Datenschutzhinweis</strong> gibt einen Überblick über die Punkte, die für die Verarbeitung Ihrer Daten in diesem Webportal durch T-Systems gelten.<br />
Weitere Informationen, auch zum Datenschutz im allgemeinen und in speziellen Produkten, erhalten Sie auf <a href='https://www.telekom.com/de/verantwortung/datenschutz-und-datensicherheit/datenschutz'>https://www.telekom.com/de/verantwortung/datenschutz-und-datensicherheit/datenschutz</a> und unter <a href='http://www.telekom.de/datenschutzhinweise'>http://www.telekom.de/datenschutzhinweise</a>.
                            </li>
                            <li className='text-justify py-3' >
                                <strong>Wer ist verantwortlich für die Datenverarbeitung? Wer ist mein Ansprechpartner, wenn ich Fragen zum Datenschutz bei der Telekom habe?</strong><br />
                                Datenverantwortliche ist die T-Systems International GmbH. Bei Fragen können Sie sich an unseren <a href='http://www.telekom.de/kontakt'>Kundenservice</a> wenden oder an unseren Datenschutzbeauftragten, Herrn Dr. Claus D. Ulmer, Friedrich-Ebert-Allee 140, 53113 Bonn, <a href='mailto:[email protected]'>[email protected]</a>.
                            </li>
                            <li className='text-justify py-3' >
                                <strong>Welche Rechte habe ich? </strong><br />
                                Sie haben das Recht,
                                <ol type='a' className='pr-2 pr-md-4'>
                                    <li>
                                        <strong>Auskunft</strong> zu verlangen zu Kategorien der verarbeiteten Daten, Verarbeitungszwecken, etwaigen Empfängern der Daten, der geplanten Speicherdauer (Art. 15 DSGVO);
                                    </li>
                                    <li>
                                        die <strong>Berichtigung</strong> bzw. Ergänzung unrichtiger bzw. unvollständiger Daten zu verlangen (Art. 16 DSGVO);
                                    </li>
                                    <li>
                                        eine erteilte Einwilligung jederzeit mit Wirkung für die Zukunft zu <strong>widerrufen</strong> (Art. 7 Abs. 3 DSGVO);
                                    </li>
                                    <li>
                                        einer Datenverarbeitung, die aufgrund eines berechtigten Interesses erfolgen soll, aus Gründen zu <strong>widersprechen</strong>, die sich aus Ihrer besonderen Situation ergeben (Art 21 Abs. 1 DSGVO);
                                    </li>
                                    <li>
                                        in bestimmten Fällen im Rahmen des Art. 17 DSGVO die <strong>Löschung</strong> von Daten zu verlangen - insbesondere soweit die Daten für den vorgesehenen Zweck nicht mehr erforderlich sind bzw. unrechtmäßig verarbeitet werden, oder Sie Ihre Einwilligung gemäß oben (c) widerrufen oder einen Widerspruch gemäß oben (d) erklärt haben;
                                    </li>
                                    <li>
                                        unter bestimmten Voraussetzungen die <strong>Einschränkung</strong> von Daten zu verlangen, soweit eine Löschung nicht möglich bzw. die Löschpflicht streitig ist (Art. 18 DSGVO);
                                    </li>
                                    <li>
                                        auf <strong>Datenübertragbarkeit</strong>, d.h. Sie können Ihre Daten, die Sie uns bereitgestellt haben, in einem gängigen maschinenlesbaren Format, wie z.B. CSV, erhalten und ggf. an andere übermitteln (Art. 20 DSGVO);
                                    </li>
                                    <li>
                                        sich bei der zuständigen <strong>Aufsichtsbehörde</strong> über die Datenverarbeitung zu <strong>beschweren</strong> (für Telekommunikationsverträge: Bundesbeauftragter für den Datenschutz und die Informationsfreiheit; im Übrigen: Landesbeauftragte für den Datenschutz und die Informationsfreiheit Nordrhein-Westfalen).
                                    </li>
                                </ol>
                            </li>

                            <li className='text-justify py-3' >
                                <strong>An wen gibt die Telekom meine Daten weiter?</strong><br />
                                <strong>An Auftragsverarbeiter</strong>, das sind Unternehmen, die wir im gesetzlich vorgesehenen Rahmen mit der Verarbeitung von Daten beauftragen, Art. 28 DSGVO (Dienstleister, Erfüllungsgehilfen). Die Telekom bleibt auch in dem Fall weiterhin für den Schutz Ihrer Daten verantwortlich. Wir beauftragen Unternehmen insbesondere in folgenden Bereichen: IT, Vertrieb, Marketing, Finanzen, Beratung, Kundenservice, Personalwesen, Logistik, Druck.<br />
                                <strong>Aufgrund gesetzlicher Verpflichtung</strong>: In bestimmten Fällen sind wir gesetzlich verpflichtet, bestimmte Daten an die anfragende staatliche Stelle zu übermitteln.
                            </li>
                            <li className='text-justify py-3' >
                                <strong>Wo werden meine Daten verarbeitet?</strong><br />
                                Ihre Daten werden in Deutschland und im europäischen Ausland verarbeitet. Findet eine Verarbeitung Ihrer Daten in Ausnahmefällen auch in Ländern außerhalb der Europäischen Union (in sog. Drittstaaten) statt, geschieht dies,
                                <ol type='a' className='pr-2 pr-md-4'>
                                    <li>
                                    soweit Sie hierin ausdrücklich eingewilligt haben (Art. 49 Abs. 1a DSGVO).  (In den meisten Ländern außerhalb der EU entspricht das Datenschutzniveau nicht den EU Standards. Dies betrifft insbesondere umfassende Überwachungs- und Kontrollrechte staatlicher Behörden, z.B. in den USA, die in den Datenschutz der europäischen Bürgerinnen und Bürger unverhältnismäßig eingreifen,
                                    </li>
                                    <li>
                                    oder soweit es für unsere Leistungserbringung Ihnen gegenüber erforderlich ist (Art. 49 Abs. 1b DSGVO),
                                    </li>
                                    <li>
                                    oder soweit es gesetzlich vorgesehen ist (Art. 6 Abs. 1c DSGVO).
                                    </li>
                                </ol>
                                Darüber hinaus erfolgt eine Verarbeitung Ihrer Daten in Drittstaaten nur, soweit durch bestimmte Maßnahmen sichergestellt ist, dass hierfür ein angemessenes Datenschutzniveau besteht (z.B. Angemessenheitsbeschluss der EU-Kommission oder sog. geeignete Garantien, Art. 44ff. DSGVO).<br/><br/>
                                Stand der Datenschutzhinweise 29.04.2021
                            </li>
                        </ol>
                    </Container>
                </Modal.Body>
                    <hr className='mx-3 mt-0' />

                {/*
    footer with ok button
    */}
                <Modal.Footer id='data-footer'>
                    <Button
                        className='py-0'
                        onClick={handleClose}
                    >
                        {t('translation:cancel')}
                    </Button>
                </Modal.Footer>
            </Modal>
        </>
    )
}