A fully dynamic, production-ready subscription cancellation flow with A/B testing, analytics, responsive design, and comprehensive configuration management.
- Exact Figma implementation - Pixel-perfect fidelity on mobile and desktop
- Complete interaction handling - All user interactions and state management
- Responsive design - Works seamlessly across all device sizes
- Deterministic testing - Consistent variant assignment per user
- Cryptographically secure - Uses
window.crypto.getRandomValues() - Local persistence - Variants stored in localStorage for consistency
- 50/50 split - Variant B offers $10 off ($25β$15, $29β$19)
- Mock implementation - Simple logging of cancellation data
- Required fields - user_id, downsell_variant, reason, accepted_downsell, created_at
- Subscription status - Mock pending_cancellation marking
- Input validation - Comprehensive sanitization and validation
- CSRF protection - Built-in CSRF token validation
- XSS protection - DOMPurify integration for content sanitization
- Rate limiting - Protection against brute force attacks
- Simple installation - npm install β npm run db:setup β npm run dev
- Mock data - Uses simple mock user and subscription data
- Stub implementations - Payment processing and other out-of-scope features as stubs
- Frontend: Next.js 15, React 19, TypeScript
- Styling: Tailwind CSS 4, CSS Modules
- Database: Supabase Cloud (PostgreSQL)
- Analytics: Google Analytics, Mixpanel, Custom
- Deployment: Vercel, Netlify, or any Node.js hosting
- Node.js 18+
- npm or yarn
- Supabase account (free tier available)
git clone <your-repo-url>
cd cancel-flow-task-main
npm installCreate a .env.local file in the root directory:
# Copy the example file
cp env.example .env.localEdit .env.local with your configuration:
# Supabase Configuration (Required)
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
# Application Configuration
NEXT_PUBLIC_APP_NAME=Migrate Mate
NEXT_PUBLIC_APP_VERSION=1.0.0
NEXT_PUBLIC_APP_ENV=development
# Feature Flags
NEXT_PUBLIC_ENABLE_AB_TESTING=true
NEXT_PUBLIC_ENABLE_ANALYTICS=true
NEXT_PUBLIC_ENABLE_FEEDBACK=true
# Pricing Configuration
NEXT_PUBLIC_DEFAULT_MONTHLY_PRICE=2500
NEXT_PUBLIC_DOWSELL_DISCOUNT_AMOUNT=1000
NEXT_PUBLIC_AB_TEST_SPLIT=0.5
# UI Configuration
NEXT_PUBLIC_PRIMARY_COLOR=#8952fc
NEXT_PUBLIC_SECONDARY_COLOR=#7b40fc
NEXT_PUBLIC_SUCCESS_COLOR=#10b981
NEXT_PUBLIC_ERROR_COLOR=#ef4444
# Analytics (Optional)
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID=your_ga_id
NEXT_PUBLIC_MIXPANEL_TOKEN=your_mixpanel_token- Go to your Supabase dashboard
- Copy your project URL and anon key
- Update
.env.localwith your credentials
- Go to supabase.com
- Create a new project
- Copy the project URL and anon key
- Update
.env.local
The database schema will be automatically created when you first run the app. If you need to manually set up the schema, you can run:
# For local development (optional)
npm run supabase:setup
# For production (using your Supabase cloud project)
# The schema will be created automatically when you first run the appnpm run devVisit http://localhost:3000 to see your application.
The application supports dynamic content through the configuration system:
// In src/lib/config.ts
cancellationReasons: [
{
id: 'too-expensive',
label: 'Too expensive',
requiresFeedback: false,
requiresAmount: true,
amountPlaceholder: '0.00'
},
// Add more reasons...
]offers: [
{
id: '50-percent-off',
label: 'Get 50% off',
discountPercentage: 50,
discountAmount: 1250,
description: 'Limited time offer',
isActive: true,
variant: 'both'
}
]- Variant A: Direct path to cancellation flow (no downsell)
- Variant B: Shows offer before cancellation flow
# 50/50 split (default)
NEXT_PUBLIC_AB_TEST_SPLIT=0.5
# 70/30 split (70% to variant A)
NEXT_PUBLIC_AB_TEST_SPLIT=0.7NEXT_PUBLIC_GOOGLE_ANALYTICS_ID=G-XXXXXXXXXXNEXT_PUBLIC_MIXPANEL_TOKEN=your_mixpanel_tokenThe application automatically adapts to different screen sizes:
- Mobile (< 768px): Full-screen modals, stacked layouts
- Tablet (768px - 1024px): Medium modals, side-by-side layouts
- Desktop (> 1024px): Large modals, optimal spacing
// In src/lib/responsive.ts
export const breakpoints = {
xs: '320px',
sm: '640px',
md: '768px',
lg: '1024px',
xl: '1280px',
'2xl': '1536px',
};- Connect your GitHub repository to Vercel
- Add environment variables in Vercel dashboard
- Deploy automatically on push
- Connect your repository to Netlify
- Add environment variables in Netlify dashboard
- Deploy automatically on push
npm run build
npm start- Variant A: Direct path to cancellation flow (no downsell)
- Variant B: Shows offer before cancellation flow
- Persistence: Uses localStorage for consistent variant assignment
- Security: Cryptographically secure random number generation
- User interactions logged to console for demonstration
- Cancellation data captured and logged with all required fields
- Payment processing handled via simple stub implementation
- Mock user used throughout the flow as required
src/
βββ app/ # Next.js app directory
βββ component/ # React components
β βββ css/ # CSS modules
β βββ tsx/ # TypeScript components
βββ lib/ # Utility libraries
β βββ config.ts # Configuration system
β βββ analytics.ts # Analytics system
β βββ responsive.ts # Responsive utilities
β βββ ab-testing.ts # A/B testing logic
β βββ database-operations.ts # Database operations
npm run dev # Start development server
npm run build # Build for production
npm run start # Start production server
npm run lint # Run ESLint
npm run supabase:setup # Setup local Supabase (optional)-
New Configuration Options
- Add to
src/lib/config.ts - Update environment variables
- Document in README
- Add to
-
New Components
- Create in
src/component/tsx/ - Add corresponding CSS module
- Update main flow in
01-MainEntry.tsx
- Create in
-
New Analytics Events
- Add to
src/lib/analytics.ts - Track in components
- Document in analytics section
- Add to
# Check environment variables
echo $NEXT_PUBLIC_SUPABASE_URL
echo $NEXT_PUBLIC_SUPABASE_ANON_KEY
# Verify Supabase project is active
# Check Row Level Security policies# Check feature flag
echo $NEXT_PUBLIC_ENABLE_AB_TESTING
# Verify database connection
# Check browser console for errors# Check feature flag
echo $NEXT_PUBLIC_ENABLE_ANALYTICS
# Verify analytics IDs are correct
# Check browser console for errorsEnable debug logging by setting:
NEXT_PUBLIC_APP_ENV=development- Tree-shaking enabled
- Dynamic imports for large components
- Optimized images and assets
- Lazy loading for non-critical components
- Preloading for critical resources
- Optimized CSS delivery
- Memoized components where appropriate
- Efficient state management
- Optimized re-renders
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
For support and questions:
- Create an issue in the repository
- Check the troubleshooting section
- Review the configuration guide
Built with β€οΈ using Next.js, React, and Supabase