antd#Space JavaScript Examples

The following examples show how to use antd#Space. 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: Loader.js    From Cowin-Notification-System with MIT License 6 votes vote down vote up
Loader = (props) => {
  return (
    <div className='center' style={props.style || {}}>
      <Space size="middle" className='center'>
        <Spin size="large" />
      </Space>
    </div>
  )
}
Example #3
Source File: SelectWalletModal.js    From bonded-stablecoin-ui with MIT License 6 votes vote down vote up
SelectWalletModal = ({ visible, onCancel }) => {
  const { t } = useTranslation();
  return (
    <Modal
      visible={visible}
      onCancel={onCancel}
      title={t("modals.select_wallet.title", "Select wallet")}
      footer={
        <Space>
          <Button key="Cancel" onClick={onCancel}>
            {t("modals.common.done", "Done")}
          </Button>
        </Space>
      }
    >
      <SelectWallet width="100%" size="large" />
    </Modal>
  );
}
Example #4
Source File: MySkeleton.jsx    From react-sendbird-messenger with GNU General Public License v3.0 6 votes vote down vote up
export function MySkeleton({
    loading = false,
    rows = 1,
    children,
    size = 'default',
    avatar,
    avatarShape = 'circle',
}) {
    if (loading) {
        return [...Array(rows).keys()].map((i) => (
            <Fragment key={i}>
                <Space style={{ padding: 12, height: 60 }}>
                    {!!avatar && (
                        <Skeleton.Avatar
                            active={true}
                            size={size}
                            shape={avatarShape}
                        />
                    )}
                    <Skeleton.Input
                        style={{ minWidth: 308, width: 355 }}
                        active={true}
                        size={size}
                    />
                </Space>
            </Fragment>
        ))
    }

    return children
}
Example #5
Source File: Header.jsx    From ui with MIT License 6 votes vote down vote up
Header = (props) => {
  const {
    experimentId, experimentData, title, extra,
  } = props;
  const experiment = useSelector((state) => state?.experiments[experimentId]);
  const experimentName = experimentData?.experimentName || experiment?.name;

  const truncateText = (text) => (
    (text && text.length > 28) ? `${text.substr(0, 27)}…` : text
  );

  return (
    <>
      <NextSeo
        title={experimentData ? `${title} · ${truncateText(experimentName)}` : title}
      />

      <PageHeader
        className={integrationTestConstants.classes.PAGE_HEADER}
        title={title}
        style={{ width: '100%', paddingTop: '10px', paddingBottom: '10px' }}
        extra={(
          <Space size='large'>
            <Space>
              <HelpButton />
              <FeedbackButton />
              <ReferralButton />
              {extra}
            </Space>
            <UserButton />
          </Space>
        )}
      />
    </>
  );
}
Example #6
Source File: Footer.js    From 4IZ268-2021-2022-ZS with MIT License 6 votes vote down vote up
Footer = () => {
    return (
        <div className={'footer-container'}>
            <img width={164} height={50} src={logo} alt='Logo SKOB'/>
            <Space direction='vertical' style={{ justifyContent: 'flex-end' }}>
                <Space>
                    <Text italic>Follow: </Text>
                    <a href='https://www.facebook.com/skobroudnice' target='_blank' rel="noreferrer">
                        <FacebookOutlined style={{ fontSize: '1.5rem' }} />
                    </a>
                    <a href='https://obroudnice.cz/' target='_blank' rel="noreferrer">
                        <ChromeOutlined style={{ fontSize: '1.5rem' }} />
                    </a>
                </Space>
                <Text italic>Design made by &copy; <a href='mailto: [email protected]'>Petr Buk</a></Text>
            </Space>
        </div>
    )
}
Example #7
Source File: index.js    From quick_redis_blog with MIT License 6 votes vote down vote up
render() {
        return (
            <div>
                <Row>
                    <Space direction="vertical" style={{ width: "100%" }}>
                        <Col span={24}>
                            <Space direction="horizontal">
                                <Button onClick={this.formatJson.bind(this)}>
                                    {intl.get("QuickMonacoEditor.format")}
                                </Button>
                                <Button onClick={this.delBlankJson.bind(this)}>
                                    {intl.get("QuickMonacoEditor.delformat")}
                                </Button>
                            </Space>
                        </Col>
                        <Col span={24}>
                            <div style={{ border: "1px solid #eee" }}>
                                <MonacoEditor
                                    ref="monacoEditor"
                                    height={this.props.height}
                                    language="json"
                                    theme="vs"
                                    value={this.props.value}
                                    defaultValue=""
                                    options={this.MONACO_EDITOR_OPTIONS}
                                    onChange={(value) => {
                                        this.props.onChange(value);
                                    }}
                                    editorDidMount={this.editorDidMount.bind(
                                        this
                                    )}
                                />
                            </div>
                        </Col>
                    </Space>
                </Row>
            </div>
        );
    }
Example #8
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 #9
Source File: no-wrapper.jsx    From virtuoso-design-system with MIT License 6 votes vote down vote up
Demo = () => {
  const [show, setShow] = React.useState(true);

  return (
    <Space>
      <Switch
        checked={show}
        onChange={() => {
          setShow(!show);
        }}
      />
      <Badge count={show ? 25 : 0} />
      <Badge count={show ? <ClockCircleOutlined style={{ color: '#f5222d' }} /> : 0} />
      <Badge count={show ? 4 : 0} className="site-badge-count-4" />
      <Badge
        className="site-badge-count-109"
        count={show ? 109 : 0}
        style={{ backgroundColor: '#52c41a' }}
      />
    </Space>
  );
}
Example #10
Source File: adminUsers.js    From ctf_platform with MIT License 5 votes vote down vote up
SelectParticipantCategoryForm = (props) => {
    const [form] = Form.useForm();
    const [loading, setLoading] = React.useState(false);
    const [options, setOptions] = React.useState("")

    useEffect(() => {
        let optionList = props.categoryList.map((currentCat) => {
            return <Radio value={currentCat}>{currentCat}</Radio>
        })
        optionList.push(<Radio value="none"><b>No Category</b></Radio>)
        setOptions(optionList)
        form.setFieldsValue({ category: props.participantCategory })

    }, [props.username])

    return (
        <Form
            form={form}
            onFinish={async (values) => {
                setLoading(true)
                await fetch(window.ipAddress + "/v1/account/change/category", {
                    method: 'post',
                    headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
                    body: JSON.stringify({
                        "username": props.username,
                        "category": values.category,
                    })
                }).then((results) => {
                    return results.json(); //return data in JSON (since its JSON data)
                }).then((data) => {
                    if (data.success === true) {
                        message.success({ content: "Category for '" + props.username + "' successfully changed to '" + values.category + "'." })
                        form.setFieldsValue({
                            category: values.category
                        })
                        props.fillTableData()
                    }
                    else if (data.error === "email-taken") {
                        message.error({ content: "Email is already taken, please try another email." })
                    }
                    else if (data.error === "wrong-password") {
                        message.error({ content: "Password is incorrect. Please try again." })
                    }
                    else if (data.error === "switching-disabled") {
                        message.error("Category switching is currently disabled by the admins.")
                    }
                    else {
                        message.error({ content: "Oops. Unknown error." })
                    }

                }).catch((error) => {
                    console.log(error)
                    message.error({ content: "Oops. There was an issue connecting with the server" });
                })
                setLoading(false)
            }}
            style={{ display: "flex", flexDirection: "column", justifyContent: "center", width: "100%", marginBottom: "2vh" }}
        >

            <h3>Category:</h3>
            <Form.Item
                name="category"
                rules={[{ required: true, message: 'Please select a category', }]}>

                <Radio.Group>
                    <Space direction="vertical">
                        {options}
                    </Space>
                </Radio.Group>
            </Form.Item>
            <span>Select a category to compete and be eligible for prizes of that category. Verification will be required after the CTF before claiming your prizes.</span>

            <Form.Item>
                <Button type="primary" htmlType="submit" icon={<ApartmentOutlined />} loading={loading} style={{ marginTop: "2ch" }}>Change Category</Button>
            </Form.Item>
        </Form>
    );
}
Example #11
Source File: index.js    From QiskitFlow with Apache License 2.0 5 votes vote down vote up
expandedRowRender(experiment) {
    let runs = experiment.runs.map((run, i) => {
      return {
        key: i,
        date: run.created_at,
        name: run.uuid,
        operation: run
      }
    })

    const runColumns = [
      { title: 'Date', dataIndex: 'date', key: 'date' },
      { title: 'Run', dataIndex: 'name', key: 'name' },
      {
        title: 'Status',
        key: 'state',
        render: () => (
          <span>
            <Badge status="success" />
            Finished
          </span>
        ),
      },
      { title: 'Tags', dataIndex: 'tags', key: 'tags', render: () => <Tag>Qiskit</Tag> },
      {
        title: 'Action',
        dataIndex: 'operation',
        key: 'operation',
        render: (run) => (
          <Space size="middle">
            <a onClick={() => {
              this.setState({...this.state, run: run})
            }}>View</a>
            <a>Rerun</a>
          </Space>
        ),
      },
    ];
  
    return <Table 
                columns={runColumns}
                dataSource={runs} 
                pagination={false} />;
  }
