\n )\n}","'use strict';\n\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nvar bind = require('./helpers/bind');\n/*global toString:true*/\n// utils is a library of generic helper functions non-specific to axios\n\n\nvar toString = Object.prototype.toString;\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an Array, otherwise false\n */\n\nfunction isArray(val) {\n return toString.call(val) === '[object Array]';\n}\n/**\n * Determine if a value is undefined\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if the value is undefined, otherwise false\n */\n\n\nfunction isUndefined(val) {\n return typeof val === 'undefined';\n}\n/**\n * Determine if a value is a Buffer\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\n\n\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) && typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val);\n}\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\n\n\nfunction isArrayBuffer(val) {\n return toString.call(val) === '[object ArrayBuffer]';\n}\n/**\n * Determine if a value is a FormData\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an FormData, otherwise false\n */\n\n\nfunction isFormData(val) {\n return typeof FormData !== 'undefined' && val instanceof FormData;\n}\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\n\n\nfunction isArrayBufferView(val) {\n var result;\n\n if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) {\n result = ArrayBuffer.isView(val);\n } else {\n result = val && val.buffer && val.buffer instanceof ArrayBuffer;\n }\n\n return result;\n}\n/**\n * Determine if a value is a String\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a String, otherwise false\n */\n\n\nfunction isString(val) {\n return typeof val === 'string';\n}\n/**\n * Determine if a value is a Number\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Number, otherwise false\n */\n\n\nfunction isNumber(val) {\n return typeof val === 'number';\n}\n/**\n * Determine if a value is an Object\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an Object, otherwise false\n */\n\n\nfunction isObject(val) {\n return val !== null && _typeof(val) === 'object';\n}\n/**\n * Determine if a value is a Date\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Date, otherwise false\n */\n\n\nfunction isDate(val) {\n return toString.call(val) === '[object Date]';\n}\n/**\n * Determine if a value is a File\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a File, otherwise false\n */\n\n\nfunction isFile(val) {\n return toString.call(val) === '[object File]';\n}\n/**\n * Determine if a value is a Blob\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Blob, otherwise false\n */\n\n\nfunction isBlob(val) {\n return toString.call(val) === '[object Blob]';\n}\n/**\n * Determine if a value is a Function\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\n\n\nfunction isFunction(val) {\n return toString.call(val) === '[object Function]';\n}\n/**\n * Determine if a value is a Stream\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Stream, otherwise false\n */\n\n\nfunction isStream(val) {\n return isObject(val) && isFunction(val.pipe);\n}\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\n\n\nfunction isURLSearchParams(val) {\n return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;\n}\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n * @returns {String} The String freed of excess whitespace\n */\n\n\nfunction trim(str) {\n return str.replace(/^\\s*/, '').replace(/\\s*$/, '');\n}\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n */\n\n\nfunction isStandardBrowserEnv() {\n if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' || navigator.product === 'NativeScript' || navigator.product === 'NS')) {\n return false;\n }\n\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n */\n\n\nfunction forEach(obj, fn) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n } // Force an array if not already something iterable\n\n\n if (_typeof(obj) !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (var i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Iterate over object keys\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n fn.call(null, obj[key], key, obj);\n }\n }\n }\n}\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n * @returns {Object} Result of all merge properties\n */\n\n\nfunction merge()\n/* obj1, obj2, obj3, ... */\n{\n var result = {};\n\n function assignValue(val, key) {\n if (_typeof(result[key]) === 'object' && _typeof(val) === 'object') {\n result[key] = merge(result[key], val);\n } else {\n result[key] = val;\n }\n }\n\n for (var i = 0, l = arguments.length; i < l; i++) {\n forEach(arguments[i], assignValue);\n }\n\n return result;\n}\n/**\n * Function equal to merge with the difference being that no reference\n * to original objects is kept.\n *\n * @see merge\n * @param {Object} obj1 Object to merge\n * @returns {Object} Result of all merge properties\n */\n\n\nfunction deepMerge()\n/* obj1, obj2, obj3, ... */\n{\n var result = {};\n\n function assignValue(val, key) {\n if (_typeof(result[key]) === 'object' && _typeof(val) === 'object') {\n result[key] = deepMerge(result[key], val);\n } else if (_typeof(val) === 'object') {\n result[key] = deepMerge({}, val);\n } else {\n result[key] = val;\n }\n }\n\n for (var i = 0, l = arguments.length; i < l; i++) {\n forEach(arguments[i], assignValue);\n }\n\n return result;\n}\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n * @return {Object} The resulting value of object a\n */\n\n\nfunction extend(a, b, thisArg) {\n forEach(b, function assignValue(val, key) {\n if (thisArg && typeof val === 'function') {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n });\n return a;\n}\n\nmodule.exports = {\n isArray: isArray,\n isArrayBuffer: isArrayBuffer,\n isBuffer: isBuffer,\n isFormData: isFormData,\n isArrayBufferView: isArrayBufferView,\n isString: isString,\n isNumber: isNumber,\n isObject: isObject,\n isUndefined: isUndefined,\n isDate: isDate,\n isFile: isFile,\n isBlob: isBlob,\n isFunction: isFunction,\n isStream: isStream,\n isURLSearchParams: isURLSearchParams,\n isStandardBrowserEnv: isStandardBrowserEnv,\n forEach: forEach,\n merge: merge,\n deepMerge: deepMerge,\n extend: extend,\n trim: trim\n};","import { PayeableType } from \"../PaymentForm\"\nimport {Discount, Driver, Payment, Transaction} from \"../../types\"\n\nexport function mapTrackDateProducts( track_date_product ) {\n\n return {\n ...track_date_product,\n price: parseFloat(track_date_product.price),\n product: {\n ...track_date_product.product,\n pricedByVehicle: track_date_product.product.priced_by_vehicle,\n pricedByTrackDate: track_date_product.product.priced_by_track_date,\n price: parseFloat(track_date_product.product.price)\n }\n }\n}\n\nexport function mapVehicleProduct(vehicle_product) {\n\n return {\n ...vehicle_product,\n price: parseFloat(vehicle_product.price),\n product: {\n ...vehicle_product.product,\n pricedByVehicle: vehicle_product.product.priced_by_vehicle,\n pricedByTrackDate: vehicle_product.product.priced_by_track_date,\n price: parseFloat(vehicle_product.product.price),\n }\n }\n}\n\nexport function mapTrackDateVehicle(track_date_vehicle) {\n\n\n return {\n ...track_date_vehicle,\n price: parseFloat(track_date_vehicle.price),\n vehicle: {\n ...track_date_vehicle.vehicle,\n price: parseFloat(track_date_vehicle.vehicle.price),\n vehicleProducts: track_date_vehicle.vehicle.vehicle_products?.map(mapVehicleProduct)\n }\n }\n}\n\nexport function mapTrackDate(track_date) {\n\n return {\n ...track_date,\n trackDateVehicles: track_date.track_date_vehicles?.map(mapTrackDateVehicle) ,\n trackDateGroup: {\n ...track_date.track_date_group,\n eventOrganizer: track_date?.track_date_group?.event_organizer,\n registrationFee: track_date?.track_date_group?.registration_fee,\n },\n trackDateProducts: track_date.track_date_products?.map(mapTrackDateProducts)\n }\n}\n\nexport function mapPayment(payment):Payment {\n\n\n let payeableType;\n\n if(payment.payeable_type == \"Reservation\") {\n payeableType = PayeableType.Reservation\n }\n\n if(payment.payeable_type == \"Checkin\") {\n payeableType = PayeableType.Checkout\n }\n\n if(payment.payeable_type == \"Transaction\") {\n payeableType = PayeableType.Transaction\n }\n\n return {\n id: payment.id,\n amount: parseFloat(payment.amount),\n refundAmount: parseFloat(payment.refund_amount),\n paymentType: payment.payment_type,\n cardType: payment.card_type,\n lastFour: payment.card_last4,\n expiresMonth: payment.card_exp_month,\n expiresYear: payment.card_exp_year,\n refundedAt: payment.refunded_at,\n createdAt: payment.created_at,\n quickbooksId: payment.quickbooks_id,\n payeableId: payment.payeable_id,\n payeableType: payeableType\n }\n}\n\nexport function mapDriver(driver):Driver {\n\n if(!driver) {\n return null\n }\n\n return {\n id: driver.id,\n firstName: driver.first_name,\n lastName: driver.last_name,\n email: driver.email,\n phone: driver.phone,\n emergencyContact: driver.emergency_name,\n emergencyPhone: driver.emergency_phone,\n experienceLevel: driver.experience_level,\n licenseNumber: driver.license_number,\n dob: driver.dob\n }\n}\n\nexport function mapTransaction(transaction):Transaction {\n if(!transaction) {\n console.log(\"transaction is null\")\n return null\n }\n\n\n return {\n id: transaction.id,\n totalPrice: parseFloat( transaction.total_price ),\n balanceDue: parseFloat( transaction.balance_due ),\n createdAt: transaction.created_at,\n draft: transaction.draft,\n payments: transaction.payments.map(mapPayment),\n lineItems: transaction.line_items.map((lineItem)=>{\n\n return {\n id: lineItem.id,\n unitPrice: lineItem.unit_price,\n quantity: parseInt( lineItem.quantity ),\n subTotal: lineItem.sub_total,\n trackDateProduct: {\n ...lineItem.track_date_product\n }\n }\n })\n }\n}\n\nexport function mapDiscount(discount):Discount {\n if(!discount) {\n return null\n }\n\n return {\n id: discount.id,\n fixed: discount.discount_type == \"fixed\",\n discountAmount: discount.amount,\n percentageAmount: discount.percentage_amount,\n percentage: discount.discount_type == \"percentage\",\n priceRule: discount.price_rule,\n code: discount.code,\n vehicle: {\n ...discount.vehicle\n },\n product: {\n ...discount.product\n },\n trackDateGroup: {\n ...discount.track_date_group,\n trackDates: (discount.track_date_group) ? discount.track_date_group?.track_dates?.map(mapTrackDate) : null\n },\n expiresAt: discount.expires_at,\n startsAt: discount.starts_at\n }\n}\n\n","module.exports = require('./lib/axios');","import React, { useReducer, useContext, createContext, useState, useEffect,useRef } from \"react\"\nimport { useReservationContext } from './Provider'\nimport client from \"../../src/client\"\nimport { formatDate, useDebounce, formatCurrency } from '../../src/utils'\nimport CurrencyField from '../CurrencyField'\nimport Button from '../Button'\nimport { ActionType } from \"../types/actions\"\nconst classNames = require(\"classnames\")\n\nexport enum PayeableType {\n Reservation = \"Reservation\",\n Checkout = \"Checkout\",\n Transaction = \"Transaction\"\n}\n\ninterface PaymentFormProps {\n onSuccess: Function\n allowMultiple: boolean,\n initialAmount: number\n payeableType: PayeableType\n payeableId: number\n}\n\nfunction buildPaymentUrl(payeableType:PayeableType,payeableId:number) {\n let url;\n\n if(payeableType == PayeableType.Reservation) {\n url = `/api/v1/reservations/${payeableId}/payment`\n }\n\n if(payeableType == PayeableType.Transaction) {\n url = `/api/v1/transactions/${payeableId}/payment`\n }\n\n\n return url\n}\n\nexport default function PaymentForm({onSuccess,initialAmount,payeableType,payeableId,allowMultiple=false}:PaymentFormProps) {\n\n if(!initialAmount) {\n initialAmount = 1\n }\n\n const { state, dispatch, reloadReservation } = useReservationContext()\n const [stripe,setStripe] = useState()\n const [card,setCard] = useState()\n const [amount,setAmount] = useState(initialAmount)\n const [paymentIntent,setPaymentIntent] = useState()\n const [paymentType,setPaymentType] = useState(\"credit_card\")\n const [busy,setBusy] = useState(false)\n const [paymentLinkMessage,setPaymentLinkMessage] = useState('Thank you for booking your track day event:')\n const [name,setName] = useState('')\n\n let ref = useRef()\n\n async function refreshPaymentIntent() {\n try {\n\n console.log(\"refresh payment intent amount=\", amount)\n let r = await client.post(\"/checkins/intent\",{\n amount: amount\n })\n setPaymentIntent(r.data)\n\n \n } catch(e) {\n\n console.error(e)\n\n }\n }\n\n useEffect(()=>{\n\n console.log(\"ref=\", ref)\n\n if(ref.current) {\n let stripeMeta = document.querySelector('meta[name=\"stripe-key\"]')\n let stripeKey = stripeMeta.getAttribute(\"content\")\n setStripe(window.Stripe(stripeKey))\n refreshPaymentIntent()\n }\n\n },[ref])\n\n\n\n useEffect(()=>{\n\n if(stripe) {\n let elements = stripe.elements()\n \n let card = elements.create(\"card\")\n card.mount(ref.current)\n card.addEventListener(\"change\", (e)=>{\n console.log(\"card listener change=\", e)\n }) \n setCard(card)\n }\n\n },[stripe])\n\n async function handleVipPush() {\n setBusy(true)\n\n let r = await client.post( `/api/v1/transactions/${payeableId}/vip_push` ,{\n\n })\n console.log(\"data=\",r.data)\n\n await onSuccess()\n }\n\n async function handlePaymentClick() {\n\n setBusy(true)\n let url = buildPaymentUrl(payeableType,payeableId)\n\n let r = await client.post( url ,{\n payment_type: paymentType,\n message: paymentLinkMessage,\n amount: amount\n })\n console.log(\"data=\",r.data)\n\n /*await reloadReservation()\n dispatch({type: ActionType.ClosePaymentModal})*/\n\n await onSuccess()\n\n }\n\n function handleCreditCardPaymentClick() {\n\n setBusy(true)\n let url = buildPaymentUrl(payeableType,payeableId)\n\n let data = {\n payment_method: {\n card: card,\n billing_details: {\n name: name\n }\n }\n } \n\n stripe.confirmCardPayment(paymentIntent.client_secret,data).then(async (result) => {\n let r = await client.post( url ,{\n payment_type: paymentType,\n payment_intent_id: paymentIntent.id,\n amount: amount\n })\n console.log(\"data=\",r.data)\n /*await reloadReservation()\n dispatch({type: ActionType.ClosePaymentModal})*/\n\n await onSuccess()\n })\n }\n\n\n function tabClassNames(isActive) {\n return classNames(\"border-b-2 p-2 uppercase text-sm cursor-pointer hover:border-primary-600\",{\n \"border-transparent\" : !isActive,\n \"border-white\": isActive\n })\n }\n\n return (\n
\n\n )\n}","import toInteger from \"../_lib/toInteger/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\nvar MILLISECONDS_IN_HOUR = 3600000;\nvar MILLISECONDS_IN_MINUTE = 60000;\nvar DEFAULT_ADDITIONAL_DIGITS = 2;\nvar patterns = {\n dateTimeDelimiter: /[T ]/,\n timeZoneDelimiter: /[Z ]/i,\n timezone: /([Z+-].*)$/\n};\nvar dateRegex = /^-?(?:(\\d{3})|(\\d{2})(?:-?(\\d{2}))?|W(\\d{2})(?:-?(\\d{1}))?|)$/;\nvar timeRegex = /^(\\d{2}(?:[.,]\\d*)?)(?::?(\\d{2}(?:[.,]\\d*)?))?(?::?(\\d{2}(?:[.,]\\d*)?))?$/;\nvar timezoneRegex = /^([+-])(\\d{2})(?::?(\\d{2}))?$/;\n/**\n * @name parseISO\n * @category Common Helpers\n * @summary Parse ISO string\n *\n * @description\n * Parse the given string in ISO 8601 format and return an instance of Date.\n *\n * Function accepts complete ISO 8601 formats as well as partial implementations.\n * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601\n *\n * If the argument isn't a string, the function cannot parse the string or\n * the values are invalid, it returns Invalid Date.\n *\n * ### v2.0.0 breaking changes:\n *\n * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).\n *\n * - The previous `parse` implementation was renamed to `parseISO`.\n *\n * ```javascript\n * // Before v2.0.0\n * parse('2016-01-01')\n *\n * // v2.0.0 onward\n * parseISO('2016-01-01')\n * ```\n *\n * - `parseISO` now validates separate date and time values in ISO-8601 strings\n * and returns `Invalid Date` if the date is invalid.\n *\n * ```javascript\n * parseISO('2018-13-32')\n * //=> Invalid Date\n * ```\n *\n * - `parseISO` now doesn't fall back to `new Date` constructor\n * if it fails to parse a string argument. Instead, it returns `Invalid Date`.\n *\n * @param {String} argument - the value to convert\n * @param {Object} [options] - an object with options.\n * @param {0|1|2} [options.additionalDigits=2] - the additional number of digits in the extended year format\n * @returns {Date} the parsed date in the local time zone\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2\n *\n * @example\n * // Convert string '2014-02-11T11:30:30' to date:\n * var result = parseISO('2014-02-11T11:30:30')\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert string '+02014101' to date,\n * // if the additional number of digits in the extended year format is 1:\n * var result = parseISO('+02014101', { additionalDigits: 1 })\n * //=> Fri Apr 11 2014 00:00:00\n */\n\nexport default function parseISO(argument, dirtyOptions) {\n requiredArgs(1, arguments);\n var options = dirtyOptions || {};\n var additionalDigits = options.additionalDigits == null ? DEFAULT_ADDITIONAL_DIGITS : toInteger(options.additionalDigits);\n\n if (additionalDigits !== 2 && additionalDigits !== 1 && additionalDigits !== 0) {\n throw new RangeError('additionalDigits must be 0, 1 or 2');\n }\n\n if (!(typeof argument === 'string' || Object.prototype.toString.call(argument) === '[object String]')) {\n return new Date(NaN);\n }\n\n var dateStrings = splitDateString(argument);\n var date;\n\n if (dateStrings.date) {\n var parseYearResult = parseYear(dateStrings.date, additionalDigits);\n date = parseDate(parseYearResult.restDateString, parseYearResult.year);\n }\n\n if (isNaN(date) || !date) {\n return new Date(NaN);\n }\n\n var timestamp = date.getTime();\n var time = 0;\n var offset;\n\n if (dateStrings.time) {\n time = parseTime(dateStrings.time);\n\n if (isNaN(time) || time === null) {\n return new Date(NaN);\n }\n }\n\n if (dateStrings.timezone) {\n offset = parseTimezone(dateStrings.timezone);\n\n if (isNaN(offset)) {\n return new Date(NaN);\n }\n } else {\n var dirtyDate = new Date(timestamp + time); // js parsed string assuming it's in UTC timezone\n // but we need it to be parsed in our timezone\n // so we use utc values to build date in our timezone.\n // Year values from 0 to 99 map to the years 1900 to 1999\n // so set year explicitly with setFullYear.\n\n var result = new Date(0);\n result.setFullYear(dirtyDate.getUTCFullYear(), dirtyDate.getUTCMonth(), dirtyDate.getUTCDate());\n result.setHours(dirtyDate.getUTCHours(), dirtyDate.getUTCMinutes(), dirtyDate.getUTCSeconds(), dirtyDate.getUTCMilliseconds());\n return result;\n }\n\n return new Date(timestamp + time + offset);\n}\n\nfunction splitDateString(dateString) {\n var dateStrings = {};\n var array = dateString.split(patterns.dateTimeDelimiter);\n var timeString; // The regex match should only return at maximum two array elements.\n // [date], [time], or [date, time].\n\n if (array.length > 2) {\n return dateStrings;\n }\n\n if (/:/.test(array[0])) {\n dateStrings.date = null;\n timeString = array[0];\n } else {\n dateStrings.date = array[0];\n timeString = array[1];\n\n if (patterns.timeZoneDelimiter.test(dateStrings.date)) {\n dateStrings.date = dateString.split(patterns.timeZoneDelimiter)[0];\n timeString = dateString.substr(dateStrings.date.length, dateString.length);\n }\n }\n\n if (timeString) {\n var token = patterns.timezone.exec(timeString);\n\n if (token) {\n dateStrings.time = timeString.replace(token[1], '');\n dateStrings.timezone = token[1];\n } else {\n dateStrings.time = timeString;\n }\n }\n\n return dateStrings;\n}\n\nfunction parseYear(dateString, additionalDigits) {\n var regex = new RegExp('^(?:(\\\\d{4}|[+-]\\\\d{' + (4 + additionalDigits) + '})|(\\\\d{2}|[+-]\\\\d{' + (2 + additionalDigits) + '})$)');\n var captures = dateString.match(regex); // Invalid ISO-formatted year\n\n if (!captures) return {\n year: null\n };\n var year = captures[1] && parseInt(captures[1]);\n var century = captures[2] && parseInt(captures[2]);\n return {\n year: century == null ? year : century * 100,\n restDateString: dateString.slice((captures[1] || captures[2]).length)\n };\n}\n\nfunction parseDate(dateString, year) {\n // Invalid ISO-formatted year\n if (year === null) return null;\n var captures = dateString.match(dateRegex); // Invalid ISO-formatted string\n\n if (!captures) return null;\n var isWeekDate = !!captures[4];\n var dayOfYear = parseDateUnit(captures[1]);\n var month = parseDateUnit(captures[2]) - 1;\n var day = parseDateUnit(captures[3]);\n var week = parseDateUnit(captures[4]);\n var dayOfWeek = parseDateUnit(captures[5]) - 1;\n\n if (isWeekDate) {\n if (!validateWeekDate(year, week, dayOfWeek)) {\n return new Date(NaN);\n }\n\n return dayOfISOWeekYear(year, week, dayOfWeek);\n } else {\n var date = new Date(0);\n\n if (!validateDate(year, month, day) || !validateDayOfYearDate(year, dayOfYear)) {\n return new Date(NaN);\n }\n\n date.setUTCFullYear(year, month, Math.max(dayOfYear, day));\n return date;\n }\n}\n\nfunction parseDateUnit(value) {\n return value ? parseInt(value) : 1;\n}\n\nfunction parseTime(timeString) {\n var captures = timeString.match(timeRegex);\n if (!captures) return null; // Invalid ISO-formatted time\n\n var hours = parseTimeUnit(captures[1]);\n var minutes = parseTimeUnit(captures[2]);\n var seconds = parseTimeUnit(captures[3]);\n\n if (!validateTime(hours, minutes, seconds)) {\n return NaN;\n }\n\n return hours * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE + seconds * 1000;\n}\n\nfunction parseTimeUnit(value) {\n return value && parseFloat(value.replace(',', '.')) || 0;\n}\n\nfunction parseTimezone(timezoneString) {\n if (timezoneString === 'Z') return 0;\n var captures = timezoneString.match(timezoneRegex);\n if (!captures) return 0;\n var sign = captures[1] === '+' ? -1 : 1;\n var hours = parseInt(captures[2]);\n var minutes = captures[3] && parseInt(captures[3]) || 0;\n\n if (!validateTimezone(hours, minutes)) {\n return NaN;\n }\n\n return sign * (hours * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE);\n}\n\nfunction dayOfISOWeekYear(isoWeekYear, week, day) {\n var date = new Date(0);\n date.setUTCFullYear(isoWeekYear, 0, 4);\n var fourthOfJanuaryDay = date.getUTCDay() || 7;\n var diff = (week - 1) * 7 + day + 1 - fourthOfJanuaryDay;\n date.setUTCDate(date.getUTCDate() + diff);\n return date;\n} // Validation functions\n// February is null to handle the leap year (using ||)\n\n\nvar daysInMonths = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\nfunction isLeapYearIndex(year) {\n return year % 400 === 0 || year % 4 === 0 && year % 100;\n}\n\nfunction validateDate(year, month, date) {\n return month >= 0 && month <= 11 && date >= 1 && date <= (daysInMonths[month] || (isLeapYearIndex(year) ? 29 : 28));\n}\n\nfunction validateDayOfYearDate(year, dayOfYear) {\n return dayOfYear >= 1 && dayOfYear <= (isLeapYearIndex(year) ? 366 : 365);\n}\n\nfunction validateWeekDate(_year, week, day) {\n return week >= 1 && week <= 53 && day >= 0 && day <= 6;\n}\n\nfunction validateTime(hours, minutes, seconds) {\n if (hours === 24) {\n return minutes === 0 && seconds === 0;\n }\n\n return seconds >= 0 && seconds < 60 && minutes >= 0 && minutes < 60 && hours >= 0 && hours < 25;\n}\n\nfunction validateTimezone(_hours, minutes) {\n return minutes >= 0 && minutes <= 59;\n}","import React, { useEffect, useState } from 'react';\nimport SlideOver from '../SlideOver';\n\nexport function formatCurrency(money) {\n return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(money).replace(/\\D00$/, '');\n}\n\nexport default function BookingsSlideOver({ open, onClose, bookings }) {\n\n const [total,setTotal] = useState(0)\n const [gross,setGross] = useState(0)\n\n useEffect(()=>{\n\n if(!bookings) {\n return null\n }\n\n setGross(bookings.reduce((acc,x)=> acc += parseFloat(x.sub_total) ,0))\n setTotal(bookings.reduce((acc,x)=> acc += 1 ,0))\n\n\n\n },[bookings])\n \n\n return (\n \n\n