deskripsi: - warna refresh control pada semua fitur - warna bottom pada modal select No Issues
328 lines
13 KiB
TypeScript
328 lines
13 KiB
TypeScript
import ModalConfirmation from "@/components/ModalConfirmation"
|
|
import AppHeader from "@/components/AppHeader"
|
|
import BorderBottomItem from "@/components/borderBottomItem"
|
|
import ButtonBackHeader from "@/components/buttonBackHeader"
|
|
import HeaderRightCalendarDetail from "@/components/calendar/headerCalendarDetail"
|
|
import DrawerBottom from "@/components/drawerBottom"
|
|
import ImageUser from "@/components/imageNew"
|
|
import MenuItemRow from "@/components/menuItemRow"
|
|
import Skeleton from "@/components/skeleton"
|
|
import Text from "@/components/Text"
|
|
import { ConstEnv } from "@/constants/ConstEnv"
|
|
import Styles from "@/constants/Styles"
|
|
import { apiDeleteCalendarMember, apiGetCalendarOne, apiGetDivisionOneFeature } from "@/lib/api"
|
|
import { setUpdateCalendar } from "@/lib/calendarUpdate"
|
|
import { useAuthSession } from "@/providers/AuthProvider"
|
|
import { useTheme } from "@/providers/ThemeProvider"
|
|
import { MaterialCommunityIcons } from "@expo/vector-icons"
|
|
import Clipboard from "@react-native-clipboard/clipboard"
|
|
import { router, Stack, useLocalSearchParams } from "expo-router"
|
|
import { useEffect, useState } from "react"
|
|
import { Pressable, RefreshControl, SafeAreaView, ScrollView, View } from "react-native"
|
|
import Toast from "react-native-toast-message"
|
|
import { useDispatch, useSelector } from "react-redux"
|
|
|
|
type Props = {
|
|
id: string;
|
|
timeStart: string;
|
|
timeEnd: string;
|
|
dateStart: string;
|
|
dateEnd: string;
|
|
idCalendar: string;
|
|
status: number;
|
|
title: string;
|
|
desc: string;
|
|
linkMeet: string;
|
|
repeatEventTyper: string;
|
|
repeatValue: number;
|
|
}
|
|
|
|
type PropsMember = {
|
|
id: string;
|
|
idUser: string;
|
|
name: string;
|
|
img: string;
|
|
email: string
|
|
}
|
|
|
|
export default function DetailEventCalendar() {
|
|
const { colors } = useTheme()
|
|
const { id, detail } = useLocalSearchParams<{ id: string, detail: string }>();
|
|
const [data, setData] = useState<Props>()
|
|
const [member, setMember] = useState<PropsMember[]>([])
|
|
const { token, decryptToken } = useAuthSession();
|
|
const [memberChoose, setMemberChoose] = useState({ id: '', name: '' })
|
|
const [isModalMember, setModalMember] = useState(false)
|
|
const update = useSelector((state: any) => state.calendarUpdate)
|
|
const dispatch = useDispatch()
|
|
const entityUser = useSelector((state: any) => state.user);
|
|
const [isMemberDivision, setIsMemberDivision] = useState(false);
|
|
const [showDeleteModal, setShowDeleteModal] = useState(false)
|
|
const [loading, setLoading] = useState(true)
|
|
const [refreshing, setRefreshing] = useState(false)
|
|
|
|
async function handleCheckMember() {
|
|
try {
|
|
const hasil = await decryptToken(String(token?.current));
|
|
const response = await apiGetDivisionOneFeature({
|
|
id,
|
|
user: hasil,
|
|
cat: "check-member",
|
|
});
|
|
|
|
setIsMemberDivision(response.data);
|
|
} catch (error) {
|
|
console.error(error);
|
|
}
|
|
}
|
|
|
|
async function handleLoad(loading: boolean) {
|
|
try {
|
|
setLoading(loading)
|
|
const hasil = await decryptToken(String(token?.current));
|
|
const response = await apiGetCalendarOne({
|
|
user: hasil,
|
|
id: detail,
|
|
cat: 'data',
|
|
});
|
|
if (response.success) {
|
|
setData(response.data);
|
|
} else {
|
|
router.replace(`/division/${id}/calendar/`)
|
|
}
|
|
} catch (error) {
|
|
console.error(error);
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
async function handleLoadMember() {
|
|
try {
|
|
const hasil = await decryptToken(String(token?.current));
|
|
const response = await apiGetCalendarOne({
|
|
user: hasil,
|
|
id: detail,
|
|
cat: 'member',
|
|
});
|
|
setMember(response.data);
|
|
} catch (error) {
|
|
console.error(error);
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
handleLoad(true);
|
|
handleCheckMember()
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
handleLoadMember();
|
|
}, [update.member]);
|
|
|
|
const handleCopy = (text: string) => {
|
|
Clipboard.setString(text);
|
|
Toast.show({ type: 'small', text1: 'Berhasil menyalin link', })
|
|
};
|
|
|
|
async function handleDeleteUser() {
|
|
try {
|
|
const hasil = await decryptToken(String(token?.current));
|
|
const response = await apiDeleteCalendarMember({
|
|
user: hasil,
|
|
idUser: memberChoose.id,
|
|
}, String(data?.idCalendar));
|
|
|
|
if (response.success) {
|
|
dispatch(setUpdateCalendar({ ...update, member: !update.member }));
|
|
}
|
|
Toast.show({ type: 'small', text1: response.message, })
|
|
} catch (error) {
|
|
console.error(error);
|
|
Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
|
} finally {
|
|
setModalMember(false)
|
|
}
|
|
}
|
|
|
|
|
|
const handleRefresh = async () => {
|
|
setRefreshing(true)
|
|
handleLoad(false)
|
|
handleLoadMember()
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
setRefreshing(false)
|
|
};
|
|
|
|
return (
|
|
<SafeAreaView style={{ flex: 1, backgroundColor: colors.background }}>
|
|
<Stack.Screen
|
|
options={{
|
|
// headerLeft: () => <ButtonBackHeader onPress={() => { router.back() }} />,
|
|
headerTitle: 'Detail Acara',
|
|
headerTitleAlign: 'center',
|
|
// headerRight: () => (entityUser.role == "user" || entityUser.role == "coadmin") && !isMemberDivision ? <></> : <HeaderRightCalendarDetail id={String(data?.idCalendar)} idReminder={String(detail)} />
|
|
header: () => (
|
|
<AppHeader
|
|
title="Detail Acara"
|
|
showBack={true}
|
|
onPressLeft={() => router.back()}
|
|
right={
|
|
(entityUser.role == "user" || entityUser.role == "coadmin") && !isMemberDivision ? <></> : <HeaderRightCalendarDetail id={String(data?.idCalendar)} idReminder={String(detail)} />
|
|
}
|
|
/>
|
|
)
|
|
}}
|
|
/>
|
|
<ScrollView
|
|
style={[Styles.h100]}
|
|
refreshControl={
|
|
<RefreshControl
|
|
refreshing={refreshing}
|
|
onRefresh={handleRefresh}
|
|
tintColor={colors.icon}
|
|
/>
|
|
}
|
|
>
|
|
<View style={[Styles.p15]}>
|
|
<View style={[Styles.wrapPaper, Styles.mb15, { backgroundColor: colors.card, borderColor: colors.background }]}>
|
|
<View style={[Styles.rowItemsCenter, { alignItems: 'flex-start' }]}>
|
|
<MaterialCommunityIcons name="calendar-text" size={30} color={colors.text} style={Styles.mr10} />
|
|
{
|
|
loading ?
|
|
<Skeleton width={80} height={10} borderRadius={10} widthType="percent" />
|
|
: <Text style={[Styles.textDefault, Styles.w90]}>{data?.title}</Text>
|
|
}
|
|
|
|
</View>
|
|
<View style={[Styles.rowItemsCenter, Styles.mt10]}>
|
|
<MaterialCommunityIcons name="calendar-month-outline" size={30} color={colors.text} style={Styles.mr10} />
|
|
{
|
|
loading ?
|
|
<Skeleton width={80} height={10} borderRadius={10} widthType="percent" />
|
|
:
|
|
<Text style={[Styles.textDefault]}>{data?.dateStart}</Text>
|
|
}
|
|
</View>
|
|
<View style={[Styles.rowItemsCenter, Styles.mt10]}>
|
|
<MaterialCommunityIcons name="clock-outline" size={30} color={colors.text} style={Styles.mr10} />
|
|
{
|
|
loading ?
|
|
<Skeleton width={80} height={10} borderRadius={10} widthType="percent" />
|
|
:
|
|
<Text style={[Styles.textDefault]}>{data?.timeStart} | {data?.timeEnd}</Text>
|
|
}
|
|
</View>
|
|
<View style={[Styles.rowItemsCenter, Styles.mt10]}>
|
|
<MaterialCommunityIcons name="repeat" size={30} color={colors.text} style={Styles.mr10} />
|
|
{
|
|
loading ?
|
|
<Skeleton width={80} height={10} borderRadius={10} widthType="percent" />
|
|
:
|
|
<Text style={[Styles.textDefault]}>
|
|
{
|
|
data?.repeatEventTyper.toString() === 'once' ? 'Acara 1 Kali' :
|
|
data?.repeatEventTyper.toString() === 'daily' ? 'Setiap Hari' :
|
|
data?.repeatEventTyper.toString() === 'weekly' ? 'Mingguan' :
|
|
data?.repeatEventTyper.toString() === 'monthly' ? 'Bulanan' :
|
|
data?.repeatEventTyper.toString() === 'yearly' ? 'Tahunan' :
|
|
''
|
|
}
|
|
</Text>
|
|
}
|
|
</View>
|
|
<View style={[Styles.rowItemsCenter, Styles.mt10]}>
|
|
<MaterialCommunityIcons name="link-variant" size={30} color={colors.text} style={Styles.mr10} />
|
|
{
|
|
loading ?
|
|
<Skeleton width={80} height={10} borderRadius={10} widthType="percent" />
|
|
:
|
|
data?.linkMeet ?
|
|
<Pressable onPress={() => { handleCopy(data.linkMeet) }}>
|
|
<Text style={[Styles.textDefault]}>{data.linkMeet}</Text>
|
|
</Pressable>
|
|
: <Text style={[Styles.textDefault]}>-</Text>
|
|
}
|
|
</View>
|
|
<View style={[Styles.rowItemsCenter, Styles.mt10, { alignItems: 'flex-start' }]}>
|
|
<MaterialCommunityIcons name="card-text-outline" size={30} color={colors.text} style={Styles.mr10} />
|
|
{
|
|
loading ?
|
|
<Skeleton width={80} height={10} borderRadius={10} widthType="percent" />
|
|
:
|
|
<Text style={[Styles.textDefault, Styles.w90]}>{data?.desc}</Text>
|
|
}
|
|
</View>
|
|
</View>
|
|
|
|
<View style={[Styles.mb15]}>
|
|
<View style={[Styles.rowSpaceBetween, Styles.mv05]}>
|
|
<Text style={[Styles.textDefaultSemiBold]}>Anggota</Text>
|
|
<Text style={[Styles.textDefault]}>Total {member.length} Anggota</Text>
|
|
</View>
|
|
|
|
<View style={[Styles.wrapPaper, { backgroundColor: colors.card, borderColor: colors.background }]}>
|
|
{
|
|
member.map((item, index) => (
|
|
<BorderBottomItem
|
|
key={index}
|
|
borderType="bottom"
|
|
icon={<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} />}
|
|
title={item.name}
|
|
subtitle={item.email}
|
|
onPress={() => {
|
|
if ((entityUser.role == "user" || entityUser.role == "coadmin") && !isMemberDivision) {
|
|
null
|
|
} else {
|
|
setMemberChoose({ id: item.idUser, name: item.name })
|
|
setModalMember(true)
|
|
}
|
|
}}
|
|
/>
|
|
))
|
|
}
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</ScrollView>
|
|
|
|
|
|
<DrawerBottom animation="slide" isVisible={isModalMember} setVisible={setModalMember} title={memberChoose.name}>
|
|
<View style={Styles.rowItemsCenter}>
|
|
<MenuItemRow
|
|
icon={<MaterialCommunityIcons name="account-eye" color={colors.text} size={25} />}
|
|
title="Lihat Profil"
|
|
onPress={() => {
|
|
setModalMember(false)
|
|
router.push(`/member/${memberChoose.id}`)
|
|
}}
|
|
/>
|
|
|
|
<MenuItemRow
|
|
icon={<MaterialCommunityIcons name="account-remove" color={colors.text} size={25} />}
|
|
title="Keluarkan"
|
|
onPress={() => {
|
|
setModalMember(false)
|
|
setTimeout(() => {
|
|
setShowDeleteModal(true)
|
|
}, 600)
|
|
}}
|
|
/>
|
|
</View>
|
|
</DrawerBottom>
|
|
|
|
<ModalConfirmation
|
|
visible={showDeleteModal}
|
|
title="Konfirmasi"
|
|
message="Apakah Anda yakin ingin mengeluarkan anggota?"
|
|
onConfirm={() => {
|
|
setShowDeleteModal(false)
|
|
handleDeleteUser()
|
|
}}
|
|
onCancel={() => setShowDeleteModal(false)}
|
|
confirmText="Keluar"
|
|
cancelText="Batal"
|
|
/>
|
|
</SafeAreaView>
|
|
)
|
|
} |