Example #12
Source File: MessageSkeleton.jsx    From react-sendbird-messenger with GNU General Public License v3.0 5 votes vote down vote up
export function MessageSkeleton({
    loading = false,
    rows = 1,
    children,
    size = 'default',
    avatar,
    avatarShape = 'circle',
}) {
    if (loading) {
        return [...Array(rows).keys()].map((i) => (
            <Fragment key={i}>
                <div
                    style={{
                        width: '100%',
                        display: 'flex',
                        justifyContent: i % 2 === 0 && 'flex-end',
                    }}
                >
                    <Space
                        style={{
                            padding: 12,
                            height: 60,
                            flexDirection: i % 2 === 0 && 'row-reverse',
                        }}
                    >
                        {!!avatar && (
                            <Skeleton.Avatar
                                style={{
                                    marginLeft: i % 2 === 0 && 8,
                                }}
                                active={true}
                                size={size}
                                shape={avatarShape}
                            />
                        )}
                        <Skeleton.Input
                            style={{ minWidth: 308, width: 355 }}
                            active={true}
                            size={size}
                        />
                    </Space>
                </div>
            </Fragment>
        ))
    }

    return children
}
Example #13
Source File: Edit.js    From Peppermint with GNU General Public License v3.0 5 votes vote down vote up
Edit = (props) => {
  const [visible, setVisible] = useState(false);
  const [isActive, setIsActive] = useState(props.n.active);
  const [title, setTitle] = useState(props.n.title);
  const [text, setText] = useState(props.n.text);

  const onClose = async (e) => {
    e.stopPropagation();
    setVisible(false);
    await postData();
  };

  const postData = async () => {
    await fetch(`/api/v1/newsletter/update`, {
      method: "PUT",
      headers: {
        "Content-Type": "application/json",
        Authorization: "Bearer " + localStorage.getItem("jwt"),
      },
      body: JSON.stringify({
        id: props.n._id,
        text,
        title,
        active: isActive,
      }),
    }).then((res) => res.json());
  };

  return (
    <div>
      <Button onClick={() => setVisible(true)}>
        Edit
        <Drawer
          width={640}
          placement="right"
          onClose={onClose}
          visible={visible}
        >
          <h4>Active : {props.n.active.toString()}</h4>
          <h4>Created By : {props.n.createdBy.name}</h4>
          <Divider />
          <h4>
            Title :{" "}
            <Input
              style={{ width: 300 }}
              onChange={(e) => setTitle(e.target.value)}
            />
          </h4>
          <Divider />
          <h5>Detail</h5>
          <Input.TextArea
            defaultValue={props.n.text}
            rows={10}
            onChange={(e) => setText(e.target.value)}
          />
          <Divider />
          <h5>Select the button below to change visability </h5>
          <Radio.Group
            buttonStyle="solid"
            value={isActive}
            onChange={(e) => setIsActive(e.target.value)}
            style={{ textAlign: "center" }}
          >
            <Space>
              <Radio.Button value={true}>Active</Radio.Button>
              <Radio.Button value={false}>Hidden</Radio.Button>
            </Space>
          </Radio.Group>
        </Drawer>
      </Button>
    </div>
  );
}
Example #14
Source File: ExampleExperimentsSpace.jsx    From ui with MIT License 5 votes vote down vote up
ExampleExperimentsSpace = ({ introductionText, imageStyle }) => {
  const dispatch = useDispatch();

  const environment = useSelector((state) => state?.networkResources?.environment);

  const [exampleExperiments, setExampleExperiments] = useState([]);

  useEffect(() => {
    if (!environment) return;

    fetchAPI('/v2/experiments/examples').then((experiments) => {
      setExampleExperiments(experiments);
    }).catch(() => { });
  }, [environment]);

  const cloneIntoCurrentExperiment = async (exampleExperimentId) => {
    const url = `/v2/experiments/${exampleExperimentId}/clone`;

    const newExperimentId = await fetchAPI(
      url,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
      },
    );

    await dispatch(loadExperiments());
    await dispatch(setActiveExperiment(newExperimentId));
  };

  return (
    <Empty
      imageStyle={imageStyle}
      description={(
        <Space size='middle' direction='vertical'>
          <Paragraph>
            {introductionText}
          </Paragraph>
          {
            exampleExperiments.length > 0 && (
              <>
                <Text>
                  Don&apos;t have data? Get started using one of our example datasets:
                </Text>
                <div style={{ width: 'auto', textAlign: 'left' }}>
                  <ul>
                    {
                      exampleExperiments.map(({ id, name }) => (
                        <li key={name}>
                          <Button
                            type='link'
                            size='small'
                            onClick={() => cloneIntoCurrentExperiment(id)}
                          >
                            {name}
                          </Button>
                        </li>
                      ))
                    }
                  </ul>
                </div>
              </>
            )
          }
        </Space>
      )}
    />
  );
}
Example #15
Source File: Backup.js    From network-rc with Apache License 2.0 5 votes vote down vote up
export default function Backup({
  serverConfig,
  resetServerConfig,
  saveServerConfig,
  updateVersion,
  updateStaus,
}) {
  const save = () => {
    var blob = new Blob([JSON.stringify(serverConfig)], {
      type: "text/plain;charset=utf-8",
    });
    saveAs(
      blob,
      `network-rc-config-backgup-${dayjs().format("YYYYMMDDTHHmmss")}.json`
    );
  };
  const load = (file) => {
    var reader = new FileReader();
    reader.onload = function (e) {
      if (reader.result) {
        saveServerConfig(JSON.parse(reader.result));
      }
    };
    reader.onerror = function (e) {
      console.error(e);
      message.error("读取备份错误");
    };

    reader.readAsText(file);
    return false;
  };
  return (
    <Form {...layout}>
      <Form.Item>
        <Space>
          <Button icon={<DownloadOutlined />} type="primary" onClick={save}>
            备份当前设置
          </Button>
          <Upload accept=".json" beforeUpload={load} showUploadList={false}>
            <Button icon={<UploadOutlined />}>恢复已保存的设置</Button>
          </Upload>

          <Button icon={<ReloadOutlined />} danger onClick={resetServerConfig}>
            恢复默认设置(所有设置)
          </Button>
        </Space>
      </Form.Item>

      <Form.Item >
        <Button
          onClick={(e) => {
            e.preventDefault();
            updateVersion();
          }}
          loading={updateStaus ? true : false}
        >
          {updateStaus || "更新版本"}
        </Button>
      </Form.Item>
    </Form>
  );
}
Example #16
Source File: Card.jsx    From open-source with MIT License 5 votes vote down vote up
IconText = ({ icon, text }) => (
  <Space>
    {React.createElement(icon)}
    {text}
  </Space>
)
Example #17
Source File: index.js    From ant-simple-pro with MIT License 5 votes vote down vote up
Globalization = memo(function Globalization(props) {
  const { t, i18n } = useTranslation();

  let listData = [];

  for (let i = 0; i < 3; i++) {
    listData.push({
      index: i,
      title: `Ant Simple Pro`,
      avatar: <SvgIcon iconClass='logon' fontSize='30px' />,
      description: t('description'),
      content: t('content')
    });
  }

  const IconText = ({ icon, text }) => (
    <Space>
      {React.createElement(icon)}
      {text}
    </Space>
  );

  const change = (val) => {
    const lang = val.target.value;
    i18n.changeLanguage(lang);
  }

  return (
    <div className='bgW padding-10px'>
      <div>
        <Radio.Group defaultValue="en" buttonStyle="solid" onChange={change}>
          <Radio.Button value="en">英文</Radio.Button>
          <Radio.Button value="zh">中文</Radio.Button>
          <Radio.Button value="ja">日文</Radio.Button>
        </Radio.Group>
        <a href="https://react.i18next.com/" style={{ padding: '0 10px' }} target='_blank'>了解过多react-i18next信息</a>
      </div>
      <List
        itemLayout="vertical"
        size="large"
        dataSource={listData}
        renderItem={item => (
          <List.Item
            key={item.index}
            actions={[
              <IconText icon={StarOutlined} text="156" key="list-vertical-star-o" />,
              <IconText icon={LikeOutlined} text="156" key="list-vertical-like-o" />,
              <IconText icon={MessageOutlined} text="2" key="list-vertical-message" />,
            ]}
            extra={
              <img
                width={272}
                alt="logo"
                src="https://gw.alipayobjects.com/zos/rmsportal/mqaQswcyDLcXyDKnZfES.png"
              />
            }
          >
            <List.Item.Meta
              avatar={item.avatar}
              title={<a href={item.href}>{item.title}</a>}
              description={item.description}
            />
            {item.content}
          </List.Item>
        )}
      />
    </div>
  )
})
Example #18
Source File: index.js    From quick_redis_blog with MIT License 5 votes vote down vote up
render() {
        return (
            <div>
                <Form initialValues={{ ...this.initValues }} ref="form">
                    <Row gutter={8}>
                        <Col span={14}>
                            <Form.Item
                                name="redisKey"
                                rules={[
                                    {
                                        required: true,
                                    },
                                ]}
                                style={{ marginBottom: "1px" }}
                            >
                                <Search
                                    prefix="key :"
                                    enterButton={
                                        <Button
                                            icon={<EditOutlined />}
                                        ></Button>
                                    }
                                    size="middle"
                                    onSearch={this.renameKey.bind(this)}
                                />
                            </Form.Item>
                        </Col>
                        <Col span={5}>
                            <Form.Item
                                name="ttl"
                                rules={[
                                    {
                                        required: true,
                                    },
                                ]}
                                style={{ marginBottom: "1px" }}
                            >
                                <Search
                                    prefix="ttl :"
                                    enterButton={
                                        <Button
                                            icon={<EditOutlined />}
                                        ></Button>
                                    }
                                    size="middle"
                                    onSearch={this.updateTtl.bind(this)}
                                />
                            </Form.Item>
                        </Col>
                        <Col span={5}>
                            <Space>
                                <Form.Item style={{ marginBottom: "1px" }}>
                                    <Popconfirm
                                        title={intl.get(
                                            "HostKey.header.key.delete.notice"
                                        )}
                                        onConfirm={() => {
                                            this.deleteKey();
                                        }}
                                    >
                                        <Button
                                            icon={<DeleteOutlined />}
                                        ></Button>
                                    </Popconfirm>
                                </Form.Item>
                                <Form.Item style={{ marginBottom: "1px" }}>
                                    <Button
                                        icon={<ReloadOutlined />}
                                        onClick={this.refreshAll.bind(this)}
                                    ></Button>
                                </Form.Item>
                            </Space>
                        </Col>
                    </Row>
                </Form>
            </div>
        );
    }
