master
hamed 3 years ago
parent 0e8ad43d2e
commit 93c1e23879
  1. 39
      navigation.js
  2. 5
      package-lock.json
  3. 1
      package.json
  4. 2
      src/components/FormButton.js
  5. 7
      src/screens/Home/components/backgroundTile.js
  6. 36
      src/screens/Home/components/carousel.js
  7. 2
      src/screens/Home/components/flexAround.js
  8. 2
      src/screens/Home/components/shop.js
  9. 7
      src/screens/Home/index.js
  10. 46
      src/screens/Login/index.js
  11. 72
      src/screens/Otp/index.js
  12. 4
      src/screens/Splash/index.js
  13. 16
      src/services/api/index.js
  14. 16
      src/services/api/utils.js
  15. 6
      src/utils/index.js

@ -1,38 +1,31 @@
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Splash from './src/screens/Splash';
import Home from './src/screens/Home';
import Login from './src/screens/Login';
import Otp from './src/screens/Otp';
import { connect } from 'react-redux';
import {connect} from 'react-redux';
const mapStateToProps = state => {
return {
profile: state.profile
}
return {
profile: state.profile
}
}
const Stack = createNativeStackNavigator();
function Navigator(props) {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen options={{headerShown: false}} name="Splash" component={Splash} />
{!props.profile.token ? (
<>
<Stack.Screen name="Login" component={Login} options={{headerShown: false}} />
<Stack.Screen name="Otp" component={Otp} options={{headerShown: false}} />
</>
) : (
<>
<Stack.Screen name="Home" component={Home} />
</>
)}
</Stack.Navigator>
</NavigationContainer>
);
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen options={{headerShown: false}} name="Splash" component={Splash}/>
<Stack.Screen name="Login" component={Login} options={{headerShown: false}}/>
<Stack.Screen name="Otp" component={Otp} options={{headerShown: false}}/>
<Stack.Screen name="Home" component={Home}/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default connect(mapStateToProps)(Navigator);

5
package-lock.json generated

@ -7514,6 +7514,11 @@
"resolved": "https://registry.npmjs.org/react-native-select-dropdown/-/react-native-select-dropdown-1.2.0.tgz",
"integrity": "sha512-qFbldUJFjcruyEmxQThuUtsPYGt7aGYrVtgDfivuJCodjGJEFed2DvcZUd9JJYk1uWe/OfSxWi2KsXYeoB2ZIw=="
},
"react-native-swiper-flatlist": {
"version": "3.0.15",
"resolved": "https://registry.npmjs.org/react-native-swiper-flatlist/-/react-native-swiper-flatlist-3.0.15.tgz",
"integrity": "sha512-ajWTGChYE2KuJ/LsHShZG5KnM6ZfytMER3YqeDMqJLtFmxUqq9SFrfsvV7SBChbGtKg82rVx9lzfsAwp9q/qJw=="
},
"react-native-vector-icons": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-8.1.0.tgz",

@ -23,6 +23,7 @@
"react-native-safe-area-context": "^3.3.2",
"react-native-screens": "^3.8.0",
"react-native-select-dropdown": "^1.2.0",
"react-native-swiper-flatlist": "^3.0.15",
"react-native-vector-icons": "^8.1.0",
"react-redux": "^7.2.5",
"redux": "^4.1.1",

@ -28,4 +28,4 @@ export default function FormButton({text, color, onPress}) {
<Text style={styles.text}>{text}</Text>
</Pressable>
);
}
}

