142 Commits

Author SHA1 Message Date
Matt
1bf06a2a68 Add comprehensive server-side logging to QR code generation API
Some checks failed
Build and Push Docker Images / docker (push) Has been cancelled
2025-11-03 21:15:03 +01:00
Matt
4adb7b0101 Force rebuild: ensure QR system is in production image
All checks were successful
Build and Push Docker Images / docker (push) Successful in 23s
2025-11-03 21:13:05 +01:00
Matt
273388bad6 Fix custom calculator type: use monetary amount instead of CO₂ tons
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m29s
Critical fix: The 'custom' calculation type should represent monetary amount
(USD) to spend on carbon offsets, not tons of CO₂. The calculator converts
money to CO₂, not the other way around.

Changes:
- Update test page label from "Custom Amount (tons CO₂)" to "Custom Amount (USD)"
- Add helper text explaining calculator converts money to CO₂
- Update description function to show "$100 USD" instead of "100 tons CO₂"
- Change default/preset values to realistic dollar amounts ($50 default, $100 preset)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 21:00:14 +01:00
Matt
b93d054558 Improve QR test page: better error handling and de-emphasize vessel info
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m34s
- Enhanced error handling to show HTTP status codes (e.g., "HTTP 404: Not Found")
- Moved vessel information to collapsible section at bottom
- Clear vessel default values (was pre-filled with test data)
- Added note explaining vessel info is metadata only, not used in calculations
- Made vessel fields visually de-emphasized with gray text and optional labels
2025-11-03 19:47:31 +01:00
Matt
2c86863845 Fix TypeScript error in qrDataValidator - use issues instead of errors
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m19s
Zod v3 uses 'issues' property instead of 'errors' for ZodError.
This fixes the production build failure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 18:32:44 +01:00
Matt
09eb2d3781 Add comprehensive QR code system for carbon calculator
Some checks failed
Build and Push Docker Images / docker (push) Failing after 2m11s
Implements complete QR code generation and decoding system for pre-filling calculator data:

- Add qrcode npm dependency (v1.5.4) and zod validation (v3.24.1)
- Create QR generation API endpoint at /api/qr-code/generate
- Implement Base64 URL-safe encoding/decoding utilities
- Add Zod validation schemas for all calculator types (fuel, distance, custom)
- Create QRCalculatorLoader wrapper component with loading/error states
- Add useQRDecoder custom hooks for automatic URL parameter processing
- Modify TripCalculator to accept initialData prop for pre-filling
- Integrate QRCalculatorLoader into main App routing
- Create test page at /qr-test for API testing and QR code visualization
- Support all three calculator types with proper validation
- Include vessel information (name, IMO) in QR data
- Add 30-day expiration for generated QR codes
- Provide PNG and SVG download options in test interface

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 18:28:51 +01:00
Matt
4e08e649da Fix NocoDB PATCH API format and reduce Wren portfolio logging
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m27s
- Fix updateOrder() in nocodbClient.js to use NocoDB v2 API format
  (PATCH to base endpoint with Id in body, not in URL path)
- Remove verbose portfolio details logging from wrenClient.js
  (keep only summary: status, duration, portfolio count)

Resolves NocoDB fulfillment update error: Cannot PATCH .../records/3

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 16:54:04 +01:00
Matt
dc4506156c Improve NocoDB configuration logging with specific missing variables and success message
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m26s
2025-11-03 16:42:10 +01:00
Matt
dc4fc45c4f Add NocoDB integration for order management with comprehensive Stripe webhook logging
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m28s
Features:
- Complete NocoDB schema with 42 fields supporting B2B and B2C customers
- Server-side NocoDB client (REST API integration)
- Stripe session data mapper with automatic field mapping
- Enhanced webhook handler with comprehensive logging
- Automatic order creation in NocoDB after payment
- Fulfillment data updates with Wren order IDs
- Support for business customers (VAT/EIN, business names)
- Complete billing address capture
- Non-blocking error handling (webhook succeeds even if NocoDB fails)