Example #19
Source File: settings.js    From hashcat.launcher with MIT License 5 votes vote down vote up
render() {
		return (
			<>
				<PageHeader
					title="Settings"
				/>
				<Content style={{ padding: '16px 24px' }}>
					<Row gutter={[16, 14]}>
						<Col span={12}>
							<Statistic title="Hashes" value={this.state._hashes.length} />
						</Col>
						<Col span={12}>
							<Statistic title="Algorithms" value={Object.keys(this.state._algorithms).length} />
						</Col>
						<Col span={12}>
							<Statistic title="Dictionaries" value={this.state._dictionaries.length} />
						</Col>
						<Col span={12}>
							<Statistic title="Rules" value={this.state._rules.length} />
						</Col>
						<Col span={12}>
							<Statistic title="Masks" value={this.state._masks.length} />
						</Col>
						<Col span={24}>
							<Button
								icon={<SyncOutlined />}
								type="primary"
								onClick={this.onClickRescan}
								loading={this.state.isLoadingRescan}
							>
								Rescan
							</Button>
						</Col>
					</Row>
					<Row style={{ marginTop: "2rem" }} gutter={[16, 14]}>
						<Col span={24}>
							<Statistic
								title="Task counter"
								value={this.state.taskCounter}
							/>
							<Space>
							<Button
								style={{ marginTop: 16 }}
								type="default"
								onClick={this.onClickRefreshTaskCounter}
								loading={this.state.isLoadingRefreshTaskCounter}
							>
								Refresh
							</Button>
							<Popconfirm
								placement="topRight"
								title="Are you sure you want to reset the task counter?"
								onConfirm={this.onClickResetTaskCounter}
								okText="Yes"
								cancelText="No"
							>
								<Button
									style={{ marginTop: 16 }}
									type="danger"
									loading={this.state.isLoadingResetTaskCounter}
								>
									Reset counter
								</Button>
							</Popconfirm>
							</Space>
						</Col>
					</Row>
				</Content>
			</>
		)
	}
