@material-ui/core#Zoom TypeScript Examples
The following examples show how to use
@material-ui/core#Zoom.
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: index.tsx From rugenerous-frontend with MIT License | 6 votes |
//import Swap from "@rugenerous/interface/src/pages/Swap"
function Swap() {
const [anchorEl, setAnchorEl] = useState(null);
const dispatch = useDispatch();
const { provider, address, connect, chainID, checkWrongNetwork } = useWeb3Context();
const [view, setView] = useState(0);
const [quantity, setQuantity] = useState<string>("");
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const handleClick = (event: any) => {
setAnchorEl(anchorEl ? null : event.currentTarget);
};
const open = Boolean(anchorEl);
return (
<div className="stake-view">
<Zoom in={true}>
<div className="stake-card">
<Grid className="stake-card-grid" container direction="column" spacing={2}>
{/* <Swap /> */}
</Grid>
</div>
</Zoom>
</div>
);
}
Example #2
Source File: ScrollTop.tsx From UsTaxes with GNU Affero General Public License v3.0 | 6 votes |
ScrollTop = (): ReactElement => {
const classes = useStyles()
const trigger = useScrollTrigger({
target: window,
disableHysteresis: true,
threshold: 100
})
const handleClick = () => {
window.scrollTo({ top: 0, behavior: 'smooth' })
}
return (
<Zoom in={trigger}>
<div onClick={handleClick} role="presentation" className={classes.root}>
<Fab color="default" size="small" aria-label="scroll back to top">
<KeyboardArrowUpIcon />
</Fab>
</div>
</Zoom>
)
}
Example #3
Source File: index.tsx From rugenerous-frontend with MIT License | 6 votes |
function Buy({ dexUrl }: ExchangeUrlProps) {
return (
<div className="choose-buy-view">
<Zoom in={true}>
<div className="choose-buy-view-card">
<div className="choose-buy-view-card-header">
<p className="choose-buy-view-card-title"> Get Rugged</p>
</div>
<iframe src={dexUrl}></iframe>
</div>
</Zoom>
</div>
);
}
Example #4
Source File: index.tsx From lobis-frontend with MIT License | 6 votes |
function Vote() {
return (
<div className="dashboard-view">
<div className="dashboard-infos-wrap">
<Zoom in={true}>
<Grid container spacing={4}>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Lobis</p>
<a className="button" target="_blank" href="https://snapshot.org/#/lobis.eth">
Go on snapshot
</a>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Frax</p>
<a className="button" target="_blank" href="https://snapshot.org/#/frax-lobis.eth">
Go on snapshot
</a>
</div>
</Grid>
</Grid>
</Zoom>
</div>
</div>
);
}
Example #5
Source File: index.tsx From uno-game with MIT License | 5 votes |
PlayerEffect: React.FC<PlayerEffectProps> = (props) => {
const { playerId } = props
const [playerEffectMessage, setPlayerEffectMessage] = useState<string>("")
const classes = useStyles()
const socket = useSocket()
const handlePlayerStateChange = (
playerState: PlayerState,
affectedPlayerId: string,
amountToBuy?: number,
) => {
if (affectedPlayerId === playerId) {
if (playerState === "Uno") {
setPlayerEffectMessage("UNO!")
} else if (playerState === "Blocked") {
setPlayerEffectMessage("BLOCKED!")
} else if (playerState === "BuyCards") {
setPlayerEffectMessage(`BUY ${amountToBuy}!`)
}
setTimeout(() => {
setPlayerEffectMessage("")
}, 2000)
}
}
const onPlayerStateChange = () => {
socket.onPlayerStateChange(handlePlayerStateChange)
}
useDidMount(() => {
onPlayerStateChange()
})
return (
<Zoom in={!!playerEffectMessage}>
<Grid
container
justify="center"
alignItems="center"
className={classes.playerEffectMessageContainer}
>
<Grid
container
justify="center"
alignItems="center"
className={classes.playerEffectMessageContent}
>
<Typography
variant="h3"
align="center"
className={classes.playerEffectMessageText}
>
{playerEffectMessage}
</Typography>
</Grid>
</Grid>
</Zoom>
)
}
Example #6
Source File: index.tsx From uno-game with MIT License | 5 votes |
LoadingScene: LoadingSceneType & React.FC<LoadingSceneProps> = (props) => {
const { onFinish, onStart, loading, children, duration } = props
const [visible, setVisible] = useState(true)
const classes = useStyles()
const handleScene = () => {
if (onStart) {
onStart()
}
setTimeout(() => {
setVisible(false)
if (onFinish) {
onFinish()
}
}, duration)
}
useDidMount(() => {
handleScene()
})
return (
<ThemeProvider theme={theme}>
<Zoom in={loading ?? visible}>
<Grid
container
direction="column"
alignItems="center"
justify="center"
className={classes.container}
>
<img
className={classes.logo}
src={logoImg}
alt="logo"
/>
</Grid>
</Zoom>
{children && (
<>
{!loading && <Fade in={!loading} children={children as React.ReactElement} />}
</>
)}
</ThemeProvider>
)
}
Example #7
Source File: button-switch.tsx From backstage with Apache License 2.0 | 5 votes |
export function ButtonSwitch<T extends string>(props: ButtonSwitchProps<T>) {
const { values, vertical = false } = props;
const onClick = useCallback(
(ev: MouseEvent<HTMLSpanElement>) => {
const btn = findParent('BUTTON', ev.target as HTMLElement);
const index = [...btn.parentElement!.children].findIndex(
child => child === btn,
);
const value = switchValue(values[index]);
if (props.multi) {
props.onChange(
props.selection.includes(value as T)
? props.selection.filter(val => val !== value)
: [...props.selection, value as T],
);
} else {
props.onChange(value as T);
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[values, props.selection, props.multi, props.onChange],
);
const hasSelection = (value: T) => {
if (props.multi) {
return props.selection.includes(value);
}
return props.selection === value;
};
const tooltipify = (value: SwitchValue<T>, elem: JSX.Element) =>
typeof value === 'object' && value.tooltip ? (
<Tooltip
key={value.value}
TransitionComponent={Zoom}
title={value.tooltip}
arrow
>
{elem}
</Tooltip>
) : (
elem
);
return (
<ButtonGroup
disableElevation
orientation={vertical ? 'vertical' : 'horizontal'}
variant="outlined"
size="small"
>
{values.map(value =>
tooltipify(
value,
<Button
key={switchValue(value)}
color={hasSelection(switchValue(value)) ? 'primary' : 'default'}
variant={
hasSelection(switchValue(value)) ? 'contained' : 'outlined'
}
onClick={onClick}
>
{switchText(value)}
</Button>,
),
)}
</ButtonGroup>
);
}
Example #8
Source File: index.tsx From wonderland-frontend with MIT License | 4 votes |
function ChooseBond() {
const { bonds } = useBonds();
const isSmallScreen = useMediaQuery("(max-width: 733px)"); // change to breakpoint query
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const marketPrice = useSelector<IReduxState, number>(state => {
return state.app.marketPrice;
});
const treasuryBalance = useSelector<IReduxState, number>(state => {
return state.app.treasuryBalance;
});
return (
<div className="choose-bond-view">
<Zoom in={true}>
<div className="choose-bond-view-card">
<div className="choose-bond-view-card-header">
<p className="choose-bond-view-card-title"> Mint (?, ?)</p>
</div>
<Grid container item xs={12} spacing={2} className="choose-bond-view-card-metrics">
<Grid item xs={12} sm={6}>
<Box textAlign="center">
<p className="choose-bond-view-card-metrics-title">Treasury Balance</p>
<p className="choose-bond-view-card-metrics-value">
{isAppLoading ? (
<Skeleton width="180px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(treasuryBalance)
)}
</p>
</Box>
</Grid>
<Grid item xs={12} sm={6}>
<Box textAlign="center">
<p className="choose-bond-view-card-metrics-title">TIME Price</p>
<p className="choose-bond-view-card-metrics-value">{isAppLoading ? <Skeleton width="100px" /> : `$${trim(marketPrice, 2)}`}</p>
</Box>
</Grid>
</Grid>
{!isSmallScreen && (
<Grid container item>
<TableContainer className="choose-bond-view-card-table">
<Table>
<TableHead>
<TableRow>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">Mint</p>
</TableCell>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">Price</p>
</TableCell>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">ROI</p>
</TableCell>
<TableCell align="right">
<p className="choose-bond-view-card-table-title">Purchased</p>
</TableCell>
<TableCell align="right"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{bonds.map(bond => (
<BondTableData key={bond.name} bond={bond} />
))}
</TableBody>
</Table>
</TableContainer>
</Grid>
)}
</div>
</Zoom>
{isSmallScreen && (
<div className="choose-bond-view-card-container">
<Grid container item spacing={2}>
{bonds.map(bond => (
<Grid item xs={12} key={bond.name}>
<BondDataCard key={bond.name} bond={bond} />
</Grid>
))}
</Grid>
</div>
)}
</div>
);
}
Example #9
Source File: index.tsx From lobis-frontend with MIT License | 4 votes |
function Dashboard() {
const { connect, provider, hasCachedProvider, chainID, connected } = useWeb3Context();
const dispatch = useDispatch();
const address = useAddress();
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const app = useSelector<IReduxState, IAppSlice>(state => state.app);
const { bonds } = useBonds();
const isSmallScreen = useMediaQuery("(max-width: 733px)"); // change to breakpoint query
useEffect(() => {
const interval = setInterval(() => {
dispatch(loadAppDetails({ networkID: chainID, provider: provider }));
console.log("dispatching app details");
}, 60000);
return () => clearInterval(interval);
}, []);
const trimmedStakingAPY = trim(app.stakingAPY * 100, 1);
const crvPerLobi = app.crvTreasuryBalance / (app.totalSupply - app.multisigLobiBalance);
const fxsPerLobi = app.fraxTreasuryBalance / (app.totalSupply - app.multisigLobiBalance);
const tokePerLobi = app.tokeTreasuryBalance / (app.totalSupply - app.multisigLobiBalance);
return (
<div className="dashboard-view">
<div className="dashboard-infos-wrap">
<Zoom in={true}>
<Grid container spacing={4}>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">{TOKEN_NAME} Price</p>
<p className="card-value">{isAppLoading ? <Skeleton width="100px" /> : `$${trim(app.marketPrice, 2)}`}</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Market Cap</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="160px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.marketCap)
)}
</p>
</div>
</Grid>
{/* <Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Supply (Staked/Total)</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
`${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.circSupply)}
/
${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.totalSupply)}`
)}
</p>
</div>
</Grid> */}
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">TVL</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.stakingTVL)
)}
</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">APY</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : parseFloat(trimmedStakingAPY) > 100000000 ? (
"100,000,000% +"
) : (
`${new Intl.NumberFormat("en-US").format(Number(trimmedStakingAPY))}%`
)}
</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Current Index</p>
<p className="card-value">{isAppLoading ? <Skeleton width="250px" /> : `${trim(Number(app.currentIndex), 4)} ${TOKEN_NAME}`}</p>
</div>
</Grid>
{isSmallScreen && (
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Treasury Balance</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.treasuryBalance)
)}
</p>
</div>
</Grid>
)}
{/*
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Backing per ${TOKEN_NAME}</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.rfv)
)}
</p>
</div>
</Grid> */}
{isSmallScreen && (
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">CRV Balance of Treasury</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
`${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.crvTreasuryBalance)} CRV`
)}
</p>
</div>
</Grid>
)}
{isSmallScreen && (
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">TOKE Balance of Treasury</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
`${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.tokeTreasuryBalance)} TOKE`
)}
</p>
</div>
</Grid>
)}
{isSmallScreen && (
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">FXS Balance of Treasury</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
`${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.fraxTreasuryBalance)} FXS`
)}
</p>
</div>
</Grid>
)}
{isSmallScreen && (
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">SDT Balance of Treasury</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
`${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.treasurySdtBalance)} SDT`
)}
</p>
</div>
</Grid>
)}
{isSmallScreen && (
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">ANGLE Balance of Treasury</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
`${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.angleTreasuryBalance)} ANGLE`
)}
</p>
</div>
</Grid>
)}
{isSmallScreen && (
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">gOHM Balance of Treasury</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
`${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.gOhmTreasuryBalance)} gOHM`
)}
</p>
</div>
</Grid>
)}
{isSmallScreen && (
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Vote per ${TOKEN_NAME}</p>
<p className="card-value card-value-small">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
`${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 2,
minimumFractionDigits: 0,
}).format(fxsPerLobi)} FXS + ${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 2,
minimumFractionDigits: 0,
}).format(crvPerLobi)} CRV + ${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 2,
minimumFractionDigits: 0,
}).format(tokePerLobi)} TOKE`
)}
</p>
</div>
</Grid>
)}
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Runway</p>
<p className="card-value">{isAppLoading ? <Skeleton width="250px" /> : `${trim(Number(app.runway), 1)} Days`}</p>
</div>
</Grid>
</Grid>
</Zoom>
</div>
{!isSmallScreen && <div className="treasury-table">{isAppLoading ? <Skeleton width="250px" /> : <TreasuryTable />}</div>}
</div>
);
}
Example #10
Source File: index.tsx From uno-game with MIT License | 4 votes |
CardStack: React.FC<CardStackProps> = (props) => {
const cardStore = useCardStore()
const socket = useSocket()
const { cards, game } = props
const classes = useStyles()
const cardStackRef = useRef()
const buyCard = () => {
socket.buyCard(game.id)
}
const putCard = (cardIds: string[], selectedColor: CardColors) => {
socket.putCard(game.id, cardIds, selectedColor)
}
const handleDrop = async (card: DraggedCardItem) => {
let selectedColor = "" as CardColors
const isColorEffectCard = (cardType: CardTypes) => cardType === "buy-4" || cardType === "change-color"
const cardComboIds = cardStore?.selectedCards?.reverse().map(card => card.id)
const isSingleColorEffect = isColorEffectCard(card.cardType)
const isComboColorEffect = cardComboIds?.length > 1 && cardStore?.selectedCards?.every(card => isColorEffectCard(card.type))
if (isSingleColorEffect || isComboColorEffect) {
selectedColor = await ChooseColorModal.open()
if (!selectedColor) {
return
}
}
if (cardComboIds?.length > 1) {
putCard(cardComboIds, selectedColor)
} else {
putCard([card.id], selectedColor)
}
}
if (game?.currentCardCombo?.amountToBuy > 0) {
lastAmountToBuy = game?.currentCardCombo?.amountToBuy
}
const [{ isHovering }, drop] = useDrop({
accept: CARD_TYPE,
drop: (item: DraggedCardItem) => handleDrop(item),
collect: monitor => ({
isHovering: monitor.isOver(),
}),
})
drop(cardStackRef)
return (
<>
<Grid
container
className={classes.cardStackContainer}
innerRef={cardStackRef}
style={{
backgroundColor: isHovering ? "rgba(255, 255, 255, 0.1)" : "",
}}
>
<Zoom
in={!!game?.currentCardCombo?.amountToBuy}
>
<Grid
container
className={classes.cardComboMessageContainer}
justify="center"
>
<Typography
variant="h2"
className={classes.cardComboMessage}
>
+{game?.currentCardCombo?.amountToBuy || lastAmountToBuy}
</Typography>
<img
src={currentComboTextImg}
alt="Current combo"
className={classes.cardComboTitle}
/>
</Grid>
</Zoom>
{socket?.currentPlayer?.canBuyCard && (
<Grid
container
justify="center"
className={classes.buyCardContainer}
>
<Button
variant="contained"
onClick={buyCard}
className={classes.buyCardButton}
>
BUY CARD
</Button>
</Grid>
)}
<Grid
container
className={classes.cardStackContent}
>
{cards?.slice(0, 20)?.map((card, index) => (
<img
key={card.id}
className={classes.card}
alt={card.name}
src={card.src}
style={{
transform: `rotate(${cards.length - index}rad)`,
zIndex: cards.length - index,
filter: (index === 0) ? "saturate(1.5)" : "contrast(0.5)",
}}
/>
))}
</Grid>
</Grid>
</>
)
}
Example #11
Source File: index.tsx From uno-game with MIT License | 4 votes |
CardDeck: React.FC<CardDeckProps> = (props) => {
const { cards, player } = props
const { gameId } = useParams<{ gameId: string }>()
const {
isDraggingAnyCard,
} = useDragLayer((monitor) => ({
isDraggingAnyCard: monitor.isDragging(),
}))
const cardStore = useCardStore()
const socketStore = useSocketStore()
const socket = useSocket()
const classes = useStyles()
const customClasses = useCustomStyles({
limitedNameWidth: 70,
avatarTimerRemainingPercentage: buildPercentage(
socketStore.gameRoundRemainingTimeInSeconds as number,
socketStore.game?.maxRoundDurationInSeconds as number,
),
})
const getCardInclination = (index: number) => {
const isMiddleCard = Math.round(cards.length / 2) === index
const isBeforeMiddleCard = index < Math.round(cards.length / 2)
let inclination: number
if (isMiddleCard) {
inclination = 0
} else if (isBeforeMiddleCard) {
inclination = -Math.abs(index - Math.round(cards.length / 2))
} else {
inclination = Math.abs(Math.round(cards.length / 2) - index)
}
const delta = Device.isMobile ? 4 : 3
return inclination * delta
}
const getCardElevation = (index: number) => {
const isMiddleCard = Math.round(cards.length / 2) === index
let elevation: number
if (isMiddleCard) {
elevation = 0
} else {
elevation = -Math.abs(index - Math.round(cards.length / 2))
}
const delta = Device.isMobile ? 3 : 7
return elevation * delta
}
const onDragEnd = () => {
cardStore.setSelectedCards([])
}
const isCardSelected = (cardId: string) => !!cardStore?.selectedCards?.some(card => card.id === cardId)
const canBePartOfCurrentCombo = (cardType: CardTypes) => !!cardStore?.selectedCards?.some(card => card.type === cardType)
const toggleSelectedCard = (cardId: string) => {
const lastSelectedCards = cardStore.selectedCards
const selectedCard = cards.find(card => card.id === cardId)
const cardOnTopOfCardStack = (socketStore.game as Game).usedCards[0]
const selectedCardTypes = lastSelectedCards?.map(card => card.type)
const isAlreadySelected = isCardSelected(cardId)
if (isAlreadySelected) {
const cardsWithoutAlreadySelected = lastSelectedCards?.filter(card => card.id !== cardId)
if (cardOnTopOfCardStack.color === selectedCard?.color) {
if (cardsWithoutAlreadySelected[0] && cardsWithoutAlreadySelected[0].type === cardOnTopOfCardStack.type) {
cardStore.setSelectedCards(cardsWithoutAlreadySelected)
} else {
cardStore.setSelectedCards([])
}
} else {
cardStore.setSelectedCards(cardsWithoutAlreadySelected)
}
} else if ((selectedCard && selectedCardTypes?.includes(selectedCard.type)) || !selectedCardTypes?.length) {
cardStore.setSelectedCards([
...(lastSelectedCards || []),
selectedCard as CardData,
])
}
}
const unselectAllCards = () => {
cardStore.setSelectedCards([])
}
const handleClickOutsideCardDeck = () => {
if (cardStore.selectedCards.length > 0) {
unselectAllCards()
}
}
const toggleOnlineStatus = () => {
socket.toggleOnlineStatus(gameId)
}
return (
<ClickAwayListener
onClickAway={handleClickOutsideCardDeck}
>
<Grid
container
alignItems="flex-end"
justify="center"
className={classes.cardContainer}
>
<PlayerEffect
playerId={player?.id}
/>
<Zoom in={player?.status === "afk"}>
<Grid
container
className={classes.afkContainer}
>
<Grid
container
alignItems="center"
justify="center"
direction="column"
className={classes.afkContent}
>
<Typography
variant="body1"
className={classes.afkInfo}
>
We noticed you are afk, so we are making random plays
{" "}
automatically for you. In case you want to keep playing by
{" "}
yourself, click on the button below.
</Typography>
<Divider orientation="horizontal" size={2} />
<Button
variant="contained"
className={classes.afkButton}
onClick={toggleOnlineStatus}
>
I'M HERE
</Button>
</Grid>
</Grid>
</Zoom>
<Grid
container
className={classes.cardContent}
style={{
width: (cards?.length * CARD_WIDTH) + CARD_WIDTH,
}}
>
{cards?.map((card, index) => (
<DraggableCard
key={card.id}
card={card}
className={classes.card}
index={index}
style={{
transform: `rotate(${getCardInclination(index)}deg)`,
bottom: getCardElevation(index),
zIndex: (index + 2),
left: index * CARD_WIDTH,
}}
onClick={() => toggleSelectedCard(card.id)}
selected={isCardSelected(card.id)}
isDraggingAnyCard={isDraggingAnyCard}
isMoreThanOneCardBeingDragged={cardStore?.selectedCards?.length > 1}
onDragEnd={onDragEnd}
canBePartOfCurrentCombo={canBePartOfCurrentCombo(card.type)}
/>
))}
</Grid>
<Grid
container
justify="center"
alignItems="center"
className={classes.avatarContainer}
style={{
opacity: player?.isCurrentRoundPlayer ? 1 : 0.5,
}}
>
<Avatar
name={player?.name}
size="small"
className={player?.isCurrentRoundPlayer ? customClasses.avatarTimer : ""}
/>
<Divider orientation="vertical" size={2} />
<Grid item>
<Typography
variant="h3"
className={`${classes.title} ${customClasses.limitedName}`}
>
{player?.name}
</Typography>
{player?.id && (
<Typography
variant="h2"
className={classes.description}
>
(You)
</Typography>
)}
</Grid>
</Grid>
</Grid>
</ClickAwayListener>
)
}
Example #12
Source File: WorkflowRunLogs.tsx From backstage with Apache License 2.0 | 4 votes |
WorkflowRunLogs = ({
entity,
runId,
inProgress,
}: {
entity: Entity;
runId: number;
inProgress: boolean;
}) => {
const config = useApi(configApiRef);
const classes = useStyles();
const projectName = getProjectNameFromEntity(entity);
// TODO: Get github hostname from metadata annotation
const hostname = readGitHubIntegrationConfigs(
config.getOptionalConfigArray('integrations.github') ?? [],
)[0].host;
const [owner, repo] = (projectName && projectName.split('/')) || [];
const jobLogs = useDownloadWorkflowRunLogs({
hostname,
owner,
repo,
id: runId,
});
const logText = jobLogs.value ? String(jobLogs.value) : undefined;
const [open, setOpen] = React.useState(false);
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<Accordion TransitionProps={{ unmountOnExit: true }} disabled={inProgress}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls={`panel-${name}-content`}
id={`panel-${name}-header`}
IconButtonProps={{
className: classes.button,
}}
>
<Typography variant="button">
{jobLogs.loading ? <CircularProgress /> : 'Job Log'}
</Typography>
<Tooltip title="Open Log" TransitionComponent={Zoom} arrow>
<DescriptionIcon
onClick={event => {
event.stopPropagation();
handleOpen();
}}
style={{ marginLeft: 'auto' }}
/>
</Tooltip>
<Modal
className={classes.modal}
onClick={event => event.stopPropagation()}
open={open}
onClose={handleClose}
>
<Fade in={open}>
<div className={classes.modalLogContainer}>
<LogViewer
text={logText ?? 'No Values Found'}
classes={{ root: classes.log }}
/>
</div>
</Fade>
</Modal>
</AccordionSummary>
{logText && (
<div className={classes.normalLogContainer}>
<LogViewer text={logText} classes={{ root: classes.log }} />
</div>
)}
</Accordion>
);
}
Example #13
Source File: index.tsx From wonderland-frontend with MIT License | 4 votes |
function Stake() {
const dispatch = useDispatch();
const { provider, address, connect, chainID, checkWrongNetwork } = useWeb3Context();
const [view, setView] = useState(0);
const [quantity, setQuantity] = useState<string>("");
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const currentIndex = useSelector<IReduxState, string>(state => {
return state.app.currentIndex;
});
const fiveDayRate = useSelector<IReduxState, number>(state => {
return state.app.fiveDayRate;
});
const timeBalance = useSelector<IReduxState, string>(state => {
return state.account.balances && state.account.balances.time;
});
const memoBalance = useSelector<IReduxState, string>(state => {
return state.account.balances && state.account.balances.memo;
});
const stakeAllowance = useSelector<IReduxState, number>(state => {
return state.account.staking && state.account.staking.time;
});
const unstakeAllowance = useSelector<IReduxState, number>(state => {
return state.account.staking && state.account.staking.memo;
});
const stakingRebase = useSelector<IReduxState, number>(state => {
return state.app.stakingRebase;
});
const stakingAPY = useSelector<IReduxState, number>(state => {
return state.app.stakingAPY;
});
const stakingTVL = useSelector<IReduxState, number>(state => {
return state.app.stakingTVL;
});
const pendingTransactions = useSelector<IReduxState, IPendingTxn[]>(state => {
return state.pendingTransactions;
});
const setMax = () => {
if (view === 0) {
setQuantity(timeBalance);
} else {
setQuantity(memoBalance);
}
};
const onSeekApproval = async (token: string) => {
if (await checkWrongNetwork()) return;
await dispatch(changeApproval({ address, token, provider, networkID: chainID }));
};
const onChangeStake = async (action: string) => {
if (await checkWrongNetwork()) return;
if (quantity === "" || parseFloat(quantity) === 0) {
dispatch(warning({ text: action === "stake" ? messages.before_stake : messages.before_unstake }));
} else {
await dispatch(changeStake({ address, action, value: String(quantity), provider, networkID: chainID }));
setQuantity("");
}
};
const hasAllowance = useCallback(
token => {
if (token === "time") return stakeAllowance > 0;
if (token === "memo") return unstakeAllowance > 0;
return 0;
},
[stakeAllowance],
);
const changeView = (newView: number) => () => {
setView(newView);
setQuantity("");
};
const trimmedMemoBalance = trim(Number(memoBalance), 6);
const trimmedStakingAPY = trim(stakingAPY * 100, 1);
const stakingRebasePercentage = trim(stakingRebase * 100, 4);
const nextRewardValue = trim((Number(stakingRebasePercentage) / 100) * Number(trimmedMemoBalance), 6);
return (
<div className="stake-view">
<Zoom in={true}>
<div className="stake-card">
<Grid className="stake-card-grid" container direction="column" spacing={2}>
<Grid item>
<div className="stake-card-header">
<p className="stake-card-header-title">TIME Staking (?, ?)</p>
<RebaseTimer />
</div>
</Grid>
<Grid item>
<div className="stake-card-metrics">
<Grid container spacing={2}>
<Grid item xs={12} sm={4} md={4} lg={4}>
<div className="stake-card-apy">
<p className="stake-card-metrics-title">APY</p>
<p className="stake-card-metrics-value">
{stakingAPY ? <>{new Intl.NumberFormat("en-US").format(Number(trimmedStakingAPY))}%</> : <Skeleton width="150px" />}
</p>
</div>
</Grid>
<Grid item xs={6} sm={4} md={4} lg={4}>
<div className="stake-card-tvl">
<p className="stake-card-metrics-title">TVL</p>
<p className="stake-card-metrics-value">
{stakingTVL ? (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(stakingTVL)
) : (
<Skeleton width="150px" />
)}
</p>
</div>
</Grid>
<Grid item xs={6} sm={4} md={4} lg={4}>
<div className="stake-card-index">
<p className="stake-card-metrics-title">Current Index</p>
<p className="stake-card-metrics-value">{currentIndex ? <>{trim(Number(currentIndex), 2)} TIME</> : <Skeleton width="150px" />}</p>
</div>
</Grid>
</Grid>
</div>
</Grid>
<div className="stake-card-area">
{!address && (
<div className="stake-card-wallet-notification">
<div className="stake-card-wallet-connect-btn" onClick={connect}>
<p>Connect Wallet</p>
</div>
<p className="stake-card-wallet-desc-text">Connect your wallet to stake TIME tokens!</p>
</div>
)}
{address && (
<div>
<div className="stake-card-action-area">
<div className="stake-card-action-stage-btns-wrap">
<div onClick={changeView(0)} className={classnames("stake-card-action-stage-btn", { active: !view })}>
<p>Stake</p>
</div>
<div onClick={changeView(1)} className={classnames("stake-card-action-stage-btn", { active: view })}>
<p>Unstake</p>
</div>
</div>
<div className="stake-card-action-row">
<OutlinedInput
type="number"
placeholder="Amount"
className="stake-card-action-input"
value={quantity}
onChange={e => setQuantity(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div onClick={setMax} className="stake-card-action-input-btn">
<p>Max</p>
</div>
</InputAdornment>
}
/>
{view === 0 && (
<div className="stake-card-tab-panel">
{address && hasAllowance("time") ? (
<div
className="stake-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "staking")) return;
onChangeStake("stake");
}}
>
<p>{txnButtonText(pendingTransactions, "staking", "Stake TIME")}</p>
</div>
) : (
<div
className="stake-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "approve_staking")) return;
onSeekApproval("time");
}}
>
<p>{txnButtonText(pendingTransactions, "approve_staking", "Approve")}</p>
</div>
)}
</div>
)}
{view === 1 && (
<div className="stake-card-tab-panel">
{address && hasAllowance("memo") ? (
<div
className="stake-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "unstaking")) return;
onChangeStake("unstake");
}}
>
<p>{txnButtonText(pendingTransactions, "unstaking", "Unstake TIME")}</p>
</div>
) : (
<div
className="stake-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "approve_unstaking")) return;
onSeekApproval("memo");
}}
>
<p>{txnButtonText(pendingTransactions, "approve_unstaking", "Approve")}</p>
</div>
)}
</div>
)}
</div>
<div className="stake-card-action-help-text">
{address && ((!hasAllowance("time") && view === 0) || (!hasAllowance("memo") && view === 1)) && (
<p>
Note: The "Approve" transaction is only needed when staking/unstaking for the first time; subsequent staking/unstaking only
requires you to perform the "Stake" or "Unstake" transaction.
</p>
)}
</div>
</div>
<div className="stake-user-data">
<div className="data-row">
<p className="data-row-name">Your Balance</p>
<p className="data-row-value">{isAppLoading ? <Skeleton width="80px" /> : <>{trim(Number(timeBalance), 4)} TIME</>}</p>
</div>
<div className="data-row">
<p className="data-row-name">Your Staked Balance</p>
<p className="data-row-value">{isAppLoading ? <Skeleton width="80px" /> : <>{trimmedMemoBalance} MEMO</>}</p>
</div>
<div className="data-row">
<p className="data-row-name">Next Reward Amount</p>
<p className="data-row-value">{isAppLoading ? <Skeleton width="80px" /> : <>{nextRewardValue} MEMO</>}</p>
</div>
<div className="data-row">
<p className="data-row-name">Next Reward Yield</p>
<p className="data-row-value">{isAppLoading ? <Skeleton width="80px" /> : <>{stakingRebasePercentage}%</>}</p>
</div>
<div className="data-row">
<p className="data-row-name">ROI (5-Day Rate)</p>
<p className="data-row-value">{isAppLoading ? <Skeleton width="80px" /> : <>{trim(Number(fiveDayRate) * 100, 4)}%</>}</p>
</div>
</div>
</div>
)}
</div>
</Grid>
</div>
</Zoom>
</div>
);
}
Example #14
Source File: index.tsx From wonderland-frontend with MIT License | 4 votes |
function Dashboard() {
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const app = useSelector<IReduxState, IAppSlice>(state => state.app);
const trimmedStakingAPY = trim(app.stakingAPY * 100, 1);
return (
<div className="dashboard-view">
<div className="dashboard-infos-wrap">
<Zoom in={true}>
<Grid container spacing={4}>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">TIME Price</p>
<p className="card-value">{isAppLoading ? <Skeleton width="100px" /> : `$${trim(app.marketPrice, 2)}`}</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Market Cap</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="160px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.marketCap)
)}
</p>
</div>
</Grid>
{/* <Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Supply (Staked/Total)</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
`${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.circSupply)}
/
${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.totalSupply)}`
)}
</p>
</div>
</Grid> */}
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">TVL</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.stakingTVL)
)}
</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">APY</p>
<p className="card-value">{isAppLoading ? <Skeleton width="250px" /> : `${new Intl.NumberFormat("en-US").format(Number(trimmedStakingAPY))}%`}</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Current Index</p>
<p className="card-value">{isAppLoading ? <Skeleton width="250px" /> : `${trim(Number(app.currentIndex), 2)} TIME`}</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Treasury Balance</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.treasuryBalance)
)}
</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Backing per $TIME</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.rfv)
)}
</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Runway</p>
<p className="card-value">{isAppLoading ? <Skeleton width="250px" /> : `${trim(Number(app.runway), 1)} Days`}</p>
</div>
</Grid>
</Grid>
</Zoom>
</div>
</div>
);
}
Example #15
Source File: index.tsx From lobis-frontend with MIT License | 4 votes |
function Stake() {
const dispatch = useDispatch();
const { provider, address, connect, chainID, checkWrongNetwork } = useWeb3Context();
const [view, setView] = useState(0);
const [quantity, setQuantity] = useState<string>("");
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const currentIndex = useSelector<IReduxState, string>(state => {
return state.app.currentIndex;
});
const fiveDayRate = useSelector<IReduxState, number>(state => {
return state.app.fiveDayRate;
});
const lobiBalance = useSelector<IReduxState, string>(state => {
return state.account.balances && state.account.balances.lobi;
});
const sTokenBalance = useSelector<IReduxState, string>(state => {
return state.account.balances && state.account.balances.sLobi;
});
const stakeAllowance = useSelector<IReduxState, number>(state => {
return state.account.staking && state.account.staking.lobi;
});
const unstakeAllowance = useSelector<IReduxState, number>(state => {
return state.account.staking && state.account.staking.sLobi;
});
const stakingRebase = useSelector<IReduxState, number>(state => {
return state.app.stakingRebase;
});
const stakingAPY = useSelector<IReduxState, number>(state => {
return state.app.stakingAPY;
});
const stakingTVL = useSelector<IReduxState, number>(state => {
return state.app.stakingTVL;
});
const lobiPrice = useSelector<IReduxState, number>(state => {
return state.app.marketPrice;
});
const pendingTransactions = useSelector<IReduxState, IPendingTxn[]>(state => {
return state.pendingTransactions;
});
const setMax = () => {
if (view === 0) {
setQuantity(lobiBalance);
} else {
setQuantity(sTokenBalance);
}
};
const onSeekApproval = async (token: string) => {
if (await checkWrongNetwork()) return;
await dispatch(changeApproval({ address, token, provider, networkID: chainID }));
};
const onChangeStake = async (action: string) => {
if (await checkWrongNetwork()) return;
if (quantity === "" || parseFloat(quantity) === 0) {
dispatch(warning({ text: action === "stake" ? messages.before_stake : messages.before_unstake }));
} else {
await dispatch(changeStake({ address, action, value: String(quantity), provider, networkID: chainID }));
setQuantity("");
}
};
const hasAllowance = useCallback(
token => {
if (token === "lobi") {
return stakeAllowance > 0;
} else if (token === "sLobi") {
return unstakeAllowance > 0;
}
return 0;
},
[stakeAllowance, unstakeAllowance],
);
const changeView = (newView: number) => () => {
setView(newView);
setQuantity("");
};
const trimmedSLobiBalance = trim(Number(sTokenBalance), 6);
const trimmedStakingAPY = trim(stakingAPY * 100, 1);
const stakingRebasePercentage = trim(stakingRebase * 100, 4);
const nextRewardValue = trim((Number(stakingRebasePercentage) / 100) * Number(trimmedSLobiBalance), 6);
const stakingAmountInUSD = Number(sTokenBalance) * lobiPrice;
const nextRewardValueInUSD = (Number(stakingRebasePercentage) / 100) * Number(trimmedSLobiBalance) * lobiPrice;
return (
<div className="stake-view">
<Zoom in={true}>
<div className="stake-card">
<Grid className="stake-card-grid" container direction="column" spacing={2}>
<Grid item>
<div className="stake-card-header">
<p className="stake-card-header-title">{TOKEN_NAME} Staking ( III , III )</p>
<RebaseTimer />
</div>
</Grid>
<Grid item>
<div className="stake-card-metrics">
<Grid container spacing={2}>
<Grid item xs={12} sm={4} md={4} lg={4}>
<div className="stake-card-apy">
<p className="stake-card-metrics-title">APY</p>
<p className="stake-card-metrics-value">
{stakingAPY ? (
<>
{parseFloat(trimmedStakingAPY) > 1000000000
? "100,000,000% +"
: `${new Intl.NumberFormat("en-US").format(Number(trimmedStakingAPY))}%`}
</>
) : (
<Skeleton width="150px" />
)}
</p>
</div>
</Grid>
<Grid item xs={6} sm={4} md={4} lg={4}>
<div className="stake-card-tvl">
<p className="stake-card-metrics-title">TVL</p>
<p className="stake-card-metrics-value">
{stakingTVL ? (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(stakingTVL)
) : (
<Skeleton width="150px" />
)}
</p>
</div>
</Grid>
<Grid item xs={6} sm={4} md={4} lg={4}>
<div className="stake-card-index">
<p className="stake-card-metrics-title">Current Index</p>
<p className="stake-card-metrics-value">
{currentIndex ? (
<>
{trim(Number(currentIndex), 4)} {TOKEN_NAME}
</>
) : (
<Skeleton width="150px" />
)}
</p>
</div>
</Grid>
</Grid>
</div>
</Grid>
<div className="stake-card-area">
{!address && (
<div className="stake-card-wallet-notification">
<div className="stake-card-wallet-connect-btn" onClick={connect}>
<p>Connect Wallet</p>
</div>
<p className="stake-card-wallet-desc-text">Connect your wallet to stake {TOKEN_NAME} tokens!</p>
</div>
)}
{address && (
<div>
<div className="stake-card-action-area">
<div className="stake-card-action-stage-btns-wrap">
<div onClick={changeView(0)} className={classnames("stake-card-action-stage-btn", { active: !view })}>
<p>Stake</p>
</div>
<div onClick={changeView(1)} className={classnames("stake-card-action-stage-btn", { active: view })}>
<p>Unstake</p>
</div>
</div>
<div className="stake-card-action-row">
<OutlinedInput
type="number"
placeholder="Amount"
className="stake-card-action-input"
value={quantity}
onChange={e => setQuantity(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div onClick={setMax} className="stake-card-action-input-btn">
<p>Max</p>
</div>
</InputAdornment>
}
/>
{view === 0 && (
<div className="stake-card-tab-panel">
{address && hasAllowance("lobi") ? (
<div
className="stake-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "staking")) return;
onChangeStake("stake");
}}
>
<p>{txnButtonText(pendingTransactions, "staking", `Stake ${TOKEN_NAME}`)}</p>
</div>
) : (
<div
className="stake-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "approve_staking")) return;
onSeekApproval("lobi");
}}
>
<p>{txnButtonText(pendingTransactions, "approve_staking", "Approve")}</p>
</div>
)}
</div>
)}
{view === 1 && (
<div className="stake-card-tab-panel">
{address && hasAllowance("sLobi") ? (
<div
className="stake-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "unstaking")) return;
onChangeStake("unstake");
}}
>
<p>{txnButtonText(pendingTransactions, "unstaking", `Unstake ${TOKEN_NAME}`)}</p>
</div>
) : (
<div
className="stake-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "approve_unstaking")) return;
onSeekApproval("sLobi");
}}
>
<p>{txnButtonText(pendingTransactions, "approve_unstaking", "Approve")}</p>
</div>
)}
</div>
)}
</div>
<div className="stake-card-action-help-text">
{address && ((!hasAllowance("lobi") && view === 0) || (!hasAllowance("sLobi") && view === 1)) && (
<p>
Note: The "Approve" transaction is only needed when staking/unstaking for the first lobi; subsequent staking/unstaking only
requires you to perform the "Stake" or "Unstake" transaction.
</p>
)}
</div>
</div>
<div className="stake-user-data">
<div className="data-row">
<p className="data-row-name">Your Balance</p>
<p className="data-row-value">
{isAppLoading ? (
<Skeleton width="80px" />
) : (
<>
{trim(Number(lobiBalance), 4)} {TOKEN_NAME}
</>
)}
</p>
</div>
<div className="data-row">
<p className="data-row-name">Your Staked Balance</p>
<p className="data-row-value">
{isAppLoading ? (
<Skeleton width="80px" />
) : (
<>
{trimmedSLobiBalance} {STAKING_TOKEN_NAME}
</>
)}
</p>
</div>
<div className="data-row">
<p className="data-row-name">$ Amount</p>
<p className="data-row-value">
{isAppLoading ? (
<Skeleton width="80px" />
) : (
<>
{new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(stakingAmountInUSD)}
</>
)}
</p>
</div>
<div className="data-row">
<p className="data-row-name">Next Reward Amount</p>
<p className="data-row-value">
{isAppLoading ? (
<Skeleton width="80px" />
) : (
<>
{nextRewardValue} {STAKING_TOKEN_NAME}
</>
)}
</p>
</div>
<div className="data-row">
<p className="data-row-name">Next Reward Amount in $</p>
<p className="data-row-value">
{isAppLoading ? (
<Skeleton width="80px" />
) : (
<>
{new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(nextRewardValueInUSD)}
</>
)}
</p>
</div>
<div className="data-row">
<p className="data-row-name">Next Reward Yield</p>
<p className="data-row-value">{isAppLoading ? <Skeleton width="80px" /> : <>{stakingRebasePercentage}%</>}</p>
</div>
<div className="data-row">
<p className="data-row-name">ROI (5-Day Rate)</p>
<p className="data-row-value">{isAppLoading ? <Skeleton width="80px" /> : <>{trim(Number(fiveDayRate) * 100, 4)}%</>}</p>
</div>
</div>
</div>
)}
</div>
</Grid>
</div>
</Zoom>
</div>
);
}
Example #16
Source File: index.tsx From wonderland-frontend with MIT License | 4 votes |
function Calculator() {
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const marketPrice = useSelector<IReduxState, number>(state => {
return state.app.marketPrice;
});
const stakingAPY = useSelector<IReduxState, number>(state => {
return state.app.stakingAPY;
});
const memoBalance = useSelector<IReduxState, string>(state => {
return state.account.balances && state.account.balances.memo;
});
const trimmedStakingAPY = trim(stakingAPY * 100, 1);
const trimmedMemoBalance = trim(Number(memoBalance), 6);
const trimeMarketPrice = trim(marketPrice, 2);
const [memoAmount, setMemoAmount] = useState(trimmedMemoBalance);
const [rewardYield, setRewardYield] = useState(trimmedStakingAPY);
const [priceAtPurchase, setPriceAtPurchase] = useState(trimeMarketPrice);
const [futureMarketPrice, setFutureMarketPrice] = useState(trimeMarketPrice);
const [days, setDays] = useState(30);
const [rewardsEstimation, setRewardsEstimation] = useState("0");
const [potentialReturn, setPotentialReturn] = useState("0");
const calcInitialInvestment = () => {
const memo = Number(memoAmount) || 0;
const price = parseFloat(priceAtPurchase) || 0;
const amount = memo * price;
return trim(amount, 2);
};
const calcCurrentWealth = () => {
const memo = Number(memoAmount) || 0;
const price = parseFloat(trimeMarketPrice);
const amount = memo * price;
return trim(amount, 2);
};
const [initialInvestment, setInitialInvestment] = useState(calcInitialInvestment());
useEffect(() => {
const newInitialInvestment = calcInitialInvestment();
setInitialInvestment(newInitialInvestment);
}, [memoAmount, priceAtPurchase]);
const calcNewBalance = () => {
let value = parseFloat(rewardYield) / 100;
value = Math.pow(value - 1, 1 / (365 * 3)) - 1 || 0;
let balance = Number(memoAmount);
for (let i = 0; i < days * 3; i++) {
balance += balance * value;
}
return balance;
};
useEffect(() => {
const newBalance = calcNewBalance();
setRewardsEstimation(trim(newBalance, 6));
const newPotentialReturn = newBalance * (parseFloat(futureMarketPrice) || 0);
setPotentialReturn(trim(newPotentialReturn, 2));
}, [days, rewardYield, futureMarketPrice, memoAmount]);
return (
<div className="calculator-view">
<Zoom in={true}>
<div className="calculator-card">
<Grid className="calculator-card-grid" container direction="column" spacing={2}>
<Grid item>
<div className="calculator-card-header">
<p className="calculator-card-header-title">Calculator</p>
<p className="calculator-card-header-subtitle">Estimate your returns</p>
</div>
</Grid>
<Grid item>
<div className="calculator-card-metrics">
<Grid container spacing={2}>
<Grid item xs={12} sm={4} md={4} lg={4}>
<div className="calculator-card-apy">
<p className="calculator-card-metrics-title">TIME Price</p>
<p className="calculator-card-metrics-value">{isAppLoading ? <Skeleton width="100px" /> : `$${trimeMarketPrice}`}</p>
</div>
</Grid>
<Grid item xs={6} sm={4} md={4} lg={4}>
<div className="calculator-card-tvl">
<p className="calculator-card-metrics-title">Current APY</p>
<p className="calculator-card-metrics-value">
{isAppLoading ? <Skeleton width="100px" /> : <>{new Intl.NumberFormat("en-US").format(Number(trimmedStakingAPY))}%</>}
</p>
</div>
</Grid>
<Grid item xs={6} sm={4} md={4} lg={4}>
<div className="calculator-card-index">
<p className="calculator-card-metrics-title">Your MEMO Balance</p>
<p className="calculator-card-metrics-value">{isAppLoading ? <Skeleton width="100px" /> : <>{trimmedMemoBalance} MEMO</>}</p>
</div>
</Grid>
</Grid>
</div>
</Grid>
<div className="calculator-card-area">
<div>
<div className="calculator-card-action-area">
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<div className="calculator-card-action-area-inp-wrap">
<p className="calculator-card-action-area-inp-wrap-title">MEMO Amount</p>
<OutlinedInput
type="number"
placeholder="Amount"
className="calculator-card-action-input"
value={memoAmount}
onChange={e => setMemoAmount(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div onClick={() => setMemoAmount(trimmedMemoBalance)} className="stake-card-action-input-btn">
<p>Max</p>
</div>
</InputAdornment>
}
/>
</div>
</Grid>
<Grid item xs={12} sm={6}>
<div className="calculator-card-action-area-inp-wrap">
<p className="calculator-card-action-area-inp-wrap-title">APY (%)</p>
<OutlinedInput
type="number"
placeholder="Amount"
className="calculator-card-action-input"
value={rewardYield}
onChange={e => setRewardYield(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div onClick={() => setRewardYield(trimmedStakingAPY)} className="stake-card-action-input-btn">
<p>Current</p>
</div>
</InputAdornment>
}
/>
</div>
</Grid>
<Grid item xs={12} sm={6}>
<div className="calculator-card-action-area-inp-wrap">
<p className="calculator-card-action-area-inp-wrap-title">TIME price at purchase ($)</p>
<OutlinedInput
type="number"
placeholder="Amount"
className="calculator-card-action-input"
value={priceAtPurchase}
onChange={e => setPriceAtPurchase(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div onClick={() => setPriceAtPurchase(trimeMarketPrice)} className="stake-card-action-input-btn">
<p>Current</p>
</div>
</InputAdornment>
}
/>
</div>
</Grid>
<Grid item xs={12} sm={6}>
<div className="calculator-card-action-area-inp-wrap">
<p className="calculator-card-action-area-inp-wrap-title">Future TIME market price ($)</p>
<OutlinedInput
type="number"
placeholder="Amount"
className="calculator-card-action-input"
value={futureMarketPrice}
onChange={e => setFutureMarketPrice(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div onClick={() => setFutureMarketPrice(trimeMarketPrice)} className="stake-card-action-input-btn">
<p>Current</p>
</div>
</InputAdornment>
}
/>
</div>
</Grid>
</Grid>
</div>
<div className="calculator-days-slider-wrap">
<p className="calculator-days-slider-wrap-title">{`${days} day${days > 1 ? "s" : ""}`}</p>
<Slider className="calculator-days-slider" min={1} max={365} value={days} onChange={(e, newValue: any) => setDays(newValue)} />
</div>
<div className="calculator-user-data">
<div className="data-row">
<p className="data-row-name">Your initial investment</p>
<p className="data-row-value">{isAppLoading ? <Skeleton width="80px" /> : <>${initialInvestment}</>}</p>
</div>
<div className="data-row">
<p className="data-row-name">Current wealth</p>
<p className="data-row-value">{isAppLoading ? <Skeleton width="80px" /> : <>${calcCurrentWealth()}</>}</p>
</div>
<div className="data-row">
<p className="data-row-name">TIME rewards estimation</p>
<p className="data-row-value">{isAppLoading ? <Skeleton width="80px" /> : <>{rewardsEstimation} TIME</>}</p>
</div>
<div className="data-row">
<p className="data-row-name">Potential return</p>
<p className="data-row-value">{isAppLoading ? <Skeleton width="80px" /> : <>${potentialReturn}</>}</p>
</div>
<div className="data-row">
<p className="data-row-name">Potential number of lambos</p>
<p className="data-row-value">{isAppLoading ? <Skeleton width="80px" /> : <>{Math.floor(Number(potentialReturn) / 220000)}</>}</p>
</div>
</div>
</div>
</div>
</Grid>
</div>
</Zoom>
</div>
);
}
Example #17
Source File: index.tsx From lobis-frontend with MIT License | 4 votes |
function ChooseBond() {
const { bonds } = useBonds();
const isSmallScreen = useMediaQuery("(max-width: 733px)"); // change to breakpoint query
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const marketPrice = useSelector<IReduxState, number>(state => {
return state.app.marketPrice;
});
const treasuryBalance = useSelector<IReduxState, number>(state => {
return state.app.treasuryBalance;
});
const pendingBonds = bonds.filter(item => item.pendingPayout > 0 || item.interestDue > 0);
return (
<div className="choose-bond-view">
{!isSmallScreen && pendingBonds.length > 0 && (
<div className="my-bonds-view-card">
<div className="choose-bond-view-card-header">
<p className="choose-bond-view-card-title"> My Bonds</p>
</div>
<Grid container item>
<TableContainer className="choose-bond-view-card-table">
<Table>
<TableHead>
<TableRow>
<TableCell align="center">
<p className="choose-bond-view-card-table-title"></p>
</TableCell>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">Pending</p>
</TableCell>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">Claimable</p>
</TableCell>
<TableCell align="right">
<p className="choose-bond-view-card-table-title">Vesting Time</p>
</TableCell>
<TableCell align="right"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{pendingBonds.map(bond => (
<MyBondTableData key={bond.name} bond={bond} />
))}
</TableBody>
</Table>
</TableContainer>
</Grid>
</div>
)}
<Zoom in={true}>
<div className="choose-bond-view-card">
<div className="choose-bond-view-card-header">
<p className="choose-bond-view-card-title"> Mint</p>
</div>
<Grid container item xs={12} spacing={2} className="choose-bond-view-card-metrics">
<Grid item xs={12} sm={6}>
<Box textAlign="center">
<p className="choose-bond-view-card-metrics-title">Treasury Balance</p>
<p className="choose-bond-view-card-metrics-value">
{isAppLoading ? (
<Skeleton width="180px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(treasuryBalance)
)}
</p>
</Box>
</Grid>
<Grid item xs={12} sm={6}>
<Box textAlign="center">
<p className="choose-bond-view-card-metrics-title">{TOKEN_NAME} Price</p>
<p className="choose-bond-view-card-metrics-value">{isAppLoading ? <Skeleton width="100px" /> : `$${trim(marketPrice, 2)}`}</p>
</Box>
</Grid>
</Grid>
{!isSmallScreen && (
<Grid container item>
<TableContainer className="choose-bond-view-card-table">
<Table>
<TableHead>
<TableRow>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">Mint</p>
</TableCell>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">Price</p>
</TableCell>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">ROI</p>
</TableCell>
<TableCell align="right">
<p className="choose-bond-view-card-table-title">Purchased</p>
</TableCell>
<TableCell align="right"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{bonds.map(bond => (
<BondTableData key={bond.name} bond={bond} />
))}
</TableBody>
</Table>
</TableContainer>
</Grid>
)}
</div>
</Zoom>
{isSmallScreen && (
<div className="choose-bond-view-card-container">
<Grid container item spacing={2}>
{bonds.map(bond => (
<Grid item xs={12} key={bond.name}>
<BondDataCard key={bond.name} bond={bond} />
</Grid>
))}
</Grid>
</div>
)}
</div>
);
}
Example #18
Source File: index.tsx From rugenerous-frontend with MIT License | 4 votes |
function Stake() {
const [anchorEl, setAnchorEl] = useState(null);
const dispatch = useDispatch();
const { provider, address, connect, chainID, checkWrongNetwork } = useWeb3Context();
const [view, setView] = useState(0);
const [quantity, setQuantity] = useState<string>("");
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const app = useSelector<IReduxState, IAppSlice>(state => state.app);
const currentIndex = useSelector<IReduxState, string>(state => {
return state.app.currentIndex;
});
const fiveDayRate = useSelector<IReduxState, number>(state => {
return state.app.fiveDayRate;
});
const timeBalance = useSelector<IReduxState, string>(state => {
return state.account.balances && state.account.balances.rug;
});
const warmupBalance = useSelector<IReduxState, string>(state => {
return state.account.warmupInfo && state.account.warmupInfo.deposit;
});
const gonsBalance = useSelector<IReduxState, string>(state => {
return state.account.warmupInfo && state.account.warmupInfo.gonsBalance;
});
const warmupExpiry = useSelector<IReduxState, string>(state => {
return state.account.warmupInfo && state.account.warmupInfo.expiry;
});
const currentEpoch = useSelector<IReduxState, string>(state => {
return state.account.warmupInfo && state.account.warmupInfo.epoch;
});
const memoBalance = useSelector<IReduxState, string>(state => {
return state.account.balances && state.account.balances.srug;
});
//Adding Durag - KM
const duragBalance = useSelector<IReduxState, string>(state => {
return state.account.balances && state.account.balances.durag;
});
const stakeAllowance = useSelector<IReduxState, number>(state => {
return state.account.staking && state.account.staking.rug;
});
const unstakeAllowance = useSelector<IReduxState, number>(state => {
return state.account.staking && state.account.staking.srug;
});
const stakingRebase = useSelector<IReduxState, number>(state => {
return state.app.stakingRebase;
});
const stakingAPY = useSelector<IReduxState, number>(state => {
return state.app.stakingAPY;
});
const stakingTVL = useSelector<IReduxState, number>(state => {
return state.app.stakingTVL;
});
const pendingTransactions = useSelector<IReduxState, IPendingTxn[]>(state => {
return state.pendingTransactions;
});
const setMax = () => {
if (view === 0) {
const fullBalance = Number(timeBalance);
setQuantity(trim(fullBalance, 4));
console.log(quantity);
} else {
setQuantity(memoBalance);
}
};
const onSeekApproval = async (token: string) => {
if (await checkWrongNetwork()) return;
await dispatch(changeApproval({ address, token, provider, networkID: chainID }));
};
const onChangeStake = async (action: string) => {
if (await checkWrongNetwork()) return;
if (quantity === "" || parseFloat(quantity) === 0) {
dispatch(warning({ text: action === "stake" ? messages.before_stake : messages.before_unstake }));
} else {
await dispatch(
changeStake({
address,
action,
value: String(quantity),
provider,
networkID: chainID,
warmUpBalance: Number(warmupBalance),
}),
);
setQuantity("");
}
};
const onChangeWarmup = async (action: string) => {
if (await checkWrongNetwork()) return;
await dispatch(
forfeitOrClaim({
address,
action,
provider,
networkID: chainID,
}),
);
};
const hasAllowance = useCallback(
token => {
if (token === "rug") return stakeAllowance > 0;
if (token === "srug") return unstakeAllowance > 0;
return 0;
},
[stakeAllowance],
);
const changeView = (newView: number) => () => {
setView(newView);
setQuantity("");
};
const trimmedMemoBalance = trim(Number(memoBalance), 6);
const trimmedMemoBalanceInUSD = trim(Number(memoBalance) * app.marketPrice, 2);
const trimmedStakingAPY = trim(stakingAPY * 100, 1);
const stakingRebasePercentage = trim(stakingRebase * 100, 4);
const nextRewardValue = trim((Number(stakingRebasePercentage) / 100) * Number(trimmedMemoBalance), 6);
const nextRewardInUSD = Number(nextRewardValue) * app.marketPrice;
const trimmedEarningsPerDay = trim(nextRewardInUSD * 3, 2);
const handleClick = (event: any) => {
setAnchorEl(anchorEl ? null : event.currentTarget);
};
const open = Boolean(anchorEl);
return (
<div className="stake-view">
<Zoom in={true}>
<div className="stake-card">
<Grid className="stake-card-grid" container direction="column" spacing={2}>
<Grid item>
<div className="stake-card-header">
<p className="stake-card-header-title">RUG Staking (?, ?)</p>
<RebaseTimer />
</div>
</Grid>
<Grid item>
<div className="stake-card-metrics">
<Grid container spacing={2}>
<Grid item xs={12} sm={4} md={4} lg={4}>
<div className="stake-card-apy">
<p className="stake-card-metrics-title">APY</p>
<>
{stakingAPY ? (
<div>
<p
className="stake-card-metrics-value"
onMouseEnter={e => handleClick(e)}
onMouseLeave={e => handleClick(e)}
>
`'Big' - trust me bro...`
</p>
<Popper className="rug-menu-popper tooltip" open={open} anchorEl={anchorEl} transition>
{({ TransitionProps }) => (
<Fade {...TransitionProps} timeout={200}>
<p className="tooltip-item">
{new Intl.NumberFormat("en-US").format(Number(trimmedStakingAPY))}%
</p>
</Fade>
)}
</Popper>
</div>
) : (
<p className="stake-card-metrics-value">
<Skeleton width="150px" />
</p>
)}
</>
</div>
</Grid>
<Grid item xs={6} sm={4} md={4} lg={4}>
<div className="stake-card-index">
<p className="stake-card-metrics-title">Current Index</p>
<p className="stake-card-metrics-value">
{currentIndex ? <>{trim(Number(currentIndex), 2)} RUG</> : <Skeleton width="150px" />}
</p>
</div>
</Grid>
<Grid item xs={6} sm={4} md={4} lg={4}>
<div className="stake-card-index">
<p className="stake-card-metrics-title">Earnings per Day</p>
<p className="stake-card-metrics-value">
{currentIndex ? <>${trimmedEarningsPerDay}</> : <Skeleton width="150px" />}
</p>
</div>
</Grid>
</Grid>
</div>
</Grid>
<div className="stake-card-area">
{!address && (
<div className="stake-card-wallet-notification">
<div className="stake-card-wallet-connect-btn" onClick={connect}>
<p>Connect Wallet</p>
</div>
<p className="stake-card-wallet-desc-text">Connect your wallet to stake RUG tokens!</p>
</div>
)}
{address && (
<div>
<div className="stake-card-action-area">
<div className="stake-card-action-stage-btns-wrap">
<div
onClick={changeView(0)}
className={classnames("stake-card-action-stage-btn", { active: !view })}
>
<p>Stake</p>
</div>
<div
onClick={changeView(1)}
className={classnames("stake-card-action-stage-btn", { active: view })}
>
<p>Unstake</p>
</div>
</div>
<div className="stake-card-action-row">
<OutlinedInput
type="number"
placeholder="Amount"
className="stake-card-action-input"
value={quantity}
onChange={e => setQuantity(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div onClick={setMax} className="stake-card-action-input-btn">
<p>Max</p>
</div>
</InputAdornment>
}
/>
{view === 0 && (
<div className="stake-card-tab-panel">
{address && hasAllowance("rug") ? (
<div
className="stake-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "staking")) return;
onChangeStake("stake");
}}
>
<p>{txnButtonText(pendingTransactions, "staking", "Stake RUG")}</p>
</div>
) : (
<div
className="stake-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "approve_staking")) return;
onSeekApproval("rug");
}}
>
<p>{txnButtonText(pendingTransactions, "approve_staking", "Approve")}</p>
</div>
)}
</div>
)}
{view === 1 && (
<div className="stake-card-tab-panel">
{address && hasAllowance("srug") ? (
<div
className="stake-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "unstaking")) return;
onChangeStake("unstake");
}}
>
<p>{txnButtonText(pendingTransactions, "unstaking", "Unstake RUG")}</p>
</div>
) : (
<div
className="stake-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "approve_unstaking")) return;
onSeekApproval("srug");
}}
>
<p>{txnButtonText(pendingTransactions, "approve_unstaking", "Approve")}</p>
</div>
)}
</div>
)}
</div>
<div className="stake-card-action-help-text">
{address && ((!hasAllowance("rug") && view === 0) || (!hasAllowance("srug") && view === 1)) && (
<p>
Note: The "Approve" transaction is only needed when staking/unstaking for the first rug;
subsequent staking/unstaking only requires you to perform the "Stake" or "Unstake"
transaction.
</p>
)}
</div>
</div>
<div className="stake-user-data">
<div className="data-row">
<p className="data-row-name">Your Balance</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>{trim(Number(timeBalance), 4)} RUG</>}
</p>
</div>
<div className="data-row">
<p className="data-row-name">Your Durag Balance</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>{trim(Number(duragBalance), 4)} DURAG</>}
</p>
</div>
{Number(warmupBalance) > 0 && (
<>
<br />
<div className="data-row">
<p className="data-row-name">Your Warm Up Balance</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>{trim(Number(warmupBalance), 4)} RUG</>}
</p>
</div>
{Number(warmupBalance) < Number(gonsBalance) && (
<>
<div className="data-row">
<p className="data-row-name">Warm Up Balance with Rebase Rewards</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>{trim(Number(gonsBalance), 4)} RUG</>}
</p>
</div>
</>
)}
<div className="data-row">
<p className="data-row-name">Pending Warm Up Till Release</p>
<p className="data-row-value">
{isAppLoading ? (
<Skeleton width="80px" />
) : Number(warmupExpiry) <= Number(currentEpoch) ? (
<>
<div
className="claim-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "claim")) return;
onChangeWarmup("claim");
}}
>
<p>{txnButtonText(pendingTransactions, "claim", "Claim SRUG")}</p>
</div>
<br />
</>
) : (
<div className="warmup-text">
{" "}
{Number(warmupExpiry) - Number(currentEpoch)} Rebase(s) left till claimable
<div className="forfeit-btn">{BasicModal(onChangeWarmup)}</div>
</div>
)}
</p>
</div>
</>
)}
<div className="data-row">
<p className="data-row-name">Your Staked Balance</p>
<p className="data-row-value">
{isAppLoading ? (
<Skeleton width="80px" />
) : (
<>
{trimmedMemoBalance} sRUG (${trimmedMemoBalanceInUSD})
</>
)}
</p>
</div>
<div className="data-row">
<p className="data-row-name">Next Reward Amount</p>
<p className="data-row-value">
{isAppLoading ? (
<Skeleton width="80px" />
) : (
<>
{nextRewardValue} sRUG (${trim(nextRewardInUSD, 2)})
</>
)}
</p>
</div>
<div className="data-row">
<p className="data-row-name">Next Reward Yield</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>{stakingRebasePercentage}%</>}
</p>
</div>
<div className="data-row">
<p className="data-row-name">ROI (5-Day Rate)</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>{trim(Number(fiveDayRate) * 100, 4)}%</>}
</p>
</div>
<div className="stake-card-action-help-text">
<br />
<p>
Please Note: there is a two-epoch warm-up period when staking. One epoch is eight hours (one
rebase window). During warm-up, your staked tokens are held by the warm-up contract. Exiting the
warm-up early will return your original deposit to your wallet.
<br />
<br />
Your staked tokens and their accrued rebase rewards will be available to claim at the start of
the third epoch after you originally staked. Once claimed, the tokens move to your staked token
balance, where they will continue to earn rebase rewards and can be unstaked at any time without
penalty.
</p>
</div>
</div>
</div>
)}
</div>
</Grid>
</div>
</Zoom>
</div>
);
}
Example #19
Source File: index.tsx From rugenerous-frontend with MIT License | 4 votes |
function Redemption() {
const [anchorEl, setAnchorEl] = useState(null);
const dispatch = useDispatch();
const { provider, address, connect, chainID, checkWrongNetwork } = useWeb3Context();
const [view, setView] = useState(0);
const [quantity, setQuantity] = useState<string>("");
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const app = useSelector<IReduxState, IAppSlice>(state => state.app);
const currentIndex = useSelector<IReduxState, number>(state => {
return state.app.rfv;
});
const setRFV = useSelector<IReduxState, number>(state => {
return state.app.setRFV;
});
const timeBalance = useSelector<IReduxState, string>(state => {
return state.account.balances && state.account.balances.rug;
});
const timeBalanceValue = (Number(timeBalance) * setRFV) / 100;
//Adding Durag - KM
const redeemAllowance = useSelector<IReduxState, number>(state => {
return state.account.redeem && state.account.redeem.rug;
});
const pendingTransactions = useSelector<IReduxState, IPendingTxn[]>(state => {
return state.pendingTransactions;
});
const setMax = () => {
const fullBalance = Number(timeBalance);
setQuantity(trim(fullBalance, 4));
console.log(quantity);
};
const onSeekApproval = async (token: string) => {
if (await checkWrongNetwork()) return;
await dispatch(changeApproval({ address, token, provider, networkID: chainID }));
};
const onRedeem = async (action: string) => {
if (await checkWrongNetwork()) return;
if (quantity === "" || parseFloat(quantity) === 0) {
dispatch(warning({ text: action === "redeem" ? messages.before_redeem : "" }));
} else {
await dispatch(
redeemFromRUG({
address,
action,
value: String(quantity),
provider,
networkID: chainID,
}),
);
setQuantity("");
}
};
const hasAllowance = useCallback(
token => {
if (token === "rug") return redeemAllowance > 0;
return 0;
},
[redeemAllowance],
);
const changeView = (newView: number) => () => {
setView(newView);
setQuantity("");
};
const handleClick = (event: any) => {
setAnchorEl(anchorEl ? null : event.currentTarget);
};
return (
<div className="redeem-view">
<Zoom in={true}>
<div className="redeem-card">
<Grid className="redeem-card-grid" container direction="column" spacing={2}>
<Grid item>
<div className="redeem-card-header">
<p className="redeem-card-header-title">The RUG Redemption (?, ?)</p>
</div>
</Grid>
<Grid item>
<div className="redeem-card-metrics">
<Grid container spacing={2}>
<Grid item xs={6} sm={4} md={4} lg={4}>
<div className="redeem-card-index">
<p className="redeem-card-metrics-title">Approximate RFV</p>
<p className="redeem-card-metrics-value">
{currentIndex ? <>${trim(Number(currentIndex), 2)}</> : <Skeleton width="150px" />}
</p>
</div>
</Grid>
<Grid item xs={6} sm={4} md={4} lg={4}>
<div className="redeem-card-index">
<p className="redeem-card-metrics-title">Applied Risk Free Value</p>
<p className="redeem-card-metrics-value">
{currentIndex ? <>${trim(Number(setRFV / 100), 2)}</> : <Skeleton width="150px" />}
</p>
</div>
</Grid>
</Grid>
</div>
</Grid>
<div className="redeem-card-area">
{!address && (
<div className="redeem-card-wallet-notification">
<div className="redeem-card-wallet-connect-btn" onClick={connect}>
<p>Connect Wallet</p>
</div>
<p className="redeem-card-wallet-desc-text">
Connect your wallet to Redeem USDC for your RUG tokens!
</p>
</div>
)}
{address && (
<div>
<div className="redeem-card-action-area">
<div className="redeem-card-action-stage-btns-wrap">
<div
onClick={changeView(0)}
className={classnames("redeem-card-action-stage-btn", { active: !view })}
>
<p>Redeem</p>
</div>
</div>
<div className="redeem-card-action-row">
<OutlinedInput
type="number"
placeholder="Amount"
className="redeem-card-action-input"
value={quantity}
onChange={e => setQuantity(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div onClick={setMax} className="redeem-card-action-input-btn">
<p>Max</p>
</div>
</InputAdornment>
}
/>
<div className="redeem-card-tab-panel">
{address && hasAllowance("rug") ? (
<div
className="redeem-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "redeem")) return;
onRedeem("redeem");
}}
>
<p>{txnButtonText(pendingTransactions, "redeem", "Redeem USDC")}</p>
</div>
) : (
<div
className="redeem-card-tab-panel-btn"
onClick={() => {
if (isPendingTxn(pendingTransactions, "approve_redeem")) return;
onSeekApproval("rug");
}}
>
<p>{txnButtonText(pendingTransactions, "approve_redeem", "Approve")}</p>
</div>
)}
</div>
</div>
<div className="redeem-card-action-help-text">
{address && !hasAllowance("rug") && view === 0 && (
<p>
Note: The "Approve" transaction is only needed when redeeming for the first time, subsequent
redemptions only requires you to perform the "Redeem" transaction.
</p>
)}
</div>
</div>
<div className="redeem-user-data">
<div className="data-row">
<p className="data-row-name">Your Balance</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>{trim(Number(timeBalance), 4)} RUG</>}
</p>
</div>
<div className="data-row">
<p className="data-row-name">Your Balance Value</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>${trim(timeBalanceValue, 4)}</>}
</p>
</div>
</div>
</div>
)}
</div>
</Grid>
</div>
</Zoom>
</div>
);
}
Example #20
Source File: index.tsx From rugenerous-frontend with MIT License | 4 votes |
function Dashboard() {
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const app = useSelector<IReduxState, IAppSlice>(state => state.app);
const trimmedStakingAPY = trim(app.stakingAPY * 100, 1);
return (
<div className="dashboard-view">
<div className="dashboard-infos-wrap">
<Zoom in={true}>
<Grid container spacing={4}>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">RUG Price</p>
<p className="card-value">
{isAppLoading ? <Skeleton width="100px" /> : `$${trim(app.marketPrice, 2)}`}
</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">5-day Staking ROI</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="160px" />
) : (
new Intl.NumberFormat("en-US", {
style: "percent",
minimumFractionDigits: 2,
}).format(Number(app.fiveDayRate))
)}
</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Market Cap</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="160px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.marketCap)
)}
</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Supply (Staked/Total)</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
`${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.circSupply)}
/
${new Intl.NumberFormat("en-US", {
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.totalSupply)}`
)}
</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">TVL</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.stakingTVL)
)}
</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">APY</p>
{isAppLoading ? (
<p className="card-value text-center">
<Skeleton width="250px" />
</p>
) : (
<p
className="card-value text-center"
data-tip={`${new Intl.NumberFormat("en-US").format(Number(trimmedStakingAPY))}%`}
>
Nice Round Number
</p>
)}
</div>
<ReactTooltip className="tooltip-value" />
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Current Index</p>
<p className="card-value">
{isAppLoading ? <Skeleton width="250px" /> : `${trim(Number(app.currentIndex), 2)} RUG`}
</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Treasury Balance</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.treasuryBalance)
)}
</p>
</div>
</Grid>
<Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Runway</p>
<p className="card-value">
{isAppLoading ? <Skeleton width="250px" /> : `${trim(Number(app.runway), 1)} Days`}
</p>
</div>
</Grid>
</Grid>
</Zoom>
</div>
</div>
// RUG Backing Grid Element
// KM - Relocating to here so we can use in the future
/* <Grid item lg={6} md={6} sm={6} xs={12}>
<div className="dashboard-card">
<p className="card-title">Backing per $RUG</p>
<p className="card-value">
{isAppLoading ? (
<Skeleton width="250px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(app.rfv)
)}
</p>
</div>
</Grid> */
);
}
Example #21
Source File: index.tsx From rugenerous-frontend with MIT License | 4 votes |
function ChooseBond() {
const { bonds } = useBonds();
const isSmallScreen = useMediaQuery("(max-width: 733px)"); // change to breakpoint query
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const marketPrice = useSelector<IReduxState, number>(state => {
return state.app.marketPrice;
});
const treasuryBalance = useSelector<IReduxState, number>(state => {
return state.app.treasuryBalance;
});
const [view, setView] = useState(0);
const changeView = (newView: number) => () => {
setView(newView);
};
return (
<div className="choose-bond-view">
<Zoom in={true}>
<div className="choose-bond-view-card">
<div className="choose-bond-view-card-header">
<p className="choose-bond-view-card-title"> Get Rugged</p>
</div>
<Grid container item xs={12} spacing={2} className="choose-bond-view-card-metrics">
<Grid item xs={12} sm={6}>
<Box textAlign="center">
<p className="choose-bond-view-card-metrics-title">Treasury Balance</p>
<p className="choose-bond-view-card-metrics-value">
{isAppLoading ? (
<Skeleton width="180px" />
) : (
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(treasuryBalance)
)}
</p>
</Box>
</Grid>
<Grid item xs={12} sm={6}>
<Box textAlign="center">
<p className="choose-bond-view-card-metrics-title">RUG Price</p>
<p className="choose-bond-view-card-metrics-value">
{isAppLoading ? <Skeleton width="100px" /> : `$${trim(marketPrice, 2)}`}
</p>
</Box>
</Grid>
</Grid>
{!isSmallScreen && (
<>
<div className="bond-one-table">
<div className={classnames("bond-one-table-btn", { active: !view })} onClick={changeView(0)}>
<p>Available Bonds</p>
</div>
<div className={classnames("bond-one-table-btn", { active: view })} onClick={changeView(1)}>
<p>Sold Out / Upcoming Bonds</p>
</div>
</div>
<TabPanel value={view} index={0}>
<Grid container item>
<TableContainer className="choose-bond-view-card-table">
<Table>
<TableHead>
<TableRow>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">Mint</p>
</TableCell>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">Price</p>
</TableCell>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">ROI</p>
</TableCell>
<TableCell align="right">
<p className="choose-bond-view-card-table-title">Purchased</p>
</TableCell>
<TableCell align="right"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{bonds.map(bond => bond.available && <BondTableData key={bond.name} bond={bond} />)}
</TableBody>
</Table>
</TableContainer>
</Grid>
</TabPanel>
<TabPanel value={view} index={1}>
<Grid container item>
<TableContainer className="choose-bond-view-card-table">
<Table>
<TableHead>
<TableRow>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">Mint</p>
</TableCell>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">Price</p>
</TableCell>
<TableCell align="center">
<p className="choose-bond-view-card-table-title">ROI</p>
</TableCell>
<TableCell align="right">
<p className="choose-bond-view-card-table-title">Purchased</p>
</TableCell>
<TableCell align="right"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{bonds.map(bond => !bond.available && <BondTableData key={bond.name} bond={bond} />)}
</TableBody>
</Table>
</TableContainer>
</Grid>
</TabPanel>
</>
)}
</div>
</Zoom>
{isSmallScreen && (
<div className="choose-bond-view-card-container">
<Grid container item spacing={2}>
{bonds.map(bond => (
<Grid item xs={12} key={bond.name}>
<BondDataCard key={bond.name} bond={bond} />
</Grid>
))}
</Grid>
</div>
)}
</div>
);
}
Example #22
Source File: index.tsx From rugenerous-frontend with MIT License | 4 votes |
function Calculator() {
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const marketPrice = useSelector<IReduxState, number>(state => {
return state.app.marketPrice;
});
const stakingAPY = useSelector<IReduxState, number>(state => {
return state.app.stakingAPY;
});
const memoBalance = useSelector<IReduxState, string>(state => {
return state.account.balances && state.account.balances.srug;
});
const trimmedStakingAPY = trim(stakingAPY * 100, 1);
const trimmedMemoBalance = trim(Number(memoBalance), 6);
const trimeMarketPrice = trim(marketPrice, 2);
const [memoAmount, setMemoAmount] = useState(trimmedMemoBalance);
const [rewardYield, setRewardYield] = useState(trimmedStakingAPY);
const [priceAtPurchase, setPriceAtPurchase] = useState(trimeMarketPrice);
const [futureMarketPrice, setFutureMarketPrice] = useState(trimeMarketPrice);
const [days, setDays] = useState(30);
const [rewardsEstimation, setRewardsEstimation] = useState("0");
const [potentialReturn, setPotentialReturn] = useState("0");
const calcInitialInvestment = () => {
const srug = Number(memoAmount) || 0;
const price = parseFloat(priceAtPurchase) || 0;
const amount = srug * price;
return trim(amount, 2);
};
const calcCurrentWealth = () => {
const srug = Number(memoAmount) || 0;
const price = parseFloat(trimeMarketPrice);
const amount = srug * price;
return trim(amount, 2);
};
const [initialInvestment, setInitialInvestment] = useState(calcInitialInvestment());
useEffect(() => {
const newInitialInvestment = calcInitialInvestment();
setInitialInvestment(newInitialInvestment);
}, [memoAmount, priceAtPurchase]);
const calcNewBalance = () => {
let value = parseFloat(rewardYield) / 100;
value = Math.pow(value - 1, 1 / (365 * 3)) - 1 || 0;
let balance = Number(memoAmount);
for (let i = 0; i < days * 3; i++) {
balance += balance * value;
}
return balance;
};
useEffect(() => {
const newBalance = calcNewBalance();
setRewardsEstimation(trim(newBalance, 6));
const newPotentialReturn = newBalance * (parseFloat(futureMarketPrice) || 0);
setPotentialReturn(trim(newPotentialReturn, 2));
}, [days, rewardYield, futureMarketPrice, memoAmount]);
return (
<div className="calculator-view">
<Zoom in={true}>
<div className="calculator-card">
<Grid className="calculator-card-grid" container direction="column" spacing={2}>
<Grid item>
<div className="calculator-card-header">
<p className="calculator-card-header-title">Super Accurate Calculator</p>
<p className="calculator-card-header-subtitle">Estimate how much you get rugged...</p>
</div>
</Grid>
<Grid item>
<div className="calculator-card-metrics">
<Grid container spacing={2}>
<Grid item xs={12} sm={4} md={4} lg={4}>
<div className="calculator-card-apy">
<p className="calculator-card-metrics-title">RUG Price</p>
<p className="calculator-card-metrics-value">
{isAppLoading ? <Skeleton width="100px" /> : `$${trimeMarketPrice}`}
</p>
</div>
</Grid>
<Grid item xs={6} sm={4} md={4} lg={4}>
<div className="calculator-card-tvl">
<p className="calculator-card-metrics-title">Current APY</p>
<p className="calculator-card-metrics-value">
{isAppLoading ? (
<Skeleton width="100px" />
) : (
<>{new Intl.NumberFormat("en-US").format(Number(trimmedStakingAPY))}%</>
)}
</p>
</div>
</Grid>
<Grid item xs={6} sm={4} md={4} lg={4}>
<div className="calculator-card-index">
<p className="calculator-card-metrics-title">Your RUGGED Balance</p>
<p className="calculator-card-metrics-value">
{isAppLoading ? <Skeleton width="100px" /> : <>{trimmedMemoBalance} RUGGED</>}
</p>
</div>
</Grid>
</Grid>
</div>
</Grid>
<div className="calculator-card-area">
<div>
<div className="calculator-card-action-area">
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<div className="calculator-card-action-area-inp-wrap">
<p className="calculator-card-action-area-inp-wrap-title">RUGGED Amount</p>
<OutlinedInput
type="number"
placeholder="Amount"
className="calculator-card-action-input"
value={memoAmount}
onChange={e => setMemoAmount(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div
onClick={() => setMemoAmount(trimmedMemoBalance)}
className="stake-card-action-input-btn"
>
<p>Max</p>
</div>
</InputAdornment>
}
/>
</div>
</Grid>
<Grid item xs={12} sm={6}>
<div className="calculator-card-action-area-inp-wrap">
<p className="calculator-card-action-area-inp-wrap-title">APY (%)</p>
<OutlinedInput
type="number"
placeholder="Amount"
className="calculator-card-action-input"
value={rewardYield}
onChange={e => setRewardYield(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div
onClick={() => setRewardYield(trimmedStakingAPY)}
className="stake-card-action-input-btn"
>
<p>Current</p>
</div>
</InputAdornment>
}
/>
</div>
</Grid>
<Grid item xs={12} sm={6}>
<div className="calculator-card-action-area-inp-wrap">
<p className="calculator-card-action-area-inp-wrap-title">RUG price at purchase ($)</p>
<OutlinedInput
type="number"
placeholder="Amount"
className="calculator-card-action-input"
value={priceAtPurchase}
onChange={e => setPriceAtPurchase(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div
onClick={() => setPriceAtPurchase(trimeMarketPrice)}
className="stake-card-action-input-btn"
>
<p>Current</p>
</div>
</InputAdornment>
}
/>
</div>
</Grid>
<Grid item xs={12} sm={6}>
<div className="calculator-card-action-area-inp-wrap">
<p className="calculator-card-action-area-inp-wrap-title">Future RUG market price ($)</p>
<OutlinedInput
type="number"
placeholder="Amount"
className="calculator-card-action-input"
value={futureMarketPrice}
onChange={e => setFutureMarketPrice(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div
onClick={() => setFutureMarketPrice(trimeMarketPrice)}
className="stake-card-action-input-btn"
>
<p>Current</p>
</div>
</InputAdornment>
}
/>
</div>
</Grid>
</Grid>
</div>
<div className="calculator-days-slider-wrap">
<p className="calculator-days-slider-wrap-title">{`${days} day${days > 1 ? "s" : ""}`}</p>
<Slider
className="calculator-days-slider"
min={1}
max={365}
value={days}
onChange={(e, newValue: any) => setDays(newValue)}
/>
</div>
<div className="calculator-user-data">
<div className="data-row">
<p className="data-row-name">Your initial investment</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>${initialInvestment}</>}
</p>
</div>
<div className="data-row">
<p className="data-row-name">Current wealth</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>${calcCurrentWealth()}</>}
</p>
</div>
<div className="data-row">
<p className="data-row-name">RUG rewards estimation</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>{rewardsEstimation} RUG</>}
</p>
</div>
<div className="data-row">
<p className="data-row-name">Potential return</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>${potentialReturn}</>}
</p>
</div>
<div className="data-row">
<p className="data-row-name">Potential number of lambos</p>
<p className="data-row-value">
{isAppLoading ? <Skeleton width="80px" /> : <>{Math.floor(Number(potentialReturn) / 220000)}</>}
</p>
</div>
</div>
</div>
</div>
</Grid>
</div>
</Zoom>
</div>
);
}
Example #23
Source File: index.tsx From lobis-frontend with MIT License | 4 votes |
function LobisMeter() {
const dispatch = useDispatch();
const { provider, address, connect, chainID, checkWrongNetwork } = useWeb3Context();
const [view, setView] = useState(0);
const [quantity, setQuantity] = useState<string>("");
const [rewardYield, setRewardYield] = useState<string>("");
const [lobiPrice, setLobiPrice] = useState<string>("");
const [days, setDays] = useState<number>(30);
const [futureLobiPrice, setFutureLobiPrice] = useState<string>("");
const [apy, setApy] = useState<string>("");
const isAppLoading = useSelector<IReduxState, boolean>(state => state.app.loading);
const sLobiBalance = useSelector<IReduxState, string>(state => {
return state.account.balances && state.account.balances.sLobi;
});
const stakingRebase = useSelector<IReduxState, number>(state => {
return state.app.stakingRebase;
});
const stakingAPY = useSelector<IReduxState, number>(state => {
return state.app.stakingAPY;
});
const marketPrice = useSelector<IReduxState, number>(state => {
return state.app.marketPrice;
});
const epoch = useSelector<IReduxState, any[]>(state => {
return state.app.epoch;
});
const handleDays = (newValue: number | number[]) => {
setDays(newValue as number);
};
const setMax = () => {
setQuantity(sLobiBalance);
};
const handleAPY = (value: string) => {
setApy(value);
const newRewardYield = (Math.pow(Number(value) / 100, 1 / (365 * dailyRebaseAmounts)) - 1) * 100;
setRewardYield(trim(newRewardYield, 4).toString());
if (value === "") {
setRewardYield("");
}
};
const handleRewardYield = (value: string) => {
setRewardYield(value);
const newAPY = (Math.pow(1 + Number(value) / 100, 365 * dailyRebaseAmounts) - 1) * 100;
setApy(trim(newAPY, 4).toString());
if (value === "") {
setApy("");
}
};
const setCurrent = (type: string) => {
switch (type) {
case "rewardYield":
setRewardYield(stakingRebasePercentage);
const newAPY = (Math.pow(1 + Number(stakingRebasePercentage) / 100, 365 * dailyRebaseAmounts) - 1) * 100;
setApy(trim(newAPY, 4).toString());
break;
case "setPrice":
setLobiPrice(marketPrice.toString());
break;
case "futurePrice":
setFutureLobiPrice(marketPrice.toString());
break;
}
};
const trimmedSLobiBalance = trim(Number(sLobiBalance), 6);
const stakingRebasePercentage = trim(stakingRebase * 100, 4);
const blockSecondLength = 13;
const rebaseTimeInSeconds = epoch ? epoch[0] * blockSecondLength : 28800;
const dailyRebaseAmounts = 86400 / rebaseTimeInSeconds;
const totalReturn = (Math.pow(1 + Number(rewardYield) / 100, days * dailyRebaseAmounts) - 1) * Number(quantity);
const initialInvestment = parseFloat(lobiPrice) * parseFloat(quantity);
const potentialReturn = parseFloat(futureLobiPrice) * (totalReturn + Number(quantity)) - initialInvestment;
const daysUntilTwoTimes = Math.log(2) / Math.log(1 + Number(rewardYield) / 100) / dailyRebaseAmounts;
const daysUntilFiveTimes = Math.log(5) / Math.log(1 + Number(rewardYield) / 100) / dailyRebaseAmounts;
const daysUntilTenTimes = Math.log(10) / Math.log(1 + Number(rewardYield) / 100) / dailyRebaseAmounts;
return (
<div className="stake-view">
<Zoom in={true}>
<div className="stake-card">
<Grid className="stake-card-grid" container direction="column" spacing={2}>
<Grid item>
<div className="stake-card-header">
<p className="stake-card-header-title">Calculator</p>
<p className="stake-card-header-description">Please fill the inputs to simulate your rewards</p>
</div>
</Grid>
<Grid item>
<div className="stake-card-metrics">
<Grid container spacing={2}>
<Grid item lg={4} md={4} sm={4} xs={12}>
<div className="stake-card-apy">
<p className="stake-card-metrics-title">{TOKEN_NAME} Price</p>
<p className="stake-card-metrics-value">{isAppLoading ? <Skeleton width="100px" /> : `$${trim(marketPrice, 2)}`}</p>
</div>
</Grid>
<Grid item xs={12} sm={4} md={4} lg={4}>
<div className="stake-card-tvl">
<p className="stake-card-metrics-title">Current Reward Yield</p>
<p className="stake-card-metrics-value">{isAppLoading ? <Skeleton width="80px" /> : <>{stakingRebasePercentage}%</>}</p>
</div>
</Grid>
<Grid item xs={12} sm={4} md={4} lg={4}>
<div className="stake-card-index">
<p className="stake-card-metrics-title">Your {STAKING_TOKEN_NAME} Balance</p>
<p className="stake-card-metrics-value">
{isAppLoading ? (
<Skeleton width="80px" />
) : (
<>
{trimmedSLobiBalance} {STAKING_TOKEN_NAME}
</>
)}
</p>
</div>
</Grid>
</Grid>
</div>
</Grid>
<div className="stake-card-area">
{address && (
<div>
<div className="stake-card-action-area">
<div className="stake-card-action-row">
<OutlinedInput
type="number"
placeholder={`${STAKING_TOKEN_NAME} amount`}
className="stake-card-action-input"
value={quantity}
onChange={e => setQuantity(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div onClick={setMax} className="stake-card-action-input-btn">
<p>Max</p>
</div>
</InputAdornment>
}
/>
</div>
<div className="stake-card-action-row">
<OutlinedInput
type="number"
placeholder={`APY (%)`}
className="stake-card-action-input"
value={apy}
onChange={e => handleAPY(e.target.value)}
labelWidth={0}
endAdornment={<InputAdornment position="end"></InputAdornment>}
/>
</div>
<div className="stake-card-action-row">
<OutlinedInput
type="number"
placeholder={`Reward yield each rebase (%)`}
className="stake-card-action-input"
value={rewardYield}
onChange={e => handleRewardYield(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div onClick={() => setCurrent("rewardYield")} className="stake-card-action-input-btn">
<p>Current</p>
</div>
</InputAdornment>
}
/>
</div>
<div className="stake-card-action-row">
<OutlinedInput
type="number"
placeholder={`${TOKEN_NAME} price at purchase ($) `}
className="stake-card-action-input"
value={lobiPrice}
onChange={e => setLobiPrice(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div onClick={() => setCurrent("setPrice")} className="stake-card-action-input-btn">
<p>Current</p>
</div>
</InputAdornment>
}
/>
</div>
<div className="stake-card-action-row">
<OutlinedInput
type="number"
placeholder={`Future ${TOKEN_NAME} market price ($)`}
className="stake-card-action-input"
value={futureLobiPrice}
onChange={e => setFutureLobiPrice(e.target.value)}
labelWidth={0}
endAdornment={
<InputAdornment position="end">
<div onClick={() => setCurrent("futurePrice")} className="stake-card-action-input-btn">
<p>Current</p>
</div>
</InputAdornment>
}
/>
</div>
<div className="stake-card-action-row">
<Slider className="slider" min={1} max={365} onChange={(e, val) => handleDays(val)} value={days} />{" "}
<p className="days-text">
{days} {days === 1 ? "Day" : "Days"}
</p>
</div>
</div>
<div className="stake-user-data">
<div className="data-row">
<p className="data-row-name">Your Initial Investment</p>
<p className="data-row-value">
{isAppLoading ? (
<Skeleton width="80px" />
) : (
<>
{initialInvestment > 0
? new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 5,
minimumFractionDigits: 0,
}).format(initialInvestment)
: new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(0)}
</>
)}
</p>
</div>
{/*<div className="data-row">
<p className="data-row-name">Current Wealth</p>
<p className="data-row-value">
{
<>
{marketPrice * parseFloat(trimmedSLobiBalance) > 0
? new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 5,
minimumFractionDigits: 0,
}).format(marketPrice * parseFloat(trimmedSLobiBalance))
: new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(0)}
</>
}
</p>
</div>*/}
<div className="data-row">
<p className="data-row-name">{`${TOKEN_NAME} rewards estimation`}</p>
<p className="data-row-value">{totalReturn > 0 ? `${trim(totalReturn, 4)} ${TOKEN_NAME}` : `0 ${TOKEN_NAME}`}</p>
</div>
<div className="data-row">
<p className="data-row-name">Total return</p>
<p className="data-row-value">
{!isNaN(potentialReturn)
? new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 5,
minimumFractionDigits: 0,
}).format(potentialReturn)
: "--"}
</p>
</div>
{rewardYield !== "" && (
<div style={{ width: "100%" }}>
<Divider style={{ backgroundColor: " rgba(255, 255, 255, 0.2)" }} />
</div>
)}
</div>
</div>
)}
{rewardYield !== "" && (
<div className="stake-user-data">
<div className="data-row">
<p className="data-row-name">Amount of days Until...</p>
<p className="data-row-value"></p>
</div>
<div className="data-row">
<p className="data-row-name">2x {STAKING_TOKEN_NAME}</p>
<p className="data-row-value">
{daysUntilTwoTimes.toFixed(1)} {daysUntilTwoTimes > 1 ? "Days" : "Day"}
</p>
</div>
<div className="data-row">
<p className="data-row-name">5x {STAKING_TOKEN_NAME}</p>
<p className="data-row-value">
{daysUntilFiveTimes.toFixed(1)} {daysUntilTwoTimes > 1 ? "Days" : "Day"}
</p>
</div>
<div className="data-row">
<p className="data-row-name">10x {STAKING_TOKEN_NAME}</p>
<p className="data-row-value">
{daysUntilTenTimes.toFixed(1)} {daysUntilTwoTimes > 1 ? "Days" : "Day"}
</p>
</div>
</div>
)}
</div>
</Grid>
</div>
</Zoom>
</div>
);
}