react-bootstrap#Card TypeScript Examples

The following examples show how to use react-bootstrap#Card. 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: card-header.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 6 votes vote down vote up
CardHeader = (props: any) => {

    const { t } = useTranslation();

    return (!props ? <></> :
        <Card.Header id='data-header' className='px-3 pt-3 pb-0'>
            <Row>
                <Col md='6' className='px-3'>
                    <Card.Title className='m-md-0 tac-xs-tal-md jcc-xs-jcfs-md' as={'h2'} >{props.title}
                        {props.disclaimerText
                            ? <DisclamerButton
                                firstTimeShow={props.firstTimeShow}
                                checked={props.checked}
                                onInit={props.onInit}
                                onCheckChange={props.onCheckChange}
                                disclaimerText={props.disclaimerText}
                            />
                            : <></>}
                    </Card.Title>
                </Col>
                {!props.idCard
                    ? <></>
                    :
                    <Col md='6' className='d-flex pl-md-0 jcc-xs-jcfe-md'>
                        <Card.Text id='id-query-text'>{t('translation:query-id-card')}</Card.Text>
                    </Col>
                }
            </Row>
            <hr />
        </Card.Header>
    )

}
Example #2
Source File: queue.tsx    From remote-office-hours-queue with Apache License 2.0 6 votes vote down vote up
VideoMeetingInfo: React.FC<VideoMeetingInfoProps> = (props) => {
    const docLinkTag = (
        <a
            href={props.backend.docs_url === null ? undefined : props.backend.docs_url}
            target='_blank'
            className='card-link'
        >
            Getting Started with {props.backend.friendly_name} at U-M
        </a>
    );

    return (
        <>
        <Row>
            <Col md={6} sm={true}>
                <Card>
                    <Card.Body>
                        <Card.Title as='h5' className='mt-0'>Joining the Meeting</Card.Title>
                        <Card.Text>
                            Once the meeting is created, click Join Meeting to join the meeting and wait for the host.
                            Download the app and test your audio now.
                            Refer to {docLinkTag} for additional help getting started.
                        </Card.Text>
                    </Card.Body>
                </Card>
            </Col>
            <Col md={6} sm={true}>
                <Card>
                    <Card.Body>
                        <Card.Title className='mt-0'>Having Trouble with Video?</Card.Title>
                        <Card.Text><DialInContent {...props} /></Card.Text>
                    </Card.Body>
                </Card>
            </Col>
        </Row>
        </>
    );
}
Example #3
Source File: index.tsx    From nouns-monorepo with GNU General Public License v3.0 6 votes vote down vote up
BioCard: React.FC<{
  name: string;
  description?: string | undefined;
  image: string;
  handle?: string | undefined;
}> = props => {
  const { name, description, image, handle } = props;
  return (
    <>
      <Card.Img variant="top" src={image} />
      <Card.Title>
        {handle && (
          <a href={`https://twitter.com/${handle}`} target="_blank" rel="noreferrer">
            <svg
              fill="currentColor"
              viewBox="0 0 20 20"
              aria-hidden="true"
              className={classes.twitterIcon}
              data-v-6cab4e66=""
            >
              <path
                d="M6.29 18.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0020 3.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.073 4.073 0 01.8 7.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 010 16.407a11.616 11.616 0 006.29 1.84"
                data-v-6cab4e66=""
              ></path>
            </svg>
            {name}
          </a>
        )}

        {!handle && name}
      </Card.Title>
      {description && <Card.Text>{description}</Card.Text>}
    </>
  );
}
Example #4
Source File: AddCollectionButton.tsx    From bada-frame with GNU General Public License v3.0 6 votes vote down vote up
export default function AddCollectionButton({
    showNextModal,
}: {
    showNextModal: () => void;
}) {
    return (
        <CollectionIcon
            style={{ margin: '10px' }}
            onClick={() => showNextModal()}>
            <Card>
                <ImageContainer>+</ImageContainer>
                <Card.Text style={{ textAlign: 'center' }}>
                    {constants.CREATE_COLLECTION}
                </Card.Text>
            </Card>
        </CollectionIcon>
    );
}
Example #5
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 #6
Source File: AboutInfoCard.tsx    From advocacy-maps with MIT License 6 votes vote down vote up
export default function AboutInfoCard({ title, bodytext }: AboutInfoCardProps) {
  return (
    <Col className="my-3">
      <Card className="h-100">
        <Card.Header
          as="h3"
          className={`text-center align-self-center text-white rounded-0 ${styles.cardHeader}`}
        >
          {title}
        </Card.Header>
        <Card.Body className={`${styles.cardBody}`}>
          <p className={`${styles.cardBodyParagraph}`}>{bodytext}</p>
        </Card.Body>
      </Card>
    </Col>
  )
}
Example #7
Source File: CollapsibleContent.tsx    From apps with MIT License 6 votes vote down vote up
CollapsibleLight = ({
    title,
    content,
    eventKey,
    defaultActiveKey,
}: {
    title: Renderable;
    content: Renderable;
    eventKey: string;
    defaultActiveKey: string;
}) => {
    return (
        <Accordion defaultActiveKey={defaultActiveKey}>
            <Card className="collapsible-card">
                <Accordion.Toggle as="div" className="collapsible-header-tight" eventKey={eventKey}>
                    <span className="collapsible-header-title">{title}</span>
                    <span className="collapsible-header-arrow">
                        <ArrowToggle eventKey={eventKey} />
                    </span>
                </Accordion.Toggle>
                <Accordion.Collapse eventKey={eventKey}>
                    <>{content}</>
                </Accordion.Collapse>
            </Card>
        </Accordion>
    );
}
Example #8
Source File: NotFoundPage.tsx    From devex with GNU General Public License v3.0 6 votes vote down vote up
NotFoundPage: React.FC = () => {

  const location = useLocation()

  return <>
    <Card className='error-card'>
      <Card.Body>
        <h4 className='mb-3'>
          Sorry! Could not find requested page. Try again later!
        </h4>
        <h6 className='mb-2'>
          Network: <strong>{useNetworkUrl()}</strong>
        </h6>
        <h6>
          Search: <strong>{useSearchParams()}</strong>
        </h6>
        <Link to={{ pathname: '/', search: location.search }}>
          <Button id='error-btn' className='mt-4'>
            <span>
              Return to Dashboard
              </span>
          </Button>
        </Link>
      </Card.Body>
    </Card>
  </>
}
Example #9
Source File: CollapsibleContent.tsx    From apps with MIT License 5 votes vote down vote up
function renderCollapsibleContent(
    {
        title,
        content,
        subheader,
        separator,
        initialOpen,
        accordionKey,
    }: {
        title: Renderable;
        content: Renderable;
        subheader: boolean;
        separator?: boolean;
        initialOpen?: boolean;
        accordionKey?: string;
    },
    enableBottomMargin = true
) {
    if (initialOpen === undefined) initialOpen = true;
    if (separator === undefined) separator = true;
    const eventKey = accordionKey ?? `${title}`;
    return (
        <Accordion defaultActiveKey={initialOpen ? eventKey : ""}>
            <Card className="collapsible-card">
                {separator && <hr className="collapsible-header-separator" />}
                <Accordion.Toggle className="collapsible-header" as="div" eventKey={eventKey}>
                    {subheader ? (
                        <h4 className="collapsible-header-title">{title}</h4>
                    ) : (
                        <h3 className="collapsible-header-title">{title}</h3>
                    )}
                    <span className="collapsible-header-arrow">
                        <ArrowToggle eventKey={eventKey} />
                    </span>
                </Accordion.Toggle>
                {/* 2 px to align the hr line with the start of content */}
                <Accordion.Collapse eventKey={eventKey}>
                    <div style={{ marginTop: "2px", marginBottom: enableBottomMargin ? "1em" : "unset" }}>
                        {content}
                    </div>
                </Accordion.Collapse>
            </Card>
        </Accordion>
    );
}
Example #10
Source File: disclamer-btn.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 5 votes vote down vote up
DisclamerButton = (props: any) => {

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

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

    return (
        <>
            <Image
                src={SpeechBubbleImage}
                className='speech-bubble'
                onClick={() => { setShow(true) }}
            />

            <Modal
                contentClassName='data-modal'
                show={show}
                backdrop={true}
                onHide={() => { setShow(false) }}
                keyboard={false}
                centered
            >
                <Modal.Header id='data-header' className='pb-0' >
                    <Row>
                        <Col >
                            <Card.Title className='m-0 jcc-xs-jcfs-md' as={'h2'} >
                                {t('translation:disclaimer-title')}</Card.Title>
                        </Col>
                    </Row>
                </Modal.Header>

                <Modal.Body className='bg-light py-0'>
                    <hr />
                    <h5 className='disclaimer-text'>
                        <Trans>{props.disclaimerText}</Trans>
                    </h5>

                    <hr />

                    <FormGroupConsentCkb controlId='formDoNotShowCheckbox' title={t('translation:disclaimer-do-not-show')}
                        onChange={(evt: any) => props.onCheckChange(evt.currentTarget.checked)}
                        type='checkbox'
                        checked={props.checked}
                    />
                </Modal.Body>

                <Modal.Footer id='data-footer'>
                    <Container className='p-0'>
                        <Row className='justify-content-end'>
                            <Col xs='6' className='p-0'>
                                <Button
                                    className='py-0'
                                    block
                                    onClick={() => { setShow(false) }}
                                >
                                    {t('translation:ok')}
                                </Button>
                            </Col>
                        </Row>
                    </Container>
                </Modal.Footer>
            </Modal>
        </>
    )
}
Example #11
Source File: index.tsx    From bada-frame with GNU General Public License v3.0 5 votes vote down vote up
export default function Home() {
    const [sessionID, setSessionID] = useState('');

    useEffect(() => {
        const main = async () => {
            router.prefetch(PAGES.CREDENTIALS);
            const user: User = getData(LS_KEYS.USER);
            if (
                !user.isTwoFactorEnabled &&
                (user.encryptedToken || user.token)
            ) {
                router.push(PAGES.CREDENTIALS);
            } else if (!user?.email || !user.twoFactorSessionID) {
                router.push(PAGES.ROOT);
            } else {
                setSessionID(user.twoFactorSessionID);
            }
        };
        main();
    }, []);

    const onSubmit = async (otp: string) => {
        try {
            const resp = await verifyTwoFactor(otp, sessionID);
            const { keyAttributes, encryptedToken, token, id } = resp;
            setData(LS_KEYS.USER, {
                ...getData(LS_KEYS.USER),
                token,
                encryptedToken,
                id,
            });
            setData(LS_KEYS.KEY_ATTRIBUTES, keyAttributes);
            router.push(PAGES.CREDENTIALS);
        } catch (e) {
            if (e.status === 404) {
                logoutUser();
            } else {
                throw e;
            }
        }
    };
    return (
        <Container>
            <Card style={{ minWidth: '300px' }} className="text-center">
                <Card.Body style={{ padding: '40px 30px', minHeight: '400px' }}>
                    <Card.Title style={{ marginBottom: '32px' }}>
                        <LogoImg src="/icon.svg" />
                        {constants.TWO_FACTOR}
                    </Card.Title>
                    <VerifyTwoFactor
                        onSubmit={onSubmit}
                        back={router.back}
                        buttonText={constants.VERIFY}
                    />
                    <div
                        style={{
                            display: 'flex',
                            flexDirection: 'column',
                            marginTop: '12px',
                        }}>
                        <Button
                            variant="link"
                            onClick={() =>
                                router.push(PAGES.TWO_FACTOR_RECOVER)
                            }>
                            {constants.LOST_DEVICE}
                        </Button>
                        <Button variant="link" onClick={logoutUser}>
                            {constants.GO_BACK}
                        </Button>
                    </div>
                </Card.Body>
            </Card>
        </Container>
    );
}
Example #12
Source File: confirm-modal.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 5 votes vote down vote up
ConfirmModal = (props: any) => {
    const { t } = useTranslation();
    const [btnOkDisabled, setBtnOkDisabled] = React.useState(true);

    const handleEnter = () => {
        setBtnOkDisabled(false);
    }

    const handleOk = () => {
        if (props.handleOk) {
            setBtnOkDisabled(true);
            props.handleOk();
        }
    }

    return (
        <Modal
            contentClassName='data-modal'
            show={props.show}
            backdrop="static"
            keyboard={false}
            onEnter={handleEnter}
            centered
        >
            <Modal.Header id='data-header' className='pb-0' >
                <Card.Title className='m-0 jcc-xs-jcfs-md' as={'h3'} >{props.title}</Card.Title>
            </Modal.Header>
            <Modal.Body className='bg-light'>
                {props.message}
            </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={props.onCancel}
                            >
                                {t('translation:cancel')}
                            </Button>
                        </Col>
                        <Col sm='6' lg='4' className='p-0 pl-sm-2'>
                            <Button
                                className='p-0'
                                block
                                onClick={handleOk}
                                disabled={btnOkDisabled}
                            >
                                {t('translation:ok')}

                                <Spinner
                                    as="span"
                                    className='btn-spinner'
                                    animation="border"
                                    hidden={!btnOkDisabled}
                                    size="sm"
                                    role="status"
                                    aria-hidden="true"
                                />
                            </Button>
                        </Col>
                    </Row>
                </Container>
            </Modal.Footer>
        </Modal>
    )
}
Example #13
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 #14
Source File: index.tsx    From bada-frame with GNU General Public License v3.0 5 votes vote down vote up
function ChangeEmailPage() {
    const [email, setEmail] = useState('');
    const [waiting, setWaiting] = useState(true);
    const [showMessage, setShowMessage] = useState(false);
    const [showBigDialog, setShowBigDialog] = useState(false);

    useEffect(() => {
        const token = getToken();
        if (!token) {
            router.push(PAGES.ROOT);
            return;
        }
        setWaiting(false);
    }, []);

    return (
        <Container>
            {waiting ? (
                <EnteSpinner>
                    <span className="sr-only">Loading...</span>
                </EnteSpinner>
            ) : (
                <EnteCard size={showBigDialog ? 'md' : 'sm'}>
                    <Card.Body style={{ padding: '40px 30px' }}>
                        <Card.Title style={{ marginBottom: '32px' }}>
                            <LogoImg src="/icon.svg" />
                            {constants.UPDATE_EMAIL}
                        </Card.Title>
                        <Alert
                            variant="success"
                            show={showMessage}
                            style={{ paddingBottom: 0 }}
                            transition
                            dismissible
                            onClose={() => setShowMessage(false)}>
                            {constants.EMAIL_SENT({ email })}
                        </Alert>
                        <ChangeEmailForm
                            showMessage={(value) => {
                                setShowMessage(value);
                                setShowBigDialog(value);
                            }}
                            setEmail={setEmail}
                        />
                    </Card.Body>
                </EnteCard>
            )}
        </Container>
    );
}
Example #15
Source File: index.tsx    From nouns-monorepo with GNU General Public License v3.0 5 votes vote down vote up
VoteCard: React.FC<VoteCardProps> = props => {
  const { proposal, percentage, nounIds, variant } = props;
  const isMobile = isMobileScreen();

  let titleClass;
  let titleCopy;
  let voteCount;
  switch (variant) {
    case VoteCardVariant.FOR:
      titleClass = classes.for;
      titleCopy = <Trans>For</Trans>;
      voteCount = proposal.forCount;
      break;
    case VoteCardVariant.AGAINST:
      titleClass = classes.against;
      titleCopy = <Trans>Against</Trans>;
      voteCount = proposal.againstCount;
      break;
    default:
      titleClass = classes.abstain;
      titleCopy = <Trans>Abstain</Trans>;
      voteCount = proposal.abstainCount;
      break;
  }

  return (
    <Col lg={4} className={classes.wrapper}>
      <Card className={classes.voteCountCard}>
        <Card.Body className="p-2">
          <Card.Text className="py-2 m-0">
            <span className={`${classes.voteCardHeaderText} ${titleClass}`}>{titleCopy}</span>
            {!isMobile && (
              <span className={classes.voteCardVoteCount}>{i18n.number(voteCount)}</span>
            )}
          </Card.Text>
          {isMobile && (
            <Card.Text className="py-2 m-0">
              <span className={classes.voteCardVoteCount}>{i18n.number(voteCount)}</span>
            </Card.Text>
          )}
          <VoteProgressBar variant={variant} percentage={percentage} />
          {!isMobile && (
            <Row className={classes.nounProfilePics}>
              <NounImageVoteTable nounIds={nounIds} propId={parseInt(proposal.id || '0')} />
            </Row>
          )}
        </Card.Body>
      </Card>
    </Col>
  );
}
Example #16
Source File: ISInfo.tsx    From devex with GNU General Public License v3.0 5 votes vote down vote up
ISInfo: React.FC = () => {

  const networkContext = useContext(NetworkContext)
  const { dataService } = networkContext!

  const [data, setData] = useState<IISInfo | null>(null)

  // Fetch data
  useEffect(() => {
    if (!dataService) return

    let receivedData: IISInfo
    const getData = async () => {
      try {
        receivedData = await dataService.getISInfo()
        if (receivedData)
          setData(receivedData)
      } catch (e) {
        console.log(e)
      }
    }
    getData()
  }, [dataService])

  return <>
    <Container className='p-0'>
      <Row>
        <Col>
          <Card className='isinfo-card'>
            <Card.Body>
              {data
                ? <div className='isinfo-detail'>
                  <span>Latest Tx Block:</span>
                  <QueryPreservingLink to={`/txbk/${data.blockNum}`}>{data.blockNum}</QueryPreservingLink>
                </div>
                : <div><Spinner animation="border" role="status" /></div>
              }
            </Card.Body>
          </Card>
        </Col>
        <Col>
          <Card className='isinfo-card'>
            <Card.Body>
              {data
                ? <div className='isinfo-detail'>
                  <span>Minimum Gas Price:</span>
                  <span>{data.minGasPrice}</span>
                </div>
                : <div><Spinner animation="border" role="status" /></div>
              }
            </Card.Body>
          </Card>
        </Col>
      </Row>
    </Container>
  </>
}
Example #17
Source File: CollectionSelector.tsx    From bada-frame with GNU General Public License v3.0 5 votes vote down vote up
CollectionCard = styled(Card)`
    display: flex;
    flex-direction: column;
    height: 221px;
`
Example #18
Source File: AccountDetailsPage.tsx    From devex with GNU General Public License v3.0 4 votes vote down vote up
AccountDetailsPage: React.FC<IProps> = ({ addr }) => {
  const networkContext = useContext(NetworkContext);
  const { dataService, networkUrl, apolloUrl } = networkContext!;

  const addrRef = useRef(addr);
  const [isLoading, setIsLoading] = useState(false);
  const [accData, setAccData] = useState<AccData | null>(null);
  const [accContracts, setAccContracts] = useState<ContractObj[] | null>(null);
  const [contractPageIndex, setContractPageIndex] = useState<number>(0);
  const [transactionsCount, setTransactionsCount] = useState<number>(0);

  const generatePagination = useCallback(
    (currentPage: number, pageCount: number, delta = 2) => {
      const separate = (a: number, b: number, isLower: boolean) => {
        const temp = b - a;
        if (temp === 0) return [a];
        else if (temp === 1) return [a, b];
        else if (temp === 2) return [a, a + 1, b];
        else return [a, isLower ? -1 : -2, b];
      };

      return Array(delta * 2 + 1)
        .fill(0)
        .map((_, index) => currentPage - delta + index)
        .filter((page) => 0 < page && page <= pageCount)
        .flatMap((page, index, { length }) => {
          if (!index) {
            return separate(1, page, true);
          }
          if (index === length - 1) {
            return separate(page, pageCount, false);
          }
          return [page];
        });
    },
    []
  );

  // Fetch data
  useEffect(() => {
    if (!dataService) return;

    let accData: AccData;
    let accContracts: ContractObj[];
    const getData = async () => {
      try {
        setIsLoading(true);
        accData = await dataService.getAccData(addrRef.current);
        accContracts = await dataService.getAccContracts(addrRef.current);
        if (accData) setAccData(accData);
        if (accContracts) setAccContracts(accContracts);
      } catch (e) {
        setAccData({
          balance: "0",
          nonce: "-",
        });
      } finally {
        setIsLoading(false);
      }
    };
    getData();
  }, [dataService]);

  const ACCOUNT_TRANSACTIONS = gql`
    query GetTransactions($addr: String!, $page: Int) {
      txPagination(
        page: $page
        filter: {
          OR: [
            { fromAddr: $addr }
            { toAddr: $addr }
            { receipt: { transitions: { addr: $addr } } }
            { receipt: { transitions: { msg: { _recipient: $addr } } } }
          ]
        }
        sort: TIMESTAMP_DESC
      ) {
        count
        items {
          ID
          receipt {
            success
            cumulative_gas
            transitions {
              addr
              msg {
                _recipient
              }
            }
          }
          gasPrice
          gasLimit
          fromAddr
          toAddr
          amount
          timestamp
          type
        }
        pageInfo {
          currentPage
          perPage
          pageCount
          itemCount
          hasNextPage
          hasPreviousPage
        }
      }
    }
  `;

  const hexAddr = zilAddrToHexAddr(addr);

  const {
    loading: transactionsLoading,
    error,
    data: txData,
    fetchMore,
  } = useQuery(ACCOUNT_TRANSACTIONS, {
    variables: { addr: hexAddr, page: 1 },
    context: {
      uri: apolloUrl,
    },
    fetchPolicy: "cache-and-network",
  });

  if (txData && transactionsCount !== txData.txPagination.count) {
    setTransactionsCount(txData.txPagination.count);
  }

  const localFetch = (page: Number) => {
    return fetchMore({
      variables: {
        page,
      },
      updateQuery: (prev: any, { fetchMoreResult }) => {
        if (!fetchMoreResult) return prev;
        return fetchMoreResult;
      },
    });
  };

  return (
    <>
      {isLoading ? (
        <div className="center-spinner">
          <Spinner animation="border" />
        </div>
      ) : null}
      {accData && (
        <>
          <div className="address-header">
            <h3 className="mb-1">
              <span className="mr-1">
                <FontAwesomeIcon className="fa-icon" icon={faWallet} />
              </span>
              <span className="ml-2">Account</span>
              <LabelStar type="Account" />
            </h3>
            <ViewBlockLink
              network={networkUrl}
              type="address"
              identifier={addrRef.current}
            />
          </div>
          <div className="subtext">
            <AddressDisp isLinked={false} addr={addrRef.current} />
          </div>
          <Card className="address-details-card">
            <Card.Body>
              <Container>
                <Row>
                  <Col>
                    <div className="address-detail">
                      <span>Balance:</span>
                      <span>{qaToZil(accData.balance)}</span>
                    </div>
                  </Col>
                </Row>
                <Row>
                  <Col>
                    <div className="address-detail">
                      <span>Nonce:</span>
                      <span>{accData.nonce}</span>
                    </div>
                  </Col>
                </Row>
                <Row>
                  <Col>
                    <div className="address-detail">
                      <span>Transactions:</span>
                      <span>{transactionsCount}</span>
                    </div>
                  </Col>
                </Row>
              </Container>
            </Card.Body>
          </Card>

          <h4 className="py-2">Transactions</h4>
          <div className="row align-items-center mb-0">
            <div className="col subtext">
              Items Per Page: <strong>20</strong>
            </div>
            <div className="col">
              {txData && txData.txPagination ? (
                <Pagination className="justify-content-end">
                  <Pagination.Prev
                    onClick={() =>
                      localFetch(txData.txPagination.pageInfo.currentPage - 1)
                    }
                    disabled={!txData.txPagination.pageInfo.hasPreviousPage}
                  />
                  {generatePagination(
                    txData.txPagination.pageInfo.currentPage + 1,
                    txData.txPagination.pageInfo.pageCount
                  ).map((page) => {
                    if (page === -1)
                      return (
                        <Pagination.Ellipsis
                          key={page}
                          onClick={() =>
                            localFetch(
                              txData.txPagination.pageInfo.currentPage - 5
                            )
                          }
                        />
                      );
                    else if (page === -2)
                      return (
                        <Pagination.Ellipsis
                          key={page}
                          onClick={() =>
                            localFetch(
                              txData.txPagination.pageInfo.currentPage + 5
                            )
                          }
                        />
                      );
                    else if (page === txData.txPagination.pageInfo.currentPage)
                      return (
                        <Pagination.Item key={page} active>
                          {page}
                        </Pagination.Item>
                      );
                    else
                      return (
                        <Pagination.Item
                          key={page}
                          onClick={() => localFetch(Number(page))}
                        >
                          {page}
                        </Pagination.Item>
                      );
                  })}
                  <Pagination.Next
                    onClick={() =>
                      localFetch(txData.txPagination.pageInfo.currentPage + 1)
                    }
                    disabled={!txData.txPagination.pageInfo.hasNextPage}
                  />
                </Pagination>
              ) : null}
            </div>
          </div>
          <Card className="txblock-card mt-0 mb-4">
            <Card.Body>
              {transactionsLoading ? (
                <div className="center-spinner">
                  <Spinner animation="border" />
                </div>
              ) : null}
              {txData && txData.txPagination ? (
                <TransactionsCard
                  transactions={txData.txPagination.items}
                  addr={addrRef.current}
                />
              ) : null}
              {error ? "Error while loading transactions" : null}
            </Card.Body>
          </Card>

          {accContracts && accContracts.length > 0 && (
            <>
              <h4 className="py-2">Deployed Contracts</h4>
              <Card className="address-details-card">
                <div className="d-flex justify-content-between">
                  <span className="num-contracts">
                    Total: {accContracts.length}{" "}
                    {accContracts.length === 1 ? "contract" : "contracts"}
                  </span>
                  <Pagination className="contract-pagination">
                    <Pagination.Prev
                      onClick={() =>
                        setContractPageIndex(
                          (contractPageIndex) => contractPageIndex - 1
                        )
                      }
                      disabled={contractPageIndex === 0}
                    />
                    {generatePagination(
                      contractPageIndex,
                      Math.ceil(accContracts.length / 10)
                    ).map((page) => {
                      if (page === -1)
                        return (
                          <Pagination.Ellipsis
                            key={page}
                            onClick={() =>
                              setContractPageIndex(
                                (contractPageIndex) => contractPageIndex - 5
                              )
                            }
                          />
                        );
                      else if (page === -2)
                        return (
                          <Pagination.Ellipsis
                            key={page}
                            onClick={() =>
                              setContractPageIndex(
                                (contractPageIndex) => contractPageIndex + 5
                              )
                            }
                          />
                        );
                      else if (page === contractPageIndex + 1)
                        return (
                          <Pagination.Item key={page} active>
                            {page}
                          </Pagination.Item>
                        );
                      else
                        return (
                          <Pagination.Item
                            key={page}
                            onClick={() => setContractPageIndex(page - 1)}
                          >
                            {page}
                          </Pagination.Item>
                        );
                    })}
                    <Pagination.Next
                      onClick={() =>
                        setContractPageIndex(
                          (contractPageIndex) => contractPageIndex + 1
                        )
                      }
                      disabled={
                        contractPageIndex ===
                        Math.ceil(accContracts.length / 10) - 1
                      }
                    />
                  </Pagination>
                </div>
                <Card.Body>
                  {accContracts
                    .slice(10 * contractPageIndex, 10 * contractPageIndex + 10)
                    .map((contract: ContractObj, index: number) => {
                      return (
                        <AccContractCard
                          key={10 * contractPageIndex + index}
                          contract={contract}
                          index={10 * contractPageIndex + index}
                        />
                      );
                    })}
                </Card.Body>
              </Card>
            </>
          )}
        </>
      )}
    </>
  );
}
Example #19
Source File: index.tsx    From bada-frame with GNU General Public License v3.0 4 votes vote down vote up
export default function Credentials() {
    const router = useRouter();
    const [keyAttributes, setKeyAttributes] = useState<KeyAttributes>();
    const appContext = useContext(AppContext);

    useEffect(() => {
        router.prefetch(PAGES.GALLERY);
        const user = getData(LS_KEYS.USER);
        const keyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES);
        const key = getKey(SESSION_KEYS.ENCRYPTION_KEY);
        if (
            (!user?.token && !user?.encryptedToken) ||
            (keyAttributes && !keyAttributes.memLimit)
        ) {
            clearData();
            router.push(PAGES.ROOT);
        } else if (!keyAttributes) {
            router.push(PAGES.GENERATE);
        } else if (key) {
            router.push(PAGES.GALLERY);
        } else {
            setKeyAttributes(keyAttributes);
        }
        appContext.showNavBar(false);
    }, []);

    const verifyPassphrase = async (passphrase, setFieldError) => {
        try {
            const cryptoWorker = await new CryptoWorker();
            let kek: string = null;
            try {
                kek = await cryptoWorker.deriveKey(
                    passphrase,
                    keyAttributes.kekSalt,
                    keyAttributes.opsLimit,
                    keyAttributes.memLimit
                );
            } catch (e) {
                logError(e, 'failed to derive key');
                throw e;
            }
            try {
                const key: string = await cryptoWorker.decryptB64(
                    keyAttributes.encryptedKey,
                    keyAttributes.keyDecryptionNonce,
                    kek
                );

                if (isFirstLogin()) {
                    await generateAndSaveIntermediateKeyAttributes(
                        passphrase,
                        keyAttributes,
                        key
                    );
                }
                await SaveKeyInSessionStore(SESSION_KEYS.ENCRYPTION_KEY, key);
                await decryptAndStoreToken(key);
                const redirectURL = appContext.redirectURL;
                appContext.setRedirectURL(null);
                router.push(redirectURL ?? PAGES.GALLERY);
            } catch (e) {
                logError(e, 'user entered a wrong password');
                setFieldError('passphrase', constants.INCORRECT_PASSPHRASE);
            }
        } catch (e) {
            setFieldError(
                'passphrase',
                `${constants.UNKNOWN_ERROR} ${e.message}`
            );
        }
    };

    return (
        <>
            <Container>
                <Card style={{ minWidth: '320px' }} className="text-center">
                    <Card.Body style={{ padding: '40px 30px' }}>
                        <Card.Title style={{ marginBottom: '32px' }}>
                            <LogoImg src="/icon.svg" />
                            {constants.PASSWORD}
                        </Card.Title>
                        <SingleInputForm
                            callback={verifyPassphrase}
                            placeholder={constants.RETURN_PASSPHRASE_HINT}
                            buttonText={constants.VERIFY_PASSPHRASE}
                            fieldType="password"
                        />
                        <div
                            style={{
                                display: 'flex',
                                flexDirection: 'column',
                                marginTop: '12px',
                            }}>
                            <Button
                                variant="link"
                                onClick={() => router.push(PAGES.RECOVER)}>
                                {constants.FORGOT_PASSWORD}
                            </Button>
                            <Button variant="link" onClick={logoutUser}>
                                {constants.GO_BACK}
                            </Button>
                        </div>
                    </Card.Body>
                </Card>
            </Container>
        </>
    );
}
Example #20
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 #21
Source File: index.tsx    From bada-frame with GNU General Public License v3.0 4 votes vote down vote up
export default function Recover() {
    const router = useRouter();
    const [keyAttributes, setKeyAttributes] = useState<KeyAttributes>();
    const [messageDialogView, SetMessageDialogView] = useState(false);
    const appContext = useContext(AppContext);

    useEffect(() => {
        router.prefetch(PAGES.GALLERY);
        const user: User = getData(LS_KEYS.USER);
        const keyAttributes: KeyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES);
        const key = getKey(SESSION_KEYS.ENCRYPTION_KEY);
        if (
            (!user?.token && !user?.encryptedToken) ||
            !keyAttributes?.memLimit
        ) {
            clearData();
            router.push(PAGES.ROOT);
        } else if (!keyAttributes) {
            router.push(PAGES.GENERATE);
        } else if (key) {
            router.push(PAGES.GALLERY);
        } else {
            setKeyAttributes(keyAttributes);
        }
        appContext.showNavBar(false);
    }, []);

    const recover = async (recoveryKey: string, setFieldError) => {
        try {
            // check if user is entering mnemonic recovery key
            if (recoveryKey.trim().indexOf(' ') > 0) {
                if (recoveryKey.trim().split(' ').length !== 24) {
                    throw new Error('recovery code should have 24 words');
                }
                recoveryKey = bip39.mnemonicToEntropy(recoveryKey);
            }
            const cryptoWorker = await new CryptoWorker();
            const masterKey: string = await cryptoWorker.decryptB64(
                keyAttributes.masterKeyEncryptedWithRecoveryKey,
                keyAttributes.masterKeyDecryptionNonce,
                await cryptoWorker.fromHex(recoveryKey)
            );
            await SaveKeyInSessionStore(SESSION_KEYS.ENCRYPTION_KEY, masterKey);
            await decryptAndStoreToken(masterKey);

            setData(LS_KEYS.SHOW_BACK_BUTTON, { value: false });
            router.push(PAGES.CHANGE_PASSWORD);
        } catch (e) {
            logError(e, 'password recovery failed');
            setFieldError('passphrase', constants.INCORRECT_RECOVERY_KEY);
        }
    };

    return (
        <>
            <Container>
                <Card style={{ minWidth: '320px' }} className="text-center">
                    <Card.Body style={{ padding: '40px 30px' }}>
                        <Card.Title style={{ marginBottom: '32px' }}>
                            <LogoImg src="/icon.svg" />
                            {constants.RECOVER_ACCOUNT}
                        </Card.Title>
                        <SingleInputForm
                            callback={recover}
                            fieldType="text"
                            placeholder={constants.RETURN_RECOVERY_KEY_HINT}
                            buttonText={constants.RECOVER}
                        />
                        <div
                            style={{
                                display: 'flex',
                                flexDirection: 'column',
                                marginTop: '12px',
                            }}>
                            <Button
                                variant="link"
                                onClick={() => SetMessageDialogView(true)}>
                                {constants.NO_RECOVERY_KEY}
                            </Button>
                            <Button variant="link" onClick={router.back}>
                                {constants.GO_BACK}
                            </Button>
                        </div>
                    </Card.Body>
                </Card>
            </Container>
            <MessageDialog
                size="lg"
                show={messageDialogView}
                onHide={() => SetMessageDialogView(false)}
                attributes={{
                    title: constants.SORRY,
                    close: {},
                    content: constants.NO_RECOVERY_KEY_MESSAGE,
                }}
            />
        </>
    );
}
Example #22
Source File: ManageProducts.tsx    From Apni-Dukan-Frontend with MIT License 4 votes vote down vote up
ManageProducts = () => {
  const [products, setProducts] = useState<Product[]>([]);

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

  const preload = () => {
    getProducts().then((data) => {
      if (data.error) {
        // console.log(data.error);
      } else {
        setProducts(data);
      }
    });
  };

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

  const deleteaProduct = (productId: string) => {
    deleteProduct(productId, _id, token).then((data) => {
      if (data.error) {
        // console.log(data.error);
      } else {
        preload();
      }
    });
  };

  const goBack = () => {
    return (
      <Link
        style={{ textDecoration: "none", color: "black" }}
        to="/admin/dashboard"
      >
        <Button variant="light"> Go Back</Button>
      </Link>
    );
  };

  const myProducts = () => {
    return (
      <div>
        <div className="lead text-dark rounded bg-warning p-2">
          Total {products.length} products available
        </div>
        <br />
        <div className="row">
          {products.map((product, index) => (
            <div key={index} className="col- col-md-4 mb-3 col-sm-6">
              <Card
                className="text-dark"
                style={{ height: "100%" }}
                key={index}
              >
                <div className="p-2">
                  <Card.Img
                    className="border border-info"
                    variant="top"
                    src={product.photo}
                  />
                </div>
                <Card.Body>
                  <Card.Title className="bg-warning p-2 rounded">
                    Product: {product.name}
                    <br />
                    <br />
                    Category: {product.category.name}
                    <br />
                    <br />
                    Stock: {product.stock}{" "}
                  </Card.Title>
                  <Card.Text>{product.description}</Card.Text>
                </Card.Body>
                <Card.Footer>
                  <Link to={`/admin/product/update/${product._id}`}>
                    <Button variant="success" className="p-1 form-control">
                      Update
                    </Button>
                  </Link>

                  <br />
                  <br />
                  <Button
                    onClick={() => deleteaProduct(product._id)}
                    variant="danger"
                    className="p-1 form-control"
                  >
                    Delete
                  </Button>
                </Card.Footer>
              </Card>
            </div>
          ))}
        </div>
        <br />
        {goBack()}
      </div>
    );
  };

  return (
    <Base title="Manage all your products here!" description="">
      <div className="p-3">
        <div className="container bg-info rounded p-4">{myProducts()}</div>
      </div>
    </Base>
  );
}
Example #23
Source File: index.tsx    From nouns-monorepo with GNU General Public License v3.0 4 votes vote down vote up
VotePage = ({
  match: {
    params: { id },
  },
}: RouteComponentProps<{ id: string }>) => {
  const proposal = useProposal(id);

  const [showVoteModal, setShowVoteModal] = useState<boolean>(false);

  const [isQueuePending, setQueuePending] = useState<boolean>(false);
  const [isExecutePending, setExecutePending] = useState<boolean>(false);

  const dispatch = useAppDispatch();
  const setModal = useCallback((modal: AlertModal) => dispatch(setAlertModal(modal)), [dispatch]);

  const { queueProposal, queueProposalState } = useQueueProposal();
  const { executeProposal, executeProposalState } = useExecuteProposal();

  // Get and format date from data
  const timestamp = Date.now();
  const currentBlock = useBlockNumber();
  const startDate =
    proposal && timestamp && currentBlock
      ? dayjs(timestamp).add(
          AVERAGE_BLOCK_TIME_IN_SECS * (proposal.startBlock - currentBlock),
          'seconds',
        )
      : undefined;

  const endDate =
    proposal && timestamp && currentBlock
      ? dayjs(timestamp).add(
          AVERAGE_BLOCK_TIME_IN_SECS * (proposal.endBlock - currentBlock),
          'seconds',
        )
      : undefined;
  const now = dayjs();

  // Get total votes and format percentages for UI
  const totalVotes = proposal
    ? proposal.forCount + proposal.againstCount + proposal.abstainCount
    : undefined;
  const forPercentage = proposal && totalVotes ? (proposal.forCount * 100) / totalVotes : 0;
  const againstPercentage = proposal && totalVotes ? (proposal.againstCount * 100) / totalVotes : 0;
  const abstainPercentage = proposal && totalVotes ? (proposal.abstainCount * 100) / totalVotes : 0;

  // Only count available votes as of the proposal created block
  const availableVotes = useUserVotesAsOfBlock(proposal?.createdBlock ?? undefined);

  const hasSucceeded = proposal?.status === ProposalState.SUCCEEDED;
  const isAwaitingStateChange = () => {
    if (hasSucceeded) {
      return true;
    }
    if (proposal?.status === ProposalState.QUEUED) {
      return new Date() >= (proposal?.eta ?? Number.MAX_SAFE_INTEGER);
    }
    return false;
  };

  const startOrEndTimeCopy = () => {
    if (startDate?.isBefore(now) && endDate?.isAfter(now)) {
      return <Trans>Ends</Trans>;
    }
    if (endDate?.isBefore(now)) {
      return <Trans>Ended</Trans>;
    }
    return <Trans>Starts</Trans>;
  };

  const startOrEndTimeTime = () => {
    if (!startDate?.isBefore(now)) {
      return startDate;
    }
    return endDate;
  };

  const moveStateButtonAction = hasSucceeded ? <Trans>Queue</Trans> : <Trans>Execute</Trans>;
  const moveStateAction = (() => {
    if (hasSucceeded) {
      return () => {
        if (proposal?.id) {
          return queueProposal(proposal.id);
        }
      };
    }
    return () => {
      if (proposal?.id) {
        return executeProposal(proposal.id);
      }
    };
  })();

  const onTransactionStateChange = useCallback(
    (
      tx: TransactionStatus,
      successMessage?: ReactNode,
      setPending?: (isPending: boolean) => void,
      getErrorMessage?: (error?: string) => ReactNode | undefined,
      onFinalState?: () => void,
    ) => {
      switch (tx.status) {
        case 'None':
          setPending?.(false);
          break;
        case 'Mining':
          setPending?.(true);
          break;
        case 'Success':
          setModal({
            title: <Trans>Success</Trans>,
            message: successMessage || <Trans>Transaction Successful!</Trans>,
            show: true,
          });
          setPending?.(false);
          onFinalState?.();
          break;
        case 'Fail':
          setModal({
            title: <Trans>Transaction Failed</Trans>,
            message: tx?.errorMessage || <Trans>Please try again.</Trans>,
            show: true,
          });
          setPending?.(false);
          onFinalState?.();
          break;
        case 'Exception':
          setModal({
            title: <Trans>Error</Trans>,
            message: getErrorMessage?.(tx?.errorMessage) || <Trans>Please try again.</Trans>,
            show: true,
          });
          setPending?.(false);
          onFinalState?.();
          break;
      }
    },
    [setModal],
  );

  useEffect(
    () =>
      onTransactionStateChange(
        queueProposalState,
        <Trans>Proposal Queued!</Trans>,
        setQueuePending,
      ),
    [queueProposalState, onTransactionStateChange, setModal],
  );

  useEffect(
    () =>
      onTransactionStateChange(
        executeProposalState,
        <Trans>Proposal Executed!</Trans>,
        setExecutePending,
      ),
    [executeProposalState, onTransactionStateChange, setModal],
  );

  const activeAccount = useAppSelector(state => state.account.activeAccount);
  const {
    loading,
    error,
    data: voters,
  } = useQuery<ProposalVotes>(proposalVotesQuery(proposal?.id ?? '0'), {
    skip: !proposal,
  });

  const voterIds = voters?.votes?.map(v => v.voter.id);
  const { data: delegateSnapshot } = useQuery<Delegates>(
    delegateNounsAtBlockQuery(voterIds ?? [], proposal?.createdBlock ?? 0),
    {
      skip: !voters?.votes?.length,
    },
  );

  const { delegates } = delegateSnapshot || {};
  const delegateToNounIds = delegates?.reduce<Record<string, string[]>>((acc, curr) => {
    acc[curr.id] = curr?.nounsRepresented?.map(nr => nr.id) ?? [];
    return acc;
  }, {});

  const data = voters?.votes?.map(v => ({
    supportDetailed: v.supportDetailed,
    nounsRepresented: delegateToNounIds?.[v.voter.id] ?? [],
  }));

  const [showToast, setShowToast] = useState(true);
  useEffect(() => {
    if (showToast) {
      setTimeout(() => {
        setShowToast(false);
      }, 5000);
    }
  }, [showToast]);

  if (!proposal || loading || !data) {
    return (
      <div className={classes.spinner}>
        <Spinner animation="border" />
      </div>
    );
  }

  if (error) {
    return <Trans>Failed to fetch</Trans>;
  }

  const isWalletConnected = !(activeAccount === undefined);
  const isActiveForVoting = startDate?.isBefore(now) && endDate?.isAfter(now);

  const forNouns = getNounVotes(data, 1);
  const againstNouns = getNounVotes(data, 0);
  const abstainNouns = getNounVotes(data, 2);

  return (
    <Section fullWidth={false} className={classes.votePage}>
      <VoteModal
        show={showVoteModal}
        onHide={() => setShowVoteModal(false)}
        proposalId={proposal?.id}
        availableVotes={availableVotes || 0}
      />
      <Col lg={10} className={classes.wrapper}>
        {proposal && (
          <ProposalHeader
            proposal={proposal}
            isActiveForVoting={isActiveForVoting}
            isWalletConnected={isWalletConnected}
            submitButtonClickHandler={() => setShowVoteModal(true)}
          />
        )}
      </Col>
      <Col lg={10} className={clsx(classes.proposal, classes.wrapper)}>
        {isAwaitingStateChange() && (
          <Row className={clsx(classes.section, classes.transitionStateButtonSection)}>
            <Col className="d-grid">
              <Button
                onClick={moveStateAction}
                disabled={isQueuePending || isExecutePending}
                variant="dark"
                className={classes.transitionStateButton}
              >
                {isQueuePending || isExecutePending ? (
                  <Spinner animation="border" />
                ) : (
                  <Trans>{moveStateButtonAction} Proposal ⌐◧-◧</Trans>
                )}
              </Button>
            </Col>
          </Row>
        )}
        <Row>
          <VoteCard
            proposal={proposal}
            percentage={forPercentage}
            nounIds={forNouns}
            variant={VoteCardVariant.FOR}
          />
          <VoteCard
            proposal={proposal}
            percentage={againstPercentage}
            nounIds={againstNouns}
            variant={VoteCardVariant.AGAINST}
          />
          <VoteCard
            proposal={proposal}
            percentage={abstainPercentage}
            nounIds={abstainNouns}
            variant={VoteCardVariant.ABSTAIN}
          />
        </Row>

        {/* TODO abstract this into a component  */}
        <Row>
          <Col xl={4} lg={12}>
            <Card className={classes.voteInfoCard}>
              <Card.Body className="p-2">
                <div className={classes.voteMetadataRow}>
                  <div className={classes.voteMetadataRowTitle}>
                    <h1>
                      <Trans>Threshold</Trans>
                    </h1>
                  </div>
                  <div className={classes.thresholdInfo}>
                    <span>
                      <Trans>Quorum</Trans>
                    </span>
                    <h3>
                      <Trans>{i18n.number(proposal.quorumVotes)} votes</Trans>
                    </h3>
                  </div>
                </div>
              </Card.Body>
            </Card>
          </Col>
          <Col xl={4} lg={12}>
            <Card className={classes.voteInfoCard}>
              <Card.Body className="p-2">
                <div className={classes.voteMetadataRow}>
                  <div className={classes.voteMetadataRowTitle}>
                    <h1>{startOrEndTimeCopy()}</h1>
                  </div>
                  <div className={classes.voteMetadataTime}>
                    <span>
                      {startOrEndTimeTime() &&
                        i18n.date(new Date(startOrEndTimeTime()?.toISOString() || 0), {
                          hour: 'numeric',
                          minute: '2-digit',
                          timeZoneName: 'short',
                        })}
                    </span>
                    <h3>
                      {startOrEndTimeTime() &&
                        i18n.date(new Date(startOrEndTimeTime()?.toISOString() || 0), {
                          dateStyle: 'long',
                        })}
                    </h3>
                  </div>
                </div>
              </Card.Body>
            </Card>
          </Col>
          <Col xl={4} lg={12}>
            <Card className={classes.voteInfoCard}>
              <Card.Body className="p-2">
                <div className={classes.voteMetadataRow}>
                  <div className={classes.voteMetadataRowTitle}>
                    <h1>Snapshot</h1>
                  </div>
                  <div className={classes.snapshotBlock}>
                    <span>
                      <Trans>Taken at block</Trans>
                    </span>
                    <h3>{proposal.createdBlock}</h3>
                  </div>
                </div>
              </Card.Body>
            </Card>
          </Col>
        </Row>

        <ProposalContent proposal={proposal} />
      </Col>
    </Section>
  );
}
Example #24
Source File: queue.tsx    From remote-office-hours-queue with Apache License 2.0 4 votes vote down vote up
function QueueAttendingJoined(props: QueueAttendingProps) {
    const meeting = props.queue.my_meeting!;
    const meetingBackend = getBackendByName(meeting.backend_type, props.backends);
    const isVideoMeeting = VideoBackendNames.includes(meetingBackend.name);
    const inProgress = meeting.status === MeetingStatus.STARTED;

    // Alerts and head
    const closedAlert = props.queue.status === 'closed' && <JoinedClosedAlert meetingStatus={meeting.status} />;

    const turnAlert = meeting.line_place !== null
        ? <WaitingTurnAlert meetingType={meetingBackend.name} placeInLine={meeting.line_place} />
        : <MeetingReadyAlert meetingType={meetingBackend.name} />;

    const headText = inProgress ? 'Your meeting is in progress.' : 'You are currently in line.';

    // Card content
    const changeMeetingType = props.queue.my_meeting?.assignee
        ? <small className="ml-2">(A Host has been assigned to this meeting. Meeting Type can no longer be changed.)</small>
        : <Button variant='link' onClick={props.onShowDialog} aria-label='Change Meeting Type' disabled={props.disabled}>Change</Button>;

    const notificationBlurb = !inProgress
        && (
            <Alert variant="info">
                <small>
                    Did you know? You can receive an SMS (text) message when
                    it's your turn by adding your cell phone number and
                    enabling attendee notifications in
                    your <Link to="/preferences">User Preferences</Link>.
                </small>
            </Alert>
        );

    const agendaBlock = !inProgress
        ? (
            <>
            <Card.Text><strong>Meeting Agenda</strong> (Optional):</Card.Text>
            <Card.Text><small>Let the host(s) know the topic you wish to discuss.</small></Card.Text>
            <EditToggleField
                id='agenda'
                value={meeting.agenda}
                formLabel='Meeting Agenda'
                placeholder=''
                buttonOptions={{ onSubmit: props.onChangeAgenda, buttonType: 'success' }}
                disabled={props.disabled}
                fieldComponent={StatelessInputGroupForm}
                fieldSchema={meetingAgendaSchema}
                showRemaining={true}
                initialState={!meeting.agenda}
            >
                Update
            </EditToggleField>
            </>
        )
        : <Card.Text><strong>Meeting Agenda</strong>: {meeting.agenda ? meeting.agenda : 'None'}</Card.Text>;

    // Meeting actions and info
    const leaveButtonText = inProgress ? 'Cancel My Meeting' : 'Leave the Line';
    const leave = (
        <Button
            variant='link'
            type='button'
            onClick={() => props.onLeaveQueue(meeting)}
            disabled={props.disabled}
            aria-label={leaveButtonText}
        >
            {leaveButtonText}
            {props.disabled && DisabledMessage}
        </Button>
    );

    const joinText = isVideoMeeting && (
        !inProgress
            ? (
                'The host has not created the meeting yet. You will be able to join the meeting once it is created. ' +
                "We'll show a message in this window when it is created -- pay attention to the window so you don't miss it."
            )
            : 'The host has created the meeting. Join it now! The host will join when they are ready for you.'
    );

    const joinedInpersonMeetingText = (
        props.queue.inperson_location === '' 
            ? (
                'The host(s) have not specified an in-person meeting location.'
            )
            : props.queue.inperson_location
    );

    const joinLink = isVideoMeeting && (
        meeting.backend_metadata!.meeting_url
            ? (
                <Button
                    href={meeting.backend_metadata!.meeting_url}
                    target='_blank'
                    variant='warning'
                    className='mr-3'
                    aria-label='Join Meeting'
                    disabled={props.disabled}
                >
                    Join Meeting
                </Button>
            )
            : <span><strong>Please wait. A Join Meeting button will appear here.</strong></span>
    );

    const meetingInfo = isVideoMeeting && <VideoMeetingInfo metadata={meeting.backend_metadata!} backend={meetingBackend} />;

    return (
        <>
        {closedAlert}
        {turnAlert}
        <h3>{headText}</h3>
        <Card className='card-middle card-width center-align'>
            <Card.Body>
                {meeting.line_place !== null && <Card.Text><strong>Your Number in Line</strong>: {meeting.line_place + 1}</Card.Text>}
                {notificationBlurb}
                <Card.Text><strong>Time Joined</strong>: <DateTimeDisplay dateTime={props.queue.my_meeting!.created_at}/></Card.Text>
                <Card.Text>
                    <strong>Meeting Via</strong>: {meetingBackend.friendly_name} {!inProgress && changeMeetingType}
                </Card.Text>
                {
                    meetingBackend.name === 'inperson' &&
                    <Card.Text>
                        <strong>Meet At</strong>: {joinedInpersonMeetingText}
                    </Card.Text>
                }
                {agendaBlock}
            </Card.Body>
        </Card>
        {joinText && <p>{joinText}</p>}
        <Row className='mb-3'>
            <Col>
                {joinLink}
                {leave}
            </Col>
        </Row>
        {meetingInfo}
        </>
    );
}
Example #25
Source File: UserView.tsx    From 3Speak-app with GNU General Public License v3.0 4 votes vote down vote up
/**
 * User about page with all the public information a casual and power user would need to see about another user.
 */
