antd#Descriptions JavaScript Examples

The following examples show how to use antd#Descriptions. 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: utils.js    From the-eye-knows-the-garbage with MIT License 7 votes vote down vote up
renderForeignKey = (text, VerboseNameMap) => {
  console.log(text);
  console.log(VerboseNameMap);
  let items = [];
  for (let key in text) {
    if (key !== 'ty_options_display_txt') {
      let one = <Descriptions.Item label={VerboseNameMap[key]}>{text[key]}</Descriptions.Item>;
      items.push(one);
    }
  }
  return <Space>
    <span>{text.ty_options_display_txt}</span>
    <Popover trigger="click" content={<Descriptions>
      {items}
    </Descriptions>} title="外键数据">
      <InfoCircleTwoTone size="small" />
    </Popover>
  </Space>;
}
Example #2
Source File: vertical.jsx    From virtuoso-design-system with MIT License 6 votes vote down vote up
storiesOf('antd/descriptions', module).add('vertical', () => 
  <Descriptions title="User Info" layout="vertical">
    <Descriptions.Item label="UserName">Zhou Maomao</Descriptions.Item>
    <Descriptions.Item label="Telephone">1810000000</Descriptions.Item>
    <Descriptions.Item label="Live">Hangzhou, Zhejiang</Descriptions.Item>
    <Descriptions.Item label="Address" span={2}>
      No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
    </Descriptions.Item>
    <Descriptions.Item label="Remark">empty</Descriptions.Item>
  </Descriptions>,
  { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Simplest Usage.</p></>) } });
Example #3
Source File: advisory_description.js    From art-dashboard-ui with Apache License 2.0 6 votes vote down vote up
render() {
        return (
            <div>
                <Descriptions title={this.state.data.id}>

                    <Descriptions.Item label={"Advisory Type"}>
                        {this.state.data.advisory_type}
                    </Descriptions.Item>

                    <Descriptions.Item label={"Advisory Status"}>
                        {this.state.data.status}
                    </Descriptions.Item>

                    <Descriptions.Item label={"Advisory Synopsis"}>
                        {this.state.data.synopsis}
                    </Descriptions.Item>

                    <Descriptions.Item label={"QA Status"}>
                        {this.state.data.qa_complete}
                    </Descriptions.Item>

                    <Descriptions.Item label={"Docs Status"}>
                        {this.state.data.doc_complete}
                    </Descriptions.Item>

                    <Descriptions.Item label={"Security Approval"}>
                        {this.state.data.security_approved}
                    </Descriptions.Item>

                    <Descriptions.Item label={"Release Date"}>
                        {this.state.data.release_date}
                    </Descriptions.Item>

                </Descriptions>
            </div>
        );
    }
Example #4
Source File: responsive.jsx    From virtuoso-design-system with MIT License 6 votes vote down vote up
renderContent = (column = 2) => (
  <Descriptions size="small" column={column}>
    <Descriptions.Item label="Created">Lili Qu</Descriptions.Item>
    <Descriptions.Item label="Association">
      <a>421421</a>
    </Descriptions.Item>
    <Descriptions.Item label="Creation Time">2017-01-10</Descriptions.Item>
    <Descriptions.Item label="Effective Time">2017-10-10</Descriptions.Item>
    <Descriptions.Item label="Remarks">
      Gonghu Road, Xihu District, Hangzhou, Zhejiang, China
    </Descriptions.Item>
  </Descriptions>
)
Example #5
Source File: Profile.jsx    From ResoBin with MIT License 6 votes vote down vote up
StyledDescriptions = styled(Descriptions)`
  padding: 0.75rem 0.75rem 0;
  background: ${({ theme }) => theme.darksecondary};
  border-radius: ${({ theme }) => theme.borderRadius};

  .ant-descriptions-item {
    padding-bottom: 0.25rem;
  }

  .ant-descriptions-item-label {
    color: ${({ theme }) => theme.primary};
    font-weight: 400;
    font-size: 0.75rem;
  }

  .ant-descriptions-item-content {
    margin-bottom: 0.5rem;
    color: ${({ theme }) => theme.textColor};
  }
`
Example #6
Source File: loan.js    From credit with Apache License 2.0 6 votes vote down vote up
render() {
    return (

      <Descriptions title="个人信用及贷款记录" bordered>
        <Descriptions.Item label="客户">李明</Descriptions.Item>
        <Descriptions.Item label="信用分">85</Descriptions.Item>
        <Descriptions.Item label="上次评估日期">2021/1/26</Descriptions.Item>
        <Descriptions.Item label="目前信用状况" span={3}>
          <Badge status="processing" text="良好" />
        </Descriptions.Item>
        <Descriptions.Item label="最大贷款金额">¥80000</Descriptions.Item>
        <Descriptions.Item label="目前贷款金额">¥40000</Descriptions.Item>
        <Descriptions.Item label="可用贷款金额">¥40000</Descriptions.Item>
        <Descriptions.Item label="贷款记录">
          1.日期:2020/2/15 金额:¥50000
                  <br />
                  状况:还款完毕
                  <br />
          <br />
                  2.日期:2020/11/13 金额:¥40000
                  <br />
                  状况:未还款
                  <br />
          <br />
        </Descriptions.Item>
        <Space direction="vertical">
          <Search placeholder="输入贷款金额" enterButton="确认" onSearch={this.addLoan} style={{ width: 500 }} />
        </Space>
      </Descriptions>




    )
  }
Example #7
Source File: text.jsx    From virtuoso-design-system with MIT License 6 votes vote down vote up
storiesOf('antd/descriptions', module).add('text', () => 
  <Descriptions title="User Info" column={2}>
    <Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
    <Descriptions.Item label={<div style={{ display: 'flex' }}>Billing Mode</div>}>
      Prepaid
    </Descriptions.Item>
    <Descriptions.Item label="Automatic Renewal">YES</Descriptions.Item>
    <Descriptions.Item label="Order time">2018-04-24 18:00:00</Descriptions.Item>
    <Descriptions.Item label="Usage Time" span={2}>
      2019-04-24 18:00:00
    </Descriptions.Item>
    <Descriptions.Item label="Status" span={3}>
      <Badge status="processing" text="Running" />
    </Descriptions.Item>
    <Descriptions.Item label="Negotiated Amount">$80.00</Descriptions.Item>
    <Descriptions.Item label="Discount">$20.00</Descriptions.Item>
    <Descriptions.Item label="Official Receipts">$60.00</Descriptions.Item>
    <Descriptions.Item label="Config Info">
      Data disk type: MongoDB
      <br />
      Database version: 3.4
      <br />
      Package: dds.mongo.mid
      <br />
      Storage space: 10 GB
      <br />
      Replication factor: 3
      <br />
      Region: East China 1<br />
    </Descriptions.Item>
    <Descriptions.Item label="Official Receipts">$60.00</Descriptions.Item>
    <Descriptions.Item label="Config Info">
      <Table size="small" pagination={false} dataSource={dataSource} columns={columns} />
    </Descriptions.Item>
  </Descriptions>,
  { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Descriptions with border and background color.</p></>) } });
