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

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

View File

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

View File

@ -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/*"]
} }
} }
} }

View File

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

View File

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

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

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

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

View File

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

View File

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

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 = '#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';

View File

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