first commit

master
Reza_ashrafi 3 years ago
parent ed04c5e32c
commit 5dc7b0d1bf
  1. 70
      App.js
  2. 3
      app.json
  3. 130
      navigation.js
  4. 22
      package.json
  5. 2
      src/actions/actionTypes.js
  6. BIN
      src/assets/icons/activation.png
  7. BIN
      src/assets/icons/ar-light.png
  8. BIN
      src/assets/icons/bookmark.png
  9. BIN
      src/assets/icons/dropdown.png
  10. BIN
      src/assets/icons/hamburger-light.png
  11. BIN
      src/assets/icons/leftWhite.png
  12. BIN
      src/assets/icons/link.png
  13. BIN
      src/assets/icons/logo.png
  14. BIN
      src/assets/icons/pdf.png
  15. BIN
      src/assets/icons/ppt.png
  16. BIN
      src/assets/icons/qr-light.png
  17. BIN
      src/assets/icons/search.png
  18. BIN
      src/assets/images/logo.png
  19. BIN
      src/assets/video.mp4
  20. 137
      src/components/AlertModal.js
  21. 59
      src/components/CustomTextInput.js
  22. 31
      src/components/FormButton.js
  23. 33
      src/components/Header.js
  24. 69
      src/components/Navbar.js
  25. 20
      src/components/Or.js
  26. 28
      src/components/Pressable.js
  27. 34
      src/components/Progress.js
  28. 30
      src/components/Redirect.js
  29. 55
      src/components/Search.js
  30. 46
      src/components/Select.js
  31. 23
      src/components/Video.js
  32. 19
      src/constants/Colors.js
  33. 29
      src/reducers/DefaultReducer.js
  34. 14
      src/reducers/index.js
  35. 13
      src/screens/AR/index.js
  36. BIN
      src/screens/Activation/assets/alert.png
  37. BIN
      src/screens/Activation/assets/bgQr.png
  38. BIN
      src/screens/Activation/assets/book.png
  39. BIN
      src/screens/Activation/assets/qr.png
  40. 121
      src/screens/Activation/index.js
  41. 13
      src/screens/Blog/index.js
  42. 13
      src/screens/Blogs/index.js
  43. 13
      src/screens/Chat/index.js
  44. 13
      src/screens/Contact/index.js
  45. 13
      src/screens/Exams/index.js
  46. BIN
      src/screens/Faq/assets/+.png
  47. BIN
      src/screens/Faq/assets/-.png
  48. BIN
      src/screens/Faq/assets/bgFaq.png
  49. 60
      src/screens/Faq/components/Instance.js
  50. 56
      src/screens/Faq/index.js
  51. BIN
      src/screens/Home/assets/ar.png
  52. BIN
      src/screens/Home/assets/arrow.png
  53. BIN
      src/screens/Home/assets/bookFeatureIcon.png
  54. BIN
      src/screens/Home/assets/food.png
  55. BIN
      src/screens/Home/assets/message.png
  56. BIN
      src/screens/Home/assets/olum1.png
  57. BIN
      src/screens/Home/assets/olum2.png
  58. BIN
      src/screens/Home/assets/packageFeatureIcon.png
  59. BIN
      src/screens/Home/assets/qr.png
  60. BIN
      src/screens/Home/assets/responsive-bg.png
  61. BIN
      src/screens/Home/assets/shoe.png
  62. BIN
      src/screens/Home/assets/testFeatureIcon.png
  63. BIN
      src/screens/Home/assets/user.png
  64. BIN
      src/screens/Home/assets/videoFeatureIcon.png
  65. BIN
      src/screens/Home/assets/zist11.png
  66. 117
      src/screens/Home/components/Blogs.js
  67. 25
      src/screens/Home/components/Header.js
  68. 93
      src/screens/Home/components/MyBooks.js
  69. 85
      src/screens/Home/components/Scroll.js
  70. 86
      src/screens/Home/components/Videos.js
  71. 55
      src/screens/Home/index.js
  72. 21
      src/screens/Login/components/IranFlag.js
  73. 132
      src/screens/Login/index.js
  74. 10
      src/screens/Login/services/index.js
  75. 18
      src/screens/Login/services/mocks.js
  76. 13
      src/screens/Login/services/services.js
  77. BIN
      src/screens/OrderDetails/assets/b1.png
  78. 70
      src/screens/OrderDetails/components/Book.js
  79. 312
      src/screens/OrderDetails/index.js
  80. BIN
      src/screens/OrdersFollowUp/assets/b1.png
  81. BIN
      src/screens/OrdersFollowUp/assets/b2.png
  82. BIN
      src/screens/OrdersFollowUp/assets/b3.png
  83. BIN
      src/screens/OrdersFollowUp/assets/leftArrow.png
  84. BIN
      src/screens/OrdersFollowUp/assets/plus.png
  85. 175
      src/screens/OrdersFollowUp/components/Order.js
  86. 66
      src/screens/OrdersFollowUp/index.js
  87. 245
      src/screens/Otp/index.js
  88. 10
      src/screens/Otp/services/index.js
  89. 18
      src/screens/Otp/services/mocks.js
  90. 13
      src/screens/Otp/services/services.js
  91. BIN
      src/screens/Product/assets/arrowMore.png
  92. BIN
      src/screens/Product/assets/poster.png
  93. BIN
      src/screens/Product/assets/user.png
  94. 192
      src/screens/Product/components/Book.js
  95. 61
      src/screens/Product/components/Comments.js
  96. 35
      src/screens/Product/components/Description.js
  97. 31
      src/screens/Product/components/LinkBox.js
  98. 61
      src/screens/Product/components/Rates.js
  99. 207
      src/screens/Product/components/Video.js
  100. 76
      src/screens/Product/index.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -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 (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<StatusBar style="auto" />
</View>
<Provider store={store}>
<Navigator />
<AlertModal />
</Provider>
);
}
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
const styles = StyleSheet.create({});
export default App;

@ -23,7 +23,8 @@
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#FFFFFF"
}
},
"package": "com.appsazz.RnDanovinExpo"
},
"web": {
"favicon": "./assets/favicon.png"

@ -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 (
<Tab.Navigator initialRouteName={'Home'}>
<Tab.Screen
name={'Profile'}
component={Profile}
options={{
title: t('profile'),
}}
/>
<Tab.Screen
name={'Exams'}
component={Exams}
options={{
title: t('exams'),
}}
/>
<Tab.Screen
name={'Videos'}
component={Videos}
options={{
title: t('videos'),
}}
/>
<Tab.Screen
name={'OrderDetails'}
component={OrderDetails}
options={{
title: t('books'),
}}
/>
<Tab.Screen
name={'Home'}
component={Home}
options={{
headerShown : false
// title: t('home'),
}}
/>
</Tab.Navigator>
);
}
function Navigator(props) {
React.useEffect(() => {
i18n.changeLanguage(props.config.lan);
}, [props.config]);
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
options={{headerShown: false}}
name="Splash"
component={Splash}
/>
<Stack.Screen
name="Login"
component={Login}
options={{headerShown: false}}
/>
{/* <Stack.Screen
name="Home"
component={Home}
options={{headerShown: false}}
/> */}
<Stack.Screen
name="Otp"
component={Otp}
options={{headerShown: false}}
/>
<Stack.Screen
name="Home"
component={BottomTab}
options={{headerShown: false}}
/>
<Stack.Screen
name="Product"
component={Product}
options={{headerShown: false}}
/>
<Stack.Screen
name="Products"
component={Products}
options={{headerShown: false}}
/>
<Stack.Screen name="QR" component={QR} options={{headerShown: true}} />
<Stack.Screen
name="سبد خرید"
component={ShoppingCart}
options={{headerShown: true}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default connect(mapStateToProps)(Navigator);

@ -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"

@ -0,0 +1,2 @@
export const PROFILE_RECORD = 'PROFILE_RECORD';
export const APP_CONFIG = 'APP_CONFIG';

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

@ -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 <>
<AwesomeAlert
show={alert.show}
progressColor="red"
showProgress={alert.showProgress}
title={alert.title}
message={alert.message}
closeOnTouchOutside={alert.closeOnTouchOutside}
closeOnHardwareBackPress={alert.closeOnHardwareBackPress}
showCancelButton={alert.showCancelButton}
showConfirmButton={alert.showConfirmButton}
cancelText={alert.cancelText}
confirmText={alert.confirmText}
confirmButtonColor={alert.confirmButtonColor}
onCancelPressed={onCancelPressed}
onConfirmPressed={(onConfirmPressed)}
contentStyle={{
width: ReactNative.Dimensions.get('window').width / 1.5,
}}
confirmButtonStyle={
{
width: ReactNative.Dimensions.get('window').width / 4,
alignItems: 'center',
justifyContent: 'center'
}
}
useNativeDriver={true}
/>
<AwesomeAlert
show={apiAlert.show}
progressColor="red"
showProgress={apiAlert.showProgress}
title={apiAlert.title}
message={apiAlert.message}
closeOnTouchOutside={apiAlert.closeOnTouchOutside}
closeOnHardwareBackPress={apiAlert.closeOnHardwareBackPress}
showCancelButton={apiAlert.showCancelButton}
showConfirmButton={apiAlert.showConfirmButton}
cancelText={apiAlert.cancelText}
confirmText={apiAlert.confirmText}
confirmButtonColor={apiAlert.confirmButtonColor}
onCancelPressed={onApiCancelPressed}
onConfirmPressed={(onApiConfirmPressed)}
contentStyle={{
width: ReactNative.Dimensions.get('window').width / 1.5
}}
confirmButtonStyle={
{
width: ReactNative.Dimensions.get('window').width / 4,
alignItems: 'center',
justifyContent: 'center'
}
}
useNativeDriver={true}
/>
</>
}
export default AlertModal;

@ -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 (
<View style={{marginTop: 18}}>
<Text
style={[styles.labelStyle, tw.style('transition-all transform duration-300')]}>
{label}
</Text>
<TextInput
style={[styles.inputStyle , tw.style('rounded-md') ]}
onChangeText={text => onChange(name, text)}
onFocus={() => setIsFocused(true)}
onBlur={() =>
value ? setIsFocused(() => true) : setIsFocused(() => false)
}
/>
</View>
);
};
export default FloatingLabelInput;

