Skip to content

Instantly share code, notes, and snippets.

@midoalone
Created September 20, 2022 06:49
Show Gist options
  • Save midoalone/0142cac99f8a5ca15e128a3fdf4bef24 to your computer and use it in GitHub Desktop.
Save midoalone/0142cac99f8a5ca15e128a3fdf4bef24 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { Container, Content, Icon, Text, View } from 'native-base'
import { Colors } from '../../Themes'
import LoginActions from '../../Redux/LoginRedux'
import I18n from '../../I18n'
import { FlatList, Image, RefreshControl, StatusBar, StyleSheet, TouchableOpacity } from 'react-native'
import { createPaymentUrl, ifIphoneX, lang, TWAlert } from '../../Lib/functions'
import { appFont, boldFont, regularFont } from '../../Config/Globals'
import { FormInput, FormItem, FormPicker } from '../../Components/Form'
import APICaller from '../../APIHelpers/APICaller'
import { Button, Radio, RadioGroup } from '@ui-kitten/components'
import NavigationService from '../../Navigation/NavigationService'
import Loader from '../../Components/Loader'
import API from '../../Services/Api'
import SettingsActions from '../../Redux/SettingsRedux'
import _ from 'lodash'
import ZadAlert from '../../Components/ZadAlert/ZadAlert'
import { ServiceItem } from './Components/ServiceItem'
import { CarItem } from './Components/CarItem'
const apiCaller = new APICaller()
const api = API.create()
const paymentMethods = [{
text: lang('Cash', 'كاش'),
id: 'cash',
icon: require("../../Images/cash.png")
}, {
text: lang('Credit Card', 'كريديت'),
id: 'visa',
icon: require("../../Images/credit-card.png")
}]
const initialState = {
refreshing: false,
selectedCar: false,
selectedService: false,
loading: false,
orderPanel: false,
discount_percent: '',
selectedPayment: 0,
payment_method: 'cash',
car_number: '',
client_id: '',
paymentUrl: null,
client_phone: null,
client_name: null,
selectedPark: null,
selectedMall: null,
balance: 0,
useBalance: false
}
function PaymentItem ({ active, onPress, title, image}) {
return (
<TouchableOpacity onPress={onPress} activeOpacity={0.8} style={{flex: 1}}>
<View padder style={{backgroundColor: Colors.background, alignItems: "center", marginRight: 10, borderRadius: 10, borderWidth: 2, borderColor: active ? Colors.brand : Colors.transparent}}>
<Image
source={image}
style={{height: 30, width: 30, tintColor: active ? Colors.brand : Colors.text}}
/>
<Text bold style={{color: active ? Colors.brand : Colors.text}}>{title}</Text>
</View>
</TouchableOpacity>
)
}
class WashOrder extends Component {
state = initialState
componentDidMount () {
const { login } = this.props
if (login) {
this.getUserBalance().done()
}
this.focusListener = this.props.navigation.addListener('didFocus', () => {
if (login) {
this.getUserBalance().done()
}
})
}
componentWillUnmount () {
this.focusListener.remove()
}
total () {
const { selectedService, discount_percent } = this.state
let price = selectedService.price || 0,
total = price
if (discount_percent > 0) {
total = price - (price * discount_percent / 100)
}
return total
}
async getUserBalance() {
const request = await api.getData('user/profile', { token: this.props.login?.token })
if(request.data) {
this.setState({balance: request?.data?.data?.balance})
}
}
async getEmployeeData () {
this.setState({ refreshing: true })
let request = await api.getData('car', { country: this.props.settings?.country?.id, relation: 'in', orderBy: 'sorter' })
let cars = request.data.data
request = await api.getData('service', { include: 'service_type,country', search: `country_id:${this.props.settings?.country?.id}`, limit: 1000 })
let services = request.data.data
this.setState({ refreshing: false })
let launch = {
cars,
services
}
this.props.saveSettings({ ...this.props.settings, ...launch })
}
createOrder () {
const { login: { token, id, phone, name }, settings: { country, malls } } = this.props
const { selectedPayment, selectedService, selectedPark, selectedMall, car_number } = this.state
apiCaller.call({
noAlert: true,
method: 'post',
endpoint: `order`,
params: {
service_id: selectedService.id,
car_number,
client_id: id,
client_phone: phone,
client_name: name,
payment_method: paymentMethods[selectedPayment].id,
total: this.total(),
mall_id: _.get(malls[selectedMall.row], 'id'),
country_id: country.id,
park_id: selectedPark ? _.get(malls[selectedMall.row].parks[selectedPark.row], 'id') : null,
is_client: 1
},
token,
onLoad: (data) => {
ZadAlert.notify({
message: I18n.t('Success'),
description: I18n.t('Your order has been submitted successfully!'),
type: 'success',
backgroundColor: Colors.success,
color: Colors.white,
duration: 2000,
titleStyle: {
fontFamily: boldFont,
color: Colors.white,
textAlign: 'left',
},
textStyle: {
fontFamily: regularFont,
lineHeight: 24,
textAlign: 'left',
fontSize: 18
}
})
this.setState(initialState)
NavigationService.navigate('OrderInvoice', { id: data.id })
}
}).done()
}
async generatePayment () {
const response = await createPaymentUrl(this.total(), __DEV__)
Loader.hide()
if (response.status === 'success') {
NavigationService.navigate('PaymentRedirect', {
redirectURL: response.paymentURL,
onDone: () => {
this.createOrder()
},
onError: () => {
TWAlert({
title: I18n.t('Error'),
message: I18n.t('Error on processing payment, please revise your payment details or contact us')
})
}
})
} else {
TWAlert(I18n.t('Error'), I18n.t('Error on creating payment link'))
}
}
completeOrder () {
if (!this.props.login) {
return NavigationService.navigate('LoginScreen')
}
const { selectedPayment } = this.state
if (selectedPayment === 1) {
return this.generatePayment().done()
}
this.createOrder()
}
render () {
const { settings: { cars, services, malls, country: { [lang('currency_en', 'currency_ar')]: CURRENCY } } } = this.props
const { selectedCar, selectedService, selectedPayment, refreshing, selectedPark, selectedMall, useBalance } = this.state
return (
<Container>
<StatusBar barStyle="dark-content" backgroundColor={Colors.white}/>
<View style={{ backgroundColor: Colors.white, height: ifIphoneX(170, 120) }}>
<View style={{ flex: 1, justifyContent: 'flex-end' }}>
<Image source={require('../../Images/logo_large.png')} style={{
width: 120,
height: 120,
resizeMode: 'contain',
alignSelf: 'center'
}}/>
</View>
</View>
<Content
padder
style={{ backgroundColor: Colors.background }}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={() => {
this.getEmployeeData().done()
}}
/>
}
showsVerticalScrollIndicator={false}
>
<View style={styles.box}>
<View row>
<View style={{ flex: 1 }}>
<Text bold style={styles.title}>{lang('Mall', 'المول')}</Text>
<FormItem required placeholder={lang('Choose Mall', 'اختر المول')}>
<FormPicker
items={malls}
titleKey={lang('name_en', 'name_ar')}
value={selectedMall && _.get(malls[selectedMall.row], lang('name_en', 'name_ar'))}
onSelect={mall => {
this.setState({ mall_id: malls[mall.row].id, selectedMall: mall, selectedPark: null })
}}
/>
</FormItem>
</View>
<View style={{ width: 10 }}/>
<View style={{ flex: 1 }}>
<Text bold style={styles.title}>{lang('Location', 'المكان')}</Text>
<FormItem required placeholder={lang('Choose Location', 'اختر مكان')}>
<FormPicker
disabled={!selectedMall}
items={malls[selectedMall?.row]?.parks}
titleKey={'park'}
value={selectedPark && _.get(malls[selectedMall.row].parks[selectedPark.row], 'park')}
onSelect={park => {
this.setState({ park_id: malls[selectedMall.row].parks[park.row].id, selectedPark: park })
}}
/>
</FormItem>
</View>
</View>
</View>
<View style={styles.box}>
<Text bold style={styles.title}>{lang('Choose your car type', 'اختر نوع سيارتك')}</Text>
<FlatList
horizontal={true}
// numColumns={3}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
data={cars}
keyExtractor={(item, index) => index}
renderItem={({ item, index }) => (
<CarItem
index={index}
image={item.image}
title={lang(item.name_en, item.name_ar)}
onPress={() => {
this.setState({ selectedCar: item })
}}
active={selectedCar === item}
/>
)}
/>
</View>
<If condition={selectedCar}>
<View style={styles.box}>
<Text bold style={styles.title}>{lang('Choose Service', 'اختر خدمة')}</Text>
<FlatList
numColumns={3}
showsVerticalScrollIndicator={false}
data={services.filter(i => i.car_id === selectedCar.id)}
keyExtractor={(item, index) => index}
renderItem={({ item }) => (
<ServiceItem
currency={CURRENCY}
title={lang(item.service_type.name_en, item.service_type.name_ar)}
subTitle={item.price}
onPress={() => {
this.setState({ selectedService: item })
}}
active={selectedService === item}
/>
)}
/>
</View>
</If>
<View style={styles.box}>
<View style={{ flex: 1 }}>
<Text bold style={styles.title}>{lang('Car Number', 'رقم السيارة')}</Text>
<FormItem
placeholder={lang('Enter Car Number', 'ادخل رقم السيارة')}
required>
<FormInput
value={this.state.car_number}
autoCapitalize={'none'}
onChangeText={car_number => {
this.setState({ car_number })
}}
/>
</FormItem>
</View>
</View>
<View style={styles.box}>
<View>
<Text bold style={styles.title}>{lang('Payment Method', 'طريقة الدفع')}</Text>
<If condition={this.props.login}>
<TouchableOpacity activeOpacity={0.8} onPress={() => this.setState({useBalance: !useBalance})}>
<View row padder style={{backgroundColor: Colors.background, alignItems: "center", marginBottom: 10, borderRadius: 10}}>
<Image source={require("../../Images/wallet.png")} style={{width: 22, height: 22, marginRight: 10}} />
<Text bold style={{flex: 1}}>{lang("Use wallet", "استخدم المحفظة")}</Text>
<Text style={{fontSize: 18, marginRight: 10}}>{this.state.balance} {CURRENCY}</Text>
<Icon name={useBalance ? "checkbox-outline" : "square-outline"} style={{fontSize: 22, color: useBalance ? Colors.success : Colors.text}} />
</View>
</TouchableOpacity>
</If>
<View row>
{paymentMethods.map((item, index) => (
<PaymentItem
key={index}
image={item.icon}
title={item.text}
onPress={() => {
this.setState({ payment_method: paymentMethods[index], selectedPayment: index })
}}
active={selectedPayment === index}
/>
))}
</View>
</View>
</View>
<If condition={selectedService && selectedMall}>
<View>
<Button size={'large'} appearance={'dark'} onPress={() => this.completeOrder()}>
{I18n.t('COMPLETE ORDER')} ({selectedService.price} {lang(selectedService.country.currency_en, selectedService.country.currency_ar)})
</Button>
</View>
</If>
</Content>
</Container>
)
}
}
const styles = StyleSheet.create({
title: { fontSize: 16, color: Colors.inText, marginVertical: 5, marginLeft: 5 },
box: {
borderRadius: 10,
padding: 10,
backgroundColor: Colors.white,
marginBottom: 10
}
})
const mapStateToProps = (state) => {
return {
settings: state.settings.data,
login: state.login.data
}
}
const mapDispatchToProps = dispatch => {
return {
saveSettings: (data) => dispatch(SettingsActions.settingsData(data)),
saveLoginData: data => {
dispatch(LoginActions.loginSuccess(data))
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(WashOrder)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment