123 lines
3.4 KiB
TypeScript
123 lines
3.4 KiB
TypeScript
import React from 'react';
|
|
import { Box, Text } from 'ink';
|
|
import { colors, formatSatoshis } from '../../../theme.js';
|
|
import { useSatoshisConversion } from '../../../hooks/useSatoshisConversion.js';
|
|
import type { VariableInput, SelectableUTXO } from '../types.js';
|
|
import type { XOTemplate } from '@xo-cash/types';
|
|
|
|
interface ReviewStepProps {
|
|
template: XOTemplate;
|
|
actionName: string;
|
|
roleIdentifier: string;
|
|
variables: VariableInput[];
|
|
availableUtxos: SelectableUTXO[];
|
|
changeAmount: bigint;
|
|
}
|
|
|
|
export function ReviewStep({
|
|
template,
|
|
actionName,
|
|
roleIdentifier,
|
|
variables,
|
|
availableUtxos,
|
|
changeAmount,
|
|
}: ReviewStepProps): React.ReactElement {
|
|
const selectedUtxos = availableUtxos.filter((u) => u.selected);
|
|
const { formatSatoshisToFiat } = useSatoshisConversion('USD');
|
|
|
|
const getFiatSuffix = (satoshis: bigint): string => {
|
|
const fiatValue = formatSatoshisToFiat(satoshis);
|
|
return fiatValue ? ` (~${fiatValue})` : '';
|
|
};
|
|
|
|
const getVariableFiatSuffix = (variable: VariableInput): string => {
|
|
if (variable.type !== 'integer') {
|
|
return '';
|
|
}
|
|
|
|
if (variable.hint?.toLowerCase().includes('satoshi') !== true) {
|
|
return '';
|
|
}
|
|
|
|
if (!/^[-]?\d+$/.test(variable.value.trim())) {
|
|
return '';
|
|
}
|
|
|
|
try {
|
|
return getFiatSuffix(BigInt(variable.value));
|
|
} catch {
|
|
return '';
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Box flexDirection='column'>
|
|
<Text color={colors.text} bold>
|
|
Review your invitation:
|
|
</Text>
|
|
|
|
{/* Summary */}
|
|
<Box marginTop={1} flexDirection='column'>
|
|
<Text color={colors.textMuted}>Template: {template?.name}</Text>
|
|
<Text color={colors.textMuted}>Action: {actionName}</Text>
|
|
<Text color={colors.textMuted}>Role: {roleIdentifier}</Text>
|
|
</Box>
|
|
|
|
{/* Variables */}
|
|
{variables.length > 0 && (
|
|
<Box marginTop={1} flexDirection='column'>
|
|
<Text color={colors.text}>Variables:</Text>
|
|
{variables.map((v) => (
|
|
<Text key={v.id} color={colors.textMuted}>
|
|
{' '}
|
|
{v.name}: {v.value || '(empty)'}
|
|
{v.value ? getVariableFiatSuffix(v) : ''}
|
|
</Text>
|
|
))}
|
|
</Box>
|
|
)}
|
|
|
|
{/* Inputs */}
|
|
{selectedUtxos.length > 0 && (
|
|
<Box marginTop={1} flexDirection='column'>
|
|
<Text color={colors.text}>
|
|
Inputs ({selectedUtxos.length}):
|
|
</Text>
|
|
{selectedUtxos.slice(0, 3).map((u) => (
|
|
<Text
|
|
key={`${u.outpointTransactionHash}:${u.outpointIndex}`}
|
|
color={colors.textMuted}
|
|
>
|
|
{' '}
|
|
{formatSatoshis(u.valueSatoshis)}
|
|
{getFiatSuffix(u.valueSatoshis)}
|
|
</Text>
|
|
))}
|
|
{selectedUtxos.length > 3 && (
|
|
<Text color={colors.textMuted}>
|
|
{' '}...and {selectedUtxos.length - 3} more
|
|
</Text>
|
|
)}
|
|
</Box>
|
|
)}
|
|
|
|
{/* Outputs */}
|
|
{changeAmount > 0n && (
|
|
<Box marginTop={1} flexDirection='column'>
|
|
<Text color={colors.text}>Outputs:</Text>
|
|
<Text color={colors.textMuted}>
|
|
{' '}Change: {formatSatoshis(changeAmount)}
|
|
{getFiatSuffix(changeAmount)}
|
|
</Text>
|
|
</Box>
|
|
)}
|
|
|
|
{/* Confirmation prompt */}
|
|
<Box marginTop={1}>
|
|
<Text color={colors.warning}>
|
|
Press Next to create and publish the invitation.
|
|
</Text>
|
|
</Box>
|
|
</Box>
|
|
);
|
|
} |