diff --git a/App.js b/App.js index 09f879b..9ee597f 100644 --- a/App.js +++ b/App.js @@ -1,20 +1,58 @@ -import { StatusBar } from 'expo-status-bar'; -import { StyleSheet, Text, View } from 'react-native'; +import React from "react"; +import { StyleSheet, useColorScheme } from "react-native"; +import AsyncStorage from "@react-native-async-storage/async-storage"; +import { Provider } from "react-redux"; +import { applyMiddleware, createStore, compose } 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 "./src/reducers"; +import Navigator from "./navigation"; +import AlertModal from "./src/components/AlertModal"; + +const persistConfig = { + key: "root", + storage: AsyncStorage, + stateReconciler: autoMergeLevel2, // see "Merge Process" section for details. + whitelist: ["profile"], +}; +const pReducer = persistReducer(persistConfig, allReducers); + +const middleWare = []; + +middleWare.push(thunk); + +const loggerMiddleware = createLogger({ + predicate: () => process.env.NODE_ENV === "development", +}); +middleWare.push(loggerMiddleware); + +const store = createStore(pReducer, compose(applyMiddleware(...middleWare))); + +const persistor = persistStore(store); + +const ReactNative = require("react-native"); +try { + ReactNative.I18nManager.allowRTL(true); + // enableScreens(); +} catch (e) { + console.log(e); +} + +console.disableYellowBox = true; + +const App = () => { + const isDarkMode = useColorScheme() === "dark"; -export default function App() { return ( - - Open up App.js to start working on your app! - - + + + + ); -} +}; -const styles = StyleSheet.create({ - container: { - flex: 1, - backgroundColor: '#fff', - alignItems: 'center', - justifyContent: 'center', - }, -}); +const styles = StyleSheet.create({}); + +export default App; diff --git a/app.json b/app.json index d0413a6..d3d545e 100644 --- a/app.json +++ b/app.json @@ -23,7 +23,8 @@ "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#FFFFFF" - } + }, + "package": "com.appsazz.RnDanovinExpo" }, "web": { "favicon": "./assets/favicon.png" diff --git a/navigation.js b/navigation.js new file mode 100644 index 0000000..6dc6560 --- /dev/null +++ b/navigation.js @@ -0,0 +1,130 @@ +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 {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'; +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) { + const {t} = useTranslation('translation', {keyPrefix: 'main'}); + + return ( + + + + + + + + ); +} + +function Navigator(props) { + React.useEffect(() => { + i18n.changeLanguage(props.config.lan); + }, [props.config]); + + return ( + + + + + {/* */} + + + + + + + + + ); +} + +export default connect(mapStateToProps)(Navigator); diff --git a/package.json b/package.json index a8f084b..ca0522a 100644 --- a/package.json +++ b/package.json @@ -10,12 +10,32 @@ "eject": "expo eject" }, "dependencies": { + "@react-native-async-storage/async-storage": "~1.15.0", + "@react-navigation/bottom-tabs": "^6.0.9", + "@react-navigation/native": "^6.0.6", + "@react-navigation/native-stack": "^6.2.5", "expo": "~44.0.0", + "expo-device": "~4.1.0", "expo-status-bar": "~1.2.0", + "i18next": "^21.6.3", + "lodash": "^4.17.21", "react": "17.0.1", "react-dom": "17.0.1", + "react-i18next": "^11.15.1", "react-native": "0.64.3", - "react-native-web": "0.17.1" + "react-native-awesome-alerts": "^1.5.2", + "react-native-restart": "^0.0.22", + "react-native-safe-area-context": "3.3.2", + "react-native-screens": "~3.10.1", + "react-native-select-dropdown": "^1.6.0", + "react-native-web": "0.17.1", + "react-redux": "^7.2.6", + "redux": "^4.1.2", + "redux-logger": "^3.0.6", + "redux-persist": "^6.0.0", + "redux-thunk": "^2.4.1", + "tailwind-react-native-classnames": "^1.5.1", + "tailwind-rn": "^3.0.1" }, "devDependencies": { "@babel/core": "^7.12.9" diff --git a/src/actions/actionTypes.js b/src/actions/actionTypes.js new file mode 100644 index 0000000..170cedd --- /dev/null +++ b/src/actions/actionTypes.js @@ -0,0 +1,2 @@ +export const PROFILE_RECORD = 'PROFILE_RECORD'; +export const APP_CONFIG = 'APP_CONFIG'; diff --git a/src/assets/icons/activation.png b/src/assets/icons/activation.png new file mode 100644 index 0000000..f368c64 Binary files /dev/null and b/src/assets/icons/activation.png differ diff --git a/src/assets/icons/ar-light.png b/src/assets/icons/ar-light.png new file mode 100644 index 0000000..1961afb Binary files /dev/null and b/src/assets/icons/ar-light.png differ diff --git a/src/assets/icons/bookmark.png b/src/assets/icons/bookmark.png new file mode 100644 index 0000000..cc45130 Binary files /dev/null and b/src/assets/icons/bookmark.png differ diff --git a/src/assets/icons/dropdown.png b/src/assets/icons/dropdown.png new file mode 100644 index 0000000..69d6468 Binary files /dev/null and b/src/assets/icons/dropdown.png differ diff --git a/src/assets/icons/hamburger-light.png b/src/assets/icons/hamburger-light.png new file mode 100644 index 0000000..a482a9e Binary files /dev/null and b/src/assets/icons/hamburger-light.png differ diff --git a/src/assets/icons/leftWhite.png b/src/assets/icons/leftWhite.png new file mode 100644 index 0000000..913c78b Binary files /dev/null and b/src/assets/icons/leftWhite.png differ diff --git a/src/assets/icons/link.png b/src/assets/icons/link.png new file mode 100644 index 0000000..b328dc1 Binary files /dev/null and b/src/assets/icons/link.png differ diff --git a/src/assets/icons/logo.png b/src/assets/icons/logo.png new file mode 100644 index 0000000..af3b208 Binary files /dev/null and b/src/assets/icons/logo.png differ diff --git a/src/assets/icons/pdf.png b/src/assets/icons/pdf.png new file mode 100644 index 0000000..7f3bd1e Binary files /dev/null and b/src/assets/icons/pdf.png differ diff --git a/src/assets/icons/ppt.png b/src/assets/icons/ppt.png new file mode 100644 index 0000000..80965ba Binary files /dev/null and b/src/assets/icons/ppt.png differ diff --git a/src/assets/icons/qr-light.png b/src/assets/icons/qr-light.png new file mode 100644 index 0000000..34595b0 Binary files /dev/null and b/src/assets/icons/qr-light.png differ diff --git a/src/assets/icons/search.png b/src/assets/icons/search.png new file mode 100644 index 0000000..02bc530 Binary files /dev/null and b/src/assets/icons/search.png differ diff --git a/src/assets/images/logo.png b/src/assets/images/logo.png new file mode 100644 index 0000000..42ea219 Binary files /dev/null and b/src/assets/images/logo.png differ diff --git a/src/assets/video.mp4 b/src/assets/video.mp4 new file mode 100644 index 0000000..fd6954b Binary files /dev/null and b/src/assets/video.mp4 differ diff --git a/src/components/AlertModal.js b/src/components/AlertModal.js new file mode 100644 index 0000000..fac4a33 --- /dev/null +++ b/src/components/AlertModal.js @@ -0,0 +1,137 @@ +import React, { useState } from "react" +import AwesomeAlert from 'react-native-awesome-alerts'; +const ReactNative = require('react-native'); + +const AlertModal = props => { + const [alert, setAlert] = useState({ + show: false, + showProgress: false, + title: "خطا", + message: "خطای ناشناخته", + closeOnTouchOutside: false, + closeOnHardwareBackPress: false, + showCancelButton: true, + showConfirmButton: true, + cancelText: "بیخیال", + confirmText: "باشه", + confirmButtonColor: "#2980b9", + onCancel: () => { + }, + onConfirm: () => { + + }, + }) + const [apiAlert, setApiAlert] = useState({ + show: false, + showProgress: false, + title: "خطا", + message: "خطای ناشناخته", + closeOnTouchOutside: false, + closeOnHardwareBackPress: false, + showCancelButton: true, + showConfirmButton: true, + cancelText: "بیخیال", + confirmText: "باشه", + confirmButtonColor: "#2980b9", + onCancel: () => { + }, + onConfirm: () => { + }, + }) + + global.globalAlert = (params) => { + setAlert({ + ...alert, + ...params + }) + } + global.globalApiAlert = (params) => { + + setApiAlert({ + ...apiAlert, + ...params + }) + } + + function hideAlert() { + setAlert({ ...alert, show: false }) + } + function onApiCancelPressed(){ + globalApiAlert({ show: false }) + + apiAlert.onCancel() + } + function onApiConfirmPressed(){ + globalApiAlert({ show: false }) + apiAlert.onConfirm() + } + function onCancelPressed(){ + hideAlert() + alert.onCancel() + } + function onConfirmPressed(){ + hideAlert() + alert.onConfirm() + } + return <> + + + + +} + +export default AlertModal; diff --git a/src/components/CustomTextInput.js b/src/components/CustomTextInput.js new file mode 100644 index 0000000..4d84604 --- /dev/null +++ b/src/components/CustomTextInput.js @@ -0,0 +1,59 @@ +import React, {useState} from 'react'; +import {TextInput, View, Text, Dimensions, StyleSheet} from 'react-native'; +import tw from 'tailwind-react-native-classnames'; + +const FloatingLabelInput = ({ + label, + textAlign, + direction, + labelBackgroundColor, + onChange, + value, + name, + ...props +}) => { + const [isFocused, setIsFocused] = useState(false); + const styles = StyleSheet.create({ + labelStyle: { + position: 'absolute', + right: 15, + backgroundColor: 'white', + zIndex: 100, + paddingHorizontal: 5, + textAlign: 'center', + top: !isFocused ? '50%' : 0, + fontSize: !isFocused ? Dimensions.get('window').width / 27 : 14, + transform: [{translateY: -Dimensions.get('window').width / 35}], + color: !isFocused ? '#555' : '#6CBE44', + // transition: Transitions.all(Transitions.) + }, + inputStyle: { + fontSize: Dimensions.get('window').width / 25, + color: '#000', + borderWidth: 0.5, + borderColor: isFocused ? '#6CBE44' : '#555', + paddingVertical: 15, + paddingHorizontal: 10, + direction: 'rtl', + textAlign: 'right', + }, + }); + return ( + + + {label} + + onChange(name, text)} + onFocus={() => setIsFocused(true)} + onBlur={() => + value ? setIsFocused(() => true) : setIsFocused(() => false) + } + /> + + ); +}; + +export default FloatingLabelInput; diff --git a/src/components/FormButton.js b/src/components/FormButton.js new file mode 100644 index 0000000..6d4af07 --- /dev/null +++ b/src/components/FormButton.js @@ -0,0 +1,31 @@ +import React from 'react'; +import {StyleSheet, Text, Pressable, Dimensions } from 'react-native'; + +export default function FormButton({text, color, onPress}) { + const styles = StyleSheet.create({ + button: { + width : '100%', + alignItems: 'center', + justifyContent: 'center', + paddingVertical: 12, + paddingHorizontal: 0, + borderRadius: 6, + elevation: 3, + backgroundColor: color, + }, + text: { + fontSize: Dimensions.get('window').width / 25, + fontWeight: '300', + color: 'white', + }, + }); + return ( + onPress} + > + {text} + + ); +} diff --git a/src/components/Header.js b/src/components/Header.js new file mode 100644 index 0000000..9aa2911 --- /dev/null +++ b/src/components/Header.js @@ -0,0 +1,33 @@ +import React from 'react'; +import {View, Text, Dimensions, Image} from 'react-native'; +import tw from 'tailwind-react-native-classnames'; + +const width = Dimensions.get('window').width; +const height = Dimensions.get('window').height; + +export default function Header({icon, title, description, background}) { + return ( + + + + + {title} + + + {description} + + + ); +} diff --git a/src/components/Navbar.js b/src/components/Navbar.js new file mode 100644 index 0000000..1260892 --- /dev/null +++ b/src/components/Navbar.js @@ -0,0 +1,69 @@ +import React, {useCallback} from 'react'; +import {Image, StyleSheet, View, TouchableOpacity} from 'react-native'; +import {useNavigation} from '@react-navigation/native'; +import tw from 'tailwind-rn'; + +//colors +import Color from '../constants/Colors'; + +//assets +import hamburgerLightIcon from '../assets/icons/hamburger-light.png'; +import logoIcon from '../assets/icons/logo.png'; +import qrLightIcon from '../assets/icons/qr-light.png'; +import arLightIcon from '../assets/icons/ar-light.png'; + +const Navbar = ({notification}) => { + const navigation = useNavigation(); + const Button = useCallback(({icon, route}) => { + return ( + navigation.navigate(route)}> + + + ); + }, []); + return ( + + + + {notification && ( + + )} + + + +