diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index 7c4bdba..da672b1 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -1,5 +1,5 @@ import { Tabs, useNavigation } from 'expo-router'; -import React, { useEffect } from 'react'; +import React, { useEffect, useRef } from 'react'; import { TabBarIcon } from '@/components/navigation/TabBarIcon'; 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 { DB } from '@/components/lib/db'; - +import ProfileScreen from './profile'; +import { AppProvider } from '@/components/AppContext'; export default function TabLayout() { 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) => { let cekLogin = await AsyncStorage.getItem('login'); if (cekLogin === null && name != 'index') { @@ -40,214 +43,216 @@ export default function TabLayout() { const navigation = useNavigation<{ navigate: (screen: string) => void }>(); // Explicitly type navigation return ( - + { - 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; - })(); - } - }, - - }} - > - - null, + screenOptions={{ + + tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint, + headerShown: false, + }} - /> - - null, + screenListeners={{ + focus : (e)=>{ + let data = e.target?.split('-') || [] + if (data[0]) { + let name = data[0]; + (function(){ + CekLogin(name); + cfg.activeTabs = name; + cfg.call(name); + return true; + })(); + } + }, }} - /> + > + + null, + }} + /> + + null, + }} + /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> + + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - null, - }} - /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - ( - - ), - tabBarStyle: { display: 'none' }, - tabBarButton: () => null, - }} - /> - + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> + null, + }} + /> + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + + }} + + /> + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> + ( + + ), + tabBarStyle: { display: 'none' }, + tabBarButton: () => null, + }} + /> + + ); } \ No newline at end of file diff --git a/app/(tabs)/history.tsx b/app/(tabs)/history.tsx index ee11302..10573cd 100644 --- a/app/(tabs)/history.tsx +++ b/app/(tabs)/history.tsx @@ -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 { Ionicons } from '@expo/vector-icons'; 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 { DB } from '@/components/lib/db'; import DetailOrder from '@/components/pageComponent/detailOrder'; +import debounce from 'lodash.debounce'; const formatNumber = function (number: any) { return number.toLocaleString('id-ID', { @@ -45,7 +46,7 @@ const Contact = ({ data: mapOfData, setDataOrder, setDataOrderList, setShowDetai return ( <> {(Array.isArray(mapOfData)?mapOfData:[]).map((data: any, key: number) => - { + { DB(` SELECT s.name @@ -64,7 +65,7 @@ const Contact = ({ data: mapOfData, setDataOrder, setDataOrderList, setShowDetai setDataOrderList(list); setShowDetail(true) }) - }} key={key}> + }}> { }; }, [navigation, showDetail, setShowDetail]) ); - - - - const callData = async () => { - let data: any = await AsyncStorage.getItem('login'); - data = JSON.parse(data); - data = data.length > 0 ? data[0] : {}; + const [pagin, setPagin] = useState(0); + const [search, setSearch] = useState(''); + const callData = async (pagin=0) => { let sales: any = await DB(` SELECT sa.write_date, @@ -203,37 +200,44 @@ const HistorySreen = () => { sa.amount_to_invoice FROM sale_order sa 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(` SELECT count(*) as total FROM sale_order sa `); - setSalesTotal(salesTotalNumber.length > 0 ? Number(salesTotalNumber[0].total):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; + console.log(pagin) + if(pagin == 0){ + setContact(sales); + }else{ + setContact(contact.concat(sales) ); } - - setContact(sales); }; cfg.action['history'] = () => { - callData() + setPagin(0); + setSearch('') + callData(pagin) } useEffect(() => { - (function () { + (async function () { 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') } - const fabAction = function () { - // console.log("action") - } - const onScroll = (event: any) => { const yOffset = event.nativeEvent.contentOffset.y; 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 ( <> { showDetail === true? - + :<> @@ -296,24 +306,24 @@ const HistorySreen = () => { {(`total\nSemua Order`).toUpperCase()} {salesTotal} @@ -362,7 +372,9 @@ const HistorySreen = () => { - { List Order - + + + + + { + let p = pagin+10; + setPagin( p ) + callData(p) + }}> + + Lebih Banyak + + + diff --git a/app/(tabs)/home.tsx b/app/(tabs)/home.tsx index 07b1b21..8ec3c5a 100644 --- a/app/(tabs)/home.tsx +++ b/app/(tabs)/home.tsx @@ -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 { useNavigation, NavigationProp } from '@react-navigation/native'; import { ProgressChart } from 'react-native-chart-kit'; @@ -9,18 +9,28 @@ import { DB } from '@/components/lib/db'; import { Asset } from 'expo-asset'; import config from '../../components/data/config.json'; 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 HomeScreen = () => { + const {loadData:profileLoad}:any = useAppContext(); + const profileScreenRef = useRef(null); const navigation = useNavigation>(); const [greeting, setGreeting] = useState(''); const [employeeData, setEmployeeData] = useState({job_title:'', name: '', work_email: '', work_phone: '' }); const [orderData, setOrderData] = useState([0]); const [visitData, setVisitData] = useState([0]); 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 asset = Asset.fromModule(require('../../assets/images/bg/SORT_bg_Home.svg')); await asset.downloadAsync(); @@ -61,10 +71,23 @@ const HomeScreen = () => { 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); return () => backHandler.remove(); - }, []); + }, [setSvgData, setInvoice,setOrder]); + + const getEmployeeData = async () => { try { @@ -78,6 +101,8 @@ const HomeScreen = () => { } }; + + const getGreeting = () => { const hour = new Date().getHours(); if (hour < 12) { @@ -140,6 +165,7 @@ const HomeScreen = () => { {items.map((item, index) => ( { + // profileLoad() navigation.navigate(item.action); }} key={`item-${i}-${index}`}> @@ -279,7 +305,7 @@ const HomeScreen = () => { - 28 Orders + {order2} Orders { 22 Pending - 31 Visits + {invoice2} Visits { TOTAL ORDER - Rp 45.600.000 + Rp {formatRupiah(order.toString())} TOTAL COLLECTED - Rp 25.550.000 + Rp {formatRupiah(invoice.toString())} diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index d4b5f9b..a2ae21e 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -1,7 +1,8 @@ import React, { useState } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, Alert, Image } from 'react-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 { DB } from '@/components/lib/db'; import { GestureHandlerRootView, ScrollView } from 'react-native-gesture-handler'; @@ -24,12 +25,6 @@ const LoginScreen = () => { }) .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){ Alert.alert(JSON.stringify(e)) } @@ -45,95 +40,101 @@ const LoginScreen = () => { return ( <> - - - + + + - + + + + S.O.R.T + + + Login + Silahkan login ke akun anda + EMAIL + + PASSWORD + + + Log In + + + Lupa Password? + + + Belum memiliki akun? + + Daftar disini! + - S.O.R.T - - - Login - Silahkan login ke akun anda - EMAIL - - PASSWORD - - - Log In - - - Lupa Password? - - - Belum memiliki akun? - - Daftar disini! - - + + ); }; @@ -164,10 +165,11 @@ const styles = StyleSheet.create({ }, input: { width: '100%', - borderWidth:1, - borderColor:"#ddd", + borderWidth: 2, + borderColor:"#333", borderRadius: 10, padding: 15, + shadowColor: "#000", marginBottom: 20, fontSize: 16, }, diff --git a/app/(tabs)/order.tsx b/app/(tabs)/order.tsx index 51ccf98..fa01766 100644 --- a/app/(tabs)/order.tsx +++ b/app/(tabs)/order.tsx @@ -181,7 +181,7 @@ const App = () => { box:0 } }); - setProducts(y) + setProducts(y); })(); },[]) @@ -426,7 +426,6 @@ const App = () => { // default company_id administrator const company_id = 1; - let dataNilai = taxCount(); amount_untaxed = dataNilai.nilaiTotal 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 newProduct:any = []; - + getProduk.forEach((c:any)=>{ // dos if(c.box > 0){ diff --git a/app/(tabs)/orderlunas.tsx b/app/(tabs)/orderlunas.tsx index 64bc206..88e57d3 100644 --- a/app/(tabs)/orderlunas.tsx +++ b/app/(tabs)/orderlunas.tsx @@ -9,6 +9,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; import { cfg, getStorage } from '@/components/lib/cfg'; import { DB } from '@/components/lib/db'; import DetailOrder from '@/components/pageComponent/detailOrder'; +import debounce from 'lodash.debounce'; const formatNumber = function (number: any) { return number.toLocaleString('id-ID', { @@ -17,7 +18,6 @@ const formatNumber = function (number: any) { }); } - function formatDate(dateString: any) { const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; @@ -141,7 +141,6 @@ const OrderLunasSreen = () => { const navigation = useNavigation>(); - useFocusEffect( React.useCallback(() => { @@ -163,24 +162,19 @@ const OrderLunasSreen = () => { }, [navigation, showDetail, setShowDetail]) ); - - 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(` - SELECT * FROM view_sales_payment_status - `); - let [salesLunas]: any = await DB(` - SELECT count(*) total FROM view_sales_payment_status_lunas - `); - let [salesPasial]: any = await DB(` - SELECT count(*) total FROM view_sales_payment_status_parsial - `); + let apiUrl = config.apihost +'/data/odoo/lunas'; + let dataFromApi = await fetch(apiUrl); + let { invoice, invoiceCount, invoicePartialCount } = await dataFromApi.json(); + let sales: any = invoice; + let [salesLunas]: any = invoiceCount; + let [salesPasial]: any = invoicePartialCount; - setSalesTotal(Number(salesLunas?.total)) - setSalesTotal2(Number(salesPasial?.total)) + setSalesTotal(Number(salesLunas?.total)); + setSalesTotal2(Number(salesPasial?.total)); setId(data?.id) setNama(data?.name) @@ -192,11 +186,10 @@ const OrderLunasSreen = () => { const [{ name }] = negara.filter((s: any) => s?.id == data?.country_id); country = name; } - setContact(sales); }; - cfg.action['history'] = () => { + cfg.action['orderlunas'] = () => { callData() } @@ -217,7 +210,7 @@ const OrderLunasSreen = () => { const onScroll = (event: any) => { const yOffset = event.nativeEvent.contentOffset.y; if (yOffset > 190) { - setBgHead(config.color.primary) + setBgHead( config.color.primary ) } else { setBgHead(null) } diff --git a/app/(tabs)/pelunasan.tsx b/app/(tabs)/pelunasan.tsx index 025595c..ba60783 100644 --- a/app/(tabs)/pelunasan.tsx +++ b/app/(tabs)/pelunasan.tsx @@ -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 ( <> {(Array.isArray(mapOfData) ? mapOfData : []).map((data: any, key: number) => @@ -146,7 +146,7 @@ const PelunasanSreen = () => { useFocusEffect( React.useCallback(() => { - + callData(); const onBackPress = () => { if (showDetail === true) { setShowDetail(false) @@ -178,9 +178,9 @@ const PelunasanSreen = () => { name VARCHAR(100), data JSON )`); - console.log("hallo") + let sales: any = await DB(` - SELECT + SELECT sa.write_date, sa.date_order, sa.name, @@ -196,7 +196,10 @@ const PelunasanSreen = () => { sa.amount_to_invoice FROM sale_order sa 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(` SELECT @@ -220,9 +223,6 @@ const PelunasanSreen = () => { setContact(sales); }; - cfg.action['history'] = () => { - callData() - } useEffect(() => { (function () { @@ -330,9 +330,12 @@ const PelunasanSreen = () => { SELECT 1 FROM sort_payment WHERE name = '${dataPaan.name}' ); `; - // console.log(query); + console.log(query); DB(query).then(function(){ - setDataForm(false); + (function(){ + callData(); + setDataForm(false); + })(); }); } }}> @@ -348,6 +351,21 @@ const PelunasanSreen = () => { }}>Simpan Pembayaran + { + setDataForm(false) + }}> + + Kembali + + @@ -424,7 +442,7 @@ const PelunasanSreen = () => { - + diff --git a/app/(tabs)/profile.tsx b/app/(tabs)/profile.tsx index 6b29aa5..232a66f 100644 --- a/app/(tabs)/profile.tsx +++ b/app/(tabs)/profile.tsx @@ -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 { FontAwesome, Ionicons } from '@expo/vector-icons'; import config from '../../components/data/config.json' @@ -12,7 +12,7 @@ import { DB } from '@/components/lib/db'; import { LineChart } from 'react-native-chart-kit'; -const ProfileSreen = () => { +const ProfileSreen = forwardRef((props, ref) => { const [bgHead, setBgHead] = useState(null) const [nama, setNama] = useState('John Doe'); const [Id, setId] = useState('John Doe'); @@ -36,8 +36,12 @@ const ProfileSreen = () => { , value: string }[]>([]); + + const navigation = useNavigation>(); + + const Contact = (props: any) => { return ( <> @@ -75,11 +79,10 @@ const ProfileSreen = () => { ) } - - - useFocusEffect( React.useCallback(() => { + + callData(); const onBackPress = () => { navigation.navigate("home"); @@ -92,9 +95,12 @@ const ProfileSreen = () => { return () => { BackHandler.removeEventListener('hardwareBackPress', onBackPress); }; - }, [navigation]) + + }, [navigation, callData]) ); + + const callData = async () => { @@ -148,9 +154,12 @@ const ProfileSreen = () => { ]); }; - cfg.action['detailcontact'] = () => { - callData() - } + useImperativeHandle(ref, () => ({ + loadData() { + console.log('Data di ContactScreen sedang di-load...'); + // Lakukan operasi loading data di sini + }, + })); useEffect(() => { (function () { @@ -345,7 +354,7 @@ const ProfileSreen = () => { ); -}; +}); export default ProfileSreen; \ No newline at end of file diff --git a/app/(tabs)/stock.tsx b/app/(tabs)/stock.tsx index 49789d7..55dc45d 100644 --- a/app/(tabs)/stock.tsx +++ b/app/(tabs)/stock.tsx @@ -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 { useNavigation, NavigationProp, useFocusEffect } from '@react-navigation/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 navigation = useNavigation>(); - + const [selectedValue, setSelectedValue] = useState('') + const [showFilter, setShowFilter] = useState(false) useFocusEffect( React.useCallback(() => { const onBackPress = () => { @@ -22,7 +28,7 @@ const StockScreen = () => { }, [navigation]) ); 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: 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" }, @@ -38,17 +44,24 @@ const StockScreen = () => { { 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: 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) => ( <> - + {item.name} Rp {item.price} - Saldo : {item.qoh} + Saldo : {item.qoh} @@ -60,6 +73,45 @@ const StockScreen = () => { 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 ( <> { - + + {navigation.navigate('home')}}> + + Back + + + + + + { + setShowFilter(!showFilter); + }}> + + + + + + {showFilter? <> + + + + + + + + + + + + + + + + :<>} 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 ( + + {children} + + ); +}; diff --git a/components/data/config.json b/components/data/config.json index f0ba5ea..3f0d279 100644 --- a/components/data/config.json +++ b/components/data/config.json @@ -4,4 +4,5 @@ }, "api" : "http://193.203.167.219:8282/data/query/odoo" ,"api2" : "https://app.rumahjo.com/data/query/odoo" + , "apihost" : "https://app.rumahjo.com" } \ No newline at end of file diff --git a/components/native/dropdown.tsx b/components/native/dropdown.tsx index 9d0931d..df435e9 100644 --- a/components/native/dropdown.tsx +++ b/components/native/dropdown.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { View, Text, Modal, TouchableOpacity, FlatList } from 'react-native'; 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 handleSelect = (item:any) => { @@ -32,7 +32,7 @@ const CustomPicker = ({ options, selectedValue, onValueChange }) => { > - {(optionSet.find(option => option.value === selectedValue)?.label || 'PILIH CUSTOMER').toUpperCase()} + {(optionSet.find((option:any) => option.value === selectedValue)?.label || (label?label:'PILIH CUSTOMER')).toUpperCase()} { + rn_bridge.channel.send(msg); +} ); + +// Inform react-native node is initialized. +rn_bridge.channel.send("Node was initialized."); \ No newline at end of file diff --git a/nodejs-assets/nodejs-project/package.json b/nodejs-assets/nodejs-project/package.json new file mode 100644 index 0000000..d0add5d --- /dev/null +++ b/nodejs-assets/nodejs-project/package.json @@ -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": "" +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9d256cd..5dab5d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sort", - "version": "1.0.0", + "version": "1.0.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sort", - "version": "1.0.0", + "version": "1.0.7", "dependencies": { "@expo-google-fonts/inter": "^0.2.3", "@expo/vector-icons": "^14.0.2", @@ -29,8 +29,11 @@ "expo-system-ui": "~3.0.7", "expo-updates": "~0.25.24", "expo-web-browser": "~13.0.3", + "lodash": "^4.17.21", + "nodejs-mobile-react-native": "^18.17.8", "react": "18.2.0", "react-dom": "18.2.0", + "react-loader-spinner": "^6.1.6", "react-native": "0.74.5", "react-native-bluetooth-escpos-printer": "^0.0.5", "react-native-calendars": "^1.1306.0", @@ -49,11 +52,13 @@ "react-native-svg-transformer": "^1.5.0", "react-native-tab-view": "^3.5.2", "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": { "@babel/core": "^7.20.0", "@types/jest": "^29.5.12", + "@types/lodash.debounce": "^4.0.9", "@types/react": "~18.2.45", "@types/react-test-renderer": "^18.0.7", "jest": "^29.2.1", @@ -2178,6 +2183,24 @@ "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": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@expo-google-fonts/inter/-/inter-0.2.3.tgz", @@ -4419,6 +4442,61 @@ "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": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", @@ -6796,6 +6874,11 @@ "@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": { "version": "8.0.0", "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", "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": { "version": "18.19.42", "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", "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": { "version": "4.0.5", "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", "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": { "version": "3.0.0", "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", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "optional": true, - "peer": true, "dependencies": { "iconv-lite": "^0.6.2" } @@ -9626,6 +9736,46 @@ "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": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -9645,6 +9795,14 @@ "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": { "version": "7.13.0", "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", "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": { "version": "1.3.2", "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" } }, + "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": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -11615,6 +11783,23 @@ "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": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -11860,6 +12045,11 @@ "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": { "version": "2.0.3", "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" } }, + "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": { "version": "250231.0.0", "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250231.0.0.tgz", @@ -14970,6 +15165,36 @@ "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": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -15577,6 +15802,22 @@ "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": { "version": "1.0.5", "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", "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": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", @@ -15725,6 +15993,14 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "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": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -15827,6 +16103,16 @@ "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": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -15849,11 +16135,159 @@ "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": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/noop-fn/-/noop-fn-1.0.0.tgz", "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": { "version": "3.0.0", "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", "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": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -16545,6 +16987,18 @@ "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": { "version": "2.4.2", "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", "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": { "version": "0.74.5", "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.74.5.tgz", @@ -17658,6 +18133,14 @@ "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": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -18100,6 +18583,15 @@ "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": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", @@ -18109,6 +18601,69 @@ "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": { "version": "0.7.4", "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", "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": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/styleq/-/styleq-0.1.3.tgz", "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": { "version": "3.34.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", @@ -19756,6 +20375,14 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "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": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index 961f3d3..6c82f9b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sort", "main": "expo-router/entry", - "version": "1.0.5", + "version": "1.0.7", "scripts": { "start": "expo start", "reset-project": "node ./scripts/reset-project.js", @@ -36,8 +36,11 @@ "expo-system-ui": "~3.0.7", "expo-updates": "~0.25.24", "expo-web-browser": "~13.0.3", + "lodash": "^4.17.21", + "nodejs-mobile-react-native": "^18.17.8", "react": "18.2.0", "react-dom": "18.2.0", + "react-loader-spinner": "^6.1.6", "react-native": "0.74.5", "react-native-bluetooth-escpos-printer": "^0.0.5", "react-native-calendars": "^1.1306.0", @@ -56,11 +59,13 @@ "react-native-svg-transformer": "^1.5.0", "react-native-tab-view": "^3.5.2", "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": { "@babel/core": "^7.20.0", "@types/jest": "^29.5.12", + "@types/lodash.debounce": "^4.0.9", "@types/react": "~18.2.45", "@types/react-test-renderer": "^18.0.7", "jest": "^29.2.1",