@ -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 (
<Pressable
color={color}
style={styles.button}
onPress={() => onPress}
>
<Text style={styles.text}>{text}</Text>
</Pressable>
);
}

@ -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 (
<View
style={[
tw.style('w-full flex flex-col items-center justify-end pb-3 relative mb-0'),
{height: height / 4.5, backgroundColor: '#196EC015'},
]}>
<Image source={background} style={[tw.style('absolute left-0 top-0'), {}]} />
<Image source={icon} style={[{width : width / 5, height : height / 10, marginBottom : 10}]} />
<Text
style={[
{fontSize: width / 18, color: '#196EC0'},
tw.style('font-semibold mb-1'),
]}>
{title}
</Text>
<Text
style={[
{color: '#86A0B9', fontSize: width / 30},
tw.style('font-semibold mb-2'),
]}>
{description}
</Text>
</View>
);
}

@ -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 (
<TouchableOpacity
style={[
tw('rounded-sm p-1'),
{
backgroundColor: Color.theme1.light.blue1,
borderColor: Color.theme1.light.blue2,
borderWidth: 1,
marginLeft : route === 'ar' ? 10 : 0
},
]}
onPress={() => navigation.navigate(route)}>
<Image source={icon} style={{width: 20, height: 20}} />
</TouchableOpacity>
);
}, []);
return (
<View
style={tw(
'w-full flex flex-row-reverse justify-between h-16 bg-white items-center px-4 relative',
)}>
<View style={tw('relative')}>
<Image source={hamburgerLightIcon} style={{width: 29.5, height: 27}} />
{notification && (
<View
style={tw(
'h-2.5 w-2.5 absolute -left-1 -top-1 bg-red-500 rounded-full',
)}></View>
)}
</View>
<Image
source={logoIcon}
style={[
tw('absolute right-1/2 top-1/2'),
{
width: 19.6,
height: 28.9,
transform: [{translateX: 0}, {translateY: -14.5}],
},
]}
/>
<View style={tw('flex flex-row items-center')}>
<Button icon={qrLightIcon} route={'qr'} />
<Button icon={arLightIcon} route={'ar'} />
</View>
</View>
);
};
export default Navbar;
const styles = StyleSheet.create({});

@ -0,0 +1,20 @@
import React, {useState} from 'react';
import {View, Text, Dimensions} from 'react-native';
import tw from 'tailwind-react-native-classnames';
const width = Dimensions.get('window').width;
function Or(props) {
return (
<View
style={[tw.style('w-full flex flex-row justify-between items-center mt-3 mb-5')]}>
<View
style={{width: '43%', height: 1, backgroundColor: '#EFEFEF'}}></View>
<Text style={{fontSize: width / 27, color: '#C2C2C2'}}>یا</Text>
<View
style={{width: '43%', height: 1, backgroundColor: '#EFEFEF'}}></View>
</View>
);
}
export default Or;

@ -0,0 +1,28 @@
import React from 'react';
import {Pressable, Text, Dimensions} from 'react-native';
import tw from 'tailwind-react-native-classnames';
const fullWidth = Dimensions.get('window').width;
export default function Pressable1({
title,
backgroundColor,
color,
border,
width,
}) {
return (
<Pressable
style={[
tw.style('rounded-md py-4 flex flex-row justify-center mb-3'),
{
backgroundColor: backgroundColor,
borderWidth: border.width,
borderColor: border.color,
width : width,
},
]}>
<Text style={{fontSize: fullWidth / 27, color: color}}>{title}</Text>
</Pressable>
);
}

@ -0,0 +1,34 @@
import React, {useState, useEffect} from 'react';
import {View} from 'react-native';
import tw from 'tailwind-rn';
//Color
import Color from '../constants/Colors';
function Progress({percent}) {
const [delayPercent, setDelayPercent] = useState(0);
useEffect(() => {
setTimeout(() => {
setDelayPercent(() => percent);
}, 1000);
}, [percent]);
return (
<View
style={[
tw('w-full h-1.5 rounded-full overflow-hidden my-3'),
{backgroundColor: '#D3E9FF'},
]}>
<View
style={[
tw('h-full transition-all duration-500 rounded-full'),
{
backgroundColor: Color.theme1.light.blue3,
width: percent + '%',
// backgroundColor: Color.theme1.light.blue4,
},
]}></View>
</View>
);
}
export default Progress;

@ -0,0 +1,30 @@
import React from 'react';
import {View, Text, Dimensions, Image} from 'react-native';
import tw from 'tailwind-react-native-classnames';
import leftIcon from '../assets/icons/leftWhite.png';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
export default function Redirect({text}) {
return (
<View
style={[
tw.style('w-full flex flex-row-reverse items-center p-4 rounded-md mb-5'),
{backgroundColor: '#196EC0'},
]}>
<View style={tw.style('flex-1 flex flex-col')}>
<Text
style={[
tw.style('font-medium text-right'),
{fontSize: width / 30, color: 'white'},
]}>
{text}
</Text>
</View>
<View style={tw.style('p-0')}>
<Image source={leftIcon} style={{width: 24, height: 24}} />
</View>
</View>
);
}

@ -0,0 +1,55 @@
import React, {useState} from 'react';
import {
TextInput,
View,
Dimensions,
StyleSheet,
Pressable,
Image,
} from 'react-native';
import tw from 'tailwind-react-native-classnames';
import searchIcon from '../assets/icons/search.png';
const width = Dimensions.get('window').width;
const Search = ({
placeholder,
textAlign,
direction,
onChange,
value,
}) => {
const styles = StyleSheet.create({
inputStyle: {
fontSize: width / 30,
color: '#000',
borderWidth: 0.5,
borderColor: '#DBDBDB',
paddingVertical: 16,
paddingHorizontal: 10,
direction: direction,
textAlign: textAlign,
backgroundColor: '#F9F9F9',
},
});
return (
<View style={[{marginTop: 18}, tw.style('w-full relative')]}>
<TextInput
style={[styles.inputStyle, tw.style('rounded-md')]}
onChangeText={text => onChange(text)}
placeholder={placeholder}
placeholderTextColor={'#cccccc'}
value={value}
/>
<Pressable style={tw.style('absolute left-3 top-0 transform inset-y-4')}>
<Image source={searchIcon} style={[{width: 20, height: 20}]} />
</Pressable>
</View>
);
};
export default Search;
Search.defaultProps = {
direction: 'rtl',
textAlign: 'right',
};

@ -0,0 +1,46 @@
import React from 'react';
import {Image, Dimensions} from 'react-native';
import SelectDropdown from 'react-native-select-dropdown';
import dropdownIcon from '../assets/icons/dropdown.png';
import tw from 'tailwind-react-native-classnames';
function Select({iconPosition, options, onChange, value, width, defaultValue}) {
return (
<SelectDropdown
data={options}
buttonStyle={{
width: width,
borderWidth: 1,
borderColor: '#DBDBDB',
borderRadius: 6,
height: 36,
backgroundColor: '#F9F9F9',
}}
rowTextStyle={{fontSize: Dimensions.get('window').width / 30}}
defaultButtonText={defaultValue}
statusBarTranslucent={true}
buttonTextStyle={{
textAlign: 'center',
justifyContent: 'flex-end',
flex: 0,
fontSize: Dimensions.get('window').width / 30,
color: '#707070',
// display: 'inline'
}}
dropdownIconPosition={iconPosition}
onSelect={selectedItem => {
onChange(selectedItem);
}}
renderDropdownIcon={() => (
<Image source={dropdownIcon} style={{width: 12, height: 8}} />
)}
/>
);
}
export default Select;
Select.defaultProps = {
options: ['1', '2', '3'],
iconPosition: 'left',
};

@ -0,0 +1,23 @@
import {StyleSheet} from 'react-native';
import Video from 'react-native-video';
import file from '../assets/video.mp4';
// Within your render function, assuming you have a file called
// "background.mp4" in your project. You can include multiple videos
// on a single screen if you like.
import React from 'react';
export default function CustomVideo() {
return (
<Video
source={file} // Can be a URL or a local file.
ref={ref => {
this.player = ref;
}} // Store reference
onBuffer={this.onBuffer} // Callback when remote video is buffering
onError={this.videoError} // Callback when video cannot be loaded
style={{width: '100%', height: '100%', borderRadius : 10}}
controls
/>
);
}

@ -0,0 +1,19 @@
const Colors = {
theme1 : {
light : {
blue1 : '#E9F0FF',
blue2 : '#D7E3FC',
blue3 : '#D3E9FF',
blue4 : '#2B8DEB',
blue5 : "#196EC0",
blue6 : '#05335F',
blue7 : '#235A90',
},
dark : {
}
}
};
export default Colors;

@ -0,0 +1,29 @@
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;
};
}

@ -0,0 +1,14 @@
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;

@ -0,0 +1,13 @@
import React from 'react'
import { View, Text } from 'react-native';
import {connect} from 'react-redux';
function AR({}) {
return (
<View>
<Text></Text>
</View>
)
}
export default AR;

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

