@ -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; |
||||
|
Before Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 46 KiB |
@ -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,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); |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 834 B |
After Width: | Height: | Size: 271 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 2.2 KiB |
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 |
||||
}) => { |
||||