reza first commit

master
Reza_ashrafi 3 years ago
parent cd997ab64f
commit 1f0ee832db
  1. 11
      .expo-shared/README.md
  2. 5
      .expo-shared/assets.json
  3. 79
      App.js
  4. 14
      app.json
  5. BIN
      assets/adaptive-icon.png
  6. BIN
      assets/appLogo.png
  7. BIN
      assets/favicon.png
  8. BIN
      assets/fonts/Farsi/Black.ttf
  9. BIN
      assets/fonts/Farsi/Bold.ttf
  10. BIN
      assets/fonts/Farsi/DemiBold.ttf
  11. BIN
      assets/fonts/Farsi/IRANSansXFaNum-ExtraBold.ttf
  12. BIN
      assets/fonts/Farsi/IRANSansXFaNum-Thin.ttf
  13. BIN
      assets/fonts/Farsi/IRANSansXFaNum-UltraLight.ttf
  14. BIN
      assets/fonts/Farsi/Light.ttf
  15. BIN
      assets/fonts/Farsi/Medium.ttf
  16. BIN
      assets/fonts/Farsi/Regular.ttf
  17. BIN
      assets/icon.png
  18. BIN
      assets/splash.png
  19. 24
      bottomNavigation.json
  20. 18
      eas.json
  21. 10
      filters.json
  22. 24
      navigation/bottomNavigation.js
  23. 668
      navigation/index.js
  24. 39
      package.json
  25. BIN
      src/assets/icons/activation.png
  26. BIN
      src/assets/icons/bookmark.png
  27. BIN
      src/assets/icons/leftWhite.png
  28. BIN
      src/assets/icons/link.png
  29. BIN
      src/assets/icons/pdf.png
  30. BIN
      src/assets/icons/ppt.png
  31. BIN
      src/assets/images/logo.png
  32. 172
      src/components/AlertModal.js
  33. 62
      src/components/Avatar.js
  34. 26
      src/components/Blur.js
  35. 107
      src/components/CustomTextInput.js
  36. 24
      src/components/Divider.js
  37. 539
      src/components/Drawer.js
  38. 63
      src/components/Empty.js
  39. 30
      src/components/FormButton.js
  40. 58
      src/components/Header.js
  41. 18
      src/components/ImageSlider.js
  42. 35
      src/components/MapSelector.js
  43. 28
      src/components/MusicPlayer.js
  44. 726
      src/components/Navbar.js
  45. 20
      src/components/Or.js
  46. 62
      src/components/Pressable.js
  47. 38
      src/components/Progress.js
  48. 32
      src/components/Redirect.js
  49. 39
      src/components/Scanner.js
  50. 63
      src/components/Search.js
  51. 91
      src/components/Select.js
  52. 46
      src/constants/Colors.js
  53. 9
      src/constants/defaultValues.js
  54. 21
      src/constants/fontSize.js
  55. 27
      src/redux/actions/activation.js
  56. 13
      src/redux/actions/blog.js
  57. 18
      src/redux/actions/book.js
  58. 32
      src/redux/actions/comment.js
  59. 14
      src/redux/actions/content.js
  60. 20
      src/redux/actions/faq.js
  61. 22
      src/redux/actions/file.js
  62. 8
      src/redux/actions/form.js
  63. 19
      src/redux/actions/index.js
  64. 26
      src/redux/actions/product.js
  65. 54
      src/redux/actions/public.js
  66. 33
      src/redux/actions/qr.js
  67. 17
      src/redux/actions/transport.js
  68. 61
      src/redux/actions/user.js
  69. 36
      src/redux/actions/userAddress.js
  70. 59
      src/redux/actions/userFactor.js
  71. 27
      src/redux/actions/userFavorite.js
  72. 42
      src/redux/actions/userProduct.js
  73. 11
      src/redux/actions/vote.js
  74. 6
      src/redux/index.js
  75. 153
      src/redux/proxy.js
  76. 39
      src/redux/reducers/activation.js
  77. 36
      src/redux/reducers/blog.js
  78. 96
      src/redux/reducers/book.js
  79. 37
      src/redux/reducers/comment.js
  80. 55
      src/redux/reducers/faq.js
  81. 26
      src/redux/reducers/file.js
  82. 24
      src/redux/reducers/form.js
  83. 18
      src/redux/reducers/index.js
  84. 31
      src/redux/reducers/product.js
  85. 190
      src/redux/reducers/public.js
  86. 33
      src/redux/reducers/qr.js
  87. 25
      src/redux/reducers/transport.js
  88. 75
      src/redux/reducers/user.js
  89. 32
      src/redux/reducers/userAddress.js
  90. 67
      src/redux/reducers/userFactor.js
  91. 41
      src/redux/reducers/userFavorite.js
  92. 62
      src/redux/reducers/userProduct.js
  93. 27
      src/redux/reducers/vote.js
  94. 65
      src/redux/store.js
  95. 55
      src/screens/AR/components/Book.js
  96. 111
      src/screens/AR/index.js
  97. BIN
      src/screens/Activation/assets/QR.png
  98. 169
      src/screens/Activation/index.js
  99. 618
      src/screens/Address/index.js
  100. 323
      src/screens/Blog/index.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -0,0 +1,11 @@