Example #20
Source File: certificateApprove.js    From credit with Apache License 2.0 5 votes vote down vote up
render() {
        const data1 = [{
            hash: randomHash(),
            addr : "0x8a0Bc5Db7E852d0A3184A03AEA525Ef91FbEB5fE",
            time: mockTime(1000000),
            name: "David"
        }]
        const columns1 = [
            {
                title: '交易哈希',
                dataIndex: 'hash',
                key: 'hash',
                render: text => {
                    if (text.length > 18) {
                        return <a>{text.substr(0, 18) + '...'}</a>
                    }
                },
            },
            {
                title: '申请方地址',
                dataIndex: 'addr',
                key: 'addr',
                render: text => {
                    if (text.length > 18) {
                        return <a>{text.substr(0, 18) + '...'}</a>
                    }
                },
            },
            {
                title: '用户名',
                dataIndex: 'name',
                key: 'name',
            },
            {
                title: '请求时间',
                dataIndex: 'time',
                key: 'time',
            },
            {
                title: '操作',
                key: 'action',
                render: (text, record) => (
                    <Space size="middle">
                        <Button type="primary">发布证书</Button>
                    </Space>
                ),
            },
        ];
        
        return (
            <div>
                <Card title="签发证书"  style={{width:1200}}>
                <Table columns={columns1} dataSource={data1} pagination={{ pageSize: 5 }} />
                </Card>
            </div>
        )
    }
Example #21
Source File: mode.jsx    From virtuoso-design-system with MIT License 5 votes vote down vote up
storiesOf('antd/date-picker', module).add('mode', () => 
  <Space direction="vertical" size={12}>
    <ControlledDatePicker />
    <ControlledRangePicker />
  </Space>,
  { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Determing which panel to show with <code>mode</code> and <code>onPanelChange</code>.</p></>) } });
