splash & login & otp

master
hamed 3 years ago
parent 19434004e0
commit 5169182cd8
  1. 18
      ios/Podfile.lock
  2. 3
      ios/RnDanovin.xcodeproj/project.pbxproj
  3. 43
      ios/RnDanovin/Images.xcassets/AppIcon.appiconset/Contents.json
  4. 4
      navigation.js
  5. 10
      package-lock.json
  6. 2
      package.json
  7. BIN
      src/assets/images/logo.png
  8. 23
      src/screens/Home/components/2d.js
  9. 24
      src/screens/Home/components/3d.js
  10. 38
      src/screens/Home/components/Identifier.js
  11. 49
      src/screens/Home/components/backgroundTile.js
  12. 50
      src/screens/Home/components/carousel.js
  13. 52
      src/screens/Home/components/flexAround.js
  14. 54
      src/screens/Home/components/shop.js
  15. 140
      src/screens/Home/data.js
  16. 30
      src/screens/Home/index.js
  17. 46
      src/screens/Home/navbar.js
  18. 17
      src/screens/Login/components/IranFlag.js
  19. 125
      src/screens/Login/index.js
  20. 10
      src/screens/Login/services/index.js
  21. 18
      src/screens/Login/services/mocks.js
  22. 13
      src/screens/Login/services/services.js
  23. 198
      src/screens/Otp/index.js
  24. 10
      src/screens/Otp/services/index.js
  25. 18
      src/screens/Otp/services/mocks.js
  26. 13
      src/screens/Otp/services/services.js
  27. 16
      src/screens/Splash/index.js
  28. 3
      src/services/api/config.js
  29. 4
      src/services/api/utils.js
  30. 23
      src/utils/index.js

