Skip to content

Commit

Permalink
refactor TokenSelect into separate component
Browse files Browse the repository at this point in the history
  • Loading branch information
ilge-ustun committed Mar 4, 2024
1 parent ca899c1 commit 49357bc
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 123 deletions.
16 changes: 7 additions & 9 deletions app/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useEffect, useState } from "react";
import logo from "./images/logo.svg"
import "./css/App.css";
// import { HCaptchaForm } from "./components/hcaptcha/hcaptcha";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import axios from "axios";
Expand All @@ -22,6 +21,7 @@ function App(): JSX.Element {
return axios.get(`${process.env.REACT_APP_FAUCET_API_URL}/info`);
};

// console.log(enabledTokens)

useEffect(() => {
getFaucetInfo()
Expand All @@ -43,7 +43,7 @@ function App(): JSX.Element {
? "Loading faucet..."
: (chainId === "100" ? "Faucet" : "Testnet Faucet")

const enabledTokens = [
const enabledTokens1 = [
{
address: "0x01",
name: "GNO",
Expand All @@ -59,13 +59,11 @@ function App(): JSX.Element {
return (
<>
<ToastContainer
position="top-right"
autoClose={false}
hideProgressBar={false}
position="bottom-right"
hideProgressBar={true}
newestOnTop={false}
closeOnClick={false}
rtl={false}
pauseOnFocusLoss
closeOnClick={true}
// pauseOnFocusLoss
draggable
pauseOnHover
/>
Expand All @@ -76,7 +74,7 @@ function App(): JSX.Element {
<h1>{title}</h1>
<h2>{subtitle}</h2>
</div>
<Faucet chainId={chainId} enabledTokens={enabledTokens}/>
<Faucet chainId={"100"} enabledTokens={enabledTokens1}/>
</div>
</>
);
Expand Down
18 changes: 4 additions & 14 deletions app/src/components/Captcha/Captcha.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
/* eslint-disable */

import React, { useRef, useState, useEffect } from "react";
import React, { useRef } from "react";
import HCaptcha from "@hcaptcha/react-hcaptcha"

const siteKey = process.env.REACT_APP_HCAPTCHA_SITE_KEY || "10000000-ffff-ffff-ffff-000000000001"

interface CaptchaProps {
setCaptchaToken: (token: string) => void
setCaptchaToken: (token: string) => void,
windowWidth: number
}

// type CaptchaSize = "compact" | "normal" | "invisible"

const Captcha: React.FC<CaptchaProps> = ({ setCaptchaToken }) => {
const Captcha: React.FC<CaptchaProps> = ({ setCaptchaToken, windowWidth }) => {
const captchaRef = useRef<HCaptcha>(null)

const [windowWidth, setWindowWidth] = useState(window.innerWidth);

useEffect(() => {
const handleResize = () => setWindowWidth(window.innerWidth)
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])

const onVerifyCaptcha = (token: string) => {
setCaptchaToken(token)
Expand Down
15 changes: 14 additions & 1 deletion app/src/components/FaucetForm/Faucet.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
.flex-row {
display: flex;
flex-direction: row;
/* min-height: 56px; */
width: 100%;
align-items: center;
flex-wrap: wrap;
Expand Down Expand Up @@ -104,3 +103,17 @@
.faucet-container button:hover {
background-color: #f0713b;
}

.success {
margin-top: 2rem;
}

.success div {
color: #f0ebde;
margin: 0.2rem 0;
}

.success a {
word-break: break-all;
color: #f0ebde;
}
173 changes: 75 additions & 98 deletions app/src/components/FaucetForm/Faucet.tsx
Original file line number Diff line number Diff line change
@@ -1,120 +1,87 @@
/* eslint-disable */
import { useState, ChangeEvent, FormEvent, useEffect } from "react"
import Select, { ActionMeta, StylesConfig } from "react-select"
import "./Faucet.css"
import { toast } from "react-toastify"
import axios from "axios"
import Captcha from "../Captcha/Captcha"
import TokenSelect, { Token } from "../TokenSelect/TokenSelect"

interface Option {
value: string,
token: string,
maximumAmount: string
}

const customStyles: StylesConfig<Option, false> = {
control: (provided) => ({
...provided,
height: "56px",
width: window.innerWidth > 500 ? "303px" : "auto",
border: "none"
})
}

interface IToken {
address: string
name: string
maximumAmount: string | number
}

interface IFaucetProps {
enabledTokens: IToken[],
interface FaucetProps {
enabledTokens: Token[],
chainId: string
}

const formatOptionLabel = ({ token, maximumAmount }: Option) => {
return (
<div>
<strong>{token}</strong> {maximumAmount}
</div>
)
}

function Faucet({ enabledTokens, chainId }: IFaucetProps): JSX.Element {
function Faucet({ enabledTokens, chainId }: FaucetProps): JSX.Element {
const [walletAddress, setWalletAddress] = useState("")
const [tokenAddress, setTokenAddress] = useState("")
const [tokenAmount, setTokenAmount] = useState(0)
const [token, setToken] = useState<Token | null>(null)

const [captchaToken, setCaptchaToken] = useState<string | null>(null)
const [loading, setLoading] = useState(true)

const handleChangeAddress = (event: ChangeEvent<HTMLInputElement>) => {
setWalletAddress(event.target.value);
}
const [txHash, setTxHash] = useState<string | null>(null)

const handleChangeToken = (option: Option | null, actionMeta: ActionMeta<Option>) => {
console.log('Selected option:', option)
const [windowWidth, setWindowWidth] = useState(window.innerWidth);

if (option) {
for (let idx in enabledTokens) {
if (enabledTokens[idx].address.toLowerCase() == option.value.toLowerCase()) {
setTokenAmount(Number(enabledTokens[idx].maximumAmount))
break
}
}
}
setTokenAddress(option?.value || "")
}
useEffect(() => {
const handleResize = () => setWindowWidth(window.innerWidth)
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])

const options: Option[] = enabledTokens.map((item) => {
return {
value: item.address,
token: item.name,
maximumAmount: `${item.maximumAmount} day`
}
})
const handleChangeAddress = (event: ChangeEvent<HTMLInputElement>) => {
setWalletAddress(event.target.value)
}

const handleSubmit = (event: FormEvent) => {
event.preventDefault()

if (walletAddress.length <= 0) {
toast.error("Please provide a wallet address.")
return;
return
}

const apiURL = `${process.env.REACT_APP_FAUCET_API_URL}/ask`

try {
setLoading(true);
const req = {
recipient: walletAddress,
captcha: captchaToken,
tokenAddress: tokenAddress,
chainId: chainId,
amount: tokenAmount,
};

axios
.post(apiURL, req)
.then((response) => {
setLoading(false);
setWalletAddress("");
// Reset captcha
// setCaptchaVerified(true)
// captchaRef.current?.resetCaptcha()

toast.success(`Tokens sent to your wallet address. Hash: ${response.data.transactionHash}`)
})
.catch((error) => {
setLoading(false)
console.log(error)
// toast.error(formatErrors(error.response.data.errors));
})
} catch (error) {
setLoading(false)
if (error instanceof Error) {
toast.error(error.message)
}
}
setTxHash("0xb241d0f92fff78f01f9f3410593294191be6dab323c3844f668d466dea835801")
toast.success(`Token sent to your wallet address. Hash: 0xlkdjflskjfl`)

// if (token) {
// try {
// setLoading(true)
// const req = {
// recipient: walletAddress,
// captcha: captchaToken,
// tokenAddress: token.address,
// chainId: chainId,
// amount: token.maximumAmount
// }

// axios
// .post(apiURL, req)
// .then((response) => {
// setLoading(false)
// setWalletAddress("")
// // Reset captcha
// // setCaptchaVerified(true)
// // captchaRef.current?.resetCaptcha()

// setToken(null)

// toast.success(`Token sent to your wallet address. Hash: ${response.data.transactionHash}`)
// setTxInfo(`Token sent to your wallet address. Hash: ${response.data.transactionHash}`)
// })
// .catch((error) => {
// setLoading(false)
// console.log(error)
// // toast.error(formatErrors(error.response.data.errors))
// })
// } catch (error) {
// setLoading(false)
// if (error instanceof Error) {
// toast.error(error.message)
// }
// }
// }
}

return (
Expand All @@ -129,28 +96,38 @@ function Faucet({ enabledTokens, chainId }: IFaucetProps): JSX.Element {
placeholder="0x123..."
onChange={handleChangeAddress}
id="address"
required
/>
</div>
</div>
<div className="flex-row">
<label htmlFor="token">Choose token:</label>
<div className="input-field">
<Select
styles={customStyles}
className="token-select"
options={options}
formatOptionLabel={formatOptionLabel}
onChange={handleChangeToken}
id="address"
<TokenSelect
enabledTokens={enabledTokens}
token={token}
setToken={setToken}
windowWidth={windowWidth}
/>
</div>
</div>
<div className="flex-row flex-row-captcha">
<Captcha setCaptchaToken={setCaptchaToken} />
<Captcha setCaptchaToken={setCaptchaToken} windowWidth={windowWidth}/>
</div>
<button type="submit">
Claim
</button>
{txHash &&
<div className="flex-row success">
<div>Token sent to your wallet address. Hash: </div>
<div>
{chainId === "100"
? <a target="_blank" href={`https://gnosisscan.io/tx/${txHash}`}>{txHash}</a>
: txHash
}
</div>
</div>
}
</form>
)
}
Expand Down
Loading

0 comments on commit 49357bc

Please sign in to comment.