From f9e4bc0149a415f9c7af509fd6b8226901eed75b Mon Sep 17 00:00:00 2001
From: Matt
Date: Tue, 3 Jun 2025 14:26:22 +0200
Subject: [PATCH] Add framer-motion animations to enhance UI interactions
- Install framer-motion dependency (v12.15.0)
- Add smooth transitions to forms and buttons in TripCalculator
- Implement hover and tap animations for interactive elements
- Add entrance/exit animations for component state changes
- Enhance user experience with motion effects in Home and OffsetOrder components
---
src/components/OffsetOrder.tsx | 93 +++++++---------------------------
1 file changed, 18 insertions(+), 75 deletions(-)
diff --git a/src/components/OffsetOrder.tsx b/src/components/OffsetOrder.tsx
index bff8c37..bcc9466 100644
--- a/src/components/OffsetOrder.tsx
+++ b/src/components/OffsetOrder.tsx
@@ -1,9 +1,6 @@
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';
@@ -59,9 +56,6 @@ export function OffsetOrder({ tons, monetaryAmount, onBack, calculatorType }: Pr
company: '',
message: `I would like to offset ${tons.toFixed(2)} tons of CO2 from my yacht's ${calculatorType} emissions.`
});
-
- // lightbox state
- const [selectedProject, setSelectedProject] = useState(null);
useEffect(() => {
if (!config.wrenApiKey) {
@@ -72,18 +66,18 @@ 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]);
+ // 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 {
@@ -341,7 +335,6 @@ useEffect(() => {
{portfolio.projects && portfolio.projects.length > 0 && (
-<<<<<<< HEAD
{
transition={{ duration: 0.5, delay: 0.1 * index }}
whileHover={{ scale: 1.03 }}
whileTap={{ scale: 0.98 }}
- onClick={() => setSelectedProject(project)}
+ onClick={() => {
+ console.log('Project clicked:', project.name);
+ setSelectedProject(project);
+ }}
>
-=======
-
- {portfolio.projects.map((project) => (
-
setSelectedProject(project)}
- className="cursor-pointer bg-gray-50 rounded-lg p-4 hover:shadow-md transition-shadow"
->
->>>>>>> 96496350ee59fb2fd226eb340094130203514ab8
@@ -407,56 +394,12 @@ useEffect(() => {
)}
-<<<<<<< HEAD
-=======
- {/* lightbox modal */}
- {selectedProject && (
- setSelectedProject(null)}
- >
-
e.stopPropagation()}
- >
-
-
- {selectedProject.name}
-
- {selectedProject.imageUrl && (
-

- )}
-
- {selectedProject.description}
-
-
- Type:
- {selectedProject.type}
-
-
- Price per ton:
- ${selectedProject.pricePerTon.toFixed(2)}
-
-
-
- )}
-
->>>>>>> 96496350ee59fb2fd226eb340094130203514ab8
Portfolio Price per Ton:
{renderPortfolioPrice(portfolio)}
@@ -539,7 +482,7 @@ useEffect(() => {
{/* Modal Content */}
{
{/* Close Button */}