From bdfb3a8b2bc510969b08733eff15979ef7a47930 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Wed, 6 May 2026 17:10:08 +0800 Subject: [PATCH] feat: redesign halaman create project dan task divisi dengan section card - Ganti ButtonSelect dengan section card (Tanggal & Tugas, File, Anggota) - Tiap card: header pressable dengan icon, badge count, chevron, dan preview isi - Background item list (file & anggota) dibuat transparan (hanya border) - Badge file seragam dengan badge tugas dan orang - Tambah prop showTitle pada SectionListAddTask - Ekstrak inline style ke Styles.ts: sectionActionRow, sectionBadge, positionBadge, listItemCard Co-Authored-By: Claude Sonnet 4.6 --- .../[id]/(fitur-division)/task/create.tsx | 131 +++++++---- app/(application)/project/create.tsx | 215 +++++++++++------- components/project/sectionListAddTask.tsx | 57 ++--- constants/Styles.ts | 25 ++ 4 files changed, 269 insertions(+), 159 deletions(-) diff --git a/app/(application)/division/[id]/(fitur-division)/task/create.tsx b/app/(application)/division/[id]/(fitur-division)/task/create.tsx index 6252ff4..ecb12cc 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/create.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/create.tsx @@ -1,6 +1,5 @@ import AppHeader from "@/components/AppHeader"; import ButtonSaveHeader from "@/components/buttonSaveHeader"; -import ButtonSelect from "@/components/buttonSelect"; import DrawerBottom from "@/components/drawerBottom"; import ImageUser from "@/components/imageNew"; import { InputForm } from "@/components/inputForm"; @@ -187,13 +186,61 @@ export default function CreateTaskDivision() { bg={colors.card} errorText="Judul Tugas tidak boleh kosong" /> - { router.push(`/division/${id}/task/create/task`); }} /> - - { router.push(`/division/${id}/task/create/member`); }} /> - - {fileForm.length > 0 && ( - - File + + {/* Tanggal & Tugas */} + + router.push(`/division/${id}/task/create/task`)} + style={[Styles.sectionActionRow, { marginBottom: taskCreate.length > 0 ? 12 : 0 }]} + > + + + + + Tanggal & Tugas + {taskCreate.length === 0 && ( + Belum ada tugas ditambahkan + )} + + {taskCreate.length > 0 && ( + + {taskCreate.length} tugas + + )} + + + {taskCreate.length > 0 && } + + + {/* File */} + + 0 ? 12 : 0 }]} + > + + + + + File + {fileForm.length === 0 && ( + Opsional — ketuk untuk upload + )} + + {fileForm.length > 0 && ( + + {fileForm.length} file + + )} + + + {fileForm.length > 0 && ( {fileForm.map((item, index) => { const ext = item.name.split('.').pop()?.toLowerCase() ?? '' @@ -204,64 +251,66 @@ export default function CreateTaskDivision() { { setIndexDelFile(index); setModal(true) }} - style={[Styles.fileCard, { backgroundColor: colors.card, borderColor: colors.icon + '18' }]} + style={[Styles.fileCard, { backgroundColor: 'transparent', borderColor: colors.icon + '18' }]} > {baseName} - - {ext.toUpperCase()} - + {ext.toUpperCase()} ) })} - - )} - {entitiesMember.length > 0 && ( - - - Anggota - {entitiesMember.length} orang + )} + + + {/* Anggota */} + + router.push(`/division/${id}/task/create/member`)} + style={[Styles.sectionActionRow, { marginBottom: entitiesMember.length > 0 ? 12 : 0 }]} + > + + + + Anggota + {entitiesMember.length === 0 && ( + Belum ada anggota dipilih + )} + + {entitiesMember.length > 0 && ( + + {entitiesMember.length} orang + + )} + + + {entitiesMember.length > 0 && ( {entitiesMember.map((item: { img: any; name: any; position?: string }, index: any) => ( {item.name} {item.position && ( - - - {item.position} - + + {item.position} )} ))} - - )} + )} + diff --git a/app/(application)/project/create.tsx b/app/(application)/project/create.tsx index e1623b9..9b74e04 100644 --- a/app/(application)/project/create.tsx +++ b/app/(application)/project/create.tsx @@ -1,6 +1,5 @@ import AppHeader from "@/components/AppHeader"; import ButtonSaveHeader from "@/components/buttonSaveHeader"; -import ButtonSelect from "@/components/buttonSelect"; import DrawerBottom from "@/components/drawerBottom"; import ImageUser from "@/components/imageNew"; import { InputForm } from "@/components/inputForm"; @@ -261,26 +260,23 @@ export default function CreateProject() { style={[Styles.h100, { backgroundColor: colors.background }]} > - { - (entityUser.role == "supadmin" || entityUser.role == "developer") - && - ( - { - setValChoose(chooseGroup.val); - setValSelect("group"); - setSelect(true); - }} - error={error.group} - errorText="Lembaga Desa tidak boleh kosong" - /> - ) - } + {(entityUser.role == "supadmin" || entityUser.role == "developer") && ( + { + setValChoose(chooseGroup.val); + setValSelect("group"); + setSelect(true); + }} + error={error.group} + errorText="Lembaga Desa tidak boleh kosong" + /> + )} + { - validationForm("title", val); - }} + onChange={(val) => validationForm("title", val)} /> - { - router.push(`/project/create/task`); - }} - error={error.task} - errorText="Tanggal & Tugas tidak boleh kosong" - /> - - { - if (entityUser.role == "supadmin" || entityUser.role == "developer") { - if (chooseGroup.val != "") { - router.push(`/project/create/member`); - } else { - Toast.show({ type: 'small', text1: "Pilih Lembaga Desa terlebih dahulu", }) - } - } else { - router.push(`/project/create/member`); - } - }} - error={error.member} - errorText="Anggota tidak boleh kosong" - /> - - {fileForm.length > 0 && ( - - File + + {/* Tanggal & Tugas */} + + router.push(`/project/create/task`)} + style={[Styles.sectionActionRow, { marginBottom: taskCreate.length > 0 ? 12 : 0 }]} + > + + + + + Tanggal & Tugas + {taskCreate.length === 0 && ( + Belum ada tugas ditambahkan + )} + + {taskCreate.length > 0 && ( + + {taskCreate.length} tugas + + )} + + + {taskCreate.length > 0 && } + {error.task && ( + + Tanggal & Tugas tidak boleh kosong + + )} + + + {/* File */} + + 0 ? 12 : 0 }]} + > + + + + + File + {fileForm.length === 0 && ( + Opsional — ketuk untuk upload + )} + + {fileForm.length > 0 && ( + + {fileForm.length} file + + )} + + + {fileForm.length > 0 && ( {fileForm.map((item, index) => { const ext = item.name.split('.').pop()?.toLowerCase() ?? '' @@ -333,64 +358,82 @@ export default function CreateProject() { { setIndexDelFile(index); setModal(true) }} - style={[Styles.fileCard, { backgroundColor: colors.card, borderColor: colors.icon + '18' }]} + style={[Styles.fileCard, { backgroundColor: 'transparent', borderColor: colors.icon + '18' }]} > {baseName} - - {ext.toUpperCase()} - + {ext.toUpperCase()} ) })} - - )} - {entitiesMember.length > 0 && ( - - - Anggota - {entitiesMember.length} orang + )} + + + {/* Anggota */} + + { + if (entityUser.role == "supadmin" || entityUser.role == "developer") { + if (chooseGroup.val != "") { + router.push(`/project/create/member`); + } else { + Toast.show({ type: 'small', text1: "Pilih Lembaga Desa terlebih dahulu" }) + } + } else { + router.push(`/project/create/member`); + } + }} + style={[Styles.sectionActionRow, { marginBottom: entitiesMember.length > 0 ? 12 : 0 }]} + > + + + + Anggota + {entitiesMember.length === 0 && ( + Belum ada anggota dipilih + )} + + {entitiesMember.length > 0 && ( + + {entitiesMember.length} orang + + )} + + + {entitiesMember.length > 0 && ( {entitiesMember.map((item: { img: any; name: any; position?: string }, index: any) => ( {item.name} {item.position && ( - - - {item.position} - + + {item.position} )} ))} - - )} + )} + {error.member && ( + + Anggota tidak boleh kosong + + )} + + diff --git a/components/project/sectionListAddTask.tsx b/components/project/sectionListAddTask.tsx index a403412..345a159 100644 --- a/components/project/sectionListAddTask.tsx +++ b/components/project/sectionListAddTask.tsx @@ -10,7 +10,7 @@ import ItemSectionTanggalTugas from "../itemSectionTanggalTugas"; import MenuItemRow from "../menuItemRow"; import Text from "../Text"; -export default function SectionListAddTask() { +export default function SectionListAddTask({ showTitle = true }: { showTitle?: boolean }) { const { colors } = useTheme(); const taskCreate = useSelector((state: any) => state.taskCreate) const [select, setSelect] = useState(null) @@ -22,39 +22,32 @@ export default function SectionListAddTask() { setModal(false) } + const items = taskCreate.map((item: { status: number; title: string; dateStart: string; dateEnd: string; }, index: Key | null | undefined) => ( + { + setSelect(index) + setModal(true) + }} + /> + )) + return ( <> - { - taskCreate.length > 0 - && + {taskCreate.length > 0 && ( <> - - - Tanggal & Tugas - - { - taskCreate.map((item: { status: number; title: string; dateStart: string; dateEnd: string; }, index: Key | null | undefined) => { - return ( - { - setSelect(index) - setModal(true) - }} - /> - ); - }) - } - - + {showTitle ? ( + + Tanggal & Tugas + {items} + + ) : ( + {items} + )} + } @@ -64,7 +57,7 @@ export default function SectionListAddTask() { - } + )} ) } \ No newline at end of file diff --git a/constants/Styles.ts b/constants/Styles.ts index 6348a68..976a1aa 100644 --- a/constants/Styles.ts +++ b/constants/Styles.ts @@ -891,6 +891,31 @@ const Styles = StyleSheet.create({ alignItems: 'center', gap: 10, }, + sectionActionRow: { + flexDirection: 'row', + alignItems: 'center', + gap: 10, + }, + sectionBadge: { + borderRadius: 10, + paddingHorizontal: 8, + paddingVertical: 2, + }, + positionBadge: { + borderRadius: 20, + paddingHorizontal: 8, + paddingVertical: 3, + }, + listItemCard: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: 'transparent', + borderRadius: 10, + borderWidth: 1, + paddingHorizontal: 12, + paddingVertical: 10, + gap: 12, + }, flex1: { flex: 1 },