@ -0,0 +1,121 @@
import React, {useState} from 'react';
import {
View,
StyleSheet,
Dimensions,
ScrollView,
Text,
Pressable,
Image,
TextInput,
} from 'react-native';
import tw from 'tailwind-react-native-classnames';
import Header from '../../components/Header';
import CustomPressable from '../../components/Pressable';
import Or from '../../components/Or';
import bgQr from './assets/bgQr.png';
import qrIcon from './assets/qr.png';
import alertIcon from './assets/alert.png';
import bookIcon from './assets/book.png';
const width = Dimensions.get('window').width;
function Activation(props) {
const [formData, setFormData] = useState({
title: null,
department: null,
message: null,
file: null,
});
const onChange = (name, value) => {
setFormData({...formData, [name]: value});
};
return (
<ScrollView
contentContainerStyle={styles.contentContainerStyle}
style={[tw.style('bg-white flex flex-col'), {width: width}]}>
<Header
background={bgQr}
title={'فعالسازی کتاب دیجیتال'}
description={''}
icon={qrIcon}
/>
<View style={tw.style('flex flex-row w-full flex-wrap p-2')}>
<View style={tw.style('w-full flex flex-row justify-center mb-7')}>
<Image source={bookIcon} style={[{width: 113, height: 113}]} />
</View>
<Pressable
style={[
tw.style(
'w-full rounded-md flex flex-row justify-end items-center py-3.5 px-3',
),
{backgroundColor: '#196EC01a'},
]}>
<Text
style={[
tw.style('text-right flex-1'),
{color: '#275077', fontSize: width / 30},
]}>
دانش آموز گرامی پس از خرید فیزیکی کتاب، یک کارت فعالسازی در درون
کتاب قرار داده شده که شما میتوانید با وارد کردن کد در قسمت زیر و یا
اسکن کد QR با دوربین موبایل خود اقدام به فعالسازی امکانات ویژه برای
کتاب خود نمائید
</Text>
<View style={tw.style('p-2')}>
<Image
source={alertIcon}
style={{width: 30, height: 30, marginLeft: 5}}
/>
</View>
</Pressable>
<TextInput
placeholder="کد فعالسازی"
placeholderTextColor="#70707070"
style={[
tw.style('w-full mt-4 mb-3 rounded-md text-center py-4'),
{
backgroundColor: '#F9F9F9',
borderColor: '#DFDFDF',
borderWidth: 1,
fontSize: width / 27,
},
]}
/>
<CustomPressable
title={'تایید کد'}
backgroundColor="#196EC0"
color={'white'}
border={{color: '#196EC0', width: 0}}
width={'100%'}
/>
<Or />
<CustomPressable
title={'فعالسازی با کد QR'}
backgroundColor="#98B2CB"
color={'white'}
border={{color: '#196EC0', width: 0}}
width={'100%'}
/>
</View>
</ScrollView>
);
}
// Later on in your styles..
const styles = StyleSheet.create({
contentContainerStyle: {
paddingBottom: 50,
alignItems: 'flex-end',
},
container: {
width: Dimensions.get('window').width,
backgroundColor: 'white',
flexDirection: 'column',
paddingVertical: 5,
paddingHorizontal: 10,
},
});
export default Activation;

@ -0,0 +1,13 @@
import React from 'react'
import { View, Text } from 'react-native';
import {connect} from 'react-redux';
function Blog({}) {
return (
<View>
<Text></Text>
</View>
)
}
export default Blog;

@ -0,0 +1,13 @@
import React from 'react'
import { View, Text } from 'react-native';
import {connect} from 'react-redux';
function Blogs({}) {
return (
<View>
<Text></Text>
</View>
)
}
export default Blogs;

@ -0,0 +1,13 @@
import React from 'react'
import { View, Text } from 'react-native';
import {connect} from 'react-redux';
function Chat({}) {
return (
<View>
<Text></Text>
</View>
)
}
export default Chat;

@ -0,0 +1,13 @@
import React from 'react'
import { View, Text } from 'react-native';
import {connect} from 'react-redux';
function Contact({}) {
return (
<View>
<Text></Text>
</View>
)
}
export default Contact;

@ -0,0 +1,13 @@
import React from 'react'
import { View, Text } from 'react-native';
import {connect} from 'react-redux';
function Exams({}) {
return (
<View>
<Text></Text>
</View>
)
}
export default Exams;

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

@ -0,0 +1,60 @@
import React, {useState} from 'react';
import {View, Text, Dimensions, Image, Pressable} from 'react-native';
import tw from 'tailwind-react-native-classnames';
import minusIcon from '../assets/-.png';
import plusIcon from '../assets/+.png';
const width = Dimensions.get('window').width;
function Instance(props) {
const [active, setActive] = useState(false);
return (
<Pressable
onPress={() => setActive(!active)}
style={[
tw.style('w-full flex flex-col my-1.5 rounded-md px-4 py-3'),
{
backgroundColor: !active ? '#F9F9F9' : '#F6F9FD',
borderColor: !active ? '#DBDBDB' : '#196EC0',
borderWidth: 1,
},
]}>
<View
style={tw.style('flex flex-row-reverse justify-between items-center')}>
<Text
style={[
{
width: '90%',
textAlign: 'right',
color: '#196EC0',
fontSize: width / 27,
},
tw.style('font-medium'),
]}>
نحوه خرید از سایت چگونه است ؟
</Text>
<Image
source={!active ? plusIcon : minusIcon}
style={{width: 14, height: 30}}
/>
</View>
{active && (
<View style={tw.style('w-full flex flex-row-reverse pt-2')}>
<Text
style={[
{color: '#196EC0', fontSize: width / 30},
tw.style('inline text-right flex-1'),
]}>
هر نفسی که فرو می بریم، مرگی را که مدام به ما دستاندازی میکند پس
میزند... در نهایت این مرگ است که باید پیروز شود، زیرا از هنگام تولد
بخشی از سرنوشت ما شده و فقط مدت کوتاهی پیش از بلعیدن طعمه اش، با آن
بازی می کند. با این همه، ما تا آنجا که ممکن است، با علاقه فراوان و
دلواپسی
</Text>
</View>
)}
</Pressable>
);
}
export default Instance;

@ -0,0 +1,56 @@
import React, {useState} from 'react';
import {View, StyleSheet, Dimensions, ScrollView, Text} from 'react-native';
import tw from 'tailwind-react-native-classnames';
import Header from '../../components/Header';
import Search from '../../components/Search';
import Instance from './components/Instance';
import bgFaq from './assets/bgFaq.png';
const width = Dimensions.get('window').width;
function Faq(props) {
const [search, setSearch] = useState('');
const onChange = (name, value) => {};
return (
<ScrollView
contentContainerStyle={styles.contentContainerStyle}
style={[tw.style('bg-white flex flex-col'), {width: width}]}>
<Header
background={bgFaq}
title={'پرسشهای متداول'}
description={'تیم پشتیبانی ما اینجاست تا شما رو کمک کنه'}
// icon={}
/>
<View style={styles.container}>
<Search
value={search}
onChange={setSearch}
placeholder={'بخشی از پرسش خود را اینجا بنویسید'}
/>
<View style={tw.style('mt-2 w-full')}>
</View>
{[0,1,2,3,4].map((item, index) => (
<Instance key={index} />
))}
</View>
</ScrollView>
);
}
// Later on in your styles..
const styles = StyleSheet.create({
contentContainerStyle: {
paddingBottom: 50,
alignItems: 'flex-end',
},
container: {
width: Dimensions.get('window').width,
backgroundColor: 'white',
flexDirection: 'column',
paddingVertical: 5,
paddingHorizontal: 10,
},
});
export default Faq;

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 956 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

@ -0,0 +1,117 @@
import React from 'react';
import {
View,
Image,
Text,
Dimensions,
TouchableOpacity,
FlatList,
} from 'react-native';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
import Header from '../components/Header';
import tw from 'tailwind-rn';
import {connect} from 'react-redux';
//asssets
import foodImage from '../assets/food.png';
import userImage from '../assets/user.png';
import messageIcon from '../assets/message.png';
//Color
import Color from '../../../constants/Colors';
function Blogs({products}) {
return (
<View style={[tw('flex flex-col pr-3 mb-5')]}>
<View style={tw('w-full pl-3')}>
<Header title={'خواندنیها'} route={'Blogs'} />
</View>
<FlatList
horizontal={true}
inverted={true}
style={[tw('flex flex-col-reverse mt-3')]}
data={products}
renderItem={({blog, index}) => <Blog blog={blog} key={index} />}
/>
</View>
);
}
const Blog = ({blog}) => {
return (
<TouchableOpacity
style={[tw('rounded-md ml-3 rounded-md relative')]}
// onPress={() => navigation.navigate('Product')}
>
<Image source={foodImage} style={{width: 227, height: 133}} />
<View
style={[
{transform: [{translateY: -20}], marginHorizontal: 10},
tw('flex flex-col bg-white rounded-md p-2'),
]}>
<Text
style={[
tw('font-bold text-sm mb-2'),
{color: Color.theme1.light.blue7},
]}>
آیا مواد غذای پر فیبر مفید هستند؟
</Text>
<View style={tw('flex flex-row-reverse justify-between')}>
<View style={tw('flex-row-reverse items-center')}>
<Image
source={userImage}
style={[tw('rounded-full ml-1'), {width: 13, height: 13}]}
/>
<Text style={[{color: Color.theme1.light.blue5}]}>
حامد دژبانی نسب
</Text>
</View>
<View style={tw('flex-row-reverse items-center')}>
<Text style={[{color: Color.theme1.light.blue5}]}>۳۰ دقیقه</Text>
<Image
source={messageIcon}
style={[tw('rounded-full mr-1'), {width: 13, height: 13}]}
/>
</View>
</View>
</View>
</TouchableOpacity>
);
};
const mapStateToProps = state => ({
// features: state.publicApi.home?.features,
});
export default connect(mapStateToProps, {})(Blogs);
Blogs.defaultProps = {
products: [
{
imageUrl: foodImage,
},
{
imageUrl: foodImage,
},
{
imageUrl: foodImage,
},
{
imageUrl: foodImage,
},
{
imageUrl: foodImage,
},
{
imageUrl: foodImage,
},
{
imageUrl: foodImage,
},
{
imageUrl: foodImage,
},
],
};

@ -0,0 +1,25 @@
import React from 'react';
import {View, Text, Image, Pressable} from 'react-native';
import {useNavigation} from '@react-navigation/native';
import tw from 'tailwind-rn';
//assets
import arrowIcon from '../assets/arrow.png';
//Color
import Color from '../../../constants/Colors';
const Header = ({title, route}) => {
const navigation = useNavigation();
return (
<View style={tw('w-full flex flex-row-reverse justify-between mb-2')}>
<Text
style={[tw('text-2xl font-bold'), {color: Color.theme1.light.blue5}]}>
{title}
</Text>
<Pressable onPress={() => navigation.navigate(route)}>
<Image source={arrowIcon} style={{width: 24, height: 24}} />
</Pressable>
</View>
);
};
export default Header;