Example #8
Source File: Detail.js    From ant-back with MIT License 6 votes vote down vote up
render() {
    const { current, loading } = this.state;
    return (
      <PageHeaderWrapper title="详情">
        <Card loading={loading}>
          <Descriptions size="large" title="基本信息">
            <Descriptions.Item label="存放路径">{current.url} </Descriptions.Item> 
            <Descriptions.Item label="访问链接">
              <a target="_blank" href={imgUrl + current.url}>
                {imgUrl + current.url}{' '}
              </a>
            </Descriptions.Item> 
          </Descriptions>
          <Divider dashed />
          <Descriptions size="large" title="其他信息">
            <Descriptions.Item label="创建时间">
              {moment(current.createdAt).format('YYYY-MM-DD HH:mm:ss')}{' '}
            </Descriptions.Item> 
            <Descriptions.Item label="上次修改时间">
              {moment(current.updatedAt).format('YYYY-MM-DD HH:mm:ss')}{' '}
            </Descriptions.Item> 
          </Descriptions>
          <Divider dashed />
          <Descriptions size="remark" title="备注">
            <Descriptions.Item> {current.remark}</Descriptions.Item> 
          </Descriptions>
          <Divider dashed />
          <img src={imgUrl + current.url} className={styles.detailImg} alt="img" />
          <Row className="marginTop textRight">
            <Button type="primary" onClick={() => router.go(-1)}>
              返回
            </Button>
          </Row>
        </Card>
      </PageHeaderWrapper>
    );
  }
Example #9
Source File: MyFile.js    From next-terminal with GNU Affero General Public License v3.0 6 votes vote down vote up
render() {
        let storage = this.state.storage;
        let contentClassName = isAdmin() ? 'page-content' : 'page-content-user';
        return (
            <div>
                <Content key='page-content' className={["site-layout-background", contentClassName]}>
                    <div style={{marginBottom: 20}}>
                        <Row justify="space-around" align="middle" gutter={24}>
                            <Col span={16} key={1}>
                                <Title level={3}>我的文件</Title>
                            </Col>
                            <Col span={8} key={2} style={{textAlign: 'right'}}>
                                <Descriptions title="" column={2}>
                                    <Descriptions.Item label={<div><FireOutlined/> 大小限制</div>}>
                                        <strong>{storage['limitSize'] < 0 ? '无限制' : renderSize(storage['limitSize'])}</strong>
                                    </Descriptions.Item>
                                    <Descriptions.Item label={<div><HeartOutlined/> 已用大小</div>}>
                                        <strong>{renderSize(storage['usedSize'])}</strong>
                                    </Descriptions.Item>
                                </Descriptions>
                            </Col>
                        </Row>
                    </div>
                    <FileSystem storageId={getCurrentUser()['id']}
                                storageType={'storages'}
                                callback={this.getDefaultStorage}
                                upload={true}
                                download={true}
                                delete={true}
                                rename={true}
                                edit={true}
                                minHeight={window.innerHeight - 203}/>
                </Content>
            </div>
        );
    }
Example #10
Source File: index copy.jsx    From prometheusPro with MIT License 6 votes vote down vote up
description = (
  <RouteContext.Consumer>
    {({ isMobile }) => (
      <Descriptions className={styles.headerList} size="small" column={isMobile ? 1 : 2}>
        {/* <Descriptions.Item label="其他信息"></Descriptions.Item> */}
      </Descriptions>
    )}
  </RouteContext.Consumer>
)
Example #11
Source File: TracksStagesCard.js    From codeclannigeria-frontend with MIT License 6 votes vote down vote up
TracksStagesCard = ({ trackData, stageData }) => {
  const avgTasksPerStage = stageData
    ? Math.round(
        stageData.items
          .map(stage => stage.taskCount)
          .reduce(function (accumulator, currentValue) {
            return accumulator + currentValue;
          }, 0) / stageData.length
      )
    : 0;

  const { description, title } = trackData;
  return (
    <div>
      <Descriptions
        title="Track Descripton"
        bordered
        size="small"

        // column={{ xxl: 4, xl: 2, lg: 3, md: 3, sm: 1, xs: 1 }}
      >
        <Descriptions.Item label="Track Name">{title}</Descriptions.Item>
        <Descriptions.Item label="No of Stages">
          {stageData.length}
        </Descriptions.Item>
        <Descriptions.Item label="Certificate upon Completion">
          Yes
        </Descriptions.Item>
        <Descriptions.Item label="Amount">Free</Descriptions.Item>
        <Descriptions.Item label="Average Tasks per Stage">
          {avgTasksPerStage}
        </Descriptions.Item>
        <Descriptions.Item label="Description">{description}</Descriptions.Item>
      </Descriptions>
    </div>
  );
}
Example #12
Source File: basic.jsx    From virtuoso-design-system with MIT License 6 votes vote down vote up
storiesOf('antd/descriptions', module).add('basic', () => 
  <Descriptions title="User Info">
    <Descriptions.Item label="UserName">Zhou Maomao</Descriptions.Item>
    <Descriptions.Item label="Telephone">1810000000</Descriptions.Item>
    <Descriptions.Item label="Live">Hangzhou, Zhejiang</Descriptions.Item>
    <Descriptions.Item label="Remark">empty</Descriptions.Item>
    <Descriptions.Item label="Address">
      No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
    </Descriptions.Item>
  </Descriptions>,
  { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Simplest Usage.</p></>) } });
Example #13
Source File: index.jsx    From prometheusPro with MIT License 6 votes vote down vote up
description = (
  <RouteContext.Consumer>
    {({ isMobile }) => (
      <Descriptions className={styles.headerList} size="small" column={isMobile ? 1 : 2}>
        <Descriptions.Item label="创建人">咕噜咕噜</Descriptions.Item>
        <Descriptions.Item label="版本">2.16.1</Descriptions.Item>
        <Descriptions.Item label="创建时间">2020-04-04 14:20</Descriptions.Item>
        <Descriptions.Item label="更新时间">2020-04-04 14:20</Descriptions.Item>
        <Descriptions.Item label="说明">表单配置 嘻嘻嘻嘻嘻嘻嘻嘻;yaml 配置反反复复付付付付反反复复付都放到发的发的发的发的</Descriptions.Item>
      </Descriptions>
    )}
  </RouteContext.Consumer>
)
Example #14
Source File: border.jsx    From virtuoso-design-system with MIT License 6 votes vote down vote up
storiesOf('antd/descriptions', module).add('border', () => 
  <Descriptions title="User Info" bordered>
    <Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
    <Descriptions.Item label="Billing Mode">Prepaid</Descriptions.Item>
    <Descriptions.Item label="Automatic Renewal">YES</Descriptions.Item>
    <Descriptions.Item label="Order time">2018-04-24 18:00:00</Descriptions.Item>
    <Descriptions.Item label="Usage Time" span={2}>
      2019-04-24 18:00:00
    </Descriptions.Item>
    <Descriptions.Item label="Status" span={3}>
      <Badge status="processing" text="Running" />
    </Descriptions.Item>
    <Descriptions.Item label="Negotiated Amount">$80.00</Descriptions.Item>
    <Descriptions.Item label="Discount">$20.00</Descriptions.Item>
    <Descriptions.Item label="Official Receipts">$60.00</Descriptions.Item>
    <Descriptions.Item label="Config Info">
      Data disk type: MongoDB
      <br />
      Database version: 3.4
      <br />
      Package: dds.mongo.mid
      <br />
      Storage space: 10 GB
      <br />
      Replication factor: 3
      <br />
      Region: East China 1<br />
    </Descriptions.Item>
  </Descriptions>,
  { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Descriptions with border and background color.</p></>) } });
