reza added all of things

master
Reza_ashrafi 3 years ago
parent 3c7c2a0df0
commit 8139d8c6a7
  1. 60
      navigation/index.js
  2. 1
      package.json
  3. BIN
      src/assets/sound.mp3
  4. BIN
      src/assets/video.mp4
  5. 3
      src/components/MusicPlayer.js
  6. 2
      src/components/Pressable.js
  7. 21
      src/constants/fontSize.js
  8. 9
      src/redux/actions/user.js
  9. 34
      src/redux/proxy.js
  10. 1
      src/redux/reducers/public.js
  11. 23
      src/redux/reducers/user.js
  12. 10
      src/redux/store.js
  13. BIN
      src/screens/Home/assets/ar.png
  14. BIN
      src/screens/Home/assets/arrow.png
  15. BIN
      src/screens/Home/assets/bookFeatureIcon.png
  16. BIN
      src/screens/Home/assets/food.png
  17. BIN
      src/screens/Home/assets/olum1.png
  18. BIN
      src/screens/Home/assets/packageFeatureIcon.png
  19. BIN
      src/screens/Home/assets/qr.png
  20. BIN
      src/screens/Home/assets/responsive-bg.png
  21. BIN
      src/screens/Home/assets/shoe.png
  22. BIN
      src/screens/Home/assets/testFeatureIcon.png
  23. BIN
      src/screens/Home/assets/videoFeatureIcon.png
  24. 71
      src/screens/Home/components/Blogs.js
  25. 10
      src/screens/Home/components/Header.js
  26. 30
      src/screens/Home/components/MyBooks.js
  27. 67
      src/screens/Home/components/Scroll.js
  28. 87
      src/screens/Home/components/Videos.js
  29. 40
      src/screens/Home/index.js
  30. 20
      src/screens/Login/index.js
  31. 106
      src/screens/Product/components/Book.js
  32. 10
      src/screens/Product/components/Comments.js
  33. 5
      src/screens/Product/components/Description.js
  34. 3
      src/screens/Product/components/LinkBox.js
  35. 9
      src/screens/Product/components/Rates.js
  36. 75
      src/screens/Product/index.js
  37. 35
      src/screens/Products/components/Book.js
  38. 9
      src/screens/Products/components/Video.js
  39. 58
      src/screens/Products/index.js
  40. 4
      src/screens/QR/Content/Voice.js
  41. 2
      src/screens/QR/Scan/index.js
  42. 2
      src/screens/QR/index.js
  43. 24
      src/screens/ShoppingCart/components/Code.js
  44. 63
      src/screens/ShoppingCart/components/Product.js
  45. 46
      src/screens/ShoppingCart/index.js
  46. 16
      src/screens/Splash/index.js
  47. 69
      src/screens/Video/components/Season.js
  48. 77
      src/screens/Video/index.js
  49. 58
      src/screens/VideoDisplay/components/Season/index.js
  50. 75
      src/screens/VideoDisplay/index.js
  51. 44
      src/screens/Videos/components/MostViewedVideo.js
  52. 32
      src/screens/Videos/components/NewestVideo.js
  53. 14
      src/screens/Videos/components/VerticalGradeFilter.js
  54. 34
      src/screens/Videos/index.js
  55. 12
      src/utils/fontSizeResponsive.js
  56. 7
      yarn.lock

