This commit is contained in:
Matt 2025-06-03 14:08:35 +02:00
commit bf0f362ab7

View File

@ -1,6 +1,9 @@
import React, { useState, useEffect } from 'react';
import { Check, AlertCircle, ArrowLeft, Loader2, Globe2, TreePine, Waves, Factory, Wind, X } from 'lucide-react';
<<<<<<< HEAD
import { motion, AnimatePresence } from 'framer-motion';
=======
>>>>>>> 96496350ee59fb2fd226eb340094130203514ab8
import { createOffsetOrder, getPortfolios } from '../api/wrenClient';
import type { CurrencyCode, OffsetOrder as OffsetOrderType, Portfolio, OffsetProject } from '../types';
import { currencies, formatCurrency, getCurrencyByCode } from '../utils/currencies';
@ -57,6 +60,9 @@ export function OffsetOrder({ tons, monetaryAmount, onBack, calculatorType }: Pr
message: `I would like to offset ${tons.toFixed(2)} tons of CO2 from my yacht's ${calculatorType} emissions.`
});
// lightbox state
const [selectedProject, setSelectedProject] = useState<OffsetProject | null>(null);
useEffect(() => {
if (!config.wrenApiKey) {
setError('Carbon offset service is currently unavailable. Please use our contact form to request offsetting.');
@ -66,6 +72,19 @@ export function OffsetOrder({ tons, monetaryAmount, onBack, calculatorType }: Pr
fetchPortfolio();
}, []);
// handle Escape key to close lightbox
useEffect(() => {
const onKey = (e: KeyboardEvent) => {
if (e.key === 'Escape') setSelectedProject(null);
};
if (selectedProject) {
document.addEventListener('keydown', onKey);
}
return () => {
document.removeEventListener('keydown', onKey);
};
}, [selectedProject]);
const fetchPortfolio = async () => {
try {
const allPortfolios = await getPortfolios();
@ -322,6 +341,7 @@ export function OffsetOrder({ tons, monetaryAmount, onBack, calculatorType }: Pr
</p>
{portfolio.projects && portfolio.projects.length > 0 && (
<<<<<<< HEAD
<motion.div
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-6"
initial={{ opacity: 0 }}
@ -339,6 +359,15 @@ export function OffsetOrder({ tons, monetaryAmount, onBack, calculatorType }: Pr
whileTap={{ scale: 0.98 }}
onClick={() => setSelectedProject(project)}
>
=======
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-6">
{portfolio.projects.map((project) => (
<div
key={project.id}
onClick={() => setSelectedProject(project)}
className="cursor-pointer bg-gray-50 rounded-lg p-4 hover:shadow-md transition-shadow"
>
>>>>>>> 96496350ee59fb2fd226eb340094130203514ab8
<div className="flex items-center justify-between mb-3">
<div className="flex items-center space-x-2">
<ProjectTypeIcon project={project} />
@ -378,12 +407,56 @@ export function OffsetOrder({ tons, monetaryAmount, onBack, calculatorType }: Pr
</motion.div>
)}
<<<<<<< HEAD
<motion.div
className="flex items-center justify-between bg-blue-50 p-4 rounded-lg"
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.5, delay: 0.5 }}
>
=======
{/* lightbox modal */}
{selectedProject && (
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
onClick={() => setSelectedProject(null)}
>
<div
className="relative bg-white rounded-lg p-6 max-w-lg w-full"
onClick={e => e.stopPropagation()}
>
<button
onClick={() => setSelectedProject(null)}
className="absolute top-4 right-4 text-gray-500 hover:text-gray-700"
>
<X size={24} />
</button>
<h3 className="text-2xl font-bold mb-4">
{selectedProject.name}
</h3>
{selectedProject.imageUrl && (
<img
src={selectedProject.imageUrl}
alt={selectedProject.name}
className="w-full h-48 object-cover rounded mb-4"
/>
)}
<p className="text-gray-700 mb-4">
{selectedProject.description}
</p>
<div className="flex justify-between">
<span className="font-medium">Type:</span>
<span>{selectedProject.type}</span>
</div>
<div className="flex justify-between mt-2">
<span className="font-medium">Price per ton:</span>
<span>${selectedProject.pricePerTon.toFixed(2)}</span>
</div>
</div>
</div>
)}
<div className="flex items-center justify-between bg-blue-50 p-4 rounded-lg">
>>>>>>> 96496350ee59fb2fd226eb340094130203514ab8
<span className="text-blue-900 font-medium">Portfolio Price per Ton:</span>
<span className="text-blue-900 font-bold text-lg">
{renderPortfolioPrice(portfolio)}