diff --git a/app.json b/app.json
index d3d545e..6a61d6a 100644
--- a/app.json
+++ b/app.json
@@ -4,9 +4,9 @@
"slug": "RnDanovinExpo",
"version": "1.0.0",
"orientation": "portrait",
- "icon": "./assets/icon.png",
+ "icon": "",
"splash": {
- "image": "./assets/splash.png",
+ "image": "",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
@@ -21,13 +21,13 @@
},
"android": {
"adaptiveIcon": {
- "foregroundImage": "./assets/adaptive-icon.png",
+ "foregroundImage": "",
"backgroundColor": "#FFFFFF"
},
"package": "com.appsazz.RnDanovinExpo"
},
"web": {
- "favicon": "./assets/favicon.png"
+ "favicon": ""
}
}
}
diff --git a/assets/adaptive-icon.png b/assets/adaptive-icon.png
deleted file mode 100644
index 03d6f6b..0000000
Binary files a/assets/adaptive-icon.png and /dev/null differ
diff --git a/assets/favicon.png b/assets/favicon.png
deleted file mode 100644
index e75f697..0000000
Binary files a/assets/favicon.png and /dev/null differ
diff --git a/assets/icon.png b/assets/icon.png
deleted file mode 100644
index a0b1526..0000000
Binary files a/assets/icon.png and /dev/null differ
diff --git a/assets/splash.png b/assets/splash.png
deleted file mode 100644
index 0e89705..0000000
Binary files a/assets/splash.png and /dev/null differ
diff --git a/navigation.js b/navigation.js
deleted file mode 100644
index 62350d3..0000000
--- a/navigation.js
+++ /dev/null
@@ -1,116 +0,0 @@
-import * as React from 'react';
-import {NavigationContainer} from '@react-navigation/native';
-import {createNativeStackNavigator} from '@react-navigation/native-stack';
-import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
-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 Product from './src/screens/Product';
-import Products from './src/screens/Products';
-import ShoppingCart from './src/screens/ShoppingCart';
-import QR from './src/screens/QR/index';
-import i18n from './src/services/i18n';
-import {useTranslation} from 'react-i18next';
-import Profile from './src/screens/Profile';
-import Videos from './src/screens/Videos';
-import Exams from './src/screens/Exams';
-import OrderDetails from './src/screens/OrderDetails';
-
-const mapStateToProps = state => {
- return {
- profile: state.profile,
- config: state.config,
- };
-};
-
-const Stack = createNativeStackNavigator();
-const Tab = createBottomTabNavigator();
-
-function BottomTab(props) {
-
- return (
-
-
-
-
-
-
-
- );
-}
-
-function Navigator(props) {
- React.useEffect(() => {
- // i18n.changeLanguage(props.config.lan);
- }, [props.config]);
-
- return (
-
-
-
-
- {/* */}
-
-
-
-
-
-
-
-
- );
-}
-
-export default Navigator;
diff --git a/navigation/index.js b/navigation/index.js
index 1e3003e..c3d012a 100644
--- a/navigation/index.js
+++ b/navigation/index.js
@@ -2,7 +2,7 @@ import React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
-import { Entypo, FontAwesome, Ionicons } from "@expo/vector-icons";
+import { Entypo, FontAwesome, Ionicons, MaterialIcons } from "@expo/vector-icons";
import OrderDetails from "../src/screens/OrderDetails";
import OrdersFollowUp from "../src/screens/OrdersFollowUp";
import { Dimensions } from "react-native";
@@ -16,8 +16,6 @@ import QR from "../src/screens/QR";
import Faq from "../src/screens/Faq"
import Activation from "../src/screens/Activation";
import { connect } from "react-redux";
-import i18n from "../src/services/i18n";
-import { useTranslation } from "react-i18next";
import Profile from "../src/screens/Profile";
import Videos from "../src/screens/Videos";
import Exams from "../src/screens/Exams";
@@ -29,7 +27,7 @@ const Tab = createBottomTabNavigator();
const BottomTabNavigator = () => {
return (
{
}}
>
(
@@ -55,7 +53,7 @@ const BottomTabNavigator = () => {
}}
/>
(
@@ -68,7 +66,16 @@ const BottomTabNavigator = () => {
}}
/>
(
+
+ ),
+ }}
+ />
+ (
@@ -77,7 +84,7 @@ const BottomTabNavigator = () => {
}}
/>
(
@@ -115,24 +122,38 @@ const ProductsStackScreen = () => {
return (
-
-
-
+
+
+
);
};
+const VODStack = createNativeStackNavigator();
+const VODStackScreen = () => {
+ return (
+
+
+
+
+
+
+
+ );
+};
+
const AuthStack = createNativeStackNavigator();
const AuthStackScreen = () => {
return (
@@ -155,7 +176,7 @@ const OrderStackScreen = () => {
}
const Stack = createNativeStackNavigator();
-const Navigation = ({ profile }) => {
+const Navigation = ({ }) => {
return (
{
const mapStateToProps = (state) => {
return {
- profile: state.profile,
- config: state.config,
+
};
};
diff --git a/package.json b/package.json
index 1ac3f82..b43b309 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
"@react-navigation/drawer": "^6.1.8",
"@react-navigation/native": "^6.0.6",
"@react-navigation/native-stack": "^6.2.5",
+ "axios": "^0.24.0",
"expo": "^44.0.1",
"expo-app-loading": "~1.3.0",
"expo-barcode-scanner": "~11.2.0",
@@ -48,5 +49,6 @@
"devDependencies": {
"@babel/core": "^7.12.9"
},
+
"private": true
}
diff --git a/src/actions/actionTypes.js b/src/actions/actionTypes.js
deleted file mode 100644
index 170cedd..0000000
--- a/src/actions/actionTypes.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export const PROFILE_RECORD = 'PROFILE_RECORD';
-export const APP_CONFIG = 'APP_CONFIG';
diff --git a/src/components/CustomTextInput.js b/src/components/CustomTextInput.js
index 64e63cb..c0d8f28 100644
--- a/src/components/CustomTextInput.js
+++ b/src/components/CustomTextInput.js
@@ -15,6 +15,7 @@ const FloatingLabelInput = ({
color,
maxLength,
autoFocus,
+ regex,
...props
}) => {
const [isFocused, setIsFocused] = useState(false);
@@ -43,7 +44,7 @@ const FloatingLabelInput = ({
onChange(name, text)}
+ onChangeText={text => onChange(name, text = regex(text))}
placeholder={'09123456789'}
onFocus={() => setIsFocused(true)}
autoFocus={autoFocus}
diff --git a/src/components/Drawer.js b/src/components/Drawer.js
index 3e024ea..f3d845b 100644
--- a/src/components/Drawer.js
+++ b/src/components/Drawer.js
@@ -62,7 +62,7 @@ const Drawer = ({ position, setBoxPosition }) => {
{
name: "سوالات متداول",
route: "Faq",
- icon: ,
+ icon: ,
toast: "",
message: "",
}
@@ -72,7 +72,7 @@ const Drawer = ({ position, setBoxPosition }) => {
return (
navigation.navigate(route.route)}
diff --git a/src/components/Search.js b/src/components/Search.js
index e8d1803..9e2f0a7 100644
--- a/src/components/Search.js
+++ b/src/components/Search.js
@@ -8,7 +8,7 @@ import {
Image,
} from 'react-native';
import tw from 'tailwind-react-native-classnames';
-import searchIcon from '../assets/icons/search.png';
+import { AntDesign } from '@expo/vector-icons';
const width = Dimensions.get('window').width;
const Search = ({
@@ -42,7 +42,7 @@ const Search = ({
value={value}
/>
-
+
);
diff --git a/src/constants/defaultValues.js b/src/constants/defaultValues.js
new file mode 100644
index 0000000..2591544
--- /dev/null
+++ b/src/constants/defaultValues.js
@@ -0,0 +1,9 @@
+export const ApiConfig = {
+ apiKey: 'AIzaSyBBksq-Asxq2M4Ot-75X19IyrEYJqNBPcg',
+ authDomain: 'dnvn.ir',
+ baseUrl: 'https://dnvn.ir/api/v1',
+ //baseUrl: 'http://localhost:3030/api/v1',
+ loginURL: 'user/login',
+ otploginURL: 'user/otp/login',
+ logoutURL: 'user/logout',
+};
\ No newline at end of file
diff --git a/src/reducers/DefaultReducer.js b/src/reducers/DefaultReducer.js
deleted file mode 100644
index c00c1a3..0000000
--- a/src/reducers/DefaultReducer.js
+++ /dev/null
@@ -1,29 +0,0 @@
-export function DefaultReducer(key, initialState = {}) {
- return (state = initialState, {type = '', payload = {}}) => {
- switch (type) {
- case key:
- return {...state, ...payload};
- }
- return state;
- };
-}
-
-export function buildAction(id) {
- return function(payload) {
- return {
- type: id,
- payload: payload,
- };
- };
-}
-
-export function buildActionForKey(id, key) {
- return function(payload) {
- let result = {
- type: id,
- payload: {},
- };
- result.payload[key] = payload;
- return result;
- };
-}
diff --git a/src/reducers/index.js b/src/reducers/index.js
deleted file mode 100644
index 1d0c85e..0000000
--- a/src/reducers/index.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import {combineReducers} from 'redux';
-import {DefaultReducer} from './DefaultReducer';
-import * as action from '../actions/actionTypes';
-
-const allReducers = combineReducers({
- profile: DefaultReducer(action.PROFILE_RECORD, {
- isLogin: false,
- }),
- config: DefaultReducer(action.APP_CONFIG, {
- lan: 'fa',
- }),
-});
-
-export default allReducers;
\ No newline at end of file
diff --git a/src/redux/actions/blog.js b/src/redux/actions/blog.js
new file mode 100644
index 0000000..d873065
--- /dev/null
+++ b/src/redux/actions/blog.js
@@ -0,0 +1,27 @@
+import proxy from "../proxy";
+const blog = {
+ list:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/blogList", data, { dispatch }),
+ // update:
+ // (data = {}, data2 = {}) =>
+ // async (dispatch : Dispatch) => {
+ // await proxy.put("blog/update", data);
+ // await proxy.get("blog/list", data2, { dispatch });
+ // },
+ // add:
+ // (data = {}, data2 = {}) =>
+ // async (dispatch : Dispatch) => {
+ // await proxy.post("blog/add", data);
+ // await proxy.get("blog/list", data2, { dispatch });
+ // },
+ // del:
+ // (data = {}, data2 = {}) =>
+ // async (dispatch : Dispatch) => {
+ // await proxy.delete("blog/delete", data);
+ // await proxy.get("blog/list", data2, { dispatch });
+ // },
+};
+
+export default blog;
diff --git a/src/redux/actions/book.js b/src/redux/actions/book.js
new file mode 100644
index 0000000..f74ec70
--- /dev/null
+++ b/src/redux/actions/book.js
@@ -0,0 +1,44 @@
+import proxy from "../proxy";
+const book = {
+ list:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("book/list", data, { dispatch }),
+ info:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("book/info", data, { dispatch }),
+ setLessonActive: (data) => async (dispatch) =>
+ await dispatch({ type: "book/lesson/active", data: data }),
+ gradeFilter: (data) => async (dispatch) =>
+ await dispatch({ type: "book/gradeFilter", data: data }),
+ sortFilter: (data) => async (dispatch) =>
+ await dispatch({ type: "book/sortFilter", data: data }),
+
+ // update:
+ // (data = {}, data2 = {}) =>
+ // async (dispatch : Dispatch) => {
+ // await proxy.put("book/update", data);
+ // await proxy.get("book/list", data2, { dispatch });
+ // },
+ // add:
+ // (data = {}, data2 = {}) =>
+ // async (dispatch) => {
+ // await proxy.post("book/add", data);
+ // await proxy.get("book/list", data2, { dispatch });
+ // },
+ // del:
+ // (data = {}, data2 = {}) =>
+ // async (dispatch) => {
+ // await proxy.delete("book/delete", data);
+ // await proxy.get("book/list", data2, { dispatch });
+ // },
+ // searchBook: (data) => async (dispatch) => {
+ // dispatch({ type: "book/search", data: data });
+ // },
+ // filterBook: (data) => async (dispatch) => {
+ // dispatch({ type: "book/filter", data: data });
+ // },
+};
+
+export default book;
diff --git a/src/redux/actions/content.js b/src/redux/actions/content.js
new file mode 100644
index 0000000..e09c8c8
--- /dev/null
+++ b/src/redux/actions/content.js
@@ -0,0 +1,14 @@
+import proxy from "../proxy";
+import { Dispatch } from "redux";
+const content = {
+ listVOD:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("content/listVOD", data, { dispatch }),
+ infoVOD:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("content/infoVOD", data, { dispatch }),
+};
+
+export default content;
diff --git a/src/redux/actions/faq.js b/src/redux/actions/faq.js
new file mode 100644
index 0000000..aaf031b
--- /dev/null
+++ b/src/redux/actions/faq.js
@@ -0,0 +1,20 @@
+import proxy from "../proxy";
+import { Dispatch } from "redux";
+const faq = {
+ list:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("faq/list", data, { dispatch }),
+ add:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.post("faq/add", data, { dispatch }),
+ selectFaq:
+ (data = {}) =>
+ async (dispatch) =>
+ await dispatch({ type: "faq/selectFaq", data: data }),
+ searchFaq: (data) => async (dispatch) =>
+ await dispatch({ type: "faq/search", data: data }),
+};
+
+export default faq;
diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js
new file mode 100644
index 0000000..02090a1
--- /dev/null
+++ b/src/redux/actions/file.js
@@ -0,0 +1,22 @@
+import proxy from "../proxy";
+const file = {
+ upload:
+ (data = {}) =>
+ async (dispatch) => {
+ var formData = new FormData();
+ for (let key in data) formData.append(key, data[key]);
+ return await proxy.post(
+ "file/upload",
+ formData,
+ {
+ dispatch,
+ headers: {
+ "Content-Type": "multipart/form-data",
+ },
+ },
+ data
+ );
+ },
+};
+
+export default file;
diff --git a/src/redux/actions/index.js b/src/redux/actions/index.js
new file mode 100644
index 0000000..9fd9385
--- /dev/null
+++ b/src/redux/actions/index.js
@@ -0,0 +1,16 @@
+// @create-index
+export { default as publicApi } from "./public";
+export { default as user } from "./user";
+export { default as book } from "./book";
+export { default as blog } from "./blog";
+export { default as product } from "./product";
+export { default as userFactor } from "./userFactor";
+export { default as userProduct } from "./userProduct";
+export { default as content } from "./content";
+export { default as faq } from "./faq";
+export { default as file } from "./file";
+
+
+
+
+
diff --git a/src/redux/actions/product.js b/src/redux/actions/product.js
new file mode 100644
index 0000000..7a770ad
--- /dev/null
+++ b/src/redux/actions/product.js
@@ -0,0 +1,26 @@
+import proxy from "../proxy";
+const product = {
+ listVOD:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("product/listVOD", data, { dispatch }),
+ addVOD:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.post("product/addVOD", data);
+ await proxy.get("product/listVOD", data2, { dispatch });
+ },
+ deleteVOD:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.delete("product/deleteVOD", data);
+ await proxy.get("product/listVOD", data2, { dispatch });
+ },
+ selectVOD:
+ (data = {}) =>
+ async (dispatch) => {
+ await dispatch({ type: "product/selectVOD", data });
+ },
+};
+
+export default product;
diff --git a/src/redux/actions/public.js b/src/redux/actions/public.js
new file mode 100644
index 0000000..dc69d7b
--- /dev/null
+++ b/src/redux/actions/public.js
@@ -0,0 +1,50 @@
+import proxy from "../proxy";
+const publicApi = {
+ setIsDark: (data) => async (dispatch) =>
+ await dispatch({ type: "public/setIsDark", data: data }),
+ getHomeData: (data) => async (dispatch) =>
+ await proxy.get("public/homePage", data, { dispatch }),
+
+ setFaqActive: (data) => async (dispatch) =>
+ await dispatch({ type: "public/faq/activate", data: data }),
+ bookInfo:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/vod/bookCourse", data, { dispatch }),
+ bookSection:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/vod/bookSection", data, { dispatch }),
+ getContactData:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/contact", data, { dispatch }),
+
+ getBlogList: (data) => async (dispatch) =>
+ await proxy.get("public/blogList", data, { dispatch }),
+
+ getBlogInfo: (data) => async (dispatch) =>
+ await proxy.get("public/blogInfo", data, { dispatch }),
+ setSubscribe: (data) => async (dispatch) =>
+ await dispatch({ type: "public/setSubscribe", data: data }),
+ getProvince:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/province", data, { dispatch }),
+ getCity:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/city", data, { dispatch }),
+ selectMenu: (data) => async (dispatch) =>
+ await dispatch({ type: "public/selectMenu", data: data }),
+ getHeader:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/VOD/homePage", data, { dispatch }),
+ activeCategory: (data) => async (dispatch) =>
+ await dispatch({ type: "active/category", data: data }),
+ setVideoActive: (data) => async (dispatch) =>
+ await dispatch({ type: "active/video", data: data }),
+};
+
+export default publicApi;
diff --git a/src/redux/actions/user.js b/src/redux/actions/user.js
new file mode 100644
index 0000000..effe838
--- /dev/null
+++ b/src/redux/actions/user.js
@@ -0,0 +1,65 @@
+import proxy from "../proxy";
+
+const user = {
+ otp: (data) => async (dispatch) => {
+ console.log(data);
+ await proxy.post("public/sendOTP", data, { dispatch });
+ },
+
+ otp_login: (data) => async (dispatch) =>
+ await proxy.login("user/otp/login", data, { dispatch }),
+
+ login: (data) => async (dispatch) =>
+ await proxy.login("user/login", data, { dispatch }),
+
+ // register: (data : undefined) => async (dispatch : Dispatch) =>
+ // await proxy.login("user/register", data, { dispatch }),
+
+ // switchRole: (data : String) => async (dispatch : Dispatch) =>
+ // await proxy.login("user/switchRole", data, { dispatch }),
+
+ logout: (data) => async (dispatch) =>
+ await proxy.logout("user/logout", data, { dispatch }),
+
+ getUserRole: (data) => async (dispatch) =>
+ await proxy.get("user/getUserRole", data, { dispatch }),
+
+ // list:
+ // (data = {}) =>
+ // async (dispatch : Dispatch) =>
+ // await proxy.get("user/list", data, { dispatch }),
+ // domains:
+ // (data = {}) =>
+ // async (dispatch : Dispatch) =>
+ // await proxy.get("user/domains", data, { dispatch }),
+ // getmothers:
+ // (data = {}) =>
+ // async (dispatch : Dispatch) =>
+ // await proxy.get("mothers/list", data, {
+ // dispatch,
+ // }),
+ getProfile:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("user/getProfile", data, { dispatch }),
+ setProfile:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.put("user/setProfile", data, { dispatch });
+ await proxy.get("user/getProfile", data2, { dispatch });
+ },
+ add:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.post("user/add", data);
+ await proxy.get("user/list", data2, { dispatch });
+ },
+ del:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.delete("user/delete", data);
+ await proxy.get("user/list", data2, { dispatch });
+ },
+};
+
+export default user;
diff --git a/src/redux/actions/userFactor.js b/src/redux/actions/userFactor.js
new file mode 100644
index 0000000..a46962c
--- /dev/null
+++ b/src/redux/actions/userFactor.js
@@ -0,0 +1,55 @@
+import proxy from "../proxy";
+const userFactor = {
+ //dnvn
+ list:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("userFactor/list", data, { dispatch }),
+ payment:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.post("userFactor/payment", data, { dispatch });
+ },
+ add:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.post("userFactor/add", data, { dispatch });
+ await proxy.get("userFactor/list", data2, { dispatch });
+ },
+ del:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.delete("userFactor/delete", data);
+ await proxy.get("userFactor/list", data2, { dispatch });
+ },
+
+ //vod
+ payment:
+ (data1 = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.post("userProduct/addVOD", data1, { dispatch });
+ await proxy.post("userFactor/paymentVOD", data2, { dispatch });
+ },
+ verify:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.post("userFactor/verifyVOD", data, { dispatch }),
+ info:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("userFactor/info", data, { dispatch }),
+ update:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.put("userFactor/update", data, { dispatch });
+ await proxy.get("userFactor/info", data2, { dispatch });
+ },
+ deleteUserOffCode:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.delete("userFactor/deleteUserOffCode", data, { dispatch });
+ await proxy.get("userFactor/info", data2, { dispatch });
+ },
+};
+
+export default userFactor;
diff --git a/src/redux/actions/userProduct.js b/src/redux/actions/userProduct.js
new file mode 100644
index 0000000..2436d7f
--- /dev/null
+++ b/src/redux/actions/userProduct.js
@@ -0,0 +1,33 @@
+import proxy from "../proxy";
+const userProduct = {
+ list:
+ (data = {}) =>
+ async (dispatch) => {
+ await proxy.get("userProduct/list", data, { dispatch });
+ },
+ info:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("userProduct/info", data, { dispatch }),
+ update:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.put("userProduct/update", data);
+ await proxy.get("userProduct/list", data2, { dispatch });
+ },
+ add:
+ (data = {}, data2 = {}, data3 = {}) =>
+ async (dispatch) => {
+ await proxy.post("userProduct/add", data, { dispatch });
+ await proxy.get("userProduct/list", data2, { dispatch });
+ await proxy.get("userFactor/info", data3, { dispatch });
+ },
+ del:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.delete("userProduct/delete", data);
+ await proxy.get("userProduct/list", data2, { dispatch });
+ },
+};
+
+export default userProduct;
diff --git a/src/redux/index.js b/src/redux/index.js
new file mode 100644
index 0000000..5b58979
--- /dev/null
+++ b/src/redux/index.js
@@ -0,0 +1,6 @@
+// @create-index
+
+export { default as actions } from './actions';
+export { default as proxy } from './proxy.js';
+export { default as reducers } from './reducers';
+export { default as store } from './store.js';
\ No newline at end of file
diff --git a/src/redux/proxy.js b/src/redux/proxy.js
new file mode 100644
index 0000000..962faee
--- /dev/null
+++ b/src/redux/proxy.js
@@ -0,0 +1,171 @@
+import { ApiConfig } from "../constants/defaultValues";
+import axios from "axios";
+import AsyncStorage from "@react-native-async-storage/async-storage";
+import { useNavigation } from "@react-navigation/native";
+
+let { baseUrl } = ApiConfig;
+let access;
+() => {
+ access = AsyncStorage.getItem("access");
+};
+
+baseUrl = baseUrl + "/";
+
+const Axios = axios.create({
+ withCredentials: true,
+ validateStatus: null,
+ baseURL: baseUrl,
+ //headers: access ? { Authorization: `Bearer ${access}` } : {},
+});
+class Proxy {
+ get = (url, params, opt, data) => {
+ try {
+ this.check(
+ url,
+ opt,
+ () => Axios.get(url, { params, ...opt }),
+ data || params
+ );
+ } catch (error) {
+ console.log("proxy get error! : ", error);
+ }
+ };
+
+ post = (url, params, opt, data) => {
+ try {
+ this.check(
+ url,
+ opt,
+ () => Axios.post(url, params, opt),
+ data || params
+ );
+ } catch (error) {
+ console.log("proxy post error! : ", error);
+ }
+ };
+
+ put = (url, params, opt, data) => {
+ try {
+ this.check(
+ url,
+ opt,
+ () => Axios.put(url, params, opt),
+ data || params
+ );
+ } catch (error) {
+ console.log("proxy put error! : ", error);
+ }
+ };
+
+ delete = (url, params, opt, data) => {
+ try {
+ this.check(
+ url,
+ opt,
+ () => Axios.delete(url, { ...opt, data: params }),
+ data || params
+ );
+ } catch (error) {
+ console.log("proxy delete error! : ", error);
+ }
+ };
+
+ check = (url, { dispatch }, fetch, params) => {
+ try {
+ dispatch = dispatch || (() => {});
+ dispatch({ type: url.split("/")[0] + "/" + "loading" });
+ let response = fetch();
+ switch (response.status) {
+ case 200:
+ dispatch({ type: url, data: response.data.data, params });
+ return response.data.data;
+ case 401:
+ if (this.refresh()) {
+ let response = fetch();
+ dispatch({ type: url, data: response.data.data, params });
+ return response.data.data;
+ }
+ break;
+ default:
+ dispatch({
+ type: url.split("/")[0] + "/" + "error",
+ data: response.data,
+ params,
+ });
+ }
+ return false;
+ } catch (error) {
+ console.log("proxy check error! : ", error);
+ }
+ };
+
+ refresh = () => {
+ try {
+ const navigation = useNavigation();
+ let refresh = AsyncStorage.getItem("refresh");
+ if (!refresh) navigation.push("Root");
+ let login = this.login(
+ "user/login",
+ {},
+ { headers: { Authorization: `Bearer ${refresh}` } }
+ );
+ return login ? true : false;
+ } catch (error) {
+ console.log("proxy refresh error! : ", error);
+ }
+ };
+
+ login = (url, params, { dispatch }) => {
+ try {
+ console.log('------------------------------login---------------------------------');
+ this.post(url, params, {
+ dispatch: (obj) => {
+ let login = obj.data;
+ console.log('login data: ',login);
+ if (!login || !login.refreshToken) return false;
+ const refresh = ["refresh", login.refreshToken];
+ const access = ["access", login.accessToken];
+ const userData = ["userData", JSON.stringify(login.profile)];
+ AsyncStorage.multiSet([refresh, access, userData]);
+ delete login.refreshToken;
+ delete login.accessToken;
+ dispatch(obj);
+ },
+ });
+ } catch (error) {
+ console.log("proxy login error! : ", error);
+ }
+ };
+
+ logout = (url, params, { dispatch }) => {
+ try {
+ this.post(url, params, {
+ dispatch: (obj) => {
+ const keys = ["refresh", "access", "userData"];
+ AsyncStorage.multiRemove(keys);
+ dispatch(obj);
+ },
+ });
+ } catch (error) {
+ console.log("proxy logout error : ", error);
+ }
+ };
+ status = () => {
+ try {
+ let refresh = AsyncStorage.getItem("refresh");
+ let userData = AsyncStorage.getItem("userData");
+ if (!refresh) return false;
+ if (refresh == "undefined") {
+ const keys = ["refresh", "access", "userData"];
+ AsyncStorage.multiRemove(keys);
+ return false;
+ }
+ return userData || null;
+ } catch (error) {
+ console.log("proxy status error : ", error);
+ }
+ };
+}
+const _proxy = new Proxy();
+
+export default _proxy;
\ No newline at end of file
diff --git a/src/redux/reducers/blog.js b/src/redux/reducers/blog.js
new file mode 100644
index 0000000..9f3005c
--- /dev/null
+++ b/src/redux/reducers/blog.js
@@ -0,0 +1,26 @@
+const initialState = {
+ loading: false,
+ error: null,
+ list: [],
+};
+export default function blog(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case "public/blogList":
+ return { ...state, loading: false, list: data, error: null };
+ // case "blog/update":
+ // return { ...state, loading: false, error: null };
+ // case "blog/add":
+ // return { ...state, loading: false, error: null };
+ // case "blog/delete":
+ // return { ...state, loading: false, error: null };
+ /////////////
+ case "blog/loading":
+ return { ...state, loading: true };
+ case "blog/error":
+ // toast.error(data.message);
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/book.js b/src/redux/reducers/book.js
new file mode 100644
index 0000000..98d2457
--- /dev/null
+++ b/src/redux/reducers/book.js
@@ -0,0 +1,167 @@
+
+const initialState = {
+ loading: false,
+ error: null,
+ list: [],
+ info: null,
+ searchResult: [],
+ filterResult: [],
+ subjects: [],
+ levels: [],
+ sortFilters: ["مرتب سازی", "محبوب ترین", "جدیدترین"],
+ selectedVideo: null,
+ gradeFilterBooks: null,
+ sortFilterCourse: null,
+ selectedGrade: null,
+ selectedSort: "پربازدید ترین ها",
+};
+
+const grades = [
+ "پیش دبستان",
+ "اول",
+ "دوم",
+ "سوم",
+ "چهارم",
+ "پنجم",
+ "ششم",
+ "هفتم",
+ "هشتم",
+ "نهم",
+ "دهم",
+ "یازدهم",
+ "دوازدهم",
+];
+
+export default function book(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case "book/list":
+ let itemsSubject = (Array.isArray(data) ? data : []).map(
+ (item, index) => item.name
+ );
+ if (window.innerWidth < 1000) {
+ itemsSubject.unshift("نام کتاب");
+ }
+ let itemsLevel = (Array.isArray(data) ? data : [])
+ .map((item) => item.gradeId * 1)
+ .sort((a, b) => a - b)
+ .map((e) => grades[e]);
+ if (window.innerWidth < 1000) {
+ itemsLevel.unshift("پایه تحصیلی");
+ }
+ return {
+ ...state,
+ loading: false,
+ list: data,
+ subjects: Array.from(new Set(itemsSubject)),
+ levels: Array.from(new Set(itemsLevel)),
+ filterResult: data,
+ error: null,
+ };
+ case "book/info":
+ return { ...state, loading: false, info: data, error: null };
+ case "book/lesson/active":
+ return {
+ ...state,
+ loading: false,
+ error: null,
+ };
+ case "book/gradeFilter":
+ if (data === state.selectedGrade) {
+ return { ...state, gradeFilterBooks: null, selectedGrade: null };
+ } else {
+ return {
+ ...state,
+ gradeFilterBooks: state.list.filter(
+ (item, i) => grades[item.gradeId] === data
+ ),
+ selectedGrade: data,
+ };
+ }
+ case "book/sortFilter":
+ const search = state.list.filter(
+ (item) => item.name.indexOf(data.search) !== -1
+ );
+ if (data.sort === "تمامی دورهها") {
+ return { ...state, sortFilterCourse: search, selectedSort: data.sort };
+ } else if (data.sort === "جدیدترینها") {
+ return {
+ ...state,
+ sortFilterCourse: search.sort((item1, item2) => {
+ return item1.publishYear - item2.publishYear;
+ }),
+ selectedSort: data.sort,
+ };
+ }
+ return { ...state, sortFilterCourse: search, selectedSort: data.sort };
+
+ // case "book/update":
+ // return { ...state, loading: false, error: null };
+ // case "book/add":
+ // return { ...state, loading: false, error: null };
+ // case "book/delete":
+ // return { ...state, loading: false, error: null };
+ // case "book/search":
+ // return { ...state };
+ // case "book/filter":
+ // const realList = state.list;
+ // const level = data.level;
+ // const subject = data.subject;
+ // const sort = data.sort;
+ // const search = data.search;
+ // if (level.length > 0 || subject.length > 0 || sort || search) {
+ // localStorage.setItem("filter", "ON");
+ // }
+ // let finalSort;
+ // let byLevelFilter = [];
+ // if (level.length > 0) {
+ // level.map((item1) => {
+ // for (let i = 0; i < realList.length; i++) {
+ // if (grades[realList[i].gradeId] === item1) {
+ // byLevelFilter.push(realList[i]);
+ // }
+ // }
+ // });
+ // } else {
+ // byLevelFilter = realList;
+ // }
+
+ // let bySubjectFilter = [];
+ // if (subject.length > 0) {
+ // subject.map((item1) => {
+ // for (let i = 0; i < byLevelFilter.length; i++) {
+ // if (byLevelFilter[i].name === item1) {
+ // bySubjectFilter.push(byLevelFilter[i]);
+ // }
+ // }
+ // });
+ // } else {
+ // bySubjectFilter = byLevelFilter;
+ // }
+
+ // const bySearchFilter = search
+ // ? bySubjectFilter.filter((item1) => item1.name.indexOf(search) !== -1)
+ // : bySubjectFilter;
+
+ // if (sort === "گران ترین") {
+ // finalSort = bySearchFilter.sort((item1, item2) => {
+ // return item1.product[0].price - item2.product[0].price;
+ // });
+ // } else {
+ // finalSort = bySearchFilter;
+ // }
+ // return {
+ // ...state,
+ // loading: false,
+ // error: null,
+ // filterResult: finalSort,
+ // };
+ case "book/loading":
+ return { ...state, loading: true };
+ case "book/error":
+ // toast.error(data.message);
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/faq.js b/src/redux/reducers/faq.js
new file mode 100644
index 0000000..4102b8d
--- /dev/null
+++ b/src/redux/reducers/faq.js
@@ -0,0 +1,56 @@
+const initialState = {
+ loading: false,
+ error: null,
+ list: [],
+ searchResult: [],
+ search: null,
+};
+
+export default function faq(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case "faq/list":
+ return { ...state, loading: false, list: data, error: null };
+ case "faq/add":
+ return { ...state, loading: false, error: null };
+ case "faq/selectFaq":
+ return {
+ ...state,
+ loading: false,
+ error: null,
+ list: !state.search
+ ? state.list.map((item) =>
+ item.id === data
+ ? { ...item, active: !item.active }
+ : { ...item, active: false }
+ )
+ : state.list,
+ searchResult: state.search
+ ? state.searchResult.map((item) =>
+ item.id === data
+ ? { ...item, active: !item.active }
+ : { ...item, active: false }
+ )
+ : state.searchResult,
+ };
+ case "faq/search":
+ return {
+ ...state,
+ loading: false,
+ error: null,
+ search: data,
+ searchResult: state.list.filter(
+ (item) =>
+ item.title.indexOf(data) !== -1 ||
+ item.description.indexOf(data) !== -1
+ ),
+ };
+ case "faq/loading":
+ return { ...state, loading: true };
+ case "faq/error":
+ // toast.error(data.message);
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/file.js b/src/redux/reducers/file.js
new file mode 100644
index 0000000..164494c
--- /dev/null
+++ b/src/redux/reducers/file.js
@@ -0,0 +1,26 @@
+const initialState = {
+ loading: false,
+ error: null,
+ uploads: {},
+ lastUpload: null,
+};
+
+export default function file(state = initialState, action) {
+ let { type, data, params } = action;
+ switch (type) {
+ case "file/upload":
+ return {
+ ...state,
+ loading: false,
+ error: null,
+ uploads: { ...state.uploads, [params?.target || "last"]: data.id },
+ lastUpload: data.id,
+ };
+ case "file/loading":
+ return { ...state, loading: true };
+ case "file/error":
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/index.js b/src/redux/reducers/index.js
new file mode 100644
index 0000000..7d836fc
--- /dev/null
+++ b/src/redux/reducers/index.js
@@ -0,0 +1,10 @@
+// @create-index
+export { default as publicApi } from "./public";
+export { default as user } from "./user";
+export { default as book } from "./book";
+export { default as blog } from "./blog";
+export { default as product } from "./product";
+export { default as faq } from "./faq";
+export { default as file } from "./file";
+export { default as userFactor } from "./userFactor";
+export { default as userProduct } from "./userProduct";
diff --git a/src/redux/reducers/product.js b/src/redux/reducers/product.js
new file mode 100644
index 0000000..23cb8fc
--- /dev/null
+++ b/src/redux/reducers/product.js
@@ -0,0 +1,26 @@
+const initialState = {
+ loading: false,
+ error: null,
+ listVOD: [],
+ selectedVOD: null,
+};
+export default function product(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case "product/listVOD":
+ return { ...state, loading: false, listVOD: data, error: null };
+ case "product/addVOD":
+ return { ...state, loading: false, error: null };
+ case "product/deleteVOD":
+ return { ...state, loading: false, error: null };
+ case "product/selectVOD":
+ return {...state, selectedVOD : data};
+ case "product/loading":
+ return { ...state, loading: true };
+ case "product/error":
+ // toast.error(data.message);
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/public.js b/src/redux/reducers/public.js
new file mode 100644
index 0000000..ebcc014
--- /dev/null
+++ b/src/redux/reducers/public.js
@@ -0,0 +1,169 @@
+import AsyncStorage from "@react-native-async-storage/async-storage";
+import { Dimensions } from "react-native";
+
+const width = Dimensions.get("window").width;
+
+const initialState = {
+ // isDark: (await AsyncStorage.getItem("isDark")) || false,
+ homeData: [],
+ newProducts: [],
+ levels: [],
+ loading: false,
+ error: null,
+ searchResult: [],
+ arList: [],
+ blogList: [],
+ blog: null,
+ province: null,
+ city: null,
+ departmans: [
+ {
+ id: 0,
+ name: "محتوا",
+ },
+ {
+ id: 0,
+ name: "دیزاین",
+ },
+ {
+ id: 0,
+ name: "برنامه نویسی",
+ },
+ ],
+ header: [],
+ selectedMenu: null,
+ contactData: null,
+ selectedVideo: null,
+ bookInfo: null,
+ activeCategory: null,
+ categories: null,
+ bookSection: null,
+ grades: {
+ 0: "پیش دبستان",
+ 1: "اول",
+ 2: "دوم",
+ 3: "سوم",
+ 4: "چهارم",
+ 5: "پنجم",
+ 6: "ششم",
+ 7: "هفتم",
+ 8: "هشتم",
+ 9: "نهم",
+ 10: "دهم",
+ 11: "یازدهم",
+ 12: "دوازدهم",
+ },
+};
+
+const grades = [
+ "پیش دبستان",
+ "اول",
+ "دوم",
+ "سوم",
+ "چهارم",
+ "پنجم",
+ "ششم",
+ "هفتم",
+ "هشتم",
+ "نهم",
+ "دهم",
+ "یازدهم",
+ "دوازدهم",
+];
+const publicApi = (state = initialState, action) => {
+ let { type, data } = action;
+ switch (type) {
+ case "public/setIsDark":
+ // AsyncStorage.setItem("isDark", data);
+ return { ...state, location: false, error: null, isDark: data };
+ case "active/video":
+ return {
+ ...state,
+ loading: false,
+ error: null,
+ selectedVideo: data,
+ };
+ case "active/category":
+ return {
+ ...state,
+ loading: false,
+ activeCategory: state.activeCategory === data ? null : data,
+ error: null,
+ };
+ case "public/vod/bookSection":
+ const videoId = location.getId();
+ return {
+ ...state,
+ loading: false,
+ bookSection: data,
+ error: null,
+ selectedVideo: data.vods?.filter((item) => item.id !== videoId)[0],
+ };
+
+ case "public/vod/bookCourse":
+ let allCats;
+ allCats = Array.from(
+ new Set(data.vods.map((item) => item.categoryId && item.categoryId))
+ );
+ return {
+ ...state,
+ loading: false,
+ bookInfo: {
+ ...data,
+ vods: data.vods.map((item) => {
+ return { ...item, active: false };
+ }),
+ },
+ error: null,
+ categories: allCats.map((item) =>
+ data.vods.filter((item1) => item1.categoryId === item)
+ ),
+ selectedVideo: data.vods.filter((item) => item.id !== 1)[0],
+ };
+ case "public/homePage":
+ let itemsLevel;
+ if (width > 1000) {
+ const jadidTarin = data.filter(
+ (item) => item.title === "جدیدترین کتابهای دانوین"
+ );
+ itemsLevel = jadidTarin[0].data
+ .map((item) => item.book.gradeId * 1)
+ .sort((a, b) => a - b)
+ .map((e) => grades[e]);
+ itemsLevel.unshift("همه");
+ }
+
+ return {
+ ...state,
+ loading: false,
+ levels: width > 1000 ? Array.from(new Set(itemsLevel)) : [],
+ error: null,
+ homeData: data,
+ };
+
+ case "public/contact":
+ return { ...state, loading: false, error: null, contactData: data };
+ case "public/blogList":
+ return { ...state, loading: false, error: null, blogList: data };
+ case "public/blogInfo":
+ return { ...state, loading: false, error: null, blog: data };
+ case "public/setSubscribe":
+ return { ...state, loading: false, error: null, selectedSubscribe: data };
+ case "public/province":
+ return { ...state, loading: false, error: null, province: data };
+ case "public/city":
+ return { ...state, loading: false, error: null, city: data };
+ case "public/selectMenu":
+ return { ...state, loading: false, error: null, selectedMenu: data };
+ case "public/VOD/homePage":
+ return { ...state, loading: false, error: null, header: data };
+ case "loading":
+ return { ...state, loading: true };
+ case "error":
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+};
+
+export default publicApi;
\ No newline at end of file
diff --git a/src/redux/reducers/user.js b/src/redux/reducers/user.js
new file mode 100644
index 0000000..a0b8d2c
--- /dev/null
+++ b/src/redux/reducers/user.js
@@ -0,0 +1,64 @@
+import proxy from "../proxy";
+import AsyncStorage from "@react-native-async-storage/async-storage";
+
+let initialState = {
+ status: proxy.status(),
+ loading: false,
+ error: null,
+ list: null,
+ domains: [],
+ mothers: [],
+ profileStatus: false,
+ setDone: false,
+ setLogin: false,
+ check : 'check'
+};
+
+const user = (state = initialState, action) => {
+ let { type, data } = action;
+ switch (type) {
+ // case "user/login":
+ // case "user/register":
+ // case "user/switchRole":
+ case "public/sendOTP":
+ return { ...state, loading: false, error: null };
+ case "user/login":
+ case "user/otp/login":
+ return {
+ ...state,
+ loading: false,
+ status: data.profile,
+ error: null,
+ setLogin: !state.setLogin,
+ };
+ case "user/getProfile":
+ const myData = JSON.stringify(data);
+ try{
+ AsyncStorage.setItem("userData", myData);
+ }catch(error){
+ console.log('user/getProfile', error);
+ }
+ return {
+ ...state,
+ loading: false,
+ status: data,
+ error: null,
+ setDone: false,
+ };
+ case "user/logout":
+ return { ...state, loading: false, status: proxy.status(), error: null };
+ case "user/getUserRole":
+ return { ...state, loading: false, userRoles: data, error: null };
+ case "user/setProfile":
+ // toast.success("تغییرات اعمال شد.");
+ return { ...state, loading: false, error: null, setDone: true };
+ case "loading":
+ return { ...state, loading: true };
+ case "error":
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
+
+export default user;
\ No newline at end of file
diff --git a/src/redux/reducers/userFactor.js b/src/redux/reducers/userFactor.js
new file mode 100644
index 0000000..8598ee5
--- /dev/null
+++ b/src/redux/reducers/userFactor.js
@@ -0,0 +1,60 @@
+import {useNavigation} from '@react-navigation/native';
+
+const initialState = {
+ loading: false,
+ error: null,
+ list: null,
+ info: null,
+ sum: null,
+ checkEmpty: false,
+ isVerified: null,
+};
+export default function userFactor(state = initialState, action) {
+ // const navigation = useNavigation();
+
+ let { type, data } = action;
+ switch (type) {
+ //dnvn
+ case "userFactor/list":
+ const checkEmpty = data.filter(
+ (item) => item.condition === 2 && item.product.productType === (1 || 3)
+ );
+ return {
+ ...state,
+ loading: false,
+ list: data,
+ checkEmpty: checkEmpty.length > 0 ? false : true,
+ error: null,
+ };
+ case "userFactor/info":
+ return { ...state, loading: false, info: data, error: null };
+ case "userFactor/add":
+ // toast.success("درخواست شما با موفقیت انجام شد.");
+ return { ...state, loading: false, error: null, sum: data.payPrice };
+ case "userFactor/delete":
+ return { ...state, loading: false, error: null };
+ case "userFactor/payment":
+ // navigation.push(data);
+ return { ...state, loading: false, error: null };
+ //vod
+ case "userFactor/myList":
+ return { ...state, loading: false, list: data, error: null };
+ case "userFactor/update":
+ // toast.success("درخواست شما با موفقیت انجام شد.");
+ return { ...state, loading: false, error: null };
+ case "userFactor/deleteUserOffCode":
+ return { ...state, loading: false, error: null };
+ case "userFactor/paymentVOD":
+ // navigation.push(data);
+ return { ...state, loading: false, error: null, isVerified: false };
+ case "userFactor/verifyVOD":
+ return { ...state, loading: false, error: null, isVerified: true };
+ case "userFactor/loading":
+ return { ...state, loading: true };
+ case "userFactor/error":
+ // toast.error(data.message);
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/userProduct.js b/src/redux/reducers/userProduct.js
new file mode 100644
index 0000000..7524513
--- /dev/null
+++ b/src/redux/reducers/userProduct.js
@@ -0,0 +1,48 @@
+const initialState = {
+ loading: false,
+ error: null,
+ list: [],
+ info: null,
+ sum: null,
+ checkEmpty: false,
+ hasPhysical: false,
+};
+export default function userFactor(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case "userProduct/list":
+ const checkEmpty = data.filter(
+ (item) => item.condition === 2 && item.product.productType === (1 || 3)
+ );
+ const hasPhysical =
+ data.filter((item) => item.product.productType === 2).length > 0
+ ? true
+ : false;
+ return {
+ ...state,
+ loading: false,
+ list: data,
+ checkEmpty: checkEmpty.length > 0 ? false : true,
+ error: null,
+ hasPhysical: hasPhysical,
+ };
+ case "userProduct/info":
+ return { ...state, loading: false, info: data, error: null };
+ case "userProduct/update":
+ return { ...state, loading: false, error: null };
+ case "userProduct/add":
+ // if (window.location.pathname.indexOf("products") !== -1) {
+ // toast.success("درخواست شما با موفقیت انجام شد.");
+ // }
+ return { ...state, loading: false, error: null, sum: data.payPrice };
+ case "userProduct/delete":
+ return { ...state, loading: false, error: null };
+ case "userProduct/loading":
+ return { ...state, loading: true };
+ case "userProduct/error":
+ // toast.error(data.message);
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/store.js b/src/redux/store.js
index 32172bb..1b8b3b7 100644
--- a/src/redux/store.js
+++ b/src/redux/store.js
@@ -1,10 +1,18 @@
import AsyncStorage from "@react-native-async-storage/async-storage";
-import { applyMiddleware, createStore, compose } from "redux";
+import { applyMiddleware, createStore, compose, combineReducers } from "redux";
import { createLogger } from "redux-logger";
import thunk from "redux-thunk";
import { persistStore, persistReducer } from "redux-persist";
import autoMergeLevel2 from "redux-persist/lib/stateReconciler/autoMergeLevel2";
-import allReducers from "../reducers";
+import publicApi from "./reducers/public";
+import user from "./reducers/user";
+import book from "./reducers/book";
+import blog from "./reducers/blog";
+import product from "./reducers/product";
+import faq from "./reducers/faq";
+import file from "./reducers/file";
+import userFactor from "./reducers/userFactor";
+import userProduct from "./reducers/userProduct";
const persistConfig = {
key: "root",
@@ -12,18 +20,34 @@ const persistConfig = {
stateReconciler: autoMergeLevel2, // see "Merge Process" section for details.
whitelist: ["profile"],
};
-const pReducer = persistReducer(persistConfig, allReducers);
-const middleWare = [];
+const initialState = {};
-middleWare.push(thunk);
+const middleWare = [thunk];
const loggerMiddleware = createLogger({
predicate: () => process.env.NODE_ENV === "development",
});
middleWare.push(loggerMiddleware);
-const store = createStore(pReducer, compose(applyMiddleware(...middleWare)));
+const store = createStore(
+ persistReducer(
+ persistConfig,
+ combineReducers({
+ publicApi,
+ user,
+ book,
+ blog,
+ product,
+ faq,
+ file,
+ userFactor,
+ userProduct,
+ })
+ ),
+ initialState,
+ compose(applyMiddleware(...middleWare))
+);
const persistor = persistStore(store);
@@ -32,9 +56,9 @@ try {
ReactNative.I18nManager.allowRTL(true);
// enableScreens();
} catch (e) {
- console.log(e);
+ // console.log(e);
}
-console.disableYellowBox = true;
+// console.disableYellowBox = true;
-export default store;
\ No newline at end of file
+export default store;
diff --git a/src/screens/Home/components/Scroll.js b/src/screens/Home/components/Scroll.js
index 753d938..bbe34c6 100644
--- a/src/screens/Home/components/Scroll.js
+++ b/src/screens/Home/components/Scroll.js
@@ -25,7 +25,7 @@ function Scroll({ products }) {
horizontal={true}
inverted={true}
style={[tw("mt-3 pb-2")]}
- data={[{}]}
+ data={[{id : 0}]}
renderItem={({}) => }
keyExtractor={(item) => item.id}
/>
diff --git a/src/screens/Login/index.js b/src/screens/Login/index.js
index 994fe5e..bed06f3 100644
--- a/src/screens/Login/index.js
+++ b/src/screens/Login/index.js
@@ -1,57 +1,46 @@
import React, { useState } from "react";
+import {connect} from 'react-redux';
+
import {
View,
Text,
Image,
ActivityIndicator,
Dimensions,
- TextInput,
TouchableHighlight,
} from "react-native";
import Logo from "./assets/logo.png";
import CustomTextInput from "../../components/CustomTextInput";
-import { digitToEn, digitToPersian } from "../../utils";
-import services from "./services";
+import onInput from '../../utils/onInput';
import { asyncAwesomeAlert } from "../../utils/AsyncWrappers";
import tw from "tailwind-rn";
+import {user} from '../../redux/actions';
const { width, height } = Dimensions.get("window");
-let faNums = ["۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹", "۰"];
function Login(props) {
const [phone, setPhone] = useState("");
const [loading, setLoading] = useState(false);
const onChangePhone = (name, value) => {
- let items = digitToPersian(value).split("");
- for (let item of items) {
- if (!faNums.includes(item)) {
- return;
- }
- }
- setPhone(digitToPersian(value));
+ setPhone(() => value);
};
const checkPhoneNumber = () => {
- return phone.split("").length === 11;
+ return phone.split("").length === 11 && phone.slice(0, 2) === '09';
};
const submit = async () => {
- setLoading(true);
- if (!checkPhoneNumber()) {
- setLoading(false);
- return asyncAwesomeAlert("خطا", "شماره وارد شده اشتباه است", {
- showCancelButton: false,
- });
- }
- let res = await services.getSmsCode({
- cellphone: digitToEn(phone),
- });
- if (res.ok) {
- setLoading(false);
- props.navigation.navigate("Otp", { phone: digitToEn(phone) });
- }
- setLoading(false);
+ // setLoading(true);
+ // if (!checkPhoneNumber()) {
+ // setLoading(false);
+ // return asyncAwesomeAlert("خطا", "شماره وارد شده اشتباه است", {
+ // showCancelButton: false,
+ // });
+ // }
+ // props.sendPhoneNumber({cellphone : phone});
+ props.navigation.navigate("Otp", { phone: '09360467907' });
+ // setLoading(false);
};
return (
@@ -99,6 +88,7 @@ function Login(props) {
value={phone}
onChange={onChangePhone}
autoFocus={true}
+ regex={onInput.phonenumber}
/>
({
+
+})
+
+const mapDispatchToProps = {
+ sendPhoneNumber : user.otp
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(Login);
+
diff --git a/src/screens/Login/services/index.js b/src/screens/Login/services/index.js
deleted file mode 100644
index 60ef7d3..0000000
--- a/src/screens/Login/services/index.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import mocks from './mocks';
-import mainServices from './services';
-
-const mock = false;
-
-let services = {...mainServices};
-if (mock) {
- services = mocks;
-}
-export default services;
diff --git a/src/screens/Login/services/mocks.js b/src/screens/Login/services/mocks.js
deleted file mode 100644
index 73017ff..0000000
--- a/src/screens/Login/services/mocks.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import { asyncAwesomeAlert, randomApiSleep } from '../../../utils/AsyncWrappers';
-
-const data = {
-
-};
-
-const getSmsCode = async () => {
- await randomApiSleep();
- return {
- ok: true,
- data: data
- };
-};
-
-
-
-const mocks = {getSmsCode};
-export default mocks;
diff --git a/src/screens/Login/services/services.js b/src/screens/Login/services/services.js
deleted file mode 100644
index 8f59758..0000000
--- a/src/screens/Login/services/services.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import {nextFetchApi} from '../../../services/api';
-const getSmsCode = async (obj) => {
- return await nextFetchApi('/public/sendOTP', {
- method: 'POST',
- payload: obj
- });
-};
-
-const mainServices = {
- getSmsCode,
-};
-
-export default mainServices;
diff --git a/src/screens/Otp/index.js b/src/screens/Otp/index.js
index 3845097..e5bc624 100644
--- a/src/screens/Otp/index.js
+++ b/src/screens/Otp/index.js
@@ -4,21 +4,16 @@ import {
Text,
Image,
TextInput,
- TouchableHighlight,
Dimensions,
- StyleSheet,
TouchableOpacity,
ActivityIndicator,
} from "react-native";
import tw from "tailwind-rn";
-import AsyncStorage from "@react-native-async-storage/async-storage";
import { connect } from "react-redux";
import Logo from "../Login/assets/logo.png";
-import IranFlag from "../Login/components/IranFlag";
-import { digitToEn, digitToPersian } from "../../utils";
-import services from "./services";
-import { buildAction } from "../../reducers/DefaultReducer";
-import { PROFILE_RECORD } from "../../actions/actionTypes";
+import { digitToEn } from "../../utils";
+import onInput from "../../utils/onInput";
+import {user} from '../../redux/actions';
const { width } = Dimensions.get("window");
let ref1;
@@ -28,15 +23,7 @@ let ref4;
let timer = 60;
-const mapStateToProps = (state) => {
- return {
- profile: state.profile,
- };
-};
-
function Otp(props) {
- let faNums = ["۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹", "۰"];
-
const [firstCode, setFirstCode] = useState("");
const [secondCode, setSecondCode] = useState("");
const [thirdCode, setThirdCode] = useState("");
@@ -44,20 +31,7 @@ function Otp(props) {
const [time, setTime] = useState(60);
const [loading, setLoading] = useState(false);
- // useEffect(() => {
- // if (fourthCode) {
- // submit();
- // }
- // }, [fourthCode]);
-
- const checkValue = (value) => {
- return faNums.includes(digitToPersian(value));
- };
-
const onChangeCode = (value, key) => {
- // if (!checkValue()) {
- // return
- // }
switch (key) {
case "1":
setFirstCode(value);
@@ -104,39 +78,17 @@ function Otp(props) {
const submit = async () => {
setLoading(true);
- let res = await services.sendOtpCode({
+ props.sendOtp({
cellphone: props.route.params.phone,
otp: String(getEnCode()),
applicationToken: "1",
userToken: "1",
});
- console.log(
- digitToEn(firstCode) +
- digitToEn(secondCode) +
- digitToEn(thirdCode) +
- digitToEn(fourthCode)
- );
- if (res.ok) {
- 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: "Root" }],
- });
- }
setLoading(false);
};
useEffect(() => {
+ ref1.focus();
let interval = setInterval(() => {
if (time > 0) {
setTime(timer - 1);
@@ -152,6 +104,12 @@ function Otp(props) {
};
}, []);
+ // useEffect(() => {
+ // if (props.isLogin) {
+ // props.navigation.navigate('Root');
+ // }
+ // }, [props.isLogin]);
+
return (
(ref1 = ref)}
- onChangeText={(text) => onChangeCode(text, "1")}
+ onChangeText={(text) =>
+ onChangeCode(text, "1")
+ }
/>
(ref2 = ref)}
- onChangeText={(text) => onChangeCode(text, "2")}
+ onChangeText={(text) =>
+ onChangeCode(text, "2")
+ }
/>
(ref3 = ref)}
- onChangeText={(text) => onChangeCode(text, "3")}
+ onChangeText={(text) =>
+ onChangeCode(text, "3")
+ }
/>
(ref4 = ref)}
- onChangeText={(text) => onChangeCode(text, "4")}
+ onChangeText={(text) =>
+ onChangeCode(text, "4")
+ }
/>
{
- props.navigation.reset({
- index: 0,
- routes: [{ name: "Login" }],
- });
- }}
+ onPress={() => props.navigation.navigate("Login")}
>
({
+ isLogin: state.user.status,
+});
+
+const mapDispatchToProps = {
+ sendOtp: user.otp_login,
+};
+
+export default connect(mapStateToProps, mapDispatchToProps)(Otp);
diff --git a/src/screens/Otp/services/index.js b/src/screens/Otp/services/index.js
deleted file mode 100644
index 60ef7d3..0000000
--- a/src/screens/Otp/services/index.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import mocks from './mocks';
-import mainServices from './services';
-
-const mock = false;
-
-let services = {...mainServices};
-if (mock) {
- services = mocks;
-}
-export default services;
diff --git a/src/screens/Otp/services/mocks.js b/src/screens/Otp/services/mocks.js
deleted file mode 100644
index 726bd43..0000000
--- a/src/screens/Otp/services/mocks.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import { asyncAwesomeAlert, randomApiSleep } from '../../../utils/AsyncWrappers';
-
-const data = {
-
-};
-
-const sendOtpCode = async () => {
- await randomApiSleep();
- return {
- ok: true,
- data: data
- };
-};
-
-
-
-const mocks = {sendOtpCode};
-export default mocks;
diff --git a/src/screens/Otp/services/services.js b/src/screens/Otp/services/services.js
deleted file mode 100644
index 599f685..0000000
--- a/src/screens/Otp/services/services.js
+++ /dev/null
@@ -1,13 +0,0 @@
-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;
diff --git a/src/screens/Product/components/Comments.js b/src/screens/Product/components/Comments.js
index c887d45..dd2e4f1 100644
--- a/src/screens/Product/components/Comments.js
+++ b/src/screens/Product/components/Comments.js
@@ -5,7 +5,6 @@ import tw from "tailwind-rn";
const width = Dimensions.get("window").width;
export default function Commnets({ comments }) {
- console.log(comments);
return (
{
- console.log(comment);
return (
{
- return {
- profile: state.profile,
- };
-};
-
-function Splash({ navigation, profile }) {
+function Splash({ navigation, isLogin, loading}) {
+
useEffect(() => {
setTimeout(() => {
- !profile.accessToken
- ? navigation.reset({
- index: 0,
- routes: [{ name: "Login" }],
- })
- : navigation.reset({
- index: 0,
- routes: [{ name: "Root" }],
- });
+ !isLogin
+ ? navigation.navigate('Login')
+ : navigation.navigate('Root');
}, 2000);
- }, [profile]);
+
+ }, [isLogin]);
+
return (
@@ -40,4 +31,11 @@ function Splash({ navigation, profile }) {
);
}
-export default connect(mapStateToProps)(Splash);
+const mapStateToProps = (state) => ({
+ isLogin: state.user.status,
+ loading : state.userProduct.loading,
+});
+
+const mapDispatchToProps = {};
+
+export default connect(mapStateToProps, mapDispatchToProps)(Splash);
diff --git a/src/screens/Videos/index.js b/src/screens/Videos/index.js
index e42b80d..43a1710 100644
--- a/src/screens/Videos/index.js
+++ b/src/screens/Videos/index.js
@@ -1,13 +1,68 @@
-import React from 'react'
-import { View, Text } from 'react-native';
-import {connect} from 'react-redux';
-
-function Videos({}) {
- return (
-
-
-
- )
+import React, { useState } from "react";
+import {
+ View,
+ StyleSheet,
+ Dimensions,
+ ScrollView,
+ SafeAreaView,
+ StatusBar,
+ Platform,
+ LayoutAnimation
+} from "react-native";
+import tw from "tailwind-react-native-classnames";
+import Navbar from "../../components/Navbar";
+import Drawer from "../../components/Drawer";
+import Search from "../../components/Search";
+
+//assets
+
+const width = Dimensions.get("window").width;
+
+function Videos(props) {
+ const [search, setSearch] = useState("");
+ const [position, setPosition] = useState("100%");
+
+ const setBoxPosition = () => {
+ LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
+ setPosition(position === "100%" ? "0%" : "100%");
+ };
+
+ return (
+
+
+
+
+
+
+
+ );
}
+// Later on in your styles..
+const styles = StyleSheet.create({
+ contentContainerStyle: {
+ paddingBottom: 100,
+ alignItems: "flex-end",
+ },
+ container: {
+ width: Dimensions.get("window").width,
+ backgroundColor: "white",
+ flexDirection: "column",
+ paddingVertical: 0,
+ paddingHorizontal: 16,
+ },
+});
+
export default Videos;
diff --git a/src/services/api/config.js b/src/services/api/config.js
deleted file mode 100644
index d57c317..0000000
--- a/src/services/api/config.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default {
- dev: 'https://dnvn.ir/api/v1',
-};
diff --git a/src/services/api/fetch-retry.js b/src/services/api/fetch-retry.js
deleted file mode 100644
index 0af96dc..0000000
--- a/src/services/api/fetch-retry.js
+++ /dev/null
@@ -1,118 +0,0 @@
-'use strict';
-
-module.exports = function (fetch, defaults) {
- defaults = defaults || {};
- if (typeof fetch !== 'function') {
- throw new ArgumentError('fetch must be a function');
- }
-
- if (typeof defaults !== 'object') {
- throw new ArgumentError('defaults must be an object');
- }
-
- if (defaults.retries !== undefined && !isPositiveInteger(defaults.retries)) {
- throw new ArgumentError('retries must be a positive integer');
- }
-
- if (defaults.retryDelay !== undefined && !isPositiveInteger(defaults.retryDelay) && typeof defaults.retryDelay !== 'function') {
- throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer');
- }
-
- if (defaults.retryOn !== undefined && !Array.isArray(defaults.retryOn) && typeof defaults.retryOn !== 'function') {
- throw new ArgumentError('retryOn property expects an array or function');
- }
-
- var baseDefaults = {
- retries: 3,
- retryDelay: 1000,
- retryOn: [500, 502, 503, 504],
- };
-
- defaults = Object.assign(baseDefaults, defaults);
-
- return function fetchRetry(input, init) {
- var retries = defaults.retries;
- var retryDelay = defaults.retryDelay;
- var retryOn = defaults.retryOn;
-
- if (init && init.retries !== undefined) {
- if (isPositiveInteger(init.retries)) {
- retries = init.retries;
- } else {
- throw new ArgumentError('retries must be a positive integer');
- }
- }
-
- if (init && init.retryDelay !== undefined) {
- if (isPositiveInteger(init.retryDelay) || (typeof init.retryDelay === 'function')) {
- retryDelay = init.retryDelay;
- } else {
- throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer');
- }
- }
-
- if (init && init.retryOn) {
- if (Array.isArray(init.retryOn) || (typeof init.retryOn === 'function')) {
- retryOn = init.retryOn;
- } else {
- throw new ArgumentError('retryOn property expects an array or function');
- }
- }
-
- // eslint-disable-next-line no-undef
- return new Promise(function (resolve, reject) {
- var wrappedFetch = function (attempt) {
- fetch(input, init)
- .then(function (response) {
- if (Array.isArray(retryOn) && retryOn.indexOf(response.status) === -1) {
- resolve(response);
- } else if (typeof retryOn === 'function') {
- if (retryOn(attempt, null, response)) {
- retry(attempt, null, response);
- } else {
- resolve(response);
- }
- } else {
- if (attempt < retries) {
- retry(attempt, null, response);
- } else {
- resolve(response);
- }
- }
- })
- .catch(function (error) {
- if (typeof retryOn === 'function') {
- if (retryOn(attempt, error, null)) {
- retry(attempt, error, null);
- } else {
- reject(error);
- }
- } else if (attempt < retries) {
- retry(attempt, error, null);
- } else {
- reject(error);
- }
- });
- };
-
- function retry(attempt, error, response) {
- var delay = (typeof retryDelay === 'function') ?
- retryDelay(attempt, error, response) : retryDelay;
- setTimeout(function () {
- wrappedFetch(++attempt);
- }, delay);
- }
-
- wrappedFetch(0);
- });
- };
-};
-
-function isPositiveInteger(value) {
- return Number.isInteger(value) && value >= 0;
-}
-
-function ArgumentError(message) {
- this.name = 'ArgumentError';
- this.message = message;
-}
\ No newline at end of file
diff --git a/src/services/api/index.js b/src/services/api/index.js
deleted file mode 100644
index 138586b..0000000
--- a/src/services/api/index.js
+++ /dev/null
@@ -1,149 +0,0 @@
-import {Alert} from 'react-native';
-import {toastMessage} from '../../utils/message';
-import {
- restartApp,
- getToken,
- deviceHeaders,
- getUrl,
- isUnexpected,
- renewTokenHandler,
- resetApp,
- networkAlert,
- unexpectedAlert,
-} from './utils';
-import FetchRetry from './fetch-retry';
-import {asyncApiAwesomeAlert} from '../../utils/AsyncWrappers';
-
-const fetchRetry = FetchRetry(fetch, {});
-let deviceInfo;
-
-export async function fetchApi(
- endPoint,
- payload = {},
- method = 'GET',
- headers = {},
- isS = false,
- splash = false,
- dev = 'production',
-) {
- var timeout = setTimeout(() => {
- console.log(endPoint, ' TIMEOUT ');
- asyncApiAwesomeAlert('خطای ارتباط', '. لطفا اینترنت خود را بررسی کنید .').then(
- async () => await fetchApi(endPoint, payload, method, headers, isS),
- );
- }, 30000);
- if (!deviceInfo) {
- deviceInfo = await deviceHeaders();
- if (!deviceInfo) {
- deviceInfo = [];
- }
- }
- let options = {
- method,
- headers: {
- Accept: 'application/json;charset=utf-8',
- 'Content-Type': 'application/json;charset=utf-8',
- Authorization: await getToken(),
- ...deviceInfo,
- ...headers,
- },
- };
- 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) })
- if (isUnexpected(statusCode)) {
- console.log('unexpected', await res.json());
- console.log('RES-unexpected', {statusCode, url: await getUrl(endPoint)});
- let check = await unexpectedAlert();
-
- return await fetchApi(
- endPoint,
- payload,
- method,
- headers,
- isS,
- false,
- true,
- );
- }
- let {data, error, status} = await res.json();
- if (res.ok) {
- return data;
- }
- if (!res.ok) {
- // 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);
-
- return resetApp();
- }
- if (statusCode === 401) {
- let checkRenew = await renewTokenHandler();
- if (!checkRenew.ok && checkRenew.restart) {
- console.log('req-401', await getUrl(endPoint), options);
-
- resetApp();
- } else if (!checkRenew.ok) {
- console.log('req-401', await getUrl(endPoint), options);
-
- restartApp();
- }
- return await fetchApi(endPoint, payload, method, headers, isS, splash);
- }
- if (statusCode === 400) {
- return error;
- }
- return data;
- }
- } catch (err) {
- clearTimeout(timeout);
- console.log('catch', endPoint, err);
- // global.globalAlert({
- // show: true
- // })
- let check = await networkAlert();
- return await fetchApi(endPoint, payload, method, headers, isS);
- }
-}
-/**
- * next version of fetch API
- * @param {String} endPoint
- * @param {Object} options
- * @param {string} options.method
- * @param {string} options.payload
- * @param {string} options.headers
- * @param {Boolean} options.splash
- */
-export async function nextFetchApi(endPoint, options = {}) {
- let {payload, method, headers, isS, splash} = options;
- try {
- let res = await fetchApi(endPoint, payload, method, headers, isS, splash);
- return {
- ok: true,
- data: res,
- };
- } catch (error) {
- return {
- ok: false,
- data: error,
- };
- }
-}
diff --git a/src/services/api/oldindex.js b/src/services/api/oldindex.js
deleted file mode 100644
index 3c1cc4d..0000000
--- a/src/services/api/oldindex.js
+++ /dev/null
@@ -1,203 +0,0 @@
-/* global fetch */
-
-import apiConfig from './config';
-import {
- Alert,
- AlertIOS,
- Platform,
- ToastAndroid,
-} from 'react-native';
-import AsyncStorage from '@react-native-async-storage/async-storage';
-import {toastMessage} from '../../utils/message';
-
-import RNRestart from 'react-native-restart';
-import config from './config';
-import Refresh from './fetch-retry';
-import FetchRetry from './fetch-retry';
-let fetchRetry = FetchRetry(fetch, {});
-
-function restartApp() {
- AsyncStorage.setItem('UID_USER', JSON.stringify({}), () => {
- RNRestart.Restart();
- });
-}
-
-export function fetchApi(
- endPoint,
- payload = {},
- method = 'GET',
- headers = {},
- isS = false,
- splash = false,
-) {
- return new Promise((resolve, reject) => {
- var timeout = setTimeout(() => {
- console.log(endPoint, ' TIMEOUT ');
- Alert.alert('خطای ارتباط', 'خطایی ارتباط با سرور پیش امده .', [
- {
- text: 'تلاش مجدد',
- onPress: () =>
- resolve(fetchApi(endPoint, payload, method, headers, isS)),
- },
- ]);
- }, 10000);
-
- AsyncStorage.getItem('UID_USER', (err, result) => {
- var tokens = '';
- var refreshTokens = '';
- var userDATA = JSON.parse(result);
- var headrsRequest = {};
-
- if (
- userDATA != null &&
- userDATA.token != null &&
- userDATA.token != '' &&
- isS
- ) {
- tokens = userDATA.token;
-
- refreshTokens = userDATA.refresh_token;
- headers = {
- Authorization: 'Bearer ' + tokens,
- };
- }
-
- if (method === 'POST' || method === 'PUT') {
- headrsRequest = {
- method: method,
- headers: {
- Accept: 'application/json;charset=utf-8',
- 'Content-Type': 'application/json;charset=utf-8',
- ...headers,
- },
- body: JSON.stringify(payload),
- };
- } else {
- headrsRequest = {
- method: method,
- headers: {
- Accept: 'application/json;charset=utf-8',
- 'Content-Type': 'application/json;charset=utf-8',
- ...headers,
- },
- };
- }
-
- AsyncStorage.getItem('SPLASH_DATA', (err, result) => {
- var splashDATA = JSON.parse(result);
-
- var baseUrl;
-
- if (endPoint.includes('splash')) {
- baseUrl = apiConfig.splash;
- } else {
- var baseUrl = splashDATA.base_urls.backend + '/v1.1';
- }
-
- fetchRetry(`${baseUrl}${endPoint}`, headrsRequest)
- .then(response => {
- const statusCode = response.status;
- const data = response.json();
- return Promise.all([statusCode, data]);
- })
- .then(([statusCode, data]) => {
- console.log(baseUrl + endPoint, statusCode, data);
- if (data.hasOwnProperty('message')) {
- toastMessage(data.message);
- }
-
- if (statusCode === 403) {
- clearTimeout(timeout);
- restartApp();
- }
-
- if (statusCode === 401) {
- clearTimeout(timeout);
-
- var dataaaaa = {
- method: 'POST',
- body: JSON.stringify({
- refresh_token: refreshTokens,
- }),
- headers: {
- Accept: 'application/json;charset=utf-8',
- 'Content-Type': 'application/json;charset=utf-8',
- },
- };
-
- fetchRetry(`${baseUrl}/auth/renew-token`, dataaaaa)
- .then(response1 => {
- const statusCode1 = response1.status;
- const data1 = response1.json();
- return Promise.all([statusCode1, data1]);
- })
- .then(([statusCode1, data1]) => {
- console.log(
- 'refresh token call and response is ',
- statusCode1,
- data1,
- refreshTokens,
- );
-
- if (statusCode1 == 200) {
- userDATA.token = data1.data.token;
- AsyncStorage.setItem(
- 'UID_USER',
- JSON.stringify(userDATA),
- () => {
- resolve(
- fetchApi(endPoint, payload, method, headers, isS),
- );
- },
- );
- } else {
- restartApp();
- }
- })
- .catch(e => restartApp());
- }
-
- if (statusCode === 400) {
- toastMessage(data.error.message);
- clearTimeout(timeout);
-
- reject(data.error);
- }
-
- if (statusCode === 200) {
- clearTimeout(timeout);
- resolve(data.data);
- }
-
- if (statusCode === 201) {
- clearTimeout(timeout);
- resolve(data.data);
- }
-
- return data;
- })
- .catch(async e => {
- console.log('e', error.message);
- let res = await neto();
- if (e.networkError) {
- toastMessage('اشکال در اتصال اینترنت دوباره تلاش کنید .');
- Alert.alert(
- 'اینترنت',
- 'اشکال در اتصال اینترنت دوباره تلاش کنید .',
- [
- {
- text: 'تلاش مجدد',
- onPress: () =>
- resolve(
- fetchApi(endPoint, payload, method, headers, isS),
- ),
- },
- {text: 'بیخیال', onPress: () => reject(e)},
- ],
- );
- }
- });
- });
- });
- });
-}
diff --git a/src/services/api/utils.js b/src/services/api/utils.js
deleted file mode 100644
index 605b433..0000000
--- a/src/services/api/utils.js
+++ /dev/null
@@ -1,145 +0,0 @@
-import RNRestart from 'react-native-restart';
-import { toastMessage } from "../../utils/message"
-import { asyncAlert, asyncAwesomeAlert, asyncApiAwesomeAlert } from "../../utils/AsyncWrappers";
-import * as Device from 'expo-device';
-import {
- ImageBackground,
- Text,
- Image,
- View,
- SafeAreaView,
- StyleSheet,
- BackHandler,
- Platform,
-} from 'react-native';
-import AsyncStorage from '@react-native-async-storage/async-storage';
-import apiConfig from './config';
-import FetchRetry from './fetch-retry'
-import { nextFetchApi } from '.';
-
-const fetchRetry = FetchRetry(fetch, {})
-
-export const restartApp = () => {
- RNRestart.Restart()
-}
-export const resetApp = () => {
- AsyncStorage.setItem('UID_USER', JSON.stringify({}), () => {
- RNRestart.Restart()
- });
-}
-export const networkAlert = async () => {
- return await asyncApiAwesomeAlert("خطا", "خطا در اتصال به اینترنت", {
- confirmText: "تلاش مجدد"
- })
-}
-export const unexpectedAlert = async () => {
- return await asyncApiAwesomeAlert("خطا", "خطای داخلی سرور!", {
- confirmText: "تلاش مجدد"
- })
- // return await asyncAlert("خطا","خطای داخلی سرور!", [
- // { text: "تلاش مجدد", value: 'retry' },
- // // { text: "بیخیال", value: 'ignore' }
- // ])
-}
-export const getToken = async () => {
- let token = await AsyncStorage.getItem('accessToken')
- if (!token) {
- return ''
- }
- return 'Bearer ' + token
-}
-export const deviceHeaders = async () => {
- return {
- 'dev-os': Platform.OS,
- 'dev-app-version': '1.6.0',
- 'dev-os-version': Platform.Version + '',
- 'dev-phone-manufacturer': Device.brand,
- 'dev-phone-model': Device.modelName,
- 'dev-phone-hash': Device.modelId,
- }
-}
-export const getUrl = async (endpoint, dev) => {
- if (endpoint.includes('splash')) {
- if (dev === 'dev') {
- return apiConfig.dev + endpoint
- }
- return apiConfig.splash + endpoint
- }
- let base_urls = await getBaseUrls()
- return base_urls + endpoint
-}
-
-export const isUnexpected = (statusCode) => {
- if (![200, 201, 400, 401, 403].includes(statusCode)) return true
- return false
-}
-export const renewTokenHandler = async () => {
- try {
- let refreshToken = JSON.parse(await AsyncStorage.getItem('refreshToken'))
- if (!refreshToken) {
- return {
- ok: false,
- restart: true
- }
- }
- const options = {
- method: 'POST',
- body: JSON.stringify({
- refresh_token: refreshToken
- }),
- headers: {
- Accept: 'application/json;charset=utf-8',
- 'Content-Type': 'application/json;charset=utf-8'
- }
- }
- let res = await fetchRetry(await getUrl('/user/login'), options)
- let { data } = await res.json()
- const statusCode = res.status
- if (statusCode == 200) {
- await AsyncStorage.setItem('refreshToken', JSON.stringify(data.refreshToken))
- await AsyncStorage.setItem('accessToken', JSON.stringify(data.accessToken))
- return {
- ok: true
- }
- }
- if (statusCode == 400) {
- return {
- ok: false,
- restart: true
- }
- }
- return {
- ok: false
- }
- } catch (error) {
- return {
- ok: false
- }
- }
-}
-export const getBaseUrls = async () => {
- // 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'))
-}
-
-export const cacheProfile = async () => {
- let data = await getProfile()
- let oldData = await getCachedProfile()
- if (data) {
- await AsyncStorage.removeItem('UID_USER')
-
- await AsyncStorage.setItem('UID_USER', JSON.stringify({
- ...oldData,
- ...data
- }))
- }
-
-}
-export const getProfile = async () => {
- let { ok, data } = await nextFetchApi('/profile?with_details=1&no_cache=1')
- if (!ok) return null
- return data
-}
diff --git a/src/services/i18n/index.js b/src/services/i18n/index.js
deleted file mode 100644
index a8531e8..0000000
--- a/src/services/i18n/index.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import i18n from "i18next";
-import { initReactI18next } from "react-i18next";
-import { Platform } from "react-native";
-import resources from './locales'
-
-i18n.use(initReactI18next).init({
- resources: resources,
- lng: "fa",
- fallbackLng: "fa",
- compatibilityJSON: Platform.OS === 'android' ? 'v3' : '',
- interpolation: {
- escapeValue: false
- }
-});
-
-export default i18n;
\ No newline at end of file
diff --git a/src/services/i18n/locales/en/translation.json b/src/services/i18n/locales/en/translation.json
deleted file mode 100644
index b012430..0000000
--- a/src/services/i18n/locales/en/translation.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "main": {
- "home": "Home",
- "settings": "Settings",
- "profile": "Profile",
- "filter": "filter"
- },
- "filter": {
- "newest": "newest",
- "oldest": "oldest"
- },
- "profile": {
- "first name": "first name",
- "last name": "last name",
- "birthday": "birthday",
- "gender": "gender",
- "addresses": "addresses",
- "day": "day",
- "month": "month",
- "year": "year",
- "male": "male",
- "female": "female",
- "submit changes": "submit changes"
- },
- "settings": {
- "language": "language"
- }
-}
diff --git a/src/services/i18n/locales/fa/translation.json b/src/services/i18n/locales/fa/translation.json
deleted file mode 100644
index 9dddd3a..0000000
--- a/src/services/i18n/locales/fa/translation.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "main": {
- "home": "صفحه اصلی",
- "books": "کتاب ها",
- "videos": "ویدئوها",
- "exams": "آزمون ها",
- "profile": "حساب کاربری"
- },
- "filter": {
- "newest": "جدیدترین",
- "oldest": "قدیمی ترین"
- },
- "profile": {
- "first name": "نام",
- "last name": "نام خانوادگی",
- "birthday": "تاریخ تولد",
- "gender": "جنسیت",
- "addresses": "آدرس ها",
- "day": "روز",
- "month": "ماه",
- "year": "سال",
- "male": "آقا",
- "female": "خانم",
- "submit changes": "ثبت تغییرات"
- },
- "settings": {
- "language": "زبان"
- }
-}
diff --git a/src/services/i18n/locales/index.js b/src/services/i18n/locales/index.js
deleted file mode 100644
index 41bce38..0000000
--- a/src/services/i18n/locales/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import en from './en/translation.json';
-import fa from './fa/translation.json';
-
-export default {
- en: {
- translation: en
- },
- fa: {
- translation: fa
- }
-}
\ No newline at end of file
diff --git a/src/utils/message.js b/src/utils/message.js
index 011e971..07d92f9 100644
--- a/src/utils/message.js
+++ b/src/utils/message.js
@@ -1,4 +1,4 @@
-import { AsyncStorage, AlertIOS, Platform, ToastAndroid, } from "react-native"
+import { AlertIOS, Platform, ToastAndroid, } from "react-native"
export const toastMessage = (msg) => {
if (Platform.OS === 'android') {
diff --git a/src/utils/onInput.js b/src/utils/onInput.js
new file mode 100644
index 0000000..8da5361
--- /dev/null
+++ b/src/utils/onInput.js
@@ -0,0 +1,280 @@
+class onInput {
+ persianOnly = (txt) => {
+ let newText = txt;
+ newText = newText.replace(/`/g, "");
+ newText = newText.replace(/0/g, "");
+ newText = newText.replace(/1/g, "");
+ newText = newText.replace(/2/g, "");
+ newText = newText.replace(/3/g, "");
+ newText = newText.replace(/4/g, "");
+ newText = newText.replace(/5/g, "");
+ newText = newText.replace(/6/g, "");
+ newText = newText.replace(/7/g, "");
+ newText = newText.replace(/8/g, "");
+ newText = newText.replace(/9/g, "");
+ newText = newText.replace(/0/g, "");
+ newText = newText.replace(/q/g, "");
+ newText = newText.replace(/w/g, "");
+ newText = newText.replace(/e/g, "");
+ newText = newText.replace(/r/g, "");
+ newText = newText.replace(/t/g, "");
+ newText = newText.replace(/y/g, "");
+ newText = newText.replace(/u/g, "");
+ newText = newText.replace(/i/g, "");
+ newText = newText.replace(/o/g, "");
+ newText = newText.replace(/p/g, "");
+ newText = newText.replace(/\[/g, "");
+ newText = newText.replace(/\]/g, "");
+ newText = newText.replace(/a/g, "");
+ newText = newText.replace(/s/g, "");
+ newText = newText.replace(/d/g, "");
+ newText = newText.replace(/f/g, "");
+ newText = newText.replace(/g/g, "");
+ newText = newText.replace(/h/g, "");
+ newText = newText.replace(/j/g, "");
+ newText = newText.replace(/k/g, "");
+ newText = newText.replace(/l/g, "");
+ newText = newText.replace(/;/g, "");
+ newText = newText.replace(/'/g, "");
+ newText = newText.replace(/z/g, "");
+ newText = newText.replace(/x/g, "");
+ newText = newText.replace(/c/g, "");
+ newText = newText.replace(/v/g, "");
+ newText = newText.replace(/b/g, "");
+ newText = newText.replace(/n/g, "");
+ newText = newText.replace(/m/g, "");
+ newText = newText.replace(/,/g, "");
+ newText = newText.replace(/./g, "");
+ newText = newText.replace(/\//g, "");
+ newText = newText.replace(/~/g, " ");
+ newText = newText.replace(/Q/g, "");
+ newText = newText.replace(/W/g, "");
+ newText = newText.replace(/E/g, "");
+ newText = newText.replace(/R/g, "");
+ newText = newText.replace(/T/g, "");
+ newText = newText.replace(/Y/g, "");
+ newText = newText.replace(/U/g, "");
+ newText = newText.replace(/I/g, "");
+ newText = newText.replace(/O/g, "");
+ newText = newText.replace(/P/g, "");
+ newText = newText.replace(/A/g, "");
+ newText = newText.replace(/S/g, "");
+ newText = newText.replace(/G/g, "");
+ newText = newText.replace(/H/g, "");
+ newText = newText.replace(/J/g, "");
+ newText = newText.replace(/K/g, "");
+ newText = newText.replace(/L/g, "");
+ newText = newText.replace(/Z/g, "");
+ newText = newText.replace(/X/g, "");
+ newText = newText.replace(/B/g, "");
+ newText = newText.replace(/N/g, "");
+ newText = newText.replace(/M/g, "");
+ newText = newText.replace(/\?/g, "");
+ if (!newText && newText.length !== 0) {
+ // toast.info("از کاراکتر فارسی استفاده کنید");
+ }
+ return newText;
+ };
+ englishAndNumberWithoutSpace = (txt) => {
+ let newText = txt;
+ newText = newText.replace(/`/g, "");
+ newText = newText.replace(/0/g, "0");
+ newText = newText.replace(/1/g, "1");
+ newText = newText.replace(/2/g, "2");
+ newText = newText.replace(/3/g, "3");
+ newText = newText.replace(/4/g, "4");
+ newText = newText.replace(/5/g, "5");
+ newText = newText.replace(/6/g, "6");
+ newText = newText.replace(/7/g, "7");
+ newText = newText.replace(/8/g, "8");
+ newText = newText.replace(/9/g, "9");
+ newText = newText.replace(/ا/g, "");
+ newText = newText.replace(/ب/g, "");
+ newText = newText.replace(/پ/g, "");
+ newText = newText.replace(/ت/g, "");
+ newText = newText.replace(/ث/g, "");
+ newText = newText.replace(/ج/g, "");
+ newText = newText.replace(/چ/g, "");
+ newText = newText.replace(/ح/g, "");
+ newText = newText.replace(/خ/g, "");
+ newText = newText.replace(/د/g, "");
+ newText = newText.replace(/\[/g, "");
+ newText = newText.replace(/\]/g, "");
+ newText = newText.replace(/ذ/g, "");
+ newText = newText.replace(/ر/g, "");
+ newText = newText.replace(/ز/g, "");
+ newText = newText.replace(/ژ/g, "");
+ newText = newText.replace(/ط/g, "");
+ newText = newText.replace(/ظ/g, "");
+ newText = newText.replace(/ع/g, "");
+ newText = newText.replace(/غ/g, "");
+ newText = newText.replace(/ف/g, "");
+ newText = newText.replace(/;/g, "");
+ newText = newText.replace(/'/g, "");
+ newText = newText.replace(/ق/g, "");
+ newText = newText.replace(/س/g, "");
+ newText = newText.replace(/ش/g, "");
+ newText = newText.replace(/ص/g, "");
+ newText = newText.replace(/ض/g, "");
+ newText = newText.replace(/ک/g, "");
+ newText = newText.replace(/گ/g, "");
+ newText = newText.replace(/,/g, "");
+ newText = newText.replace(/\./g, "");
+ newText = newText.replace(/\//g, "");
+ newText = newText.replace(/~/g, " ");
+ newText = newText.replace(/ل/g, "");
+ newText = newText.replace(/م/g, "");
+ newText = newText.replace(/ن/g, "");
+ newText = newText.replace(/و/g, "");
+ newText = newText.replace(/ه/g, "");
+ newText = newText.replace(/ی/g, "");
+ newText = newText.replace(/\?/g, "");
+ if (!newText && newText.length !== 0) {
+ // toast.info("از کاراکتر انگلیسی واعداداستفاده کنید");
+ }
+ return newText;
+ };
+ numberOnly = (txt) => {
+ let newText = txt;
+ newText = newText.replace(/`/g, "");
+ newText = newText.replace(/0/g, "0");
+ newText = newText.replace(/1/g, "1");
+ newText = newText.replace(/2/g, "2");
+ newText = newText.replace(/3/g, "3");
+ newText = newText.replace(/4/g, "4");
+ newText = newText.replace(/5/g, "5");
+ newText = newText.replace(/6/g, "6");
+ newText = newText.replace(/7/g, "7");
+ newText = newText.replace(/8/g, "8");
+ newText = newText.replace(/9/g, "9");
+ newText = newText.replace(/ا/g, "");
+ newText = newText.replace(/ب/g, "");
+ newText = newText.replace(/پ/g, "");
+ newText = newText.replace(/ت/g, "");
+ newText = newText.replace(/ث/g, "");
+ newText = newText.replace(/ج/g, "");
+ newText = newText.replace(/چ/g, "");
+ newText = newText.replace(/ح/g, "");
+ newText = newText.replace(/خ/g, "");
+ newText = newText.replace(/د/g, "");
+ newText = newText.replace(/\[/g, "");
+ newText = newText.replace(/\]/g, "");
+ newText = newText.replace(/ذ/g, "");
+ newText = newText.replace(/ر/g, "");
+ newText = newText.replace(/ز/g, "");
+ newText = newText.replace(/ژ/g, "");
+ newText = newText.replace(/ط/g, "");
+ newText = newText.replace(/ظ/g, "");
+ newText = newText.replace(/ع/g, "");
+ newText = newText.replace(/غ/g, "");
+ newText = newText.replace(/ف/g, "");
+ newText = newText.replace(/;/g, "");
+ newText = newText.replace(/'/g, "");
+ newText = newText.replace(/ق/g, "");
+ newText = newText.replace(/س/g, "");
+ newText = newText.replace(/ش/g, "");
+ newText = newText.replace(/ص/g, "");
+ newText = newText.replace(/ض/g, "");
+ newText = newText.replace(/ک/g, "");
+ newText = newText.replace(/گ/g, "");
+ newText = newText.replace(/\,/g, "");
+ newText = newText.replace(/\./g, "");
+ newText = newText.replace(/\//g, "");
+ newText = newText.replace(/~/g, " ");
+ newText = newText.replace(/ل/g, "");
+ newText = newText.replace(/م/g, "");
+ newText = newText.replace(/ن/g, "");
+ newText = newText.replace(/و/g, "");
+ newText = newText.replace(/ه/g, "");
+ newText = newText.replace(/ی/g, "");
+ newText = newText.replace(/\?/g, "");
+ newText = newText.replace(/q/g, "");
+ newText = newText.replace(/w/g, "");
+ newText = newText.replace(/e/g, "");
+ newText = newText.replace(/r/g, "");
+ newText = newText.replace(/t/g, "");
+ newText = newText.replace(/y/g, "");
+ newText = newText.replace(/u/g, "");
+ newText = newText.replace(/i/g, "");
+ newText = newText.replace(/o/g, "");
+ newText = newText.replace(/p/g, "");
+ newText = newText.replace(/a/g, "");
+ newText = newText.replace(/s/g, "");
+ newText = newText.replace(/d/g, "");
+ newText = newText.replace(/f/g, "");
+ newText = newText.replace(/g/g, "");
+ newText = newText.replace(/h/g, "");
+ newText = newText.replace(/j/g, "");
+ newText = newText.replace(/k/g, "");
+ newText = newText.replace(/l/g, "");
+ newText = newText.replace(/z/g, "");
+ newText = newText.replace(/x/g, "");
+ newText = newText.replace(/c/g, "");
+ newText = newText.replace(/v/g, "");
+ newText = newText.replace(/b/g, "");
+ newText = newText.replace(/n/g, "");
+ newText = newText.replace(/m/g, "");
+ newText = newText.replace(/Q/g, "");
+ newText = newText.replace(/W/g, "");
+ newText = newText.replace(/E/g, "");
+ newText = newText.replace(/R/g, "");
+ newText = newText.replace(/T/g, "");
+ newText = newText.replace(/Y/g, "");
+ newText = newText.replace(/U/g, "");
+ newText = newText.replace(/I/g, "");
+ newText = newText.replace(/O/g, "");
+ newText = newText.replace(/P/g, "");
+ newText = newText.replace(/A/g, "");
+ newText = newText.replace(/S/g, "");
+ newText = newText.replace(/G/g, "");
+ newText = newText.replace(/H/g, "");
+ newText = newText.replace(/J/g, "");
+ newText = newText.replace(/K/g, "");
+ newText = newText.replace(/L/g, "");
+ newText = newText.replace(/Z/g, "");
+ newText = newText.replace(/X/g, "");
+ newText = newText.replace(/B/g, "");
+ newText = newText.replace(/N/g, "");
+ newText = newText.replace(/M/g, "");
+ if (!newText && newText.length !== 0) {
+ // toast.info("از اعداداستفاده کنید");
+ }
+ return newText;
+ };
+ dayHandler = (num) => {
+ let newNum = this.numberOnly(num);
+ if (newNum > 31) {
+ // toast.error("روز نباید بزرگتر از 31 باشد.");
+ return Math.floor(newNum / 10);
+ }
+ return newNum;
+ };
+ monthHandler = (num) => {
+ let newNum = this.numberOnly(num);
+ if (newNum > 12 || newNum < 0) {
+ // toast.error("ماه باید بین 1 تا 12 باشد.");
+ return Math.floor(newNum / 10);
+ }
+ return newNum;
+ };
+ yearHandler = (num) => {
+ let newNum = this.numberOnly(num);
+ if (newNum > 1395) {
+ // toast.error("سال باید کوچکتر از 1395 باشد.");
+ return Math.floor(newNum / 10);
+ }
+ return newNum;
+ };
+ phonenumber = (value) => {
+ let formattedValue = value
+ .replace(/[\u0660-\u0669\u06f0-\u06f9]/g, function (c) {
+ return c.charCodeAt(0) & 0xf;
+ })
+ .replace(/[^\d]/, "");
+ return formattedValue;
+ };
+}
+
+const _onInput = new onInput();
+
+export default _onInput;
diff --git a/yarn.lock b/yarn.lock
index b047327..a22da5d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1845,6 +1845,13 @@ atob@^2.1.2:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
+axios@^0.24.0:
+ version "0.24.0"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6"
+ integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==
+ dependencies:
+ follow-redirects "^1.14.4"
+
babel-core@^7.0.0-bridge.0:
version "7.0.0-bridge.0"
resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece"
@@ -3143,6 +3150,11 @@ flow-parser@^0.121.0:
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.121.0.tgz#9f9898eaec91a9f7c323e9e992d81ab5c58e618f"
integrity sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg==
+follow-redirects@^1.14.4:
+ version "1.14.6"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd"
+ integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==
+
fontfaceobserver@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fontfaceobserver/-/fontfaceobserver-2.1.0.tgz#e2705d293e2c585a6531c2a722905657317a2991"