Files Added:
- server/utils/nocodbClient.js - NocoDB REST API client
- server/utils/nocodbMapper.js - Stripe to NocoDB data mapper
- docs/NOCODB_SCHEMA.md - Complete field reference (42 columns)
- docs/NOCODB_INTEGRATION_GUIDE.md - Testing and deployment guide
- docs/TESTING_STRIPE_WEBHOOK.md - Webhook testing instructions
- docs/STRIPE_INTEGRATION_SUMMARY.md - Project overview

Files Modified:
- server/routes/webhooks.js - Added NocoDB integration and enhanced logging
- src/types.ts - Updated OrderRecord interface with new fields
- src/api/nocodbClient.ts - Added createOrder() method
- .env.example - Added NocoDB configuration template

Schema includes:
- Payment tracking (Stripe session/intent/customer IDs, amounts, fees)
- Carbon offset details (tons, portfolio, Wren order ID)
- Customer information (name, email, phone, business name)
- Tax ID collection (VAT, EIN, etc.)
- Complete billing address
- Optional vessel/trip details for yacht calculations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 16:35:15 +01:00
Matt
94f422e540 Remove invalid size prop from RechartsPortfolioPieChart component
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m27s
Fixed TypeScript error where size prop was being passed to RechartsPortfolioPieChart
but the component only accepts projects and totalTons props. The component is
responsive by default and doesn't need a size parameter.

This resolves the Docker build error:
Property 'size' does not exist on type 'IntrinsicAttributes & RechartsPortfolioPieChartProps'

Verified with tsc --noEmit that no other TypeScript errors exist.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 15:49:49 +01:00
Matt
7faeb9b3f0 Fix TypeScript type error in demo page - change project IDs from number to string
Some checks failed
Build and Push Docker Images / docker (push) Failing after 2m8s
Changed all project IDs in mock data from numeric type (1, 2, 3, 4) to string type ('1', '2', '3', '4') to match the OffsetProject interface which expects string IDs.

This resolves the Docker build error:
Type 'number' is not assignable to type 'string' at line 312

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 15:45:34 +01:00
Matt
b4e155778d Fix Tailwind configuration and optimize print layout for checkout success page
Some checks failed
Build and Push Docker Images / docker (push) Failing after 2m14s
- Add emerald and cyan to Tailwind safelist pattern to fix gradient rendering
- Include app/ and components/ directories in Tailwind content paths
- Optimize print layout with compressed spacing, margins, and fonts
- Reduce page margins from 0.5in to 0.3in for better content fit
- All content now fits on single printed page without cutoff

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 15:41:51 +01:00
Matt
9aa4dd7a68 Add demo page for checkout success comparison
Some checks failed
Build and Push Docker Images / docker (push) Failing after 2m9s
- Create /checkout/success/demo route with mock data
- Hardcoded order details for visual testing
- Same styling as real success page
- Yellow banner indicates demo mode

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 15:16:30 +01:00
Matt
372e4ae33e Fix checkout success page styling to match old Vite version
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m20s
- Change header gradient from cyan-400/blue-400 to cyan-500/blue-500/indigo-600 (vibrant 3-color gradient)
- Exclude /checkout/success from RootLayoutClient wrapper for fullscreen layout
- Update color scheme throughout: gray → slate, green → blue/cyan/emerald
- Add floating success badge below header
- Add gradient backgrounds to offset sections
- Update button styles with gradients and transform effects

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 15:05:11 +01:00
Matt
baa2849352 Restore old project color scheme for checkout success page
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m21s
- Replace all blue/cyan gradients with clean white/gray backgrounds
- Change all slate colors to gray (gray-50, gray-600, gray-700, gray-800)
- Change all buttons and accents to green-500/600
- Simplify header to white background with gray border
- Remove fancy gradients and shadows for clean, simple design
- Match exact color scheme from original Vite project
2025-11-03 14:32:58 +01:00
Matt
fe0c1c182f Restore project/ folder for comparison reference
- Restored legacy Vite application folder from git history
- Needed for comparing old vs new Next.js implementation
- Contains original component implementations and utilities
2025-11-03 14:23:42 +01:00
Matt
15ab551f11 Consolidate environment configuration and remove legacy files
- Merged admin auth variables from root .env into .env.local
- Added NocoDB credentials to server/.env for backend webhook integration
- Deleted legacy root .env file (superseded by .env.local)
- Deleted legacy project/ folder (old Vite app before Next.js migration)