@ -0,0 +1,93 @@
import React, {useState, useEffect} from 'react';
import {
View,
Text,
Image,
TouchableOpacity,
Dimensions,
FlatList,
} from 'react-native';
import tw from 'tailwind-rn';
import {connect} from 'react-redux';
// import { book } from "../../../../../redux/actions";
import Progress from '../../../components/Progress';
//assets
import bookImage from '../assets/zist11.png';
//Color
import Color from '../../../constants/Colors';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
function MyBooks({getList, list, grades}) {
return (
<View style={[tw('w-full px-4 mb-5')]}>
<View
style={[
tw(
'w-full flex flex-col rounded-md pt-2 px-2 bg-blueFF1 overflow-hidden',
),
{
backgroundColor: Color.theme1.light.blue1,
borderColor: Color.theme1.light.blue2,
borderWidth: 1,
},
]}>
<Text
style={[tw('font-bold text-lg'), {color: Color.theme1.light.blue5}]}>
کتابهای من
</Text>
<FlatList
style={[tw('py-3')]}
horizontal={true}
inverted={true}
data={list}
renderItem={(book, index) => <Book key={index} />}
/>
</View>
</View>
);
}
const Book = ({book, grades}) => {
return (
<TouchableOpacity style={tw('flex flex-col ml-3')}>
<Image
source={bookImage}
style={[
tw('rounded-md'),
{
height: 180,
width: 114,
},
]}
/>
<Text
style={[
tw('mt-2 text-md font-semibold'),
{color: Color.theme1.light.blue6},
]}>
{'نام کتاب'}
</Text>
<Text
style={[
tw('font-medium text-xs mt-1'),
{color: Color.theme1.light.blue5},
]}>{`پایه ${'اول'}`}</Text>
<Progress percent={60} />
</TouchableOpacity>
);
};
const mapStateToProps = state => ({
// list: state.book.list,
// grades : state.publicApi.grades
});
export default connect(mapStateToProps, {})(MyBooks);
MyBooks.defaultProps = {
list: [{name: 1}, {name: 2}, {name: 3}, {name: 4}, {name: 5}],
};

@ -0,0 +1,85 @@
import React from 'react';
import {
View,
Image,
Dimensions,
TouchableOpacity,
FlatList,
} from 'react-native';
import Header from '../components/Header';
import tw from 'tailwind-rn';
import {connect} from 'react-redux';
import olum1Image from '../assets/olum1.png';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
function Scroll({products}) {
return (
<View style={[tw('flex flex-col px-3 mb-5')]}>
<Header title={'فروشگاه'} route={'Products'} />
<FlatList
horizontal={true}
inverted={true}
style={[tw('flex flex-col-reverse mt-3'), {height: 245}]}
data={products}
renderItem={({product, index}) => (
<Product product={product} position={Number(index)} key={index} />
)}
/>
</View>
);
}
const Product = ({product, position}) => {
return (
<TouchableOpacity
style={[
tw('rounded-md mx-1 overflow-hidden rounded-md'),
{
width: position === 0 ? 163 : 79,
height: position === 0 ? 245 : 118,
},
]}
// onPress={() => navigation.navigate('Product')}
>
<Image source={olum1Image} style={{width: '100%', height: '100%'}} />
</TouchableOpacity>
);
};
const mapStateToProps = state => ({
// features: state.publicApi.home?.features,
});
export default connect(mapStateToProps, {})(Scroll);
Scroll.defaultProps = {
products: [
{
imageUrl: olum1Image,
},
{
imageUrl: olum1Image,
},
{
imageUrl: olum1Image,
},
{
imageUrl: olum1Image,
},
{
imageUrl: olum1Image,
},
{
imageUrl: olum1Image,
},
{
imageUrl: olum1Image,
},
{
imageUrl: olum1Image,
},
],
};

@ -0,0 +1,86 @@
import React, {useState, useEffect} from 'react';
import {
View,
Text,
Image,
TouchableOpacity,
Dimensions,
FlatList,
} from 'react-native';
import tw from 'tailwind-rn';
import {connect} from 'react-redux';
// import { book } from "../../../../../redux/actions";
import Progress from '../../../components/Progress';
import Header from '../components/Header';
//assets
import bookImage from '../assets/zist11.png';
//Color
import Color from '../../../constants/Colors';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
function Videos({getList, list, grades}) {
return (
<View style={[tw('w-full px-4 mb-5')]}>
<View
style={[
tw(
'w-full flex flex-col rounded-md pt-2 px-2 bg-blueFF1 overflow-hidden',
),
]}>
<Header title="دورههای ویدئویی شما" route={'Videos'} />
<FlatList
style={[tw('py-3')]}
horizontal={true}
inverted={true}
data={list}
renderItem={(video, index) => <Video key={index} />}
/>
</View>
</View>
);
}
const Video = ({book, grades}) => {
return (
<TouchableOpacity style={tw('flex flex-col ml-3')}>
<Image
source={bookImage}
style={[
tw('rounded-md'),
{
height: 180,
width: 114,
},
]}
/>
<Text
style={[
tw('mt-2 text-md font-semibold'),
{color: Color.theme1.light.blue6},
]}>
{'نام کتاب'}
</Text>
<Text
style={[
tw('font-medium text-xs mt-1'),
{color: Color.theme1.light.blue5},
]}>{`پایه ${'اول'}`}</Text>
<Progress percent={60} />
</TouchableOpacity>
);
};
const mapStateToProps = state => ({
// list: state.book.list,
// grades : state.publicApi.grades
});
export default connect(mapStateToProps, {})(Videos);
Videos.defaultProps = {
list: [{name: 1}, {name: 2}, {name: 3}, {name: 4}, {name: 5}],
};

@ -0,0 +1,55 @@
import React from 'react';
import {useTranslation} from 'react-i18next';
import {
View,
StyleSheet,
Dimensions,
ScrollView,
SafeAreaView,
} from 'react-native';
import Navbar from '../../components/Navbar';
import tw from 'tailwind-rn';
import Scroll from './components/Scroll';
import MyBooks from './components/MyBooks';
import Videos from './components/Videos';
import Blogs from './components/Blogs';
import qrIcon from './assets/qr.png';
import arIcon from './assets/ar.png';
// import { SafeAreaView } from 'react-native-safe-area-context';
// Within your render function
function Home(props) {
return (
<SafeAreaView>
<Navbar />
<ScrollView
contentContainerStyle={styles.contentContainerStyle}
style={[
styles.container,
tw('w-full flex flex-col'),
]}>
<MyBooks />
<Scroll />
<Videos />
<Blogs />
</ScrollView>
</SafeAreaView>
);
}
// Later on in your styles..
const styles = StyleSheet.create({
contentContainerStyle: {
paddingBottom: 100,
},
container: {
width: Dimensions.get('window').width,
backgroundColor: 'white',
flexDirection: 'column',
paddingVertical: 0,
paddingHorizontal: 0,
},
});
export default Home;

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

@ -0,0 +1,132 @@
import React, {useState} from 'react';
import {View, Text, Image, ActivityIndicator, Dimensions, TextInput, TouchableHighlight} from 'react-native';
import Logo from '../../assets/images/logo.png';
import IranFlag from "./components/IranFlag";
import {digitToEn, digitToPersian} from "../../utils";
import services from "./services";
import {asyncAwesomeAlert} from "../../utils/AsyncWrappers";
const {width, height} = Dimensions.get('window');
let faNums = ['۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹', '۰']
function Login(props) {
const [phone, setPhone] = useState('');
const [loading, setLoading] = useState(false)
const onChangePhone = (value) => {
let items = digitToPersian(value).split('');
for (let item of items) {
if (!faNums.includes(item)) {
return
}
}
setPhone(digitToPersian(value));
}
const checkPhoneNumber = () => {
return phone.split('').length === 9;
}
const submit = async () => {
setLoading(true)
if (!checkPhoneNumber()) {
setLoading(false)
return asyncAwesomeAlert('خطا', 'شماره وارد شده اشتباه است', {showCancelButton: false});
}
let res = await services.getSmsCode({
cellphone: '09' + digitToEn(phone)
})
if (res.ok) {
setLoading(false)
props.navigation.navigate('Otp', {phone: '09' + digitToEn(phone)});
}
setLoading(false)
}
return (
<View style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
}}>
<Image source={Logo} style={{
width: width * 0.7,
height: width * 0.7 / 2.09,
}} />
<Text style={{
width: width,
paddingHorizontal: 10,
marginTop: 20,
fontSize: 20,
textAlign: 'right',
}}>{'دانوین'}</Text>
<Text style={{
width: width,
paddingHorizontal: 10,
marginTop: 10,
fontSize: 14,
color: '#6f7074',
textAlign: 'right',
}}>{'به دانوین خوش اومدی برای عضویت و ادامه شماره موبایلت رو وارد کن و روی گزینه ثبت بزن'}</Text>
<View style={{
width: width - 10,
height: width / 8,
borderRadius: 8,
backgroundColor: '#f2f2f2',
flexDirection: 'row',
marginTop: 10,
alignItems: 'center'
}}>
<IranFlag />
<Text style={{
// width: width / 7 - 15,
fontSize: 18,
marginLeft: 10,
color: '#a2a2a2',
textAlign: 'right',
// marginRight: 5,
}}>
{'۰۹'}
</Text>
<TextInput
style={{
width: width / 1.5,
color: '#a2a2a2',
fontSize: 18
}}
maxLength={9}
underlineColorAndroid={'transparent'}
value={phone}
onChangeText={text => onChangePhone(text)}
/>
</View>
<TouchableHighlight
disabled={loading}
style={{
width: width - 10,
height: width / 9,
backgroundColor: '#6cbe44',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 10,
marginTop: 15,
}}
onPress={() => submit()}>
{loading ?
<ActivityIndicator size={'small'} color={'white'}/>
:
<Text style={{
color: 'white',
fontSize: 18,
}}>
{'ادامه'}
</Text>
}
</TouchableHighlight>
</View>
);
}
export default Login;

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

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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

@ -0,0 +1,70 @@
import React from 'react';
import {View, Text, Dimensions, Image} from 'react-native';
import tw from 'tailwind-react-native-classnames';
import _ from 'lodash';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
export default function Book({book}) {
return (
<View
style={[
tw.style('w-full flex flex-row-reverse justify-between py-3'),
{borderBottomWidth: 1, borderColor: '#86A0B933'},
]}>
<View style={tw.style('flex flex-row-reverse items-center flex-1')}>
<Image
source={book}
style={[
tw.style('rounded-md'),
{width: width / 5.5, height: height / 8},
]}
/>
<View style={tw.style('flex flex-col items-end mr-2')}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 30, color: '#05335F'},
]}>
علوم اجتماعی
</Text>
<Text
style={[
tw.style('font-medium mt-2'),
{fontSize: width / 36, color: '#707070'},
]}>
پایه دوم
</Text>
<Text
style={[
tw.style('font-medium mt-2'),
{fontSize: width / 36, color: '#707070'},
]}>
نسخه دیجیتال
</Text>
</View>
</View>
<View style={tw.style('flex flex-row-reverse items-center')}>
<Text
style={[
tw.style('font-medium py-1 px-2'),
{
color: '#132F52',
fontSize: width / 34,
backgroundColor: '#F1F1F1',
},
]}>
1
</Text>
<Text
style={[
tw.style('font-medium mr-3'),
{color: '#132F52', fontSize: width / 34},
]}>
126.000 تومان
</Text>
</View>
</View>
);
}

