All checks were successful
Build and Push Docker Image / docker (push) Successful in 42s
## Stripe Payment Integration - Add Express.js backend server with Stripe Checkout Sessions - Create SQLite database for order tracking - Implement Stripe webhook handlers for payment events - Integrate with Wren Climate API for carbon offset fulfillment - Add CheckoutSuccess and CheckoutCancel pages - Create checkout API client for frontend - Update OffsetOrder component to redirect to Stripe Checkout - Add processing fee calculation (3% of base amount) - Implement order status tracking (pending → paid → fulfilled) Backend (server/): - Express server with CORS and middleware - SQLite database with Order schema - Stripe configuration and client - Order CRUD operations model - Checkout session creation endpoint - Webhook handler for payment confirmation - Wren API client for offset fulfillment Frontend: - CheckoutSuccess page with order details display - CheckoutCancel page with retry encouragement - Updated OffsetOrder to use Stripe checkout flow - Added checkout routes to App.tsx - TypeScript interfaces for checkout flow ## Visual & UX Enhancements - Add CertificationBadge component for project verification status - Create PortfolioDonutChart for visual portfolio allocation - Implement RadialProgress for percentage displays - Add reusable form components (FormInput, FormTextarea, FormSelect, FormFieldWrapper) - Refactor OffsetOrder with improved layout and animations - Add offset percentage slider with visual feedback - Enhance MobileOffsetOrder with better responsive design - Improve TripCalculator with cleaner UI structure - Update CurrencySelect with better styling - Add portfolio distribution visualization - Enhance project cards with hover effects and animations - Improve color palette and gradient usage throughout ## Configuration - Add VITE_API_BASE_URL environment variable - Create backend .env.example template - Update frontend .env.example with API URL - Add Stripe documentation references 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
95 lines
2.0 KiB
JavaScript
95 lines
2.0 KiB
JavaScript
/** @type {import('tailwindcss').Config} */
|
|
export default {
|
|
content: [
|
|
'./index.html',
|
|
'./src/**/*.{js,ts,jsx,tsx}',
|
|
],
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
'puffin-blue': {
|
|
DEFAULT: '#005A9C',
|
|
light: '#E6F0F6',
|
|
focus: '#3B82F6',
|
|
},
|
|
'puffin-gray': {
|
|
label: '#6B7280',
|
|
border: '#D1D5DB',
|
|
disabled: '#F3F4F6',
|
|
},
|
|
'puffin-error': {
|
|
DEFAULT: '#EF4444',
|
|
focus: '#F87171',
|
|
},
|
|
},
|
|
boxShadow: {
|
|
'focus-blue': '0 0 0 3px rgba(59, 130, 246, 0.3)',
|
|
'focus-red': '0 0 0 3px rgba(239, 68, 68, 0.3)',
|
|
},
|
|
},
|
|
},
|
|
plugins: [],
|
|
safelist: [
|
|
// Colors
|
|
{
|
|
pattern: /^(bg|text|border|hover:bg|hover:text)-(blue|gray|green|red|purple|teal|orange|indigo)-(50|100|200|300|400|500|600|700|800|900)/,
|
|
},
|
|
// Spacing
|
|
{
|
|
pattern: /^(p|px|py|m|mx|my|mt|mb|ml|mr)-[0-9]+/,
|
|
},
|
|
// Sizing
|
|
{
|
|
pattern: /^(w|h)-[0-9]+/,
|
|
},
|
|
// Layout
|
|
{
|
|
pattern: /^(min-h|max-w|aspect)-/,
|
|
},
|
|
// Grid
|
|
{
|
|
pattern: /^(grid-cols|gap)-/,
|
|
},
|
|
// Flexbox
|
|
{
|
|
pattern: /^(flex|items|justify|space|rounded|shadow)/,
|
|
},
|
|
// Transitions
|
|
'transform',
|
|
'transition-colors',
|
|
'transition-transform',
|
|
'duration-300',
|
|
'hover:scale-105',
|
|
// Interactivity
|
|
'cursor-pointer',
|
|
'cursor-not-allowed',
|
|
'disabled:opacity-50',
|
|
'disabled:hover:text-gray-600',
|
|
// Typography
|
|
'font-semibold',
|
|
'font-bold',
|
|
'text-center',
|
|
'text-left',
|
|
// Position
|
|
'relative',
|
|
'absolute',
|
|
'fixed',
|
|
'inset-0',
|
|
// Display
|
|
'object-cover',
|
|
'overflow-hidden',
|
|
'drop-shadow-lg',
|
|
// Animation
|
|
'animate-spin',
|
|
// Focus
|
|
'focus:ring',
|
|
'focus:ring-blue-500',
|
|
'focus:border-blue-500',
|
|
'focus:ring-opacity-50',
|
|
'focus:outline-none',
|
|
// Forms
|
|
'form-input',
|
|
'form-select',
|
|
'form-textarea'
|
|
]
|
|
}; |