export function UserView(props: any) {
  const [profileAbout, setProfileAbout] = useState('')
  const [hiveBalance, setHiveBalance] = useState<number>()
  const [hbdBalance, setHbdBalance] = useState<number>()
  const [coverUrl, setCoverUrl] = useState('')
  const [profileUrl, setProfileUrl] = useState('')

  const reflink = useMemo(() => {
    return RefLink.parse(props.match.params.reflink)
  }, [props.match])

  const username = useMemo(() => {
    return reflink.root
  }, [reflink])

  useEffect(() => {
    const load = async () => {
      const accountBalances = await AccountService.getAccountBalances(reflink)

      setProfileUrl(await AccountService.getProfilePictureURL(reflink))
      setProfileAbout(await AccountService.getProfileAbout(reflink))
      setHiveBalance(accountBalances.hive)
      setHbdBalance(accountBalances.hbd)
      setCoverUrl(await AccountService.getProfileBackgroundImageUrl(reflink))
    }

    void load()
  }, [reflink])

  return (
    <div>
      <div className="single-channel-image">
        <img
          className="img-fluid mh-20"
          style={{
            objectFit: 'cover',
            objectPosition: 'center',
            maxHeight: '500px',
          }}
          alt=""
          src={coverUrl}
        />
        <div className="channel-profile" style={{ position: profileUrl ? 'absolute' : 'unset' }}>
          <img className="channel-profile-img" alt="" src={profileUrl} />
        </div>
      </div>
      <div className="single-channel-nav">
        <Navbar expand="lg" bg="light">
          <a className="channel-brand">{username}</a>
          <Navbar.Toggle
            aria-controls="navbarSupportedContent"
            aria-expanded="false"
            aria-label="Toggle navigation"
          >
            <span className="navbar-toggler-icon"></span>
          </Navbar.Toggle>
          <Navbar.Collapse id="navbarSupportedContent">
            <Nav className="mr-auto">
              <Nav.Link href={`#/user/${reflink.toString()}/`}>
                Videos <span className="sr-only">(current)</span>
              </Nav.Link>
              <Nav.Link href={`#/user/${reflink.toString()}/earning`}>Earnings</Nav.Link>
              <Nav.Link href={`#/user/${reflink.toString()}/about`}>About</Nav.Link>
            </Nav>
            <div className="form-inline my-2 my-lg-0">
              <FollowWidget reflink={reflink.toString()} />
            </div>
          </Navbar.Collapse>
        </Navbar>
      </div>
      <Switch>
        <Route exact path={`/user/${reflink.toString()}`}>
          <section className="content_home" style={{ height: 'auto !important' }}>
            <GridFeedView type={'@' + username} awaitingMoreData={true} />
          </section>
        </Route>
        <Route path={`/user/${reflink.toString()}/earning`}>
          <Row>
            <Col md={6}>
              <Card className="bg-steem status">
                <Card.Header>
                  <Card.Title className="text-center">{hiveBalance}</Card.Title>
                </Card.Header>
                <Card.Body className="bg-white text-center">
                  <strong>Available HIVE Balance</strong>
                </Card.Body>
              </Card>
            </Col>
            <Col md={6}>
              <Card className="bg-sbd status">
                <Card.Header>
                  <Card.Title className="text-center">{hbdBalance}</Card.Title>
                </Card.Header>
                <Card.Body className="bg-white text-center">
                  <strong>Available HBD Balance</strong>
                </Card.Body>
              </Card>
            </Col>
          </Row>
        </Route>
        <Route path={`/user/${reflink.toString()}/about`}>
          <ReactMarkdown className={'p-3'} source={profileAbout} />
        </Route>
      </Switch>
    </div>
  )
}
Example #26
Source File: imprint.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
ImprintPage = (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
                // dialogClassName='modal-90w'
                size='lg'
                scrollable
                contentClassName='bg-light'
                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:imprint-title')}</Card.Title>
                        </Col>
                    </Row>
                </Modal.Header>
                <hr className='mx-3 mb-0' />
                <Modal.Body className='px-3 bg-light'>

                    <h5 className='text-justify'>
                        T-Systems International GmbH
                    </h5>

                    <Container className='px-1 px-sm-2 px-md-3'>
                        <br />

                        <p>
                            <strong>Adresse:</strong><br />
                            Hahnstraße 43d<br />
                            D-60528 Frankfurt am Main<br />
                            E-Mail: <a href='mailto:[email protected]'>[email protected]</a><br />
                            Telefon: 069 20060 - 0
                        </p>

                        <p>
                            <strong>Handelsregister:</strong><br />
                            Amtsgericht Frankfurt am Main, HRB 55933, Sitz der Gesellschaft: Frankfurt am Main, Deutschland<br />
                            Ust.-IdNr. DE 118 645 675<br />
                            WEEE-Reg.-Nr. DE50335567
                        </p>

                        <p>
                            <strong>Aufsichtsbehörde:</strong><br />
                            Bundesnetzagentur für Elektrizität, Gas, Telekommunikation, Post und Eisenbahnen<br />
                            Tulpenfeld 4, 53113 Bonn
                        </p>

                        <p>
                            <strong>Aufsichtsrat:</strong><br />
                            Dr. Christian P. Illek (Vorsitzender)
                        </p>

                        <p>
                            <strong>Vertretungsberechtigt:</strong><br />
                            Adel Al-Saleh (Vorsitzender), Christoph Ahrendt, François Fleutiaux, Georg Pepping
                        </p>

                        <p>
                            <strong>Verantwortlich:</strong><br />
                            T-Systems International GmbH<br />
                            Christian R. Andersen<br />
                            Friedrich-Ebert-Allee-140<br />
                            D – 53113 Bonn
                        </p>

                        <p>
                            <a href='https://www.t-systems.com/de/de/kontakt#_blank' rel='noreferrer' target='_blank'>Kontakt aufnehmen</a>
                        </p>

                    </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>
        </>
    )
}
Example #27
Source File: TxnDetailsPage.tsx    From devex with GNU General Public License v3.0 4 votes vote down vote up
TxnDetailsPage: React.FC = () => {
  const { txnHash } = useParams();
  const networkContext = useContext(NetworkContext);
  const { dataService, networkUrl } = networkContext!;

  const [isLoading, setIsLoading] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);
  const [data, setData] = useState<TransactionDetails | null>(null);

  // Fetch data
  useEffect(() => {
    if (!dataService) return;

    let receivedData: TransactionDetails;
    const getData = async () => {
      try {
        setIsLoading(true);
        receivedData = await dataService.getTransactionDetails(txnHash);
        if (receivedData) {
          setData(receivedData);
        }
      } catch (e) {
        console.log(e);
        setError(e);
      } finally {
        setIsLoading(false);
      }
    };

    getData();
    return () => {
      setData(null);
      setError(null);
    };
  }, [dataService, txnHash]);

  return (
    <>
      {isLoading ? (
        <div className="center-spinner">
          <Spinner animation="border" />
        </div>
      ) : null}
      {error ? (
        <NotFoundPage />
      ) : (
        data &&
        data.txn.txParams.receipt && (
          <>
            <div className="transaction-header">
              <h3 className="mb-1">
                <span className="mr-1">
                  {data.txn.txParams.receipt.success === undefined ||
                  data.txn.txParams.receipt.success ? (
                    <FontAwesomeIcon color="green" icon={faExchangeAlt} />
                  ) : (
                    <FontAwesomeIcon color="red" icon={faExclamationCircle} />
                  )}
                </span>
                <span className="ml-2">Transaction</span>
                <LabelStar type="Transaction" />
              </h3>
              <ViewBlockLink
                network={networkUrl}
                type="tx"
                identifier={data.hash}
              />
            </div>
            <div className="subtext">
              <HashDisp hash={"0x" + data.hash} />
            </div>
            <Card className="txn-details-card">
              <Card.Body>
                <Container>
                  <Row>
                    <Col>
                      <div className="txn-detail">
                        <span>From:</span>
                        <span>
                          <QueryPreservingLink
                            to={`/address/${hexAddrToZilAddr(
                              data.txn.senderAddress
                            )}`}
                          >
                            {hexAddrToZilAddr(data.txn.senderAddress)}
                          </QueryPreservingLink>
                        </span>
                      </div>
                    </Col>
                    <Col>
                      <div className="txn-detail">
                        <span>To:</span>
                        <span>
                          {data.contractAddr ? (
                            data.txn.txParams.receipt.success ? (
                              <QueryPreservingLink
                                to={`/address/${hexAddrToZilAddr(
                                  data.contractAddr
                                )}`}
                              >
                                <FontAwesomeIcon
                                  color="darkturquoise"
                                  icon={faFileContract}
                                />{" "}
                                {hexAddrToZilAddr(data.contractAddr)}
                              </QueryPreservingLink>
                            ) : (
                              <QueryPreservingLink
                                to={`/address/${hexAddrToZilAddr(
                                  data.txn.txParams.toAddr
                                )}`}
                              >
                                {hexAddrToZilAddr(data.txn.txParams.toAddr)}
                              </QueryPreservingLink>
                            )
                          ) : (
                            <QueryPreservingLink
                              to={`/address/${hexAddrToZilAddr(
                                data.txn.txParams.toAddr
                              )}`}
                            >
                              {hexAddrToZilAddr(data.txn.txParams.toAddr)}
                            </QueryPreservingLink>
                          )}
                        </span>
                      </div>
                    </Col>
                  </Row>
                  <Row>
                    <Col>
                      <div className="txn-detail">
                        <span>Amount:</span>
                        <span>
                          {qaToZil(data.txn.txParams.amount.toString())}
                        </span>
                      </div>
                    </Col>
                    <Col>
                      <div className="txn-detail">
                        <span>Nonce:</span>
                        <span>{data.txn.txParams.nonce}</span>
                      </div>
                    </Col>
                  </Row>
                  <Row>
                    <Col>
                      <div className="txn-detail">
                        <span>Gas Limit:</span>
                        <span>{data.txn.txParams.gasLimit.toString()}</span>
                      </div>
                    </Col>
                    <Col>
                      <div className="txn-detail">
                        <span>Gas Price:</span>
                        <span>
                          {qaToZil(data.txn.txParams.gasPrice.toString())}
                        </span>
                      </div>
                    </Col>
                  </Row>
                  <Row>
                    <Col>
                      <div className="txn-detail">
                        <span>Transaction Fee:</span>
                        <span>
                          {qaToZil(
                            Number(data.txn.txParams.gasPrice) *
                              data.txn.txParams.receipt!.cumulative_gas
                          )}
                        </span>
                      </div>
                    </Col>
                    <Col>
                      <div className="txn-detail">
                        <span>Transaction Block:</span>
                        <span>
                          <QueryPreservingLink
                            to={`/txbk/${data.txn.txParams.receipt.epoch_num}`}
                          >
                            {data.txn.txParams.receipt.epoch_num}
                          </QueryPreservingLink>
                        </span>
                      </div>
                    </Col>
                  </Row>
                  <Row>
                    <Col>
                      <div className="txn-detail">
                        <span>Success:</span>
                        <span>{`${data.txn.txParams.receipt.success}`}</span>
                      </div>
                    </Col>
                    {data.txn.txParams.receipt.accepted !== undefined && (
                      <Col>
                        <div className="txn-detail">
                          <span>Accepts $ZIL:</span>
                          <span>{`${data.txn.txParams.receipt.accepted}`}</span>
                        </div>
                      </Col>
                    )}
                  </Row>
                </Container>
              </Card.Body>
            </Card>
            <TransactionFlow hash={txnHash} txn={data.txn} />
            <InfoTabs tabs={generateTabsFromTxnDetails(data)} />
          </>
        )
      )}
    </>
  );
}
Example #28
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>
        </>
    )
}
Example #29
Source File: ContractDetailsPage.tsx    From devex with GNU General Public License v3.0 4 votes vote down vote up
ContractDetailsPage: React.FC<IProps> = ({ addr }) => {
  const networkContext = useContext(NetworkContext);
  const { dataService, isIsolatedServer, networkUrl } = networkContext!;

  const addrRef = useRef(addr);
  const [contractData, setContractData] = useState<ContractData | null>(null);
  const [creationTxnHash, setCreationTxnHash] = useState<string | null>(null);
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const [owner, setOwner] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [transactionsCount, setTransactionsCount] = useState<number>(0);

    const isFungibleToken = (contractData: ContractData) => {
      const symbol = contractData.initParams.find(
        (item) => item.vname === "symbol"
      );
      const name = contractData.initParams.find(
        (item) => item.vname === "name"
      );
      const init_supply = contractData.initParams.find(
        (item) => item.vname === "init_supply"
      );
      const decimals = contractData.initParams.find(
        (item) => item.vname === "decimals"
      );

      if (symbol && name && init_supply && decimals) {
        const holders = Object.keys(contractData.state.balances).length;
        /* const holds = Object.values(contractData.state.balances);

      const init_value = typeof (init_supply.value === "string")
        ? parseFloat(init_supply.value)
        : 0;

      console.log(holds);
      const supply =
        init_value -
        (holds.length
          ? holds.reduce(
              (prev: number, current: any) => prev + parseFloat(current),
              0
            )
          : 0); */

        return {
          symbol,
          name,
          init_supply,
          decimals,
          holders,
        };
      }
      return false;
    };

    const fungibleToken = contractData ? isFungibleToken(contractData) : false;


  // Fetch data
  useEffect(() => {
    setIsLoading(true);
    if (!dataService || isIsolatedServer === null) return;

    let contractData: ContractData;
    let creationTxnHash: string;
    let owner: string;
    const getData = async () => {
      try {
        if (isIsolatedServer) {
          contractData = await dataService.getContractData(addrRef.current);
        } else {
          contractData = await dataService.getContractData(addrRef.current);
          creationTxnHash = await dataService.getTxnIdFromContractData(
            contractData
          );
          owner = await dataService.getTransactionOwner(creationTxnHash);
        }
        if (contractData) setContractData(contractData);
        if (creationTxnHash) setCreationTxnHash(creationTxnHash);
        if (owner) setOwner(owner);
      } catch (e) {
        console.log(e);
      } finally {
        setIsLoading(false);
      }
    };
    getData();
  }, [dataService, isIsolatedServer]);

  const generateTabsObj = () => {
    const tabs: {
      tabHeaders: string[];
      tabTitles: string[];
      tabContents: React.ReactNode[];
    } = {
      tabHeaders: [],
      tabTitles: [],
      tabContents: [],
    };

    if (!contractData) return tabs;

    tabs.tabHeaders.push("transactions");
    tabs.tabTitles.push("Transactions");
    tabs.tabContents.push(
      <ContractTransactionsTab
        initParams={contractData.initParams}
        contractAddr={addrRef.current}
        fungibleToken={fungibleToken}
        onTransactionsCount={setTransactionsCount}
      />
    );

    tabs.tabHeaders.push("initParams");
    tabs.tabTitles.push("Init Parameters");
    tabs.tabContents.push(
      <InitParamsTab initParams={contractData.initParams} />
    );

    tabs.tabHeaders.push("State");
    tabs.tabTitles.push("State");
    tabs.tabContents.push(<DefaultTab content={contractData.state} />);

    tabs.tabHeaders.push("code");
    tabs.tabTitles.push("Code");
    tabs.tabContents.push(<CodeTab code={contractData.code} />);

    return tabs;
  };

  return (
    <>
      {isLoading ? (
        <div className="center-spinner">
          <Spinner animation="border" />
        </div>
      ) : null}
      {contractData && (
        <>
          <div className="address-header">
            <h3 className="mb-1">
              <span className="mr-1">
                <FontAwesomeIcon className="fa-icon" icon={faFileContract} />
              </span>
              <span className="ml-2">Contract</span>
              <LabelStar type="Contract" />
            </h3>
            <ViewBlockLink
              network={networkUrl}
              type="address"
              identifier={addrRef.current}
            />
          </div>
          <div className="subtext">
            <AddressDisp isLinked={false} addr={addrRef.current} />
          </div>
          <Card className="address-details-card">
            <Card.Body>
              <Container>
                <Row className="mb-4">
                  <Col>
                    <div className="subtext text-small">Balance</div>
                    <div>{qaToZil(contractData.state["_balance"])}</div>
                  </Col>
                  <Col>
                    <div className="subtext text-small">Transactions</div>
                    <div>{transactionsCount}</div>
                  </Col>
                  {fungibleToken ? (
                    <>
                      <Col>
                        <div className="subtext text-small">Token Info</div>
                        <div>
                          {fungibleToken.name.value} <br />
                          {fungibleToken.symbol.value}
                        </div>
                      </Col>
                      <Col>
                        <div className="subtext text-small">Token Holders</div>
                        <div>{fungibleToken.holders}</div>
                      </Col>
                      <Col>
                        <div className="subtext text-small">
                          Token Transfers
                        </div>
                        <div></div>
                      </Col>
                      <Col>
                        <div className="subtext text-small">Token Supply</div>
                        <div>{fungibleToken.init_supply.value}</div>
                      </Col>
                    </>
                  ) : null}
                </Row>
                {creationTxnHash && (
                  <>
                    <Row className="mb-0">
                      <Col>
                        <div>
                          <span className="mr-2">Contract Creation:</span>
                          <span className="pl-2">
                            <QueryPreservingLink to={`/tx/${creationTxnHash}`}>
                              {creationTxnHash}
                            </QueryPreservingLink>
                          </span>
                        </div>
                      </Col>
                    </Row>
                  </>
                )}
              </Container>
            </Card.Body>
          </Card>
          <InfoTabs tabs={generateTabsObj()} />
        </>
      )}
    </>
  );
}