Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add income table #113

Merged
merged 4 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 169 additions & 35 deletions front/package-lock.json

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions front/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
"prepare": "husky install"
},
"dependencies": {
"@massalabs/massa-web3": "^5.0.0-next",
"@massalabs/react-ui-kit": "^0.1.1-dev",
"@massalabs/wallet-provider": "^3.0.0-next",
"@massalabs/massa-web3": "^5.0.0",
"@massalabs/react-ui-kit": "^1.0.1-dev",
"@massalabs/wallet-provider": "^3.0.0",
"copy-to-clipboard": "^3.3.3",
"currency.js": "^2.0.4",
"delay": "^6.0.0",
Expand Down Expand Up @@ -65,5 +65,9 @@
"typescript": "^5.2.2",
"vite": "^5.1.7",
"vite-plugin-image-optimizer": "^1.1.8"
},
"overrides": {
"@massalabs/massa-web3": "^5.0.0",
"@massalabs/wallet-provider": "^3.0.0"
}
}
5 changes: 2 additions & 3 deletions front/src/components/ConnectWalletPopup/ConnectButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function ConnectButton() {
<Button
disabled={isFetching}
variant="secondary"
customClass="h-[54px] text-primary relative"
customClass="h-[54px] text-primary dark:text-primary relative"
onClick={() => setOpen(true)}
>
{truncateAddress(connectedAccount?.address)}
Expand All @@ -30,7 +30,7 @@ export function ConnectButton() {
<Button
variant="secondary"
disabled={isFetching}
customClass="h-[54px] dark:text-gray relative"
customClass="h-[54px] text-primary dark:text-primary relative"
onClick={() => setOpen(true)}
>
{Intl.t('connect-wallet.title')}
Expand All @@ -50,7 +50,6 @@ export function ConnectButton() {
);
}

// TODO: To move in ui-kit
function PingAnimation() {
return (
<span className="absolute flex h-3 w-3 top-0 right-0 -mr-2 -mt-2">
Expand Down
4 changes: 2 additions & 2 deletions front/src/components/CreateScheduleButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import useSchedule from '@/hooks/useSchedule';
import { commonButton } from '@/styles/buttons';
import { redButton } from '@/styles/buttons';
import { Button, toast } from '@massalabs/react-ui-kit';

export function CreateScheduleButton({ disabled }: { disabled: boolean }) {
Expand All @@ -16,7 +16,7 @@ export function CreateScheduleButton({ disabled }: { disabled: boolean }) {

return (
<Button
customClass={`bg-primary text-white ${commonButton}`}
customClass={redButton}
onClick={handleCreateSchedule}
disabled={disabled}
variant="secondary"
Expand Down
5 changes: 2 additions & 3 deletions front/src/components/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { ConnectButton } from './ConnectWalletPopup';
import LogoSyntra from '../assets/logo-syntra.svg';
import { useNetworkStore } from '@/store/network';
import { dappNetwork } from '@/const/network';

export function NavBar() {
const { network } = useNetworkStore();
return (
<nav className="flex justify-between items-center px-10 py-5 w-full">
<div className="flex flex-col">
<img src={LogoSyntra} alt="Syntra" className="w-40 h-14" />
<p className="font-caveat text-white self-end -m-5 first-letter:uppercase">
{network}
{dappNetwork}
</p>
</div>
<ConnectButton />
Expand Down
29 changes: 20 additions & 9 deletions front/src/components/ScheduleForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,16 @@ import { AllowanceButton } from './AllowanceButton';
import { tipsModeDesc, vestingModeDesc } from '@/const/tooltips';
import { RepeatInput } from './RepeatInput';
import { CreateScheduleButton } from './CreateScheduleButton';
import { useNetworkStore } from '@/store/network';

import { useSchedulerStore } from '@/store/scheduler';
import { dappNetwork } from '@/const/network';

export function ScheduleForm() {
const { connectedAccount, network: walletNetwork } = useAccountStore();
const { scheduleInfo, setScheduleInfo } = useSchedulerStore();
const { tokens } = useTokenStore();
const [isVesting, setVesting] = useState<boolean>(scheduleInfo.isVesting);

const { network } = useNetworkStore();

const selectedToken = tokens.find(
(token) => token.address === scheduleInfo.asset.address,
);
Expand Down Expand Up @@ -55,7 +54,7 @@ export function ScheduleForm() {
!isAllowanceSufficient && !isMasToken,
].some(Boolean);

const isRightNetwork = network === walletNetwork;
const isRightNetwork = dappNetwork === walletNetwork?.name;
const formDisabled = !connectedAccount || !isRightNetwork;

const handleModeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -70,13 +69,25 @@ export function ScheduleForm() {
}
};

function renderError() {
if (!connectedAccount) {
return (
<p className="text-red-500 text-center p-6 font-Poppins font-bold text-xl">
Please connect your wallet
</p>
);
}
if (!isRightNetwork) {
return (
<p className="text-red-500 text-center p-6 font-Poppins font-bold text-xl">
Please switch your wallet to {dappNetwork}
</p>
);
}
}
return (
<section className="max-w-2xl w-full mx-auto rounded-2xl shadow-lg p-7 bg-white -mt-40">
{walletNetwork && !isRightNetwork && (
<p className="text-red-500 text-center p-6">
Please switch your wallet to {network}
</p>
)}
{renderError()}
<Card customClass="bg-transparent grid grid-flow-row gap-4">
<SelectMode
isVesting={isVesting}
Expand Down
92 changes: 53 additions & 39 deletions front/src/components/ScheduleTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { MasToken } from '../const/assets';
import ScheduleHistory from '@/components/ScheduleHistory';
import { getRecurrenceFromPeriods } from './Recurrence';
import { useTokenStore } from '@/store/token';
import { useSchedulerStore } from '@/store/scheduler';

interface ScheduleTableProps {
schedules: Schedule[];
Expand All @@ -30,28 +31,30 @@ const CopyableAddress: React.FC<{
</span>
);

const TableHeader: React.FC = () => (
<thead>
<tr className="bg-primary text-white text-sm py-5">
<th className="font-normal px-4 py-5"></th>
<th className="font-normal hidden xl:table-cell px-4 py-5">
OperationId
</th>
<th className="font-normal hidden lg:table-cell px-4 py-5">Mode</th>
<th className="font-normal px-4 py-5">Token</th>
<th className="font-normal px-4 py-5">Recipient</th>
<th className="font-normal px-4 py-5">Amount</th>
<th className="font-normal hidden md:table-cell px-4 py-5">Interval</th>
<th className="font-normal hidden md:table-cell px-4 py-5">
Occurrences
</th>
<th className="font-normal px-4 py-5">Remaining</th>
<th className="font-normal hidden px-4 py-5 lg:table-cell">
Execution history
</th>
</tr>
</thead>
);
const TableHeader: React.FC = () => {
return (
<thead>
<tr className="bg-primary text-white text-sm py-5">
<th className="font-normal px-4 py-5"></th>
<th className="font-normal hidden xl:table-cell px-4 py-5">
OperationId
</th>
<th className="font-normal hidden lg:table-cell px-4 py-5">Mode</th>
<th className="font-normal px-4 py-5">Spender</th>
<th className="font-normal px-4 py-5">Recipient</th>
<th className="font-normal px-4 py-5">Amount</th>
<th className="font-normal hidden md:table-cell px-4 py-5">Interval</th>
<th className="font-normal hidden md:table-cell px-4 py-5">
Occurrences
</th>
<th className="font-normal px-4 py-5">Remaining</th>
<th className="font-normal hidden px-4 py-5 lg:table-cell">
Execution history
</th>
</tr>
</thead>
);
};

interface TableRowProps {
schedule: Schedule;
Expand All @@ -65,18 +68,22 @@ const TableRow: React.FC<TableRowProps> = ({
onCheckboxChange,
}) => {
const { tokens } = useTokenStore();
const { showUserPayments } = useSchedulerStore();
const asset =
tokens.find((token) => token.address === schedule.tokenAddress) || MasToken;
const formattedAmount = formatAmount(schedule.amount, asset.decimals);
const isMas = schedule.tokenAddress === '';

return (
<tr>
<td className=" text-center px-6 py-6">
<CheckBox
isSelected={isSelected}
onChange={onCheckboxChange}
id={schedule.id}
/>
{showUserPayments && (
<CheckBox
isSelected={isSelected}
onChange={onCheckboxChange}
id={schedule.id}
/>
)}
</td>
<td className="text-center hidden xl:table-cell">
<CopyableAddress
Expand All @@ -88,26 +95,33 @@ const TableRow: React.FC<TableRowProps> = ({
<td className="text-center px-6 py-6 hidden lg:table-cell">
{schedule.isVesting ? 'Vesting' : 'Tips'}
</td>
<td className="text-center ">
{isMas ? (
'MAS'
) : (
<CopyableAddress
label="Token address"
address={asset.address}
value={asset.symbol}
/>
)}
<td className="text-center px-6 py-6">
<CopyableAddress
address={schedule.spender}
label={'Spender'}
value={truncateAddress(schedule.spender)}
/>
</td>
<td className="text-center px-6 py-6">
<CopyableAddress
address={schedule.recipient}
label="Recipient address"
label={'Recipient'}
value={truncateAddress(schedule.recipient)}
/>
</td>
<td className="text-center ">
<span title={formattedAmount.full}>{formattedAmount.preview}</span>
<span>
{isMas ? (
' MAS'
) : (
<CopyableAddress
label="Token address"
address={asset.address}
value={asset.symbol}
/>
)}
</span>
</td>
<td className="text-center px-6 py-6 hidden md:table-cell">
{getRecurrenceFromPeriods(schedule.interval).unit}
Expand All @@ -116,7 +130,7 @@ const TableRow: React.FC<TableRowProps> = ({
{schedule.occurrences.toString()}
</td>
<td className="text-center px-6 py-6">{schedule.remaining.toString()}</td>
<td className="text-center hidden lg:table-cell">
<td className="text-center hidden lg:table-cell py-4">
<ScheduleHistory schedule={schedule} />
</td>
</tr>
Expand Down
59 changes: 59 additions & 0 deletions front/src/components/ScheduleTablesSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useSchedulerStore } from '@/store/scheduler';
import { redButton } from '@/styles/buttons';
import { Button } from '@massalabs/react-ui-kit';
import ScheduleTable from './ScheduleTable';

export function ScheduleTablesSection() {
const { userPayments, userReceive, showUserPayments, setShowUserPayments } =
useSchedulerStore();

const schedules = showUserPayments ? userPayments : userReceive;

return (
<div className="flex flex-col w-full">
<div className="flex w-full justify-center mt-12">
<SwitchTableButton
isActive={showUserPayments}
onClick={() => setShowUserPayments(true)}
label="Payed"
className="rounded-r-none"
/>
<SwitchTableButton
isActive={!showUserPayments}
onClick={() => setShowUserPayments(false)}
label="Received"
className="rounded-l-none"
/>
</div>

<div className={`min-w-full `}>
<ScheduleTable schedules={schedules} />
</div>
</div>
);
}

interface SwitchTableButtonProps {
isActive: boolean;
onClick: () => void;
label: string;
className?: string;
}

const SwitchTableButton: React.FC<SwitchTableButtonProps> = ({
isActive,
onClick,
label,
className,
}) => {
return (
<Button
className={`${
isActive ? redButton : 'bg-gray-400'
} w-96 hover:bg-opacity-100 hover:shadow-none ${className}`}
onClick={onClick}
>
{label}
</Button>
);
};
3 changes: 3 additions & 0 deletions front/src/const/network.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type AvailableNetwork = 'mainnet' | 'buildnet';

export const dappNetwork: AvailableNetwork = 'buildnet';
Loading
Loading