upd: project

Deskripsi;
- hapus detail project task
- edit detail project task
- fix tambah detail project task

No Issues
This commit is contained in:
amel
2025-05-13 11:52:43 +08:00
parent a9368e3e32
commit f7fac510ec
4 changed files with 174 additions and 43 deletions

View File

@@ -68,7 +68,7 @@ export default function ProjectAddTask() {
async function handleCreate() { async function handleCreate() {
try { try {
const hasil = await decryptToken(String(token?.current)); const hasil = await decryptToken(String(token?.current));
const response = await apiCreateProjectTask({ data: { name: title, dateStart: new Date(from), dateEnd: new Date(to), user: hasil }, id }); const response = await apiCreateProjectTask({ data: { name: title, dateStart: dayjs(range.startDate).format("YYYY-MM-DD"), dateEnd: dayjs(range.endDate).format("YYYY-MM-DD"), user: hasil }, id });
if (response.success) { if (response.success) {
dispatch(setUpdateProject({ ...update, task: !update.task, progress: !update.progress })) dispatch(setUpdateProject({ ...update, task: !update.task, progress: !update.progress }))
ToastAndroid.show("Berhasil menambah data", ToastAndroid.SHORT); ToastAndroid.show("Berhasil menambah data", ToastAndroid.SHORT);

View File

@@ -2,22 +2,102 @@ import ButtonBackHeader from "@/components/buttonBackHeader";
import ButtonSaveHeader from "@/components/buttonSaveHeader"; import ButtonSaveHeader from "@/components/buttonSaveHeader";
import { InputForm } from "@/components/inputForm"; import { InputForm } from "@/components/inputForm";
import Styles from "@/constants/Styles"; import Styles from "@/constants/Styles";
import { apiEditProjectTask, apiGetProjectTask } from "@/lib/api";
import { setUpdateProject } from "@/lib/projectUpdate";
import { useAuthSession } from "@/providers/AuthProvider";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { router, Stack, useLocalSearchParams } from "expo-router"; import { router, Stack, useLocalSearchParams } from "expo-router";
import { useState } from "react"; import { useEffect, useState } from "react";
import { SafeAreaView, ScrollView, Text, ToastAndroid, View } from "react-native"; import { SafeAreaView, ScrollView, Text, ToastAndroid, View } from "react-native";
import DateTimePicker, { DateType, getDefaultStyles } from "react-native-ui-datepicker"; import DateTimePicker, { DateType, getDefaultStyles } from "react-native-ui-datepicker";
import { useDispatch, useSelector } from "react-redux";
export default function UpdateProjectTask() { export default function UpdateProjectTask() {
const { detail } = useLocalSearchParams() const dispatch = useDispatch()
const update = useSelector((state: any) => state.projectUpdate)
const { token, decryptToken } = useAuthSession();
const { detail } = useLocalSearchParams<{ detail: string }>();
const [range, setRange] = useState<{ startDate: DateType; endDate: DateType; }>({ startDate: undefined, endDate: undefined }); const [range, setRange] = useState<{ startDate: DateType; endDate: DateType; }>({ startDate: undefined, endDate: undefined });
const defaultStyles = getDefaultStyles() const defaultStyles = getDefaultStyles()
const [month, setMonth] = useState<any>()
const [year, setYear] = useState<any>()
const [loading, setLoading] = useState(true)
const [disableBtn, setDisableBtn] = useState(false)
const [title, setTitle] = useState('')
const [error, setError] = useState({
startDate: false,
endDate: false,
title: false,
})
const from = range.startDate const from = range.startDate
? dayjs(range.startDate).format('MMM DD, YYYY') ? dayjs(range.startDate).format("DD-MM-YYYY")
: ''; : '';
const to = range.endDate ? dayjs(range.endDate).format('MMM DD, YYYY') : ''; const to = range.endDate ? dayjs(range.endDate).format("DD-MM-YYYY") : '';
async function handleLoad() {
try {
setLoading(true)
const hasil = await decryptToken(String(token?.current));
const response = await apiGetProjectTask({
user: hasil,
id: detail,
});
setTitle(response.data.title)
setRange({
startDate: new Date(response.data.dateStart),
endDate: new Date(response.data.dateEnd),
})
setMonth(new Date(response.data.dateStart).getMonth())
setYear(new Date(response.data.dateStart).getFullYear())
} catch (error) {
console.error(error);
} finally {
setLoading(false)
}
}
useEffect(() => {
handleLoad()
}, [])
async function handleEdit() {
try {
const hasil = await decryptToken(String(token?.current));
const response = await apiEditProjectTask({ data: { title, dateStart: dayjs(range.startDate).format("YYYY-MM-DD"), dateEnd: dayjs(range.endDate).format("YYYY-MM-DD"), user: hasil }, id: detail });
if (response.success) {
dispatch(setUpdateProject({ ...update, task: !update.task, progress: !update.progress }))
ToastAndroid.show("Berhasil mengubah data", ToastAndroid.SHORT);
router.back();
}
} catch (error) {
console.error(error);
}
}
function checkAll() {
if (from == "" || to == "" || title == "" || title == "null" || error.startDate || error.endDate || error.title) {
setDisableBtn(true)
} else {
setDisableBtn(false)
}
}
function onValidation(cat: string, val: string) {
if (cat == "title") {
setTitle(val)
if (val == "" || val == "null") {
setError(error => ({ ...error, title: true }))
} else {
setError(error => ({ ...error, title: false }))
}
}
}
useEffect(() => {
checkAll()
}, [from, to, title, error])
return ( return (
<SafeAreaView> <SafeAreaView>
@@ -26,43 +106,68 @@ export default function UpdateProjectTask() {
headerLeft: () => <ButtonBackHeader onPress={() => { router.back() }} />, headerLeft: () => <ButtonBackHeader onPress={() => { router.back() }} />,
headerTitle: 'Edit Tanggal dan Tugas', headerTitle: 'Edit Tanggal dan Tugas',
headerTitleAlign: 'center', headerTitleAlign: 'center',
headerRight: () => <ButtonSaveHeader category="create" onPress={() => { headerRight: () => <ButtonSaveHeader
ToastAndroid.show('Berhasil menambah data', ToastAndroid.SHORT) disable={disableBtn}
router.push('/project/4324') category="update"
}} /> onPress={() => {handleEdit()}}
/>
}} }}
/> />
<ScrollView> <ScrollView>
<View style={[Styles.p15, Styles.mb100]}> <View style={[Styles.p15, Styles.mb100]}>
<View style={[Styles.wrapPaper, Styles.p10]}> <View style={[Styles.wrapPaper, Styles.p10]}>
<DateTimePicker {
mode="range" !loading
startDate={range.startDate} &&
endDate={range.endDate} <DateTimePicker
onChange={(param) => setRange(param)} mode="range"
// styles={defaultStyles} startDate={range.startDate}
styles={{ endDate={range.endDate}
selected: Styles.selectedDate, onChange={(param) => setRange(param)}
selected_label: Styles.cWhite, // styles={defaultStyles}
range_fill: Styles.selectRangeDate, month={month}
}} year={year}
/> styles={{
selected: Styles.selectedDate,
selected_label: Styles.cWhite,
range_fill: Styles.selectRangeDate,
}}
/>
}
</View> </View>
<View style={[Styles.rowSpaceBetween, Styles.mv10]}> <View style={[Styles.mv10]}>
<View style={[{ width: '48%' }]}> <View style={[Styles.rowSpaceBetween]}>
<Text style={[Styles.mb05]}>Tanggal Mulai <Text style={Styles.cError}>*</Text></Text> <View style={[{ width: '48%' }]}>
<View style={[Styles.wrapPaper, Styles.p10]}> <Text style={[Styles.mb05]}>Tanggal Mulai <Text style={Styles.cError}>*</Text></Text>
<Text style={{ textAlign: 'center' }}>{from}</Text> <View style={[Styles.wrapPaper, Styles.p10]}>
</View> <Text style={{ textAlign: 'center' }}>{from}</Text>
</View> </View>
<View style={[{ width: '48%' }]}> </View>
<Text style={[Styles.mb05]}>Tanggal Berakhir <Text style={Styles.cError}>*</Text></Text> <View style={[{ width: '48%' }]}>
<View style={[Styles.wrapPaper, Styles.p10]}> <Text style={[Styles.mb05]}>Tanggal Berakhir <Text style={Styles.cError}>*</Text></Text>
<Text style={{ textAlign: 'center' }}>{to}</Text> <View style={[Styles.wrapPaper, Styles.p10]}>
<Text style={{ textAlign: 'center' }}>{to}</Text>
</View>
</View> </View>
</View> </View>
{
(error.endDate || error.startDate) && <Text style={[Styles.textInformation, Styles.cError, Styles.mt05]}>Tanggal tidak boleh kosong</Text>
}
</View> </View>
<InputForm label="Judul Tugas" type="default" placeholder="Judul Tugas" required bg="white" /> <InputForm
label="Judul Tugas"
type="default"
placeholder="Judul Tugas"
required
bg="white"
value={title}
error={error.title}
errorText="Judul tidak boleh kosong"
onChange={(e) => {
onValidation("title", e)
}}
/>
</View> </View>
</ScrollView> </ScrollView>
</SafeAreaView> </SafeAreaView>

View File

@@ -1,5 +1,5 @@
import Styles from "@/constants/Styles"; import Styles from "@/constants/Styles";
import { apiGetProjectOne, apiUpdateStatusProjectTask } from "@/lib/api"; import { apiDeleteProjectTask, apiGetProjectOne, apiUpdateStatusProjectTask } from "@/lib/api";
import { setUpdateProject } from "@/lib/projectUpdate"; import { setUpdateProject } from "@/lib/projectUpdate";
import { useAuthSession } from "@/providers/AuthProvider"; import { useAuthSession } from "@/providers/AuthProvider";
import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons";
@@ -74,6 +74,23 @@ export default function SectionTanggalTugasProject() {
} }
} }
async function handleDelete() {
try {
const hasil = await decryptToken(String(token?.current));
const response = await apiDeleteProjectTask({
user: hasil,
idProject: id,
}, tugas.id);
if (response.success) {
dispatch(setUpdateProject({ ...update, progress: !update.progress, task: !update.task }))
setModal(false);
ToastAndroid.show("Berhasil menghapus data", ToastAndroid.SHORT);
}
} catch (error) {
console.error(error);
}
}
return ( return (
<> <>
<View style={[Styles.mb15, Styles.mt10]}> <View style={[Styles.mb15, Styles.mt10]}>
@@ -140,7 +157,7 @@ export default function SectionTanggalTugasProject() {
title="Edit Tugas" title="Edit Tugas"
onPress={() => { onPress={() => {
setModal(false); setModal(false);
router.push(`/project/update/124`); router.push(`/project/update/${tugas.id}`);
}} }}
/> />
@@ -151,13 +168,7 @@ export default function SectionTanggalTugasProject() {
AlertKonfirmasi({ AlertKonfirmasi({
title: "Konfirmasi", title: "Konfirmasi",
desc: "Apakah anda yakin ingin menghapus data ini?", desc: "Apakah anda yakin ingin menghapus data ini?",
onPress: () => { onPress: () => { handleDelete() },
setModal(false);
ToastAndroid.show(
"Berhasil menghapus data",
ToastAndroid.SHORT
);
},
}); });
}} }}
/> />

View File

@@ -248,7 +248,7 @@ export const apiEditProject = async (data: { name: string, user: string }, id: s
return response.data; return response.data;
}; };
export const apiCreateProjectTask = async ({ data, id }: { data: { name: string, dateStart: Date, user: string, dateEnd: Date }, id: string }) => { export const apiCreateProjectTask = async ({ data, id }: { data: { name: string, dateStart: string, user: string, dateEnd: string }, id: string }) => {
const response = await api.post(`/mobile/project/${id}`, data) const response = await api.post(`/mobile/project/${id}`, data)
return response.data; return response.data;
}; };
@@ -261,4 +261,19 @@ export const apiCancelProject = async (data: { user: string, reason: string }, i
export const apiUpdateStatusProjectTask = async (data: { user: string, status: number, idProject: string }, id: string) => { export const apiUpdateStatusProjectTask = async (data: { user: string, status: number, idProject: string }, id: string) => {
const response = await api.put(`mobile/project/detail/${id}`, data) const response = await api.put(`mobile/project/detail/${id}`, data)
return response.data return response.data
};
export const apiDeleteProjectTask = async (data: { user: string, idProject: string }, id: string) => {
const response = await api.delete(`mobile/project/detail/${id}`, { data })
return response.data
};
export const apiGetProjectTask = async ({ user, id }: { user: string, id: string }) => {
const response = await api.get(`mobile/project/detail/${id}?user=${user}`);
return response.data;
};
export const apiEditProjectTask = async ({ data, id }: { data: { title: string, dateStart: string, user: string, dateEnd: string }, id: string }) => {
const response = await api.post(`/mobile/project/detail/${id}`, data)
return response.data;
}; };