185 lines
7.7 KiB
TypeScript
185 lines
7.7 KiB
TypeScript
import React, { useEffect, useState, useRef } from 'react';
|
|
import { BackHandler } from 'react-native';
|
|
import { useNavigation, NavigationProp, useFocusEffect } from '@react-navigation/native';
|
|
import { RootStackParamList } from '@/types';
|
|
import config from '../../components/data/config.json';
|
|
import { DB } from '@/components/lib/db';
|
|
import { cfg } from '@/components/lib/cfg';
|
|
import { ScrollView, View, Text, TouchableOpacity } from 'react-native';
|
|
import { GestureHandlerRootView, TextInput } from 'react-native-gesture-handler';
|
|
import { Ionicons } from '@expo/vector-icons';
|
|
import { FAB } from 'react-native-elements/dist/buttons/FAB';
|
|
import CustDetail from '@/components/pageComponent/customer';
|
|
|
|
const CustomerScreen = () => {
|
|
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
|
|
const [search, setSearch] = useState('');
|
|
const [dataJson, setDataJson] = useState<any>([]);
|
|
const [cX, setCx] = useState(false)
|
|
|
|
const showData = function(data:any){
|
|
setDataJson(data);
|
|
}
|
|
|
|
const getData = async function (cond: string) {
|
|
let data: any = await DB(`SELECT * FROM res_partner WHERE lower(name) LIKE '%${cond.toLowerCase()}%' ORDER BY id ASC`);
|
|
setDataJson(data);
|
|
};
|
|
|
|
useEffect(() => {
|
|
(async function () {
|
|
getData('');
|
|
})();
|
|
}, []);
|
|
|
|
useFocusEffect(
|
|
React.useCallback(() => {
|
|
const onBackPress = () => {
|
|
if(cX){
|
|
setCx(false)
|
|
}else{
|
|
navigation.navigate("home");
|
|
}
|
|
return true; // Prevent default behavior (exit app)
|
|
};
|
|
|
|
BackHandler.addEventListener('hardwareBackPress', onBackPress);
|
|
navigation.setOptions({ headerLeft: () => null }); // Remove back button
|
|
|
|
return () => {
|
|
BackHandler.removeEventListener('hardwareBackPress', onBackPress);
|
|
};
|
|
}, [navigation, setCx, cX])
|
|
);
|
|
const [dataSend, setDataSend] = useState<any>({})
|
|
|
|
const Action = {
|
|
preeFABCustomer: async function (prop: any) {
|
|
navigation.navigate('formcustomer');
|
|
}
|
|
};
|
|
|
|
cfg.action['customer'] = function () {
|
|
getData('');
|
|
};
|
|
|
|
const getDataShow = function (search='') {
|
|
getData(search);
|
|
};
|
|
|
|
// Add a ref to store the timeout
|
|
const searchTimeout = useRef<NodeJS.Timeout | null>(null);
|
|
|
|
const handleSearchChange = (text: string) => {
|
|
setSearch(text); // Update the search state
|
|
if (searchTimeout.current) {
|
|
clearTimeout(searchTimeout.current); // Clear previous timeout
|
|
}
|
|
searchTimeout.current = setTimeout(() => {
|
|
changeSearch(text); // Call changeSearch after delay
|
|
}, 300); // Adjust delay as needed (300ms here)
|
|
};
|
|
|
|
const changeSearch = (text: string) => {
|
|
getData(text.trim() !== '' ? text : ''); // Fetch data based on the search text
|
|
};
|
|
|
|
const openMenuCustomer = async function(prop: any) {
|
|
setDataSend({
|
|
datacus: btoa(JSON.stringify([prop])),
|
|
contactActive: prop?.email,
|
|
contactActiveData: btoa(JSON.stringify(prop))
|
|
})
|
|
setCx(true);
|
|
}
|
|
|
|
function buatAlias(nama:any) {
|
|
// Pisahkan nama menjadi kata-kata
|
|
const kata = nama.split(' ');
|
|
|
|
let alias;
|
|
if (kata.length === 1) {
|
|
// Jika nama hanya terdiri dari satu kata, ambil dua huruf pertama
|
|
alias = kata[0].substring(0, 2).toUpperCase();
|
|
} else {
|
|
// Ambil huruf pertama dari kata pertama dan kedua
|
|
alias = kata[0][0].toUpperCase() + kata[1][0].toUpperCase();
|
|
}
|
|
|
|
return alias;
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{cX === true?<>
|
|
<CustDetail act={getDataShow} search={search} show={showData} data={dataJson} send={dataSend} hidedata={setCx} />
|
|
</>:<>
|
|
<>
|
|
<GestureHandlerRootView>
|
|
<View style={{
|
|
height: 100,
|
|
backgroundColor: config.color.primary,
|
|
flexDirection: "row",
|
|
padding: 20,
|
|
alignItems: 'flex-end'
|
|
}}>
|
|
<TextInput
|
|
value={search}
|
|
onChangeText={handleSearchChange}
|
|
placeholder="search.."
|
|
style={{ paddingHorizontal: 16, borderRadius: 5, flex: 1, height: 40, backgroundColor: "white" }}
|
|
/>
|
|
<Ionicons style={{ paddingVertical: 10, paddingHorizontal: 18 }} size={20} color={'white'} name='search' />
|
|
</View>
|
|
<ScrollView>
|
|
<View style={{padding:10}}>
|
|
{dataJson.map((s:any,i:any)=>
|
|
<TouchableOpacity key={i} onPress={()=>{
|
|
openMenuCustomer(s);
|
|
}}>
|
|
<View style={{
|
|
padding:10
|
|
, backgroundColor:'white'
|
|
, flexDirection:'row'
|
|
, marginBottom:10
|
|
, borderRadius: 10
|
|
}}>
|
|
<View style={{width:60}}>
|
|
<View style={{
|
|
width:50
|
|
,height:50
|
|
,flexDirection:"row"
|
|
, alignItems:'center'
|
|
, justifyContent:'center'
|
|
, backgroundColor: config.color.primary
|
|
, borderRadius:50
|
|
}}>
|
|
<Text style={{
|
|
color:'white'
|
|
, fontWeight:600
|
|
, fontSize:18
|
|
}}>{buatAlias(s.name)}</Text>
|
|
</View>
|
|
</View>
|
|
<View style={{flex:1}}>
|
|
<Text style={{
|
|
fontSize:18,
|
|
fontWeight:'bold'
|
|
}}>{s.name}</Text>
|
|
<Text>{s.email}</Text>
|
|
</View>
|
|
</View>
|
|
</TouchableOpacity>
|
|
)}
|
|
</View>
|
|
</ScrollView>
|
|
<FAB onPress={Action.preeFABCustomer} color={config.color.primary} icon={{ name: "add", color:"white" }} style={{ position: "absolute", bottom: 20, right: 20 }}></FAB>
|
|
</GestureHandlerRootView>
|
|
</>
|
|
</>}
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default CustomerScreen;
|