diff --git a/packages/apps/rwa-demo/src/components/BadgeFeezeForm/BadgeFeezeForm.tsx b/packages/apps/rwa-demo/src/components/BadgeFeezeForm/BadgeFeezeForm.tsx new file mode 100644 index 0000000000..36b541589a --- /dev/null +++ b/packages/apps/rwa-demo/src/components/BadgeFeezeForm/BadgeFeezeForm.tsx @@ -0,0 +1,67 @@ +import { useBatchFreezeInvestors } from '@/hooks/batchFreezeInvestors'; +import type { IBatchSetAddressFrozenProps } from '@/services/batchSetAddressFrozen'; +import { MonoPause, MonoPlayArrow } from '@kadena/kode-icons'; +import { Button } from '@kadena/kode-ui'; + +import { useAccount } from '@/hooks/account'; +import type { FC } from 'react'; +import type { UseFormHandleSubmit, UseFormReset } from 'react-hook-form'; +import { TransactionTypeSpinner } from '../TransactionTypeSpinner/TransactionTypeSpinner'; +import { TXTYPES } from '../TransactionsProvider/TransactionsProvider'; + +interface IProps { + pause: boolean; + isDisabled: boolean; + handleReset: UseFormReset<{ + select: []; + }>; + handleSubmit: UseFormHandleSubmit< + { + select: []; + }, + undefined + >; +} + +export const BadgeFreezeForm: FC = ({ + handleSubmit, + handleReset, + isDisabled, + pause, +}) => { + const { account } = useAccount(); + const { submit, isAllowed } = useBatchFreezeInvestors(); + + const onSubmit = async ({ select }: { select: string[] }) => { + const data: IBatchSetAddressFrozenProps = { + investorAccounts: select, + pause, + }; + const tx = await submit(data); + tx?.listener.subscribe( + () => {}, + () => {}, + () => { + handleReset({ select: [] }); + }, + ); + }; + + return ( + + ); +}; diff --git a/packages/apps/rwa-demo/src/components/InvestorList/InvestorList.tsx b/packages/apps/rwa-demo/src/components/InvestorList/InvestorList.tsx index f8af5fd6a1..edf8a7e405 100644 --- a/packages/apps/rwa-demo/src/components/InvestorList/InvestorList.tsx +++ b/packages/apps/rwa-demo/src/components/InvestorList/InvestorList.tsx @@ -13,8 +13,12 @@ import { } from '@kadena/kode-ui/patterns'; import { useRouter } from 'next/navigation'; import type { FC } from 'react'; +import { useRef } from 'react'; +import { useForm } from 'react-hook-form'; +import { BadgeFreezeForm } from '../BadgeFeezeForm/BadgeFeezeForm'; import { InvestorBatchForm } from '../InvestorBatchForm/InvestorBatchForm'; import { InvestorForm } from '../InvestorForm/InvestorForm'; +import { FormatCheckbox } from '../TableFormatters/FormatCheckbox'; import { FormatDeleteInvestor } from '../TableFormatters/FormatDeleteInvestor'; import { FormatFreeze } from '../TableFormatters/FormatFreeze'; import { FormatInvestorBalance } from '../TableFormatters/FormatInvestorBalance'; @@ -22,107 +26,146 @@ import { TransactionTypeSpinner } from '../TransactionTypeSpinner/TransactionTyp import { TXTYPES } from '../TransactionsProvider/TransactionsProvider'; export const InvestorList: FC = () => { + const formRef = useRef(null); const { data, isLoading } = useGetInvestors(); const router = useRouter(); const { isAllowed: isAddInvestorAllowed } = useAddInvestor({}); + const { + reset, + register, + handleSubmit, + formState: { isDirty }, + } = useForm<{ + select: []; + }>({ + defaultValues: { + select: [], + }, + }); + const handleLink = async (accountName: any) => { router.push(`/investors/${accountName}`); }; return ( <> - - - - } - > - Batch add investors - - } - /> - } - > - Add Investor - - } - /> - - } - /> - - - + + + + + + + } - onPress={handleLink} - /> - ), - }), - }, - { - label: '', - key: 'accountName', - width: '5%', - render: FormatDeleteInvestor(), - }, - ]} - data={isLoading ? loadingData : data} + isDisabled={!isAddInvestorAllowed} + endVisual={} + > + Batch add investors + + } + /> + } + > + Add Investor + + } + /> + + } /> - - - + + + + } + onPress={handleLink} + /> + ), + }), + }, + { + label: '', + key: 'accountName', + width: '5%', + render: FormatDeleteInvestor(), + }, + ]} + data={isLoading ? loadingData : data} + /> + + + + ); }; diff --git a/packages/apps/rwa-demo/src/components/TableFormatters/FormatCheckbox.tsx b/packages/apps/rwa-demo/src/components/TableFormatters/FormatCheckbox.tsx new file mode 100644 index 0000000000..f9b96a65cf --- /dev/null +++ b/packages/apps/rwa-demo/src/components/TableFormatters/FormatCheckbox.tsx @@ -0,0 +1,26 @@ +import type { ICompactTableFormatterProps } from '@kadena/kode-ui/patterns'; +import React from 'react'; +import type { UseFormRegister } from 'react-hook-form'; + +export interface IActionProps { + name: 'select'; + register: UseFormRegister<{ + select: []; + }>; +} + +export const FormatCheckbox = ({ name, register }: IActionProps) => { + const Component = ({ value }: ICompactTableFormatterProps) => { + return ( + + ); + }; + return Component; +}; diff --git a/packages/apps/rwa-demo/src/components/TransactionsProvider/TransactionsProvider.tsx b/packages/apps/rwa-demo/src/components/TransactionsProvider/TransactionsProvider.tsx index b17d32bd03..e73d6e87a8 100644 --- a/packages/apps/rwa-demo/src/components/TransactionsProvider/TransactionsProvider.tsx +++ b/packages/apps/rwa-demo/src/components/TransactionsProvider/TransactionsProvider.tsx @@ -163,7 +163,7 @@ export const TransactionsProvider: FC = ({ children }) => { }, ); - return 2222; + return r; }, [], ); diff --git a/packages/apps/rwa-demo/src/hooks/batchFreezeInvestors.ts b/packages/apps/rwa-demo/src/hooks/batchFreezeInvestors.ts new file mode 100644 index 0000000000..65a3b027d8 --- /dev/null +++ b/packages/apps/rwa-demo/src/hooks/batchFreezeInvestors.ts @@ -0,0 +1,61 @@ +import type { ITransaction } from '@/components/TransactionsProvider/TransactionsProvider'; +import { + interpretErrorMessage, + TXTYPES, +} from '@/components/TransactionsProvider/TransactionsProvider'; +import type { IBatchSetAddressFrozenProps } from '@/services/batchSetAddressFrozen'; +import { batchSetAddressFrozen } from '@/services/batchSetAddressFrozen'; +import { getClient } from '@/utils/client'; +import { useNotifications } from '@kadena/kode-ui/patterns'; +import { useEffect, useState } from 'react'; +import { useAccount } from './account'; +import { useAsset } from './asset'; +import { useTransactions } from './transactions'; + +export const useBatchFreezeInvestors = () => { + const { account, sign, isMounted, accountRoles } = useAccount(); + const { paused } = useAsset(); + const { addTransaction, isActiveAccountChangeTx } = useTransactions(); + const { addNotification } = useNotifications(); + const [isAllowed, setIsAllowed] = useState(false); + + const submit = async ( + data: IBatchSetAddressFrozenProps, + ): Promise => { + try { + const tx = await batchSetAddressFrozen(data, account!); + const signedTransaction = await sign(tx); + if (!signedTransaction) return; + + const client = getClient(); + const res = await client.submit(signedTransaction); + + return addTransaction({ + ...res, + type: TXTYPES.FREEZEINVESTOR, + accounts: [...data.investorAccounts, account!.address], + }); + } catch (e: any) { + addNotification({ + intent: 'negative', + label: 'there was an error', + message: interpretErrorMessage(e.message), + }); + } + }; + + useEffect(() => { + if (!isMounted) return; + setIsAllowed( + !paused && accountRoles.isFreezer() && !isActiveAccountChangeTx, + ); + }, [ + paused, + account?.address, + isMounted, + accountRoles, + isActiveAccountChangeTx, + ]); + + return { submit, isAllowed }; +}; diff --git a/packages/apps/rwa-demo/src/services/batchSetAddressFrozen.ts b/packages/apps/rwa-demo/src/services/batchSetAddressFrozen.ts new file mode 100644 index 0000000000..223bc8fd24 --- /dev/null +++ b/packages/apps/rwa-demo/src/services/batchSetAddressFrozen.ts @@ -0,0 +1,38 @@ +import type { IWalletAccount } from '@/components/AccountProvider/AccountType'; +import { getNetwork } from '@/utils/client'; +import { getAsset } from '@/utils/getAsset'; +import { getPubkeyFromAccount } from '@/utils/getPubKey'; +import { Pact } from '@kadena/client'; + +export interface IBatchSetAddressFrozenProps { + investorAccounts: string[]; + pause: boolean; +} + +export const batchSetAddressFrozen = async ( + data: IBatchSetAddressFrozenProps, + account: IWalletAccount, +) => { + return Pact.builder + .execution( + `(${getAsset()}.batch-set-address-frozen (read-msg 'investors) (read-msg 'pause)) + `, + ) + .addData('investors', data.investorAccounts) + .addData( + 'pause', + data.investorAccounts.map((_) => data.pause), + ) + .addData('agent', account.address) + .setMeta({ + senderAccount: account.address, + chainId: getNetwork().chainId, + }) + .addSigner(getPubkeyFromAccount(account), (withCap) => [ + withCap(`${getAsset()}.ONLY-AGENT`, 'freezer'), + withCap(`coin.GAS`), + ]) + + .setNetworkId(getNetwork().networkId) + .createTransaction(); +};