feat: redesign section progress, report, link, file, dan cancel pada project & division/task

- SectionProgress: progress bar animated, badge persentase, label status, task count
- SectionReport: header ikon, left accent border, TextExpandable dengan label Indonesia
- SectionLink: tap langsung buka URL, ikon per domain, long press untuk hapus
- SectionFile: icon container konsisten 30×30 di semua section
- SectionCancel: card subtle dengan warna error, konsisten dengan visual language baru
- TextExpandable: fix bug show/hide tidak muncul setelah content diupdate
- Tambah 14 style class baru di Styles.ts untuk menggantikan inline style
- Terapkan semua perubahan ke fitur division/task
- Fix menu "Edit Tugas" di sectionTanggalTugasTask yang terpotong karena overflow

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 16:22:52 +08:00
parent eccfe29387
commit b61cd51628
16 changed files with 736 additions and 510 deletions

View File

@@ -1,20 +1,19 @@
import Styles from "@/constants/Styles";
import { apiDeleteLinkTask, apiGetTaskOne } from "@/lib/api";
import { urlCompleted } from "@/lib/fun_urlCompleted";
import { setUpdateTask } from "@/lib/taskUpdate";
import { useAuthSession } from "@/providers/AuthProvider";
import { useTheme } from "@/providers/ThemeProvider";
import { Feather, Ionicons } from "@expo/vector-icons";
import { Ionicons } from "@expo/vector-icons";
import { useLocalSearchParams } from "expo-router";
import { useEffect, useState } from "react";
import { Linking, View } from "react-native";
import { View } from "react-native";
import Toast from "react-native-toast-message";
import { useDispatch, useSelector } from "react-redux";
import ModalConfirmation from "../ModalConfirmation";
import BorderBottomItem from "../borderBottomItem";
import DrawerBottom from "../drawerBottom";
import MenuItemRow from "../menuItemRow";
import Text from "../Text";
import ItemSectionLink from "../project/itemSectionLink";
type Props = {
id: string
@@ -62,84 +61,60 @@ export default function SectionLinkTask({ refreshing, isMemberDivision }: { refr
} else {
Toast.show({ type: 'small', text1: response.message, })
}
} catch (error : any ) {
} catch (error: any) {
console.error(error);
const message = error?.response?.data?.message || "Gagal menghapus link"
Toast.show({ type: 'small', text1: message })
} finally {
setModal(false)
}
}
if (data.length === 0) return null;
const canDelete = (entityUser.role !== "user" && entityUser.role !== "coadmin") || isMemberDivision;
return (
<>
{
data.length > 0 &&
<>
<View style={[Styles.mb15]}>
<Text style={[Styles.textDefaultSemiBold, Styles.mv05]}>Link</Text>
<View style={[Styles.wrapPaper, { backgroundColor: colors.card, borderColor: colors.background }]}>
{
data.map((item, index) => {
return (
<BorderBottomItem
key={index}
borderType="all"
icon={<Feather name="link" size={25} color={colors.text} />}
title={item.link}
titleWeight="normal"
onPress={() => { setSelectLink(item); setModal(true) }}
/>
)
})
}
</View>
</View>
<View style={[Styles.mb15]}>
<Text style={[Styles.textDefaultSemiBold, Styles.mv05]}>Link</Text>
<View>
{data.map((item, index) => (
<ItemSectionLink
key={index}
link={item.link}
canDelete={canDelete}
onLongPress={() => { setSelectLink(item); setModal(true) }}
/>
))}
</View>
</View>
<DrawerBottom animation="slide" isVisible={isModal} setVisible={setModal} title="Menu">
<View style={Styles.rowItemsCenter}>
<MenuItemRow
icon={<Feather name="external-link" color={colors.text} size={25} />}
title="Buka Link"
onPress={() => {
Linking.openURL(urlCompleted(String(selectLink?.link)))
}}
/>
{
(entityUser.role != "user" && entityUser.role != "coadmin") || isMemberDivision
?
<MenuItemRow
icon={<Ionicons name="trash-outline" color={colors.text} size={25} />}
title="Hapus"
onPress={() => {
setModal(false)
setTimeout(() => {
setShowDeleteModal(true)
}, 600)
}}
/>
:
<></>
}
</View>
</DrawerBottom>
<ModalConfirmation
visible={showDeleteModal}
title="Konfirmasi"
message="Apakah Anda yakin ingin menghapus link ini? Link yang dihapus tidak dapat dikembalikan"
onConfirm={() => {
setShowDeleteModal(false)
handleDelete()
<DrawerBottom animation="slide" isVisible={isModal} setVisible={setModal} title="Menu">
<View style={Styles.rowItemsCenter}>
<MenuItemRow
icon={<Ionicons name="trash-outline" color={colors.text} size={25} />}
title="Hapus Link"
onPress={() => {
setModal(false)
setTimeout(() => setShowDeleteModal(true), 600)
}}
onCancel={() => setShowDeleteModal(false)}
confirmText="Hapus"
cancelText="Batal"
/>
</>
}
</View>
</DrawerBottom>
<ModalConfirmation
visible={showDeleteModal}
title="Konfirmasi"
message="Apakah Anda yakin ingin menghapus link ini? Link yang dihapus tidak dapat dikembalikan"
onConfirm={() => {
setShowDeleteModal(false)
handleDelete()
}}
onCancel={() => setShowDeleteModal(false)}
confirmText="Hapus"
cancelText="Batal"
/>
</>
)
}
}