206 lines
7.7 KiB
TypeScript
206 lines
7.7 KiB
TypeScript
import Styles from "@/constants/Styles"
|
|
import { apiGetDivisionGroup, apiGetDocumentInformasi, apiGetListDivisionByIdDivision } from "@/lib/api"
|
|
import { useAuthSession } from "@/providers/AuthProvider"
|
|
import { AntDesign } from "@expo/vector-icons"
|
|
import { useEffect, useState } from "react"
|
|
import { Pressable, ScrollView, Text, ToastAndroid, View } from "react-native"
|
|
import { ButtonForm } from "./buttonForm"
|
|
import DrawerBottom from "./drawerBottom"
|
|
|
|
type Props = {
|
|
open: boolean
|
|
close: (value: boolean) => void
|
|
title: string
|
|
category: 'share-division' | 'choose-division'
|
|
choose: string
|
|
onSelect: (value: any[]) => void
|
|
value?: any
|
|
item?: any
|
|
}
|
|
|
|
type CheckedState = {
|
|
[key: string]: string[];
|
|
}
|
|
|
|
type GroupData = {
|
|
id: string;
|
|
name: string;
|
|
Division: {
|
|
id: string;
|
|
name: string;
|
|
}[];
|
|
}
|
|
|
|
export default function ModalSelectMultiple({ open, close, title, category, choose, onSelect, value, item }: Props) {
|
|
const [isChoose, setChoose] = useState(choose)
|
|
const { token, decryptToken } = useAuthSession()
|
|
const [data, setData] = useState<any>([])
|
|
const [checked, setChecked] = useState<CheckedState>({});
|
|
const [selectedDivision, setSelectedDivision] = useState<any>([]);
|
|
|
|
async function handleLoadChooseDivision() {
|
|
try {
|
|
const hasil = await decryptToken(String(token?.current))
|
|
const response = await apiGetDivisionGroup({ user: hasil })
|
|
setData(response.data)
|
|
|
|
if (value?.length > 0) {
|
|
const formatArray = value.reduce((result: any, obj: any) => {
|
|
result[obj.id] = obj.Division.map((item: any) => item.id);
|
|
return result;
|
|
}, {})
|
|
setChecked(formatArray)
|
|
}
|
|
} catch (error) {
|
|
console.error(error)
|
|
}
|
|
}
|
|
|
|
async function handleLoadShareDivision() {
|
|
try {
|
|
const hasil = await decryptToken(String(token?.current))
|
|
const response = await apiGetListDivisionByIdDivision({ user: hasil, search: '', division: value })
|
|
const response2 = await apiGetDocumentInformasi({ user: hasil, item: item, cat: 'share' })
|
|
setData(response.data.filter((i: any) => i.id != value))
|
|
setSelectedDivision(response2.data)
|
|
} catch (error) {
|
|
console.error(error)
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (open) {
|
|
if (category == 'choose-division') {
|
|
handleLoadChooseDivision()
|
|
} else if (category == 'share-division') {
|
|
handleLoadShareDivision()
|
|
}
|
|
}
|
|
|
|
}, [open]);
|
|
|
|
const handleCheck = (groupId: string, divisionId: string) => {
|
|
const newChecked = { ...checked };
|
|
if (newChecked[groupId]) {
|
|
if (newChecked[groupId].includes(divisionId)) {
|
|
newChecked[groupId] = newChecked[groupId].filter(item => item !== divisionId);
|
|
if (newChecked[groupId]?.length === 0) {
|
|
delete newChecked[groupId];
|
|
}
|
|
} else {
|
|
newChecked[groupId].push(divisionId);
|
|
}
|
|
} else {
|
|
newChecked[groupId] = [divisionId];
|
|
}
|
|
setChecked(newChecked);
|
|
};
|
|
|
|
|
|
const handleGroupCheck = (groupId: string) => {
|
|
const newChecked = { ...checked };
|
|
if (newChecked[groupId]) {
|
|
delete newChecked[groupId];
|
|
} else {
|
|
if (data.find((item: { id: string }) => item.id === groupId)?.Division?.length == 0) {
|
|
return ToastAndroid.show('Tidak ada divisi', ToastAndroid.SHORT)
|
|
}
|
|
newChecked[groupId] = data.find((item: { id: string }) => item.id === groupId)?.Division.map((item: { id: any }) => item.id) || [];
|
|
}
|
|
setChecked(newChecked);
|
|
};
|
|
|
|
const handleDivisionClick = (index: number) => {
|
|
if (selectedDivision.some((i: any) => i.id == data[index].id)) {
|
|
setSelectedDivision(
|
|
selectedDivision.filter((i: any) => i.id != data[index].id)
|
|
);
|
|
} else {
|
|
setSelectedDivision([
|
|
...selectedDivision,
|
|
{ id: data[index].id, name: data[index].name },
|
|
]);
|
|
}
|
|
};
|
|
|
|
|
|
const handleSubmit = () => {
|
|
if (category == "choose-division") {
|
|
const selectedGroups: GroupData[] = [];
|
|
Object.keys(checked).forEach((groupId) => {
|
|
const group = data.find((item: { id: string }) => item.id === groupId);
|
|
if (group) {
|
|
selectedGroups.push({
|
|
id: group.id,
|
|
name: group.name,
|
|
Division: group.Division.filter((division: { id: string }) => checked[groupId].includes(division.id)),
|
|
});
|
|
}
|
|
});
|
|
onSelect(selectedGroups);
|
|
} else {
|
|
onSelect(selectedDivision);
|
|
}
|
|
|
|
};
|
|
|
|
return (
|
|
<DrawerBottom animation="slide" isVisible={open} setVisible={close} title={title} height={85}>
|
|
<ScrollView style={[Styles.mb50]}>
|
|
{
|
|
category == 'share-division' ?
|
|
<>
|
|
{
|
|
data.map((item: any, index: number) => {
|
|
return (
|
|
<Pressable key={index} style={[Styles.itemSelectModal]} onPress={() => {
|
|
handleDivisionClick(index)
|
|
}}>
|
|
<Text numberOfLines={1} style={[Styles.w80]}>{item.name}</Text>
|
|
{
|
|
selectedDivision.some((i: any) => i.id == item.id)
|
|
? <AntDesign name="check" size={18} />
|
|
: <></>
|
|
}
|
|
</Pressable>
|
|
)
|
|
})
|
|
}
|
|
</>
|
|
:
|
|
data.map((item: any, index: number) => {
|
|
return (
|
|
<View key={index}>
|
|
<Pressable style={[Styles.itemSelectModal]} onPress={() => { handleGroupCheck(item.id) }}>
|
|
<Text style={[Styles.textMediumSemiBold]}>{item.name}</Text>
|
|
{
|
|
checked[item.id] && checked[item.id]?.length === item.Division?.length
|
|
? <AntDesign name="check" size={20} />
|
|
: (checked[item.id] && checked[item.id]?.length > 0 && checked[item.id]?.length < item.Division?.length)
|
|
? <AntDesign name="minus" size={20} />
|
|
: <></>
|
|
}
|
|
</Pressable>
|
|
{
|
|
item.Division.map((child: any, v: number) => {
|
|
return (
|
|
<Pressable key={v} style={[Styles.itemSelectModal]} onPress={() => { handleCheck(item.id, child.id) }}>
|
|
<Text style={[Styles.ml10, Styles.textMediumNormal, Styles.w80]} numberOfLines={1} ellipsizeMode="tail" >{child.name}</Text>
|
|
{
|
|
checked[item.id] && checked[item.id].includes(child.id) && <AntDesign name="check" size={20} />
|
|
}
|
|
</Pressable>
|
|
)
|
|
})
|
|
}
|
|
</View>
|
|
)
|
|
})
|
|
}
|
|
</ScrollView>
|
|
<View style={[Styles.absolute0, { width: '100%' }]}>
|
|
<ButtonForm text="PILIH" onPress={() => { handleSubmit() }} />
|
|
</View>
|
|
</DrawerBottom>
|
|
)
|
|
} |