@ -0,0 +1,312 @@
import React from 'react';
import {View, Text, Dimensions, StyleSheet, ScrollView} from 'react-native';
import Book from './components/Book';
import {connect} from 'react-redux';
import tw from 'tailwind-react-native-classnames';
import b1Image from './assets/b1.png';
import _ from 'lodash';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
const colors = {
1: '#FFF700',
4: '#FF0000',
3: '#4CFF00',
2: '#196EC0',
};
const status = {
1: 'در حال پردازش',
4: 'درخواست رد شد',
3: 'تکمیل شد',
2: 'ارسال شده',
};
function OrderDetails({order}) {
return (
<ScrollView
contentContainerStyle={styles.contentContainerStyle}
style={styles.container}>
<View
style={[
tw.style(
'flex flex-row-reverse w-full justify-between items-center p-3',
),
{backgroundColor: '#EEF7FF'},
]}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#20297B'},
]}>
{_.join(['شماره سفارش:', order.number], ' ')}
</Text>
<View style={tw.style('flex flex-row-reverse items-center')}>
<Text
style={[
tw.style('font-light'),
{color: '#20297B', fontSize: width / 32},
]}>
{status[order.status]}
</Text>
<View
style={[
tw.style('h-4 w-4 rounded-full mr-2'),
{backgroundColor: colors[order.status]},
]}></View>
</View>
</View>
<View
style={[
tw.style('w-full flex flex-row-reverse py-4'),
{borderBottomWidth: 1, borderColor: '#86A0B933'},
]}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#05335F'},
]}>
آدرس تحویل:
</Text>
<Text
style={[
tw.style('flex-1 font-light text-right mr-2'),
{fontSize: width / 32, lineHeight: 17, color: '#05335F'},
]}>
{order.address}
</Text>
</View>
<View
style={[
tw.style('w-full flex flex-row-reverse justify-between py-4'),
{borderBottomWidth: 1, borderColor: '#86A0B933'},
]}>
<View style={tw.style('flex flex-row-reverse')}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#05335F'},
]}>
مشخصات تحویل گیرنده:
</Text>
<Text
style={[
tw.style('font-light text-right mr-1'),
{fontSize: width / 32, lineHeight: 15, color: '#05335F'},
]}>
{order.name}
</Text>
</View>
<View style={tw.style('flex flex-row-reverse')}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#05335F'},
]}>
شماره موبایل:
</Text>
<Text
style={[
tw.style('font-light text-right mr-1'),
{fontSize: width / 32, lineHeight: 17, color: '#05335F'},
]}>
{order.cellphone}
</Text>
</View>
</View>
<View
style={[
tw.style('w-full rounded-md flex flex-col p-4 items-end mt-2'),
{backgroundColor: '#EEF6FF'},
]}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#05335F'},
]}>
{_.join(['کد تحویل', order.receiveCode], ' ')}
</Text>
<Text
style={[
tw.style('font-light text-right mt-2'),
{fontSize: width / 32, lineHeight: 17, color: '#05335F'},
]}>
این کد را پس از دریافت کالا، به مامور ارسال دانوین اعلام فرمایید
</Text>
</View>
<View style={tw.style('w-full flex flex-column items-end')}>
{order.items.map((item, index) => (
<Book book={item} key={index} />
))}
</View>
<View
style={[tw.style('w-full flex flex-row-reverse justify-between py-4')]}>
<View style={tw.style('flex flex-row-reverse')}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#05335F'},
]}>
مبلغ سبد خرید:
</Text>
<Text
style={[
tw.style('font-light text-right mr-1'),
{fontSize: width / 32, lineHeight: 15, color: '#05335F'},
]}>
{_.join([order.shoppingCardPrice, 'تومان'], ' ')}
</Text>
</View>
<View style={tw.style('flex flex-row-reverse')}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#05335F'},
]}>
تخفیف:
</Text>
<Text
style={[
tw.style('font-light text-right mr-1'),
{fontSize: width / 32, lineHeight: 17, color: '#05335F'},
]}>
{_.join([order.discountPrice, 'تومان'], ' ')}
</Text>
</View>
</View>
<View
style={[
tw.style('w-full flex flex-row-reverse justify-between py-4'),
{borderBottomWidth: 1, borderColor: '#86A0B933'},
]}>
<View style={tw.style('flex flex-row-reverse')}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#05335F'},
]}>
هزینه ارسال کالا:
</Text>
<Text
style={[
tw.style('font-light text-right mr-1'),
{fontSize: width / 32, lineHeight: 15, color: '#05335F'},
]}>
{_.join([order.sendPrice, 'تومان'], ' ')}
</Text>
</View>
<View style={tw.style('flex flex-row-reverse')}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#05335F'},
]}>
جمع هزینه پرداختی:
</Text>
<Text
style={[
tw.style('font-light text-right mr-1'),
{fontSize: width / 32, lineHeight: 17, color: '#05335F'},
]}>
{_.join([order.totalPrice, 'تومان'], ' ')}
</Text>
</View>
</View>
<View
style={[
tw.style('w-full flex flex-row-reverse justify-between py-4'),
{borderBottomWidth: 1, borderColor: '#86A0B933'},
]}>
<View style={tw.style('flex flex-row-reverse')}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#05335F'},
]}>
نحوه پرداخت:
</Text>
<Text
style={[
tw.style('font-light text-right mr-1'),
{fontSize: width / 32, lineHeight: 15, color: '#05335F'},
]}>
{order.payMethod}
</Text>
</View>
<View style={tw.style('flex flex-row-reverse')}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#05335F'},
]}>
شماره تراکنش:
</Text>
<Text
style={[
tw.style('font-light text-right mr-1'),
{fontSize: width / 32, lineHeight: 17, color: '#05335F'},
]}>
{order.transactionNumber}
</Text>
</View>
</View>
<View
style={[tw.style('w-full flex flex-row-reverse justify-between py-4')]}>
<View style={tw.style('flex flex-row-reverse')}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#05335F'},
]}>
تاریخ تحویل:
</Text>
<Text
style={[
tw.style('font-light text-right mr-1'),
{fontSize: width / 32, lineHeight: 15, color: '#05335F'},
]}>
{order.date}
</Text>
</View>
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
contentContainerStyle: {
paddingBottom: 50,
alignItems: 'flex-end',
},
container: {
width: width,
backgroundColor: 'white',
flexDirection: 'column',
paddingVertical: 5,
paddingHorizontal: 10,
},
});
export default OrderDetails;
OrderDetails.defaultProps = {
order: {
number: '535353523653',
receiveCode: '300031',
status: 2,
items: [b1Image, b1Image],
date: '1400/1/11',
cost: '1.240.000',
address:
'تهران خیابان انقلاب حدفاصل ابوریحان و فلسطین بن بست سروش پلاک 2 واحد 12 شرقی',
name: 'هومن عابدی',
cellphone: '09121234568',
shoppingCardPrice: '981.000',
discountPrice: '12.000',
sendPrice: '18.000',
totalPrice: '18.000',
payMethod: 'حضوری',
transactionNumber: ' BS3194DNB98312',
},
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

@ -0,0 +1,175 @@
import React from 'react';
import {
View,
Text,
Dimensions,
StyleSheet,
Image,
Pressable,
} from 'react-native';
import tw from 'tailwind-react-native-classnames';
import leftArrowIcon from '../assets/leftArrow.png';
import plusIcon from '../assets/plus.png';
import _ from 'lodash';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
const colors = {
1: '#FFF700',
4: '#FF0000',
3: '#4CFF00',
2: '#196EC0',
};
const status = {
1: 'در حال پردازش',
4: 'درخواست رد شد',
3: 'تکمیل شد',
2: 'ارسال شده',
};
function Order({order}) {
return (
<View
style={[
tw.style('w-full flex flex-col rounded-md overflow-hidden my-3'),
{borderWidth: 1, borderColor: '#EEF7FF'},
]}>
<View
style={[
tw.style(
'flex flex-row-reverse w-full justify-between items-center p-3',
),
{backgroundColor: '#EEF7FF'},
]}>
<Text
style={[
tw.style('font-medium'),
{fontSize: width / 32, color: '#20297B'},
]}>
{_.join(['شماره سفارش:', order.number], ' ')}
</Text>
<View style={tw.style('flex flex-row-reverse items-center')}>
<Text
style={[
tw.style('font-light'),
{color: '#20297B', fontSize: width / 32},
]}>
{status[order.status]}
</Text>
<View
style={[
tw.style('h-4 w-4 rounded-full mr-2'),
{backgroundColor: colors[order.status]},
]}></View>
</View>
</View>
<View
style={tw.style('w-full flex flex-row-reverse justify-between p-3')}>
<View style={tw.style('flex flex-col')}>
<View style={tw.style('flex flex-row-reverse mb-2')}>
{order.items.length < 2
? order?.items?.map(item => (
<Image
source={item}
style={[
tw.style('rounded-md ml-1.5'),
{width: width / 5.8, height: height / 8},
]}
/>
))
: order.items
?.slice(0, 1)
?.map(item => (
<Image
source={item}
style={[
tw.style('rounded-md ml-1.5'),
{width: width / 5.8, height: height / 8},
]}
/>
))}
{order.items.length >= 2 && (
<View
style={[
tw.style(
'flex flex-row-reverse items-center justify-center relative rounded-md overflow-hidden',
),
{
width: width / 5.8,
height: height / 8,
backgroundColor: '#EBEBEB',
},
]}>
{/* <Image
source={order.items[2]}
style={[tw.style('absolute left-0 top-0 h-full w-full z-10')]}
/> */}
<Image source={plusIcon} style={[tw.style('w-4 h-6 z-30')]} />
</View>
)}
</View>
<View style={[tw.style('bg-red-400')]}>
<Text
style={[
tw.style('p-2 rounded-md text-center'),
{
fontSize: width / 32,
backgroundColor: '#F0FFF1',
color: '#05335F',
},
]}>
{_.join(['کد تحویل:', order.receiveCode], ' ')}
</Text>
</View>
</View>
<View style={tw.style('flex flex-col items-center mr-4')}>
<Text
style={[
tw.style('my-3'),
{fontSize: width / 25, color: '#132F52'},
]}>
{_.join(['جمع فاکتور:', order.cost], ' ')}
</Text>
<Pressable
style={[
tw.style('rounded-md flex flex-row-reverse justify-center px-5 py-3'),
{borderWidth: 1, borderColor: '#1999C0'},
]}>
<Text style={{fontSize: width / 28, color: '#1999C0'}}>
جزئیات سفارش
</Text>
<Image
source={leftArrowIcon}
style={{width: 18, height: 18, marginRight: 10}}
/>
</Pressable>
<Text
style={[
tw.style('my-5'),
{fontSize: width / 30, color: '#132F52'},
]}>
{_.join(['تاریخ سفارش:', order.date], ' ')}
</Text>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
contentContainerStyle: {
paddingBottom: 50,
alignItems: 'flex-end',
},
container: {
width: width,
backgroundColor: 'white',
flexDirection: 'column',
paddingVertical: 5,
paddingHorizontal: 10,
},
});
export default Order;

@ -0,0 +1,66 @@
import React from 'react';
import {View, Text, Dimensions, StyleSheet, ScrollView} from 'react-native';
import Order from './components/Order';
import {connect} from 'react-redux';
import b1Image from './assets/b1.png';
import b2Image from './assets/b2.png';
import b3Image from './assets/b3.png';
const width = Dimensions.get('window').width;
function OrdersFollowUp({orders}) {
return (
<ScrollView
contentContainerStyle={styles.contentContainerStyle}
style={styles.container}>
{
orders.map((order, index) => <Order order={order} key={index} />)
}
</ScrollView>
);
}
const styles = StyleSheet.create({
contentContainerStyle: {
paddingBottom: 50,
alignItems: 'flex-end',
},
container: {
width: width,
backgroundColor: 'white',
flexDirection: 'column',
paddingVertical: 5,
paddingHorizontal: 10,
},
});
export default OrdersFollowUp;
OrdersFollowUp.defaultProps = {
orders: [
{
number: '535353523653',
receiveCode: '300031',
status: 2,
items: [b1Image, b2Image, b3Image, b3Image],
date: '1400/1/12',
cost: '1.240.000',
},
{
number: '535353523653',
receiveCode: '300031',
status: 3,
items: [b1Image, b2Image, b3Image],
date: '1400/1/12',
cost: '1.240.000',
},
{
number: '535353523653',
receiveCode: '300031',
status: 4,
items: [b1Image, b2Image, b3Image],
date: '1400/1/12',
cost: '1.240.000',
},
],
};

@ -0,0 +1,245 @@
import React, {useEffect, useState} from 'react'
import {
View,
Text,
Image,
TextInput,
TouchableHighlight,
Dimensions,
StyleSheet,
TouchableOpacity,
ActivityIndicator,
AsyncStorage
} from 'react-native';
import {connect} from 'react-redux';
import Logo from "../../assets/images/logo.png";
import IranFlag from "../Login/components/IranFlag";
import {digitToEn, digitToPersian} from "../../utils";
import services from "./services";
import {buildAction} from "../../reducers/DefaultReducer";
import {PROFILE_RECORD} from "../../actions/actionTypes";
const {width} = Dimensions.get('window')
let ref1;
let ref2;
let ref3;
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('');
const [fourthCode, setFourthCode] = useState('');
const [time, setTime] = useState(60);
const [loading, setLoading] = useState(false);
const checkValue = (value) => {
return faNums.includes(digitToPersian(value));
}
const onChangeCode = (value, key) => {
// if (!checkValue()) {
// return
// }
switch (key) {
case '1':
setFirstCode(digitToPersian(value));
ref2.focus();
break;
case '2':
setSecondCode(digitToPersian(value));
ref3.focus();
break;
case '3':
setThirdCode(digitToPersian(value));
ref4.focus();
break;
case '4':
setFourthCode(digitToPersian(value))
submit();
break;
}
}
const getEnCode = () => {
return Number(digitToEn(firstCode) + digitToEn(secondCode) + digitToEn(thirdCode) + digitToEn(fourthCode))
}
const submit = async () => {
setLoading(true)
let res = await services.sendOtpCode({
cellphone: props.route.params.phone,
otp: String(getEnCode()),
applicationToken: "1",
userToken: "1"
})
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: 'Home'}]
})
}
setLoading(false)
}
useEffect(() => {
let interval = setInterval(() => {
if (time > 0) {
setTime(timer - 1);
timer -= 1;
}
}, 1000);
let timeout = setTimeout(() => {
clearInterval(interval)
}, 60000)
return () => {
clearInterval(interval);
clearTimeout(timeout)
}
}, []);
return (
<View style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
}}>
<Image source={Logo} style={{
width: width * 0.7,
height: width * 0.7 / 2.09,
}} />
<Text style={{
width: width,
paddingHorizontal: 10,
marginTop: 20,
fontSize: 20,
textAlign: 'right',
}}>{'دانوین'}</Text>
<Text style={{
width: width,
paddingHorizontal: 10,
marginTop: 10,
fontSize: 14,
color: '#6f7074',
textAlign: 'right',
}}>{`یک کد تائیدیه به شماره ${props.route.params.phone} ارسال شد. آن را در قسمت زیر وارد کنید`}</Text>
<View style={{
width: width - 10,
height: width / 8,
borderRadius: 8,
flexDirection: 'row',
marginTop: 10,
alignItems: 'center',
justifyContent: 'space-evenly'
}}>
<TextInput
style={styles.input}
underlineColorAndroid={'transparent'}
value={firstCode}
maxLength={1}
ref={ref => ref1 = ref}
onChangeText={text => onChangeCode(text, '1')}
/>
<TextInput
style={styles.input}
underlineColorAndroid={'transparent'}
value={secondCode}
maxLength={1}
ref={ref => ref2 = ref}
onChangeText={text => onChangeCode(text, '2')}
/>
<TextInput
style={styles.input}
underlineColorAndroid={'transparent'}
value={thirdCode}
maxLength={1}
ref={ref => ref3 = ref}
onChangeText={text => onChangeCode(text, '3')}
/>
<TextInput
style={styles.input}
underlineColorAndroid={'transparent'}
value={fourthCode}
maxLength={1}
ref={ref => ref4 = ref}
onChangeText={text => onChangeCode(text, '4')}
/>
</View>
<TouchableOpacity
disabled={loading}
style={{
width: width - 10,
height: width / 9,
backgroundColor: '#6cbe44',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 10,
marginTop: 15,
}}
onPress={() => submit()}>
{loading ?
<ActivityIndicator color={'white'} size={'small'} /> :
<Text style={{
color: 'white',
fontSize: 18,
}}>
{'ثبت'}
</Text>
}
</TouchableOpacity>
<View>
<Text style={{marginTop: 30, textAlign: 'center'}}>
{'زمان باقی مانده تا انقضای کد: ' + time}
</Text>
<TouchableOpacity
style={{
marginTop: 20,
}}
onPress={() => {
props.navigation.reset({
index: 0,
routes: [{ name: 'Login' }],
});
}}>
<Text style={{textAlign: 'center'}}>
{'بازگشت به مرحله قبل و اصلاح شماره'}
</Text>
</TouchableOpacity>
</View>
</View>
)
}
const styles = StyleSheet.create({
input: {
width: width / 13 * 2,
height: width / 16 * 2,
backgroundColor: '#a2a2a2',
color: '#000',
fontSize: 22,
borderRadius: 8,
textAlign: 'center'
}
})
export default connect(mapStateToProps)(Otp);

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

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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