@ -24,7 +24,10 @@ const backgroundTile = ({ item }) => {
const styles = StyleSheet.create({
container: {
margin: 5,
borderRadius: 10
borderRadius: 10,
overflow: 'hidden',
alignItems: 'center',
justifyContent: 'center',
},
cover: {
minHeight: "100%",
@ -36,7 +39,7 @@ const styles = StyleSheet.create({
},
title: {
fontSize: 21,
fontWeight: 600,
fontWeight: '600',
marginBottom: 5,
color: "white"
},

@ -1,27 +1,27 @@
import React from "react";
import { ImageBackground, Dimensions, StyleSheet, View } from "react-native";
// import { SwiperFlatList } from "react-native-swiper-flatlist";
import { SwiperFlatList } from "react-native-swiper-flatlist";
const Carousel = ({ list }) => {
return (
<View style={styles.container}>
{/*<SwiperFlatList*/}
{/* autoplay*/}
{/* autoplayDelay={2}*/}
{/* autoplayLoop*/}
{/* index={2}*/}
{/* // showPagination*/}
{/* data={list}*/}
{/* renderItem={({ item }) => (*/}
{/* <View style={[styles.child]}>*/}
{/* <ImageBackground*/}
{/* source={{ uri: item.imageUrl }}*/}
{/* resizeMode="cover"*/}
{/* style={styles.image}*/}
{/* ></ImageBackground>*/}
{/* </View>*/}
{/* )}*/}
{/*/>*/}
<SwiperFlatList
autoplay
autoplayDelay={2}
autoplayLoop
index={2}
// showPagination
data={list}
renderItem={({ item }) => (
<View style={[styles.child]}>
<ImageBackground
source={{ uri: item.imageUrl }}
resizeMode="cover"
style={styles.image}
></ImageBackground>
</View>
)}
/>
</View>
);
};

@ -39,7 +39,7 @@ const styles = StyleSheet.create({
},
title: {
fontSize: 21,
fontWeight: 600,
fontWeight: '600',
marginBottom: 5,
color: "white"
},

@ -45,7 +45,7 @@ const styles = StyleSheet.create({
},
title: {
fontSize: 18,
fontWeight: 600,
fontWeight: '600',
marginBottom: 5,
color: "white"
}

@ -6,7 +6,7 @@ import Identifier from "./components/Identifier";
// Within your render function
function Home() {
return (
<ScrollView style={styles.container}>
<ScrollView contentContainerStyle={styles.contentContainerStyle} style={styles.container}>
{data?.map((item, i) => (
<Identifier {...item} key={i} />
))}
@ -16,11 +16,14 @@ function Home() {
// Later on in your styles..
const styles = StyleSheet.create({
contentContainerStyle: {
paddingBottom: 50
},
container: {
width: Dimensions.get("window").width,
backgroundColor: "white",
flexDirection: "column",
padding: 5
padding: 5,
}
});

@ -1,5 +1,5 @@
import React, {useState} from 'react';
import {View, Text, Image, Button, Dimensions, TextInput, TouchableHighlight} from 'react-native';
import {View, Text, Image, ActivityIndicator, Dimensions, TextInput, TouchableHighlight} from 'react-native';
import Logo from '../../assets/images/logo.png';
import IranFlag from "./components/IranFlag";
import {digitToEn, digitToPersian} from "../../utils";
@ -12,6 +12,7 @@ let faNums = ['۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹', '۰']
function Login(props) {
const [phone, setPhone] = useState('');
const [loading, setLoading] = useState(false)
const onChangePhone = (value) => {
let items = digitToPersian(value).split('');
@ -28,15 +29,19 @@ function Login(props) {
}
const submit = async () => {
// if (!checkPhoneNumber()) {
// return asyncAwesomeAlert('خطا', 'شماره وارد شده اشتباه است', {showCancelButton: false});
// }
// let res = await services.getSmsCode({
// cellphone: '09' + digitToEn(phone)
// })
// if (res.ok) {
props.navigation.navigate('Otp', {phone: phone});
// }
setLoading(true)
if (!checkPhoneNumber()) {
setLoading(false)
return asyncAwesomeAlert('خطا', 'شماره وارد شده اشتباه است', {showCancelButton: false});
}
let res = await services.getSmsCode({
cellphone: '09' + digitToEn(phone)
})
if (res.ok) {
setLoading(false)
props.navigation.navigate('Otp', {phone: '09' + digitToEn(phone)});
}
setLoading(false)
}
return (
@ -91,12 +96,15 @@ function Login(props) {
color: '#a2a2a2',
fontSize: 18
}}
maxLength={9}
underlineColorAndroid={'transparent'}
value={phone}
onChangeText={text => onChangePhone(text)}
/>
</View>
<TouchableHighlight style={{
<TouchableHighlight
disabled={loading}
style={{
width: width - 10,
height: width / 9,
backgroundColor: '#6cbe44',
@ -106,12 +114,16 @@ function Login(props) {
marginTop: 15,
}}
onPress={() => submit()}>
<Text style={{
color: 'white',
fontSize: 18,
}}>
{'ادامه'}
</Text>
{loading ?
<ActivityIndicator size={'small'} color={'white'}/>
:
<Text style={{
color: 'white',
fontSize: 18,
}}>
{'ادامه'}
</Text>
}
</TouchableHighlight>
</View>
);

@ -1,10 +1,23 @@
import React, {useEffect, useState} from 'react'
import {View, Text, Image, TextInput, TouchableHighlight, Dimensions, StyleSheet, TouchableOpacity} from 'react-native';
import {
View,
Text,
Image,
TextInput,
TouchableHighlight,
Dimensions,
StyleSheet,
TouchableOpacity,
ActivityIndicator
} from 'react-native';
import {connect} from 'react-redux';
import Logo from "../../assets/images/logo.png";
import IranFlag from "../Login/components/IranFlag";
import {digitToEn, digitToPersian} from "../../utils";
import services from "./services";
import AsyncStorage from "@react-native-community/async-storage";
import {buildAction} from "../../reducers/DefaultReducer";
import {PROFILE_RECORD} from "../../actions/actionTypes";
const {width} = Dimensions.get('window')
let ref1;
@ -13,6 +26,13 @@ let ref3;
let ref4;
let timer = 60;
const mapStateToProps = state => {
return {
profile: state.profile,
}
}
function Otp(props) {
let faNums = ['۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹', '۰']
@ -21,6 +41,7 @@ function Otp(props) {
const [thirdCode, setThirdCode] = useState('');
const [fourthCode, setFourthCode] = useState('');
const [time, setTime] = useState(60);
const [loading, setLoading] = useState(false);
const checkValue = (value) => {
return faNums.includes(digitToPersian(value));
@ -45,6 +66,7 @@ function Otp(props) {
break;
case '4':
setFourthCode(digitToPersian(value))
submit();
break;
}
}
@ -54,13 +76,29 @@ function Otp(props) {
}
const submit = async () => {
setLoading(true)
let res = await services.sendOtpCode({
cellphone: props.route.params.phone,
otp: getEnCode()
otp: String(getEnCode()),
applicationToken: "1",
userToken: "1"
})
if (res.ok) {
console.log(res)
setLoading(false)
await AsyncStorage.setItem('accessToken', res.data.accessToken);
await AsyncStorage.setItem('refreshToken', res.data.refreshToken);
let action = buildAction(PROFILE_RECORD);
await props.dispatch(action({
accessToken: res.data.accessToken,
refreshToken: res.data.refreshToken,
...res.data.profile,
}))
props.navigation.reset({
index: 0,
routes: [{name: 'Home'}]
})
}
setLoading(false)
}
useEffect(() => {
@ -148,6 +186,7 @@ function Otp(props) {
/>
</View>
<TouchableOpacity
disabled={loading}
style={{
width: width - 10,
height: width / 9,
@ -158,12 +197,15 @@ function Otp(props) {
marginTop: 15,
}}
onPress={() => submit()}>
<Text style={{
color: 'white',
fontSize: 18,
}}>
{'ثبت'}
</Text>
{loading ?
<ActivityIndicator color={'white'} size={'small'} /> :
<Text style={{
color: 'white',
fontSize: 18,
}}>
{'ثبت'}
</Text>
}
</TouchableOpacity>
<View>
<Text style={{marginTop: 30, textAlign: 'center'}}>
@ -174,10 +216,10 @@ function Otp(props) {
marginTop: 20,
}}
onPress={() => {
if (time !== 0) {
return
}
props.navigation.goBack();
props.navigation.reset({
index: 0,
routes: [{ name: 'Login' }],
});
}}>
<Text style={{textAlign: 'center'}}>
{'بازگشت به مرحله قبل و اصلاح شماره'}
@ -193,11 +235,11 @@ const styles = StyleSheet.create({
width: width / 13 * 2,
height: width / 16 * 2,
backgroundColor: '#a2a2a2',
color: '#333',
color: '#000',
fontSize: 22,
borderRadius: 8,
textAlign: 'center'
}
})
export default Otp;
export default connect(mapStateToProps)(Otp);

@ -15,7 +15,7 @@ function Splash({navigation, profile}) {
useEffect(() => {
setTimeout(() => {
!profile.token ? navigation.reset({
!profile.accessToken ? navigation.reset({
index: 0,
routes: [{ name: 'Login' }],
}) : navigation.reset({
@ -23,7 +23,7 @@ function Splash({navigation, profile}) {
routes: [{ name: 'Home' }],
})
}, 2000)
}, [])
}, [profile])
return (
<View style={{justifyContent: 'center', alignItems: 'center', flex: 1}}>

@ -51,9 +51,14 @@ export async function fetchApi(
if (['POST', 'PUT'].includes(method)) {
options.body = JSON.stringify(payload);
}
console.log('===========================')
console.log(await getUrl(endPoint, dev))
console.log(options)
console.log('===========================')
try {
// console.log('req', await getUrl(endPoint), options)
let res = await fetchRetry(await getUrl(endPoint, dev), options);
clearTimeout(timeout);
let statusCode = res.status;
// console.log('RES', { statusCode, url: await getUrl(endPoint) })
@ -77,9 +82,14 @@ export async function fetchApi(
return data;
}
if (!res.ok) {
if (data.hasOwnProperty('message')) {
toastMessage(data.message);
}
// if (data.hasOwnProperty('message')) {
// toastMessage(data.message);
// }
console.log('=====================')
console.log(statusCode)
console.log(data)
console.log(error)
console.log('=====================')
if (statusCode === 403) {
console.log('req-401', await getUrl(endPoint), options);

@ -42,9 +42,7 @@ export const unexpectedAlert = async () => {
// ])
}
export const getToken = async () => {
let user = await AsyncStorage.getItem('UID_USER')
if (!user) return ''
let { token } = JSON.parse(user)
let token = await AsyncStorage.getItem('accessToken')
if (!token) {
return ''
}
@ -68,7 +66,7 @@ export const getUrl = async (endpoint, dev) => {
return apiConfig.splash + endpoint
}
let base_urls = await getBaseUrls()
return base_urls.backend + endpoint
return base_urls + endpoint
}
export const isUnexpected = (statusCode) => {
@ -77,8 +75,8 @@ export const isUnexpected = (statusCode) => {
}
export const renewTokenHandler = async () => {
try {
let splashData = JSON.parse(await AsyncStorage.getItem('UID_USER'))
if (!splashData || !splashData.refresh_token) {
let refreshToken = JSON.parse(await AsyncStorage.getItem('refreshToken'))
if (!refreshToken) {
return {
ok: false,
restart: true
@ -87,7 +85,7 @@ export const renewTokenHandler = async () => {
const options = {
method: 'POST',
body: JSON.stringify({
refresh_token: splashData.refresh_token
refresh_token: refreshToken
}),
headers: {
Accept: 'application/json;charset=utf-8',
@ -98,8 +96,8 @@ export const renewTokenHandler = async () => {
let { data } = await res.json()
const statusCode = res.status
if (statusCode == 200) {
splashData.token = data.token
await AsyncStorage.setItem('UID_USER', JSON.stringify(splashData))
await AsyncStorage.setItem('refreshToken', JSON.stringify(data.refreshToken))
await AsyncStorage.setItem('accessToken', JSON.stringify(data.accessToken))
return {
ok: true
}

@ -21,3 +21,9 @@ export const digitToEn = (digit) => {
}
return digitArray.join('')
}
export const waitToFinish = async (setLoading, func) => {
setLoading(true);
await func();
setLoading(false)
}

Loading…
Cancel
Save