csa-react-60/src/screens/redeem/RedeemScreen.js
2025-08-19 17:14:51 +07:00

292 lines
11 KiB
JavaScript

import React from 'react'
import LinearGradient from "react-native-linear-gradient";
import {BackgroundImage} from "../../components/BackgroundImage";
import {Animated, FlatList, RefreshControl, ScrollView, StyleSheet, Text, TouchableOpacity, View} from "react-native";
import {NavigationEvents} from "react-navigation";
import IconFeather from "react-native-vector-icons/Feather";
import IconMaterial from 'react-native-vector-icons/MaterialCommunityIcons'
import Image from 'react-native-fast-image'
import {getLevelMembership, getListReward, getUserProfile} from "../../api/UserApi";
import {connect} from "react-redux";
import {bindActionCreators} from "redux";
import {appSetUser} from "../../redux/app/action";
import {t} from "../../utils/i18n";
import IndicatorLoading from "../../components/IndicatorLoading";
class RedeemScreen extends React.Component {
constructor(props){
super(props);
this.state = {
isLoading: false,
refreshing: false,
cateGoryRewards: [
{source: require('../../../assets/images/discount_rent.png'), text: t('rental_discount'), id: 1},
{source: require('../../../assets/images/discount_product.png'), text: t('product_discount'), id: 2},
{source: require('../../../assets/images/discount_redeem.png'), text: t('redeem_service'), id: 3},
{source: require('../../../assets/images/discount_coupon.png'), text: t('lucky_draw'), id: 4}
],
allRewards: [],
point: 0,
scrollY: '',
membel_level: ''
}
}
initData = () => {
this.setState({
isLoading: true,
refreshing: true,
}, () => {
Promise.all([
this.getListReward(),
this.getUserProfile(),
this.getLevelMember()
]).then(() => {
this.setState({
isLoading: false,
refreshing: false
})
});
})
}
async getListReward () {
return await getListReward()
.then(res => {
if(res.data){
this.setState({
allRewards: res.data.data,
isLoading: false
})
}
})
}
async getUserProfile () {
return await getUserProfile()
.then(res => {
if(res.data && res.ok){
this.setState({
point: res.data.point_balance,
}, () => {
let user_data = this.props.user;
user_data = {
...user_data,
point: this.state.point
}
this.props.appSetUser(user_data)
})
}
});
}
async getLevelMember () {
return await getLevelMembership()
.then(res => {
if(res.data && res.data.success){
this.setState({
membel_level: res.data.data && res.data.data.user_level ? res.data.data.user_level : ''
})
}
})
}
_onRefresh = () => {
this.initData()
}
renderItemImages = (item) => {
return (
<TouchableOpacity style={{ height: 300, width: 200, flex: 1, backgroundColor: 'white', borderRadius: 6, marginRight: 13}}
onPress={() => this.props.navigation.navigate('RewardDetail', {id: item.id})}>
<View style={{flex: 0.7}}>
<Image source={{uri: item.image_reward ? item.image_reward : ''}} style={{height: '100%'}} resizeMode={'contain'} />
</View>
<View style={{flex: 0.3, padding: 8, flexDirection: 'column', justifyContent: 'center'}}>
<Text style={{fontWeight: '600', fontFamily: 'Prompt-Regular',}}>{item.name}</Text>
<Text style={{textAlign: 'right', color: '#FF6122', fontFamily: 'Prompt-Regular', fontWeight: '600'}}>{item.points_to_redeem} Point</Text>
</View>
</TouchableOpacity>
)
}
_keyExtractorNewHead = (item, index) => 'reward_' + index
render() {
let cateGoryRewards = this.state.cateGoryRewards;
let allRewards = this.state.allRewards;
return (
<LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{
flex: 1,
width: null,
height: null,
resizeMode: 'cover'
}}>
<NavigationEvents
onDidFocus={() => {
this.initData()
}}
/>
<BackgroundImage>
<ScrollView contentContainerStyle={styles.contentContainer}
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this._onRefresh}
/>
}
showsVerticalScrollIndicator={false}
scrollEventThrottle={16}
// onScroll={Animated.event(
// [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }]
// )}
>
<View style={{flex: 1, padding: 10}}>
<View style={{flex: 0.1, display: 'flex', flexDirection: 'row'}}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('HistoryRedeem')} style={{flex: 1, marginRight: 8}}>
<LinearGradient start={{x: 0, y: 0}} end={{x: 1, y: 0}} colors={['#FFA800', '#E46F00']} style={styles.pointContain}>
<View style={{ flex: 0.4}}>
<IconMaterial name="star-circle-outline" color="white" size={56}/>
</View>
<View style={{ flex: 0.6 }}>
<TouchableOpacity style={[styles.membershipLevelBox]} onPress={() => this.props.navigation.navigate('MembershipLevelDetail')}>
<IconMaterial name="rhombus" size={16} color="#DA7A16"/>
<Text style={{color: '#DA7A16', fontSize: 16, paddingLeft: 5, fontFamily: 'Prompt-Regular', fontWeight: '500'}}>{this.state.membel_level}</Text>
</TouchableOpacity>
<View style={{flexDirection: 'row', alignItems: 'flex-end'}}>
<Text style={[styles.textPoint, {marginRight: 5, fontSize: 20}]}>{parseFloat(this.state.point).toLocaleString()}</Text>
<Text style={{fontSize: 10, paddingBottom: 6, color: 'white', fontFamily: 'Prompt-Regular'}}>Points</Text>
</View>
</View>
</LinearGradient>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('MyRewards')} style={{flex: 1}}>
<LinearGradient start={{x: 0, y: 0}} end={{x: 1, y: 0}} colors={['#1BCEDF', '#002A57']} style={styles.pointContain}>
<IconFeather name="smile" color="white" size={32}/>
<Text style={[styles.textPoint, {fontSize: 20}]}>My Rewards</Text>
</LinearGradient>
</TouchableOpacity>
</View>
<View style={styles.categoryContain}>
<Text style={{color: 'white', fontWeight: 'bold', fontSize: 24, fontFamily: 'Prompt-Regular'}}>Category Rewards</Text>
<View style={{flexDirection: 'row', flex: 1, paddingVertical: 18}}>
{
cateGoryRewards && cateGoryRewards.map((category, index) => (
<TouchableOpacity style={[styles.subCateContain, {marginRight: index === (cateGoryRewards.length -1) ? 0 : 5}]}
onPress={() => this.props.navigation.navigate('AllRewards', {id: category.id})}
key={`reward_${category.id}_${index}`}
>
<Image source={category.source} style={{height: 56}} resizeMode={'contain'}/>
<View style={styles.textDiscountContain}>
<Text style={styles.textDiscount}>{category.text}</Text>
</View>
</TouchableOpacity>
))
}
</View>
</View>
<View style={{flex: 0.6}}>
<View style={{flexDirection: 'row', justifyContent: 'space-between', marginVertical: 15, alignItems: 'flex-end'}}>
<Text style={styles.textPoint}>All Rewards</Text>
{
allRewards && allRewards.length > 1 &&
<TouchableOpacity onPress={() => this.props.navigation.navigate('AllRewards')}>
<Text style={{fontSize: 18, color: 'white', fontWeight: '500', fontFamily: 'Prompt-Regular'}}>See More ></Text>
</TouchableOpacity>
}
</View>
{
allRewards && allRewards.length > 0
? <View style={{flex: 1, flexDirection: 'row'}}>
<FlatList
data={allRewards}
renderItem={({ item }) => this.renderItemImages(item)}
horizontal={true}
showsHorizontalScrollIndicator={false}
keyExtractor={this._keyExtractorNewHead}
initialNumToRender={2}
extraData={allRewards}
// onScroll={this._onCarouselScroll}
/>
</View>
: <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', margin: 0,padding:16,borderRadius:5,backgroundColor:'white'}}>
<Text style={{fontSize: 16, textAlign: 'center', fontFamily: 'Prompt-Regular'}}> Rewards not found. </Text>
</View>
}
</View>
</View>
</ScrollView>
</BackgroundImage>
<IndicatorLoading loadingVisible={this.state.isLoading}/>
</LinearGradient>
);
}
}
const styles = StyleSheet.create({
contentContainer: {
paddingVertical: 0,
},
pointContain: {
paddingHorizontal: 7,
flex: 1,
borderRadius: 5,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between'
},
textPoint: {
color: 'white',
fontSize: 24,
fontWeight: 'bold',
fontFamily: 'Prompt-Regular',
},
categoryContain: {
flex: 0.3,
backgroundColor: '#00420A',
padding: 10,
marginTop: 8,
borderRadius: 6
},
subCateContain: {
flex: 1
},
textDiscount: {
color: 'white',
fontWeight: '600',
fontSize: 10.5,
width: '100%',
textAlign: 'center',
fontFamily: 'Prompt-Regular'
},
textDiscountContain: {
backgroundColor: '#318F00',
paddingVertical: 5,
paddingHorizontal: 5,
borderRadius: 50,
marginTop: -5
},
membershipLevelBox: {
backgroundColor: 'white',
paddingHorizontal: 5,
paddingVertical: 5,
borderBottomLeftRadius: 5,
borderBottomRightRadius: 5,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center'
}
});
const mapDisPatchToProps = state => {
return state.app
}
const propSet = dispatch => bindActionCreators({
appSetUser,
}, dispatch)
export default connect(mapDisPatchToProps, propSet)(RedeemScreen)