Skip to content

Commit 84c0463

Browse files
committed
handle cents
1 parent 9c58bae commit 84c0463

File tree

2 files changed

+41
-18
lines changed

2 files changed

+41
-18
lines changed

components/donate/DonateWidget.tsx

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -89,48 +89,70 @@ export function DonateWidget({
8989
const [currentAmount, setCurrentAmount] = useState(
9090
() => defaultAmount ?? amounts[frequency][currency][0]
9191
)
92+
const [amountDisplay, setAmountDisplay] = useState(() =>
93+
((defaultAmount ?? amounts[frequency][currency][0]) / 100).toFixed(2)
94+
)
9295
const [dirty, setDirty] = useState(false)
9396
const [loadingCheckout, setLoadingCheckout] = useState(false)
9497
const [error, setError] = useState<string | null>(null)
9598

9699
const intl = useIntl()
97100

101+
const updateAmount = useCallback((amount: number) => {
102+
const intAmount = Math.round(amount)
103+
if (isNaN(intAmount) || intAmount < 100) {
104+
return
105+
}
106+
setCurrentAmount(intAmount)
107+
setAmountDisplay((intAmount / 100).toFixed(2))
108+
}, [])
109+
98110
const handleChangeFrequency = useCallback(
99111
(toFrequency: DonationFrequency) => () => {
100112
setFrequency(toFrequency)
101-
setCurrentAmount(amounts[toFrequency][currency][0])
113+
updateAmount(amounts[toFrequency][currency][0])
102114
setDirty(false)
103115
setError(null)
104116
},
105-
[amounts, currency]
117+
[amounts, currency, updateAmount]
106118
)
107119
const handleChangeCurrency = useCallback(
108120
(toCurrency: Currency) => {
109121
setCurrency(toCurrency)
110-
setCurrentAmount(amounts[frequency][toCurrency][0])
122+
updateAmount(amounts[frequency][toCurrency][0])
111123
setDirty(false)
112124
setError(null)
113125
},
114-
[amounts, frequency]
126+
[amounts, frequency, updateAmount]
115127
)
116128
const handleChangeAmount: React.ChangeEventHandler<HTMLInputElement> =
117129
useCallback(
118130
(event) => {
119-
setCurrentAmount(event.currentTarget.valueAsNumber * 100)
120131
setDirty(true)
121-
if (event.currentTarget.valueAsNumber < 1) {
122-
setError(intl.formatMessage(messages.amountError))
123-
} else {
124-
setError(null)
132+
const { value, valueAsNumber } = event.currentTarget
133+
setAmountDisplay(
134+
value.replaceAll(/[^0-9\.]+/g, "") ||
135+
valueAsNumber.toFixed(2) ||
136+
(currentAmount / 100).toFixed(2)
137+
)
138+
if (isNaN(valueAsNumber) || valueAsNumber < 1) {
139+
return
125140
}
141+
setCurrentAmount(valueAsNumber * 100)
126142
},
127-
[intl]
143+
[currentAmount]
128144
)
129-
const handleClickAmount = useCallback((amount: number) => {
130-
setCurrentAmount(amount)
131-
setDirty(false)
132-
setError(null)
133-
}, [])
145+
const handleClickAmount = useCallback(
146+
(amount: number) => {
147+
updateAmount(amount)
148+
setDirty(false)
149+
setError(null)
150+
},
151+
[updateAmount]
152+
)
153+
const handleBlurAmount = useCallback(() => {
154+
setAmountDisplay((currentAmount / 100).toFixed(2))
155+
}, [currentAmount])
134156

135157
const handleDonate = useCallback(() => {
136158
setLoadingCheckout(true)
@@ -191,10 +213,11 @@ export function DonateWidget({
191213
<Input
192214
className="rounded-l-none focus:shadow-none"
193215
type="number"
194-
value={currentAmount / 100}
216+
value={amountDisplay}
195217
onChange={handleChangeAmount}
218+
onBlur={handleBlurAmount}
196219
min={1}
197-
step={1}
220+
step={0.01}
198221
aria-label={intl.formatMessage(messages.amountSelect)}
199222
disabled={loadingCheckout}
200223
fullWidth

pages/donate/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export default function DonatePage({
3232
const params = new URLSearchParams({
3333
url: donation_url,
3434
frequency,
35-
amount: amount.toString(),
35+
amount: amount.toFixed(0),
3636
currency,
3737
})
3838
router.push(`/donate/checkout?${params.toString()}`)

0 commit comments

Comments
 (0)