Result: Clean 2-file .env structure:
- .env.local: Next.js frontend + API routes + admin auth
- server/.env: Express backend + Stripe webhooks + NocoDB

.env.local, server/.env
2025-11-03 14:17:04 +01:00
Matt
e9b79531e1 Add comprehensive webhook payload logging for customer data extraction
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m20s
- Log full Stripe webhook JSON payload for debugging
- Extract and log customer name, address, and metadata
- Makes it easy to see business names and custom fields in logs
- Helps identify available data for future enhancements

server/routes/webhooks.js:32-36, 101-109
2025-11-03 14:08:19 +01:00
Matt
039ddc0fa8 Fix admin email to display correct payment amount
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m18s
- Admin notification was showing 6 instead of 600
- Root cause: double cents-to-dollars conversion
- webhooks.js already converts to dollars before calling sendAdminNotification
- Updated sendAdminNotification to handle pre-converted dollar amounts
- Simplified formatting logic for clarity

server/utils/emailService.js:155-162
2025-11-03 13:47:03 +01:00
Matt
e11d04e1bc Restore old color scheme for checkout success page
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m19s
- Changed header gradient from darker cyan-blue-indigo to brighter cyan-blue
- Matches original design with more vibrant teal/cyan colors
- Updated from-cyan-500 via-blue-500 to-indigo-600 → from-cyan-400 to-blue-400

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 13:39:03 +01:00
Matt
6e2b841d9e Fix API routes 404 - Remove incorrect .next/server copy
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m12s
The previous fix incorrectly copied .next/server which conflicts
with Next.js standalone mode. Standalone is self-contained and
already includes compiled API routes internally.

Root cause: Next.js output:'standalone' creates a self-contained
.next/standalone directory that already contains all compiled API
routes. Copying .next/server separately creates path conflicts that
break the server's route resolution.

Official Next.js standalone pattern only requires copying:
- .next/standalone (contains server.js and routes)
- .next/static (static assets)
- public (public files)

Fixes: API routes returning 404 in production
2025-11-03 13:12:15 +01:00
Matt
b8bb0c8ae3 Fix Docker API routes 404 - Add .next/server copy
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m20s
Next.js 16 with standalone output creates two separate directories:
- .next/standalone (server infrastructure)
- .next/server (compiled App Router routes)

