migrate naise pos
@ -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',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
5
.vscode/settings.json
vendored
@ -1,3 +1,6 @@
|
||||
{
|
||||
"nuxt.isNuxtApp": false
|
||||
"nuxt.isNuxtApp": false,
|
||||
"editor.tabSize": 2,
|
||||
"editor.useTabStops": true,
|
||||
"editor.detectIndentation": false,
|
||||
}
|
5
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 (
|
||||
<Provider store={store}>
|
||||
<PersistGate persistor={persistor}>
|
||||
|
@ -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">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
@ -12,7 +12,8 @@
|
||||
"services": ["src/services/*"],
|
||||
"store": ["src/store/*"],
|
||||
"global-styles": ["src/styles/*"],
|
||||
"utilities": ["src/utilities/*"]
|
||||
"utilities": ["src/utilities/*"],
|
||||
"helpers": ["src/helpers/*"]
|
||||
}
|
||||
}
|
||||
}
|
10
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",
|
||||
|
@ -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,
|
||||
},
|
||||
});
|
||||
|
@ -1 +1,2 @@
|
||||
export * from './auth-action';
|
||||
export * from './auth.action';
|
||||
export * from './sale-order.action';
|
||||
|
8
src/actions/sale-order.action.js
Normal file
@ -0,0 +1,8 @@
|
||||
import {ActionType} from 'constants';
|
||||
|
||||
export const addProductSale = data => ({
|
||||
type: ActionType.STORE_SALE_ORDER_PRODUCTS,
|
||||
payload: {
|
||||
data: data,
|
||||
},
|
||||
});
|
BIN
src/assets/images/login_1.png
Normal file
After Width: | Height: | Size: 236 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/images/tab-icons/home_active.png
Normal file
After Width: | Height: | Size: 904 B |
BIN
src/assets/images/tab-icons/home_inactive.png
Normal file
After Width: | Height: | Size: 777 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.8 KiB |
BIN
src/assets/images/tab-icons/other_active.png
Normal file
After Width: | Height: | Size: 448 B |
BIN
src/assets/images/tab-icons/other_inactive.png
Normal file
After Width: | Height: | Size: 385 B |
BIN
src/assets/images/tab-icons/pembelian_active.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/images/tab-icons/pembelian_inactive.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/images/tab-icons/transaksi_active.png
Normal file
After Width: | Height: | Size: 525 B |
BIN
src/assets/images/tab-icons/transaksi_inactive.png
Normal file
After Width: | Height: | Size: 476 B |
47
src/components/Button/DefaultPressable/index.js
Normal file
@ -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,
|
||||
}) => (
|
||||
<Pressable
|
||||
style={styles(isOutline, disabled)}
|
||||
android_ripple={{color: Colors.TERTIARY}}
|
||||
android_disableSound
|
||||
onPress={onPress}
|
||||
disabled={disabled}
|
||||
onLongPress={onLongPress}
|
||||
>
|
||||
{loading ? (
|
||||
<ActivityIndicator size="small" color={isOutline} />
|
||||
) : (
|
||||
<Text style={styles(isOutline, disabled).title}>{title}</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
);
|
||||
|
||||
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;
|
80
src/components/Card/TransactionProductCard/index.js
Normal file
@ -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 => (
|
||||
<TouchableWithoutFeedback onPress={props.onAdd}>
|
||||
<View style={style.cardProduct}>
|
||||
{props.data.image.Valid ? (
|
||||
<ImageBackground
|
||||
source={{uri: RestConstant.BASE_URL + props.data.image.String}}
|
||||
resizeMode="cover"
|
||||
style={style.thumbnail}
|
||||
imageStyle={{
|
||||
borderTopLeftRadius: RFValue(5),
|
||||
borderTopRightRadius: RFValue(5),
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<View style={style.thumbnail}>
|
||||
<Text
|
||||
style={{
|
||||
color: Colors.SECONDARY,
|
||||
fontFamily: FONTS.poppins[500],
|
||||
fontSize: RFValue(32),
|
||||
textAlign: 'center',
|
||||
}}>
|
||||
{cutStringProduct(props.data.name)}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
<View>
|
||||
<Text style={{color: 'black'}} numberOfLines={2}>
|
||||
{props.data.name}
|
||||
</Text>
|
||||
<Text style={style.cardPrice}>
|
||||
Rp {currencyFloatNoSymbol(parseFloat(props.data.selling_price))}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
|
||||
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),
|
||||
},
|
||||
});
|
5
src/components/Card/TransactionProductCard/styles.js
Normal file
@ -0,0 +1,5 @@
|
||||
import { StyleSheet } from "react-native";
|
||||
|
||||
export default StyleSheet.create({
|
||||
|
||||
})
|
@ -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}) => (
|
||||
<SafeAreaProvider
|
||||
style={[{...defaultStyle, ...{backgroundColor: backgroundColor}}]}>
|
||||
<StatusBar barStyle={barStyle} backgroundColor={barColor} />
|
||||
<SafeAreaView style={{flex: 1}}>{children}</SafeAreaView>
|
||||
<SafeAreaView style={[safeAreaStyleProps, {flex: 1}]}>{children}</SafeAreaView>
|
||||
</SafeAreaProvider>
|
||||
);
|
||||
|
||||
|
107
src/components/Header/SellHeader/index.js
Normal file
@ -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) => (
|
||||
<TouchableWithoutFeedback onPress={props.close}>
|
||||
<Icon name="search" type='Feather' style={{
|
||||
fontSize:RFValue(18),
|
||||
color: props.cus ? '#E0E0E0' : '#E1E1E1',
|
||||
marginRight:RFValue(-5),
|
||||
marginTop: 2
|
||||
}}/>
|
||||
</TouchableWithoutFeedback>
|
||||
)
|
||||
|
||||
const SearchIconRemove = () => (
|
||||
<View style={styles.searchRemove}>
|
||||
<Icon name="close" type='AntDesign' style={{fontSize:RFValue(8),color : Colors.WHITE}}/>
|
||||
</View>
|
||||
)
|
||||
|
||||
const FilterTab = ({ data, filter, onPress, secondary }) => (
|
||||
<View style={{ height: RFValue(35), flexDirection: 'row', backgroundColor: secondary ? Colors.WHITE : Colors.SECONDARY }}>
|
||||
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
|
||||
{data.map((item, index) => (
|
||||
<TouchableOpacity
|
||||
activeOpacity={0.5}
|
||||
style={{
|
||||
paddingHorizontal: RFValue(15),
|
||||
justifyContent: 'center',
|
||||
borderBottomWidth: RFValue(3),
|
||||
borderColor: index == filter ? (secondary ? Colors.PRIMARY : 'blue') : (secondary ? Colors.WHITE : Colors.PRIMARY)
|
||||
}}
|
||||
onPress={() => onPress({ index: index, item: item})}
|
||||
>
|
||||
<Text style={{ color: 'black'}}>{item.name}</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
)
|
||||
|
||||
const SellHeader = ({setSearch, searchValue, navigation, categories}) => (
|
||||
<View style={{elevation: 1, backgroundColor: Colors.SECONDARY}}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
height: RFValue(45),
|
||||
paddingRight: RFValue(5),
|
||||
}}>
|
||||
<TouchableOpacity
|
||||
activeOpacity={0.5}
|
||||
style={{
|
||||
width: RFValue(30),
|
||||
marginHorizontal: RFValue(5),
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
onPress={() => navigation.goBack()}>
|
||||
<Icon
|
||||
name="chevron-left"
|
||||
type="Feather"
|
||||
style={{
|
||||
color: Colors.WHITE,
|
||||
// marginLeft: RFValue(-20),
|
||||
fontSize: RFValue(18),
|
||||
}}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<View style={{flex: 1, justifyContent: 'center'}}>
|
||||
<SearchInput
|
||||
inputViewStyles={{backgroundColor: Colors.PRIMARY, borderRadius: 7}}
|
||||
onChangeText={setSearch}
|
||||
placeholder={'Cari produk...'}
|
||||
placeholderTextColor={Colors.WHITE}
|
||||
style={styles.searchBar}
|
||||
clearIconViewStyles={styles.searchIconRemove}
|
||||
clearIcon={
|
||||
searchValue != '' ? <SearchIconRemove /> : <SearchIcon cus />
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
activeOpacity={0.5}
|
||||
style={styles.buttonFilter}
|
||||
onPress={() => alert('barcode')}>
|
||||
<Icon
|
||||
name="barcode-scan"
|
||||
type="MaterialCommunityIcons"
|
||||
style={styles.iconBarcode}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
{/* <CashierKeep navigation={this.props.navigation} /> */}
|
||||
</View>
|
||||
<FilterTab
|
||||
data={categories}
|
||||
onPress={(index, item) => alert(index, item)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
export default SellHeader;
|
35
src/components/Header/SellHeader/styles.js
Normal file
@ -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),
|
||||
}
|
||||
});
|
@ -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,
|
||||
|
@ -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';
|
||||
|
@ -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 => {
|
||||
|
@ -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`,
|
||||
};
|
||||
|
@ -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'),
|
||||
},
|
||||
];
|
||||
|
16
src/helpers/common.js
Normal file
@ -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;
|
||||
};
|
21
src/helpers/currency.js
Normal file
@ -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;
|
||||
}
|
||||
};
|
2
src/helpers/index.js
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './common';
|
||||
export * from './currency';
|
@ -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 = () => (
|
||||
<AppStack.Navigator screenOptions={{headerShown: false}}>
|
||||
<AppStack.Navigator screenOptions={{
|
||||
gestureEnabled: true,
|
||||
gestureDirection: 'horizontal',
|
||||
headerShown: false,
|
||||
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS
|
||||
}}>
|
||||
<AppStack.Screen name="Home" component={TabStack} />
|
||||
<AppStack.Screen name="Selling" component={Selling}/>
|
||||
</AppStack.Navigator>
|
||||
);
|
||||
|
||||
|
@ -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 (
|
||||
|
@ -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 (
|
||||
<RootStack.Navigator screenOptions={{headerShown: false}}>
|
||||
<RootStack.Screen name="Unauthorized" component={AuthStack} />
|
||||
{/* {userToken ? (
|
||||
{/* <RootStack.Screen name="Unauthorized" component={AuthStack} /> */}
|
||||
{userToken ? (
|
||||
<RootStack.Screen name="App" component={AppStack} />
|
||||
) : (
|
||||
<RootStack.Screen name="Unauthorized" component={AuthStack} />
|
||||
)} */}
|
||||
)}
|
||||
</RootStack.Navigator>
|
||||
);
|
||||
};
|
||||
|
@ -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 (
|
||||
// <Image
|
||||
// source={focused ? icon.active : icon.inactive}
|
||||
// style={{width: width * 0.06, height: width * 0.06}}
|
||||
// />
|
||||
// );
|
||||
// };
|
||||
const TabIcon = ({routeName, focused, color, size}) => {
|
||||
const icon = Icons.find(el => el.label === routeName);
|
||||
return (
|
||||
<Image
|
||||
source={focused ? icon.active : icon.inactive}
|
||||
style={{width: width * 0.06, height: width * 0.06}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
// const TabStackScreen = () => {
|
||||
// return (
|
||||
// <TabStack.Navigator
|
||||
// screenOptions={({route}) => ({
|
||||
// tabBarIcon: ({focused}) => {
|
||||
// return (
|
||||
// <TabIcon
|
||||
// routeName={route.name}
|
||||
// focused={focused}
|
||||
// color={focused ? Colors.PRIMARY : Colors.LINE_STROKE}
|
||||
// />
|
||||
// );
|
||||
// },
|
||||
// headerShown: false,
|
||||
// tabBarActiveTintColor: Colors.TEXT,
|
||||
// tabBarInactiveTintColor: Colors.GREY_TEXT,
|
||||
// tabBarLabelStyle: {
|
||||
// fontFamily: FONTS.poppins[500],
|
||||
// fontSize: RFValue(8),
|
||||
// },
|
||||
// })}>
|
||||
// <TabStack.Screen name="Explore" component={Home} />
|
||||
// <TabStack.Screen name="Orders" component={Home} />
|
||||
// <TabStack.Screen name="Inbox" component={Home} />
|
||||
// <TabStack.Screen name="Profile" component={Home} />
|
||||
// </TabStack.Navigator>
|
||||
// );
|
||||
// };
|
||||
const TabStackScreen = () => {
|
||||
return (
|
||||
<TabStack.Navigator
|
||||
screenOptions={({route}) => ({
|
||||
tabBarIcon: ({focused}) => {
|
||||
return (
|
||||
<TabIcon
|
||||
routeName={route.name}
|
||||
focused={focused}
|
||||
color={focused ? Colors.PRIMARY : Colors.LINE_STROKE}
|
||||
/>
|
||||
);
|
||||
},
|
||||
headerShown: false,
|
||||
tabBarActiveTintColor: Colors.PRIMARY,
|
||||
tabBarInactiveTintColor: Colors.GREY_TEXT,
|
||||
tabBarLabelStyle: {
|
||||
fontFamily: FONTS.poppins[500],
|
||||
fontSize: RFValue(8),
|
||||
},
|
||||
})}>
|
||||
<TabStack.Screen name="Home" component={Home} />
|
||||
<TabStack.Screen name="Transaksi" component={Home} />
|
||||
<TabStack.Screen name="Lainnya" component={Home} />
|
||||
</TabStack.Navigator>
|
||||
);
|
||||
};
|
||||
|
||||
// export default TabStackScreen;
|
||||
export default TabStackScreen;
|
||||
|
@ -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;
|
@ -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) => {
|
||||
|
16
src/reducers/sale-order.reducer.js
Normal file
@ -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;
|
||||
}
|
||||
};
|
68
src/scenes/Home/index.js
Normal file
@ -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}) => (
|
||||
<View style={{ alignItems: 'center'}}>
|
||||
<View style={{ backgroundColor: Colors.TERTIARY, borderRadius: 10, padding: 5, alignItems: 'center', width: RFValue(36), height: RFValue(36), marginBottom: RFValue(5), justifyContent: 'center'}}>
|
||||
<Icon
|
||||
name={name}
|
||||
type={type}
|
||||
style={{color: Colors.PRIMARY, fontSize: RFValue(16)}}
|
||||
/>
|
||||
</View>
|
||||
<Text style={{color: 'black', fontFamily: FONTS.poppins[400], fontSize: RFValue(10)}}>{title}</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
const Home = ({ navigation }) => {
|
||||
const dispatch = useDispatch();
|
||||
const profile = useSelector(state => state.auth.data);
|
||||
const cleanReduxState = () => {
|
||||
AsyncStorage.clear();
|
||||
dispatch(signOut());
|
||||
};
|
||||
|
||||
return (
|
||||
<Container backgroundColor={Colors.WHITE} safeAreaStyleProps={{margin: 10}}>
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: FONTS.poppins[700],
|
||||
color: Colors.PRIMARY,
|
||||
fontSize: RFValue(18),
|
||||
}}>
|
||||
{profile ? profile.outlet_name.toUpperCase() : ''}
|
||||
</Text>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
marginHorizontal: RFValue(10),
|
||||
}}>
|
||||
{menu.map(val => (
|
||||
<>
|
||||
<MenuButton title={val.label} name={val.name} type={val.type} />
|
||||
</>
|
||||
))}
|
||||
</View>
|
||||
<TouchableOpacity onPress={() => navigation.navigate('Selling')}>
|
||||
<Text style={{color: 'black'}}>MULAI JUALAN</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={{flexDirection: 'row'}}>
|
||||
<Text style={{color: 'black'}}>Total Penjualan</Text>
|
||||
<Text style={{color: 'black'}}>Jumlah Nominal Penjualan</Text>
|
||||
</View>
|
||||
<TouchableOpacity onPress={() => cleanReduxState()}>
|
||||
<Text style={{color: 'black'}}>Logout</Text>
|
||||
</TouchableOpacity>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
export default Home;
|
22
src/scenes/Home/menu.js
Normal file
@ -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',
|
||||
},
|
||||
];
|
0
src/scenes/Home/styles.js
Normal file
@ -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 (
|
||||
<Container backgroundColor={Colors.WHITE}>
|
||||
<View style={styles.container}>
|
||||
<KeyboardAvoidingView
|
||||
style={{flex: 1}}
|
||||
behavior={Platform.OS === 'ios' ? 'height' : undefined}>
|
||||
<TouchableOpacity
|
||||
<Container backgroundColor={Colors.WHITE} safeAreaStyleProps={styles.container}>
|
||||
{/* <TouchableOpacity
|
||||
onPress={() => setModalLanguage(true)}
|
||||
style={styles.translateButton}>
|
||||
<Icon
|
||||
@ -61,75 +82,77 @@ const Login = ({route, navigation}) => {
|
||||
}
|
||||
style={styles.translateButtonImage}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</TouchableOpacity> */}
|
||||
<ScrollView
|
||||
keyboardShouldPersistTaps='always'
|
||||
>
|
||||
<View style={styles.boardingSection}>
|
||||
<Image
|
||||
source={require('assets/images/chef-pana.png')}
|
||||
{/* <Image
|
||||
source={require('assets/images/login_1.png')}
|
||||
style={styles.boardingImage}
|
||||
/>
|
||||
/> */}
|
||||
<View style={styles.boardingContentSection}>
|
||||
<Text style={styles.boardingTitle}>{t('welcome_text')}</Text>
|
||||
<Text style={styles.boardingSubTitle}>
|
||||
Through a wide range of caterers & brand partners, personalized
|
||||
services
|
||||
</Text>
|
||||
<Text style={styles.boardingTitle}>Naise</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.wrapper}>
|
||||
<View style={styles.formSection}>
|
||||
<Text style={styles.formLabel}>
|
||||
{t('phone_input')}{' '}
|
||||
<Text style={{color: Colors.PRIMARY}}>*</Text>
|
||||
Email
|
||||
</Text>
|
||||
<View style={styles.postSection}>
|
||||
<View style={styles.numberIdSection}>
|
||||
<Text style={styles.numberIdText}>🇮🇩 +62</Text>
|
||||
</View>
|
||||
<View style={styles.inputSection}>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
value={phone}
|
||||
onChangeText={val => 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()}
|
||||
/>
|
||||
<TouchableOpacity onPress={() => setPhone('')}>
|
||||
<Icon
|
||||
name="closecircle"
|
||||
type="AntDesign"
|
||||
style={styles.cleanInputIcon}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
{error?.phone?.message && (
|
||||
<Text style={styles.error}>{error.phone.message}</Text>
|
||||
)}
|
||||
<TouchableOpacity style={styles.phoneIssueButton}>
|
||||
<Text style={styles.phoneIssueButtonTitle}>
|
||||
{t('phone_issue')}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<Text style={[styles.formLabel, { marginTop: RFValue(20)}]}>
|
||||
Password
|
||||
</Text>
|
||||
<View style={styles.postSection}>
|
||||
<View style={styles.inputSection}>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
ref={passwordInputRef}
|
||||
value={password}
|
||||
secureTextEntry={!isPasswordVisible}
|
||||
onChangeText={val => setPassword(val)}
|
||||
placeholder="Password"
|
||||
/>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
onPress={() => setIsPasswordVisible(!isPasswordVisible)}
|
||||
>
|
||||
<Icon
|
||||
name={!isPasswordVisible ? "eye" : "eye-with-line"}
|
||||
type="Entypo"
|
||||
style={{ color: Colors.DARK_GREY, fontSize: RFValue(20) }}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
{error?.phone?.message && (
|
||||
<Text style={styles.error}>{error.phone.message}</Text>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.buttonSignInSection}>
|
||||
<Button
|
||||
title={t('login')}
|
||||
onPress={() => alert('login')}
|
||||
disabled={loading ? true : phone === '' ? true : false}
|
||||
onPress={() => onLogin()}
|
||||
disabled={loading ? true : email === '' ? true : false}
|
||||
loading={loading}
|
||||
/>
|
||||
<Text style={styles.textOr}>{t('or_text')}</Text>
|
||||
<Button
|
||||
title={t('register')}
|
||||
onPress={() => navigation.navigate('Register')}
|
||||
loading={loading}
|
||||
outline
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
</View>
|
||||
</ScrollView>
|
||||
<ModalOTP
|
||||
isVisible={modalOTP.visible}
|
||||
code={otpCode}
|
||||
@ -143,11 +166,6 @@ const Login = ({route, navigation}) => {
|
||||
message={modal.message}
|
||||
onClose={() => setModal({visible: false, message: ''})}
|
||||
/>
|
||||
<ModalLanguage
|
||||
isVisible={modalLanguage}
|
||||
onSave={() => setModalLanguage(false)}
|
||||
onClose={() => setModalLanguage(false)}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
@ -10,21 +10,17 @@ export default StyleSheet.create({
|
||||
},
|
||||
|
||||
boardingSection: {
|
||||
flex: 1.2,
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
boardingImage: {
|
||||
width: width * 0.7,
|
||||
height: width * 0.7,
|
||||
alignSelf: 'center',
|
||||
},
|
||||
boardingContentSection: {
|
||||
paddingBottom: width * 0.04,
|
||||
flex: 1,
|
||||
},
|
||||
// boardingImage: {
|
||||
// width: RFValue(300),
|
||||
// height: RFValue(240),
|
||||
// alignSelf: 'center',
|
||||
// },
|
||||
boardingTitle: {
|
||||
fontFamily: FONTS.poppins[700],
|
||||
fontSize: RFValue(21),
|
||||
color: Colors.BLACK,
|
||||
color: Colors.PRIMARY,
|
||||
},
|
||||
boardingSubTitle: {
|
||||
fontFamily: FONTS.poppins[400],
|
||||
@ -33,15 +29,18 @@ export default StyleSheet.create({
|
||||
marginTop: width * 0.01,
|
||||
marginRight: width * 0.05,
|
||||
},
|
||||
|
||||
boardingContentSection: {
|
||||
marginTop: RFValue(30),
|
||||
},
|
||||
wrapper: {
|
||||
flex: 1,
|
||||
backgroundColor: Colors.WHITE,
|
||||
justifyContent: 'center',
|
||||
marginTop: RFValue(10),
|
||||
},
|
||||
|
||||
//form section
|
||||
formSection: {
|
||||
paddingTop: width * 0.02,
|
||||
paddingVertical: RFValue(20),
|
||||
},
|
||||
formLabel: {
|
||||
fontFamily: FONTS.poppins[600],
|
||||
@ -52,6 +51,8 @@ export default StyleSheet.create({
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingTop: width * 0.02,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: Colors.DARK_GREY,
|
||||
},
|
||||
numberIdSection: {
|
||||
borderWidth: 1,
|
||||
@ -72,8 +73,7 @@ export default StyleSheet.create({
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: Colors.BLACK,
|
||||
|
||||
paddingVertical: width * 0.02,
|
||||
marginLeft: width * 0.02,
|
||||
},
|
||||
@ -87,6 +87,7 @@ export default StyleSheet.create({
|
||||
},
|
||||
cleanInputIcon: {
|
||||
fontSize: RFValue(12),
|
||||
color: 'black',
|
||||
},
|
||||
inputNote: {
|
||||
fontFamily: FONTS.poppins[400],
|
||||
@ -113,7 +114,7 @@ export default StyleSheet.create({
|
||||
|
||||
// button section
|
||||
buttonSignInSection: {
|
||||
// marginBottom: Platform.OS === 'ios' ? keyboardHeight : width * 0.05,
|
||||
marginTop: RFValue(50),
|
||||
},
|
||||
textOr: {
|
||||
fontFamily: FONTS.poppins[500],
|
||||
|
@ -1,7 +1,9 @@
|
||||
import {useState} from 'react';
|
||||
|
||||
const useLogin = navigation => {
|
||||
const [phone, setPhone] = useState('');
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [modalOTP, setModalOTP] = useState({visible: false, loading: false});
|
||||
const [otpCode, setOTPCode] = useState('');
|
||||
@ -13,8 +15,12 @@ const useLogin = navigation => {
|
||||
});
|
||||
|
||||
return {
|
||||
phone,
|
||||
setPhone,
|
||||
email,
|
||||
setEmail,
|
||||
password,
|
||||
setPassword,
|
||||
isPasswordVisible,
|
||||
setIsPasswordVisible,
|
||||
modalOTP,
|
||||
setModalOTP,
|
||||
otpCode,
|
||||
|
77
src/scenes/Selling/index.js
Normal file
@ -0,0 +1,77 @@
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import { Text, TouchableOpacity, View } from 'react-native';
|
||||
import { RFValue } from 'react-native-responsive-fontsize';
|
||||
import SearchInput, { createFilter } from 'react-native-search-filter';
|
||||
import { Container,Icon, SellHeader, TransactionProductCard } from 'components';
|
||||
import { Colors } from 'global-styles';
|
||||
import styles from './styles';
|
||||
import { getCategories,getProducts } from 'services';
|
||||
import { ScrollView } from 'react-native-gesture-handler';
|
||||
import { FlatGrid } from 'react-native-super-grid';
|
||||
const KEYS_TO_FILTERS = ['name', 'code'];
|
||||
|
||||
const Selling = ({ navigation,searchUpdated }) => {
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [products, setProducts] = useState([]);
|
||||
const [categories, setCategories] = useState([]);
|
||||
|
||||
getListCategories = async () => {
|
||||
const payload = {
|
||||
page_id: 1,
|
||||
page_size: 20,
|
||||
}
|
||||
|
||||
getCategories(payload).then((res) => {
|
||||
console.log("res");
|
||||
console.log(res);
|
||||
const data = [{name: 'Semua'}, ...res.data];
|
||||
setCategories(data)
|
||||
}).catch(err => {
|
||||
console.log("ERR")
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
getListProducts = async () => {
|
||||
const payload = {
|
||||
page_id: 1,
|
||||
page_size: 1000,
|
||||
};
|
||||
|
||||
getProducts(payload).then((res) => {
|
||||
setProducts(res.data);
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getListCategories();
|
||||
getListProducts();
|
||||
}, []);
|
||||
|
||||
// const filteredData = products.filter(createFilter(searchValue, KEYS_TO_FILTERS));
|
||||
|
||||
return (
|
||||
<Container backgroundColor={Colors.WHITE} barColor={Colors.SECONDARY} barStyle='light-content'>
|
||||
<SellHeader
|
||||
setSearch={(search) => setSearchValue(search)}
|
||||
searchValue={searchValue}
|
||||
navigation={navigation}
|
||||
categories={categories}
|
||||
/>
|
||||
<FlatGrid
|
||||
data={products}
|
||||
contentContainerStyle={{marginTop: RFValue(5)}}
|
||||
spacing={2}
|
||||
renderItem={({ item, index }) => (
|
||||
<TransactionProductCard
|
||||
data={item}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
export default Selling
|
7
src/scenes/Selling/styles.js
Normal file
@ -0,0 +1,7 @@
|
||||
import {StyleSheet} from 'react-native';
|
||||
import {RFValue} from 'react-native-responsive-fontsize';
|
||||
import {Colors} from 'global-styles';
|
||||
|
||||
export default StyleSheet.create({
|
||||
|
||||
});
|
@ -9,10 +9,14 @@ import MenuCategory from './Products/MenuCategory';
|
||||
import AddMenuCategory from './Products/MenuCategory/AddMenuCategory';
|
||||
import ProductList from './Products/ProductList';
|
||||
import AddProduct from './Products/ProductList/AddProduct';
|
||||
import Home from './Home';
|
||||
import Selling from './Selling';
|
||||
|
||||
export {
|
||||
Login,
|
||||
Register,
|
||||
Home,
|
||||
Selling,
|
||||
BusinessProfileRegistration,
|
||||
BusinessSummary,
|
||||
OutletSummary,
|
||||
|
@ -8,10 +8,11 @@ const initialState = {
|
||||
export const userLogin = async payload => {
|
||||
const newState = {...initialState};
|
||||
try {
|
||||
const response = await HttpRequest.post(RestConstant.login, payload);
|
||||
const response = await HttpRequest.postAuth(RestConstant.login, payload);
|
||||
console.log(response);
|
||||
switch (response.request.status) {
|
||||
case StatusCode.OK:
|
||||
newState._data = response.data;
|
||||
newState._data = response.data.data;
|
||||
return newState;
|
||||
case StatusCode.UNAUTHORIZED:
|
||||
newState._error = response.response.data;
|
||||
@ -43,30 +44,3 @@ export const userRegister = async payload => {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
export const verifyOTP = async (token, otp) => {
|
||||
const newState = {...initialState};
|
||||
try {
|
||||
const response = await HttpRequest.post(
|
||||
RestConstant.verifyOTP,
|
||||
{
|
||||
otp_code: otp,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'eboga-auth': token,
|
||||
},
|
||||
},
|
||||
);
|
||||
switch (response.request.status) {
|
||||
case StatusCode.OK:
|
||||
newState._data = response.data;
|
||||
return newState;
|
||||
case StatusCode.UNAUTHORIZED:
|
||||
newState._error = response.response.data;
|
||||
return newState;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
@ -1,2 +1,4 @@
|
||||
export * from './auth-services';
|
||||
export * from './master-service';
|
||||
export * from './product-categories.service';
|
||||
export * from './product.service';
|
||||
|
29
src/services/product-categories.service.js
Normal file
@ -0,0 +1,29 @@
|
||||
import {HttpRequest, RestConstant, StatusCode} from 'constants';
|
||||
|
||||
const initialState = {
|
||||
data: undefined,
|
||||
error: undefined,
|
||||
};
|
||||
|
||||
export const getCategories = async payload => {
|
||||
const newState = {...initialState};
|
||||
const url = `${RestConstant.productCategories}?page_id=${payload.page_id}&page_size=${payload.page_size}`;
|
||||
try {
|
||||
const response = await HttpRequest.get(url);
|
||||
console.log(response);
|
||||
switch (response.request.status) {
|
||||
case StatusCode.OK:
|
||||
newState.data = response.data;
|
||||
return newState;
|
||||
case StatusCode.UNAUTHORIZED:
|
||||
newState.error = response.response.data;
|
||||
return newState;
|
||||
case StatusCode.SERVER_ERROR:
|
||||
newState.error = response.response.data;
|
||||
return newState;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.log(error);
|
||||
}
|
||||
};
|
28
src/services/product.service.js
Normal file
@ -0,0 +1,28 @@
|
||||
import {StatusCode, HttpRequest, RestConstant} from 'constants';
|
||||
|
||||
const initialState = {
|
||||
data: undefined,
|
||||
error: undefined,
|
||||
};
|
||||
|
||||
export const getProducts = async payload => {
|
||||
const {page_id, page_size} = payload;
|
||||
const newState = {...initialState};
|
||||
const url = `${RestConstant.products}?page_id=${page_id}&page_size=${page_size}`;
|
||||
try {
|
||||
const response = await HttpRequest.get(url);
|
||||
switch (response.request.status) {
|
||||
case StatusCode.OK:
|
||||
newState.data = response.data;
|
||||
return newState;
|
||||
case StatusCode.UNAUTHORIZED:
|
||||
newState.error = response.response.data;
|
||||
return newState;
|
||||
case StatusCode.SERVER_ERROR:
|
||||
newState.error = response.response.data;
|
||||
return newState;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
@ -1,8 +1,13 @@
|
||||
export const PRIMARY = '#FD795B';
|
||||
// COLOR PALETTE https://colorhunt.co/palette/edf1d69dc08b60996640513b
|
||||
|
||||
export const PRIMARY = '#609966';
|
||||
export const SECONDARY = '#9DC08B';
|
||||
export const TERTIARY = '#EDF1D6';
|
||||
export const TEXT = '#4A4A4A';
|
||||
export const TEXT_LIGHT = '#666666';
|
||||
export const LINE_STROKE = '#EFEFEF';
|
||||
export const GREY = '#D9D9D9';
|
||||
export const DARK_GREY = '#c4c4c4';
|
||||
export const GREY_LIGHT = '#FAFAFA';
|
||||
export const GREY_TEXT = '#A2A2A2';
|
||||
export const GREEN = '#3B8628';
|
||||
|
89
yarn.lock
@ -772,6 +772,13 @@
|
||||
exec-sh "^0.3.2"
|
||||
minimist "^1.2.0"
|
||||
|
||||
"@egjs/hammerjs@^2.0.17":
|
||||
version "2.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@egjs/hammerjs/-/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124"
|
||||
integrity sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==
|
||||
dependencies:
|
||||
"@types/hammerjs" "^2.0.36"
|
||||
|
||||
"@eslint/eslintrc@^0.4.3":
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
|
||||
@ -1286,19 +1293,16 @@
|
||||
react-is "^16.13.0"
|
||||
use-latest-callback "^0.1.5"
|
||||
|
||||
"@react-navigation/elements@^1.3.17":
|
||||
version "1.3.17"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-1.3.17.tgz#9cb95765940f2841916fc71686598c22a3e4067e"
|
||||
integrity sha512-sui8AzHm6TxeEvWT/NEXlz3egYvCUog4tlXA4Xlb2Vxvy3purVXDq/XsM56lJl344U5Aj/jDzkVanOTMWyk4UA==
|
||||
|
||||
"@react-navigation/elements@^1.3.7":
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-1.3.7.tgz#40d80a7f34d645b605289da10bc4b6c3a7667215"
|
||||
integrity sha512-OZg2N/dd2tl6qkfrWvmUjFsYsbEyHEv4NbZSBuT+CR+d1pzmexN2IeVmi4cEMoR7U7GwhFcHRevF36yBsjU/dw==
|
||||
|
||||
"@react-navigation/native-stack@^6.9.1":
|
||||
version "6.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/native-stack/-/native-stack-6.9.2.tgz#8c861a59a2a86aaf25f0f33a990958edc36ddac4"
|
||||
integrity sha512-W5CYX+mYVyOYUgWoN15O34Pv/JieX2/pU09yh+kacxPHPEm4gYTQM/OIHACOov5T2WyiNSU6iIHjfzQ6e7M9zw==
|
||||
dependencies:
|
||||
"@react-navigation/elements" "^1.3.7"
|
||||
warn-once "^0.1.0"
|
||||
|
||||
"@react-navigation/native@^6.0.13":
|
||||
version "6.0.14"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-6.0.14.tgz#3ce3a4176ac7dc5495241d56a28db18449baf754"
|
||||
@ -1316,6 +1320,15 @@
|
||||
dependencies:
|
||||
nanoid "^3.1.23"
|
||||
|
||||
"@react-navigation/stack@^6.3.16":
|
||||
version "6.3.16"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-6.3.16.tgz#cf94e3c8c1587455515743e91d328beef722e0ab"
|
||||
integrity sha512-KTOn9cNuZ6p154Htbl2DiR95Wl+c7niLPRiGs7gjOkyVDGiaGQF9ODNQTYBDE1OxZGHe/EyYc6T2CbmiItLWDg==
|
||||
dependencies:
|
||||
"@react-navigation/elements" "^1.3.17"
|
||||
color "^4.2.3"
|
||||
warn-once "^0.1.0"
|
||||
|
||||
"@sideway/address@^4.1.3":
|
||||
version "4.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0"
|
||||
@ -1402,6 +1415,11 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/hammerjs@^2.0.36":
|
||||
version "2.0.41"
|
||||
resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.41.tgz#f6ecf57d1b12d2befcce00e928a6a097c22980aa"
|
||||
integrity sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA==
|
||||
|
||||
"@types/hoist-non-react-statics@^3.3.0":
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
|
||||
@ -1620,6 +1638,11 @@ acorn@^8.2.4:
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73"
|
||||
integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==
|
||||
|
||||
add@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/add/-/add-2.0.6.tgz#248f0a9f6e5a528ef2295dbeec30532130ae2235"
|
||||
integrity sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q==
|
||||
|
||||
agent-base@6:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
||||
@ -2586,6 +2609,11 @@ detect-newline@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
|
||||
integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
|
||||
|
||||
diacritics@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/diacritics/-/diacritics-1.3.0.tgz#3efa87323ebb863e6696cebb0082d48ff3d6f7a1"
|
||||
integrity sha512-wlwEkqcsaxvPJML+rDh/2iS824jbREk6DUMUKkEaSlxdYHeS43cClJtsWglvw2RfeXGm6ohKDqsXteJ5sP5enA==
|
||||
|
||||
diff-sequences@^26.6.2:
|
||||
version "26.6.2"
|
||||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1"
|
||||
@ -3308,6 +3336,11 @@ functions-have-names@^1.2.2:
|
||||
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
|
||||
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
|
||||
|
||||
fuse.js@^3.4.5:
|
||||
version "3.6.1"
|
||||
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.6.1.tgz#7de85fdd6e1b3377c23ce010892656385fd9b10c"
|
||||
integrity sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw==
|
||||
|
||||
gensync@^1.0.0-beta.2:
|
||||
version "1.0.0-beta.2"
|
||||
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
||||
@ -4673,7 +4706,7 @@ lodash.truncate@^4.4.2:
|
||||
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
|
||||
integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==
|
||||
|
||||
lodash@^4.17.10, lodash@^4.17.15, lodash@^4.7.0:
|
||||
lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.7.0:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
@ -5660,7 +5693,7 @@ prompts@^2.0.1, prompts@^2.4.0:
|
||||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.5"
|
||||
|
||||
prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
@ -5770,6 +5803,17 @@ react-native-dropdown-picker@^5.4.3:
|
||||
resolved "https://registry.yarnpkg.com/react-native-dropdown-picker/-/react-native-dropdown-picker-5.4.3.tgz#adc16cfa52e8f3481220b377dd780040c3debf96"
|
||||
integrity sha512-cwZzFcpyx/Stw3lZH2bvXxcsgwkR8c3rRZtOnlvyuN5pAplzA/9AiAxYlnJuspP9VvyU1XMePKOpgcHce6iyhA==
|
||||
|
||||
react-native-gesture-handler@^2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.9.0.tgz#2f63812e523c646f25b9ad660fc6f75948e51241"
|
||||
integrity sha512-a0BcH3Qb1tgVqUutc6d3VuWQkI1AM3+fJx8dkxzZs9t06qA27QgURYFoklpabuWpsUTzuKRpxleykp25E8m7tg==
|
||||
dependencies:
|
||||
"@egjs/hammerjs" "^2.0.17"
|
||||
hoist-non-react-statics "^3.3.0"
|
||||
invariant "^2.2.4"
|
||||
lodash "^4.17.21"
|
||||
prop-types "^15.7.2"
|
||||
|
||||
react-native-gradle-plugin@^0.70.3:
|
||||
version "0.70.3"
|
||||
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.70.3.tgz#cbcf0619cbfbddaa9128701aa2d7b4145f9c4fc8"
|
||||
@ -5828,6 +5872,26 @@ react-native-screens@^3.18.2:
|
||||
react-freeze "^1.0.0"
|
||||
warn-once "^0.1.0"
|
||||
|
||||
react-native-search-filter@^0.1.5:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/react-native-search-filter/-/react-native-search-filter-0.1.5.tgz#15d02f5c990d918532e06b1b0d226c9ae0ccd3a7"
|
||||
integrity sha512-uzA7/8XL93ez/uRKVjX2SxO0TrHi9awMWZxNMFWwisYvUDm2RaxuTc7TgAEOrogp+qhCYr3guet/A90AHqMSCg==
|
||||
dependencies:
|
||||
diacritics "^1.3.0"
|
||||
fuse.js "^3.4.5"
|
||||
|
||||
react-native-super-grid@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-super-grid/-/react-native-super-grid-5.0.0.tgz#0cf9cfb86864198a1e6925d26496bd005b319e3e"
|
||||
integrity sha512-iivBlleD7ufDtKSd74w1w86bvIzUXHaLjKwRuqMOUQwXxm5hoIGT8YtJiWtS5/bkH38xLw/T0eEn0NHFgzmYiA==
|
||||
dependencies:
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react-native-swipe-up-down@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-swipe-up-down/-/react-native-swipe-up-down-1.2.0.tgz#9a5f8282333343966e18a5914df78e5da49d2003"
|
||||
integrity sha512-pZa/EF3f85A/29thoLuVHHCNJO3GLN+zvuveW34qUgfJIvvx1Fh5dKMZlD2cHbOhhEvZaWds6MdrMQsoaTBRvw==
|
||||
|
||||
react-native-vector-icons@^9.2.0:
|
||||
version "9.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-vector-icons/-/react-native-vector-icons-9.2.0.tgz#3c0c82e95defd274d56363cbe8fead8d53167ebd"
|
||||
@ -7322,6 +7386,11 @@ yargs@^16.1.1:
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^20.2.2"
|
||||
|
||||
yarn@^1.22.19:
|
||||
version "1.22.19"
|
||||
resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.19.tgz#4ba7fc5c6e704fce2066ecbfb0b0d8976fe62447"
|
||||
integrity sha512-/0V5q0WbslqnwP91tirOvldvYISzaqhClxzyUKXYxs07yUILIs5jx/k6CFe8bvKSkds5w+eiOqta39Wk3WxdcQ==
|
||||
|
||||
yocto-queue@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||
|