Skip to content

Commit

Permalink
validation on metabox
Browse files Browse the repository at this point in the history
  • Loading branch information
chalabi2 committed Sep 4, 2024
1 parent afd08f6 commit 1616fec
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 134 deletions.
11 changes: 4 additions & 7 deletions components/factory/components/metaBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useState, useEffect, useCallback } from 'react';
import { MetadataSDKType } from '@chalabi/manifestjs/dist/codegen/cosmos/bank/v1beta1/bank';
import MintForm from '@/components/factory/forms/MintForm';
import BurnForm from '@/components/factory/forms/BurnForm';
import TransferForm from '@/components/factory/forms/TransferForm';

import { useGroupsByAdmin, usePoaParams } from '@/hooks';

export default function MetaBox({
Expand All @@ -16,7 +16,7 @@ export default function MetaBox({
refetch: () => void;
balance: string;
}>) {
const [activeTab, setActiveTab] = useState<'transfer' | 'burn' | 'mint'>('mint');
const [activeTab, setActiveTab] = useState<'burn' | 'mint'>('mint');

const { poaParams, isPoaParamsLoading, refetchPoaParams, isPoaParamsError } = usePoaParams();
const admin = poaParams?.admins[0];
Expand Down Expand Up @@ -51,15 +51,15 @@ export default function MetaBox({
{`${activeTab.charAt(0).toUpperCase() + activeTab.slice(1)} ${denom.display}`}
</h2>
<div role="tablist" className="tabs tabs-lifted tabs-md -mr-4 items-end" aria-label="tabs">
{[...(denom.base.includes('mfx') ? [] : ['transfer']), 'burn', 'mint'].map(tab => (
{['burn', 'mint'].map(tab => (
<button
key={tab}
type="button"
role="tab"
className={`tab [--tab-bg:#edf2f7] dark:[--tab-bg:#202020] [--tab-border-color:transparent] ${
activeTab === tab ? 'tab-active' : ''
}`}
onClick={() => setActiveTab(tab as 'transfer' | 'burn' | 'mint')}
onClick={() => setActiveTab(tab as 'burn' | 'mint')}
>
{tab.charAt(0).toUpperCase() + tab.slice(1)}
</button>
Expand All @@ -78,9 +78,6 @@ export default function MetaBox({
)}
{denom && (
<>
{!denom.base.includes('mfx') && activeTab === 'transfer' && (
<TransferForm balance={balance} refetch={refetch} address={address} denom={denom} />
)}
{activeTab === 'burn' && (
<BurnForm
isAdmin={isAdmin ?? false}
Expand Down
144 changes: 92 additions & 52 deletions components/factory/forms/BurnForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { chainName } from '@/config';
import { useFeeEstimation, useTx } from '@/hooks';
import { useTokenFactoryBalance, useFeeEstimation, useTx } from '@/hooks';
import { cosmos, manifest, osmosis } from '@chalabi/manifestjs';
import { MetadataSDKType } from '@chalabi/manifestjs/dist/codegen/cosmos/bank/v1beta1/bank';
import { PiAddressBook } from 'react-icons/pi';
Expand All @@ -9,6 +9,9 @@ import { Any } from '@chalabi/manifestjs/dist/codegen/google/protobuf/any';
import { MsgBurnHeldBalance } from '@chalabi/manifestjs/dist/codegen/manifest/v1/tx';
import { MultiBurnModal } from '../modals/multiMfxBurnModal';
import { useToast } from '@/contexts';
import { Formik, Form } from 'formik';
import Yup from '@/utils/yupExtensions';
import { NumberInput, TextInput } from '@/components/react/inputs';

interface BurnPair {
address: string;
Expand Down Expand Up @@ -45,6 +48,21 @@ export default function BurnForm({
const exponent = denom?.denom_units?.find(unit => unit.denom === denom.display)?.exponent || 0;
const isMFX = denom.base.includes('mfx');

const { balance: recipientBalance } = useTokenFactoryBalance(recipient ?? '', denom.base);
const balanceNumber = parseFloat(
shiftDigits(isMFX ? recipientBalance?.amount || '0' : balance, -exponent)
);

const BurnSchema = Yup.object().shape({
amount: Yup.number()
.positive('Amount must be positive')
.required('Amount is required')
.max(1e12, 'Amount is too large')
.test('max-balance', 'Amount exceeds balance', function (value) {
return value <= balanceNumber;
}),
});

const handleBurn = async () => {
if (!amount || isNaN(Number(amount))) {
return;
Expand Down Expand Up @@ -187,58 +205,80 @@ export default function BurnForm({
<p className="font-semibold text-md max-w-[20ch] truncate">{denom.display}</p>
</div>
</div>
<div className="flex space-x-4 mt-8">
<div className="flex-1">
<label className="label p-0">
<p className="text-md">AMOUNT</p>
</label>
<input
type="text"
placeholder="Enter amount"
className="input input-bordered h-10 input-sm w-full"
value={amount}
onChange={e => setAmount(e.target.value)}
/>
</div>
<div className="flex-1">
<label className="label p-0">
<p className="text-md">TARGET</p>
</label>
<div className="flex flex-row items-center">
<input
type="text"
placeholder="Target address"
className="input input-bordered input-sm h-10 rounded-tl-lg rounded-bl-lg rounded-tr-none rounded-br-none w-full"
value={recipient}
onChange={e => setRecipient(e.target.value)}
/>
<button
onClick={handleAddressBookClick}
className="btn btn-secondary btn-sm h-10 rounded-tr-lg rounded-br-lg rounded-bl-none rounded-tl-none"
>
<PiAddressBook className="w-6 h-6" />
</button>
</div>
</div>
</div>
<div className="flex justify-end mt-6 space-x-2">
<button
onClick={handleBurn}
className="btn btn-secondary btn-md flex-grow"
disabled={isSigning}
>
{isSigning ? <span className="loading loading-dots loading-xs"></span> : 'Burn'}
</button>
{isMFX && (
<button
onClick={() => setIsModalOpen(true)}
className="btn btn-secondary btn-md"
aria-label={'multi-burn-btn'}
>
Multi Burn
</button>
<Formik
initialValues={{ amount: '' }}
validationSchema={BurnSchema}
onSubmit={values => {
setAmount(values.amount);
handleBurn();
}}
validateOnChange={true}
validateOnBlur={true}
validateOnMount={true}
>
{({ isValid, dirty, setFieldValue }) => (
<Form>
<div className="flex space-x-4 mt-8">
<div className="flex-1">
<NumberInput
label="AMOUNT"
name="amount"
placeholder="Enter amount"
value={amount}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setAmount(e.target.value);
setFieldValue('amount', e.target.value);
}}
/>
</div>
<div className="flex-1">
<label className="label p-0">
<p className="text-md">TARGET</p>
</label>
<div className="flex flex-row items-center">
<input
type="text"
disabled={!isMFX}
placeholder="Target address"
className="input input-bordered input-sm h-10 rounded-tl-lg rounded-bl-lg rounded-tr-none rounded-br-none w-full"
value={isMFX ? recipient : address}
onChange={e => setRecipient(e.target.value)}
/>
<button
onClick={handleAddressBookClick}
className="btn btn-secondary btn-sm h-10 rounded-tr-lg rounded-br-lg rounded-bl-none rounded-tl-none"
>
<PiAddressBook className="w-6 h-6" />
</button>
</div>
{isMFX && <p className="text-sm text-gray-500">{balanceNumber}</p>}
</div>
</div>
<div className="flex justify-end mt-6 space-x-2">
<button
onClick={handleBurn}
className="btn btn-secondary btn-md flex-grow"
disabled={isSigning || !isValid}
>
{isSigning ? (
<span className="loading loading-dots loading-xs"></span>
) : (
'Burn'
)}
</button>
{isMFX && (
<button
onClick={() => setIsModalOpen(true)}
className="btn btn-secondary btn-md"
aria-label={'multi-burn-btn'}
>
Multi Burn
</button>
)}
</div>
</Form>
)}
</div>
</Formik>
{isMFX && (
<MultiBurnModal
isOpen={isModalOpen}
Expand Down
Loading

0 comments on commit 1616fec

Please sign in to comment.