- {formatCurrency(pricePerTon, targetCurrency)}
+
+
+ Phone
+
+ handleInputChange('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"
+ />
-
-
Your Details
-
-
-
-
-
- Full Name
-
- handleInputChange('name', e.target.value)}
- placeholder="Enter your full name"
- className="w-full py-3 px-4 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent"
- required
- />
-
-
-
-
-
- Email Address
-
- handleInputChange('email', e.target.value)}
- placeholder="Enter your email"
- className="w-full py-3 px-4 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent"
- required
- />
-
-
-
-
-
- Phone Number (Optional)
-
-
handleInputChange('phone', e.target.value)}
- placeholder="Enter your phone number"
- className="w-full py-3 px-4 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent"
- />
-
+ ) : loadingPortfolio ? (
+
+
+ Loading portfolio information...
-
+ ) : portfolio ? (
+ <>
+
+
Offset Summary
+
+
+
+
+
CO₂ to Offset
+
From your yacht emissions
+
+
+ {tons.toFixed(2)} tons
+
+
-
- Proceed to Payment
-
+
+
+
Price per Ton
+
Verified carbon credits
+
+
+ {renderPortfolioPrice(portfolio)}
+
+
+
+
+
+ Total Cost
+
+ {formatCurrency(offsetCost, targetCurrency)}
+
+
+
+
+
+
+
+
Portfolio
+
{portfolio.name}
+
{portfolio.description}
+
+
+
+ View Projects & Continue
+
+ >
+ ) : null}
);
@@ -205,180 +305,104 @@ export function MobileOffsetOrder({ tons, monetaryAmount, currency, onBack }: Pr
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
>
-
-
Project Portfolio
-
- Your offset will be distributed across these verified carbon reduction projects
-
-
-
- {projects.map((project, index) => (
-
-
-
-
-
-
{project.name}
-
{project.location}
-
+ {portfolio && (
+ <>
+
+
{portfolio.name}
+
+ Your offset will be distributed across these verified carbon reduction projects
+
+
+ {portfolio.projects && portfolio.projects.length > 0 && (
+
+ {portfolio.projects.map((project, index) => (
+
handleProjectClick(project)}
+ >
+ {project.imageUrl && (
+
+
+
+
+
{project.name}
+
+
+ )}
+
+
+ {!project.imageUrl && (
+
{project.name}
+ )}
+
+
+
+
+
+ {project.type || 'Environmental Project'}
+
+
+ {project.percentage && (
+
+ {(project.percentage * 100).toFixed(0)}%
+
+ )}
+
+
+
+ {project.shortDescription || project.description}
+
+
+
+ Price per ton
+ ${project.pricePerTon.toFixed(2)}
+
+
+
+ ))}
-
-
-
-
- {project.type}
-
-
- {(project.percentage * 100).toFixed(0)}%
-
-
-
-
- {project.description}
-
-
-
- Price per ton
- ${project.pricePerTon}
-
+ )}
+
+
+
+
+ Total CO₂ Offset
+ {tons.toFixed(2)} tons
+
+
+ Portfolio Price
+
+ {formatCurrency(offsetCost, targetCurrency)}
+
+
+
+
+
+ {loading ? (
+
+
+ Processing...
-
- ))}
-
-
-
-
-
- Total CO₂ Offset
- {tons.toFixed(2)} tons
-
-
- Portfolio Price
-
- {formatCurrency(totalCost, targetCurrency)}
-
-
-
-
-
- Continue to Payment
-
-
- );
-
- const renderPaymentStep = () => (
-
-
-
-
- Payment Information
-
-
-
-
-
- Card Number
-
-
-
-
-
-
-
-
- Cardholder Name
-
-
-
-
-
-
-
-
Order Summary
-
-
- CO₂ Offset:
- {tons.toFixed(2)} tons
-
-
- Total:
-
- {formatCurrency(totalCost, targetCurrency)}
-
-
-
-
-
-
-
setCurrentStep('summary')}
- className="py-3 px-4 border border-gray-300 text-gray-700 rounded-xl font-medium hover:bg-gray-50 transition-colors"
- >
- Back
-
-
- {loading ? (
-
-
- Processing...
-
- ) : (
- 'Place Order'
- )}
-
-
+ ) : (
+ 'Confirm Offset Order'
+ )}
+
+ >
+ )}
);
@@ -395,42 +419,52 @@ export function MobileOffsetOrder({ tons, monetaryAmount, currency, onBack }: Pr
- Order Confirmed!
+ {order ? 'Offset Order Successful!' : 'Request Sent!'}
- Congratulations! You've successfully offset {tons.toFixed(2)} tons of CO₂ from your yacht emissions.
+ {order
+ ? "Your order has been processed successfully. You'll receive a confirmation email shortly."
+ : "Your offset request has been sent. Our team will contact you shortly to complete the process."
+ }
-
-
Order Details
-
-
- Order ID:
- {generateOrderId()}
-
-
- CO₂ Offset:
- {tons.toFixed(2)} tons
-
-
- Amount Paid:
-
- {formatCurrency(totalCost, targetCurrency)}
-
-
-
-
Email:
-
{orderData.email}
+ {order && (
+
+
Order Details
+
+
+ Order ID:
+ {order.id}
+
+
+ CO₂ Offset:
+ {order.tons} tons
+
+
+ Amount:
+
+ {formatCurrency(order.amountCharged / 100, currencies[order.currency])}
+
+
+
+ Portfolio:
+ {order.portfolio.name}
+
-
+ )}
-
-
- 📧 A confirmation email has been sent to {orderData.email} with your certificate and receipt.
-
-
+ {formData.email && (
+
+
+ 📧 {order
+ ? `A confirmation email has been sent to ${formData.email}`
+ : `We'll contact you at ${formData.email}`
+ }
+
+
+ )}
{
- if (currentStep === 'payment') {
+ if (currentStep === 'projects') {
setCurrentStep('summary');
} else {
onBack();
@@ -471,7 +505,6 @@ export function MobileOffsetOrder({ tons, monetaryAmount, currency, onBack }: Pr
{currentStep === 'summary' ? 'Order Summary' :
currentStep === 'projects' ? 'Project Portfolio' :
- currentStep === 'payment' ? 'Payment' :
'Order Confirmed'}
@@ -484,13 +517,10 @@ export function MobileOffsetOrder({ tons, monetaryAmount, currency, onBack }: Pr
@@ -501,10 +531,105 @@ export function MobileOffsetOrder({ tons, monetaryAmount, currency, onBack }: Pr
{currentStep === 'summary' && renderSummaryStep()}
{currentStep === 'projects' && renderProjectsStep()}
- {currentStep === 'payment' && renderPaymentStep()}
{currentStep === 'confirmation' && renderConfirmationStep()}
+
+ {/* Lightbox Modal for Project Details */}
+
+ {selectedProject && (
+
+ e.stopPropagation()}
+ initial={{ opacity: 0, scale: 0.8, y: 20 }}
+ animate={{ opacity: 1, scale: 1, y: 0 }}
+ exit={{ opacity: 0, scale: 0.8, y: 20 }}
+ transition={{
+ duration: 0.4,
+ ease: [0.22, 1, 0.36, 1],
+ scale: { type: "spring", stiffness: 300, damping: 30 }
+ }}
+ >
+
+
+
+
+ {selectedProject.imageUrl && (
+
+
+
+
+
{selectedProject.name}
+
+
+ )}
+
+
+ {!selectedProject.imageUrl && (
+ <>
+
{selectedProject.name}
+
+
+
{selectedProject.type || 'Environmental Project'}
+
+ >
+ )}
+
+
+ {selectedProject.description || selectedProject.shortDescription}
+
+
+
+
+
Price per Ton
+
${selectedProject.pricePerTon.toFixed(2)}
+
+ {selectedProject.percentage && (
+
+
Portfolio Allocation
+
{(selectedProject.percentage * 100).toFixed(1)}%
+
+ )}
+
+
+ {(selectedProject.location || selectedProject.verificationStandard) && (
+
+ {selectedProject.location && (
+
+ Location:
+ {selectedProject.location}
+
+ )}
+ {selectedProject.verificationStandard && (
+
+ Verification:
+ {selectedProject.verificationStandard}
+
+ )}
+
+ )}
+
+
+
+ )}
+