@ -272,6 +272,8 @@ PODS:
- React-jsinspector (0.66.0)
- React-logger (0.66.0):
- glog
- react-native-restart (0.0.22):
- React-Core
- react-native-safe-area-context (3.3.2):
- React-Core
- React-perflogger (0.66.0)
@ -341,9 +343,13 @@ PODS:
- React-perflogger (= 0.66.0)
- RNCAsyncStorage (1.15.9):
- React-Core
- RNDeviceInfo (8.4.5):
- React-Core
- RNScreens (3.8.0):
- React-Core
- React-RCTImage
- RNVectorIcons (8.1.0):
- React-Core
- Yoga (1.14.0)
- YogaKit (1.18.1):
- Yoga (~> 1.14)
@ -389,6 +395,7 @@ DEPENDENCIES:
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- react-native-restart (from `../node_modules/react-native-restart`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
@ -403,7 +410,9 @@ DEPENDENCIES:
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
- RNScreens (from `../node_modules/react-native-screens`)
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
SPEC REPOS:
@ -458,6 +467,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/jsinspector"
React-logger:
:path: "../node_modules/react-native/ReactCommon/logger"
react-native-restart:
:path: "../node_modules/react-native-restart"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
React-perflogger:
@ -486,8 +497,12 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon"
RNCAsyncStorage:
:path: "../node_modules/@react-native-async-storage/async-storage"
RNDeviceInfo:
:path: "../node_modules/react-native-device-info"
RNScreens:
:path: "../node_modules/react-native-screens"
RNVectorIcons:
:path: "../node_modules/react-native-vector-icons"
Yoga:
:path: "../node_modules/react-native/ReactCommon/yoga"
@ -522,6 +537,7 @@ SPEC CHECKSUMS:
React-jsiexecutor: 6a05173dc0142abc582bd4edd2d23146b8cc218a
React-jsinspector: be95ad424ba9f7b817aff22732eb9b1b810a000a
React-logger: 9a9cd87d4ea681ae929b32ef580638ff1b50fb24
react-native-restart: d4ea7637e193da7558d229b3704d500ec0d75f9c
react-native-safe-area-context: 5cf05f49df9d17261e40e518481f2e334c6cd4b5
React-perflogger: 1f554c2b684e2f484f9edcdfdaeedab039fbaca8
React-RCTActionSheet: 610d5a5d71ab4808734782c8bca6a12ec3563672
@ -536,7 +552,9 @@ SPEC CHECKSUMS:
React-runtimeexecutor: 4bb657a97aa74568d9ed634c8bd478299bb8a3a6
ReactCommon: eb059748e842a1a86025ebbd4ac9d99e74492f88
RNCAsyncStorage: d599364c12b1ddb042cc2d7ab6f8258962b83097
RNDeviceInfo: 3b3bbe00f478907223daa580b6882f0bae162f72
RNScreens: 6e1ea5787989f92b0671049b808aef64fa1ef98c
RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4
Yoga: c11abbf5809216c91fcd62f5571078b83d9b6720
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a

@ -364,7 +364,6 @@
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-RnDanovin/Pods-RnDanovin-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@ -557,6 +556,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = M52GT6568Q;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = RnDanovin/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -583,6 +583,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = M52GT6568Q;
INFOPLIST_FILE = RnDanovin/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",

@ -2,37 +2,52 @@
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
"scale" : "3x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}

@ -22,8 +22,8 @@ function Navigator(props) {
<Stack.Screen options={{headerShown: false}} name="Splash" component={Splash} />
{!props.profile.token ? (
<>
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Otp" component={Otp} />
<Stack.Screen name="Login" component={Login} options={{headerShown: false}} />
<Stack.Screen name="Otp" component={Otp} options={{headerShown: false}} />
</>
) : (
<>

10
package-lock.json generated

@ -7471,6 +7471,11 @@
"nullthrows": "^1.1.1"
}
},
"react-native-device-info": {
"version": "8.4.5",
"resolved": "https://registry.npmjs.org/react-native-device-info/-/react-native-device-info-8.4.5.tgz",
"integrity": "sha512-0uKO9rBF4Uv8X+xLJdR6HkuyB2C4gNEcWdHPcS1MhtsIExP6NTbC3tgkrUUWZ7HODbn1MFx5LG5cGDe4X0zhWA=="
},
"react-native-iphone-x-helper": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz",
@ -7486,6 +7491,11 @@
"react-native-iphone-x-helper": "^1.3.1"
}
},
"react-native-restart": {
"version": "0.0.22",
"resolved": "https://registry.npmjs.org/react-native-restart/-/react-native-restart-0.0.22.tgz",
"integrity": "sha512-XwCqAMAKsO8yCM3xACPFKvkDQZe41lcavOuO0gUEu803IuTLtciualCq/qs83ryRDCDh1jkXYRqFjsGjLMCN3Q=="
},
"react-native-safe-area-context": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-3.3.2.tgz",

@ -17,7 +17,9 @@
"react": "17.0.2",
"react-native": "0.66.0",
"react-native-awesome-alerts": "^1.5.2",
"react-native-device-info": "^8.4.5",
"react-native-paper": "^4.9.2",
"react-native-restart": "0.0.22",
"react-native-safe-area-context": "^3.3.2",
"react-native-screens": "^3.8.0",
"react-native-select-dropdown": "^1.2.0",

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

@ -0,0 +1,23 @@
import React from "react";
import { View, StyleSheet, Dimensions } from "react-native";
import Identifier from "./Identifier";
function component2D({ list, flexDirection }) {
return (
<View style={[styles.container, { flexDirection: flexDirection }]}>
{list.map((item, i) => (
<Identifier {...item} key={i} />
))}
</View>
);
}
const { width } = Dimensions.get("window");
const styles = StyleSheet.create({
container: {
// width,
borderRadius: 10,
flex: 1
}
});
export default component2D;

