import React, { Component, FormEvent } from 'react'; import { Box, Text, Flex } from '@rebass/emotion'; import { StaticQuery, graphql, Link } from 'gatsby'; import { inject, observer } from 'mobx-react'; import moment from 'moment'; import { ProductOrderService, DeliveryValidator } from 'lib'; import { ICON_NAMES } from 'utils/constants/assets'; import TextInput from 'components/fields/text-input'; import LoadingSpinner from 'components/loading-spinner'; import Icon from 'components/icon'; import Countdown from 'components/countdown'; import * as Types from './postalcode-checker.types'; import * as Styles from './postalcode-checker.styles'; class PostalCodeChecker extends Component { state: Types.PostalCodeCheckerState = { postalCode: { value: '', valueToSend: '', isValid: false }, deliveryConfig: null, shouldDisplayPostalCodeError: false, isValidatingPostalCode: false, canDeliverToUser: false, isDisplayingCoverageError: false, hasDeliveryConfig: false, availableConfig: null }; setIsLoading = (): void => { this.setState({ isValidatingPostalCode: true }); } setHasError = (): void => { this.setState({ shouldDisplayPostalCodeError: true }); } disableIsLoading = (): void => { setTimeout(() => { this.setState({ isValidatingPostalCode: false }); }, 400); } checkDelivery = (e: FormEvent): void => { e.preventDefault(); if (this.props.deliveryStore!.livePostalCode.isValid) { this.setIsLoading(); ProductOrderService.fetchProductDeliveryConfig( [this.props.product.fxId], this.props.deliveryStore!.livePostalCode.valueToSend ) .then(result => { this.setState({ deliveryConfig: result.data.data.products[0], hasDeliveryConfig: false }, () => { this.buildDeliveryConfig() this.disableIsLoading(); }); }) .catch(error => { this.disableIsLoading(); }); } else { this.setHasError(); } } buildDeliveryConfig = (): void | boolean => { const validator = new DeliveryValidator( [this.state.deliveryConfig], this.props.deliveryStore!.livePostalCode.valueToSend ) .validateDeliveryZones(); if (!validator.hasValidDeliveryCoverage()) { this.displayCoverageError(); return false; } const availableConfig = validator .validateSameDay() .buildDeliveryOptions() .buildConfig() this.setState({ hasDeliveryConfig: true, availableConfig }, () => { this.props.setCanAddToBasket( this.state.availableConfig.deliveryOptions.find((option: any) => option.config) ) }) } timeOut = () => { this.buildDeliveryConfig(); } displayCoverageError = (): void => { this.setState({ canDeliverToUser: false, isDisplayingCoverageError: true }); } setPostalCode = (value: string): void => { this.props.deliveryStore!.setLivePostalCode(value); this.setState({ shouldDisplayPostalCodeError: false, canDeliverToUser: false, isDisplayingCoverageError: false }); } buildPostalCodeError = (currency: string): React.ReactNode => { const postalCodeFormat = currency === 'GBP' ? 'postcode' : 'zip code'; switch (true) { case !this.props.deliveryStore!.livePostalCode.value.length: return `Please enter a ${postalCodeFormat}` case this.isPostalCodeInvalid(): return `Your ${postalCodeFormat} code is invalid`; case this.hasCoverageError(): return ( This product doesn't deliver to {this.props.deliveryStore!.livePostalCode.valueToSend}. Try a different {postalCodeFormat} or search {' '}our shop ); default: return 'An error has occured'; } } renderError = (currency: string): React.ReactNode => { if (!this.shouldDisplayError()) return null; return ( {this.buildPostalCodeError(currency)} ); } isPostalCodeInvalid = (): boolean => !this.props.deliveryStore!.livePostalCode.isValid && this.state.shouldDisplayPostalCodeError; hasCoverageError = (): boolean => !this.state.canDeliverToUser && this.state.isDisplayingCoverageError shouldDisplayError = (): boolean => this.isPostalCodeInvalid() || this.hasCoverageError(); getNearestDeliveryOption = () => this.state.availableConfig.deliveryOptions.find((option: any) => option.date); renderNextDeliveryDate = (): any => { return moment(this.getNearestDeliveryOption().date).utc().calendar(undefined, { sameDay: `[Today,] Mo`, nextDay: `[Tomorrow,] Mo`, nextWeek: `ddd Do MMM`, sameElse: `ddd Do MMM` }); } render(): React.ReactNode { return( { return ( <> { !this.state.hasDeliveryConfig ? Delivery address We need to verify if your address is part of our delivery area {this.renderError(fxMerchantConfig.currency)} { !this.state.isValidatingPostalCode ? : ( ) } :
Next Delivery Day: {this.renderNextDeliveryDate()}
} ); }} /> ); } } export default inject('deliveryStore')(observer(PostalCodeChecker));