@ -0,0 +1,192 @@
import {t} from 'i18next';
import React from 'react';
import {
View,
Text,
Image,
Dimensions,
ScrollView,
Pressable,
} from 'react-native';
import CustomPressable from '../../../components/Pressable';
import Description from './Description';
import LinkBox from './LinkBox';
import Comments from './Comments';
import Rates from './Rates';
import tw from 'tailwind-react-native-classnames';
import arrowMoreIcon from '../assets/arrowMore.png';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
export default function Book({product}) {
return (
<ScrollView style={[tw.style('flex flex-col flex-1')]}>
<View style={tw.style('flex flex-row-reverse')}>
<View
style={[
tw.style('rounded-md'),
{height: height / 5, width: width / 3.5},
]}>
<Image
source={{uri: product.imageUrl}}
style={[tw.style('rounded-md h-full w-full')]}
/>
</View>
<View
style={[
tw.style('flex flex-col flex-1 justify-between items-end'),
{
paddingRight: 10,
},
]}>
<View style={tw.style('flex flex-col items-end')}>
<Text
style={{
color: '#05335F',
fontSize: width / 17,
marginBottom: 5,
}}>
{product.name}
</Text>
<Text style={{color: '#196EC0', fontSize: width / 30}}>
{product.grade}
</Text>
</View>
<Text
style={[
tw.style('text-right w-full'),
{color: '#323232', fontSize: width / 32},
]}>
{product.text}
</Text>
</View>
</View>
<View
style={tw.style(
'flex flex-row-reverse items-center justify-around py-6',
)}>
<View>
<Text
style={{
color: '#196EC0',
textAlign: 'center',
fontSize: width / 27,
}}>
{' '}
{473 + '\n' + 'صفحه'}
</Text>
</View>
<View
style={{backgroundColor: '#196EC055', height: 20, width: 2}}></View>
<View>
<Text
style={{
color: '#196EC0',
textAlign: 'center',
fontSize: width / 27,
}}>
{' '}
{'فیزیکی- دیجیتالی - ویدئو' + '\n' + 'در دسترس'}
</Text>
</View>
<View
style={{backgroundColor: '#196EC055', height: 20, width: 2}}></View>
<View>
<Text
style={{
color: '#196EC0',
textAlign: 'center',
fontSize: width / 27,
}}>
{' '}
{4.8 + '\n' + 'امتیاز'}
</Text>
</View>
</View>
<View style={'flex flex-col mt-3'}>
<Text
style={[
tw.style('w-full text-right font-medium'),
{color: '#196EC0', fontSize: width / 26},
]}>
نسخه محصول را انتخاب کنید
</Text>
<View style={tw.style('flex justify-between')}></View>
</View>
<View
style={tw.style(
'flex flex-row-reverse justify-between flex-wrap py-3',
)}>
<CustomPressable
title={'نسخه فیزیکی'}
backgroundColor="transparent"
color={'#196EC0'}
border={{color: '#196EC0', width: 1}}
width={'49%'}
/>
<CustomPressable
title={'نسخه دیجیتال'}
backgroundColor="transparent"
color={'#196EC0'}
border={{color: '#196EC0', width: 1}}
width={'49%'}
/>
<CustomPressable
title={'خرید با قیمت 245.000 تومان'}
backgroundColor="#196EC0"
color={'white'}
border={{color: '#196EC0', width: 0}}
width={'65%'}
/>
<CustomPressable
title={'مشاهده نمونه'}
backgroundColor="transparent"
color={'#196EC0'}
border={{color: '#196EC0', width: 1}}
width={'33%'}
/>
<Pressable
style={[
tw.style(
'w-full rounded-md flex flex-row justify-center items-center py-3.5',
),
{backgroundColor: '#196EC01a'},
]}>
<Image
source={arrowMoreIcon}
style={{width: 12, height: 16, marginRight: 10}}
/>
<Text
style={[tw.style(''), {color: '#275077', fontSize: width / 27}]}>
مشاهده دوره ویدئویی این محصول
</Text>
</Pressable>
</View>
<Description description={product.description} />
<LinkBox title="مشخصات محصول" path="" />
<LinkBox title="نقد بررسی و توضیحات تکمیلی محصول" path="" />
<LinkBox title="پرسش و پاسخ" path="" />
<View
style={tw.style(
'flex flex-row-reverse justify-between items-center my-4',
)}>
<Text
style={[
{fontSize: width / 25, color: '#275077'},
tw.style('semibold'),
]}>
امتیازات و نظرات
</Text>
<Image
source={arrowMoreIcon}
style={{width: 12, height: 16, marginRight: 10}}
/>
</View>
<Rates rates={product.rates} />
<Comments comments={product.comments} />
</ScrollView>
);
}