@ -0,0 +1,24 @@
import React from "react";
import { View, StyleSheet, Dimensions } from "react-native";
import Identifier from "./Identifier";
function component3D({ list }) {
return (
<View style={styles.container}>
{list.map((item, i) => (
<Identifier {...item} key={i} />
))}
</View>
);
}
const { width } = Dimensions.get("window");
const styles = StyleSheet.create({
container: {
// width,
borderRadius: 10,
flex: 1,
flexDirection: "row-reverse"
}
});
export default component3D;

@ -0,0 +1,38 @@
import React from "react";
import Carousel from "./carousel";
import Component2D from "./2d";
import Component3D from "./3d";
import FlexAround from "./flexAround";
import BackgroundTile from "./backgroundTile";
import Shop from "./shop.js";
const Identifier = (item) => {
let component;
switch (item.name) {
case "carousel":
component = <Carousel list={item.list} />;
break;
case "2d":
component = (
<Component2D list={item.items} flexDirection={item.flexDirection} />
);
break;
case "3d":
component = <Component3D list={item.items} />;
break;
case "flex-around":
component = <FlexAround item={item} />;
break;
case "background-tile":
component = <BackgroundTile item={item} />;
break;
case "shop":
component = <Shop item={item} />;
break;
default:
component = null;
}
return <>{component}</>;
};
export default Identifier;

@ -0,0 +1,49 @@
import React from "react";
import { StyleSheet, View, Text, ImageBackground } from "react-native";
const backgroundTile = ({ item }) => {
return (
<ImageBackground
source={{ uri: item.imageUrl }}
resizeMode="cover"
style={[styles.container, { flex: item.flex }]}
>
<View
style={[
styles.cover,
{ backgroundColor: item.backgroundColor, alignItems: item.alignItems }
]}
>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.subTitle}>{item.subTitle}</Text>
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
container: {
margin: 5,
borderRadius: 10
},
cover: {
minHeight: "100%",
minWidth: "100%",
flexDirection: "column",
justifyContent: "center",
padding: 10,
borderRadius: 10
},
title: {
fontSize: 21,
fontWeight: 600,
marginBottom: 5,
color: "white"
},
subTitle: {
fontSize: 14,
color: "white"
}
});
export default backgroundTile;

@ -0,0 +1,50 @@
import React from "react";
import { ImageBackground, Dimensions, StyleSheet, View } from "react-native";
// 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>*/}
{/* )}*/}
{/*/>*/}
</View>
);
};
const { width } = Dimensions.get("window");
const styles = StyleSheet.create({
container: {
minHeight: 300,
borderRadius: 10,
margin: 5
},
child: {
width,
justifyContent: "center",
borderRadius: 10,
alignItems: "center"
},
image: {
width,
flex: 1,
justifyContent: "center",
borderRadius: 10
}
});
export default Carousel;

@ -0,0 +1,52 @@
import React from "react";
import { StyleSheet, View, Text, Image } from "react-native";
const FlexAround = ({ item }) => {
return (
<View
style={[
styles.container,
{ flex: item.flex, backgroundColor: item.backgroundColor }
]}
>
<View style={[styles.column]}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.subTitle}>{item.subTitle}</Text>
</View>
<Image source={{ uri: item.imageUrl }} style={styles.image} />
</View>
);
};
const styles = StyleSheet.create({
container: {
borderRadius: 10,
flex: 1,
paddingVertical: 30,
flexDirection: "row-reverse",
alignItems: "center",
justifyContent: "space-around",
textAlign: "right",
margin: 5
},
column: {
display: "flex",
flexDirection: "column"
},
image: {
width: 60,
height: 60
},
title: {
fontSize: 21,
fontWeight: 600,
marginBottom: 5,
color: "white"
},
subTitle: {
fontSize: 14,
color: "white"
}
});
export default FlexAround;