@ -1,4 +1,4 @@
import React from "react"; import React, { useEffect } from "react";
import { NavigationContainer } from "@react-navigation/native"; import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack"; import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
@ -27,6 +27,7 @@ import Exams from "../src/screens/Exams";
import ShoppingCart from "../src/screens/ShoppingCart"; import ShoppingCart from "../src/screens/ShoppingCart";
import Video from "../src/screens/Video"; import Video from "../src/screens/Video";
import VideoDisplay from "../src/screens/VideoDisplay"; import VideoDisplay from "../src/screens/VideoDisplay";
import { user } from "../src/redux/actions";
const width = Dimensions.get("window").width; const width = Dimensions.get("window").width;
@ -41,6 +42,7 @@ const BottomTabNavigator = () => {
tabBarInactiveTintColor: "grey", tabBarInactiveTintColor: "grey",
tabBarStyle: { tabBarStyle: {
backgroundColor: "#CCE6FF", backgroundColor: "#CCE6FF",
zIndex: 10,
}, },
tabBarLabelStyle: { tabBarLabelStyle: {
fontSize: width / 39, fontSize: width / 39,
@ -50,15 +52,6 @@ const BottomTabNavigator = () => {
// tabBarLabel : 'reza' // tabBarLabel : 'reza'
}} }}
> >
{/* <Tab.Screen
name="SplashTab"
component={AuthStackScreen}
options={{
tabBarIcon: ({ focused, color }) => (
<FontAwesome name="user" size={focused ? 27 : 23} color={color} />
),
}}
/> */}
<Tab.Screen <Tab.Screen
name="ShoppingCartTab" name="ShoppingCartTab"
component={ShoppingCart} component={ShoppingCart}
@ -119,11 +112,7 @@ const HomeStackScreen = () => {
initialRouteName="Home" initialRouteName="Home"
> >
<HomeStack.Screen name="Home" component={Home} /> <HomeStack.Screen name="Home" component={Home} />
<HomeStack.Screen name="QR" component={QR} />
<HomeStack.Screen name="Product" component={Product} /> <HomeStack.Screen name="Product" component={Product} />
<Stack.Screen name="Orders" component={OrderStackScreen} />
<Stack.Screen name="Faq" component={Faq} />
<Stack.Screen name="Activation" component={Activation} />
</HomeStack.Navigator> </HomeStack.Navigator>
); );
}; };
@ -133,11 +122,7 @@ const ProductsStackScreen = () => {
return ( return (
<ProductsStack.Navigator screenOptions={{ headerShown: false }}> <ProductsStack.Navigator screenOptions={{ headerShown: false }}>
<ProductsStack.Screen name="Products" component={Products} /> <ProductsStack.Screen name="Products" component={Products} />
<ProductsStack.Screen name="QR" component={QR} />
<ProductsStack.Screen name="Product" component={Product} /> <ProductsStack.Screen name="Product" component={Product} />
<ProductsStack.Screen name="Orders" component={OrderStackScreen} />
<ProductsStack.Screen name="Faq" component={Faq} />
<ProductsStack.Screen name="Activation" component={Activation} />
</ProductsStack.Navigator> </ProductsStack.Navigator>
); );
}; };
@ -149,10 +134,6 @@ const VODStackScreen = () => {
<VODStack.Screen name="VOD" component={Videos} /> <VODStack.Screen name="VOD" component={Videos} />
<VODStack.Screen name="Video" component={Video} /> <VODStack.Screen name="Video" component={Video} />
<VODStack.Screen name="VideoDisplay" component={VideoDisplay} /> <VODStack.Screen name="VideoDisplay" component={VideoDisplay} />
<VODStack.Screen name="QR" component={QR} />
<VODStack.Screen name="Orders" component={OrderStackScreen} />
<VODStack.Screen name="Faq" component={Faq} />
<VODStack.Screen name="Activation" component={Activation} />
</VODStack.Navigator> </VODStack.Navigator>
); );
}; };
@ -171,21 +152,12 @@ const AuthStackScreen = () => {
); );
}; };
const OrderStack = createNativeStackNavigator();
const OrderStackScreen = () => {
return (
<OrderStack.Navigator
screenOptions={{ headerShown: false }}
initialRouteName="Orders"
>
<OrderStack.Screen name="Orders" component={OrdersFollowUp} />
<OrderStack.Screen name="Order" component={OrderDetails} />
</OrderStack.Navigator>
);
};
const Stack = createNativeStackNavigator(); const Stack = createNativeStackNavigator();
const Navigation = ({}) => { const Navigation = ({ getStatus, isLogin }) => {
useEffect(() => {
getStatus();
}, []);
return ( return (
<NavigationContainer> <NavigationContainer>
<Stack.Navigator <Stack.Navigator
@ -193,17 +165,23 @@ const Navigation = ({}) => {
screenOptions={{ headerShown: false }} screenOptions={{ headerShown: false }}
> >
<Stack.Screen name="Splash" component={Splash} /> <Stack.Screen name="Splash" component={Splash} />
<Stack.Screen name="QR" component={QR} />
<Stack.Screen name="Root" component={BottomTabNavigator} />
<Stack.Screen name="Login" component={Login} /> <Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Otp" component={Otp} /> <Stack.Screen name="Otp" component={Otp} />
<Stack.Screen name="Root" component={BottomTabNavigator} /> <Stack.Screen name="Orders" component={OrdersFollowUp} />
<Stack.Screen name="Order" component={OrderDetails} />
<Stack.Screen name="Faq" component={Faq} />
<Stack.Screen name="Activation" component={Activation} />
</Stack.Navigator> </Stack.Navigator>
</NavigationContainer> </NavigationContainer>
); );
}; };
const mapStateToProps = (state) => { const mapStateToProps = (state) => ({
return {}; isLogin: state.user.status,
});
const mapDispatchToProps = {
getStatus: user.getStatus,
}; };
export default connect(mapStateToProps, mapDispatchToProps)(Navigation);
export default connect(mapStateToProps)(Navigation);

@ -25,6 +25,7 @@
"expo-camera": "~12.1.0", "expo-camera": "~12.1.0",
"expo-device": "~4.1.0", "expo-device": "~4.1.0",
"expo-font": "^10.0.4", "expo-font": "^10.0.4",
"expo-screen-orientation": "~4.1.1",
"expo-status-bar": "~1.2.0", "expo-status-bar": "~1.2.0",
"i18next": "^21.6.3", "i18next": "^21.6.3",
"install": "^0.13.0", "install": "^0.13.0",

Binary file not shown.

Binary file not shown.

@ -2,14 +2,13 @@ import React, { useState, useEffect } from "react";
import { StyleSheet, TouchableOpacity, View, Image, Text } from "react-native"; import { StyleSheet, TouchableOpacity, View, Image, Text } from "react-native";
import { Ionicons } from "@expo/vector-icons"; import { Ionicons } from "@expo/vector-icons";
import { Audio } from "expo-av"; import { Audio } from "expo-av";
import sound from '../assets/sound.mp3';
const audioBookPlaylist = [ const audioBookPlaylist = [
{ {
title: "Hamlet - Act I", title: "Hamlet - Act I",
author: "William Shakespeare", author: "William Shakespeare",
source: "Librivox", source: "Librivox",
uri: sound, uri: "",
imageSource: imageSource:
"http://www.archive.org/download/LibrivoxCdCoverArt8/hamlet_1104.jpg", "http://www.archive.org/download/LibrivoxCdCoverArt8/hamlet_1104.jpg",
}, },

@ -10,9 +10,11 @@ export default function Pressable1({
color, color,
border, border,
width, width,
onPress,
}) { }) {
return ( return (
<Pressable <Pressable
onPress={() => onPress()}
style={[ style={[
tw.style('rounded-md py-3 flex flex-row justify-center mb-3'), tw.style('rounded-md py-3 flex flex-row justify-center mb-3'),
{ {

@ -0,0 +1,21 @@
import { Dimensions } from "react-native"
import { fontSizeHandler } from "../utils/fontSizeResponsive"
const {width} = Dimensions.get("window");
const minWidth = 320;
const maxWidth = 1200;
const fontSize = {
xs : fontSizeHandler(width, 10, 12, minWidth, maxWidth),
sm : fontSizeHandler(width,12, 14, minWidth, maxWidth),
base : fontSizeHandler(width, 14, 16, minWidth, maxWidth),
lg : fontSizeHandler(width, 16 , 18, minWidth, maxWidth),
xl : fontSizeHandler(width, 18, 20, minWidth, maxWidth),
xl2 : fontSizeHandler(width, 20, 22, minWidth, maxWidth),
xl3 : fontSizeHandler(width, 22, 24, minWidth, maxWidth),
xl4 : fontSizeHandler(width, 24, 26, minWidth, maxWidth),
xl5 : fontSizeHandler(width, 26, 28, minWidth, maxWidth),
xl6 : fontSizeHandler(width, 28, 30, minWidth, maxWidth)
};
export default fontSize;

@ -1,13 +1,16 @@
import proxy from "../proxy"; import proxy from "../proxy";
const user = { const user = {
getStatus: () => async (dispatch) => {
await proxy.getStatus({ dispatch });
},
otp: (data) => async (dispatch) => { otp: (data) => async (dispatch) => {
console.log(data);
await proxy.post("public/sendOTP", data, { dispatch }); await proxy.post("public/sendOTP", data, { dispatch });
}, },
otp_login: (data) => async (dispatch) => otp_login: (data = {}) => async (dispatch) => {
await proxy.login("user/otp/login", data, { dispatch }), await proxy.login("user/otp/login", data, { dispatch });
},
login: (data) => async (dispatch) => login: (data) => async (dispatch) =>
await proxy.login("user/login", data, { dispatch }), await proxy.login("user/login", data, { dispatch }),

@ -33,12 +33,7 @@ class Proxy {
post = (url, params, opt, data) => { post = (url, params, opt, data) => {
try { try {
this.check( this.check(url, opt, () => Axios.post(url, params, opt), data || params);
url,
opt,
() => Axios.post(url, params, opt),
data || params
);
} catch (error) { } catch (error) {
console.log("proxy post error! : ", error); console.log("proxy post error! : ", error);
} }
@ -46,12 +41,7 @@ class Proxy {
put = (url, params, opt, data) => { put = (url, params, opt, data) => {
try { try {
this.check( this.check(url, opt, () => Axios.put(url, params, opt), data || params);
url,
opt,
() => Axios.put(url, params, opt),
data || params
);
} catch (error) { } catch (error) {
console.log("proxy put error! : ", error); console.log("proxy put error! : ", error);
} }
@ -70,11 +60,11 @@ class Proxy {
} }
}; };
check = (url, { dispatch }, fetch, params) => { check = async (url, { dispatch }, fetch, params) => {
try { try {
dispatch = dispatch || (() => {}); dispatch = dispatch || (() => {});
dispatch({ type: url.split("/")[0] + "/" + "loading" }); dispatch({ type: url.split("/")[0] + "/" + "loading" });
let response = fetch(); let response = await fetch();
switch (response.status) { switch (response.status) {
case 200: case 200:
dispatch({ type: url, data: response.data.data, params }); dispatch({ type: url, data: response.data.data, params });
@ -82,6 +72,7 @@ class Proxy {
case 401: case 401:
if (this.refresh()) { if (this.refresh()) {
let response = fetch(); let response = fetch();
console.log('check 401', response )
dispatch({ type: url, data: response.data.data, params }); dispatch({ type: url, data: response.data.data, params });
return response.data.data; return response.data.data;
} }
@ -116,13 +107,14 @@ class Proxy {
}; };
login = (url, params, { dispatch }) => { login = (url, params, { dispatch }) => {
console.log('login called');
try { try {
console.log('------------------------------login---------------------------------');
this.post(url, params, { this.post(url, params, {
dispatch: (obj) => { dispatch: (obj) => {
let login = obj.data; let login = obj.data;
console.log('login data: ',login); if (!login || !login.refreshToken){
if (!login || !login.refreshToken) return false; return false;
}
const refresh = ["refresh", login.refreshToken]; const refresh = ["refresh", login.refreshToken];
const access = ["access", login.accessToken]; const access = ["access", login.accessToken];
const userData = ["userData", JSON.stringify(login.profile)]; const userData = ["userData", JSON.stringify(login.profile)];
@ -163,9 +155,13 @@ class Proxy {
return userData || null; return userData || null;
} catch (error) { } catch (error) {
console.log("proxy status error : ", error); console.log("proxy status error : ", error);
return nulll;
} }
}; };
getStatus = async ({ dispatch }) => {
let status = await this.status();
dispatch({ type: "user/getStatus", data: {status}})
}
} }
const _proxy = new Proxy(); const _proxy = new Proxy();
export default _proxy;
export default _proxy;

@ -105,6 +105,7 @@ const publicApi = (state = initialState, action) => {
allCats = Array.from( allCats = Array.from(
new Set(data.vods.map((item) => item.categoryId && item.categoryId)) new Set(data.vods.map((item) => item.categoryId && item.categoryId))
); );
allCats.sort((a , b) => a - b);
return { return {
...state, ...state,
loading: false, loading: false,

@ -1,13 +1,8 @@
import proxy from "../proxy"; import proxy from "../proxy";
import AsyncStorage from "@react-native-async-storage/async-storage"; import AsyncStorage from "@react-native-async-storage/async-storage";
const checkStatus = async () => {
let status = await proxy.status();
return status;
}
let initialState = { let initialState = {
status: checkStatus(), status: null,
loading: false, loading: false,
error: null, error: null,
list: null, list: null,
@ -16,7 +11,7 @@ let initialState = {
profileStatus: false, profileStatus: false,
setDone: false, setDone: false,
setLogin: false, setLogin: false,
check : 'check' check: "check",
}; };
const user = (state = initialState, action) => { const user = (state = initialState, action) => {
@ -27,6 +22,8 @@ const user = (state = initialState, action) => {
// case "user/switchRole": // case "user/switchRole":
case "public/sendOTP": case "public/sendOTP":
return { ...state, loading: false, error: null }; return { ...state, loading: false, error: null };
case "user/getStatus":
return { ...state, status: data.status, error: null };
case "user/login": case "user/login":
case "user/otp/login": case "user/otp/login":
return { return {
@ -38,10 +35,10 @@ const user = (state = initialState, action) => {
}; };
case "user/getProfile": case "user/getProfile":
const myData = JSON.stringify(data); const myData = JSON.stringify(data);
try{ try {
AsyncStorage.setItem("userData", myData); AsyncStorage.setItem("userData", myData);
}catch(error){ } catch (error) {
console.log('user/getProfile', error); console.log("user/getProfile", error);
} }
return { return {
...state, ...state,
@ -51,7 +48,7 @@ const user = (state = initialState, action) => {
setDone: false, setDone: false,
}; };
case "user/logout": case "user/logout":
return { ...state, loading: false, status: proxy.status(), error: null }; return { ...state, loading: false, status: null, error: null };
case "user/getUserRole": case "user/getUserRole":
return { ...state, loading: false, userRoles: data, error: null }; return { ...state, loading: false, userRoles: data, error: null };
case "user/setProfile": case "user/setProfile":
@ -64,6 +61,6 @@ const user = (state = initialState, action) => {
default: default:
return state; return state;
} }
} };
export default user; export default user;

@ -25,10 +25,10 @@ const initialState = {};
const middleWare = [thunk]; const middleWare = [thunk];
const loggerMiddleware = createLogger({ // const loggerMiddleware = createLogger({
predicate: () => process.env.NODE_ENV === "development", // predicate: () => process.env.NODE_ENV === "development",
}); // });
middleWare.push(loggerMiddleware); // middleWare.push(loggerMiddleware);
const store = createStore( const store = createStore(
persistReducer( persistReducer(
@ -59,6 +59,6 @@ try {
// console.log(e); // console.log(e);
} }
console.disableYellowBox = true; // console.disableYellowBox = true;
export default store; export default store;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 800 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 956 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 591 B

@ -7,35 +7,32 @@ import {
TouchableOpacity, TouchableOpacity,
FlatList, FlatList,
} from "react-native"; } from "react-native";
import { connect } from "react-redux";
const width = Dimensions.get("window").width;
const height = Dimensions.get("window").height;
import Header from "../components/Header"; import Header from "../components/Header";
import fontSize from "../../../constants/fontSize";
import tw from "tailwind-rn"; import tw from "tailwind-rn";
import { connect } from "react-redux";
//asssets //asssets
import foodImage from "../assets/food.png";
import userImage from "../assets/user.png"; import userImage from "../assets/user.png";
import messageIcon from "../assets/message.png"; import messageIcon from "../assets/message.png";
//Color //Color
import Color from "../../../constants/Colors"; import Color from "../../../constants/Colors";
function Blogs({ products }) { const { width} = Dimensions.get("window");
function Blogs({ blogs }) {
return ( return (
<View style={[tw("flex flex-col pr-3 mb-5")]}> <View style={[tw("flex flex-col pr-3 mb-5")]}>
<View style={tw("w-full pl-3")}> <View style={tw("w-full pl-3")}>
<Header title={"خواندنیها"} route={"Blogs"} /> <Header title={"خواندنیها"} route={"Blogs"} />
</View> </View>
<FlatList <FlatList
showsHorizontalScrollIndicator={false}
horizontal={true} horizontal={true}
inverted={true} inverted={true}
style={[tw("flex flex-row mt-3")]} style={[tw("flex flex-row mt-3")]}
data={products} data={blogs}
renderItem={({ item }) => <Blog blog={item} />} renderItem={({ item }) => <Blog blog={item} />}
keyExtractor={item => item.id} keyExtractor={(item) => item.id}
/> />
</View> </View>
); );
@ -44,10 +41,16 @@ function Blogs({ products }) {
const Blog = ({ blog }) => { const Blog = ({ blog }) => {
return ( return (
<TouchableOpacity <TouchableOpacity
style={[tw("rounded-md ml-3 rounded-md relative")]} style={[
tw("rounded-md ml-3 rounded-md relative"),
{ width: width / 1.5},
]}
// onPress={() => navigation.navigate('Product')} // onPress={() => navigation.navigate('Product')}
> >
<Image source={foodImage} style={{ width: 227, height: 133 }} /> <Image
source={{ uri: `https://dnvn.ir/api/v1/file/${blog.fileIds}` }}
style={[tw("rounded-md"), {width : '100%', height : width / 1.5 * 9 / 16}]}
/>
<View <View
style={[ style={[
{ transform: [{ translateY: -20 }], marginHorizontal: 10 }, { transform: [{ translateY: -20 }], marginHorizontal: 10 },
@ -60,11 +63,11 @@ const Blog = ({ blog }) => {
{ {
color: Color.theme1.light.blue7, color: Color.theme1.light.blue7,
fontFamily: "bold", fontFamily: "bold",
fontSize: width / 36, fontSize: fontSize.sm,
}, },
]} ]}
> >
آیا مواد غذای پر فیبر مفید هستند؟ {blog.title}
</Text> </Text>
<View style={tw("flex flex-row-reverse justify-between")}> <View style={tw("flex flex-row-reverse justify-between")}>
<View style={tw("flex-row-reverse items-center")}> <View style={tw("flex-row-reverse items-center")}>
@ -77,7 +80,7 @@ const Blog = ({ blog }) => {
{ {
color: Color.theme1.light.blue5, color: Color.theme1.light.blue5,
fontFamily: "light", fontFamily: "light",
fontSize: width / 40, fontSize: fontSize.xs,
}, },
]} ]}
> >
@ -90,7 +93,7 @@ const Blog = ({ blog }) => {
{ {
color: Color.theme1.light.blue5, color: Color.theme1.light.blue5,
fontFamily: "light", fontFamily: "light",
fontSize: width / 40, fontSize: fontSize.xs,
}, },
]} ]}
> >
@ -112,39 +115,3 @@ const mapStateToProps = (state) => ({
}); });
export default connect(mapStateToProps, {})(Blogs); export default connect(mapStateToProps, {})(Blogs);
Blogs.defaultProps = {
products: [
{
imageUrl: foodImage,
id: 0,
},
{
imageUrl: foodImage,
id: 1,
},
{
imageUrl: foodImage,
id: 2,
},
{
imageUrl: foodImage,
id: 3,
},
{
imageUrl: foodImage,
id: 4,
},
{
imageUrl: foodImage,
id: 5,
},
{
imageUrl: foodImage,
id: 6,
},
{
imageUrl: foodImage,
id: 7,
},
],
};

@ -1,15 +1,13 @@
import React from "react"; import React from "react";
import { View, Text, Image, Pressable, Dimensions } from "react-native"; import { View, Text, Pressable } from "react-native";
import {Entypo} from '@expo/vector-icons'; import {Entypo} from '@expo/vector-icons';
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
import fontSize from '../../../constants/fontSize';
import tw from "tailwind-rn"; import tw from "tailwind-rn";
//assets
import arrowIcon from "../assets/arrow.png";
//Color //Color
import Color from "../../../constants/Colors"; import Color from "../../../constants/Colors";
const width = Dimensions.get('window').width;
const Header = ({ title, route }) => { const Header = ({ title, route }) => {
const navigation = useNavigation(); const navigation = useNavigation();
return ( return (
@ -19,7 +17,7 @@ const Header = ({ title, route }) => {
{ {
color: Color.theme1.light.blue5, color: Color.theme1.light.blue5,
fontFamily : 'bold', fontFamily : 'bold',
fontSize : width / 30 fontSize : fontSize.base
}, },
]} ]}
> >

@ -8,12 +8,12 @@ import {
FlatList, FlatList,
} from "react-native"; } from "react-native";
import tw from "tailwind-rn"; import tw from "tailwind-rn";
import fontSize from '../../../constants/fontSize';
import {useNavigation} from '@react-navigation/native'; import {useNavigation} from '@react-navigation/native';
import { connect } from "react-redux"; import { connect } from "react-redux";
import Progress from "../../../components/Progress"; import Progress from "../../../components/Progress";
//assets //assets
import bookImage from "../assets/zist11.png";
//Color //Color
import Color from "../../../constants/Colors"; import Color from "../../../constants/Colors";
@ -21,7 +21,7 @@ import Color from "../../../constants/Colors";
const width = Dimensions.get("window").width; const width = Dimensions.get("window").width;
const height = Dimensions.get("window").height; const height = Dimensions.get("window").height;
function MyBooks({ getList, list, grades }) { function MyBooks({ books, grades }) {
return ( return (
<View style={[tw("w-full px-4 mb-5")]}> <View style={[tw("w-full px-4 mb-5")]}>
<View <View
@ -39,18 +39,19 @@ function MyBooks({ getList, list, grades }) {
{ {
color: Color.theme1.light.blue5, color: Color.theme1.light.blue5,
fontFamily: "bold", fontFamily: "bold",
fontSize: width / 30, fontSize: fontSize.base,
}, },
]} ]}
> >
کتابهای من کتابهای من
</Text> </Text>
<FlatList <FlatList
showsHorizontalScrollIndicator={false}
style={[tw("py-3")]} style={[tw("py-3")]}
horizontal={true} horizontal={true}
inverted={true} inverted={true}
data={list} data={books}
renderItem={({ item }) => <Book book={item} />} renderItem={({ item }) => <Book book={item} grades={grades} />}
keyExtractor={(book) => book.name} keyExtractor={(book) => book.name}
/> />
</View> </View>
@ -66,7 +67,7 @@ const Book = ({ book, grades }) => {
onPress={() => navigation.navigate("Product")} onPress={() => navigation.navigate("Product")}
> >
<Image <Image
source={bookImage} source={{uri : `https://dnvn.ir/api/v1/file/${book.product.book.fileIds}` }}
style={[ style={[
tw("rounded-md"), tw("rounded-md"),
{ {
@ -81,11 +82,11 @@ const Book = ({ book, grades }) => {
{ {
color: Color.theme1.light.blue6, color: Color.theme1.light.blue6,
fontFamily: "bold", fontFamily: "bold",
fontSize: width / 36, fontSize: fontSize.sm,
}, },
]} ]}
> >
{"نام کتاب"} {book.product.book.name}
</Text> </Text>
<Text <Text
style={[ style={[
@ -93,22 +94,17 @@ const Book = ({ book, grades }) => {
{ {
color: Color.theme1.light.blue5, color: Color.theme1.light.blue5,
fontFamily: "light", fontFamily: "light",
fontSize: width / 40, fontSize: fontSize.xs,
}, },
]} ]}
>{`پایه ${"اول"}`}</Text> >{'پایه' + ' ' + grades[book.product.book.gradeId]}</Text>
<Progress percent={60} alignItems={'items-end'} /> <Progress percent={60} alignItems={'items-end'} />
</TouchableOpacity> </TouchableOpacity>
); );
}; };
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
// list: state.book.list, grades : state.publicApi.grades
// grades : state.publicApi.grades
}); });
export default connect(mapStateToProps, {})(MyBooks); export default connect(mapStateToProps)(MyBooks);
MyBooks.defaultProps = {
list: [{ name: 1 }, { name: 2 }, { name: 3 }, { name: 4 }, { name: 5 }],
};

@ -2,7 +2,6 @@ import React from "react";
import { import {
View, View,
Image, Image,
Dimensions,
TouchableOpacity, TouchableOpacity,
FlatList, FlatList,
} from "react-native"; } from "react-native";
@ -12,28 +11,24 @@ import tw from "tailwind-rn";
import { connect } from "react-redux"; import { connect } from "react-redux";
import olum1Image from "../assets/olum1.png"; function Scroll({ books }) {
const width = Dimensions.get("window").width;
const height = Dimensions.get("window").height;
function Scroll({ products }) {
return ( return (
<View style={[tw("flex flex-col px-3 mb-5")]}> <View style={[tw("flex flex-col px-3 mb-5")]}>
<Header title={"فروشگاه"} route={"Products"} /> <Header title={"فروشگاه"} route={"Products"} />
<FlatList <FlatList
showsHorizontalScrollIndicator={false}
horizontal={true} horizontal={true}
inverted={true} inverted={true}
style={[tw("mt-3 pb-2")]} style={[tw("mt-3 pb-2")]}
data={[{id : 0}]} data={[{ id: 0 }]}
renderItem={({}) => <Box products={products} />} renderItem={({}) => <Box books={books} />}
keyExtractor={(item) => item.id} keyExtractor={(item) => item.id}
/> />
</View> </View>
); );
} }
const Box = ({ products }) => { const Box = ({ books }) => {
return ( return (
<View <View
style={[ style={[
@ -41,18 +36,18 @@ const Box = ({ products }) => {
{ height: 245, direction: "rtl" }, { height: 245, direction: "rtl" },
]} ]}
> >
{products.map((item, index) => ( {books.map((book, index) => (
<Product product={item} position={Number(item.id)} key={index} /> <Product book={book} position={Number(index)} key={index} />
))} ))}
</View> </View>
); );
}; };
const Product = ({ product, position }) => { const Product = ({ book, position }) => {
const navigation = useNavigation(); const navigation = useNavigation();
return ( return (
<TouchableOpacity <TouchableOpacity
onPress={() => navigation.navigate('Product')} onPress={() => navigation.navigate("Product")}
style={[ style={[
tw("rounded-md mx-1 overflow-hidden rounded-md"), tw("rounded-md mx-1 overflow-hidden rounded-md"),
{ {
@ -60,9 +55,12 @@ const Product = ({ product, position }) => {
height: position === 0 ? 245 : 118, height: position === 0 ? 245 : 118,
}, },
]} ]}
// onPress={() => navigation.navigate('Product')} onPress={() => navigation.navigate('Product')}
> >
<Image source={olum1Image} style={{ width: "100%", height: "100%" }} /> <Image
source={{ uri: `https://dnvn.ir/api/v1/file/${book.fileIds}` }}
style={{ width: "100%", height: "100%" }}
/>
</TouchableOpacity> </TouchableOpacity>
); );
}; };
@ -71,40 +69,3 @@ const mapStateToProps = (state) => ({
// features: state.publicApi.home?.features, // features: state.publicApi.home?.features,
}); });
export default connect(mapStateToProps, {})(Scroll); export default connect(mapStateToProps, {})(Scroll);
Scroll.defaultProps = {
products: [
{
imageUrl: olum1Image,
id: 0,
},
{
imageUrl: olum1Image,
id: 1,
},
{
imageUrl: olum1Image,
id: 2,
},
{
imageUrl: olum1Image,
id: 3,
},
{
imageUrl: olum1Image,
id: 4,
},
{
imageUrl: olum1Image,
id: 5,
},
{
imageUrl: olum1Image,
id: 6,
},
{
imageUrl: olum1Image,
id: 7,
},
],
};

@ -1,57 +1,49 @@
import React, {useState, useEffect} from 'react';
import { import {
View, View,
Text, Text,
Image, Image,
TouchableOpacity, TouchableOpacity,
Dimensions,
FlatList, FlatList,
} from 'react-native'; } from "react-native";
import tw from 'tailwind-rn'; import tw from "tailwind-rn";
import {connect} from 'react-redux'; import fontSize from "../../../constants/fontSize";
// import { book } from "../../../../../redux/actions"; import { connect } from "react-redux";
import Progress from '../../../components/Progress'; import Progress from "../../../components/Progress";
import Header from '../components/Header'; import Header from "../components/Header";
//assets
import bookImage from '../assets/zist11.png';
//Color //Color
import Color from '../../../constants/Colors'; import Color from "../../../constants/Colors";
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
function Videos({getList, list, grades}) { function Videos({ videos, grades }) {
return ( return (
<View style={[tw('w-full px-2 mb-5')]}> <View style={[tw("w-full px-2 mb-5")]}>
<View <View
style={[ style={[
tw( tw("w-full flex flex-col rounded-md pt-2 px-2 overflow-hidden"),
'w-full flex flex-col rounded-md pt-2 px-2 overflow-hidden', ]}
), >
]}> <Header title="دورههای ویدئویی شما" route={"Videos"} />
<Header title="دورههای ویدئویی شما" route={'Videos'} />
<FlatList <FlatList
style={[tw('py-3')]} showsHorizontalScrollIndicator={false}
style={[tw("py-3")]}
horizontal={true} horizontal={true}
inverted={true} inverted={true}
data={list} data={videos}
renderItem={(item) => <Video video={item} />} renderItem={({item}) => <Video video={item} grades={grades} />}
keyExtractor={item => item.name} keyExtractor={(item) => item.id}
/> />
</View> </View>
</View> </View>
); );
} }
const Video = ({book, grades}) => { const Video = ({ video, grades }) => {
return ( return (
<TouchableOpacity style={tw('flex flex-col ml-3')}> <TouchableOpacity style={tw("flex flex-col ml-3")}>
<Image <Image
source={bookImage} source={{uri : `https://dnvn.ir/api/v1/file/${video.fileIds}`}}
style={[ style={[
tw('rounded-md'), tw("rounded-md"),
{ {
height: 160, height: 160,
width: 110, width: 110,
@ -60,28 +52,33 @@ const Video = ({book, grades}) => {
/> />
<Text <Text
style={[ style={[
tw('mt-2 pr-1'), tw("mt-2 pr-1"),
{color: Color.theme1.light.blue6, fontFamily : 'bold', fontSize : width / 36}, {
]}> color: Color.theme1.light.blue6,
{'نام کتاب'} fontFamily: "bold",
fontSize: fontSize.sm,
},
]}
>
{video.name}
</Text> </Text>
<Text <Text
style={[ style={[
tw('mt-1 pr-1'), tw("mt-1 pr-1"),
{color: Color.theme1.light.blue5, fontFamily : 'light', fontSize : width / 40}, {
]}>{`پایه ${'اول'}`}</Text> color: Color.theme1.light.blue5,
<Progress percent={60} alignItems={'items-end'} /> fontFamily: "light",
fontSize: fontSize.xs,
},
]}
>{grades[video.gradeId]}</Text>
<Progress percent={60} alignItems={"items-end"} />
</TouchableOpacity> </TouchableOpacity>
); );
}; };
const mapStateToProps = state => ({ const mapStateToProps = (state) => ({
// list: state.book.list, grades : state.publicApi.grades
// grades : state.publicApi.grades
}); });
export default connect(mapStateToProps, {})(Videos); export default connect(mapStateToProps, {})(Videos);
Videos.defaultProps = {
list: [{name: 1}, {name: 2}, {name: 3}, {name: 4}, {name: 5}],
};

@ -1,6 +1,6 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { publicApi } from "../../redux/actions"; import { blog, book, userProduct } from "../../redux/actions";
import { import {
View, View,
StyleSheet, StyleSheet,
@ -22,9 +22,25 @@ import Drawer from "../../components/Drawer";
// import { SafeAreaView } from 'react-native-safe-area-context'; // import { SafeAreaView } from 'react-native-safe-area-context';
// Within your render function // Within your render function
const Home = ({ isLogi, setHeaderOptions }) => { const Home = ({
blogs,
getBlogs,
books,
getBooks,
videos,
getVideos,
userProducts,
getUserProducts,
}) => {
const [position, setPosition] = useState("100%"); const [position, setPosition] = useState("100%");
useEffect(() => {
getBlogs();
getBooks();
getUserProducts();
// getVideos();
}, []);
const setBoxPosition = () => { const setBoxPosition = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setPosition(position === "100%" ? "0%" : "100%"); setPosition(position === "100%" ? "0%" : "100%");
@ -54,10 +70,10 @@ const Home = ({ isLogi, setHeaderOptions }) => {
contentContainerStyle={styles.contentContainerStyle} contentContainerStyle={styles.contentContainerStyle}
style={[styles.container, tw("w-full flex flex-col")]} style={[styles.container, tw("w-full flex flex-col")]}
> >
<MyBooks /> {userProducts.length > 0 && <MyBooks books={userProducts} />}
<Scroll /> {books.length > 0 && <Scroll books={books} />}
<Videos /> {books.length > 0 && <Videos videos={books} />}
<Blogs /> {blogs.length > 0 && <Blogs blogs={blogs} />}
</ScrollView> </ScrollView>
</SafeAreaView> </SafeAreaView>
); );
@ -78,9 +94,17 @@ const styles = StyleSheet.create({
}); });
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
isLogin: state.user.status, blogs: state.blog.list,
books: state.book.list,
userProducts: state.userProduct.list,
videos: state.product.listVOD,
}); });
const mapDispatchToProps = {}; const mapDispatchToProps = {
getBlogs: blog.list,
getBooks: book.list,
getUserProducts: userProduct.list,
// getVideos: product.listVOD
};
export default connect(mapStateToProps, mapDispatchToProps)(Home); export default connect(mapStateToProps, mapDispatchToProps)(Home);

@ -32,16 +32,16 @@ function Login(props) {
}; };
const submit = async () => { const submit = async () => {
// setLoading(true); setLoading(true);
// if (!checkPhoneNumber()) { if (!checkPhoneNumber()) {
// setLoading(false); setLoading(false);
// return asyncAwesomeAlert("خطا", "شماره وارد شده اشتباه است", { return asyncAwesomeAlert("خطا", "شماره وارد شده اشتباه است", {
// showCancelButton: false, showCancelButton: false,
// }); });
// } }
// props.sendPhoneNumber({cellphone : phone}); props.sendPhoneNumber({cellphone : phone});
props.navigation.navigate("Otp", { phone: '09360467907' }); props.navigation.navigate("Otp", { phone : phone});
// setLoading(false); setLoading(false);
}; };
return ( return (

@ -1,5 +1,4 @@
import { t } from "i18next"; import React, { useState } from "react";
import React from "react";
import { import {
View, View,
Text, Text,
@ -8,24 +7,28 @@ import {
ScrollView, ScrollView,
Pressable, Pressable,
} from "react-native"; } from "react-native";
import { Entypo } from '@expo/vector-icons'; import { Entypo } from "@expo/vector-icons";
import CustomPressable from "../../../components/Pressable"; import CustomPressable from "../../../components/Pressable";
import Description from "./Description"; import Description from "./Description";
import LinkBox from "./LinkBox"; import LinkBox from "./LinkBox";
import Comments from "./Comments"; import Comments from "./Comments";
import Rates from "./Rates"; import Rates from "./Rates";
import tw from "tailwind-react-native-classnames"; import tw from "tailwind-react-native-classnames";
import fontSize from "../../../constants/fontSize";
import { product, userProduct } from "../../../redux/actions";
import { connect } from "react-redux";
const width = Dimensions.get("window").width; const width = Dimensions.get("window").width;
const height = Dimensions.get("window").height; const height = Dimensions.get("window").height;
export default function Book({ product }) { function Book({ book, grades, pushToCart, userId }) {
const [type, setType] = useState(1);
return ( return (
<ScrollView style={[tw.style("flex flex-col flex-1")]}> <ScrollView style={[tw.style("flex flex-col flex-1")]}>
<View style={tw.style("flex flex-row-reverse")}> <View style={tw.style("flex flex-row-reverse")}>
<View style={[tw.style("rounded-md"), { height: 160, width: 110 }]}> <View style={[tw.style("rounded-md"), { height: 160, width: 110 }]}>
<Image <Image
source={{ uri: product.imageUrl }} source={{ uri: `https://dnvn.ir/api/v1/file/${book.fileIds}` }}
style={[tw.style("rounded-md h-full w-full")]} style={[tw.style("rounded-md h-full w-full")]}
/> />
</View> </View>
@ -42,30 +45,30 @@ export default function Book({ product }) {
<Text <Text
style={{ style={{
color: "#05335F", color: "#05335F",
fontSize: width / 18, fontSize: fontSize.xl2,
marginBottom: 5, marginBottom: 5,
fontFamily: "bold", fontFamily: "bold",
}} }}
> >
{product.name} {book.product[type].name}
</Text> </Text>
<Text <Text
style={{ style={{
color: "#196EC0", color: "#196EC0",
fontSize: width / 37, fontSize: fontSize.sm,
fontFamily: "light", fontFamily: "light",
}} }}
> >
{product.grade} {"پایه" + " " + grades[book.gradeId]}
</Text> </Text>
</View> </View>
<Text <Text
style={[ style={[
tw.style("text-right w-full"), tw.style("text-right w-full"),
{ color: "#323232", fontSize: width / 38, fontFamily: "light" }, { color: "#323232", fontSize: fontSize.sm, fontFamily: "light" },
]} ]}
> >
{product.text} {book.text}
</Text> </Text>
</View> </View>
</View> </View>
@ -79,12 +82,12 @@ export default function Book({ product }) {
style={{ style={{
color: "#196EC0", color: "#196EC0",
textAlign: "center", textAlign: "center",
fontSize: width / 37, fontSize: fontSize.sm,
fontFamily: "light", fontFamily: "light",
}} }}
> >
{" "} {" "}
{473 + "\n" + "صفحه"} {book.pagesNum + "\n" + "صفحه"}
</Text> </Text>
</View> </View>
<View <View
@ -95,7 +98,7 @@ export default function Book({ product }) {
style={{ style={{
color: "#196EC0", color: "#196EC0",
textAlign: "center", textAlign: "center",
fontSize: width / 37, fontSize: fontSize.sm,
fontFamily: "light", fontFamily: "light",
}} }}
> >
@ -111,7 +114,7 @@ export default function Book({ product }) {
style={{ style={{
color: "#196EC0", color: "#196EC0",
textAlign: "center", textAlign: "center",
fontSize: width / 37, fontSize: fontSize.sm,
fontFamily: "light", fontFamily: "light",
}} }}
> >
@ -124,7 +127,7 @@ export default function Book({ product }) {
<Text <Text
style={[ style={[
tw.style("w-full text-right font-medium"), tw.style("w-full text-right font-medium"),
{ color: "#196EC0", fontSize: width / 36, fontFamily: "regular" }, { color: "#196EC0", fontSize: fontSize.sm, fontFamily: "regular" },
]} ]}
> >
نسخه محصول را انتخاب کنید نسخه محصول را انتخاب کنید
@ -136,24 +139,33 @@ export default function Book({ product }) {
> >
<CustomPressable <CustomPressable
title={"نسخه فیزیکی"} title={"نسخه فیزیکی"}
backgroundColor="transparent" onPress={() => setType(1)}
color={"#196EC0"} backgroundColor={type === 0 ? "transparent" : "#196EC0"}
color={type === 0 ? "#196EC0" : "white"}
border={{ color: "#196EC0", width: 1 }} border={{ color: "#196EC0", width: 1 }}
width={"49%"} width={"49%"}
/> />
<CustomPressable <CustomPressable
onPress={() => setType(0)}
title={"نسخه دیجیتال"} title={"نسخه دیجیتال"}
backgroundColor="transparent" backgroundColor={type === 1 ? "transparent" : "#196EC0"}
color={"#196EC0"} color={type === 1 ? "#196EC0" : "white"}
border={{ color: "#196EC0", width: 1 }} border={{ color: "#196EC0", width: 1 }}
width={"49%"} width={"49%"}
/> />
<CustomPressable <CustomPressable
title={"خرید با قیمت 245.000 تومان"} title={`خرید با قیمت ${book.product[type].price} تومان`}
backgroundColor="#196EC0" backgroundColor="#196EC0"
color={"white"} color={"white"}
border={{ color: "#196EC0", width: 0 }} border={{ color: "#196EC0", width: 0 }}
width={"65%"} width={"65%"}
onPress={() =>
pushToCart({
productId: book?.product[type]?.id,
userId: userId,
count: 1,
})
}
/> />
<CustomPressable <CustomPressable
title={"مشاهده نمونه"} title={"مشاهده نمونه"}
@ -174,31 +186,53 @@ export default function Book({ product }) {
<Text <Text
style={[ style={[
tw.style(""), tw.style(""),
{ color: "#275077", fontSize: width / 36, fontFamily: "light" }, { color: "#275077", fontSize: fontSize.sm, fontFamily: "light" },
]} ]}
> >
مشاهده دوره ویدئویی این محصول مشاهده دوره ویدئویی این محصول
</Text> </Text>
</Pressable> </Pressable>
</View> </View>
<Description description={product.description} /> {book.product[type].description && (
<Description description={book.description} />
)}
<LinkBox title="مشخصات محصول" path="" /> <LinkBox title="مشخصات محصول" path="" />
<LinkBox title="نقد بررسی و توضیحات تکمیلی محصول" path="" /> <LinkBox title="نقد بررسی و توضیحات تکمیلی محصول" path="" />
<LinkBox title="پرسش و پاسخ" path="" /> <LinkBox title="پرسش و پاسخ" path="" />
<View {product.rates && (
style={tw.style( <View
"flex flex-row-reverse justify-between items-center my-6" style={tw.style(
)} "flex flex-row-reverse justify-between items-center my-6"
> )}
<Text
style={[{ fontSize: width / 36, color: "#275077", fontFamily: "regular"}, tw.style("")]}
> >
امتیازات و نظرات <Text
</Text> style={[
<Entypo name="chevron-small-left" size={20} color="#196EC0" /> {
</View> fontSize: fontSize.sm,
<Rates rates={product.rates} /> color: "#275077",
<Comments comments={product.comments} /> fontFamily: "regular",
},
tw.style(""),
]}
>
امتیازات و نظرات
</Text>
<Entypo name="chevron-small-left" size={20} color="#196EC0" />
</View>
)}
{/* <Rates rates={book.rates} /> */}
<Comments comments={book.comments} />
</ScrollView> </ScrollView>
); );
} }
const mapStateToProps = (state) => ({
userId: state.user.status.id,
});
const mapDispatchToProps = {
pushToCart: userProduct.add,
};
export default connect(mapStateToProps, mapDispatchToProps)(Book);

@ -1,12 +1,14 @@
import React from "react"; import React from "react";
import { View, Text, FlatList, Image, Dimensions } from "react-native"; import { View, Text, FlatList, Image, Dimensions } from "react-native";
import tw from "tailwind-rn"; import tw from "tailwind-rn";
import fontSize from '../../../constants/fontSize';
const width = Dimensions.get("window").width; const width = Dimensions.get("window").width;
export default function Commnets({ comments }) { export default function Commnets({ comments }) {
return ( return (
<FlatList <FlatList
showsHorizontalScrollIndicator={false}
horizontal={true} horizontal={true}
inverted={true} inverted={true}
style={{ marginTop: 20, paddingBottom: 10 }} style={{ marginTop: 20, paddingBottom: 10 }}
@ -33,7 +35,7 @@ const Comment = ({ comment }) => {
/> />
<Text <Text
style={[ style={[
{ fontSize: width / 36, color: "#132F52", fontFamily: "bold" }, { fontSize: fontSize.sm, color: "#132F52", fontFamily: "bold" },
, ,
]} ]}
> >
@ -43,7 +45,7 @@ const Comment = ({ comment }) => {
<View style={tw("flex flex-row items-center")}> <View style={tw("flex flex-row items-center")}>
<Text <Text
style={{ style={{
fontSize: width / 40, fontSize: fontSize.xs,
color: "#196EC0", color: "#196EC0",
fontFamily: "light", fontFamily: "light",
}} }}
@ -60,7 +62,7 @@ const Comment = ({ comment }) => {
></View> ></View>
<Text <Text
style={{ style={{
fontSize: width / 40, fontSize: fontSize.xs,
color: "#196EC0", color: "#196EC0",
fontFamily: "light", fontFamily: "light",
}} }}
@ -71,7 +73,7 @@ const Comment = ({ comment }) => {
</View> </View>
<Text <Text
style={[ style={[
{ fontSize: width / 40, lineHeight: 20, color: "#132F52", fontFamily: "light",}, { fontSize: fontSize.sm, lineHeight: 20, color: "#132F52", fontFamily: "light",},
tw("mt-2"), tw("mt-2"),
]} ]}
> >

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import {View, Text, Dimensions, Image} from 'react-native'; import {View, Text, Dimensions, Image} from 'react-native';
import tw from 'tailwind-react-native-classnames'; import tw from 'tailwind-react-native-classnames';
import fontSize from '../../../constants/fontSize';
import {Entypo} from '@expo/vector-icons'; import {Entypo} from '@expo/vector-icons';
const width = Dimensions.get('window').width; const width = Dimensions.get('window').width;
@ -13,7 +14,7 @@ export default function Description({description}) {
style={tw.style('flex flex-row-reverse justify-between items-center mb-2')}> style={tw.style('flex flex-row-reverse justify-between items-center mb-2')}>
<Text <Text
style={[ style={[
{fontSize: width / 36, color: '#275077', fontFamily: 'regular'}, {fontSize: fontSize.sm, color: '#275077', fontFamily: 'regular'},
tw.style(''), tw.style(''),
]}> ]}>
توضیحات توضیحات
@ -23,7 +24,7 @@ export default function Description({description}) {
<Text <Text
style={[ style={[
tw.style('w-full text-right mt-2'), tw.style('w-full text-right mt-2'),
{fontSize: width / 36, color: '#323232bb', lineHeight: 20, fontFamily : 'light'}, {fontSize: fontSize.sm, color: '#323232bb', lineHeight: 20, fontFamily : 'light'},
]}> ]}>
{description} {description}
</Text> </Text>

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import {View, Text, Dimensions, Image} from 'react-native'; import {View, Text, Dimensions, Image} from 'react-native';
import tw from 'tailwind-react-native-classnames'; import tw from 'tailwind-react-native-classnames';
import fontSize from '../../../constants/fontSize';
import {Entypo} from '@expo/vector-icons'; import {Entypo} from '@expo/vector-icons';
const width = Dimensions.get('window').width; const width = Dimensions.get('window').width;
@ -17,7 +18,7 @@ export default function Description({title, path}) {
]}> ]}>
<Text <Text
style={[ style={[
{fontSize: width / 36, color: '#275077', fontFamily: 'regular'}, {fontSize: fontSize.sm, color: '#275077', fontFamily: 'regular'},
tw.style(''), tw.style(''),
]}> ]}>
{title} {title}

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import {View, Text, Dimensions} from 'react-native'; import {View, Text, Dimensions} from 'react-native';
import tw from 'tailwind-react-native-classnames'; import tw from 'tailwind-react-native-classnames';
import fontSize from '../../../constants/fontSize';
const width = Dimensions.get('window').width; const width = Dimensions.get('window').width;
@ -14,11 +15,11 @@ export default function Rates({rates}) {
]}> ]}>
<Text <Text
style={[ style={[
{fontSize: width / 13, color: '#05335F', fontFamily: 'bold'}, {fontSize: fontSize.xl6, color: '#05335F', fontFamily: 'bold'},
]}> ]}>
{rates.mid} {rates.mid}
</Text> </Text>
<Text style={{fontSize: width / 36, color: '#707070', fontFamily: 'light'}}> <Text style={{fontSize: fontSize.sm, color: '#707070', fontFamily: 'light'}}>
{'از' + ' ' + rates.allRates + ' ' + 'نفر'} {'از' + ' ' + rates.allRates + ' ' + 'نفر'}
</Text> </Text>
</View> </View>
@ -34,7 +35,7 @@ export default function Rates({rates}) {
const Progress = ({data}) => { const Progress = ({data}) => {
return ( return (
<View style={[tw.style('flex flex-1 flex-row items-center py-0.5')]}> <View style={[tw.style('flex flex-1 flex-row items-center py-0.5')]}>
<Text style={{fontSize: width / 36, color: '#05335F', fontFamily: 'regular'}}>{data.name}</Text> <Text style={{fontSize: fontSize.sm, color: '#05335F', fontFamily: 'regular'}}>{data.name}</Text>
<View <View
style={[ style={[
tw.style('rounded-md ml-2 flex-1'), tw.style('rounded-md ml-2 flex-1'),
@ -48,7 +49,7 @@ const Progress = ({data}) => {
</View> </View>
<Text <Text
style={{ style={{
fontSize: width / 40, fontSize: fontSize.xs,
fontFamily: 'light', fontFamily: 'light',
width: width / 7.5, width: width / 7.5,
textAlign: 'center', textAlign: 'center',

@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useState, useEffect } from "react";
import { import {
View, View,
StyleSheet, StyleSheet,
@ -11,57 +11,23 @@ import {
import Book from "./components/Book"; import Book from "./components/Book";
import Video from "./components/Video"; import Video from "./components/Video";
import { connect } from "react-redux"; import { connect } from "react-redux";
import {book} from "../../redux/actions";
import userImage from "./assets/user.png"; import userImage from "./assets/user.png";
import poster from "./assets/poster.png"; import poster from "./assets/poster.png";
import Navbar from "../../components/Navbar"; import Navbar from "../../components/Navbar";
import Drawer from "../../components/Drawer"; import Drawer from "../../components/Drawer";
function Product({ function Product({
product = { route,
type: "کتاب ها", book,
name: "ریاضی", getBook,
price: "145.000 تومان", grades,
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: [
{
id: 0,
name: "سورنا عابدی",
imageUrl: userImage,
vote: 4,
date: new Date(),
message:
"خالد حسینی تو رمان باد بادک باز مینویسه : ﻣﺮﺩ ﺁﻫﺴﺘﻪ ﺩﺭ ﮔﻮﺵ ﻓﺮﺯﻧﺪ ﺗﺎﺯﻩ ﺑﻪ ﺑﻠﻮﻍ ﺭﺳﯿﺪﻩ ﺍﺵ ﺑﺮﺍﯼ ﭘﻨﺪ ﭼﻨﯿﻦ ﻧﺠﻮﺍ ﮐﺮﺩ : ” ﭘﺴﺮﻡ ﺩﺭ ﺯﻧﺪﮔﯽ ﻫﺮﮔﺰ ﺩﺯﺩﯼ ﻧﮑﻦ ” ﭘﺴﺮ ﻣﺘﻌﺠﺐ ﻭ ﻣﺒﻬﻮﺕ ﺑﻪ ﭘﺪﺭ ﻧﮕﺎﻩ ﮐﺮﺩ ﺑﺪﯾﻦ ﻣﻌﻨﺎ ﮐﻪ ﺍﻭ ﻫﺮﮔﺰ ﺩﺳﺖ ﮐﺞ ﻧﺪﺍﺷﺘﻪ ﭘﺪﺭ ﺑﻪ ﻧﮕﺎﻩ ﻣﺘﻌﺠﺐ ﻓﺮﺯﻧﺪ ﻟﺒﺨﻨﺪﯼ ﺯﺩ ﻭ ﺍﺩﺍﻣﻪ ",
},
{
id: 1,
name: "سورنا عابدی",
imageUrl: userImage,
vote: 4,
date: new Date(),
message:
"خالد حسینی تو رمان باد بادک باز مینویسه : ﻣﺮﺩ ﺁﻫﺴﺘﻪ ﺩﺭ ﮔﻮﺵ ﻓﺮﺯﻧﺪ ﺗﺎﺯﻩ ﺑﻪ ﺑﻠﻮﻍ ﺭﺳﯿﺪﻩ ﺍﺵ ﺑﺮﺍﯼ ﭘﻨﺪ ﭼﻨﯿﻦ ﻧﺠﻮﺍ ﮐﺮﺩ : ” ﭘﺴﺮﻡ ﺩﺭ ﺯﻧﺪﮔﯽ ﻫﺮﮔﺰ ﺩﺯﺩﯼ ﻧﮑﻦ ” ﭘﺴﺮ ﻣﺘﻌﺠﺐ ﻭ ﻣﺒﻬﻮﺕ ﺑﻪ ﭘﺪﺭ ﻧﮕﺎﻩ ﮐﺮﺩ ﺑﺪﯾﻦ ﻣﻌﻨﺎ ﮐﻪ ﺍﻭ ﻫﺮﮔﺰ ﺩﺳﺖ ﮐﺞ ﻧﺪﺍﺷﺘﻪ ﭘﺪﺭ ﺑﻪ ﻧﮕﺎﻩ ﻣﺘﻌﺠﺐ ﻓﺮﺯﻧﺪ ﻟﺒﺨﻨﺪﯼ ﺯﺩ ﻭ ﺍﺩﺍﻣﻪ ",
},
],
},
}) { }) {
const [position, setPosition] = useState("100%"); const [position, setPosition] = useState("100%");
useEffect(() => {
getBook({id : route.params.id});
},[]);
const setBoxPosition = () => { const setBoxPosition = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setPosition(position === "100%" ? "0%" : "100%"); setPosition(position === "100%" ? "0%" : "100%");
@ -90,11 +56,12 @@ function Product({
contentContainerStyle={styles.contentContainerStyle} contentContainerStyle={styles.contentContainerStyle}
style={styles.container} style={styles.container}
> >
{product.type === "ویدئوها" ? (
<Video product={product} /> {book && (route.params.type === 'video' ? (
<Video />
) : ( ) : (
<Book product={product} /> <Book book={book} grades={grades} />
)} ))}
</ScrollView> </ScrollView>
</SafeAreaView> </SafeAreaView>
); );
@ -112,4 +79,14 @@ const styles = StyleSheet.create({
paddingHorizontal: 16, paddingHorizontal: 16,
}, },
}); });
export default Product;
const mapStateToProps = (state) => ({
book : state.book.info,
grades : state.publicApi.grades
});
const mapDispatchToProps = {
getBook : book.info
}
export default connect(mapStateToProps, mapDispatchToProps)(Product);

@ -2,23 +2,16 @@ import React from "react";
import { View, Image, Text, Dimensions, Pressable } from "react-native"; import { View, Image, Text, Dimensions, Pressable } from "react-native";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
import tw from "tailwind-react-native-classnames"; import tw from "tailwind-react-native-classnames";
import fontSize from '../../../constants/fontSize';
const width = Dimensions.get("window").width; const width = Dimensions.get("window").width;
const height = Dimensions.get("window").height;
function Book({ function Book({book, grades, type}) {
item = {
name: "ریاضی",
price: "145.000 تومان",
grade: "4",
imageUrl: "https://dnvn.ir/api/v1/file/2105",
},
}) {
const navigation = useNavigation(); const navigation = useNavigation();
return ( return (
<Pressable <Pressable
style={[ style={[
{ {
width: width / 2 - 20, width: width / 2 - 25,
// shadowColor : "#000", // shadowColor : "#000",
// shadowOffset : {width : 0, height : 2}, // shadowOffset : {width : 0, height : 2},
// shadowRadius : 20, // shadowRadius : 20,
@ -27,34 +20,34 @@ function Book({
borderWidth: 1, borderWidth: 1,
borderColor: "#ddd", borderColor: "#ddd",
}, },
tw.style("flex flex-col items-end p-2 rounded-md"), tw.style("flex flex-col items-end px-2 pt-2 rounded-md"),
]} ]}
onPress={() => navigation.navigate("Product")} onPress={() => navigation.navigate("Product", { id : book.id, type : 'book'})}
> >
<Image <Image
source={{ uri: item.imageUrl }} source={{ uri: `https://dnvn.ir/api/v1/file/${book.fileIds}` }}
style={[tw.style("w-full rounded-md"), { height: height / 3.8 }]} style={[tw.style("w-full rounded-md"), { height: (width / 2 - 25) * 16 / 14 }]}
/> />
<Text <Text
style={{ style={{
fontSize: width / 31, fontSize: fontSize.lg,
marginTop: 5, marginTop: 5,
color: "#05335F", color: "#05335F",
fontFamily: "bold", fontFamily: "bold",
}} }}
> >
{item.name} { (type === 1 ? 'کتاب فیزیکی' : 'کتاب دیجیتال') + ' ' + book.name}
</Text> </Text>
<Text style={{ color: "#196EC0", fontSize: width / 37, marginTop: 5, fontFamily : 'light' }}> <Text style={{ color: "#196EC0", fontSize: fontSize.sm, marginTop: 5, fontFamily : 'light' }}>
{"پایه" + " " + item.grade} {'پایه' + ' ' + grades[book.gradeId]}
</Text> </Text>
<Text <Text
style={[ style={[
tw.style("w-full text-center"), tw.style("w-full text-center mb-1"),
{ marginTop: 10, color: "#132F52", fontFamily : 'bold', fontSize: width / 31 }, { marginTop: 10, color: "#132F52", fontFamily : 'bold', fontSize: fontSize.base },
]} ]}
> >
{item.price} {( type=== 1 ? book.product[1].price : book.product[0].price ) + ' ' + 'تومان'}
</Text> </Text>
</Pressable> </Pressable>
); );

@ -2,6 +2,7 @@ import React from "react";
import { View, Image, Text, Dimensions, Pressable } from "react-native"; import { View, Image, Text, Dimensions, Pressable } from "react-native";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
import tw from "tailwind-react-native-classnames"; import tw from "tailwind-react-native-classnames";
import fontSize from '../../../constants/fontSize';
import posterImage from "../assets/poster.png"; import posterImage from "../assets/poster.png";
const width = Dimensions.get("window").width; const width = Dimensions.get("window").width;
@ -56,7 +57,7 @@ function Video({
</View> </View>
<Text <Text
style={{ style={{
fontSize: width / 31, fontSize: fontSize.lg,
marginTop: 5, marginTop: 5,
color: "#05335F", color: "#05335F",
fontFamily: "bold", fontFamily: "bold",
@ -74,8 +75,8 @@ function Video({
{ {
marginTop: 10, marginTop: 10,
color: "#132F52", color: "#132F52",
fontFamily: "light", fontFamily: "bold",
fontSize: width / 37, fontSize: fontSize.base,
}, },
]} ]}
> >
@ -85,7 +86,7 @@ function Video({
style={{ style={{
color: "#196EC0", color: "#196EC0",
fontFamily: "light", fontFamily: "light",
fontSize: width / 37, fontSize: fontSize.sm,
marginTop: 5, marginTop: 5,
}} }}
> >

@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useState, useEffect } from "react";
import { import {
View, View,
@ -9,26 +9,27 @@ import {
StatusBar, StatusBar,
LayoutAnimation, LayoutAnimation,
} from "react-native"; } from "react-native";
import tw from "tailwind-react-native-classnames";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { book } from "../../redux/actions";
import tw from "tailwind-react-native-classnames";
import Book from "./components/Book"; import Book from "./components/Book";
import Video from "./components/Video"; import Video from "./components/Video";
import Search from "../../components/Search"; import Search from "../../components/Search";
import Select from "../../components/Select"; import Select from "../../components/Select";
import Navbar from "../../components/Navbar";
import Drawer from "../../components/Drawer"; import Drawer from "../../components/Drawer";
function Products({ grades, productTypes }) { function Products({ grades, productTypes, books }) {
const [position, setPosition] = useState("100%"); const [position, setPosition] = useState("100%");
const [productType, setProductType] = useState("کتاب فیزیکی");
const [grade, setGrade] = useState("");
const [search, setSearch] = useState("");
useEffect(() => {}, []);
const setBoxPosition = () => { const setBoxPosition = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setPosition(position === "100%" ? "0%" : "100%"); setPosition(position === "100%" ? "0%" : "100%");
}; };
const [productType, setProductType] = useState("");
const [grade, setGrade] = useState("");
const [search, setSearch] = useState("");
const onChange = (name, value) => {}; const onChange = (name, value) => {};
return ( return (
<SafeAreaView <SafeAreaView
@ -73,13 +74,14 @@ function Products({ grades, productTypes }) {
"flex flex-1 w-full py-5 flex-row flex-wrap justify-between bg-white" "flex flex-1 w-full py-5 flex-row flex-wrap justify-between bg-white"
)} )}
> >
{[0, 1, 2, 3, 4, 5, 6, 7].map((item, index) => {productType === "کتاب فیزیکی" &&
productType === "ویدئوها" ? ( books.map((book, index) => (
<Video key={index} /> <Book book={book} key={index} grades={grades} type={1} />
) : ( ))}
<Book key={index} /> {productType === "کتاب دیجیتال" &&
) books.map((book, index) => (
)} <Book book={book} key={index} grades={grades} type={0} />
))}
</View> </View>
</ScrollView> </ScrollView>
</SafeAreaView> </SafeAreaView>
@ -99,23 +101,17 @@ const styles = StyleSheet.create({
}, },
}); });
export default Products; const mapStateToProps = (state) => ({
grades: state.publicApi.grades,
books: state.book.list,
});
const mapDispatchToProps = {
getBooks: book.list,
};
export default connect(mapStateToProps, mapDispatchToProps)(Products);
Products.defaultProps = { Products.defaultProps = {
grades: [
"پیش دبستان",
"اول",
"دوم",
"سوم",
"چهارم",
"پنجم",
"ششم",
"هفتم",
"هشتم",
"نهم",
"دهم",
"یازدهم",
"دوازدهم",
],
productTypes: ["کتاب فیزیکی", "کتاب دیجیتال", "ویدئوها", "اشتراک"], productTypes: ["کتاب فیزیکی", "کتاب دیجیتال", "ویدئوها", "اشتراک"],
}; };

@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import { View, Text, Dimensions } from "react-native"; import { View, Text, Dimensions } from "react-native";
import tw from "tailwind-rn"; import tw from "tailwind-rn";
import MusicPlayer from "../../../components/MusicPlayer"; // import MusicPlayer from "../../../components/MusicPlayer";
const { width } = Dimensions.get("window"); const { width } = Dimensions.get("window");
@ -16,7 +16,7 @@ export default function Voice({ name, file }) {
> >
{name} {name}
</Text> </Text>
<MusicPlayer /> {/* <MusicPlayer /> */}
</View> </View>
); );
} }

@ -45,7 +45,7 @@ export default function Scan({}) {
<ImageBackground <ImageBackground
source={laptopImage} source={laptopImage}
resizeMode="cover" resizeMode="cover"
style={[tw("w-full"), { height: height - 78 }]} style={[tw("w-full"), { height: height }]}
> >
<View <View
style={tw( style={tw(

@ -60,5 +60,5 @@ const styles = StyleSheet.create({
}); });
QR.defaultProps = { QR.defaultProps = {
page: "scan", page: "content",
}; };

@ -7,10 +7,18 @@ import {
Dimensions, Dimensions,
KeyboardAvoidingView, KeyboardAvoidingView,
} from "react-native"; } from "react-native";
import { connect } from "react-redux";
import { userFactor } from "../../../redux/actions";
import tw from "tailwind-react-native-classnames"; import tw from "tailwind-react-native-classnames";
const width = Dimensions.get("window").width; const width = Dimensions.get("window").width;
export default function Code({}) { function Code({ codeId, setCodeId, userId, factorId }) {
const [value, setValue] = React.useState(codeId || "");
const setOff = () => {
setCodeId({ offCodeValue: value, userId: userId, id: factorId });
};
return ( return (
<KeyboardAvoidingView <KeyboardAvoidingView
enabled enabled
@ -22,6 +30,7 @@ export default function Code({}) {
)} )}
> >
<TextInput <TextInput
onChaneText={(text) => setValue(text)}
style={[ style={[
tw.style("border-0 flex-1 text-right pr-4"), tw.style("border-0 flex-1 text-right pr-4"),
{ fontSize: width / 36, fontFamily: "light" }, { fontSize: width / 36, fontFamily: "light" },
@ -30,6 +39,7 @@ export default function Code({}) {
placeholderTextColor="#707070" placeholderTextColor="#707070"
/> />
<Pressable <Pressable
onClick={() => setOff()}
style={[ style={[
tw.style("py-2 px-5"), tw.style("py-2 px-5"),
{ {
@ -52,3 +62,15 @@ export default function Code({}) {
</KeyboardAvoidingView> </KeyboardAvoidingView>
); );
} }
const mapStateToProps = (state) => ({
codeId: state.userFactor.info?.codeId,
userId: state.user.status.id,
factorId: state.userFactor.info?.id,
});
const mapDispatchToProps = {
setCodeId: userFactor.update,
};
export default connect(mapStateToProps, mapDispatchToProps)(Code);

@ -1,5 +1,7 @@
import React from "react"; import React from "react";
import { View, Text, Image, Dimensions, Pressable } from "react-native"; import { View, Text, Image, Dimensions, Pressable } from "react-native";
import { connect } from "react-redux";
import { userProduct } from "../../../redux/actions";
import { AntDesign } from "@expo/vector-icons"; import { AntDesign } from "@expo/vector-icons";
import tw from "tailwind-react-native-classnames"; import tw from "tailwind-react-native-classnames";
import bookImage from "../assets/book.png"; import bookImage from "../assets/book.png";
@ -8,7 +10,7 @@ import deleteIcon from "../assets/delete.png";
const width = Dimensions.get("window").width; const width = Dimensions.get("window").width;
const height = Dimensions.get("window").height; const height = Dimensions.get("window").height;
export default function Product({ product }) { function Product({ product, grades, pushToCart }) {
return ( return (
<View <View
style={[ style={[
@ -18,7 +20,9 @@ export default function Product({ product }) {
> >
<View style={tw.style("flex flex-row-reverse")}> <View style={tw.style("flex flex-row-reverse")}>
<Image <Image
source={bookImage} source={{
uri: "https://dnvn.ir/api/v1/file/" + product.product.book.fileIds,
}}
style={[tw.style("rounded-md"), { width: 60, height: 90 }]} style={[tw.style("rounded-md"), { width: 60, height: 90 }]}
/> />
<View style={tw.style("flex flex-col items-end pr-2")}> <View style={tw.style("flex flex-col items-end pr-2")}>
@ -30,7 +34,7 @@ export default function Product({ product }) {
fontFamily: "bold", fontFamily: "bold",
}} }}
> >
علوم اجتماعی {product.product.book.name}
</Text> </Text>
<Text <Text
style={{ style={{
@ -40,7 +44,7 @@ export default function Product({ product }) {
fontFamily: "light", fontFamily: "light",
}} }}
> >
پایه دوم {"پایه" + " " + grades[product.product.book.gradeId]}
</Text> </Text>
<Text <Text
style={{ style={{
@ -49,15 +53,37 @@ export default function Product({ product }) {
fontFamily: "light", fontFamily: "light",
}} }}
> >
نسخه فیزیکی {product.productType === 2 ? "نسخه فیزیکی" : "نسخه دیجیتال"}
</Text> </Text>
</View> </View>
</View> </View>
<View style={tw.style("flex flex-col justify-between items-start")}> <View style={tw.style("flex flex-col justify-between items-start")}>
<AntDesign name="close" size={20} color="black" /> <AntDesign
name="close"
size={20}
color="black"
onPress={() =>
pushToCart(
{
productId: product?.productId,
userId: product?.userId,
count: product?.productType === 1 ? -1 : -product?.count,
},
{},
{ id: product?.factorId }
)
}
/>
<View style={tw.style("flex flex-col items-center mt-2")}> <View style={tw.style("flex flex-col items-center mt-2")}>
<View style={tw.style("flex flex-row-reverse items-center mb-3")}> <View style={tw.style("flex flex-row-reverse items-center mb-3")}>
<Pressable <Pressable
onPress={() =>
pushToCart({
productId: product?.productId,
userId: product?.userId,
count: 1,
})
}
style={[ style={[
tw.style( tw.style(
"rounded-md py-0 px-2 flex flex-row justify-center items-center border" "rounded-md py-0 px-2 flex flex-row justify-center items-center border"
@ -87,9 +113,16 @@ export default function Product({ product }) {
}, },
]} ]}
> >
1 {product.count}
</Text> </Text>
<Pressable <Pressable
onPress={() =>
pushToCart({
productId: product?.productId,
userId: product?.userId,
count: -1,
})
}
style={[ style={[
tw.style( tw.style(
"rounded-md py-0 px-2.5 flex flex-row justify-center items-center border" "rounded-md py-0 px-2.5 flex flex-row justify-center items-center border"
@ -110,11 +143,23 @@ export default function Product({ product }) {
</Text> </Text>
</Pressable> </Pressable>
</View> </View>
<Text style={[tw.style("", { fontSize: width / 25, fontFamily: "bold"})]}> <Text
145.000 style={[tw.style("", { fontSize: width / 25, fontFamily: "bold" })]}
>
{product.product.price + ' ' + 'تومان'}
</Text> </Text>
</View> </View>
</View> </View>
</View> </View>
); );
} }
const mapStateToProps = (state) => ({
grades: state.publicApi.grades,
});
const mapDispatchToProps = {
pushToCart: userProduct.add,
};
export default connect(mapStateToProps, mapDispatchToProps)(Product);

@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useState, useEffect } from "react";
import { import {
View, View,
Text, Text,
@ -11,6 +11,8 @@ import {
StatusBar, StatusBar,
LayoutAnimation, LayoutAnimation,
} from "react-native"; } from "react-native";
import { connect } from "react-redux";
import { userProduct, userFactor, publicApi } from "../../redux/actions";
import { Ionicons } from "@expo/vector-icons"; import { Ionicons } from "@expo/vector-icons";
import Product from "./components/Product"; import Product from "./components/Product";
import Code from "./components/Code"; import Code from "./components/Code";
@ -19,8 +21,6 @@ import Navbar from "../../components/Navbar";
import Drawer from "../../components/Drawer"; import Drawer from "../../components/Drawer";
import tw from "tailwind-react-native-classnames"; import tw from "tailwind-react-native-classnames";
import { connect } from "react-redux";
const width = Dimensions.get("window").width; const width = Dimensions.get("window").width;
const PriceStatus = ({ name, value, type }) => { const PriceStatus = ({ name, value, type }) => {
@ -50,9 +50,14 @@ const PriceStatus = ({ name, value, type }) => {
); );
}; };
function ShoppingCart({}) { function ShoppingCart({ userId, list, factorInfo, getList, getFactorInfo }) {
const [position, setPosition] = useState("100%"); const [position, setPosition] = useState("100%");
useEffect(() => {
getList();
getFactorInfo({ userId });
}, []);
const setBoxPosition = () => { const setBoxPosition = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setPosition(position === "100%" ? "0%" : "100%"); setPosition(position === "100%" ? "0%" : "100%");
@ -74,7 +79,7 @@ function ShoppingCart({}) {
title: "سبد خرید", title: "سبد خرید",
bookmark: false, bookmark: false,
qr: false, qr: false,
back: true, back: false,
}} }}
/> />
<Drawer setBoxPosition={setBoxPosition} position={position} /> <Drawer setBoxPosition={setBoxPosition} position={position} />
@ -82,7 +87,7 @@ function ShoppingCart({}) {
contentContainerStyle={styles.contentContainerStyle} contentContainerStyle={styles.contentContainerStyle}
style={styles.container} style={styles.container}
> >
{[0, 1].map((product, index) => ( {list.length > 0 && list.map((product, index) => (
<Product key={index} product={product} /> <Product key={index} product={product} />
))} ))}
<Code /> <Code />
@ -93,13 +98,17 @@ function ShoppingCart({}) {
> >
<PriceStatus <PriceStatus
name="مبلغ سبد خرید" name="مبلغ سبد خرید"
value="265000 تومان" value={factorInfo?.sumPrice}
type="normal" type="normal"
/> />
<PriceStatus name="میزان تخفیف" value="0 تومان" type="error" /> <PriceStatus
name="میزان تخفیف"
value={factorInfo?.offPrice}
type="error"
/>
<PriceStatus <PriceStatus
name="مالیات بر ارزش افزوده" name="مالیات بر ارزش افزوده"
value="0 تومان" value={factorInfo?.sumPrice * 0.009}
type="error" type="error"
/> />
</View> </View>
@ -122,7 +131,7 @@ function ShoppingCart({}) {
{ fontSize: width / 31, color: "#246E8A", fontFamily: "bold" }, { fontSize: width / 31, color: "#246E8A", fontFamily: "bold" },
]} ]}
> >
235.000 تومان {factorInfo?.payPrice + ' ' + 'تومان'}
</Text> </Text>
</View> </View>
<Pressable <Pressable
@ -155,7 +164,22 @@ function ShoppingCart({}) {
); );
} }
export default ShoppingCart; const mapStateToProps = (state) => ({
list: state.userProduct.list,
payPrice: state.userProduct.sum,
factorInfo: state.userFactor.info,
userId: state.user.status.id,
hasPhysical: state.userProduct.hasPhysical,
});
const mapDispatchToProps = {
getList: userProduct.list,
getInfo: userProduct.info,
getFactorInfo: userFactor.info,
payFactor: userFactor.payment,
};
export default connect(mapStateToProps, mapDispatchToProps)(ShoppingCart);
const styles = StyleSheet.create({ const styles = StyleSheet.create({
contentContainerStyle: { contentContainerStyle: {

@ -5,17 +5,17 @@ import Logo from "../../assets/images/logo.png";
const { width, height } = Dimensions.get("window"); const { width, height } = Dimensions.get("window");
function Splash({ navigation, isLogin}) { function Splash({ navigation, isLogin }) {
useEffect(() => { useEffect(() => {
setTimeout(() => { if (isLogin !== null) {
!isLogin setTimeout(() => {
? navigation.navigate('Login') isLogin === false
: navigation.navigate('Root'); ? navigation.navigate("Login")
}, 2000); : navigation.navigate("Root");
}, 3000);
}
}, [isLogin]); }, [isLogin]);
return ( return (
<View style={{ justifyContent: "center", alignItems: "center", flex: 1 }}> <View style={{ justifyContent: "center", alignItems: "center", flex: 1 }}>
<Image <Image

@ -6,14 +6,22 @@ import {
Pressable, Pressable,
TouchableOpacity, TouchableOpacity,
} from "react-native"; } from "react-native";
import { connect } from "react-redux";
import { publicApi } from "../../../redux/actions";
import tw from "tailwind-rn"; import tw from "tailwind-rn";
import fontSize from "../../../constants/fontSize";
import Colors from "../../../constants/Colors"; import Colors from "../../../constants/Colors";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
const { width, height } = Dimensions.get("window");
const Season = ({ season }) => { const duration = (value) => {
const minute = value % 60;
const hour = Math.round(value / 60);
return (hour > 0 ? hour + " " + "ساعت" : "") + " " + minute + " " + "دقیقه";
};
const Season = ({ season, toggle, activeSeason, realSeasons, seasonName }) => {
// const [selectedSeason, setSelectedSeason] = useState(null);
const navigation = useNavigation(); const navigation = useNavigation();
const [activeSeason, setActiveSeason] = useState(null);
const Unit = ({ unit }) => { const Unit = ({ unit }) => {
return ( return (
<View <View
@ -37,7 +45,7 @@ const Season = ({ season }) => {
style={[ style={[
{ {
fontFamily: "regular", fontFamily: "regular",
fontSize: width / 34, fontSize: fontSize.sm,
color: Colors.theme1.light.blue5, color: Colors.theme1.light.blue5,
}, },
]} ]}
@ -48,16 +56,16 @@ const Season = ({ season }) => {
style={[ style={[
{ {
fontFamily: "regular", fontFamily: "regular",
fontSize: width / 36, fontSize: fontSize.sm,
color: Colors.theme1.light.blue5, color: Colors.theme1.light.blue5,
}, },
]} ]}
> >
{unit.duration} {duration(unit.duration)}
</Text> </Text>
</View> </View>
<View style={[tw("w-full flex flex-row-reverse")]}> <View style={[tw("w-full flex flex-row-reverse")]}>
{unit.play && ( {1 && (
<Pressable <Pressable
style={[ style={[
tw("flex flex-1 flex-row items-center py-1.5 px-2"), tw("flex flex-1 flex-row items-center py-1.5 px-2"),
@ -66,14 +74,20 @@ const Season = ({ season }) => {
borderColor: Colors.theme1.light.blue3, borderColor: Colors.theme1.light.blue3,
}, },
]} ]}
onPress={() => navigation.navigate("VideoDisplay")} onPress={() =>
navigation.navigate("VideoDisplay", {
season : season,
unit : unit,
name : seasonName
})
}
> >
<Text <Text
style={{ style={{
width: "100%", width: "100%",
textAlign: "center", textAlign: "center",
fontFamily: "regular", fontFamily: "regular",
fontSize: width / 34, fontSize: fontSize.sm,
color: Colors.theme1.light.blue5, color: Colors.theme1.light.blue5,
}} }}
> >
@ -81,7 +95,7 @@ const Season = ({ season }) => {
</Text> </Text>
</Pressable> </Pressable>
)} )}
{unit.download && ( {1 && (
<Pressable <Pressable
style={tw("flex flex-1 flex-row items-center py-1.5 px-2")} style={tw("flex flex-1 flex-row items-center py-1.5 px-2")}
> >
@ -90,7 +104,7 @@ const Season = ({ season }) => {
width: "100%", width: "100%",
textAlign: "center", textAlign: "center",
fontFamily: "regular", fontFamily: "regular",
fontSize: width / 34, fontSize: fontSize.sm,
color: Colors.theme1.light.blue5, color: Colors.theme1.light.blue5,
}} }}
> >
@ -111,38 +125,49 @@ const Season = ({ season }) => {
), ),
{ backgroundColor: Colors.theme1.light.blue5 }, { backgroundColor: Colors.theme1.light.blue5 },
]} ]}
onPress={() => onPress={() => toggle(season[0].categoryId)}
setActiveSeason(season.name === activeSeason ? null : season.name)
}
> >
<Text <Text
style={[ style={[
{ {
fontFamily: "regular", fontFamily: "regular",
fontSize: width / 34, fontSize: fontSize.sm,
color: "white", color: "white",
}, },
]} ]}
> >
{season.name} {
realSeasons.filter((item) => item.id === season[0].categoryId)[0]
.name
}
</Text> </Text>
<Text {/* <Text
style={[ style={[
{ {
fontFamily: "regular", fontFamily: "regular",
fontSize: width / 36, fontSize: fontSize.sm,
color: "white", color: "white",
}, },
]} ]}
> >
{season.duration} {season.duration}
</Text> </Text> */}
</TouchableOpacity> </TouchableOpacity>
{season.name === activeSeason && {season[0].categoryId === activeSeason &&
season.units.map((unit, index) => <Unit unit={unit} key={index} />)} season.map((unit, index) => <Unit unit={unit} key={index} />)}
</View> </View>
); );
}; };
export default Season; const mapStateToProps = (state) => ({
activeSeason: state.publicApi.activeCategory,
realSeasons: state.publicApi.bookInfo?.categories,
vodDuration: state.publicApi.bookInfo?.vodDuration,
});
const mapDispatchToProps = {
toggle: publicApi.activeCategory,
};
export default connect(mapStateToProps, mapDispatchToProps)(Season);

@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useState, useEffect } from "react";
import { import {
View, View,
StyleSheet, StyleSheet,
@ -11,54 +11,29 @@ import {
Text, Text,
} from "react-native"; } from "react-native";
import { connect } from "react-redux"; import { connect } from "react-redux";
import userImage from "./assets/user.png"; import {publicApi} from '../../redux/actions';
import poster from "./assets/poster.png";
import Navbar from "../../components/Navbar"; import Navbar from "../../components/Navbar";
import Drawer from "../../components/Drawer"; import Drawer from "../../components/Drawer";
import Divider from "../../components/Divider"; import Divider from "../../components/Divider";
import Season from "./components/Season"; import Season from "./components/Season";
import tw from "tailwind-rn"; import tw from "tailwind-rn";
import fontSize from '../../constants/fontSize';
const { height, width } = Dimensions.get("window"); const { height, width } = Dimensions.get("window");
function Product({ function Product({
product = { route,
type: "کتاب ها", getBook,
name: "ریاضی", book,
price: "145.000 تومان", seasons,
imageUrl: "https://dnvn.ir/api/v1/file/2105", grades,
poster: poster,
grade: "پایه هفتم ابتدایی",
seasons: [
{
name: "فصل اول: مباحث جوشش مواد مذاب در مرکز زمین",
duration: "2:30:13",
units: [
{
name: "مقدمه جالب توجه نویسنده کتاب برای شما",
duration: "14:30",
download: true,
play: true,
},
{
name: "چگونگی ساخت نیروگاههای برقی ",
duration: "14:30",
download: false,
play: true,
},
{
name: "آیا گوگل از ما دزدی میکند ؟",
duration: "14:30",
download: true,
play: true,
},
],
},
],
},
}) { }) {
const [position, setPosition] = useState("100%"); const [position, setPosition] = useState("100%");
useEffect(() => {
getBook({bookId : route.params.id });
},[]);
const setBoxPosition = () => { const setBoxPosition = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setPosition(position === "100%" ? "0%" : "100%"); setPosition(position === "100%" ? "0%" : "100%");
@ -97,11 +72,11 @@ function Product({
]} ]}
> >
<Image <Image
source={product.poster} source={{uri : `https://dnvn.ir/api/v1/file/${book?.fileIds}`}}
style={tw("w-full rounded-md h-full absolute left-0 top-0")} style={tw("w-full rounded-md h-full absolute left-0 top-0")}
/> />
<Image <Image
source={{ uri: product.imageUrl }} source={{ uri: `https://dnvn.ir/api/v1/file/${book?.fileIds}` }}
style={[ style={[
tw("rounded-md h-full rounded-md ml-2"), tw("rounded-md h-full rounded-md ml-2"),
{ width: 70, height: 100 }, { width: 70, height: 100 },
@ -121,30 +96,30 @@ function Product({
style={{ style={{
marginTop: 5, marginTop: 5,
color: "#05335F", color: "#05335F",
fontSize: width / 21, fontSize: fontSize.xl,
marginBottom: 0, marginBottom: 0,
fontFamily: "bold", fontFamily: "bold",
}} }}
> >
{product.name} {book?.name}
</Text> </Text>
<Text <Text
style={{ style={{
color: "#196EC0", color: "#196EC0",
fontSize: width / 37, fontSize: fontSize.sm,
marginBottom: 5, marginBottom: 5,
fontFamily: "light", fontFamily: "light",
}} }}
> >
{product.grade} {'پایه' + ' ' + grades[book?.gradeId]}
</Text> </Text>
</View> </View>
<Divider type={"vertical"} /> <Divider type={"vertical"} />
</View> </View>
</View> </View>
<View style={tw("flex flex-col")}> <View style={tw("flex flex-col")}>
{product.seasons.map((season, index) => ( {seasons?.map((season, index) => (
<Season season={season} key={index} /> <Season season={season} key={index} id={route.params.id} seasonName={book?.name} />
))} ))}
</View> </View>
</ScrollView> </ScrollView>
@ -164,4 +139,14 @@ const styles = StyleSheet.create({
paddingHorizontal: 16, paddingHorizontal: 16,
}, },
}); });
export default Product;
const mapStateToProps = (state) => ({
book : state.publicApi.bookInfo,
seasons : state.publicApi.categories,
grades : state.publicApi.grades
});
const mapDispatchToProps = {
getBook: publicApi.bookInfo
}
export default connect(mapStateToProps, mapDispatchToProps)(Product);

@ -1,23 +1,23 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { import { View, Text, Dimensions, Pressable } from "react-native";
View, import { connect } from "react-redux";
Text, import { publicApi } from "../../../../redux/actions";
Dimensions,
Pressable,
} from "react-native";
import tw from "tailwind-rn"; import tw from "tailwind-rn";
import Colors from "../../../../constants/Colors"; import Colors from "../../../../constants/Colors";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
const { width, height } = Dimensions.get("window"); const { width, height } = Dimensions.get("window");
const Season = ({ season }) => { const Season = ({ season, activeUnit, name }) => {
const navigation = useNavigation(); const navigation = useNavigation();
const Unit = ({ unit }) => { const Unit = ({ unit }) => {
return ( return (
<View <View
style={[ style={[
tw("w-full flex flex-col rounded-md overflow-hidden mb-3"), tw("w-full flex flex-col rounded-md overflow-hidden mb-3"),
{ borderWidth: 1, borderColor: Colors.theme1.light.blue3 }, {
borderWidth: 1,
borderColor: Colors.theme1.light.blue3,
},
]} ]}
> >
<View <View
@ -28,6 +28,7 @@ const Season = ({ season }) => {
{ {
borderBottomWidth: 1, borderBottomWidth: 1,
borderColor: Colors.theme1.light.blue3, borderColor: Colors.theme1.light.blue3,
backgroundColor: activeUnit === unit ? "#aaa" : "transparent",
}, },
]} ]}
> >
@ -36,37 +37,44 @@ const Season = ({ season }) => {
{ {
fontFamily: "regular", fontFamily: "regular",
fontSize: width / 34, fontSize: width / 34,
color: Colors.theme1.light.blue5, color:
activeUnit === unit ? "white" : Colors.theme1.light.blue5,
}, },
]} ]}
> >
{unit.name} {unit.name}
</Text> </Text>
<Text {/* <Text
style={[ style={[
{ {
fontFamily: "regular", fontFamily: "regular",
fontSize: width / 36, fontSize: width / 36,
color: Colors.theme1.light.blue5, color: Colors.theme1.light.blue5,
backgroundColor : 'white', backgroundColor: "white",
}, },
]} ]}
> >
{unit.duration} {unit.duration}
</Text> </Text> */}
</View> </View>
<View style={[tw("w-full flex flex-row-reverse")]}> <View style={[tw("w-full flex flex-row-reverse")]}>
{unit.play && ( {1 && (
<Pressable <Pressable
style={[ style={[
tw("flex flex-1 flex-row items-center py-1.5 px-2"), tw("flex flex-1 flex-row items-center py-1.5 px-2"),
{ {
borderLeftWidth: 1, borderLeftWidth: 1,
borderColor: Colors.theme1.light.blue3, borderColor: Colors.theme1.light.blue3,
backgroundColor: 'white', backgroundColor: "white",
}, },
]} ]}
onPress={() => navigation.navigate("VideoDisplay")} onPress={() =>
navigation.navigate("VideoDisplay", {
season: season,
unit: unit,
name: name,
})
}
> >
<Text <Text
style={{ style={{
@ -81,7 +89,7 @@ const Season = ({ season }) => {
</Text> </Text>
</Pressable> </Pressable>
)} )}
{unit.download && ( {1 && (
<Pressable <Pressable
style={tw("flex flex-1 flex-row items-center py-1.5 px-2")} style={tw("flex flex-1 flex-row items-center py-1.5 px-2")}
> >
@ -121,7 +129,7 @@ const Season = ({ season }) => {
}, },
]} ]}
> >
{season.name} {name}
</Text> </Text>
<Text <Text
style={[ style={[
@ -135,12 +143,22 @@ const Season = ({ season }) => {
{season.duration} {season.duration}
</Text> </Text>
</Pressable> </Pressable>
{season.map((unit, index) => (
{season.units.map((unit, index) => (
<Unit unit={unit} key={index} /> <Unit unit={unit} key={index} />
))} ))}
</View> </View>
); );
}; };
export default Season; const mapStateToProps = (state) => ({
selectedVideo: state.publicApi.selectedVideo,
realSeasons: state.publicApi.bookInfo?.categories,
vods: state.publicApi.bookSection?.vods,
userid: state.user.status.id,
});
const mapDispatchToProps = {
setVideoActive: publicApi.setVideoActive,
};
export default connect(mapStateToProps, mapDispatchToProps)(Season);

@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useState, useEffect } from "react";
import { import {
View, View,
StyleSheet, StyleSheet,
@ -9,54 +9,39 @@ import {
LayoutAnimation, LayoutAnimation,
} from "react-native"; } from "react-native";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { book, publicApi } from "../../redux/actions";
import Navbar from "../../components/Navbar"; import Navbar from "../../components/Navbar";
import Drawer from "../../components/Drawer"; import Drawer from "../../components/Drawer";
import { Video, AVPlaybackStatus } from "expo-av"; import { Video, AVPlaybackStatus } from "expo-av";
import tw from "tailwind-rn"; import tw from 'tailwind-rn';
import * as ScreenOrientation from 'expo-screen-orientation';
import Season from "./components/Season"; import Season from "./components/Season";
import movie from "../../assets/video.mp4";
const { height, width } = Dimensions.get("window"); const { height, width } = Dimensions.get("window");
function VideoDisplay({ function VideoDisplay({ route, selectedVideo }) {
product = {
type: "کتاب ها",
name: "ریاضی",
grade: "پایه هفتم ابتدایی",
video: movie,
season: {
name: "فصل اول: مباحث جوشش مواد مذاب در مرکز زمین",
duration: "2:30:13",
units: [
{
name: "مقدمه جالب توجه نویسنده کتاب برای شما",
duration: "14:30",
download: true,
play: true,
},
{
name: "چگونگی ساخت نیروگاههای برقی ",
duration: "14:30",
download: false,
play: true,
},
{
name: "آیا گوگل از ما دزدی میکند ؟",
duration: "14:30",
download: true,
play: true,
},
],
},
},
}) {
const video = React.useRef(null); const video = React.useRef(null);
const [status, setStatus] = React.useState({}); const [status, setStatus] = React.useState({});
const [position, setPosition] = useState("100%"); const [position, setPosition] = useState("100%");
useEffect(() => {}, []);
const setBoxPosition = () => { const setBoxPosition = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setPosition(position === "100%" ? "0%" : "100%"); setPosition(position === "100%" ? "0%" : "100%");
}; };
function setOrientation() {
if (Dimensions.get('window').height > Dimensions.get('window').width) {
//Device is in portrait mode, rotate to landscape mode.
ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE);
}
else {
//Device is in landscape mode, rotate to portrait mode.
ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT);
}
}
return ( return (
<SafeAreaView <SafeAreaView
style={{ style={{
@ -85,13 +70,20 @@ function VideoDisplay({
<Video <Video
ref={video} ref={video}
style={{ width: "100%", height: (width * 9) / 16 - 16 }} style={{ width: "100%", height: (width * 9) / 16 - 16 }}
source={product.video} source={{
uri: `https://dnvn.ir/api/v1/file/${selectedVideo?.fileIds}`,
}}
useNativeControls useNativeControls
resizeMode="cover" resizeMode="cover"
onFullscreenUpdate={setOrientation}
isLooping isLooping
onPlaybackStatusUpdate={(status) => setStatus(() => status)} onPlaybackStatusUpdate={(status) => setStatus(() => status)}
/> />
<Season season={product.season} /> <Season
season={route.params.season}
activeUnit={route.params.unit}
name={route.params.name}
/>
</View> </View>
</ScrollView> </ScrollView>
</SafeAreaView> </SafeAreaView>
@ -110,4 +102,11 @@ const styles = StyleSheet.create({
paddingHorizontal: 16, paddingHorizontal: 16,
}, },
}); });
export default VideoDisplay;
const mapStateToProps = (state) => ({
selectedVideo: state.publicApi.selectedVideo,
});
const mapDispatchToProps = {};
export default connect(mapStateToProps, mapDispatchToProps)(VideoDisplay);

@ -2,39 +2,39 @@ import React from "react";
import { View, FlatList, Pressable, Image, Dimensions, Text } from "react-native"; import { View, FlatList, Pressable, Image, Dimensions, Text } from "react-native";
import {useNavigation} from '@react-navigation/native'; import {useNavigation} from '@react-navigation/native';
import tw from "tailwind-rn"; import tw from "tailwind-rn";
import fontSize from '../../../constants/fontSize';
const { width, height } = Dimensions.get("window"); const { width, height } = Dimensions.get("window");
import Header from "../../Home/components/Header"; import Header from "../../Home/components/Header";
import posterImage from "../../Products/assets/poster.png";
function MostViewedVideo({}) { function MostViewedVideo({videos, grades}) {
const navigation = useNavigation(); const navigation = useNavigation();
const Video = ({ video }) => { const Video = ({ video }) => {
return ( return (
<Pressable <Pressable
style={[ style={[
{ {
width : 320, width : width / 1.5,
}, },
tw("flex flex-col items-end rounded-md ml-4"), tw("flex flex-col items-end rounded-md ml-6"),
]} ]}
onPress={() => navigation.navigate("Video")} onPress={() => navigation.navigate("Video", {id: video.id})}
> >
<View <View
style={[ style={[
tw( tw(
"w-full flex flex-row flex-1 justify-between items-center relative overflow-hidden" "w-full flex flex-row flex-1 justify-between items-center relative overflow-hidden"
), ),
{ height: height / 3.8 }, { height: height / 4 },
]} ]}
> >
<Image <Image
source={video.poster} source={{uri : `https://dnvn.ir/api/v1/file/${video.fileIds}`}}
style={tw("w-full h-full absolute left-0 top-0 rounded-md")} style={tw("w-full h-full absolute left-0 top-0 rounded-md")}
/> />
<Image <Image
source={{ uri: video.imageUrl }} source={{ uri: `https://dnvn.ir/api/v1/file/${video.fileIds}` }}
style={[ style={[
tw("rounded-md h-full absolute left-2 inset-y-1/4 rounded-md"), tw("rounded-md h-full absolute left-2 inset-y-1/4 rounded-md"),
{ width: 70, height: 100 }, { width: 70, height: 100 },
@ -43,8 +43,9 @@ function MostViewedVideo({}) {
</View> </View>
<Text <Text
style={{ style={{
fontSize: width / 27, fontSize: fontSize.lg,
marginTop: 5, marginTop: 5,
paddingRight : 4,
color: "#05335F", color: "#05335F",
fontFamily: "bold", fontFamily: "bold",
}} }}
@ -53,7 +54,7 @@ function MostViewedVideo({}) {
</Text> </Text>
<View <View
style={tw("w-full flex flex-row justify-between items-center")} style={tw("w-full flex flex-row justify-between items-center px-1")}
> >
<Text <Text
style={[ style={[
@ -61,22 +62,22 @@ function MostViewedVideo({}) {
{ {
marginTop: 10, marginTop: 10,
color: "#132F52", color: "#132F52",
fontFamily: "light", fontFamily: "bold",
fontSize: width / 37, fontSize: fontSize.sm,
}, },
]} ]}
> >
{video.price} {video.product[0].price + ' ' + 'تومان'}
</Text> </Text>
<Text <Text
style={{ style={{
color: "#196EC0", color: "#196EC0",
fontFamily: "light", fontFamily: "light",
fontSize: width / 37, fontSize: fontSize.sm,
marginTop: 5, marginTop: 5,
}} }}
> >
{"پایه" + " " + video.grade} {"پایه" + " " + grades[video.gradeId]}
</Text> </Text>
</View> </View>
</Pressable> </Pressable>
@ -86,22 +87,17 @@ function MostViewedVideo({}) {
<View style={tw("w-full flex flex-col w-full")}> <View style={tw("w-full flex flex-col w-full")}>
<Header title="پربازدیدترین" /> <Header title="پربازدیدترین" />
<FlatList <FlatList
showsHorizontalScrollIndicator={false}
horizontal={true} horizontal={true}
inverted={true} inverted={true}
style={tw("pb-1.5 mt-3 flex flex-row w-full")} style={tw("pb-1.5 mt-3 flex flex-row w-full")}
data={[0,1,2]} data={videos}
renderItem={({ item }) => ( renderItem={({ item }) => (
<Video <Video
video={{ video={item}
name: "ریاضی",
price: "145.000 تومان",
grade: "4",
imageUrl: "https://dnvn.ir/api/v1/file/2105",
poster: posterImage,
}}
/> />
)} )}
keyExtractor={(item) => item} keyExtractor={(item) => item.id}
/> />
</View> </View>
); );

@ -2,13 +2,14 @@ import React from "react";
import { View, Pressable, Image, Dimensions, Text } from "react-native"; import { View, Pressable, Image, Dimensions, Text } from "react-native";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
import tw from "tailwind-rn"; import tw from "tailwind-rn";
import fontSize from "../../../constants/fontSize";
const { width, height } = Dimensions.get("window"); const { width, height } = Dimensions.get("window");
import Header from "../../Home/components/Header"; import Header from "../../Home/components/Header";
import posterImage from "../../Products/assets/poster.png"; import posterImage from "../../Products/assets/poster.png";
const NewestVideo = () => { const NewestVideo = ({ videos, grades }) => {
const navigation = useNavigation(); const navigation = useNavigation();
const Video = ({ video }) => { const Video = ({ video }) => {
return ( return (
@ -19,18 +20,18 @@ const NewestVideo = () => {
}, },
tw("flex flex-col items-end mb-4"), tw("flex flex-col items-end mb-4"),
]} ]}
onPress={() => navigation.navigate("Video")} onPress={() => navigation.navigate("Video", { id: video.id })}
> >
<Image <Image
source={video.poster} source={{ uri: `https://dnvn.ir/api/v1/file/${video.fileIds}` }}
style={[ style={[
tw("rounded-sm"), tw("rounded-md"),
{ width: '100%', height: ((width / 2.5 * 3 / 4)) }, { width: "100%", height: ((width / 2.5) * 3) / 4 },
]} ]}
/> />
<Text <Text
style={{ style={{
fontSize: width / 27, fontSize: fontSize.base,
marginTop: 5, marginTop: 5,
color: "#05335F", color: "#05335F",
fontFamily: "bold", fontFamily: "bold",
@ -42,11 +43,11 @@ const NewestVideo = () => {
style={{ style={{
color: "#196EC0", color: "#196EC0",
fontFamily: "light", fontFamily: "light",
fontSize: width / 37, fontSize: fontSize.sm,
marginTop: 5, marginTop: 5,
}} }}
> >
{"پایه" + " " + video.grade} {"پایه" + " " + grades[video.gradeId]}
</Text> </Text>
</Pressable> </Pressable>
); );
@ -55,21 +56,12 @@ const NewestVideo = () => {
<View style={tw("w-full flex flex-col w-full")}> <View style={tw("w-full flex flex-col w-full")}>
<Header title="جدیدترین دورهها" /> <Header title="جدیدترین دورهها" />
<View style={tw("w-full flex flex-row flex-wrap justify-between mt-3")}> <View style={tw("w-full flex flex-row flex-wrap justify-between mt-3")}>
{[0, 1, 2, 3].map((video, index) => ( {videos.map((video, index) => (
<Video <Video video={video} key={index} />
video={{
name: "ریاضی",
price: "145.000 تومان",
grade: "4",
imageUrl: "https://dnvn.ir/api/v1/file/2105",
poster: posterImage,
}}
key={index}
/>
))} ))}
</View> </View>
</View> </View>
); );
}; };
export default NewestVideo; export default NewestVideo;

@ -2,6 +2,8 @@ import React from "react";
import { View, Text, FlatList, TouchableOpacity } from "react-native"; import { View, Text, FlatList, TouchableOpacity } from "react-native";
import { connect } from "react-redux"; import { connect } from "react-redux";
import tw from "tailwind-rn"; import tw from "tailwind-rn";
import fontSize from '../../../constants/fontSize';
import Header from "../../Home/components/Header"; import Header from "../../Home/components/Header";
const VerticalGradeFilter = ({ grades }) => { const VerticalGradeFilter = ({ grades }) => {
@ -9,11 +11,11 @@ const VerticalGradeFilter = ({ grades }) => {
return ( return (
<TouchableOpacity <TouchableOpacity
style={[ style={[
tw("p-3 rounded-sm border border-gray-300 mt-2 ml-2"), tw("px-3 py-1.5 rounded-sm border border-gray-300 mt-2 ml-2"),
{ backgroundColor: "#f9f9f9" }, { backgroundColor: "#f9f9f9" },
]} ]}
> >
<Text style={[tw("text-xs text-gray-600"), { fontFamily: "light" }]}> <Text style={[tw("text-gray-600"), { fontFamily: "light", fontSize: fontSize.sm }]}>
{grades[grade]} {grades[grade]}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
@ -23,6 +25,7 @@ const VerticalGradeFilter = ({ grades }) => {
<View style={tw("w-full flex flex-col mt-3")}> <View style={tw("w-full flex flex-col mt-3")}>
<Header title={"پایه تحصیلی"} /> <Header title={"پایه تحصیلی"} />
<FlatList <FlatList
showsHorizontalScrollIndicator={false}
style={tw("flex flex-row w-full pb-1.5")} style={tw("flex flex-row w-full pb-1.5")}
horizontal={true} horizontal={true}
inverted={true} inverted={true}
@ -30,14 +33,9 @@ const VerticalGradeFilter = ({ grades }) => {
renderItem={({ item }) => <Grade grade={item} />} renderItem={({ item }) => <Grade grade={item} />}
keyExtractor={(item) => item} keyExtractor={(item) => item}
/> />
</View> </View>
); );
}; };
const mapStateToProps = (state) => ({ export default VerticalGradeFilter;
grades: state.publicApi.grades,
});
export default connect(mapStateToProps)(VerticalGradeFilter);

@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useState, useEffect } from "react";
import { import {
View, View,
StyleSheet, StyleSheet,
@ -9,7 +9,8 @@ import {
Platform, Platform,
LayoutAnimation, LayoutAnimation,
} from "react-native"; } from "react-native";
import tw from "tailwind-rn"; import { connect } from "react-redux";
import {book} from '../../redux/actions';
import Navbar from "../../components/Navbar"; import Navbar from "../../components/Navbar";
import Drawer from "../../components/Drawer"; import Drawer from "../../components/Drawer";
import Search from "../../components/Search"; import Search from "../../components/Search";
@ -21,10 +22,14 @@ import NewestVideo from "./components/NewestVideo";
const width = Dimensions.get("window").width; const width = Dimensions.get("window").width;
function Videos(props) { function Videos({ grades, videos, getVideos }) {
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
const [position, setPosition] = useState("100%"); const [position, setPosition] = useState("100%");
useEffect(() => {
getVideos();
},[]);
const setBoxPosition = () => { const setBoxPosition = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setPosition(position === "100%" ? "0%" : "100%"); setPosition(position === "100%" ? "0%" : "100%");
@ -59,11 +64,15 @@ function Videos(props) {
onChange={setSearch} onChange={setSearch}
placeholder={"نام کتاب یا دوره را جستجو کنید"} placeholder={"نام کتاب یا دوره را جستجو کنید"}
/> />
<VerticalGradeFilter /> <VerticalGradeFilter grades={grades} />
<Divider type={"vertical"} />
<MostViewedVideo />
<Divider type={"vertical"} /> <Divider type={"vertical"} />
<NewestVideo /> {videos.length > 0 && (
<>
<MostViewedVideo videos={videos} grades={grades} />
<Divider type={"vertical"} />
<NewestVideo videos={videos.sort((a,b) => a.updatedAt - b.updatedAt).slice(0,4)} grades={grades} />
</>
)}
</ScrollView> </ScrollView>
</SafeAreaView> </SafeAreaView>
); );
@ -84,4 +93,13 @@ const styles = StyleSheet.create({
}, },
}); });
export default Videos; const mapStateToProps = (state) => ({
grades: state.publicApi.grades,
videos: state.book.list,
grades: state.publicApi.grades,
});
const mapDispatchToProps = {
getVideos : book.list
}
export default connect(mapStateToProps, mapDispatchToProps)(Videos);

@ -0,0 +1,12 @@
export const fontSizeHandler = (
currentWidth,
minimumFontSize,
maximumFontSize,
minimumWidth,
maximumWidth
) => {
const alpha = (currentWidth - minimumWidth) / (maximumWidth - minimumWidth);
const deltaFontSize = maximumFontSize - minimumFontSize;
const currentFontSize = minimumFontSize + deltaFontSize * alpha;
return currentFontSize;
};

@ -2946,6 +2946,13 @@ expo-modules-core@0.6.3:
compare-versions "^3.4.0" compare-versions "^3.4.0"
invariant "^2.2.4" invariant "^2.2.4"
expo-screen-orientation@~4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/expo-screen-orientation/-/expo-screen-orientation-4.1.1.tgz#f61c241da8266baeb6e7e2c3427b5ca97e0c889b"
integrity sha512-qfJzgJ78wyG+BBVv5gdmAA6PUOY8FM++PFb0osAcAn2v4qSlz0V8rBCBpeBvFXc3fIhzspoGZdpEsnGtlqFQ5g==
dependencies:
"@expo/config-plugins" "^4.0.2"
expo-splash-screen@~0.14.0: expo-splash-screen@~0.14.0:
version "0.14.1" version "0.14.1"
resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.14.1.tgz#7647c8b98c679b8313d24a7c14729402c3c16631" resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.14.1.tgz#7647c8b98c679b8313d24a7c14729402c3c16631"

Loading…
Cancel
Save