react-bootstrap#Image JavaScript Examples
The following examples show how to use
react-bootstrap#Image.
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: ChartPart.js From real-time-web-samples with MIT License | 7 votes |
render() {
const options = {
legend: {
position: "bottom"
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}}]
},
plugins: {
datalabels: {
display: function(context) {
return context
},
font: {
weight: 'bold'
}
}
},
tooltips: {
enabled: false
}
};
return (
<div>
<Image src={azureImage} style={{width: "98%"}} />
<h3 className="text-left my-3">实时统计</h3>
<Bar data={this.state.chartData} options={options} plugins={DataLabels}/>
<NoticeAlert />
</div>
)
}
Example #2
Source File: NoticeForm.js From real-time-web-samples with MIT License | 6 votes |
render() {
return (
<Container fluid>
<Row>
<Col xs={{ span: 2, offset: 10 }} md={{ span: 1, offset: 11 }}>
<Image src={staffImage} roundedCircle fluid className="border border-primary my-3" />
</Col>
</Row>
<Row>
<Col md="6" className="mb-3">
<Form onSubmit={this.submitNotice}>
<Form.Group controlId="ControlTextarea">
<Form.Control className="" style={{backgroundColor: 'rgba(255, 255, 255, 6%)'}} value={this.state.formText} onChange={this.changeNotice} name="formText" as="textarea" rows="10" placeholder="输入通知消息..."/>
</Form.Group>
<Button variant="primary" type="submit" className="float-right">通知</Button>
</Form>
</Col>
<Col md="6">
<Image src={azureImage} fluid />
</Col>
</Row>
</Container>
);
}
Example #3
Source File: index.js From wedding-planner with MIT License | 6 votes |
/**
* Navbar Component using {Link}
*/
function NavigationBar() {
const { isAuthenticated } = useAuth0();
return (
<Navbar bg="light" shadow="lg" expand="lg">
<Navbar.Brand href="/">
<Image src={logo} className="custom-img" />
</Navbar.Brand>
<Navbar.Toggle aria-controls="navbar-nav" />
<Navbar.Collapse>
{isAuthenticated ? (
<Nav className="ml-auto color-link">
<NavDropdown title="Events" id="basic-nav-dropdown">
<NavDropdown.Item href="/events">
Your Events
</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="/events/new">
Create New
</NavDropdown.Item>
</NavDropdown>
<ProfileLink />
<LogoutLink />
</Nav>
) : (
<Nav className="ml-auto color-link">
<LoginLink />
<SignupLink />
</Nav>
)}
</Navbar.Collapse>
</Navbar>
);
}
Example #4
Source File: ErrorPage.js From CS-Hut with MIT License | 6 votes |
export default function ErrorPage() {
return (
<div>
<div className="Container">
<p className="NotFoundMessage">
The page you are looking for doesn’ t exist!
</p>
<Col className="ImgColumn">
<Image
className="NotFoundImage"
src={NotFound}
alt="Page Not Found"
/>
</Col>
</div>
</div>
);
}
Example #5
Source File: intro_screen.js From twmwallet with MIT License | 6 votes |
render() {
return (
<div className="width100 height100 d-flex flex-column text-center intro-background-image">
<Container fluid className="height100 flex-column d-flex justify-content-center">
<Image onClick={() => app.quit()} className="entry-off-button pointer" src={require("./../../img/off_black.svg")}/>
<Row className="row justify-content-md justify-content-center p-3 intro-safex-logo">
<Image className="w-50 intro-safex-logo " src={require("./../../img/safex-home-multi.png")}/>
</Row>
<button onClick={this.open_select} className="w-50 custom-button-entry my-5 intro-safex-logo">
Get Started
</button>
</Container>
</div>
);
}
Example #6
Source File: MainHeader.js From twmwallet with MIT License | 6 votes |
export default function MainHeader(props) {
const renderMenuItem = (activeOnView, label, onClick) => {
const isActive = props.view === activeOnView;
return (<Col className={isActive ? "menu-link-active" : ""}>
<p className="pointer" onClick={() => onClick()}>
{label}
</p>
</Col>)
}
return (
<Row id="header" className="main-header">
<Col sm={2} className="main-header-logo">
<Image src={require("./../../img/white-logo.svg")}/>
</Col>
<Col sm={6} className="d-flex">
{renderMenuItem('home', 'Home', props.goHome)}
{renderMenuItem('market', 'Market', props.goToMarket)}
{renderMenuItem('merchant', 'Merchant', props.goToMerchant)}
{renderMenuItem('tokens', 'Tokens', props.goToTokens)}
</Col>
<Col sm={2} className="">
<BiCog tabIndex={4} size={40} className="m-3 pointer" onClick={props.goToSettings}/>
<BiPowerOff tabIndex={5} size={40} className="m-3 pointer" onClick={props.logout}/>
</Col>
</Row>
)
}
Example #7
Source File: index.js From Devhipster with MIT License | 6 votes |
function CardCourse({ title, description, icon, url, color }) {
const history = useHistory();
function handleClick() {
history.push(url);
}
return (
<Col md='4' style={{ padding: '15px' }} >
<Card className={['dark', color, 'shadow'].join(' ')} bg="dark" text="white">
<Card.Body className="text-white">
<Card.Title className={color}>
<h3>{title}</h3>
</Card.Title>
<Image fluid={true} src={icon} />
<h5>{description}</h5>
<Button
onClick={handleClick}
variant='dark'
>
<h5 style={{ margin: 0 }} >EM BREVE</h5>
</Button>
</Card.Body>
</Card>
</Col>
);
}
Example #8
Source File: Member.js From dscmec-website with MIT License | 6 votes |
MemberResponsive = (props) => {
return (
<>
<div className="member-responsive">
<Image className="rect-icon" src={props.img} alt="member" />
</div>
<div className="details-responsive">
<h4><strong>{props.name}</strong></h4>
<h5>{props.designation}</h5>
<a href={props.link} target="_blank" rel="noreferrer">
<Image className="ln-icon-resp" src={linkedinIcon} alt="member" />
</a>
</div>
</>
)
}
Example #9
Source File: Member.js From dscmec-website with MIT License | 6 votes |
Member = (props) => {
return (
<>
<div className="member">
<Image className="circle-icon" src={props.img} alt="member" />
<a href={props.link} target="_blank" rel="noreferrer">
<Image className="ln-icon" src={linkedinIcon} alt="member" />
</a>
</div>
<div className="details">
<h4><strong>{props.name}</strong></h4>
<h5>{props.designation}</h5>
</div>
</>
)
}
Example #10
Source File: maintenancePage.js From community-forum-frontend with GNU General Public License v3.0 | 6 votes |
function MaintenancePage() {
return (
<Container className="common-page-maintenance-container">
<Row className="center-row">
<Col>
<h2 className="main-heading">
<PowerIcon />
Under Maintenance
</h2>
<Image
src={maintenanceImage}
className="common-page-maintenance-image"
/>
<h6 className="common-page-maintenance-message">
We are currently under maintenance. Apologies for the
inconvenience caused. Please check back sometime later.
</h6>
</Col>
</Row>
</Container>
);
}
Example #11
Source File: TokenAvatar.js From plenty-interface with GNU General Public License v3.0 | 6 votes |
TokenAvatar = (props) => {
if (!props.imgPath1) {
return <Image src={null} height={32} width={32} alt={''} />;
}
if (props.imgPath2) {
return (
<div className={styles.root}>
<Image src={props.imgPath1.url} height={32} width={32} alt={''} className={styles.token1} />
<Image src={props.imgPath2.url} height={32} width={32} alt={''} className={styles.token2} />
</div>
);
}
return <Image src={props.imgPath1.url} height={32} width={32} alt={''} />;
}
Example #12
Source File: VideoPart.js From real-time-web-samples with MIT License | 6 votes |
render() {
return (
<div>
<div className="position-relative overflow-hidden">
<video controls className="w-100" src={this.state.videoSource}></video>
{this.state.comments.map((comment, index) =>
<p key={index} className="h4 comment text-dark" style={{top: comment.position + "px"}}>{comment.text}</p>
)}
</div>
<form style={{backgroundColor: '#262930'}} className="form-inline py-1 px-3" onSubmit={this.submitComment}>
<div className="form-group m-0">
<input name="commentText" value={this.state.commentText} onChange={this.changeComment} type="text" className="form-control" placeholder="聊天..." id="comment" />
</div>
<Button variant="primary" type="submit" className="mx-2">发送</Button>
<Image src={staffImage} roundedCircle fluid className="border border-primary position-absolute" style={{ width: "5%", right: "40px" }} />
</form>
</div>
)
}
Example #13
Source File: FirstTimeDisclaimer.js From plenty-interface with GNU General Public License v3.0 | 5 votes |
FirstTimeDisclaimer = () => {
const [checked, setChecked] = useState([false, false]);
const onAccept = () => {
localStorage.setItem(FIRST_TIME_DISCLAIMER, 'true');
window.location.reload(); // ? Try moving this to redux later
};
return (
<div className="d-flex justify-content-center align-center vh-100 vw-100">
<div className={clsx(styles.card, 'p-4')}>
<div className="d-flex justify-content-center p-2">
<Image src={PlentyLogo} alt={'Plenty'} className={styles.logo} />
</div>
<hr />
<div>
<div className={clsx('d-flex', styles.checkbox)}>
<input
value={checked[0]}
type="checkbox"
onChange={(ev) => setChecked([ev.target.checked, checked[1]])}
id="d-01"
/>
<label className={clsx(styles.disclaimerItem, 'ml-3 mb-2 p-3')} htmlFor="d-01">
I understand that I am using this product in beta at my own risk. Any losses incurred
due to my actions are my own responsibility.
</label>
</div>
<div className={clsx('d-flex', styles.checkbox)}>
<input
value={checked[1]}
type="checkbox"
onChange={(ev) => setChecked([checked[0], ev.target.checked])}
id="d-02"
/>
<label className={clsx(styles.disclaimerItem, 'ml-3 mb-2 p-3')} htmlFor="d-02">
I understand that this product is still in beta. I am participating at my own risk.
</label>
</div>
</div>
<Button
onClick={onAccept}
color={'primary'}
disabled={!checked.every((x) => x)}
className="w-100"
>
Confirm
</Button>
</div>
</div>
);
}
Example #14
Source File: 500.js From stacker.news with MIT License | 5 votes |
export default function fourZeroFour () {
return (
<LayoutError>
<Image width='500' height='375' src='/falling.gif' fluid />
<h1 className={styles.fourZeroFour}><span>500</span><span className={styles.notFound}>server error</span></h1>
</LayoutError>
)
}
Example #15
Source File: 404.js From stacker.news with MIT License | 5 votes |
export default function fourZeroFour () {
return (
<LayoutError>
<Image width='500' height='376' src='/maze.gif' fluid />
<h1 className={styles.fourZeroFour}><span>404</span><span className={styles.notFound}>page not found</span></h1>
</LayoutError>
)
}
Example #16
Source File: select_entry.js From twmwallet with MIT License | 5 votes |
render() {
return (
<div className="width100 height100 d-flex flex-column text-center">
<Container fluid className="height100 flex-column d-flex justify-content-center start-background-image">
<Image onClick={this.back} className="entry-off-button pointer" src={require("./../../img/off_black.svg")}/>
<Row className="rowjustify-content-md-center justify-content-center p-3">
<Image className="w-25" src={require("./../../img/safex-home-multi.png")}/>
</Row>
<Col className="my-5">
<Col className="my-2 p-3">
<button onClick={this.open_existing} className="custom-button-entry">Open Existing Wallet</button>
</Col>
<Col className="my-2 p-3">
<button onClick={this.create_new} className="custom-button-entry">Create New Wallet</button>
</Col>
<Col className="my-2 p-3">
<button onClick={this.restore_keys} className="custom-button-entry">Recover Wallet From Keys</button>
</Col>
<Col className="my-2 p-3">
<button onClick={this.seed_phrase} className="custom-button-entry">Recover Wallet From Seed Phrase</button>
</Col>
{this.state.legacy_detected ?
(
<Col className="my-5 p-3">
<button className="custom-button-entry orange-border" onClick={() => this.setState({showLegacyAlert: !this.state.showLegacyAlert})}>Open Legacy Wallet</button>
<Collapse in={this.state.showLegacyAlert}>
<Alert
variant="info"
transition={false}
className="mt-3 w-50 mx-auto entry-back-text"
>
<Alert.Heading>We are working on this feature. Thank you for your patience!</Alert.Heading>
</Alert>
</Collapse>
</Col>
)
:
(<div></div>)
}
</Col>
</Container>
</div>);
}
Example #17
Source File: MerchantTabs.js From twmwallet with MIT License | 5 votes |
export default function MerchantTabs(props) {
return (
<div className="merchant-tabs-box">
<div onClick={props.handleNewAccountForm} className="merchant-tab pointer">
<Image
onClick={props.handleNewAccountForm}
width={75}
height={75}
src={props.newAccountImage}
roundedCircle
/>
<h1 onClick={props.handleNewAccountForm} >Make a New Account</h1>
</div>
<div onClick={props.showAccounts} className="merchant-tab pointer">
<Image
width={75}
height={75}
src={props.accountsImage}
roundedCircle
/>
<h1>See Your Accounts</h1>
</div>
<div onClick={props.handleNewOfferForm} className="merchant-tab pointer">
<Image
width={75}
height={75}
src={props.newOfferImage}
roundedCircle
/>
<h1>Make a New Offer</h1>
</div>
<div onClick={props.showOffers} className="merchant-tab pointer">
<Image
width={75}
height={75}
src={props.offersImage}
roundedCircle
/>
<h1>See Your Offers</h1>
</div>
</div>
)
}
Example #18
Source File: index.js From pooled-loan with MIT License | 5 votes |
export default function SwapTokens() {
const [showMetamaskError, setShowMetamaskError] =
useState(false);
useEffect(() => {
if (typeof window.ethereum === 'undefined' ||
!window.ethereum.selectedAddress
) {
setShowMetamaskError(true);
}
}, []);
return (
<div>
{showMetamaskError ?
<AlertModal
open={showMetamaskError}
toggle={() => {
setShowMetamaskError(false);
history.push('/');
}}
>
<div>
{typeof window.ethereum === 'undefined' ?
<div>
You can't use these features without Metamask.
<br />
Please install
<Image width="50px" src={metamask}></Image>
first !!
</div>
:
<div>
Please connect to
<Image width="50px" src={metamask}></Image>
to use this feature !!
</div>
}
</div>
</AlertModal>
:
<CardDeck style={{ marginTop: "12%" }}>
<Card className="hidden-card"></Card>
<SwapToken fixedBuyToken={false} buyToken="DAI" />
<Card className="hidden-card"></Card>
</CardDeck>
}
</div>
);
}
Example #19
Source File: index.js From pooled-loan with MIT License | 5 votes |
export default function Header() {
const [errorModal, setErrorModal] = useState(false);
const handleConnectMetamask = () => {
if (isMetamaskInstalled()) {
initContract();
} else {
setErrorModal(true);
}
};
const isMetamaskInstalled = () => {
return (typeof window.ethereum !== 'undefined');
}
return (
<div>
<Navbar collapseOnSelect bg="light" variant="light">
<Navbar.Brand href="#">
<Image width="120px" src={logo} />
</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Nav className="mr-auto">
<Nav.Link href="#create-pool">Create Pool</Nav.Link>
<Nav.Link href="#swap-token">Swap Token</Nav.Link>
</Nav>
<Nav>
<Image
style={{ cursor: "pointer" }}
width="60px"
src={metamask}
onClick={handleConnectMetamask}
/>
</Nav>
</Navbar>
<AlertModal
open={errorModal}
toggle={() => setErrorModal(false)}
>
You can't use these features without Metamask.
<br />
Please install
<Image width="50px" src={metamask}></Image>
first !!
</AlertModal>
</div>
)
}
Example #20
Source File: MultiMedia.js From tclone with MIT License | 5 votes |
function MM(props) {
let { post, expanded = false, className } = props
let style = {
card: {
maxHeight: !expanded ? '350' : 'fit-content',
overflow: 'hidden',
},
}
let { entities = {}, text } = post
let {
media: [photo] = [],
urls: [url],
} = entities
if (photo) {
photo = <Image fluid rounded={true} src={photo.media_url_https} alt="media preview" />
}
if (!url) {
// TODO see if this even necessary
let unparsed_urls = Array.from(getUrls(text))
if (unparsed_urls.length) {
url = {
expanded_url: unparsed_urls[0], // just the first one
}
}
}
if (url) {
url = (
<ReactTinyLink
width="100%"
cardSize={expanded ? 'large' : 'small'}
autoPlay={expanded}
showGraphic={true}
maxLine={2}
minLine={1}
url={url.expanded_url}
/>
)
}
if (photo || url)
return (
<Card className={`${className} w-100 bg-transparent`} style={style.card}>
{photo}
<div className="mt-1">{url}</div>
</Card>
)
else return <></>
}
Example #21
Source File: Jumbotron.js From talk4free with MIT License | 5 votes |
Jumbotron = props => {
const signInHandler = () => {
document.getElementById("signInBtn").click();
};
return (
<section className="jumbotron">
<Container>
<Row className="mt-5">
<Col md="6">
<h1>Practice lenguages at anytime.</h1>
<p className="lead mt-5 mb-5">
Talk4Free is created to talk to people around the world in many
languages such as English, Mandarin, Spanish, French, German,
Italian, Portuguese, Arabic, Russian, Japanese among others.
<br />
<br />
People can exchange languages and culture, make friends and meet
up people around the world.
</p>
<div className="callToActions">
<a
href="#test"
className="btn btn-primary my-2"
onClick={props.isLoggedIn ? console.log("") : signInHandler}
>
Join & Talk Now! <FaSignInAlt />
</a>
<a
type="btn"
href="#test"
className="btn btn-secondary my-2 ml-4"
>
Rules & Penalies <FaSkull />
</a>
</div>
</Col>
<Col md="6" className="introImage">
<Image src={require("./logo10x10.png")} />
</Col>
</Row>
</Container>
</section>
);
}
Example #22
Source File: App.js From masakhane-web with MIT License | 5 votes |
function App() {
return (
<Router>
<div>
<Navbar style={{ backgroundColor: '#F2F0E9', width: '100%' }} >
<Navbar.Brand href="#home" variant="dark" style={{ fontFamily: 'lato', color: 'grey'}}>Masakhane</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav" className="justify-content-start">
<Nav className="ml-auto">
<Nav.Link href="/">Home</Nav.Link>
<Nav.Link href="/about">About</Nav.Link>
<Nav.Link href="/faq">FAQ</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
<Jumbotron xs={12} style={{ backgroundColor: '#F2F0E9', paddingTop: '50px', paddingBottom: '50px',backgroundSize: 'cover', backgroundSize: 'cover'}} fluid>
<Container style={{display:'flex', flexDirection:'row', alignItems:'center', justifyContent:'center'}}>
<Image src={image} className="d-none d-sm-block" width='240' height='250' roundedCircle style={{position:"absolute", left:0, right:0}}/>
<Row xs={12} md={8} style={{display:'flex', flexDirection:'column' ,justifyContent:'center', alignItems:'center'}}>
<h1 style={{ fontFamily: 'lato, sans-serif', fontWeight: 'lighter', fontSize: 80 }}>Masakhane</h1>
<p>Machine translation service for African languages</p>
</Row>
</Container>
</Jumbotron>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
<Route path="/faq">
<FAQPage />
</Route>
</Switch>
{/* <Container className="my-4">
<br />
<br />
<TranslateCard />
<br />
<p style={{fontSize: 12, color: 'gray'}}>This is a community research project. Read more about it <span style={{color: 'blue'}}>here</span></p>
</Container> */}
</div>
</Router>
);
}
Example #23
Source File: Stats.js From plenty-interface with GNU General Public License v3.0 | 5 votes |
Stats = (props) => {
const loading = useMemo(() => {
return (
props.valueLocked == null || props.plentyInWallet == null || props.plentyToHarvest == null
);
}, [props.plentyInWallet, props.plentyToHarvest, props.valueLocked]);
return (
<div className={clsx('p-3', 'bg-themed', styles.container)}>
<Row className="p-1">
<Col xs={12}>
<span className="d-flex font-weight-bold m-0 py-3">
Your Stats
<Image className="ml-2" src={greenBullet} />
</span>
<hr />
</Col>
</Row>
<Row className="p-1">
<Col xs={6}>
<Label
text={
loading ? null : (
<NumericLabel params={currencyOptionsWithSymbol}>
{props.valueLocked.toFixed(0)}
</NumericLabel>
)
}
subText={'Total value locked'}
icon={dollar}
iconClass={'mt-1'}
className={'pt-1'}
/>
</Col>
<Col xs={6}>
<Label
text={loading ? null : `${props.plentyToHarvest?.toFixed(5)}`}
subText={'PLENTY to harvest'}
icon={plentyToHarvest}
iconClass={'mt-1'}
/>
</Col>
</Row>
<hr className="mt-0" />
<Row className="p-1">
<Col xs={6}>
<Label
text={loading ? null : `${props.plentyInWallet?.toFixed(5)}`}
subText={'PLENTY in wallet'}
icon={plentyInWallet}
iconClass={'mt-1'}
/>
</Col>
<Col xs={6}>
<Label
text={loading ? null : `${props.xplentyBalance?.toFixed(5)}`}
subText={'xPLENTY in wallet'}
icon={xplentyIcon}
iconClass={'mt-1'}
/>
</Col>
</Row>
<Row className="p-1 mt-1">
<Col>
<Button
onClick={props.harvestAll}
color={'primary'}
className={'w-100'}
disabled={false}
loading={props.harvestAllOperations.loading}
>
Harvest all
</Button>
</Col>
</Row>
</div>
);
}
Example #24
Source File: SwapDetailsConfirmSwap.js From plenty-interface with GNU General Public License v3.0 | 4 votes |
SwapDetailsConfirmSwap = (props) => {
const [isOpen, setOpen] = useState(false);
const swapRoute = useMemo(() => {
if (props.routePath?.length > 2) {
return props.routePath.map((tokenName) => tokens.find((token) => token.name === tokenName));
}
return null;
}, [props.routePath]);
if (!props.firstTokenAmount && !swapRoute) {
return null;
}
return (
<div className={clsx('swap-detail-wrapper-cs', isOpen ? 'bg-themed-light' : 'closedbg')}>
<div
className="space-between-confirmswap"
onClick={() => setOpen(!isOpen)}
style={{ cursor: 'pointer' }}
>
<div className="flex">
<p className="price-formula-cs whitespace-prewrap flex flex-row">
1 {props.tokenIn.name} ={' '}
<OverlayTrigger
placement="auto"
overlay={
<Tooltip id="swap-token-out-tooltip" {...props}>
{props.isStableSwap
? Number(props.computedOutDetails.data.exchangeRate).toFixed(6)
: fromExponential(props.routeData.bestRouteUntilNoInput.tokenOutPerTokenIn)}
</Tooltip>
}
>
<div>
{props.isStableSwap
? Number(props.computedOutDetails.data.exchangeRate).toFixed(3)
: props.routeData.bestRouteUntilNoInput.tokenOutPerTokenIn
? Number(props.routeData.bestRouteUntilNoInput.tokenOutPerTokenIn).toFixed(3)
: 0}{' '}
{props.tokenOut.name === 'tez'
? 'TEZ'
: props.tokenOut.name === 'ctez'
? 'CTEZ'
: props.tokenOut.name}
</div>
</OverlayTrigger>
</p>
</div>
<span
className={`material-icons-round buttonanim button--trigger open-confirmswap-details ${
isOpen ? 'dropdown-open' : 'dropdown-close'
}`}
>
expand_more
</span>
{/* {isOpen ? (
<span className="material-icons-round flex buttonanim button--trigger-todisappear open-confirmswap-details">
keyboard_arrow_up
</span>
) : (
<span className="material-icons-round buttonanim button--trigger flex open-confirmswap-details">
keyboard_arrow_down
</span>
)} */}
</div>
<div className="buttonanim button--disapear-cs">
{props.firstTokenAmount &&
(isOpen ? (
<div className="scale-in-animation-confirm-swap">
<div className="flex flex-row mt-3 align-items-center">
<p className="swap-detail-amt-details-cs">Minimum received </p>
<OverlayTrigger
key="top"
placement="top"
overlay={
<Tooltip
id="button-tooltip-swap-details-minimum-received"
arrowProps={{ styles: { display: 'none' } }}
>
Your transaction will revert if there is a large, unfavorable price movement
before it is confirmed.
</Tooltip>
}
>
<span
style={{ cursor: 'pointer' }}
className="material-icons-round ml-1 swap-detail-amt-details-cs"
>
help_outline
</span>
</OverlayTrigger>
<p className="swap-detail-amt-details-cs ml-auto">
{props.computedOutDetails.data.finalMinimumOut
? props.computedOutDetails.data.finalMinimumOut
: '0.00'}{' '}
{props.tokenOut.name === 'tez'
? 'TEZ'
: props.tokenOut.name === 'ctez'
? 'CTEZ'
: props.tokenOut.name}
</p>
</div>
<div className="flex flex-row align-items-center">
<p className="swap-detail-amt-details-cs">Price Impact </p>
<OverlayTrigger
key="top"
placement="top"
overlay={
<Tooltip
id="button-tooltip-swap-details"
arrowProps={{ styles: { display: 'none' } }}
>
The difference between the market price and estimated price due to trade size.
</Tooltip>
}
>
<span
style={{ cursor: 'pointer' }}
className="material-icons-round ml-1 swap-detail-amt-details-cs"
>
help_outline
</span>
</OverlayTrigger>
<p className="swap-detail-amt-details-cs ml-auto">
{props.computedOutDetails.data.priceImpact
? props.computedOutDetails.data.priceImpact
: '0.00'}{' '}
%
</p>
</div>
<div className="flex flex-row align-items-center">
<p className="swap-detail-amt-details-cs">Fee </p>
<OverlayTrigger
key="top"
placement="top"
overlay={
<Tooltip
id="button-tooltip-swap-details"
arrowProps={{ styles: { display: 'none' } }}
>
Fees are 0.35% for each volatile swap and 0.10% for each stable swap.
</Tooltip>
}
>
<span
style={{ cursor: 'pointer' }}
className="material-icons-round ml-1 swap-detail-amt-details-cs"
>
help_outline
</span>
</OverlayTrigger>
<p className="swap-detail-amt-details-cs ml-auto">
{props.isStableSwap ? '0.10' : props.computedOutDetails.data.maxfee} %
</p>
</div>
{/* {props.isConfirmSwap && !props.isStableSwap && (
<div className="flex flex-row align-items-center">
<p className="swap-detail-amt-details-cs">xPlenty Fee </p>
<OverlayTrigger
key="top"
placement="top"
overlay={
<Tooltip
id="button-tooltip-swap-details"
arrowProps={{ styles: { display: 'none' } }}
>
A portion of each trade (0.09%) goes to xPLENTY holders as a protocol
incentive.
</Tooltip>
}
>
<span
style={{ cursor: 'pointer' }}
className="material-icons-round ml-1 swap-detail-amt-details-cs"
>
help_outline
</span>
</OverlayTrigger>
<p className="swap-detail-amt-details-cs ml-auto">
{props.firstTokenAmount / 1000} {props.tokenIn.name}
</p>
</div>
)} */}
{props.isConfirmSwap ? (
<div className="flex flex-row align-items-center">
<p className="swap-detail-amt-details-cs">Slippage tolerance </p>
<OverlayTrigger
key="top"
placement="top"
overlay={
<Tooltip
id="button-tooltip-swap-details"
arrowProps={{ styles: { display: 'none' } }}
>
Change the slippage tolerance in the transaction settings.
</Tooltip>
}
>
<span
style={{ cursor: 'pointer' }}
className="material-icons-round ml-1 swap-detail-amt-details-cs"
>
help_outline
</span>
</OverlayTrigger>
<p className="swap-detail-amt-details-cs ml-auto">{props.slippage} %</p>
</div>
) : null}
</div>
) : null)}
{props.firstTokenAmount && swapRoute && <hr />}
{swapRoute && (
<>
<div className="flex flex-row">
<p className="swap-detail-amt-details-cs">Route </p>
<OverlayTrigger
key="top"
placement="top"
overlay={
<Tooltip
id="button-tooltip-swap-details"
arrowProps={{ styles: { display: 'none' } }}
>
Routing through these tokens results in the best price for your trade
</Tooltip>
}
>
<span
style={{ cursor: 'pointer' }}
className="material-icons-round ml-1 swap-detail-amt-details-cs"
>
help_outline
</span>
</OverlayTrigger>
</div>
<div className="swap-detail-route-container mt-3">
{swapRoute.map((token, idx) => (
<div key={token.name} className="d-flex my-2">
<Image src={token.image} height={20} width={20} alt={''} />
<span className="ml-1 my-auto">{token.name}</span>
{swapRoute[idx + 1] && <MdChevronRight className="" fontSize={20} />}
</div>
))}
</div>
</>
)}
</div>
</div>
);
}
Example #25
Source File: Frontpage.js From plenty-interface with GNU General Public License v3.0 | 4 votes |
Frontpage = ({
homeStats,
tvl,
getTVL,
getHomeStats,
wallet,
plentyToHarvest,
plentyBalance,
getPlentyToHarvest,
getPlentyBalanceOfUser,
getTVLOfUser,
userTVL,
harvestAll,
openCloseModal,
modalData,
harvestAllOperations,
rpcNode,
xplentyBalance,
theme,
setLoader,
}) => {
const [showConfirmTransaction, setShowConfirmTransaction] = useState(false);
const [loaderMessage, setLoaderMessage] = useState({});
useEffect(() => {
const getAllData = () => {
getHomeStats();
getTVL();
if (wallet) {
getPlentyToHarvest(wallet);
getPlentyBalanceOfUser(wallet);
getTVLOfUser(wallet);
}
};
getAllData();
const intervalId = setInterval(getAllData(), 60 * 1000);
return () => clearInterval(intervalId);
}, [wallet, rpcNode]);
const handleClose = () => {
setShowConfirmTransaction(false);
};
const walletConnected = !!wallet;
const onHarvestAll = () => {
setShowConfirmTransaction(true);
setLoader(true);
!!wallet && harvestAll(wallet, setShowConfirmTransaction, setLoader);
};
useEffect(() => {
if (harvestAllOperations.completed || harvestAllOperations.failed) {
setLoader(false);
setLoaderMessage({
message: harvestAllOperations.completed ? 'Transaction confirmed' : 'Transaction failed',
type: harvestAllOperations.completed ? 'success' : 'error',
});
setTimeout(() => {
setLoaderMessage({});
}, 5000);
} else {
setLoaderMessage({});
}
}, [harvestAllOperations]);
return (
<>
<Container fluid>
<div className={`d-flex flex-column ${styles.fullScreen}`}>
<FrontPageGradientDiv className={`row flex-grow-1 ${styles.homePageBanner}`}>
<div
className={clsx(
`${styles.centerAlign}`,
'py-5',
walletConnected ? ['col-lg-6', 'col-sm-12', 'col-md-12'] : 'col-sm-12 col-md-12',
)}
>
<div
className={clsx(
walletConnected
? [
'd-flex',
'flex-column',
'col-10',
'col-xl-9',
'm-auto',
'py-lg-5',
'text-center',
'align-items-center',
'ml-lg-auto',
'mr-lg-0',
'align-items-lg-start',
'text-lg-left',
]
: [
'col-10',
'col-lg-7',
'm-auto',
'd-flex',
'align-items-center',
'text-center',
'flex-column',
'py-lg-5',
],
)}
>
<h5 className={`mb-3 text-white font-weight-light ${styles.textMulish}`}>
Total Value Locked
</h5>
<h1 className="mb-3 text-white font-weight-bold">
<NumericLabel params={currencyOptionsWithSymbol}>{tvl ? tvl : '0'}</NumericLabel>
</h1>
<h5
className={`mb-4 text-white text-mulish font-weight-light ${styles.textMulish}`}
>
Bridge, trade, and earn. There is plenty of DeFi to explore on Tezos.
</h5>
<Link to={'swap'} className="text-decoration-none">
<Button
className={`px-lg-3 btn-frontPage ${styles.button}`}
color={'tertiary'}
onClick={null}
>
Enter App
</Button>
</Link>
</div>
</div>
{walletConnected && (
<div className={`py-3 pb-lg-5 col-lg-6 col-sm-12 ${styles.centerAlign}`}>
<div
className="col-lg-9 col-xl-7 m-auto py-lg-5 px-0 text-center
align-items-center align-items-lg-start text-lg-left"
>
<Stats
wallet={wallet}
harvestAll={onHarvestAll}
valueLocked={userTVL}
plentyEarned={251_532}
plentyInWallet={plentyBalance}
plentyToHarvest={plentyToHarvest}
harvestAllOperations={harvestAllOperations}
xplentyBalance={xplentyBalance}
/>
</div>
</div>
)}
</FrontPageGradientDiv>
<Row className="row bg-themed border-bottom-themed-dark-none">
<Col sm={6} md={4} xl={2} className="px-5 pb-2 pt-3 m-sm-auto">
<Label
text={
homeStats.price ? (
<NumericLabel params={currencyOptions}>{homeStats.price}</NumericLabel>
) : (
'0'
)
}
icon={theme === 'light' ? dollar : dollarDark}
subText={'Price'}
/>
</Col>
<Col sm={6} md={4} xl={2} className="px-5 pb-2 pt-3 m-sm-auto">
<Label
text={
homeStats.marketcap ? (
<NumericLabel params={currencyOptions}>
{homeStats.marketcap.toFixed(0)}
</NumericLabel>
) : (
'0'
)
}
icon={theme === 'light' ? marketCap : marketCapDark}
subText={'Market Cap'}
/>
</Col>
<Col sm={6} md={4} xl={2} className="px-5 pb-2 pt-3 m-sm-auto">
<Label
text={
homeStats.total_minted ? (
<NumericLabel params={currencyOptions}>
{homeStats.total_minted.toFixed(0)}
</NumericLabel>
) : (
'0'
)
}
icon={theme === 'light' ? farms : farmsDark}
subText={'Total minted'}
/>
</Col>
<Col sm={6} md={4} xl={2} className="px-5 pb-2 pt-3 m-sm-auto">
<Label
text={
homeStats.total_burned ? (
<NumericLabel params={currencyOptions}>
{homeStats.total_burned.toFixed(0)}
</NumericLabel>
) : (
'0'
)
}
icon={theme === 'light' ? totalBurned : totalBurnedDark}
subText={'Total burned'}
/>
</Col>
<Col sm={6} md={4} xl={2} className="px-5 pb-2 pt-3 m-sm-auto">
<Label
text={
homeStats.circulating_supply ? (
<NumericLabel params={currencyOptions}>
{homeStats.circulating_supply.toFixed(0)}
</NumericLabel>
) : (
'0'
)
}
icon={theme === 'light' ? circulatingSupply : circulatingSupplyDark}
subText={'Circulating Supply'}
/>
</Col>
<Col sm={6} md={4} xl={2} className="px-5 pb-2 pt-3 m-sm-auto">
<Label
text={
homeStats.plenty_per_block ? (
<NumericLabel params={currencyOptions}>
{homeStats.plenty_per_block}
</NumericLabel>
) : (
'0'
)
}
subText={'New PLENTY/Block'}
icon={theme === 'light' ? plentyBlock : plentyBlockDark}
/>
</Col>
</Row>
</div>
<Row>
<Col xs={12} className="text-center my-5">
<h2 className="font-weight-bold">
<p>Plenty of DeFi on Tezos</p>
</h2>
</Col>
</Row>
<Row className="mb-4 mx-lg-5">
<div
className="col-xl-11 row m-auto"
style={{
display: 'flex',
justifyContent: 'center',
}}
>
<Col xs={12} md={6} xl={3} className="mb-3 d-flex">
<LinkTile
text={'Transfer your tokens from Ethereum to Tezos within five minutes.'}
linkTo={'/bridge'}
linkText={'Enter Bridge'}
headerIcon={theme === 'light' ? bridge : bridgeDark}
headerText={'Bridge'}
/>
</Col>
<Col xs={12} md={6} xl={3} className="mb-3 d-flex">
<LinkTile
text={'Swap tokens instantly with high liquidity and audited smart contracts.'}
linkTo={'/swap'}
linkText={'Enter Exchange'}
headerIcon={theme === 'light' ? amm : ammDark}
headerText={'Swap'}
/>
</Col>
<Col xs={12} md={6} xl={3} className="mb-3 d-flex">
<LinkTile
text={'Add liquidity for any trading pair and start earning trading fees.'}
linkTo={'/liquidity'}
linkText={'Add Liquidity'}
headerIcon={theme === 'light' ? liquidity : liquidityDark}
headerText={'Pool'}
/>
</Col>
<Col xs={12} md={6} xl={3} className="mb-3 d-flex">
<LinkTile
text={
'Earn PLENTY and other tokens by staking Plenty Liquidity Provider tokens in a farm.'
}
linkTo={'/farms'}
linkText={'Enter Farms'}
headerIcon={theme === 'light' ? farms2 : farms2Dark}
headerText={'Farm'}
/>
</Col>
</div>
</Row>
<Row className="py-5 bg-themed-alt">
<Col lg={6} xs={12}>
<div
className="col-10 col-lg-9 col-xl-7 m-auto py-lg-5 px-0 text-center
align-items-center align-items-lg-start text-lg-left"
>
<h2 className={`mb-1 font-weight-bold ${styles.about}`}>
<p>About Plenty</p>
</h2>
<div className={`mb-3 ${styles.aboutSubtext}`}>
<span>
<p>
Plenty is expanding DeFi use cases on Tezos towards a full scale decentralized
financial ecosystem. Empowering traders, liquidity providers & developers to
participate in an open financial marketplace.
</p>
</span>
</div>
<a href={'https://plentydefi.medium.com/'} target="_blank" rel="noreferrer">
<Medium className="mr-2 icon-themed" />
</a>
<a href={'https://discord.gg/9wZ4CuvkuJ'} target="_blank" rel="noreferrer">
<Discord className="mr-2 icon-themed" />
</a>
<a href={'https://twitter.com/PlentyDeFi'} target="_blank" rel="noreferrer">
<Twitter className="mr-2 icon-themed" />
</a>
</div>
</Col>
<Col lg={6} className="d-none d-lg-block">
<div className="p-lg-5">
<Image src={plentyBig} />
</div>
</Col>
</Row>
<FrontPageBottomGradientDiv className="row">
<Col className="pt-5">
<Row>
<Col xs={12} md={6}>
<div
className="col-10 col-xl-8 m-auto pb-5 py-lg-3 px-0
align-items-start text-left"
>
<h2 className="text-white font-weight-bold">Frequently asked questions</h2>
</div>
</Col>
</Row>
<Row className="border-bottom-themed">
<Col xs={12} md={6}>
<div
className="col-10 col-xl-8 m-auto py-lg-5 px-0
align-items-start text-left"
>
<Accordion isOpen={true} text={'What is Plenty?'} className={styles.divider}>
<div>
<p className="text-white">
The Plenty protocol enables swapping of fungible tokens on Tezos.
</p>
<p className="text-white">
You can only swap tokens on Plenty if there is enough liquidity for those
tokens. Providing liquidity will get you Plenty Liquidity Provider (PLP)
tokens, which will generate rewards in the form of trading fees for making
sure there's always liquidity for the exchange to use.
</p>
<p className="text-white">
Yield farming lets users that are providing liquidity earn PLENTY rewards by
locking their PLP tokens into a farm.
</p>
</div>
</Accordion>
<Accordion text={'How does Plenty work?'} className={styles.divider}>
<div>
<p className="text-white">
Plenty is a collection of smart contracts to make liquidity pools and
corresponding markets that are compatible with each other. The architecture
is based on
<a
href={
'https://docs.uniswap.org/protocol/V2/concepts/protocol-overview/how-uniswap-works'
}
target="_blank"
rel="noreferrer"
>
Uniswap V2
</a>
.
</p>
<p className="text-white">
Each pool is defined by a smart contract that includes a few functions to
enable swapping tokens, adding liquidity and more. At its core each pool
uses the function x*y=k to maintain a curve along which trades can happen.
The pools keep track of reserves (liquidity) and update those reserves every
single time someone trades. Because the reserves are automatically
rebalanced, a liquidity pool can always be used to buy or sell a token
without requiring a counterparty on the other side of a trade.
</p>
</div>
</Accordion>
<Accordion text={'Why can’t I trade native tez?'} className={styles.divider}>
<div>
<p className="text-white">
Plenty is the first token-to-token Automated Market Maker (AMM) on Tezos.
This means that native tez trading is not supported. However, trading with a
collateralized version of tez, called
<a href={'https://ctez.app/'} target="_blank" rel="noreferrer">
ctez
</a>
is supported.
</p>
<p className="text-white">
Ctez solves the issue of using tez inside DeFi contracts without worrying
about the governance matter of "who should be the baker" and
without the opportunity cost of not delegating.
</p>
</div>
</Accordion>
</div>
</Col>
<Col xs={12} md={6}>
<div
className="col-10 col-xl-8 m-auto py-lg-5 px-0
align-items-start text-left"
>
<Accordion text={'How do I use Plenty?'} className={styles.divider}>
<div>
<p className="text-white">
First you’ll need a Tezos wallet and some tez. Tez is available at all big
crypto exchanges like
<a href={'https://www.coinbase.com/'} target="_blank" rel="noreferrer">
Coinbase
</a>
,
<a href={'https://www.kraken.com/'} target="_blank" rel="noreferrer">
Kraken
</a>
and
<a href={'https://www.binance.com/'} target="_blank" rel="noreferrer">
Binance
</a>
. Do you have some tez? Go to
<a href={'https://ctez.app/'} target="_blank" rel="noreferrer">
ctez.app
</a>
to swap it for ctez!
</p>
<p className="text-white">
Each transaction on Tezos comes with a small gas fee, paid in tez, which is
a fee for the bakers to keep the Proof of Stake network running. So make
sure you to keep some tez for these fees.
</p>
<p className="text-white">
If you are a DeFi user from another blockchain, you can wrap your assets
using the
<a href={'https://www.benderlabs.io/wrap'} target="_blank" rel="noreferrer">
Wrap Protocol
</a>
. Wrap tokens like USDC, BUSD, LINK, MATIC, or WBTC on the Ethereum
blockchain, and use them on Plenty to trade and earn.
</p>
</div>
</Accordion>
<Accordion text={'How are prices determined?'} className={styles.divider} s>
<div>
<p className="text-white">
Prices are determined by the amount of each token in a pool. The smart
contract maintains a constant using the following function: x*y=k. For
example, x = tokenABC, y = tokenXYZ, and k = constant. During each trade, a
certain amount of one token is removed from the pool for an amount of the
other token. To maintain k, the balances held by the smart contract are
adjusted during the execution of the trade, thereby changing the price.
</p>
</div>
</Accordion>
<Accordion text={'Are there risks?'} className={styles.divider}>
<div>
<p className="text-white">
Using smart contracts always brings risk. To reduce this risk, the Plenty
smart contracts are audited. Both the AMM and staking smart contracts
<a
href={
'https://plenty-defi.notion.site/Audits-70fdccf107ec42feb0bcf720cb6c5ba5'
}
target="_blank"
rel="noreferrer"
>
were audited
</a>
successfully.
</p>
<p className="text-white">
For liquidity providers there is the risk of Impermanent loss. This is a
price difference that can occur when holding tokens in an AMM liquidity pool
instead of holding them in your wallet. It occurs when the price of tokens
inside an AMM diverge in any direction. The more divergence, the greater the
impermanent loss.
</p>
</div>
</Accordion>
<Image className={'mt-4'} src={plentyMedium} />
</div>
</Col>
</Row>
<Row className="justify-content-center mb-5 mt-4">
<Footer />
</Row>
</Col>
</FrontPageBottomGradientDiv>
</Container>
<InfoModal
open={modalData.open === HOME_PAGE_MODAL.TRANSACTION_SUCCESS}
theme={theme}
InfoMessage={'Harvest tokens'}
onClose={() => openCloseModal({ open: HOME_PAGE_MODAL.NULL, transactionId: '' })}
message={'Transaction submitted'}
buttonText={'View on Block Explorer'}
onBtnClick={
!modalData.transactionId
? undefined
: () => window.open(`https://tzkt.io/${modalData.transactionId}`, '_blank')
}
/>
{modalData.snackbar && (
<Loader
loading={harvestAllOperations.processing}
loaderMessage={loaderMessage}
setLoaderMessage={setLoaderMessage}
content={'Harvest tokens'}
theme={theme}
onBtnClick={
!modalData.transactionId
? undefined
: () => window.open(`https://tzkt.io/${modalData.transactionId}`, '_blank')
}
/>
)}
<ConfirmTransaction
show={showConfirmTransaction}
theme={theme}
content={'Harvest tokens'}
onHide={handleClose}
/>
</>
);
}
Example #26
Source File: Tokens.js From plenty-interface with GNU General Public License v3.0 | 4 votes |
Tokens = () => {
const {
data = [],
isLoading,
error,
} = useGetTokensQuery(undefined, {
pollingInterval: 30_000,
});
const { data: priceChangeData = {}, isLoading: priceChangeLoading } = useGet7DaysChangeQuery(
undefined,
{
pollingInterval: 30_000,
},
);
const { imgPaths } = useLazyImages({ data });
const { isOnlyFavTokens, setIsOnlyFavTokens, favoriteTokens, editFavoriteTokenList } =
useFavoriteToken('token');
const { positiveOrNegative, valueFormat, stringSort, numberSort } = useTableNumberUtils();
// ? Move to React Table filter later
const finalData = useMemo(() => {
if (isOnlyFavTokens) {
return data?.filter((datum) => favoriteTokens.includes(datum.symbol_token)) ?? [];
}
return data;
}, [favoriteTokens, isOnlyFavTokens, data]);
const columns = useMemo(
() => [
{
Header: (
<TokensSymbolHeader
className={styles.favoriteIcon}
isOnlyFavTokens={isOnlyFavTokens}
setIsOnlyFavTokens={setIsOnlyFavTokens}
/>
),
id: 'favorite',
accessor: 'symbol_token',
disableSortBy: true,
Cell: (row) => (
<TokensSymbol
tokenSymbol={row.value}
className={styles.favoriteIcon}
favoriteTokens={favoriteTokens}
editFavoriteTokenList={editFavoriteTokenList}
/>
),
},
{
Header: <span className="ml-2">Name</span>,
id: 'token',
accessor: 'symbol_token',
sortType: stringSort,
Cell: (row) => (
<div className="d-flex pl-2 align-items-center">
<Image src={imgPaths[row.value]?.url} height={32} width={32} alt={''} />
<span className="ml-2 mr-4">
{row.value === 'tez' ? 'TEZ' : row.value === 'ctez' ? 'CTEZ' : row.value}
</span>
</div>
),
width: 120,
},
{
Header: 'Price',
accessor: 'token_price',
sortType: numberSort,
Cell: (row) => <span title={row.value}>{valueFormat(row.value)}</span>,
},
{
Header: '24h Change',
accessor: 'price_change_percentage',
sortType: numberSort,
Cell: (row) => (
<span>{positiveOrNegative(valueFormat(row.value, { percentChange: true }))}</span>
),
},
{
Header: '24h Volume',
accessor: 'volume_token',
sortType: numberSort,
Cell: (row) => <span>{valueFormat(row.value)}</span>,
},
{
Header: 'Liquidity',
accessor: 'liquidity',
sortType: numberSort,
Cell: (row) => <span>{valueFormat(row.value)}</span>,
},
{
id: 'price7d',
Header: 'Last 7 Days',
accessor: 'symbol_token',
Cell: (row) => {
let value = [...(priceChangeData[row.value] ?? [])].reverse();
if (priceChangeLoading) return <div />;
if (value.length === 0) return <div>N/A</div>;
const changePositive = value[value.length - 1].value >= value[0].value;
if (value.length <= 38) {
const timeData = priceChangeData.PLENTY.map((x) => ({
...x,
value: undefined,
})).reverse();
value = [...timeData.filter((x) => x.time < value[0].time), ...value];
}
return (
<SimpleLineChart
data={value}
color={changePositive ? '#4FBF67' : '#FF7A68'}
className="mx-2"
/>
);
},
minWidth: 170,
disableSortBy: true,
},
{
disableSortBy: true,
Header: '',
id: 'trade',
accessor: (x) => (
<Link style={{ textDecoration: 'none' }} to={`/swap?from=${x.symbol_token}`}>
<Button color="primary" className={styles.tradeBtn}>
Trade
</Button>
</Link>
),
width: 120,
},
],
[
isOnlyFavTokens,
setIsOnlyFavTokens,
stringSort,
numberSort,
favoriteTokens,
editFavoriteTokenList,
imgPaths,
priceChangeData,
priceChangeLoading,
],
);
const [searchQuery, setSearchQuery] = useState('');
return (
<>
<Container fluid className={clsx(styles.tokens, styles.tokensTable)}>
<div className="w-100 d-flex justify-content-between px-5 align-items-center">
<h5 className="font-weight-bolder">Tokens</h5>
<InputGroup className={styles.searchBar}>
<InputGroup.Prepend>
<InputGroup.Text className={`${styles.searchIcon} border-right-0`}>
<BsSearch />
</InputGroup.Text>
</InputGroup.Prepend>
<FormControl
placeholder="Search"
className={`shadow-none border-left-0 ${styles.searchBox}`}
value={searchQuery}
onChange={(ev) => setSearchQuery(ev.target.value)}
/>
</InputGroup>
</div>
{data.length > 0 && (
<div>
<Table searchQuery={searchQuery} data={finalData} columns={columns} />
</div>
)}
{data.length === 0 && (isLoading || error) && (
<div className="d-flex justify-content-between w-100" style={{ height: 800 }}>
<div className="m-auto">
{error ? <div>Something went wrong</div> : <PuffLoader color={'#813CE1'} size={56} />}
</div>
</div>
)}
</Container>
<FavoriteIconGradient />
</>
);
}
Example #27
Source File: NFTprofile.js From RC4Community with Apache License 2.0 | 4 votes |
GalleryModal = ({
handleClose,
show,
assets,
handleImage,
uid,
select,
load,
setLoad,
errMess,
setErrMess,
}) => {
const [upsertNFT, { data, loading, error, reset }] = useMutation(UPSERT_NFT);
useEffect(() => {
if (data) {
setLoad(false);
}
}, [data]);
if (loading) {
setLoad(true);
}
const handleSubmit = (e) => {
e.preventDefault();
const assetSelected = assets[select.split("_")[1]];
const address = assetSelected.asset_contract.address;
const token = assetSelected.token_id;
upsertNFT({ variables: { id: uid, address: address, token: token } });
};
if (error) {
if (error.graphQLErrors[0].extensions.code == "instance not found") {
setErrMess("User not found");
}
if (error.graphQLErrors[0].extensions.code == "instance not unique") {
setErrMess("NFT is owned by someone else");
} else {
setErrMess(error.message);
}
setTimeout(() => {
reset();
setLoad(false);
}, 5000);
}
return (
<>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Select a NFT</Modal.Title>
</Modal.Header>
{error && (
<Alert variant={"danger"}>{errMess} - Please try again!</Alert>
)}
<Modal.Body className={styles.selectNFT}>
{assets
? assets.map(
(a, i) =>
a.image_url && (
<div key={i} className={styles.asset}>
<Image
key={i}
onClick={handleImage}
className={`${styles.assetImage} nim_${i}`}
src={a.image_url}
/>
</div>
)
)
: "No assets available"}
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button variant="primary" disabled={load} onClick={handleSubmit}>
{!load ? (
"Save Changes"
) : (
<Spinner
as="span"
animation="grow"
size="sm"
role="status"
aria-hidden="true"
/>
)}
</Button>
</Modal.Footer>
</Modal>
</>
);
}
Example #28
Source File: user-header.js From stacker.news with MIT License | 4 votes |
export default function UserHeader ({ user }) { const [editting, setEditting] = useState(false) const me = useMe() const router = useRouter() const client = useApolloClient() const [setName] = useMutation(NAME_MUTATION) const isMe = me?.name === user.name const Satistics = () => <div className={`mb-2 ml-0 ml-sm-1 ${styles.username} text-success`}>{isMe ? `${user.sats} sats \\ ` : ''}{user.stacked} stacked</div> const UserSchema = Yup.object({ name: Yup.string() .required('required') .matches(/^[\w_]+$/, 'only letters, numbers, and _') .max(32, 'too long') .test({ name: 'name', test: async name => { if (!name || !name.length) return false const { data } = await client.query({ query: NAME_QUERY, variables: { name }, fetchPolicy: 'network-only' }) return data.nameAvailable }, message: 'taken' }) }) const lnurlp = encodeLNUrl(new URL(`https://stacker.news/.well-known/lnurlp/${user.name}`)) return ( <> <div className='d-flex mt-2 flex-wrap flex-column flex-sm-row'> <div className='position-relative' style={{ width: 'fit-content' }}> <Image src={user.photoId ? `https://${process.env.NEXT_PUBLIC_AWS_UPLOAD_BUCKET}.s3.amazonaws.com/${user.photoId}` : '/dorian400.jpg'} width='135' height='135' className={styles.userimg} /> {isMe && <PhotoEditor userId={me.id} />} </div> <div className='ml-0 ml-sm-1 mt-3 mt-sm-0 justify-content-center align-self-sm-center'> {editting ? ( <Form schema={UserSchema} initial={{ name: user.name }} validateImmediately onSubmit={async ({ name }) => { if (name === user.name) { setEditting(false) return } const { error } = await setName({ variables: { name } }) if (error) { throw new Error({ message: error.toString() }) } router.replace({ pathname: router.pathname, query: { ...router.query, name } }) client.writeFragment({ id: `User:${user.id}`, fragment: gql` fragment CurUser on User { name } `, data: { name } }) setEditting(false) }} > <div className='d-flex align-items-center mb-2'> <Input prepend=<InputGroup.Text>@</InputGroup.Text> name='name' autoFocus groupClassName={styles.usernameForm} showValid /> <SubmitButton variant='link' onClick={() => setEditting(true)}>save</SubmitButton> </div> </Form> ) : ( <div className='d-flex align-items-center mb-2'> <div className={styles.username}>@{user.name}</div> {isMe && <Button className='py-0' style={{ lineHeight: '1.25' }} variant='link' onClick={() => setEditting(true)}>edit nym</Button>} </div> )} <Satistics user={user} /> <ModalButton clicker={ <Button className='font-weight-bold ml-0 ml-sm-2'> <LightningIcon width={20} height={20} className='mr-1' />{user.name}@stacker.news </Button> } > <a className='d-flex m-auto p-3' style={{ background: 'white', width: 'fit-content' }} href={`lightning:${lnurlp}`}> <QRCode className='d-flex m-auto' value={lnurlp} renderAs='svg' size={300} /> </a> <div className='text-center font-weight-bold text-muted mt-3'>click or scan</div> </ModalButton> </div> </div> <Nav className={styles.nav} activeKey={router.asPath.split('?')[0]} > <Nav.Item> <Link href={'/' + user.name} passHref> <Nav.Link>bio</Nav.Link> </Link> </Nav.Item> <Nav.Item> <Link href={'/' + user.name + '/posts'} passHref> <Nav.Link>{user.nitems} posts</Nav.Link> </Link> </Nav.Item> <Nav.Item> <Link href={'/' + user.name + '/comments'} passHref> <Nav.Link>{user.ncomments} comments</Nav.Link> </Link> </Nav.Item> {isMe && <Nav.Item> <Link href='/satistics?inc=invoice,withdrawal' passHref> <Nav.Link eventKey='/satistics'>satistics</Nav.Link> </Link> </Nav.Item>} </Nav> </> ) }
Example #29
Source File: index.jsx From nightfall_3 with Creative Commons Zero v1.0 Universal | 4 votes |
Transactions = () => {
const [txs, setTxs] = React.useState([]);
const [isActive, setActive] = React.useState('all');
const [showModal, setShowModal] = React.useState({ show: false });
const [delay, setDelay] = React.useState(50);
const [etherscan] = React.useState(
ChainIdMapping[process.env.REACT_APP_MODE].chainName === 'Ethereum Mainnet'
? 'etherscan.io'
: 'goerli.etherscan.io',
);
const initialPrices = {};
supportedTokens.forEach(t => {
initialPrices[t.id] = 0;
}, {});
const [currencyValues, setCurrencyValues] = React.useState({ now: 0, ...initialPrices });
React.useEffect(async () => {
if (!getPricing()) await setPricing(supportedTokens.map(t => t.id));
else if (Date.now() - getPricing().time > 86400)
await setPricing(supportedTokens.map(t => t.id));
setCurrencyValues(getPricing());
}, []);
useInterval(async () => {
console.log('currencyVals', currencyValues);
const transactionsDB = await getAllTransactions();
const commitmentsDB = await getAllCommitments();
const commits = commitmentsDB.map(c => c._id);
const nullifiers = commitmentsDB.map(c => c.nullifier);
const transactions = Array.from(new Set(transactionsDB)).filter(
t =>
t.commitments.some(c => commits.includes(c)) ||
t.nullifiers.some(n => nullifiers.includes(n)),
);
const shieldContractAddress = shieldAddressGet();
const shieldContractInstance = await getContractInstance(
SHIELD_CONTRACT_NAME,
shieldContractAddress,
);
setDelay(20000);
const blocks = await findBlocksFromBlockNumberL2(-1);
const promisedTxs = transactions.map(async tx => {
const safeTransactionType = BigInt(tx.transactionType).toString();
let value = BigInt(tx.value);
// The value of transfers need to be derived from the components making up the transfer
// Add sum nullifiers in transactions
// Subtract sum of commitments we have.
if (safeTransactionType === '1' || safeTransactionType === '2')
commitmentsDB.forEach(c => {
if (tx.nullifiers.includes(c.nullifier)) value -= BigInt(c.preimage.value);
else if (tx.commitments.includes(c._id)) value += BigInt(c.preimage.value);
});
const safeValue = value.toString();
const { ercAddress } = commitmentsDB.find(c => {
return tx.commitments.includes(c._id) || tx.nullifiers.includes(c.nullifier);
})?.preimage ?? {
ercAddress: '0x00',
};
// eslint-disable-next-line no-param-reassign
if (tx?.blockNumberL2) tx.isOnChain = tx.blockNumberL2; // Temp for handling transfers
blocks.forEach(b => {
if (tx.isOnChain >= 0) return;
if (b.transactionHashes.includes(tx._id)) {
// eslint-disable-next-line no-param-reassign
tx.isOnChain = b.blockNumberL2;
}
// eslint-disable-next-line no-param-reassign
else tx.isOnChain = -1;
});
let withdrawReady = false;
if (
safeTransactionType === '3' &&
tx.isOnChain > 0 &&
tx.withdrawState !== 'finalised' &&
Math.floor(Date.now() / 1000) - tx.createdTime > 3600 * 24 * 7
) {
withdrawReady = await isValidWithdrawal(tx._id, shieldContractAddress);
}
if (tx.withdrawState === 'instant') {
const newOwner = await shieldContractInstance.methods.advancedWithdrawals(tx._id).call();
const myAddress = await Web3.getAccount();
if (newOwner.toLowerCase() !== ZERO && newOwner.toLowerCase() !== myAddress.toLowerCase())
// eslint-disable-next-line no-param-reassign
tx.withdrawState = 'fulfilled';
}
const { logoURI, decimals, id, symbol } = supportedTokens.find(
t => t.address.toLowerCase() === `0x${ercAddress.slice(-40).toLowerCase()}`,
) ?? {
logoURI: null,
decimals: 0,
id: '',
};
const currencyValue = id !== '' ? currencyValues[id] : 0;
return {
...tx,
transactionHash: tx._id,
txType: safeTransactionType,
value: safeValue,
now: Math.floor(Date.now() / 1000),
logoURI,
decimals,
currencyValue,
symbol,
withdrawReady,
};
});
const mappedTxs = (await Promise.all(promisedTxs)).sort(
(a, b) => b.createdTime - a.createdTime,
);
console.log('Transactions', transactions);
setTxs(mappedTxs);
}, delay);
function downloadFile(content) {
const a = document.createElement('a');
const file = new Blob([content], { type: 'text/plain' });
a.href = URL.createObjectURL(file);
a.download = 'pnf_bkp.json';
a.click();
}
const handleExportIndedexDB = async () => {
const exportedDB = await exportIndexdDB('nightfall_commitments');
const filteredTables = exportedDB.filter(
arr => arr.table === 'commitments' || arr.table === 'transactions',
);
downloadFile(JSON.stringify(filteredTables));
};
return (
<div className="pagePartition" style={{ width: '100%' }}>
<TxInfoModal onHide={() => setShowModal(false)} {...showModal} />
<div className="infoWrapper">
<div className="wrapperTabList">
<div className="tab-list">
<div
className={`tab-list-item ${isActive === 'all' ? 'active' : ''}`}
onClick={() => setActive('all')}
>
All Transactions
</div>
<div
className={`tab-list-item ${isActive === 'pending' ? 'active' : ''}`}
onClick={() => setActive('pending')}
>
Pending
</div>
<div
className={`tab-list-item ${isActive === 'deposit' ? 'active' : ''}`}
onClick={() => setActive('deposit')}
>
Deposits
</div>
<div
className={`tab-list-item ${isActive === 'transfer' ? 'active' : ''}`}
onClick={() => setActive('transfer')}
>
Transfers
</div>
<div
className={`tab-list-item ${isActive === 'withdraw' ? 'active' : ''}`}
onClick={() => setActive('withdraw')}
>
Withdraws
</div>
</div>
<div>
<button onClick={() => handleExportIndedexDB()} className="exportTransactionsButton">
Export transactions
</button>
</div>
</div>
<div className="separator" />
<div className="innerWrapper">
{txs
.filter(f => {
switch (isActive) {
case 'deposit':
return f.txType === '0';
case 'transfer':
return f.txType === '1' || f.txType === '2';
case 'withdraw':
return f.txType === '3';
case 'pending':
return f.isOnChain === -1;
default:
return f;
}
})
.map(tx => (
<Row
key={tx.transactionHash}
className="transactionRow"
onClick={() =>
setShowModal({
show: true,
transactionhash: tx.transactionHash,
symbol: tx.symbol,
value: new BigFloat(BigInt(tx.value), tx.decimals).toFixed(4),
_id: tx._id,
recipientaddress: tx.recipientAddress,
withdrawready: tx.withdrawReady ? 1 : 0,
txtype: tx.txType,
})
}
>
<Row>
<div className="transactionDetails">
<div>
{tx.isOnChain >= 0 ? (
<Image src={tickBox} />
) : (
<Spinner animation="border" variant="warning" />
)}
</div>
<div style={{ marginLeft: '14px' }}>
{/* Details */}
<div style={{ display: 'flex', fontWeight: '600', fontSize: '14px' }}>
{/* tx-type-time */}
<div style={{ textTransform: 'capitalize' }}>
{txTypeOptions[tx.txType]}
</div>
{/* tx-type-time-type */}
<div style={{ color: '#b0b4bb', paddingLeft: '5px' }}>
{/* tx-type-time-time */}
{displayTime(tx.createdTime, tx.now)}
</div>
</div>
<div
style={{
display: 'flex',
color: '#52555d',
fontWeight: '400',
fontSize: '12px',
lineHeight: '16px',
}}
>
{/* tx-status-hash */}
{/* <div> 1/3 • Action Required • From Mumbai to Goerli</div> */}
<div style={{ textTransform: 'capitalize' }}>
{tx.isOnChain >= 0 ? 'Success' : 'Pending'} • {txTypeDest[tx.txType]}{' '}
{!tx.withdrawState ? '' : `• ${tx.withdrawState}`}
</div>
</div>
</div>
</div>
<div
style={{
padding: '20px',
width: '42%',
alignItems: 'center',
display: 'flex',
}}
>
{/* details-section */}
<div style={{ display: 'block' }}>
{/* token-image */}
<img src={tx.logoURI} alt="" height="32" width="32" />
</div>
<div
style={{
width: 'calc(50% - 50px)',
marginLeft: '8px',
flexShrink: '0',
}}
>
{/* amount-details */}
<div style={{ fontWeight: '600', fontSize: '14px', lineHeight: '20px' }}>
{new BigFloat(BigInt(tx.value), tx.decimals).toFixed(4)} {tx.symbol}
</div>
<div
style={{
color: '#52555d',
marginTop: '4px',
wordBreak: 'break-all',
fontWeight: '400',
fontSize: '12px',
lineHeight: '16px',
}}
>
$
{new BigFloat(BigInt(tx.value), tx.decimals)
.mul(tx.currencyValue)
.toFixed(4)}
</div>
</div>
<div
style={{
marginLeft: '8px',
width: 'calc(50% - 50px)',
flexShrink: '0',
}}
>
{/* Transaction Details */}
<div style={{ fontWeight: '600', fontSize: '14px', lineHeight: '20px' }}>
{/* Transaction Hash label */}
Transaction Hash
</div>
<div
style={{
color: '#52555d',
marginTop: '4px',
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
fontWeight: '400',
fontSize: '12px',
lineHeight: '16px',
}}
>
{/* Tooltip */}
<img src={polygonChainImage} alt="Polygon Chain" height="16" width="16" />
<div style={{ marginLeft: '4px' }}>{`${tx.transactionHash.slice(
0,
5,
)}...${tx.transactionHash.slice(-5)}`}</div>
</div>
</div>
<a
href={`https://${etherscan}/tx/${tx.l1Hash}`}
className="etherscanLink"
rel="noopener noreferrer"
target="_blank"
style={{ marginLeft: '20px' }}
onClick={e => e.stopPropagation()}
>
<Image src={etherscanArrow} />
</a>
</div>
</Row>
{tx.txType === '3' && tx.isOnChain > 0 && !tx.withdrawState ? (
<WithdrawTransaction
withdrawready={tx.withdrawReady}
transactionhash={tx.transactionHash}
/>
) : (
<></>
)}
</Row>
))}
</div>
<Row>
<div className="bottomSection">
<img src={bridgeInfoImage} alt="" height="219" width="326" />
</div>
</Row>
</div>
</div>
);
}