@ -0,0 +1,54 @@
import React from "react";
import { StyleSheet, View, Text, Image } from "react-native";
const Shop = ({ item }) => {
return (
<View
style={[
styles.container,
{ flex: item.flex, backgroundColor: item.backgroundColor }
]}
>
<Text style={styles.title}>{item.title}</Text>
<View style={[styles.list]}>
{item.items.map((item1) => (
<View>
<Image source={{ uri: item1.imageUrl }} style={styles.product} />
</View>
))}
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
borderRadius: 10,
flex: 1,
paddingVertical: 5,
paddingHorizontal: 10,
flexDirection: "column",
textAlign: "right",
margin: 5
},
list: {
display: "flex",
flexDirection: "row",
justifyContent: "space-around",
marginTop: 10
},
product: {
width: 50,
height: 65,
borderRadius: 10
},
title: {
fontSize: 18,
fontWeight: 600,
marginBottom: 5,
color: "white"
}
});
export default Shop;

@ -0,0 +1,140 @@
const data = [
{
name: "carousel",
list: [
{
id: 0,
imageUrl: "https://dnvn.ir/api/v1/file/5299"
},
{
id: 1,
imageUrl: "https://dnvn.ir/api/v1/file/6581"
},
{
id: 2,
imageUrl: "https://dnvn.ir/api/v1/file/6586"
}
]
},
{
name: "2d",
flexDirection: "row-reverse",
items: [
{
name: "flex-around",
title: "qr خوان",
subTitle: "در صفحات کتاب هوشمند",
imageUrl: "https://dnvn.ir/api/v1/file/1855",
backgroundColor: "blue",
flex: 1
},
{
name: "flex-around",
title: "واقعیت افزوده",
subTitle: "فعال شده و دیجیتال",
imageUrl: "https://dnvn.ir/api/v1/file/1851",
backgroundColor: "green",
flex: 1
}
]
},
{
name: "2d",
flexDirection: "row-reverse",
items: [
{
name: "flex-around",
title: "qr خوان",
subTitle: "در صفحات کتاب هوشمند",
imageUrl: "https://dnvn.ir/api/v1/file/1855",
backgroundColor: "blue",
flex: 1.6
},
{
name: "background-tile",
title: "کتاب های من",
subTitle: "فعال شده و دیجیتال",
imageUrl: "https://dnvn.ir/api/v1/file/1860",
backgroundColor: "#ff00ff77",
flex: 1,
alignItems: "flex-end"
}
]
},
{
name: "2d",
flexDirection: "row-reverse",
items: [
{
name: "background-tile",
title: "بلاگ",
subTitle: "",
imageUrl: "https://dnvn.ir/api/v1/file/1852",
backgroundColor: "#00ff0066",
flex: 1,
alignItems: "center"
},
{
name: "shop",
title: "فروشگاه",
backgroundColor: "#8888ff",
flex: 1.6,
items: [
{
id: 0,
imageUrl: "https://dnvn.ir/api/v1/file/1857"
},
{
id: 1,
imageUrl: "https://dnvn.ir/api/v1/file/1858"
},
{
id: 2,
imageUrl: "https://dnvn.ir/api/v1/file/1859"
}
]
}
]
},
{
name: "3d",
items: [
{
name: "2d",
flexDirection: "column",
items: [
{
name: "background-tile",
title: "پیگیری سفارشات",
subTitle: "",
imageUrl: "",
backgroundColor: "#ff5555",
flex: 1,
alignItems: "center"
},
{
name: "background-tile",
title: "پشتیبانی",
subTitle: "",
imageUrl: "",
backgroundColor: "#ffaa00",
flex: 1,
alignItems: "center"
}
]
},
{
name: "background-tile",
title: "بلاگ",
subTitle: "",
imageUrl: "https://dnvn.ir/api/v1/file/1853",
backgroundColor: "#00ffff66",
flex: 1,
alignItems: "center"
}
]
}
];
export default data;

