diff --git a/app.config.js b/app.config.js index f8aba53..d782fc9 100644 --- a/app.config.js +++ b/app.config.js @@ -79,6 +79,12 @@ export default { URL_FIREBASE_DB: process.env.URL_FIREBASE_DB, PASS_ENC: process.env.PASS_ENC, WA_SERVER_TOKEN: process.env.WA_SERVER_TOKEN, + FIREBASE_API_KEY: process.env.FIREBASE_API_KEY, + FIREBASE_AUTH_DOMAIN: process.env.FIREBASE_AUTH_DOMAIN, + FIREBASE_PROJECT_ID: process.env.FIREBASE_PROJECT_ID, + FIREBASE_STORAGE_BUCKET: process.env.FIREBASE_STORAGE_BUCKET, + FIREBASE_MESSAGING_SENDER_ID: process.env.FIREBASE_MESSAGING_SENDER_ID, + FIREBASE_APP_ID: process.env.FIREBASE_APP_ID, } } }; diff --git a/app/(application)/_layout.tsx b/app/(application)/_layout.tsx index 57cced1..5d77e94 100644 --- a/app/(application)/_layout.tsx +++ b/app/(application)/_layout.tsx @@ -112,6 +112,18 @@ export default function RootLayout() { ) }} /> + { router.back() }} />, + title: 'Pengaturan', + headerTitleAlign: 'center', + // headerRight: () => + header: () => ( + router.back()} + /> + ) + }} /> { router.back() }} />, title: 'Anggota', diff --git a/app/(application)/announcement/[id].tsx b/app/(application)/announcement/[id].tsx index f07dca5..da4a254 100644 --- a/app/(application)/announcement/[id].tsx +++ b/app/(application)/announcement/[id].tsx @@ -200,12 +200,12 @@ export default function DetailAnnouncement() { handleRefresh()} - tintColor={colors.primary} + tintColor={colors.icon} /> } > - + { loading ? @@ -243,7 +243,7 @@ export default function DetailAnnouncement() { { dataFile.length > 0 && ( - + File @@ -268,7 +268,7 @@ export default function DetailAnnouncement() { ) } - + { loading ? arrSkeleton.map((item, index) => { diff --git a/app/(application)/announcement/index.tsx b/app/(application)/announcement/index.tsx index 4319656..d362143 100644 --- a/app/(application)/announcement/index.tsx +++ b/app/(application)/announcement/index.tsx @@ -112,9 +112,9 @@ export default function Announcement() { borderType="bottom" bgColor="transparent" icon={ - - - + // + + // } title={item.title} desc={item.desc.replace(/<[^>]*>?/gm, '').replace(/\r?\n|\r/g, ' ')} @@ -130,7 +130,7 @@ export default function Announcement() { } /> diff --git a/app/(application)/banner/index.tsx b/app/(application)/banner/index.tsx index a25e786..dc2507f 100644 --- a/app/(application)/banner/index.tsx +++ b/app/(application)/banner/index.tsx @@ -1,9 +1,9 @@ -import AlertKonfirmasi from "@/components/alertKonfirmasi" import AppHeader from "@/components/AppHeader" import HeaderRightBannerList from "@/components/banner/headerBannerList" import BorderBottomItem from "@/components/borderBottomItem" import DrawerBottom from "@/components/drawerBottom" import MenuItemRow from "@/components/menuItemRow" +import ModalConfirmation from "@/components/ModalConfirmation" import ModalLoading from "@/components/modalLoading" import Text from "@/components/Text" import { ConstEnv } from "@/constants/ConstEnv" @@ -42,6 +42,7 @@ export default function BannerList() { const [refreshing, setRefreshing] = useState(false) const [loadingOpen, setLoadingOpen] = useState(false) const [viewImg, setViewImg] = useState(false) + const [showDeleteModal, setShowDeleteModal] = useState(false) const handleDeleteEntity = async () => { try { @@ -132,7 +133,7 @@ export default function BannerList() { } style={[Styles.h100, { backgroundColor: colors.background }]} @@ -196,11 +197,9 @@ export default function BannerList() { title="Hapus" onPress={() => { setModal(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah anda yakin ingin menghapus data?', - onPress: () => { handleDeleteEntity() } - }) + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> @@ -213,6 +212,19 @@ export default function BannerList() { onRequestClose={() => setViewImg(false)} doubleTapToZoomEnabled /> + + { + setShowDeleteModal(false) + handleDeleteEntity() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/app/(application)/discussion/[id].tsx b/app/(application)/discussion/[id].tsx index 8eff8d7..82d064b 100644 --- a/app/(application)/discussion/[id].tsx +++ b/app/(application)/discussion/[id].tsx @@ -1,4 +1,3 @@ -import AlertKonfirmasi from "@/components/alertKonfirmasi"; import AppHeader from "@/components/AppHeader"; import BorderBottomItem from "@/components/borderBottomItem"; import BorderBottomItem2 from "@/components/borderBottomItem2"; @@ -8,10 +7,10 @@ import ImageUser from "@/components/imageNew"; import { InputForm } from "@/components/inputForm"; import LabelStatus from "@/components/labelStatus"; import MenuItemRow from "@/components/menuItemRow"; +import ModalConfirmation from "@/components/ModalConfirmation"; import Skeleton from "@/components/skeleton"; import SkeletonContent from "@/components/skeletonContent"; import Text from '@/components/Text'; -import { ColorsStatus } from "@/constants/ColorsStatus"; import { ConstEnv } from "@/constants/ConstEnv"; import { regexOnlySpacesOrEnter } from "@/constants/OnlySpaceOrEnter"; import Styles from "@/constants/Styles"; @@ -81,6 +80,7 @@ export default function DetailDiscussionGeneral() { comment: '' }) const [viewEdit, setViewEdit] = useState(false) + const [showDeleteModal, setShowDeleteModal] = useState(false) useEffect(() => { const onValueChange = reference.on('value', snapshot => { @@ -247,7 +247,7 @@ export default function DetailDiscussionGeneral() { handleRefresh()} - tintColor={colors.primary} + tintColor={colors.icon} /> } > @@ -370,7 +370,7 @@ export default function DetailDiscussionGeneral() { Platform.OS == 'android' && Styles.mb12, ]} > - + } /> @@ -396,7 +396,7 @@ export default function DetailDiscussionGeneral() { Platform.OS == 'android' && Styles.mb12, ]} > - + } /> @@ -425,17 +425,27 @@ export default function DetailDiscussionGeneral() { icon={} title="Hapus" onPress={() => { - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah anda yakin ingin menghapus komentar?', - onPress: () => { - handleDeleteKomentar() - } - }) + setVisible(false) + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> + + { + setShowDeleteModal(false) + handleDeleteKomentar() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/app/(application)/discussion/add-member/[id].tsx b/app/(application)/discussion/add-member/[id].tsx index 1e9f4f5..31ce33c 100644 --- a/app/(application)/discussion/add-member/[id].tsx +++ b/app/(application)/discussion/add-member/[id].tsx @@ -94,7 +94,7 @@ export default function AddMemberDiscussionDetail() { return ( - + <> { router.back() }} />, @@ -127,7 +127,7 @@ export default function AddMemberDiscussionDetail() { ) }} /> - + { @@ -188,6 +188,6 @@ export default function AddMemberDiscussionDetail() { } - + ) } \ No newline at end of file diff --git a/app/(application)/discussion/index.tsx b/app/(application)/discussion/index.tsx index 3f01cb6..a8d0f44 100644 --- a/app/(application)/discussion/index.tsx +++ b/app/(application)/discussion/index.tsx @@ -166,7 +166,7 @@ export default function Discussion() { leftBottomInfo={ - Diskusikan + Diskusikan } rightBottomInfo={`${item.total_komentar} Komentar`} @@ -182,7 +182,7 @@ export default function Discussion() { } /> diff --git a/app/(application)/discussion/member/[id].tsx b/app/(application)/discussion/member/[id].tsx index ee3ce94..76f1113 100644 --- a/app/(application)/discussion/member/[id].tsx +++ b/app/(application)/discussion/member/[id].tsx @@ -1,9 +1,9 @@ -import AlertKonfirmasi from "@/components/alertKonfirmasi"; import AppHeader from "@/components/AppHeader"; import BorderBottomItem from "@/components/borderBottomItem"; import DrawerBottom from "@/components/drawerBottom"; import ImageUser from "@/components/imageNew"; import MenuItemRow from "@/components/menuItemRow"; +import ModalConfirmation from "@/components/ModalConfirmation"; import SkeletonTwoItem from "@/components/skeletonTwoItem"; import Text from '@/components/Text'; import { ColorsStatus } from "@/constants/ColorsStatus"; @@ -36,6 +36,8 @@ export default function MemberDiscussionDetail() { const update = useSelector((state: any) => state.discussionGeneralDetailUpdate) const [loading, setLoading] = useState(true) const arrSkeleton = Array.from({ length: 5 }, (_, index) => index) + const [showDeleteModal, setShowDeleteModal] = useState(false) + async function handleLoad(loading: boolean) { try { @@ -151,20 +153,28 @@ export default function MemberDiscussionDetail() { title="Keluarkan" onPress={() => { setModal(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah Anda yakin ingin mengeluarkan anggota?', - onPress: () => { - handleDeleteUser() - } - }) - + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> } + + { + setShowDeleteModal(false) + handleDeleteUser() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/index.tsx b/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/index.tsx index 37b1b56..5bdf203 100644 --- a/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/index.tsx @@ -1,4 +1,4 @@ -import AlertKonfirmasi from "@/components/alertKonfirmasi" +import ModalConfirmation from "@/components/ModalConfirmation" import AppHeader from "@/components/AppHeader" import BorderBottomItem from "@/components/borderBottomItem" import ButtonBackHeader from "@/components/buttonBackHeader" @@ -57,6 +57,7 @@ export default function DetailEventCalendar() { 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) @@ -179,6 +180,7 @@ export default function DetailEventCalendar() { } > @@ -301,18 +303,26 @@ export default function DetailEventCalendar() { title="Keluarkan" onPress={() => { setModalMember(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah Anda yakin ingin mengeluarkan anggota?', - onPress: () => { - handleDeleteUser() - } - }) - + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> + + { + setShowDeleteModal(false) + handleDeleteUser() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Keluar" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/app/(application)/division/[id]/(fitur-division)/calendar/index.tsx b/app/(application)/division/[id]/(fitur-division)/calendar/index.tsx index 4e4b654..7664f62 100644 --- a/app/(application)/division/[id]/(fitur-division)/calendar/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/calendar/index.tsx @@ -155,6 +155,7 @@ export default function CalendarDivision() { } style={[Styles.h100]} diff --git a/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/index.tsx b/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/index.tsx index 9d06ec3..805d8a6 100644 --- a/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/index.tsx @@ -1,4 +1,3 @@ -import AlertKonfirmasi from "@/components/alertKonfirmasi"; import AppHeader from "@/components/AppHeader"; import BorderBottomItem from "@/components/borderBottomItem"; import BorderBottomItem2 from "@/components/borderBottomItem2"; @@ -8,6 +7,7 @@ import ImageUser from "@/components/imageNew"; import { InputForm } from "@/components/inputForm"; import LabelStatus from "@/components/labelStatus"; import MenuItemRow from "@/components/menuItemRow"; +import ModalConfirmation from "@/components/ModalConfirmation"; import Skeleton from "@/components/skeleton"; import SkeletonContent from "@/components/skeletonContent"; import Text from "@/components/Text"; @@ -23,9 +23,9 @@ import { } from "@/lib/api"; import { getDB } from "@/lib/firebaseDatabase"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Feather, Ionicons, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons"; import { ref } from "@react-native-firebase/database"; -import { useTheme } from "@/providers/ThemeProvider"; import { useHeaderHeight } from '@react-navigation/elements'; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -92,6 +92,7 @@ export default function DiscussionDetail() { comment: '' }) const [viewEdit, setViewEdit] = useState(false) + const [showDeleteModal, setShowDeleteModal] = useState(false) @@ -314,6 +315,7 @@ export default function DiscussionDetail() { } > @@ -385,6 +387,7 @@ export default function DiscussionDetail() { desc={item.comment} rightBottomInfo={item.isEdited ? "Edited" : ""} descEllipsize={detailMore.includes(item.id) ? false : true} + bgColor="transparent" onPress={() => { setDetailMore((prev: any) => { if (prev.includes(item.id)) { @@ -541,17 +544,27 @@ export default function DiscussionDetail() { icon={} title="Hapus" onPress={() => { - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah anda yakin ingin menghapus komentar?', - onPress: () => { - handleDeleteKomentar() - } - }) + setVisible(false) + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> + + { + setShowDeleteModal(false) + handleDeleteKomentar() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> ); } diff --git a/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx b/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx index c4bac68..742bc1c 100644 --- a/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx @@ -192,6 +192,7 @@ export default function DiscussionDivision() { } rightBottomInfo={item.total_komentar + ' Komentar'} + bgColor="transparent" /> ) }} @@ -203,6 +204,7 @@ export default function DiscussionDivision() { } /> diff --git a/app/(application)/division/[id]/(fitur-division)/document/index.tsx b/app/(application)/division/[id]/(fitur-division)/document/index.tsx index d308578..5db917c 100644 --- a/app/(application)/division/[id]/(fitur-division)/document/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/document/index.tsx @@ -1,4 +1,4 @@ -import AlertKonfirmasi from "@/components/alertKonfirmasi"; +import ModalConfirmation from "@/components/ModalConfirmation"; import AppHeader from "@/components/AppHeader"; import { ButtonHeader } from "@/components/buttonHeader"; import HeaderRightDocument from "@/components/document/headerDocument"; @@ -89,6 +89,7 @@ export default function DocumentDivision() { const [loadingOpen, setLoadingOpen] = useState(false) const [isMemberDivision, setIsMemberDivision] = useState(false) const entityUser = useSelector((state: any) => state.user) + const [showDeleteModal, setShowDeleteModal] = useState(false) const [bodyRename, setBodyRename] = useState({ id: "", name: "", @@ -414,6 +415,7 @@ export default function DocumentDivision() { }> @@ -499,13 +501,7 @@ export default function DocumentDivision() { } title="Hapus" onPress={() => { - AlertKonfirmasi({ - title: "Konfirmasi", - desc: "Apakah anda yakin ingin menghapus dokumen?", - onPress: () => { - handleDelete(); - }, - }); + setShowDeleteModal(true) }} column="many" color="white" @@ -612,6 +608,19 @@ export default function DocumentDivision() { value={id} item={selectedFiles[0]?.id} /> + + { + setShowDeleteModal(false) + handleDelete() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> ); } diff --git a/app/(application)/division/[id]/(fitur-division)/task/[detail]/index.tsx b/app/(application)/division/[id]/(fitur-division)/task/[detail]/index.tsx index 8eecb3c..9a27a0b 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/[detail]/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/[detail]/index.tsx @@ -127,6 +127,7 @@ export default function DetailTaskDivision() { } > diff --git a/app/(application)/division/[id]/(fitur-division)/task/index.tsx b/app/(application)/division/[id]/(fitur-division)/task/index.tsx index c708325..24a8d53 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/index.tsx @@ -235,6 +235,7 @@ export default function ListTask() { } /> @@ -301,6 +302,7 @@ export default function ListTask() { } /> diff --git a/app/(application)/division/[id]/(fitur-division)/task/update/[detail].tsx b/app/(application)/division/[id]/(fitur-division)/task/update/[detail].tsx index 1511f0c..475e7b0 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/update/[detail].tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/update/[detail].tsx @@ -1,15 +1,16 @@ import AppHeader from "@/components/AppHeader"; import ButtonSaveHeader from "@/components/buttonSaveHeader"; +import ButtonSelect from "@/components/buttonSelect"; import { InputForm } from "@/components/inputForm"; import ModalAddDetailTugasTask from "@/components/task/modalAddDetailTugasTask"; import Text from "@/components/Text"; import Styles from "@/constants/Styles"; -import { useTheme } from "@/providers/ThemeProvider"; import { apiEditTaskTugas, apiGetTaskTugas } from "@/lib/api"; import { formatDateOnly } from "@/lib/fun_formatDateOnly"; import { getDatesInRange } from "@/lib/fun_getDatesInRange"; import { setUpdateTask } from "@/lib/taskUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { useHeaderHeight } from '@react-navigation/elements'; import { router, Stack, useLocalSearchParams } from "expo-router"; import 'intl'; @@ -19,7 +20,6 @@ import { useEffect, useState } from "react"; import { KeyboardAvoidingView, Platform, - Pressable, SafeAreaView, ScrollView, View @@ -263,7 +263,7 @@ export default function UpdateProjectTaskDivision() { Tanggal Mulai * - + {from} @@ -271,7 +271,7 @@ export default function UpdateProjectTaskDivision() { Tanggal Berakhir * - + {to} @@ -281,13 +281,14 @@ export default function UpdateProjectTaskDivision() { Tanggal tidak boleh kosong )} - { setModalDetail(true) }} > Detail - + */} + { setModalDetail(true) }} /> } showsVerticalScrollIndicator={false} diff --git a/app/(application)/division/[id]/info.tsx b/app/(application)/division/[id]/info.tsx index a9aba24..0132cb9 100644 --- a/app/(application)/division/[id]/info.tsx +++ b/app/(application)/division/[id]/info.tsx @@ -1,4 +1,4 @@ -import AlertKonfirmasi from "@/components/alertKonfirmasi" +import ModalConfirmation from "@/components/ModalConfirmation" import AppHeader from "@/components/AppHeader" import BorderBottomItem from "@/components/borderBottomItem" import HeaderRightDivisionInfo from "@/components/division/headerDivisionInfo" @@ -59,14 +59,13 @@ export default function InformationDivision() { name: '', isAdmin: false }) + const [showDeleteModal, setShowDeleteModal] = useState(false) function handleMemberOut() { setModal(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah anda yakin ingin mengeluarkan anggota?', - onPress: () => { memberOut() } - }) + setTimeout(() => { + setShowDeleteModal(true) + }, 600) } async function memberOut() { @@ -187,6 +186,7 @@ export default function InformationDivision() { } style={[Styles.h100, { backgroundColor: colors.background }]} @@ -287,6 +287,19 @@ export default function InformationDivision() { + + { + setShowDeleteModal(false) + memberOut() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Keluar" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/app/(application)/division/create.tsx b/app/(application)/division/create.tsx index e8ec765..516951a 100644 --- a/app/(application)/division/create.tsx +++ b/app/(application)/division/create.tsx @@ -1,4 +1,4 @@ -import AlertKonfirmasi from "@/components/alertKonfirmasi"; +import ModalConfirmation from "@/components/ModalConfirmation"; import AppHeader from "@/components/AppHeader"; import ButtonNextHeader from "@/components/buttonNextHeader"; import { InputForm } from "@/components/inputForm"; @@ -25,6 +25,7 @@ export default function CreateDivision() { const entityUser = useSelector((state: any) => state.user) const userLogin = useSelector((state: any) => state.entities) const [loadingBtn, setLoadingBtn] = useState(false) + const [showWarningModal, setShowWarningModal] = useState(false) const [error, setError] = useState({ idGroup: false, name: false, @@ -69,12 +70,7 @@ export default function CreateDivision() { const response = await apiCheckDivisionName({ data: { ...dataForm }, user: hasil }) if (response.success) { if (!response.available) { - AlertKonfirmasi({ - title: 'Peringatan', - category: 'warning', - desc: 'Nama divisi sudah ada. Tidak dapat membuat divisi dengan nama yang sama', - onPress: () => { } - }) + setShowWarningModal(true) } else { handleSetData() } @@ -181,6 +177,15 @@ export default function CreateDivision() { open={isSelect} valChoose={chooseGroup.val} /> + + setShowWarningModal(false)} + onCancel={() => setShowWarningModal(false)} + confirmText="Oke" + /> ); } diff --git a/app/(application)/division/index.tsx b/app/(application)/division/index.tsx index d48fabd..f305370 100644 --- a/app/(application)/division/index.tsx +++ b/app/(application)/division/index.tsx @@ -253,6 +253,7 @@ export default function ListDivision() { } /> @@ -288,6 +289,7 @@ export default function ListDivision() { } /> diff --git a/app/(application)/edit-profile.tsx b/app/(application)/edit-profile.tsx index 6b32dda..3157aa4 100644 --- a/app/(application)/edit-profile.tsx +++ b/app/(application)/edit-profile.tsx @@ -1,4 +1,4 @@ -import ButtonBackHeader from "@/components/buttonBackHeader"; +import AppHeader from "@/components/AppHeader"; import ButtonSaveHeader from "@/components/buttonSaveHeader"; import { InputForm } from "@/components/inputForm"; import ModalSelect from "@/components/modalSelect"; @@ -219,24 +219,40 @@ export default function EditProfile() { ( - { - router.back(); - }} - /> - ), + // headerLeft: () => ( + // { + // router.back(); + // }} + // /> + // ), headerTitle: "Edit Profile", headerTitleAlign: "center", - headerRight: () => ( - { - handleEdit() - }} + header: () => ( + router.back()} + right={ + { + handleEdit() + }} + /> + } /> - ), + ) + // headerRight: () => ( + // { + // handleEdit() + // }} + // /> + // ), }} /> index) const [loading, setLoading] = useState(true) + const [showDeleteModal, setShowDeleteModal] = useState(false) const [status, setStatus] = useState<'true' | 'false'>('true') const [loadingSubmit, setLoadingSubmit] = useState(false) const [idChoose, setIdChoose] = useState('') @@ -189,7 +190,7 @@ export default function Index() { } /> @@ -205,11 +206,9 @@ export default function Index() { title={activeChoose ? "Non Aktifkan" : "Aktifkan"} onPress={() => { setModal(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: activeChoose ? 'Apakah anda yakin ingin menonaktifkan data?' : 'Apakah anda yakin ingin mengaktifkan data?', - onPress: () => { handleDelete() } - }) + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> + + { + setShowDeleteModal(false) + handleDelete() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText={activeChoose ? "Nonaktifkan" : "Aktifkan"} + cancelText="Batal" + /> ) diff --git a/app/(application)/home.tsx b/app/(application)/home.tsx index e8f0dc5..6e0a310 100644 --- a/app/(application)/home.tsx +++ b/app/(application)/home.tsx @@ -67,7 +67,7 @@ export default function Home() { } showsVerticalScrollIndicator={false} diff --git a/app/(application)/member/[id].tsx b/app/(application)/member/[id].tsx index ae575cf..bd12512 100644 --- a/app/(application)/member/[id].tsx +++ b/app/(application)/member/[id].tsx @@ -99,7 +99,7 @@ export default function MemberDetail() { } > diff --git a/app/(application)/member/index.tsx b/app/(application)/member/index.tsx index b789b78..35ede2d 100644 --- a/app/(application)/member/index.tsx +++ b/app/(application)/member/index.tsx @@ -171,7 +171,7 @@ export default function Index() { } /> diff --git a/app/(application)/notification.tsx b/app/(application)/notification.tsx index 7c56cd8..12c5f96 100644 --- a/app/(application)/notification.tsx +++ b/app/(application)/notification.tsx @@ -1,4 +1,5 @@ import BorderBottomItem from "@/components/borderBottomItem"; +import BorderBottomItemVertical from "@/components/borderBottomItemVertical"; import SkeletonTwoItem from "@/components/skeletonTwoItem"; import Text from "@/components/Text"; import { ColorsStatus } from "@/constants/ColorsStatus"; @@ -116,11 +117,11 @@ export default function Notification() { getItem={getItem} renderItem={({ item, index }: { item: Props, index: number }) => { return ( - - + + } title={item.title} @@ -129,8 +130,8 @@ export default function Notification() { textColor={item.isRead ? 'gray' : colors.text} onPress={() => { handleReadNotification(item.id, item.category, item.idContent) - }} + bgColor={'transparent'} /> ) }} @@ -142,7 +143,7 @@ export default function Notification() { } /> diff --git a/app/(application)/position/index.tsx b/app/(application)/position/index.tsx index 17a6ab1..5b775d9 100644 --- a/app/(application)/position/index.tsx +++ b/app/(application)/position/index.tsx @@ -1,4 +1,4 @@ -import AlertKonfirmasi from "@/components/alertKonfirmasi"; +import ModalConfirmation from "@/components/ModalConfirmation"; import BorderBottomItem from "@/components/borderBottomItem"; import { ButtonForm } from "@/components/buttonForm"; import ButtonTab from "@/components/buttonTab"; @@ -50,6 +50,7 @@ export default function Index() { name: false, }); const [refreshing, setRefreshing] = useState(false) + const [showDeleteModal, setShowDeleteModal] = useState(false) const dispatch = useDispatch() const update = useSelector((state: any) => state.positionUpdate) @@ -215,7 +216,7 @@ export default function Index() { } /> @@ -230,11 +231,9 @@ export default function Index() { title={chooseData.active ? 'Non Aktifkan' : "Aktifkan"} onPress={() => { setModal(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: chooseData.active ? 'Apakah anda yakin ingin menonaktifkan data?' : 'Apakah anda yakin ingin mengaktifkan data?', - onPress: () => { handleDelete() } - }) + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> + + { + setShowDeleteModal(false) + handleDelete() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText={chooseData.active ? "Nonaktifkan" : "Aktifkan"} + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/app/(application)/profile.tsx b/app/(application)/profile.tsx index 24f1b8a..d25cd22 100644 --- a/app/(application)/profile.tsx +++ b/app/(application)/profile.tsx @@ -1,4 +1,3 @@ -import AlertKonfirmasi from "@/components/alertKonfirmasi"; import AppHeader from "@/components/AppHeader"; import { ButtonHeader } from "@/components/buttonHeader"; import ItemDetailMember from "@/components/itemDetailMember"; @@ -6,39 +5,42 @@ import Text from "@/components/Text"; import { assetUserImage } from "@/constants/AssetsError"; import { ConstEnv } from "@/constants/ConstEnv"; import Styles from "@/constants/Styles"; +import { apiGetProfile } from "@/lib/api"; +import { setEntities } from "@/lib/entitiesSlice"; import { useAuthSession } from "@/providers/AuthProvider"; import { useTheme } from "@/providers/ThemeProvider"; -import { AntDesign, Ionicons } from "@expo/vector-icons"; -import { router, Stack } from "expo-router"; +import { Feather } from "@expo/vector-icons"; import { LinearGradient } from "expo-linear-gradient"; +import { router, Stack } from "expo-router"; import { useState } from "react"; -import { Image, Modal, Pressable, SafeAreaView, ScrollView, TouchableOpacity, View } from "react-native"; +import { Image, Pressable, RefreshControl, SafeAreaView, ScrollView, View } from "react-native"; import ImageViewing from 'react-native-image-viewing'; -import { useSelector } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; export default function Profile() { - const { signOut } = useAuthSession() - const { theme, setTheme, colors } = useTheme(); + const { colors } = useTheme(); const entities = useSelector((state: any) => state.entities) const [error, setError] = useState(false) const [preview, setPreview] = useState(false) - const [showThemeModal, setShowThemeModal] = useState(false) + const [refreshing, setRefreshing] = useState(false) + const dispatch = useDispatch() + const { token, decryptToken } = useAuthSession() - const ThemeOption = ({ label, value, icon }: { label: string, value: 'light' | 'dark' | 'system', icon: string }) => ( - { - setTheme(value); - setShowThemeModal(false); - }} - > - - - {label} - - {theme === value && } - - ); + async function handleUserLogin() { + const hasil = await decryptToken(String(token?.current)) + apiGetProfile({ id: hasil }) + .then((data) => dispatch(setEntities(data.data))) + .catch((error) => { + console.error(error) + }); + } + + const handleRefresh = async () => { + setRefreshing(true) + handleUserLogin() + await new Promise(resolve => setTimeout(resolve, 2000)); + setRefreshing(false) + }; return ( @@ -53,13 +55,9 @@ export default function Profile() { onPressLeft={() => router.back()} right={ } + item={} onPress={() => { - AlertKonfirmasi({ - title: 'Keluar', - desc: 'Apakah anda yakin ingin keluar?', - onPress: () => { signOut() } - }) + router.push('/setting') }} /> } @@ -67,7 +65,16 @@ export default function Profile() { ) }} /> - + + } + style={[Styles.h100, { backgroundColor: colors.background }]} + > {entities.role} - - Tampilan - - - setShowThemeModal(true)} - style={[Styles.wrapItemBorderAll, { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', borderColor: colors.icon + '40', backgroundColor: colors.background }]} - > - - - Tema Aplikasi - - - - {theme === 'light' ? 'Terang' : theme === 'dark' ? 'Gelap' : 'Sistem'} - - - - - - + Informasi - { - entities.idUserRole != "developer" && { router.push('/edit-profile') }} style={[Styles.textLink]}>Edit - } {/* Note: ItemDetailMember might need updates to support dynamic colors if it uses default text colors */} @@ -121,29 +105,6 @@ export default function Profile() { - setShowThemeModal(false)} - > - setShowThemeModal(false)}> - - - Pilih Tema - setShowThemeModal(false)}> - - - - - - - - - - - - } > diff --git a/app/(application)/project/index.tsx b/app/(application)/project/index.tsx index c08b44a..adcd1d7 100644 --- a/app/(application)/project/index.tsx +++ b/app/(application)/project/index.tsx @@ -275,6 +275,7 @@ export default function ListProject() { } /> @@ -353,6 +354,7 @@ export default function ListProject() { } /> diff --git a/app/(application)/project/update/[detail].tsx b/app/(application)/project/update/[detail].tsx index f4a2057..0051a37 100644 --- a/app/(application)/project/update/[detail].tsx +++ b/app/(application)/project/update/[detail].tsx @@ -1,5 +1,6 @@ import AppHeader from "@/components/AppHeader"; import ButtonSaveHeader from "@/components/buttonSaveHeader"; +import ButtonSelect from "@/components/buttonSelect"; import { InputForm } from "@/components/inputForm"; import ModalAddDetailTugasProject from "@/components/project/modalAddDetailTugasProject"; import Text from "@/components/Text"; @@ -16,7 +17,7 @@ import 'intl'; import 'intl/locale-data/jsonp/id'; import moment from "moment"; import React, { useEffect, useState } from "react"; -import { KeyboardAvoidingView, Platform, Pressable, SafeAreaView, ScrollView, View } from "react-native"; +import { KeyboardAvoidingView, Platform, SafeAreaView, ScrollView, View } from "react-native"; import Toast from "react-native-toast-message"; import DateTimePicker, { DateType } from "react-native-ui-datepicker"; import { useDispatch, useSelector } from "react-redux"; @@ -235,13 +236,13 @@ export default function UpdateProjectTask() { Tanggal Mulai * - + {from} Tanggal Berakhir * - + {to} @@ -249,13 +250,14 @@ export default function UpdateProjectTask() { { (error.endDate || error.startDate) && Tanggal tidak boleh kosong } - { setModalDetail(true) }} > Detail - + */} + { setModalDetail(true) }} /> } > diff --git a/app/(application)/setting/index.tsx b/app/(application)/setting/index.tsx new file mode 100644 index 0000000..0a25d8e --- /dev/null +++ b/app/(application)/setting/index.tsx @@ -0,0 +1,186 @@ +import ModalConfirmation from "@/components/ModalConfirmation"; +import Text from "@/components/Text"; +import ButtonSetting from "@/components/buttonSetting"; +import DrawerBottom from "@/components/drawerBottom"; +import Styles from "@/constants/Styles"; +import { apiRegisteredToken, apiUnregisteredToken } from "@/lib/api"; +import { checkPermission, getToken, openSettings, requestPermission } from "@/lib/useNotification"; +import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; +import { Feather, Ionicons } from "@expo/vector-icons"; +import { router } from "expo-router"; +import { useCallback, useEffect, useState } from "react"; +import { AppState, AppStateStatus, Pressable, View } from "react-native"; +import { useSelector } from "react-redux"; + +export default function ListSetting() { + const { theme, setTheme, colors } = useTheme() + const { signOut } = useAuthSession() + const [isNotificationEnabled, setIsNotificationEnabled] = useState(null); + const entities = useSelector((state: any) => state.entities) + const [modalVisible, setModalVisible] = useState(false); + const [modalConfig, setModalConfig] = useState({ + title: '', + message: '', + confirmText: 'Buka Pengaturan', + onConfirm: () => { } + }); + + const [showLogoutModal, setShowLogoutModal] = useState(false) + const [showThemeModal, setShowThemeModal] = useState(false) + + const registerToken = async () => { + try { + const token = await getToken(); + if (token) { + await apiRegisteredToken({ user: entities.id, token }); + } + } catch (error) { + console.warn('Error registering token:', error); + } + }; + + const unregisterToken = async () => { + try { + const token = await getToken(); + if (token) { + await apiUnregisteredToken({ user: entities.id, token }); + } + } catch (error) { + console.warn('Error unregistering token:', error); + } + }; + + const checkNotif = useCallback(async () => { + const status = await checkPermission(); + setIsNotificationEnabled((prev) => { + if (prev === false && status === true) { + registerToken(); + } else if (prev === true && status === false) { + unregisterToken(); + } + return !!status; + }); + }, [entities.id]); + + useEffect(() => { + checkNotif(); + + const subscription = AppState.addEventListener('change', (nextAppState: AppStateStatus) => { + if (nextAppState === 'active') { + checkNotif(); + } + }); + + return () => { + subscription.remove(); + }; + }, [checkNotif]); + + const handleToggleNotif = async () => { + if (isNotificationEnabled) { + setModalConfig({ + title: "Matikan Notifikasi?", + message: "Anda akan diarahkan ke pengaturan sistem untuk mematikan notifikasi.", + confirmText: "Buka Pengaturan", + onConfirm: () => { + setModalVisible(false); + openSettings(); + } + }); + setModalVisible(true); + } else { + const granted = await requestPermission(); + if (granted) { + setIsNotificationEnabled(true); + registerToken(); + } else { + setModalConfig({ + title: "Aktifkan Notifikasi?", + message: "Izin notifikasi tidak diberikan. Buka pengaturan sistem untuk mengaktifkannya?", + confirmText: "Buka Pengaturan", + onConfirm: () => { + setModalVisible(false); + openSettings(); + } + }); + setModalVisible(true); + } + } + }; + + const ThemeOption = ({ label, value, icon }: { label: string, value: 'light' | 'dark' | 'system', icon: string }) => ( + { + setTheme(value); + }} + > + + + {label} + + {theme === value && } + + ); + + return ( + + + { + entities.idUserRole != "developer" && + } + onPress={() => { router.push('/edit-profile') }} + /> + } + } + onPress={() => setShowThemeModal(true)} + value={theme === 'light' ? 'Terang' : theme === 'dark' ? 'Gelap' : 'Sistem'} + /> + } + onPress={handleToggleNotif} + value={isNotificationEnabled === null ? 'Memuat...' : isNotificationEnabled ? 'Aktif' : 'Nonaktif'} + /> + } + onPress={() => setShowLogoutModal(true)} + borderBottom={false} + /> + + + setModalVisible(false)} + /> + + { + setShowLogoutModal(false) + signOut() + }} + onCancel={() => setShowLogoutModal(false)} + confirmText="Keluar" + cancelText="Batal" + /> + + + + + + + ) +} \ No newline at end of file diff --git a/app/verification.tsx b/app/verification.tsx index d0290d1..98e5769 100644 --- a/app/verification.tsx +++ b/app/verification.tsx @@ -20,10 +20,16 @@ export default function Index() { const { signIn } = useAuthSession(); const login = (): void => { - const random: string = 'contohLoginMobileDarmasaba'; - var mytexttoEncryption = "contohLoginMobileDarmasaba" - const encrypted = CryptoES.AES.encrypt(mytexttoEncryption, ConstEnv.pass_encrypt).toString(); - signIn(encrypted); + // WARNING: This is a hardcoded bypass for development purposes. + // It should be removed or secured before production release. + if (__DEV__) { + const random: string = 'contohLoginMobileDarmasaba'; + var mytexttoEncryption = "contohLoginMobileDarmasaba" + const encrypted = CryptoES.AES.encrypt(mytexttoEncryption, ConstEnv.pass_encrypt).toString(); + signIn(encrypted); + } else { + console.warn("Bypass login disabled in production."); + } } return ( diff --git a/assets/images/bgproject-dark.png b/assets/images/bgproject-dark.png new file mode 100644 index 0000000..6384656 Binary files /dev/null and b/assets/images/bgproject-dark.png differ diff --git a/assets/images/bgproject-light.png b/assets/images/bgproject-light.png new file mode 100644 index 0000000..90aa1e0 Binary files /dev/null and b/assets/images/bgproject-light.png differ diff --git a/assets/images/cogniti-dark.png b/assets/images/cogniti-dark.png new file mode 100644 index 0000000..60de6fd Binary files /dev/null and b/assets/images/cogniti-dark.png differ diff --git a/assets/images/cogniti-light.png b/assets/images/cogniti-light.png new file mode 100644 index 0000000..b2515cc Binary files /dev/null and b/assets/images/cogniti-light.png differ diff --git a/assets/images/logo-dark.png b/assets/images/logo-dark.png new file mode 100644 index 0000000..7512623 Binary files /dev/null and b/assets/images/logo-dark.png differ diff --git a/components/ModalConfirmation.tsx b/components/ModalConfirmation.tsx new file mode 100644 index 0000000..8bb5d50 --- /dev/null +++ b/components/ModalConfirmation.tsx @@ -0,0 +1,82 @@ +import Styles from '@/constants/Styles'; +import { useTheme } from '@/providers/ThemeProvider'; +import React from 'react'; +import { Modal, TouchableOpacity, View } from 'react-native'; +import Text from './Text'; + +interface ModalConfirmationProps { + visible: boolean; + title: string; + message: string; + onConfirm: () => void; + onCancel: () => void; + confirmText?: string; + cancelText?: string; + isDestructive?: boolean; +} + +const ModalConfirmation: React.FC = ({ + visible, + title, + message, + onConfirm, + onCancel, + confirmText = 'Ya', + cancelText = 'Batal', + isDestructive = false, +}) => { + const { colors } = useTheme(); + + return ( + + + + + {title} + + {message} + + + + + + + + + {cancelText} + + + + + + + + {confirmText} + + + + + + + ); +}; + +export default ModalConfirmation; diff --git a/components/announcement/headerAnnouncementDetail.tsx b/components/announcement/headerAnnouncementDetail.tsx index d39d784..336fcef 100644 --- a/components/announcement/headerAnnouncementDetail.tsx +++ b/components/announcement/headerAnnouncementDetail.tsx @@ -9,7 +9,7 @@ import { useState } from "react" import { View } from "react-native" import Toast from "react-native-toast-message" import { useDispatch, useSelector } from "react-redux" -import AlertKonfirmasi from "../alertKonfirmasi" +import ModalConfirmation from "../ModalConfirmation" import ButtonMenuHeader from "../buttonMenuHeader" import DrawerBottom from "../drawerBottom" import MenuItemRow from "../menuItemRow" @@ -22,6 +22,7 @@ export default function HeaderRightAnnouncementDetail({ id }: Props) { const { colors } = useTheme(); const [isVisible, setVisible] = useState(false) const update = useSelector((state: any) => state.announcementUpdate) + const [showDeleteModal, setShowDeleteModal] = useState(false) const dispatch = useDispatch() @@ -60,17 +61,26 @@ export default function HeaderRightAnnouncementDetail({ id }: Props) { title="Hapus" onPress={() => { setVisible(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah anda yakin ingin menghapus pengumuman ini?', - onPress: () => { - handleDelete() - } - }) + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> + + { + setShowDeleteModal(false) + handleDelete() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/components/auth/viewLogin.tsx b/components/auth/viewLogin.tsx index 2b9e4f3..8173817 100644 --- a/components/auth/viewLogin.tsx +++ b/components/auth/viewLogin.tsx @@ -53,11 +53,10 @@ export default function ViewLogin({ onValidate }: Props) { return ( - +62} info="Kami akan mengirim kode verifikasi melalui WhatsApp, guna mengonfirmasikan nomor Anda." /> - { handleCheckPhone() }} - disabled={disableLogin} - /> + + { handleCheckPhone() }} + disabled={disableLogin} + /> + + + + + { loadingLogin && } + ) diff --git a/components/auth/viewVerification.tsx b/components/auth/viewVerification.tsx index fc921a9..0dc96bf 100644 --- a/components/auth/viewVerification.tsx +++ b/components/auth/viewVerification.tsx @@ -5,7 +5,7 @@ import { useTheme } from "@/providers/ThemeProvider"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { StatusBar } from "expo-status-bar"; import { useState } from "react"; -import { Image, Platform, View } from "react-native"; +import { Image, SafeAreaView, View } from "react-native"; import { OtpInput } from "react-native-otp-entry"; import Toast from 'react-native-toast-message'; import { ButtonForm } from "../buttonForm"; @@ -58,13 +58,12 @@ export default function ViewVerification({ phone, otp }: Props) { } return ( - <> + - - + - { onCheckOtp() }} - /> - - Tidak Menerima kode verifikasi? { resendOtp() }}>Kirim Ulang + + { onCheckOtp() }} + /> + + + Tidak Menerima kode verifikasi? { resendOtp() }} style={[{ color: colors.tint }]}>Kirim Ulang + + + + - + + ) } \ No newline at end of file diff --git a/components/borderBottomItem.tsx b/components/borderBottomItem.tsx index 40b06bd..acc64c6 100644 --- a/components/borderBottomItem.tsx +++ b/components/borderBottomItem.tsx @@ -18,17 +18,14 @@ type Props = { rightBottomInfo?: React.ReactNode | string titleWeight?: 'normal' | 'bold' bgColor?: string - width?: number descEllipsize?: boolean textColor?: string, colorPress?: boolean titleShowAll?: boolean } -export default function BorderBottomItem({ title, subtitle, icon, desc, onPress, onLongPress, rightTopInfo, borderType, leftBottomInfo, rightBottomInfo, titleWeight, bgColor, width, descEllipsize, textColor, colorPress, titleShowAll }: Props) { - const lebarDim = Dimensions.get("window").width; +export default function BorderBottomItem({ title, subtitle, icon, desc, onPress, onLongPress, rightTopInfo, borderType, leftBottomInfo, rightBottomInfo, titleWeight, bgColor, descEllipsize, textColor, colorPress, titleShowAll }: Props) { const { colors } = useTheme(); - const lebar = width ? lebarDim * width / 100 : 'auto'; const textColorFix = textColor ? textColor : colors.text; const [isTap, setIsTap] = useState(false); @@ -50,8 +47,8 @@ export default function BorderBottomItem({ title, subtitle, icon, desc, onPress, > {icon} - - + + {title} { subtitle && @@ -81,7 +78,7 @@ export default function BorderBottomItem({ title, subtitle, icon, desc, onPress, } { typeof rightBottomInfo == 'string' ? - {rightBottomInfo} + {rightBottomInfo} : rightBottomInfo } diff --git a/components/borderBottomItemVertical.tsx b/components/borderBottomItemVertical.tsx new file mode 100644 index 0000000..94a32c4 --- /dev/null +++ b/components/borderBottomItemVertical.tsx @@ -0,0 +1,53 @@ +import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; +import React, { useState } from "react"; +import { Pressable, View } from "react-native"; +import Text from "./Text"; + +type Props = { + title?: string + icon: React.ReactNode + desc?: string + rightTopInfo?: string + onPress?: () => void + onLongPress?: () => void + borderType: 'all' | 'bottom' | 'none' + titleWeight?: 'normal' | 'bold' + bgColor?: string + descEllipsize?: boolean + textColor?: string, + titleShowAll?: boolean +} + +export default function BorderBottomItemVertical({ title, icon, desc, onPress, onLongPress, rightTopInfo, borderType, titleWeight, bgColor, descEllipsize, textColor, titleShowAll }: Props) { + const { colors } = useTheme(); + const textColorFix = textColor ? textColor : colors.text; + + return ( + [ + borderType == 'bottom' + ? [Styles.wrapItemBorderBottom, { borderBottomColor: colors.icon + '20' }] + : borderType == 'all' + ? [Styles.wrapItemBorderAll, { borderColor: colors.icon + '20' }] + : Styles.wrapItemBorderNone, + bgColor == "transparent" ? { backgroundColor: 'transparent' } : { backgroundColor: colors.card }, + ]} + > + + {icon} + + + + {title} + + { + rightTopInfo && {rightTopInfo} + } + + {desc && {desc}} + + + + ) +} \ No newline at end of file diff --git a/components/buttonForm.tsx b/components/buttonForm.tsx index 551f60f..9ee7a1d 100644 --- a/components/buttonForm.tsx +++ b/components/buttonForm.tsx @@ -1,5 +1,5 @@ -import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { TouchableOpacity } from "react-native"; import Text from './Text'; @@ -10,8 +10,9 @@ type Props = { }; export function ButtonForm({ text, onPress, disabled }: Props) { + const { colors } = useTheme(); return ( - + {text} ); diff --git a/components/buttonSaveHeader.tsx b/components/buttonSaveHeader.tsx index fdd87f8..230c207 100644 --- a/components/buttonSaveHeader.tsx +++ b/components/buttonSaveHeader.tsx @@ -1,6 +1,7 @@ import { Feather } from "@expo/vector-icons" -import AlertKonfirmasi from "./alertKonfirmasi" +import ModalConfirmation from "./ModalConfirmation" import { ButtonHeader } from "./buttonHeader" +import { useState } from "react" type Props = { category: 'create' | 'update' | 'cancel' | 'update-calendar' @@ -9,29 +10,37 @@ type Props = { } export default function ButtonSaveHeader({ category, onPress, disable }: Props) { + const [showModal, setShowModal] = useState(false) return ( <> } onPress={() => { if (!disable) { - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: category == 'create' - ? 'Apakah anda yakin ingin menambahkan data?' - : category == 'cancel' - ? 'Apakah anda yakin ingin membatalkan kegiatan? Pembatalan bersifat permanen' - : category == 'update-calendar' - ? 'Apakah Anda yakin ingin mengubah data acara ini? Data ini akan mempengaruhi semua data yang terkait' - : 'Apakah anda yakin mengubah data?', - onPress: () => { - onPress && onPress() - } - }) + setShowModal(true) } - } + }} + /> + { + setShowModal(false) + onPress && onPress() + }} + onCancel={() => setShowModal(false)} + confirmText="Ya" + cancelText="Batal" /> ) diff --git a/components/buttonSetting.tsx b/components/buttonSetting.tsx new file mode 100644 index 0000000..419b227 --- /dev/null +++ b/components/buttonSetting.tsx @@ -0,0 +1,33 @@ +import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; +import { ReactNode } from "react"; +import { Pressable, View } from "react-native"; +import Text from "./Text"; + +type Props = { + title: string + onPress?: () => void, + icon?: ReactNode, + borderBottom?: boolean + value?: string +} + +export default function ButtonSetting({ title, onPress, icon, borderBottom = true, value }: Props) { + const { colors } = useTheme(); + return ( + + + + {icon} + {title} + + {value && {value}} + + + ) + +} \ No newline at end of file diff --git a/components/calendar/headerCalendarDetail.tsx b/components/calendar/headerCalendarDetail.tsx index 70f3889..b7a2839 100644 --- a/components/calendar/headerCalendarDetail.tsx +++ b/components/calendar/headerCalendarDetail.tsx @@ -9,7 +9,7 @@ import { useState } from "react" import { View } from "react-native" import Toast from "react-native-toast-message" import { useDispatch, useSelector } from "react-redux" -import AlertKonfirmasi from "../alertKonfirmasi" +import ModalConfirmation from "../ModalConfirmation" import ButtonMenuHeader from "../buttonMenuHeader" import DrawerBottom from "../drawerBottom" import MenuItemRow from "../menuItemRow" @@ -23,6 +23,7 @@ export default function HeaderRightCalendarDetail({ id, idReminder }: Props) { const { colors } = useTheme() const [isVisible, setVisible] = useState(false) const { token, decryptToken } = useAuthSession() + const [showDeleteModal, setShowDeleteModal] = useState(false) const update = useSelector((state: any) => state.calendarUpdate) const dispatch = useDispatch() @@ -71,17 +72,26 @@ export default function HeaderRightCalendarDetail({ id, idReminder }: Props) { title="Hapus" onPress={() => { setVisible(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah anda yakin ingin menghapus data ini? Data ini akan mempengaruhi semua data yang terkait', - onPress: () => { - handleDeleteCalendar() - } - }) + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> + + { + setShowDeleteModal(false) + handleDeleteCalendar() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/components/discussion/headerDiscussionDetail.tsx b/components/discussion/headerDiscussionDetail.tsx index e25af32..454e24a 100644 --- a/components/discussion/headerDiscussionDetail.tsx +++ b/components/discussion/headerDiscussionDetail.tsx @@ -9,7 +9,7 @@ import { useState } from "react" import { View } from "react-native" import Toast from "react-native-toast-message" import { useDispatch, useSelector } from "react-redux" -import AlertKonfirmasi from "../alertKonfirmasi" +import ModalConfirmation from "../ModalConfirmation" import ButtonMenuHeader from "../buttonMenuHeader" import DrawerBottom from "../drawerBottom" import MenuItemRow from "../menuItemRow" @@ -25,6 +25,8 @@ export default function HeaderRightDiscussionDetail({ id, status, isActive }: Pr const [isVisible, setVisible] = useState(false) const { token, decryptToken } = useAuthSession() const update = useSelector((state: any) => state.discussionUpdate) + const [showModal, setShowModal] = useState(false) + const [modalConfig, setModalConfig] = useState({ title: '', message: '', onConfirm: () => { } }) const dispatch = useDispatch() const handleOpenClose = async () => { @@ -86,13 +88,14 @@ export default function HeaderRightDiscussionDetail({ id, status, isActive }: Pr title={status == 1 ? 'Tutup Diskusi' : 'Buka Diskusi'} onPress={() => { setVisible(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: `Apakah anda yakin ingin ${status == 1 ? 'menutup' : 'membuka'} diskusi?`, - onPress: () => { - handleOpenClose() - } - }) + setTimeout(() => { + setModalConfig({ + title: 'Konfirmasi', + message: `Apakah anda yakin ingin ${status == 1 ? 'menutup' : 'membuka'} diskusi?`, + onConfirm: () => handleOpenClose() + }) + setShowModal(true) + }, 600) }} /> @@ -102,17 +105,31 @@ export default function HeaderRightDiscussionDetail({ id, status, isActive }: Pr title={isActive ? 'Arsipkan' : 'Aktifkan Diskusi'} onPress={() => { setVisible(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: isActive ? 'Apakah anda yakin ingin mengarsipkan diskusi?' : 'Apakah anda yakin ingin mengaktifkan diskusi?', - onPress: () => { - handleArchive() - } - }) + setTimeout(() => { + setModalConfig({ + title: 'Konfirmasi', + message: isActive ? 'Apakah anda yakin ingin mengarsipkan diskusi?' : 'Apakah anda yakin ingin mengaktifkan diskusi?', + onConfirm: () => handleArchive() + }) + setShowModal(true) + }, 600) }} /> + + { + setShowModal(false) + modalConfig.onConfirm() + }} + onCancel={() => setShowModal(false)} + confirmText="Ya" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/components/discussion_general/headerDiscussionDetail.tsx b/components/discussion_general/headerDiscussionDetail.tsx index 43b1d78..309bed3 100644 --- a/components/discussion_general/headerDiscussionDetail.tsx +++ b/components/discussion_general/headerDiscussionDetail.tsx @@ -9,7 +9,7 @@ import { useState } from "react" import { View } from "react-native" import Toast from "react-native-toast-message" import { useDispatch, useSelector } from "react-redux" -import AlertKonfirmasi from "../alertKonfirmasi" +import ModalConfirmation from "../ModalConfirmation" import ButtonMenuHeader from "../buttonMenuHeader" import DrawerBottom from "../drawerBottom" import MenuItemRow from "../menuItemRow" @@ -25,6 +25,8 @@ export default function HeaderRightDiscussionGeneralDetail({ id, active, status const { colors } = useTheme(); const [isVisible, setVisible] = useState(false) const entityUser = useSelector((state: any) => state.user) + const [showModal, setShowModal] = useState(false) + const [modalConfig, setModalConfig] = useState({ title: '', message: '', onConfirm: () => { } }) const dispatch = useDispatch() const update = useSelector((state: any) => state.discussionGeneralDetailUpdate) @@ -88,13 +90,14 @@ export default function HeaderRightDiscussionGeneralDetail({ id, active, status title={status == 1 ? 'Tutup Diskusi' : 'Buka Diskusi'} onPress={() => { setVisible(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: status == 1 ? 'Apakah anda yakin ingin menutup diskusi?' : 'Apakah anda yakin ingin membuka diskusi?', - onPress: () => { - handleUpdateStatus() - } - }) + setTimeout(() => { + setModalConfig({ + title: 'Konfirmasi', + message: status == 1 ? 'Apakah anda yakin ingin menutup diskusi?' : 'Apakah anda yakin ingin membuka diskusi?', + onConfirm: () => handleUpdateStatus() + }) + setShowModal(true) + }, 600) }} /> @@ -105,11 +108,14 @@ export default function HeaderRightDiscussionGeneralDetail({ id, active, status title="Aktifkan Diskusi" onPress={() => { setVisible(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah anda yakin ingin mengaktifkan diskusi ini?', - onPress: () => { handleDelete() } - }) + setTimeout(() => { + setModalConfig({ + title: 'Konfirmasi', + message: 'Apakah anda yakin ingin mengaktifkan diskusi ini?', + onConfirm: () => handleDelete() + }) + setShowModal(true) + }, 600) }} /> @@ -125,16 +131,32 @@ export default function HeaderRightDiscussionGeneralDetail({ id, active, status title="Arsipkan" onPress={() => { setVisible(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah anda yakin ingin mengarsipkan diskusi?', - onPress: () => { handleDelete() } - }) + setTimeout(() => { + setModalConfig({ + title: 'Konfirmasi', + message: 'Apakah anda yakin ingin mengarsipkan diskusi?', + onConfirm: () => handleDelete() + }) + setShowModal(true) + }, 600) }} /> } + + { + setShowModal(false) + modalConfig.onConfirm() + }} + onCancel={() => setShowModal(false)} + confirmText="Ya" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/components/division/FiturGridItem.tsx b/components/division/FiturGridItem.tsx new file mode 100644 index 0000000..e9844e1 --- /dev/null +++ b/components/division/FiturGridItem.tsx @@ -0,0 +1,38 @@ +import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; +import React from "react"; +import { Pressable, View } from "react-native"; +import Text from "../Text"; + +type Props = { + title: string; + subtitle: string; + icon: React.ReactNode; + onPress: () => void; +}; + +export default function FiturGridItem({ title, subtitle, icon, onPress }: Props) { + const { colors } = useTheme(); + + return ( + [ + Styles.wrapGridItem, + { + backgroundColor: colors.card, + borderColor: colors.icon + '20', + }, + pressed && { opacity: 0.7 } + ]} + > + + {icon} + + + {title} + {subtitle} + + + ); +} diff --git a/components/division/fiturDivisionDetail.tsx b/components/division/fiturDivisionDetail.tsx index ba15e92..1ee740d 100644 --- a/components/division/fiturDivisionDetail.tsx +++ b/components/division/fiturDivisionDetail.tsx @@ -6,9 +6,9 @@ import { AntDesign, Feather, MaterialIcons, SimpleLineIcons } from "@expo/vector import { router, useLocalSearchParams } from "expo-router" import { useEffect, useState } from "react" import { View } from "react-native" -import BorderBottomItem from "../borderBottomItem" import { useTheme } from "@/providers/ThemeProvider" import Text from "../Text" +import FiturGridItem from "./FiturGridItem" type Props = { tugas: number @@ -50,66 +50,34 @@ export default function FiturDivisionDetail({ refreshing }: { refreshing: boolea return ( Fitur - - - - - - } - title="Tugas" - subtitle={`${data.tugas} Tugas`} - width={30} - onPress={() => { router.push(`/division/${id}/task?status=0`) }} - /> + + } + onPress={() => { router.push(`/division/${id}/task?status=0`) }} + /> - - - - } - title="Dokumen" - subtitle={`${data.dokumen} File`} - width={30} - onPress={() => { router.push(`/division/${id}/document`) }} - /> - + } + onPress={() => { router.push(`/division/${id}/document`) }} + /> - - - - - } - title="Diskusi" - subtitle={`${data.diskusi} Diskusi`} - width={30} - onPress={() => { router.push(`/division/${id}/discussion?active=true`) }} - /> + } + onPress={() => { router.push(`/division/${id}/discussion?active=true`) }} + /> - - - - } - title="Kalender" - subtitle={`${data.kalender} Acara`} - width={30} - onPress={() => { router.push(`/division/${id}/calendar`) }} - /> - + } + onPress={() => { router.push(`/division/${id}/calendar`) }} + /> ) diff --git a/components/division/headerDivisionInfo.tsx b/components/division/headerDivisionInfo.tsx index 6112fac..7091161 100644 --- a/components/division/headerDivisionInfo.tsx +++ b/components/division/headerDivisionInfo.tsx @@ -8,7 +8,7 @@ import { useState } from "react" import { View } from "react-native" import Toast from "react-native-toast-message" import { useDispatch, useSelector } from "react-redux" -import AlertKonfirmasi from "../alertKonfirmasi" +import ModalConfirmation from "../ModalConfirmation" import ButtonMenuHeader from "../buttonMenuHeader" import DrawerBottom from "../drawerBottom" import MenuItemRow from "../menuItemRow" @@ -23,6 +23,7 @@ export default function HeaderRightDivisionInfo({ id, active }: Props) { const { colors } = useTheme(); const [isVisible, setVisible] = useState(false) const { token, decryptToken } = useAuthSession() + const [showModal, setShowModal] = useState(false) const update = useSelector((state: any) => state.divisionUpdate) const dispatch = useDispatch() @@ -62,15 +63,26 @@ export default function HeaderRightDivisionInfo({ id, active }: Props) { title={active ? "Non Aktifkan" : "Aktifkan"} onPress={() => { setVisible(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: active ? 'Apakah anda yakin ingin menonaktifkan divisi?' : 'Apakah anda yakin ingin mengaktifkan divisi?', - onPress: () => { handleUpdateStatus() } - }) + setTimeout(() => { + setShowModal(true) + }, 600) }} /> + + { + setShowModal(false) + handleUpdateStatus() + }} + onCancel={() => setShowModal(false)} + confirmText="Konfirmasi" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/components/document/menuBottomSelectDocument.tsx b/components/document/menuBottomSelectDocument.tsx index f746c71..6bf9fe2 100644 --- a/components/document/menuBottomSelectDocument.tsx +++ b/components/document/menuBottomSelectDocument.tsx @@ -6,7 +6,7 @@ import { useState } from "react"; import { Pressable, ScrollView, View } from "react-native"; import { useSharedValue } from "react-native-reanimated"; import Toast from "react-native-toast-message"; -import AlertKonfirmasi from "../alertKonfirmasi"; +import ModalConfirmation from "../ModalConfirmation"; import DrawerBottom from "../drawerBottom"; import { InputForm } from "../inputForm"; import ItemAccordion from "../itemAccordion"; @@ -29,6 +29,7 @@ export default function MenuBottomSelectDocument({ onDone }: Props) { const [isRename, setRename] = useState(false) const [isShare, setShare] = useState(false) const [isMoveCopy, setMoveCopy] = useState(false) + const [showDeleteModal, setShowDeleteModal] = useState(false) const [valMoveCopy, setValMoveCopy] = useState<'move' | 'copy'>('copy') const open = useSharedValue(false) @@ -58,15 +59,7 @@ export default function MenuBottomSelectDocument({ onDone }: Props) { icon={} title="Hapus" onPress={() => { - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah anda yakin ingin menghapus data?', - - onPress: () => { - onDone() - Toast.show({ type: 'small', text1: 'Berhasil menghapus data', }) - } - }) + setShowDeleteModal(true) }} column="many" color="white" @@ -213,6 +206,20 @@ export default function MenuBottomSelectDocument({ onDone }: Props) { }} /> { }} dataChoose={[]} /> + + { + setShowDeleteModal(false) + onDone() + Toast.show({ type: 'small', text1: 'Berhasil menghapus data', }) + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/components/home/projectHome.tsx b/components/home/projectHome.tsx index 46c820f..ff890d9 100644 --- a/components/home/projectHome.tsx +++ b/components/home/projectHome.tsx @@ -78,11 +78,11 @@ export default function ProjectHome({ refreshing }: { refreshing: boolean }) { {error && ({errorText})} - {info != undefined && ({info})} + {info != undefined && ({info})} ) } diff --git a/components/member/headerMemberDetail.tsx b/components/member/headerMemberDetail.tsx index 0e4d18f..6e30e10 100644 --- a/components/member/headerMemberDetail.tsx +++ b/components/member/headerMemberDetail.tsx @@ -9,7 +9,7 @@ import { useState } from "react" import { View } from "react-native" import Toast from "react-native-toast-message" import { useDispatch, useSelector } from "react-redux" -import AlertKonfirmasi from "../alertKonfirmasi" +import ModalConfirmation from "../ModalConfirmation" import ButtonMenuHeader from "../buttonMenuHeader" import DrawerBottom from "../drawerBottom" import MenuItemRow from "../menuItemRow" @@ -23,6 +23,7 @@ export default function HeaderRightMemberDetail({ active, id }: Props) { const { token, decryptToken } = useAuthSession() const [isVisible, setVisible] = useState(false) const update = useSelector((state: any) => state.memberUpdate) + const [showModal, setShowModal] = useState(false) const { colors } = useTheme(); const dispatch = useDispatch() @@ -54,13 +55,9 @@ export default function HeaderRightMemberDetail({ active, id }: Props) { title={active ? "Non Aktifkan" : "Aktifkan"} onPress={() => { setVisible(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: active ? 'Apakah anda yakin ingin menonaktifkan user?' : 'Apakah anda yakin ingin mengaktifkan user?', - onPress: () => { - handleActive() - } - }) + setTimeout(() => { + setShowModal(true) + }, 600) }} /> + + { + setShowModal(false) + handleActive() + }} + onCancel={() => setShowModal(false)} + confirmText="Konfirmasi" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/components/modalSelect.tsx b/components/modalSelect.tsx index ea0f500..2b68035 100644 --- a/components/modalSelect.tsx +++ b/components/modalSelect.tsx @@ -162,7 +162,7 @@ export default function ModalSelect({ open, close, title, category, idParent, on category != 'status-task' ? data.length > 0 ? data.map((item: any, index: any) => ( - { onChoose(item.id, item.name, item.img) }}> + { onChoose(item.id, item.name, item.img) }}> { category == 'member' ? @@ -188,7 +188,7 @@ export default function ModalSelect({ open, close, title, category, idParent, on <> { dataStatus.map((item: any, index: any) => ( - { + { onSelect(item) close(false) }}> diff --git a/components/paperGridContent.tsx b/components/paperGridContent.tsx index 79dd7fa..0efe6b8 100644 --- a/components/paperGridContent.tsx +++ b/components/paperGridContent.tsx @@ -1,9 +1,12 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; import { useTheme } from "@/providers/ThemeProvider"; -import { Pressable, View } from "react-native"; +import { ImageBackground, Pressable, View } from "react-native"; import Text from "./Text"; +import bgDark from '@/assets/images/bgproject-dark.png'; +import bgLight from '@/assets/images/bgproject-light.png'; + type Props = { content: 'carousel' | 'page'; children: React.ReactNode; @@ -15,13 +18,27 @@ type Props = { height?: number }; export default function PaperGridContent({ content, children, title, headerColor, onPress, contentPosition, titleTail, height }: Props) { - const { colors } = useTheme(); + const { colors, activeTheme } = useTheme(); + const bgSource = activeTheme === 'light' ? bgLight : bgDark; return ( - - {title} - + { + headerColor == 'warning' ? ( + + {title} + + ) : ( + + {title} + + ) + } state.projectUpdate) const [isAddLink, setAddLink] = useState(false) + const [showDeleteModal, setShowDeleteModal] = useState(false) const [link, setLink] = useState("") async function handleDelete() { @@ -152,11 +154,9 @@ export default function HeaderRightProjectDetail({ id, status }: Props) { title="Hapus" onPress={() => { setVisible(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah Anda yakin ingin menghapus kegiatan ini? Kegiatan yang dihapus tidak dapat dikembalikan', - onPress: () => { handleDelete() } - }) + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> : @@ -173,6 +173,19 @@ export default function HeaderRightProjectDetail({ id, status }: Props) { } + { + setShowDeleteModal(false) + handleDelete() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> + (null) + const [showDeleteModal, setShowDeleteModal] = useState(false) const [loadingOpen, setLoadingOpen] = useState(false) async function handleLoad(loading: boolean) { @@ -185,19 +186,27 @@ export default function SectionFile({ status, member, refreshing }: { status: nu onPress={() => { if (status == 3) return setModal(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah Anda yakin ingin menghapus file ini? File yang dihapus tidak dapat dikembalikan', - onPress: () => { - handleDelete() - } - }) - + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> } + + { + setShowDeleteModal(false) + handleDelete() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/components/project/sectionLink.tsx b/components/project/sectionLink.tsx index 84498e1..f24e511 100644 --- a/components/project/sectionLink.tsx +++ b/components/project/sectionLink.tsx @@ -10,7 +10,7 @@ import { useEffect, useState } from "react"; import { Linking, View } from "react-native"; import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; -import AlertKonfirmasi from "../alertKonfirmasi"; +import ModalConfirmation from "../ModalConfirmation"; import BorderBottomItem from "../borderBottomItem"; import DrawerBottom from "../drawerBottom"; import MenuItemRow from "../menuItemRow"; @@ -32,6 +32,7 @@ export default function SectionLink({ status, member, refreshing }: { status: nu const update = useSelector((state: any) => state.projectUpdate) const dispatch = useDispatch() const [selectLink, setSelectLink] = useState(null) + const [showDeleteModal, setShowDeleteModal] = useState(false) async function handleLoad() { try { @@ -122,19 +123,27 @@ export default function SectionLink({ status, member, refreshing }: { status: nu onPress={() => { if (status == 3) return setModal(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah Anda yakin ingin menghapus link ini? Link yang dihapus tidak dapat dikembalikan', - onPress: () => { - handleDelete() - } - }) - + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> } + + { + setShowDeleteModal(false) + handleDelete() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> } diff --git a/components/project/sectionMember.tsx b/components/project/sectionMember.tsx index 864876e..5050309 100644 --- a/components/project/sectionMember.tsx +++ b/components/project/sectionMember.tsx @@ -10,7 +10,7 @@ import { useEffect, useState } from "react"; import { View } from "react-native"; import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; -import AlertKonfirmasi from "../alertKonfirmasi"; +import ModalConfirmation from "../ModalConfirmation"; import BorderBottomItem from "../borderBottomItem"; import DrawerBottom from "../drawerBottom"; import ImageUser from "../imageNew"; @@ -35,6 +35,8 @@ export default function SectionMember({ status, refreshing }: { status: number | const [isModal, setModal] = useState(false); const { token, decryptToken } = useAuthSession(); const { id } = useLocalSearchParams<{ id: string }>(); + const [selectLink, setSelectLink] = useState(null); + const [showDeleteModal, setShowDeleteModal] = useState(false); const [data, setData] = useState([]); const [loading, setLoading] = useState(true) const arrSkeleton = Array.from({ length: 3 }) @@ -168,16 +170,27 @@ export default function SectionMember({ status, refreshing }: { status: number | title="Keluarkan" onPress={() => { setModal(false) - AlertKonfirmasi({ - title: "Konfirmasi", - desc: "Apakah Anda yakin ingin mengeluarkan anggota?", - onPress: () => { handleDeleteMember() }, - }); + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> } + + { + setShowDeleteModal(false) + handleDeleteMember() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Keluarkan" + cancelText="Batal" + /> ); } diff --git a/components/project/sectionTanggalTugas.tsx b/components/project/sectionTanggalTugas.tsx index ec96d72..a5619fa 100644 --- a/components/project/sectionTanggalTugas.tsx +++ b/components/project/sectionTanggalTugas.tsx @@ -9,7 +9,7 @@ import { useEffect, useState } from "react"; import { View } from "react-native"; import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; -import AlertKonfirmasi from "../alertKonfirmasi"; +import ModalConfirmation from "../ModalConfirmation"; import DrawerBottom from "../drawerBottom"; import ItemSectionTanggalTugas from "../itemSectionTanggalTugas"; import MenuItemRow from "../menuItemRow"; @@ -45,6 +45,7 @@ export default function SectionTanggalTugasProject({ status, member, refreshing id: '', status: 0, }) + const [showDeleteModal, setShowDeleteModal] = useState(false) async function handleLoad(loading: boolean) { try { @@ -215,16 +216,27 @@ export default function SectionTanggalTugasProject({ status, member, refreshing title="Hapus Tugas" onPress={() => { setModal(false) - AlertKonfirmasi({ - title: "Konfirmasi", - desc: "Apakah anda yakin ingin menghapus data ini?", - onPress: () => { handleDelete() }, - }); + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> + { + setShowDeleteModal(false) + handleDelete() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> + { setSelect(false) }} diff --git a/components/task/headerTaskDetail.tsx b/components/task/headerTaskDetail.tsx index 7f001f0..83fe4db 100644 --- a/components/task/headerTaskDetail.tsx +++ b/components/task/headerTaskDetail.tsx @@ -9,7 +9,7 @@ import { useState } from "react" import { View } from "react-native" import Toast from "react-native-toast-message" import { useDispatch, useSelector } from "react-redux" -import AlertKonfirmasi from "../alertKonfirmasi" +import ModalConfirmation from "../ModalConfirmation" import ButtonMenuHeader from "../buttonMenuHeader" import DrawerBottom from "../drawerBottom" import { InputForm } from "../inputForm" @@ -31,6 +31,7 @@ export default function HeaderRightTaskDetail({ id, division, status, isAdminDiv const dispatch = useDispatch() const update = useSelector((state: any) => state.taskUpdate) const [isAddLink, setAddLink] = useState(false) + const [showDeleteModal, setShowDeleteModal] = useState(false) const [link, setLink] = useState("") async function handleDelete() { @@ -158,11 +159,9 @@ export default function HeaderRightTaskDetail({ id, division, status, isAdminDiv title="Hapus" onPress={() => { setVisible(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah Anda yakin ingin menghapus tugas ini? Tugas yang dihapus tidak dapat dikembalikan', - onPress: () => { handleDelete() } - }) + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> @@ -180,6 +179,19 @@ export default function HeaderRightTaskDetail({ id, division, status, isAdminDiv } + { + setShowDeleteModal(false) + handleDelete() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> + () const [data, setData] = useState([]) @@ -174,14 +178,9 @@ export default function SectionFileTask({ refreshing, isMemberDivision }: { refr title="Hapus" onPress={() => { setModal(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah Anda yakin ingin menghapus file ini? File yang dihapus tidak dapat dikembalikan', - onPress: () => { - handleDelete() - } - }) - + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> : @@ -190,6 +189,19 @@ export default function SectionFileTask({ refreshing, isMemberDivision }: { refr + + { + setShowDeleteModal(false) + handleDelete() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> ) } \ No newline at end of file diff --git a/components/task/sectionLinkTask.tsx b/components/task/sectionLinkTask.tsx index e5d568c..7ed3ae1 100644 --- a/components/task/sectionLinkTask.tsx +++ b/components/task/sectionLinkTask.tsx @@ -10,7 +10,7 @@ import { useEffect, useState } from "react"; import { Linking, View } from "react-native"; import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; -import AlertKonfirmasi from "../alertKonfirmasi"; +import ModalConfirmation from "../ModalConfirmation"; import BorderBottomItem from "../borderBottomItem"; import DrawerBottom from "../drawerBottom"; import MenuItemRow from "../menuItemRow"; @@ -30,6 +30,7 @@ export default function SectionLinkTask({ refreshing, isMemberDivision }: { refr const update = useSelector((state: any) => state.taskUpdate) const dispatch = useDispatch() const [selectLink, setSelectLink] = useState(null) + const [showDeleteModal, setShowDeleteModal] = useState(false) const entityUser = useSelector((state: any) => state.user); async function handleLoad() { @@ -112,11 +113,9 @@ export default function SectionLinkTask({ refreshing, isMemberDivision }: { refr title="Hapus" onPress={() => { setModal(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah Anda yakin ingin menghapus link ini? Link yang dihapus tidak dapat dikembalikan', - onPress: () => { handleDelete() } - }) + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> : @@ -125,6 +124,19 @@ export default function SectionLinkTask({ refreshing, isMemberDivision }: { refr + + { + setShowDeleteModal(false) + handleDelete() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> } diff --git a/components/task/sectionMemberTask.tsx b/components/task/sectionMemberTask.tsx index cf4b74d..7e2cc45 100644 --- a/components/task/sectionMemberTask.tsx +++ b/components/task/sectionMemberTask.tsx @@ -10,7 +10,7 @@ import { useEffect, useState } from "react"; import { View } from "react-native"; import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; -import AlertKonfirmasi from "../alertKonfirmasi"; +import ModalConfirmation from "../ModalConfirmation"; import BorderBottomItem from "../borderBottomItem"; import DrawerBottom from "../drawerBottom"; import ImageUser from "../imageNew"; @@ -30,6 +30,8 @@ type Props = { export default function SectionMemberTask({ refreshing, isAdminDivision }: { refreshing: boolean, isAdminDivision: boolean }) { const { colors } = useTheme() const [isModal, setModal] = useState(false); + const [selectLink, setSelectLink] = useState(null) + const [showDeleteModal, setShowDeleteModal] = useState(false) const entityUser = useSelector((state: any) => state.user); const { token, decryptToken } = useAuthSession(); const { id, detail } = useLocalSearchParams<{ id: string; detail: string }>(); @@ -132,7 +134,7 @@ export default function SectionMemberTask({ refreshing, isAdminDivision }: { ref ); }) ) : ( - + Tidak ada anggota ) @@ -177,11 +179,9 @@ export default function SectionMemberTask({ refreshing, isAdminDivision }: { ref title="Keluarkan" onPress={() => { setModal(false) - AlertKonfirmasi({ - title: "Konfirmasi", - desc: "Apakah Anda yakin ingin mengeluarkan anggota?", - onPress: () => { handleDeleteMember() }, - }); + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> : @@ -189,6 +189,19 @@ export default function SectionMemberTask({ refreshing, isAdminDivision }: { ref } + + { + setShowDeleteModal(false) + handleDeleteMember() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Keluarkan" + cancelText="Batal" + /> ); } diff --git a/components/task/sectionTanggalTugasTask.tsx b/components/task/sectionTanggalTugasTask.tsx index 7342503..e365afd 100644 --- a/components/task/sectionTanggalTugasTask.tsx +++ b/components/task/sectionTanggalTugasTask.tsx @@ -9,7 +9,7 @@ import { useEffect, useState } from "react"; import { View } from "react-native"; import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; -import AlertKonfirmasi from "../alertKonfirmasi"; +import ModalConfirmation from "../ModalConfirmation"; import DrawerBottom from "../drawerBottom"; import ItemSectionTanggalTugas from "../itemSectionTanggalTugas"; import MenuItemRow from "../menuItemRow"; @@ -44,6 +44,7 @@ export default function SectionTanggalTugasTask({ refreshing, isMemberDivision } id: '', status: 0, }) + const [showDeleteModal, setShowDeleteModal] = useState(false) async function handleLoad(loading: boolean) { try { @@ -211,14 +212,9 @@ export default function SectionTanggalTugasTask({ refreshing, isMemberDivision } title="Hapus Tugas" onPress={() => { setModal(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah anda yakin ingin menghapus data ini?', - onPress: () => { - handleDelete() - } - }) - + setTimeout(() => { + setShowDeleteModal(true) + }, 600) }} /> @@ -227,6 +223,19 @@ export default function SectionTanggalTugasTask({ refreshing, isMemberDivision } } + { + setShowDeleteModal(false) + handleDelete() + }} + onCancel={() => setShowDeleteModal(false)} + confirmText="Hapus" + cancelText="Batal" + /> + setSelect(false)} diff --git a/components/toastCustom.tsx b/components/toastCustom.tsx index 3004826..6385743 100644 --- a/components/toastCustom.tsx +++ b/components/toastCustom.tsx @@ -7,12 +7,19 @@ import Text from "./Text"; export default function ToastCustom({ position }: { position?: 'top' | 'bottom' }) { const { colors } = useTheme() return ( - Toast.hide()} visibilityTime={1500} position={position || 'bottom'} config={{ - small: ({ text1 }) => ( - - {text1} - - ) - }} /> + Toast.hide()} + visibilityTime={1500} + position={position || 'bottom'} + bottomOffset={80} + config={{ + small: ({ text1 }) => ( + + {text1} + + ) + }} + /> ) } \ No newline at end of file diff --git a/constants/Colors.ts b/constants/Colors.ts index 520ca2b..22215ae 100644 --- a/constants/Colors.ts +++ b/constants/Colors.ts @@ -6,7 +6,7 @@ export const Colors = { text: '#11181C', background: '#f7f7f7ff', tint: tintColorLight, - primary: '#19345E', + primary: '#1F3C88', icon: '#1F3C88', card: '#ffffff', tabIconDefault: '#687076', @@ -24,7 +24,7 @@ export const Colors = { text: '#ECEDEE', background: '#0F1B2D', tint: tintColorDark, - primary: '#19345E', + primary: '#123A6F', icon: '#9DB9E8', card: '#16233A', // slightly lighter than background #151718 tabIconDefault: '#9BA1A6', diff --git a/constants/ConstEnv.ts b/constants/ConstEnv.ts index 923221e..dc45423 100644 --- a/constants/ConstEnv.ts +++ b/constants/ConstEnv.ts @@ -2,5 +2,14 @@ import Constants from 'expo-constants'; export const ConstEnv = { url_storage: Constants?.expoConfig?.extra?.URL_STORAGE, - pass_encrypt: Constants?.expoConfig?.extra?.PASS_ENC + pass_encrypt: Constants?.expoConfig?.extra?.PASS_ENC, + firebase: { + apiKey: Constants?.expoConfig?.extra?.FIREBASE_API_KEY, + authDomain: Constants?.expoConfig?.extra?.FIREBASE_AUTH_DOMAIN, + projectId: Constants?.expoConfig?.extra?.FIREBASE_PROJECT_ID, + storageBucket: Constants?.expoConfig?.extra?.FIREBASE_STORAGE_BUCKET, + messagingSenderId: Constants?.expoConfig?.extra?.FIREBASE_MESSAGING_SENDER_ID, + appId: Constants?.expoConfig?.extra?.FIREBASE_APP_ID, + databaseURL: Constants?.expoConfig?.extra?.URL_FIREBASE_DB, + } } \ No newline at end of file diff --git a/constants/Styles.ts b/constants/Styles.ts index b12a5a9..39267a7 100644 --- a/constants/Styles.ts +++ b/constants/Styles.ts @@ -88,6 +88,9 @@ const Styles = StyleSheet.create({ mb15: { marginBottom: 15 }, + mb20: { + marginBottom: 20 + }, mb30: { marginBottom: 30 }, @@ -130,6 +133,9 @@ const Styles = StyleSheet.create({ mt15: { marginTop: 15 }, + mt30: { + marginTop: 30 + }, mr05: { marginRight: 5 }, @@ -291,9 +297,9 @@ const Styles = StyleSheet.create({ borderWidth: 1, }, btnRound: { - backgroundColor: '#19345E', + backgroundColor: '#1F3C88', borderWidth: 0, - borderColor: '#19345E', + borderColor: '#1F3C88', alignItems: 'center', borderRadius: 30, marginTop: 15, @@ -309,7 +315,7 @@ const Styles = StyleSheet.create({ }, btnLainnya: { alignSelf: 'flex-start', - backgroundColor: '#19345E', + backgroundColor: '#1F3C88', paddingVertical: 5, marginVertical: 5 }, @@ -473,7 +479,7 @@ const Styles = StyleSheet.create({ borderColor: '#d6d8f6', borderWidth: 1, borderRadius: 5, - marginBottom: 10 + marginBottom: 5 }, wrapItemBorderNone: { padding: 10, @@ -502,7 +508,7 @@ const Styles = StyleSheet.create({ iconContent: { padding: 10, borderRadius: 100, - backgroundColor:'#E5E7EB' + backgroundColor: '#E5E7EB' }, wrapHeadViewMember: { backgroundColor: '#19345E', @@ -578,7 +584,6 @@ const Styles = StyleSheet.create({ padding: 10, flexDirection: 'row', justifyContent: 'space-between', - borderColor: '#d6d8f6', borderBottomWidth: 1, alignItems: 'center' }, @@ -723,6 +728,69 @@ const Styles = StyleSheet.create({ shadowOpacity: 0.2, shadowRadius: 5, elevation: 50, + }, + modalOverlay: { + flex: 1, + backgroundColor: 'rgba(0, 0, 0, 0.6)', + justifyContent: 'center', + alignItems: 'center', + }, + modalConfirmContainer: { + width: '80%', + borderRadius: 14, + overflow: 'hidden', + elevation: 5, + shadowColor: '#000', + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.25, + shadowRadius: 3.84, + }, + modalConfirmContent: { + padding: 20, + alignItems: 'center', + }, + modalConfirmTitle: { + fontSize: 18, + fontWeight: 'bold', + marginBottom: 8, + textAlign: 'center', + }, + modalConfirmMessage: { + fontSize: 14, + textAlign: 'center', + lineHeight: 20, + }, + modalConfirmDivider: { + height: 1, + width: '100%', + }, + modalConfirmFooter: { + flexDirection: 'row', + height: 50, + }, + modalConfirmButton: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + modalConfirmButtonText: { + fontSize: 16, + }, + modalConfirmVerticalDivider: { + width: 1, + height: '100%', + }, + wrapGridItem: { + borderWidth: 1, + borderRadius: 5, + padding: 10, + flexDirection: 'row', + alignItems: 'center', + width: '48.5%', + marginBottom: 10, + }, + flex1: { + flex: 1 } }) diff --git a/declarations.d.ts b/declarations.d.ts new file mode 100644 index 0000000..2046d60 --- /dev/null +++ b/declarations.d.ts @@ -0,0 +1,24 @@ +declare module "*.png" { + const value: any; + export default value; +} + +declare module "*.jpg" { + const value: any; + export default value; +} + +declare module "*.jpeg" { + const value: any; + export default value; +} + +declare module "*.svg" { + const value: any; + export default value; +} + +declare module "*.gif" { + const value: any; + export default value; +} diff --git a/lib/api.ts b/lib/api.ts index b81d90f..9ce5413 100644 --- a/lib/api.ts +++ b/lib/api.ts @@ -96,30 +96,18 @@ export const apiGetGroup = async ({ user, active, search }: { user: string, acti }; export const apiCreateGroup = async (data: { user: string, name: string }) => { - await api.post('mobile/group', data).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.post('mobile/group', data); + return response.data; }; export const apiEditGroup = async (data: { user: string, name: string }, id: string) => { - await api.put(`mobile/group/${id}`, data).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.put(`mobile/group/${id}`, data); + return response.data; }; export const apiDeleteGroup = async (data: { user: string, isActive: boolean }, id: string) => { - await api.delete(`mobile/group/${id}`, { data }).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.delete(`mobile/group/${id}`, { data }); + return response.data; }; export const apiGetPosition = async ({ user, active, search, group }: { user: string, active: string, search: string, group?: string }) => { @@ -128,22 +116,14 @@ export const apiGetPosition = async ({ user, active, search, group }: { user: st }; export const apiCreatePosition = async (data: { user: string, name: string, idGroup: string }) => { - await api.post('mobile/position', data).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.post('mobile/position', data); + return response.data; }; export const apiDeletePosition = async (data: { user: string, isActive: boolean }, id: string) => { - await api.delete(`mobile/position/${id}`, { data }).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.delete(`mobile/position/${id}`, { data }); + return response.data; }; export const apiEditPosition = async (data: { user: string, name: string, idGroup: string }, id: string) => { @@ -207,12 +187,8 @@ export const apiUpdateDiscussionGeneralCommentar = async ({ id, data }: { id: st export const apiDeleteMemberDiscussionGeneral = async (data: { user: string, idUser: string }, id: string) => { - await api.delete(`mobile/discussion-general/${id}/member`, { data }).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.delete(`mobile/discussion-general/${id}/member`, { data }); + return response.data; }; @@ -222,19 +198,10 @@ export const apiUpdateStatusDiscussionGeneral = async ({ id, data }: { id: strin }; export const apiDeleteDiscussionGeneral = async (data: { user: string, active: boolean }, id: string) => { - await api.delete(`mobile/discussion-general/${id}`, { data }).then(response => { - return response.data; - }) - .catch(error => { - console.error('Error:', error); - }); + const response = await api.delete(`mobile/discussion-general/${id}`, { data }); + return response.data; }; -// export const apiEditDiscussionGeneral = async (data: { user: string, title: string, desc: string }, id: string) => { -// const response = await api.put(`/mobile/discussion-general/${id}`, data) -// return response.data; -// }; - export const apiEditDiscussionGeneral = async (data: FormData, id: string) => { const response = await api.put(`/mobile/discussion-general/${id}`, data, { headers: { diff --git a/lib/pushToPage.ts b/lib/pushToPage.ts index e510536..ed23ffc 100644 --- a/lib/pushToPage.ts +++ b/lib/pushToPage.ts @@ -23,6 +23,10 @@ export function pushToPage(category: string, idContent: string) { return router.push(`/member/${idContent}`) } else if (cat[0] == 'project') { return router.push(`/project/${idContent}`) + } else if (cat[0] == 'group') { + return router.push(`/group`) + } else if (cat[0] == 'position') { + return router.push(`/position`) } } } \ No newline at end of file diff --git a/lib/useNotification.ts b/lib/useNotification.ts index b1dd761..7a9ac7c 100644 --- a/lib/useNotification.ts +++ b/lib/useNotification.ts @@ -6,25 +6,29 @@ import { } from '@react-native-firebase/messaging'; import * as Notifications from 'expo-notifications'; import { useEffect } from 'react'; -import { PermissionsAndroid, Platform } from 'react-native'; +import { Linking, PermissionsAndroid, Platform } from 'react-native'; +import { ConstEnv } from '@/constants/ConstEnv'; -// Firebase config const RNfirebaseConfig = { - apiKey: "AIzaSyB2hbsW91J3oRQx4_jgrCCNY0tNt5-21e8", - authDomain: "googleapis.com", - projectId: "mobile-darmasaba", - storageBucket: "mobile-darmasaba.appspot.com", - messagingSenderId: "867439221179", - appId: "1:867439221179:android:4509f77478c8dce99b0c9e", - databaseURL: "https://mobile-darmasaba-default-rtdb.asia-southeast1.firebasedatabase.app/" + apiKey: ConstEnv.firebase.apiKey, + authDomain: ConstEnv.firebase.authDomain, + projectId: ConstEnv.firebase.projectId, + storageBucket: ConstEnv.firebase.storageBucket, + messagingSenderId: ConstEnv.firebase.messagingSenderId, + appId: ConstEnv.firebase.appId, + databaseURL: ConstEnv.firebase.databaseURL }; const initializeFirebase = async () => { try { - const app = getApps().length ? getApp() : initializeApp(RNfirebaseConfig); + let app; + const apps = getApps(); + if (apps.length) { + app = getApp() as any; + } else { + app = initializeApp(RNfirebaseConfig) as any; + } const mess = getMessaging(app); - // await registerDeviceForRemoteMessages(mess); - // `registerDeviceForRemoteMessages` tidak perlu lagi await setAutoInitEnabled(mess, true); return mess; @@ -33,6 +37,30 @@ const initializeFirebase = async () => { } }; +export const checkPermission = async () => { + try { + if (Platform.OS === 'android') { + return await PermissionsAndroid.check( + PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS + ); + } else if (Platform.OS === 'ios') { + const { status } = await Notifications.getPermissionsAsync(); + return status === 'granted'; + } + } catch (err) { + console.warn('Error checking notification permissions:', err); + return false; + } +}; + +export const openSettings = () => { + if (Platform.OS === 'ios') { + Linking.openURL('app-settings:'); + } else { + Linking.openSettings(); + } +}; + export const requestPermission = async () => { try { if (Platform.OS === 'android') { diff --git a/providers/AuthProvider.tsx b/providers/AuthProvider.tsx index bff0a8a..ac1f23c 100644 --- a/providers/AuthProvider.tsx +++ b/providers/AuthProvider.tsx @@ -40,9 +40,8 @@ export default function AuthProvider({ children }: { children: ReactNode }): Rea }, []); const decryptToken = (async (token: string) => { - var C = require("crypto-js"); - var Decrypted = C.AES.decrypt(token, ConstEnv.pass_encrypt); - var result = Decrypted.toString(C.enc.Utf8); + var Decrypted = CryptoES.AES.decrypt(token, ConstEnv.pass_encrypt); + var result = Decrypted.toString(CryptoES.enc.Utf8); return result })