All files / features/donation/components DonationAmountSelector.tsx

100% Statements 14/14
92.85% Branches 13/14
100% Functions 5/5
100% Lines 13/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101                                2x           27x 27x   27x 27x             27x                   108x       2x                                                 27x     27x     1x 1x 1x                                        
import { Button } from '@core/components/ui/button'
import { Card, CardHeader, CardTitle, CardContent } from '@core/components/ui/card'
import { Input } from '@core/components/ui/input'
import { useTranslation } from 'react-i18next'
import { useCurrencyFormatter } from '@core/hooks/useCurrencyFormatter'
import type { UseFormRegister, FieldErrors, UseFormSetValue } from 'react-hook-form'
import type { DonationFormValues } from '../schemas/donation.schema'
 
interface DonationAmountSelectorProps {
    selectedAmount: number
    onAmountSelect: (amount: number) => void
    register: UseFormRegister<DonationFormValues>
    errors: FieldErrors<DonationFormValues>
    setValue: UseFormSetValue<DonationFormValues>
}
 
export const DonationAmountSelector = ({
    selectedAmount,
    onAmountSelect,
    register,
    errors,
}: DonationAmountSelectorProps) => {
    const { t } = useTranslation('common')
    const { formatCurrency } = useCurrencyFormatter()
 
    const glassCardClass = 'backdrop-blur-md border overflow-hidden'
    const glassCardStyle = {
        backgroundColor: 'var(--glass-bg)',
        borderColor: 'var(--glass-border)',
        backdropFilter: 'blur(var(--glass-blur))',
        boxShadow: 'var(--glass-shadow)',
    }
 
    return (
        <Card className={glassCardClass} style={glassCardStyle}>
            <CardHeader>
                <CardTitle className="text-xl" style={{ color: 'var(--donation-title-color)' }}>
                    {t('donation.amount')}
                </CardTitle>
            </CardHeader>
            <CardContent className="space-y-4">
                <div className="grid grid-cols-3 gap-3">
                    {[10, 20, 50, 100].map((amt) => (
                        <Button
                            key={amt}
                            type="button"
                            variant={selectedAmount === amt ? 'default' : 'outline'}
                            onClick={() => onAmountSelect(amt)}
                            className={`h-12 text-lg transition-all ${selectedAmount === amt ? 'shadow-lg scale-105' : 'hover:opacity-90'}`}
                            style={{
                                backgroundColor:
                                    selectedAmount === amt
                                        ? 'var(--donation-amount-button-selected-bg)'
                                        : 'var(--donation-amount-button-bg)',
                                color:
                                    selectedAmount === amt
                                        ? 'var(--donation-amount-button-selected-text)'
                                        : 'var(--donation-amount-button-text)',
                                borderColor:
                                    selectedAmount !== amt
                                        ? 'var(--donation-input-border)'
                                        : 'transparent',
                            }}
                        >
                            {formatCurrency(amt)}
                        </Button>
                    ))}
                    <div className="col-span-2 relative">
                        <Input
                            type="number"
                            placeholder={t('donation.custom_amount')}
                            {...(() => {
                                const { onChange, ...rest } = register('amount', {
                                    valueAsNumber: true,
                                })
                                return {
                                    ...rest,
                                    onChange: (e: React.ChangeEvent<HTMLInputElement>) => {
                                        onChange(e)
                                        const val = parseFloat(e.target.value)
                                        Eif (!isNaN(val)) onAmountSelect(val)
                                    },
                                }
                            })()}
                            className="h-12 transition-colors"
                            style={{
                                backgroundColor: 'var(--donation-input-bg)',
                                color: 'var(--donation-input-text)',
                                borderColor: 'var(--donation-input-border)',
                            }}
                        />
                    </div>
                </div>
                {errors.amount && (
                    <p className="text-sm text-red-500 font-medium">{errors.amount.message}</p>
                )}
            </CardContent>
        </Card>
    )
}