Add numerical formatting to custom amount field in calculators
All checks were successful
Build and Push Docker Images / docker (push) Successful in 52s

- Updated TripCalculator custom amount field to use formatNumber helper
- Updated MobileCalculator custom amount field to use formatNumber helper
- Changed input type from "number" to "text" to display formatted values
- Strip commas when converting to numbers for calculations
- Custom amount inputs now display thousand separators for better readability

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Matt 2025-10-30 14:58:10 +01:00
parent 0b2d8685d8
commit 6753337135
2 changed files with 14 additions and 16 deletions

View File

@ -116,9 +116,9 @@ export function MobileCalculator({ vesselData, onOffsetClick, onBack }: Props) {
const handleCustomAmountChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => { const handleCustomAmountChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value; const value = e.target.value.replace(/,/g, '');
if (value === '' || Number(value) >= 0) { if (value === '' || /^\d*\.?\d*$/.test(value)) {
setCustomAmount(value); setCustomAmount(formatNumber(value));
} }
}, []); }, []);
@ -267,11 +267,10 @@ export function MobileCalculator({ vesselData, onOffsetClick, onBack }: Props) {
<span className="text-gray-500 text-lg">{currencies[currency].symbol}</span> <span className="text-gray-500 text-lg">{currencies[currency].symbol}</span>
</div> </div>
<input <input
type="number" type="text"
value={customAmount} value={customAmount}
onChange={handleCustomAmountChange} onChange={handleCustomAmountChange}
placeholder="0.00" placeholder="0.00"
min="0"
className="w-full pl-10 pr-16 py-4 text-lg border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent" className="w-full pl-10 pr-16 py-4 text-lg border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/> />
<div className="absolute inset-y-0 right-0 pr-4 flex items-center pointer-events-none"> <div className="absolute inset-y-0 right-0 pr-4 flex items-center pointer-events-none">
@ -281,11 +280,11 @@ export function MobileCalculator({ vesselData, onOffsetClick, onBack }: Props) {
</div> </div>
</div> </div>
{customAmount && Number(customAmount) > 0 && ( {customAmount && Number(customAmount.replace(/,/g, '')) > 0 && (
<motion.button <motion.button
onClick={() => { onClick={() => {
setOffsetTons(0); setOffsetTons(0);
setMonetaryAmount(Number(customAmount)); setMonetaryAmount(Number(customAmount.replace(/,/g, '')));
setShowOffsetOrder(true); setShowOffsetOrder(true);
}} }}
className="w-full mt-6 bg-gradient-to-r from-blue-500 to-blue-600 text-white py-4 px-6 rounded-xl font-semibold text-lg shadow-md hover:shadow-lg transition-all" className="w-full mt-6 bg-gradient-to-r from-blue-500 to-blue-600 text-white py-4 px-6 rounded-xl font-semibold text-lg shadow-md hover:shadow-lg transition-all"
@ -294,7 +293,7 @@ export function MobileCalculator({ vesselData, onOffsetClick, onBack }: Props) {
initial={{ opacity: 0, y: 10 }} initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
> >
Offset {formatCurrency(Number(customAmount), getCurrencyByCode(currency))} Offset {formatCurrency(Number(customAmount.replace(/,/g, '')), getCurrencyByCode(currency))}
</motion.button> </motion.button>
)} )}
</div> </div>

View File

@ -97,9 +97,9 @@ export function TripCalculator({ vesselData, onOffsetClick }: Props) {
const handleCustomAmountChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => { const handleCustomAmountChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value; const value = e.target.value.replace(/,/g, '');
if (value === '' || Number(value) >= 0) { if (value === '' || /^\d*\.?\d*$/.test(value)) {
setCustomAmount(value); setCustomAmount(formatNumber(value));
} }
}, []); }, []);
@ -241,11 +241,10 @@ export function TripCalculator({ vesselData, onOffsetClick }: Props) {
<span className="text-gray-500 text-sm font-semibold">$</span> <span className="text-gray-500 text-sm font-semibold">$</span>
</div> </div>
<input <input
type="number" type="text"
value={customAmount} value={customAmount}
onChange={handleCustomAmountChange} onChange={handleCustomAmountChange}
placeholder="Enter amount" placeholder="Enter amount"
min="0"
className="block w-full pl-10 pr-16 py-2.5 rounded-lg border border-gray-200 shadow-sm transition-all duration-200 text-sm text-gray-900 font-medium outline-none hover:border-gray-300 hover:shadow-md focus:border-blue-500 focus:ring-2 focus:ring-blue-100 focus:shadow-md" className="block w-full pl-10 pr-16 py-2.5 rounded-lg border border-gray-200 shadow-sm transition-all duration-200 text-sm text-gray-900 font-medium outline-none hover:border-gray-300 hover:shadow-md focus:border-blue-500 focus:ring-2 focus:ring-blue-100 focus:shadow-md"
required required
/> />
@ -255,9 +254,9 @@ export function TripCalculator({ vesselData, onOffsetClick }: Props) {
</div> </div>
</div> </div>
{customAmount && Number(customAmount) > 0 && ( {customAmount && Number(customAmount.replace(/,/g, '')) > 0 && (
<motion.button <motion.button
onClick={() => onOffsetClick?.(0, Number(customAmount))} onClick={() => onOffsetClick?.(0, Number(customAmount.replace(/,/g, '')))}
className="w-full bg-blue-500 text-white py-2 px-4 rounded-lg hover:bg-blue-600 transition-colors mt-6" className="w-full bg-blue-500 text-white py-2 px-4 rounded-lg hover:bg-blue-600 transition-colors mt-6"
whileHover={{ scale: 1.03 }} whileHover={{ scale: 1.03 }}
whileTap={{ scale: 0.97 }} whileTap={{ scale: 0.97 }}