diff --git a/app/(application)/announcement/[id].tsx b/app/(application)/announcement/[id].tsx index b63051e..a3ec9a2 100644 --- a/app/(application)/announcement/[id].tsx +++ b/app/(application)/announcement/[id].tsx @@ -7,7 +7,7 @@ import { apiGetAnnouncementOne } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; import { Entypo, MaterialIcons } from "@expo/vector-icons"; import { router, Stack, useLocalSearchParams } from "expo-router"; -import { useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { Dimensions, SafeAreaView, ScrollView, View } from "react-native"; import RenderHTML from 'react-native-render-html'; import { useSelector } from "react-redux"; @@ -51,6 +51,11 @@ export default function DetailAnnouncement() { handleLoad(true) }, []) + function hasHtmlTags(text: string) { + const htmlRegex = /<[a-z][\s\S]*>/i; + return htmlRegex.test(text); + }; + return ( {data?.title} - + { + hasHtmlTags(data?.desc) ? + + : + {data?.desc} + } } diff --git a/app/(application)/banner/index.tsx b/app/(application)/banner/index.tsx index dcbf335..a1f0e4a 100644 --- a/app/(application)/banner/index.tsx +++ b/app/(application)/banner/index.tsx @@ -119,7 +119,7 @@ export default function BannerList() { onRefresh={handleRefresh} /> } - style={[{height:'100%'}]} + style={[Styles.h100]} > {entities.map((index: any, key: number) => ( diff --git a/app/(application)/discussion/[id].tsx b/app/(application)/discussion/[id].tsx index 36aee1e..194e713 100644 --- a/app/(application)/discussion/[id].tsx +++ b/app/(application)/discussion/[id].tsx @@ -6,6 +6,7 @@ import { InputForm } from "@/components/inputForm"; import LabelStatus from "@/components/labelStatus"; import Skeleton from "@/components/skeleton"; import SkeletonContent from "@/components/skeletonContent"; +import Text from '@/components/Text'; import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; import { apiGetDiscussionGeneralOne, apiSendDiscussionGeneralCommentar } from "@/lib/api"; @@ -14,8 +15,7 @@ import { Ionicons, MaterialIcons } from "@expo/vector-icons"; import { firebase } from '@react-native-firebase/database'; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; -import { Pressable, ScrollView, View } from "react-native"; -import Text from '@/components/Text'; +import { KeyboardAvoidingView, Platform, Pressable, ScrollView, View } from "react-native"; import { useSelector } from "react-redux"; type Props = { @@ -195,30 +195,34 @@ export default function DetailDiscussionGeneral() { - - { - (komentar != '' && data?.status === 1 && data?.isActive && (memberDiscussion || (entityUser.role != "user" && entityUser.role != "coadmin"))) - && handleKomentar() - }}> - - - } - /> - + + + { + (komentar != '' && data?.status === 1 && data?.isActive && (memberDiscussion || (entityUser.role != "user" && entityUser.role != "coadmin"))) + && handleKomentar() + }}> + + + } + /> + + ) diff --git a/app/(application)/discussion/add-member/[id].tsx b/app/(application)/discussion/add-member/[id].tsx index d2657ac..648d6af 100644 --- a/app/(application)/discussion/add-member/[id].tsx +++ b/app/(application)/discussion/add-member/[id].tsx @@ -114,7 +114,7 @@ export default function AddMemberDiscussionDetail() { onChoose(item.idUser, item.name, item.img)} /> )) diff --git a/app/(application)/discussion/create.tsx b/app/(application)/discussion/create.tsx index c78da75..257218c 100644 --- a/app/(application)/discussion/create.tsx +++ b/app/(application)/discussion/create.tsx @@ -101,9 +101,12 @@ export default function CreateDiscussionGeneral() { dispatch(setUpdateDiscussionGeneralDetail(!update)) Toast.show({ type: 'small', text1: 'Berhasil menambahkan data', }) router.back() + }else{ + Toast.show({ type: 'small', text1: response.message, }) } } catch (error) { console.error(error); + Toast.show({ type: 'small', text1: 'Terjadi kesalahan', }) } } diff --git a/app/(application)/division/[id]/(fitur-division)/calendar/index.tsx b/app/(application)/division/[id]/(fitur-division)/calendar/index.tsx index be93162..2df22f4 100644 --- a/app/(application)/division/[id]/(fitur-division)/calendar/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/calendar/index.tsx @@ -144,7 +144,9 @@ export default function CalendarDivision() { refreshing={refreshing} onRefresh={handleRefresh} /> - }> + } + style={[Styles.h100]} + > ) : ( isList ? ( - + ) : ( - + - - } - > - - - { setStatus("true") }} - label="Aktif" - icon={} - n={2} /> - { setStatus("false") }} - label="Tidak Aktif" - icon={} - n={2} /> - - + + + { setStatus("true") }} + label="Aktif" + icon={} + n={2} /> + { setStatus("false") }} + label="Tidak Aktif" + icon={} + n={2} /> + + + + } + style={[Styles.h100]} + > { @@ -173,8 +174,8 @@ export default function Index() { Tidak ada data } - - + + setModal(false)} title={titleChoose}> @@ -203,7 +204,7 @@ export default function Index() { - setVisibleEdit(false)} title="Edit Lembaga Desa"> + setVisibleEdit(false)} title="Edit Lembaga Desa"> diff --git a/app/(application)/member/[id].tsx b/app/(application)/member/[id].tsx index 02b6686..7ee9a85 100644 --- a/app/(application)/member/[id].tsx +++ b/app/(application)/member/[id].tsx @@ -9,7 +9,7 @@ import Styles from "@/constants/Styles"; import { apiGetProfile } from "@/lib/api"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; -import { SafeAreaView, ScrollView, View } from "react-native"; +import { RefreshControl, SafeAreaView, ScrollView, View } from "react-native"; import { useSelector } from "react-redux"; type Props = { @@ -34,10 +34,11 @@ export default function MemberDetail() { const [isEdit, setEdit] = useState(true) const arrSkeleton = Array.from({ length: 5 }, (_, index) => index) const [loading, setLoading] = useState(true) + const [refreshing, setRefreshing] = useState(false) - async function handleLoad() { + async function handleLoad(loading: boolean) { try { - setLoading(true) + setLoading(loading) const response = await apiGetProfile({ id: id }) setData(response.data) setEdit(valueRoleUser.filter((v) => v.login == entityUser.role)[0]?.data.some((i: any) => i.id == response.data.idUserRole)) @@ -50,9 +51,17 @@ export default function MemberDetail() { useEffect(() => { - handleLoad() + handleLoad(true) }, []); + + const handleRefresh = async () => { + setRefreshing(true) + handleLoad(false) + await new Promise(resolve => setTimeout(resolve, 2000)); + setRefreshing(false) + }; + return ( - - - - { - loading ? - <> - - - - - : - <> - - {data?.name} - {data?.role} - + + } + > + + { + loading ? + <> + + + + + : + <> + + {data?.name} + {data?.role} + - } + } + + + + Informasi - - - Informasi - - { - loading ? - arrSkeleton.map((item, index) => { - return ( - - ) - }) - : - <> - - - - - - - - } + { + loading ? + arrSkeleton.map((item, index) => { + return ( + + ) + }) + : + <> + + + + + + + + } - diff --git a/app/(application)/member/create.tsx b/app/(application)/member/create.tsx index 6c45209..f76801f 100644 --- a/app/(application)/member/create.tsx +++ b/app/(application)/member/create.tsx @@ -15,6 +15,8 @@ import { router, Stack } from "expo-router"; import { useEffect, useState } from "react"; import { Image, + KeyboardAvoidingView, + Platform, Pressable, SafeAreaView, ScrollView, @@ -213,132 +215,139 @@ export default function CreateMember() { ), }} /> - - - - {selectedImage != undefined ? ( - - - - ) : ( - - + + + + {selectedImage != undefined ? ( + + + + ) : ( + + + + )} + + {(entityUser.role == "supadmin" || + entityUser.role == "developer") && ( + { + setValChoose(chooseGroup.val); + setValSelect("group"); + setSelect(true); + }} + error={error.group} + errorText="Lembaga Desa tidak boleh kosong" /> - - )} + )} + { + setValChoose(choosePosition.val); + setValSelect("position"); + setSelect(true); + }} + error={error.position} + errorText="Jabatan tidak boleh kosong" + /> + { + setValChoose(chooseRole.val); + setValSelect("role"); + setSelect(true); + }} + error={error.role} + errorText="Role tidak boleh kosong" + /> + { + validationForm("nik", val) + }} + /> + { + validationForm("name", val) + }} + /> + { + validationForm("email", val) + }} + /> + +62} + error={error.phone} + errorText="Nomor Telepon tidak valid" + onChange={val => { + validationForm("phone", val) + }} + /> + { + setValChoose(chooseGender.val); + setValSelect("gender"); + setSelect(true); + }} + error={error.gender} + errorText="Jenis Kelamin tidak boleh kosong" + /> - {(entityUser.role == "supadmin" || - entityUser.role == "developer") && ( - { - setValChoose(chooseGroup.val); - setValSelect("group"); - setSelect(true); - }} - error={error.group} - errorText="Lembaga Desa tidak boleh kosong" - /> - )} - { - setValChoose(choosePosition.val); - setValSelect("position"); - setSelect(true); - }} - error={error.position} - errorText="Jabatan tidak boleh kosong" - /> - { - setValChoose(chooseRole.val); - setValSelect("role"); - setSelect(true); - }} - error={error.role} - errorText="Role tidak boleh kosong" - /> - { - validationForm("nik", val) - }} - /> - { - validationForm("name", val) - }} - /> - { - validationForm("email", val) - }} - /> - +62} - error={error.phone} - errorText="Nomor Telepon tidak valid" - onChange={val => { - validationForm("phone", val) - }} - /> - { - setValChoose(chooseGender.val); - setValSelect("gender"); - setSelect(true); - }} - error={error.gender} - errorText="Jenis Kelamin tidak boleh kosong" - /> - - + + + { setSelect(false) }} onSelect={(value) => { validationForm(valSelect, value.val, value.label); }} diff --git a/app/(application)/member/edit/[id].tsx b/app/(application)/member/edit/[id].tsx index 0fef919..b25575e 100644 --- a/app/(application)/member/edit/[id].tsx +++ b/app/(application)/member/edit/[id].tsx @@ -13,6 +13,8 @@ import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { Image, + KeyboardAvoidingView, + Platform, Pressable, SafeAreaView, ScrollView, @@ -249,131 +251,138 @@ export default function EditMember() { ), }} /> - - - - { - errorImg ? - - { - { setErrorImg(true) }} - /> - } - - : - selectedImage != undefined ? ( + + + + + + { + errorImg ? - { setErrorImg(true) }} - /> + { + { setErrorImg(true) }} + /> + } - ) : ( - - ) - } + : + selectedImage != undefined ? ( + + { setErrorImg(true) }} + /> + + ) : ( + + ) + } + + { + setValChoose(choosePosition.val); + setValSelect("position"); + setSelect(true); + }} + error={error.position} + errorText="Jabatan tidak boleh kosong" + /> + { + setValChoose(chooseRole.val); + setValSelect("role"); + setSelect(true); + }} + error={error.role} + errorText="Role tidak boleh kosong" + /> + { + validationForm("nik", val) + }} + /> + { + validationForm("name", val) + }} + /> + { + validationForm("email", val) + }} + /> + +62} + value={data?.phone} + error={error.phone} + errorText="Nomor Telepon tidak valid" + onChange={val => { + validationForm("phone", val) + }} + /> + { + setValChoose(chooseGender.val); + setValSelect("gender"); + setSelect(true); + }} + error={error.gender} + errorText="Jenis Kelamin tidak boleh kosong" + /> - { - setValChoose(choosePosition.val); - setValSelect("position"); - setSelect(true); - }} - error={error.position} - errorText="Jabatan tidak boleh kosong" - /> - { - setValChoose(chooseRole.val); - setValSelect("role"); - setSelect(true); - }} - error={error.role} - errorText="Role tidak boleh kosong" - /> - { - validationForm("nik", val) - }} - /> - { - validationForm("name", val) - }} - /> - { - validationForm("email", val) - }} - /> - +62} - value={data?.phone} - error={error.phone} - errorText="Nomor Telepon tidak valid" - onChange={val => { - validationForm("phone", val) - }} - /> - { - setValChoose(chooseGender.val); - setValSelect("gender"); - setSelect(true); - }} - error={error.gender} - errorText="Jenis Kelamin tidak boleh kosong" - /> - - + + - - }> - - - { setStatus("true") }} - label="Aktif" - icon={} - n={2} /> - { setStatus("false") }} - label="Tidak Aktif" - icon={} - n={2} /> + + + { setStatus("true") }} + label="Aktif" + icon={} + n={2} /> + { setStatus("false") }} + label="Tidak Aktif" + icon={} + n={2} /> + + + { + (entityUser.role == "supadmin" || entityUser.role == "developer") && + + Filter : {nameGroup} - - { - (entityUser.role == "supadmin" || entityUser.role == "developer") && - - Filter : {nameGroup} - - } + } + + }> { loading ? @@ -193,8 +193,8 @@ export default function Index() { Tidak ada data } - - + + setModal(false)} title={chooseData.name}> @@ -224,7 +224,7 @@ export default function Index() { - setVisibleEdit(false)} title="Edit Jabatan"> + setVisibleEdit(false)} title="Edit Jabatan"> state.projectUpdate) const [isMember, setIsMember] = useState(false) const entityUser = useSelector((state: any) => state.user) + const [refreshing, setRefreshing] = useState(false) async function handleLoad(cat: 'data' | 'progress') { try { @@ -79,6 +80,14 @@ export default function DetailProject() { }, []) + const handleRefresh = async () => { + setRefreshing(true) + await handleLoad('data') + await handleLoad('progress') + await new Promise(resolve => setTimeout(resolve, 2000)); + setRefreshing(false) + }; + return ( (entityUser.role == "user" || entityUser.role == "coadmin") && !isMember ? null : , }} /> - + + } + > { data?.reason != null && data?.reason != "" && } - - - + + + diff --git a/app/(application)/project/index.tsx b/app/(application)/project/index.tsx index 2e0a873..f13bd65 100644 --- a/app/(application)/project/index.tsx +++ b/app/(application)/project/index.tsx @@ -220,7 +220,7 @@ export default function ListProject() { data.length > 0 ? isList ? ( - + data.length} @@ -280,7 +280,7 @@ export default function ListProject() { } */} ) : ( - + data.length} diff --git a/components/buttonTab.tsx b/components/buttonTab.tsx index 501ef49..b5449a9 100644 --- a/components/buttonTab.tsx +++ b/components/buttonTab.tsx @@ -17,7 +17,7 @@ export default function ButtonTab({ active, value, onPress, label, n, icon }: Pr return ( { onPress() }}> {icon} - {label} + {label} ) } \ No newline at end of file diff --git a/components/discussion_general/headerDiscussionGeneral.tsx b/components/discussion_general/headerDiscussionGeneral.tsx index 94d88a6..8b7e6b9 100644 --- a/components/discussion_general/headerDiscussionGeneral.tsx +++ b/components/discussion_general/headerDiscussionGeneral.tsx @@ -34,7 +34,9 @@ export default function HeaderDiscussionGeneral() { title="Filter" onPress={() => { setVisible(false) - setFilter(true) + setTimeout(() => { + setFilter(true) + }, 600) }} /> } diff --git a/components/division/headerDivisionList.tsx b/components/division/headerDivisionList.tsx index 71691e8..8a6147f 100644 --- a/components/division/headerDivisionList.tsx +++ b/components/division/headerDivisionList.tsx @@ -37,7 +37,9 @@ export default function HeaderRightDivisionList() { title="Filter" onPress={() => { setVisible(false) - setFilter(true) + setTimeout(() => { + setFilter(true) + }, 600); }} /> } diff --git a/components/drawerBottom.tsx b/components/drawerBottom.tsx index 82734d2..750df0b 100644 --- a/components/drawerBottom.tsx +++ b/components/drawerBottom.tsx @@ -1,8 +1,8 @@ import Styles from "@/constants/Styles"; import { MaterialIcons } from "@expo/vector-icons"; -import { Pressable, View } from "react-native"; -import Text from "./Text"; +import { Dimensions, KeyboardAvoidingView, Platform, Pressable, View } from "react-native"; import Modal from 'react-native-modal'; +import Text from "./Text"; type Props = { isVisible: boolean @@ -12,28 +12,15 @@ type Props = { animation?: 'slide' | 'none' | 'fade' height?: number backdropPressable?: boolean + keyboard?: boolean } -export default function DrawerBottom({ isVisible, setVisible, title, children, animation, height, backdropPressable = true }: Props) { - return ( - // - // - // - // - // {title} - // setVisible(false)}> - // - // - // - // - // {children} - // - // - // - // +export default function DrawerBottom({ isVisible, setVisible, title, children, animation, height, backdropPressable = true, keyboard = false }: Props) { + const tinggiScreen = Dimensions.get("window").height; + const tinggiInput = height != undefined ? height : 25 + const tinggiFix = tinggiScreen * tinggiInput / 100; + return ( - - - {title} - setVisible(false)}> - - - - - {children} - - + { + keyboard ? + + + + {title} + setVisible(false)}> + + + + + {children} + + + + : + + + {title} + setVisible(false)}> + + + + + {children} + + + } ) } \ No newline at end of file diff --git a/components/group/headerGroupList.tsx b/components/group/headerGroupList.tsx index fb443fd..490dd76 100644 --- a/components/group/headerGroupList.tsx +++ b/components/group/headerGroupList.tsx @@ -78,7 +78,7 @@ export default function HeaderRightGroupList() { - setVisibleTambah(false)} title="Tambah Lembaga Desa"> + setVisibleTambah(false)} title="Tambah Lembaga Desa"> { setVisible(true) }} /> - + setVisible(false)} title="Menu"> } @@ -34,7 +34,9 @@ export default function HeaderMemberList() { title="Filter" onPress={() => { setVisible(false) - setFilter(true) + setTimeout(() => { + setFilter(true) + }, 600) }} /> } diff --git a/components/modalSelect.tsx b/components/modalSelect.tsx index 4c892ea..9b174da 100644 --- a/components/modalSelect.tsx +++ b/components/modalSelect.tsx @@ -126,7 +126,7 @@ export default function ModalSelect({ open, close, title, category, idParent, on } return ( - + { category == 'member' && <> diff --git a/components/position/headerRightPositionList.tsx b/components/position/headerRightPositionList.tsx index 4abe608..6d0daa4 100644 --- a/components/position/headerRightPositionList.tsx +++ b/components/position/headerRightPositionList.tsx @@ -123,7 +123,7 @@ export default function HeaderRightPositionList() { - setVisibleTambah(false)} title="Tambah Jabatan"> + setVisibleTambah(false)} title="Tambah Jabatan"> { diff --git a/components/project/headerProjectList.tsx b/components/project/headerProjectList.tsx index 43e9465..7da08f8 100644 --- a/components/project/headerProjectList.tsx +++ b/components/project/headerProjectList.tsx @@ -37,7 +37,9 @@ export default function HeaderRightProjectList() { title="Filter" onPress={() => { setVisible(false) - setFilter(true) + setTimeout(() => { + setFilter(true) + }, 600) }} /> } diff --git a/components/project/sectionFile.tsx b/components/project/sectionFile.tsx index dd3e11f..24caa18 100644 --- a/components/project/sectionFile.tsx +++ b/components/project/sectionFile.tsx @@ -28,7 +28,7 @@ type Props = { idStorage: string } -export default function SectionFile({ status, member }: { status: number | undefined, member: boolean }) { +export default function SectionFile({ status, member, refreshing }: { status: number | undefined, member: boolean, refreshing?: boolean }) { const entityUser = useSelector((state: any) => state.user) const [isModal, setModal] = useState(false) const { token, decryptToken } = useAuthSession(); @@ -62,6 +62,11 @@ export default function SectionFile({ status, member }: { status: number | undef handleLoad(false); }, [update.file]); + useEffect(() => { + if (refreshing) + handleLoad(false); + }, [refreshing]); + useEffect(() => { handleLoad(true); diff --git a/components/project/sectionMember.tsx b/components/project/sectionMember.tsx index d87865c..65ecf57 100644 --- a/components/project/sectionMember.tsx +++ b/components/project/sectionMember.tsx @@ -25,7 +25,7 @@ type Props = { position: string; }; -export default function SectionMember({ status }: { status: number | undefined }) { +export default function SectionMember({ status, refreshing }: { status: number | undefined, refreshing?: boolean }) { const dispatch = useDispatch() const entityUser = useSelector((state: any) => state.user) const update = useSelector((state: any) => state.projectUpdate) @@ -62,6 +62,11 @@ export default function SectionMember({ status }: { status: number | undefined } handleLoad(false); }, [update.member]); + useEffect(() => { + if (refreshing) + handleLoad(false); + }, [refreshing]); + useEffect(() => { handleLoad(true); }, []); @@ -75,7 +80,7 @@ export default function SectionMember({ status }: { status: number | undefined } }, id) if (response.success) { Toast.show({ type: 'small', text1: 'Berhasil menghapus anggota', }) - dispatch(setUpdateProject({ ...update, member: !update.progress })) + dispatch(setUpdateProject({ ...update, member: !update.member })) setModal(false); } } catch (error) { diff --git a/components/project/sectionTanggalTugas.tsx b/components/project/sectionTanggalTugas.tsx index 37a61a4..ee3cb40 100644 --- a/components/project/sectionTanggalTugas.tsx +++ b/components/project/sectionTanggalTugas.tsx @@ -26,7 +26,7 @@ type Props = { createdAt: string; }; -export default function SectionTanggalTugasProject({ status, member }: { status: number | undefined, member: boolean }) { +export default function SectionTanggalTugasProject({ status, member, refreshing }: { status: number | undefined, member: boolean, refreshing?: boolean }) { const entityUser = useSelector((state: any) => state.user) const dispatch = useDispatch() const update = useSelector((state: any) => state.projectUpdate) @@ -63,6 +63,11 @@ export default function SectionTanggalTugasProject({ status, member }: { status: handleLoad(false); }, [update.task]); + useEffect(() => { + if (refreshing) + handleLoad(false); + }, [refreshing]); + useEffect(() => { handleLoad(true); }, []); @@ -163,7 +168,9 @@ export default function SectionTanggalTugasProject({ status, member }: { status: title="Update Status" onPress={() => { setModal(false); - setSelect(true); + setTimeout(() => { + setSelect(true); + }, 600) }} /> { setSelect(false) }} onSelect={(value) => { handleUpdate(Number(value.val)) }} diff --git a/constants/Styles.ts b/constants/Styles.ts index e078327..082fd1e 100644 --- a/constants/Styles.ts +++ b/constants/Styles.ts @@ -188,6 +188,9 @@ const Styles = StyleSheet.create({ round10: { borderRadius: 10 }, + h100: { + height: '100%' + }, w100: { width: '100%' },