Skip to main content
The service hours system allows you to configure operating hours, set closed dates, and control when customers can place orders through the platform.

Configuration

Service hours are configured in src/config/serviceHours.js:
src/config/serviceHours.js
export const DEFAULT_SERVICE_HOURS = {
  // Service start time (24-hour format)
  startHour: 8,
  startMinute: 30,
  
  // Service end time (24-hour format)
  endHour: 20,
  endMinute: 30,
  
  // Weekday service enabled (Monday-Friday)
  weekdaysEnabled: true,
  
  // Weekend service enabled (Saturday-Sunday)
  weekendsEnabled: true,
  
  // Special closed dates (YYYY-MM-DD format)
  closedDates: [
    // Example: '2024-01-01', // New Year
    // Example: '2024-12-25', // Christmas
  ],
  
  // Test mode (if true, always open)
  testMode: false
};
Default hours are 8:30 AM to 8:30 PM, 7 days a week.

Edge Config Integration

The system supports dynamic configuration via Vercel Edge Config:
src/config/serviceHours.js
import { getEdgeConfigServiceSettings } from './edgeConfig';

let ACTIVE_SERVICE_HOURS = { ...DEFAULT_SERVICE_HOURS };
let STORE_STATUS = {
  isOpen: true,
  temporarilyClosed: false,
  maintenanceMode: false,
  reason: ""
};

export const loadEdgeConfigSettings = async () => {
  try {
    const edgeSettings = await getEdgeConfigServiceSettings();
    
    if (edgeSettings) {
      if (edgeSettings.serviceHours) {
        ACTIVE_SERVICE_HOURS = {
          ...DEFAULT_SERVICE_HOURS,
          ...edgeSettings.serviceHours
        };
      }
      
      if (edgeSettings.storeStatus) {
        STORE_STATUS = edgeSettings.storeStatus;
      }
    }
  } catch (error) {
    console.warn('Edge Config failed, using default settings:', error);
  }
};
Edge Config allows you to change service hours without redeploying your application.

Store Status Management

Store Status Object

const STORE_STATUS = {
  isOpen: true,              // Master on/off switch
  temporarilyClosed: false,  // Temporary closure
  maintenanceMode: false,    // Maintenance mode
  reason: ""                 // Reason for closure
};

Get Store Status

src/config/serviceHours.js
export const getStoreStatus = () => STORE_STATUS;
Usage:
const status = getStoreStatus();
if (status.temporarilyClosed) {
  console.log('Store temporarily closed:', status.reason);
}

Service Hours Validation

Check if Service is Open

Main function to determine if orders can be placed:
src/config/serviceHours.js
export const isServiceOpen = async () => {
  // Load Edge Config settings
  await loadEdgeConfigSettings();
  
  const serviceHours = getActiveServiceHours();
  const storeStatus = getStoreStatus();
  
  // Manual closure check
  if (!storeStatus.isOpen || storeStatus.temporarilyClosed || storeStatus.maintenanceMode) {
    return false;
  }
  
  // Test mode check
  if (serviceHours.testMode) {
    return true;
  }

  const now = new Date();
  const currentDay = now.getDay(); // 0=Sunday, 1=Monday, ..., 6=Saturday
  const currentHour = now.getHours();
  const currentMinute = now.getMinutes();
  const currentTime = currentHour * 60 + currentMinute;
  
  // Check closed dates
  const today = now.toISOString().split('T')[0];
  if (serviceHours.closedDates.includes(today)) {
    return false;
  }
  
  // Weekday/weekend check
  const isWeekend = currentDay === 0 || currentDay === 6;
  if (isWeekend && !serviceHours.weekendsEnabled) {
    return false;
  }
  if (!isWeekend && !serviceHours.weekdaysEnabled) {
    return false;
  }
  
  // Time range check
  const startTime = serviceHours.startHour * 60 + serviceHours.startMinute;
  const endTime = serviceHours.endHour * 60 + serviceHours.endMinute;
  
  return currentTime >= startTime && currentTime <= endTime;
};
  1. Load Edge Config - Fetch latest settings
  2. Store Status - Check if manually closed
  3. Test Mode - Return true if enabled
  4. Closed Dates - Check against specific dates
  5. Day of Week - Verify weekday/weekend settings
  6. Time Range - Validate current time is within service hours

Display Service Hours

Format Service Hours Text