> Why do I have a folder named ".expo-shared" in my project?
The ".expo-shared" folder is created when running commands that produce state that is intended to be shared with all developers on the project. For example, "npx expo-optimize".
> What does the "assets.json" file contain?
The "assets.json" file describes the assets that have been optimized through "expo-optimize" and do not need to be processed again.
> Should I commit the ".expo-shared" folder?
Yes, you should share the ".expo-shared" folder with your collaborators.

@ -1,4 +1 @@
{
"12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
"40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
}
{}

@ -1,20 +1,69 @@
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import { StyleSheet, View } from "react-native";
import { useFonts } from "expo-font";
import Navigation from "./navigation/index";
import AlertModal from "./src/components/AlertModal";
import { Provider } from "react-redux";
import { store, persistor } from "./src/redux/store";
import * as SplashScreen from 'expo-splash-screen';
import React from "react";
import { PersistGate } from "redux-persist/integration/react";
const App = () => {
const [appIsReady, setAppIsReady] = React.useState(false);
let [fontsLoaded] = useFonts({
light: require("./assets/fonts/Farsi/Light.ttf"),
regular: require("./assets/fonts/Farsi/Regular.ttf"),
bold: require("./assets/fonts/Farsi/Medium.ttf"),
demi: require("./assets/fonts/Farsi/DemiBold.ttf"),
});
React.useEffect(() => {
async function prepare() {
try {
// Keep the splash screen visible while we fetch resources
await SplashScreen.preventAutoHideAsync();
// Pre-load fonts, make any API calls you need to do here
// Artificially delay for two seconds to simulate a slow loading
// experience. Please remove this if you copy and paste the code!
await new Promise((resolve) => setTimeout(resolve, 2000));
} catch (e) {
console.warn(e);
} finally {
// Tell the application to render
setAppIsReady(true);
}
}
prepare();
}, []);
const onLayoutRootView = React.useCallback(async () => {
if (fontsLoaded) {
// This tells the splash screen to hide immediately! If we call this after
// `setAppIsReady`, then we may see a blank screen while the app is
// loading its initial state and rendering its first pixels. So instead,
// we hide the splash screen once we know the root view has already
// performed layout.
await SplashScreen.hideAsync();
}
}, [fontsLoaded]);
if (!fontsLoaded) {
return null;
}
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<StatusBar style="auto" />
<View style={{ flex: 1 }} onLayout={onLayoutRootView}>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<Navigation />
<AlertModal />
</PersistGate>
</Provider>
</View>
);
}
};
const styles = StyleSheet.create({});
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default App;

@ -4,10 +4,10 @@
"slug": "final_danovin_expo",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"icon": "./assets/appLogo.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"image": "",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
@ -22,12 +22,14 @@
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"foregroundImage": "",
"backgroundColor": "#FFFFFF"
}
},
"package": "com.appsazz.final_danovin_expo"
},
"web": {
"favicon": "./assets/favicon.png"
}
"favicon": ""
},
"description": ""
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

@ -0,0 +1,24 @@
{
"bottomNavigationList": {
"home": {
"label": "خانه",
"isActive": true
},
"products": {
"label": "کتابها",
"isActive": true
},
"vod": {
"label": "ویدئوها",
"isActive": true
},
"cart": {
"label": "سبد خرید",
"isActive": true
},
"profile": {
"label": "پروفایل",
"isActive": true
}
}
}

@ -0,0 +1,18 @@
{
"cli": {
"version": ">= 0.52.0"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal"
},
"preview": {
"distribution": "internal"
},
"production": {}
},
"submit": {
"production": {}
}
}

@ -0,0 +1,10 @@
{
"sort": ["مرتب سازی", "مرتب سازی", "محبوب ترین", "جدیدترین"],
"productTypes" : [
"نوع محصول",
"کتاب فیزیکی",
"کتاب دیجیتال",
"دوره ویدئویی",
"بسته های آموزشی"
]
}

@ -0,0 +1,24 @@
const bottomNavigationList = {
home: {
label: "خانه",
isActive: true,
},
products: {
label: "کتابها",
isActive: true,
},
vod: {
label: "ویدئوها",
isActive: false,
},
cart: {
label: "سبد خرید",
isActive: true,
},
profile: {
label: "پروفایل",
isActive: true,
},
};
export default bottomNavigationList;