Example #22
Source File: QuestionGen.js    From official-website-backend with MIT License 4 votes vote down vote up
QuestionGen = ({ onRemove, id }) => {
  const { TextArea } = Input;

  const makeAnswerField = (t) => {
    if (t === "TextArea")
      return (
        <Form.Item
          label="Placeholder ::"
          name={`field_${id}_placeholder`}
          rules={[
            {
              required: true,
              message: "field required",
            },
          ]}
        >
          <TextArea
            style={{ maxWidth: "60%" }}
            rows={4}
            placeholder="write a placeholder"
          />
        </Form.Item>
      );
    if (t === "Selection")
      return (
        <Form.List name={`field_${id}_selection`}>
          {(fields, { add, remove }) => (
            <>
              {fields.map(({ key, name, fieldKey, ...restField }, index) => (
                <Space
                  key={key}
                  style={{ display: "flex", marginBottom: 8 }}
                  align="baseline"
                >
                  <Form.Item
                    {...restField}
                    name={[name, `selectionItem_${key}`]}
                    fieldKey={[fieldKey, `selectionItem_${key}`]}
                    label={`Option #${index + 1}`}
                    rules={[
                      { required: true, message: "Missing Selection Item" },
                    ]}
                  >
                    <Input
                      placeholder="write a Selection Item"
                      style={{ marginLeft: "1em" }}
                    />
                  </Form.Item>
                  <span
                    className="menu-close"
                    onClick={() => remove(name)}
                    style={{ cursor: "pointer", marginLeft: "2em" }}
                  >
                    <FontAwesomeIcon
                      icon={faTimes}
                      color={"white"}
                      title="Erase option"
                    />
                  </span>
                </Space>
              ))}
              <Form.Item>
                <Button
                  type="ghost"
                  style={{ color: "white", marginLeft: "3em" }}
                  shape="round"
                  onClick={() => add()}
                  block
                  className={"col-3"}
                >
                  + Add field
                </Button>
              </Form.Item>
            </>
          )}
        </Form.List>
      );
    if (t === "Text" || t === "Email")
      return (
        <Form.Item label="Placeholder ::" name={`field_${id}_placeholder`}>
          <Input
            style={{ maxWidth: "60%" }}
            placeholder="write a placeholder"
          />
        </Form.Item>
      );
  };
  const [answer, setAnswer] = useState();
  const handleAnswer = (type) => {
    const a = makeAnswerField(type);
    setAnswer(a);
  };

  return (
    <div
      style={{
        boxShadow:
          "0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)",
        borderRadius: "1em",
        padding: "1em",
        margin: "1em",
      }}
    >
      <Form.Item noStyle>
        <span
          className="menu-close"
          onClick={() => onRemove(id)}
          style={{
            cursor: "pointer",
            float: "right",
            margin: "1em",
            marginTop: "5px",
          }}
        >
          <FontAwesomeIcon icon={faTimes} color={"white"} title="Erase Field" />
        </span>
        <br />

        <Form.Item
          rules={[
            {
              required: true,
              message: "field required",
            },
          ]}
          label="Label ::"
          name={`field_${id}_label`}
        >
          <Input
            placeholder="Please enter a label for the field"
            style={{ maxWidth: "60%", marginLeft: "2.7em" }}
          />
        </Form.Item>

        <Form.Item
          rules={[
            {
              required: true,
              message: "field required",
            },
          ]}
          label="Answer Type ::"
          name={`field_${id}_answerType`}
        >
          <Radio.Group
            onChange={(e) => {
              handleAnswer(e.target.value);
            }}
          >
            <Radio.Button value="Text" style={{ background: "transparent" }}>
              Text
            </Radio.Button>
            <Radio.Button value="Email" style={{ background: "transparent" }}>
              Email
            </Radio.Button>
            <Radio.Button
              value="TextArea"
              style={{ background: "transparent" }}
            >
              TextArea
            </Radio.Button>
            <Radio.Button
              value="Selection"
              style={{ background: "transparent" }}
            >
              Selection
            </Radio.Button>
          </Radio.Group>
        </Form.Item>
        {answer}
        <Form.Item
          rules={[
            {
              required: true,
              message: "field required",
            },
          ]}
          label="Is it required ::"
          name={`field_${id}_isRequired`}
        >
          <Radio.Group>
            <Radio.Button value={true} style={{ background: "transparent" }}>
              Yes
            </Radio.Button>
            <Radio.Button value={false} style={{ background: "transparent" }}>
              No
            </Radio.Button>
          </Radio.Group>
        </Form.Item>
      </Form.Item>
    </div>
  );
}
Example #23
Source File: adminChallengeCreate.js    From ctf_platform with MIT License 4 votes vote down vote up
CreateChallengeForm = (props) => {
    const [form] = Form.useForm();
    const [editorValue, setEditorValue] = React.useState("")
    const [existingCats, setExistingCats] = React.useState([])
    const [finalSortedChalls, setfinalSortedChalls] = React.useState([])

    useEffect(() => {
        var currentValues = form.getFieldsValue()
        currentValues.flags = [""]

        form.setFieldsValue(currentValues)
        //Render existing categories select options
        let existCats = []
        for (let i = 0; i < props.allCat.length; i++) {
            existCats.push(<Option key={props.allCat[i].key} value={props.allCat[i].key}>{props.allCat[i].key}</Option>)
        }
        setExistingCats(existCats)
        //Render existing challenges select options
        let existChalls = {}
        for (let i = 0; i < props.challenges.length; i++) {
            if (!(props.challenges[i].category in existChalls)) existChalls[props.challenges[i].category] = []
            existChalls[props.challenges[i].category].push({
                value: props.challenges[i]._id,
                label: props.challenges[i].name
            })
        }

        let finalChalls = []
        for (const category in existChalls) {
            finalChalls.push({
                value: category,
                label: category,
                children: existChalls[category]
            })
        }
        setfinalSortedChalls(finalChalls)
    }, [])

    return (
        <Form
            form={form}
            name="create_challenge_form"
            className="create_challenge_form"
            onValuesChange={() => { if (props.state.edited === false) props.setState({ edited: true }) }}
            onFinish={async (values) => {
                props.setState({ edited: false })
                if (typeof values.flags === "undefined") {
                    message.warn("Please enter at least 1 flag")
                }
                else {
                    //console.log(values)
                    props.setState({ loading: true })
                    if (values.visibility === "false") {
                        values.visibility = false
                    }
                    else {
                        values.visibility = true
                    }
                    if (values.dynamic === "false") {
                        values.dynamic = false
                    }
                    else {
                        values.dynamic = true
                    }
                    if (typeof values.writeup !== "undefined") {
                        if (typeof values.writeupComplete === "undefined") {
                            values.writeupComplete = true
                        }
                    }
                    const category = (typeof values.category1 !== "undefined") ? values.category1 : values.category2
                    let requires = undefined
                    if (values.requires && values.requires.length > 0) requires = values.requires[1]
                    await fetch(window.ipAddress + "/v1/challenge/new", {
                        method: 'post',
                        headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
                        body: JSON.stringify({
                            "name": values.name,
                            "category": category,
                            "description": values.description,
                            "points": values.points,
                            "flags": values.flags,
                            "tags": values.tags,
                            "hints": values.hints,
                            "max_attempts": values.max_attempts,
                            "visibility": values.visibility,
                            "writeup": values.writeup,
                            "writeupComplete": values.writeupComplete,
                            "requires": requires,
                            "dynamic": values.dynamic,
                            "initial": values.initial,
                            "minSolves": values.minSolves,
                            "minimum": values.minimum
                        })
                    }).then((results) => {
                        return results.json(); //return data in JSON (since its JSON data)
                    }).then((data) => {
                        //console.log(data)
                        if (data.success === true) {
                            message.success({ content: "Created challenge " + values.name + " successfully!" })
                            form.resetFields()
                            props.handleCreateBack()
                        }
                        else if (data.error === "exists") {
                            message.warn("A challenge with an existing name exists")
                        }
                        else {
                            message.error({ content: "Oops. Unknown error, please contact an admin." })
                        }



                    }).catch((error) => {
                        console.log(error)
                        message.error({ content: "Oops. Issue connecting with the server or client error, please check console and report the error. " });
                    })
                    props.setState({ loading: false })


                }

            }}

        >
            <Prompt
                when={props.state.edited}
                message='The challenge details you entered have not been saved. Are you sure you want to leave?'
            />

            <h1>Challenge Name:</h1>
            <Form.Item
                name="name"
                rules={[{ required: true, message: 'Please enter a challenge name' }]}
            >

                <Input allowClear placeholder="Challenge name" />
            </Form.Item>

            <Divider />
            <h1>Challenge Category:</h1>
            <h4>Select an Existing Category: </h4>
            <Form.Item
                name="category1"
                rules={[{ required: !props.state.selectCatDisabled, message: 'Please enter a challenge category' }]}
            >

                <Select
                    disabled={props.state.selectCatDisabled}
                    allowClear
                    showSearch
                    placeholder="Select an existing Category"
                    onChange={(value) => {
                        if (value) {
                            props.setState({ inputCatDisabled: true })
                        }
                        else {
                            props.setState({ inputCatDisabled: false })
                        }
                    }}
                >
                    {existingCats}
                </Select>

            </Form.Item>
            <h4>Enter a New Category</h4>
            <Form.Item
                name="category2"
                rules={[{ required: !props.state.inputCatDisabled, message: 'Please enter a challenge category' }]}
            >

                <Input onChange={(e) => {
                    e.target.value.length > 0 ? props.setState({ selectCatDisabled: true }) : props.setState({ selectCatDisabled: false })
                }} disabled={props.state.inputCatDisabled} allowClear placeholder="Enter a new challenge category" />
            </Form.Item>

            <Divider />

            <Suspense fallback={<div style={{ height: "100%", width: "100%", display: "flex", justifyContent: "center", alignItems: "center", zIndex: 15 }}>
                <Ellipsis color="#177ddc" size={120} ></Ellipsis>
            </div>}>
                <h1>Challenge Description (Supports <a href="https://guides.github.com/features/mastering-markdown/" target="_blank" rel="noreferrer">Markdown</a> and <a href="https://github.com/rehypejs/rehype-raw" target="_blank" rel="noreferrer">HTML</a>):</h1>
                <Form.Item
                    name="description"
                    rules={[{ required: true, message: 'Please enter a description' }]}
                    valuePropName={editorValue}
                >
                    <MDEditor value={editorValue} onChange={(value) => { setEditorValue(value) }} preview="edit" />
                </Form.Item>
                <h3>Challenge Description Preview</h3>
                <Card
                    type="inner"
                    bordered={true}
                    bodyStyle={{ backgroundColor: "#262626", textAlign: "center" }}
                    className="challengeModal"
                >
                    <MarkdownRender>{editorValue}</MarkdownRender>
                </Card>
            </Suspense>


            <Divider />

            <div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>

                <div style={{ display: "flex", flexDirection: "column", justifyContent: "center" }}>

                    <Card>
                        <h1>Challenge Points:</h1>
                        <Form.Item
                            name="points"
                            rules={[{ required: true, message: 'Please enter challenge points' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 0-100000",
                            },]}
                            initialValue={0}
                        >

                            <InputNumber disabled={props.state.dynamic} min={0} max={100000} style={{ width: "30ch" }} ></InputNumber>
                        </Form.Item>
                    </Card>

                    <Card>
                        <h1>Maximum Number of Attempts (Set to 0 for unlimited)</h1>
                        <Form.Item
                            name="max_attempts"
                            rules={[{ required: true, message: 'Please enter the maximum number of attempts' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 0-10000",
                            },]}
                            style={{ alignText: 'center' }}
                            initialValue={0}
                        >

                            <InputNumber min={0} max={10000} style={{ width: "30ch" }}></InputNumber>
                        </Form.Item>
                    </Card>
                </div>

                <Divider type="vertical" style={{ height: "inherit" }} />

                <div style={{ display: "flex", flexDirection: "column" }}>
                    <Form.List name="flags" >
                        {(fields, { add, remove }) => {
                            return (
                                <Card>
                                    <h1>Flags</h1>
                                    {fields.map(field => (
                                        <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
                                            <Form.Item
                                                {...field}
                                                name={[field.name]}
                                                fieldKey={[field.fieldKey]}
                                                rules={[{ required: true, message: 'Missing flag' }, { message: "Please enter a flag that is < 1000 characters", pattern: /^.{1,1000}$/ }]}
                                            >
                                                <Input style={{ width: "50ch" }} placeholder="Flag" />
                                            </Form.Item>

                                            {fields.length > 1 ? (
                                                <MinusCircleOutlined
                                                    className="dynamic-delete-button"
                                                    style={{ margin: '0 8px', color: "red" }}
                                                    onClick={() => {
                                                        remove(field.name);
                                                    }}
                                                />
                                            ) : null}
                                        </Space>
                                    ))}

                                    <Form.Item>
                                        <Button
                                            type="dashed"
                                            onLoad={() => { if (fields.length < 1) add() }}
                                            onClick={() => {
                                                add();
                                            }}
                                            block
                                            style={{ width: "50ch" }}
                                        >
                                            <PlusOutlined /> Add Flag
                                        </Button>
                                    </Form.Item>


                                </Card>
                            );
                        }}
                    </Form.List>

                    <Form.List name="tags">
                        {(fields, { add, remove }) => {
                            return (
                                <Card>
                                    <h1>Tags</h1>
                                    {fields.map(field => (
                                        <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">

                                            <Form.Item
                                                {...field}
                                                name={[field.name]}
                                                fieldKey={[field.fieldKey]}
                                                rules={[{ required: true, message: 'Missing tag' }]}
                                            >
                                                <Input placeholder="Tag" style={{ width: "50ch" }} />
                                            </Form.Item>


                                            <MinusCircleOutlined
                                                className="dynamic-delete-button"
                                                style={{ margin: '0 8px', color: "red" }}
                                                onClick={() => {
                                                    remove(field.name);
                                                }}
                                            />
                                        </Space>
                                    ))}

                                    <Form.Item>
                                        <Button
                                            type="dashed"
                                            onClick={() => {
                                                add();
                                            }}
                                            block
                                            style={{ width: "50ch" }}
                                        >
                                            <PlusOutlined /> Add Tag
                                        </Button>
                                    </Form.Item>
                                </Card>
                            );
                        }}
                    </Form.List>
                </div>
            </div>

            <Divider />


            <div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>

                <div style={{ display: "flex", flexDirection: "column" }}>

                    <Form.List name="hints" >
                        {(fields, { add, remove }) => {
                            return (
                                <Card>
                                    <h1>Hints</h1>
                                    {fields.map(field => (
                                        <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
                                            <Form.Item
                                                {...field}
                                                name={[field.name, "hint"]}
                                                fieldKey={[field.fieldKey, "hint"]}
                                                rules={[{ required: true, message: 'Missing hint' }]}
                                            >
                                                <Input placeholder="Hint" style={{ width: "20vw" }} />
                                            </Form.Item>

                                            <Form.Item
                                                {...field}
                                                name={[field.name, "cost"]}
                                                fieldKey={[field.fieldKey, "cost"]}
                                                rules={[{ required: true, message: 'Missing cost for hint' }, {
                                                    type: 'integer',
                                                    message: "Please enter a valid integer between 0-10000",
                                                },]}
                                            >
                                                <InputNumber min={0} max={10000} placeholder="Cost"></InputNumber>
                                            </Form.Item>

                                            <MinusCircleOutlined
                                                style={{ color: "red" }}
                                                onClick={() => {
                                                    remove(field.name);
                                                }}
                                            />
                                        </Space>
                                    ))}

                                    <Form.Item>
                                        <Button
                                            type="dashed"
                                            onClick={() => {
                                                add();
                                            }}
                                            block
                                            style={{ width: "50ch" }}
                                        >
                                            <PlusOutlined /> Add Hint
                                        </Button>
                                    </Form.Item>
                                </Card>
                            );
                        }}
                    </Form.List>

                    <Card>
                        <h1>Writeup Link (Optional)</h1>
                        <Form.Item
                            name="writeup"
                            rules={[
                                {
                                    type: 'url',
                                    message: "Please enter a valid link",
                                }]}
                        >

                            <Input allowClear style={{ width: "50ch" }} placeholder="Enter a writeup link for this challenge" />
                        </Form.Item>
                        <div style={{ display: "flex", alignContent: "center" }}>
                            <h4 style={{ marginRight: "2ch" }}>Release Writeup Only After Completion: </h4>
                            <Form.Item
                                name="writeupComplete"
                            >
                                <Switch defaultChecked />
                            </Form.Item>
                        </div>
                    </Card>

                    <Card>
                        <h1>Visibility</h1>
                        <Form.Item
                            name="visibility"
                            rules={[{ required: true, message: 'Please set the challenge visibility' }]}
                            initialValue="false"
                        >
                            <Select style={{ width: "20ch" }}>
                                <Option value="false"><span style={{ color: "#d32029" }}>Hidden <EyeInvisibleOutlined /></span></Option>
                                <Option value="true"><span style={{ color: "#49aa19" }}>Visible <EyeOutlined /></span></Option>
                            </Select>

                        </Form.Item>
                    </Card>
                </div>

                <Divider type="vertical" style={{ height: "inherit" }} />

                <div style={{ display: "flex", flexDirection: "column" }}>

                    <Card>
                        <h1>Challenge Required: </h1>
                        <Form.Item
                            name="requires"
                        >

                            <Cascader
                                options={finalSortedChalls}
                                allowClear
                                showSearch
                                placeholder="Select an existing challenge" />

                        </Form.Item>
                        <p>Locks this challenge until the provided challenge above has been solved.</p>
                    </Card>

                    <Card>
                        <h1>Dynamic Scoring</h1>
                        <Form.Item
                            name="dynamic"
                            rules={[{ required: true, message: 'Please set whether the challenge uses dynamic scoring' }]}
                            initialValue="false"
                        >
                            <Select onSelect={(option) => { option === "false" ? props.setState({ dynamic: false }) : props.setState({ dynamic: true }) }} style={{ width: "20ch" }}>
                                <Option value="false"><span style={{ color: "#d32029" }}>Disabled</span></Option>
                                <Option value="true"><span style={{ color: "#49aa19" }}>Enabled</span></Option>
                            </Select>

                        </Form.Item>

                        <h1>Initial Points:</h1>
                        <Form.Item
                            name="initial"
                            rules={[{ required: props.state.dynamic, message: 'Please enter the initial challenge points' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 1-100000",
                            },]}
                            initialValue={500}
                        >
                            <InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
                        </Form.Item>
                        <p>Initial number of points when there are 0/1 solves on a challenge</p>

                        <h1>Minimum Points:</h1>
                        <Form.Item
                            name="minimum"
                            rules={[{ required: props.state.dynamic, message: 'Please enter the minimum challenge points' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 0-100000",
                            },]}
                            initialValue={100}
                        >
                            <InputNumber disabled={!props.state.dynamic} min={0} max={100000} ></InputNumber>
                        </Form.Item>
                        <p>Minimum amount of points that the challenge can decay too</p>

                        <h1>Solves to Minimum:</h1>
                        <Form.Item
                            name="minSolves"
                            rules={[{ required: props.state.dynamic, message: 'Please enter the solves to minimum' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 1-100000",
                            },]}
                            initialValue={50}
                        >
                            <InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
                        </Form.Item>
                        <p>Number of solves on the challenge till it decays to the minimum point.</p>
                    </Card>
                </div>

            </div>

            <Form.Item>
                <div style={{ display: "flex", justifyContent: "space-between", flexDirection: "row", marginTop: "2vh" }}>
                    <div>
                        <Button style={{ marginBottom: "1.5vh", marginRight: "2vw", backgroundColor: "#d4b106", borderColor: "", color: "white" }} onClick={() => { props.previewChallenge(form.getFieldsValue()); }}>Preview</Button>
                        <Button loading={props.loadingStatus} type="primary" htmlType="submit" className="login-form-button" style={{ marginBottom: "1.5vh" }}>Create Challenge</Button>
                    </div>
                    <div>
                        <Button style={{ marginRight: "2vw" }} type="primary" danger onClick={() => { form.resetFields() }}>Clear</Button>
                    </div>
                </div>
            </Form.Item>

        </Form>
    );
}
Example #24
Source File: Swap.jsx    From Tai-Shang-NFT-Wallet 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], ethers.utils.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], ethers.utils.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(ethers.utils.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(ethers.utils.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(
          ethers.utils.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(ethers.utils.formatUnits(balanceIn, tokens[tokenIn].decimals)) < amountIn
    : null;
  const inputIsToken = tokenIn !== "ETH";
  const insufficientAllowance = !inputIsToken
    ? false
    : routerAllowance
    ? parseFloat(ethers.utils.formatUnits(routerAllowance, tokens[tokenIn].decimals)) < amountIn
    : null;
  const formattedBalanceIn = balanceIn
    ? parseFloat(ethers.utils.formatUnits(balanceIn, tokens[tokenIn].decimals)).toPrecision(6)
    : null;
  const formattedBalanceOut = balanceOut
    ? parseFloat(ethers.utils.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(ethers.utils.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 ? ethers.utils.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>
  );
}
Example #25
Source File: Swap.jsx    From moonshot 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)

  let blockNumber = useBlockNumber(selectedProvider, 3000)

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

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

  const getTrades = async () => {
    if(tokenIn && tokenOut && (amountIn || amountOut)) {

    let pairs = (arr) => arr.map( (v, i) => arr.slice(i + 1).map(w => [v,w]) ).flat();

    let 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)
    })

    let listOfPairwiseTokens = pairs(baseTokens)

    const getPairs = async (list) => {

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

    let 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) {

      let accountList = await selectedProvider.listAccounts()

      if(tokenIn) {
        let tempContractIn = new ethers.Contract(tokens[tokenIn].address, erc20Abi, selectedProvider);
        let 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) {
        let tempContractOut = new ethers.Contract(tokens[tokenOut].address, erc20Abi, selectedProvider);
        let newBalanceOut = await getBalance(tokenOut, accountList[0], tempContractOut)
        setBalanceOut(newBalanceOut)
      }
    }
  }

  usePoller(getAccountInfo, 6000)

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

  const updateRouterAllowance = async (newAllowance) => {
    setApproving(true)
    try {
    let tempContract = new ethers.Contract(tokens[tokenIn].address, erc20Abi, signer);
    let 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 () => {
    let approvalAmount = exact === 'in' ? ethers.utils.hexlify(parseUnits(amountIn.toString(), tokens[tokenIn].decimals)) : amountInMax.raw.toString()
    console.log(approvalAmount)
    let approval = updateRouterAllowance(approvalAmount)
    if(approval) {
      notification.open({
        message: 'Token transfer approved',
        description:
        `You can now swap up to ${amountIn} ${tokenIn}`,
      });
    }
  }

  const removeRouterAllowance = async () => {
    let approvalAmount = ethers.utils.hexlify(0)
    console.log(approvalAmount)
    let 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
      let metadata = {}

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

      if (exact === 'in') {
        let _amountIn = ethers.utils.hexlify(parseUnits(amountIn.toString(), tokens[tokenIn].decimals))
        let _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') {
        let _amountOut = ethers.utils.hexlify(parseUnits(amountOut.toString(), tokens[tokenOut].decimals))
        let _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)
      let 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);
  };

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

  let metaIn = tokens && tokenList && tokenIn ? tokenList.filter(function (t) {
    return t.address === tokens[tokenIn].address
  })[0] : null
  let 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
  }
  }

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

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

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

  let 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)

         let 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>
  )

}
Example #26
Source File: AddProtectionModal.js    From bonded-stablecoin-ui with MIT License 4 votes vote down vote up
AddProtectionModal = ({
  visible,
  setVisible,
  activeWallet,
  deposit = {},
}) => {
  const { params, deposit_aa, reserve_asset_symbol } = useSelector((state) => state.active);
  const [amount, setAmount] = useState({
    value: undefined,
    valid: undefined,
  });
  const amountInputRef = useRef(null);
  const addBtnRef = useRef(null);
  const { t } = useTranslation();

  const { id, amount: currentAmount, protection } = deposit;
  const { reserve_asset, reserve_asset_decimals, decimals2 } = params;

  const handleChangeAmount = (ev) => {
    const value = ev.target.value;
    const reg = /^[0-9.]+$/;

    if (value === "" || value === "0" || Number(value) === 0) {
      setAmount({ value, valid: undefined });
    } else {
      if (
        (~(value + "").indexOf(".") ? (value + "").split(".")[1].length : 0) <=
        reserve_asset_decimals
      ) {
        if (reg.test(String(value))) {
          setAmount({ value, valid: true });
        } else {
          setAmount({ value, valid: false });
        }
      }
    }
  };

  useEffect(() => {
    if (amountInputRef.current) {
      setAmount({ value: undefined, valid: false });
      amountInputRef.current.focus();
    }
  }, [visible]);

  const totalProtectionRatio = (((protection || 0) / 10 ** reserve_asset_decimals + (amount.valid ? Number(amount.value) : 0))) / (currentAmount / 10 ** decimals2);
  
  return (
    <Modal
      visible={visible}
      title={t("modals.add_protection.title", "Add protection to deposit")}
      onCancel={setVisible}
      style={{ zIndex: -1 }}
      footer={
        <Space>
          <QRButton
            type="primary"
            disabled={!amount.valid}
            ref={addBtnRef}
            onClick={() =>
              setTimeout(() => {
                setVisible();
              }, 100)
            }
            href={generateLink(
              amount.value * 10 ** reserve_asset_decimals,
              { add_protection: 1, id },
              activeWallet,
              deposit_aa,
              reserve_asset,
              true
            )}
          >
            {t("modals.add_protection.btn", "Add protection")}
          </QRButton>
          <Button type="default" onClick={setVisible}>
            {t("modals.common.close", "Close")}
          </Button>
        </Space>
      }
    >
      <Form size="large">
        <Form.Item>
          <Input
            placeholder={t("modals.common.amount", "Amount")}
            onChange={handleChangeAmount}
            value={amount.value}
            ref={amountInputRef}
            suffix={
              reserve_asset in config.reserves
                ? config.reserves[reserve_asset].name
                : reserve_asset_symbol || "reserve token"
            }
            onKeyPress={(ev) => {
              if (ev.key === "Enter") {
                if (amount.valid) {
                  addBtnRef.current.click();
                }
              }
            }}
            autoFocus={true}
          />
        </Form.Item>
      </Form>
      <div>
        <b>{t("modals.add_protection.ratio", "Protection ratio")}:</b> {+Number(totalProtectionRatio).toPrecision(3)}
      </div>
    </Modal>
  );
}
Example #27
Source File: Account.jsx    From quadratic-diplomacy with MIT License 4 votes vote down vote up
/*
  ~ What it does? ~

  Displays an Address, Balance, and Wallet as one Account component,
  also allows users to log in to existing accounts and log out

  ~ How can I use? ~

  <Account
    address={address}
    localProvider={localProvider}
    userProvider={userProvider}
    mainnetProvider={mainnetProvider}
    price={price}
    web3Modal={web3Modal}
    loadWeb3Modal={loadWeb3Modal}
    logoutOfWeb3Modal={logoutOfWeb3Modal}
    blockExplorer={blockExplorer}
  />

  ~ Features ~

  - Provide address={address} and get balance corresponding to the given address
  - Provide localProvider={localProvider} to access balance on local network
  - Provide userProvider={userProvider} to display a wallet
  - Provide mainnetProvider={mainnetProvider} and your address will be replaced by ENS name
              (ex. "0xa870" => "user.eth")
  - Provide price={price} of ether and get your balance converted to dollars
  - Provide web3Modal={web3Modal}, loadWeb3Modal={loadWeb3Modal}, logoutOfWeb3Modal={logoutOfWeb3Modal}
              to be able to log in/log out to/from existing accounts
  - Provide blockExplorer={blockExplorer}, click on address and get the link
              (ex. by default "https://etherscan.io/" or for xdai "https://blockscout.com/poa/xdai/")
*/