@ -0,0 +1,61 @@
import React from 'react';
import {View, Text, ScrollView, Image, Dimensions} from 'react-native';
import tw from 'tailwind-react-native-classnames';
const width = Dimensions.get('window').width;
export default function Commnets({comments}) {
return (
<ScrollView horizontal={true} style={{direction: 'rtl', marginTop: 20}}>
{comments.map((comment, index) => (
<Comment comment={comment} key={index} />
))}
</ScrollView>
);
}
const Comment = ({comment}) => {
return (
<View
style={[
tw.style('flex flex-col rounded-md p-4 ml-2'),
{width: width / 1.3, borderWidth: 1, borderColor: '#7070701a'},
]}>
<View style={[tw.style('flex flex-row justify-between items-center')]}>
<View style={tw.style('flex flex-row items-center')}>
<Image
source={comment.imageUrl}
style={[tw.style('rounded-full'), {width: 35, height: 35}]}
/>
<Text
style={[
{fontSize: width / 25, color: '#132F52'},
tw.style('font-bold'),
]}>
{comment.name}
</Text>
</View>
<View style={tw.style('flex flex-row items-center')}>
<Text style={{fontSize: width / 38, color: '#196EC0'}}>18:20</Text>
<View
style={{
backgroundColor: '#196EC055',
height: 12,
width: 2,
marginHorizontal: 4,
}}></View>
<Text style={{fontSize: width / 38, color: '#196EC0'}}>
1400/08/19
</Text>
</View>
</View>
<Text
style={[
{fontSize: width / 32, lineHeight: 20, color: '#132F52'},
tw.style('text-left mt-2'),
]}>
{comment.message}
</Text>
</View>
);
};

@ -0,0 +1,35 @@
import React from 'react';
import {View, Text, Dimensions, Image} from 'react-native';
import tw from 'tailwind-react-native-classnames';
import arrowMoreIcon from '../assets/arrowMore.png';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
export default function Description({description}) {
return (
<View style={[tw.style('w-full flex flex-col pt-6 mt-2 mb-3'), {borderTopWidth : 1, borderColor : '#86A0B944'}]}>
<View
style={tw.style('flex flex-row-reverse justify-between items-center mb-2')}>
<Text
style={[
{fontSize: width / 25, color: '#275077'},
tw.style('semibold'),
]}>
توضیحات
</Text>
<Image
source={arrowMoreIcon}
style={{width: 12, height: 16, marginRight: 10}}
/>
</View>
<Text
style={[
tw.style('w-full text-right mt-2'),
{fontSize: width / 30, color: '#323232bb', lineHeight: 20},
]}>
{description}
</Text>
</View>
);
}

@ -0,0 +1,31 @@
import React from 'react';
import {View, Text, Dimensions, Image} from 'react-native';
import tw from 'tailwind-react-native-classnames';
import arrowMoreIcon from '../assets/arrowMore.png';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
export default function Description({title, path}) {
return (
<View
style={[
tw.style('flex flex-row-reverse justify-between items-center mt-3 rounded-md px-5 py-4'),
{
backgroundColor: '#50A9FF33'
}
]}>
<Text
style={[
{fontSize: width / 30, color: '#275077'},
tw.style('semibold'),
]}>
{title}
</Text>
<Image
source={arrowMoreIcon}
style={{width: 12, height: 16, marginRight: 10}}
/>
</View>
);
}

@ -0,0 +1,61 @@
import React from 'react';
import {View, Text, Dimensions} from 'react-native';
import tw from 'tailwind-react-native-classnames';
const width = Dimensions.get('window').width;
export default function Rates({rates}) {
return (
<View style={tw.style('flex flex-row-reverse')}>
<View
style={[
tw.style('flex flex-col items-center justify-center'),
{width: '25%'},
]}>
<Text
style={[
tw.style('font-bold'),
{fontSize: width / 10, color: '#05335F'},
]}>
{rates.mid}
</Text>
<Text style={{fontSize: width / 30, color: '#707070'}}>
{'از' + ' ' + rates.allRates + ' ' + 'نفر'}
</Text>
</View>
<View style={[tw.style('flex flex-col flex-1'), {width: '60%'}]}>
{rates.fields.map((field, index) => (
<Progress key={index} data={field} />
))}
</View>
</View>
);
}
const Progress = ({data}) => {
return (
<View style={[tw.style('flex flex-1 flex-row items-center py-0.5')]}>
<Text style={{fontSize: width / 30, color: '#05335F'}}>{data.name}</Text>
<View
style={[
tw.style('rounded-md ml-2 flex-1'),
{height: 6, backgroundColor: '#D3E9FF'},
]}>
<View
style={[
tw.style('h-full rounded-md my-auto'),
{width: data.value + '%', backgroundColor: '#2B8DEB'},
]}></View>
</View>
<Text
style={{
fontSize: width / 30,
width: width / 7.5,
textAlign: 'center',
color: '#05335F',
}}>
{data.value + '%'}
</Text>
</View>
);
};

@ -0,0 +1,207 @@
import {t} from 'i18next';
import React from 'react';
import {
View,
Text,
Image,
Dimensions,
ScrollView,
Pressable,
} from 'react-native';
import CustomPressable from '../../../components/Pressable';
import Description from './Description';
import LinkBox from './LinkBox';
import Comments from './Comments';
import Rates from './Rates';
import tw from 'tailwind-react-native-classnames';
import arrowMoreIcon from '../assets/arrowMore.png';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
export default function Video({product}) {
return (
<ScrollView style={[tw.style('flex flex-col flex-1')]}>
<View style={tw.style('flex flex-column')}>
<View
style={[
tw.style(
'w-full flex flex-row flex-1 justify-between items-center relative overflow-hidden',
),
{height: height / 3.8},
]}>
{/* <View
style={[
tw.style('rounded-full bg-black bg-opacity-20 z-50'),
{width: 50, height: 50},
]}></View> */}
<Image
source={product.poster}
style={tw.style('w-full rounded-md h-full absolute left-0 top-0')}
/>
<Image
source={{uri: product.imageUrl}}
style={[
tw.style('rounded-md h-full rounded-md ml-2'),
{width: width / 5, height: height / 7},
]}
/>
</View>
<View
style={[
tw.style('flex flex-col flex-1 justify-between items-end'),
{
paddingRight: 10,
},
]}>
<View style={tw.style('flex flex-col items-end')}>
<Text
style={{
marginTop : 5,
color: '#05335F',
fontSize: width / 17,
marginBottom: 5,
}}>
{product.name}
</Text>
<Text style={{color: '#196EC0', fontSize: width / 30, marginBottom: 10}}>
{product.grade}
</Text>
</View>
<Text
style={[
tw.style('text-right w-full'),
{color: '#323232', fontSize: width / 32},
]}>
{product.text}
</Text>
</View>
</View>
<View
style={tw.style(
'flex flex-row-reverse items-center justify-around py-6',
)}>
<View>
<Text
style={{
color: '#196EC0',
textAlign: 'center',
fontSize: width / 27,
}}>
{' '}
{473 + '\n' + 'صفحه'}
</Text>
</View>
<View
style={{backgroundColor: '#196EC055', height: 20, width: 2}}></View>
<View>
<Text
style={{
color: '#196EC0',
textAlign: 'center',
fontSize: width / 27,
}}>
{' '}
{'فیزیکی- دیجیتالی - ویدئو' + '\n' + 'در دسترس'}
</Text>
</View>
<View
style={{backgroundColor: '#196EC055', height: 20, width: 2}}></View>
<View>
<Text
style={{
color: '#196EC0',
textAlign: 'center',
fontSize: width / 27,
}}>
{' '}
{4.8 + '\n' + 'امتیاز'}
</Text>
</View>
</View>
<View style={'flex flex-col mt-3'}>
<Text
style={[
tw.style('w-full text-right font-medium'),
{color: '#196EC0', fontSize: width / 26},
]}>
نسخه محصول را انتخاب کنید
</Text>
<View style={tw.style('flex justify-between')}></View>
</View>
<View
style={tw.style(
'flex flex-row-reverse justify-between flex-wrap py-3',
)}>
<CustomPressable
title={'نسخه فیزیکی'}
backgroundColor="transparent"
color={'#196EC0'}
border={{color: '#196EC0', width: 1}}
width={'49%'}
/>
<CustomPressable
title={'نسخه دیجیتال'}
backgroundColor="transparent"
color={'#196EC0'}
border={{color: '#196EC0', width: 1}}
width={'49%'}
/>
<CustomPressable
title={'خرید با قیمت 245.000 تومان'}
backgroundColor="#196EC0"
color={'white'}
border={{color: '#196EC0', width: 0}}
width={'65%'}
/>
<CustomPressable
title={'مشاهده نمونه'}
backgroundColor="transparent"
color={'#196EC0'}
border={{color: '#196EC0', width: 1}}
width={'33%'}
/>
<Pressable
style={[
tw.style(
'w-full rounded-md flex flex-row justify-center items-center py-3.5',
),
{backgroundColor: '#196EC01a'},
]}>
<Image
source={arrowMoreIcon}
style={{width: 12, height: 16, marginRight: 10}}
/>
<Text
style={[tw.style(''), {color: '#275077', fontSize: width / 27}]}>
مشاهده دوره ویدئویی این محصول
</Text>
</Pressable>
</View>
<Description description={product.description} />
<LinkBox title="مشخصات محصول" path="" />
<LinkBox title="نقد بررسی و توضیحات تکمیلی محصول" path="" />
<LinkBox title="پرسش و پاسخ" path="" />
<View
style={tw.style(
'flex flex-row-reverse justify-between items-center my-4',
)}>
<Text
style={[
{fontSize: width / 25, color: '#275077'},
tw.style('semibold'),
]}>
امتیازات و نظرات
</Text>
<Image
source={arrowMoreIcon}
style={{width: 12, height: 16, marginRight: 10}}
/>
</View>
<Rates rates={product.rates} />
<Comments comments={product.comments} />
</ScrollView>
);
}

