Skip to content

Commit

Permalink
DAO-557: The number of decimals displayed should be the same across t…
Browse files Browse the repository at this point in the history
…he dApp (#95)

* treasury page

* proposal page

* user page

* rename some input components

* move form textarea and label

* use input number on stake modal

* format proposal votes

* fix build

* fix proposal form validation
  • Loading branch information
rodrigoncalves authored Aug 8, 2024
1 parent 972b0e1 commit af659b5
Show file tree
Hide file tree
Showing 28 changed files with 339 additions and 304 deletions.
3 changes: 2 additions & 1 deletion src/app/proposals/LatestProposalsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ComparativeProgressBar } from '@/components/ComparativeProgressBar/Comp
import { Popover } from '@/components/Popover'
import { Table } from '@/components/Table'
import { Header, Paragraph } from '@/components/Typography'
import { toFixed } from '@/lib/utils'
import { useRouter } from 'next/navigation'
import { useMemo } from 'react'

Expand All @@ -26,7 +27,7 @@ const ProposalNameColumn = ({ name, proposalId }: ProposalNameColumnProps) => {
const VotesColumn = ({ proposalId }: Omit<ProposalNameColumnProps, 'name'>) => {
const data = useGetProposalVotes(proposalId)
const votes = data.reduce((prev, next) => Number(next) + prev, 0)
return <p>{votes.toString()}</p>
return <p>{toFixed(votes)}</p>
}

const PopoverSentiment = ({ votes }: { votes: string[] }) => {
Expand Down
5 changes: 4 additions & 1 deletion src/app/proposals/hooks/useGetProposalVotes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { useReadContract } from 'wagmi'
import { GovernorAddress } from '@/lib/contracts'
import { GovernorAbi } from '@/lib/abis/Governor'
import { formatUnits } from 'viem'
import { toFixed } from '@/lib/utils'

// 0 = against, 1 = forVotes, 2 = abstain
export const useGetProposalVotes = (proposalId: string, shouldRefetch = false) => {
const { data } = useReadContract({
Expand All @@ -15,7 +17,8 @@ export const useGetProposalVotes = (proposalId: string, shouldRefetch = false) =
})

if (data) {
return [formatUnits(data[0], 18), formatUnits(data[1], 18), formatUnits(data[2], 18)]
const format = (value: bigint) => toFixed(formatUnits(value, 18))
return [format(data[0]), format(data[1]), format(data[2])]
}
return ['0', '0', '0']
}
3 changes: 2 additions & 1 deletion src/app/treasury/TokenHoldings.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { TreasurySymbolsSupported, useTreasuryContext } from '@/app/treasury/TreasuryContext'
import { toFixed } from '@/lib/utils'

interface TokenHoldingsProps {
symbol: TreasurySymbolsSupported
Expand All @@ -8,7 +9,7 @@ export const TokenHoldings = ({ symbol }: TokenHoldingsProps) => {
const { bucketsTotal } = useTreasuryContext()
return (
<p>
{bucketsTotal[symbol]} {symbol}
{toFixed(bucketsTotal[symbol])} {symbol}
</p>
)
}
5 changes: 3 additions & 2 deletions src/app/treasury/TokenHoldingsStRIF.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { StRIFTokenAbi } from '@/lib/abis/StRIFTokenAbi'
import { tokenContracts } from '@/lib/contracts'
import { toFixed } from '@/lib/utils'
import { useMemo } from 'react'
import { formatEther } from 'viem'
import { useReadContract } from 'wagmi'
Expand All @@ -11,7 +12,7 @@ export const TokenHoldingsStRIF = () => {
functionName: 'totalSupply',
})

const balance = useMemo(() => formatEther(data ?? 0n), [data])
const balance = useMemo(() => Number(formatEther(data ?? 0n)), [data])

return <p>{balance} stRIF</p>
return <p>{toFixed(balance)} stRIF</p>
}
2 changes: 1 addition & 1 deletion src/app/treasury/TotalTokenHoldingsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const tableData = [
{
token: 'Staked Rootstock Infrastructure Framework',
symbol: 'stRIF',
price: '-',
price: '',
holdings: <TokenHoldingsStRIF />,
},
]
Expand Down
2 changes: 1 addition & 1 deletion src/app/treasury/TreasurySection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const TreasurySection = () => {
const [bucketOne, bucketTwo, bucketThree] = buckets
return (
<div>
<Paragraph className="font-semibold text-[18px]">Treasury</Paragraph>
<Paragraph className="font-semibold text-[18px] mb-[17px]">Treasury</Paragraph>
<div className="grid grid-cols-3 gap-[24px]">
<MetricsCard
title="Treasury 1 RIF Holdings"
Expand Down
4 changes: 2 additions & 2 deletions src/app/user/Balances/RenderTotalBalance.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useBalancesContext } from '@/app/user/Balances/context/BalancesContext'
import { SupportedTokens } from '@/lib/contracts'
import { formatCurrency } from '@/lib/utils'
import { formatCurrency, toFixed } from '@/lib/utils'

interface Props {
symbol: SupportedTokens
Expand All @@ -12,7 +12,7 @@ export const RenderTotalBalance = ({ symbol }: Props) => {
return (
<>
<p>
{token.balance} {token.symbol}
{toFixed(token.balance)} {token.symbol}
</p>
{prices[symbol] && <p>= {formatCurrency(prices[symbol].price * Number(token.balance) ?? 0)}</p>}
</>
Expand Down
13 changes: 4 additions & 9 deletions src/app/user/Stake/StakeInput.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { TextInput } from '@/components/TextInput/TextInput'
import { isValidNumber } from '@/lib/utils'
import { Input } from '@/components/Input'

interface Props {
onChange: (value: string) => void
Expand All @@ -9,16 +8,12 @@ interface Props {
}

export const StakeInput = ({ onChange, value, symbol = 'RIF', labelText }: Props) => {
const handleChange = (value: string) => {
if (isValidNumber(value)) {
onChange(value)
}
}
return (
<TextInput
<Input
type="number"
label={labelText}
placeholder={`${symbol} Amount`}
onChange={handleChange}
onChange={onChange}
value={value}
name="amount-stake"
fullWidth
Expand Down
127 changes: 58 additions & 69 deletions src/app/user/Stake/StakeRIF.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,74 +26,63 @@ export const StakeRIF = ({
totalBalanceConverted,
actionName,
symbol = 'RIF',
}: Props) => {
const onUserAmountInput = useCallback((value: string) => onAmountChange(value), [onAmountChange])

const onPercentageButtonClick = useCallback(
(percentageClicked: number) => onPercentageClicked(percentageClicked),
[onPercentageClicked],
)

return (
<div>
<div className="px-[50px] py-[20px]">
<Header className="text-center">
{textsDependingOnAction[actionName].modalTitle}
{symbol}
</Header>
<StakeInput
onChange={onUserAmountInput}
value={amount}
symbol={symbol}
labelText={textsDependingOnAction[actionName].inputLabel}
/>
<Label>
Available: {totalBalance} {symbol} {totalBalanceConverted && `= ${totalBalanceConverted}`}
</Label>
{/* Percentage button */}
<div className="flex justify-end gap-2 pt-1">
<PercentageButton
percentage={10}
onClick={onPercentageButtonClick}
totalAmountAllowed={totalBalance}
amount={amount}
/>
<PercentageButton
percentage={20}
onClick={onPercentageButtonClick}
totalAmountAllowed={totalBalance}
amount={amount}
/>
<PercentageButton
percentage={50}
onClick={onPercentageButtonClick}
totalAmountAllowed={totalBalance}
amount={amount}
/>
<PercentageButton
percentage={100}
onClick={onPercentageButtonClick}
totalAmountAllowed={totalBalance}
amount={amount}
/>
</div>
{/* @TODO if we're unstaking we should have a component here - check design */}
{/* Stake */}
<div className="flex justify-center pt-10">
<Button
onClick={shouldEnableGoNext ? onGoNext : undefined}
disabled={!shouldEnableGoNext}
buttonProps={{
'data-testid': 'StakeRIF',
}}
>
{textsDependingOnAction[actionName].confirmButtonText}
</Button>
</div>
</div>
}: Props) => (
<div className="px-[50px] py-[20px]">
<Header className="text-center">
{textsDependingOnAction[actionName].modalTitle}
{symbol}
</Header>
<StakeInput
onChange={onAmountChange}
value={amount}
symbol={symbol}
labelText={textsDependingOnAction[actionName].inputLabel}
/>
<Label>
Available: {totalBalance} {symbol} {totalBalanceConverted && `= ${totalBalanceConverted}`}
</Label>
{/* Percentage button */}
<div className="flex justify-end gap-2 pt-1">
<PercentageButton
percentage={10}
onClick={onPercentageClicked}
totalAmountAllowed={totalBalance}
amount={amount}
/>
<PercentageButton
percentage={20}
onClick={onPercentageClicked}
totalAmountAllowed={totalBalance}
amount={amount}
/>
<PercentageButton
percentage={50}
onClick={onPercentageClicked}
totalAmountAllowed={totalBalance}
amount={amount}
/>
<PercentageButton
percentage={100}
onClick={onPercentageClicked}
totalAmountAllowed={totalBalance}
amount={amount}
/>
</div>
)
}
{/* @TODO if we're unstaking we should have a component here - check design */}
{/* Stake */}
<div className="flex justify-center pt-10">
<Button
onClick={shouldEnableGoNext ? onGoNext : undefined}
disabled={!shouldEnableGoNext}
buttonProps={{
'data-testid': 'StakeRIF',
}}
>
{textsDependingOnAction[actionName].confirmButtonText}
</Button>
</div>
</div>
)

interface PercentageButtonProps {
amount: string
Expand All @@ -103,7 +92,7 @@ interface PercentageButtonProps {
}

const PercentageButton = ({ amount, percentage, totalAmountAllowed, onClick }: PercentageButtonProps) => {
const onPercentageButtonClick = () => onClick(percentage)
const onPercentageClicked = () => onClick(percentage)

const isActive = useMemo(() => {
const totalAmountAllowedPercentage = Number(totalAmountAllowed) * (percentage / 100)
Expand All @@ -113,7 +102,7 @@ const PercentageButton = ({ amount, percentage, totalAmountAllowed, onClick }: P
return (
<Button
variant={isActive ? 'secondary-full' : 'secondary'}
onClick={onPercentageButtonClick}
onClick={onPercentageClicked}
buttonProps={{
'data-testid': `Percentage${percentage}`,
}}
Expand Down
4 changes: 2 additions & 2 deletions src/app/user/Stake/StakingContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export const StakingProvider: FC<Props> = ({

const stakePreviewFrom = useMemo(
() => ({
amount: toFixed(Number(stakeData.amount)),
amount: toFixed(stakeData.amount),
amountConvertedToCurrency:
'USD ' + formatCurrency(Number(tokenToSend.price) * Number(stakeData.amount) ?? 0),
balance: tokenToSend.balance,
Expand All @@ -117,7 +117,7 @@ export const StakingProvider: FC<Props> = ({

const stakePreviewTo = useMemo(
() => ({
amount: toFixed(Number(amountDataToReceive.amountToReceive)),
amount: toFixed(amountDataToReceive.amountToReceive),
amountConvertedToCurrency: amountDataToReceive.amountToReceiveConvertedToCurrency,
balance: tokenToReceive.balance,
tokenSymbol: tokenToReceive.symbol,
Expand Down
14 changes: 7 additions & 7 deletions src/components/Form/Form.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Meta, StoryObj } from '@storybook/react'
import { useForm } from 'react-hook-form'
import { FaBitcoin } from 'react-icons/fa6'
import { Input } from '../Input'
import { Button } from '../Button'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../Select'
import { Textarea } from '../Textarea'
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from './Form'
import { Button } from '../Button'
import { FormInput } from './FormInput'
import { FormTextarea } from './FormTextarea'

const meta = {
title: 'Components/Form',
Expand All @@ -28,7 +28,7 @@ export const Default: Omit<Story, 'args'> = {
<FormItem>
<FormLabel>Proposal name</FormLabel>
<FormControl>
<Input placeholder="name your proposal" {...field} />
<FormInput placeholder="name your proposal" {...field} />
</FormControl>
</FormItem>
)}
Expand All @@ -40,7 +40,7 @@ export const Default: Omit<Story, 'args'> = {
<FormItem className="mb-6 mx-1">
<FormLabel>Description</FormLabel>
<FormControl>
<Textarea placeholder="Enter a description..." {...field} />
<FormTextarea placeholder="Enter a description..." {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -53,7 +53,7 @@ export const Default: Omit<Story, 'args'> = {
<FormItem className="mb-6 mx-1">
<FormLabel>Transfer to</FormLabel>
<FormControl>
<Input placeholder="0x123...456" {...field} />
<FormInput placeholder="0x123...456" {...field} />
</FormControl>
<FormDescription>Write or paste the wallet address of the recipient</FormDescription>
<FormMessage />
Expand Down Expand Up @@ -102,7 +102,7 @@ export const Default: Omit<Story, 'args'> = {
<FormItem className="mb-6 mx-1">
<FormLabel>Amount</FormLabel>
<FormControl>
<Input placeholder="0.00" type="number" className="w-64" {...field} />
<FormInput placeholder="0.00" type="number" className="w-64" {...field} />
</FormControl>
<FormDescription>= $ USD 0.00</FormDescription>
<FormMessage />
Expand Down
19 changes: 14 additions & 5 deletions src/components/Form/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react'
import * as LabelPrimitive from '@radix-ui/react-label'
import { Slot } from '@radix-ui/react-slot'
import * as React from 'react'
import {
Controller,
ControllerProps,
Expand All @@ -11,7 +11,7 @@ import {
} from 'react-hook-form'

import { cn } from '@/lib/utils'
import { LabelForm } from './LabelForm'
import { cva } from 'class-variance-authority'

const Form = FormProvider

Expand Down Expand Up @@ -79,13 +79,22 @@ const FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivEl
)
FormItem.displayName = 'FormItem'

const labelVariants = cva(
'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
)
const FormLabel = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
>(({ className, ...props }, ref) => {
const { formItemId } = useFormField()

return <LabelForm ref={ref} className={className} htmlFor={formItemId} {...props} />
return (
<LabelPrimitive.Root
ref={ref}
className={cn(labelVariants(), className)}
htmlFor={formItemId}
{...props}
/>
)
})
FormLabel.displayName = 'FormLabel'

Expand Down Expand Up @@ -141,4 +150,4 @@ const FormMessage = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<
)
FormMessage.displayName = 'FormMessage'

export { useFormField, Form, FormItem, FormLabel, FormControl, FormDescription, FormMessage, FormField }
export { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField }
Loading

0 comments on commit af659b5

Please sign in to comment.