Example #15
Source File: LiquidityMiningDescription.js    From dexwebapp with Apache License 2.0 6 votes vote down vote up
render() {
    const theme = this.props.theme;
    const tokens = this.props.exchange.tokens;
    const tokenId = this.props.config.tokenId;
    const token = config.getTokenByTokenId(tokenId, tokens);
    const amount = config.fromWEI(
      token.symbol,
      this.props.config.amount,
      tokens,
      {
        precision: 0,
      }
    );

    const rewardTokenId = this.props.config.rewardTokenId;
    const rewardToken = config.getTokenByTokenId(rewardTokenId, tokens);

    return (
      <BackgroundDiv>
        <Descriptions column={1} title={`${this.props.market}`} size={'small'}>
          <Descriptions.Item label={<I s="Reward" />}>
            {amount} {token.symbol}
          </Descriptions.Item>
          <Descriptions.Item label={<I s="Reward Token" />}>
            {rewardToken ? rewardToken.symbol : ''}
          </Descriptions.Item>
          <Descriptions.Item label={<I s="Max Spread" />}>
            {this.props.config.maxSpread > 0
              ? `${this.props.config.maxSpread * 100}%`
              : '-'}
          </Descriptions.Item>
          <Descriptions.Item label={<I s="Activity Time" />}>
            {Moment(this.props.config.rangeFrom).format(theme.timeFormat)} -{' '}
            {Moment(this.props.config.rangeTo).format(theme.timeFormat)}
          </Descriptions.Item>
        </Descriptions>
      </BackgroundDiv>
    );
  }
Example #16
Source File: size.jsx    From virtuoso-design-system with MIT License 5 votes vote down vote up
render() {
    return (
      <div>
        <Radio.Group onChange={this.onChange} value={this.state.size}>
          <Radio value="default">default</Radio>
          <Radio value="middle">middle</Radio>
          <Radio value="small">small</Radio>
        </Radio.Group>
        <br />
        <br />
        <Descriptions
          bordered
          title="Custom Size"
          size={this.state.size}
          extra={<Button type="primary">Edit</Button>}
        >
          <Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
          <Descriptions.Item label="Billing">Prepaid</Descriptions.Item>
          <Descriptions.Item label="time">18:00:00</Descriptions.Item>
          <Descriptions.Item label="Amount">$80.00</Descriptions.Item>
          <Descriptions.Item label="Discount">$20.00</Descriptions.Item>
          <Descriptions.Item label="Official">$60.00</Descriptions.Item>
          <Descriptions.Item label="Config Info">
            Data disk type: MongoDB
            <br />
            Database version: 3.4
            <br />
            Package: dds.mongo.mid
            <br />
            Storage space: 10 GB
            <br />
            Replication factor: 3
            <br />
            Region: East China 1<br />
          </Descriptions.Item>
        </Descriptions>
        <br />
        <br />
        <Descriptions
          title="Custom Size"
          size={this.state.size}
          extra={<Button type="primary">Edit</Button>}
        >
          <Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
          <Descriptions.Item label="Billing">Prepaid</Descriptions.Item>
          <Descriptions.Item label="time">18:00:00</Descriptions.Item>
          <Descriptions.Item label="Amount">$80.00</Descriptions.Item>
          <Descriptions.Item label="Discount">$20.00</Descriptions.Item>
          <Descriptions.Item label="Official">$60.00</Descriptions.Item>
        </Descriptions>
      </div>
    );
  }
Example #17
Source File: UserDashboard.js    From credit with Apache License 2.0 5 votes vote down vote up
render() {
        return (
            <div className="user-background">
                <h3 className="title">个人信息</h3>
                <Row justify="space-between">
                    <Col span={6}>
                        <Card style={{ width: 300, marginTop: 16 }} bordered={false}>
                            <Meta
                                avatar={
                                    <Avatar src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2586243650,1628445668&fm=26&gp=0.jpg" />
                                }
                                title="欢迎回来,Chris"
                                description="这里是您的详情信息"
                            />
                        </Card>
                    </Col>
                    <Col span={6}>
                        <Card style={{ width: 300, marginTop: 16 }} bordered={false}>
                            <Statistic
                                title="当前信用分"
                                value={710}
                                precision={2}
                                valueStyle={{ color: '#3f8600' }}
                            />
                        </Card>
                    </Col>
                    <Col span={6}>
                    </Col>
                    <Col span={6}>

                    </Col>
                    <Col span={6}>

                    </Col>
                </Row>
                <Row>
                    <Descriptions bordered>
                        <Descriptions.Item label="用户姓名">Chris</Descriptions.Item>
                        <Descriptions.Item label="性别">男</Descriptions.Item>
                        <Descriptions.Item label="年龄">25</Descriptions.Item>
                        <Descriptions.Item label="信息录入时间">2021-03-15 18:03:15</Descriptions.Item>
                        <Descriptions.Item label="信用评分时间" span={2}>
                            2021-03-15 18:15:08
                        </Descriptions.Item>
                        <Descriptions.Item label="账户地址" span={3}>
                            <a>0x10a12eB389B0Df756C63778E522C3463B7B60BD0</a>
                        </Descriptions.Item>
                        <Descriptions.Item label="当前数据状态" span={3}>
                            <Badge status="processing" text="尚未授权机构使用" />
                        </Descriptions.Item>
                        <Descriptions.Item label="名下房产数量">1</Descriptions.Item>
                        <Descriptions.Item label="贷款余额">¥200000.00</Descriptions.Item>
                        <Descriptions.Item label="月收入">¥15000.00</Descriptions.Item>
                        <Descriptions.Item label="信用历史">
                            三个月内信用卡逾期次数:<span className="normal">0</span>
                            <br />
                            半年内信用卡逾期次数: <span className="warning">1</span>
                            <br />
                            一年内信用卡逾期次数: <span className="warning">1</span>
                            <br />
                            两年内信用卡逾期次数: <span className="warning">2</span>
                            <br />
                        </Descriptions.Item>
                    </Descriptions>
                </Row>
                <a>{'>>'}更多</a>
            </div>
        )
    }
Example #18
Source File: JobDetailsModal.js    From placement-portal with MIT License 5 votes vote down vote up
render() {

        const {modalVisible, handleOk, handleCancel, jobId, filteredJobs} = this.props;

        const jobDetails = filteredJobs.find(job => job._id === jobId);
        const modalProps = {
            centered: true,
            title: "Job Profile",
            visible: modalVisible,
            onOk: handleOk,
            onCancel: handleCancel,
            width: "50vw"
        };

        return (
            <Modal {...modalProps}>
                <Row>
                    <Descriptions
                        column={1}
                    >
                        <Descriptions.Item label={"Company name"}>
                            {jobDetails.company_name}
                        </Descriptions.Item>
                        <Descriptions.Item label={"Job headline"}>
                            {jobDetails.job_headline}
                        </Descriptions.Item>
                        <Descriptions.Item label={"Job type"}>
                            {jobDetails.type_of_job}
                        </Descriptions.Item>
                        <Descriptions.Item label={"Location"}>
                            {jobDetails.job_location}
                        </Descriptions.Item>
                        <Descriptions.Item label="Skills required">
                            {
                                jobDetails.skills ? jobDetails["skills"].map(item =>
                                    <Tag key={item} color='blue' style={{margin: 5}}>{item}</Tag>
                                ) : null
                            }
                        </Descriptions.Item>
                        <Descriptions.Item label={"Base Salary"}>
                            {jobDetails.base_salary}
                        </Descriptions.Item>
                        <Descriptions.Item label={"Job description"}>
                            {jobDetails.job_description}
                        </Descriptions.Item>
                    </Descriptions>
                </Row>
            </Modal>
        );
    }
