From 263875ae55ad1263c7495504a8e1baef883acf58 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Tue, 19 Aug 2025 17:39:27 +0800 Subject: [PATCH] upd: fitur tambahan project Deskripsi: - tampilan list detail waktu task project - integrasi api mobile list detail - tampilan tambah detail task project > blm selesai No Issues --- app/(application)/project/[id]/add-task.tsx | 11 +- app/(application)/project/create/task.tsx | 2 +- components/modalFloat.tsx | 2 +- .../project/modalListDetailTugasProject.tsx | 116 ++++++++++++++++++ components/project/sectionTanggalTugas.tsx | 26 ++++ constants/Styles.ts | 6 + lib/api.ts | 4 +- 7 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 components/project/modalListDetailTugasProject.tsx diff --git a/app/(application)/project/[id]/add-task.tsx b/app/(application)/project/[id]/add-task.tsx index 640817a..78e8f3c 100644 --- a/app/(application)/project/[id]/add-task.tsx +++ b/app/(application)/project/[id]/add-task.tsx @@ -6,14 +6,16 @@ import Styles from "@/constants/Styles"; import { apiCreateProjectTask } from "@/lib/api"; import { setUpdateProject } from "@/lib/projectUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; -import 'intl'; -import 'intl/locale-data/jsonp/id'; +import { useHeaderHeight } from '@react-navigation/elements'; import dayjs from "dayjs"; import { router, Stack, useLocalSearchParams } from "expo-router"; +import 'intl'; +import 'intl/locale-data/jsonp/id'; import { useEffect, useState } from "react"; import { KeyboardAvoidingView, Platform, + Pressable, SafeAreaView, ScrollView, View @@ -23,7 +25,6 @@ import DateTimePicker, { DateType } from "react-native-ui-datepicker"; import { useDispatch, useSelector } from "react-redux"; -import { useHeaderHeight } from '@react-navigation/elements'; export default function ProjectAddTask() { const headerHeight = useHeaderHeight(); @@ -162,6 +163,10 @@ export default function ProjectAddTask() { { (error.endDate || error.startDate) && Tanggal tidak boleh kosong } + {/* TODO */} + + Detail + void title?: string children: React.ReactNode - onSubmit: () => void + onSubmit?: () => void disableSubmit?: boolean buttonHide?: boolean } diff --git a/components/project/modalListDetailTugasProject.tsx b/components/project/modalListDetailTugasProject.tsx new file mode 100644 index 0000000..8c665c5 --- /dev/null +++ b/components/project/modalListDetailTugasProject.tsx @@ -0,0 +1,116 @@ +import Styles from "@/constants/Styles"; +import { apiGetProjectTask } from "@/lib/api"; +import { useAuthSession } from "@/providers/AuthProvider"; +import { useEffect, useState } from "react"; +import { Dimensions, View, VirtualizedList } from "react-native"; +import { InputDate } from "../inputDate"; +import ModalFloat from "../modalFloat"; +import Skeleton from "../skeleton"; +import Text from "../Text"; + +interface Props { + id: string; + date: string; + timeStart: string; + timeEnd: string; +} + +export default function ModalListDetailTugasProject({ isVisible, setVisible, idTask }: { isVisible: boolean, setVisible: (value: boolean) => void, idTask: string }) { + const [data, setData] = useState([]) + const [loading, setLoading] = useState(false) + const { token, decryptToken } = useAuthSession() + const arrSkeleton = Array.from({ length: 3 }, (_, index) => index) + const tinggiScreen = Dimensions.get("window").height; + const tinggiFix = tinggiScreen * 70 / 100; + + + + async function getData() { + try { + setLoading(true) + const hasil = await decryptToken(String(token?.current)); + const res = await apiGetProjectTask({ user: hasil, id: idTask, cat: "detailTask" }) + setData(res.data) + } catch (error) { + console.error(error) + } finally { + setLoading(false) + } + } + + useEffect(() => { + if (isVisible) { + getData() + } + }, [isVisible, idTask]) + + const getItem = (_data: unknown, index: number): Props => ({ + id: data[index].id, + date: data[index].date, + timeStart: data[index].timeStart, + timeEnd: data[index].timeEnd, + }) + + return ( + + + { + loading ? + arrSkeleton.map((item: any, i: number) => { + return ( + + ) + }) + : + data.length > 0 ? + ( + data.length} + getItem={getItem} + renderItem={({ item, index }: { item: Props, index: number }) => { + return ( + + {item.date} + + + { }} + value={item.timeStart} + label="Waktu Awal" + placeholder="--:--" + /> + + + { }} + mode="time" + value={item.timeEnd} + label="Waktu Akhir" + placeholder="--:--" + disable + /> + + + + ) + }} + keyExtractor={(item, index) => String(index)} + showsVerticalScrollIndicator={false} + /> + ) + : + Tidak ada data + } + + + + ) +} \ No newline at end of file diff --git a/components/project/sectionTanggalTugas.tsx b/components/project/sectionTanggalTugas.tsx index ee3cb40..285b55e 100644 --- a/components/project/sectionTanggalTugas.tsx +++ b/components/project/sectionTanggalTugas.tsx @@ -15,6 +15,7 @@ import MenuItemRow from "../menuItemRow"; import ModalSelect from "../modalSelect"; import SkeletonTask from "../skeletonTask"; import Text from "../Text"; +import ModalListDetailTugasProject from "./modalListDetailTugasProject"; type Props = { id: string; @@ -33,6 +34,7 @@ export default function SectionTanggalTugasProject({ status, member, refreshing const [isModal, setModal] = useState(false); const [isSelect, setSelect] = useState(false); const { token, decryptToken } = useAuthSession(); + const [modalDetail, setModalDetail] = useState(false) const { id } = useLocalSearchParams<{ id: string }>(); const [data, setData] = useState([]); const [loading, setLoading] = useState(true) @@ -188,6 +190,24 @@ export default function SectionTanggalTugasProject({ status, member, refreshing }} /> + + } + title="Detail Waktu" + onPress={() => { + setModal(false); + setTimeout(() => { + setModalDetail(true) + }, 600) + }} + /> + + } title="Hapus Tugas" @@ -213,6 +233,12 @@ export default function SectionTanggalTugasProject({ status, member, refreshing open={isSelect} valChoose={String(tugas.status)} /> + + ); } diff --git a/constants/Styles.ts b/constants/Styles.ts index 4b22a9d..88b95a3 100644 --- a/constants/Styles.ts +++ b/constants/Styles.ts @@ -269,6 +269,12 @@ const Styles = StyleSheet.create({ flexDirection: 'row', justifyContent: 'center' }, + btnLainnya: { + alignSelf: 'flex-start', + backgroundColor: '#19345E', + paddingVertical: 5, + marginVertical: 5 + }, btnMenuRow: { width: '33%', alignItems: 'center' diff --git a/lib/api.ts b/lib/api.ts index 8b1f509..3a485df 100644 --- a/lib/api.ts +++ b/lib/api.ts @@ -301,8 +301,8 @@ export const apiDeleteProjectTask = async (data: { user: string, idProject: stri return response.data }; -export const apiGetProjectTask = async ({ user, id }: { user: string, id: string }) => { - const response = await api.get(`mobile/project/detail/${id}?user=${user}`); +export const apiGetProjectTask = async ({ user, id, cat }: { user: string, id: string, cat?: string }) => { + const response = await api.get(`mobile/project/detail/${id}?user=${user}${cat ? `&cat=${cat}` : ""}`); return response.data; };