@ -1,13 +1,27 @@
import React from 'react'
import { View, Text } from 'react-native';
import {connect} from 'react-redux';
import React from "react";
import { View, StyleSheet, Dimensions, ScrollView } from "react-native";
import data from "./data";
import Identifier from "./components/Identifier";
function Home({}) {
// Within your render function
function Home() {
return (
<View>
<Text></Text>
</View>
)
<ScrollView style={styles.container}>
{data?.map((item, i) => (
<Identifier {...item} key={i} />
))}
</ScrollView>
);
}
// Later on in your styles..
const styles = StyleSheet.create({
container: {
width: Dimensions.get("window").width,
backgroundColor: "white",
flexDirection: "column",
padding: 5
}
});
export default Home;

@ -0,0 +1,46 @@
import React from "react";
import { Button, StyleSheet, Text, View, Dimensions } from "react-native";
function App() {
return (
<View style={styles.navbar}>
<View style={[styles.flex, styles.row, styles.alignCenter]}>
<Text style={styles.head}>دانوین</Text>
</View>
<Button title="ورود" color="#6cbe44" />
</View>
);
}
const styles = StyleSheet.create({
navbar: {
position: "fixed",
display: "flex",
paddingHorizontal: 10,
flexDirection: "row-reverse",
left: 0,
top: 0,
width: Dimensions.get("window").width,
height: 60,
backgroundColor: "#ccc",
justifyContent: "space-between",
alignItems: "center"
},
head: {
fontWeight: "bold",
fontSize: 20,
marginRight: 10
},
flex: {
display: "flex"
},
row: {
flexDirection: "row-reverse"
},
alignCenter: {
alignItems: "center"
}
});
export default App;

