This commit is contained in:
Gugus Darmayanto 2024-09-24 07:17:23 +07:00
parent 09c19b9423
commit 2259540ba0
16 changed files with 1292 additions and 417 deletions

View File

@ -1,5 +1,5 @@
import { Tabs, useNavigation } from 'expo-router'; import { Tabs, useNavigation } from 'expo-router';
import React, { useEffect } from 'react'; import React, { useEffect, useRef } from 'react';
import { TabBarIcon } from '@/components/navigation/TabBarIcon'; import { TabBarIcon } from '@/components/navigation/TabBarIcon';
import { Colors } from '@/constants/Colors'; import { Colors } from '@/constants/Colors';
@ -9,7 +9,8 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
import { addStorage, cfg } from '@/components/lib/cfg'; import { addStorage, cfg } from '@/components/lib/cfg';
import { DB } from '@/components/lib/db'; import { DB } from '@/components/lib/db';
import ProfileScreen from './profile';
import { AppProvider } from '@/components/AppContext';
export default function TabLayout() { export default function TabLayout() {
const colorScheme = useColorScheme(); const colorScheme = useColorScheme();
@ -24,6 +25,8 @@ export default function TabLayout() {
})(); })();
},[]) },[])
const profileScreenRef = useRef(null); // Move this line outside of CekLogin function
const CekLogin = async (name:any) => { const CekLogin = async (name:any) => {
let cekLogin = await AsyncStorage.getItem('login'); let cekLogin = await AsyncStorage.getItem('login');
if (cekLogin === null && name != 'index') { if (cekLogin === null && name != 'index') {
@ -40,214 +43,216 @@ export default function TabLayout() {
const navigation = useNavigation<{ navigate: (screen: string) => void }>(); // Explicitly type navigation const navigation = useNavigation<{ navigate: (screen: string) => void }>(); // Explicitly type navigation
return ( return (
<Tabs <AppProvider>
<Tabs
screenOptions={{
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint, screenOptions={{
headerShown: false,
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
}} headerShown: false,
screenListeners={{
focus : (e)=>{
let data = e.target?.split('-') || []
if (data[0]) {
let name = data[0];
console.log(name);
(function(){
CekLogin(name);
cfg.activeTabs = name;
cfg.call(name);
return true;
})();
}
},
}}
>
<Tabs.Screen
name="index"
options={{
title: 'Login',
tabBarStyle: { display: 'none' },
tabBarButton: () => null,
}} }}
/> screenListeners={{
focus : (e)=>{
<Tabs.Screen let data = e.target?.split('-') || []
name="signup" if (data[0]) {
options={{ let name = data[0];
title: 'Register', (function(){
tabBarStyle: { display: 'none' }, CekLogin(name);
tabBarButton: () => null, cfg.activeTabs = name;
cfg.call(name);
return true;
})();
}
},
}} }}
/> >
<Tabs.Screen
name="index"
options={{
title: 'Login',
tabBarStyle: { display: 'none' },
tabBarButton: () => null,
}}
/>
<Tabs.Screen
name="signup"
options={{
title: 'Register',
tabBarStyle: { display: 'none' },
tabBarButton: () => null,
}}
/>
<Tabs.Screen <Tabs.Screen
name="home" name="home"
options={{ options={{
title: 'Home', title: 'Home',
tabBarIcon: ({ color, focused }) => ( tabBarIcon: ({ color, focused }) => (
<TabBarIcon name={focused ? 'home' : 'home-outline'} color={color} /> <TabBarIcon name={focused ? 'home' : 'home-outline'} color={color} />
), ),
tabBarStyle: { display: 'none' }, tabBarStyle: { display: 'none' },
tabBarButton: () => null, tabBarButton: () => null,
}} }}
/> />
<Tabs.Screen <Tabs.Screen
name="explore" name="explore"
options={{ options={{
title: 'Explore', title: 'Explore',
tabBarIcon: ({ color, focused }) => ( tabBarIcon: ({ color, focused }) => (
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
), ),
tabBarStyle: { display: 'none' }, tabBarStyle: { display: 'none' },
tabBarButton: () => null, tabBarButton: () => null,
}} }}
/> />
<Tabs.Screen <Tabs.Screen
name="setting" name="setting"
options={{ options={{
title: 'Setting', title: 'Setting',
tabBarIcon: ({ color, focused }) => ( tabBarIcon: ({ color, focused }) => (
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
), ),
tabBarStyle: { display: 'none' }, tabBarStyle: { display: 'none' },
tabBarButton: () => null, tabBarButton: () => null,
}} }}
/> />
<Tabs.Screen <Tabs.Screen
name="order" name="order"
options={{ options={{
title: 'Order', title: 'Order',
tabBarStyle: { display: 'none' }, tabBarStyle: { display: 'none' },
tabBarButton: () => null, tabBarButton: () => null,
}} }}
/> />
<Tabs.Screen <Tabs.Screen
name="profile" name="profile"
options={{ options={{
title: 'Profile', title: 'Profile',
tabBarIcon: ({ color, focused }) => ( tabBarIcon: ({ color, focused }) => (
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
), ),
tabBarStyle: { display: 'none' }, tabBarStyle: { display: 'none' },
tabBarButton: () => null, tabBarButton: () => null,
}}
/> }}
<Tabs.Screen
name="history" />
options={{ <Tabs.Screen
title: 'history', name="history"
tabBarIcon: ({ color, focused }) => ( options={{
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> title: 'history',
), tabBarIcon: ({ color, focused }) => (
tabBarStyle: { display: 'none' }, <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
tabBarButton: () => null, ),
}} tabBarStyle: { display: 'none' },
/> tabBarButton: () => null,
<Tabs.Screen }}
name="dashboard" />
options={{ <Tabs.Screen
title: 'dashboard', name="dashboard"
tabBarIcon: ({ color, focused }) => ( options={{
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> title: 'dashboard',
), tabBarIcon: ({ color, focused }) => (
tabBarStyle: { display: 'none' }, <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
tabBarButton: () => null, ),
}} tabBarStyle: { display: 'none' },
/> tabBarButton: () => null,
<Tabs.Screen }}
name="stock" />
options={{ <Tabs.Screen
title: 'stock', name="stock"
tabBarIcon: ({ color, focused }) => ( options={{
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> title: 'stock',
), tabBarIcon: ({ color, focused }) => (
tabBarStyle: { display: 'none' }, <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
tabBarButton: () => null, ),
}} tabBarStyle: { display: 'none' },
/> tabBarButton: () => null,
<Tabs.Screen }}
name="customer" />
options={{ <Tabs.Screen
title: 'customer', name="customer"
tabBarIcon: ({ color, focused }) => ( options={{
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> title: 'customer',
), tabBarIcon: ({ color, focused }) => (
tabBarStyle: { display: 'none' }, <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
tabBarButton: () => null, ),
}} tabBarStyle: { display: 'none' },
/> tabBarButton: () => null,
<Tabs.Screen }}
name="detailcontact" />
options={{ <Tabs.Screen
title: 'detailcontact', name="detailcontact"
tabBarIcon: ({ color, focused }) => ( options={{
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> title: 'detailcontact',
), tabBarIcon: ({ color, focused }) => (
tabBarStyle: { display: 'none' }, <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
tabBarButton: () => null, ),
}} tabBarStyle: { display: 'none' },
/> tabBarButton: () => null,
<Tabs.Screen }}
name="singleedit" />
options={{ <Tabs.Screen
title: 'singleedit', name="singleedit"
tabBarIcon: ({ color, focused }) => ( options={{
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> title: 'singleedit',
), tabBarIcon: ({ color, focused }) => (
tabBarStyle: { display: 'none' }, <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
tabBarButton: () => null, ),
}} tabBarStyle: { display: 'none' },
/> tabBarButton: () => null,
<Tabs.Screen }}
name="formcustomer" />
options={{ <Tabs.Screen
title: 'formcustomer', name="formcustomer"
tabBarIcon: ({ color, focused }) => ( options={{
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> title: 'formcustomer',
), tabBarIcon: ({ color, focused }) => (
tabBarStyle: { display: 'none' }, <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
tabBarButton: () => null, ),
}} tabBarStyle: { display: 'none' },
/> tabBarButton: () => null,
<Tabs.Screen }}
name="pelunasan" />
options={{ <Tabs.Screen
title: 'formcustomer', name="pelunasan"
tabBarIcon: ({ color, focused }) => ( options={{
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> title: 'formcustomer',
), tabBarIcon: ({ color, focused }) => (
tabBarStyle: { display: 'none' }, <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
tabBarButton: () => null, ),
}} tabBarStyle: { display: 'none' },
/> tabBarButton: () => null,
<Tabs.Screen }}
name="orderlunas" />
options={{ <Tabs.Screen
title: 'formcustomer', name="orderlunas"
tabBarIcon: ({ color, focused }) => ( options={{
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> title: 'formcustomer',
), tabBarIcon: ({ color, focused }) => (
tabBarStyle: { display: 'none' }, <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
tabBarButton: () => null, ),
}} tabBarStyle: { display: 'none' },
/> tabBarButton: () => null,
<Tabs.Screen }}
name="orderbelumlunas" />
options={{ <Tabs.Screen
title: 'formcustomer', name="orderbelumlunas"
tabBarIcon: ({ color, focused }) => ( options={{
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> title: 'formcustomer',
), tabBarIcon: ({ color, focused }) => (
tabBarStyle: { display: 'none' }, <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} />
tabBarButton: () => null, ),
}} tabBarStyle: { display: 'none' },
/> tabBarButton: () => null,
</Tabs> }}
/>
</Tabs>
</AppProvider>
); );
} }

View File

@ -1,4 +1,4 @@
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState, useCallback } from 'react';
import { ScrollView, View, Text, Image, TouchableOpacity, BackHandler, Dimensions, ImageBackground } from 'react-native'; import { ScrollView, View, Text, Image, TouchableOpacity, BackHandler, Dimensions, ImageBackground } from 'react-native';
import { Ionicons } from '@expo/vector-icons'; import { Ionicons } from '@expo/vector-icons';
import config from '../../components/data/config.json' import config from '../../components/data/config.json'
@ -9,6 +9,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
import { cfg, getStorage } from '@/components/lib/cfg'; import { cfg, getStorage } from '@/components/lib/cfg';
import { DB } from '@/components/lib/db'; import { DB } from '@/components/lib/db';
import DetailOrder from '@/components/pageComponent/detailOrder'; import DetailOrder from '@/components/pageComponent/detailOrder';
import debounce from 'lodash.debounce';
const formatNumber = function (number: any) { const formatNumber = function (number: any) {
return number.toLocaleString('id-ID', { return number.toLocaleString('id-ID', {
@ -45,7 +46,7 @@ const Contact = ({ data: mapOfData, setDataOrder, setDataOrderList, setShowDetai
return ( return (
<> <>
{(Array.isArray(mapOfData)?mapOfData:[]).map((data: any, key: number) => {(Array.isArray(mapOfData)?mapOfData:[]).map((data: any, key: number) =>
<TouchableOpacity onPress={() => { <TouchableOpacity key={key} onPress={() => {
DB(` DB(`
SELECT SELECT
s.name s.name
@ -64,7 +65,7 @@ const Contact = ({ data: mapOfData, setDataOrder, setDataOrderList, setShowDetai
setDataOrderList(list); setDataOrderList(list);
setShowDetail(true) setShowDetail(true)
}) })
}} key={key}> }}>
<View style={{ <View style={{
paddingLeft: 10, paddingLeft: 10,
backgroundColor: "green", backgroundColor: "green",
@ -179,13 +180,9 @@ const HistorySreen = () => {
}; };
}, [navigation, showDetail, setShowDetail]) }, [navigation, showDetail, setShowDetail])
); );
const [pagin, setPagin] = useState(0);
const [search, setSearch] = useState('');
const callData = async (pagin=0) => {
const callData = async () => {
let data: any = await AsyncStorage.getItem('login');
data = JSON.parse(data);
data = data.length > 0 ? data[0] : {};
let sales: any = await DB(` let sales: any = await DB(`
SELECT SELECT
sa.write_date, sa.write_date,
@ -203,37 +200,44 @@ const HistorySreen = () => {
sa.amount_to_invoice sa.amount_to_invoice
FROM sale_order sa FROM sale_order sa
LEFT JOIN res_partner rp ON sa.partner_id = rp.id LEFT JOIN res_partner rp ON sa.partner_id = rp.id
ORDER BY sa.name DESC WHERE lower(rp.name) LIKE '%${search}%'
ORDER BY sa.name DESC LIMIT 10 OFFSET ${pagin}
`); `);
let salesTotalNumber: any = await DB(` let salesTotalNumber: any = await DB(`
SELECT SELECT
count(*) as total count(*) as total
FROM sale_order sa FROM sale_order sa
`); `);
setSalesTotal(salesTotalNumber.length > 0 ? Number(salesTotalNumber[0].total):0) setSalesTotal(salesTotalNumber.length > 0 ? Number(salesTotalNumber[0].total):0)
console.log(pagin)
setId(data?.id) if(pagin == 0){
setNama(data?.name) setContact(sales);
setEmail("Salesman") }else{
setContact(contact.concat(sales) );
let country = 'Indonesia';
if (data?.country_id) {
const negara: any = await getStorage('negara')
const [{ name }] = negara.filter((s: any) => s?.id == data?.country_id);
country = name;
} }
setContact(sales);
}; };
cfg.action['history'] = () => { cfg.action['history'] = () => {
callData() setPagin(0);
setSearch('')
callData(pagin)
} }
useEffect(() => { useEffect(() => {
(function () { (async function () {
callData() callData()
let data: any = await AsyncStorage.getItem('login');
data = JSON.parse(data);
data = data.length > 0 ? data[0] : {};
setId(data?.id)
setNama(data?.name)
setEmail("Salesman")
let country = 'Indonesia';
if (data?.country_id) {
const negara: any = await getStorage('negara')
const [{ name }] = negara.filter((s: any) => s?.id == data?.country_id);
country = name;
}
})(); })();
}, []) }, [])
@ -241,10 +245,6 @@ const HistorySreen = () => {
navigation.navigate('home') navigation.navigate('home')
} }
const fabAction = function () {
// console.log("action")
}
const onScroll = (event: any) => { const onScroll = (event: any) => {
const yOffset = event.nativeEvent.contentOffset.y; const yOffset = event.nativeEvent.contentOffset.y;
if (yOffset > 190) { if (yOffset > 190) {
@ -254,11 +254,21 @@ const HistorySreen = () => {
} }
}; };
const debouncedFetchData = useCallback(debounce((query) => {
callData();
}, 300), [callData]);
const handleInputChange = (text:string) => {
setSearch(text);
setPagin(0)
debouncedFetchData(text); // Mengambil data setelah 500ms tidak mengetik
};
return ( return (
<> <>
{ {
showDetail === true? showDetail === true?
<DetailOrder order={dataOrder} orderlist={dataOrderList} config={config} act={setShowDetail} /> <DetailOrder order={dataOrder} orderlist={dataOrderList} config={config} act={setShowDetail} />
:<> :<>
<GestureHandlerRootView> <GestureHandlerRootView>
<ScrollView onScroll={onScroll}> <ScrollView onScroll={onScroll}>
@ -296,24 +306,24 @@ const HistorySreen = () => {
<View style={{position:"static", top:-80}}> <View style={{position:"static", top:-80}}>
<View style={{ paddingHorizontal: 20, paddingVertical: 10 }}> <View style={{ paddingHorizontal: 20, paddingVertical: 10 }}>
<View style={{ <View style={{
backgroundColor: "orange" backgroundColor : "orange"
, padding: 10 , padding : 10
, paddingVertical: 20 , paddingVertical : 20
, borderRadius: 15 , borderRadius : 15
, flexDirection: 'row' , flexDirection : 'row'
}}> }}>
<View style={{ flex: 1 }}> <View style={{ flex: 1 }}>
<Text style={{ <Text style={{
fontSize: 12 fontSize : 12
, color: '#000' , color : '#000'
, fontWeight: '600' , fontWeight : '600'
, textAlign: 'center' , textAlign : 'center'
}}>{(`total\nSemua Order`).toUpperCase()}</Text> }}>{(`total\nSemua Order`).toUpperCase()}</Text>
<Text style={{ <Text style={{
fontSize: 28 fontSize : 28
, color: '#000' , color : '#000'
, fontWeight: 'bold' , fontWeight : 'bold'
, textAlign: 'center' , textAlign : 'center'
}}>{salesTotal}</Text> }}>{salesTotal}</Text>
</View> </View>
<View style={{ flex: 1 }}> <View style={{ flex: 1 }}>
@ -362,7 +372,9 @@ const HistorySreen = () => {
</View> </View>
</View> </View>
<View style={{marginVertical:10, flexDirection:"row", paddingHorizontal:20}}> <View style={{marginVertical:10, flexDirection:"row", paddingHorizontal:20}}>
<TextInput style={{ <TextInput
value={search}
onChangeText={handleInputChange} style={{
flex:1, flex:1,
backgroundColor:"white", backgroundColor:"white",
height:40, height:40,
@ -390,7 +402,24 @@ const HistorySreen = () => {
<Text style={{fontSize:24, textAlign:'center', fontWeight:'600'}}>List Order</Text> <Text style={{fontSize:24, textAlign:'center', fontWeight:'600'}}>List Order</Text>
</View> </View>
<View style={[{ paddingHorizontal: 20, paddingVertical: 5 }]}> <View style={[{ paddingHorizontal: 20, paddingVertical: 5 }]}>
<Contact setShowDetail={setShowDetail} setDataOrderList={setDataOrderList} setDataOrder={setDataOrder} data={contact}></Contact> <Contact setShowDetail={setShowDetail} setDataOrderList={setDataOrderList} setDataOrder={setDataOrder} data={contact}></Contact>
</View>
<View>
<View style={{
flexDirection:"row",
justifyContent:"center",
alignItems:"center"
}}>
<TouchableOpacity onPress={()=>{
let p = pagin+10;
setPagin( p )
callData(p)
}}>
<View style={{padding: 10, backgroundColor:'white', borderWidth:2, borderColor:"#ddd"}}>
<Text>Lebih Banyak</Text>
</View>
</TouchableOpacity>
</View>
</View> </View>
</View> </View>
</View> </View>

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react';
import { View, Image, Text, StyleSheet, Dimensions, ScrollView, BackHandler, Alert, TouchableOpacity, ImageBackground } from 'react-native'; import { View, Image, Text, StyleSheet, Dimensions, ScrollView, BackHandler, Alert, TouchableOpacity, ImageBackground } from 'react-native';
import { useNavigation, NavigationProp } from '@react-navigation/native'; import { useNavigation, NavigationProp } from '@react-navigation/native';
import { ProgressChart } from 'react-native-chart-kit'; import { ProgressChart } from 'react-native-chart-kit';
@ -9,18 +9,28 @@ import { DB } from '@/components/lib/db';
import { Asset } from 'expo-asset'; import { Asset } from 'expo-asset';
import config from '../../components/data/config.json'; import config from '../../components/data/config.json';
import TimeLive from '@/components/Time'; import TimeLive from '@/components/Time';
import { useAppContext } from '@/components/AppContext';
import { useFocusEffect } from 'expo-router';
import { formatRupiah } from '@/components/Helper';
const screenWidth = Dimensions.get("window").width; const screenWidth = Dimensions.get("window").width;
const HomeScreen = () => { const HomeScreen = () => {
const {loadData:profileLoad}:any = useAppContext();
const profileScreenRef = useRef(null);
const navigation = useNavigation<NavigationProp<any>>(); const navigation = useNavigation<NavigationProp<any>>();
const [greeting, setGreeting] = useState(''); const [greeting, setGreeting] = useState('');
const [employeeData, setEmployeeData] = useState({job_title:'', name: '', work_email: '', work_phone: '' }); const [employeeData, setEmployeeData] = useState({job_title:'', name: '', work_email: '', work_phone: '' });
const [orderData, setOrderData] = useState([0]); const [orderData, setOrderData] = useState([0]);
const [visitData, setVisitData] = useState([0]); const [visitData, setVisitData] = useState([0]);
const [svgData, setSvgData] = useState(''); const [svgData, setSvgData] = useState('');
useEffect(() => { const [order, setOrder] = useState(0)
const [invoice, setInvoice] = useState(0)
const [order2, setOrder2] = useState(0)
const [invoice2, setInvoice2] = useState(0)
useEffect(() => {
const loadSvg = async () => { const loadSvg = async () => {
const asset = Asset.fromModule(require('../../assets/images/bg/SORT_bg_Home.svg')); const asset = Asset.fromModule(require('../../assets/images/bg/SORT_bg_Home.svg'));
await asset.downloadAsync(); await asset.downloadAsync();
@ -61,10 +71,23 @@ const HomeScreen = () => {
return true; return true;
}; };
(async function(){
let [ord, inv]:any = await DB(`SELECT * FROM total_order`);
let [ord2, inv2]: any = await DB(`SELECT * FROM total_order_count`);
setInvoice(Number(inv.total))
setOrder(Number(ord.total))
setInvoice2(Number(inv2.total))
setOrder2(Number(ord2.total))
setOrderData([Math.min(100, ((Number(ord2.total) / (Number(ord2.total) + Number(inv2.total)) )) )]);
setVisitData([Math.min(100, ((Number(inv2.total) / (Number(ord2.total) + Number(inv2.total)))))]);
})();
const backHandler = BackHandler.addEventListener('hardwareBackPress', backAction); const backHandler = BackHandler.addEventListener('hardwareBackPress', backAction);
return () => backHandler.remove(); return () => backHandler.remove();
}, []); }, [setSvgData, setInvoice,setOrder]);
const getEmployeeData = async () => { const getEmployeeData = async () => {
try { try {
@ -78,6 +101,8 @@ const HomeScreen = () => {
} }
}; };
const getGreeting = () => { const getGreeting = () => {
const hour = new Date().getHours(); const hour = new Date().getHours();
if (hour < 12) { if (hour < 12) {
@ -140,6 +165,7 @@ const HomeScreen = () => {
<View style={styles.menuRow} key={`row-${i}`}> <View style={styles.menuRow} key={`row-${i}`}>
{items.map((item, index) => ( {items.map((item, index) => (
<TouchableOpacity style={{ padding: 0, margin: 0 }} onPress={() => { <TouchableOpacity style={{ padding: 0, margin: 0 }} onPress={() => {
// profileLoad()
navigation.navigate(item.action); navigation.navigate(item.action);
}} key={`item-${i}-${index}`}> }} key={`item-${i}-${index}`}>
<View style={[styles.cardMenu]}> <View style={[styles.cardMenu]}>
@ -279,7 +305,7 @@ const HomeScreen = () => {
<ScrollView> <ScrollView>
<View style={styles.gaugeRow}> <View style={styles.gaugeRow}>
<View style={styles.card}> <View style={styles.card}>
<Text style={{ fontWeight: '700', fontSize: 16 }}>28 Orders</Text> <Text style={{ fontWeight: '700', fontSize: 16 }}>{order2} Orders</Text>
<ProgressChart <ProgressChart
data={{ data: orderData }} data={{ data: orderData }}
width={(screenWidth / 2) - 50} width={(screenWidth / 2) - 50}
@ -296,7 +322,7 @@ const HomeScreen = () => {
<Text style={{ fontSize: 16, fontWeight: '600', textAlign: 'center' }}>22 Pending</Text> <Text style={{ fontSize: 16, fontWeight: '600', textAlign: 'center' }}>22 Pending</Text>
</View> </View>
<View style={styles.card}> <View style={styles.card}>
<Text style={{ fontWeight: '700', fontSize: 16 }}>31 Visits</Text> <Text style={{ fontWeight: '700', fontSize: 16 }}>{invoice2} Visits</Text>
<ProgressChart <ProgressChart
data={{ data: visitData }} data={{ data: visitData }}
width={(screenWidth / 2) - 50} width={(screenWidth / 2) - 50}
@ -334,11 +360,11 @@ const HomeScreen = () => {
<View style={{flex:1}}> <View style={{flex:1}}>
<View style={{padding:10, borderBottomColor:"#ddd", borderBottomWidth:1}}> <View style={{padding:10, borderBottomColor:"#ddd", borderBottomWidth:1}}>
<Text style={styles.statLabel}>TOTAL ORDER</Text> <Text style={styles.statLabel}>TOTAL ORDER</Text>
<Text style={styles.statValue}>Rp 45.600.000</Text> <Text style={styles.statValue}>Rp {formatRupiah(order.toString())}</Text>
</View> </View>
<View style={{ padding: 10}}> <View style={{ padding: 10}}>
<Text style={styles.statLabel}>TOTAL COLLECTED</Text> <Text style={styles.statLabel}>TOTAL COLLECTED</Text>
<Text style={styles.statValue}>Rp 25.550.000</Text> <Text style={styles.statValue}>Rp {formatRupiah(invoice.toString())}</Text>
</View> </View>
</View> </View>
</View> </View>

View File

@ -1,7 +1,8 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, StyleSheet, Alert, Image } from 'react-native'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, Alert, Image } from 'react-native';
import { useNavigation, NavigationProp, Link } from '@react-navigation/native'; import { useNavigation, NavigationProp, Link } from '@react-navigation/native';
import { RootStackParamList } from '@/types'; // Update the import path to the correct one
import { RootStackParamList } from '../../types';
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
import { DB } from '@/components/lib/db'; import { DB } from '@/components/lib/db';
import { GestureHandlerRootView, ScrollView } from 'react-native-gesture-handler'; import { GestureHandlerRootView, ScrollView } from 'react-native-gesture-handler';
@ -24,12 +25,6 @@ const LoginScreen = () => {
}) })
.catch(function(err){ .catch(function(err){
}) })
// Alert.alert(JSON.stringify(data));
// if(data.length > 0){
// await AsyncStorage.setItem('login', JSON.stringify(data));
// }else{
// Alert.alert("Login", "Email atau Password salah")
// }
}catch(e){ }catch(e){
Alert.alert(JSON.stringify(e)) Alert.alert(JSON.stringify(e))
} }
@ -45,95 +40,101 @@ const LoginScreen = () => {
return ( return (
<> <>
<View style={{ flex: 1, backgroundColor:'#2563eb'}}> <GestureHandlerRootView>
<View style={{ <ScrollView>
flexDirection:"column" <View style={{ flex: 1, backgroundColor:'#2563eb'}}>
, height:300 <View style={{
, justifyContent:"center" flexDirection:"column"
, alignItems:"center" , height:300
}}> , justifyContent:"center"
<View style={{ , alignItems:"center"
width:"auto",
backgroundColor:"white",
padding: 10,
borderRadius: 20
}}> }}>
<Image <View style={{
source={require('../../assets/images/logo.png')} width:"auto",
style={{ backgroundColor:"white",
width: 75 padding: 10,
, height: 75 borderRadius: 20
}} }}>
resizeMode="contain" // You can adjust this based on how you want the image to scale <Image
/> source={require('../../assets/images/logo.png')}
style={{
width: 75
, height: 75
}}
resizeMode="contain" // You can adjust this based on how you want the image to scale
/>
</View>
<Text style={{
color:"white",
paddingVertical: 10,
fontWeight:"bold",
fontSize: 30
}}>S.O.R.T</Text>
</View>
<View style={[styles.container]}>
<Text style={{
textAlign:"center"
, fontSize:50
, fontWeight:'bold'
, color:"#2563eb"
}}>Login</Text>
<Text style={{
textAlign:"center"
, fontSize:18
, fontWeight:'bold'
, color:"#777"
, marginVertical:20
}}>Silahkan login ke akun anda</Text>
<Text style={{
textAlign:"left"
, fontSize:18
, fontWeight:'bold'
, color:"#777"
, marginTop:10
, marginBottom: 10
,width:'100%'
}}>EMAIL</Text>
<TextInput
style={styles.input}
placeholder="youremail@gmail.com"
value={username}
onChangeText={setUsername}
/>
<Text style={{
textAlign: "left"
, fontSize: 18
, fontWeight: 'bold'
, color: "#777"
, marginBottom: 10
, marginTop: 10
, width: '100%'
}}>PASSWORD</Text>
<TextInput
style={styles.input}
placeholder="******"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<TouchableOpacity style={styles.button} onPress={handleLogin}>
<Text style={styles.buttonText}>Log In</Text>
</TouchableOpacity>
<TouchableOpacity onPress={handleForgotPassword}>
<Text style={styles.forgotPasswordText}>Lupa Password?</Text>
</TouchableOpacity>
<View style={{flexDirection:"row"}}>
<Text>Belum memiliki akun?</Text>
<TouchableOpacity onPress={handleSignUp} style={{marginHorizontal:5}}>
<Text style={{
color:"blue",
fontWeight:"bold"
}}>Daftar disini!</Text>
</TouchableOpacity>
</View> </View>
<Text style={{
color:"white",
paddingVertical: 10,
fontWeight:"bold",
fontSize: 30
}}>S.O.R.T</Text>
</View>
<View style={[styles.container]}>
<Text style={{
textAlign:"center"
, fontSize:50
, fontWeight:'bold'
, color:"#2563eb"
}}>Login</Text>
<Text style={{
textAlign:"center"
, fontSize:18
, fontWeight:'bold'
, color:"#777"
, marginVertical:20
}}>Silahkan login ke akun anda</Text>
<Text style={{
textAlign:"left"
, fontSize:18
, fontWeight:'bold'
, color:"#777"
, marginTop:10
,width:'100%'
}}>EMAIL</Text>
<TextInput
style={styles.input}
placeholder="youremail@gmail.com"
value={username}
onChangeText={setUsername}
/>
<Text style={{
textAlign: "left"
, fontSize: 18
, fontWeight: 'bold'
, color: "#777"
, marginTop: 10
, width: '100%'
}}>PASSWORD</Text>
<TextInput
style={styles.input}
placeholder="******"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<TouchableOpacity style={styles.button} onPress={handleLogin}>
<Text style={styles.buttonText}>Log In</Text>
</TouchableOpacity>
<TouchableOpacity onPress={handleForgotPassword}>
<Text style={styles.forgotPasswordText}>Lupa Password?</Text>
</TouchableOpacity>
<View style={{flexDirection:"row"}}>
<Text>Belum memiliki akun?</Text>
<TouchableOpacity onPress={handleSignUp} style={{marginHorizontal:5}}>
<Text style={{
color:"blue",
fontWeight:"bold"
}}>Daftar disini!</Text>
</TouchableOpacity>
</View> </View>
</View> </View>
</View> </ScrollView>
</GestureHandlerRootView>
</> </>
); );
}; };
@ -164,10 +165,11 @@ const styles = StyleSheet.create({
}, },
input: { input: {
width: '100%', width: '100%',
borderWidth:1, borderWidth: 2,
borderColor:"#ddd", borderColor:"#333",
borderRadius: 10, borderRadius: 10,
padding: 15, padding: 15,
shadowColor: "#000",
marginBottom: 20, marginBottom: 20,
fontSize: 16, fontSize: 16,
}, },

View File

@ -181,7 +181,7 @@ const App = () => {
box:0 box:0
} }
}); });
setProducts(y) setProducts(y);
})(); })();
},[]) },[])
@ -426,7 +426,6 @@ const App = () => {
// default company_id administrator // default company_id administrator
const company_id = 1; const company_id = 1;
let dataNilai = taxCount(); let dataNilai = taxCount();
amount_untaxed = dataNilai.nilaiTotal amount_untaxed = dataNilai.nilaiTotal
amount_tax = dataNilai.nilaiTax; amount_tax = dataNilai.nilaiTax;
@ -464,9 +463,9 @@ const App = () => {
); );
let ds: any = await DB(`SELECT id as newId FROM sale_order ORDER BY id DESC LIMIT 1`); let ds: any = await DB(`SELECT id as newId FROM sale_order ORDER BY id DESC LIMIT 1`);
let newProduct:any = []; let newProduct:any = [];
getProduk.forEach((c:any)=>{ getProduk.forEach((c:any)=>{
// dos // dos
if(c.box > 0){ if(c.box > 0){

View File

@ -9,6 +9,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
import { cfg, getStorage } from '@/components/lib/cfg'; import { cfg, getStorage } from '@/components/lib/cfg';
import { DB } from '@/components/lib/db'; import { DB } from '@/components/lib/db';
import DetailOrder from '@/components/pageComponent/detailOrder'; import DetailOrder from '@/components/pageComponent/detailOrder';
import debounce from 'lodash.debounce';
const formatNumber = function (number: any) { const formatNumber = function (number: any) {
return number.toLocaleString('id-ID', { return number.toLocaleString('id-ID', {
@ -17,7 +18,6 @@ const formatNumber = function (number: any) {
}); });
} }
function formatDate(dateString: any) { function formatDate(dateString: any) {
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
@ -141,7 +141,6 @@ const OrderLunasSreen = () => {
const navigation = useNavigation<NavigationProp<RootStackParamList>>(); const navigation = useNavigation<NavigationProp<RootStackParamList>>();
useFocusEffect( useFocusEffect(
React.useCallback(() => { React.useCallback(() => {
@ -163,24 +162,19 @@ const OrderLunasSreen = () => {
}, [navigation, showDetail, setShowDetail]) }, [navigation, showDetail, setShowDetail])
); );
const callData = async () => { const callData = async () => {
let data : any = await AsyncStorage.getItem('login'); let data : any = await AsyncStorage.getItem('login');
data = JSON.parse(data); data = JSON.parse(data);
data = data.length > 0 ? data[0] : {}; data = data.length > 0 ? data[0] : {};
let sales: any = await DB(` let apiUrl = config.apihost +'/data/odoo/lunas';
SELECT * FROM view_sales_payment_status let dataFromApi = await fetch(apiUrl);
`); let { invoice, invoiceCount, invoicePartialCount } = await dataFromApi.json();
let [salesLunas]: any = await DB(` let sales: any = invoice;
SELECT count(*) total FROM view_sales_payment_status_lunas let [salesLunas]: any = invoiceCount;
`); let [salesPasial]: any = invoicePartialCount;
let [salesPasial]: any = await DB(`
SELECT count(*) total FROM view_sales_payment_status_parsial
`);
setSalesTotal(Number(salesLunas?.total)) setSalesTotal(Number(salesLunas?.total));
setSalesTotal2(Number(salesPasial?.total)) setSalesTotal2(Number(salesPasial?.total));
setId(data?.id) setId(data?.id)
setNama(data?.name) setNama(data?.name)
@ -192,11 +186,10 @@ const OrderLunasSreen = () => {
const [{ name }] = negara.filter((s: any) => s?.id == data?.country_id); const [{ name }] = negara.filter((s: any) => s?.id == data?.country_id);
country = name; country = name;
} }
setContact(sales); setContact(sales);
}; };
cfg.action['history'] = () => { cfg.action['orderlunas'] = () => {
callData() callData()
} }
@ -217,7 +210,7 @@ const OrderLunasSreen = () => {
const onScroll = (event: any) => { const onScroll = (event: any) => {
const yOffset = event.nativeEvent.contentOffset.y; const yOffset = event.nativeEvent.contentOffset.y;
if (yOffset > 190) { if (yOffset > 190) {
setBgHead(config.color.primary) setBgHead( config.color.primary )
} else { } else {
setBgHead(null) setBgHead(null)
} }

View File

@ -41,7 +41,7 @@ function formatDate(dateString: any) {
}; };
} }
const Contact = ({ setData, setForm, data: mapOfData, setDataOrder, setDataOrderList, setShowDetail }: any) => { const Contact = ({ setData, setForm, data: mapOfData, updateList, setDataOrder, setDataOrderList, setShowDetail }: any) => {
return ( return (
<> <>
{(Array.isArray(mapOfData) ? mapOfData : []).map((data: any, key: number) => {(Array.isArray(mapOfData) ? mapOfData : []).map((data: any, key: number) =>
@ -146,7 +146,7 @@ const PelunasanSreen = () => {
useFocusEffect( useFocusEffect(
React.useCallback(() => { React.useCallback(() => {
callData();
const onBackPress = () => { const onBackPress = () => {
if (showDetail === true) { if (showDetail === true) {
setShowDetail(false) setShowDetail(false)
@ -178,9 +178,9 @@ const PelunasanSreen = () => {
name VARCHAR(100), name VARCHAR(100),
data JSON data JSON
)`); )`);
console.log("hallo")
let sales: any = await DB(` let sales: any = await DB(`
SELECT SELECT
sa.write_date, sa.write_date,
sa.date_order, sa.date_order,
sa.name, sa.name,
@ -196,7 +196,10 @@ const PelunasanSreen = () => {
sa.amount_to_invoice sa.amount_to_invoice
FROM sale_order sa FROM sale_order sa
LEFT JOIN res_partner rp ON sa.partner_id = rp.id LEFT JOIN res_partner rp ON sa.partner_id = rp.id
ORDER BY sa.name DESC LIMIT 10 LEFT JOIN (
SELECT DISTINCT invoice_origin FROM account_move WHERE invoice_origin IS NOT NULL
) ori ON ori.invoice_origin = sa.name
WHERE ori.invoice_origin IS NULL ORDER BY sa.name DESC
`); `);
let salesTotalNumber: any = await DB(` let salesTotalNumber: any = await DB(`
SELECT SELECT
@ -220,9 +223,6 @@ const PelunasanSreen = () => {
setContact(sales); setContact(sales);
}; };
cfg.action['history'] = () => {
callData()
}
useEffect(() => { useEffect(() => {
(function () { (function () {
@ -330,9 +330,12 @@ const PelunasanSreen = () => {
SELECT 1 FROM sort_payment WHERE name = '${dataPaan.name}' SELECT 1 FROM sort_payment WHERE name = '${dataPaan.name}'
); );
`; `;
// console.log(query); console.log(query);
DB(query).then(function(){ DB(query).then(function(){
setDataForm(false); (function(){
callData();
setDataForm(false);
})();
}); });
} }
}}> }}>
@ -348,6 +351,21 @@ const PelunasanSreen = () => {
}}>Simpan Pembayaran</Text> }}>Simpan Pembayaran</Text>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity onPress={()=>{
setDataForm(false)
}}>
<View>
<Text style={{
padding:10,
backgroundColor:'lightblue',
fontSize: 18,
textAlign:'center'
, borderRadius: 10
, marginTop: 20
, fontWeight: '600'
}}>Kembali</Text>
</View>
</TouchableOpacity>
</View> </View>
</View> </View>
</View> </View>
@ -424,7 +442,7 @@ const PelunasanSreen = () => {
<View style={[{ paddingHorizontal: 20, paddingVertical: 5 }]}> <View style={[{ paddingHorizontal: 20, paddingVertical: 5 }]}>
</View> </View>
<View style={[{ paddingHorizontal: 20, paddingVertical: 5 }]}> <View style={[{ paddingHorizontal: 20, paddingVertical: 5 }]}>
<Contact setData={setDataPaan} setForm={setDataForm} setShowDetail={setShowDetail} setDataOrderList={setDataOrderList} setDataOrder={setDataOrder} data={contact}></Contact> <Contact updateList={callData} setData={setDataPaan} setForm={setDataForm} setShowDetail={setShowDetail} setDataOrderList={setDataOrderList} setDataOrder={setDataOrder} data={contact}></Contact>
</View> </View>
</View> </View>
</View> </View>

View File

@ -1,4 +1,4 @@
import React, { useEffect, useRef, useState } from 'react'; import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
import { ScrollView, View, Text, Image, TouchableOpacity, BackHandler, Dimensions, Keyboard, ImageBackground } from 'react-native'; import { ScrollView, View, Text, Image, TouchableOpacity, BackHandler, Dimensions, Keyboard, ImageBackground } from 'react-native';
import { FontAwesome, Ionicons } from '@expo/vector-icons'; import { FontAwesome, Ionicons } from '@expo/vector-icons';
import config from '../../components/data/config.json' import config from '../../components/data/config.json'
@ -12,7 +12,7 @@ import { DB } from '@/components/lib/db';
import { LineChart } from 'react-native-chart-kit'; import { LineChart } from 'react-native-chart-kit';
const ProfileSreen = () => { const ProfileSreen = forwardRef((props, ref) => {
const [bgHead, setBgHead] = useState<any>(null) const [bgHead, setBgHead] = useState<any>(null)
const [nama, setNama] = useState('John Doe'); const [nama, setNama] = useState('John Doe');
const [Id, setId] = useState('John Doe'); const [Id, setId] = useState('John Doe');
@ -36,8 +36,12 @@ const ProfileSreen = () => {
, value: string , value: string
}[]>([]); }[]>([]);
const navigation = useNavigation<NavigationProp<RootStackParamList>>(); const navigation = useNavigation<NavigationProp<RootStackParamList>>();
const Contact = (props: any) => { const Contact = (props: any) => {
return ( return (
<> <>
@ -75,11 +79,10 @@ const ProfileSreen = () => {
) )
} }
useFocusEffect( useFocusEffect(
React.useCallback(() => { React.useCallback(() => {
callData();
const onBackPress = () => { const onBackPress = () => {
navigation.navigate("home"); navigation.navigate("home");
@ -92,9 +95,12 @@ const ProfileSreen = () => {
return () => { return () => {
BackHandler.removeEventListener('hardwareBackPress', onBackPress); BackHandler.removeEventListener('hardwareBackPress', onBackPress);
}; };
}, [navigation])
}, [navigation, callData])
); );
const callData = async () => { const callData = async () => {
@ -148,9 +154,12 @@ const ProfileSreen = () => {
]); ]);
}; };
cfg.action['detailcontact'] = () => { useImperativeHandle(ref, () => ({
callData() loadData() {
} console.log('Data di ContactScreen sedang di-load...');
// Lakukan operasi loading data di sini
},
}));
useEffect(() => { useEffect(() => {
(function () { (function () {
@ -345,7 +354,7 @@ const ProfileSreen = () => {
</GestureHandlerRootView> </GestureHandlerRootView>
</> </>
); );
}; });
export default ProfileSreen; export default ProfileSreen;

View File

@ -1,11 +1,17 @@
import React, { useState } from 'react'; import React, { useEffect, useState } from 'react';
import { View, Text, TextInput, FlatList, Image, TouchableOpacity, StyleSheet, ImageBackground } from 'react-native'; import { View, Text, TextInput, FlatList, Image, TouchableOpacity, StyleSheet, ImageBackground } from 'react-native';
import { useNavigation, NavigationProp, useFocusEffect } from '@react-navigation/native'; import { useNavigation, NavigationProp, useFocusEffect } from '@react-navigation/native';
import { BackHandler } from 'react-native'; import { BackHandler } from 'react-native';
import config from '../../components/data/config.json'
import { Ionicons } from '@expo/vector-icons';
import CustomPicker from '@/components/native/dropdown';
import { cfg } from '@/components/lib/cfg';
import { DB } from '@/components/lib/db';
const StockScreen = () => { const StockScreen = () => {
const navigation = useNavigation<NavigationProp<RootStackParamList>>(); const navigation = useNavigation<NavigationProp<RootStackParamList>>();
const [selectedValue, setSelectedValue] = useState('')
const [showFilter, setShowFilter] = useState(false)
useFocusEffect( useFocusEffect(
React.useCallback(() => { React.useCallback(() => {
const onBackPress = () => { const onBackPress = () => {
@ -22,7 +28,7 @@ const StockScreen = () => {
}, [navigation]) }, [navigation])
); );
const [searchQuery, setSearchQuery] = useState(''); const [searchQuery, setSearchQuery] = useState('');
const [products, setProducts] = useState([ const settingFormat = [
{ id: 1, name: "A1-F12", sku: "-", price: 15500, qoh: 122, backgroundColor: "#c7e3ff", titleColor: "#1e90ff" }, { id: 1, name: "A1-F12", sku: "-", price: 15500, qoh: 122, backgroundColor: "#c7e3ff", titleColor: "#1e90ff" },
{ id: 2, name: "A1-K12", sku: "-", price: 7300, qoh: 60, backgroundColor: "#bbf7d0", titleColor: "#22c55e" }, { id: 2, name: "A1-K12", sku: "-", price: 7300, qoh: 60, backgroundColor: "#bbf7d0", titleColor: "#22c55e" },
{ id: 3, name: "A1-F16", sku: "-", price: 20900, qoh: 180, backgroundColor: "#c7e3ff", titleColor: "#1e90ff" }, { id: 3, name: "A1-F16", sku: "-", price: 20900, qoh: 180, backgroundColor: "#c7e3ff", titleColor: "#1e90ff" },
@ -38,17 +44,24 @@ const StockScreen = () => {
{ id: 13, name: "SHR F12", sku: "-", price: 13800, qoh: 46, backgroundColor: "#bbf7d0", titleColor: "#22c55e" }, { id: 13, name: "SHR F12", sku: "-", price: 13800, qoh: 46, backgroundColor: "#bbf7d0", titleColor: "#22c55e" },
{ id: 14, name: "SHR K12", sku: "-", price: 7800, qoh: 150, backgroundColor: "#c7e3ff", titleColor: "#1e90ff" }, { id: 14, name: "SHR K12", sku: "-", price: 7800, qoh: 150, backgroundColor: "#c7e3ff", titleColor: "#1e90ff" },
{ id: 15, name: "EVEREST", sku: "-", price: 25400, qoh: 156, backgroundColor: "#c7e3ff", titleColor: "#1e90ff" } { id: 15, name: "EVEREST", sku: "-", price: 25400, qoh: 156, backgroundColor: "#c7e3ff", titleColor: "#1e90ff" }
]); ];
const warna = settingFormat.map((w) => w.backgroundColor);
const warnatitle = settingFormat.map((w) => w.titleColor);
const [products, setProducts] = useState([]);
const renderStockCard = ({ item } : any) => ( const renderStockCard = ({ item } : any) => (
<> <>
<View style={[styles.card, { backgroundColor: item.backgroundColor, borderTopWidth:4, borderTopColor: item.titleColor}]}> <View style={[styles.card, { backgroundColor: item.backgroundColor, borderLeftWidth:4, borderLeftColor: item.titleColor}]}>
<Text style={[styles.cardTitle, { color: item.titleColor }]}>{item.name}</Text> <Text style={[styles.cardTitle, { color: item.titleColor }]}>{item.name}</Text>
<View style={styles.cardDates}> <View style={styles.cardDates}>
<Text style={styles.cardDate}>Rp {item.price}</Text> <Text style={styles.cardDate}>Rp {item.price}</Text>
<View style={{alignItems:'flex-end'}}> <View style={{alignItems:'flex-end'}}>
<Text style={{color: item.titleColor, fontWeight: 'bold'}}>Saldo : {item.qoh}</Text> <Text style={{color: item.titleColor, fontSize:18, fontWeight: 'bold'}}>Saldo : {item.qoh}</Text>
</View> </View>
</View> </View>
</View> </View>
@ -60,6 +73,45 @@ const StockScreen = () => {
return item.name.toLowerCase().includes(query); return item.name.toLowerCase().includes(query);
}; };
const callData = async () =>{
let data:any = await DB(`SELECT
pt.id,
ss.name,
ss.masuk,
ss.keluar,
ss.sisa,
pt.list_price price
FROM sisa_stock ss
LEFT JOIN product_template pt ON pt.name->>'en_US' = ss.name
ORDER BY pt.id ASC`);
let databaru:[] = data.map((s:any,i:number)=>{
return {
id: i
, name: s?.name
, sku: "-"
, price: s?.price
, qoh: s?.sisa
, backgroundColor: warna[i] ? warna[i]:warna.pop()
, titleColor: warnatitle[i] ? warnatitle[i] : warnatitle.pop()
}
});
setProducts(databaru);
}
useEffect(()=>{
callData();
},[callData]);
cfg.action['stock'] = () => {
callData()
}
const dataPilih = [
{ label: 'SISA STOCK', value: 1 },
{ label: 'STOCK KELUAR', value: 2 },
{ label: 'STOCK MASUK', value: 3 },
]
return ( return (
<> <>
<View style={{ <View style={{
@ -89,12 +141,71 @@ const StockScreen = () => {
</ImageBackground> </ImageBackground>
</View> </View>
<View style={styles.container}> <View style={styles.container}>
<TextInput <View style={[{flexDirection:"row", paddingHorizontal:15,marginBottom:10}]}>
style={styles.searchInput} <TouchableOpacity onPress={()=>{navigation.navigate('home')}}>
placeholder="Search..." <View style={[{ borderRadius: 8, paddingHorizontal: 8, paddingVertical: 5, backgroundColor: config.color.primary }]}>
value={searchQuery} <Text style={{fontSize:16, color:"white"}}>Back</Text>
onChangeText={setSearchQuery} </View>
/> </TouchableOpacity>
</View>
<View style={[{
marginHorizontal:15
, flexDirection: 'row',
}]}>
<TextInput
style={styles.searchInput}
placeholder="Search..."
value={searchQuery}
onChangeText={setSearchQuery}
/>
<TouchableOpacity onPress={()=>{
setShowFilter(!showFilter);
}}>
<View style={[{height:40, width:40,marginLeft:10,borderRadius:5,backgroundColor:"gray", flexDirection:"row", alignItems:"center", justifyContent:"center"}]}>
<Ionicons name="filter-outline" color={"white"} style={{fontSize:20}} />
</View>
</TouchableOpacity>
</View>
{showFilter? <>
<View style={[{height:75, flexDirection:"row", marginHorizontal:15}]}>
<View style={{flex:1, backgroundColor:"gray", height:60, padding:15, borderRadius:5}}>
<CustomPicker
options={dataPilih}
selectedValue={selectedValue}
onValueChange={setSelectedValue}
label={`Pilih Type`}
/>
</View>
<TouchableOpacity>
<View style={{
flexDirection:"row"
, justifyContent:"center"
, alignItems: "center"
, height: 60
, width: 40
, backgroundColor:"#eee"
, borderRadius:10
, marginHorizontal:5
}}>
<Ionicons name="chevron-up" style={{fontSize:30}} />
</View>
</TouchableOpacity>
<TouchableOpacity>
<View style={{
flexDirection:"row"
, justifyContent:"center"
, alignItems: "center"
, height: 60
, width: 40
, backgroundColor:"#eee"
, borderRadius:10
, marginHorizontal:5
}}>
<Ionicons name="chevron-down" style={{fontSize:30}} />
</View>
</TouchableOpacity>
</View>
</> :<></>}
<FlatList <FlatList
contentContainerStyle={styles.listContainer} contentContainerStyle={styles.listContainer}
data={products.filter(searchFilter)} data={products.filter(searchFilter)}
@ -121,11 +232,12 @@ const styles = StyleSheet.create({
marginBottom: 10, marginBottom: 10,
}, },
searchInput: { searchInput: {
flex:1,
height: 40, height: 40,
borderWidth: 2, borderWidth: 2,
borderRadius:5, borderRadius:5,
borderColor:'#A9A9A9', borderColor:'#A9A9A9',
marginBottom: 10, marginBottom: 15,
paddingHorizontal: 10, paddingHorizontal: 10,
}, },
card: { card: {
@ -153,6 +265,8 @@ const styles = StyleSheet.create({
}, },
cardDate: { cardDate: {
color: '#888', color: '#888',
fontSize: 16,
fontWeight:'medium'
}, },
cardContent: { cardContent: {
justifyContent: 'space-between', justifyContent: 'space-between',

23
components/AppContext.tsx Normal file
View File

@ -0,0 +1,23 @@
// AppContext.js
import React, { createContext, useContext, useState } from 'react';
// Membuat Context
const AppContext = createContext({});
// Hook untuk menggunakan Context
export const useAppContext = () => useContext(AppContext);
// Provider untuk membungkus aplikasi
export const AppProvider = ({ children }: any) => {
const [data, setData] = useState(null);
const loadData = () => {
console.log('Data sedang di-load...');
};
return (
<AppContext.Provider value={{ data, loadData }}>
{children}
</AppContext.Provider>
);
};

View File

@ -4,4 +4,5 @@
}, },
"api" : "http://193.203.167.219:8282/data/query/odoo" "api" : "http://193.203.167.219:8282/data/query/odoo"
,"api2" : "https://app.rumahjo.com/data/query/odoo" ,"api2" : "https://app.rumahjo.com/data/query/odoo"
, "apihost" : "https://app.rumahjo.com"
} }

View File

@ -2,7 +2,7 @@ import React, { useState } from 'react';
import { View, Text, Modal, TouchableOpacity, FlatList } from 'react-native'; import { View, Text, Modal, TouchableOpacity, FlatList } from 'react-native';
import { Ionicons } from '@expo/vector-icons'; // Optional for adding icons import { Ionicons } from '@expo/vector-icons'; // Optional for adding icons
const CustomPicker = ({ options, selectedValue, onValueChange }) => { const CustomPicker = ({ label, options, selectedValue, onValueChange }:any) => {
const [isVisible, setIsVisible] = useState(false); const [isVisible, setIsVisible] = useState(false);
const handleSelect = (item:any) => { const handleSelect = (item:any) => {
@ -32,7 +32,7 @@ const CustomPicker = ({ options, selectedValue, onValueChange }) => {
> >
<View style={{flex:1}}> <View style={{flex:1}}>
<Text style={{ color: 'white', fontSize: 20, fontWeight:'600' }}> <Text style={{ color: 'white', fontSize: 20, fontWeight:'600' }}>
{(optionSet.find(option => option.value === selectedValue)?.label || 'PILIH CUSTOMER').toUpperCase()} {(optionSet.find((option:any) => option.value === selectedValue)?.label || (label?label:'PILIH CUSTOMER')).toUpperCase()}
</Text> </Text>
</View> </View>
<Ionicons <Ionicons

View File

@ -0,0 +1,12 @@
// Rename this sample file to main.js to use on your project.
// The main.js file will be overwritten in updates/reinstalls.
var rn_bridge = require('rn-bridge');
// Echo every message received from react-native.
rn_bridge.channel.on('message', (msg) => {
rn_bridge.channel.send(msg);
} );
// Inform react-native node is initialized.
rn_bridge.channel.send("Node was initialized.");

View File

@ -0,0 +1,12 @@
{
"//":
["Rename this sample file to package.json to use on your project."
, "The sample-package.json file will be overwritten in updates/reinstalls."
],
"name": "sample-node-project",
"version": "0.0.1",
"description": "node part of the project",
"main": "main.js",
"author": "janeasystems",
"license": ""
}

635
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "sort", "name": "sort",
"version": "1.0.0", "version": "1.0.7",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "sort", "name": "sort",
"version": "1.0.0", "version": "1.0.7",
"dependencies": { "dependencies": {
"@expo-google-fonts/inter": "^0.2.3", "@expo-google-fonts/inter": "^0.2.3",
"@expo/vector-icons": "^14.0.2", "@expo/vector-icons": "^14.0.2",
@ -29,8 +29,11 @@
"expo-system-ui": "~3.0.7", "expo-system-ui": "~3.0.7",
"expo-updates": "~0.25.24", "expo-updates": "~0.25.24",
"expo-web-browser": "~13.0.3", "expo-web-browser": "~13.0.3",
"lodash": "^4.17.21",
"nodejs-mobile-react-native": "^18.17.8",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-loader-spinner": "^6.1.6",
"react-native": "0.74.5", "react-native": "0.74.5",
"react-native-bluetooth-escpos-printer": "^0.0.5", "react-native-bluetooth-escpos-printer": "^0.0.5",
"react-native-calendars": "^1.1306.0", "react-native-calendars": "^1.1306.0",
@ -49,11 +52,13 @@
"react-native-svg-transformer": "^1.5.0", "react-native-svg-transformer": "^1.5.0",
"react-native-tab-view": "^3.5.2", "react-native-tab-view": "^3.5.2",
"react-native-web": "~0.19.10", "react-native-web": "~0.19.10",
"react-native-webview": "13.8.6" "react-native-webview": "13.8.6",
"socket.io-client": "^4.7.5"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.20.0", "@babel/core": "^7.20.0",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/lodash.debounce": "^4.0.9",
"@types/react": "~18.2.45", "@types/react": "~18.2.45",
"@types/react-test-renderer": "^18.0.7", "@types/react-test-renderer": "^18.0.7",
"jest": "^29.2.1", "jest": "^29.2.1",
@ -2178,6 +2183,24 @@
"node": ">=0.8.0" "node": ">=0.8.0"
} }
}, },
"node_modules/@emotion/is-prop-valid": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz",
"integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==",
"dependencies": {
"@emotion/memoize": "^0.8.1"
}
},
"node_modules/@emotion/memoize": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
},
"node_modules/@emotion/unitless": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
},
"node_modules/@expo-google-fonts/inter": { "node_modules/@expo-google-fonts/inter": {
"version": "0.2.3", "version": "0.2.3",
"resolved": "https://registry.npmjs.org/@expo-google-fonts/inter/-/inter-0.2.3.tgz", "resolved": "https://registry.npmjs.org/@expo-google-fonts/inter/-/inter-0.2.3.tgz",
@ -4419,6 +4442,61 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/@npmcli/agent": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz",
"integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==",
"dependencies": {
"agent-base": "^7.1.0",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.1",
"lru-cache": "^10.0.1",
"socks-proxy-agent": "^8.0.3"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/@npmcli/agent/node_modules/agent-base": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
"integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
"dependencies": {
"debug": "^4.3.4"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/@npmcli/agent/node_modules/http-proxy-agent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
"integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
"dependencies": {
"agent-base": "^7.1.0",
"debug": "^4.3.4"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/@npmcli/agent/node_modules/https-proxy-agent": {
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
"integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
"dependencies": {
"agent-base": "^7.0.2",
"debug": "4"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/@npmcli/agent/node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
},
"node_modules/@npmcli/fs": { "node_modules/@npmcli/fs": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz",
@ -6796,6 +6874,11 @@
"@sinonjs/commons": "^3.0.0" "@sinonjs/commons": "^3.0.0"
} }
}, },
"node_modules/@socket.io/component-emitter": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="
},
"node_modules/@svgr/babel-plugin-add-jsx-attribute": { "node_modules/@svgr/babel-plugin-add-jsx-attribute": {
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
@ -7280,6 +7363,21 @@
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="
}, },
"node_modules/@types/lodash": {
"version": "4.17.7",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz",
"integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==",
"dev": true
},
"node_modules/@types/lodash.debounce": {
"version": "4.0.9",
"resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.9.tgz",
"integrity": "sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==",
"dev": true,
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "18.19.42", "version": "18.19.42",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.42.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.42.tgz",
@ -7359,6 +7457,11 @@
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw=="
}, },
"node_modules/@types/stylis": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz",
"integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw=="
},
"node_modules/@types/tough-cookie": { "node_modules/@types/tough-cookie": {
"version": "4.0.5", "version": "4.0.5",
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
@ -7433,6 +7536,14 @@
"deprecated": "Use your platform's native atob() and btoa() methods instead", "deprecated": "Use your platform's native atob() and btoa() methods instead",
"dev": true "dev": true
}, },
"node_modules/abbrev": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
"integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/abort-controller": { "node_modules/abort-controller": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
@ -9613,7 +9724,6 @@
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
"optional": true, "optional": true,
"peer": true,
"dependencies": { "dependencies": {
"iconv-lite": "^0.6.2" "iconv-lite": "^0.6.2"
} }
@ -9626,6 +9736,46 @@
"once": "^1.4.0" "once": "^1.4.0"
} }
}, },
"node_modules/engine.io-client": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.4.tgz",
"integrity": "sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.17.1",
"xmlhttprequest-ssl": "~2.0.0"
}
},
"node_modules/engine.io-client/node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/engine.io-parser": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/entities": { "node_modules/entities": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@ -9645,6 +9795,14 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/env-paths": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"engines": {
"node": ">=6"
}
},
"node_modules/envinfo": { "node_modules/envinfo": {
"version": "7.13.0", "version": "7.13.0",
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz",
@ -9661,6 +9819,11 @@
"resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz", "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz",
"integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==" "integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg=="
}, },
"node_modules/err-code": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="
},
"node_modules/error-ex": { "node_modules/error-ex": {
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@ -11378,6 +11541,11 @@
"url": "https://github.com/fb55/entities?sponsor=1" "url": "https://github.com/fb55/entities?sponsor=1"
} }
}, },
"node_modules/http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="
},
"node_modules/http-errors": { "node_modules/http-errors": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@ -11615,6 +11783,23 @@
"loose-envify": "^1.0.0" "loose-envify": "^1.0.0"
} }
}, },
"node_modules/ip-address": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
"integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
"dependencies": {
"jsbn": "1.1.0",
"sprintf-js": "^1.1.3"
},
"engines": {
"node": ">= 12"
}
},
"node_modules/ip-address/node_modules/sprintf-js": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="
},
"node_modules/ip-regex": { "node_modules/ip-regex": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
@ -11860,6 +12045,11 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/is-lambda": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
"integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ=="
},
"node_modules/is-negative-zero": { "node_modules/is-negative-zero": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
@ -14253,6 +14443,11 @@
"js-yaml": "bin/js-yaml.js" "js-yaml": "bin/js-yaml.js"
} }
}, },
"node_modules/jsbn": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
"integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
},
"node_modules/jsc-android": { "node_modules/jsc-android": {
"version": "250231.0.0", "version": "250231.0.0",
"resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250231.0.0.tgz", "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250231.0.0.tgz",
@ -14970,6 +15165,36 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/make-fetch-happen": {
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz",
"integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==",
"dependencies": {
"@npmcli/agent": "^2.0.0",
"cacache": "^18.0.0",
"http-cache-semantics": "^4.1.1",
"is-lambda": "^1.0.1",
"minipass": "^7.0.2",
"minipass-fetch": "^3.0.0",
"minipass-flush": "^1.0.5",
"minipass-pipeline": "^1.2.4",
"negotiator": "^0.6.3",
"proc-log": "^4.2.0",
"promise-retry": "^2.0.1",
"ssri": "^10.0.0"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/make-fetch-happen/node_modules/proc-log": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
"integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/makeerror": { "node_modules/makeerror": {
"version": "1.0.12", "version": "1.0.12",
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
@ -15577,6 +15802,22 @@
"node": ">=16 || 14 >=14.17" "node": ">=16 || 14 >=14.17"
} }
}, },
"node_modules/minipass-fetch": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz",
"integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==",
"dependencies": {
"minipass": "^7.0.3",
"minipass-sized": "^1.0.3",
"minizlib": "^2.1.2"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
},
"optionalDependencies": {
"encoding": "^0.1.13"
}
},
"node_modules/minipass-flush": { "node_modules/minipass-flush": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
@ -15631,6 +15872,33 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}, },
"node_modules/minipass-sized": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
"integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass-sized/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass-sized/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/minizlib": { "node_modules/minizlib": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
@ -15725,6 +15993,14 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true "dev": true
}, },
"node_modules/ncp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
"integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==",
"bin": {
"ncp": "bin/ncp"
}
},
"node_modules/negotiator": { "node_modules/negotiator": {
"version": "0.6.3", "version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@ -15827,6 +16103,16 @@
"node": ">= 6.13.0" "node": ">= 6.13.0"
} }
}, },
"node_modules/node-gyp-build-mobile": {
"version": "4.6.0-2",
"resolved": "https://registry.npmjs.org/node-gyp-build-mobile/-/node-gyp-build-mobile-4.6.0-2.tgz",
"integrity": "sha512-5Fkii5Jrvjgcsx+rhrby7IDYKmbM4+c6klvhryyCFr9p/sHLvUAE2Vyrb0vWjZpkwz5rc6mGT7PdyFGZiJ6eaw==",
"bin": {
"node-gyp-build-mobile": "bin.js",
"node-gyp-build-mobile-optional": "optional.js",
"node-gyp-build-mobile-test": "build-test.js"
}
},
"node_modules/node-int64": { "node_modules/node-int64": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@ -15849,11 +16135,159 @@
"url": "https://github.com/sponsors/antelle" "url": "https://github.com/sponsors/antelle"
} }
}, },
"node_modules/nodejs-mobile-gyp": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/nodejs-mobile-gyp/-/nodejs-mobile-gyp-0.4.0.tgz",
"integrity": "sha512-10vkX/+msYevC66DE+OfvfLe0bfxjkHQpxc/HoaKP4P7BGuXygzNI8oz5F6pl23Lb9cxRr+fq2W6XjR53QriUQ==",
"dependencies": {
"env-paths": "^2.2.0",
"exponential-backoff": "^3.1.1",
"glob": "^10.3.10",
"graceful-fs": "^4.2.6",
"make-fetch-happen": "^13.0.0",
"nopt": "^7.0.0",
"proc-log": "^3.0.0",
"semver": "^7.3.5",
"tar": "^6.1.2",
"which": "^4.0.0"
},
"bin": {
"nodejs-mobile-gyp": "bin/node-gyp.js"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/nodejs-mobile-gyp/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/nodejs-mobile-gyp/node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/nodejs-mobile-gyp/node_modules/isexe": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz",
"integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
"engines": {
"node": ">=16"
}
},
"node_modules/nodejs-mobile-gyp/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/nodejs-mobile-gyp/node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/nodejs-mobile-gyp/node_modules/which": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
"integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
"dependencies": {
"isexe": "^3.1.1"
},
"bin": {
"node-which": "bin/which.js"
},
"engines": {
"node": "^16.13.0 || >=18.0.0"
}
},
"node_modules/nodejs-mobile-react-native": {
"version": "18.17.8",
"resolved": "https://registry.npmjs.org/nodejs-mobile-react-native/-/nodejs-mobile-react-native-18.17.8.tgz",
"integrity": "sha512-GapuxMAKZ4Z878/aTFAY3LlQYXGmGfZBavAbTdB1AV/LR1yhzNipVp/deBnpY+HerYAb7Loep/sZEOyN3YT8xQ==",
"hasInstallScript": true,
"dependencies": {
"mkdirp": "^0.5.1",
"ncp": "^2.0.0",
"node-gyp-build-mobile": "4.6.0-2",
"nodejs-mobile-gyp": "^0.4.0",
"xcode": "^2.0.0"
},
"peerDependencies": {
"react-native": ">=0.60.0"
}
},
"node_modules/nodejs-mobile-react-native/node_modules/uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
"bin": {
"uuid": "bin/uuid"
}
},
"node_modules/nodejs-mobile-react-native/node_modules/xcode": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/xcode/-/xcode-2.1.0.tgz",
"integrity": "sha512-uCrmPITrqTEzhn0TtT57fJaNaw8YJs1aCzs+P/QqxsDbvPZSv7XMPPwXrKvHtD6pLjBM/NaVwraWJm8q83Y4iQ==",
"dependencies": {
"simple-plist": "^1.0.0",
"uuid": "^3.3.2"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/noop-fn": { "node_modules/noop-fn": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/noop-fn/-/noop-fn-1.0.0.tgz", "resolved": "https://registry.npmjs.org/noop-fn/-/noop-fn-1.0.0.tgz",
"integrity": "sha512-pQ8vODlgXt2e7A3mIbFDlizkr46r75V+BJxVAyat8Jl7YmI513gG5cfyRL0FedKraoZ+VAouI1h4/IWpus5pcQ==" "integrity": "sha512-pQ8vODlgXt2e7A3mIbFDlizkr46r75V+BJxVAyat8Jl7YmI513gG5cfyRL0FedKraoZ+VAouI1h4/IWpus5pcQ=="
}, },
"node_modules/nopt": {
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
"integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
"dependencies": {
"abbrev": "^2.0.0"
},
"bin": {
"nopt": "bin/nopt.js"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/normalize-path": { "node_modules/normalize-path": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -16524,6 +16958,14 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
}, },
"node_modules/proc-log": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz",
"integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/process-nextick-args": { "node_modules/process-nextick-args": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@ -16545,6 +16987,18 @@
"asap": "~2.0.3" "asap": "~2.0.3"
} }
}, },
"node_modules/promise-retry": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
"integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
"dependencies": {
"err-code": "^2.0.2",
"retry": "^0.12.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/prompts": { "node_modules/prompts": {
"version": "2.4.2", "version": "2.4.2",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
@ -16786,6 +17240,27 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}, },
"node_modules/react-loader-spinner": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-6.1.6.tgz",
"integrity": "sha512-x5h1Jcit7Qn03MuKlrWcMG9o12cp9SNDVHVJTNRi9TgtGPKcjKiXkou4NRfLAtXaFB3+Z8yZsVzONmPzhv2ErA==",
"dependencies": {
"react-is": "^18.2.0",
"styled-components": "^6.1.2"
},
"engines": {
"node": ">= 12"
},
"peerDependencies": {
"react": "^16.0.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-loader-spinner/node_modules/react-is": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
},
"node_modules/react-native": { "node_modules/react-native": {
"version": "0.74.5", "version": "0.74.5",
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.74.5.tgz", "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.74.5.tgz",
@ -17658,6 +18133,14 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
"integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
"engines": {
"node": ">= 4"
}
},
"node_modules/reusify": { "node_modules/reusify": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@ -18100,6 +18583,15 @@
"node": ">=8.0.0" "node": ">=8.0.0"
} }
}, },
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/snake-case": { "node_modules/snake-case": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
@ -18109,6 +18601,69 @@
"tslib": "^2.0.3" "tslib": "^2.0.3"
} }
}, },
"node_modules/socket.io-client": {
"version": "4.7.5",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz",
"integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
"engine.io-client": "~6.5.2",
"socket.io-parser": "~4.2.4"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-parser": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socks": {
"version": "2.8.3",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
"integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==",
"dependencies": {
"ip-address": "^9.0.5",
"smart-buffer": "^4.2.0"
},
"engines": {
"node": ">= 10.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/socks-proxy-agent": {
"version": "8.0.4",
"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz",
"integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==",
"dependencies": {
"agent-base": "^7.1.1",
"debug": "^4.3.4",
"socks": "^2.8.3"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/socks-proxy-agent/node_modules/agent-base": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
"integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
"dependencies": {
"debug": "^4.3.4"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/source-map": { "node_modules/source-map": {
"version": "0.7.4", "version": "0.7.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
@ -18482,11 +19037,75 @@
"resolved": "https://registry.npmjs.org/structured-headers/-/structured-headers-0.4.1.tgz", "resolved": "https://registry.npmjs.org/structured-headers/-/structured-headers-0.4.1.tgz",
"integrity": "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==" "integrity": "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg=="
}, },
"node_modules/styled-components": {
"version": "6.1.13",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz",
"integrity": "sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==",
"dependencies": {
"@emotion/is-prop-valid": "1.2.2",
"@emotion/unitless": "0.8.1",
"@types/stylis": "4.2.5",
"css-to-react-native": "3.2.0",
"csstype": "3.1.3",
"postcss": "8.4.38",
"shallowequal": "1.1.0",
"stylis": "4.3.2",
"tslib": "2.6.2"
},
"engines": {
"node": ">= 16"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/styled-components"
},
"peerDependencies": {
"react": ">= 16.8.0",
"react-dom": ">= 16.8.0"
}
},
"node_modules/styled-components/node_modules/postcss": {
"version": "8.4.38",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
"integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.0",
"source-map-js": "^1.2.0"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/styled-components/node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/styleq": { "node_modules/styleq": {
"version": "0.1.3", "version": "0.1.3",
"resolved": "https://registry.npmjs.org/styleq/-/styleq-0.1.3.tgz", "resolved": "https://registry.npmjs.org/styleq/-/styleq-0.1.3.tgz",
"integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==" "integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA=="
}, },
"node_modules/stylis": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
"integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg=="
},
"node_modules/sucrase": { "node_modules/sucrase": {
"version": "3.34.0", "version": "3.34.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
@ -19756,6 +20375,14 @@
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
"dev": true "dev": true
}, },
"node_modules/xmlhttprequest-ssl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
"integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/xtend": { "node_modules/xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

View File

@ -1,7 +1,7 @@
{ {
"name": "sort", "name": "sort",
"main": "expo-router/entry", "main": "expo-router/entry",
"version": "1.0.5", "version": "1.0.7",
"scripts": { "scripts": {
"start": "expo start", "start": "expo start",
"reset-project": "node ./scripts/reset-project.js", "reset-project": "node ./scripts/reset-project.js",
@ -36,8 +36,11 @@
"expo-system-ui": "~3.0.7", "expo-system-ui": "~3.0.7",
"expo-updates": "~0.25.24", "expo-updates": "~0.25.24",
"expo-web-browser": "~13.0.3", "expo-web-browser": "~13.0.3",
"lodash": "^4.17.21",
"nodejs-mobile-react-native": "^18.17.8",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-loader-spinner": "^6.1.6",
"react-native": "0.74.5", "react-native": "0.74.5",
"react-native-bluetooth-escpos-printer": "^0.0.5", "react-native-bluetooth-escpos-printer": "^0.0.5",
"react-native-calendars": "^1.1306.0", "react-native-calendars": "^1.1306.0",
@ -56,11 +59,13 @@
"react-native-svg-transformer": "^1.5.0", "react-native-svg-transformer": "^1.5.0",
"react-native-tab-view": "^3.5.2", "react-native-tab-view": "^3.5.2",
"react-native-web": "~0.19.10", "react-native-web": "~0.19.10",
"react-native-webview": "13.8.6" "react-native-webview": "13.8.6",
"socket.io-client": "^4.7.5"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.20.0", "@babel/core": "^7.20.0",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/lodash.debounce": "^4.0.9",
"@types/react": "~18.2.45", "@types/react": "~18.2.45",
"@types/react-test-renderer": "^18.0.7", "@types/react-test-renderer": "^18.0.7",
"jest": "^29.2.1", "jest": "^29.2.1",