Created
September 20, 2022 06:49
-
-
Save midoalone/0142cac99f8a5ca15e128a3fdf4bef24 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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