change: 10$ minimum transfer

This commit is contained in:
Face 2025-06-02 12:23:34 +03:00
parent 8f2aee1552
commit 3a2677b334
3 changed files with 51 additions and 10 deletions

View file

@ -35,6 +35,12 @@
coinHoldings.find((holding) => holding.symbol === selectedCoinSymbol) coinHoldings.find((holding) => holding.symbol === selectedCoinSymbol)
); );
let estimatedValue = $derived(
transferType === 'COIN' && selectedCoinHolding && numericAmount > 0
? numericAmount * selectedCoinHolding.currentPrice
: 0
);
let maxAmount = $derived( let maxAmount = $derived(
transferType === 'CASH' ? userBalance : selectedCoinHolding ? selectedCoinHolding.quantity : 0 transferType === 'CASH' ? userBalance : selectedCoinHolding ? selectedCoinHolding.quantity : 0
); );
@ -47,10 +53,20 @@
: false : false
); );
let isWithinCashLimit = $derived(
transferType === 'CASH' ? numericAmount >= 10 : true
);
let isWithinCoinValueLimit = $derived(
transferType === 'COIN' ? estimatedValue >= 10 : true
);
let canSend = $derived( let canSend = $derived(
hasValidAmount && hasValidAmount &&
hasValidRecipient && hasValidRecipient &&
hasEnoughFunds && hasEnoughFunds &&
isWithinCashLimit &&
isWithinCoinValueLimit &&
!loading && !loading &&
(transferType === 'CASH' || selectedCoinSymbol.length > 0) (transferType === 'CASH' || selectedCoinSymbol.length > 0)
); );
@ -65,7 +81,11 @@
} }
function setMaxAmount() { function setMaxAmount() {
amount = maxAmount.toString(); if (transferType === 'CASH') {
amount = Math.max(maxAmount, 10).toString();
} else {
amount = maxAmount.toString();
}
} }
function handleTypeChange(value: string) { function handleTypeChange(value: string) {
@ -151,12 +171,6 @@
})() })()
); );
let estimatedValue = $derived(
transferType === 'COIN' && selectedCoinHolding && numericAmount > 0
? numericAmount * selectedCoinHolding.currentPrice
: 0
);
function handleCoinChange(value: string) { function handleCoinChange(value: string) {
selectedCoinSymbol = value; selectedCoinSymbol = value;
} }
@ -267,15 +281,32 @@
</p> </p>
{/if} {/if}
</div> </div>
{#if transferType === 'CASH'}
<p class="text-muted-foreground text-xs">
Minimum: $10.00 per transfer
</p>
{:else if transferType === 'COIN'}
<p class="text-muted-foreground text-xs">
Minimum estimated value: $10.00 per transfer
</p>
{/if}
</div> </div>
{#if !hasEnoughFunds && hasValidAmount} {#if !hasEnoughFunds && hasValidAmount}
<Badge variant="destructive" class="text-xs"> <Badge variant="destructive" class="text-xs">
Insufficient {transferType === 'CASH' ? 'funds' : 'coins'} Insufficient {transferType === 'CASH' ? 'funds' : 'coins'}
</Badge> </Badge>
{:else if !isWithinCashLimit && hasValidAmount}
<Badge variant="destructive" class="text-xs">
Cash transfers require a minimum of $10.00
</Badge>
{:else if !isWithinCoinValueLimit && hasValidAmount}
<Badge variant="destructive" class="text-xs">
Coin transfers require a minimum estimated value of $10.00
</Badge>
{/if} {/if}
{#if hasValidAmount && hasEnoughFunds && hasValidRecipient} {#if hasValidAmount && hasEnoughFunds && hasValidRecipient && isWithinCashLimit && isWithinCoinValueLimit}
<div class="bg-muted/50 rounded-lg p-3"> <div class="bg-muted/50 rounded-lg p-3">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<span class="text-sm font-medium">You're sending:</span> <span class="text-sm font-medium">You're sending:</span>

View file

@ -30,6 +30,10 @@ export const POST: RequestHandler = async ({ request }) => {
throw error(400, 'Transfer amount too large'); throw error(400, 'Transfer amount too large');
} }
if (type === 'CASH' && amount < 10) {
throw error(400, 'Cash transfers require a minimum of $10.00');
}
if (type === 'COIN' && !coinSymbol) { if (type === 'COIN' && !coinSymbol) {
throw error(400, 'Coin symbol required for coin transfers'); throw error(400, 'Coin symbol required for coin transfers');
} }
@ -140,6 +144,13 @@ export const POST: RequestHandler = async ({ request }) => {
throw error(404, 'Coin not found'); throw error(404, 'Coin not found');
} }
const coinPrice = Number(coinData.currentPrice) || 0;
const estimatedValue = amount * coinPrice;
if (estimatedValue < 10) {
throw error(400, `Coin transfers require a minimum estimated value of $10.00. ${amount.toFixed(6)} ${coinData.symbol} is worth approximately $${estimatedValue.toFixed(2)}`);
}
const [senderHolding] = await tx const [senderHolding] = await tx
.select({ .select({
quantity: userPortfolio.quantity quantity: userPortfolio.quantity
@ -167,7 +178,6 @@ export const POST: RequestHandler = async ({ request }) => {
.for('update') .for('update')
.limit(1); .limit(1);
const coinPrice = Number(coinData.currentPrice) || 0;
const totalValue = amount * coinPrice; const totalValue = amount * coinPrice;
const newSenderQuantity = Number(senderHolding.quantity) - amount; const newSenderQuantity = Number(senderHolding.quantity) - amount;

View file

@ -108,7 +108,7 @@
return; return;
} }
if (userBalance <= 100_000) { if (userBalance <= 100_000) {
toast.error('You need at least $100,000 in your portfolio to create a question.'); toast.error('You need at least $100,000 in your portfolio (cash) to create a question.');
return; return;
} }
showCreateDialog = true; showCreateDialog = true;