Compare commits
8 Commits
amalia/19-
...
amalia/22-
| Author | SHA1 | Date | |
|---|---|---|---|
| 1dc69b64d2 | |||
| a409bfef2f | |||
| 99c81f6f0d | |||
| 4e6b27bbcc | |||
| 6a97ae76fc | |||
| 40c1fa4ed2 | |||
| e2c8f1db39 | |||
| 72fa18565d |
@@ -65,8 +65,9 @@ export default {
|
||||
},
|
||||
URL_API: process.env.URL_API,
|
||||
URL_OTP: process.env.URL_OTP,
|
||||
URL_STORAGE : process.env.URL_STORAGE,
|
||||
URL_FIREBASE_DB : process.env.URL_FIREBASE_DB
|
||||
URL_STORAGE: process.env.URL_STORAGE,
|
||||
URL_FIREBASE_DB: process.env.URL_FIREBASE_DB,
|
||||
PASS_ENC: process.env.PASS_ENC
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@ import ButtonBackHeader from "@/components/buttonBackHeader";
|
||||
import ButtonSaveHeader from "@/components/buttonSaveHeader";
|
||||
import { InputForm } from "@/components/inputForm";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiEditBanner, apiGetBanner, apiGetBannerOne } from "@/lib/api";
|
||||
import { setEntities } from "@/lib/bannerSlice";
|
||||
@@ -50,7 +51,7 @@ export default function EditBanner() {
|
||||
const hasil = await decryptToken(String(token?.current));
|
||||
const data = await apiGetBannerOne({ user: hasil, id });
|
||||
setSelectedImage({
|
||||
uri: `https://wibu-storage.wibudev.com/api/files/${data.data.image}`,
|
||||
uri: `${ConstEnv.url_storage}/files/${data.data.image}`,
|
||||
});
|
||||
setTitle(data.data.title);
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import ButtonBackHeader from "@/components/buttonBackHeader"
|
||||
import DrawerBottom from "@/components/drawerBottom"
|
||||
import MenuItemRow from "@/components/menuItemRow"
|
||||
import ModalLoading from "@/components/modalLoading"
|
||||
import { ConstEnv } from "@/constants/ConstEnv"
|
||||
import Styles from "@/constants/Styles"
|
||||
import { apiDeleteBanner, apiGetBanner } from "@/lib/api"
|
||||
import { setEntities } from "@/lib/bannerSlice"
|
||||
@@ -20,7 +21,6 @@ import * as mime from 'react-native-mime-types'
|
||||
import Toast from "react-native-toast-message"
|
||||
import { useDispatch, useSelector } from "react-redux"
|
||||
|
||||
|
||||
type Props = {
|
||||
id: string
|
||||
title: string
|
||||
@@ -71,7 +71,7 @@ export default function BannerList() {
|
||||
const openFile = () => {
|
||||
setModal(false)
|
||||
setLoadingOpen(true)
|
||||
let remoteUrl = 'https://wibu-storage.wibudev.com/api/files/' + selectFile?.image;
|
||||
let remoteUrl = ConstEnv.url_storage + '/files/' + selectFile?.image;
|
||||
const fileName = selectFile?.title + '.' + selectFile?.extension;
|
||||
let localPath = `${FileSystem.documentDirectory}/${fileName}`;
|
||||
const mimeType = mime.lookup(fileName)
|
||||
@@ -112,7 +112,7 @@ export default function BannerList() {
|
||||
}}
|
||||
/>
|
||||
<ModalLoading isVisible={loadingOpen} setVisible={setLoadingOpen} />
|
||||
<ScrollView
|
||||
<ScrollView
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
@@ -133,7 +133,7 @@ export default function BannerList() {
|
||||
borderType="all"
|
||||
icon={
|
||||
<Image
|
||||
source={{ uri: `https://wibu-storage.wibudev.com/api/files/${index.image}` }}
|
||||
source={{ uri: `${ConstEnv.url_storage}/files/${index.image}` }}
|
||||
style={[Styles.imgListBanner]}
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import Skeleton from "@/components/skeleton";
|
||||
import SkeletonContent from "@/components/skeletonContent";
|
||||
import Text from '@/components/Text';
|
||||
import { ColorsStatus } from "@/constants/ColorsStatus";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiGetDiscussionGeneralOne, apiSendDiscussionGeneralCommentar } from "@/lib/api";
|
||||
import { getDB } from "@/lib/firebaseDatabase";
|
||||
@@ -184,7 +185,7 @@ export default function DetailDiscussionGeneral() {
|
||||
key={i}
|
||||
borderType="bottom"
|
||||
icon={
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} size="xs" />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} size="xs" />
|
||||
}
|
||||
title={item.username}
|
||||
rightTopInfo={item.createdAt}
|
||||
|
||||
@@ -4,6 +4,7 @@ import ImageUser from "@/components/imageNew";
|
||||
import ImageWithLabel from "@/components/imageWithLabel";
|
||||
import InputSearch from "@/components/inputSearch";
|
||||
import Text from '@/components/Text';
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiAddMemberDiscussionGeneral, apiGetDiscussionGeneralOne, apiGetUser } from "@/lib/api";
|
||||
import { setUpdateDiscussionGeneralDetail } from "@/lib/discussionGeneralDetail";
|
||||
@@ -121,7 +122,7 @@ export default function AddMemberDiscussionDetail() {
|
||||
<ImageWithLabel
|
||||
key={index}
|
||||
label={item.name}
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
onClick={() => onChoose(item.idUser, item.name, item.img)}
|
||||
/>
|
||||
))
|
||||
@@ -147,7 +148,7 @@ export default function AddMemberDiscussionDetail() {
|
||||
}}
|
||||
>
|
||||
<View style={[Styles.rowItemsCenter]}>
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} border />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} border />
|
||||
<View style={[Styles.ml10]}>
|
||||
<Text style={[Styles.textDefault]}>{item.name}</Text>
|
||||
{
|
||||
@@ -156,7 +157,7 @@ export default function AddMemberDiscussionDetail() {
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
selectMember.some((i: any) => i.idUser == item.id) && <AntDesign name="check" size={20} color={'black'}/>
|
||||
selectMember.some((i: any) => i.idUser == item.id) && <AntDesign name="check" size={20} color={'black'} />
|
||||
}
|
||||
</Pressable>
|
||||
)
|
||||
|
||||
@@ -7,6 +7,7 @@ import { InputForm } from "@/components/inputForm";
|
||||
import ModalSelect from "@/components/modalSelect";
|
||||
import SelectForm from "@/components/selectForm";
|
||||
import Text from '@/components/Text';
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiCreateDiscussionGeneral } from "@/lib/api";
|
||||
import { setUpdateDiscussionGeneralDetail } from "@/lib/discussionGeneralDetail";
|
||||
@@ -215,7 +216,7 @@ export default function CreateDiscussionGeneral() {
|
||||
key={index}
|
||||
borderType="bottom"
|
||||
icon={
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} size="sm" />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} size="sm" />
|
||||
}
|
||||
title={item.name}
|
||||
/>
|
||||
|
||||
@@ -7,6 +7,7 @@ import MenuItemRow from "@/components/menuItemRow";
|
||||
import SkeletonTwoItem from "@/components/skeletonTwoItem";
|
||||
import Text from '@/components/Text';
|
||||
import { ColorsStatus } from "@/constants/ColorsStatus";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiDeleteMemberDiscussionGeneral, apiGetDiscussionGeneralOne } from "@/lib/api";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
@@ -109,7 +110,7 @@ export default function MemberDiscussionDetail() {
|
||||
key={index}
|
||||
borderType="bottom"
|
||||
icon={
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} size="sm" />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} size="sm" />
|
||||
}
|
||||
title={item.name}
|
||||
onPress={() => {
|
||||
|
||||
@@ -4,6 +4,7 @@ import ImageUser from "@/components/imageNew";
|
||||
import ImageWithLabel from "@/components/imageWithLabel";
|
||||
import InputSearch from "@/components/inputSearch";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiAddMemberCalendar, apiGetCalendarOne, apiGetDivisionMember } from "@/lib/api";
|
||||
import { setUpdateCalendar } from "@/lib/calendarUpdate";
|
||||
@@ -128,7 +129,7 @@ export default function AddMemberCalendarEvent() {
|
||||
<ImageWithLabel
|
||||
key={index}
|
||||
label={item.name}
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
onClick={() => onChoose(item.idUser, item.name, item.img)}
|
||||
/>
|
||||
))
|
||||
@@ -154,7 +155,7 @@ export default function AddMemberCalendarEvent() {
|
||||
}}
|
||||
>
|
||||
<View style={[Styles.rowItemsCenter]}>
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} border />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} border />
|
||||
<View style={[Styles.ml10, { width: '80%' }]}>
|
||||
<Text numberOfLines={1} ellipsizeMode="tail" style={[Styles.textDefault]}>{item.name}</Text>
|
||||
{
|
||||
@@ -163,7 +164,7 @@ export default function AddMemberCalendarEvent() {
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
selectMember.some((i: any) => i.idUser == item.id) && <AntDesign name="check" size={20} color={'black'}/>
|
||||
selectMember.some((i: any) => i.idUser == item.id) && <AntDesign name="check" size={20} color={'black'} />
|
||||
}
|
||||
</Pressable>
|
||||
)
|
||||
|
||||
@@ -7,6 +7,7 @@ import ImageUser from "@/components/imageNew"
|
||||
import MenuItemRow from "@/components/menuItemRow"
|
||||
import Skeleton from "@/components/skeleton"
|
||||
import Text from "@/components/Text"
|
||||
import { ConstEnv } from "@/constants/ConstEnv"
|
||||
import Styles from "@/constants/Styles"
|
||||
import { apiDeleteCalendarMember, apiGetCalendarOne, apiGetDivisionOneFeature } from "@/lib/api"
|
||||
import { setUpdateCalendar } from "@/lib/calendarUpdate"
|
||||
@@ -70,7 +71,7 @@ export default function DetailEventCalendar() {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleLoad(loading:boolean) {
|
||||
async function handleLoad(loading: boolean) {
|
||||
try {
|
||||
setLoading(loading)
|
||||
const hasil = await decryptToken(String(token?.current));
|
||||
@@ -241,7 +242,7 @@ export default function DetailEventCalendar() {
|
||||
<BorderBottomItem
|
||||
key={index}
|
||||
borderType="bottom"
|
||||
icon={<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} />}
|
||||
icon={<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} />}
|
||||
title={item.name}
|
||||
subtitle={item.email}
|
||||
onPress={() => {
|
||||
|
||||
@@ -4,6 +4,7 @@ import ImageUser from "@/components/imageNew";
|
||||
import ImageWithLabel from "@/components/imageWithLabel";
|
||||
import InputSearch from "@/components/inputSearch";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiCreateCalendar, apiGetDivisionMember } from "@/lib/api";
|
||||
import { setFormCreateCalendar } from "@/lib/calendarCreate";
|
||||
@@ -117,7 +118,7 @@ export default function CreateCalendarAddMember() {
|
||||
<ImageWithLabel
|
||||
key={index}
|
||||
label={item.name}
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
onClick={() => onChoose(item.idUser, item.name, item.img)}
|
||||
/>
|
||||
))
|
||||
@@ -140,13 +141,13 @@ export default function CreateCalendarAddMember() {
|
||||
onPress={() => { onChoose(item.idUser, item.name, item.img) }}
|
||||
>
|
||||
<View style={[Styles.rowItemsCenter, Styles.w70]}>
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} border />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} border />
|
||||
<View style={[Styles.ml10]}>
|
||||
<Text style={[Styles.textDefault]} numberOfLines={1} ellipsizeMode="tail">{item.name}</Text>
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
selectMember.some((i: any) => i.idUser == item.idUser) && <AntDesign name="check" size={20} color={'black'}/>
|
||||
selectMember.some((i: any) => i.idUser == item.idUser) && <AntDesign name="check" size={20} color={'black'} />
|
||||
}
|
||||
</Pressable>
|
||||
)
|
||||
|
||||
@@ -7,6 +7,7 @@ import LabelStatus from "@/components/labelStatus";
|
||||
import Skeleton from "@/components/skeleton";
|
||||
import SkeletonContent from "@/components/skeletonContent";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import {
|
||||
apiGetDiscussionOne,
|
||||
@@ -220,7 +221,7 @@ export default function DiscussionDetail() {
|
||||
borderType="bottom"
|
||||
icon={
|
||||
<ImageUser
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${data?.user_img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${data?.user_img}`}
|
||||
size="sm"
|
||||
/>
|
||||
}
|
||||
@@ -267,7 +268,7 @@ export default function DiscussionDetail() {
|
||||
borderType="bottom"
|
||||
icon={
|
||||
<ImageUser
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
size="xs"
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import InputSearch from "@/components/inputSearch";
|
||||
import LabelStatus from "@/components/labelStatus";
|
||||
import SkeletonContent from "@/components/skeletonContent";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiGetDiscussion } from "@/lib/api";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
@@ -141,7 +142,7 @@ export default function DiscussionDivision() {
|
||||
onPress={() => { router.push(`./discussion/${item.id}`) }}
|
||||
borderType="bottom"
|
||||
icon={
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} size="sm" />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} size="sm" />
|
||||
}
|
||||
title={item.user_name}
|
||||
subtitle={
|
||||
@@ -170,33 +171,8 @@ export default function DiscussionDivision() {
|
||||
/>
|
||||
}
|
||||
/>
|
||||
// data.map((item, index) => (
|
||||
// <BorderBottomItem
|
||||
// key={index}
|
||||
// onPress={() => { router.push(`./discussion/${item.id}`) }}
|
||||
// borderType="bottom"
|
||||
// icon={
|
||||
// <ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} size="sm" />
|
||||
// }
|
||||
// title={item.user_name}
|
||||
// subtitle={
|
||||
// active == "true" ? item.status == 1 ? <LabelStatus category='success' text='BUKA' size="small" /> : <LabelStatus category='error' text='TUTUP' size="small" /> : <></>
|
||||
// }
|
||||
// rightTopInfo={item.createdAt}
|
||||
// desc={item.desc}
|
||||
// leftBottomInfo={
|
||||
// <View style={[Styles.rowItemsCenter]}>
|
||||
// <Ionicons name="chatbox-ellipses-outline" size={18} color="grey" style={Styles.mr05} />
|
||||
// <Text style={[Styles.textInformation, Styles.cGray, Styles.mb05]}>Diskusikan</Text>
|
||||
// </View>
|
||||
// }
|
||||
// rightBottomInfo={item.total_komentar + ' Komentar'}
|
||||
// />
|
||||
// ))
|
||||
:
|
||||
(
|
||||
<Text style={[Styles.textDefault, Styles.cGray, Styles.mv10, { textAlign: "center" }]}>Tidak ada diskusi</Text>
|
||||
)
|
||||
(<Text style={[Styles.textDefault, Styles.cGray, Styles.mv10, { textAlign: "center" }]}>Tidak ada diskusi</Text>)
|
||||
}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -13,6 +13,7 @@ import ModalSelectMultiple from "@/components/modalSelectMultiple";
|
||||
import Skeleton from "@/components/skeleton";
|
||||
import Text from "@/components/Text";
|
||||
import { ColorsStatus } from "@/constants/ColorsStatus";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import {
|
||||
apiDocumentDelete,
|
||||
@@ -268,7 +269,7 @@ export default function DocumentDivision() {
|
||||
|
||||
const openFile = (item: Props) => {
|
||||
if (Platform.OS == 'android') setLoadingOpen(true)
|
||||
let remoteUrl = 'https://wibu-storage.wibudev.com/api/files/' + item.idStorage;
|
||||
let remoteUrl = ConstEnv.url_storage + '/files/' + item.idStorage;
|
||||
const fileName = item.name + '.' + item.extension;
|
||||
let localPath = `${FileSystem.documentDirectory}/${fileName}`;
|
||||
const mimeType = mime.lookup(fileName)
|
||||
@@ -440,20 +441,6 @@ export default function DocumentDivision() {
|
||||
{(selectedFiles.length > 0 || dariSelectAll) && (
|
||||
<View style={[ColorsStatus.primary, Styles.bottomMenuSelectDocument]}>
|
||||
<View style={[Styles.rowItemsCenter, { justifyContent: "center" }]}>
|
||||
{/* <MenuItemRow
|
||||
icon={
|
||||
<MaterialCommunityIcons
|
||||
name="download-outline"
|
||||
color="white"
|
||||
size={25}
|
||||
/>
|
||||
}
|
||||
title="Unduh"
|
||||
onPress={() => { }}
|
||||
column="many"
|
||||
color="white"
|
||||
disabled={selectedFiles.length == 0 || !copyAllowed}
|
||||
/> */}
|
||||
<MenuItemRow
|
||||
icon={
|
||||
<MaterialCommunityIcons
|
||||
|
||||
@@ -4,6 +4,7 @@ import ImageUser from "@/components/imageNew";
|
||||
import ImageWithLabel from "@/components/imageWithLabel";
|
||||
import InputSearch from "@/components/inputSearch";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiAddMemberTask, apiGetDivisionMember, apiGetTaskOne } from "@/lib/api";
|
||||
import { setUpdateTask } from "@/lib/taskUpdate";
|
||||
@@ -123,7 +124,7 @@ export default function AddMemberTask() {
|
||||
<ImageWithLabel
|
||||
key={index}
|
||||
label={item.name}
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
onClick={() => onChoose(item.idUser, item.name, item.img)}
|
||||
/>
|
||||
))
|
||||
@@ -149,7 +150,7 @@ export default function AddMemberTask() {
|
||||
}}
|
||||
>
|
||||
<View style={[Styles.rowItemsCenter, Styles.w80]}>
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} border />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} border />
|
||||
<View style={[Styles.ml10]}>
|
||||
<Text style={[Styles.textDefault]} numberOfLines={1}>{item.name}</Text>
|
||||
{
|
||||
@@ -158,7 +159,7 @@ export default function AddMemberTask() {
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
selectMember.some((i: any) => i.idUser == item.idUser) && <AntDesign name="check" size={20} color={'black'}/>
|
||||
selectMember.some((i: any) => i.idUser == item.idUser) && <AntDesign name="check" size={20} color={'black'} />
|
||||
}
|
||||
</Pressable>
|
||||
)
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
import ButtonBackHeader from "@/components/buttonBackHeader";
|
||||
import ButtonSaveHeader from "@/components/buttonSaveHeader";
|
||||
import { InputForm } from "@/components/inputForm";
|
||||
import ModalAddDetailTugasTask from "@/components/task/modalAddDetailTugasTask";
|
||||
import Text from "@/components/Text";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiCreateTaskTugas } from "@/lib/api";
|
||||
import { formatDateOnly } from "@/lib/fun_formatDateOnly";
|
||||
import { getDatesInRange } from "@/lib/fun_getDatesInRange";
|
||||
import { setUpdateTask } from "@/lib/taskUpdate";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import dayjs from "dayjs";
|
||||
import { useHeaderHeight } from '@react-navigation/elements';
|
||||
import { router, Stack, useLocalSearchParams } from "expo-router";
|
||||
import 'intl';
|
||||
import 'intl/locale-data/jsonp/id';
|
||||
import moment from "moment";
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
KeyboardAvoidingView, Platform, SafeAreaView,
|
||||
KeyboardAvoidingView, Platform, Pressable, SafeAreaView,
|
||||
ScrollView,
|
||||
View
|
||||
} from "react-native";
|
||||
import Toast from "react-native-toast-message";
|
||||
import DateTimePicker, { DateType } from "react-native-ui-datepicker";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useHeaderHeight } from '@react-navigation/elements';
|
||||
|
||||
export default function TaskDivisionAddTask() {
|
||||
const { token, decryptToken } = useAuthSession();
|
||||
@@ -38,12 +41,13 @@ export default function TaskDivisionAddTask() {
|
||||
endDate: false,
|
||||
title: false,
|
||||
});
|
||||
const [title, setTitle] = useState("");
|
||||
const [title, setTitle] = useState("")
|
||||
const [dataDetail, setDataDetail] = useState<any>([])
|
||||
const [modalDetail, setModalDetail] = useState(false)
|
||||
const [dsbButton, setDsbButton] = useState(true)
|
||||
|
||||
const from = range.startDate
|
||||
? dayjs(range.startDate).format("DD-MM-YYYY")
|
||||
: "";
|
||||
const to = range.endDate ? dayjs(range.endDate).format("DD-MM-YYYY") : "";
|
||||
const from = formatDateOnly(range.startDate);
|
||||
const to = formatDateOnly(range.endDate);
|
||||
|
||||
function checkAll() {
|
||||
if (
|
||||
@@ -72,21 +76,49 @@ export default function TaskDivisionAddTask() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function checkButton() {
|
||||
if (range.startDate == null || range.endDate == null || range.startDate == undefined || range.endDate == undefined) {
|
||||
setDsbButton(true)
|
||||
setDataDetail([])
|
||||
} else {
|
||||
setDsbButton(false)
|
||||
const awal = formatDateOnly(range.startDate, "YYYY-MM-DD")
|
||||
const akhir = formatDateOnly(range.endDate, "YYYY-MM-DD")
|
||||
const datanya = getDatesInRange(awal, akhir)
|
||||
setDataDetail(datanya.map((item: any) => ({
|
||||
date: item,
|
||||
timeStart: null,
|
||||
timeEnd: null,
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkAll();
|
||||
}, [from, to, title, error]);
|
||||
|
||||
useEffect(() => {
|
||||
checkButton()
|
||||
}, [range])
|
||||
|
||||
async function handleCreate() {
|
||||
try {
|
||||
setLoading(true)
|
||||
const dataDetailFix = dataDetail.map((item: any) => ({
|
||||
date: moment(item.date, "DD-MM-YYYY").format("YYYY-MM-DD"),
|
||||
timeStart: item.timeStart,
|
||||
timeEnd: item.timeEnd,
|
||||
}))
|
||||
const hasil = await decryptToken(String(token?.current));
|
||||
const response = await apiCreateTaskTugas({
|
||||
data: {
|
||||
title,
|
||||
dateStart: dayjs(range.startDate).format("YYYY-MM-DD"),
|
||||
dateEnd: dayjs(range.endDate).format("YYYY-MM-DD"),
|
||||
dateStart: formatDateOnly(range.startDate, "YYYY-MM-DD"),
|
||||
dateEnd: formatDateOnly(range.endDate, "YYYY-MM-DD"),
|
||||
user: hasil,
|
||||
idDivision: id,
|
||||
dataDetail: dataDetailFix,
|
||||
},
|
||||
id: detail,
|
||||
});
|
||||
@@ -177,6 +209,13 @@ export default function TaskDivisionAddTask() {
|
||||
{
|
||||
(error.endDate || error.startDate) && <Text style={[Styles.textInformation, Styles.cError, Styles.mt05]}>Tanggal tidak boleh kosong</Text>
|
||||
}
|
||||
<Pressable
|
||||
style={[Styles.btnTab, Styles.btnLainnya, dsbButton && Styles.btnDisabled]}
|
||||
disabled={dsbButton}
|
||||
onPress={() => { setModalDetail(true) }}
|
||||
>
|
||||
<Text style={[dsbButton ? Styles.cGray : Styles.cWhite]}>Detail</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
<InputForm
|
||||
label="Judul Tugas"
|
||||
@@ -194,7 +233,14 @@ export default function TaskDivisionAddTask() {
|
||||
</View>
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
|
||||
<ModalAddDetailTugasTask
|
||||
isVisible={modalDetail}
|
||||
setVisible={setModalDetail}
|
||||
dataTanggal={dataDetail}
|
||||
onSubmit={(data) => {
|
||||
setDataDetail(data)
|
||||
}}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import MenuItemRow from "@/components/menuItemRow";
|
||||
import ModalSelect from "@/components/modalSelect";
|
||||
import SectionListAddTask from "@/components/project/sectionListAddTask";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiCreateTask } from "@/lib/api";
|
||||
import { setMemberChoose } from "@/lib/memberChoose";
|
||||
@@ -189,7 +190,7 @@ export default function CreateTaskDivision() {
|
||||
borderType="bottom"
|
||||
icon={
|
||||
<ImageUser
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
size="sm"
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import ImageUser from "@/components/imageNew";
|
||||
import ImageWithLabel from "@/components/imageWithLabel";
|
||||
import InputSearch from "@/components/inputSearch";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiGetDivisionMember } from "@/lib/api";
|
||||
import { setMemberChoose } from "@/lib/memberChoose";
|
||||
@@ -93,7 +94,7 @@ export default function AddMemberCreateTask() {
|
||||
<ImageWithLabel
|
||||
key={index}
|
||||
label={item.name}
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
onClick={() => onChoose(item.idUser, item.name, item.img)}
|
||||
/>
|
||||
))
|
||||
@@ -118,13 +119,13 @@ export default function AddMemberCreateTask() {
|
||||
}}
|
||||
>
|
||||
<View style={[Styles.rowItemsCenter]}>
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} border />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} border />
|
||||
<View style={[Styles.ml10]}>
|
||||
<Text style={[Styles.textDefault]}>{item.name}</Text>
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
selectMember.some((i: any) => i.idUser == item.idUser) && <AntDesign name="check" size={20} color={'black'}/>
|
||||
selectMember.some((i: any) => i.idUser == item.idUser) && <AntDesign name="check" size={20} color={'black'} />
|
||||
}
|
||||
</Pressable>
|
||||
)
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
import ButtonBackHeader from "@/components/buttonBackHeader";
|
||||
import ButtonSaveHeader from "@/components/buttonSaveHeader";
|
||||
import { InputForm } from "@/components/inputForm";
|
||||
import ModalAddDetailTugasTask from "@/components/task/modalAddDetailTugasTask";
|
||||
import Text from "@/components/Text";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { formatDateOnly } from "@/lib/fun_formatDateOnly";
|
||||
import { getDatesInRange } from "@/lib/fun_getDatesInRange";
|
||||
import { setTaskCreate } from "@/lib/taskCreate";
|
||||
import dayjs from "dayjs";
|
||||
import { useHeaderHeight } from '@react-navigation/elements';
|
||||
import { router, Stack } from "expo-router";
|
||||
import 'intl';
|
||||
import 'intl/locale-data/jsonp/id';
|
||||
import moment from "moment";
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
Pressable,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
View
|
||||
@@ -20,7 +25,6 @@ import DateTimePicker, {
|
||||
DateType
|
||||
} from "react-native-ui-datepicker";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useHeaderHeight } from '@react-navigation/elements';
|
||||
|
||||
export default function CreateTaskAddTugas() {
|
||||
const headerHeight = useHeaderHeight();
|
||||
@@ -37,11 +41,12 @@ export default function CreateTaskAddTugas() {
|
||||
})
|
||||
const [title, setTitle] = useState('');
|
||||
const taskCreate = useSelector((state: any) => state.taskCreate)
|
||||
const [dsbButton, setDsbButton] = useState(true)
|
||||
const [dataDetail, setDataDetail] = useState<any>([])
|
||||
const [modalDetail, setModalDetail] = useState(false)
|
||||
|
||||
const from = range.startDate
|
||||
? dayjs(range.startDate).format("DD-MM-YYYY")
|
||||
: "";
|
||||
const to = range.endDate ? dayjs(range.endDate).format("DD-MM-YYYY") : "";
|
||||
const from = formatDateOnly(range.startDate, "DD-MM-YYYY")
|
||||
const to = formatDateOnly(range.endDate, "DD-MM-YYYY")
|
||||
|
||||
function checkAll() {
|
||||
if (from == "" || to == "" || title == "" || title == "null" || error.startDate || error.endDate || error.title) {
|
||||
@@ -62,18 +67,45 @@ export default function CreateTaskAddTugas() {
|
||||
}
|
||||
}
|
||||
|
||||
function checkButton() {
|
||||
if (range.startDate == null || range.endDate == null || range.startDate == undefined || range.endDate == undefined) {
|
||||
setDsbButton(true)
|
||||
setDataDetail([])
|
||||
} else {
|
||||
setDsbButton(false)
|
||||
const awal = formatDateOnly(range.startDate, "YYYY-MM-DD")
|
||||
const akhir = formatDateOnly(range.endDate, "YYYY-MM-DD")
|
||||
const datanya = getDatesInRange(awal, akhir)
|
||||
setDataDetail(datanya.map((item: any) => ({
|
||||
date: item,
|
||||
timeStart: null,
|
||||
timeEnd: null,
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkAll()
|
||||
}, [from, to, title, error])
|
||||
|
||||
useEffect(() => {
|
||||
checkButton()
|
||||
}, [range])
|
||||
|
||||
async function handleCreate() {
|
||||
try {
|
||||
const dataDetailFix = dataDetail.map((item: any) => ({
|
||||
date: moment(item.date, "DD-MM-YYYY").format("YYYY-MM-DD"),
|
||||
timeStart: item.timeStart,
|
||||
timeEnd: item.timeEnd,
|
||||
}))
|
||||
dispatch(setTaskCreate([...taskCreate, {
|
||||
title: title,
|
||||
dateStart: from,
|
||||
dateEnd: to,
|
||||
dateStartFix: dayjs(range.startDate).format("YYYY-MM-DD"),
|
||||
dateEndFix: dayjs(range.endDate).format("YYYY-MM-DD"),
|
||||
dateStartFix: formatDateOnly(range.startDate, "YYYY-MM-DD"),
|
||||
dateEndFix: formatDateOnly(range.endDate, "YYYY-MM-DD"),
|
||||
dataDetail: dataDetailFix
|
||||
}]))
|
||||
router.back();
|
||||
} catch (error) {
|
||||
@@ -151,6 +183,13 @@ export default function CreateTaskAddTugas() {
|
||||
{
|
||||
(error.endDate || error.startDate) && <Text style={[Styles.textInformation, Styles.cError, Styles.mt05]}>Tanggal tidak boleh kosong</Text>
|
||||
}
|
||||
<Pressable
|
||||
style={[Styles.btnTab, Styles.btnLainnya, dsbButton && Styles.btnDisabled]}
|
||||
disabled={dsbButton}
|
||||
onPress={() => { setModalDetail(true) }}
|
||||
>
|
||||
<Text style={[dsbButton ? Styles.cGray : Styles.cWhite]}>Detail</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
<InputForm
|
||||
label="Judul Tugas"
|
||||
@@ -168,6 +207,14 @@ export default function CreateTaskAddTugas() {
|
||||
</View>
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
<ModalAddDetailTugasTask
|
||||
isVisible={modalDetail}
|
||||
setVisible={setModalDetail}
|
||||
dataTanggal={dataDetail}
|
||||
onSubmit={(data) => {
|
||||
setDataDetail(data)
|
||||
}}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
import ButtonBackHeader from "@/components/buttonBackHeader";
|
||||
import ButtonSaveHeader from "@/components/buttonSaveHeader";
|
||||
import { InputForm } from "@/components/inputForm";
|
||||
import ModalAddDetailTugasTask from "@/components/task/modalAddDetailTugasTask";
|
||||
import Text from "@/components/Text";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiEditTaskTugas, apiGetTaskTugas } from "@/lib/api";
|
||||
import { formatDateOnly } from "@/lib/fun_formatDateOnly";
|
||||
import { getDatesInRange } from "@/lib/fun_getDatesInRange";
|
||||
import { setUpdateTask } from "@/lib/taskUpdate";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import { useHeaderHeight } from '@react-navigation/elements';
|
||||
import dayjs from "dayjs";
|
||||
import { router, Stack, useLocalSearchParams } from "expo-router";
|
||||
import 'intl';
|
||||
import 'intl/locale-data/jsonp/id';
|
||||
import moment from "moment";
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
Pressable,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
View
|
||||
@@ -38,6 +42,9 @@ export default function UpdateProjectTaskDivision() {
|
||||
const [year, setYear] = useState<any>();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [disableBtn, setDisableBtn] = useState(false);
|
||||
const [dataDetail, setDataDetail] = useState<any>([])
|
||||
const [modalDetail, setModalDetail] = useState(false)
|
||||
const [dsbButton, setDsbButton] = useState(true)
|
||||
const [title, setTitle] = useState("");
|
||||
const [error, setError] = useState({
|
||||
startDate: false,
|
||||
@@ -45,10 +52,8 @@ export default function UpdateProjectTaskDivision() {
|
||||
title: false,
|
||||
});
|
||||
|
||||
const from = range.startDate
|
||||
? dayjs(range.startDate).format("DD-MM-YYYY")
|
||||
: "";
|
||||
const to = range.endDate ? dayjs(range.endDate).format("DD-MM-YYYY") : "";
|
||||
const from = formatDateOnly(range.startDate);
|
||||
const to = formatDateOnly(range.endDate);
|
||||
|
||||
async function handleLoad() {
|
||||
try {
|
||||
@@ -65,6 +70,22 @@ export default function UpdateProjectTaskDivision() {
|
||||
});
|
||||
setMonth(new Date(response.data.dateStart).getMonth());
|
||||
setYear(new Date(response.data.dateStart).getFullYear());
|
||||
|
||||
const response2 = await apiGetTaskTugas({
|
||||
user: hasil,
|
||||
id: detail,
|
||||
cat: "detailTask"
|
||||
});
|
||||
if (response2.data.length == 0) {
|
||||
const datanya = getDatesInRange(response.data.dateStart, response.data.dateEnd)
|
||||
setDataDetail(datanya.map((item: any) => ({
|
||||
date: item,
|
||||
timeStart: null,
|
||||
timeEnd: null,
|
||||
})))
|
||||
} else {
|
||||
setDataDetail(response2.data)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
@@ -79,8 +100,22 @@ export default function UpdateProjectTaskDivision() {
|
||||
async function handleEdit() {
|
||||
try {
|
||||
setLoadingSubmit(true)
|
||||
const dataDetailFix = dataDetail.map((item: any) => ({
|
||||
date: moment(item.date, "DD-MM-YYYY").format("YYYY-MM-DD"),
|
||||
timeStart: item.timeStart,
|
||||
timeEnd: item.timeEnd,
|
||||
}))
|
||||
const hasil = await decryptToken(String(token?.current));
|
||||
const response = await apiEditTaskTugas({ data: { title, dateStart: dayjs(range.startDate).format("YYYY-MM-DD"), dateEnd: dayjs(range.endDate).format("YYYY-MM-DD"), user: hasil }, id: detail });
|
||||
const response = await apiEditTaskTugas({
|
||||
data: {
|
||||
title,
|
||||
dateStart: formatDateOnly(range.startDate, "YYYY-MM-DD"),
|
||||
dateEnd: formatDateOnly(range.endDate, "YYYY-MM-DD"),
|
||||
user: hasil,
|
||||
dataDetail: dataDetailFix
|
||||
},
|
||||
id: detail
|
||||
});
|
||||
if (response.success) {
|
||||
dispatch(setUpdateTask({ ...update, task: !update.task }))
|
||||
Toast.show({ type: 'small', text1: 'Berhasil mengubah data', })
|
||||
@@ -123,10 +158,33 @@ export default function UpdateProjectTaskDivision() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function checkButton() {
|
||||
if (range.startDate == null || range.endDate == null || range.startDate == undefined || range.endDate == undefined) {
|
||||
setDsbButton(true)
|
||||
setDataDetail([])
|
||||
} else {
|
||||
setDsbButton(false)
|
||||
const awal = formatDateOnly(range.startDate, "YYYY-MM-DD")
|
||||
const akhir = formatDateOnly(range.endDate, "YYYY-MM-DD")
|
||||
const datanya = getDatesInRange(awal, akhir)
|
||||
setDataDetail(datanya.map((item: any) => ({
|
||||
date: item,
|
||||
timeStart: null,
|
||||
timeEnd: null,
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkAll();
|
||||
}, [from, to, title, error]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
checkButton()
|
||||
}, [range])
|
||||
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<Stack.Screen
|
||||
@@ -205,6 +263,13 @@ export default function UpdateProjectTaskDivision() {
|
||||
Tanggal tidak boleh kosong
|
||||
</Text>
|
||||
)}
|
||||
<Pressable
|
||||
style={[Styles.btnTab, Styles.btnLainnya, dsbButton && Styles.btnDisabled]}
|
||||
disabled={dsbButton}
|
||||
onPress={() => { setModalDetail(true) }}
|
||||
>
|
||||
<Text style={[dsbButton ? Styles.cGray : Styles.cWhite]}>Detail</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
<InputForm
|
||||
label="Judul Tugas"
|
||||
@@ -222,7 +287,14 @@ export default function UpdateProjectTaskDivision() {
|
||||
</View>
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
|
||||
<ModalAddDetailTugasTask
|
||||
isVisible={modalDetail}
|
||||
setVisible={setModalDetail}
|
||||
dataTanggal={dataDetail}
|
||||
onSubmit={(data) => {
|
||||
setDataDetail(data)
|
||||
}}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import ImageUser from "@/components/imageNew";
|
||||
import ImageWithLabel from "@/components/imageWithLabel";
|
||||
import InputSearch from "@/components/inputSearch";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiAddMemberDivision, apiGetDivisionOneDetail, apiGetUser } from "@/lib/api";
|
||||
import { setUpdateDivision } from "@/lib/divisionUpdate";
|
||||
@@ -124,7 +125,7 @@ export default function AddMemberDivision() {
|
||||
<ImageWithLabel
|
||||
key={index}
|
||||
label={item.name}
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
onClick={() => onChoose(item.idUser, item.name, item.img)}
|
||||
/>
|
||||
))
|
||||
@@ -150,7 +151,7 @@ export default function AddMemberDivision() {
|
||||
}}
|
||||
>
|
||||
<View style={[Styles.rowItemsCenter]}>
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} border />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} border />
|
||||
<View style={[Styles.ml10]}>
|
||||
<Text style={[Styles.textDefault]} numberOfLines={1} ellipsizeMode="tail">{item.name}</Text>
|
||||
{
|
||||
@@ -159,7 +160,7 @@ export default function AddMemberDivision() {
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
selectMember.some((i: any) => i.idUser == item.id) && <AntDesign name="check" size={20} color={'black'}/>
|
||||
selectMember.some((i: any) => i.idUser == item.id) && <AntDesign name="check" size={20} color={'black'} />
|
||||
}
|
||||
</Pressable>
|
||||
)
|
||||
|
||||
@@ -8,6 +8,7 @@ import SectionCancel from "@/components/sectionCancel"
|
||||
import Skeleton from "@/components/skeleton"
|
||||
import SkeletonTwoItem from "@/components/skeletonTwoItem"
|
||||
import { ColorsStatus } from "@/constants/ColorsStatus"
|
||||
import { ConstEnv } from "@/constants/ConstEnv"
|
||||
import Styles from "@/constants/Styles"
|
||||
import { apiDeleteMemberDivision, apiGetDivisionOneDetail, apiUpdateStatusAdminDivision } from "@/lib/api"
|
||||
import { useAuthSession } from "@/providers/AuthProvider"
|
||||
@@ -188,7 +189,7 @@ export default function InformationDivision() {
|
||||
borderType="bottom"
|
||||
onPress={() => { dataDetail?.isActive && handleChooseMember(item) }}
|
||||
icon={
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} size="sm" />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} size="sm" />
|
||||
}
|
||||
title={item.name}
|
||||
rightTopInfo={item.isAdmin ? "Admin" : "Anggota"}
|
||||
|
||||
@@ -2,6 +2,7 @@ import ButtonBackHeader from "@/components/buttonBackHeader";
|
||||
import ButtonSaveHeader from "@/components/buttonSaveHeader";
|
||||
import ImageUser from "@/components/imageNew";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiCreateDivision } from "@/lib/api";
|
||||
import { setFormCreateDivision } from "@/lib/divisionCreate";
|
||||
@@ -103,7 +104,7 @@ export default function CreateDivisionAddAdmin() {
|
||||
}}
|
||||
>
|
||||
<View style={[Styles.rowItemsCenter, Styles.w70]}>
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} border />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} border />
|
||||
<View style={[Styles.ml10]}>
|
||||
<Text style={[Styles.textDefault]} numberOfLines={1} ellipsizeMode="tail">{item.name}</Text>
|
||||
{
|
||||
@@ -112,7 +113,7 @@ export default function CreateDivisionAddAdmin() {
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
selectMember.some((i: any) => i == item.idUser) && <AntDesign name="check" size={20} color={'black'}/>
|
||||
selectMember.some((i: any) => i == item.idUser) && <AntDesign name="check" size={20} color={'black'} />
|
||||
}
|
||||
</Pressable>
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import ImageUser from "@/components/imageNew";
|
||||
import ImageWithLabel from "@/components/imageWithLabel";
|
||||
import InputSearch from "@/components/inputSearch";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiGetUser } from "@/lib/api";
|
||||
import { setFormCreateDivision } from "@/lib/divisionCreate";
|
||||
@@ -86,7 +87,7 @@ export default function CreateDivisionAddMember() {
|
||||
<ImageWithLabel
|
||||
key={index}
|
||||
label={item.name}
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
onClick={() => onChoose(item.idUser, item.name, item.img)}
|
||||
/>
|
||||
))
|
||||
@@ -112,7 +113,7 @@ export default function CreateDivisionAddMember() {
|
||||
}}
|
||||
>
|
||||
<View style={[Styles.rowItemsCenter, Styles.w70]}>
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} border />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} border />
|
||||
<View style={[Styles.ml10]}>
|
||||
<Text style={[Styles.textDefault]} numberOfLines={1} ellipsizeMode="tail">{item.name}</Text>
|
||||
{
|
||||
@@ -121,7 +122,7 @@ export default function CreateDivisionAddMember() {
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
selectMember.some((i: any) => i.idUser == item.id) && <AntDesign name="check" size={20} color={'black'}/>
|
||||
selectMember.some((i: any) => i.idUser == item.id) && <AntDesign name="check" size={20} color={'black'} />
|
||||
}
|
||||
</Pressable>
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import { InputForm } from "@/components/inputForm";
|
||||
import ModalSelect from "@/components/modalSelect";
|
||||
import SelectForm from "@/components/selectForm";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiEditProfile, apiGetProfile } from "@/lib/api";
|
||||
import { setEntities } from "@/lib/entitiesSlice";
|
||||
@@ -252,7 +253,7 @@ export default function EditProfile() {
|
||||
) : (
|
||||
<Pressable onPress={pickImageAsync}>
|
||||
<Image
|
||||
source={errorImg ? require("../../assets/images/user.jpg") : { uri: `https://wibu-storage.wibudev.com/api/files/${data?.img}` }}
|
||||
source={errorImg ? require("../../assets/images/user.jpg") : { uri: `${ConstEnv.url_storage}/files/${data?.img}` }}
|
||||
style={[Styles.userProfileBig]}
|
||||
onError={() => { setErrorImg(true) }}
|
||||
/>
|
||||
|
||||
@@ -5,6 +5,7 @@ import LabelStatus from "@/components/labelStatus";
|
||||
import HeaderRightMemberDetail from "@/components/member/headerMemberDetail";
|
||||
import Skeleton from "@/components/skeleton";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import { valueRoleUser } from "@/constants/RoleUser";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiGetProfile } from "@/lib/api";
|
||||
@@ -93,7 +94,7 @@ export default function MemberDetail() {
|
||||
</>
|
||||
:
|
||||
<>
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${data?.img}`} size="lg" />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${data?.img}`} size="lg" />
|
||||
<Text style={[Styles.textSubtitle, Styles.cWhite, Styles.mt10]}>{data?.name}</Text>
|
||||
<Text style={[Styles.textMediumNormal, Styles.cWhite]}>{data?.role}</Text>
|
||||
</>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { InputForm } from "@/components/inputForm";
|
||||
import ModalSelect from "@/components/modalSelect";
|
||||
import SelectForm from "@/components/selectForm";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiEditUser, apiGetProfile } from "@/lib/api";
|
||||
import { setUpdateMember } from "@/lib/memberSlice";
|
||||
@@ -83,7 +84,7 @@ export default function EditMember() {
|
||||
try {
|
||||
const response = await apiGetProfile({ id: id });
|
||||
setData(response.data);
|
||||
setSelectedImage({ uri: `https://wibu-storage.wibudev.com/api/files/${response.data.img}`, });
|
||||
setSelectedImage({ uri: `${ConstEnv.url_storage}/files/${response.data.img}`, });
|
||||
setChoosePosition({
|
||||
val: response.data.idPosition,
|
||||
label: response.data.position,
|
||||
@@ -270,7 +271,7 @@ export default function EditMember() {
|
||||
errorImg ?
|
||||
<Pressable onPress={pickImageAsync}>
|
||||
<Image
|
||||
source={errorImg ? require("../../../../assets/images/user.jpg") : { uri: `https://wibu-storage.wibudev.com/api/files/${data?.img}` }}
|
||||
source={errorImg ? require("../../../../assets/images/user.jpg") : { uri: `${ConstEnv.url_storage}/files/${data?.img}` }}
|
||||
style={[Styles.userProfileBig]}
|
||||
onError={() => { setErrorImg(true) }}
|
||||
/>
|
||||
|
||||
@@ -4,6 +4,7 @@ import ImageUser from "@/components/imageNew";
|
||||
import InputSearch from "@/components/inputSearch";
|
||||
import SkeletonTwoItem from "@/components/skeletonTwoItem";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiGetUser } from "@/lib/api";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
@@ -150,7 +151,7 @@ export default function Index() {
|
||||
onPress={() => { router.push(`/member/${item.id}`) }}
|
||||
borderType="all"
|
||||
icon={
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} />
|
||||
}
|
||||
title={item.name}
|
||||
subtitle={`${item.group} - ${item.position}`}
|
||||
|
||||
@@ -3,6 +3,7 @@ import ButtonBackHeader from "@/components/buttonBackHeader";
|
||||
import { ButtonHeader } from "@/components/buttonHeader";
|
||||
import ItemDetailMember from "@/components/itemDetailMember";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import { AntDesign } from "@expo/vector-icons";
|
||||
@@ -41,7 +42,7 @@ export default function Profile() {
|
||||
<View style={{ flexDirection: 'column' }}>
|
||||
<View style={[Styles.wrapHeadViewMember]}>
|
||||
<Image
|
||||
source={error ? require("../../assets/images/user.jpg") : { uri: `https://wibu-storage.wibudev.com/api/files/${entities.img}` }}
|
||||
source={error ? require("../../assets/images/user.jpg") : { uri: `${ConstEnv.url_storage}/files/${entities.img}` }}
|
||||
onError={() => { setError(true) }}
|
||||
style={[Styles.userProfileBig]}
|
||||
/>
|
||||
|
||||
@@ -4,6 +4,7 @@ import ImageUser from "@/components/imageNew";
|
||||
import ImageWithLabel from "@/components/imageWithLabel";
|
||||
import InputSearch from "@/components/inputSearch";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiAddMemberProject, apiGetProjectOne, apiGetUser } from "@/lib/api";
|
||||
import { setUpdateProject } from "@/lib/projectUpdate";
|
||||
@@ -122,7 +123,7 @@ export default function AddMemberProject() {
|
||||
<ImageWithLabel
|
||||
key={index}
|
||||
label={item.name}
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
onClick={() => onChoose(item.idUser, item.name, item.img)}
|
||||
/>
|
||||
))
|
||||
@@ -147,7 +148,7 @@ export default function AddMemberProject() {
|
||||
}}
|
||||
>
|
||||
<View style={[Styles.rowItemsCenter, Styles.w80]}>
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} border />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} border />
|
||||
<View style={[Styles.ml10]}>
|
||||
<Text style={[Styles.textDefault]} numberOfLines={1}>{item.name}</Text>
|
||||
{
|
||||
@@ -156,7 +157,7 @@ export default function AddMemberProject() {
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
selectMember.some((i: any) => i.idUser == item.id) && <AntDesign name="check" size={20} color={'black'}/>
|
||||
selectMember.some((i: any) => i.idUser == item.id) && <AntDesign name="check" size={20} color={'black'} />
|
||||
}
|
||||
</Pressable>
|
||||
)
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import ButtonBackHeader from "@/components/buttonBackHeader";
|
||||
import ButtonSaveHeader from "@/components/buttonSaveHeader";
|
||||
import { InputForm } from "@/components/inputForm";
|
||||
import ModalAddDetailTugasProject from "@/components/project/modalAddDetailTugasProject";
|
||||
import Text from "@/components/Text";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiCreateProjectTask } from "@/lib/api";
|
||||
import { formatDateOnly } from "@/lib/fun_formatDateOnly";
|
||||
import { getDatesInRange } from "@/lib/fun_getDatesInRange";
|
||||
import { setUpdateProject } from "@/lib/projectUpdate";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import { useHeaderHeight } from '@react-navigation/elements';
|
||||
import dayjs from "dayjs";
|
||||
import { router, Stack, useLocalSearchParams } from "expo-router";
|
||||
import 'intl';
|
||||
import 'intl/locale-data/jsonp/id';
|
||||
import moment from "moment";
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
KeyboardAvoidingView,
|
||||
@@ -31,6 +34,8 @@ export default function ProjectAddTask() {
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const dispatch = useDispatch()
|
||||
const update = useSelector((state: any) => state.projectUpdate)
|
||||
const [dataDetail, setDataDetail] = useState<any>([])
|
||||
const [modalDetail, setModalDetail] = useState(false)
|
||||
const { id } = useLocalSearchParams<{ id: string }>();
|
||||
const [disable, setDisable] = useState(true);
|
||||
const [range, setRange] = useState<{
|
||||
@@ -44,11 +49,10 @@ export default function ProjectAddTask() {
|
||||
})
|
||||
const [title, setTitle] = useState('');
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [dsbButton, setDsbButton] = useState(true)
|
||||
|
||||
const from = range.startDate
|
||||
? dayjs(range.startDate).format("DD-MM-YYYY")
|
||||
: "";
|
||||
const to = range.endDate ? dayjs(range.endDate).format("DD-MM-YYYY") : "";
|
||||
const from = formatDateOnly(range.startDate);
|
||||
const to = formatDateOnly(range.endDate);
|
||||
|
||||
function checkAll() {
|
||||
if (from == "" || to == "" || title == "" || title == "null" || error.startDate || error.endDate || error.title) {
|
||||
@@ -69,15 +73,50 @@ export default function ProjectAddTask() {
|
||||
}
|
||||
}
|
||||
|
||||
function checkButton() {
|
||||
if (range.startDate == null || range.endDate == null || range.startDate == undefined || range.endDate == undefined) {
|
||||
setDsbButton(true)
|
||||
setDataDetail([])
|
||||
} else {
|
||||
setDsbButton(false)
|
||||
const awal = formatDateOnly(range.startDate, "YYYY-MM-DD")
|
||||
const akhir = formatDateOnly(range.endDate, "YYYY-MM-DD")
|
||||
const datanya = getDatesInRange(awal, akhir)
|
||||
setDataDetail(datanya.map((item: any) => ({
|
||||
date: item,
|
||||
timeStart: null,
|
||||
timeEnd: null,
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkAll()
|
||||
}, [from, to, title, error])
|
||||
|
||||
useEffect(() => {
|
||||
checkButton()
|
||||
}, [range])
|
||||
|
||||
|
||||
async function handleCreate() {
|
||||
try {
|
||||
setLoading(true)
|
||||
const dataDetailFix = dataDetail.map((item: any) => ({
|
||||
date: moment(item.date, "DD-MM-YYYY").format("YYYY-MM-DD"),
|
||||
timeStart: item.timeStart,
|
||||
timeEnd: item.timeEnd,
|
||||
}))
|
||||
const hasil = await decryptToken(String(token?.current));
|
||||
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 });
|
||||
const response = await apiCreateProjectTask({
|
||||
data: {
|
||||
name: title,
|
||||
dateStart: formatDateOnly(range.startDate, "YYYY-MM-DD"),
|
||||
dateEnd: formatDateOnly(range.endDate, "YYYY-MM-DD"),
|
||||
user: hasil,
|
||||
dataDetail: dataDetailFix
|
||||
}, id
|
||||
});
|
||||
if (response.success) {
|
||||
dispatch(setUpdateProject({ ...update, task: !update.task, progress: !update.progress }))
|
||||
Toast.show({ type: 'small', text1: 'Berhasil menambah data', })
|
||||
@@ -126,7 +165,7 @@ export default function ProjectAddTask() {
|
||||
mode="range"
|
||||
startDate={range.startDate}
|
||||
endDate={range.endDate}
|
||||
onChange={(param) => setRange(param)}
|
||||
onChange={(param) => { setRange(param) }}
|
||||
styles={{
|
||||
selected: Styles.selectedDate,
|
||||
selected_label: Styles.cWhite,
|
||||
@@ -163,9 +202,12 @@ export default function ProjectAddTask() {
|
||||
{
|
||||
(error.endDate || error.startDate) && <Text style={[Styles.textInformation, Styles.cError, Styles.mt05]}>Tanggal tidak boleh kosong</Text>
|
||||
}
|
||||
{/* TODO */}
|
||||
<Pressable style={[Styles.btnTab, Styles.btnLainnya]}>
|
||||
<Text style={[Styles.cWhite]}>Detail</Text>
|
||||
<Pressable
|
||||
style={[Styles.btnTab, Styles.btnLainnya, dsbButton && Styles.btnDisabled]}
|
||||
disabled={dsbButton}
|
||||
onPress={() => { setModalDetail(true) }}
|
||||
>
|
||||
<Text style={[dsbButton ? Styles.cGray : Styles.cWhite]}>Detail</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
<InputForm
|
||||
@@ -184,6 +226,14 @@ export default function ProjectAddTask() {
|
||||
</View>
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
<ModalAddDetailTugasProject
|
||||
isVisible={modalDetail}
|
||||
setVisible={setModalDetail}
|
||||
dataTanggal={dataDetail}
|
||||
onSubmit={(data) => {
|
||||
setDataDetail(data)
|
||||
}}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import ModalSelect from "@/components/modalSelect";
|
||||
import SectionListAddTask from "@/components/project/sectionListAddTask";
|
||||
import SelectForm from "@/components/selectForm";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiCreateProject } from "@/lib/api";
|
||||
import { setGroupChoose } from "@/lib/groupChoose";
|
||||
@@ -251,18 +252,12 @@ export default function CreateProject() {
|
||||
onPress={() => {
|
||||
if (entityUser.role == "supadmin" || entityUser.role == "developer") {
|
||||
if (chooseGroup.val != "") {
|
||||
// setSelect(true);
|
||||
// setValSelect("member");
|
||||
router.push(`/project/create/member`);
|
||||
} else {
|
||||
Toast.show({ type: 'small', text1: "Pilih Lembaga Desa terlebih dahulu", })
|
||||
}
|
||||
} else {
|
||||
router.push(`/project/create/member`);
|
||||
// validationForm('group', userLogin.idGroup, userLogin.group);
|
||||
// setValChoose(userLogin.idGroup)
|
||||
// setSelect(true);
|
||||
// setValSelect("member");
|
||||
}
|
||||
}}
|
||||
error={error.member}
|
||||
@@ -306,7 +301,7 @@ export default function CreateProject() {
|
||||
borderType="bottom"
|
||||
icon={
|
||||
<ImageUser
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
size="sm"
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import ImageUser from "@/components/imageNew";
|
||||
import ImageWithLabel from "@/components/imageWithLabel";
|
||||
import InputSearch from "@/components/inputSearch";
|
||||
import Text from "@/components/Text";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiGetUser } from "@/lib/api";
|
||||
import { setMemberChoose } from "@/lib/memberChoose";
|
||||
@@ -100,7 +101,7 @@ export default function AddMemberCreateProject() {
|
||||
<ImageWithLabel
|
||||
key={index}
|
||||
label={item.name}
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
onClick={() => onChoose(item.idUser, item.name, item.img)}
|
||||
/>
|
||||
))
|
||||
@@ -125,7 +126,7 @@ export default function AddMemberCreateProject() {
|
||||
}}
|
||||
>
|
||||
<View style={[Styles.rowItemsCenter]}>
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} border />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} border />
|
||||
<View style={[Styles.ml10]}>
|
||||
<Text style={[Styles.textDefault]}>{item.name}</Text>
|
||||
</View>
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
import ButtonBackHeader from "@/components/buttonBackHeader";
|
||||
import ButtonSaveHeader from "@/components/buttonSaveHeader";
|
||||
import { InputForm } from "@/components/inputForm";
|
||||
import ModalAddDetailTugasProject from "@/components/project/modalAddDetailTugasProject";
|
||||
import Text from "@/components/Text";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { formatDateOnly } from "@/lib/fun_formatDateOnly";
|
||||
import { getDatesInRange } from "@/lib/fun_getDatesInRange";
|
||||
import { setTaskCreate } from "@/lib/taskCreate";
|
||||
import { useHeaderHeight } from '@react-navigation/elements';
|
||||
import dayjs from "dayjs";
|
||||
import { router, Stack } from "expo-router";
|
||||
import 'intl';
|
||||
import 'intl/locale-data/jsonp/id';
|
||||
import moment from "moment";
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
Pressable,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
View
|
||||
@@ -37,11 +41,12 @@ export default function CreateProjectAddTask() {
|
||||
})
|
||||
const [title, setTitle] = useState('');
|
||||
const taskCreate = useSelector((state: any) => state.taskCreate)
|
||||
const [dsbButton, setDsbButton] = useState(true)
|
||||
const [dataDetail, setDataDetail] = useState<any>([])
|
||||
const [modalDetail, setModalDetail] = useState(false)
|
||||
|
||||
const from = range.startDate
|
||||
? dayjs(range.startDate).format("DD-MM-YYYY")
|
||||
: "";
|
||||
const to = range.endDate ? dayjs(range.endDate).format("DD-MM-YYYY") : "";
|
||||
const from = formatDateOnly(range.startDate, "DD-MM-YYYY");
|
||||
const to = formatDateOnly(range.endDate, "DD-MM-YYYY");
|
||||
|
||||
function checkAll() {
|
||||
if (from == "" || to == "" || title == "" || title == "null" || error.startDate || error.endDate || error.title) {
|
||||
@@ -62,18 +67,45 @@ export default function CreateProjectAddTask() {
|
||||
}
|
||||
}
|
||||
|
||||
function checkButton() {
|
||||
if (range.startDate == null || range.endDate == null || range.startDate == undefined || range.endDate == undefined) {
|
||||
setDsbButton(true)
|
||||
setDataDetail([])
|
||||
} else {
|
||||
setDsbButton(false)
|
||||
const awal = formatDateOnly(range.startDate, "YYYY-MM-DD")
|
||||
const akhir = formatDateOnly(range.endDate, "YYYY-MM-DD")
|
||||
const datanya = getDatesInRange(awal, akhir)
|
||||
setDataDetail(datanya.map((item: any) => ({
|
||||
date: item,
|
||||
timeStart: null,
|
||||
timeEnd: null,
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkAll()
|
||||
}, [from, to, title, error])
|
||||
|
||||
useEffect(() => {
|
||||
checkButton()
|
||||
}, [range])
|
||||
|
||||
async function handleCreate() {
|
||||
try {
|
||||
const dataDetailFix = dataDetail.map((item: any) => ({
|
||||
date: moment(item.date, "DD-MM-YYYY").format("YYYY-MM-DD"),
|
||||
timeStart: item.timeStart,
|
||||
timeEnd: item.timeEnd,
|
||||
}))
|
||||
dispatch(setTaskCreate([...taskCreate, {
|
||||
title: title,
|
||||
dateStart: from,
|
||||
dateEnd: to,
|
||||
dateStartFix: dayjs(range.startDate).format("YYYY-MM-DD"),
|
||||
dateEndFix: dayjs(range.endDate).format("YYYY-MM-DD"),
|
||||
dateStartFix: formatDateOnly(range.startDate, "YYYY-MM-DD"),
|
||||
dateEndFix: formatDateOnly(range.endDate, "YYYY-MM-DD"),
|
||||
dataDetail: dataDetailFix
|
||||
}]))
|
||||
router.back();
|
||||
} catch (error) {
|
||||
@@ -151,6 +183,13 @@ export default function CreateProjectAddTask() {
|
||||
{
|
||||
(error.endDate || error.startDate) && <Text style={[Styles.textInformation, Styles.cError, Styles.mt05]}>Tanggal tidak boleh kosong</Text>
|
||||
}
|
||||
<Pressable
|
||||
style={[Styles.btnTab, Styles.btnLainnya, dsbButton && Styles.btnDisabled]}
|
||||
disabled={dsbButton}
|
||||
onPress={() => { setModalDetail(true) }}
|
||||
>
|
||||
<Text style={[dsbButton ? Styles.cGray : Styles.cWhite]}>Detail</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
<InputForm
|
||||
label="Judul Tugas"
|
||||
@@ -168,6 +207,14 @@ export default function CreateProjectAddTask() {
|
||||
</View>
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
<ModalAddDetailTugasProject
|
||||
isVisible={modalDetail}
|
||||
setVisible={setModalDetail}
|
||||
dataTanggal={dataDetail}
|
||||
onSubmit={(data) => {
|
||||
setDataDetail(data)
|
||||
}}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
import ButtonBackHeader from "@/components/buttonBackHeader";
|
||||
import ButtonSaveHeader from "@/components/buttonSaveHeader";
|
||||
import { InputForm } from "@/components/inputForm";
|
||||
import ModalAddDetailTugasProject from "@/components/project/modalAddDetailTugasProject";
|
||||
import Text from "@/components/Text";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiEditProjectTask, apiGetProjectTask } from "@/lib/api";
|
||||
import { formatDateOnly } from "@/lib/fun_formatDateOnly";
|
||||
import { getDatesInRange } from "@/lib/fun_getDatesInRange";
|
||||
import { setUpdateProject } from "@/lib/projectUpdate";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import { useHeaderHeight } from '@react-navigation/elements';
|
||||
import dayjs from "dayjs";
|
||||
import { router, Stack, useLocalSearchParams } from "expo-router";
|
||||
import 'intl';
|
||||
import 'intl/locale-data/jsonp/id';
|
||||
import moment from "moment";
|
||||
import { useEffect, useState } from "react";
|
||||
import { KeyboardAvoidingView, Platform, SafeAreaView, ScrollView, View } from "react-native";
|
||||
import { KeyboardAvoidingView, Platform, Pressable, SafeAreaView, ScrollView, View } from "react-native";
|
||||
import Toast from "react-native-toast-message";
|
||||
import DateTimePicker, { DateType } from "react-native-ui-datepicker";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
@@ -29,6 +32,9 @@ export default function UpdateProjectTask() {
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [disableBtn, setDisableBtn] = useState(false)
|
||||
const [loadingSubmit, setLoadingSubmit] = useState(false)
|
||||
const [dataDetail, setDataDetail] = useState<any>([])
|
||||
const [modalDetail, setModalDetail] = useState(false)
|
||||
const [dsbButton, setDsbButton] = useState(true)
|
||||
|
||||
const [title, setTitle] = useState('')
|
||||
const [error, setError] = useState({
|
||||
@@ -37,10 +43,8 @@ export default function UpdateProjectTask() {
|
||||
title: false,
|
||||
})
|
||||
|
||||
const from = range.startDate
|
||||
? dayjs(range.startDate).format("DD-MM-YYYY")
|
||||
: '';
|
||||
const to = range.endDate ? dayjs(range.endDate).format("DD-MM-YYYY") : '';
|
||||
const from = formatDateOnly(range.startDate);
|
||||
const to = formatDateOnly(range.endDate);
|
||||
|
||||
async function handleLoad() {
|
||||
try {
|
||||
@@ -57,6 +61,23 @@ export default function UpdateProjectTask() {
|
||||
})
|
||||
setMonth(new Date(response.data.dateStart).getMonth())
|
||||
setYear(new Date(response.data.dateStart).getFullYear())
|
||||
|
||||
const response2 = await apiGetProjectTask({
|
||||
user: hasil,
|
||||
id: detail,
|
||||
cat: "detailTask"
|
||||
});
|
||||
if (response2.data.length == 0) {
|
||||
const datanya = getDatesInRange(response.data.dateStart, response.data.dateEnd)
|
||||
setDataDetail(datanya.map((item: any) => ({
|
||||
date: item,
|
||||
timeStart: null,
|
||||
timeEnd: null,
|
||||
})))
|
||||
} else {
|
||||
setDataDetail(response2.data)
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
@@ -71,8 +92,22 @@ export default function UpdateProjectTask() {
|
||||
async function handleEdit() {
|
||||
try {
|
||||
setLoadingSubmit(true)
|
||||
const dataDetailFix = dataDetail.map((item: any) => ({
|
||||
date: moment(item.date, "DD-MM-YYYY").format("YYYY-MM-DD"),
|
||||
timeStart: item.timeStart,
|
||||
timeEnd: item.timeEnd,
|
||||
}))
|
||||
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 });
|
||||
const response = await apiEditProjectTask({
|
||||
data: {
|
||||
title,
|
||||
dateStart: formatDateOnly(range.startDate, "YYYY-MM-DD"),
|
||||
dateEnd: formatDateOnly(range.endDate, "YYYY-MM-DD"),
|
||||
user: hasil,
|
||||
dataDetail: dataDetailFix
|
||||
},
|
||||
id: detail
|
||||
});
|
||||
if (response.success) {
|
||||
dispatch(setUpdateProject({ ...update, task: !update.task, progress: !update.progress }))
|
||||
Toast.show({ type: 'small', text1: 'Berhasil mengubah data', })
|
||||
@@ -107,10 +142,32 @@ export default function UpdateProjectTask() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function checkButton() {
|
||||
if (range.startDate == null || range.endDate == null || range.startDate == undefined || range.endDate == undefined) {
|
||||
setDsbButton(true)
|
||||
setDataDetail([])
|
||||
} else {
|
||||
setDsbButton(false)
|
||||
const awal = formatDateOnly(range.startDate, "YYYY-MM-DD")
|
||||
const akhir = formatDateOnly(range.endDate, "YYYY-MM-DD")
|
||||
const datanya = getDatesInRange(awal, akhir)
|
||||
setDataDetail(datanya.map((item: any) => ({
|
||||
date: item,
|
||||
timeStart: null,
|
||||
timeEnd: null,
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkAll()
|
||||
}, [from, to, title, error])
|
||||
|
||||
useEffect(() => {
|
||||
checkButton()
|
||||
}, [range])
|
||||
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<Stack.Screen
|
||||
@@ -176,6 +233,13 @@ export default function UpdateProjectTask() {
|
||||
{
|
||||
(error.endDate || error.startDate) && <Text style={[Styles.textInformation, Styles.cError, Styles.mt05]}>Tanggal tidak boleh kosong</Text>
|
||||
}
|
||||
<Pressable
|
||||
style={[Styles.btnTab, Styles.btnLainnya, dsbButton && Styles.btnDisabled]}
|
||||
disabled={dsbButton}
|
||||
onPress={() => { setModalDetail(true) }}
|
||||
>
|
||||
<Text style={[dsbButton ? Styles.cGray : Styles.cWhite]}>Detail</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
<InputForm
|
||||
label="Judul Tugas"
|
||||
@@ -193,6 +257,15 @@ export default function UpdateProjectTask() {
|
||||
</View>
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
|
||||
<ModalAddDetailTugasProject
|
||||
isVisible={modalDetail}
|
||||
setVisible={setModalDetail}
|
||||
dataTanggal={dataDetail}
|
||||
onSubmit={(data) => {
|
||||
setDataDetail(data)
|
||||
}}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import ButtonBackHeader from "@/components/buttonBackHeader";
|
||||
import InputSearch from "@/components/inputSearch";
|
||||
import Text from '@/components/Text';
|
||||
import { ColorsStatus } from "@/constants/ColorsStatus";
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiGetSearch } from "@/lib/api";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
@@ -92,7 +93,7 @@ export default function Search() {
|
||||
<BorderBottomItem
|
||||
borderType="bottom"
|
||||
icon={<Image
|
||||
source={{ uri: `https://wibu-storage.wibudev.com/api/files/${item.img}` }}
|
||||
source={{ uri: `${ConstEnv.url_storage}/files/${item.img}` }}
|
||||
style={[Styles.userProfileSmall]}
|
||||
/>}
|
||||
title={item.name}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ButtonForm } from "@/components/buttonForm";
|
||||
import Text from '@/components/Text';
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import CryptoES from "crypto-es";
|
||||
@@ -19,10 +20,7 @@ export default function Index() {
|
||||
const login = (): void => {
|
||||
const random: string = 'contohLoginMobileDarmasaba';
|
||||
var mytexttoEncryption = "contohLoginMobileDarmasaba"
|
||||
const encrypted = CryptoES.AES.encrypt(mytexttoEncryption, "your password").toString();
|
||||
// var C = require("crypto-js");
|
||||
// var Decrypted = C.AES.decrypt(encrypted, "your password");
|
||||
// var result = Decrypted.toString(C.enc.Utf8);
|
||||
const encrypted = CryptoES.AES.encrypt(mytexttoEncryption, ConstEnv.pass_encrypt).toString();
|
||||
signIn(encrypted);
|
||||
}
|
||||
return (
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiGetDivisionOneFeature } from "@/lib/api";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
@@ -8,11 +9,11 @@ import { useLocalSearchParams } from "expo-router";
|
||||
import * as Sharing from 'expo-sharing';
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Alert, Dimensions, Platform, Pressable, View } from "react-native";
|
||||
import Text from "../Text";
|
||||
import * as mime from 'react-native-mime-types';
|
||||
import { ICarouselInstance } from "react-native-reanimated-carousel";
|
||||
import Skeleton from "../skeleton";
|
||||
import ModalLoading from "../modalLoading";
|
||||
import Skeleton from "../skeleton";
|
||||
import Text from "../Text";
|
||||
|
||||
type Props = {
|
||||
id: string
|
||||
@@ -52,7 +53,7 @@ export default function FileDivisionDetail() {
|
||||
|
||||
const openFile = (item: Props) => {
|
||||
if (Platform.OS == 'android') setLoadingOpen(true)
|
||||
let remoteUrl = 'https://wibu-storage.wibudev.com/api/files/' + item.idStorage;
|
||||
let remoteUrl = ConstEnv.url_storage + '/files/' + item.idStorage;
|
||||
const fileName = item.name + '.' + item.extension;
|
||||
let localPath = `${FileSystem.documentDirectory}/${fileName}`;
|
||||
const mimeType = mime.lookup(fileName)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiGetBanner, apiGetProfile } from "@/lib/api";
|
||||
import { setEntities } from "@/lib/bannerSlice";
|
||||
@@ -50,7 +51,7 @@ export default function CaraouselHome() {
|
||||
onProgressChange={progress}
|
||||
renderItem={({ index }) => (
|
||||
<Image
|
||||
source={{ uri: `https://wibu-storage.wibudev.com/api/files/${entities[index].image}` }}
|
||||
source={{ uri: `${ConstEnv.url_storage}/files/${entities[index].image}` }}
|
||||
style={[Styles.caraoselContent]}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { ColorsStatus } from "@/constants/ColorsStatus";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { stringToDate, stringToDateTime } from "@/lib/fun_stringToDate";
|
||||
import DateTimePicker from "@react-native-community/datetimepicker";
|
||||
import dayjs from "dayjs";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Platform, Pressable, View } from "react-native";
|
||||
import Text from "./Text";
|
||||
import ModalFloat from "./modalFloat";
|
||||
@@ -26,20 +27,50 @@ type Props = {
|
||||
|
||||
export function InputDate({ label, value, placeholder, onChange, info, disable, error, errorText, required, mode, round, width, }: Props) {
|
||||
const [modal, setModal] = useState(false);
|
||||
const [valueFix, setValueFix] = useState(new Date())
|
||||
const [valueFirst, setValueFirst] = useState("")
|
||||
|
||||
const onChangeDate = (type: string, selectedDate: any) => {
|
||||
if (type === "set") {
|
||||
let formatted = ""
|
||||
if (mode == "date") {
|
||||
onChange(dayjs(selectedDate).format("DD-MM-YYYY"))
|
||||
formatted = dayjs(selectedDate).format("DD-MM-YYYY")
|
||||
} else if (mode == "time") {
|
||||
onChange(dayjs(selectedDate).format("HH:mm"))
|
||||
formatted = dayjs(selectedDate).format("HH:mm")
|
||||
}
|
||||
|
||||
setValueFirst(formatted)
|
||||
|
||||
if (Platform.OS == "android") {
|
||||
onChange(formatted)
|
||||
setModal(false)
|
||||
}
|
||||
setModal(false)
|
||||
} else {
|
||||
setModal(false);
|
||||
}
|
||||
};
|
||||
|
||||
function onSetValue() {
|
||||
onChange(valueFirst)
|
||||
setModal(false)
|
||||
}
|
||||
|
||||
function changeValue() {
|
||||
if (value) {
|
||||
let valDate = new Date()
|
||||
if (mode == "date") {
|
||||
valDate = stringToDate(value)
|
||||
} else if (mode == "time") {
|
||||
valDate = stringToDateTime("", value)
|
||||
}
|
||||
setValueFix(valDate)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (modal) changeValue()
|
||||
}, [value, modal])
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={[Styles.mb10]}>
|
||||
@@ -63,23 +94,24 @@ export function InputDate({ label, value, placeholder, onChange, info, disable,
|
||||
<ModalFloat
|
||||
isVisible={modal}
|
||||
setVisible={setModal}
|
||||
onSubmit={() => { }}
|
||||
buttonHide
|
||||
disableSubmit
|
||||
onSubmit={() => { onSetValue() }}
|
||||
title={mode == "date" ? "Pilih Tanggal" : mode == "time" ? "Pilih Jam" : "Pilih Tanggal & Jam"}>
|
||||
<DateTimePicker
|
||||
value={new Date()}
|
||||
value={valueFix}
|
||||
mode={mode}
|
||||
display="spinner"
|
||||
onChange={(event, date) => { onChangeDate(event.type, date) }}
|
||||
onChange={(event, date) => {
|
||||
onChangeDate(event.type, date)
|
||||
}}
|
||||
onTouchCancel={() => setModal(false)}
|
||||
|
||||
/>
|
||||
</ModalFloat>
|
||||
)
|
||||
) : (
|
||||
modal && (
|
||||
<DateTimePicker
|
||||
value={new Date()}
|
||||
value={valueFix}
|
||||
mode={mode}
|
||||
display="inline"
|
||||
onChange={(event, date) => { onChangeDate(event.type, date) }}
|
||||
|
||||
@@ -33,10 +33,10 @@ export default function ModalFloat({ isVisible, setVisible, title, children, onS
|
||||
!buttonHide && (
|
||||
<View style={[Styles.rowItemsCenter, { justifyContent: 'flex-end' }]}>
|
||||
<Pressable style={[Styles.ph15, Styles.pv05, Styles.round10, Styles.mr10]} onPress={() => { setVisible(false) }}>
|
||||
<Text style={[Styles.textDefault]}>Batal</Text>
|
||||
<Text style={[Styles.textDefaultSemiBold]}>Batal</Text>
|
||||
</Pressable>
|
||||
<Pressable style={[Styles.ph15, Styles.pv05, Styles.round10]} onPress={onSubmit} disabled={disableSubmit}>
|
||||
<Text style={[Styles.textDefault, disableSubmit && Styles.cGray]}>Simpan</Text>
|
||||
<Text style={[Styles.textDefaultSemiBold, disableSubmit && Styles.cGray]}>Simpan</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ConstEnv } from "@/constants/ConstEnv"
|
||||
import { valueGender } from "@/constants/Gender"
|
||||
import { valueRoleUser } from "@/constants/RoleUser"
|
||||
import Styles from "@/constants/Styles"
|
||||
@@ -140,7 +141,7 @@ export default function ModalSelect({ open, close, title, category, idParent, on
|
||||
<ImageWithLabel
|
||||
key={index}
|
||||
label={item.name}
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
src={`${ConstEnv.url_storage}/files/${item.img}`}
|
||||
onClick={() => onChoose(item.idUser, item.name, item.img)}
|
||||
/>
|
||||
))
|
||||
@@ -164,7 +165,7 @@ export default function ModalSelect({ open, close, title, category, idParent, on
|
||||
category == 'member'
|
||||
?
|
||||
<View style={[Styles.rowItemsCenter]}>
|
||||
<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} border />
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} border />
|
||||
<Text style={[Styles.textDefault, Styles.ml10]}>{item.name}</Text>
|
||||
</View>
|
||||
:
|
||||
|
||||
135
components/project/modalAddDetailTugasProject.tsx
Normal file
135
components/project/modalAddDetailTugasProject.tsx
Normal file
@@ -0,0 +1,135 @@
|
||||
import Styles from "@/constants/Styles";
|
||||
import { stringToDateTime } from "@/lib/fun_stringToDate";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Dimensions, View, VirtualizedList } from "react-native";
|
||||
import { InputDate } from "../inputDate";
|
||||
import ModalFloat from "../modalFloat";
|
||||
import Text from "../Text";
|
||||
|
||||
interface Props {
|
||||
date: string;
|
||||
timeStart: string;
|
||||
timeEnd: string;
|
||||
}
|
||||
|
||||
export default function ModalAddDetailTugasProject({ isVisible, setVisible, dataTanggal, onSubmit }: { isVisible: boolean, setVisible: (value: boolean) => void, dataTanggal: Props[], onSubmit: (data: Props[]) => void }) {
|
||||
const [data, setData] = useState<Props[]>(dataTanggal)
|
||||
const tinggiScreen = Dimensions.get("window").height;
|
||||
const tinggiFix = tinggiScreen * 70 / 100;
|
||||
const [error, setError] = useState<any>([])
|
||||
|
||||
useEffect(() => {
|
||||
if (isVisible) {
|
||||
setData(dataTanggal)
|
||||
setError([])
|
||||
}
|
||||
}, [isVisible, dataTanggal])
|
||||
|
||||
|
||||
const getItem = (_data: unknown, index: number): Props => ({
|
||||
date: data[index].date,
|
||||
timeStart: data[index].timeStart,
|
||||
timeEnd: data[index].timeEnd,
|
||||
})
|
||||
|
||||
function settingError(date: string, cat: 'timeStart' | 'timeEnd', val: boolean) {
|
||||
const ada = error.find((item: any) => item.date == date)
|
||||
if (ada) {
|
||||
setError(error.map((item: any) => {
|
||||
if (item.date == date) {
|
||||
return { ...item, [cat]: val }
|
||||
}
|
||||
return item
|
||||
}))
|
||||
} else {
|
||||
setError([...error, { date, [cat]: val }])
|
||||
}
|
||||
}
|
||||
|
||||
function validationForm(cat: "timeStart" | "timeEnd", val: string, date: string) {
|
||||
if (cat == "timeEnd") {
|
||||
const start = stringToDateTime("", String(data.find((item) => item.date == date)?.timeStart))
|
||||
const end = stringToDateTime("", val)
|
||||
const timestampAwal = start.getTime()
|
||||
const timestampAkhir = end.getTime()
|
||||
if (val == "" || val == null || timestampAwal > timestampAkhir) {
|
||||
settingError(date, "timeEnd", true)
|
||||
} else {
|
||||
settingError(date, "timeEnd", false)
|
||||
}
|
||||
} else {
|
||||
const end = stringToDateTime("", String(data.find((item) => item.date == date)?.timeEnd))
|
||||
const start = stringToDateTime("", val)
|
||||
const timestampAwal = start.getTime()
|
||||
const timestampAkhir = end.getTime()
|
||||
|
||||
if (val == "" || val == null || timestampAwal > timestampAkhir) {
|
||||
settingError(date, "timeEnd", true)
|
||||
} else {
|
||||
settingError(date, "timeEnd", false)
|
||||
}
|
||||
}
|
||||
|
||||
setData(data.map((item) => {
|
||||
if (item.date == date) {
|
||||
return { ...item, [cat]: val }
|
||||
}
|
||||
return item
|
||||
}))
|
||||
}
|
||||
|
||||
return (
|
||||
<ModalFloat
|
||||
title="Detail Tanggal dan Waktu Tugas"
|
||||
isVisible={isVisible}
|
||||
setVisible={setVisible}
|
||||
disableSubmit={Object.values(error).some((val: any) => val.timeEnd == true || val.timeStart == true)}
|
||||
onSubmit={() => {
|
||||
onSubmit(data)
|
||||
setVisible(false)
|
||||
}}
|
||||
>
|
||||
<View style={[{ height: tinggiFix }]} >
|
||||
<VirtualizedList
|
||||
data={data}
|
||||
getItemCount={() => data.length}
|
||||
getItem={getItem}
|
||||
renderItem={({ item, index }: { item: Props, index: number }) => {
|
||||
return (
|
||||
<View key={index} style={[Styles.borderBottom, Styles.pv05]}>
|
||||
<Text style={[Styles.textDefaultSemiBold]}>{item.date}</Text>
|
||||
<View style={[Styles.rowSpaceBetween]}>
|
||||
<View style={[{ width: "48%" }]}>
|
||||
<InputDate
|
||||
mode="time"
|
||||
onChange={(val) => { validationForm("timeStart", val, item.date) }}
|
||||
value={item.timeStart}
|
||||
label="Waktu Awal"
|
||||
placeholder="--:--"
|
||||
error={error.find((error: any) => error.date == item.date)?.timeStart}
|
||||
errorText="Waktu awal tidak valid"
|
||||
/>
|
||||
</View>
|
||||
<View style={[{ width: "48%" }]}>
|
||||
<InputDate
|
||||
onChange={(val) => { validationForm("timeEnd", val, item.date) }}
|
||||
mode="time"
|
||||
value={item.timeEnd}
|
||||
label="Waktu Akhir"
|
||||
placeholder="--:--"
|
||||
error={error.find((error: any) => error.date == item.date)?.timeEnd}
|
||||
errorText="Waktu akhir harus lebih dari waktu awal"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}}
|
||||
keyExtractor={(item, index) => String(index)}
|
||||
showsVerticalScrollIndicator={false}
|
||||
/>
|
||||
</View>
|
||||
|
||||
</ModalFloat>
|
||||
)
|
||||
}
|
||||
@@ -16,7 +16,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function ModalListDetailTugasProject({ isVisible, setVisible, idTask }: { isVisible: boolean, setVisible: (value: boolean) => void, idTask: string }) {
|
||||
const [data, setData] = useState([])
|
||||
const [data, setData] = useState<Props[]>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const arrSkeleton = Array.from({ length: 3 }, (_, index) => index)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiDeleteFileProject, apiGetProjectOne } from "@/lib/api";
|
||||
import { setUpdateProject } from "@/lib/projectUpdate";
|
||||
@@ -94,7 +95,7 @@ export default function SectionFile({ status, member, refreshing }: { status: nu
|
||||
const openFile = () => {
|
||||
setModal(false)
|
||||
setLoadingOpen(true)
|
||||
let remoteUrl = 'https://wibu-storage.wibudev.com/api/files/' + selectFile?.idStorage;
|
||||
let remoteUrl = ConstEnv.url_storage + '/files/' + selectFile?.idStorage;
|
||||
const fileName = selectFile?.name + '.' + selectFile?.extension;
|
||||
let localPath = `${FileSystem.documentDirectory}/${fileName}`;
|
||||
const mimeType = mime.lookup(fileName)
|
||||
@@ -172,14 +173,6 @@ export default function SectionFile({ status, member, refreshing }: { status: nu
|
||||
openFile()
|
||||
}}
|
||||
/>
|
||||
{/* <MenuItemRow
|
||||
icon={<MaterialCommunityIcons name="download" color="black" size={25} />}
|
||||
title="Download"
|
||||
onPress={() => {
|
||||
// download()
|
||||
// setModal(false)
|
||||
}}
|
||||
/> */}
|
||||
{
|
||||
!member && (entityUser.role == "user" || entityUser.role == "coadmin") ? <></>
|
||||
:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiDeleteProjectMember, apiGetProjectOne } from "@/lib/api";
|
||||
import { setUpdateProject } from "@/lib/projectUpdate";
|
||||
@@ -112,7 +113,7 @@ export default function SectionMember({ status, refreshing }: { status: number |
|
||||
<BorderBottomItem
|
||||
key={index}
|
||||
borderType="bottom"
|
||||
icon={<ImageUser src={`https://wibu-storage.wibudev.com/api/files/${item.img}`} />}
|
||||
icon={<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} />}
|
||||
title={item.name}
|
||||
onPress={() => {
|
||||
if (status == 3) return
|
||||
|
||||
135
components/task/modalAddDetailTugasTask.tsx
Normal file
135
components/task/modalAddDetailTugasTask.tsx
Normal file
@@ -0,0 +1,135 @@
|
||||
import Styles from "@/constants/Styles";
|
||||
import { stringToDateTime } from "@/lib/fun_stringToDate";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Dimensions, View, VirtualizedList } from "react-native";
|
||||
import { InputDate } from "../inputDate";
|
||||
import ModalFloat from "../modalFloat";
|
||||
import Text from "../Text";
|
||||
|
||||
interface Props {
|
||||
date: string;
|
||||
timeStart: string;
|
||||
timeEnd: string;
|
||||
}
|
||||
|
||||
export default function ModalAddDetailTugasTask({ isVisible, setVisible, dataTanggal, onSubmit }: { isVisible: boolean, setVisible: (value: boolean) => void, dataTanggal: Props[], onSubmit: (data: Props[]) => void }) {
|
||||
const [data, setData] = useState<Props[]>(dataTanggal)
|
||||
const tinggiScreen = Dimensions.get("window").height;
|
||||
const tinggiFix = tinggiScreen * 70 / 100;
|
||||
const [error, setError] = useState<any>([])
|
||||
|
||||
useEffect(() => {
|
||||
if (isVisible) {
|
||||
setData(dataTanggal)
|
||||
setError([])
|
||||
}
|
||||
}, [isVisible, dataTanggal])
|
||||
|
||||
|
||||
const getItem = (_data: unknown, index: number): Props => ({
|
||||
date: data[index].date,
|
||||
timeStart: data[index].timeStart,
|
||||
timeEnd: data[index].timeEnd,
|
||||
})
|
||||
|
||||
function settingError(date: string, cat: 'timeStart' | 'timeEnd', val: boolean) {
|
||||
const ada = error.find((item: any) => item.date == date)
|
||||
if (ada) {
|
||||
setError(error.map((item: any) => {
|
||||
if (item.date == date) {
|
||||
return { ...item, [cat]: val }
|
||||
}
|
||||
return item
|
||||
}))
|
||||
} else {
|
||||
setError([...error, { date, [cat]: val }])
|
||||
}
|
||||
}
|
||||
|
||||
function validationForm(cat: "timeStart" | "timeEnd", val: string, date: string) {
|
||||
if (cat == "timeEnd") {
|
||||
const start = stringToDateTime("", String(data.find((item) => item.date == date)?.timeStart))
|
||||
const end = stringToDateTime("", val)
|
||||
const timestampAwal = start.getTime()
|
||||
const timestampAkhir = end.getTime()
|
||||
if (val == "" || val == null || timestampAwal > timestampAkhir) {
|
||||
settingError(date, "timeEnd", true)
|
||||
} else {
|
||||
settingError(date, "timeEnd", false)
|
||||
}
|
||||
} else {
|
||||
const end = stringToDateTime("", String(data.find((item) => item.date == date)?.timeEnd))
|
||||
const start = stringToDateTime("", val)
|
||||
const timestampAwal = start.getTime()
|
||||
const timestampAkhir = end.getTime()
|
||||
|
||||
if (val == "" || val == null || timestampAwal > timestampAkhir) {
|
||||
settingError(date, "timeEnd", true)
|
||||
} else {
|
||||
settingError(date, "timeEnd", false)
|
||||
}
|
||||
}
|
||||
|
||||
setData(data.map((item) => {
|
||||
if (item.date == date) {
|
||||
return { ...item, [cat]: val }
|
||||
}
|
||||
return item
|
||||
}))
|
||||
}
|
||||
|
||||
return (
|
||||
<ModalFloat
|
||||
title="Detail Tanggal dan Waktu Tugas"
|
||||
isVisible={isVisible}
|
||||
setVisible={setVisible}
|
||||
disableSubmit={Object.values(error).some((val: any) => val.timeEnd == true || val.timeStart == true)}
|
||||
onSubmit={() => {
|
||||
onSubmit(data)
|
||||
setVisible(false)
|
||||
}}
|
||||
>
|
||||
<View style={[{ height: tinggiFix }]} >
|
||||
<VirtualizedList
|
||||
data={data}
|
||||
getItemCount={() => data.length}
|
||||
getItem={getItem}
|
||||
renderItem={({ item, index }: { item: Props, index: number }) => {
|
||||
return (
|
||||
<View key={index} style={[Styles.borderBottom, Styles.pv05]}>
|
||||
<Text style={[Styles.textDefaultSemiBold]}>{item.date}</Text>
|
||||
<View style={[Styles.rowSpaceBetween]}>
|
||||
<View style={[{ width: "48%" }]}>
|
||||
<InputDate
|
||||
mode="time"
|
||||
onChange={(val) => { validationForm("timeStart", val, item.date) }}
|
||||
value={item.timeStart}
|
||||
label="Waktu Awal"
|
||||
placeholder="--:--"
|
||||
error={error.find((error: any) => error.date == item.date)?.timeStart}
|
||||
errorText="Waktu awal tidak valid"
|
||||
/>
|
||||
</View>
|
||||
<View style={[{ width: "48%" }]}>
|
||||
<InputDate
|
||||
onChange={(val) => { validationForm("timeEnd", val, item.date) }}
|
||||
mode="time"
|
||||
value={item.timeEnd}
|
||||
label="Waktu Akhir"
|
||||
placeholder="--:--"
|
||||
error={error.find((error: any) => error.date == item.date)?.timeEnd}
|
||||
errorText="Waktu akhir harus lebih dari waktu awal"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}}
|
||||
keyExtractor={(item, index) => String(index)}
|
||||
showsVerticalScrollIndicator={false}
|
||||
/>
|
||||
</View>
|
||||
|
||||
</ModalFloat>
|
||||
)
|
||||
}
|
||||
116
components/task/modalListDetailTugasTask.tsx
Normal file
116
components/task/modalListDetailTugasTask.tsx
Normal file
@@ -0,0 +1,116 @@
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiGetProjectTask, apiGetTaskTugas } from "@/lib/api";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Dimensions, View, VirtualizedList } from "react-native";
|
||||
import { InputDate } from "../inputDate";
|
||||
import ModalFloat from "../modalFloat";
|
||||
import Skeleton from "../skeleton";
|
||||
import Text from "../Text";
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
date: string;
|
||||
timeStart: string;
|
||||
timeEnd: string;
|
||||
}
|
||||
|
||||
export default function ModalListDetailTugasTask({ isVisible, setVisible, idTask }: { isVisible: boolean, setVisible: (value: boolean) => void, idTask: string }) {
|
||||
const [data, setData] = useState<Props[]>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const arrSkeleton = Array.from({ length: 3 }, (_, index) => index)
|
||||
const tinggiScreen = Dimensions.get("window").height;
|
||||
const tinggiFix = tinggiScreen * 70 / 100;
|
||||
|
||||
|
||||
|
||||
async function getData() {
|
||||
try {
|
||||
setLoading(true)
|
||||
const hasil = await decryptToken(String(token?.current));
|
||||
const res = await apiGetTaskTugas({ user: hasil, id: idTask, cat: "detailTask" })
|
||||
setData(res.data)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isVisible) {
|
||||
getData()
|
||||
}
|
||||
}, [isVisible, idTask])
|
||||
|
||||
const getItem = (_data: unknown, index: number): Props => ({
|
||||
id: data[index].id,
|
||||
date: data[index].date,
|
||||
timeStart: data[index].timeStart,
|
||||
timeEnd: data[index].timeEnd,
|
||||
})
|
||||
|
||||
return (
|
||||
<ModalFloat
|
||||
title="Detail Tanggal dan Waktu Tugas"
|
||||
isVisible={isVisible}
|
||||
setVisible={setVisible}
|
||||
buttonHide
|
||||
>
|
||||
<View style={[{ height: tinggiFix }]} >
|
||||
{
|
||||
loading ?
|
||||
arrSkeleton.map((item: any, i: number) => {
|
||||
return (
|
||||
<Skeleton key={i} width={100} widthType="percent" height={40} borderRadius={5} />
|
||||
)
|
||||
})
|
||||
:
|
||||
data.length > 0 ?
|
||||
(
|
||||
<VirtualizedList
|
||||
data={data}
|
||||
getItemCount={() => data.length}
|
||||
getItem={getItem}
|
||||
renderItem={({ item, index }: { item: Props, index: number }) => {
|
||||
return (
|
||||
<View key={index} style={[Styles.borderBottom, Styles.pv05]}>
|
||||
<Text style={[Styles.textDefaultSemiBold]}>{item.date}</Text>
|
||||
<View style={[Styles.rowSpaceBetween]}>
|
||||
<View style={[{ width: "48%" }]}>
|
||||
<InputDate
|
||||
mode="time"
|
||||
disable
|
||||
onChange={(val) => { }}
|
||||
value={item.timeStart}
|
||||
label="Waktu Awal"
|
||||
placeholder="--:--"
|
||||
/>
|
||||
</View>
|
||||
<View style={[{ width: "48%" }]}>
|
||||
<InputDate
|
||||
onChange={(val) => { }}
|
||||
mode="time"
|
||||
value={item.timeEnd}
|
||||
label="Waktu Akhir"
|
||||
placeholder="--:--"
|
||||
disable
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}}
|
||||
keyExtractor={(item, index) => String(index)}
|
||||
showsVerticalScrollIndicator={false}
|
||||
/>
|
||||
)
|
||||
:
|
||||
<Text style={[Styles.textDefault, Styles.cGray, { textAlign: 'center' }]} >Tidak ada data</Text>
|
||||
}
|
||||
</View>
|
||||
|
||||
</ModalFloat>
|
||||
)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiDeleteFileTask, apiGetTaskOne } from "@/lib/api";
|
||||
import { setUpdateTask } from "@/lib/taskUpdate";
|
||||
@@ -27,7 +28,7 @@ type Props = {
|
||||
idStorage: string
|
||||
}
|
||||
|
||||
export default function SectionFileTask({refreshing}: {refreshing: boolean}) {
|
||||
export default function SectionFileTask({ refreshing }: { refreshing: boolean }) {
|
||||
const [isModal, setModal] = useState(false)
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const { detail } = useLocalSearchParams<{ detail: string }>()
|
||||
@@ -68,7 +69,7 @@ export default function SectionFileTask({refreshing}: {refreshing: boolean}) {
|
||||
const openFile = () => {
|
||||
setModal(false)
|
||||
setLoadingOpen(true)
|
||||
let remoteUrl = 'https://wibu-storage.wibudev.com/api/files/' + selectFile?.idStorage;
|
||||
let remoteUrl = ConstEnv.url_storage + '/files/' + selectFile?.idStorage;
|
||||
const fileName = selectFile?.name + '.' + selectFile?.extension;
|
||||
let localPath = `${FileSystem.documentDirectory}/${fileName}`;
|
||||
const mimeType = mime.lookup(fileName)
|
||||
@@ -160,17 +161,8 @@ export default function SectionFileTask({refreshing}: {refreshing: boolean}) {
|
||||
title="Lihat / Share"
|
||||
onPress={() => {
|
||||
openFile()
|
||||
// setModal(false)
|
||||
}}
|
||||
/>
|
||||
{/* <MenuItemRow
|
||||
icon={<MaterialCommunityIcons name="download" color="black" size={25} />}
|
||||
title="Download"
|
||||
onPress={() => {
|
||||
setModal(false)
|
||||
}}
|
||||
/> */}
|
||||
|
||||
<MenuItemRow
|
||||
icon={<Ionicons name="trash" color="black" size={25} />}
|
||||
title="Hapus"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ConstEnv } from "@/constants/ConstEnv";
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiDeleteTaskMember, apiGetTaskOne } from "@/lib/api";
|
||||
import { setUpdateTask } from "@/lib/taskUpdate";
|
||||
@@ -114,9 +115,7 @@ export default function SectionMemberTask({ refreshing }: { refreshing: boolean
|
||||
key={index}
|
||||
borderType="bottom"
|
||||
icon={
|
||||
<ImageUser
|
||||
src={`https://wibu-storage.wibudev.com/api/files/${item.img}`}
|
||||
/>
|
||||
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} />
|
||||
}
|
||||
title={item.name}
|
||||
onPress={() => {
|
||||
|
||||
@@ -15,6 +15,7 @@ import MenuItemRow from "../menuItemRow";
|
||||
import ModalSelect from "../modalSelect";
|
||||
import SkeletonTask from "../skeletonTask";
|
||||
import Text from "../Text";
|
||||
import ModalListDetailTugasTask from "./modalListDetailTugasTask";
|
||||
|
||||
|
||||
type Props = {
|
||||
@@ -25,7 +26,7 @@ type Props = {
|
||||
dateEnd: string;
|
||||
}
|
||||
|
||||
export default function SectionTanggalTugasTask({refreshing}: {refreshing: boolean}) {
|
||||
export default function SectionTanggalTugasTask({ refreshing }: { refreshing: boolean }) {
|
||||
const dispatch = useDispatch()
|
||||
const update = useSelector((state: any) => state.taskUpdate)
|
||||
const [isModal, setModal] = useState(false)
|
||||
@@ -33,6 +34,7 @@ export default function SectionTanggalTugasTask({refreshing}: {refreshing: boole
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const [loading, setLoading] = useState(true)
|
||||
const arrSkeleton = Array.from({ length: 5 })
|
||||
const [modalDetail, setModalDetail] = useState(false)
|
||||
const { id, detail } = useLocalSearchParams<{ id: string, detail: string }>();
|
||||
const [data, setData] = useState<Props[]>([])
|
||||
const [tugas, setTugas] = useState({
|
||||
@@ -171,7 +173,24 @@ export default function SectionTanggalTugasTask({refreshing}: {refreshing: boole
|
||||
router.push(`./update/${tugas.id}`)
|
||||
}}
|
||||
/>
|
||||
|
||||
<MenuItemRow
|
||||
icon={
|
||||
<MaterialCommunityIcons
|
||||
name="clock-time-three-outline"
|
||||
color="black"
|
||||
size={25}
|
||||
/>
|
||||
}
|
||||
title="Detail Waktu"
|
||||
onPress={() => {
|
||||
setModal(false);
|
||||
setTimeout(() => {
|
||||
setModalDetail(true)
|
||||
}, 600)
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<View style={[Styles.rowItemsCenter, Styles.mt15]}>
|
||||
<MenuItemRow
|
||||
icon={<Ionicons name="trash" color="black" size={25} />}
|
||||
title="Hapus Tugas"
|
||||
@@ -198,6 +217,12 @@ export default function SectionTanggalTugasTask({refreshing}: {refreshing: boole
|
||||
open={isSelect}
|
||||
valChoose={String(tugas.status)}
|
||||
/>
|
||||
|
||||
<ModalListDetailTugasTask
|
||||
isVisible={modalDetail}
|
||||
setVisible={setModalDetail}
|
||||
idTask={tugas.id}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import Constants from 'expo-constants';
|
||||
|
||||
export const ConstEnv = {
|
||||
url_storage : Constants?.expoConfig?.extra?.URL_STORAGE
|
||||
url_storage: Constants?.expoConfig?.extra?.URL_STORAGE,
|
||||
pass_encrypt: Constants?.expoConfig?.extra?.PASS_ENC
|
||||
}
|
||||
@@ -275,6 +275,9 @@ const Styles = StyleSheet.create({
|
||||
paddingVertical: 5,
|
||||
marginVertical: 5
|
||||
},
|
||||
btnDisabled: {
|
||||
backgroundColor: '#d6d8f6',
|
||||
},
|
||||
btnMenuRow: {
|
||||
width: '33%',
|
||||
alignItems: 'center'
|
||||
|
||||
12
lib/api.ts
12
lib/api.ts
@@ -281,7 +281,7 @@ export const apiReportProject = async (data: { report: string, user: string }, i
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const apiCreateProjectTask = async ({ data, id }: { data: { name: string, dateStart: string, user: string, dateEnd: string }, id: string }) => {
|
||||
export const apiCreateProjectTask = async ({ data, id }: { data: { name: string, dateStart: string, user: string, dateEnd: string, dataDetail: any[] }, id: string }) => {
|
||||
const response = await api.post(`/mobile/project/${id}`, data)
|
||||
return response.data;
|
||||
};
|
||||
@@ -306,7 +306,7 @@ export const apiGetProjectTask = async ({ user, id, cat }: { user: string, id: s
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const apiEditProjectTask = async ({ data, id }: { data: { title: string, dateStart: string, user: string, dateEnd: string }, id: string }) => {
|
||||
export const apiEditProjectTask = async ({ data, id }: { data: { title: string, dateStart: string, user: string, dateEnd: string, dataDetail: any[] }, id: string }) => {
|
||||
const response = await api.post(`/mobile/project/detail/${id}`, data)
|
||||
return response.data;
|
||||
};
|
||||
@@ -529,12 +529,12 @@ export const apiUpdateStatusTaskDivision = async (data: { user: string, status:
|
||||
return response.data
|
||||
};
|
||||
|
||||
export const apiGetTaskTugas = async ({ user, id }: { user: string, id: string }) => {
|
||||
const response = await api.get(`mobile/task/detail/${id}?user=${user}`);
|
||||
export const apiGetTaskTugas = async ({ user, id, cat }: { user: string, id: string, cat?: string }) => {
|
||||
const response = await api.get(`mobile/task/detail/${id}?user=${user}${cat ? `&cat=${cat}` : ""}`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const apiEditTaskTugas = async ({ data, id }: { data: { title: string, dateStart: string, user: string, dateEnd: string }, id: string }) => {
|
||||
export const apiEditTaskTugas = async ({ data, id }: { data: { title: string, dateStart: string, user: string, dateEnd: string, dataDetail: any[] }, id: string }) => {
|
||||
const response = await api.post(`/mobile/task/detail/${id}`, data)
|
||||
return response.data;
|
||||
};
|
||||
@@ -559,7 +559,7 @@ export const apiDeleteTaskMember = async (data: { user: string, idUser: string }
|
||||
return response.data
|
||||
};
|
||||
|
||||
export const apiCreateTaskTugas = async ({ data, id }: { data: { title: string, dateStart: string, user: string, dateEnd: string, idDivision: string }, id: string }) => {
|
||||
export const apiCreateTaskTugas = async ({ data, id }: { data: { title: string, dateStart: string, user: string, dateEnd: string, idDivision: string, dataDetail: any[] }, id: string }) => {
|
||||
const response = await api.post(`/mobile/task/${id}`, data)
|
||||
return response.data;
|
||||
};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { getApp } from '@react-native-firebase/app';
|
||||
import { getDatabase } from '@react-native-firebase/database';
|
||||
import Constants from 'expo-constants';
|
||||
|
||||
// Ganti URL sesuai punya kamu
|
||||
const DATABASE_URL = 'https://mobile-darmasaba-default-rtdb.asia-southeast1.firebasedatabase.app';
|
||||
const DATABASE_URL = Constants?.expoConfig?.extra?.URL_FIREBASE_DB
|
||||
|
||||
export function getDB() {
|
||||
return getDatabase(getApp(), DATABASE_URL);
|
||||
|
||||
18
lib/fun_formatDateOnly.ts
Normal file
18
lib/fun_formatDateOnly.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc";
|
||||
import timezone from "dayjs/plugin/timezone";
|
||||
import { DateType } from "react-native-ui-datepicker";
|
||||
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(timezone);
|
||||
|
||||
export function formatDateOnly(
|
||||
date?: DateType,
|
||||
format: "DD-MM-YYYY" | "YYYY-MM-DD" = "DD-MM-YYYY"
|
||||
) {
|
||||
if (!date) return "";
|
||||
|
||||
return dayjs(date)
|
||||
.tz(dayjs.tz.guess())
|
||||
.format(format);
|
||||
}
|
||||
14
lib/fun_getDatesInRange.ts
Normal file
14
lib/fun_getDatesInRange.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export function getDatesInRange(startDate: string, endDate: string) {
|
||||
const dates = [];
|
||||
const currentDate = new Date(startDate);
|
||||
const endDateNew = new Date(endDate);
|
||||
|
||||
while (currentDate <= endDateNew) {
|
||||
dates.push(dayjs(new Date(currentDate)).format("DD-MM-YYYY"));
|
||||
currentDate.setDate(currentDate.getDate() + 1);
|
||||
}
|
||||
|
||||
return dates;
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ConstEnv } from '@/constants/ConstEnv';
|
||||
import { apiRegisteredToken, apiUnregisteredToken } from '@/lib/api';
|
||||
import { getToken, requestPermission } from '@/lib/useNotification';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
@@ -41,13 +42,13 @@ export default function AuthProvider({ children }: { children: ReactNode }): Rea
|
||||
|
||||
const decryptToken = (async (token: string) => {
|
||||
var C = require("crypto-js");
|
||||
var Decrypted = C.AES.decrypt(token, "your password");
|
||||
var Decrypted = C.AES.decrypt(token, ConstEnv.pass_encrypt);
|
||||
var result = Decrypted.toString(C.enc.Utf8);
|
||||
return result
|
||||
})
|
||||
|
||||
const encryptToken = (async (token: string) => {
|
||||
var result = CryptoES.AES.encrypt(token, "your password").toString();
|
||||
var result = CryptoES.AES.encrypt(token, ConstEnv.pass_encrypt).toString();
|
||||
return result
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user