Skip to content

Building a Smart Vacation Optimizer: React, TypeScript & International Holidays

After years of manually planning vacations around holidays and trying to maximize time off, I decided to build a comprehensive solution: the Vacation Time Optimizer. This React-based application transforms vacation planning from a tedious manual process into an intelligent, data-driven experience.

The Challenge: Vacation Planning is Complex

Most people approach vacation planning by looking at a calendar and guessing which dates might give them the most bang for their buck. But optimal vacation planning involves:

  • Understanding your available vacation days
  • Identifying upcoming holidays in your region
  • Calculating efficiency ratios (total days off vs. vacation days used)
  • Visualizing different time periods (months, quarters, years)
  • Exporting plans to your calendar system

This complexity inspired me to build a tool that handles all these calculations automatically.

Technical Architecture

React 18 + TypeScript Foundation

The application is built on React 18 with TypeScript throughout, providing end-to-end type safety:

interface VacationPlan {
  startDate: string;
  endDate: string;
  vacationDaysUsed: number;
  totalDays: number;
  weekendDays: number;
  holidayDays: number;
  efficiency: number;
}

interface Holiday {
  date: string;
  name: string;
  type: 'government' | 'company';
}

Multi-View Calendar System

One of the most challenging aspects was building a flexible calendar system that automatically switches views based on vacation length:

// Auto-switch to appropriate view based on highlighted period
useEffect(() => {
  if (highlightedPeriod) {
    const start = highlightedPeriod.start;
    const end = highlightedPeriod.end;
    const daysDifference = Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));

    // If vacation spans more than 2 months, show year view
    if (start.getMonth() !== end.getMonth() && 
        (end.getMonth() - start.getMonth() > 1 || end.getFullYear() !== start.getFullYear())) {
      setCurrentView('year');
    }
    // If vacation spans 2 months or is longer than 2 weeks, show quarter view
    else if (start.getMonth() !== end.getMonth() || daysDifference > 14) {
      setCurrentView('quarter');
    }
    // Otherwise, month view is fine
    else {
      setCurrentView('month');
    }
  }
}, [highlightedPeriod]);

International Holiday Integration

Supporting multiple countries required building a comprehensive holiday database:

export const getCountryHolidays = (country: CountryCode): Holiday[] => {
  const holidayData = {
    'US': [
      { date: '2025-01-01', name: 'New Year\'s Day', type: 'government' as const },
      { date: '2025-01-20', name: 'Martin Luther King Jr. Day', type: 'government' as const },
      { date: '2025-02-17', name: 'Presidents\' Day', type: 'government' as const },
      // ... more holidays
    ],
    'CA': [
      { date: '2025-01-01', name: 'New Year\'s Day', type: 'government' as const },
      { date: '2025-02-17', name: 'Family Day', type: 'government' as const },
      // ... provincial variations
    ],
    // Support for UK, Germany, France, Japan, Australia
  };

  return holidayData[country] || [];
};

Smart Recommendation Engine

The heart of the application is the vacation optimization algorithm:

export const findOptimalVacationPeriods = (
  availableDays: number,
  holidays: Holiday[],
  year: number,
  targetDays: number = 7
): VacationPlan[] => {
  const recommendations: VacationPlan[] = [];

  // Look for periods around holidays
  holidays.forEach(holiday => {
    const holidayDate = parseDate(holiday.date);

    // Check periods before and after holidays
    for (let daysBefore = 0; daysBefore <= 4; daysBefore++) {
      for (let daysAfter = 0; daysAfter <= 4; daysAfter++) {
        const startDate = addDays(holidayDate, -daysBefore);
        const endDate = addDays(holidayDate, daysAfter);

        const plan = calculateVacationPlan(startDate, endDate, holidays);

        if (plan.vacationDaysUsed <= availableDays && 
            plan.totalDays >= targetDays) {
          recommendations.push(plan);
        }
      }
    }
  });

  // Sort by efficiency (total days / vacation days used)
  return recommendations
    .sort((a, b) => b.efficiency - a.efficiency)
    .slice(0, 10); // Top 10 recommendations
};

