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 * as React from 'react';
import { NavigationContainer } from '@react-navigation/native'; import {NavigationContainer} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack'; import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Splash from './src/screens/Splash'; import Splash from './src/screens/Splash';
import Home from './src/screens/Home'; import Home from './src/screens/Home';
import Login from './src/screens/Login'; import Login from './src/screens/Login';
import Otp from './src/screens/Otp'; import Otp from './src/screens/Otp';
import { connect } from 'react-redux'; import {connect} from 'react-redux';
const mapStateToProps = state => { const mapStateToProps = state => {
return { return {
profile: state.profile profile: state.profile
} }
} }
const Stack = createNativeStackNavigator(); const Stack = createNativeStackNavigator();
function Navigator(props) { function Navigator(props) {
return ( return (
<NavigationContainer> <NavigationContainer>
<Stack.Navigator> <Stack.Navigator>
<Stack.Screen options={{headerShown: false}} name="Splash" component={Splash} /> <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="Login" component={Login} options={{headerShown: false}} /> <Stack.Screen name="Home" component={Home}/>
<Stack.Screen name="Otp" component={Otp} options={{headerShown: false}} /> </Stack.Navigator>
</> </NavigationContainer>
) : ( );
<>
<Stack.Screen name="Home" component={Home} />
</>
)}
</Stack.Navigator>
</NavigationContainer>
);
} }
export default connect(mapStateToProps)(Navigator); 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", "resolved": "https://registry.npmjs.org/react-native-select-dropdown/-/react-native-select-dropdown-1.2.0.tgz",
"integrity": "sha512-qFbldUJFjcruyEmxQThuUtsPYGt7aGYrVtgDfivuJCodjGJEFed2DvcZUd9JJYk1uWe/OfSxWi2KsXYeoB2ZIw==" "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": { "react-native-vector-icons": {
"version": "8.1.0", "version": "8.1.0",
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-8.1.0.tgz", "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-safe-area-context": "^3.3.2",
"react-native-screens": "^3.8.0", "react-native-screens": "^3.8.0",
"react-native-select-dropdown": "^1.2.0", "react-native-select-dropdown": "^1.2.0",
"react-native-swiper-flatlist": "^3.0.15",
"react-native-vector-icons": "^8.1.0", "react-native-vector-icons": "^8.1.0",
"react-redux": "^7.2.5", "react-redux": "^7.2.5",
"redux": "^4.1.1", "redux": "^4.1.1",

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

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

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

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

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

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

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

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

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

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

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

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

Loading…
Cancel
Save