@ -0,0 +1,17 @@
import React from 'react';
import {Image, Dimensions} from "react-native";
const {width} = Dimensions.get('window')
function IranFlag() {
return (
<Image source={{uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAUCAYAAACaq43EAAAABHNCSVQICAgIfAhkiAAAAiBJREFUSEvtVkFrU0EQ/mb3vTRJ08bURAVFA4K0CIKCNw8WQQQPKqj/oN56qgePnv0Vnjy0YPAiItWLFw8VtWhF9BClGE3S5tnmxaR5u+PuPgIKSnlQ46UDww6zM/PtNztveTR3HwEIeQxRBHCS5irgIWI6KAKmd4GH0nXX6sWVO+6Ou9F3p2kvj0LmCD6uPcXB8VO/+X89lY2rbS4jnz6ErD/h4npGD4ydQOvHJ2z2aiiNTrqUQV1rV1vPUMxOzlC1/uKD4khJ8qRd7aa1NVQkID3rE+QJc0oaxLkBqX0TNDYOlcsozZG2OWyEjPwtZ5D/ZWN5lsIwTDTV4u076GIR/uMn6J8/B9FsQh+fSnpFpxMBU70B+XwJ+mgZqYUH6N6chf9oEWrqWFLwZMCWrah+hi4fjoFv34I/X3Fs+9evJGGdDNgxfv0G1AogV94jOnsG7ElwYc+/ZewotUN4Sy+RunvPAW9dvQTkRpOwtbGGcRB8hVJbkNI3a99VEDJFWndZihHrM4OqWcS2266uZtHeUBDCM4PVBbOxTY5ZWZBwcSQkBratzeal1DGObKzfoN58hanTAYUd6FLR3SGX9gIjKdBqzdm03gKUju3GGnhfMX5zbU4mbTDMs8+mslGdy5kdY7fbloDzW+H9JVC9abQBnijMEF+8luhzStrTP8YTT+8C70gnty3y31rN5g+EL1wuw/PK255ypwI0BfRw4dVPHMAgJ7WnxBQAAAAASUVORK5CYII='}}
style={{
width: width / 8,
height: width / 8 / 1.5,
left: 5
}} />
)
}
export default IranFlag;

@ -1,15 +1,118 @@
import React from 'react';
import {View, Text, Image, Button} from 'react-native';
import {connect} from 'react-redux';
import SelectDropdown from 'react-native-select-dropdown';
import {Provider as PaperProvider} from 'react-native-paper';
import Icon from 'react-native-vector-icons/Ionicons';
import Select from '../../components/Select';
function Login() {
import React, {useState} from 'react';
import {View, Text, Image, Button, Dimensions, TextInput, TouchableHighlight} from 'react-native';
import Logo from '../../assets/images/logo.png';
import IranFlag from "./components/IranFlag";
import {digitToEn, digitToPersian} from "../../utils";
import services from "./services";
import {asyncAwesomeAlert} from "../../utils/AsyncWrappers";
const {width, height} = Dimensions.get('window');
let faNums = ['۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹', '۰']
function Login(props) {
const [phone, setPhone] = useState('');
const onChangePhone = (value) => {
let items = digitToPersian(value).split('');
for (let item of items) {
if (!faNums.includes(item)) {
return
}
}
setPhone(digitToPersian(value));
}
const checkPhoneNumber = () => {
return phone.split('').length === 9;
}
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});
// }
}
return (
<View>
<Select iconPosition={'right'} options={['asdaa', 'aasd']} />
<View style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
}}>
<Image source={Logo} style={{
width: width * 0.7,
height: width * 0.7 / 2.09,
}} />
<Text style={{
width: width,
paddingHorizontal: 10,
marginTop: 20,
fontSize: 20,
textAlign: 'right',
}}>{'دانوین'}</Text>
<Text style={{
width: width,
paddingHorizontal: 10,
marginTop: 10,
fontSize: 14,
color: '#6f7074',
textAlign: 'right',
}}>{'به دانوین خوش اومدی برای عضویت و ادامه شماره موبایلت رو وارد کن و روی گزینه ثبت بزن'}</Text>
<View style={{
width: width - 10,
height: width / 8,
borderRadius: 8,
backgroundColor: '#f2f2f2',
flexDirection: 'row',
marginTop: 10,
alignItems: 'center'
}}>
<IranFlag />
<Text style={{
// width: width / 7 - 15,
fontSize: 18,
marginLeft: 10,
color: '#a2a2a2',
textAlign: 'right',
// marginRight: 5,
}}>
{'۰۹'}
</Text>
<TextInput
style={{
width: width / 1.5,
color: '#a2a2a2',
fontSize: 18
}}
underlineColorAndroid={'transparent'}
value={phone}
onChangeText={text => onChangePhone(text)}
/>
</View>
<TouchableHighlight style={{
width: width - 10,
height: width / 9,
backgroundColor: '#6cbe44',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 10,
marginTop: 15,
}}
onPress={() => submit()}>
<Text style={{
color: 'white',
fontSize: 18,
}}>
{'ادامه'}
</Text>
</TouchableHighlight>
</View>
);
}

@ -0,0 +1,10 @@
import mocks from './mocks';
import mainServices from './services';
const mock = false;
let services = {...mainServices};
if (mock) {
services = mocks;
}
export default services;

@ -0,0 +1,18 @@
import { asyncAwesomeAlert, randomApiSleep } from '../../../utils/AsyncWrappers';
const data = {
};
const getSmsCode = async () => {
await randomApiSleep();
return {
ok: true,
data: data
};
};
const mocks = {getSmsCode};
export default mocks;

@ -0,0 +1,13 @@
import {nextFetchApi} from '../../../services/api';
const getSmsCode = async (obj) => {
return await nextFetchApi('/public/sendOTP', {
method: 'POST',
payload: obj
});
};
const mainServices = {
getSmsCode,
};
export default mainServices;

