UNPKG

@open-tender/utils

Version:

A library of utils for use with Open Tender applications that utilize our cloud-based Order API.

146 lines (145 loc) 6.66 kB
import { serviceTypeNamesMap } from './constants'; import { dateToZonedDateStr, fmtDate, formatDateStr, isoToDate, makeOrderTimes, makeReadableDateStrFromIso, makeWeekday, time24ToDate, timezoneMap } from './datetimes'; import { capitalize } from './helpers'; import { format } from 'date-fns'; import { utcToZonedTime } from 'date-fns-tz'; export const makeOrderAddress = (address) => { const { street, unit, city, state, postal_code } = address || {}; return street ? `${street}${unit ? `, ${unit}` : ''}` : postal_code ? `${postal_code} ${city}, ${state}` : 'No address provided'; }; export const makeFullAddress = (address) => { const { street, city, state, postal_code } = address || {}; return `${street ? `${street}, ` : ''}${city}, ${state} ${postal_code}`; }; export const makeOrderTypeFromParam = (param) => { switch (param) { case 'outpost': return ['OLO', 'PICKUP', true]; case 'pickup': return ['OLO', 'PICKUP']; case 'delivery': return ['OLO', 'DELIVERY']; case 'catering': return ['CATERING', 'DELIVERY']; case 'merch': return ['MERCH', 'DELIVERY']; default: return null; } }; export const makeServiceTypeName = (serviceType, isCatering, isOutpost, outpostName) => { let serviceTypeName = serviceTypeNamesMap[serviceType]; if (isCatering) { serviceTypeName = `Catering ${serviceTypeName}`; } else if (isOutpost) { serviceTypeName = `${outpostName || 'Outpost'} ${serviceTypeName}`; } return serviceTypeName; }; export const makeOrderTypeName = (orderType, serviceType) => { return orderType === 'OLO' ? serviceTypeNamesMap[serviceType] : capitalize(orderType); }; const makeOrderMsg = (tz, serviceType, requestedAt, firstTime, orderTime, waitTime) => { var _a, _b; if (!firstTime && !orderTime) return null; let readableDate; if (firstTime) { const seconds = firstTime.utc ? isoToDate(firstTime.utc).getSeconds() : 0; const estimate = requestedAt !== 'asap' && seconds ? 'at about' : 'at'; readableDate = requestedAt === 'asap' && firstTime.has_asap ? `in about ${waitTime} minutes` : makeReadableDateStrFromIso(firstTime.utc, tz, true) .replace('Today', 'today') .replace('Tomorrow', 'TOMORROW') .replace('@', estimate); } else { const orderTimes = makeOrderTimes([orderTime], tz); const { start_time, end_time } = orderTimes[0]; const startTime = time24ToDate(start_time); const startTimeStr = (_a = formatDateStr(startTime.toISOString(), 'h:mma')) === null || _a === void 0 ? void 0 : _a.toLowerCase(); const endTime = time24ToDate(end_time); const endTimeStr = (_b = formatDateStr(endTime.toISOString(), 'h:mma')) === null || _b === void 0 ? void 0 : _b.toLowerCase(); const todayWeekday = makeWeekday(); const weekday = orderTimes[0].weekday === todayWeekday ? '' : `${capitalize(orderTimes[0].weekday)}, ${fmtDate(orderTimes[0].date, 'MMMM d')} @ `; readableDate = startTimeStr === endTimeStr ? `${weekday}${startTimeStr}` : `${weekday}${startTimeStr} to ${endTimeStr}`; } const serviceTypeName = serviceTypeNamesMap[serviceType]; const orderMsg = `The first available ${serviceTypeName === null || serviceTypeName === void 0 ? void 0 : serviceTypeName.toLowerCase()} time is ${readableDate}`; return orderMsg; }; export const makeNotAcceptingOrdersMsg = (serviceType) => { const serviceTypeName = serviceTypeNamesMap[serviceType]; if (!serviceTypeName) { return 'This location is not currently accepting orders.'; } return `This location is not currently accepting ${serviceTypeName.toLowerCase()} orders.`; }; export const makeRevenueCenterMsg = (revenueCenter, serviceType, requestedAt, statusMessages) => { var _a; const settings = revenueCenter; const { first_times, order_times, wait_times } = settings; const tz = timezoneMap[(_a = revenueCenter === null || revenueCenter === void 0 ? void 0 : revenueCenter.timezone) !== null && _a !== void 0 ? _a : 'US/Central']; const st = serviceType === 'WALKIN' ? 'PICKUP' : serviceType; const firstTime = first_times ? first_times[st] : null; const orderTime = order_times ? order_times[st] : null; const waitTime = wait_times ? wait_times[st] : null; const tempClosed = revenueCenter.status === 'CLOSED_TEMPORARILY'; const statusMsg = !tempClosed ? statusMessages[revenueCenter.status] : null; const orderMsg = !statusMsg && (firstTime || (orderTime && orderTime.length)) ? makeOrderMsg(tz, serviceType, requestedAt, firstTime, orderTime ? orderTime[0] : null, waitTime !== null && waitTime !== void 0 ? waitTime : 0) : null; let message = orderMsg || (statusMsg ? statusMsg.subtitle : makeNotAcceptingOrdersMsg(serviceType)); let color = orderMsg ? 'success' : 'alert'; if (tempClosed) { color = 'alert'; message = message.charAt(0).toLowerCase() + message.substring(1); message = `This location is temporarily closed for technical or operational reasons. Please try back later today, otherwise ${message} if you want to place an order now.`; } return { message, color }; }; export const getRevenueCenterStatus = (revenueCenter, serviceType) => { const { first_times, status, timezone, revenue_center_type, is_outpost } = revenueCenter; if (revenue_center_type !== 'OLO' || is_outpost) return null; if (status !== 'OPEN' && status !== 'HIDDEN') return 'Closed'; const tz = timezoneMap[timezone]; const firstTimes = first_times ? first_times[serviceType] : null; if (!firstTimes) return 'Closed'; const { date, has_asap, utc } = firstTimes; const firstDt = utcToZonedTime(utc, tz); const now = new Date(); const today = dateToZonedDateStr(now, tz, 'yyyy-MM-dd'); const tomorrow = dateToZonedDateStr(now, tz, 'yyyy-MM-dd', 1); const isToday = date === today; const isTomorrow = date === tomorrow; if (isToday) { if (has_asap) { return 'Open Now'; } else { return 'Currently closed, order for later today'; } } const nextDay = isTomorrow ? 'tomorrow' : format(firstDt, 'EEEE'); return `Closed for today, order for ${nextDay}`; };