@ -0,0 +1,76 @@
import React from 'react';
import {View, StyleSheet, Dimensions, ScrollView} from 'react-native';
import Book from './components/Book';
import Video from './components/Video';
import {connect} from 'react-redux';
import userImage from './assets/user.png';
import poster from './assets/poster.png';
function Product({
product = {
type: 'ویدئوها',
name: 'ریاضی',
price: '145.000 تومان',
imageUrl: 'https://dnvn.ir/api/v1/file/2105',
poster : poster,
grade: 'پایه هفتم ابتدایی',
text: 'خالد حسینی تو رمان باد بادک باز مینویسه : ﻣﺮﺩ ﺁﻫﺴﺘﻪ ﺩﺭ ﮔﻮﺵ ﻓﺮﺯﻧﺪ ﺗﺎﺯﻩ ﺑﻪ ﺑﻠﻮﻍ ﺭﺳﯿﺪﻩ ﺍﺵ ﺑﺮﺍﯼ ﭘﻨﺪ ﭼﻨﯿﻦ ﻧﺠﻮﺍ ﮐﺮﺩ : ” ﭘﺴﺮﻡ ﺩﺭ ﺯﻧﺪﮔﯽ ﻫﺮﮔﺰ ﺩﺯﺩﯼ ﻧﮑﻦ ” ﭘﺴﺮ ﻣﺘﻌﺠﺐ ﻭ ﻣﺒﻬﻮﺕ ﺑﻪ ﭘﺪﺭ ﻧﮕﺎﻩ ﮐﺮﺩ ﺑﺪﯾﻦ ',
description:
'خالد حسینی تو رمان باد بادک باز مینویسه : ﻣﺮﺩ ﺁﻫﺴﺘﻪ ﺩﺭ ﮔﻮﺵ ﻓﺮﺯﻧﺪ ﺗﺎﺯﻩ ﺑﻪ ﺑﻠﻮﻍ ﺭﺳﯿﺪﻩ ﺍﺵ ﺑﺮﺍﯼ ﭘﻨﺪ ﭼﻨﯿﻦ ﻧﺠﻮﺍ ﮐﺮﺩ : ” ﭘﺴﺮﻡ ﺩﺭ ﺯﻧﺪﮔﯽ ﻫﺮﮔﺰ ﺩﺯﺩﯼ ﻧﮑﻦ ” ﭘﺴﺮ ﻣﺘﻌﺠﺐ ﻭ ﻣﺒﻬﻮﺕ ﺑﻪ ﭘﺪﺭ ﻧﮕﺎﻩ ﮐﺮﺩ ﺑﺪﯾﻦ ﻣﻌﻨﺎ ﮐﻪ ﺍﻭ ﻫﺮﮔﺰ ﺩﺳﺖ ﮐﺞ ﻧﺪﺍﺷﺘﻪ ﭘﺪﺭ ﺑﻪ ﻧﮕﺎﻩ ﻣﺘﻌﺠﺐ ﻓﺮﺯﻧﺪ ﻟﺒﺨﻨﺪﯼ ﺯﺩ ﻭ ﺍﺩﺍﻣﻪ ﺩﺍﺩ : ﺩﺭ ﺯﻧﺪﮔﯽ ﺩﺭﻭﻍ ﻧﮕﻮ ﭼﺮﺍ ﮐﻪ ﺍﮔﺮ ﮔﻔﺘﯽ ﺻﺪﺍﻗﺖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﺧﯿﺎﻧﺖ ﻧﮑﻦ ﮐﻪ ﺍﮔﺮ ﮐﺮﺩﯼ ﻋﺸﻖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﺧﺸﻮﻧﺖ ﻧﮑﻦ ﺍﮔﺮ ﮐﺮﺩﯼ ﻣﺤﺒﺖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﻧﺎ ﺣﻖ ﻧﮕﻮ ﺍﮔﺮ ﮔﻔﺘﯽ ﺣﻖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﺑﯽ ﺣﯿﺎﯾﯽ ﻧﮑﻦ ﺍﮔﺮ ﮐﺮﺩﯼ ﺷﺮﺍﻓﺖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍی... ﭘﺲ ﺩﺭ ﺯﻧﺪﮔﯽ ﻓﻘﻂ ﺩﺯﺩﯼ نکن ',
rates: {
mid: 4.5,
allRates: 2456,
fields: [
{name: 'field1', value: 49},
{name: 'field2', value: 31},
{name: 'field3', value: 9},
{name: 'field4', value: 5},
{name: 'field5', value: 4},
],
},
comments: [
{
name: 'سورنا عابدی',
imageUrl: userImage,
vote: 4,
date: new Date(),
message:
'خالد حسینی تو رمان باد بادک باز مینویسه : ﻣﺮﺩ ﺁﻫﺴﺘﻪ ﺩﺭ ﮔﻮﺵ ﻓﺮﺯﻧﺪ ﺗﺎﺯﻩ ﺑﻪ ﺑﻠﻮﻍ ﺭﺳﯿﺪﻩ ﺍﺵ ﺑﺮﺍﯼ ﭘﻨﺪ ﭼﻨﯿﻦ ﻧﺠﻮﺍ ﮐﺮﺩ : ” ﭘﺴﺮﻡ ﺩﺭ ﺯﻧﺪﮔﯽ ﻫﺮﮔﺰ ﺩﺯﺩﯼ ﻧﮑﻦ ” ﭘﺴﺮ ﻣﺘﻌﺠﺐ ﻭ ﻣﺒﻬﻮﺕ ﺑﻪ ﭘﺪﺭ ﻧﮕﺎﻩ ﮐﺮﺩ ﺑﺪﯾﻦ ﻣﻌﻨﺎ ﮐﻪ ﺍﻭ ﻫﺮﮔﺰ ﺩﺳﺖ ﮐﺞ ﻧﺪﺍﺷﺘﻪ ﭘﺪﺭ ﺑﻪ ﻧﮕﺎﻩ ﻣﺘﻌﺠﺐ ﻓﺮﺯﻧﺪ ﻟﺒﺨﻨﺪﯼ ﺯﺩ ﻭ ﺍﺩﺍﻣﻪ ',
},
{
name: 'سورنا عابدی',
imageUrl: userImage,
vote: 4,
date: new Date(),
message:
'خالد حسینی تو رمان باد بادک باز مینویسه : ﻣﺮﺩ ﺁﻫﺴﺘﻪ ﺩﺭ ﮔﻮﺵ ﻓﺮﺯﻧﺪ ﺗﺎﺯﻩ ﺑﻪ ﺑﻠﻮﻍ ﺭﺳﯿﺪﻩ ﺍﺵ ﺑﺮﺍﯼ ﭘﻨﺪ ﭼﻨﯿﻦ ﻧﺠﻮﺍ ﮐﺮﺩ : ” ﭘﺴﺮﻡ ﺩﺭ ﺯﻧﺪﮔﯽ ﻫﺮﮔﺰ ﺩﺯﺩﯼ ﻧﮑﻦ ” ﭘﺴﺮ ﻣﺘﻌﺠﺐ ﻭ ﻣﺒﻬﻮﺕ ﺑﻪ ﭘﺪﺭ ﻧﮕﺎﻩ ﮐﺮﺩ ﺑﺪﯾﻦ ﻣﻌﻨﺎ ﮐﻪ ﺍﻭ ﻫﺮﮔﺰ ﺩﺳﺖ ﮐﺞ ﻧﺪﺍﺷﺘﻪ ﭘﺪﺭ ﺑﻪ ﻧﮕﺎﻩ ﻣﺘﻌﺠﺐ ﻓﺮﺯﻧﺪ ﻟﺒﺨﻨﺪﯼ ﺯﺩ ﻭ ﺍﺩﺍﻣﻪ ',
},
],
},
}) {
return (
<ScrollView
contentContainerStyle={styles.contentContainerStyle}
style={styles.container}>
{product.type === 'ویدئوها' ? (
<Video product={product} />
) : (
<Book product={product} />
)}
</ScrollView>
);
}
const styles = StyleSheet.create({
contentContainerStyle: {
paddingBottom: 50,
},
container: {
width: Dimensions.get('window').width,
backgroundColor: 'white',
flexDirection: 'column',
paddingVertical: 5,
paddingHorizontal: 10,
},
});
export default Product;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save