Previous Dockerfile only copied standalone, causing all /api/*
routes to return 404 in production. This adds the missing copy
command to include compiled API route handlers.

Fixes: /api/wren/portfolios returning 404 after deployment
2025-11-03 12:36:57 +01:00
Matt
5680dfa65f Remove client-side Wren API key validation
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m30s
The config.ts file was still checking for NEXT_PUBLIC_WREN_API_TOKEN
which no longer exists after moving to server-side proxy routes.

Changes:
- Remove all client-side environment variable checks
- Set wrenApiKey to dummy value 'server-proxy'
- Add comments explaining API key is server-side only
- Remove error logging for missing client-side key

This fixes the console error: "Missing required environment variable: NEXT_PUBLIC_WREN_API_TOKEN"
2025-11-03 12:23:46 +01:00
Matt
7751976fc9 Fix all remaining TypeScript build errors
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m28s
- Import and use OffsetOrderSource type in wrenClient.ts
- Fix Recharts PieChart label rendering with proper props
- Remove unused POST body parameter in orders route

All TypeScript errors now resolved, build succeeds.
2025-11-03 12:02:05 +01:00
Matt
10b277b853 Fix Next.js 16 async params in dynamic route
Some checks failed
Build and Push Docker Images / docker (push) Failing after 2m11s
Next.js 16 breaking change: route params are now Promises
- Updated GET, PATCH, DELETE handlers to await params
- Changed signature from { params: { id: string } }
  to { params: Promise<{ id: string }> }
- Extract id with: const { id } = await params;
2025-11-03 11:07:44 +01:00
Matt
cfa7e88ed2 Remove all build-time variables and secure Wren API
Some checks failed
Build and Push Docker Images / docker (push) Failing after 2m20s
BREAKING CHANGE: All environment variables are now runtime-configurable

Changes:
- Removed ALL build-time NEXT_PUBLIC_* variables from Dockerfile and CI/CD
- Created server-side proxy routes for Wren API (/api/wren/*)
- Refactored wrenClient.ts to use proxy endpoints (reduced from 400+ to 200 lines)
- Updated checkoutClient.ts and emailClient.ts to remove NEXT_PUBLIC_ fallbacks
- Hardcoded metadataBase in layout.tsx (no longer depends on env var)
- Updated .env.local to use runtime-only variables (WREN_API_TOKEN, NocoDB config)

Security improvements:
- Wren API token never exposed to browser
- All secrets stay server-side
- No sensitive data baked into build

Configuration:
- Wren API: Set WREN_API_TOKEN in docker-compose or .env
- NocoDB: Set NOCODB_* variables in docker-compose or .env
- No Gitea secrets/variables needed for build (only registry credentials)

Docker build is now truly environment-agnostic - same image works in
any environment with different runtime configuration.
2025-11-03 11:03:42 +01:00
Matt
c08c46aa6c Fix nocodbClient import path - move to root api/ directory
Some checks failed
Build and Push Docker Images / docker (push) Failing after 2m2s
- Created api/ directory at project root
- Copied nocodbClient.ts from src/api/ to api/
- Resolves build error: Module not found @/api/nocodbClient
- Aligns with Next.js app router structure (@/ alias points to root)
2025-11-03 10:55:40 +01:00
Matt
bfb163c21a Remove Formspree and secure Wren API token
Some checks failed
Build and Push Docker Images / docker (push) Failing after 1m54s
Security & Cleanup Changes:
1. Removed NEXT_PUBLIC_WREN_API_TOKEN from frontend (security risk)
2. Removed Formspree references (no longer needed)
3. Wren API token now lives in backend only (runtime configurable)
4. Added NocoDB env vars to frontend for admin portal server-side API

Changes:
- Dockerfile: Removed Formspree and NEXT_PUBLIC_WREN_API_TOKEN build args
- CI/CD: Updated build-args to only include necessary variables
- Frontend should call backend /api/wren/* endpoints
- Backend handles Wren API with WREN_API_TOKEN (can change anytime!)

Benefits:
 API token no longer exposed in browser
 Can change Wren token without rebuilding images
 Cleaner build process
 Removed unused Formspree dependencies

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 10:50:33 +01:00
Matt
bfe5897232 Fix NEXT_PUBLIC environment variables for production builds
Some checks failed
Build and Push Docker Images / docker (push) Failing after 1m56s
Problem:
- NEXT_PUBLIC_* variables must be baked into Next.js build at BUILD TIME
- Setting them in docker-compose is too late (bundle already built)
- This caused "NEXT_PUBLIC_WREN_API_TOKEN is undefined" errors in production

Solution:
1. Updated Dockerfile to accept ARG values for all NEXT_PUBLIC_* variables
2. Set ARGs as ENV variables before npm run build (lines 15-26)
3. Updated CI/CD workflow to pass build-args from Gitea secrets/vars
4. Variables are now baked into the image during build

Next Steps:
1. Add these secrets to Gitea repository settings:
   - NEXT_PUBLIC_WREN_API_TOKEN
   - NEXT_PUBLIC_FORMSPREE_CONTACT_ID
   - NEXT_PUBLIC_FORMSPREE_OFFSET_ID
   - NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY

2. Add this variable to Gitea repository settings:
   - NEXT_PUBLIC_API_BASE_URL

3. Next push will build image with variables baked in
4. Can simplify docker-compose (remove NEXT_PUBLIC_* from web service)

Files Changed:
- Dockerfile: Added ARG and ENV declarations before build step
- .gitea/workflows/build-deploy.yml: Added build-args to frontend image build

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 10:47:27 +01:00
Matt
a6484de35e Integrate NocoDB backend for admin portal with real data
Some checks failed
Build and Push Docker Images / docker (push) Failing after 1m57s
Phase 2 Backend Integration Complete:

Backend Infrastructure:
- Created NocoDB client abstraction layer (src/api/nocodbClient.ts)
- Clean TypeScript API hiding NocoDB query syntax complexity
- Helper methods for orders, stats, search, timeline, and filtering
- Automatic date range handling and pagination support

API Routes:
- POST /api/admin/stats - Dashboard statistics with time range filtering
- GET /api/admin/orders - List orders with search, filter, sort, pagination
- GET /api/admin/orders/[id] - Single order details
- PATCH /api/admin/orders/[id] - Update order fields
- DELETE /api/admin/orders/[id] - Cancel order (soft delete)
- GET /api/admin/orders/export - CSV/Excel export with filters

Dashboard Updates:
- Real-time data fetching from NocoDB
- Time range selector (7d, 30d, 90d, all time)
- Recharts line chart for orders timeline
- Recharts pie chart for status distribution
- Loading states and error handling
- Dynamic stat cards with real numbers

Dependencies Added:
- papaparse - CSV export
- xlsx - Excel export with styling
- @types/papaparse - TypeScript support

Data Types:
- OrderRecord interface for NocoDB data structure
- DashboardStats, TimelineData, OrderFilters interfaces
- Full type safety across API and UI

Environment Configuration:
- NOCODB_BASE_URL, NOCODB_BASE_ID configured
- NOCODB_API_KEY, NOCODB_ORDERS_TABLE_ID configured
- All credentials stored securely in .env.local

Ready for testing with sample data in NocoDB!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 10:40:25 +01:00
Matt
1e4461cf43 Refine login page color scheme for elegant professional aesthetic
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m17s
🎨 Color harmony improvements for better visual balance:

## Changes Made
- **Icons**: User/Lock icons changed from bright maritime-teal to subdued deep-sea-blue/60
- **Input Focus**: Focus rings changed from bright teal to elegant deep-sea-blue/50
- **Sign In Button**: Simplified from teal-green gradient to solid deep-sea-blue
- **Error Messages**: More subdued red-900/30 background for better harmony

## Result
- More cohesive professional appearance
- Better contrast balance against Monaco harbor background
- Elegant, understated design that doesn't compete with background
- WCAG AA compliant contrast ratios maintained

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 09:41:02 +01:00
Matt
683a65c1fd Implement Modern Maritime admin panel design with Monaco background
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m15s
🎨 Complete UI redesign of admin panel with professional color scheme:

## New Modern Maritime Color Palette
- Deep Sea Blue (#1D2939) - Sidebar background
- Sail White (#F8F9FA) - Main background
- Maritime Teal (#008B8B) - Primary accent
- Sea Green (#1E8449) - Success/environmental theme
- Muted Gold (#D68910) - Revenue highlights
- Royal Purple (#884EA0) - Brand accent
- Off-White (#EAECEF) - Text on dark backgrounds

## Admin Panel Features
-  JWT-based authentication system
-  Protected routes with middleware
-  Elegant sidebar navigation with Puffin logo
-  Dashboard with stat cards (Orders, CO₂, Revenue, Fulfillment)
-  Monaco harbor image background on login page
-  Responsive glassmorphism design
-  WCAG AA contrast compliance

## New Files
- app/admin/ - Admin pages (login, dashboard, orders)
- app/api/admin/ - Auth API routes (login, logout, verify)
- components/admin/ - AdminSidebar component
- lib/auth.ts - JWT authentication utilities
- public/monaco_high_res.jpg - Luxury background image

## Updated
- tailwind.config.js - Custom maritime color palette
- package.json - Added jsonwebtoken dependency
- app/layout.tsx - RootLayoutClient integration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 09:35:43 +01:00
Matt
6b12e2ae2a Fix header spacing and homepage centering issues
All checks were successful
Build and Push Docker Images / docker (push) Successful in 2m12s
- Changed layout padding from Tailwind pt-48 to inline style paddingTop: 110px for reliable CSS specificity
- Added negative margin to homepage hero section to maintain vertical centering
- Updated client components (About, Contact, HowItWorks) from py-12 to pb-12 for proper spacing
- All pages now have proper header clearance without content cutoff

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 19:13:15 +01:00
Matt
fdffb62220 Remove unused imports and code from project/src/App.tsx
Some checks failed
Build and Push Docker Images / docker (push) Failing after 2m4s
Removed unused imports and state variables that were causing TypeScript build errors:
- Removed YachtSearch import (not used)
- Removed calculateTripCarbon import (not used)
- Removed getVesselData import (only used in unused handleSearch)
- Removed CarbonCalculation type import (not used)
- Removed unused state variables: loading, error, vesselData
- Removed unused handleSearch function

This fixes the Docker build failure: 'YachtSearch' is declared but its value is never read.
2025-11-02 13:03:35 +01:00
Matt
98e5b5e633 Fix unused React imports in project/src directory
Some checks failed
Build and Push Docker Images / docker (push) Failing after 2m0s
Remove unused 'React' imports from App.tsx and all component files in project/src/components/. These imports are not needed with the modern JSX transform and were causing TypeScript build errors in strict mode.

Files updated:
- project/src/App.tsx
- project/src/components/About.tsx
- project/src/components/CarbonOffset.tsx
- project/src/components/Contact.tsx
- project/src/components/CurrencySelect.tsx
- project/src/components/ErrorBoundary.tsx
- project/src/components/Home.tsx
- project/src/components/HowItWorks.tsx
- project/src/components/OffsetOrder.tsx
- project/src/components/PuffinAdvantage.tsx
- project/src/components/TripCalculator.tsx
- project/src/components/YachtSearch.tsx

This fixes the Docker build failure caused by TypeScript strict mode detecting unused variables.
2025-10-31 22:30:37 +01:00
Matt
82f72941ca Migrate from Vite to Next.js 16 with Turbopack
Some checks failed
Build and Push Docker Images / docker (push) Failing after 1m58s
This is a major migration from Vite to Next.js 16.0.1 for improved
performance, better SEO, and modern React features.

## Next.js Migration Changes
- Upgraded to Next.js 16.0.1 with Turbopack (from Vite 6)
- Migrated from client-side routing to App Router architecture
- Created app/ directory with Next.js page structure
- Added server components and client components pattern
- Configured standalone Docker builds for production

## Bug Fixes - React Hooks
- Fixed infinite loop in Header.tsx scroll behavior (removed lastScrollY state dependency)
- Fixed infinite loop in useCalculatorState.ts (wrapped saveState/clearState in useCallback)
- Fixed infinite loop in OffsetOrder.tsx (removed savedState from useEffect dependencies)
- Removed unused React imports from all client components

## Environment Variable Migration
- Migrated all VITE_ variables to NEXT_PUBLIC_ prefix
- Updated src/utils/config.ts to use direct static references (required for Next.js)
- Updated src/api/checkoutClient.ts, emailClient.ts, aisClient.ts for Next.js env vars
- Updated src/vite-env.d.ts types for Next.js environment
- Maintained backward compatibility with Docker window.env

## Layout & UX Improvements
- Fixed footer to always stay at bottom of viewport using flexbox
- Updated app/layout.tsx with flex-1 main content area
- Preserved glass morphism effects and luxury styling

## TypeScript & Build
- Fixed TypeScript strict mode compilation errors
- Removed unused imports and variables
- Fixed Axios interceptor types in project/src/api/wrenClient.ts
- Production build verified and passing

## Testing & Verification
- Tested calculator end-to-end in Playwright
- Verified Wren API integration working (11 portfolios fetched)
- Confirmed calculation: 5000L → 13.47 tons CO₂ → $3,206 total
- All navigation routes working correctly
- Footer positioning verified across all pages

## Files Added
- app/ directory with Next.js routes
- components/ directory with client components
- next.config.mjs, next-env.d.ts
- ENV_MIGRATION.md, NEXTJS_MIGRATION_COMPLETE.md documentation

## Files Modified
- Docker configuration for Next.js standalone builds
- package.json dependencies (Next.js, React 19)
- ts config.json for Next.js
- All API clients for new env var pattern

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 22:23:45 +01:00
Matt
55384b337b Make email receipt sections more compact
All checks were successful
Build and Push Docker Images / docker (push) Successful in 1m0s
Carbon Offset Distribution section:
- Remove "Carbon Offset" subheader from each project
- Remove colored dots next to project names
- Reduce padding from 30px to 20px
- Reduce title margin from 24px to 16px
- Reduce item padding from 14px to 10px
- Reduce spacing between items from 12px to 8px

Your Impact section:
- Reduce padding from 32px to 20px
- Reduce title font size from 26px to 22px
- Reduce subtitle margin from 28px to 16px
- Reduce card padding from 20px to 14px
- Reduce icon size from 36px to 30px
- Reduce value font size from 28px to 24px
- Reduce grid gap from 16px to 12px
- Reduce footer note margin from 20px to 12px

Overall more compact layout while maintaining readability.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 21:08:45 +01:00
Matt
0b66378423 Update admin email to matt@puffinoffset.com
All checks were successful
Build and Push Docker Images / docker (push) Successful in 58s
- Update default admin email from admin@ to matt@puffinoffset.com
- Add ADMIN_EMAIL environment variable to docker-compose.yml
- Add complete Email Configuration section to .env.example
- Admin email receives contact form submissions and order notifications

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 21:01:57 +01:00
Matt
a23cdfe396 Remove Portfolio line from receipts
All checks were successful
Build and Push Docker Images / docker (push) Successful in 1m1s
Remove portfolio ID display from both:
- Email receipt template (receipt.hbs)
- Digital receipt page (CheckoutSuccess.tsx)

Portfolio information is internal and not needed in customer-facing receipts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 20:57:52 +01:00
Matt
977ecb6d38 Fix confirmation email display issues
All checks were successful
Build and Push Docker Images / docker (push) Successful in 1m5s
- Remove escaped dollar signs in currency displays
- Fix percentage calculations (multiply decimal by 100)
- Force white text color on mobile for "Your Impact" header
- Add comma formatting to currency values (16343.46 → 16,343.46)
- Update portfolioColors.js to properly convert Wren API decimal percentages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 20:53:04 +01:00
Matt
470101a2d1 Add SMTP environment variables to backend Docker container
All checks were successful
Build and Push Docker Images / docker (push) Successful in 23s
Fix for "Missing credentials for PLAIN" error when sending emails.
The backend container was missing SMTP configuration environment
variables, causing nodemailer authentication to fail.

Added SMTP variables to docker-compose.yml:
- SMTP_HOST, SMTP_PORT, SMTP_SECURE
- SMTP_USER, SMTP_PASSWORD
- SMTP_FROM_NAME, SMTP_FROM_EMAIL

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 20:40:07 +01:00
Matt
37d861f9eb Migrate frontend contact forms from Formspree to SMTP backend
All checks were successful
Build and Push Docker Images / docker (push) Successful in 3m16s
- Replace Formspree integration with new backend email API
- Update Contact, OffsetOrder, and MobileOffsetOrder components
- Remove Formspree config from environment variables
- Add emailClient API for backend communication
- Centralize email sending through SMTP service

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 20:17:37 +01:00
Matt
7bdd462be9 Implement comprehensive email templates with SMTP integration
Some checks failed
Build and Push Docker Images / docker (push) Has been cancelled
- Add beautiful HTML email templates for receipts, admin notifications, and contact forms
- Implement SMTP email service with Nodemailer and Handlebars templating
- Add carbon equivalency calculations with EPA/DEFRA/IMO 2024 conversion factors
- Add portfolio color palette system for project visualization
- Integrate Wren API portfolio fetching in webhook handler
- Add light mode enforcement for email client compatibility
- Include Puffin logo from MinIO S3 in all templates
- Add test email endpoint for template validation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 20:09:31 +01:00
Matt
d40b1a6853 Replace carbon offset icon with Lucide Leaf icon
All checks were successful
Build and Push Docker Images / docker (push) Successful in 1m7s
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 19:02:10 +01:00
Matt
eca244e160 Compress print layout to fit all order info on page 1
All checks were successful
Build and Push Docker Images / docker (push) Successful in 1m1s
- Implement aggressive spacing compression (padding: 0.5rem, margins: 0.25rem)
- Reduce all font sizes by 10-25% for better vertical fit
- Compress line-height to 1.3 for tighter spacing
- Add print-color-adjust: exact to force gradients and colors to print
- Optimize logo, grid gaps, and section spacing
- Keep ALL gradient backgrounds and colorful styling

Result: Payment ID, Status, Email, Date now fit on page 1 with beautiful colors

Based on comprehensive Zen analysis of print layout optimization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 18:57:55 +01:00
Matt
6617f06987 Preserve colorful styling in print while fixing layout
All checks were successful
Build and Push Docker Images / docker (push) Successful in 1m7s
- Remove aggressive black/white print styling
- Keep original gradients, colors, and visual design
- Maintain layout optimizations (spacing, sizing, page breaks)
- Update portfolio table with colorful gradient header
- Fix label overlap by showing styled table in print
- Optimize spacing and font sizes for better page fit

Result: Beautiful colored receipt that fits properly on pages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 18:46:27 +01:00
Matt
109f350ee8 Implement comprehensive print optimization for receipt page
All checks were successful
Build and Push Docker Images / docker (push) Successful in 57s
- Replace pie chart with print-optimized table to eliminate label overlap
- Add extensive @media print CSS for high-contrast, professional output
- Convert all gradients to white backgrounds with black borders
- Optimize spacing and font sizes for print media
- Update CarbonImpactComparison with high-contrast print styling
- Ensure full page width utilization and proper page breaks
- Zero new dependencies (Pure CSS approach per consensus)

Resolves print quality issues: label collision, poor contrast, wasted whitespace

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 18:37:27 +01:00
Matt
f0337101cf Show project name and percentage on same line in pie chart
All checks were successful
Build and Push Docker Images / docker (push) Successful in 58s
- Combine project name and percentage into single label line
- Format: "Project Name (25.0%)"
- Reduces vertical space and improves readability
- Cleaner, more compact label design

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 18:10:41 +01:00
Matt
3273d4af2a Make receipt page responsive and add print page breaks
All checks were successful
Build and Push Docker Images / docker (push) Successful in 58s
- Increase max width from max-w-3xl to max-w-4xl/5xl for better screen fit
- Add responsive breakpoints: full width on mobile, constrained on larger screens
- Add print-page-break class for automatic page breaks between sections
- Each major section now prints on separate page:
  - Page 1: Order summary with payment details
  - Page 2: Portfolio distribution chart
  - Page 3: Carbon impact comparisons
- Improve print styling: remove shadows, borders, rounded corners
- Set print page size to standard letter format
- Reduce padding on mobile for better space utilization

Fixes receipt layout to be responsive on all screen sizes while
maintaining excellent print quality with proper page breaks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 18:06:23 +01:00
Matt
69e1465f69 Remove tonnage from pie chart labels for cleaner display
All checks were successful
Build and Push Docker Images / docker (push) Successful in 58s
- Remove middle tonnage line from chart labels
- Keep only project name and percentage
- Tonnage still visible in legend below chart
- Reduces label clutter and improves readability

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 18:01:27 +01:00