Files
com.blitzwallet/app/components/admin/homeComponents/pools/presetAmountGrid.js
T

176 lines
5.0 KiB
JavaScript

import { StyleSheet, TouchableOpacity, View } from 'react-native';
import { ThemeText } from '../../../../functions/CustomElements';
import { SIZES, SATSPERBITCOIN } from '../../../../constants';
import { COLORS } from '../../../../constants/theme';
import GetThemeColors from '../../../../hooks/themeColors';
import { useGlobalThemeContext } from '../../../../../context-store/theme';
import displayCorrectDenomination from '../../../../functions/displayCorrectDenomination';
import { useGlobalContextProvider } from '../../../../../context-store/context';
const PRESET_AMOUNTS_USD = [5, 10, 25, 50, 100];
/**
* Cash App-style preset amount selection grid.
* Shows $5, $10, $25, $50, $100 and a "..." for custom amounts.
* Dynamically adjusts to 2 rows of 3 or 3 rows of 2 based on content width.
*
* @param {function} onSelectPreset - Called with sats (number) when a preset is selected
* @param {number} selectedAmountSats - Currently selected amount in sats (for highlight)
* @param {Object} fiatStats - Fiat conversion stats { value: pricePerBTC }
*/
export default function PresetAmountGrid({
onSelectPreset,
selectedAmountSats = 0,
fiatStats,
onCustomPress,
}) {
const { theme, darkModeType } = useGlobalThemeContext();
const { masterInfoObject } = useGlobalContextProvider();
const { backgroundOffset, backgroundColor } = GetThemeColors();
const fiatPrice = fiatStats?.value || 0;
const isFiatMode = masterInfoObject.userBalanceDenomination === 'fiat';
// Convert USD to sats using current BTC price
const usdToSats = usdAmount => {
if (!fiatPrice || fiatPrice <= 0) return 0;
return Math.round((usdAmount / fiatPrice) * SATSPERBITCOIN);
};
// Create preset objects with both representations
const presets = PRESET_AMOUNTS_USD.map(usd => ({
usd,
sats: usd * 1000, // Fixed sats amount
satValueOfUsd: usdToSats(usd), // Dynamic conversion based on BTC price
}));
const handleCustomAmount = () => {
if (onCustomPress) {
onCustomPress();
}
};
const handleSelect = preset => {
onSelectPreset(isFiatMode ? preset.satValueOfUsd : preset.sats);
};
const isPresetSelected = preset => {
if (!selectedAmountSats) return false;
const presetValue = isFiatMode ? preset.satValueOfUsd : preset.sats;
return selectedAmountSats === presetValue;
};
const isCustomSelected = () => {
if (!selectedAmountSats) return false;
return !presets.some(preset => {
const presetValue = isFiatMode ? preset.satValueOfUsd : preset.sats;
return selectedAmountSats === presetValue;
});
};
// Create all items (presets + custom)
const allItems = [...presets, { isCustomButton: true }];
// Split into rows based on layout
const rows = [
allItems.slice(0, 2),
allItems.slice(2, 4),
allItems.slice(4, 6),
];
const renderButton = item => {
if (item.isCustomButton) {
return (
<TouchableOpacity
key="custom"
activeOpacity={0.7}
onPress={handleCustomAmount}
style={[
styles.presetButton,
{
backgroundColor: theme
? darkModeType
? backgroundColor
: backgroundOffset
: COLORS.darkModeText,
borderColor: isCustomSelected()
? theme
? COLORS.darkModeText
: COLORS.primary
: 'transparent',
},
]}
>
<ThemeText styles={styles.presetText} content={'...'} />
</TouchableOpacity>
);
}
return (
<TouchableOpacity
key={item.usd}
activeOpacity={0.7}
onPress={() => handleSelect(item)}
style={[
styles.presetButton,
{
backgroundColor: theme
? darkModeType
? backgroundColor
: backgroundOffset
: COLORS.darkModeText,
borderColor: isPresetSelected(item)
? theme
? COLORS.darkModeText
: COLORS.primary
: 'transparent',
},
]}
>
<ThemeText
styles={styles.presetText}
content={displayCorrectDenomination({
amount: isFiatMode ? item.usd : item.sats,
masterInfoObject,
fiatStats,
convertAmount: !isFiatMode,
})}
/>
</TouchableOpacity>
);
};
return (
<View style={styles.grid}>
{rows.map((row, rowIndex) => (
<View key={`row-${rowIndex}`} style={styles.row}>
{row.map(item => renderButton(item))}
</View>
))}
</View>
);
}
const styles = StyleSheet.create({
grid: {
gap: 12,
},
row: {
flexDirection: 'row',
gap: 12,
},
presetButton: {
flex: 1,
minHeight: 50,
borderRadius: 12,
justifyContent: 'center',
alignItems: 'center',
borderWidth: 2,
paddingHorizontal: 8,
},
presetText: {
fontSize: SIZES.medium,
includeFontPadding: false,
},
});