@ -1,13 +1,203 @@
import React from 'react'
import { View, Text } from 'react-native';
import React, {useEffect, useState} from 'react'
import {View, Text, Image, TextInput, TouchableHighlight, Dimensions, StyleSheet, TouchableOpacity} 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";
const {width} = Dimensions.get('window')
let ref1;
let ref2;
let ref3;
let ref4;
let timer = 60;
function Otp(props) {
let faNums = ['۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹', '۰']
const [firstCode, setFirstCode] = useState('');
const [secondCode, setSecondCode] = useState('');
const [thirdCode, setThirdCode] = useState('');
const [fourthCode, setFourthCode] = useState('');
const [time, setTime] = useState(60);
const checkValue = (value) => {
return faNums.includes(digitToPersian(value));
}
const onChangeCode = (value, key) => {
// if (!checkValue()) {
// return
// }
switch (key) {
case '1':
setFirstCode(digitToPersian(value));
ref2.focus();
break;
case '2':
setSecondCode(digitToPersian(value));
ref3.focus();
break;
case '3':
setThirdCode(digitToPersian(value));
ref4.focus();
break;
case '4':
setFourthCode(digitToPersian(value))
break;
}
}
const getEnCode = () => {
return Number(digitToEn(firstCode) + digitToEn(secondCode) + digitToEn(thirdCode) + digitToEn(fourthCode))
}
const submit = async () => {
let res = await services.sendOtpCode({
cellphone: props.route.params.phone,
otp: getEnCode()
})
if (res.ok) {
console.log(res)
}
}
useEffect(() => {
let interval = setInterval(() => {
if (time > 0) {
setTime(timer - 1);
timer -= 1;
}
}, 1000);
let timeout = setTimeout(() => {
clearInterval(interval)
}, 60000)
return () => {
clearInterval(interval);
clearTimeout(timeout)
}
}, []);
function Otp({}) {
return (
<View style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
}}>
<Image source={Logo} style={{
width: width * 0.7,
height: width * 0.7 / 2.09,
}} />
<Text style={{
width: width,
paddingHorizontal: 10,
marginTop: 20,
fontSize: 20,
textAlign: 'right',
}}>{'دانوین'}</Text>
<Text style={{
width: width,
paddingHorizontal: 10,
marginTop: 10,
fontSize: 14,
color: '#6f7074',
textAlign: 'right',
}}>{`یک کد تائیدیه به شماره ${props.route.params.phone} ارسال شد. آن را در قسمت زیر وارد کنید`}</Text>
<View style={{
width: width - 10,
height: width / 8,
borderRadius: 8,
flexDirection: 'row',
marginTop: 10,
alignItems: 'center',
justifyContent: 'space-evenly'
}}>
<TextInput
style={styles.input}
underlineColorAndroid={'transparent'}
value={firstCode}
maxLength={1}
ref={ref => ref1 = ref}
onChangeText={text => onChangeCode(text, '1')}
/>
<TextInput
style={styles.input}
underlineColorAndroid={'transparent'}
value={secondCode}
maxLength={1}
ref={ref => ref2 = ref}
onChangeText={text => onChangeCode(text, '2')}
/>
<TextInput
style={styles.input}
underlineColorAndroid={'transparent'}
value={thirdCode}
maxLength={1}
ref={ref => ref3 = ref}
onChangeText={text => onChangeCode(text, '3')}
/>
<TextInput
style={styles.input}
underlineColorAndroid={'transparent'}
value={fourthCode}
maxLength={1}
ref={ref => ref4 = ref}
onChangeText={text => onChangeCode(text, '4')}
/>
</View>
<TouchableOpacity
style={{
width: width - 10,
height: width / 9,
backgroundColor: '#6cbe44',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 10,
marginTop: 15,
}}
onPress={() => submit()}>
<Text style={{
color: 'white',
fontSize: 18,
}}>
{'ثبت'}
</Text>
</TouchableOpacity>
<View>
<Text></Text>
<Text style={{marginTop: 30, textAlign: 'center'}}>
{'زمان باقی مانده تا انقضای کد: ' + time}
</Text>
<TouchableOpacity
style={{
marginTop: 20,
}}
onPress={() => {
if (time !== 0) {
return
}
props.navigation.goBack();
}}>
<Text style={{textAlign: 'center'}}>
{'بازگشت به مرحله قبل و اصلاح شماره'}
</Text>
</TouchableOpacity>
</View>
</View>
)
}
const styles = StyleSheet.create({
input: {
width: width / 13 * 2,
height: width / 16 * 2,
backgroundColor: '#a2a2a2',
color: '#333',
fontSize: 22,
borderRadius: 8,
textAlign: 'center'
}
})
export default Otp;

