migrate naise pos
@ -2,6 +2,10 @@ module.exports = {
|
|||||||
root: true,
|
root: true,
|
||||||
extends: '@react-native-community',
|
extends: '@react-native-community',
|
||||||
plugins: ['import'],
|
plugins: ['import'],
|
||||||
|
rules: {
|
||||||
|
'prettier/prettier': ['error', {endOfLine: 'auto'}],
|
||||||
|
'react-native/no-inline-styles': 0,
|
||||||
|
},
|
||||||
settings: {
|
settings: {
|
||||||
'import/resolver': {
|
'import/resolver': {
|
||||||
node: {
|
node: {
|
||||||
@ -18,6 +22,7 @@ module.exports = {
|
|||||||
store: './src/store',
|
store: './src/store',
|
||||||
'global-styles': './src/styles',
|
'global-styles': './src/styles',
|
||||||
utilities: './src/utilities',
|
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 {Provider} from 'react-redux';
|
||||||
import configureStore from 'store';
|
import configureStore from 'store';
|
||||||
import {PersistGate} from 'redux-persist/integration/react';
|
import {PersistGate} from 'redux-persist/integration/react';
|
||||||
import {enableLatestRenderer} from 'react-native-maps';
|
import 'react-native-gesture-handler';
|
||||||
import 'moment/locale/id';
|
import 'moment/locale/id';
|
||||||
import 'utilities/i18';
|
import 'utilities/i18';
|
||||||
|
|
||||||
enableLatestRenderer();
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const {persistor, store} = configureStore();
|
const {store, persistor} = configureStore();
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<PersistGate persistor={persistor}>
|
<PersistGate persistor={persistor}>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:windowSoftInputMode="adjustResize"
|
android:windowSoftInputMode="adjustPan"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
"services": ["src/services/*"],
|
"services": ["src/services/*"],
|
||||||
"store": ["src/store/*"],
|
"store": ["src/store/*"],
|
||||||
"global-styles": ["src/styles/*"],
|
"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-native-async-storage/async-storage": "^1.17.11",
|
||||||
"@react-navigation/bottom-tabs": "^6.4.0",
|
"@react-navigation/bottom-tabs": "^6.4.0",
|
||||||
"@react-navigation/native": "^6.0.13",
|
"@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",
|
"axios": "^0.22.0",
|
||||||
"babel-plugin-module-resolver": "^4.1.0",
|
"babel-plugin-module-resolver": "^4.1.0",
|
||||||
"eslint-import-resolver-babel-module": "^5.3.1",
|
"eslint-import-resolver-babel-module": "^5.3.1",
|
||||||
@ -26,6 +27,7 @@
|
|||||||
"react-native": "0.70.6",
|
"react-native": "0.70.6",
|
||||||
"react-native-currency-input": "^1.1.0",
|
"react-native-currency-input": "^1.1.0",
|
||||||
"react-native-dropdown-picker": "^5.4.3",
|
"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-keyboard-aware-scroll-view": "^0.9.5",
|
||||||
"react-native-localize": "^2.2.4",
|
"react-native-localize": "^2.2.4",
|
||||||
"react-native-maps": "^1.3.2",
|
"react-native-maps": "^1.3.2",
|
||||||
@ -33,11 +35,15 @@
|
|||||||
"react-native-responsive-fontsize": "^0.5.1",
|
"react-native-responsive-fontsize": "^0.5.1",
|
||||||
"react-native-safe-area-context": "^4.4.1",
|
"react-native-safe-area-context": "^4.4.1",
|
||||||
"react-native-screens": "^3.18.2",
|
"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-native-vector-icons": "^9.2.0",
|
||||||
"react-redux": "^7.2.6",
|
"react-redux": "^7.2.6",
|
||||||
"redux": "^4.1.2",
|
"redux": "^4.1.2",
|
||||||
"redux-persist": "^6.0.0",
|
"redux-persist": "^6.0.0",
|
||||||
"redux-thunk": "^2.4.1"
|
"redux-thunk": "^2.4.1",
|
||||||
|
"yarn": "^1.22.19"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.9",
|
"@babel/core": "^7.12.9",
|
||||||
|
@ -3,7 +3,8 @@ import {ActionType} from 'constants';
|
|||||||
export const signIn = data => ({
|
export const signIn = data => ({
|
||||||
type: ActionType.SIGN_IN,
|
type: ActionType.SIGN_IN,
|
||||||
payload: {
|
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 = {
|
const defaultStyle = {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
};
|
};
|
||||||
const Container = ({children, backgroundColor, barStyle, barColor}) => (
|
const Container = ({children, backgroundColor, barStyle, barColor, safeAreaStyleProps}) => (
|
||||||
<SafeAreaProvider
|
<SafeAreaProvider
|
||||||
style={[{...defaultStyle, ...{backgroundColor: backgroundColor}}]}>
|
style={[{...defaultStyle, ...{backgroundColor: backgroundColor}}]}>
|
||||||
<StatusBar barStyle={barStyle} backgroundColor={barColor} />
|
<StatusBar barStyle={barStyle} backgroundColor={barColor} />
|
||||||
<SafeAreaView style={{flex: 1}}>{children}</SafeAreaView>
|
<SafeAreaView style={[safeAreaStyleProps, {flex: 1}]}>{children}</SafeAreaView>
|
||||||
</SafeAreaProvider>
|
</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 ModalError from './Modal/ModalError';
|
||||||
import ProductRegular from './Product/ProductRegular';
|
import ProductRegular from './Product/ProductRegular';
|
||||||
import Button from './Button';
|
import Button from './Button';
|
||||||
|
import DefaultPressable from './Button/DefaultPressable';
|
||||||
|
|
||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
|
import SellHeader from './Header/SellHeader';
|
||||||
|
|
||||||
|
import TransactionProductCard from './Card/TransactionProductCard';
|
||||||
|
|
||||||
import Input from './Input';
|
import Input from './Input';
|
||||||
import Note from './Note';
|
import Note from './Note';
|
||||||
import ModalSetHours from './Modal/ModalSetHours';
|
import ModalSetHours from './Modal/ModalSetHours';
|
||||||
@ -20,8 +26,11 @@ export {
|
|||||||
ModalLanguage,
|
ModalLanguage,
|
||||||
ModalError,
|
ModalError,
|
||||||
ProductRegular,
|
ProductRegular,
|
||||||
|
TransactionProductCard,
|
||||||
Button,
|
Button,
|
||||||
|
DefaultPressable,
|
||||||
Header,
|
Header,
|
||||||
|
SellHeader,
|
||||||
Input,
|
Input,
|
||||||
Note,
|
Note,
|
||||||
ModalSetHours,
|
ModalSetHours,
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
export const SIGN_IN = 'SIGN_IN';
|
export const SIGN_IN = 'SIGN_IN';
|
||||||
export const SIGN_OUT = 'SIGN_OUT';
|
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 Axios from 'axios';
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
|
|
||||||
|
// const {persistor, store} = configureStore();
|
||||||
|
const authAxios = Axios.create();
|
||||||
|
|
||||||
Axios.interceptors.request.use(
|
Axios.interceptors.request.use(
|
||||||
async config => {
|
async config => {
|
||||||
const token = await AsyncStorage.getItem('userToken');
|
const token = await AsyncStorage.getItem('token');
|
||||||
console.log('token ', token);
|
|
||||||
if (token) {
|
if (token) {
|
||||||
config.headers.Authorization = 'Bearer ' + token;
|
config.headers.Authorization = 'Bearer ' + token;
|
||||||
}
|
}
|
||||||
@ -16,6 +18,7 @@ Axios.interceptors.request.use(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const get = async (url, config = null) => {
|
export const get = async (url, config = null) => {
|
||||||
|
console.log(config);
|
||||||
return Axios.get(url, config)
|
return Axios.get(url, config)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
return 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) => {
|
export const put = (url, data, config = null) => {
|
||||||
return Axios.put(url, data, config)
|
return Axios.put(url, data, config)
|
||||||
.then(response => {
|
.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 {
|
export default {
|
||||||
login: `${baseUrl}/login`,
|
BASE_URL: `${baseUrl}/`,
|
||||||
|
login: `${baseUrl}/user/login`,
|
||||||
register: `${baseUrl}/register`,
|
register: `${baseUrl}/register`,
|
||||||
verifyOTP: `${baseUrl}/verify-otp`,
|
verifyOTP: `${baseUrl}/verify-otp`,
|
||||||
|
productCategories: `${baseUrl}/api/product/categories`,
|
||||||
|
products: `${baseUrl}/api/products`,
|
||||||
};
|
};
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
{
|
{
|
||||||
label: 'Explore',
|
label: 'Home',
|
||||||
active: require('assets/images/tab-icons/explore-active.png'),
|
active: require('assets/images/tab-icons/home_active.png'),
|
||||||
inactive: require('assets/images/tab-icons/explore-inactive.png'),
|
inactive: require('assets/images/tab-icons/home_inactive.png'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Orders',
|
label: 'Transaksi',
|
||||||
active: require('assets/images/tab-icons/order-active.png'),
|
active: require('assets/images/tab-icons/transaksi_active.png'),
|
||||||
inactive: require('assets/images/tab-icons/order-inactive.png'),
|
inactive: require('assets/images/tab-icons/transaksi_inactive.png'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Inbox',
|
label: 'Pembelian',
|
||||||
active: require('assets/images/tab-icons/inbox-active.png'),
|
active: require('assets/images/tab-icons/pembelian_active.png'),
|
||||||
inactive: require('assets/images/tab-icons/inbox-inactive.png'),
|
inactive: require('assets/images/tab-icons/pembelian_inactive.png'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Profile',
|
label: 'Lainnya',
|
||||||
active: require('assets/images/tab-icons/profile-active.png'),
|
active: require('assets/images/tab-icons/other_active.png'),
|
||||||
inactive: require('assets/images/tab-icons/profile-inactive.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 React from 'react';
|
||||||
import {createNativeStackNavigator} from '@react-navigation/native-stack';
|
import {CardStyleInterpolators, createStackNavigator} from '@react-navigation/stack';
|
||||||
import {Home} from 'scenes';
|
import {Home} from 'scenes';
|
||||||
import TabStack from './tab-navigation';
|
import TabStack from './tab-navigation';
|
||||||
|
import {Selling} from 'scenes';
|
||||||
|
|
||||||
const AppStack = createNativeStackNavigator();
|
const AppStack = createStackNavigator();
|
||||||
const AppStackScreen = () => (
|
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="Home" component={TabStack} />
|
||||||
|
<AppStack.Screen name="Selling" component={Selling}/>
|
||||||
</AppStack.Navigator>
|
</AppStack.Navigator>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable prettier/prettier */
|
/* eslint-disable prettier/prettier */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {createNativeStackNavigator} from '@react-navigation/native-stack';
|
import {createStackNavigator} from '@react-navigation/stack';
|
||||||
import {
|
import {
|
||||||
Login,
|
Login,
|
||||||
Register,
|
Register,
|
||||||
@ -15,7 +15,7 @@ import {
|
|||||||
AddProduct,
|
AddProduct,
|
||||||
} from 'scenes';
|
} from 'scenes';
|
||||||
|
|
||||||
const AuthStack = createNativeStackNavigator();
|
const AuthStack = createStackNavigator();
|
||||||
|
|
||||||
const AuthStackScreen = () => {
|
const AuthStackScreen = () => {
|
||||||
return (
|
return (
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {NavigationContainer} from '@react-navigation/native';
|
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 AuthStack from './auth-navigator';
|
||||||
import AppStack from './app-navigator';
|
import AppStack from './app-navigator';
|
||||||
import {useSelector} from 'react-redux';
|
import {useSelector} from 'react-redux';
|
||||||
|
|
||||||
const RootStack = createNativeStackNavigator();
|
const RootStack = createStackNavigator();
|
||||||
|
|
||||||
const RootStackScreen = ({userToken}) => {
|
const RootStackScreen = ({userToken}) => {
|
||||||
return (
|
return (
|
||||||
<RootStack.Navigator screenOptions={{headerShown: false}}>
|
<RootStack.Navigator screenOptions={{headerShown: false}}>
|
||||||
<RootStack.Screen name="Unauthorized" component={AuthStack} />
|
{/* <RootStack.Screen name="Unauthorized" component={AuthStack} /> */}
|
||||||
{/* {userToken ? (
|
{userToken ? (
|
||||||
<RootStack.Screen name="App" component={AppStack} />
|
<RootStack.Screen name="App" component={AppStack} />
|
||||||
) : (
|
) : (
|
||||||
<RootStack.Screen name="Unauthorized" component={AuthStack} />
|
<RootStack.Screen name="Unauthorized" component={AuthStack} />
|
||||||
)} */}
|
)}
|
||||||
</RootStack.Navigator>
|
</RootStack.Navigator>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,52 +1,51 @@
|
|||||||
// import React from 'react';
|
import React from 'react';
|
||||||
// import {Dimensions, Image} from 'react-native';
|
import {Dimensions, Image} from 'react-native';
|
||||||
// import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
|
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
|
||||||
// import {RFValue} from 'react-native-responsive-fontsize';
|
import {RFValue} from 'react-native-responsive-fontsize';
|
||||||
// import {TabIcon as Icons} from 'constants';
|
import {TabIcon as Icons} from 'constants';
|
||||||
// import {Colors, FONTS} from 'global-styles';
|
import {Colors, FONTS} from 'global-styles';
|
||||||
// import {Home} from 'scenes';
|
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 TabIcon = ({routeName, focused, color, size}) => {
|
||||||
// const icon = Icons.find(el => el.label === routeName);
|
const icon = Icons.find(el => el.label === routeName);
|
||||||
// return (
|
return (
|
||||||
// <Image
|
<Image
|
||||||
// source={focused ? icon.active : icon.inactive}
|
source={focused ? icon.active : icon.inactive}
|
||||||
// style={{width: width * 0.06, height: width * 0.06}}
|
style={{width: width * 0.06, height: width * 0.06}}
|
||||||
// />
|
/>
|
||||||
// );
|
);
|
||||||
// };
|
};
|
||||||
|
|
||||||
// const TabStackScreen = () => {
|
const TabStackScreen = () => {
|
||||||
// return (
|
return (
|
||||||
// <TabStack.Navigator
|
<TabStack.Navigator
|
||||||
// screenOptions={({route}) => ({
|
screenOptions={({route}) => ({
|
||||||
// tabBarIcon: ({focused}) => {
|
tabBarIcon: ({focused}) => {
|
||||||
// return (
|
return (
|
||||||
// <TabIcon
|
<TabIcon
|
||||||
// routeName={route.name}
|
routeName={route.name}
|
||||||
// focused={focused}
|
focused={focused}
|
||||||
// color={focused ? Colors.PRIMARY : Colors.LINE_STROKE}
|
color={focused ? Colors.PRIMARY : Colors.LINE_STROKE}
|
||||||
// />
|
/>
|
||||||
// );
|
);
|
||||||
// },
|
},
|
||||||
// headerShown: false,
|
headerShown: false,
|
||||||
// tabBarActiveTintColor: Colors.TEXT,
|
tabBarActiveTintColor: Colors.PRIMARY,
|
||||||
// tabBarInactiveTintColor: Colors.GREY_TEXT,
|
tabBarInactiveTintColor: Colors.GREY_TEXT,
|
||||||
// tabBarLabelStyle: {
|
tabBarLabelStyle: {
|
||||||
// fontFamily: FONTS.poppins[500],
|
fontFamily: FONTS.poppins[500],
|
||||||
// fontSize: RFValue(8),
|
fontSize: RFValue(8),
|
||||||
// },
|
},
|
||||||
// })}>
|
})}>
|
||||||
// <TabStack.Screen name="Explore" component={Home} />
|
<TabStack.Screen name="Home" component={Home} />
|
||||||
// <TabStack.Screen name="Orders" component={Home} />
|
<TabStack.Screen name="Transaksi" component={Home} />
|
||||||
// <TabStack.Screen name="Inbox" component={Home} />
|
<TabStack.Screen name="Lainnya" component={Home} />
|
||||||
// <TabStack.Screen name="Profile" component={Home} />
|
</TabStack.Navigator>
|
||||||
// </TabStack.Navigator>
|
);
|
||||||
// );
|
};
|
||||||
// };
|
|
||||||
|
|
||||||
// export default TabStackScreen;
|
export default TabStackScreen;
|
||||||
|
@ -6,13 +6,15 @@ const initialState = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default (state = initialState, action) => {
|
export default (state = initialState, action) => {
|
||||||
const newState = {...state};
|
let newState = {...state};
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case ActionType.SIGN_IN:
|
case ActionType.SIGN_IN:
|
||||||
newState.userToken = action.payload.data;
|
newState.userToken = action.payload.token;
|
||||||
|
newState.data = action.payload.user;
|
||||||
return newState;
|
return newState;
|
||||||
case ActionType.SIGN_OUT:
|
case ActionType.SIGN_OUT:
|
||||||
newState.userToken = undefined;
|
newState.userToken = undefined;
|
||||||
|
newState.data = undefined;
|
||||||
return newState;
|
return newState;
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
@ -2,10 +2,12 @@ import {combineReducers} from 'redux';
|
|||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
import {ActionType} from 'constants';
|
import {ActionType} from 'constants';
|
||||||
|
|
||||||
import AuthReducer from './auth-reducer';
|
import AuthReducer from './auth.reducer';
|
||||||
|
import SaleOrderReducer from './sale-order.reducer';
|
||||||
|
|
||||||
const appReducer = combineReducers({
|
const appReducer = combineReducers({
|
||||||
auth: AuthReducer,
|
auth: AuthReducer,
|
||||||
|
saleOrder: SaleOrderReducer,
|
||||||
});
|
});
|
||||||
|
|
||||||
const rootReducer = (state, action) => {
|
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 {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
TextInput,
|
TextInput,
|
||||||
ActivityIndicator,
|
ScrollView,
|
||||||
Image,
|
|
||||||
KeyboardAvoidingView,
|
|
||||||
Platform,
|
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import {
|
import {
|
||||||
Container,
|
Container,
|
||||||
Icon,
|
Icon,
|
||||||
ModalOTP,
|
ModalOTP,
|
||||||
ModalError,
|
ModalError,
|
||||||
ModalLanguage,
|
|
||||||
Button,
|
Button,
|
||||||
} from 'components';
|
} from 'components';
|
||||||
import {Colors} from 'global-styles';
|
import {Colors} from 'global-styles';
|
||||||
@ -22,13 +18,24 @@ import styles from './styles';
|
|||||||
import {useKeyboard} from 'utilities';
|
import {useKeyboard} from 'utilities';
|
||||||
import useLogin from './useLogin';
|
import useLogin from './useLogin';
|
||||||
import {useTranslation} from 'react-i18next';
|
import {useTranslation} from 'react-i18next';
|
||||||
|
import { RFValue } from 'react-native-responsive-fontsize';
|
||||||
const Login = ({route, navigation}) => {
|
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 {t, i18n} = useTranslation();
|
||||||
const keyboardHeight = useKeyboard();
|
const keyboardHeight = useKeyboard();
|
||||||
|
const passwordInputRef = useRef();
|
||||||
|
const dispatch = useDispatch();
|
||||||
const {
|
const {
|
||||||
phone,
|
email,
|
||||||
setPhone,
|
setEmail,
|
||||||
|
password,
|
||||||
|
setPassword,
|
||||||
|
isPasswordVisible,
|
||||||
|
setIsPasswordVisible,
|
||||||
modalOTP,
|
modalOTP,
|
||||||
otpCode,
|
otpCode,
|
||||||
setOTPCode,
|
setOTPCode,
|
||||||
@ -36,16 +43,30 @@ const Login = ({route, navigation}) => {
|
|||||||
error,
|
error,
|
||||||
modal,
|
modal,
|
||||||
setModal,
|
setModal,
|
||||||
setModalLanguage,
|
|
||||||
modalLanguage,
|
|
||||||
} = useLogin(navigation);
|
} = 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 (
|
return (
|
||||||
<Container backgroundColor={Colors.WHITE}>
|
<Container backgroundColor={Colors.WHITE} safeAreaStyleProps={styles.container}>
|
||||||
<View style={styles.container}>
|
{/* <TouchableOpacity
|
||||||
<KeyboardAvoidingView
|
|
||||||
style={{flex: 1}}
|
|
||||||
behavior={Platform.OS === 'ios' ? 'height' : undefined}>
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={() => setModalLanguage(true)}
|
onPress={() => setModalLanguage(true)}
|
||||||
style={styles.translateButton}>
|
style={styles.translateButton}>
|
||||||
<Icon
|
<Icon
|
||||||
@ -61,75 +82,77 @@ const Login = ({route, navigation}) => {
|
|||||||
}
|
}
|
||||||
style={styles.translateButtonImage}
|
style={styles.translateButtonImage}
|
||||||
/>
|
/>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity> */}
|
||||||
|
<ScrollView
|
||||||
|
keyboardShouldPersistTaps='always'
|
||||||
|
>
|
||||||
<View style={styles.boardingSection}>
|
<View style={styles.boardingSection}>
|
||||||
<Image
|
{/* <Image
|
||||||
source={require('assets/images/chef-pana.png')}
|
source={require('assets/images/login_1.png')}
|
||||||
style={styles.boardingImage}
|
style={styles.boardingImage}
|
||||||
/>
|
/> */}
|
||||||
<View style={styles.boardingContentSection}>
|
<View style={styles.boardingContentSection}>
|
||||||
<Text style={styles.boardingTitle}>{t('welcome_text')}</Text>
|
<Text style={styles.boardingTitle}>Naise</Text>
|
||||||
<Text style={styles.boardingSubTitle}>
|
|
||||||
Through a wide range of caterers & brand partners, personalized
|
|
||||||
services
|
|
||||||
</Text>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.wrapper}>
|
<View style={styles.wrapper}>
|
||||||
<View style={styles.formSection}>
|
<View style={styles.formSection}>
|
||||||
<Text style={styles.formLabel}>
|
<Text style={styles.formLabel}>
|
||||||
{t('phone_input')}{' '}
|
Email
|
||||||
<Text style={{color: Colors.PRIMARY}}>*</Text>
|
|
||||||
</Text>
|
</Text>
|
||||||
<View style={styles.postSection}>
|
<View style={styles.postSection}>
|
||||||
<View style={styles.numberIdSection}>
|
|
||||||
<Text style={styles.numberIdText}>🇮🇩 +62</Text>
|
|
||||||
</View>
|
|
||||||
<View style={styles.inputSection}>
|
<View style={styles.inputSection}>
|
||||||
<TextInput
|
<TextInput
|
||||||
style={styles.input}
|
style={styles.input}
|
||||||
value={phone}
|
value={email}
|
||||||
onChangeText={val => setPhone(val)}
|
onChangeText={val => setEmail(val)}
|
||||||
placeholder="Nomor HP"
|
placeholder="email@gmail.com"
|
||||||
keyboardType="number-pad"
|
returnKeyType='next'
|
||||||
autoFocus={true}
|
onSubmitEditing={() => passwordInputRef.current.focus()}
|
||||||
/>
|
/>
|
||||||
<TouchableOpacity onPress={() => setPhone('')}>
|
|
||||||
<Icon
|
|
||||||
name="closecircle"
|
|
||||||
type="AntDesign"
|
|
||||||
style={styles.cleanInputIcon}
|
|
||||||
/>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
{error?.phone?.message && (
|
{error?.phone?.message && (
|
||||||
<Text style={styles.error}>{error.phone.message}</Text>
|
<Text style={styles.error}>{error.phone.message}</Text>
|
||||||
)}
|
)}
|
||||||
<TouchableOpacity style={styles.phoneIssueButton}>
|
<Text style={[styles.formLabel, { marginTop: RFValue(20)}]}>
|
||||||
<Text style={styles.phoneIssueButtonTitle}>
|
Password
|
||||||
{t('phone_issue')}
|
</Text>
|
||||||
</Text>
|
<View style={styles.postSection}>
|
||||||
</TouchableOpacity>
|
<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>
|
||||||
<View style={styles.buttonSignInSection}>
|
<View style={styles.buttonSignInSection}>
|
||||||
<Button
|
<Button
|
||||||
title={t('login')}
|
title={t('login')}
|
||||||
onPress={() => alert('login')}
|
onPress={() => onLogin()}
|
||||||
disabled={loading ? true : phone === '' ? true : false}
|
disabled={loading ? true : email === '' ? true : false}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
/>
|
/>
|
||||||
<Text style={styles.textOr}>{t('or_text')}</Text>
|
|
||||||
<Button
|
|
||||||
title={t('register')}
|
|
||||||
onPress={() => navigation.navigate('Register')}
|
|
||||||
loading={loading}
|
|
||||||
outline
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</KeyboardAvoidingView>
|
</ScrollView>
|
||||||
</View>
|
|
||||||
<ModalOTP
|
<ModalOTP
|
||||||
isVisible={modalOTP.visible}
|
isVisible={modalOTP.visible}
|
||||||
code={otpCode}
|
code={otpCode}
|
||||||
@ -143,11 +166,6 @@ const Login = ({route, navigation}) => {
|
|||||||
message={modal.message}
|
message={modal.message}
|
||||||
onClose={() => setModal({visible: false, message: ''})}
|
onClose={() => setModal({visible: false, message: ''})}
|
||||||
/>
|
/>
|
||||||
<ModalLanguage
|
|
||||||
isVisible={modalLanguage}
|
|
||||||
onSave={() => setModalLanguage(false)}
|
|
||||||
onClose={() => setModalLanguage(false)}
|
|
||||||
/>
|
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -10,21 +10,17 @@ export default StyleSheet.create({
|
|||||||
},
|
},
|
||||||
|
|
||||||
boardingSection: {
|
boardingSection: {
|
||||||
flex: 1.2,
|
flex: 1,
|
||||||
justifyContent: 'space-between',
|
|
||||||
},
|
|
||||||
boardingImage: {
|
|
||||||
width: width * 0.7,
|
|
||||||
height: width * 0.7,
|
|
||||||
alignSelf: 'center',
|
|
||||||
},
|
|
||||||
boardingContentSection: {
|
|
||||||
paddingBottom: width * 0.04,
|
|
||||||
},
|
},
|
||||||
|
// boardingImage: {
|
||||||
|
// width: RFValue(300),
|
||||||
|
// height: RFValue(240),
|
||||||
|
// alignSelf: 'center',
|
||||||
|
// },
|
||||||
boardingTitle: {
|
boardingTitle: {
|
||||||
fontFamily: FONTS.poppins[700],
|
fontFamily: FONTS.poppins[700],
|
||||||
fontSize: RFValue(21),
|
fontSize: RFValue(21),
|
||||||
color: Colors.BLACK,
|
color: Colors.PRIMARY,
|
||||||
},
|
},
|
||||||
boardingSubTitle: {
|
boardingSubTitle: {
|
||||||
fontFamily: FONTS.poppins[400],
|
fontFamily: FONTS.poppins[400],
|
||||||
@ -33,15 +29,18 @@ export default StyleSheet.create({
|
|||||||
marginTop: width * 0.01,
|
marginTop: width * 0.01,
|
||||||
marginRight: width * 0.05,
|
marginRight: width * 0.05,
|
||||||
},
|
},
|
||||||
|
boardingContentSection: {
|
||||||
|
marginTop: RFValue(30),
|
||||||
|
},
|
||||||
wrapper: {
|
wrapper: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
backgroundColor: Colors.WHITE,
|
backgroundColor: Colors.WHITE,
|
||||||
|
justifyContent: 'center',
|
||||||
|
marginTop: RFValue(10),
|
||||||
},
|
},
|
||||||
|
|
||||||
//form section
|
//form section
|
||||||
formSection: {
|
formSection: {
|
||||||
paddingTop: width * 0.02,
|
paddingVertical: RFValue(20),
|
||||||
},
|
},
|
||||||
formLabel: {
|
formLabel: {
|
||||||
fontFamily: FONTS.poppins[600],
|
fontFamily: FONTS.poppins[600],
|
||||||
@ -52,6 +51,8 @@ export default StyleSheet.create({
|
|||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingTop: width * 0.02,
|
paddingTop: width * 0.02,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: Colors.DARK_GREY,
|
||||||
},
|
},
|
||||||
numberIdSection: {
|
numberIdSection: {
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
@ -72,8 +73,7 @@ export default StyleSheet.create({
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
borderBottomWidth: 1,
|
|
||||||
borderBottomColor: Colors.BLACK,
|
|
||||||
paddingVertical: width * 0.02,
|
paddingVertical: width * 0.02,
|
||||||
marginLeft: width * 0.02,
|
marginLeft: width * 0.02,
|
||||||
},
|
},
|
||||||
@ -87,6 +87,7 @@ export default StyleSheet.create({
|
|||||||
},
|
},
|
||||||
cleanInputIcon: {
|
cleanInputIcon: {
|
||||||
fontSize: RFValue(12),
|
fontSize: RFValue(12),
|
||||||
|
color: 'black',
|
||||||
},
|
},
|
||||||
inputNote: {
|
inputNote: {
|
||||||
fontFamily: FONTS.poppins[400],
|
fontFamily: FONTS.poppins[400],
|
||||||
@ -113,7 +114,7 @@ export default StyleSheet.create({
|
|||||||
|
|
||||||
// button section
|
// button section
|
||||||
buttonSignInSection: {
|
buttonSignInSection: {
|
||||||
// marginBottom: Platform.OS === 'ios' ? keyboardHeight : width * 0.05,
|
marginTop: RFValue(50),
|
||||||
},
|
},
|
||||||
textOr: {
|
textOr: {
|
||||||
fontFamily: FONTS.poppins[500],
|
fontFamily: FONTS.poppins[500],
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import {useState} from 'react';
|
import {useState} from 'react';
|
||||||
|
|
||||||
const useLogin = navigation => {
|
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 [loading, setLoading] = useState(false);
|
||||||
const [modalOTP, setModalOTP] = useState({visible: false, loading: false});
|
const [modalOTP, setModalOTP] = useState({visible: false, loading: false});
|
||||||
const [otpCode, setOTPCode] = useState('');
|
const [otpCode, setOTPCode] = useState('');
|
||||||
@ -13,8 +15,12 @@ const useLogin = navigation => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
phone,
|
email,
|
||||||
setPhone,
|
setEmail,
|
||||||
|
password,
|
||||||
|
setPassword,
|
||||||
|
isPasswordVisible,
|
||||||
|
setIsPasswordVisible,
|
||||||
modalOTP,
|
modalOTP,
|
||||||
setModalOTP,
|
setModalOTP,
|
||||||
otpCode,
|
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 AddMenuCategory from './Products/MenuCategory/AddMenuCategory';
|
||||||
import ProductList from './Products/ProductList';
|
import ProductList from './Products/ProductList';
|
||||||
import AddProduct from './Products/ProductList/AddProduct';
|
import AddProduct from './Products/ProductList/AddProduct';
|
||||||
|
import Home from './Home';
|
||||||
|
import Selling from './Selling';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Login,
|
Login,
|
||||||
Register,
|
Register,
|
||||||
|
Home,
|
||||||
|
Selling,
|
||||||
BusinessProfileRegistration,
|
BusinessProfileRegistration,
|
||||||
BusinessSummary,
|
BusinessSummary,
|
||||||
OutletSummary,
|
OutletSummary,
|
||||||
|
@ -8,10 +8,11 @@ const initialState = {
|
|||||||
export const userLogin = async payload => {
|
export const userLogin = async payload => {
|
||||||
const newState = {...initialState};
|
const newState = {...initialState};
|
||||||
try {
|
try {
|
||||||
const response = await HttpRequest.post(RestConstant.login, payload);
|
const response = await HttpRequest.postAuth(RestConstant.login, payload);
|
||||||
|
console.log(response);
|
||||||
switch (response.request.status) {
|
switch (response.request.status) {
|
||||||
case StatusCode.OK:
|
case StatusCode.OK:
|
||||||
newState._data = response.data;
|
newState._data = response.data.data;
|
||||||
return newState;
|
return newState;
|
||||||
case StatusCode.UNAUTHORIZED:
|
case StatusCode.UNAUTHORIZED:
|
||||||
newState._error = response.response.data;
|
newState._error = response.response.data;
|
||||||
@ -43,30 +44,3 @@ export const userRegister = async payload => {
|
|||||||
console.log(error);
|
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 './auth-services';
|
||||||
export * from './master-service';
|
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 = '#4A4A4A';
|
||||||
export const TEXT_LIGHT = '#666666';
|
export const TEXT_LIGHT = '#666666';
|
||||||
export const LINE_STROKE = '#EFEFEF';
|
export const LINE_STROKE = '#EFEFEF';
|
||||||
export const GREY = '#D9D9D9';
|
export const GREY = '#D9D9D9';
|
||||||
|
export const DARK_GREY = '#c4c4c4';
|
||||||
export const GREY_LIGHT = '#FAFAFA';
|
export const GREY_LIGHT = '#FAFAFA';
|
||||||
export const GREY_TEXT = '#A2A2A2';
|
export const GREY_TEXT = '#A2A2A2';
|
||||||
export const GREEN = '#3B8628';
|
export const GREEN = '#3B8628';
|
||||||
|
89
yarn.lock
@ -772,6 +772,13 @@
|
|||||||
exec-sh "^0.3.2"
|
exec-sh "^0.3.2"
|
||||||
minimist "^1.2.0"
|
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":
|
"@eslint/eslintrc@^0.4.3":
|
||||||
version "0.4.3"
|
version "0.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
|
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
|
||||||
@ -1286,19 +1293,16 @@
|
|||||||
react-is "^16.13.0"
|
react-is "^16.13.0"
|
||||||
use-latest-callback "^0.1.5"
|
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":
|
"@react-navigation/elements@^1.3.7":
|
||||||
version "1.3.7"
|
version "1.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-1.3.7.tgz#40d80a7f34d645b605289da10bc4b6c3a7667215"
|
resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-1.3.7.tgz#40d80a7f34d645b605289da10bc4b6c3a7667215"
|
||||||
integrity sha512-OZg2N/dd2tl6qkfrWvmUjFsYsbEyHEv4NbZSBuT+CR+d1pzmexN2IeVmi4cEMoR7U7GwhFcHRevF36yBsjU/dw==
|
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":
|
"@react-navigation/native@^6.0.13":
|
||||||
version "6.0.14"
|
version "6.0.14"
|
||||||
resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-6.0.14.tgz#3ce3a4176ac7dc5495241d56a28db18449baf754"
|
resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-6.0.14.tgz#3ce3a4176ac7dc5495241d56a28db18449baf754"
|
||||||
@ -1316,6 +1320,15 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
nanoid "^3.1.23"
|
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":
|
"@sideway/address@^4.1.3":
|
||||||
version "4.1.4"
|
version "4.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0"
|
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0"
|
||||||
@ -1402,6 +1415,11 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@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":
|
"@types/hoist-non-react-statics@^3.3.0":
|
||||||
version "3.3.1"
|
version "3.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
|
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"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73"
|
||||||
integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==
|
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:
|
agent-base@6:
|
||||||
version "6.0.2"
|
version "6.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
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"
|
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
|
||||||
integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
|
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:
|
diff-sequences@^26.6.2:
|
||||||
version "26.6.2"
|
version "26.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1"
|
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"
|
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
|
||||||
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
|
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:
|
gensync@^1.0.0-beta.2:
|
||||||
version "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"
|
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"
|
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
|
||||||
integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==
|
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"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
@ -5660,7 +5693,7 @@ prompts@^2.0.1, prompts@^2.4.0:
|
|||||||
kleur "^3.0.3"
|
kleur "^3.0.3"
|
||||||
sisteransi "^1.0.5"
|
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"
|
version "15.8.1"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
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"
|
resolved "https://registry.yarnpkg.com/react-native-dropdown-picker/-/react-native-dropdown-picker-5.4.3.tgz#adc16cfa52e8f3481220b377dd780040c3debf96"
|
||||||
integrity sha512-cwZzFcpyx/Stw3lZH2bvXxcsgwkR8c3rRZtOnlvyuN5pAplzA/9AiAxYlnJuspP9VvyU1XMePKOpgcHce6iyhA==
|
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:
|
react-native-gradle-plugin@^0.70.3:
|
||||||
version "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"
|
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"
|
react-freeze "^1.0.0"
|
||||||
warn-once "^0.1.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:
|
react-native-vector-icons@^9.2.0:
|
||||||
version "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"
|
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"
|
y18n "^5.0.5"
|
||||||
yargs-parser "^20.2.2"
|
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:
|
yocto-queue@^0.1.0:
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||||
|