migrate naise pos

This commit is contained in:
nochill 2023-04-14 23:33:18 +07:00
parent 130b4a4851
commit be131dcd60
62 changed files with 912 additions and 213 deletions

View File

@ -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',
},
},
},

View File

@ -1,3 +1,6 @@
{
"nuxt.isNuxtApp": false
"nuxt.isNuxtApp": false,
"editor.tabSize": 2,
"editor.useTabStops": true,
"editor.detectIndentation": false,
}

5
App.js
View File

@ -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}>

View File

@ -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" />

View File

@ -12,7 +12,8 @@
"services": ["src/services/*"],
"store": ["src/store/*"],
"global-styles": ["src/styles/*"],
"utilities": ["src/utilities/*"]
"utilities": ["src/utilities/*"],
"helpers": ["src/helpers/*"]
}
}
}

View File

@ -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",

View File

@ -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,
},
});

View File

@ -1 +1,2 @@
export * from './auth-action';
export * from './auth.action';
export * from './sale-order.action';

View File

@ -0,0 +1,8 @@
import {ActionType} from 'constants';
export const addProductSale = data => ({
type: ActionType.STORE_SALE_ORDER_PRODUCTS,
payload: {
data: data,
},
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

View 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;

View 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),
},
});

View File

@ -0,0 +1,5 @@
import { StyleSheet } from "react-native";
export default StyleSheet.create({
})

View File

@ -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>
);

View 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;

View 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),
}
});

View File

@ -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,

View File

@ -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';

View File

@ -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 => {

View File

@ -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`,
};

View File

@ -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
View 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
View 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
View File

@ -0,0 +1,2 @@
export * from './common';
export * from './currency';

View File

@ -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>
);

View File

@ -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 (

View File

@ -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>
);
};

View File

@ -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;

View File

@ -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;

View File

@ -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) => {

View 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
View 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
View 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',
},
];

View File

View 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>
);
};

View File

@ -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],

View File

@ -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,

View 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

View 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({
});

View File

@ -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,

View File

@ -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);
}
};

View File

@ -1,2 +1,4 @@
export * from './auth-services';
export * from './master-service';
export * from './product-categories.service';
export * from './product.service';

View 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);
}
};

View 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);
}
};

View File

@ -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';

View File

@ -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"