Skip to content

Commit

Permalink
Add multiple currencies to mobile app
Browse files Browse the repository at this point in the history
  • Loading branch information
aelassas committed Dec 15, 2024
1 parent e3eba48 commit 5509172
Show file tree
Hide file tree
Showing 28 changed files with 580 additions and 194 deletions.
2 changes: 1 addition & 1 deletion frontend/src/assets/css/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ div.content {

@media only screen and (width <=550px) {
.search-dialog-content {
width: calc(100% - 20px);
width: auto;
max-width: 480px;
}
}
Expand Down
4 changes: 0 additions & 4 deletions frontend/src/config/env.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ const CURRENCIES: Currency[] = [
code: 'GBP',
symbol: '£',
}
// {
// code: 'IQD',
// symbol: 'IQD',
// }
]

const env = {
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/pages/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ const Home = () => {
</div>

<Dialog
fullWidth={env.isMobile}
// fullWidth={env.isMobile}
maxWidth={false}
open={openLocationSearchFormDialog}
onClose={() => {
Expand All @@ -557,15 +557,15 @@ const Home = () => {
<SearchForm
ranges={bookcarsHelper.getAllRanges()}
pickupLocation={pickupLocation}
onCancel={() => {
setOpenLocationSearchFormDialog(false)
}}
// onCancel={() => {
// setOpenLocationSearchFormDialog(false)
// }}
/>
</DialogContent>
</Dialog>

<Dialog
fullWidth={env.isMobile}
// fullWidth={env.isMobile}
maxWidth={false}
open={openRangeSearchFormDialog}
onClose={() => {
Expand Down
3 changes: 1 addition & 2 deletions mobile/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ BC_MINIMUM_AGE=21
BC_STRIPE_PUBLISHABLE_KEY=STRIPE_PUBLISHABLE_KEY
BC_STRIPE_MERCHANT_IDENTIFIER=MERCHANT_IDENTIFIER
BC_STRIPE_COUNTRY_CODE=US
BC_STRIPE_CURRENCY_CODE=USD
BC_CURRENCY=$
BC_BASE_CURRENCY=USD
BC_DEPOSIT_FILTER_VALUE_1=250
BC_DEPOSIT_FILTER_VALUE_2=500
BC_DEPOSIT_FILTER_VALUE_3=750
183 changes: 126 additions & 57 deletions mobile/common/helper.ts

Large diffs are not rendered by default.

47 changes: 38 additions & 9 deletions mobile/components/Booking.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { memo } from 'react'
import React, { memo, useEffect, useState } from 'react'
import { StyleSheet, Text, View, Image } from 'react-native'
import { MaterialIcons } from '@expo/vector-icons'
import { Locale, format } from 'date-fns'
Expand All @@ -10,6 +10,7 @@ import Button from './Button'
import * as helper from '@/common/helper'
import * as env from '@/config/env.config'
import i18n from '@/lang/i18n'
import * as StripeService from '@/services/StripeService'

interface BookingProps {
booking: bookcarsTypes.Booking
Expand Down Expand Up @@ -44,7 +45,35 @@ const Booking = ({
const _fr = bookcarsHelper.isFrench(language)
const _format = _fr ? 'eee d LLL yyyy kk:mm' : 'eee, d LLL yyyy, p'

return (
const [loading, setLoading] = useState(true)
const [currencySymbol, setCurrencySymbol] = useState('')
const [price, setPrice] = useState(0)
const [cancellation, setCancellation] = useState('')
const [amendments, setAmendments] = useState('')
const [collisionDamageWaiver, setCollisionDamageWaiver] = useState('')
const [theftProtection, setTheftProtection] = useState('')
const [fullInsurance, setFullInsurance] = useState('')
const [additionalDriver, setAdditionalDriver] = useState('')

useEffect(() => {
const init = async () => {
if (booking && car && language && days) {
setCurrencySymbol(await StripeService.getCurrencySymbol())
setPrice(await StripeService.convertPrice(booking.price!))
setCancellation(await helper.getCancellationOption(car.cancellation, language, true))
setAmendments(await helper.getAmendmentsOption(car.amendments, language, true))
setCollisionDamageWaiver(await helper.getCollisionDamageWaiverOption(car.collisionDamageWaiver, days, language, true))
setTheftProtection(await helper.getTheftProtectionOption(car.theftProtection, days, language, true))
setFullInsurance(await helper.getFullInsuranceOption(car.fullInsurance, days, language, true))
setAdditionalDriver(await helper.getAdditionalDriverOption(car.additionalDriver, days, language, true))
setLoading(false)
}
}

init()
}, [booking, car.additionalDriver, car.amendments, car.cancellation, car.collisionDamageWaiver, car.fullInsurance, car.theftProtection, days, language])

Check warning on line 74 in mobile/components/Booking.tsx

View workflow job for this annotation

GitHub Actions / build (lts/*)

React Hook useEffect has a missing dependency: 'car'. Either include it or remove the dependency array

Check warning on line 74 in mobile/components/Booking.tsx

View workflow job for this annotation

GitHub Actions / build (lts/*)

React Hook useEffect has a missing dependency: 'car'. Either include it or remove the dependency array

return !loading && price && (
<View key={booking._id} style={styles.bookingContainer}>
<View style={styles.booking}>
<View style={styles.header}>
Expand Down Expand Up @@ -89,55 +118,55 @@ const Booking = ({
<View style={styles.extra}>
<MaterialIcons style={styles.extraIcon} name="check" size={extraIconSize} color={extraIconColor} />
<Text style={styles.extraTitle}>{i18n.t('CANCELLATION')}</Text>
<Text style={styles.extraText}>{helper.getCancellationOption(car.cancellation, language, true)}</Text>
<Text style={styles.extraText}>{cancellation}</Text>
</View>
)}

{booking.amendments && (
<View style={styles.extra}>
<MaterialIcons style={styles.extraIcon} name="check" size={extraIconSize} color={extraIconColor} />
<Text style={styles.extraTitle}>{i18n.t('AMENDMENTS')}</Text>
<Text style={styles.extraText}>{helper.getAmendmentsOption(car.amendments, language, true)}</Text>
<Text style={styles.extraText}>{amendments}</Text>
</View>
)}

{booking.collisionDamageWaiver && (
<View style={styles.extra}>
<MaterialIcons style={styles.extraIcon} name="check" size={extraIconSize} color={extraIconColor} />
<Text style={styles.extraTitle}>{i18n.t('COLLISION_DAMAGE_WAVER')}</Text>
<Text style={styles.extraText}>{helper.getCollisionDamageWaiverOption(car.collisionDamageWaiver, days, language, true)}</Text>
<Text style={styles.extraText}>{collisionDamageWaiver}</Text>
</View>
)}

{booking.theftProtection && (
<View style={styles.extra}>
<MaterialIcons style={styles.extraIcon} name="check" size={extraIconSize} color={extraIconColor} />
<Text style={styles.extraTitle}>{i18n.t('THEFT_PROTECTION')}</Text>
<Text style={styles.extraText}>{helper.getTheftProtectionOption(car.theftProtection, days, language, true)}</Text>
<Text style={styles.extraText}>{theftProtection}</Text>
</View>
)}

{booking.fullInsurance && (
<View style={styles.extra}>
<MaterialIcons style={styles.extraIcon} name="check" size={extraIconSize} color={extraIconColor} />
<Text style={styles.extraTitle}>{i18n.t('FULL_INSURANCE')}</Text>
<Text style={styles.extraText}>{helper.getFullInsuranceOption(car.fullInsurance, days, language, true)}</Text>
<Text style={styles.extraText}>{fullInsurance}</Text>
</View>
)}

{booking.additionalDriver && (
<View style={styles.extra}>
<MaterialIcons style={styles.extraIcon} name="check" size={extraIconSize} color={extraIconColor} />
<Text style={styles.extraTitle}>{i18n.t('ADDITIONAL_DRIVER')}</Text>
<Text style={styles.extraText}>{helper.getAdditionalDriverOption(car.additionalDriver, days, language, true)}</Text>
<Text style={styles.extraText}>{additionalDriver}</Text>
</View>
)}
</View>
</>
)}

<Text style={styles.detailTitle}>{i18n.t('COST')}</Text>
<Text style={styles.detailTextBold}>{`${bookcarsHelper.formatPrice(booking.price as number, i18n.t('CURRENCY'), language)}`}</Text>
<Text style={styles.detailTextBold}>{`${bookcarsHelper.formatPrice(price, currencySymbol, language)}`}</Text>

{booking.cancellation
&& !booking.cancelRequest
Expand Down
47 changes: 34 additions & 13 deletions mobile/components/Car.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Button from './Button'
import * as helper from '@/common/helper'
import * as env from '@/config/env.config'
import i18n from '@/lang/i18n'
import * as StripeService from '@/services/StripeService'

interface CarProps {
navigation: NativeStackNavigationProp<StackParams, keyof StackParams>
Expand Down Expand Up @@ -46,14 +47,34 @@ const Car = ({
const fr = bookcarsHelper.isFrench(language)

const [days, setDays] = useState<number>()
const [loading, setLoading] = useState(true)
const [currencySymbol, setCurrencySymbol] = useState('')
const [totalPrice, setTotalPrice] = useState<number>()
const [cancellation, setCancellation] = useState('')
const [amendments, setAmendments] = useState('')
const [collisionDamageWaiver, setCollisionDamageWaiver] = useState('')
const [theftProtection, setTheftProtection] = useState('')
const [fullInsurance, setFullInsurance] = useState('')
const [additionalDriver, setAdditionalDriver] = useState('')

useEffect(() => {
if (car && from && to) {
setDays(bookcarsHelper.days(from, to))
setTotalPrice(bookcarsHelper.calculateTotalPrice(car, from as Date, to as Date))
const init = async () => {
if (car && from && to && language) {
setCurrencySymbol(await StripeService.getCurrencySymbol())
setDays(bookcarsHelper.days(from, to))
setTotalPrice(await StripeService.convertPrice(bookcarsHelper.calculateTotalPrice(car, from as Date, to as Date)))
setCancellation(await helper.getCancellation(car.cancellation, language))
setAmendments(await helper.getAmendments(car.amendments, language))
setCollisionDamageWaiver(await helper.getCollisionDamageWaiver(car.collisionDamageWaiver, language))
setTheftProtection(await helper.getTheftProtection(car.theftProtection, language))
setFullInsurance(await helper.getFullInsurance(car.fullInsurance, language))
setAdditionalDriver(await helper.getAdditionalDriver(car.additionalDriver, language))
setLoading(false)
}
}
}, [car, from, to])

init()
}, [car, from, language, to])

const styles = StyleSheet.create({
carContainer: {
Expand Down Expand Up @@ -248,7 +269,7 @@ const Car = ({
},
})

return days && totalPrice && (
return !loading && days && totalPrice && (
<View key={car._id} style={styles.carContainer}>
{pickupLocationName && (
<>
Expand Down Expand Up @@ -318,37 +339,37 @@ const Car = ({
{car.cancellation > -1 && (
<View style={styles.extra}>
<MaterialIcons name={getExtraIcon(car.cancellation)} color={getExtraColor(car.cancellation)} size={iconSize} style={styles.infoIcon} />
<Text style={styles.text}>{helper.getCancellation(car.cancellation, language)}</Text>
<Text style={styles.text}>{cancellation}</Text>
</View>
)}
{car.amendments > -1 && (
<View style={styles.extra}>
<MaterialIcons name={getExtraIcon(car.amendments)} color={getExtraColor(car.amendments)} size={iconSize} style={styles.infoIcon} />
<Text style={styles.text}>{helper.getAmendments(car.amendments, language)}</Text>
<Text style={styles.text}>{amendments}</Text>
</View>
)}
{car.theftProtection > -1 && (
<View style={styles.extra}>
<MaterialIcons name={getExtraIcon(car.theftProtection)} color={getExtraColor(car.theftProtection)} size={iconSize} style={styles.infoIcon} />
<Text style={styles.text}>{helper.getTheftProtection(car.theftProtection, language)}</Text>
<Text style={styles.text}>{theftProtection}</Text>
</View>
)}
{car.collisionDamageWaiver > -1 && (
<View style={styles.extra}>
<MaterialIcons name={getExtraIcon(car.collisionDamageWaiver)} color={getExtraColor(car.collisionDamageWaiver)} size={iconSize} style={styles.infoIcon} />
<Text style={styles.text}>{helper.getCollisionDamageWaiver(car.collisionDamageWaiver, language)}</Text>
<Text style={styles.text}>{collisionDamageWaiver}</Text>
</View>
)}
{car.fullInsurance > -1 && (
<View style={styles.extra}>
<MaterialIcons name={getExtraIcon(car.fullInsurance)} color={getExtraColor(car.fullInsurance)} size={iconSize} style={styles.infoIcon} />
<Text style={styles.text}>{helper.getFullInsurance(car.fullInsurance, language)}</Text>
<Text style={styles.text}>{fullInsurance}</Text>
</View>
)}
{car.additionalDriver > -1 && (
<View style={styles.extra}>
<MaterialIcons name={getExtraIcon(car.additionalDriver)} color={getExtraColor(car.additionalDriver)} size={iconSize} style={styles.infoIcon} />
<Text style={styles.text}>{helper.getAdditionalDriver(car.additionalDriver, language)}</Text>
<Text style={styles.text}>{additionalDriver}</Text>
</View>
)}
</View>
Expand Down Expand Up @@ -395,8 +416,8 @@ const Car = ({
{!hidePrice && from && to && (
<View style={styles.price}>
<Text style={styles.priceSecondary}>{helper.getDays(days)}</Text>
<Text style={styles.pricePrimary}>{`${bookcarsHelper.formatPrice(totalPrice, i18n.t('CURRENCY'), language)}`}</Text>
<Text style={styles.priceSecondary}>{`${i18n.t('PRICE_PER_DAY')} ${bookcarsHelper.formatPrice(totalPrice / days, i18n.t('CURRENCY'), language)}`}</Text>
<Text style={styles.pricePrimary}>{`${bookcarsHelper.formatPrice(totalPrice, currencySymbol, language)}`}</Text>
<Text style={styles.priceSecondary}>{`${i18n.t('PRICE_PER_DAY')} ${bookcarsHelper.formatPrice(totalPrice / days, currencySymbol, language)}`}</Text>
</View>
)}
</View>
Expand Down
45 changes: 25 additions & 20 deletions mobile/components/CarList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react'
import { StyleSheet, Text, View, ActivityIndicator, RefreshControl } from 'react-native'
import { KeyboardAwareFlatList } from 'react-native-keyboard-aware-scroll-view'
import type { NativeStackNavigationProp } from '@react-navigation/native-stack'
import { RouteProp } from '@react-navigation/native'
import * as bookcarsTypes from ':bookcars-types'

import * as helper from '@/common/helper'
Expand Down Expand Up @@ -34,7 +35,8 @@ interface CarListProps {
cars?: bookcarsTypes.Car[]
hidePrice?: boolean
footerComponent?: React.ReactElement
route?: 'Cars' | 'Checkout',
routeName?: 'Cars' | 'Checkout',
route: RouteProp<StackParams, keyof StackParams>
onLoad?: bookcarsTypes.DataEvent<bookcarsTypes.Car>
}

Expand All @@ -61,6 +63,7 @@ const CarList = ({
cars,
hidePrice,
footerComponent,
routeName,
route,
onLoad
}: CarListProps) => {
Expand Down Expand Up @@ -247,25 +250,27 @@ const CarList = ({
<RefreshControl refreshing={refreshing} onRefresh={() => {
setRefreshing(true)

if ((route && pickupLocation && dropOffLocation && from && to) && ((route === 'Checkout' && cars && cars.length > 0) || route === 'Cars')) {
if (route === 'Cars') {
navigation.navigate(route, {
pickupLocation: pickupLocation!,
dropOffLocation: dropOffLocation!,
from: from!.getTime(),
to: to!.getTime(),
d: Date.now(),
})
} else {
navigation.navigate(route, {
car: cars![0]._id,
pickupLocation: pickupLocation!,
dropOffLocation: dropOffLocation!,
from: from!.getTime(),
to: to!.getTime(),
d: Date.now(),
})
}
if ((routeName && pickupLocation && dropOffLocation && from && to) && ((routeName === 'Checkout' && cars && cars.length > 0) || routeName === 'Cars')) {
helper.navigate(route, navigation, true)

// if (route === 'Cars') {
// navigation.navigate(route, {
// pickupLocation: pickupLocation!,
// dropOffLocation: dropOffLocation!,
// from: from!.getTime(),
// to: to!.getTime(),
// d: Date.now(),
// })
// } else {
// navigation.navigate(route, {
// car: cars![0]._id,
// pickupLocation: pickupLocation!,
// dropOffLocation: dropOffLocation!,
// from: from!.getTime(),
// to: to!.getTime(),
// d: Date.now(),
// })
// }

// navigation.dispatch((state) => {
// const { routes } = state
Expand Down
Loading

0 comments on commit 5509172

Please sign in to comment.