Skip to content

Commit

Permalink
feat(rwa): add a message when a investor is frozen (#2779)
Browse files Browse the repository at this point in the history
  • Loading branch information
sstraatemans authored Jan 8, 2025
1 parent 9722418 commit 4d4d0ee
Show file tree
Hide file tree
Showing 14 changed files with 305 additions and 103 deletions.
2 changes: 2 additions & 0 deletions packages/apps/rwa-demo/src/app/(app)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { ActiveTransactionsList } from '@/components/ActiveTransactionsList/ActiveTransactionsList';
import { AssetInfo } from '@/components/AssetInfo/AssetInfo';
import { DemoBanner } from '@/components/DemoBanner/DemoBanner';
import { FrozenInvestorBanner } from '@/components/FrozenInvestorBanner/FrozenInvestorBanner';
import { GraphOnlineBanner } from '@/components/GraphOnlineBanner/GraphOnlineBanner';
import { TransactionPendingIcon } from '@/components/TransactionPendingIcon/TransactionPendingIcon';
import { useAccount } from '@/hooks/account';
Expand Down Expand Up @@ -92,6 +93,7 @@ const RootLayout = ({
<Stack width="100%" gap="xs" flexDirection="column">
<DemoBanner />
<GraphOnlineBanner />
<FrozenInvestorBanner />
</Stack>
}
logo={
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { useBatchFreezeInvestors } from '@/hooks/batchFreezeInvestors';
import type { IBatchSetAddressFrozenProps } from '@/services/batchSetAddressFrozen';
import { MonoPause, MonoPlayArrow } from '@kadena/kode-icons';
import {
Button,
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
TextareaField,
} from '@kadena/kode-ui';

import { useAccount } from '@/hooks/account';
import type { ChangeEvent, FC } from 'react';
import { useState } 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<IProps> = ({
handleSubmit,
handleReset,
isDisabled,
pause,
}) => {
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [message, setMessage] = useState<string>('');
const { account } = useAccount();
const { submit, isAllowed } = useBatchFreezeInvestors();

const onSubmit = async ({ select }: { select: string[] }) => {
const data: IBatchSetAddressFrozenProps = {
investorAccounts: select,
pause,
message,
};
const tx = await submit(data);
setIsModalOpen(false);
tx?.listener.subscribe(
() => {},
() => {},
() => {
handleReset({ select: [] });
},
);
};

const handleMessageChange = (e: ChangeEvent) => {
setMessage((e.target as HTMLTextAreaElement).value);
};

const handleStart = async () => {
if (pause) {
setIsModalOpen(true);
return;
}
};

return (
<>
{pause && (
<Dialog isOpen={isModalOpen} onOpenChange={() => setIsModalOpen(false)}>
<DialogHeader>Freeze selected accounts</DialogHeader>
<DialogContent>
<TextareaField
onChange={handleMessageChange}
label="message"
maxLength={100}
rows={5}
/>
</DialogContent>
<DialogFooter>
<Button variant="outlined" onPress={() => setIsModalOpen(false)}>
Cancel
</Button>
<Button
onClick={handleSubmit(onSubmit)}
isDisabled={isDisabled || !isAllowed}
variant="primary"
>
Freeze
</Button>
</DialogFooter>
</Dialog>
)}
<Button
isDisabled={isDisabled || !isAllowed}
onClick={pause ? handleStart : handleSubmit(onSubmit)}
isCompact
variant="outlined"
endVisual={
<TransactionTypeSpinner
type={[TXTYPES.FREEZEINVESTOR]}
account={account?.address}
fallbackIcon={pause ? <MonoPlayArrow /> : <MonoPause />}
/>
}
>
{pause ? 'Freeze' : 'Unfreeze'}
</Button>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { FC } from 'react';

export const DemoBanner: FC = () => {
return (
<Notification role="status" type="inlineStacked" intent="info">
<Notification role="status" type="stacked" intent="info">
<NotificationHeading>
This is a demo app. And is not running on Mainnet
</NotificationHeading>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@ import { useFreeze } from '@/hooks/freeze';
import { useFreezeInvestor } from '@/hooks/freezeInvestor';
import { MonoPause, MonoPlayArrow } from '@kadena/kode-icons';
import type { IButtonProps } from '@kadena/kode-ui';
import { Button } from '@kadena/kode-ui';
import {
Button,
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogHeaderSubtitle,
maskValue,
Text,
TextareaField,
} from '@kadena/kode-ui';
import type { FC } from 'react';
import React, { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { SendTransactionAnimation } from '../SendTransactionAnimation/SendTransactionAnimation';
import { TransactionPendingIcon } from '../TransactionPendingIcon/TransactionPendingIcon';
import { TXTYPES } from '../TransactionsProvider/TransactionsProvider';
Expand All @@ -30,50 +41,105 @@ export const FreezeInvestor: FC<IProps> = ({
isCompact,
variant,
}) => {
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const { frozen } = useFreeze({ investorAccount });
const [isLoading, setIsLoading] = useState<boolean>(true);
const { submit, isAllowed } = useFreezeInvestor();

const handleFreeze = async () => {
const {
register,
handleSubmit,
formState: { isValid },
} = useForm<{ message: string }>({
values: {
message: '',
},
});

const handleFreeze = async (data?: { message: string }) => {
if (frozen === undefined) return;

const data = {
const newData = {
investorAccount: investorAccount,
pause: !frozen,
message: data?.message,
};
try {
setIsLoading(true);
return await submit(data);
return await submit(newData);
} catch (e: any) {
setIsLoading(false);
} finally {
setIsModalOpen(false);
}
};

const handleStart = async () => {
if (frozen === undefined || frozen === false) {
setIsModalOpen(true);
return;
}

await handleFreeze();
};

useEffect(() => {
setIsLoading(false);
}, [frozen]);

const label = iconOnly ? '' : frozen ? 'Unfreeze account' : 'Freeze account';

return (
<SendTransactionAnimation
onPress={handleFreeze}
trigger={
<Button
startVisual={
<TransactionTypeSpinner
type={TXTYPES.FREEZEINVESTOR}
account={investorAccount}
fallbackIcon={getVisual(frozen, isLoading)}
<>
<Dialog isOpen={isModalOpen} onOpenChange={() => setIsModalOpen(false)}>
<form onSubmit={handleSubmit(handleFreeze)}>
<DialogHeader>Freeze the account</DialogHeader>
<DialogHeaderSubtitle>
<Text variant="code">{maskValue(investorAccount)}</Text>
</DialogHeaderSubtitle>
<DialogContent>
<TextareaField
label="message"
{...register('message', {
required: false,
maxLength: 100,
})}
rows={5}
/>
}
isDisabled={!isAllowed}
isCompact={isCompact}
variant={variant}
>
{label}
</Button>
}
></SendTransactionAnimation>
</DialogContent>
<DialogFooter>
<Button variant="outlined" onPress={() => setIsModalOpen(false)}>
Cancel
</Button>
<Button
type="submit"
isDisabled={!isValid || !isAllowed}
variant="primary"
>
Freeze
</Button>
</DialogFooter>
</form>
</Dialog>
<SendTransactionAnimation
onPress={handleStart}
trigger={
<Button
startVisual={
<TransactionTypeSpinner
type={TXTYPES.FREEZEINVESTOR}
account={investorAccount}
fallbackIcon={getVisual(frozen, isLoading)}
/>
}
isDisabled={!isAllowed}
isCompact={isCompact}
variant={variant}
>
{label}
</Button>
}
></SendTransactionAnimation>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useAccount } from '@/hooks/account';
import type { FC } from 'react';
import { InvestorFrozenMessage } from '../InvestorFrozenMessage/InvestorFrozenMessage';

export const FrozenInvestorBanner: FC = () => {
const { account } = useAccount();
if (!account) return;
return <InvestorFrozenMessage investorAccount={account.address} />;
};
Loading

0 comments on commit 4d4d0ee

Please sign in to comment.