= ({
+ isVesting,
+ handleModeChange,
+ mode,
+ modeDesc,
+ disabled,
+}) => {
+ return (
+
+ );
+};
+
+export default ModeRadioButton;
diff --git a/front/src/components/NavBar.tsx b/front/src/components/NavBar.tsx
new file mode 100644
index 0000000..d3caa5b
--- /dev/null
+++ b/front/src/components/NavBar.tsx
@@ -0,0 +1,18 @@
+import { ConnectButton } from './ConnectWalletPopup';
+import LogoSyntra from '../assets/logo-syntra.svg';
+import { useNetworkStore } from '@/store/network';
+
+export function NavBar() {
+ const { network } = useNetworkStore();
+ return (
+
+ );
+}
diff --git a/front/src/components/NumericInput.tsx b/front/src/components/NumericInput.tsx
index eed1f3e..9e1f5a2 100644
--- a/front/src/components/NumericInput.tsx
+++ b/front/src/components/NumericInput.tsx
@@ -9,11 +9,11 @@ type NumericInputProps = {
onValueChange: (e: string) => void;
asset?: Asset;
error?: string;
+ disabled?: boolean;
};
-// TODO: To add in ui-kit
export function NumericInput(props: NumericInputProps) {
- const { value, placeholder, asset, onValueChange, error } = props;
+ let { value, placeholder, asset, onValueChange, error, disabled } = props;
const [amountError, setAmountError] = useState('');
@@ -31,7 +31,11 @@ export function NumericInput(props: NumericInputProps) {
return (
onValueChange(o.value)}
placeholder={placeholder}
diff --git a/front/src/components/RecipientAddressInput.tsx b/front/src/components/RecipientAddressInput.tsx
index 7143336..5f8e0a5 100644
--- a/front/src/components/RecipientAddressInput.tsx
+++ b/front/src/components/RecipientAddressInput.tsx
@@ -1,18 +1,21 @@
-import { Input } from '@massalabs/react-ui-kit';
+import { Input, useAccountStore } from '@massalabs/react-ui-kit';
import { useState } from 'react';
import { isValidAddress } from '../utils/address';
+import { InputLabel } from './InputLabel';
interface RecipientAddressInputProps {
value: string;
onAddressChange: (address: string) => void;
- error?: string;
+ disabled?: boolean;
}
export function RecipientAddressInput({
value,
onAddressChange,
+ disabled,
}: RecipientAddressInputProps) {
const [error, setError] = useState('');
+ const { connectedAccount } = useAccountStore();
function onChange(e: React.ChangeEvent) {
onAddressChange(e.target.value);
setError('');
@@ -27,15 +30,26 @@ export function RecipientAddressInput({
if (!isValidAddress(value)) {
setError('Invalid address');
}
+
+ if (value === connectedAccount?.address) {
+ setError('Spender can not be the same as recipient');
+ }
}
return (
-
+ <>
+
+
+ >
);
}
diff --git a/front/src/components/Recurrence.tsx b/front/src/components/Recurrence.tsx
index 191c019..ebecfb7 100644
--- a/front/src/components/Recurrence.tsx
+++ b/front/src/components/Recurrence.tsx
@@ -1,24 +1,68 @@
import { useEffect, useRef, useState } from 'react';
import { Dropdown } from '@massalabs/react-ui-kit';
import Intl from '@/i18n/i18n';
-import { NumericInput } from './NumericInput';
import { InputLabel } from './InputLabel';
+import { NumericInput } from './NumericInput';
const periodInMilliseconds = 16 * 1000; // 16 seconds
const recurrenceUnits = [
- { name: Intl.t('recurrence.minute'), milliseconds: 60 * 1000 },
- { name: Intl.t('recurrence.hour'), milliseconds: 60 * 60 * 1000 },
- { name: Intl.t('recurrence.day'), milliseconds: 24 * 60 * 60 * 1000 },
- { name: Intl.t('recurrence.week'), milliseconds: 7 * 24 * 60 * 60 * 1000 },
- { name: Intl.t('recurrence.month'), milliseconds: 30 * 24 * 60 * 60 * 1000 },
- { name: Intl.t('recurrence.year'), milliseconds: 365 * 24 * 60 * 60 * 1000 },
+ { name: Intl.t('recurrence.minute'), milliseconds: 60 * 1000, periods: 225 },
+ {
+ name: Intl.t('recurrence.hour'),
+ milliseconds: 60 * 60 * 1000,
+ periods: 225,
+ },
+ {
+ name: Intl.t('recurrence.day'),
+ milliseconds: 24 * 60 * 60 * 1000,
+ periods: 5400,
+ },
+ {
+ name: Intl.t('recurrence.week'),
+ milliseconds: 7 * 24 * 60 * 60 * 1000,
+ periods: 37800,
+ },
+ {
+ name: Intl.t('recurrence.month'),
+ milliseconds: 30 * 24 * 60 * 60 * 1000,
+ periods: 162000,
+ },
+ {
+ name: Intl.t('recurrence.year'),
+ milliseconds: 365 * 24 * 60 * 60 * 1000,
+ periods: 1971000,
+ },
];
+export function getRecurrenceFromPeriods(periods: bigint) {
+ const totalMilliseconds = BigInt(periods) * BigInt(periodInMilliseconds);
+
+ // Iterate from largest to smallest unit
+ for (let i = recurrenceUnits.length - 1; i >= 0; i--) {
+ const unit = recurrenceUnits[i];
+ const unitMilliseconds = BigInt(unit.milliseconds);
+
+ if (totalMilliseconds >= unitMilliseconds) {
+ const numUnits = Number(totalMilliseconds / unitMilliseconds);
+ return { unit: unit.name, value: numUnits };
+ }
+ }
+
+ // Fallback to the smallest unit (should rarely happen with given units)
+ const smallestUnit = recurrenceUnits[0];
+ return {
+ unit: smallestUnit.name,
+ value: Number(totalMilliseconds / BigInt(smallestUnit.milliseconds)),
+ };
+}
+
export function Recurrence({
onRecurrenceChange,
+ disabled,
}: {
onRecurrenceChange: (value: bigint) => void;
+ disabled?: boolean;
}) {
const [unitIndex, setUnitIndex] = useState(4);
const [numUnits, setNumUnits] = useState(1);
@@ -58,17 +102,26 @@ export function Recurrence({
value={numUnits.toString()}
placeholder={'0'}
onValueChange={handleNumUnitsChange}
+ disabled={disabled}
/>
-
({
- item: unit.name,
- onClick: () => handleUnitChange(index),
- }))}
- />
+
+ ({
+ item: unit.name,
+ onClick: () => handleUnitChange(index),
+ }))}
+ />
+