UNPKG

@kiwicom/smart-faq

Version:

Smart FAQ

195 lines (175 loc) 5.49 kB
// @flow import idx from 'idx'; import * as React from 'react'; import css from 'styled-jsx/css'; import { parsePhoneNumber } from 'libphonenumber-js'; import { CountryFlag } from '@kiwicom/orbit-components'; import { InformationCircle } from '@kiwicom/orbit-components/lib/icons'; import { graphql, createFragmentContainer } from 'react-relay'; import { CODES } from '@kiwicom/orbit-components/lib/CountryFlag/consts'; import addMinutes from 'date-fns/add_minutes'; import { track } from '../shared/cuckoo/tracker'; import Tooltip from '../SmartFAQ/common/Tooltip/HoverHelpTooltip'; import type { Phone as PhoneType } from './__generated__/Phone.graphql'; const styles = css` div.containerPhoneNumber { display: flex; align-items: center; margin-bottom: 10px; } div.containerPhoneNumber :global(.Tooltip) { bottom: 110%; right: -100px; } div.containerPhoneNumber :global(.Tooltip-inner.Tooltip-inner) { max-width: 275px; width: 200px; } div.containerPhoneNumber :global(.HelpTooltip) { vertical-align: top; } div.phoneNumber { margin-left: 4px; margin-right: 4px; } a { color: #00ad98; text-decoration: none; font-family: 'Roboto', -apple-system, '.SFNSText-Regular', 'San Francisco', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande', sans-serif; } `; type Props = {| data: PhoneType, |}; const formatTime = (datetime: Date) => `${datetime.getUTCHours() % 12}${ datetime.getUTCMinutes() > 0 ? `:${datetime.getUTCMinutes()}` : '' } ${datetime.getUTCHours() >= 12 ? 'pm' : 'am'}`; const parseUTCTimeToDate = (utcString: string) => { const hour = parseInt(utcString.split(':')[0], 10); const minute = parseInt(utcString.split(':')[1], 10); const now = new Date(); return new Date( Date.UTC(now.getFullYear(), now.getMonth(), now.getDay(), hour, minute), ); }; const convertToTimezone = addMinutes; const convertToLocalTimezone = (datetime: Date) => { // it's negative because the offset has to be subtracted return convertToTimezone(datetime, -new Date().getTimezoneOffset()); }; const getTimezone = () => { const offset = new Date().getTimezoneOffset(); const offsetHours = Math.floor(Math.abs(offset / 60)); const offsetMinutes = Math.abs(offset % 60); const formattedOffset = `${'00' .concat(offsetHours.toString()) .slice(-2)}:${'00'.concat(offsetMinutes.toString()).slice(-2)}`; if (offset > 0) { return `GMT-${formattedOffset}`; } else if (offset === 0) { return 'GMT'; } else { return `GMT+${formattedOffset}`; } }; const formatOpenHours = (from: string, to: string): string => { const fromDate = convertToLocalTimezone(parseUTCTimeToDate(from)); const toDate = convertToLocalTimezone(parseUTCTimeToDate(to)); return `${formatTime(fromDate)}-${formatTime(toDate)} ${getTimezone()}`; }; const parseAvailabilityTimes = ( phoneLanguageAvailability, hasMultipleLanguages, language, ) => { const { type } = phoneLanguageAvailability; if (type === 'NONSTOP') { return 'Support Available in '; } else if (type === 'WORKING_DAYS') { const { to, from } = phoneLanguageAvailability; if (to && from && language) { return `${ hasMultipleLanguages ? language : '' } Mon - Fri ${formatOpenHours(from, to)}; `; } } return ''; }; const Phone = ({ data }: Props) => { const { number: phoneNumber, localeTerritory, countryName, supportedLanguages, } = data; let parsedPhoneNumber; try { parsedPhoneNumber = parsePhoneNumber(phoneNumber).formatInternational(); } catch (e) { parsedPhoneNumber = phoneNumber; } const flagCode = localeTerritory && CODES[localeTerritory.toUpperCase()]; const hasMultipleLanguages = supportedLanguages && supportedLanguages.length > 1; const availabilityInfo = supportedLanguages ? supportedLanguages.reduce((acc, supportedLanguage) => { const language = idx(supportedLanguage, _ => _.language); const languageAvailability = idx(supportedLanguage, _ => _.phoneLanguageAvailability) || {}; return ( `${parseAvailabilityTimes( languageAvailability, hasMultipleLanguages, language, )}` + acc ); }, 'English 24/7;') : null; return ( <div data-code={localeTerritory} className="containerPhoneNumber"> {flagCode && countryName && <CountryFlag code={flagCode} name={countryName} />} <div dir="ltr" className="phoneNumber"> {phoneNumber && ( <a href={`tel:${phoneNumber.replace(/\s/g, '')}`} onClick={() => track('ContactForm', 'phoneClicked', { localeTerritory }) } > {parsedPhoneNumber} </a> )} </div> <div dir="ltr" style={{ cursor: 'pointer' }}> <Tooltip content={availabilityInfo} placement="top"> <InformationCircle size="small" color="tertiary" /> </Tooltip> </div> <style>{styles}</style> </div> ); }; export default createFragmentContainer( Phone, graphql` fragment Phone on CustomerSupportNumber { number countryName localeTerritory supportedLanguages { language languageCode phoneLanguageAvailability { type ... on CSPhoneAvailabilityWorkingDays { from to } } } } `, );