import React, { useState, useCallback } from 'react'; import { Route } from 'lucide-react'; import type { VesselData, TripEstimate, CurrencyCode } from '../types'; import { calculateTripCarbon, calculateCarbonFromFuel } from '../utils/carbonCalculator'; import { currencies, formatCurrency } from '../utils/currencies'; import { CurrencySelect } from './CurrencySelect'; interface Props { vesselData: VesselData; onOffsetClick?: (tons: number, monetaryAmount?: number) => void; } export function TripCalculator({ vesselData, onOffsetClick }: Props) { const [calculationType, setCalculationType] = useState<'fuel' | 'distance' | 'custom'>('fuel'); const [distance, setDistance] = useState(''); const [speed, setSpeed] = useState('12'); const [fuelRate, setFuelRate] = useState('100'); const [fuelAmount, setFuelAmount] = useState(''); const [fuelUnit, setFuelUnit] = useState<'liters' | 'gallons'>('liters'); const [tripEstimate, setTripEstimate] = useState(null); const [currency, setCurrency] = useState('USD'); const [offsetPercentage, setOffsetPercentage] = useState(100); const [customPercentage, setCustomPercentage] = useState(''); const [customAmount, setCustomAmount] = useState(''); const handleCalculate = useCallback((e: React.FormEvent) => { e.preventDefault(); if (calculationType === 'distance') { const estimate = calculateTripCarbon( vesselData, Number(distance), Number(speed), Number(fuelRate) ); setTripEstimate(estimate); } else if (calculationType === 'fuel') { const co2Emissions = calculateCarbonFromFuel(Number(fuelAmount), fuelUnit === 'gallons'); setTripEstimate({ distance: 0, duration: 0, fuelConsumption: Number(fuelAmount), co2Emissions }); } }, [calculationType, distance, speed, fuelRate, fuelAmount, fuelUnit, vesselData]); const handleCustomPercentageChange = useCallback((e: React.ChangeEvent) => { const value = e.target.value; if (value === '' || (Number(value) >= 0 && Number(value) <= 100)) { setCustomPercentage(value); if (value !== '') { setOffsetPercentage(Number(value)); } } }, []); const handlePresetPercentage = useCallback((percentage: number) => { setOffsetPercentage(percentage); setCustomPercentage(''); }, []); const calculateOffsetAmount = useCallback((emissions: number, percentage: number) => { return (emissions * percentage) / 100; }, []); const handleCustomAmountChange = useCallback((e: React.ChangeEvent) => { const value = e.target.value; if (value === '' || Number(value) >= 0) { setCustomAmount(value); } }, []); return (

Carbon Offset Calculator

{calculationType === 'custom' ? (
{currencies[currency].symbol}
{currency}
{customAmount && Number(customAmount) > 0 && ( )}
) : (
{calculationType === 'fuel' && (
setFuelAmount(e.target.value)} placeholder="Enter amount" className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200" required />
)} {calculationType === 'distance' && ( <>
setDistance(e.target.value)} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200" required />
setSpeed(e.target.value)} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200" required />
setFuelRate(e.target.value)} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200" required />

Typical range: 50 - 500 liters per hour for most yachts

)}
)} {tripEstimate && calculationType !== 'custom' && (
{calculationType === 'distance' && (

Trip Duration

{tripEstimate.duration.toFixed(1)} hours

)}

Fuel Consumption

{tripEstimate.fuelConsumption.toLocaleString()} {fuelUnit}

{[100, 75, 50, 25].map((percent) => ( ))}
%

Selected CO₂ Offset

{calculateOffsetAmount(tripEstimate.co2Emissions, offsetPercentage).toFixed(2)} tons

{offsetPercentage}% of {tripEstimate.co2Emissions.toFixed(2)} tons

)}
); }