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 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 17:10:08 +08:00
parent 11bb1ddc98
commit bdfb3a8b2b
4 changed files with 269 additions and 159 deletions

View File

@@ -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"
/>
<ButtonSelect value="Tambah Tanggal & Tugas" onPress={() => { router.push(`/division/${id}/task/create/task`); }} />
<ButtonSelect value="Upload File" onPress={pickDocumentAsync} />
<ButtonSelect value="Tambah Anggota" onPress={() => { router.push(`/division/${id}/task/create/member`); }} />
<SectionListAddTask />
{fileForm.length > 0 && (
<View style={Styles.mb15}>
<Text style={[Styles.textDefaultSemiBold, Styles.mv05]}>File</Text>
{/* Tanggal & Tugas */}
<View style={[
Styles.wrapPaper, Styles.mb15, Styles.sectionCard,
{ backgroundColor: colors.card, borderColor: colors.icon + '18' }
]}>
<Pressable
onPress={() => router.push(`/division/${id}/task/create/task`)}
style={[Styles.sectionActionRow, { marginBottom: taskCreate.length > 0 ? 12 : 0 }]}
>
<View style={[Styles.sectionIconBox, { backgroundColor: colors.tabActive + '18' }]}>
<MaterialCommunityIcons name="calendar-check-outline" size={18} color={colors.tabActive} />
</View>
<View style={Styles.flex1}>
<Text style={[Styles.textDefaultSemiBold, { color: colors.text }]}>Tanggal & Tugas</Text>
{taskCreate.length === 0 && (
<Text style={[Styles.textMediumNormal, { color: colors.dimmed }]}>Belum ada tugas ditambahkan</Text>
)}
</View>
{taskCreate.length > 0 && (
<View style={[Styles.sectionBadge, { backgroundColor: colors.tabActive + '18' }]}>
<Text style={[Styles.textSmallSemiBold, { color: colors.tabActive }]}>{taskCreate.length} tugas</Text>
</View>
)}
<MaterialCommunityIcons name="chevron-right" size={18} color={colors.dimmed} />
</Pressable>
{taskCreate.length > 0 && <SectionListAddTask showTitle={false} />}
</View>
{/* File */}
<View style={[
Styles.wrapPaper, Styles.mb15, Styles.sectionCard,
{ backgroundColor: colors.card, borderColor: colors.icon + '18' }
]}>
<Pressable
onPress={pickDocumentAsync}
style={[Styles.sectionActionRow, { marginBottom: fileForm.length > 0 ? 12 : 0 }]}
>
<View style={[Styles.sectionIconBox, { backgroundColor: colors.icon + '15' }]}>
<MaterialCommunityIcons name="paperclip" size={18} color={colors.dimmed} />
</View>
<View style={Styles.flex1}>
<Text style={[Styles.textDefaultSemiBold, { color: colors.text }]}>File</Text>
{fileForm.length === 0 && (
<Text style={[Styles.textMediumNormal, { color: colors.dimmed }]}>Opsional ketuk untuk upload</Text>
)}
</View>
{fileForm.length > 0 && (
<View style={[Styles.sectionBadge, { backgroundColor: colors.dimmed + '18' }]}>
<Text style={[Styles.textSmallSemiBold, { color: colors.dimmed }]}>{fileForm.length} file</Text>
</View>
)}
<MaterialCommunityIcons name="chevron-right" size={18} color={colors.dimmed} />
</Pressable>
{fileForm.length > 0 && (
<View style={Styles.fileGrid}>
{fileForm.map((item, index) => {
const ext = item.name.split('.').pop()?.toLowerCase() ?? ''
@@ -204,64 +251,66 @@ export default function CreateTaskDivision() {
<Pressable
key={index}
onPress={() => { setIndexDelFile(index); setModal(true) }}
style={[Styles.fileCard, { backgroundColor: colors.card, borderColor: colors.icon + '18' }]}
style={[Styles.fileCard, { backgroundColor: 'transparent', borderColor: colors.icon + '18' }]}
>
<View style={[Styles.sectionIconBox, { backgroundColor: iconColor + '20' }]}>
<MaterialCommunityIcons name={iconName} size={18} color={iconColor} />
</View>
<View style={Styles.flex1}>
<Text style={Styles.textDefault} numberOfLines={1}>{baseName}</Text>
<Text style={[Styles.textSmallSemiBold, { color: colors.dimmed }]}>
{ext.toUpperCase()}
</Text>
<Text style={[Styles.textSmallSemiBold, { color: colors.dimmed }]}>{ext.toUpperCase()}</Text>
</View>
</Pressable>
)
})}
</View>
</View>
)}
{entitiesMember.length > 0 && (
<View style={Styles.mb15}>
<View style={[Styles.rowSpaceBetween, Styles.mv05]}>
<Text style={Styles.textDefaultSemiBold}>Anggota</Text>
<Text style={[Styles.textDefault, { color: colors.dimmed }]}>{entitiesMember.length} orang</Text>
)}
</View>
{/* Anggota */}
<View style={[
Styles.wrapPaper, Styles.mb15, Styles.sectionCard,
{ backgroundColor: colors.card, borderColor: colors.icon + '18' }
]}>
<Pressable
onPress={() => router.push(`/division/${id}/task/create/member`)}
style={[Styles.sectionActionRow, { marginBottom: entitiesMember.length > 0 ? 12 : 0 }]}
>
<View style={[Styles.sectionIconBox, { backgroundColor: colors.tabActive + '18' }]}>
<MaterialCommunityIcons name="account-group-outline" size={18} color={colors.tabActive} />
</View>
<View style={Styles.flex1}>
<Text style={[Styles.textDefaultSemiBold, { color: colors.text }]}>Anggota</Text>
{entitiesMember.length === 0 && (
<Text style={[Styles.textMediumNormal, { color: colors.dimmed }]}>Belum ada anggota dipilih</Text>
)}
</View>
{entitiesMember.length > 0 && (
<View style={[Styles.sectionBadge, { backgroundColor: colors.tabActive + '18' }]}>
<Text style={[Styles.textSmallSemiBold, { color: colors.tabActive }]}>{entitiesMember.length} orang</Text>
</View>
)}
<MaterialCommunityIcons name="chevron-right" size={18} color={colors.dimmed} />
</Pressable>
{entitiesMember.length > 0 && (
<View style={{ gap: 6 }}>
{entitiesMember.map((item: { img: any; name: any; position?: string }, index: any) => (
<View
key={index}
style={{
flexDirection: 'row',
alignItems: 'center',
backgroundColor: colors.card,
borderRadius: 10,
borderWidth: 1,
borderColor: colors.icon + '18',
paddingHorizontal: 12,
paddingVertical: 10,
gap: 12,
}}
style={[Styles.listItemCard, { borderColor: colors.icon + '18' }]}
>
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} size="xs" />
<Text style={[Styles.textDefault, Styles.flex1, { color: colors.text }]} numberOfLines={1}>{item.name}</Text>
{item.position && (
<View style={{
backgroundColor: colors.dimmed + '15',
borderRadius: 20,
paddingHorizontal: 8,
paddingVertical: 3,
}}>
<Text style={[Styles.textSmallSemiBold, { color: colors.dimmed }]} numberOfLines={1}>
{item.position}
</Text>
<View style={[Styles.positionBadge, { backgroundColor: colors.dimmed + '15' }]}>
<Text style={[Styles.textSmallSemiBold, { color: colors.dimmed }]} numberOfLines={1}>{item.position}</Text>
</View>
)}
</View>
))}
</View>
</View>
)}
)}
</View>
</View>
</ScrollView>