Example #19
Source File: actions.jsx    From virtuoso-design-system with MIT License 5 votes vote down vote up
storiesOf('antd/page-header', module).add('actions', () => 
  <>
    <PageHeader
      className="site-page-header"
      onBack={() => window.history.back()}
      title="Title"
      subTitle="This is a subtitle"
      extra={[
        <Button key="3">Operation</Button>,
        <Button key="2">Operation</Button>,
        <Button key="1" type="primary">
          Primary
        </Button>,
      ]}
    >
      <Descriptions size="small" column={3}>
        <Descriptions.Item label="Created">Lili Qu</Descriptions.Item>
        <Descriptions.Item label="Association">
          <a>421421</a>
        </Descriptions.Item>
        <Descriptions.Item label="Creation Time">2017-01-10</Descriptions.Item>
        <Descriptions.Item label="Effective Time">2017-10-10</Descriptions.Item>
        <Descriptions.Item label="Remarks">
          Gonghu Road, Xihu District, Hangzhou, Zhejiang, China
        </Descriptions.Item>
      </Descriptions>
    </PageHeader>
    <br />
    <PageHeader
      onBack={() => window.history.back()}
      title="Title"
      tags={<Tag color="blue">Running</Tag>}
      subTitle="This is a subtitle"
      extra={[
        <Button key="3">Operation</Button>,
        <Button key="2">Operation</Button>,
        <Button key="1" type="primary">
          Primary
        </Button>,
      ]}
    >
      <Row>
        <Statistic title="Status" value="Pending" />
        <Statistic
          title="Price"
          prefix="$"
          value={568.08}
          style={{
            margin: '0 32px',
          }}
        />
        <Statistic title="Balance" prefix="$" value={3345.08} />
      </Row>
    </PageHeader>
  </>,
  { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Use the operating area and customize the sub-nodes, suitable for use in the need to display some complex information to help users quickly understand the information and operations of this page.</p></>) } });
Example #20
Source File: CompanyProfileModal.js    From placement-portal with MIT License 5 votes vote down vote up
render() {
        const { data, modalState, onClose, isMobile} = this.props;

        return (
            <Modal
                title={data.email}
                visible={modalState}
                onCancel={onClose}
                onOk={onClose}
                width= {isMobile ?'90vw' : '50vw'}
            >
                <Layout
                    style={{background: '#fff'}}
                >
                    <Row type="flex" justify="center" style={{background: '#fff'}}>
                        <Col md={16} xs={24} sm={24} style={{margin: 10}}>
                            <Content
                                style={{
                                    background: "#fff"
                                }}
                            >
                                <Avatar src={data.logo_link} size={100} style={{margin: 10}}/>
                                <Descriptions column={1}>
                                    <Descriptions.Item label="Company Name" >{data.company_name}</Descriptions.Item>
                                    <Descriptions.Item label="Email" >{data.email}</Descriptions.Item>
                                    <Descriptions.Item label="Website" >{data.website}</Descriptions.Item>
                                    <Descriptions.Item label="Address" >{data.company_address}</Descriptions.Item>
                                    <Descriptions.Item label="Introduction">{data.company_introduction}</Descriptions.Item>
                                    <Descriptions.Item label="Last Modified">{new Date(data.last_modified_date).toDateString()}</Descriptions.Item>
                                </Descriptions>
                                {data.contact_details.map((contact, index) =>
                                    (<Descriptions key={index}>
                                            <Descriptions.Item lable="Designation">{contact.designation}</Descriptions.Item>
                                            <Descriptions.Item lable="Email">{contact.email}</Descriptions.Item>
                                            <Descriptions.Item label="Contact number">{contact.phone}</Descriptions.Item>
                                        </Descriptions>
                                    )
                                )
                                }
                            </Content>
                        </Col>
                    </Row>
                </Layout>
            </Modal>
        );
    }
