A modern web application for Sri Lankan tour and vehicle booking services built with Next.js 15, TypeScript, and Tailwind CSS.
- Vehicle Booking System with real-time pricing calculation
- Tour Package Management with detailed information
- Contact Form with dual email notifications (customer + business)
- Email Integration via SendGrid for confirmations
- Google Analytics tracking with comprehensive event monitoring
- Responsive Design optimized for all devices
- Supabase - Database (PostgreSQL) for tours, vehicles, and locations
- SendGrid - Email delivery service
- Google Analytics GA4 - Analytics and event tracking
- reCAPTCHA - Form spam protection
- Vercel Analytics - Performance monitoring
- Node.js 18+
- npm or yarn
- Supabase account
- SendGrid account
- Google Analytics property
- reCAPTCHA site keys
git clone <repository-url>
cd jnw
npm installCreate .env.local with the following variables:
# Database
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
# Email Service
SENDGRID_API_KEY=your_sendgrid_api_key
# Analytics
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX
# Security
NEXT_PUBLIC_RECAPTCHA_SITE_KEY=your_recaptcha_site_key
RECAPTCHA_SECRET_KEY=your_recaptcha_secret_key
# Admin Authentication
PASSWORD=your_admin_password
ADMIN_API_KEY=your_admin_api_keyFull containerized development environment with PostgreSQL database:
# Start all services (Next.js + PostgreSQL + pgAdmin)
npm run docker:dev
# Or using docker-compose directly
docker-compose up -d
# Stop services
docker-compose downDocker Services:
- Next.js Dev Server: http://localhost:3000
- PostgreSQL Database: localhost:5432
- pgAdmin: http://localhost:8080 (admin@jnw.com / admin)
Docker Environment:
- Database automatically initialized with schema and sample data
- No local database setup required
- Isolated development environment
For local development without Docker:
# Ensure PostgreSQL is running locally
# Update .env.local with local database URL:
# DATABASE_URL=postgresql://postgres:postgres@localhost:5432/jnw_tours
npm run devDatabase is automatically set up with:
- Schema initialization from
schema.sql - Sample data import from CSV files
- Health checks and automatic retries
Ensure your Supabase database has the following tables:
tours- Tour packages with detailsvehicles- Available vehicles with pricinglocations- Pickup/dropoff locations
- Create SendGrid account and get API key
- Verify sender email addresses
- Configure domain authentication (for production)
- Create GA4 property
- Add measurement ID to environment variables
- Configure data streams for your domains
# Docker (recommended)
npm run docker:dev
# Local
npm run devsrc/
βββ app/ # Next.js 15 app router
β βββ api/ # API routes
β β βββ admin/ # Admin-only endpoints (tours, vehicles, locations)
β β βββ auth/ # Authentication endpoints (password)
β β βββ bookings/ # Booking submissions
β β βββ contact/ # Contact form handler
β β βββ locations/ # Location data
β β βββ tours/ # Tour data
β βββ admin/ # Admin panel pages (password protected)
β βββ booking/ # Booking flow pages
β βββ contact/ # Contact page
β βββ tours/ # Tour pages
β βββ analytics-test/ # GA debugging tools
βββ components/ # React components
β βββ admin/ # Admin panel components
β βββ analytics/ # Google Analytics integration
β βββ booking/ # Booking-related components
β βββ contact/ # Contact form
β βββ home/ # Homepage components
β βββ layout/ # Layout components (Header, Footer)
β βββ shared/ # Shared components (Hero, PasswordGate, ErrorBoundary)
β βββ tours/ # Tour display components
β βββ ui/ # Reusable UI components
β β βββ Button.tsx # Button component with variants
β β βββ Input.tsx # Form input component
β β βββ Select.tsx # Dropdown select component
β β βββ Textarea.tsx # Textarea component
β β βββ ErrorMessage.tsx # Error message display
β β βββ SuccessMessage.tsx # Success message display
β β βββ NavLink.tsx # Navigation link component
β βββ vehicles/ # Vehicle display components
βββ constants/ # Static data and configurations
βββ hooks/ # Custom React hooks
β βββ useAdminCrud.ts # Admin CRUD operations hook
β βββ useRecaptcha.ts # reCAPTCHA integration hook
βββ utils/ # Utility functions
β βββ api.ts # Centralized fetch wrapper
β βββ auth.ts # Authentication utilities
β βββ config.ts # Configuration management
β βββ date.ts # Date parsing and calculation
β βββ db.ts # Database helpers (Supabase)
β βββ email.ts # Email templates and sending
β βββ format.ts # Data formatting utilities
β βββ image.ts # Image source handling
β βββ logger.ts # Logging utilities
β βββ passwordAuth.ts # Password authentication utilities
β βββ recaptcha.ts # reCAPTCHA validation
β βββ validation.ts # Form validation
βββ styles/ # Global styles
- VehicleSelection - Choose vehicle and view pricing
- BookingPageClient - Manage booking state
- FullBookingForm - Complete booking details with reCAPTCHA
- Email Confirmation - Automated SendGrid emails
- PasswordGate - Password authentication wrapper
- useAdminCrud Hook - Reusable CRUD operations for admin pages
- Admin Forms - Tour, Vehicle, and Location management
- Cookie-based Authentication - Secure admin access
- Button - Variants: primary, secondary, danger, outline, ghost
- Input - Form input with label and error support
- Select - Dropdown select component
- Textarea - Multi-line text input
- ErrorMessage/SuccessMessage - User feedback components
- NavLink - Consistent navigation links
- Dual Email System: Customer confirmation + Business notification
- reCAPTCHA Protection: Spam prevention via
useRecaptchahook - Tour Integration: Pre-select tours from links
- Page views and user interactions
- Booking funnel events
- Contact form submissions
- Vehicle interest tracking
- Next.js Font Optimization: Using
next/font/google - Inter: Primary sans-serif font
- Poppins: Display font for headings
- Automatic font subsetting and optimization
- Customer confirmation emails
- Business notification emails
- SendGrid integration with detailed logging
Visit /analytics-test for comprehensive GA debugging:
- Event testing tools
- Real-time data verification
- DataLayer inspection
- Console logging
- Development mode with enhanced logging
- Production optimizations
- Environment-specific configurations
booking_started- User begins booking processbooking_completed- Successful booking submissioncontact_form_submitted- Contact form submissionsvehicle_viewed- Vehicle detail views
- SendGrid message IDs for delivery tracking
- Success/failure logging
- Customer and business email confirmations
npm run build
vercel deployEnsure all environment variables are configured in your deployment platform.
- Update Google Analytics allowed domains
- Configure SendGrid domain authentication
- Update reCAPTCHA allowed domains
- Verify SendGrid API key and sender email
- Check spam folders for test emails
- Review SendGrid activity dashboard
- Use
/analytics-testdebug page - Check browser console for errors
- Verify GA measurement ID
- Ensure domain is allowed in GA property
- Verify Supabase credentials
- Check RLS policies if enabled
- Review database schema
- Follow TypeScript best practices
- Use modular component architecture
- Maintain comprehensive error handling
- Add tests for new features
- Update documentation for changes
Submit vehicle booking with customer details and send confirmation emails.
Process contact form submissions with dual email notifications.
Retrieve available tour packages.
Retrieve pickup/dropoff locations.
- Password-based authentication via
/api/auth/password - Cookie-based session management (
auth_tokencookie, 24-hour expiration) - API key fallback for programmatic access (
x-api-keyheader) - PasswordGate component protects all admin pages
- Admin API routes accept either password cookie OR API key header
- reCAPTCHA v3 protection on contact and booking forms
- Input validation and sanitization on all forms
- Server-side validation for all API endpoints
- Environment variable security
- HTTPS enforcement in production
- Rate limiting (recommended for production)
[Add your license information here]
Built with β€οΈ for JNW Lanka Tours