@ -0,0 +1,10 @@
import mocks from './mocks';
import mainServices from './services';
const mock = false;
let services = {...mainServices};
if (mock) {
services = mocks;
}
export default services;

@ -0,0 +1,18 @@
import { asyncAwesomeAlert, randomApiSleep } from '../../../utils/AsyncWrappers';
const data = {
};
const sendOtpCode = async () => {
await randomApiSleep();
return {
ok: true,
data: data
};
};
const mocks = {sendOtpCode};
export default mocks;

@ -0,0 +1,13 @@
import {nextFetchApi} from '../../../services/api';
const sendOtpCode = async (obj) => {
return await nextFetchApi('/user/otp/login', {
method: 'POST',
payload: obj
});
};
const mainServices = {
sendOtpCode,
};
export default mainServices;

@ -1,6 +1,9 @@
import React, {useEffect} from 'react'
import { View, Text } from 'react-native';
import {View, Text, Image, ActivityIndicator, Dimensions} from 'react-native';
import {connect} from 'react-redux';
import Logo from '../../assets/images/logo.png';
const {width, height} = Dimensions.get('window');
const mapStateToProps = state => {
return {
@ -15,13 +18,20 @@ function Splash({navigation, profile}) {
!profile.token ? navigation.reset({
index: 0,
routes: [{ name: 'Login' }],
}) : navigation.navigate('Home')
}) : navigation.reset({
index: 0,
routes: [{ name: 'Home' }],
})
}, 2000)
}, [])
return (
<View style={{justifyContent: 'center', alignItems: 'center', flex: 1}}>
<Text>Splash</Text>
<Image source={Logo} style={{
width: width * 0.7,
height: width * 0.7 / 2.09,
}} />
<ActivityIndicator size={'large'} style={{marginTop: 20}}/>
</View>
)
}

@ -1,4 +1,3 @@
export default {
dev: 'https://dnvn.ir/api/v1/',
splash: 'https://topsito.ir/api/v1.1',
dev: 'https://dnvn.ir/api/v1',
};

@ -120,8 +120,8 @@ export const renewTokenHandler = async () => {
}
}
export const getBaseUrls = async () => {
let { base_urls } = JSON.parse((await AsyncStorage.getItem('SPLASH_DATA')))
return base_urls
// let { base_urls } = JSON.parse((await AsyncStorage.getItem('SPLASH_DATA')))
return apiConfig.dev
}
export const getCachedProfile = async () => {
return JSON.parse(await AsyncStorage.getItem('UID_USER'))

@ -0,0 +1,23 @@
export const digitToPersian = (digit) => {
let enNums = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
let faNums = ['۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹', '۰']
let digitString = digit + '';
let digitArray = digitString.split('');
for (let i in digitArray) {
if (enNums.includes(digitArray[i]))
digitArray[i] = faNums[enNums.indexOf(digitArray[i])]
}
return digitArray.join('')
}
export const digitToEn = (digit) => {
let enNums = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
let faNums = ['۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹', '۰']
let digitString = digit + '';
let digitArray = digitString.split('');
for (let i in digitArray) {
if (faNums.includes(digitArray[i]))
digitArray[i] = enNums[faNums.indexOf(digitArray[i])]
}
return digitArray.join('')
}
Loading…
Cancel
Save