Example #21
Source File: Profile.jsx    From ResoBin with MIT License 5 votes vote down vote up
Profile = () => {
  const profile = useSelector(selectUserProfile)

  return (
    <FlexVerticalGap>
      <UserAvatar size={72} src={profile?.profilePicture} />

      <UserInfo>
        <h2>{profile.name}</h2>
        <span>({profile.ldapId})</span>
      </UserInfo>

      <StyledDescriptions column={1} layout="vertical">
        <Descriptions.Item label="Email">{profile.email}</Descriptions.Item>

        <Descriptions.Item label="Department">
          {profile.department}
        </Descriptions.Item>
      </StyledDescriptions>

      <StyledDescriptions column={1} layout="vertical">
        <Descriptions.Item label="Favorites courses">
          {profile.favoriteCourses.length
            ? profile.favoriteCourses.join(', ')
            : 'None'}
        </Descriptions.Item>

        <Descriptions.Item label="Resources requested for">
          {profile.resourcesRequested.length
            ? profile.resourcesRequested.join(', ')
            : 'None'}
        </Descriptions.Item>

        <Descriptions.Item label="Reviews requested for">
          {profile.reviewsRequested.length
            ? profile.reviewsRequested.join(', ')
            : 'None'}
        </Descriptions.Item>
      </StyledDescriptions>
    </FlexVerticalGap>
  )
}
Example #22
Source File: ProjectCard.jsx    From ui with MIT License 5 votes vote down vote up
{ Item } = Descriptions
Example #23
Source File: Header.js    From react-perspective-cropper with MIT License 5 votes vote down vote up
Header = () => {
  return (
    <div className='site-page-header'>
      <PageHeader ghost={false} title='react-perspective-cropper'>
        <Descriptions size='small' column={2}>
          <Descriptions.Item label='Package'>
            <a href='https://www.npmjs.com/package/react-perspective-cropper'>
              <img
                alt='npm'
                src='https://img.shields.io/npm/v/react-perspective-cropper.svg'
              />
            </a>
            <a href='https://standardjs.com'>
              <img
                alt='standardjs'
                src='https://img.shields.io/badge/code_style-standard-brightgreen.svg'
              />
            </a>
          </Descriptions.Item>
          <Descriptions.Item label='Description'>
            <Paragraph>
              React component performing border detection, perspective
              correction and simple image filters over a provided image ? ?
            </Paragraph>
          </Descriptions.Item>
          <Descriptions.Item label='Created by'>
            Giacomo Cerquone from
            <span
              aria-label='italy flag'
              role='img'
              style={{ margin: '0 10px' }}
            >
              ??
            </span>
            with{' '}
            <span aria-label='heart' role='img' style={{ margin: '0 10px' }}>
              ❤️
            </span>
          </Descriptions.Item>
          <Descriptions.Item label='Info'>
            <Paragraph>
              Make sure to only use HiRes images!
              <br />
              <b>
                <a
                  rel='noreferrer'
                  target='_blank'
                  href='https://github.com/giacomocerquone/react-perspective-cropper/blob/master/gifs/example-img.jpg?raw=true'
                >
                  You could use this image for example.
                </a>
              </b>
            </Paragraph>
          </Descriptions.Item>
        </Descriptions>
      </PageHeader>
    </div>
  )
}
Example #24
Source File: index.jsx    From prometheusPro with MIT License 5 votes vote down vote up
Step3 = props => {
  const { data, dispatch } = props;

  if (!data) {
    return null;
  }

  const { payAccount, receiverAccount, receiverName, amount } = data;

  const onFinish = () => {
    if (dispatch) {
      dispatch({
        type: 'formAndstepForm/saveCurrentStep',
        payload: 'info',
      });
    }
  };

  const information = (
    <div className={styles.information}>
      <Descriptions column={1}>
        <Descriptions.Item label="付款账户"> {payAccount}</Descriptions.Item>
        <Descriptions.Item label="收款账户"> {receiverAccount}</Descriptions.Item>
        <Descriptions.Item label="收款人姓名"> {receiverName}</Descriptions.Item>
        <Descriptions.Item label="转账金额">
          <Statistic value={amount} suffix="元" />
        </Descriptions.Item>
      </Descriptions>
    </div>
  );
  const extra = (
    <>
      <Button type="primary" onClick={onFinish}>
        再转一笔
      </Button>
      <Button>查看账单</Button>
    </>
  );
  return (
    <Result
      status="success"
      title="操作成功"
      subTitle="预计两小时内到账"
      extra={extra}
      className={styles.result}
    >
      {information}
    </Result>
  );
}
Example #25
Source File: GradingModal.js    From codeclannigeria-frontend with MIT License 5 votes vote down vote up
GradingModal = ({ visible, onCancel, onCreate, taskId }) => {
  

  const dispatch = useDispatch();
  useEffect(() => {
    if (taskId && visible) {
      dispatch(getTaskSubmissionAction(taskId));
    }
  }, [dispatch, taskId, visible]);

  const task = useSelector(state => state.tasks.singleMenteeSubmittedTask);

  return (
    <React.Fragment>
      <Modal visible={visible} cancelText="Done" onCancel={onCancel}>
        {task.data ? (
          <Descriptions
            title={`Task ${taskId} `}
            size="small"
            layout="vertical"
            bordered={true}
            // column={{ xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 }}
          >
            <Descriptions.Item label="Task Id">
              #{task.data.id}
            </Descriptions.Item>
            <Descriptions.Item label="Task Url">
              <a href={task.data.taskUrl}>{task.data.taskUrl}</a>
            </Descriptions.Item>
            <Descriptions.Item label="Grade %">
              {task.data.gradePercentage} %
            </Descriptions.Item>
            <Descriptions.Item label="Your Comment" span={3}>
              {task.data.menteeComment}
            </Descriptions.Item>
            <Descriptions.Item label="Mentor Comment" span={3}>
              {task.data.mentorComment}
            </Descriptions.Item>
          </Descriptions>
        ) : null}

        {task.loading ? <CustomLoader /> : null}
      </Modal>
    </React.Fragment>
  );
}
Example #26
Source File: index.jsx    From prometheusPro with MIT License 5 votes vote down vote up
content = (
  <>
    <Descriptions title="项目名称">
      <Descriptions.Item label="项目 ID">23421</Descriptions.Item>
      <Descriptions.Item label="负责人">曲丽丽</Descriptions.Item>
      <Descriptions.Item label="生效时间">2016-12-12 ~ 2017-12-12</Descriptions.Item>
    </Descriptions>
    <br />
    <Steps progressDot current={1}>
      <Step
        title={
          <span
            style={{
              fontSize: 14,
            }}
          >
            创建项目
          </span>
        }
        description={desc1}
      />
      <Step
        title={
          <span
            style={{
              fontSize: 14,
            }}
          >
            部门初审
          </span>
        }
        description={desc2}
      />
      <Step
        title={
          <span
            style={{
              fontSize: 14,
            }}
          >
            财务复核
          </span>
        }
      />
      <Step
        title={
          <span
            style={{
              fontSize: 14,
            }}
          >
            完成
          </span>
        }
      />
    </Steps>
  </>
)
Example #27
Source File: index.jsx    From micro-front-template with MIT License 5 votes vote down vote up
Status = () => {
  const [userInfo, setUserInfo] = useState();
  useEffect(() => {
    if (!token) return;

    (async () => {
      setUserInfo({
        nickname: "shadows",
        avatarUrl: "",
        gender: 1,
        country: "中国",
        province: "广东",
        city: "深圳",
      });
    })();
  }, []);

  if (!userInfo) return null;

  return (
    <section>
      <Descriptions title={`欢迎你,${userInfo.nickname}`}>
        <Descriptions.Item label="Avatar">
          <Avatar src={userInfo.avatarUrl} />
        </Descriptions.Item>
        <Descriptions.Item label="UserName">
          {userInfo.nickname}
        </Descriptions.Item>
        <Descriptions.Item label="Gender">
          {userInfo.gender ? "boy" : "girl"}
        </Descriptions.Item>
        <Descriptions.Item label="Live">{`${userInfo.country} ${userInfo.province} ${userInfo.city}`}</Descriptions.Item>
      </Descriptions>
      <style jsx>{`
        section {
          padding: 20px;
        }
      `}</style>
    </section>
  );
}
Example #28
Source File: index.jsx    From prometheusPro with MIT License 4 votes vote down vote up
Step2 = props => {
  const { form, data, dispatch, submitting } = props;

  if (!data) {
    return null;
  }

  const { getFieldDecorator, validateFields, getFieldsValue } = form;

  const onPrev = () => {
    if (dispatch) {
      const values = getFieldsValue();
      dispatch({
        type: 'formAndstepForm/saveStepFormData',
        payload: { ...data, ...values },
      });
      dispatch({
        type: 'formAndstepForm/saveCurrentStep',
        payload: 'info',
      });
    }
  };

  const onValidateForm = e => {
    e.preventDefault();
    validateFields((err, values) => {
      if (!err) {
        if (dispatch) {
          dispatch({
            type: 'formAndstepForm/submitStepForm',
            payload: { ...data, ...values },
          });
        }
      }
    });
  };

  const { payAccount, receiverAccount, receiverName, amount } = data;
  return (
    <Form layout="horizontal" className={styles.stepForm}>
      <Alert
        closable
        showIcon
        message="确认转账后,资金将直接打入对方账户,无法退回。"
        style={{
          marginBottom: 24,
        }}
      />
      <Descriptions column={1}>
        <Descriptions.Item label="付款账户"> {payAccount}</Descriptions.Item>
        <Descriptions.Item label="收款账户"> {receiverAccount}</Descriptions.Item>
        <Descriptions.Item label="收款人姓名"> {receiverName}</Descriptions.Item>
        <Descriptions.Item label="转账金额">
          <Statistic value={amount} suffix="元" />
        </Descriptions.Item>
      </Descriptions>
      <Divider
        style={{
          margin: '24px 0',
        }}
      />
      <Form.Item {...formItemLayout} label="支付密码" required={false}>
        {getFieldDecorator('password', {
          initialValue: '123456',
          rules: [
            {
              required: true,
              message: '需要支付密码才能进行支付',
            },
          ],
        })(
          <Input
            type="password"
            autoComplete="off"
            style={{
              width: '80%',
            }}
          />,
        )}
      </Form.Item>
      <Form.Item
        style={{
          marginBottom: 8,
        }}
        wrapperCol={{
          xs: {
            span: 24,
            offset: 0,
          },
          sm: {
            span: formItemLayout.wrapperCol.span,
            offset: formItemLayout.labelCol.span,
          },
        }}
        label=""
      >
        <Button type="primary" onClick={onValidateForm} loading={submitting}>
          提交
        </Button>
        <Button
          onClick={onPrev}
          style={{
            marginLeft: 8,
          }}
        >
          上一步
        </Button>
      </Form.Item>
    </Form>
  );
}
Example #29
Source File: Swap.jsx    From nft-e2e-example with MIT License 4 votes vote down vote up
function Swap({ selectedProvider, tokenListURI }) {
  const [tokenIn, setTokenIn] = useState(defaultToken);
  const [tokenOut, setTokenOut] = useState(defaultTokenOut);
  const [exact, setExact] = useState();
  const [amountIn, setAmountIn] = useState();
  const [amountInMax, setAmountInMax] = useState();
  const [amountOut, setAmountOut] = useState();
  const [amountOutMin, setAmountOutMin] = useState();
  const [trades, setTrades] = useState();
  const [routerAllowance, setRouterAllowance] = useState();
  const [balanceIn, setBalanceIn] = useState();
  const [balanceOut, setBalanceOut] = useState();
  const [slippageTolerance, setSlippageTolerance] = useState(
    new Percent(Math.round(defaultSlippage * 100).toString(), "10000"),
  );
  const [timeLimit, setTimeLimit] = useState(defaultTimeLimit);
  const [swapping, setSwapping] = useState(false);
  const [approving, setApproving] = useState(false);
  const [settingsVisible, setSettingsVisible] = useState(false);
  const [swapModalVisible, setSwapModalVisible] = useState(false);

  const [tokenList, setTokenList] = useState([]);

  const [tokens, setTokens] = useState();

  const [invertPrice, setInvertPrice] = useState(false);

  const blockNumber = useBlockNumber(selectedProvider, 3000);

  const signer = selectedProvider.getSigner();
  const routerContract = new ethers.Contract(ROUTER_ADDRESS, IUniswapV2Router02ABI, signer);

  const _tokenListUri = tokenListURI || "https://gateway.ipfs.io/ipns/tokens.uniswap.org";

  const debouncedAmountIn = useDebounce(amountIn, 500);
  const debouncedAmountOut = useDebounce(amountOut, 500);

  const activeChainId = process.env.REACT_APP_NETWORK === "kovan" ? ChainId.KOVAN : ChainId.MAINNET;

  useEffect(() => {
    const getTokenList = async () => {
      console.log(_tokenListUri);
      try {
        const tokenList = await fetch(_tokenListUri);
        const tokenListJson = await tokenList.json();
        const filteredTokens = tokenListJson.tokens.filter(function (t) {
          return t.chainId === activeChainId;
        });
        const ethToken = WETH[activeChainId];
        ethToken.name = "Ethereum";
        ethToken.symbol = "ETH";
        ethToken.logoURI =
          "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png";
        const _tokenList = [ethToken, ...filteredTokens];
        setTokenList(_tokenList);
        const _tokens = tokenListToObject(_tokenList);
        setTokens(_tokens);
      } catch (e) {
        console.log(e);
      }
    };
    getTokenList();
  }, [tokenListURI]);

  const getTrades = async () => {
    if (tokenIn && tokenOut && (amountIn || amountOut)) {
      const pairs = arr => arr.map((v, i) => arr.slice(i + 1).map(w => [v, w])).flat();

      const baseTokens = tokenList
        .filter(function (t) {
          return ["DAI", "USDC", "USDT", "COMP", "ETH", "MKR", "LINK", tokenIn, tokenOut].includes(t.symbol);
        })
        .map(el => {
          return new Token(el.chainId, el.address, el.decimals, el.symbol, el.name);
        });

      const listOfPairwiseTokens = pairs(baseTokens);

      const getPairs = async list => {
        const listOfPromises = list.map(item => Fetcher.fetchPairData(item[0], item[1], selectedProvider));
        return Promise.all(listOfPromises.map(p => p.catch(() => undefined)));
      };

      const listOfPairs = await getPairs(listOfPairwiseTokens);

      let bestTrade;

      if (exact === "in") {
        setAmountInMax();
        bestTrade = Trade.bestTradeExactIn(
          listOfPairs.filter(item => item),
          new TokenAmount(tokens[tokenIn], parseUnits(amountIn.toString(), tokens[tokenIn].decimals)),
          tokens[tokenOut],
          { maxNumResults: 3, maxHops: 1 },
        );
        if (bestTrade[0]) {
          setAmountOut(bestTrade[0].outputAmount.toSignificant(6));
        } else {
          setAmountOut();
        }
      } else if (exact === "out") {
        setAmountOutMin();
        bestTrade = Trade.bestTradeExactOut(
          listOfPairs.filter(item => item),
          tokens[tokenIn],
          new TokenAmount(tokens[tokenOut], parseUnits(amountOut.toString(), tokens[tokenOut].decimals)),
          { maxNumResults: 3, maxHops: 1 },
        );
        if (bestTrade[0]) {
          setAmountIn(bestTrade[0].inputAmount.toSignificant(6));
        } else {
          setAmountIn();
        }
      }

      setTrades(bestTrade);

      console.log(bestTrade);
    }
  };

  useEffect(() => {
    getTrades();
  }, [tokenIn, tokenOut, debouncedAmountIn, debouncedAmountOut, slippageTolerance, selectedProvider]);

  useEffect(() => {
    if (trades && trades[0]) {
      if (exact === "in") {
        setAmountOutMin(trades[0].minimumAmountOut(slippageTolerance));
      } else if (exact === "out") {
        setAmountInMax(trades[0].maximumAmountIn(slippageTolerance));
      }
    }
  }, [slippageTolerance, amountIn, amountOut, trades]);

  const getBalance = async (_token, _account, _contract) => {
    let newBalance;
    if (_token === "ETH") {
      newBalance = await selectedProvider.getBalance(_account);
    } else {
      newBalance = await makeCall("balanceOf", _contract, [_account]);
    }
    return newBalance;
  };

  const getAccountInfo = async () => {
    if (tokens) {
      const accountList = await selectedProvider.listAccounts();

      if (tokenIn) {
        const tempContractIn = new ethers.Contract(tokens[tokenIn].address, erc20Abi, selectedProvider);
        const newBalanceIn = await getBalance(tokenIn, accountList[0], tempContractIn);
        setBalanceIn(newBalanceIn);

        let allowance;

        if (tokenIn === "ETH") {
          setRouterAllowance();
        } else {
          allowance = await makeCall("allowance", tempContractIn, [accountList[0], ROUTER_ADDRESS]);
          setRouterAllowance(allowance);
        }
      }

      if (tokenOut) {
        const tempContractOut = new ethers.Contract(tokens[tokenOut].address, erc20Abi, selectedProvider);
        const newBalanceOut = await getBalance(tokenOut, accountList[0], tempContractOut);
        setBalanceOut(newBalanceOut);
      }
    }
  };

  usePoller(getAccountInfo, 6000);

  const route = trades
    ? trades.length > 0
      ? trades[0].route.path.map(function (item) {
          return item.symbol;
        })
      : []
    : [];

  const updateRouterAllowance = async newAllowance => {
    setApproving(true);
    try {
      const tempContract = new ethers.Contract(tokens[tokenIn].address, erc20Abi, signer);
      const result = await makeCall("approve", tempContract, [ROUTER_ADDRESS, newAllowance]);
      console.log(result);
      setApproving(false);
      return true;
    } catch (e) {
      notification.open({
        message: "Approval unsuccessful",
        description: `Error: ${e.message}`,
      });
    }
  };

  const approveRouter = async () => {
    const approvalAmount =
      exact === "in"
        ? ethers.utils.hexlify(parseUnits(amountIn.toString(), tokens[tokenIn].decimals))
        : amountInMax.raw.toString();
    console.log(approvalAmount);
    const approval = updateRouterAllowance(approvalAmount);
    if (approval) {
      notification.open({
        message: "Token transfer approved",
        description: `You can now swap up to ${amountIn} ${tokenIn}`,
      });
    }
  };

  const removeRouterAllowance = async () => {
    const approvalAmount = ethers.utils.hexlify(0);
    console.log(approvalAmount);
    const removal = updateRouterAllowance(approvalAmount);
    if (removal) {
      notification.open({
        message: "Token approval removed",
        description: `The router is no longer approved for ${tokenIn}`,
      });
    }
  };

  const executeSwap = async () => {
    setSwapping(true);
    try {
      let args;
      const metadata = {};

      let call;
      const deadline = Math.floor(Date.now() / 1000) + timeLimit;
      const path = trades[0].route.path.map(function (item) {
        return item.address;
      });
      console.log(path);
      const accountList = await selectedProvider.listAccounts();
      const address = accountList[0];

      if (exact === "in") {
        const _amountIn = ethers.utils.hexlify(parseUnits(amountIn.toString(), tokens[tokenIn].decimals));
        const _amountOutMin = ethers.utils.hexlify(ethers.BigNumber.from(amountOutMin.raw.toString()));
        if (tokenIn === "ETH") {
          call = "swapExactETHForTokens";
          args = [_amountOutMin, path, address, deadline];
          metadata.value = _amountIn;
        } else {
          call = tokenOut === "ETH" ? "swapExactTokensForETH" : "swapExactTokensForTokens";
          args = [_amountIn, _amountOutMin, path, address, deadline];
        }
      } else if (exact === "out") {
        const _amountOut = ethers.utils.hexlify(parseUnits(amountOut.toString(), tokens[tokenOut].decimals));
        const _amountInMax = ethers.utils.hexlify(ethers.BigNumber.from(amountInMax.raw.toString()));
        if (tokenIn === "ETH") {
          call = "swapETHForExactTokens";
          args = [_amountOut, path, address, deadline];
          metadata.value = _amountInMax;
        } else {
          call = tokenOut === "ETH" ? "swapTokensForExactETH" : "swapTokensForExactTokens";
          args = [_amountOut, _amountInMax, path, address, deadline];
        }
      }
      console.log(call, args, metadata);
      const result = await makeCall(call, routerContract, args, metadata);
      console.log(result);
      notification.open({
        message: "Swap complete ?",
        description: (
          <>
            <Text>{`Swapped ${tokenIn} for ${tokenOut}, transaction: `}</Text>
            <Text copyable>{result.hash}</Text>
          </>
        ),
      });
      setSwapping(false);
    } catch (e) {
      console.log(e);
      setSwapping(false);
      notification.open({
        message: "Swap unsuccessful",
        description: `Error: ${e.message}`,
      });
    }
  };

  const showSwapModal = () => {
    setSwapModalVisible(true);
  };

  const handleSwapModalOk = () => {
    setSwapModalVisible(false);
    executeSwap();
  };

  const handleSwapModalCancel = () => {
    setSwapModalVisible(false);
  };

  const insufficientBalance = balanceIn
    ? parseFloat(formatUnits(balanceIn, tokens[tokenIn].decimals)) < amountIn
    : null;
  const inputIsToken = tokenIn !== "ETH";
  const insufficientAllowance = !inputIsToken
    ? false
    : routerAllowance
    ? parseFloat(formatUnits(routerAllowance, tokens[tokenIn].decimals)) < amountIn
    : null;
  const formattedBalanceIn = balanceIn
    ? parseFloat(formatUnits(balanceIn, tokens[tokenIn].decimals)).toPrecision(6)
    : null;
  const formattedBalanceOut = balanceOut
    ? parseFloat(formatUnits(balanceOut, tokens[tokenOut].decimals)).toPrecision(6)
    : null;

  const metaIn =
    tokens && tokenList && tokenIn
      ? tokenList.filter(function (t) {
          return t.address === tokens[tokenIn].address;
        })[0]
      : null;
  const metaOut =
    tokens && tokenList && tokenOut
      ? tokenList.filter(function (t) {
          return t.address === tokens[tokenOut].address;
        })[0]
      : null;

  const cleanIpfsURI = uri => {
    try {
      return uri.replace("ipfs://", "https://ipfs.io/ipfs/");
    } catch (e) {
      console.log(e, uri);
      return uri;
    }
  };

  const logoIn = metaIn ? cleanIpfsURI(metaIn.logoURI) : null;
  const logoOut = metaOut ? cleanIpfsURI(metaOut.logoURI) : null;

  const rawPrice = trades && trades[0] ? trades[0].executionPrice : null;
  const price = rawPrice ? rawPrice.toSignificant(7) : null;
  const priceDescription = rawPrice
    ? invertPrice
      ? `${rawPrice.invert().toSignificant(7)} ${tokenIn} per ${tokenOut}`
      : `${price} ${tokenOut} per ${tokenIn}`
    : null;

  const priceWidget = (
    <Space>
      <Text type="secondary">{priceDescription}</Text>
      <Button
        type="text"
        onClick={() => {
          setInvertPrice(!invertPrice);
        }}
      >
        <RetweetOutlined />
      </Button>
    </Space>
  );

  const swapModal = (
    <Modal title="Confirm swap" visible={swapModalVisible} onOk={handleSwapModalOk} onCancel={handleSwapModalCancel}>
      <Row>
        <Space>
          <img src={logoIn} alt={tokenIn} width="30" />
          {amountIn}
          {tokenIn}
        </Space>
      </Row>
      <Row justify="center" align="middle" style={{ width: 30 }}>
        <span>↓</span>
      </Row>
      <Row>
        <Space>
          <img src={logoOut} alt={tokenOut} width="30" />
          {amountOut}
          {tokenOut}
        </Space>
      </Row>
      <Divider />
      <Row>{priceWidget}</Row>
      <Row>
        {trades && ((amountOutMin && exact === "in") || (amountInMax && exact === "out"))
          ? exact === "in"
            ? `Output is estimated. You will receive at least ${amountOutMin.toSignificant(
                6,
              )} ${tokenOut} or the transaction will revert.`
            : `Input is estimated. You will sell at most ${amountInMax.toSignificant(
                6,
              )} ${tokenIn} or the transaction will revert.`
          : null}
      </Row>
    </Modal>
  );

  return (
    <Card
      title={
        <Space>
          <img src="https://ipfs.io/ipfs/QmXttGpZrECX5qCyXbBQiqgQNytVGeZW5Anewvh2jc4psg" width="40" alt="uniswapLogo" />
          <Typography>Uniswapper</Typography>
        </Space>
      }
      extra={
        <Button
          type="text"
          onClick={() => {
            setSettingsVisible(true);
          }}
        >
          <SettingOutlined />
        </Button>
      }
    >
      <Space direction="vertical">
        <Row justify="center" align="middle">
          <Card
            size="small"
            type="inner"
            title={`From${exact === "out" && tokenIn && tokenOut ? " (estimate)" : ""}`}
            extra={
              <>
                <img src={logoIn} alt={tokenIn} width="30" />
                <Button
                  type="link"
                  onClick={() => {
                    setAmountOut();
                    setAmountIn(formatUnits(balanceIn, tokens[tokenIn].decimals));
                    setAmountOutMin();
                    setAmountInMax();
                    setExact("in");
                  }}
                >
                  {formattedBalanceIn}
                </Button>
              </>
            }
            style={{ width: 400, textAlign: "left" }}
          >
            <InputNumber
              style={{ width: "160px" }}
              min={0}
              size="large"
              value={amountIn}
              onChange={e => {
                setAmountOut();
                setTrades();
                setAmountIn(e);
                setExact("in");
              }}
            />
            <Select
              showSearch
              value={tokenIn}
              style={{ width: "120px" }}
              size="large"
              bordered={false}
              defaultValue={defaultToken}
              onChange={value => {
                console.log(value);
                if (value === tokenOut) {
                  console.log("switch!", tokenIn);
                  setTokenOut(tokenIn);
                  setAmountOut(amountIn);
                  setBalanceOut(balanceIn);
                }
                setTokenIn(value);
                setTrades();
                setAmountIn();
                setExact("out");
                setBalanceIn();
              }}
              filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
              optionFilterProp="children"
            >
              {tokenList.map(token => (
                <Option key={token.symbol} value={token.symbol}>
                  {token.symbol}
                </Option>
              ))}
            </Select>
          </Card>
        </Row>
        <Row justify="center" align="middle">
          <Tooltip title={route.join("->")}>
            <span>↓</span>
          </Tooltip>
        </Row>
        <Row justify="center" align="middle">
          <Card
            size="small"
            type="inner"
            title={`To${exact === "in" && tokenIn && tokenOut ? " (estimate)" : ""}`}
            extra={
              <>
                <img src={logoOut} width="30" alt={tokenOut} />
                <Button type="text">{formattedBalanceOut}</Button>
              </>
            }
            style={{ width: 400, textAlign: "left" }}
          >
            <InputNumber
              style={{ width: "160px" }}
              size="large"
              min={0}
              value={amountOut}
              onChange={e => {
                setAmountOut(e);
                setAmountIn();
                setTrades();
                setExact("out");
              }}
            />
            <Select
              showSearch
              value={tokenOut}
              style={{ width: "120px" }}
              size="large"
              bordered={false}
              onChange={value => {
                console.log(value, tokenIn, tokenOut);
                if (value === tokenIn) {
                  console.log("switch!", tokenOut);
                  setTokenIn(tokenOut);
                  setAmountIn(amountOut);
                  setBalanceIn(balanceOut);
                }
                setTokenOut(value);
                setExact("in");
                setAmountOut();
                setTrades();
                setBalanceOut();
              }}
              filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
              optionFilterProp="children"
            >
              {tokenList.map(token => (
                <Option key={token.symbol} value={token.symbol}>
                  {token.symbol}
                </Option>
              ))}
            </Select>
          </Card>
        </Row>
        <Row justify="center" align="middle">
          {priceDescription ? priceWidget : null}
        </Row>
        <Row justify="center" align="middle">
          <Space>
            {inputIsToken ? (
              <Button size="large" loading={approving} disabled={!insufficientAllowance} onClick={approveRouter}>
                {!insufficientAllowance && amountIn && amountOut ? "Approved" : "Approve"}
              </Button>
            ) : null}
            <Button
              size="large"
              loading={swapping}
              disabled={insufficientAllowance || insufficientBalance || !amountIn || !amountOut}
              onClick={showSwapModal}
            >
              {insufficientBalance ? "Insufficient balance" : "Swap!"}
            </Button>
            {swapModal}
          </Space>
        </Row>
      </Space>
      <Drawer
        visible={settingsVisible}
        onClose={() => {
          setSettingsVisible(false);
        }}
        width={500}
      >
        <Descriptions title="Details" column={1} style={{ textAlign: "left" }}>
          <Descriptions.Item label="blockNumber">{blockNumber}</Descriptions.Item>
          <Descriptions.Item label="routerAllowance">
            <Space>
              {routerAllowance ? formatUnits(routerAllowance, tokens[tokenIn].decimals) : null}
              {routerAllowance > 0 ? <Button onClick={removeRouterAllowance}>Remove Allowance</Button> : null}
            </Space>
          </Descriptions.Item>
          <Descriptions.Item label="route">{route.join("->")}</Descriptions.Item>
          <Descriptions.Item label="exact">{exact}</Descriptions.Item>
          <Descriptions.Item label="bestPrice">
            {trades ? (trades.length > 0 ? trades[0].executionPrice.toSignificant(6) : null) : null}
          </Descriptions.Item>
          <Descriptions.Item label="nextMidPrice">
            {trades ? (trades.length > 0 ? trades[0].nextMidPrice.toSignificant(6) : null) : null}
          </Descriptions.Item>
          <Descriptions.Item label="priceImpact">
            {trades ? (trades.length > 0 ? trades[0].priceImpact.toSignificant(6) : null) : null}
          </Descriptions.Item>
          <Descriptions.Item label="slippageTolerance">
            <InputNumber
              defaultValue={defaultSlippage}
              min={0}
              max={100}
              precision={2}
              formatter={value => `${value}%`}
              parser={value => value.replace("%", "")}
              onChange={value => {
                console.log(value);

                const slippagePercent = new Percent(Math.round(value * 100).toString(), "10000");
                setSlippageTolerance(slippagePercent);
              }}
            />
          </Descriptions.Item>
          <Descriptions.Item label="amountInMax">{amountInMax ? amountInMax.toExact() : null}</Descriptions.Item>
          <Descriptions.Item label="amountOutMin">{amountOutMin ? amountOutMin.toExact() : null}</Descriptions.Item>
          <Descriptions.Item label="timeLimitInSeconds">
            <InputNumber
              min={0}
              max={3600}
              defaultValue={defaultTimeLimit}
              onChange={value => {
                console.log(value);
                setTimeLimit(value);
              }}
            />
          </Descriptions.Item>
        </Descriptions>
      </Drawer>
    </Card>
  );
}