diff --git a/.eslintrc.js b/.eslintrc.js index 3033d9d..e8c7653 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2,6 +2,10 @@ module.exports = { root: true, extends: '@react-native-community', plugins: ['import'], + rules: { + 'prettier/prettier': ['error', {endOfLine: 'auto'}], + 'react-native/no-inline-styles': 0, + }, settings: { 'import/resolver': { node: { @@ -18,6 +22,7 @@ module.exports = { store: './src/store', 'global-styles': './src/styles', utilities: './src/utilities', + helpers: './src/helpers', }, }, }, diff --git a/.vscode/settings.json b/.vscode/settings.json index 13ee2b0..e2006ed 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,6 @@ { - "nuxt.isNuxtApp": false + "nuxt.isNuxtApp": false, + "editor.tabSize": 2, + "editor.useTabStops": true, + "editor.detectIndentation": false, } \ No newline at end of file diff --git a/App.js b/App.js index 1dc12b3..3be88c2 100644 --- a/App.js +++ b/App.js @@ -11,13 +11,12 @@ import AppNavigator from 'navigations'; import {Provider} from 'react-redux'; import configureStore from 'store'; import {PersistGate} from 'redux-persist/integration/react'; -import {enableLatestRenderer} from 'react-native-maps'; +import 'react-native-gesture-handler'; import 'moment/locale/id'; import 'utilities/i18'; -enableLatestRenderer(); const App = () => { - const {persistor, store} = configureStore(); + const {store, persistor} = configureStore(); return ( diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 405c6cd..8e02284 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -18,7 +18,7 @@ android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:launchMode="singleTask" - android:windowSoftInputMode="adjustResize" + android:windowSoftInputMode="adjustPan" android:exported="true"> diff --git a/jsconfig.json b/jsconfig.json index 855d1e2..98936a9 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -12,7 +12,8 @@ "services": ["src/services/*"], "store": ["src/store/*"], "global-styles": ["src/styles/*"], - "utilities": ["src/utilities/*"] + "utilities": ["src/utilities/*"], + "helpers": ["src/helpers/*"] } } } \ No newline at end of file diff --git a/package.json b/package.json index d3aa6fd..b81b254 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "@react-native-async-storage/async-storage": "^1.17.11", "@react-navigation/bottom-tabs": "^6.4.0", "@react-navigation/native": "^6.0.13", - "@react-navigation/native-stack": "^6.9.1", + "@react-navigation/stack": "^6.3.16", + "add": "^2.0.6", "axios": "^0.22.0", "babel-plugin-module-resolver": "^4.1.0", "eslint-import-resolver-babel-module": "^5.3.1", @@ -26,6 +27,7 @@ "react-native": "0.70.6", "react-native-currency-input": "^1.1.0", "react-native-dropdown-picker": "^5.4.3", + "react-native-gesture-handler": "^2.9.0", "react-native-keyboard-aware-scroll-view": "^0.9.5", "react-native-localize": "^2.2.4", "react-native-maps": "^1.3.2", @@ -33,11 +35,15 @@ "react-native-responsive-fontsize": "^0.5.1", "react-native-safe-area-context": "^4.4.1", "react-native-screens": "^3.18.2", + "react-native-search-filter": "^0.1.5", + "react-native-super-grid": "^5.0.0", + "react-native-swipe-up-down": "^1.2.0", "react-native-vector-icons": "^9.2.0", "react-redux": "^7.2.6", "redux": "^4.1.2", "redux-persist": "^6.0.0", - "redux-thunk": "^2.4.1" + "redux-thunk": "^2.4.1", + "yarn": "^1.22.19" }, "devDependencies": { "@babel/core": "^7.12.9", diff --git a/src/actions/auth-action.js b/src/actions/auth.action.js similarity index 81% rename from src/actions/auth-action.js rename to src/actions/auth.action.js index 1e085ef..7cadff9 100644 --- a/src/actions/auth-action.js +++ b/src/actions/auth.action.js @@ -3,7 +3,8 @@ import {ActionType} from 'constants'; export const signIn = data => ({ type: ActionType.SIGN_IN, payload: { - data: data, + token: data.token, + user: data.user, }, }); diff --git a/src/actions/index.js b/src/actions/index.js index d135f0c..61f8c8d 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -1 +1,2 @@ -export * from './auth-action'; +export * from './auth.action'; +export * from './sale-order.action'; diff --git a/src/actions/sale-order.action.js b/src/actions/sale-order.action.js new file mode 100644 index 0000000..2a5a05c --- /dev/null +++ b/src/actions/sale-order.action.js @@ -0,0 +1,8 @@ +import {ActionType} from 'constants'; + +export const addProductSale = data => ({ + type: ActionType.STORE_SALE_ORDER_PRODUCTS, + payload: { + data: data, + }, +}); diff --git a/src/assets/images/login_1.png b/src/assets/images/login_1.png new file mode 100644 index 0000000..b419ac4 Binary files /dev/null and b/src/assets/images/login_1.png differ diff --git a/src/assets/images/tab-icons/explore-active.png b/src/assets/images/tab-icons/explore-active.png deleted file mode 100644 index b763ea7..0000000 Binary files a/src/assets/images/tab-icons/explore-active.png and /dev/null differ diff --git a/src/assets/images/tab-icons/explore-inactive.png b/src/assets/images/tab-icons/explore-inactive.png deleted file mode 100644 index 108a8ff..0000000 Binary files a/src/assets/images/tab-icons/explore-inactive.png and /dev/null differ diff --git a/src/assets/images/tab-icons/home_active.png b/src/assets/images/tab-icons/home_active.png new file mode 100644 index 0000000..82eb900 Binary files /dev/null and b/src/assets/images/tab-icons/home_active.png differ diff --git a/src/assets/images/tab-icons/home_inactive.png b/src/assets/images/tab-icons/home_inactive.png new file mode 100644 index 0000000..6a839e0 Binary files /dev/null and b/src/assets/images/tab-icons/home_inactive.png differ diff --git a/src/assets/images/tab-icons/inbox-active.png b/src/assets/images/tab-icons/inbox-active.png deleted file mode 100644 index d44d864..0000000 Binary files a/src/assets/images/tab-icons/inbox-active.png and /dev/null differ diff --git a/src/assets/images/tab-icons/inbox-inactive.png b/src/assets/images/tab-icons/inbox-inactive.png deleted file mode 100644 index 9bc5c5d..0000000 Binary files a/src/assets/images/tab-icons/inbox-inactive.png and /dev/null differ diff --git a/src/assets/images/tab-icons/order-active.png b/src/assets/images/tab-icons/order-active.png deleted file mode 100644 index dd815aa..0000000 Binary files a/src/assets/images/tab-icons/order-active.png and /dev/null differ diff --git a/src/assets/images/tab-icons/order-inactive.png b/src/assets/images/tab-icons/order-inactive.png deleted file mode 100644 index 9cb5670..0000000 Binary files a/src/assets/images/tab-icons/order-inactive.png and /dev/null differ diff --git a/src/assets/images/tab-icons/other_active.png b/src/assets/images/tab-icons/other_active.png new file mode 100644 index 0000000..37996db Binary files /dev/null and b/src/assets/images/tab-icons/other_active.png differ diff --git a/src/assets/images/tab-icons/other_inactive.png b/src/assets/images/tab-icons/other_inactive.png new file mode 100644 index 0000000..5090ca3 Binary files /dev/null and b/src/assets/images/tab-icons/other_inactive.png differ diff --git a/src/assets/images/tab-icons/pembelian_active.png b/src/assets/images/tab-icons/pembelian_active.png new file mode 100644 index 0000000..777b663 Binary files /dev/null and b/src/assets/images/tab-icons/pembelian_active.png differ diff --git a/src/assets/images/tab-icons/pembelian_inactive.png b/src/assets/images/tab-icons/pembelian_inactive.png new file mode 100644 index 0000000..09574ed Binary files /dev/null and b/src/assets/images/tab-icons/pembelian_inactive.png differ diff --git a/src/assets/images/tab-icons/profile-active.png b/src/assets/images/tab-icons/profile-active.png deleted file mode 100644 index 36c701b..0000000 Binary files a/src/assets/images/tab-icons/profile-active.png and /dev/null differ diff --git a/src/assets/images/tab-icons/profile-inactive.png b/src/assets/images/tab-icons/profile-inactive.png deleted file mode 100644 index d745423..0000000 Binary files a/src/assets/images/tab-icons/profile-inactive.png and /dev/null differ diff --git a/src/assets/images/tab-icons/transaksi_active.png b/src/assets/images/tab-icons/transaksi_active.png new file mode 100644 index 0000000..fed7782 Binary files /dev/null and b/src/assets/images/tab-icons/transaksi_active.png differ diff --git a/src/assets/images/tab-icons/transaksi_inactive.png b/src/assets/images/tab-icons/transaksi_inactive.png new file mode 100644 index 0000000..5c27e1d Binary files /dev/null and b/src/assets/images/tab-icons/transaksi_inactive.png differ diff --git a/src/components/Button/DefaultPressable/index.js b/src/components/Button/DefaultPressable/index.js new file mode 100644 index 0000000..dee6340 --- /dev/null +++ b/src/components/Button/DefaultPressable/index.js @@ -0,0 +1,47 @@ +import React from 'react'; +import { Pressable,StyleSheet,Text } from 'react-native'; +import { Colors,FONTS } from 'global-styles'; +import { RFValue } from 'react-native-responsive-fontsize'; + +const DefaultPressable = ({ + isOutline, + onPress, + onLongPress, + disabled, + title, + loading, +}) => ( + + {loading ? ( + + ) : ( + {title} + )} + +); + +DefaultPressable.defaultProps = { + isOutline: false, + onLongPress: undefined, + loading: false, + disabled: false, +} + +const styles = (isOutline, disabled) => + StyleSheet.create({ + container: { + backgroundColor: Colors.PRIMARY, + alignItems: 'center', + padding: RFValue(10), + borderRadius: RFValue(10), + } + }) + +export default DefaultPressable; diff --git a/src/components/Card/TransactionProductCard/index.js b/src/components/Card/TransactionProductCard/index.js new file mode 100644 index 0000000..9e5557c --- /dev/null +++ b/src/components/Card/TransactionProductCard/index.js @@ -0,0 +1,80 @@ +import React from 'react'; +import { + TouchableWithoutFeedback, + ImageBackground, + View, + Text, + StyleSheet, +} from 'react-native'; +import {RestConstant} from 'constants'; +import {cutStringProduct, currencyFloatNoSymbol} from 'helpers'; +import {RFValue} from 'react-native-responsive-fontsize'; +import {Colors, FONTS} from 'global-styles'; + +const TransactionProductCard = props => ( + + + {props.data.image.Valid ? ( + + ) : ( + + + {cutStringProduct(props.data.name)} + + + )} + + + {props.data.name} + + + Rp {currencyFloatNoSymbol(parseFloat(props.data.selling_price))} + + + + +); + +export default TransactionProductCard; + +const style = StyleSheet.create({ + cardProduct: { + flex: 1, + backgroundColor: Colors.WHITE, + marginHorizontal: RFValue(4), + marginVertical: RFValue(4), + elevation: 1, + height: RFValue(132), + borderRadius: RFValue(5), + }, + thumbnail: { + width: '100%', + height: RFValue(70), + justifyContent: 'center', + borderTopLeftRadius: RFValue(5), + borderTopRightRadius: RFValue(5), + backgroundColor: Colors.TERTIARY, + }, + cardPrice: { + position: 'absolute', + right: RFValue(5), + top: RFValue(35), + color: 'black', + fontFamily: FONTS.poppins[600], + fontSize: RFValue(10), + }, +}); diff --git a/src/components/Card/TransactionProductCard/styles.js b/src/components/Card/TransactionProductCard/styles.js new file mode 100644 index 0000000..db25c00 --- /dev/null +++ b/src/components/Card/TransactionProductCard/styles.js @@ -0,0 +1,5 @@ +import { StyleSheet } from "react-native"; + +export default StyleSheet.create({ + +}) \ No newline at end of file diff --git a/src/components/Container/index.js b/src/components/Container/index.js index b5d809b..94284f6 100644 --- a/src/components/Container/index.js +++ b/src/components/Container/index.js @@ -4,11 +4,11 @@ import {SafeAreaProvider, SafeAreaView} from 'react-native-safe-area-context'; const defaultStyle = { flex: 1, }; -const Container = ({children, backgroundColor, barStyle, barColor}) => ( +const Container = ({children, backgroundColor, barStyle, barColor, safeAreaStyleProps}) => ( - {children} + {children} ); diff --git a/src/components/Header/SellHeader/index.js b/src/components/Header/SellHeader/index.js new file mode 100644 index 0000000..6d1641b --- /dev/null +++ b/src/components/Header/SellHeader/index.js @@ -0,0 +1,107 @@ +import React from 'react'; +import { TouchableOpacity, View, TouchableWithoutFeedback, Text } from 'react-native'; +import { RFValue } from 'react-native-responsive-fontsize'; +import SearchInput from 'react-native-search-filter'; +import { Icon } from 'components'; +import { Colors } from 'global-styles'; +import styles from './styles'; +import { ScrollView } from 'react-native-gesture-handler'; + +const SearchIcon = (props) => ( + + + +) + +const SearchIconRemove = () => ( + + + +) + +const FilterTab = ({ data, filter, onPress, secondary }) => ( + + + {data.map((item, index) => ( + onPress({ index: index, item: item})} + > + {item.name} + + ))} + + +) + +const SellHeader = ({setSearch, searchValue, navigation, categories}) => ( + + + navigation.goBack()}> + + + + : + } + /> + + alert('barcode')}> + + + {/* */} + + alert(index, item)} + /> + +); + +export default SellHeader; \ No newline at end of file diff --git a/src/components/Header/SellHeader/styles.js b/src/components/Header/SellHeader/styles.js new file mode 100644 index 0000000..c055d35 --- /dev/null +++ b/src/components/Header/SellHeader/styles.js @@ -0,0 +1,35 @@ +import {StyleSheet} from 'react-native'; +import {RFValue} from 'react-native-responsive-fontsize'; +import {Colors} from 'global-styles'; + +export default StyleSheet.create({ + searchBar: { + height: RFValue(33), + borderRadius: RFValue(6), + paddingRight: RFValue(35), + paddingLeft: RFValue(10), + fontSize: RFValue(13), + backgroundColor: Colors.TERNIARY, + color: Colors.WHITE, + }, + searchRemove: { + marginTop: 5, + width: RFValue(15), + height: RFValue(15), + borderRadius: RFValue(10), + backgroundColor: 'rgba(0, 0, 0, 0.1)', + justifyContent: 'center', + alignItems: 'center', + }, + searchIconRemove: { + position: 'absolute', + top: RFValue(5), + right: RFValue(13), + }, + buttonFilter: { + flexDirection: 'row', + alignItems: 'center', + marginLeft: RFValue(5), + width: RFValue(35), + } +}); \ No newline at end of file diff --git a/src/components/index.js b/src/components/index.js index b3c7973..aa9cd36 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -5,7 +5,13 @@ import ModalLanguage from './Modal/ModalLanguage'; import ModalError from './Modal/ModalError'; import ProductRegular from './Product/ProductRegular'; import Button from './Button'; +import DefaultPressable from './Button/DefaultPressable'; + import Header from './Header'; +import SellHeader from './Header/SellHeader'; + +import TransactionProductCard from './Card/TransactionProductCard'; + import Input from './Input'; import Note from './Note'; import ModalSetHours from './Modal/ModalSetHours'; @@ -20,8 +26,11 @@ export { ModalLanguage, ModalError, ProductRegular, + TransactionProductCard, Button, + DefaultPressable, Header, + SellHeader, Input, Note, ModalSetHours, diff --git a/src/constants/action-type.js b/src/constants/action-type.js index 00968da..33f6c94 100644 --- a/src/constants/action-type.js +++ b/src/constants/action-type.js @@ -1,2 +1,3 @@ export const SIGN_IN = 'SIGN_IN'; export const SIGN_OUT = 'SIGN_OUT'; +export const STORE_SALE_ORDER_PRODUCTS = 'STORE_SALE_ORDER_PRODUCTS'; diff --git a/src/constants/http-request.js b/src/constants/http-request.js index 3aeed89..7588754 100644 --- a/src/constants/http-request.js +++ b/src/constants/http-request.js @@ -1,10 +1,12 @@ import Axios from 'axios'; import AsyncStorage from '@react-native-async-storage/async-storage'; +// const {persistor, store} = configureStore(); +const authAxios = Axios.create(); + Axios.interceptors.request.use( async config => { - const token = await AsyncStorage.getItem('userToken'); - console.log('token ', token); + const token = await AsyncStorage.getItem('token'); if (token) { config.headers.Authorization = 'Bearer ' + token; } @@ -16,6 +18,7 @@ Axios.interceptors.request.use( ); export const get = async (url, config = null) => { + console.log(config); return Axios.get(url, config) .then(response => { return response; @@ -35,6 +38,16 @@ export const post = (url, data, config = null) => { }); }; +export const postAuth = (url, data, config = null) => { + return authAxios.post(url, data, config) + .then(response => { + return response; + }) + .catch(err => { + return err; + }); +}; + export const put = (url, data, config = null) => { return Axios.put(url, data, config) .then(response => { diff --git a/src/constants/rest-api.js b/src/constants/rest-api.js index 6755143..bd06cc9 100644 --- a/src/constants/rest-api.js +++ b/src/constants/rest-api.js @@ -1,7 +1,10 @@ -const baseUrl = 'http://54.90.216.145/api/v1'; +const baseUrl = 'https://fe49-158-140-167-180.ngrok-free.app'; export default { - login: `${baseUrl}/login`, + BASE_URL: `${baseUrl}/`, + login: `${baseUrl}/user/login`, register: `${baseUrl}/register`, verifyOTP: `${baseUrl}/verify-otp`, + productCategories: `${baseUrl}/api/product/categories`, + products: `${baseUrl}/api/products`, }; diff --git a/src/constants/tab-icons.js b/src/constants/tab-icons.js index db3691a..e2558e9 100644 --- a/src/constants/tab-icons.js +++ b/src/constants/tab-icons.js @@ -1,22 +1,22 @@ module.exports = [ { - label: 'Explore', - active: require('assets/images/tab-icons/explore-active.png'), - inactive: require('assets/images/tab-icons/explore-inactive.png'), + label: 'Home', + active: require('assets/images/tab-icons/home_active.png'), + inactive: require('assets/images/tab-icons/home_inactive.png'), }, { - label: 'Orders', - active: require('assets/images/tab-icons/order-active.png'), - inactive: require('assets/images/tab-icons/order-inactive.png'), + label: 'Transaksi', + active: require('assets/images/tab-icons/transaksi_active.png'), + inactive: require('assets/images/tab-icons/transaksi_inactive.png'), }, { - label: 'Inbox', - active: require('assets/images/tab-icons/inbox-active.png'), - inactive: require('assets/images/tab-icons/inbox-inactive.png'), + label: 'Pembelian', + active: require('assets/images/tab-icons/pembelian_active.png'), + inactive: require('assets/images/tab-icons/pembelian_inactive.png'), }, { - label: 'Profile', - active: require('assets/images/tab-icons/profile-active.png'), - inactive: require('assets/images/tab-icons/profile-inactive.png'), + label: 'Lainnya', + active: require('assets/images/tab-icons/other_active.png'), + inactive: require('assets/images/tab-icons/other_inactive.png'), }, ]; diff --git a/src/helpers/common.js b/src/helpers/common.js new file mode 100644 index 0000000..56b14a5 --- /dev/null +++ b/src/helpers/common.js @@ -0,0 +1,16 @@ +export const cutStringProduct = string => { + let length = 0; + let res; + if (string !== undefined) { + length = string.length; + + if (length === 1) { + res = string[0].toUpperCase(); + } else if (string[1] === ' ') { + res = string[0].toUpperCase() + '' + string[2].toLowerCase(); + } else { + res = string[0].toUpperCase() + '' + string[1].toLowerCase(); + } + } + return res; +}; diff --git a/src/helpers/currency.js b/src/helpers/currency.js new file mode 100644 index 0000000..6f76778 --- /dev/null +++ b/src/helpers/currency.js @@ -0,0 +1,21 @@ +export const currencyFloatNoSymbol = num => { + if (num !== undefined && num !== null) { + if (num.toString().indexOf('.') != -1) { + return num + .toFixed(2) + .replace('.', ',') + .replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.'); + } else { + var rupiah = ''; + var numrev = num.toString().split('').reverse().join(''); + for (var i = 0; i < numrev.length; i++) + if (i % 3 == 0) rupiah += numrev.substr(i, 3) + '.'; + return rupiah + .split('', rupiah.length - 1) + .reverse() + .join(''); + } + } else { + return 0; + } +}; diff --git a/src/helpers/index.js b/src/helpers/index.js new file mode 100644 index 0000000..8442ae6 --- /dev/null +++ b/src/helpers/index.js @@ -0,0 +1,2 @@ +export * from './common'; +export * from './currency'; \ No newline at end of file diff --git a/src/navigations/app-navigator.js b/src/navigations/app-navigator.js index 9da8bda..15827db 100644 --- a/src/navigations/app-navigator.js +++ b/src/navigations/app-navigator.js @@ -1,12 +1,19 @@ import React from 'react'; -import {createNativeStackNavigator} from '@react-navigation/native-stack'; +import {CardStyleInterpolators, createStackNavigator} from '@react-navigation/stack'; import {Home} from 'scenes'; import TabStack from './tab-navigation'; +import {Selling} from 'scenes'; -const AppStack = createNativeStackNavigator(); +const AppStack = createStackNavigator(); const AppStackScreen = () => ( - + + ); diff --git a/src/navigations/auth-navigator.js b/src/navigations/auth-navigator.js index 369915f..5e23574 100644 --- a/src/navigations/auth-navigator.js +++ b/src/navigations/auth-navigator.js @@ -1,6 +1,6 @@ /* eslint-disable prettier/prettier */ import React from 'react'; -import {createNativeStackNavigator} from '@react-navigation/native-stack'; +import {createStackNavigator} from '@react-navigation/stack'; import { Login, Register, @@ -15,7 +15,7 @@ import { AddProduct, } from 'scenes'; -const AuthStack = createNativeStackNavigator(); +const AuthStack = createStackNavigator(); const AuthStackScreen = () => { return ( diff --git a/src/navigations/index.js b/src/navigations/index.js index 54e8e36..1389918 100644 --- a/src/navigations/index.js +++ b/src/navigations/index.js @@ -1,21 +1,21 @@ import React from 'react'; import {NavigationContainer} from '@react-navigation/native'; -import {createNativeStackNavigator} from '@react-navigation/native-stack'; +import {createStackNavigator} from '@react-navigation/stack'; import AuthStack from './auth-navigator'; import AppStack from './app-navigator'; import {useSelector} from 'react-redux'; -const RootStack = createNativeStackNavigator(); +const RootStack = createStackNavigator(); const RootStackScreen = ({userToken}) => { return ( - - {/* {userToken ? ( + {/* */} + {userToken ? ( ) : ( - )} */} + )} ); }; diff --git a/src/navigations/tab-navigation.js b/src/navigations/tab-navigation.js index b93f5d7..b8009ce 100644 --- a/src/navigations/tab-navigation.js +++ b/src/navigations/tab-navigation.js @@ -1,52 +1,51 @@ -// import React from 'react'; -// import {Dimensions, Image} from 'react-native'; -// import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; -// import {RFValue} from 'react-native-responsive-fontsize'; -// import {TabIcon as Icons} from 'constants'; -// import {Colors, FONTS} from 'global-styles'; -// import {Home} from 'scenes'; +import React from 'react'; +import {Dimensions, Image} from 'react-native'; +import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; +import {RFValue} from 'react-native-responsive-fontsize'; +import {TabIcon as Icons} from 'constants'; +import {Colors, FONTS} from 'global-styles'; +import {Home} from 'scenes'; -// const {width} = Dimensions.get('window'); +const {width} = Dimensions.get('window'); -// const TabStack = createBottomTabNavigator(); +const TabStack = createBottomTabNavigator(); -// const TabIcon = ({routeName, focused, color, size}) => { -// const icon = Icons.find(el => el.label === routeName); -// return ( -// -// ); -// }; +const TabIcon = ({routeName, focused, color, size}) => { + const icon = Icons.find(el => el.label === routeName); + return ( + + ); +}; -// const TabStackScreen = () => { -// return ( -// ({ -// tabBarIcon: ({focused}) => { -// return ( -// -// ); -// }, -// headerShown: false, -// tabBarActiveTintColor: Colors.TEXT, -// tabBarInactiveTintColor: Colors.GREY_TEXT, -// tabBarLabelStyle: { -// fontFamily: FONTS.poppins[500], -// fontSize: RFValue(8), -// }, -// })}> -// -// -// -// -// -// ); -// }; +const TabStackScreen = () => { + return ( + ({ + tabBarIcon: ({focused}) => { + return ( + + ); + }, + headerShown: false, + tabBarActiveTintColor: Colors.PRIMARY, + tabBarInactiveTintColor: Colors.GREY_TEXT, + tabBarLabelStyle: { + fontFamily: FONTS.poppins[500], + fontSize: RFValue(8), + }, + })}> + + + + + ); +}; -// export default TabStackScreen; +export default TabStackScreen; diff --git a/src/reducers/auth-reducer.js b/src/reducers/auth.reducer.js similarity index 70% rename from src/reducers/auth-reducer.js rename to src/reducers/auth.reducer.js index c0287d6..ed7f6f3 100644 --- a/src/reducers/auth-reducer.js +++ b/src/reducers/auth.reducer.js @@ -6,13 +6,15 @@ const initialState = { }; export default (state = initialState, action) => { - const newState = {...state}; + let newState = {...state}; switch (action.type) { case ActionType.SIGN_IN: - newState.userToken = action.payload.data; + newState.userToken = action.payload.token; + newState.data = action.payload.user; return newState; case ActionType.SIGN_OUT: newState.userToken = undefined; + newState.data = undefined; return newState; default: return state; diff --git a/src/reducers/index.js b/src/reducers/index.js index 0ffa40a..7a15a1e 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -2,10 +2,12 @@ import {combineReducers} from 'redux'; import AsyncStorage from '@react-native-async-storage/async-storage'; import {ActionType} from 'constants'; -import AuthReducer from './auth-reducer'; +import AuthReducer from './auth.reducer'; +import SaleOrderReducer from './sale-order.reducer'; const appReducer = combineReducers({ auth: AuthReducer, + saleOrder: SaleOrderReducer, }); const rootReducer = (state, action) => { diff --git a/src/reducers/sale-order.reducer.js b/src/reducers/sale-order.reducer.js new file mode 100644 index 0000000..aa396dd --- /dev/null +++ b/src/reducers/sale-order.reducer.js @@ -0,0 +1,16 @@ +import {ActionType} from 'constants'; + +const initialState = { + data: [], +}; + +export default (state = initialState, action) => { + const newState = {...state}; + switch (action.type) { + case ActionType.STORE_SALE_ORDER_PRODUCTS: + newState.data = action.payload.data; + return newState; + default: + return state; + } +}; diff --git a/src/scenes/Home/index.js b/src/scenes/Home/index.js new file mode 100644 index 0000000..e3cd870 --- /dev/null +++ b/src/scenes/Home/index.js @@ -0,0 +1,68 @@ +import React from 'react'; +import { View,Text, TouchableOpacity, Touchable, Pressable } from 'react-native'; +import { Container, Icon } from 'components'; +import { useDispatch, useSelector } from 'react-redux'; +import { signOut } from 'actions'; +import { Colors, FONTS } from 'global-styles' +import { RFValue } from 'react-native-responsive-fontsize'; +import menu from './menu'; +import AsyncStorage from '@react-native-async-storage/async-storage'; + +const MenuButton = ({title, name, type}) => ( + + + + + {title} + +); + +const Home = ({ navigation }) => { + const dispatch = useDispatch(); + const profile = useSelector(state => state.auth.data); + const cleanReduxState = () => { + AsyncStorage.clear(); + dispatch(signOut()); + }; + + return ( + + + {profile ? profile.outlet_name.toUpperCase() : ''} + + + {menu.map(val => ( + <> + + + ))} + + navigation.navigate('Selling')}> + MULAI JUALAN + + + Total Penjualan + Jumlah Nominal Penjualan + + cleanReduxState()}> + Logout + + + ); +} + +export default Home; \ No newline at end of file diff --git a/src/scenes/Home/menu.js b/src/scenes/Home/menu.js new file mode 100644 index 0000000..56861cd --- /dev/null +++ b/src/scenes/Home/menu.js @@ -0,0 +1,22 @@ +module.exports = [ + { + label: 'Produk', + name: 'box', + type: 'FontAwesome5', + }, + { + label: 'Pembelian', + name: 'cart-plus', + type: 'MaterialCommunityIcons', + }, + { + label: 'Karyawan', + name: 'md-people-outline', + type: 'Ionicons', + }, + { + label: 'Laporan', + name: 'chart-line', + type: 'MaterialCommunityIcons', + }, +]; diff --git a/src/scenes/Home/styles.js b/src/scenes/Home/styles.js new file mode 100644 index 0000000..e69de29 diff --git a/src/scenes/Login/index.js b/src/scenes/Login/index.js index f184b4b..829008c 100644 --- a/src/scenes/Login/index.js +++ b/src/scenes/Login/index.js @@ -1,20 +1,16 @@ -import React, {useState} from 'react'; +import React, {useRef} from 'react'; import { View, Text, TouchableOpacity, TextInput, - ActivityIndicator, - Image, - KeyboardAvoidingView, - Platform, + ScrollView, } from 'react-native'; import { Container, Icon, ModalOTP, ModalError, - ModalLanguage, Button, } from 'components'; import {Colors} from 'global-styles'; @@ -22,13 +18,24 @@ import styles from './styles'; import {useKeyboard} from 'utilities'; import useLogin from './useLogin'; import {useTranslation} from 'react-i18next'; - -const Login = ({route, navigation}) => { +import { RFValue } from 'react-native-responsive-fontsize'; +import { userLogin } from 'services'; +import { useDispatch} from 'react-redux'; +import {signIn} from 'actions'; +import AsyncStorage from '@react-native-async-storage/async-storage'; + +const Login = ({route, navigation}, props) => { const {t, i18n} = useTranslation(); const keyboardHeight = useKeyboard(); + const passwordInputRef = useRef(); + const dispatch = useDispatch(); const { - phone, - setPhone, + email, + setEmail, + password, + setPassword, + isPasswordVisible, + setIsPasswordVisible, modalOTP, otpCode, setOTPCode, @@ -36,16 +43,30 @@ const Login = ({route, navigation}) => { error, modal, setModal, - setModalLanguage, - modalLanguage, } = useLogin(navigation); + + const onLogin = async () => { + const payload = { + email: email.toLowerCase(), + password: password, + }; + + const res = await userLogin(payload); + console.log(res); + if (res._error) { + console.log(res._error); + } else { + await AsyncStorage.setItem('token', res._data.user_token.access_token); + dispatch(signIn({ + token: res._data.user_token, + user: res._data.user, + })); + } + }; + return ( - - - - + {/* setModalLanguage(true)} style={styles.translateButton}> { } style={styles.translateButtonImage} /> - + */} + - + /> */} - {t('welcome_text')} - - Through a wide range of caterers & brand partners, personalized - services - + Naise - {t('phone_input')}{' '} - * + Email - - 🇮🇩 +62 - setPhone(val)} - placeholder="Nomor HP" - keyboardType="number-pad" - autoFocus={true} + value={email} + onChangeText={val => setEmail(val)} + placeholder="email@gmail.com" + returnKeyType='next' + onSubmitEditing={() => passwordInputRef.current.focus()} /> - setPhone('')}> - - {error?.phone?.message && ( {error.phone.message} )} - - - {t('phone_issue')} - - + + Password + + + + setPassword(val)} + placeholder="Password" + /> + + setIsPasswordVisible(!isPasswordVisible)} + > + + + + {error?.phone?.message && ( + {error.phone.message} + )}