Generate human-readable service hours:
src/config/serviceHours.js
export const getServiceHoursText = () => {
  const serviceHours = getActiveServiceHours();
  
  const formatTime = (hour, minute) => {
    return `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;
  };
  
  const startTime = formatTime(serviceHours.startHour, serviceHours.startMinute);
  const endTime = formatTime(serviceHours.endHour, serviceHours.endMinute);
  
  return `${startTime} - ${endTime}`;
};
Output:
08:30 - 20:30

Calculate Next Service Time

src/config/serviceHours.js
export const getNextServiceTime = () => {
  const serviceHours = getActiveServiceHours();
  
  if (serviceHours.testMode) {
    return null;
  }

  const now = new Date();
  const tomorrow = new Date(now);
  tomorrow.setDate(tomorrow.getDate() + 1);
  tomorrow.setHours(serviceHours.startHour, serviceHours.startMinute, 0, 0);
  
  return tomorrow;
};

Real-Time Status Checking

Implement real-time service hours monitoring:
src/components/OrderButton.js
import { isServiceOpen, getServiceHoursText, getStoreStatus } from '../config/serviceHours';

const OrderButton = () => {
  const [serviceOpen, setServiceOpen] = useState(false);
  const [storeStatus, setStoreStatus] = useState(null);

  useEffect(() => {
    const checkServiceStatus = async () => {
      const isOpen = await isServiceOpen();
      const status = getStoreStatus();
      setServiceOpen(isOpen);
      setStoreStatus(status);
    };

    // Initial check
    checkServiceStatus();

    // Check every minute
    const interval = setInterval(checkServiceStatus, 60000);

    return () => clearInterval(interval);
  }, []);

  return (
    <button disabled={!serviceOpen}>
      {!serviceOpen
        ? storeStatus?.temporarilyClosed 
          ? 'Geçici Olarak Kapalı'
          : storeStatus?.maintenanceMode
            ? 'Bakım Modunda'
            : `Servis Saatleri: ${getServiceHoursText()}`
        : 'Sipariş Ver'
      }
    </button>
  );
};
The service status is checked every 60 seconds. This interval can be adjusted based on your needs.

Configuration Examples

Weekdays Only

src/config/serviceHours.js
export const DEFAULT_SERVICE_HOURS = {
  startHour: 9,
  startMinute: 0,
  endHour: 18,
  endMinute: 0,
  weekdaysEnabled: true,
  weekendsEnabled: false, // No weekend service
  closedDates: [],
  testMode: false
};

Extended Weekend Hours

Use Edge Config to set different weekend hours:
Edge Config
{
  "serviceHours": {
    "startHour": 10,
    "startMinute": 0,
    "endHour": 22,
    "endMinute": 0
  }
}

Holiday Closures

src/config/serviceHours.js
export const DEFAULT_SERVICE_HOURS = {
  // ... other settings
  closedDates: [
    '2024-01-01', // New Year's Day
    '2024-04-23', // National Sovereignty Day
    '2024-05-01', // Labor Day
    '2024-05-19', // Youth and Sports Day
    '2024-08-30', // Victory Day
    '2024-10-29', // Republic Day
  ],
};

Temporary Closure

Use Edge Config for emergency closures:
Edge Config
{
  "storeStatus": {
    "isOpen": false,
    "temporarilyClosed": true,
    "reason": "Teknik arıza nedeniyle geçici olarak kapalıyız"
  }
}

Test Mode

Enable test mode for development:
src/config/serviceHours.js
export const DEFAULT_SERVICE_HOURS = {
  // ... other settings
  testMode: true  // Always returns true for isServiceOpen()
};
Never enable test mode in production! It bypasses all service hour restrictions.

Integration with Order Flow

Disable Order Button

src/components/OrderButton.js
const isButtonDisabled = !serviceOpen || !orderValidation.isValid;

return (
  <button 
    onClick={handleOrderClick}
    disabled={isButtonDisabled}
    className={isButtonDisabled ? 'order-button-disabled' : ''}
  >
    {buttonText}
  </button>
);

Show Service Hours in UI

ServiceHoursDisplay.js
import { getServiceHoursText, isServiceOpen } from '../config/serviceHours';

function ServiceHoursDisplay() {
  const [isOpen, setIsOpen] = useState(false);

  useEffect(() => {
    const checkStatus = async () => {
      setIsOpen(await isServiceOpen());
    };
    checkStatus();
  }, []);

  return (
    <div className={`status ${isOpen ? 'open' : 'closed'}`}>
      {isOpen ? '🟢 Açık' : '🔴 Kapalı'}
      <span>Servis Saatleri: {getServiceHoursText()}</span>
    </div>
  );
}

Timezone Considerations

The system uses the client’s local timezone. Ensure your server and client timezones are properly configured.
For server-side rendering:
// Use specific timezone
const now = new Date().toLocaleString('en-US', { timeZone: 'Europe/Istanbul' });

Best Practices

Edge Config

Use Edge Config for production to enable real-time updates without redeployment.

Clear Messaging

Always display service hours and reasons for closure to customers.

Graceful Degradation

Fallback to default settings if Edge Config fails to load.

Testing

Test service hour logic across different timezones and edge cases.

Troubleshooting

Service Hours Not Updating

// Clear and reload Edge Config
await loadEdgeConfigSettings();
const hours = getActiveServiceHours();
console.log('Active hours:', hours);

Always Showing as Closed

// Enable test mode temporarily
const DEFAULT_SERVICE_HOURS = {
  // ... other settings
  testMode: true  // Temporarily enable
};

Debugging Service Status

const debugServiceHours = async () => {
  const isOpen = await isServiceOpen();
  const hours = getActiveServiceHours();
  const status = getStoreStatus();
  
  console.log('Is Open:', isOpen);
  console.log('Service Hours:', hours);
  console.log('Store Status:', status);
  console.log('Current Time:', new Date().toLocaleString());
};

WhatsApp Ordering

See how service hours integrate with the order button

Edge Config Setup

Learn how to configure Vercel Edge Config for dynamic settings

Build docs developers (and LLMs) love