import React, { useState, useEffect } from 'react' import { View, StyleSheet, BackHandler, TouchableOpacity, I18nManager } from 'react-native' import LinearGradient from 'react-native-linear-gradient' import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder'; import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons' import AntIcon from 'react-native-vector-icons/AntDesign' import { Messages } from '../Messages' import { ShareComponent } from '../ShareComponent' import AsyncStorage from '@react-native-async-storage/async-storage'; import { useLanguage, OrderDetails as OrderDetailsConTableoller, useUtils, useConfig, useSession, useOrder } from 'ordering-components/native' import { OrderDetailsContainer, Header, OrderContent, OrderBusiness, Logo, OrderData, OrderInfo, OrderStatus, StaturBar, StatusImage, OrderCustomer, CustomerPhoto, InfoBlock, HeaderInfo, Customer, OrderProducts, Table, OrderBill, Total, Icons, OrderDriver, Map, LoadingWrapper, Divider } from './styles' import { OButton, OIcon, OModal, OText } from '../shared' import { ProductItemAccordion } from '../ProductItemAccordion' import { OrderDetailsParams } from '../../types' import { USER_TYPE } from '../../config/constants' import { GoogleMap } from '../GoogleMap' import { verifyDecimals } from '../../utils' import { useTheme } from 'styled-components/native' import { NotFoundSource } from '../NotFoundSource' import { OrderCreating } from '../OrderCreating'; import { OSRow } from '../OrderSummary/styles'; import { TaxInformation } from '../TaxInformation'; export const OrderDetailsUI = (props: OrderDetailsParams) => { const { navigation, messages, setMessages, readMessages, messagesReadList, isFromCheckout, isFromRoot, driverLocation, goToBusinessList, onNavigationRedirect, getOrder } = props const theme = useTheme() const styles = StyleSheet.create({ rowDirection: { flexDirection: 'row' }, statusBar: { transform: [{ scaleX: I18nManager.isRTL ? -1 : 1 }], height: 10, }, logo: { width: 75, height: 75, borderRadius: 10 }, textBold: { fontWeight: 'bold' }, btnBackArrow: { borderWidth: 0, backgroundColor: theme.colors.primary, borderColor: theme.colors.primary, shadowColor: theme.colors.primary, alignItems: 'flex-start', justifyContent: 'flex-start', paddingLeft: 0, height: 30 }, }) const [, t] = useLanguage() const [{ parsePrice, parseNumber, parseDate }] = useUtils() const [{ user }] = useSession() const [{ configs }] = useConfig() const [, { refreshOrderOptions }] = useOrder() const [openModalForBusiness, setOpenModalForBusiness] = useState(false) const [openModalForDriver, setOpenModalForDriver] = useState(false) const [unreadAlert, setUnreadAlert] = useState({ business: false, driver: false }) const [isReviewed, setIsReviewed] = useState(false) const [openOrderCreating, setOpenOrderCreating] = useState(false) const [openTaxModal, setOpenTaxModal] = useState({ open: false, tax: null, type: '' }) const { order, loading, businessData, error } = props.order const getOrderStatus = (s: string) => { const status = parseInt(s) const orderStatus = [ { key: 0, value: t('PENDING', 'Pending'), slug: 'PENDING', percentage: 0.25, image: theme.images.order.status0 }, { key: 1, value: t('COMPLETED', 'Completed'), slug: 'COMPLETED', percentage: 1, image: theme.images.order.status1 }, { key: 2, value: t('REJECTED', 'Rejected'), slug: 'REJECTED', percentage: 0, image: theme.images.order.status2 }, { key: 3, value: t('DRIVER_IN_BUSINESS', 'Driver in business'), slug: 'DRIVER_IN_BUSINESS', percentage: 0.60, image: theme.images.order.status3 }, { key: 4, value: t('PREPARATION_COMPLETED', 'Preparation Completed'), slug: 'PREPARATION_COMPLETED', percentage: 0.70, image: theme.images.order.status4 }, { key: 5, value: t('REJECTED_BY_BUSINESS', 'Rejected by business'), slug: 'REJECTED_BY_BUSINESS', percentage: 0, image: theme.images.order.status5 }, { key: 6, value: t('REJECTED_BY_DRIVER', 'Rejected by Driver'), slug: 'REJECTED_BY_DRIVER', percentage: 0, image: theme.images.order.status6 }, { key: 7, value: t('ACCEPTED_BY_BUSINESS', 'Accepted by business'), slug: 'ACCEPTED_BY_BUSINESS', percentage: 0.35, image: theme.images.order.status7 }, { key: 8, value: t('ACCEPTED_BY_DRIVER', 'Accepted by driver'), slug: 'ACCEPTED_BY_DRIVER', percentage: 0.45, image: theme.images.order.status8 }, { key: 9, value: t('PICK_UP_COMPLETED_BY_DRIVER', 'Pick up completed by driver'), slug: 'PICK_UP_COMPLETED_BY_DRIVER', percentage: 0.80, image: theme.images.order.status9 }, { key: 10, value: t('PICK_UP_FAILED_BY_DRIVER', 'Pick up Failed by driver'), slug: 'PICK_UP_FAILED_BY_DRIVER', percentage: 0, image: theme.images.order.status10 }, { key: 11, value: t('DELIVERY_COMPLETED_BY_DRIVER', 'Delivery completed by driver'), slug: 'DELIVERY_COMPLETED_BY_DRIVER', percentage: 1, image: theme.images.order.status11 }, { key: 12, value: t('DELIVERY_FAILED_BY_DRIVER', 'Delivery Failed by driver'), slug: 'DELIVERY_FAILED_BY_DRIVER', percentage: 0, image: theme.images.order.status12 }, { key: 13, value: t('PREORDER', 'PreOrder'), slug: 'PREORDER', percentage: 0, image: theme.images.order.status13 }, { key: 14, value: t('ORDER_NOT_READY', 'Order not ready'), slug: 'ORDER_NOT_READY', percentage: 0, image: theme.images.order.status14 }, { key: 15, value: t('ORDER_PICKEDUP_COMPLETED_BY_CUSTOMER', 'Order picked up completed by customer'), slug: 'ORDER_PICKEDUP_COMPLETED_BY_CUSTOMER', percentage: 100, image: theme.images.order.status15 }, { key: 16, value: t('CANCELLED_BY_CUSTOMER', 'Cancelled by customer'), slug: 'CANCELLED_BY_CUSTOMER', percentage: 0, image: theme.images.order.status16 }, { key: 17, value: t('ORDER_NOT_PICKEDUP_BY_CUSTOMER', 'Order not picked up by customer'), slug: 'ORDER_NOT_PICKEDUP_BY_CUSTOMER', percentage: 0, image: theme.images.order.status17 }, { key: 18, value: t('DRIVER_ALMOST_ARRIVED_TO_BUSINESS', 'Driver almost arrived to business'), slug: 'DRIVER_ALMOST_ARRIVED_TO_BUSINESS', percentage: 0.15, image: theme.images.order.status18 }, { key: 19, value: t('DRIVER_ALMOST_ARRIVED_TO_CUSTOMER', 'Driver almost arrived to customer'), slug: 'DRIVER_ALMOST_ARRIVED_TO_CUSTOMER', percentage: 0.90, image: theme.images.order.status19 }, { key: 20, value: t('ORDER_CUSTOMER_ALMOST_ARRIVED_BUSINESS', 'Customer almost arrived to business'), slug: 'ORDER_CUSTOMER_ALMOST_ARRIVED_BUSINESS', percentage: 90, image: theme.images.order.status20 }, { key: 21, value: t('ORDER_CUSTOMER_ARRIVED_BUSINESS', 'Customer arrived to business'), slug: 'ORDER_CUSTOMER_ARRIVED_BUSINESS', percentage: 95, image: theme.images.order.status21 }, { key: 22, value: t('ORDER_LOOKING_FOR_DRIVER', 'Looking for driver'), slug: 'ORDER_LOOKING_FOR_DRIVER', percentage: 35, image: theme.images.order.status22 }, { key: 23, value: t('ORDER_DRIVER_ON_WAY', 'Driver on way'), slug: 'ORDER_DRIVER_ON_WAY', percentage: 45, image: theme.images.order.status23 } ] const objectStatus = orderStatus.find((o) => o.key === status) return objectStatus && objectStatus } const handleOpenMessagesForBusiness = () => { setOpenModalForBusiness(true) readMessages && readMessages() setUnreadAlert({ ...unreadAlert, business: false }) } const handleOpenMessagesForDriver = () => { setOpenModalForDriver(true) readMessages && readMessages() setUnreadAlert({ ...unreadAlert, driver: false }) } const unreadMessages = () => { const length = messages?.messages.length const unreadLength = order?.unread_count const unreadedMessages = messages.messages.slice(length - unreadLength, length) const business = unreadedMessages.some((message: any) => message?.can_see?.includes(2)) const driver = unreadedMessages.some((message: any) => message?.can_see?.includes(4)) setUnreadAlert({ business, driver }) } const handleCloseModal = () => { setOpenModalForBusiness(false) setOpenModalForDriver(false) } const handleArrowBack: any = () => { if ((!isFromCheckout && !goToBusinessList) || isFromRoot) { navigation?.canGoBack() && navigation.goBack(); return } if (goToBusinessList) { refreshOrderOptions() } navigation.navigate('BottomTab'); } const handleClickOrderReview = (order: any) => { navigation.navigate( 'ReviewOrder', { order: { id: order?.id, business_id: order?.business_id, logo: order.business?.logo, driver: order?.driver, products: order?.products, review: order?.review, user_review: order?.user_review }, setIsReviewed } ) } const getIncludedTaxes = () => { if (order?.taxes?.length === 0) { return order.tax_type === 1 ? order?.summary?.tax ?? 0 : 0 } else { return order?.taxes.reduce((taxIncluded: number, tax: any) => { return taxIncluded + (tax.type === 1 ? tax.summary?.tax : 0) }, 0) } } const getIncludedTaxesDiscounts = () => { return order?.taxes?.filter((tax: any) => tax?.type === 1)?.reduce((carry: number, tax: any) => carry + (tax?.summary?.tax_after_discount ?? tax?.summary?.tax), 0) } useEffect(() => { BackHandler.addEventListener('hardwareBackPress', handleArrowBack); return () => { BackHandler.removeEventListener('hardwareBackPress', handleArrowBack); } }, []) useEffect(() => { if (messagesReadList?.length) { openModalForBusiness ? setUnreadAlert({ ...unreadAlert, business: false }) : setUnreadAlert({ ...unreadAlert, driver: false }) } }, [messagesReadList]) let locations = [ { ...order?.driver?.location, title: t('DRIVER', 'Driver'), icon: order?.driver?.photo || 'https://res.cloudinary.com/demo/image/fetch/c_thumb,g_face,r_max/https://www.freeiconspng.com/thumbs/driver-icon/driver-icon-14.png' }, { ...order?.business?.location, title: order?.business?.name, icon: order?.business?.logo || theme.images.dummies.businessLogo }, { ...order?.customer?.location, title: t('YOUR_LOCATION', 'Your Location'), icon: order?.customer?.photo || 'https://res.cloudinary.com/demo/image/upload/c_thumb,g_face,r_max/d_avatar.png/non_existing_id.png' } ] useEffect(() => { if (driverLocation) { locations[0] = { ...locations[0], lat: driverLocation.lat, lng: driverLocation.lng } } }, [driverLocation]) useEffect(() => { if (!loading) { setOpenOrderCreating(false) try { AsyncStorage.removeItem('business-address') } catch { console.log('error') } } }, [loading]) useEffect(() => { AsyncStorage.getItem('business-address', (err, result) => { if (result !== null) setOpenOrderCreating(true) }) }, []) return ( {order && order?.id && !error && !loading && ( <>
handleArrowBack()} imgLeftStyle={{ tintColor: '#fff' }} /> {order?.customer?.name} {t('THANKS_ORDER', 'thanks for your order!')} {t('ORDER_MESSAGE_HEADER_TEXT', 'Once business accepts your order, we will send you an email, thank you!')} {t('TOTAL', 'Total')} {parsePrice(order?.summary?.total ?? order?.total)}
{order?.business?.name} {order?.business?.email} {order?.business?.cellphone} {order.uuid && order.hash_key && ( )} props.navigation.navigate('Business', { store: businessData?.slug })} /> handleOpenMessagesForBusiness()}> {t('ORDER', 'Order')} #{order?.id} {t('DATE_TIME_FOR_ORDER', 'Date and time for your order')} { order?.delivery_datetime_utc ? parseDate(order?.delivery_datetime_utc) : parseDate(order?.delivery_datetime, { utc: false }) } {getOrderStatus(order?.status)?.value} {t('CUSTOMER', 'Customer')} {order?.customer?.name} {order?.customer?.lastname} {order?.customer?.address} {(!!order?.customer?.cellphone) && ( {(order?.customer?.country_phone_code) && `+${(order?.customer?.country_phone_code)} `}{(order?.customer?.cellphone)} )} {order?.delivery_option !== undefined && order?.delivery_type === 1 && ( {t('DELIVERY_PREFERENCE', 'Delivery Preference')} {order?.delivery_option?.name} )} {!!order?.comment && ( {t('COMMENT', 'Comment')} {order?.comment} )} {order?.driver && ( <> {order?.driver?.location && parseInt(order?.status) === 9 && ( )} )} {order?.driver && ( {t('YOUR_DRIVER', 'Your Driver')} {order?.driver?.name} {order?.driver?.lastname} handleOpenMessagesForDriver()}> )} {t('YOUR_ORDER', 'Your Order')} {order?.products?.length && order?.products.map((product: any, i: number) => ( ))} {t('SUBTOTAL', 'Subtotal')} {parsePrice(((order?.summary?.subtotal ?? order?.subtotal) + getIncludedTaxes()))}
{(order?.summary?.discount > 0 ?? order?.discount > 0) && order?.offers?.length === 0 && ( {order?.offer_type === 1 ? ( {t('DISCOUNT', theme?.defaultLanguages?.DISCOUNT || 'Discount')}{' '} {`(${verifyDecimals(order?.offer_rate, parsePrice)}%)`} ) : ( {t('DISCOUNT', theme?.defaultLanguages?.DISCOUNT || 'Discount')} )} - {parsePrice(order?.summary?.discount ?? order?.discount)}
)} { order?.offers?.length > 0 && order?.offers?.filter((offer: any) => offer?.target === 1)?.map((offer: any) => ( {offer.name} {offer.rate_type === 1 && ( {`(${verifyDecimals(offer?.rate, parsePrice)}%)`} )} setOpenTaxModal({ open: true, data: offer, type: 'offer_target_1' })}> - {parsePrice(offer?.summary?.discount)}
)) } {order?.summary?.subtotal_with_discount > 0 && order?.summary?.discount > 0 && order?.summary?.total >= 0 && ( {t('SUBTOTAL_WITH_DISCOUNT', 'Subtotal with discount')} {order?.tax_type === 1 ? ( {parsePrice((order?.summary?.subtotal_with_discount + getIncludedTaxesDiscounts() ?? 0))} ) : ( {parsePrice(order?.summary?.subtotal_with_discount ?? 0)} )}
)} { order?.taxes?.length === 0 && order?.tax_type === 2 && order?.summary?.tax > 0 && ( {t('TAX', 'Tax')} {`(${verifyDecimals(order?.tax, parseNumber)}%)`} {parsePrice(order?.summary?.tax ?? 0)}
) } { order?.fees?.length === 0 && order?.summary?.service_fee > 0 && ( {t('SERVICE_FEE', 'Service fee')} {`(${verifyDecimals(order?.service_fee, parseNumber)}%)`} {parsePrice(order?.summary?.service_fee ?? 0)}
) } { order?.taxes?.length > 0 && order?.taxes?.filter((tax: any) => tax?.type === 2 && tax?.rate !== 0).map((tax: any) => ( {tax.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')} {`(${verifyDecimals(tax?.rate, parseNumber)}%)`}{' '} setOpenTaxModal({ open: true, data: tax, type: 'tax' })}> {parsePrice(tax?.summary?.tax_after_discount ?? tax?.summary?.tax ?? 0)}
)) } { order?.fees?.length > 0 && order?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0))?.map((fee: any) => ( {fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')} ({fee?.fixed > 0 && `${parsePrice(fee?.fixed)} + `}{fee.percentage}%){' '} setOpenTaxModal({ open: true, data: fee, type: 'fee' })}> {parsePrice(fee?.summary?.fixed + (fee?.summary?.percentage_after_discount ?? fee?.summary?.percentage) ?? 0)}
)) } { order?.offers?.length > 0 && order?.offers?.filter((offer: any) => offer?.target === 3)?.map((offer: any) => ( {offer.name} {offer.rate_type === 1 && ( {`(${verifyDecimals(offer?.rate, parsePrice)}%)`} )} setOpenTaxModal({ open: true, data: offer, type: 'offer_target_3' })}> - {parsePrice(offer?.summary?.discount)}
)) } {order?.summary?.delivery_price > 0 && ( {t('DELIVERY_FEE', 'Delivery Fee')}{parsePrice(order?.summary?.delivery_price)}
)} { order?.offers?.length > 0 && order?.offers?.filter((offer: any) => offer?.target === 2)?.map((offer: any) => ( {offer.name} {offer.rate_type === 1 && ( {`(${verifyDecimals(offer?.rate, parsePrice)}%)`} )} setOpenTaxModal({ open: true, data: offer, type: 'offer_target_2' })}> - {parsePrice(offer?.summary?.discount)}
)) } {order?.summary?.driver_tip > 0 && ( {t('DRIVER_TIP', 'Driver tip')} {order?.summary?.driver_tip > 0 && parseInt(configs?.driver_tip_type?.value, 10) === 2 && !parseInt(configs?.driver_tip_use_custom?.value, 10) && ( `(${verifyDecimals(order?.summary?.driver_tip, parseNumber)}%)` )} {parsePrice(order?.summary?.driver_tip ?? order?.totalDriverTip)}
)} {t('TOTAL', 'Total')} {parsePrice(order?.summary?.total ?? order?.total)}
{ ( parseInt(order?.status) === 1 || parseInt(order?.status) === 11 || parseInt(order?.status) === 15 ) && !order.review && !isReviewed && ( handleClickOrderReview(order)} text={t('REVIEW_YOUR_ORDER', 'Review your order')} textStyle={{ color: theme.colors.white }} imgRightSrc='' /> )}
)} {loading && !error && ( )} {!loading && error && ( onNavigationRedirect('BusinessList')} /> )} handleCloseModal()} > setOpenTaxModal({ open: false, data: null, type: '' })} entireModal title={`${openTaxModal.data?.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')} ${openTaxModal.data?.rate_type !== 2 ? `(${typeof openTaxModal.data?.rate === 'number' ? `${openTaxModal.data?.rate}%` : `${parsePrice(openTaxModal.data?.fixed ?? 0)} + ${openTaxModal.data?.percentage}%`})` : ''} `} >
) } export const OrderDetails = (props: OrderDetailsParams) => { const orderDetailsProps = { ...props, UIComponent: OrderDetailsUI } return ( ) }