Merge pull request 'amalia/05-agustus-25' (#13) from amalia/05-agustus-25 into join

Reviewed-on: bip/mobile-darmasaba#13
This commit is contained in:
2025-08-05 17:39:56 +08:00
19 changed files with 188 additions and 68 deletions

View File

@@ -17,6 +17,7 @@ import { router, Stack, useLocalSearchParams } from "expo-router";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { KeyboardAvoidingView, Platform, Pressable, ScrollView, View } from "react-native"; import { KeyboardAvoidingView, Platform, Pressable, ScrollView, View } from "react-native";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { useHeaderHeight } from '@react-navigation/elements';
type Props = { type Props = {
id: string id: string
@@ -49,6 +50,7 @@ export default function DetailDiscussionGeneral() {
const [loadingKomentar, setLoadingKomentar] = useState(true) const [loadingKomentar, setLoadingKomentar] = useState(true)
const arrSkeleton = Array.from({ length: 3 }, (_, index) => index) const arrSkeleton = Array.from({ length: 3 }, (_, index) => index)
const reference = firebase.app().database('https://mobile-darmasaba-default-rtdb.asia-southeast1.firebasedatabase.app').ref(`/discussion-general/${id}`); const reference = firebase.app().database('https://mobile-darmasaba-default-rtdb.asia-southeast1.firebasedatabase.app').ref(`/discussion-general/${id}`);
const headerHeight = useHeaderHeight();
useEffect(() => { useEffect(() => {
const onValueChange = reference.on('value', snapshot => { const onValueChange = reference.on('value', snapshot => {
@@ -197,7 +199,7 @@ export default function DetailDiscussionGeneral() {
</ScrollView> </ScrollView>
<KeyboardAvoidingView <KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : undefined} behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={110} keyboardVerticalOffset={headerHeight}
> >
<View style={[ <View style={[
Styles.contentItemCenter, Styles.contentItemCenter,

View File

@@ -17,6 +17,7 @@ import {
View View
} from "react-native"; } from "react-native";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { useHeaderHeight } from '@react-navigation/elements';
export default function CalendarDivisionCreate() { export default function CalendarDivisionCreate() {
const { id } = useLocalSearchParams<{ id: string }>() const { id } = useLocalSearchParams<{ id: string }>()
@@ -24,6 +25,7 @@ export default function CalendarDivisionCreate() {
const [isSelect, setSelect] = useState(false) const [isSelect, setSelect] = useState(false)
const update = useSelector((state: any) => state.calendarCreate) const update = useSelector((state: any) => state.calendarCreate)
const dispatch = useDispatch() const dispatch = useDispatch()
const headerHeight = useHeaderHeight();
const [error, setError] = useState({ const [error, setError] = useState({
title: false, title: false,
dateStart: false, dateStart: false,
@@ -145,7 +147,7 @@ export default function CalendarDivisionCreate() {
/> />
<KeyboardAvoidingView <KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : undefined} behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={110} keyboardVerticalOffset={headerHeight}
> >
<ScrollView> <ScrollView>
<View style={[Styles.p15]}> <View style={[Styles.p15]}>

View File

@@ -78,7 +78,9 @@ export default function CalendarDivision() {
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} finally { } finally {
setLoadingBtn(false) setTimeout(() => {
setLoadingBtn(false)
}, 500)
} }
} }
@@ -155,6 +157,7 @@ export default function CalendarDivision() {
date={selected} date={selected}
month={month} month={month}
onChange={({ date }) => setSelected(date)} onChange={({ date }) => setSelected(date)}
onMonthChange={(month) => setMonth(month)}
styles={{ styles={{
selected: Styles.selectedDate, selected: Styles.selectedDate,
month_label: Styles.cBlack, month_label: Styles.cBlack,

View File

@@ -20,6 +20,7 @@ import { router, Stack, useLocalSearchParams } from "expo-router";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { KeyboardAvoidingView, Platform, Pressable, RefreshControl, ScrollView, View } from "react-native"; import { KeyboardAvoidingView, Platform, Pressable, RefreshControl, ScrollView, View } from "react-native";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { useHeaderHeight } from '@react-navigation/elements';
type Props = { type Props = {
id: string; id: string;
@@ -59,6 +60,7 @@ export default function DiscussionDetail() {
const arrSkeleton = Array.from({ length: 3 }) const arrSkeleton = Array.from({ length: 3 })
const reference = firebase.app().database('https://mobile-darmasaba-default-rtdb.asia-southeast1.firebasedatabase.app').ref(`/discussion-division/${detail}`); const reference = firebase.app().database('https://mobile-darmasaba-default-rtdb.asia-southeast1.firebasedatabase.app').ref(`/discussion-division/${detail}`);
const [refreshing, setRefreshing] = useState(false) const [refreshing, setRefreshing] = useState(false)
const headerHeight = useHeaderHeight();
useEffect(() => { useEffect(() => {
@@ -283,7 +285,7 @@ export default function DiscussionDetail() {
</ScrollView> </ScrollView>
<KeyboardAvoidingView <KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : undefined} behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={110} keyboardVerticalOffset={headerHeight}
> >
<View <View
style={[ style={[

View File

@@ -8,6 +8,8 @@ import { setUpdateTask } from "@/lib/taskUpdate";
import { useAuthSession } from "@/providers/AuthProvider"; import { useAuthSession } from "@/providers/AuthProvider";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { router, Stack, useLocalSearchParams } from "expo-router"; import { router, Stack, useLocalSearchParams } from "expo-router";
import 'intl';
import 'intl/locale-data/jsonp/id';
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { import {
KeyboardAvoidingView, Platform, SafeAreaView, KeyboardAvoidingView, Platform, SafeAreaView,
@@ -17,6 +19,7 @@ import {
import Toast from "react-native-toast-message"; import Toast from "react-native-toast-message";
import DateTimePicker, { DateType } from "react-native-ui-datepicker"; import DateTimePicker, { DateType } from "react-native-ui-datepicker";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { useHeaderHeight } from '@react-navigation/elements';
export default function TaskDivisionAddTask() { export default function TaskDivisionAddTask() {
const { token, decryptToken } = useAuthSession(); const { token, decryptToken } = useAuthSession();
@@ -25,6 +28,7 @@ export default function TaskDivisionAddTask() {
const { id, detail } = useLocalSearchParams<{ id: string; detail: string }>(); const { id, detail } = useLocalSearchParams<{ id: string; detail: string }>();
const [disable, setDisable] = useState(true); const [disable, setDisable] = useState(true);
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const headerHeight = useHeaderHeight();
const [range, setRange] = useState<{ const [range, setRange] = useState<{
startDate: DateType; startDate: DateType;
endDate: DateType; endDate: DateType;
@@ -127,7 +131,7 @@ export default function TaskDivisionAddTask() {
/> />
<KeyboardAvoidingView <KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : undefined} behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={110} keyboardVerticalOffset={headerHeight}
> >
<ScrollView> <ScrollView>
<View style={[Styles.p15, Styles.mb100]}> <View style={[Styles.p15, Styles.mb100]}>
@@ -141,6 +145,13 @@ export default function TaskDivisionAddTask() {
selected: Styles.selectedDate, selected: Styles.selectedDate,
selected_label: Styles.cWhite, selected_label: Styles.cWhite,
range_fill: Styles.selectRangeDate, range_fill: Styles.selectRangeDate,
month_label: Styles.cBlack,
month_selector_label: Styles.cBlack,
year_label: Styles.cBlack,
year_selector_label: Styles.cBlack,
day_label: Styles.cBlack,
time_label: Styles.cBlack,
weekday_label: Styles.cBlack,
}} }}
/> />
</View> </View>

View File

@@ -6,6 +6,8 @@ import Styles from "@/constants/Styles";
import { setTaskCreate } from "@/lib/taskCreate"; import { setTaskCreate } from "@/lib/taskCreate";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { router, Stack } from "expo-router"; import { router, Stack } from "expo-router";
import 'intl';
import 'intl/locale-data/jsonp/id';
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { import {
KeyboardAvoidingView, KeyboardAvoidingView,
@@ -18,8 +20,10 @@ import DateTimePicker, {
DateType DateType
} from "react-native-ui-datepicker"; } from "react-native-ui-datepicker";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { useHeaderHeight } from '@react-navigation/elements';
export default function CreateTaskAddTugas() { export default function CreateTaskAddTugas() {
const headerHeight = useHeaderHeight();
const dispatch = useDispatch() const dispatch = useDispatch()
const [disable, setDisable] = useState(true); const [disable, setDisable] = useState(true);
const [range, setRange] = useState<{ const [range, setRange] = useState<{
@@ -101,7 +105,7 @@ export default function CreateTaskAddTugas() {
/> />
<KeyboardAvoidingView <KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : undefined} behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={110} keyboardVerticalOffset={headerHeight}
> >
<ScrollView> <ScrollView>
<View style={[Styles.p15, Styles.mb100]}> <View style={[Styles.p15, Styles.mb100]}>
@@ -115,6 +119,13 @@ export default function CreateTaskAddTugas() {
selected: Styles.selectedDate, selected: Styles.selectedDate,
selected_label: Styles.cWhite, selected_label: Styles.cWhite,
range_fill: Styles.selectRangeDate, range_fill: Styles.selectRangeDate,
month_label: Styles.cBlack,
month_selector_label: Styles.cBlack,
year_label: Styles.cBlack,
year_selector_label: Styles.cBlack,
day_label: Styles.cBlack,
time_label: Styles.cBlack,
weekday_label: Styles.cBlack,
}} }}
/> />
</View> </View>

View File

@@ -6,8 +6,11 @@ import Styles from "@/constants/Styles";
import { apiEditTaskTugas, apiGetTaskTugas } from "@/lib/api"; import { apiEditTaskTugas, apiGetTaskTugas } from "@/lib/api";
import { setUpdateTask } from "@/lib/taskUpdate"; import { setUpdateTask } from "@/lib/taskUpdate";
import { useAuthSession } from "@/providers/AuthProvider"; import { useAuthSession } from "@/providers/AuthProvider";
import { useHeaderHeight } from '@react-navigation/elements';
import dayjs from "dayjs"; import dayjs from "dayjs";
import { router, Stack, useLocalSearchParams } from "expo-router"; import { router, Stack, useLocalSearchParams } from "expo-router";
import 'intl';
import 'intl/locale-data/jsonp/id';
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { import {
KeyboardAvoidingView, KeyboardAvoidingView,
@@ -21,6 +24,7 @@ import DateTimePicker, { DateType } from "react-native-ui-datepicker";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
export default function UpdateProjectTaskDivision() { export default function UpdateProjectTaskDivision() {
const headerHeight = useHeaderHeight();
const { detail } = useLocalSearchParams<{ detail: string }>(); const { detail } = useLocalSearchParams<{ detail: string }>();
const dispatch = useDispatch(); const dispatch = useDispatch();
const update = useSelector((state: any) => state.taskUpdate); const update = useSelector((state: any) => state.taskUpdate);
@@ -149,7 +153,7 @@ export default function UpdateProjectTaskDivision() {
/> />
<KeyboardAvoidingView <KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : undefined} behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={110} keyboardVerticalOffset={headerHeight}
> >
<ScrollView> <ScrollView>
<View style={[Styles.p15, Styles.mb100]}> <View style={[Styles.p15, Styles.mb100]}>
@@ -166,6 +170,13 @@ export default function UpdateProjectTaskDivision() {
selected: Styles.selectedDate, selected: Styles.selectedDate,
selected_label: Styles.cWhite, selected_label: Styles.cWhite,
range_fill: Styles.selectRangeDate, range_fill: Styles.selectRangeDate,
month_label: Styles.cBlack,
month_selector_label: Styles.cBlack,
year_label: Styles.cBlack,
year_selector_label: Styles.cBlack,
day_label: Styles.cBlack,
time_label: Styles.cBlack,
weekday_label: Styles.cBlack,
}} }}
/> />
)} )}

View File

@@ -42,14 +42,9 @@ export default function Index() {
const dispatch = useDispatch() const dispatch = useDispatch()
const update = useSelector((state: any) => state.groupUpdate) const update = useSelector((state: any) => state.groupUpdate)
const [error, setError] = useState({
const [data11, setData1] = useState(Array.from({ length: 20 }, (_, i) => `Item ${i}`)); title: false,
});
const renderItem = ({ item }: { item: string }) => (
<View style={{ padding: 20, borderBottomWidth: 1, borderColor: '#ccc' }}>
<Text>{item}</Text>
</View>
);
async function handleEdit() { async function handleEdit() {
@@ -109,6 +104,17 @@ export default function Index() {
setRefreshing(false) setRefreshing(false)
}; };
function validationForm(val: any, cat: 'title') {
if (cat === 'title') {
setTitleChoose(val)
if (val == "" || val.length < 3) {
setError((prev) => ({ ...prev, title: true }))
} else {
setError((prev) => ({ ...prev, title: false }))
}
}
}
return ( return (
<SafeAreaView> <SafeAreaView>
@@ -207,10 +213,18 @@ export default function Index() {
<DrawerBottom animation="none" keyboard height={30} isVisible={isVisibleEdit} setVisible={() => setVisibleEdit(false)} title="Edit Lembaga Desa"> <DrawerBottom animation="none" keyboard height={30} isVisible={isVisibleEdit} setVisible={() => setVisibleEdit(false)} title="Edit Lembaga Desa">
<View style={{ flex: 1 }}> <View style={{ flex: 1 }}>
<View> <View>
<InputForm type="default" placeholder="Nama Lembaga Desa" required label="Lembaga Desa" value={titleChoose} onChange={setTitleChoose} /> <InputForm
type="default"
placeholder="Nama Lembaga Desa"
required
label="Lembaga Desa"
value={titleChoose}
error={error.title}
errorText="Lembaga Desa tidak boleh kosong & minimal 3 karakter"
onChange={(val) => { validationForm(val, 'title') }} />
</View> </View>
<View> <View>
<ButtonForm text="SIMPAN" onPress={() => { handleEdit() }} /> <ButtonForm text="SIMPAN" disabled={Object.values(error).some((v) => v == true) || titleChoose == ""} onPress={() => { handleEdit() }} />
</View> </View>
</View> </View>
</DrawerBottom> </DrawerBottom>

View File

@@ -24,8 +24,10 @@ import {
} from "react-native"; } from "react-native";
import Toast from "react-native-toast-message"; import Toast from "react-native-toast-message";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { useHeaderHeight } from '@react-navigation/elements';
export default function CreateMember() { export default function CreateMember() {
const headerHeight = useHeaderHeight();
const dispatch = useDispatch() const dispatch = useDispatch()
const update = useSelector((state: any) => state.memberUpdate) const update = useSelector((state: any) => state.memberUpdate)
const { token, decryptToken } = useAuthSession() const { token, decryptToken } = useAuthSession()
@@ -230,7 +232,7 @@ export default function CreateMember() {
<KeyboardAvoidingView <KeyboardAvoidingView
style={[Styles.h100]} style={[Styles.h100]}
behavior={Platform.OS === 'ios' ? 'padding' : undefined} behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={110} keyboardVerticalOffset={headerHeight}
> >
<ScrollView> <ScrollView>
<View style={[Styles.p15]}> <View style={[Styles.p15]}>

View File

@@ -22,6 +22,7 @@ import {
} from "react-native"; } from "react-native";
import Toast from "react-native-toast-message"; import Toast from "react-native-toast-message";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { useHeaderHeight } from '@react-navigation/elements';
type Props = { type Props = {
id: string; id: string;
@@ -38,6 +39,7 @@ type Props = {
}; };
export default function EditMember() { export default function EditMember() {
const headerHeight = useHeaderHeight();
const dispatch = useDispatch() const dispatch = useDispatch()
const update = useSelector((state: any) => state.memberUpdate) const update = useSelector((state: any) => state.memberUpdate)
const { token, decryptToken } = useAuthSession() const { token, decryptToken } = useAuthSession()
@@ -259,7 +261,7 @@ export default function EditMember() {
<KeyboardAvoidingView <KeyboardAvoidingView
style={[Styles.h100]} style={[Styles.h100]}
behavior={Platform.OS === 'ios' ? 'padding' : undefined} behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={110} keyboardVerticalOffset={headerHeight}
> >
<ScrollView> <ScrollView>
<View style={[Styles.p15, Styles.mb100]}> <View style={[Styles.p15, Styles.mb100]}>

View File

@@ -6,6 +6,8 @@ import Styles from "@/constants/Styles";
import { apiCreateProjectTask } from "@/lib/api"; import { apiCreateProjectTask } from "@/lib/api";
import { setUpdateProject } from "@/lib/projectUpdate"; import { setUpdateProject } from "@/lib/projectUpdate";
import { useAuthSession } from "@/providers/AuthProvider"; import { useAuthSession } from "@/providers/AuthProvider";
import 'intl';
import 'intl/locale-data/jsonp/id';
import dayjs from "dayjs"; import dayjs from "dayjs";
import { router, Stack, useLocalSearchParams } from "expo-router"; import { router, Stack, useLocalSearchParams } from "expo-router";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
@@ -21,8 +23,10 @@ import DateTimePicker, {
DateType DateType
} from "react-native-ui-datepicker"; } from "react-native-ui-datepicker";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { useHeaderHeight } from '@react-navigation/elements';
export default function ProjectAddTask() { export default function ProjectAddTask() {
const headerHeight = useHeaderHeight();
const { token, decryptToken } = useAuthSession() const { token, decryptToken } = useAuthSession()
const dispatch = useDispatch() const dispatch = useDispatch()
const update = useSelector((state: any) => state.projectUpdate) const update = useSelector((state: any) => state.projectUpdate)
@@ -77,7 +81,7 @@ export default function ProjectAddTask() {
dispatch(setUpdateProject({ ...update, task: !update.task, progress: !update.progress })) dispatch(setUpdateProject({ ...update, task: !update.task, progress: !update.progress }))
Toast.show({ type: 'small', text1: 'Berhasil menambah data', }) Toast.show({ type: 'small', text1: 'Berhasil menambah data', })
router.back(); router.back();
}else{ } else {
Toast.show({ type: 'small', text1: response.message, }) Toast.show({ type: 'small', text1: response.message, })
} }
} catch (error) { } catch (error) {
@@ -112,7 +116,7 @@ export default function ProjectAddTask() {
/> />
<KeyboardAvoidingView <KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : undefined} behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={110} keyboardVerticalOffset={headerHeight}
> >
<ScrollView> <ScrollView>
<View style={[Styles.p15, Styles.mb100]}> <View style={[Styles.p15, Styles.mb100]}>
@@ -126,6 +130,13 @@ export default function ProjectAddTask() {
selected: Styles.selectedDate, selected: Styles.selectedDate,
selected_label: Styles.cWhite, selected_label: Styles.cWhite,
range_fill: Styles.selectRangeDate, range_fill: Styles.selectRangeDate,
month_label: Styles.cBlack,
month_selector_label: Styles.cBlack,
year_label: Styles.cBlack,
year_selector_label: Styles.cBlack,
day_label: Styles.cBlack,
time_label: Styles.cBlack,
weekday_label: Styles.cBlack,
}} }}
/> />
</View> </View>

View File

@@ -6,6 +6,8 @@ import Styles from "@/constants/Styles";
import { setTaskCreate } from "@/lib/taskCreate"; import { setTaskCreate } from "@/lib/taskCreate";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { router, Stack } from "expo-router"; import { router, Stack } from "expo-router";
import 'intl';
import 'intl/locale-data/jsonp/id';
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { import {
KeyboardAvoidingView, KeyboardAvoidingView,
@@ -18,8 +20,10 @@ import DateTimePicker, {
DateType DateType
} from "react-native-ui-datepicker"; } from "react-native-ui-datepicker";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { useHeaderHeight } from '@react-navigation/elements';
export default function CreateProjectAddTask() { export default function CreateProjectAddTask() {
const headerHeight = useHeaderHeight();
const dispatch = useDispatch() const dispatch = useDispatch()
const [disable, setDisable] = useState(true); const [disable, setDisable] = useState(true);
const [range, setRange] = useState<{ const [range, setRange] = useState<{
@@ -101,7 +105,7 @@ export default function CreateProjectAddTask() {
/> />
<KeyboardAvoidingView <KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : undefined} behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={110} keyboardVerticalOffset={headerHeight}
> >
<ScrollView> <ScrollView>
<View style={[Styles.p15, Styles.mb100]}> <View style={[Styles.p15, Styles.mb100]}>
@@ -115,6 +119,13 @@ export default function CreateProjectAddTask() {
selected: Styles.selectedDate, selected: Styles.selectedDate,
selected_label: Styles.cWhite, selected_label: Styles.cWhite,
range_fill: Styles.selectRangeDate, range_fill: Styles.selectRangeDate,
month_label: Styles.cBlack,
month_selector_label: Styles.cBlack,
year_label: Styles.cBlack,
year_selector_label: Styles.cBlack,
day_label: Styles.cBlack,
time_label: Styles.cBlack,
weekday_label: Styles.cBlack,
}} }}
/> />
</View> </View>

View File

@@ -6,8 +6,11 @@ import Styles from "@/constants/Styles";
import { apiEditProjectTask, apiGetProjectTask } from "@/lib/api"; import { apiEditProjectTask, apiGetProjectTask } from "@/lib/api";
import { setUpdateProject } from "@/lib/projectUpdate"; import { setUpdateProject } from "@/lib/projectUpdate";
import { useAuthSession } from "@/providers/AuthProvider"; import { useAuthSession } from "@/providers/AuthProvider";
import { useHeaderHeight } from '@react-navigation/elements';
import dayjs from "dayjs"; import dayjs from "dayjs";
import { router, Stack, useLocalSearchParams } from "expo-router"; import { router, Stack, useLocalSearchParams } from "expo-router";
import 'intl';
import 'intl/locale-data/jsonp/id';
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { KeyboardAvoidingView, Platform, SafeAreaView, ScrollView, View } from "react-native"; import { KeyboardAvoidingView, Platform, SafeAreaView, ScrollView, View } from "react-native";
import Toast from "react-native-toast-message"; import Toast from "react-native-toast-message";
@@ -15,6 +18,7 @@ import DateTimePicker, { DateType } from "react-native-ui-datepicker";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
export default function UpdateProjectTask() { export default function UpdateProjectTask() {
const headerHeight = useHeaderHeight();
const dispatch = useDispatch() const dispatch = useDispatch()
const update = useSelector((state: any) => state.projectUpdate) const update = useSelector((state: any) => state.projectUpdate)
const { token, decryptToken } = useAuthSession(); const { token, decryptToken } = useAuthSession();
@@ -123,7 +127,7 @@ export default function UpdateProjectTask() {
/> />
<KeyboardAvoidingView <KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : undefined} behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={110} keyboardVerticalOffset={headerHeight}
> >
<ScrollView> <ScrollView>
<View style={[Styles.p15, Styles.mb100]}> <View style={[Styles.p15, Styles.mb100]}>
@@ -136,13 +140,19 @@ export default function UpdateProjectTask() {
startDate={range.startDate} startDate={range.startDate}
endDate={range.endDate} endDate={range.endDate}
onChange={(param) => setRange(param)} onChange={(param) => setRange(param)}
// styles={defaultStyles}
month={month} month={month}
year={year} year={year}
styles={{ styles={{
selected: Styles.selectedDate, selected: Styles.selectedDate,
selected_label: Styles.cWhite, selected_label: Styles.cWhite,
range_fill: Styles.selectRangeDate, range_fill: Styles.selectRangeDate,
month_label: Styles.cBlack,
month_selector_label: Styles.cBlack,
year_label: Styles.cBlack,
year_selector_label: Styles.cBlack,
day_label: Styles.cBlack,
time_label: Styles.cBlack,
weekday_label: Styles.cBlack,
}} }}
/> />
} }

View File

@@ -48,9 +48,9 @@ export default function HeaderRightGroupList() {
if (cat === 'title') { if (cat === 'title') {
setTitle(val) setTitle(val)
if (val == "" || val.length < 3) { if (val == "" || val.length < 3) {
setError({ ...error, title: true }) setError((prev) => ({ ...prev, title: true }))
} else { } else {
setError({ ...error, title: false }) setError((prev) => ({ ...prev, title: false }))
} }
} }
} }
@@ -91,7 +91,7 @@ export default function HeaderRightGroupList() {
/> />
</View> </View>
<View> <View>
<ButtonForm text="SIMPAN" onPress={() => { onCheck() }} /> <ButtonForm text="SIMPAN" disabled={Object.values(error).some((v) => v == true) || title == ""} onPress={() => { onCheck() }} />
</View> </View>
</View> </View>
</DrawerBottom> </DrawerBottom>

View File

@@ -1,11 +1,11 @@
import { ColorsStatus } from "@/constants/ColorsStatus"; import { ColorsStatus } from "@/constants/ColorsStatus";
import Styles from "@/constants/Styles"; import Styles from "@/constants/Styles";
import { stringToDate } from "@/lib/fun_stringToDate";
import DateTimePicker from "@react-native-community/datetimepicker"; import DateTimePicker from "@react-native-community/datetimepicker";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { useState } from "react"; import { useState } from "react";
import { Pressable, View } from "react-native"; import { Platform, Pressable, View } from "react-native";
import Text from "./Text"; import Text from "./Text";
import ModalFloat from "./modalFloat";
type Props = { type Props = {
label?: string; label?: string;
@@ -58,14 +58,34 @@ export function InputDate({ label, value, placeholder, onChange, info, disable,
{info != undefined && (<Text style={[Styles.textInformation, Styles.mt05, Styles.cGray]}>{info}</Text>)} {info != undefined && (<Text style={[Styles.textInformation, Styles.mt05, Styles.cGray]}>{info}</Text>)}
</View> </View>
{ {
modal && ( Platform.OS === 'ios' ? (
<DateTimePicker modal && (
value={new Date()} <ModalFloat
mode={mode} isVisible={modal}
display="default" setVisible={setModal}
onChange={(event, date) => { onChangeDate(event.type, date) }} onSubmit={() => { }}
onTouchCancel={() => setModal(false)} buttonHide
/> disableSubmit
title={mode == "date" ? "Pilih Tanggal" : mode == "time" ? "Pilih Jam" : "Pilih Tanggal & Jam"}>
<DateTimePicker
value={new Date()}
mode={mode}
display="spinner"
onChange={(event, date) => { onChangeDate(event.type, date) }}
onTouchCancel={() => setModal(false)}
/>
</ModalFloat>
)
) : (
modal && (
<DateTimePicker
value={new Date()}
mode={mode}
display="inline"
onChange={(event, date) => { onChangeDate(event.type, date) }}
onTouchCancel={() => setModal(false)}
/>
)
) )
} }
</> </>

View File

@@ -1,5 +1,5 @@
import Styles from "@/constants/Styles"; import Styles from "@/constants/Styles";
import { Dimensions, TextInput, View } from "react-native"; import { Dimensions, Platform, TextInput, View } from "react-native";
import Text from "./Text"; import Text from "./Text";
type Props = { type Props = {
@@ -36,7 +36,14 @@ export function InputForm({ label, value, placeholder, onChange, info, disable,
</Text> </Text>
) )
} }
<View style={[Styles.inputRoundForm, itemRight != undefined ? Styles.inputRoundFormRight : Styles.inputRoundFormLeft, round && Styles.round30, { backgroundColor: bg && bg == 'white' ? 'white' : 'transparent' }, error && { borderColor: "red" }]}> <View style={[
Styles.inputRoundForm,
itemRight != undefined ? Styles.inputRoundFormRight : Styles.inputRoundFormLeft,
round && Styles.round30,
{ backgroundColor: bg && bg == 'white' ? 'white' : 'transparent' },
error && { borderColor: "red" },
Platform.OS == 'ios' && { paddingVertical: 10 },
]}>
{itemRight != undefined ? itemRight : itemLeft} {itemRight != undefined ? itemRight : itemLeft}
<TextInput <TextInput
editable={!disable} editable={!disable}

View File

@@ -1,7 +1,7 @@
import Styles from '@/constants/Styles'; import Styles from '@/constants/Styles';
import { Pressable, View } from 'react-native'; import { Pressable, View } from 'react-native';
import Text from './Text';
import Modal from 'react-native-modal'; import Modal from 'react-native-modal';
import Text from './Text';
type Props = { type Props = {
isVisible: boolean isVisible: boolean
@@ -10,9 +10,10 @@ type Props = {
children: React.ReactNode children: React.ReactNode
onSubmit: () => void onSubmit: () => void
disableSubmit?: boolean disableSubmit?: boolean
buttonHide?: boolean
} }
export default function ModalFloat({ isVisible, setVisible, title, children, onSubmit, disableSubmit }: Props) { export default function ModalFloat({ isVisible, setVisible, title, children, onSubmit, disableSubmit, buttonHide }: Props) {
return ( return (
<Modal <Modal
animationIn={"fadeIn"} animationIn={"fadeIn"}
@@ -28,14 +29,18 @@ export default function ModalFloat({ isVisible, setVisible, title, children, onS
<View style={[Styles.mb10]}> <View style={[Styles.mb10]}>
{children} {children}
</View> </View>
<View style={[Styles.rowItemsCenter, { justifyContent: 'flex-end' }]}> {
<Pressable style={[Styles.ph15, Styles.pv05, Styles.round10, Styles.mr10]} onPress={() => { setVisible(false) }}> !buttonHide && (
<Text style={[Styles.textDefault]}>Batal</Text> <View style={[Styles.rowItemsCenter, { justifyContent: 'flex-end' }]}>
</Pressable> <Pressable style={[Styles.ph15, Styles.pv05, Styles.round10, Styles.mr10]} onPress={() => { setVisible(false) }}>
<Pressable style={[Styles.ph15, Styles.pv05, Styles.round10]} onPress={onSubmit} disabled={disableSubmit}> <Text style={[Styles.textDefault]}>Batal</Text>
<Text style={[Styles.textDefault, disableSubmit && Styles.cGray]}>Simpan</Text> </Pressable>
</Pressable> <Pressable style={[Styles.ph15, Styles.pv05, Styles.round10]} onPress={onSubmit} disabled={disableSubmit}>
</View> <Text style={[Styles.textDefault, disableSubmit && Styles.cGray]}>Simpan</Text>
</Pressable>
</View>
)
}
</View> </View>
</Modal> </Modal>
) )

View File

@@ -9,13 +9,13 @@ import { useAuthSession } from "@/providers/AuthProvider"
import { AntDesign } from "@expo/vector-icons" import { AntDesign } from "@expo/vector-icons"
import { useEffect, useState } from "react" import { useEffect, useState } from "react"
import { Pressable, ScrollView, View } from "react-native" import { Pressable, ScrollView, View } from "react-native"
import Text from "./Text";
import { useDispatch, useSelector } from "react-redux" import { useDispatch, useSelector } from "react-redux"
import { ButtonForm } from "./buttonForm" import { ButtonForm } from "./buttonForm"
import DrawerBottom from "./drawerBottom" import DrawerBottom from "./drawerBottom"
import ImageUser from "./imageNew" import ImageUser from "./imageNew"
import ImageWithLabel from "./imageWithLabel" import ImageWithLabel from "./imageWithLabel"
import InputSearch from "./inputSearch" import InputSearch from "./inputSearch"
import Text from "./Text"
type Props = { type Props = {
open: boolean open: boolean
@@ -89,8 +89,7 @@ export default function ModalSelect({ open, close, title, category, idParent, on
useEffect(() => { useEffect(() => {
if (category == 'group') { if (category == 'group') {
if (entitiesGroup.length == 0) handleLoadGroup()
handleLoadGroup()
setData(entitiesGroup) setData(entitiesGroup)
} else if (category == 'position') { } else if (category == 'position') {
handleLoadPosition() handleLoadPosition()
@@ -174,9 +173,9 @@ export default function ModalSelect({ open, close, title, category, idParent, on
{ {
(category == 'member') (category == 'member')
? ?
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'} />
: :
chooseValue.val == item.id && <AntDesign name="check" size={20} color={'black'}/> chooseValue.val == item.id && <AntDesign name="check" size={20} color={'black'} />
} }
</Pressable> </Pressable>
)) ))
@@ -192,7 +191,7 @@ export default function ModalSelect({ open, close, title, category, idParent, on
}}> }}>
<Text style={[chooseValue.val == item.val ? Styles.textDefaultSemiBold : Styles.textDefault]}>{item.label}</Text> <Text style={[chooseValue.val == item.val ? Styles.textDefaultSemiBold : Styles.textDefault]}>{item.label}</Text>
{ {
valChoose == item.val && <AntDesign name="check" size={20} color={'black'}/> valChoose == item.val && <AntDesign name="check" size={20} color={'black'} />
} }
</Pressable> </Pressable>
)) ))

View File

@@ -30,19 +30,16 @@ export default function HeaderRightProjectList() {
}} }}
/> />
} }
{ <MenuItemRow
(entityUser.role == 'supadmin' || entityUser.role == 'developer') && icon={<AntDesign name="filter" color="black" size={25} />}
<MenuItemRow title="Filter"
icon={<AntDesign name="filter" color="black" size={25} />} onPress={() => {
title="Filter" setVisible(false)
onPress={() => { setTimeout(() => {
setVisible(false) setFilter(true)
setTimeout(() => { }, 600)
setFilter(true) }}
}, 600) />
}}
/>
}
</View> </View>
</DrawerBottom> </DrawerBottom>
<ModalFilter <ModalFilter