@ -0,0 +1,668 @@
import React, { useEffect } from "react";
import { Restart } from "fiction-expo-restart";
import { I18nManager, StatusBar } from "react-native";
import * as Linking from "expo-linking";
import Svg, { G, Path } from "react-native-svg";
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";
import OrdersFollowUp from "../src/screens/OrdersFollowUp";
import Splash from "../src/screens/Splash";
import Home from "../src/screens/Home";
import Products from "../src/screens/Products";
import Login from "../src/screens/Login";
import Otp from "../src/screens/Otp";
import Product from "../src/screens/Product";
import AR from "../src/screens/AR";
import QR from "../src/screens/QR";
import QRContent from "../src/screens/QRContent";
import Faq from "../src/screens/Faq";
import Activation from "../src/screens/Activation";
import Videos from "../src/screens/Videos";
import Video from "../src/screens/Video";
import VideoDisplay from "../src/screens/VideoDisplay";
import Contact from "../src/screens/Contact";
import Tests from "../src/screens/Tests";
import ShoppingCart from "../src/screens/ShoppingCart";
import DeliveryForm from "../src/screens/DeliveryForm";
import Address from "../src/screens/Address";
import Profile from "../src/screens/Profile";
import ProfileBookmark from "../src/screens/Profile/components/ProfileBookmark";
import ProfileAddress from "../src/screens/Profile/components/ProfileAddress";
import Blogs from "../src/screens/Blogs";
import Blog from "../src/screens/Blog";
import Sample from "../src/screens/Product/components/Sample";
import Info from "../src/screens/Product/components/Info";
import Rules from "../src/screens/Rules/index";
import MyCourses from "../src/screens/Profile/components/MyCourses";
import Ticket from "../src/screens/Contact/layouts/Ticket";
import Tickets from "../src/screens/Contact/layouts/Tickets";
import TicketStatus from "../src/screens/Contact/layouts/TicketStatus";
import MoreBlog from "../src/screens/Blogs/layouts/More";
//style
import Colors from "../src/constants/Colors";
import fontSize from "../src/constants/fontSize";
const Tab = createBottomTabNavigator();
const BottomTabNavigator = ({ theme, userProducts }) => {
const insets = useSafeAreaInsets();
const [headerShown, setHeaderShown] = React.useState(true);
React.useEffect(() => {
setTimeout(() => {
setHeaderShown(false);
}, 600);
}, []);
return (
<Tab.Navigator
initialRouteName="HomeTab"
screenOptions={{
tabBarHideOnKeyboard: true,
headerShown,
headerStyle: {
backgroundColor:
theme === "light" ? Colors.theme1.white : Colors.theme1.dark,
},
tabBarIconStyle: {
transform: [{ scaleX: -1 }],
},
tabBarLabelPosition: "below-icon",
tabBarActiveTintColor:
theme === "light" ? Colors.theme1.green79 : Colors.theme1.greenCF,
tabBarInactiveTintColor:
theme === "light" ? Colors.theme1.gray20 : Colors.theme1.white,
tabBarStyle: {
backgroundColor:
theme === "light" ? Colors.theme1.white : Colors.theme1.dark,
transform: [{ scaleX: -1 }],
height: 65 + insets.bottom,
borderWidth: 0,
},
tabBarLabelStyle: {
transform: [{ scaleX: -1 }, { translateY: -5 }],
fontSize: fontSize.xs,
fontFamily: "bold",
},
tabBarShowLabel: true,
}}
>
{bottomNavigationList.home.isActive ? (
<Tab.Screen
name="HomeTab"
children={() => <HomeStackScreen theme={theme} />}
options={{
title: bottomNavigationList.home.label,
tabBarIcon: ({ focused, color }) =>
focused ? (
<Svg
xmlns="http://www.w3.org/2000/svg"
width={33.58}
height={33.579}
>
<Path
d="M12.62 3.974 5.079 9.85a6.658 6.658 0 0 0-2.281 4.645v10.368a5.912 5.912 0 0 0 5.89 5.9h16.2a5.909 5.909 0 0 0 5.89-5.89V14.691a6.609 6.609 0 0 0-2.518-4.827l-8.644-6.058a6.278 6.278 0 0 0-6.996.168Z"
fill={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF
}
/>
<Path
data-name="Vector"
d="M16.79 25.471v-6.693"
fill="none"
stroke={theme === "light" ? "#fff" : Colors.theme1.dark}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
/>
</Svg>
) : (
<Svg
xmlns="http://www.w3.org/2000/svg"
width={33.58}
height={33.579}
style={{
transform: [{ scale: 0.7 }],
}}
>
<Path
d="M12.62 3.974 5.079 9.85a6.658 6.658 0 0 0-2.281 4.645v10.368a5.912 5.912 0 0 0 5.89 5.9h16.2a5.909 5.909 0 0 0 5.89-5.89V14.691a6.609 6.609 0 0 0-2.518-4.827l-8.644-6.058a6.278 6.278 0 0 0-6.996.168Z"
fill="none"
stroke={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.white
}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
/>
<Path
data-name="Vector"
d="M16.79 25.471v-6.693"
fill="none"
stroke={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.white
}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
/>
</Svg>
),
}}
/>
) : null}
{bottomNavigationList.products.isActive ? (
<Tab.Screen
name="ProductsTab"
children={() => <ProductsStackScreen theme={theme} />}
options={{
title: bottomNavigationList.products.label,
tabBarIcon: ({ focused, color }) =>
focused ? (
<Svg
xmlns="http://www.w3.org/2000/svg"
width={35.135}
height={34.763}
>
<Path
d="M32.207 24.227V6.798a2.869 2.869 0 0 0-3.179-2.875h-.088a27.857 27.857 0 0 0-10.35 3.422l-.249.159a1.641 1.641 0 0 1-1.552 0l-.361-.216A27.72 27.72 0 0 0 6.09 3.909a2.864 2.864 0 0 0-3.162 2.874v17.444a2.981 2.981 0 0 0 2.547 2.859l.425.058a37.976 37.976 0 0 1 10.892 3.524l.059.029a1.6 1.6 0 0 0 1.405 0 37.631 37.631 0 0 1 10.921-3.552l.483-.058a2.981 2.981 0 0 0 2.547-2.86Z"
fill={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF
}
/>
<Path
data-name="Vector"
d="M17.567 8.851v20.774M29.213 12.298h-3.294M29.159 16.643h-4.392"
fill="none"
stroke={theme === "light" ? "#fff" : Colors.theme1.dark}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
/>
</Svg>
) : (
<Svg
xmlns="http://www.w3.org/2000/svg"
width={35.135}
height={34.763}
style={{
transform: [{ scale: 0.7 }],
}}
>
<G
fill="none"
stroke={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.white
}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
>
<Path d="M32.207 24.227V6.798a2.869 2.869 0 0 0-3.179-2.875h-.088a27.857 27.857 0 0 0-10.35 3.422l-.249.159a1.641 1.641 0 0 1-1.552 0l-.361-.216A27.72 27.72 0 0 0 6.09 3.909a2.864 2.864 0 0 0-3.162 2.874v17.444a2.981 2.981 0 0 0 2.547 2.859l.425.058a37.976 37.976 0 0 1 10.892 3.524l.059.029a1.6 1.6 0 0 0 1.405 0 37.631 37.631 0 0 1 10.921-3.552l.483-.058a2.981 2.981 0 0 0 2.547-2.86Z" />
<Path
data-name="Vector"
d="M17.567 7.666v21.959M29.213 12.298h-3.294M29.159 16.643h-4.392"
/>
</G>
</Svg>
),
}}
/>
) : null}
{bottomNavigationList.vod.isActive ? (
<Tab.Screen
name="VODTab"
children={() => <VODStackScreen theme={theme} />}
options={{
unmountOnExit: true,
unmountOnBlur: true,
title: bottomNavigationList.vod.label,
tabBarIcon: ({ focused, color }) =>
focused ? (
<Svg
xmlns="http://www.w3.org/2000/svg"
width={35}
height={31.1}
>
<G data-name="Group 2000">
<Path
d="M25.421 29.241H8.974C4.04 29.241.75 26.392.75 19.744V10.25c0-6.651 3.29-9.5 8.224-9.5h16.447c4.935 0 8.229 2.849 8.229 9.5v9.5c0 6.642-3.294 9.491-8.229 9.491Z"
fill={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF
}
stroke={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF
}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
data-name="vuesax/linear/music-playlist"
/>
<Path
data-name="Vector"
d="M12.427 14.995v-2.083c0-2.673 1.892-3.766 4.2-2.43l1.805 1.042 1.806 1.041c2.308 1.336 2.308 3.523 0 4.86l-1.806 1.041-1.805 1.046c-2.308 1.332-4.2.239-4.2-2.434v-2.083Z"
fill="none"
stroke={theme === "light" ? "#fff" : Colors.theme1.dark}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
/>
</G>
</Svg>
) : (
<Svg
xmlns="http://www.w3.org/2000/svg"
width={35}
height={32}
style={{
transform: [{ scale: 0.7 }],
}}
>
<G data-name="Group 1999">
<Path
d="M25.421 29.241H8.974C4.04 29.241.75 26.392.75 19.744V10.25c0-6.651 3.29-9.5 8.224-9.5h16.447c4.935 0 8.229 2.849 8.229 9.5v9.5c0 6.642-3.294 9.491-8.229 9.491Z"
fill="none"
stroke={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.white
}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
data-name="vuesax/linear/music-playlist"
/>
<Path
data-name="Vector"
d="M12.427 14.995v-2.083c0-2.673 1.892-3.766 4.2-2.43l1.805 1.042 1.806 1.041c2.308 1.336 2.308 3.523 0 4.86l-1.806 1.041-1.805 1.046c-2.308 1.332-4.2.239-4.2-2.434v-2.083Z"
fill="none"
stroke={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.white
}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
/>
</G>
</Svg>
),
}}
/>
) : null}
{bottomNavigationList.cart.isActive ? (
<Tab.Screen
name="ShoppingCartTab"
children={() => <CARTStackScreen theme={theme} />}
options={{
tabBarBadge: userProducts.filter((product) => product.condition < 2)
.length
? userProducts.filter((product) => product.condition < 2).length
: null,
tabBarBadgeStyle: {
color: "white",
backgroundColor:
theme === "light"
? Colors.theme1.greenCF
: Colors.theme1.greenCF,
fontSize: fontSize.sm,
paddingTop: 2,
color:
theme === "light" ? Colors.theme1.white : Colors.theme1.dark,
borderWidth: 1,
borderColor:
theme === "light" ? Colors.theme1.greenCF : Colors.theme1.dark,
fontFamily: "bold",
},
title: bottomNavigationList.cart.label,
tabBarIcon: ({ focused, color }) =>
focused ? (
<Svg
xmlns="http://www.w3.org/2000/svg"
width={31.017}
height={31.017}
style={{ transform: [{ scale: 1.2 }] }}
>
<G
fill={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF
}
stroke={theme === "light" ? "white" : Colors.theme1.dark}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
data-name="vuesax/linear/bag-2"
>
<Path d="M9.693 9.912V8.659a6.168 6.168 0 0 1 5.247-6.036 5.816 5.816 0 0 1 6.384 5.79v1.782" />
<Path
data-name="Vector"
d="M11.631 28.433h7.754c5.2 0 6.126-2.081 6.4-4.614l.969-7.754c.345-3.154-.555-5.726-6.076-5.726H10.339c-5.519 0-6.423 2.572-6.074 5.725l.969 7.754c.271 2.534 1.202 4.615 6.397 4.615ZM20.027 15.509h.011M10.979 15.509h.011"
/>
</G>
</Svg>
) : (
<Svg
xmlns="http://www.w3.org/2000/svg"
width={31.017}
height={31.017}
style={{
transform: [{ scale: 0.8 }],
}}
>
<G
fill="none"
stroke={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.white
}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
data-name="vuesax/linear/bag-2"
>
<Path d="M9.693 9.912V8.659a6.168 6.168 0 0 1 5.247-6.036 5.816 5.816 0 0 1 6.384 5.79v1.782" />
<Path
data-name="Vector"
d="M11.631 28.433h7.754c5.2 0 6.126-2.081 6.4-4.614l.969-7.754c.345-3.154-.555-5.726-6.076-5.726H10.339c-5.519 0-6.423 2.572-6.074 5.725l.969 7.754c.271 2.534 1.202 4.615 6.397 4.615ZM20.027 15.509h.011M10.979 15.509h.011"
/>
</G>
</Svg>
),
}}
/>
) : null}
{bottomNavigationList.profile.isActive ? (
<Tab.Screen
name="ProfileTab"
children={() => <PROFILEStackScreen theme={theme} />}
options={{
title: bottomNavigationList.profile.label,
tabBarIcon: ({ focused, color }) =>
focused ? (
<Svg
xmlns="http://www.w3.org/2000/svg"
width={31.192}
height={31.192}
>
<G
fill={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.greenCF
}
>
<Path d="M15.803 14.127a2.363 2.363 0 0 0-.429 0 5.777 5.777 0 1 1 .429 0Z" />
<Path
data-name="Vector"
d="M9.306 18.923c-3.145 2.105-3.145 5.537 0 7.629a12.693 12.693 0 0 0 13.01 0c3.145-2.105 3.145-5.537 0-7.629a12.752 12.752 0 0 0-13.01 0Z"
/>
</G>
</Svg>
) : (
<Svg
xmlns="http://www.w3.org/2000/svg"
width={31.192}
height={31.192}
style={{
transform: [{ scale: 0.8 }],
}}
>
<G
fill="none"
stroke={
theme === "light"
? Colors.theme1.green79
: Colors.theme1.white
}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
>
<Path d="M15.803 14.127a2.363 2.363 0 0 0-.429 0 5.777 5.777 0 1 1 .429 0Z" />
<Path
data-name="Vector"
d="M9.306 18.923c-3.145 2.105-3.145 5.537 0 7.629a12.693 12.693 0 0 0 13.01 0c3.145-2.105 3.145-5.537 0-7.629a12.752 12.752 0 0 0-13.01 0Z"
/>
</G>
</Svg>
),
contentStyle: {
backgroundColor: "white",
},
}}
/>
) : null}
</Tab.Navigator>
);
};
const HomeStack = createNativeStackNavigator();
const HomeStackScreen = ({ theme }) => {
return (
<HomeStack.Navigator
screenOptions={{
headerShown: false,
contentStyle: {
backgroundColor:
theme === "light" ? Colors.theme1.white : Colors.theme1.dark,
},
}}
initialRouteName="Home"
>
<HomeStack.Screen name="Home" component={Home} />
<HomeStack.Screen name="VOD" component={Videos} />
<HomeStack.Screen name="Video" component={Video} unmountOnExit={true} />
<HomeStack.Screen name="VideoDisplay" component={VideoDisplay} />
<HomeStack.Screen name="Products" component={Products} />
<HomeStack.Screen name="Product" component={Product} />
<HomeStack.Screen name="Sample" component={Sample} />
<HomeStack.Screen name="Blogs" component={Blogs} />
<HomeStack.Screen name="MoreBlog" component={MoreBlog} />
<HomeStack.Screen name="Blog" component={Blog} />
<HomeStack.Screen name="Info" component={Info} />
</HomeStack.Navigator>
);
};
const ProductsStack = createNativeStackNavigator();
const ProductsStackScreen = ({ theme }) => {
return (
<ProductsStack.Navigator
screenOptions={{
headerShown: false,
contentStyle: {
backgroundColor:
theme === "light" ? Colors.theme1.white : Colors.theme1.dark,
},
}}
initialRouteName="Products"
>
<ProductsStack.Screen name="Products" component={Products} />
<ProductsStack.Screen name="Product" component={Product} />
<ProductsStack.Screen name="Sample" component={Sample} />
<ProductsStack.Screen name="Info" component={Info} />
</ProductsStack.Navigator>
);
};
const VODStack = createNativeStackNavigator();
const VODStackScreen = ({ theme }) => {
return (
<VODStack.Navigator
screenOptions={{
headerShown: false,
contentStyle: {
backgroundColor:
theme === "light" ? Colors.theme1.white : Colors.theme1.dark,
},
}}
initialRouteName="VOD"
>
<VODStack.Screen name="VOD" component={Videos} />
<VODStack.Screen name="Video" component={Video} unmountOnExit={true} />
<VODStack.Screen name="VideoDisplay" component={VideoDisplay} />
</VODStack.Navigator>
);
};
const CARTStack = createNativeStackNavigator();
const CARTStackScreen = ({ theme }) => {
return (
<CARTStack.Navigator
screenOptions={{
headerShown: false,
contentStyle: {
backgroundColor:
theme === "light" ? Colors.theme1.white : Colors.theme1.dark,
},
}}
initialRouteName="ShoppingCart"
>
<CARTStack.Screen name="ShoppingCart" component={ShoppingCart} />
<CARTStack.Screen name="DeliveryForm" component={DeliveryForm} />
<CARTStack.Screen name="Info" component={Info} />
</CARTStack.Navigator>
);
};
const PROFILEStack = createNativeStackNavigator();
const PROFILEStackScreen = ({ theme }) => {
return (
<PROFILEStack.Navigator
screenOptions={{
headerShown: false,
contentStyle: {
backgroundColor:
theme === "light" ? Colors.theme1.white : Colors.theme1.dark,
},
}}
>
<PROFILEStack.Screen name="Profile" component={Profile} />
<PROFILEStack.Screen name="ProfileBookmark" component={ProfileBookmark} />
<PROFILEStack.Screen name="Products" component={Products} />
<PROFILEStack.Screen name="Product" component={Product} />
<PROFILEStack.Screen name="Blogs" component={Blogs} />
<PROFILEStack.Screen name="MoreBlog" component={MoreBlog} />
<PROFILEStack.Screen name="Blog" component={Blog} />
<PROFILEStack.Screen name="MyCourses" component={MyCourses} />
</PROFILEStack.Navigator>
);
};
const prefix = Linking.createURL("/");
const Stack = createNativeStackNavigator();
const Navigation = ({
getStatus,
isLogin,
userProducts,
ltr,
setLTR,
theme,
}) => {
const linking = {
prefixes: [prefix],
};
const setDirection = async () => {
setLTR();
await I18nManager.allowRTL(false);
};
useEffect(() => {
if (I18nManager.isRTL && !ltr) {
setDirection();
Restart();
}
getStatus();
StatusBar.setBarStyle(
`${theme === "light" ? "dark" : "light"}-content`,
true
);
return () => {
console.log("This will be logged on unmount");
};
}, []);
return (
<NavigationContainer linking={linking}>
<Stack.Navigator
// initialRouteName="Root"
screenOptions={{
headerShown: false,
contentStyle: {
backgroundColor:
theme === "light" ? Colors.theme1.white : Colors.theme1.dark,
},
}}
>
<Stack.Screen name="Splash" component={Splash} />
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Rules" component={Rules} />
<Stack.Screen name="Otp" component={Otp} />
<Stack.Screen
name="Root"
children={() => (
<BottomTabNavigator theme={theme} userProducts={userProducts} />
)}
/>
<Stack.Screen name="QR" component={QR} />
<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.Screen name="QRContent" component={QRContent} />
<Stack.Screen name="Contact" component={Contact} />
<Stack.Screen name="AR" component={AR} />
<Stack.Screen name="CreateAddress" component={Address} />
<Stack.Screen name="ProfileAddress" component={ProfileAddress} />
<Stack.Screen name="Info" component={Info} />
<Stack.Screen name="Ticket" component={Ticket} />
<Stack.Screen name="Tickets" component={Tickets} />
<Stack.Screen name="TicketStatus" component={TicketStatus} />
</Stack.Navigator>
</NavigationContainer>
);
};
const mapStateToProps = (state) => ({
isLogin: state.user.status,
userProducts: state.userProduct.list,
theme: state.publicApi.theme,
ltr: state.publicApi.ltr,
});
const mapDispatchToProps = {
getStatus: user.getStatus,
setLTR: publicApi.setLTR,
};
export default connect(mapStateToProps, mapDispatchToProps)(Navigation);

