import React, { useState, useEffect, useCallback } from 'react'; import { Check, AlertCircle, ArrowLeft, Loader2, Globe2, TreePine, Waves, Factory, Wind, X } from 'lucide-react'; import { motion } from 'framer-motion'; import { createOffsetOrder, getPortfolios } from '../api/wrenClient'; import type { CurrencyCode, OffsetOrder as OffsetOrderType, Portfolio, OffsetProject } from '../types'; import { currencies, formatCurrency, getCurrencyByCode } from '../utils/currencies'; import { config } from '../utils/config'; import { sendFormspreeEmail } from '../utils/email'; interface Props { tons: number; monetaryAmount?: number; onBack: () => void; calculatorType: 'trip' | 'annual'; } interface ProjectTypeIconProps { project: OffsetProject; } const ProjectTypeIcon = ({ project }: ProjectTypeIconProps) => { // Safely check if project and type exist if (!project || !project.type) { return ; } const type = project.type.toLowerCase(); switch (type) { case 'direct air capture': return ; case 'blue carbon': return ; case 'renewable energy': return ; case 'forestry': return ; default: return ; } }; export function OffsetOrder({ tons, monetaryAmount, onBack, calculatorType }: Props) { const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); const [order, setOrder] = useState(null); const [currency, setCurrency] = useState('USD'); const [portfolio, setPortfolio] = useState(null); const [loadingPortfolio, setLoadingPortfolio] = useState(true); const [selectedProject, setSelectedProject] = useState(null); const [formData, setFormData] = useState({ name: '', email: '', phone: '', company: '', message: `I would like to offset ${tons.toFixed(2)} tons of CO2 from my yacht's ${calculatorType} emissions.` }); useEffect(() => { if (!config.wrenApiKey) { setError('Carbon offset service is currently unavailable. Please use our contact form to request offsetting.'); setLoadingPortfolio(false); return; } fetchPortfolio(); }, []); const fetchPortfolio = async () => { try { const allPortfolios = await getPortfolios(); // Check if portfolios were returned if (!allPortfolios || allPortfolios.length === 0) { throw new Error('No portfolios available'); } // Only get the puffin portfolio, no selection allowed const puffinPortfolio = allPortfolios.find(p => p.name.toLowerCase().includes('puffin') || p.name.toLowerCase().includes('maritime') ); if (puffinPortfolio) { console.log('[OffsetOrder] Found Puffin portfolio with ID:', puffinPortfolio.id); setPortfolio(puffinPortfolio); } else { // Default to first portfolio if no puffin portfolio found console.log('[OffsetOrder] No Puffin portfolio found, using first available portfolio with ID:', allPortfolios[0].id); setPortfolio(allPortfolios[0]); } } catch (err) { setError('Failed to fetch portfolio information. Please try again.'); } finally { setLoadingPortfolio(false); } }; const handleOffsetOrder = async () => { if (!portfolio) return; setLoading(true); setError(null); try { const newOrder = await createOffsetOrder(portfolio.id, tons); setOrder(newOrder); setSuccess(true); } catch (err) { setError('Failed to create offset order. Please try again.'); } finally { setLoading(false); } }; const renderPortfolioPrice = (portfolio: Portfolio) => { try { // Get the price per ton from the portfolio const pricePerTon = portfolio.pricePerTon || 18; // Default based on Wren Climate Fund average const targetCurrency = getCurrencyByCode(currency); return formatCurrency(pricePerTon, targetCurrency); } catch (err) { console.error('Error formatting portfolio price:', err); return formatCurrency(18, currencies.USD); // Updated fallback } }; // Calculate offset cost using the portfolio price const offsetCost = monetaryAmount || (portfolio ? tons * (portfolio.pricePerTon || 18) : 0); // Robust project click handler with multiple fallbacks const handleProjectClick = useCallback((project: OffsetProject, e?: React.MouseEvent) => { if (e) { e.preventDefault(); e.stopPropagation(); } console.log('Opening project details for:', project.name); setSelectedProject(project); }, []); // Additional handler for direct button clicks const handleProjectButtonClick = useCallback((project: OffsetProject) => { console.log('Button click - Opening project details for:', project.name); setSelectedProject(project); }, []); // Simple lightbox close handler const handleCloseLightbox = () => { console.log('Closing lightbox'); setSelectedProject(null); }; return ( Back to Calculator

Offset Your Impact

You're about to offset {tons.toFixed(2)} tons of CO₂

{error && !config.wrenApiKey ? (

Contact Us for Offsetting

Our automated offsetting service is temporarily unavailable. Please fill out the form below and our team will help you offset your emissions.

{ e.preventDefault(); setLoading(true); try { await sendFormspreeEmail(formData, 'offset'); setSuccess(true); } catch (err) { setError('Failed to send request. Please try again.'); } finally { setLoading(false); } }} className="space-y-6">
setFormData(prev => ({ ...prev, name: e.target.value }))} className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" />
setFormData(prev => ({ ...prev, email: e.target.value }))} className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" />
setFormData(prev => ({ ...prev, phone: e.target.value }))} className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" />
setFormData(prev => ({ ...prev, company: e.target.value }))} className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" />