- tambah komponen ModalRiwayatApproval dan ModalTolakApproval - update itemSectionTanggalTugas untuk mendukung status menunggu persetujuan - update sectionTanggalTugas (project) dan sectionTanggalTugasTask (divisi) dengan alur approval lengkap - tambah API approval project task dan division task di lib/api.ts - tambah toggle approver di headerMemberDetail dan tampilkan badge approver di detail member - update carouselHome untuk dispatch isApprover ke Redux - update drawerBottom untuk mendukung scroll pada modal - ganti label 'Belum dimulai' menjadi 'Belum ada tugas yang diselesaikan'
88 lines
3.1 KiB
TypeScript
88 lines
3.1 KiB
TypeScript
import Styles from "@/constants/Styles";
|
|
import { useTheme } from "@/providers/ThemeProvider";
|
|
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
|
import { useEffect, useRef } from "react";
|
|
import { Animated, View } from "react-native";
|
|
import Text from "./Text";
|
|
|
|
type Props = {
|
|
progress: number
|
|
doneCount?: number
|
|
totalCount?: number
|
|
}
|
|
|
|
export default function SectionProgress({ progress, doneCount, totalCount }: Props) {
|
|
const { colors } = useTheme();
|
|
const animatedWidth = useRef(new Animated.Value(0)).current;
|
|
|
|
const progressColor = colors.tabActive;
|
|
|
|
const statusLabel = progress === 100
|
|
? 'Selesai'
|
|
: progress > 0
|
|
? 'Sedang berlangsung'
|
|
: 'Belum ada tugas yang diselesaikan';
|
|
|
|
useEffect(() => {
|
|
animatedWidth.setValue(0);
|
|
Animated.timing(animatedWidth, {
|
|
toValue: progress,
|
|
duration: 900,
|
|
useNativeDriver: false,
|
|
}).start();
|
|
}, [progress]);
|
|
|
|
return (
|
|
<View style={[
|
|
Styles.wrapPaper,
|
|
Styles.mb15,
|
|
Styles.sectionCard,
|
|
{ backgroundColor: colors.card, borderColor: progressColor + '30' },
|
|
]}>
|
|
<View style={Styles.sectionHeaderRow}>
|
|
<View style={Styles.flex1}>
|
|
<View style={Styles.rowItemsCenter}>
|
|
<View style={[Styles.sectionIconBox, Styles.mr10, { backgroundColor: progressColor + '22' }]}>
|
|
<MaterialCommunityIcons name="chart-line" size={18} color={progressColor} />
|
|
</View>
|
|
<Text style={[Styles.textDefaultSemiBold, { color: colors.text }]}>
|
|
Kemajuan Kegiatan
|
|
</Text>
|
|
</View>
|
|
<Text style={[Styles.textMediumNormal, { color: colors.dimmed, marginLeft: 42 }]}>
|
|
{statusLabel}
|
|
</Text>
|
|
</View>
|
|
|
|
<View style={Styles.badgeCol}>
|
|
<View style={[Styles.progressBadge, { backgroundColor: progressColor + '18', borderColor: progressColor + '45' }]}>
|
|
<Text style={[Styles.textProgressPercent, { color: progressColor }]}>
|
|
{progress}%
|
|
</Text>
|
|
</View>
|
|
{totalCount !== undefined && doneCount !== undefined && (
|
|
<View style={[Styles.taskCountBadge, { backgroundColor: progressColor + '18' }]}>
|
|
<Text style={[Styles.textSmallSemiBold, { color: progressColor }]}>
|
|
{doneCount}/{totalCount} tugas
|
|
</Text>
|
|
</View>
|
|
)}
|
|
</View>
|
|
</View>
|
|
|
|
<View style={[Styles.progressTrack, { backgroundColor: colors.icon + '20' }]}>
|
|
<Animated.View style={[
|
|
Styles.progressFill,
|
|
{
|
|
backgroundColor: progressColor,
|
|
width: animatedWidth.interpolate({
|
|
inputRange: [0, 100],
|
|
outputRange: ['0%', '100%'],
|
|
}),
|
|
},
|
|
]} />
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|