@ -7,15 +7,48 @@
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
"eject": "expo eject",
"build:tailwind": "tailwindcss --input input.css --output tailwind.css --no-autoprefixer && tailwind-rn",
"dev:tailwind": "concurrently \"tailwindcss --input input.css --output tailwind.css --no-autoprefixer --watch\" \"tailwind-rn --watch\""
},
"dependencies": {
"expo": "~45.0.0",
"@react-native-async-storage/async-storage": "~1.17.3",
"@react-native-community/masked-view": "^0.1.11",
"@react-navigation/bottom-tabs": "^6.3.1",
"@react-navigation/native": "^6.0.10",
"@react-navigation/native-stack": "^6.6.2",
"axios": "^0.27.2",
"expo": "^45.0.0",
"expo-av": "~11.2.3",
"expo-barcode-scanner": "~11.3.0",
"expo-blur": "~11.1.0",
"expo-font": "~10.1.0",
"expo-linear-gradient": "~11.3.0",
"expo-linking": "~3.1.0",
"expo-screen-orientation": "~4.2.0",
"expo-splash-screen": "~0.15.1",
"expo-status-bar": "~1.3.0",
"fiction-expo-restart": "^1.1.2",
"jalali-moment": "^3.3.11",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-native": "0.68.1",
"react-native-web": "0.17.7"
"react-native-awesome-alerts": "^1.5.2",
"react-native-htmlview": "^0.16.0",
"react-native-openanything": "^0.0.6",
"react-native-ratings": "^8.1.0",
"react-native-safe-area-context": "4.2.4",
"react-native-screens": "~3.11.1",
"react-native-select-dropdown": "^1.13.0",
"react-native-svg": "12.3.0",
"react-native-web": "0.17.7",
"react-native-webview": "11.18.1",
"react-navigation-stack": "^2.10.4",
"react-redux": "^8.0.1",
"redux": "^4.2.0",
"redux-persist": "^6.0.0",
"redux-thunk": "^2.4.1",
"tailwind-rn": "3.0.1"
},
"devDependencies": {
"@babel/core": "^7.12.9"

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

@ -0,0 +1,172 @@
import React, { useState } from "react";
import { Dimensions } from "react-native";
import { connect } from "react-redux";
import AwesomeAlert from "react-native-awesome-alerts";
//style
import Colors from "../constants/Colors";
//variables
const { width } = Dimensions.get("window");
const AlertModal = (props) => {
const [alert, setAlert] = useState({
show: false,
showProgress: false,
title: "خطا",
message: "خطای ناشناخته",
closeOnTouchOutside: false,
closeOnHardwareBackPress: false,
showCancelButton: true,
showConfirmButton: true,
cancelText: "بیخیال",
confirmText: "باشه",
confirmButtonColor: "#2980b9",
onCancel: () => {},
onConfirm: () => {},
});
const [apiAlert, setApiAlert] = useState({
show: false,
showProgress: false,
title: "خطا",
message: "خطای ناشناخته",
closeOnTouchOutside: false,
closeOnHardwareBackPress: false,
showCancelButton: true,
showConfirmButton: true,
cancelText: "بیخیال",
confirmText: "باشه",
confirmButtonColor: "#2980b9",
onCancel: () => {},
onConfirm: () => {},
});
global.globalAlert = (params) => {
setAlert({
...alert,
...params,
});
};
global.globalApiAlert = (params) => {
setApiAlert({
...apiAlert,
...params,
});
};
function hideAlert() {
setAlert({ ...alert, show: false });
}
function onApiCancelPressed() {
globalApiAlert({ show: false });
apiAlert.onCancel();
}
function onApiConfirmPressed() {
globalApiAlert({ show: false });
apiAlert.onConfirm();
}
function onCancelPressed() {
hideAlert();
alert.onCancel();
}
function onConfirmPressed() {
hideAlert();
alert.onConfirm();
}
return (
<>
<AwesomeAlert
show={alert.show}
progressColor="red"
showProgress={alert.showProgress}
title={alert.title}
titleStyle={{
fontFamily: "bold",
color:
props.theme === "light"
? Colors.theme1.gray20
: Colors.theme1.white,
}}
message={alert.message}
messageStyle={{
textAlign: "right",
fontFamily: "regular",
color:
props.theme === "light"
? Colors.theme1.gray20
: Colors.theme1.white,
}}
closeOnTouchOutside={alert.closeOnTouchOutside}
closeOnHardwareBackPress={alert.closeOnHardwareBackPress}
showCancelButton={alert.showCancelButton}
showConfirmButton={alert.showConfirmButton}
cancelText={alert.cancelText}
confirmText={alert.confirmText}
confirmButtonColor={alert.confirmButtonColor}
onCancelPressed={onCancelPressed}
onConfirmPressed={onConfirmPressed}
cancelButtonTextStyle={{
color: props.theme === "light" ? "#777" : Colors.theme1.grayE3,
fontFamily: "regular",
}}
confirmButtonTextStyle={{
fontFamily: "regular",
}}
contentStyle={{
width: width / 1.5,
}}
cancelButtonStyle={{
fontFamily: "regular",
borderColor: props.theme === "light" ? "#777" : Colors.theme1.grayE3,
borderWidth: 1,
backgroundColor:
props.theme === "light" ? Colors.theme1.white : Colors.theme1.black,
}}
confirmButtonStyle={{
alignItems: "center",
justifyContent: "center",
fontFamily: "regular",
borderColor: "#2980b9",
borderWidth: 1,
}}
contentContainerStyle={{
backgroundColor:
props.theme === "light" ? "white" : Colors.theme1.black,
}}
useNativeDriver={true}
/>
<AwesomeAlert
show={apiAlert.show}
progressColor="red"
showProgress={apiAlert.showProgress}
title={apiAlert.title}
message={apiAlert.message}
closeOnTouchOutside={apiAlert.closeOnTouchOutside}
closeOnHardwareBackPress={apiAlert.closeOnHardwareBackPress}
showCancelButton={apiAlert.showCancelButton}
showConfirmButton={apiAlert.showConfirmButton}
cancelText={apiAlert.cancelText}
confirmText={apiAlert.confirmText}
confirmButtonColor={apiAlert.confirmButtonColor}
onCancelPressed={onApiCancelPressed}
onConfirmPressed={onApiConfirmPressed}
contentStyle={{
width: width / 1.5,
}}
confirmButtonStyle={{
width: width / 4,
alignItems: "center",
justifyContent: "center",
}}
useNativeDriver={true}
/>
</>
);
};
const mapStateToProps = (state) => ({
theme: state.publicApi.theme,
});
export default connect(mapStateToProps)(AlertModal);

@ -0,0 +1,62 @@
import React from "react";
import { Image, View } from "react-native";
import Svg, { G, Path } from "react-native-svg";
import { connect } from "react-redux";
//style
import tw from "tailwind-rn";
import Colors from "../constants/Colors";
function Avatar({ source, size, theme }) {
return (
<View
style={[
tw("rounded-full overflow-hidden flex justify-center items-center"),
{
minWidth: size,
minHeight: size,
backgroundColor:
theme === "light"
? Colors.theme1.grayE3
: Colors.theme1.white + '55',
},
]}
>
{source ? (
<Image
source={{ uri: `https:dnvn.ir/api/v1/file/${source}` }}
style={{ minWidth: "100%", minHeight: "100%" }}
resizeMode="contain"
/>
) : (
<Svg
data-name="vuesax/bold/frame"
xmlns="http://www.w3.org/2000/svg"
width={36.975}
height={36.975}
>
<G fill="none">
<Path d="M18.488 3.081a7.311 7.311 0 0 0-.185 14.621 1.243 1.243 0 0 1 .339 0h.108a7.313 7.313 0 0 0-.262-14.621Z" />
<Path
d="M18.488 5.081a5.324 5.324 0 0 0-5.318 5.318c0 1.395.528 2.705 1.486 3.689.94.965 2.215 1.535 3.6 1.61.165-.011.328-.01.484.002a5.31 5.31 0 0 0 5.066-5.304 5.324 5.324 0 0 0-5.318-5.315m0-2a7.325 7.325 0 0 1 7.318 7.318 7.3 7.3 0 0 1-7.056 7.303h-.108a1.243 1.243 0 0 0-.339 0c-4.036-.14-7.133-3.344-7.133-7.303a7.325 7.325 0 0 1 7.318-7.318Z"
fill={theme === 'light' ? "#818181" : Colors.theme1.white}
/>
<G data-name="Vector">
<Path d="M26.314 21.8a15.3 15.3 0 0 0-15.637 0 6.081 6.081 0 0 0-3.035 4.976 6.03 6.03 0 0 0 3.02 4.945 14.234 14.234 0 0 0 7.826 2.172 14.234 14.234 0 0 0 7.826-2.172 6.078 6.078 0 0 0 3.02-4.976 6.066 6.066 0 0 0-3.02-4.945Z" />
<Path
d="M18.507 21.651c-2.528 0-4.977.661-6.721 1.814-1.383.926-2.144 2.102-2.144 3.311 0 1.201.756 2.366 2.129 3.282l.006.003c1.734 1.165 4.18 1.833 6.711 1.833 2.53 0 4.977-.668 6.708-1.83 1.762-1.189 2.136-2.455 2.138-3.31-.01-.862-.388-2.129-2.129-3.29-1.729-1.152-4.17-1.813-6.698-1.813m0-2c2.831 0 5.658.716 7.807 2.15 1.942 1.293 3.005 3.05 3.02 4.945 0 1.91-1.078 3.666-3.02 4.976-4.313 2.896-11.339 2.896-15.652 0-1.942-1.294-3.02-3.05-3.02-4.946 0-1.895 1.078-3.666 3.035-4.976 2.165-1.433 5-2.149 7.83-2.149Z"
fill={theme === 'light' ? "#818181" : Colors.theme1.white}
/>
</G>
</G>
</Svg>
)}
</View>
);
}
const mapStateToProps = (state) => ({
theme: state.publicApi.theme,
});
export default connect(mapStateToProps)(Avatar);

@ -0,0 +1,26 @@
import React from "react";
import { BlurView } from "expo-blur";
import { ActivityIndicator } from "react-native";
import { connect } from "react-redux";
import tw from "tailwind-rn";
function Blur({ theme }) {
return (
<BlurView
intensity={280}
tint="dark"
style={[
{ width: "100%", height: "100%" },
tw("flex-1 flex justify-center items-center"),
]}
>
<ActivityIndicator size="large" color="#12CF7F" />
</BlurView>
);
}
const mapStateToProps = (state) => ({
theme: state.publicApi.theme,
});
export default connect(mapStateToProps)(Blur);

@ -0,0 +1,107 @@
import React from "react";
import { TextInput, View, Text, StyleSheet } from "react-native";
import { connect } from "react-redux";
import tw from "tailwind-rn";
import Colors from "../constants/Colors";
import fontSize from "../constants/fontSize";
const FloatingLabelInput = ({
label,
textAlign,
direction,
labelBackgroundColor,
onChange,
name,
value,
textColor,
placeholder,
maxLength,
autoFocus,
regex,
mobile,
keyboardType,
multiline,
theme,
editable = true,
...props
}) => {