export default function Account({
  address,
  userSigner,
  localProvider,
  mainnetProvider,
  price,
  minimized,
  web3Modal,
  loadWeb3Modal,
  logoutOfWeb3Modal,
  blockExplorer,
  isAdmin,
  isVoter,
}) {
  const modalButtons = [];
  if (web3Modal) {
    if (web3Modal.cachedProvider) {
      modalButtons.push(
        <Button
          key="logoutbutton"
          style={{ verticalAlign: "top", marginLeft: 8, marginTop: 4 }}
          shape="round"
          size="large"
          onClick={logoutOfWeb3Modal}
        >
          logout
        </Button>,
      );
    } else {
      modalButtons.push(
        <Button
          key="loginbutton"
          style={{ verticalAlign: "top", marginLeft: 8, marginTop: 4 }}
          shape="round"
          size="large"
          /* type={minimized ? "default" : "primary"}     too many people just defaulting to MM and having a bad time */
          onClick={loadWeb3Modal}
        >
          connect
        </Button>,
      );
    }
  }

  const { currentTheme } = useThemeSwitcher();

  const display = minimized ? (
    ""
  ) : (
    <Space>
      {isAdmin && <Badge count={"admin"} />}
      {isVoter && <Badge count={"voter"} style={{ backgroundColor: "#52c41a" }} />}
      {address ? (
        <Address address={address} ensProvider={mainnetProvider} blockExplorer={blockExplorer} />
      ) : (
        "Connecting..."
      )}
      <Balance address={address} provider={localProvider} price={price} />
      <Wallet
        address={address}
        provider={localProvider}
        signer={userSigner}
        ensProvider={mainnetProvider}
        price={price}
        color={currentTheme === "light" ? "#1890ff" : "#2caad9"}
      />
    </Space>
  );

  return (
    <div>
      {display}
      {modalButtons}
    </div>
  );
}
Example #28
Source File: SubmissionList.js    From codeclannigeria-frontend with MIT License 4 votes vote down vote up
function SubmissionList({
  mentorTasks,
  loading,
  getUserMenteesProfileApi,
  getAllMentorSubmissions,
  gradeTaskAction,
}) {
  const [visible, setVisible] = useState();
  const [currentRecord, setCurrentRecord] = useState();
  const dispatch = useDispatch();
  console.log(mentorTasks);

  const onCreate = (values, initialData) => {
    values.id = initialData.id;
    gradeTaskAction(values);
  };
  const [form] = Form.useForm();

  const onCancel = () => {
    setCurrentRecord(null);
  };

  useEffect(() => {
    if (currentRecord) {
      form.setFieldsValue({ ...currentRecord });
      setVisible(true);

      // setCurrentRecord(null);
    } else {
      setVisible(false);
    }
  }, [currentRecord, form]);

  const handleModalVisibility = record => {
    dispatch({ type: 'TASKS_RESET' });

    setCurrentRecord(record);
  };

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

  const columns = [
    // {
    //   title: 'Id',
    //   dataIndex: 'id',
    //   visible: false,
    // },
    {
      title: 'Name',
      dataIndex: 'mentee',
      sorter: (a, b) => a.mentee.firstName > b.mentee.firstName,
      render: (_, { mentee }) => mentee.firstName,
    },
    {
      title: 'Surname',
      dataIndex: 'mentee',
      sorter: (a, b) => a.mentee.lastName.length > b.mentee.lastName,
      render: (_, { mentee }) => mentee.lastName,
    },
    {
      title: 'Task',
      dataIndex: 'task',
      // sorter: (a, b) => a.task.title > b.task.title,
      render: (_, { task }) => task ? task.title: null,
    },
    {
      title: 'Updated',
      render: (_, { updatedAt }) => updatedAt,
      sorter: (a, b) => a.updatedAt > b.updatedAt,
    },
    {
      title: 'Grade %',
      dataIndex: 'gradePercentage',
      filters: [
        {
          text: 'Not Graded',
          value: 'notGraded',
        },
        {
          text: 'Graded',
          value: 'graded',
        },
      ],
      // specify the condition of filtering result
      // here is that finding the name started with `value`
      onFilter: (value, record) =>
        value === 'graded'
          ? record.gradePercentage > 0
          : record.gradePercentage <= 0,
    },
    {
      title: 'Grade',
      key: 'action',
      render: (text, record) => (
        <Space size="middle">
          <Button
            type="primary"
            //ref
            onClick={() => handleModalVisibility(record)}
          >
            Grade
          </Button>
        </Space>
      ),
    },
  ];

  return (
    <div>
      <h2 className="ml-4">Mentees Task Submissions</h2>
      <Table
        className="mentee-table ml-4"
        columns={columns}
        dataSource={mentorTasks}
        size="small"
        rowKey="id"
        pagination={{ pageSize: 10 }}
        // scroll={{ y: 240 }}
      />
      <TaskForm
        initialData={currentRecord}
        visible={visible}
        onCreate={onCreate}
        onCancel={onCancel}
        loadiing={loading}
        form={form}
      />
    </div>
  );
}
Example #29
Source File: EditInfo.js    From Peppermint with GNU General Public License v3.0 4 votes vote down vote up
EditInfo = (props) => {
  // eslint-disable-next-line
  const [users, setUsers] = useState(props.user);
  const [name, setName] = useState(props.user.name);
  const [email, setEmail] = useState(props.user.email);
  const [role, setRole] = useState(props.user.role);
  const [visible, setVisible] = useState(false);

  const postData = async () => {
    await fetch(`/api/v1/auth/edit`, {
      method: "PUT",
      headers: {
        "Content-Type": "application/json",
        Authorization: "Bearer " + localStorage.getItem("jwt"),
      },
      body: JSON.stringify({
        id: users._id,
        name,
        email,
        role,
      }),
    }).then((res) => res.json);
  };

  const onCreate = async () => {
    setVisible(false);
    email.toString(email);
    await postData();
  };

  const onCancel = () => {
    setVisible(false);
  };

  return (
    <div>
      <p
        type="primary"
        onClick={() => {
          setVisible(true);
        }}
      >
        Edit User info & Role
      </p>
      <Modal
        visible={visible}
        title="Edit a users info"
        okText="Update"
        cancelText="Cancel"
        onCancel={onCancel}
        onOk={onCreate}
      >
        <Row>
          <h5>
            Edit Name :{" "}
            <Input
              defaultValue={users.name}
              onChange={(e) => setName(e.target.value)}
              style={{ width: 300 }}
            />
          </h5>
        </Row>
        <Row>
          <h5>
            Edit Email :{" "}
            <Input
              defaultValue={users.email}
              onChange={(e) => setEmail(e.target.value)}
              style={{ width: 300, marginLeft: 5 }}
            />
          </h5>
        </Row>
        <Row>
          <h5>Edit Role : </h5>
          <Radio.Group
            buttonStyle="solid"
            defaultValue={users.role}
            onChange={(e) => setRole(e.target.value)}
            style={{ marginLeft: 20 }}
          >
            <Space>
              <Radio.Button value="user">User</Radio.Button>
              <Radio.Button value="admin">Admin</Radio.Button>
            </Space>
          </Radio.Group>
        </Row>
      </Modal>
    </div>
  );
}