diff --git a/bottomNavigation.json b/bottomNavigation.json deleted file mode 100644 index 2ea77e8..0000000 --- a/bottomNavigation.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "bottomNavigationList": { - "home": { - "label": "خانه", - "isActive": true - }, - "products": { - "label": "کتاب‌ها", - "isActive": true - }, - "vod": { - "label": "ویدئوها", - "isActive": true - }, - "cart": { - "label": "سبد خرید", - "isActive": true - }, - "profile": { - "label": "پروفایل", - "isActive": true - } - } -} diff --git a/filters.json b/filters.json deleted file mode 100644 index 8ce4df9..0000000 --- a/filters.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "sort": ["مرتب سازی", "مرتب سازی", "محبوب ترین", "جدیدترین"], - "productTypes" : [ - "نوع محصول", - "کتاب فیزیکی", - "کتاب دیجیتال", - "دوره ویدئویی", - "بسته های آموزشی" - ] -} diff --git a/navigation/bottomNavigation.js b/navigation/bottomNavigation.js deleted file mode 100644 index e821cc1..0000000 --- a/navigation/bottomNavigation.js +++ /dev/null @@ -1,24 +0,0 @@ -const bottomNavigationList = { - home: { - label: "خانه", - isActive: true, - }, - products: { - label: "کتاب‌ها", - isActive: true, - }, - vod: { - label: "ویدئوها", - isActive: true, - }, - cart: { - label: "سبد خرید", - isActive: true, - }, - profile: { - label: "پروفایل", - isActive: true, - }, -}; - -export default bottomNavigationList; \ No newline at end of file diff --git a/navigation/index.js b/navigation/index.js index e465044..c6d60e4 100644 --- a/navigation/index.js +++ b/navigation/index.js @@ -3,14 +3,13 @@ import { Restart } from "fiction-expo-restart"; import { I18nManager, StatusBar, Dimensions } from "react-native"; import * as Linking from "expo-linking"; import Svg, { G, Path } from "react-native-svg"; -import {asyncAwesomeAlert} from "../src/utils/AsyncWrappers"; +import { asyncAwesomeAlert } from "../src/utils/AsyncWrappers"; import { NavigationContainer } from "@react-navigation/native"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import { connect } from "react-redux"; import { user, publicApi } from "../src/redux/actions"; import { useSafeAreaInsets } from "react-native-safe-area-context"; -import bottomNavigationList from "./bottomNavigation"; //components import OrderDetails from "../src/screens/OrderDetails"; @@ -53,7 +52,7 @@ import Colors from "../src/constants/Colors"; import fontSize from "../src/constants/fontSize"; const Tab = createBottomTabNavigator(); -const BottomTabNavigator = ({ theme, userProducts }) => { +const BottomTabNavigator = ({ theme, userProducts, bottomNavigation }) => { const insets = useSafeAreaInsets(); const [headerShown, setHeaderShown] = React.useState(true); React.useEffect(() => { @@ -95,12 +94,12 @@ const BottomTabNavigator = ({ theme, userProducts }) => { tabBarShowLabel: true, }} > - {bottomNavigationList.home.isActive ? ( + {bottomNavigation.home.isActive ? ( } options={{ - title: bottomNavigationList.home.label, + title: bottomNavigation.home.label, tabBarIcon: ({ focused, color }) => focused ? ( { /> ) : null} - {bottomNavigationList.products.isActive ? ( + {bottomNavigation.products.isActive ? ( } options={{ - title: bottomNavigationList.products.label, + title: bottomNavigation.products.label, tabBarIcon: ({ focused, color }) => focused ? ( { /> ) : null} - {bottomNavigationList.vod.isActive ? ( + {bottomNavigation.vod.isActive ? ( } options={{ unmountOnExit: true, unmountOnBlur: true, - title: bottomNavigationList.vod.label, + title: bottomNavigation.vod.label, tabBarIcon: ({ focused, color }) => focused ? ( { /> ) : null} - {bottomNavigationList.cart.isActive ? ( + {bottomNavigation.cart.isActive ? ( } options={{ - tabBarBadge: userProducts.filter((product) => product.condition < 2) + tabBarBadge: userProducts?.filter((product) => product?.condition < 2) .length - ? userProducts.filter((product) => product.condition < 2).length + ? userProducts?.filter((product) => product?.condition < 2)?.length : null, tabBarBadgeStyle: { color: "white", @@ -340,7 +339,7 @@ const BottomTabNavigator = ({ theme, userProducts }) => { theme === "light" ? Colors.theme1.greenCF : Colors.theme1.dark, fontFamily: "bold", }, - title: bottomNavigationList.cart.label, + title: bottomNavigation.cart.label, tabBarIcon: ({ focused, color }) => focused ? ( { /> ) : null} - {bottomNavigationList.profile.isActive ? ( + {bottomNavigation.profile.isActive ? ( } options={{ - title: bottomNavigationList.profile.label, + title: bottomNavigation.profile.label, tabBarIcon: ({ focused, color }) => focused ? ( { const linking = { prefixes: [prefix], @@ -611,7 +611,6 @@ const Navigation = ({ ); }, []); - Dimensions.addEventListener("change", () => { const dim = Dimensions.get("window"); setOrientation(dim.height > dim.width ? "portrait" : "landscape"); @@ -636,7 +635,11 @@ const Navigation = ({ ( - + )} /> @@ -662,6 +665,7 @@ const mapStateToProps = (state) => ({ userProducts: state.userProduct.list, theme: state.publicApi.theme, ltr: state.publicApi.ltr, + bottomNavigation: state.config.bottomNavigation, }); const mapDispatchToProps = { getStatus: user.getStatus, diff --git a/src/redux/actions/config.js b/src/redux/actions/config.js index 5308980..c764dff 100644 --- a/src/redux/actions/config.js +++ b/src/redux/actions/config.js @@ -4,7 +4,11 @@ const config = { getBottomNavigation: (data = {}) => async (dispatch) => - await proxy.get("config/bottomNavigations", data, { dispatch }), + await proxy.get("config/bottomNavigationList", data, { dispatch }), + getFilters: + (data = {}) => + async (dispatch) => + await proxy.get("config/filters", data, { dispatch }), }; export default config; diff --git a/src/redux/reducers/blog.js b/src/redux/reducers/blog.js index a7f09db..b8e0eb9 100644 --- a/src/redux/reducers/blog.js +++ b/src/redux/reducers/blog.js @@ -1,7 +1,7 @@ const initialState = { loading: false, error: null, - list: [], + list: null, info: null, hashtags : [], hashtag : null, diff --git a/src/redux/reducers/book.js b/src/redux/reducers/book.js index 8ad723b..65513a4 100644 --- a/src/redux/reducers/book.js +++ b/src/redux/reducers/book.js @@ -1,9 +1,9 @@ -import {asyncAwesomeAlert} from '../../utils/AsyncWrappers'; +import { asyncAwesomeAlert } from "../../utils/AsyncWrappers"; const initialState = { loading: false, error: null, - list: [], + list: null, info: null, searchResult: [], filterResult: [], @@ -18,7 +18,7 @@ const initialState = { filterOptions: { grade: "", subject: "", - productType: '', + productType: "", available: false, sort: null, search: "", @@ -51,6 +51,13 @@ const grades = [ export default function book(state = initialState, action) { let { type, data } = action; switch (type) { + case "config/filters": + return { + ...state, + error: false, + loading: false, + productTypes: ["نوع محصول", ...data.productTypes], + }; case "book/list": let itemsSubject = (Array.isArray(data) ? data : []).map( (item, index) => item.name @@ -87,7 +94,7 @@ export default function book(state = initialState, action) { case "book/error": asyncAwesomeAlert("خطا", data.message, { showCancelButton: false, - confirmText: "باشه" + confirmText: "باشه", }); return { ...state, loading: false, error: data.message }; default: diff --git a/src/redux/reducers/config.js b/src/redux/reducers/config.js index 880bc55..6e917bb 100644 --- a/src/redux/reducers/config.js +++ b/src/redux/reducers/config.js @@ -1,18 +1,17 @@ const initialState = { loading: false, error: null, - bottomNavigations: null, + bottomNavigation: null, }; export default function config(state = initialState, action) { let { type, data } = action; switch (type) { - case "config/bottomNavigations": - console.log(data); + case "config/bottomNavigationList": return { ...state, loading: false, - bottomNavigations: data, + bottomNavigation: data.bottomNavigationList, error: null, }; case "config/loading": diff --git a/src/redux/reducers/userProduct.js b/src/redux/reducers/userProduct.js index 9db329e..a368d84 100644 --- a/src/redux/reducers/userProduct.js +++ b/src/redux/reducers/userProduct.js @@ -3,7 +3,7 @@ import { asyncAwesomeAlert } from "../../utils/AsyncWrappers"; const initialState = { loading: false, error: null, - list: [], + list: null, myList: [], info: null, sum: null, @@ -19,20 +19,13 @@ export default function userFactor(state = initialState, action) { case "userProduct/myList": return { ...state, loading: false, myList: data, error: null }; case "userProduct/list": - const checkEmpty = data.filter( - (item) => item.condition === 2 && item.product.productType === (1 || 3) - ); - const hasPhysical = - data.filter((item) => item.product.productType === 2).length > 0 - ? true - : false; return { ...state, loading: false, list: data, - checkEmpty: checkEmpty.length > 0 ? false : true, + // checkEmpty: checkEmpty.length > 0 ? false : true, error: null, - hasPhysical: hasPhysical, + // hasPhysical: hasPhysical, }; case "userProduct/info": return { ...state, loading: false, info: data, error: null }; diff --git a/src/redux/store.js b/src/redux/store.js index ba1edee..d5a0d1a 100644 --- a/src/redux/store.js +++ b/src/redux/store.js @@ -19,6 +19,7 @@ import comment from "./reducers/comment"; import form from "./reducers/form"; import userFavorite from "./reducers/userFavorite"; import vote from "./reducers/vote"; +import config from "./reducers/config"; const persistConfig = { key: "root", @@ -50,6 +51,7 @@ const persistedReducer = persistReducer( form, userFavorite, vote, + config }) ); diff --git a/src/screens/Blogs/index.js b/src/screens/Blogs/index.js index 64f6921..18186df 100644 --- a/src/screens/Blogs/index.js +++ b/src/screens/Blogs/index.js @@ -97,7 +97,7 @@ function Blogs({ getList, blogs, hashtag, setHashtag, theme }) { horizontal={true} inverted={true} style={[tw("flex flex-row mt-3 pb-3")]} - data={blogs.slice(0, 7)} + data={blogs?.slice(0, 7)} renderItem={({ item }) => } keyExtractor={(item) => item?.id} /> @@ -107,7 +107,7 @@ function Blogs({ getList, blogs, hashtag, setHashtag, theme }) { horizontal={true} inverted={true} style={[tw("flex flex-row mt-3 pb-3")]} - data={blogs.slice(0, 7)} + data={blogs?.slice(0, 7)} renderItem={({ item }) => } keyExtractor={(item) => item?.id} /> diff --git a/src/screens/Home/components/Scroll.js b/src/screens/Home/components/Scroll.js index 9555df2..ed70ac6 100644 --- a/src/screens/Home/components/Scroll.js +++ b/src/screens/Home/components/Scroll.js @@ -6,6 +6,7 @@ import tw from "tailwind-rn"; const ios = Platform.OS === "ios"; import { connect } from "react-redux"; +import Tab from "../../QRContent/Tab"; function Scroll({ books, mobile }) { const Box = ({ books }) => { @@ -14,7 +15,10 @@ function Scroll({ books, mobile }) { return ( - navigation.navigate("Product", { id: book?.id, type: "book" }) + navigation.push("Product", { + id: book?.id, + type: "book", + }) } style={[ tw("mr-1 overflow-hidden"), @@ -43,7 +47,7 @@ function Scroll({ books, mobile }) { { height: mobile ? 242 : 350, direction: "rtl" }, ]} > - {books.slice(0, 14)?.map((book, index) => ( + {books?.slice(0, 14)?.map((book, index) => ( ))} diff --git a/src/screens/Home/components/Videos.js b/src/screens/Home/components/Videos.js index 886dd0f..f503b49 100644 --- a/src/screens/Home/components/Videos.js +++ b/src/screens/Home/components/Videos.js @@ -24,7 +24,7 @@ function Videos({ videos, grades, mobile, theme }) { { navigation.navigate("Video", { id: video?.id })} > @@ -61,7 +61,7 @@ const Video = ({ video, mobile, grades, theme }) => { style={[ tw("bg-gray-100"), { - height: mobile ? 130 : 130, + height: mobile ? 130 : 170, }, ]} /> @@ -72,7 +72,7 @@ const Video = ({ video, mobile, grades, theme }) => { color: theme === "light" ? Colors.theme1.gray20 : Colors.theme1.white, fontFamily: "bold", - fontSize: mobile ? fontSize.sm : fontSize.xl, + fontSize: mobile ? fontSize.sm : fontSize.tiny, textAlign: ios ? "right" : "auto", }, ]} @@ -86,7 +86,7 @@ const Video = ({ video, mobile, grades, theme }) => { color: theme === "light" ? Colors.theme1.gray20 : Colors.theme1.white, fontFamily: "regular", - fontSize: mobile ? fontSize.xs : fontSize.base, + fontSize: mobile ? fontSize.xs : fontSize.sm, textAlign: ios ? "right" : "auto", }, ]} diff --git a/src/screens/Home/index.js b/src/screens/Home/index.js index b435053..91b9174 100644 --- a/src/screens/Home/index.js +++ b/src/screens/Home/index.js @@ -1,7 +1,7 @@ import React, { useState } from "react"; import { connect } from "react-redux"; -import { blog, book, userProduct } from "../../redux/actions"; -import {useNavigation} from "@react-navigation/native"; +import { blog, book, user, userProduct } from "../../redux/actions"; +import { useNavigation } from "@react-navigation/native"; import { View, @@ -37,6 +37,7 @@ const Home = ({ getBlogs, getBooks, getUserProducts, + bottomNavigation, }) => { const navigation = useNavigation(); const [position, setPosition] = useState("100%"); @@ -47,15 +48,15 @@ const Home = ({ }; React.useEffect(() => { - if (blogs?.length === 0) { + if (!blogs) { getBlogs(); - } else if (books?.length === 0) { + } else if (!books) { getBooks({ vod: true }); - } else if (userProducts?.length === 0) { + } else if (!userProducts) { getUserProducts(); } - }, [books, userProducts, blogs]); - + }, []); + return ( - {/* */} + {bottomNavigation.vod.isActive ? : null} @@ -114,6 +115,7 @@ const mapStateToProps = (state) => ({ books: state.book.list, userProducts: state.userProduct.list, mobile: state.publicApi.isMobile, + bottomNavigation: state.config.bottomNavigation, }); const mapDispatchToProps = { diff --git a/src/screens/OrderDetails/index.js b/src/screens/OrderDetails/index.js index 6f98934..de10d7d 100644 --- a/src/screens/OrderDetails/index.js +++ b/src/screens/OrderDetails/index.js @@ -284,7 +284,7 @@ function OrderDetails({ mobile, route, theme }) { - {order?.userProducts.map((item, index) => ( + {order?.userProducts?.map((item, index) => ( ))} diff --git a/src/screens/Product/components/Book.js b/src/screens/Product/components/Book.js index c9b29d9..d7165f1 100644 --- a/src/screens/Product/components/Book.js +++ b/src/screens/Product/components/Book.js @@ -278,7 +278,7 @@ function Book({ ? Colors.theme1.green79 : Colors.theme1.white, - fontSize: mobile ? fontSize.tiny : fontSize.lg, + fontSize: mobile ? fontSize.tiny : fontSize.base, fontFamily: "demi", }, ]} diff --git a/src/screens/Products/components/Main.js b/src/screens/Products/components/Main.js index 139f190..019e9b3 100644 --- a/src/screens/Products/components/Main.js +++ b/src/screens/Products/components/Main.js @@ -68,198 +68,200 @@ const Main = ({ books, filterOptions, grades, mobile, theme, orientation }) => { bySearchFilter = byAvailableFilter; } - return filterOptions?.productType === "دوره ویدئویی" + return filterOptions?.productType === "محصولات ویدیویی" ? bySearchFilter?.map((product, index) => ( - // navigation.navigate("Video", { id: product.id })} - // > - // - // - // + navigation.navigate("Video", { id: product.id })} + > + + + - // - // {"دوره ویدئویی" + " " + product?.name} - // - // - // {"پایه" + " " + grades[product?.gradeId]} - // - // - // {separate( - // product?.product?.filter( - // (product) => product?.productType === 4 - // )[0].price - // )}{" "} - // تومان - // - // - <> + + {"دوره ویدئویی" + " " + product?.name} + + + {"پایه" + " " + grades[product?.gradeId]} + + + {separate( + product?.product?.filter( + (product) => product?.productType === 4 + )[0].price + )}{" "} + تومان + + )) : bySearchFilter?.map((product, index) => ( {( productType - ? productType === ("کتاب دیجیتال" || "همه محصولات") + ? productType === ("محصولات دیجیتال" || "همه محصولات") : true ) ? ( - // - // navigation.navigate("Product", { - // id: product?.id, - // type: "book", - // }) - // } - // > - // - // - // - // {"کتاب دیجیتال" + " " + product?.name} - // - // - // {"پایه" + " " + grades[product?.gradeId]} - // - // - // - // - // {separate( - // product?.product?.filter( - // (product) => product?.productType === 1 - // )[0]?.price - // )} - // - // - // تومان - // - // - // - <> + + navigation.navigate("Product", { + id: product?.id, + type: "book", + }) + } + > + + + + {"کتاب دیجیتال" + " " + product?.name} + + + {"پایه" + " " + grades[product?.gradeId]} + + + + + {separate( + product?.product?.filter( + (product) => product?.productType === 1 + )[0]?.price + )} + + + تومان + + + ) : null} {( productType - ? productType === ("کتاب فیزیکی" || "همه محصولات") + ? productType === ("محصولات فیزیکی" || "همه محصولات") : true ) ? ( { flex: 1, height: mobile ? ((width / 2 - 25) * 4) / 2.9 - : orientation === "portrait" - ? ((width / 4.2) * 16) / 11 - : ((width / 5.2) * 16) / 11, + : ((width / 3.2) * 16) / 16, }, ]} /> { { { ? Colors.theme1.gray20 : Colors.theme1.white, fontFamily: "bold", - fontSize: fontSize.xl2, + fontSize: mobile ? fontSize.xl2 : fontSize.lg, }, ]} > @@ -381,9 +381,9 @@ const Main = ({ books, filterOptions, grades, mobile, theme, orientation }) => { ), ]} > - {/* {filterOptions?.productType === "دوره ویدئویی" ? Items(2) : null} */} - {/* {filterOptions?.productType === "کتاب دیجیتال" ? Items(0) : null} */} - {filterOptions?.productType === "کتاب فیزیکی" ? Items(1) : null} + {filterOptions?.productType === "محصولات ویدیویی" ? Items(2) : null} + {filterOptions?.productType === "محصولات دیجیتال" ? Items(0) : null} + {filterOptions?.productType === "محصولات فیزیکی" ? Items(1) : null} {!filterOptions?.productType ? Items(0) : null} {/* {filterLoading && ( diff --git a/src/screens/Products/index.js b/src/screens/Products/index.js index 8d5d81e..8319c5b 100644 --- a/src/screens/Products/index.js +++ b/src/screens/Products/index.js @@ -9,7 +9,7 @@ import { LayoutAnimation, } from "react-native"; import { connect } from "react-redux"; -import { book } from "../../redux/actions"; +import { book, config } from "../../redux/actions"; //components import Drawer from "../../components/Drawer"; @@ -29,10 +29,12 @@ function Products({ route, setFilterOptions, filterOptions, + getFilters }) { const [position, setPosition] = useState("100%"); useEffect(() => { + getFilters(); getBooks({ vod: true }); }, []); @@ -43,7 +45,7 @@ function Products({ useEffect(() => { if (route?.params?.productType === "دوره ویدئویی") { - setFilterOptions({ ...filterOptions, productType: "دوره ویدئویی" }); + setFilterOptions({ ...filterOptions, productType: "محصولات ویدیویی" }); } }, [route]); @@ -84,10 +86,7 @@ const mapStateToProps = (state) => ({ const mapDispatchToProps = { getBooks: book.list, setFilterOptions: book.setFilterOptions, + getFilters: config.getFilters }; -export default connect(mapStateToProps, mapDispatchToProps)(Products); - -Products.defaultProps = { - productTypes: ["کتاب فیزیکی", "کتاب دیجیتال", "ویدئوها", "اشتراک"], -}; +export default connect(mapStateToProps, mapDispatchToProps)(Products); \ No newline at end of file diff --git a/src/screens/Splash/index.js b/src/screens/Splash/index.js index 29bd8d6..6613c49 100644 --- a/src/screens/Splash/index.js +++ b/src/screens/Splash/index.js @@ -29,9 +29,7 @@ function Splash({ navigation, theme, isLogin, - blogs, getBlogs, - books, getBooks, userProducts, getUserProducts, @@ -39,9 +37,7 @@ function Splash({ getBottomNavigation, bottomNavigation, }) { - const isFocused = useIsFocused(); - const [out, setOut] = React.useState(false); - + const [sendRequest, setSendRequest] = React.useState(false); React.useEffect(() => { StatusBar.setBarStyle( `${theme === "light" ? "dark" : "light"}-content`, @@ -54,33 +50,27 @@ function Splash({ setIsDark(!theme ? "light" : theme); }; - const setOutHandler = React.useCallback( - (value) => { - setOut(value); - }, - [out] - ); - useEffect(() => { getTheme(); if (isLogin !== null) { if (isLogin === false) { - setOutHandler(true); - navigation.reset({ - index: 0, - routes: [{ name: "Login" }], - }); + setTimeout(() => { + getBottomNavigation(); + navigation.reset({ + index: 0, + routes: [{ name: "Login" }], + }); + }, 700); } else { - if (!blogs.length) { + if (!sendRequest) { + setSendRequest(true); + getBottomNavigation(); + getUserProducts(); getBlogs(); - } else if (!books.length) { getBooks({ vod: true }); - } else if (!userProducts.length) { - getUserProducts(); - } else if (!bottomNavigation) { - getBottomNavigation(); - } else { - setOutHandler(true); + } + + if (bottomNavigation) { navigation.reset({ index: 0, routes: [{ name: "Root" }], @@ -88,32 +78,7 @@ function Splash({ } } } - }, [isLogin, books, userProducts, blogs, bottomNavigation]); - - // if (isFocused && out) { - // setOutHandler(false); - // BackHandler.exitApp(); - // } - - // if (isFocused && !out) { - // if (isLogin !== null) { - // if (isLogin === false) { - // setOutHandler(true); - // navigation.push("Login"); - // } else { - // if (blogs.length === 0) { - // getBlogs(); - // } else if (books.length === 0) { - // getBooks({ vod: true }); - // } else if (userProducts.length === 0) { - // getUserProducts(); - // } else { - // setOutHandler(true); - // navigation.push("Root"); - // } - // } - // } - // } + }, [isLogin, bottomNavigation, userProducts]); return ( ({ isLogin: state.user.status, - blogs: state.blog.list, - books: state.book.list, userProducts: state.userProduct.list, theme: state.publicApi.theme, bottomNavigation: state.config.bottomNavigation, diff --git a/src/screens/Videos/components/MostViewedVideo.js b/src/screens/Videos/components/MostViewedVideo.js index c46917b..579bff5 100644 --- a/src/screens/Videos/components/MostViewedVideo.js +++ b/src/screens/Videos/components/MostViewedVideo.js @@ -53,7 +53,7 @@ function MostViewedVideo({ videos, grades, mobile, theme }) { resizeMode="contain" style={[ tw( - `rounded-sm h-full absolute left-2 ${mobile ? "" : "top-1/5"}` + `rounded-sm h-full absolute left-2` ), { width: mobile ? 70 : 105,