Calendar Export Integration

Modern vacation planning requires seamless integration with existing calendar systems:

export const generateGoogleCalendarUrl = (plan: VacationPlan): string => {
  const startDate = parseDate(plan.startDate);
  const endDate = parseDate(plan.endDate);

  const title = `Vacation - ${plan.totalDays} days off`;
  const details = `Optimized vacation using ${plan.vacationDaysUsed} vacation days for ${plan.totalDays} total days off. Efficiency: ${plan.efficiency.toFixed(1)}x`;

  const params = new URLSearchParams({
    action: 'TEMPLATE',
    text: title,
    details: details,
    dates: `${formatDateForCalendar(startDate)}/${formatDateForCalendar(endDate)}`,
    ctz: Intl.DateTimeFormat().resolvedOptions().timeZone
  });

  return `https://calendar.google.com/calendar/render?${params.toString()}`;
};

Mobile-First Design Philosophy

The application follows a progressive enhancement approach:

// Touch navigation for mobile
const TouchSwipe: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [touchStart, setTouchStart] = useState<number | null>(null);
  const [touchEnd, setTouchEnd] = useState<number | null>(null);

  const handleTouchStart = (e: React.TouchEvent) => {
    setTouchEnd(null);
    setTouchStart(e.targetTouches[0].clientX);
  };

  const handleTouchMove = (e: React.TouchEvent) => {
    setTouchEnd(e.targetTouches[0].clientX);
  };

  const handleTouchEnd = () => {
    if (!touchStart || !touchEnd) return;

    const distance = touchStart - touchEnd;
    const isLeftSwipe = distance > 50;
    const isRightSwipe = distance < -50;

    if (isLeftSwipe) {
      // Navigate to next month/quarter/year
    }
    if (isRightSwipe) {
      // Navigate to previous month/quarter/year
    }
  };

  return (
    <div
      onTouchStart={handleTouchStart}
      onTouchMove={handleTouchMove}
      onTouchEnd={handleTouchEnd}
    >
      {children}
    </div>
  );
};

Performance Optimizations

With complex calendar calculations and international holiday data, performance was crucial:

  1. Memoized Calculations: Heavy date calculations are memoized
  2. Efficient Rendering: Only visible calendar months are rendered
  3. Optimized Bundle: Tree-shaking and code splitting with Vite
  4. Strategic State Management: Minimal re-renders through careful state design

Accessibility & User Experience

The application prioritizes accessibility:

  • ARIA Labels: Complete screen reader support
  • Keyboard Navigation: Full functionality without mouse
  • Focus Management: Logical tab order throughout the interface
  • Color Contrast: High contrast mode for visual accessibility
  • Mobile Touch Targets: Large, touch-friendly interactive elements

Results & Impact

The Vacation Time Optimizer transforms a complex manual process into an intuitive, data-driven experience. Users can:

  • Save Hours of manual vacation planning
  • Maximize Time Off through efficiency scoring
  • Plan Internationally with built-in holiday support
  • Export Seamlessly to any calendar system
  • Access Anywhere through responsive design

Technical Lessons Learned

  1. Complex State Management: Managing multiple calendar views and vacation periods required careful state architecture
  2. International Considerations: Holiday systems vary significantly between countries
  3. Date Calculations: Working with dates across timezones and DST transitions is challenging
  4. Mobile Performance: Calendar rendering on mobile devices requires optimization
  5. User Experience: Auto-switching views based on vacation length greatly improves UX

Open Source & Future Plans

The project is open source under Apache License 2.0, encouraging community contributions. Future enhancements include:

  • Team vacation coordination features
  • Advanced analytics and reporting
  • PWA capabilities with offline support
  • Machine learning for personalized recommendations
  • Integration with HR systems

The Vacation Time Optimizer demonstrates how thoughtful application of modern web technologies can solve real-world problems while providing exceptional user experiences.


Check out the live application and contribute to the project on GitHub. Your next perfect vacation is just a few clicks away!