Merge pull request 'amalia/29-agustus-25' (#32) from amalia/29-agustus-25 into join
Reviewed-on: bip/mobile-darmasaba#32
This commit is contained in:
@@ -13,9 +13,10 @@ import { apiDeleteCalendarMember, apiGetCalendarOne, apiGetDivisionOneFeature }
|
|||||||
import { setUpdateCalendar } from "@/lib/calendarUpdate"
|
import { setUpdateCalendar } from "@/lib/calendarUpdate"
|
||||||
import { useAuthSession } from "@/providers/AuthProvider"
|
import { useAuthSession } from "@/providers/AuthProvider"
|
||||||
import { MaterialCommunityIcons } from "@expo/vector-icons"
|
import { MaterialCommunityIcons } from "@expo/vector-icons"
|
||||||
|
import Clipboard from "@react-native-clipboard/clipboard"
|
||||||
import { router, Stack, useLocalSearchParams } from "expo-router"
|
import { router, Stack, useLocalSearchParams } from "expo-router"
|
||||||
import { useEffect, useState } from "react"
|
import { useEffect, useState } from "react"
|
||||||
import { RefreshControl, SafeAreaView, ScrollView, View } from "react-native"
|
import { Pressable, RefreshControl, SafeAreaView, ScrollView, View } 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"
|
||||||
|
|
||||||
@@ -115,6 +116,11 @@ export default function DetailEventCalendar() {
|
|||||||
handleLoadMember();
|
handleLoadMember();
|
||||||
}, [update.member]);
|
}, [update.member]);
|
||||||
|
|
||||||
|
const handleCopy = (text: string) => {
|
||||||
|
Clipboard.setString(text);
|
||||||
|
Toast.show({ type: 'small', text1: 'Berhasil menyalin link', })
|
||||||
|
};
|
||||||
|
|
||||||
async function handleDeleteUser() {
|
async function handleDeleteUser() {
|
||||||
try {
|
try {
|
||||||
const hasil = await decryptToken(String(token?.current));
|
const hasil = await decryptToken(String(token?.current));
|
||||||
@@ -216,10 +222,14 @@ export default function DetailEventCalendar() {
|
|||||||
loading ?
|
loading ?
|
||||||
<Skeleton width={80} height={10} borderRadius={10} widthType="percent" />
|
<Skeleton width={80} height={10} borderRadius={10} widthType="percent" />
|
||||||
:
|
:
|
||||||
<Text style={[Styles.textDefault]}>{data?.linkMeet ? data.linkMeet : '-'}</Text>
|
data?.linkMeet ?
|
||||||
|
<Pressable onPress={() => { handleCopy(data.linkMeet) }}>
|
||||||
|
<Text style={[Styles.textDefault]}>{data.linkMeet}</Text>
|
||||||
|
</Pressable>
|
||||||
|
: <Text style={[Styles.textDefault]}>-</Text>
|
||||||
}
|
}
|
||||||
</View>
|
</View>
|
||||||
<View style={[Styles.rowItemsCenter, Styles.mt10, {alignItems:'flex-start'}]}>
|
<View style={[Styles.rowItemsCenter, Styles.mt10, { alignItems: 'flex-start' }]}>
|
||||||
<MaterialCommunityIcons name="card-text-outline" size={30} color="black" style={Styles.mr10} />
|
<MaterialCommunityIcons name="card-text-outline" size={30} color="black" style={Styles.mr10} />
|
||||||
{
|
{
|
||||||
loading ?
|
loading ?
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ type PropsPath = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function DocumentDivision() {
|
export default function DocumentDivision() {
|
||||||
|
const [loadingRename, setLoadingRename] = useState(false)
|
||||||
const [isShare, setShare] = useState(false)
|
const [isShare, setShare] = useState(false)
|
||||||
const { token, decryptToken } = useAuthSession()
|
const { token, decryptToken } = useAuthSession()
|
||||||
const { id } = useLocalSearchParams<{ id: string }>()
|
const { id } = useLocalSearchParams<{ id: string }>()
|
||||||
@@ -201,6 +202,7 @@ export default function DocumentDivision() {
|
|||||||
|
|
||||||
async function handleRename() {
|
async function handleRename() {
|
||||||
try {
|
try {
|
||||||
|
setLoadingRename(true)
|
||||||
const hasil = await decryptToken(String(token?.current));
|
const hasil = await decryptToken(String(token?.current));
|
||||||
const response = await apiDocumentRename({ user: hasil, ...bodyRename });
|
const response = await apiDocumentRename({ user: hasil, ...bodyRename });
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
@@ -214,7 +216,8 @@ export default function DocumentDivision() {
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
||||||
} finally {
|
} finally {
|
||||||
setRename(false);
|
setLoadingRename(false)
|
||||||
|
setRename(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,25 +363,20 @@ export default function DocumentDivision() {
|
|||||||
<View style={[Styles.p15, Styles.mb100]}>
|
<View style={[Styles.p15, Styles.mb100]}>
|
||||||
<View style={[Styles.rowItemsCenter]}>
|
<View style={[Styles.rowItemsCenter]}>
|
||||||
{
|
{
|
||||||
loading ?
|
dataJalur.map((item, index) => (
|
||||||
arrSkeleton.map((item, index) => (
|
<Pressable
|
||||||
<Skeleton key={index} width={60} height={10} borderRadius={10} style={[Styles.mr05]} />
|
key={index}
|
||||||
))
|
style={[Styles.rowItemsCenter]}
|
||||||
:
|
onPress={() => {
|
||||||
dataJalur.map((item, index) => (
|
setPath(item.id);
|
||||||
<Pressable
|
}}
|
||||||
key={index}
|
>
|
||||||
style={[Styles.rowItemsCenter]}
|
{item.id != "home" && (
|
||||||
onPress={() => {
|
<AntDesign name="right" style={[Styles.mh05, Styles.mt02]} color="black" />
|
||||||
setPath(item.id);
|
)}
|
||||||
}}
|
<Text> {item.name} </Text>
|
||||||
>
|
</Pressable>
|
||||||
{item.id != "home" && (
|
))
|
||||||
<AntDesign name="right" style={[Styles.mh05, Styles.mt02]} color="black" />
|
|
||||||
)}
|
|
||||||
<Text> {item.name} </Text>
|
|
||||||
</Pressable>
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
</View>
|
</View>
|
||||||
<View>
|
<View>
|
||||||
@@ -538,7 +536,7 @@ export default function DocumentDivision() {
|
|||||||
isVisible={isRename}
|
isVisible={isRename}
|
||||||
setVisible={() => { setRename(false) }}
|
setVisible={() => { setRename(false) }}
|
||||||
onSubmit={() => { handleRename() }}
|
onSubmit={() => { handleRename() }}
|
||||||
disableSubmit={bodyRename.name == ""}
|
disableSubmit={bodyRename.name == "" || loadingRename}
|
||||||
>
|
>
|
||||||
<View>
|
<View>
|
||||||
<InputForm
|
<InputForm
|
||||||
|
|||||||
@@ -24,9 +24,11 @@ export default function HeaderRightDocument({ path }: { path: string }) {
|
|||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const update = useSelector((state: any) => state.dokumenUpdate)
|
const update = useSelector((state: any) => state.dokumenUpdate)
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [loadingFolder, setLoadingFolder] = useState(false)
|
||||||
|
|
||||||
async function handleCreateFolder() {
|
async function handleCreateFolder() {
|
||||||
try {
|
try {
|
||||||
|
setLoadingFolder(true)
|
||||||
const hasil = await decryptToken(String(token?.current))
|
const hasil = await decryptToken(String(token?.current))
|
||||||
const response = await apiCreateFolderDocument({ data: { user: hasil, name, path, idDivision: id } })
|
const response = await apiCreateFolderDocument({ data: { user: hasil, name, path, idDivision: id } })
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
@@ -39,6 +41,7 @@ export default function HeaderRightDocument({ path }: { path: string }) {
|
|||||||
console.error(error)
|
console.error(error)
|
||||||
Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
||||||
} finally {
|
} finally {
|
||||||
|
setLoadingFolder(false)
|
||||||
setNewFolder(false)
|
setNewFolder(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,7 +151,7 @@ export default function HeaderRightDocument({ path }: { path: string }) {
|
|||||||
title="Buat Folder Baru"
|
title="Buat Folder Baru"
|
||||||
isVisible={newFolder}
|
isVisible={newFolder}
|
||||||
setVisible={() => { setNewFolder(false) }}
|
setVisible={() => { setNewFolder(false) }}
|
||||||
disableSubmit={name == ""}
|
disableSubmit={name == "" || loadingFolder}
|
||||||
onSubmit={() => { handleCreateFolder() }}
|
onSubmit={() => { handleCreateFolder() }}
|
||||||
>
|
>
|
||||||
<View>
|
<View>
|
||||||
|
|||||||
65
components/document/modalNewFolder.tsx
Normal file
65
components/document/modalNewFolder.tsx
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import Styles from "@/constants/Styles";
|
||||||
|
import { apiCreateFolderDocument } from "@/lib/api";
|
||||||
|
import { useAuthSession } from "@/providers/AuthProvider";
|
||||||
|
import { useLocalSearchParams } from "expo-router";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { Pressable, View } from "react-native";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
import Text from "../Text";
|
||||||
|
import { InputForm } from "../inputForm";
|
||||||
|
import ModalFloat from "../modalFloat";
|
||||||
|
|
||||||
|
export function ModalNewFolder({ path, onCreated }: { path: string, onCreated: () => void }) {
|
||||||
|
const { token, decryptToken } = useAuthSession()
|
||||||
|
const [newFolder, setNewFolder] = useState(false)
|
||||||
|
const [name, setName] = useState("")
|
||||||
|
const [loadingFolder, setLoadingFolder] = useState(false)
|
||||||
|
const { id } = useLocalSearchParams<{ id: string }>();
|
||||||
|
|
||||||
|
|
||||||
|
async function handleCreateFolder() {
|
||||||
|
try {
|
||||||
|
setLoadingFolder(true)
|
||||||
|
const hasil = await decryptToken(String(token?.current))
|
||||||
|
const response = await apiCreateFolderDocument({ data: { user: hasil, name, path, idDivision: id } })
|
||||||
|
if (response.success) {
|
||||||
|
Toast.show({ type: 'small', text1: 'Berhasil membuat folder baru', })
|
||||||
|
} else {
|
||||||
|
Toast.show({ type: 'small', text1: response.message, })
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
||||||
|
} finally {
|
||||||
|
onCreated()
|
||||||
|
setLoadingFolder(false)
|
||||||
|
setNewFolder(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Pressable style={[Styles.pv05, Styles.borderRight, { width: '50%' }]} onPress={() => setNewFolder(true)}>
|
||||||
|
<Text style={[Styles.textDefaultSemiBold, { textAlign: 'center' }]}>FOLDER BARU</Text>
|
||||||
|
</Pressable>
|
||||||
|
|
||||||
|
<ModalFloat
|
||||||
|
title="Buat Folder Baru"
|
||||||
|
isVisible={newFolder}
|
||||||
|
setVisible={() => { setNewFolder(false) }}
|
||||||
|
disableSubmit={name == "" || loadingFolder}
|
||||||
|
onSubmit={() => { handleCreateFolder() }}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<InputForm
|
||||||
|
type="default"
|
||||||
|
placeholder="Nama Folder"
|
||||||
|
required
|
||||||
|
label="Nama Folder"
|
||||||
|
onChange={(value: string) => { setName(value) }}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</ModalFloat>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import { Pressable, View } from "react-native"
|
|||||||
import BorderBottomItem from "../borderBottomItem"
|
import BorderBottomItem from "../borderBottomItem"
|
||||||
import DrawerBottom from "../drawerBottom"
|
import DrawerBottom from "../drawerBottom"
|
||||||
import Text from "../Text"
|
import Text from "../Text"
|
||||||
|
import { ModalNewFolder } from "./modalNewFolder"
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
open: boolean
|
open: boolean
|
||||||
@@ -106,9 +107,7 @@ export default function ModalSalinMove({ open, close, category, onConfirm, dataC
|
|||||||
}
|
}
|
||||||
</View>
|
</View>
|
||||||
<View style={[Styles.rowOnly, Styles.mt15, Styles.absolute0]}>
|
<View style={[Styles.rowOnly, Styles.mt15, Styles.absolute0]}>
|
||||||
<Pressable style={[Styles.pv05, Styles.borderRight, { width: '50%' }]} onPress={() => close(false)}>
|
<ModalNewFolder path={path} onCreated={() => getData()} />
|
||||||
<Text style={[Styles.textDefaultSemiBold, { textAlign: 'center' }]}>BATAL</Text>
|
|
||||||
</Pressable>
|
|
||||||
<Pressable style={[Styles.pv05, { width: '50%' }]} onPress={() => onConfirm(path)}>
|
<Pressable style={[Styles.pv05, { width: '50%' }]} onPress={() => onConfirm(path)}>
|
||||||
<Text style={[Styles.textDefaultSemiBold, { textAlign: 'center' }]}>{category == 'copy' ? 'SALIN' : 'PINDAH'}</Text>
|
<Text style={[Styles.textDefaultSemiBold, { textAlign: 'center' }]}>{category == 'copy' ? 'SALIN' : 'PINDAH'}</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ type Props = {
|
|||||||
|
|
||||||
export default function ImageWithLabel({ src, label, onClick }: Props) {
|
export default function ImageWithLabel({ src, label, onClick }: Props) {
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity style={[Styles.contentItemCenter, Styles.mh05, { width: 70 }]} onPress={onClick}>
|
<TouchableOpacity style={[Styles.contentItemCenter, Styles.mh03, { width: 55 }]} onPress={onClick}>
|
||||||
<ImageUser src={src} border />
|
<ImageUser src={src} border />
|
||||||
<Text numberOfLines={1} ellipsizeMode="tail" style={[{ textAlign: 'center' }]}>{label}</Text>
|
<Text numberOfLines={1} ellipsizeMode="tail" style={[{ textAlign: 'center' }]}>{label}</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ type Props = {
|
|||||||
export function InputDate({ label, value, placeholder, onChange, info, disable, error, errorText, required, mode, round, width, }: Props) {
|
export function InputDate({ label, value, placeholder, onChange, info, disable, error, errorText, required, mode, round, width, }: Props) {
|
||||||
const [modal, setModal] = useState(false);
|
const [modal, setModal] = useState(false);
|
||||||
const [valueFix, setValueFix] = useState(new Date())
|
const [valueFix, setValueFix] = useState(new Date())
|
||||||
const [valueFirst, setValueFirst] = useState("")
|
const [valueFirst, setValueFirst] = useState(mode == "date" ? dayjs(new Date()).format("DD-MM-YYYY") : mode == "time" ? dayjs(new Date()).format("HH:mm") : "")
|
||||||
|
|
||||||
const onChangeDate = (type: string, selectedDate: any) => {
|
const onChangeDate = (type: string, selectedDate: any) => {
|
||||||
if (type === "set") {
|
if (type === "set") {
|
||||||
@@ -45,6 +45,8 @@ export function InputDate({ label, value, placeholder, onChange, info, disable,
|
|||||||
onChange(formatted)
|
onChange(formatted)
|
||||||
setModal(false)
|
setModal(false)
|
||||||
}
|
}
|
||||||
|
} else if (type === "dismissed") {
|
||||||
|
setModal(false)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,11 +102,8 @@ export function InputDate({ label, value, placeholder, onChange, info, disable,
|
|||||||
value={valueFix}
|
value={valueFix}
|
||||||
mode={mode}
|
mode={mode}
|
||||||
display="spinner"
|
display="spinner"
|
||||||
onChange={(event, date) => {
|
onChange={(event, date) => { onChangeDate(event.type, date) }}
|
||||||
onChangeDate(event.type, date)
|
|
||||||
}}
|
|
||||||
onTouchCancel={() => setModal(false)}
|
onTouchCancel={() => setModal(false)}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
</ModalFloat>
|
</ModalFloat>
|
||||||
)
|
)
|
||||||
@@ -115,7 +114,7 @@ export function InputDate({ label, value, placeholder, onChange, info, disable,
|
|||||||
mode={mode}
|
mode={mode}
|
||||||
display="inline"
|
display="inline"
|
||||||
onChange={(event, date) => { onChangeDate(event.type, date) }}
|
onChange={(event, date) => { onChangeDate(event.type, date) }}
|
||||||
onTouchCancel={() => setModal(false)}
|
onTouchCancel={() => { setModal(false) }}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,93 +1,19 @@
|
|||||||
import Styles from "@/constants/Styles"
|
import Styles from "@/constants/Styles"
|
||||||
import { apiCreatePosition } from "@/lib/api"
|
|
||||||
import { setUpdatePosition } from "@/lib/positionSlice"
|
|
||||||
import { useAuthSession } from "@/providers/AuthProvider"
|
|
||||||
import { AntDesign } from "@expo/vector-icons"
|
import { AntDesign } from "@expo/vector-icons"
|
||||||
import { useEffect, useState } from "react"
|
import { useState } from "react"
|
||||||
import { View } from "react-native"
|
import { View } from "react-native"
|
||||||
import Toast from "react-native-toast-message"
|
import { useSelector } from "react-redux"
|
||||||
import { useDispatch, useSelector } from "react-redux"
|
|
||||||
import { ButtonForm } from "../buttonForm"
|
|
||||||
import ButtonMenuHeader from "../buttonMenuHeader"
|
import ButtonMenuHeader from "../buttonMenuHeader"
|
||||||
import DrawerBottom from "../drawerBottom"
|
import DrawerBottom from "../drawerBottom"
|
||||||
import { InputForm } from "../inputForm"
|
|
||||||
import MenuItemRow from "../menuItemRow"
|
import MenuItemRow from "../menuItemRow"
|
||||||
import ModalFilter from "../modalFilter"
|
import ModalFilter from "../modalFilter"
|
||||||
import ModalSelect from "../modalSelect"
|
import ModalFormCreatePosition from "./modalFormCreatePosition"
|
||||||
import SelectForm from "../selectForm"
|
|
||||||
|
|
||||||
export default function HeaderRightPositionList() {
|
export default function HeaderRightPositionList() {
|
||||||
const dispatch = useDispatch()
|
|
||||||
const update = useSelector((state: any) => state.positionUpdate)
|
|
||||||
const { token, decryptToken } = useAuthSession()
|
|
||||||
const entityUser = useSelector((state: any) => state.user)
|
const entityUser = useSelector((state: any) => state.user)
|
||||||
const [isVisible, setVisible] = useState(false)
|
const [isVisible, setVisible] = useState(false)
|
||||||
const [isVisibleTambah, setVisibleTambah] = useState(false)
|
const [isVisibleTambah, setVisibleTambah] = useState(false)
|
||||||
const [isFilter, setFilter] = useState(false)
|
const [isFilter, setFilter] = useState(false)
|
||||||
const [isSelect, setSelect] = useState(false)
|
|
||||||
const [choose, setChoose] = useState({ val: '', label: '' })
|
|
||||||
const [disable, setDisable] = useState(true)
|
|
||||||
const [dataForm, setDataForm] = useState({
|
|
||||||
name: "",
|
|
||||||
idGroup: "",
|
|
||||||
})
|
|
||||||
const [error, setError] = useState({
|
|
||||||
name: false,
|
|
||||||
idGroup: false
|
|
||||||
});
|
|
||||||
|
|
||||||
function validationForm(val: any, cat: 'name' | 'idGroup') {
|
|
||||||
if (cat === 'name') {
|
|
||||||
setDataForm({ ...dataForm, name: val })
|
|
||||||
if (val == "") {
|
|
||||||
setError({ ...error, name: true })
|
|
||||||
} else {
|
|
||||||
setError({ ...error, name: false })
|
|
||||||
}
|
|
||||||
} else if (cat === "idGroup") {
|
|
||||||
setDataForm({ ...dataForm, idGroup: val })
|
|
||||||
if (val == "") {
|
|
||||||
setError({ ...error, idGroup: true })
|
|
||||||
} else {
|
|
||||||
setError({ ...error, idGroup: false })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkAll() {
|
|
||||||
let nilai = false
|
|
||||||
if (dataForm.name == "") {
|
|
||||||
nilai = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((entityUser.role == "supadmin" || entityUser.role == "developer") && (dataForm.idGroup == "" || String(dataForm.idGroup) == "null")) {
|
|
||||||
nilai = true
|
|
||||||
}
|
|
||||||
|
|
||||||
setDisable(nilai)
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
checkAll()
|
|
||||||
}, [dataForm])
|
|
||||||
|
|
||||||
async function handleTambah() {
|
|
||||||
try {
|
|
||||||
setDisable(true)
|
|
||||||
const hasil = await decryptToken(String(token?.current))
|
|
||||||
const response = await apiCreatePosition({ user: hasil, name: dataForm.name, idGroup: dataForm.idGroup })
|
|
||||||
dispatch(setUpdatePosition(!update))
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
} finally {
|
|
||||||
setDisable(false)
|
|
||||||
setVisibleTambah(false)
|
|
||||||
setVisible(false)
|
|
||||||
Toast.show({ type: 'small', text1: 'Berhasil menambahkan data', })
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -121,64 +47,13 @@ export default function HeaderRightPositionList() {
|
|||||||
</DrawerBottom>
|
</DrawerBottom>
|
||||||
|
|
||||||
<DrawerBottom animation="slide" height={45} keyboard isVisible={isVisibleTambah} setVisible={() => setVisibleTambah(false)} title="Tambah Jabatan">
|
<DrawerBottom animation="slide" height={45} keyboard isVisible={isVisibleTambah} setVisible={() => setVisibleTambah(false)} title="Tambah Jabatan">
|
||||||
<View style={{ flex: 1, justifyContent: 'space-between' }}>
|
<ModalFormCreatePosition onClose={() => setVisibleTambah(false)} />
|
||||||
<View>
|
|
||||||
{
|
|
||||||
(entityUser.role == 'supadmin' || entityUser.role == 'developer') &&
|
|
||||||
<SelectForm
|
|
||||||
label="Lembaga Desa"
|
|
||||||
placeholder="Pilih Lembaga Desa"
|
|
||||||
value={choose.label}
|
|
||||||
required
|
|
||||||
onPress={() => {
|
|
||||||
setVisibleTambah(false)
|
|
||||||
setTimeout(() => {
|
|
||||||
setSelect(true)
|
|
||||||
}, 600)
|
|
||||||
}}
|
|
||||||
error={error.idGroup}
|
|
||||||
errorText="Lembaga Desa harus diisi"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
<InputForm
|
|
||||||
type="default"
|
|
||||||
placeholder="Nama Jabatan"
|
|
||||||
required
|
|
||||||
label="Jabatan"
|
|
||||||
onChange={(value) => { validationForm(value, 'name') }}
|
|
||||||
error={error.name}
|
|
||||||
errorText="Nama jabatan harus diisi"
|
|
||||||
value={dataForm.name}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<View style={Styles.mb30}>
|
|
||||||
<ButtonForm
|
|
||||||
text="SIMPAN"
|
|
||||||
onPress={() => { handleTambah() }}
|
|
||||||
disabled={disable} />
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</DrawerBottom>
|
</DrawerBottom>
|
||||||
|
|
||||||
<ModalFilter close={() => {
|
<ModalFilter close={() => {
|
||||||
setFilter(false)
|
setFilter(false)
|
||||||
setVisible(false)
|
setVisible(false)
|
||||||
}} open={isFilter} page="position" />
|
}} open={isFilter} page="position" />
|
||||||
|
|
||||||
<ModalSelect
|
|
||||||
category="group"
|
|
||||||
close={setSelect}
|
|
||||||
onSelect={(value) => {
|
|
||||||
validationForm(value.val, 'idGroup')
|
|
||||||
setChoose(value)
|
|
||||||
setSelect(false)
|
|
||||||
setTimeout(() => {
|
|
||||||
setVisibleTambah(true)
|
|
||||||
}, 600)
|
|
||||||
}}
|
|
||||||
title="Lembaga Desa"
|
|
||||||
open={isSelect}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
133
components/position/modalFormCreatePosition.tsx
Normal file
133
components/position/modalFormCreatePosition.tsx
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
import Styles from "@/constants/Styles"
|
||||||
|
import { apiCreatePosition } from "@/lib/api"
|
||||||
|
import { setUpdatePosition } from "@/lib/positionSlice"
|
||||||
|
import { useAuthSession } from "@/providers/AuthProvider"
|
||||||
|
import { update } from "@react-native-firebase/database"
|
||||||
|
import { useEffect, useState } from "react"
|
||||||
|
import { View } from "react-native"
|
||||||
|
import Toast from "react-native-toast-message"
|
||||||
|
import { useDispatch, useSelector } from "react-redux"
|
||||||
|
import { ButtonForm } from "../buttonForm"
|
||||||
|
import { InputForm } from "../inputForm"
|
||||||
|
import SelectForm from "../selectForm"
|
||||||
|
import ModalSelect from "../modalSelect"
|
||||||
|
|
||||||
|
export default function ModalFormCreatePosition({ onClose }: { onClose: () => void }) {
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
const { token, decryptToken } = useAuthSession()
|
||||||
|
const entityUser = useSelector((state: any) => state.user)
|
||||||
|
const [choose, setChoose] = useState({ val: '', label: '' })
|
||||||
|
const [isSelect, setSelect] = useState(false)
|
||||||
|
const [disable, setDisable] = useState(true)
|
||||||
|
const [dataForm, setDataForm] = useState({
|
||||||
|
name: "",
|
||||||
|
idGroup: "",
|
||||||
|
})
|
||||||
|
const [error, setError] = useState({
|
||||||
|
name: false,
|
||||||
|
idGroup: false
|
||||||
|
});
|
||||||
|
|
||||||
|
function validationForm(val: any, cat: 'name' | 'idGroup') {
|
||||||
|
if (cat === 'name') {
|
||||||
|
setDataForm({ ...dataForm, name: val })
|
||||||
|
if (val == "") {
|
||||||
|
setError({ ...error, name: true })
|
||||||
|
} else {
|
||||||
|
setError({ ...error, name: false })
|
||||||
|
}
|
||||||
|
} else if (cat === "idGroup") {
|
||||||
|
setDataForm({ ...dataForm, idGroup: val })
|
||||||
|
if (val == "") {
|
||||||
|
setError({ ...error, idGroup: true })
|
||||||
|
} else {
|
||||||
|
setError({ ...error, idGroup: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkAll() {
|
||||||
|
let nilai = false
|
||||||
|
if (dataForm.name == "") {
|
||||||
|
nilai = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((entityUser.role == "supadmin" || entityUser.role == "developer") && (dataForm.idGroup == "" || String(dataForm.idGroup) == "null")) {
|
||||||
|
nilai = true
|
||||||
|
}
|
||||||
|
|
||||||
|
setDisable(nilai)
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
checkAll()
|
||||||
|
}, [dataForm])
|
||||||
|
|
||||||
|
async function handleTambah() {
|
||||||
|
try {
|
||||||
|
setDisable(true)
|
||||||
|
const hasil = await decryptToken(String(token?.current))
|
||||||
|
const response = await apiCreatePosition({ user: hasil, name: dataForm.name, idGroup: dataForm.idGroup })
|
||||||
|
dispatch(setUpdatePosition(!update))
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
} finally {
|
||||||
|
setDisable(false)
|
||||||
|
Toast.show({ type: 'small', text1: 'Berhasil menambahkan data', })
|
||||||
|
onClose()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<View style={{ flex: 1, justifyContent: 'space-between' }}>
|
||||||
|
<View>
|
||||||
|
{
|
||||||
|
(entityUser.role == 'supadmin' || entityUser.role == 'developer') &&
|
||||||
|
<SelectForm
|
||||||
|
label="Lembaga Desa"
|
||||||
|
placeholder="Pilih Lembaga Desa"
|
||||||
|
value={choose.label}
|
||||||
|
required
|
||||||
|
onPress={() => {
|
||||||
|
setSelect(true)
|
||||||
|
}}
|
||||||
|
error={error.idGroup}
|
||||||
|
errorText="Lembaga Desa harus diisi"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
<InputForm
|
||||||
|
type="default"
|
||||||
|
placeholder="Nama Jabatan"
|
||||||
|
required
|
||||||
|
label="Jabatan"
|
||||||
|
onChange={(value) => { validationForm(value, 'name') }}
|
||||||
|
error={error.name}
|
||||||
|
errorText="Nama jabatan harus diisi"
|
||||||
|
value={dataForm.name}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={Styles.mb30}>
|
||||||
|
<ButtonForm
|
||||||
|
text="SIMPAN"
|
||||||
|
onPress={() => { handleTambah() }}
|
||||||
|
disabled={disable} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<ModalSelect
|
||||||
|
category="group"
|
||||||
|
close={setSelect}
|
||||||
|
onSelect={(value) => {
|
||||||
|
validationForm(value.val, 'idGroup')
|
||||||
|
setChoose(value)
|
||||||
|
setSelect(false)
|
||||||
|
}}
|
||||||
|
title="Lembaga Desa"
|
||||||
|
open={isSelect}
|
||||||
|
valChoose={choose.val}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -94,6 +94,9 @@ const Styles = StyleSheet.create({
|
|||||||
mv15: {
|
mv15: {
|
||||||
marginVertical: 15
|
marginVertical: 15
|
||||||
},
|
},
|
||||||
|
mh03: {
|
||||||
|
marginHorizontal: 3
|
||||||
|
},
|
||||||
mh05: {
|
mh05: {
|
||||||
marginHorizontal: 5
|
marginHorizontal: 5
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2027,6 +2027,8 @@ PODS:
|
|||||||
- React-utils (= 0.79.5)
|
- React-utils (= 0.79.5)
|
||||||
- RNCAsyncStorage (2.1.2):
|
- RNCAsyncStorage (2.1.2):
|
||||||
- React-Core
|
- React-Core
|
||||||
|
- RNCClipboard (1.16.3):
|
||||||
|
- React-Core
|
||||||
- RNDateTimePicker (8.4.1):
|
- RNDateTimePicker (8.4.1):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNFBApp (22.4.0):
|
- RNFBApp (22.4.0):
|
||||||
@@ -2328,6 +2330,7 @@ DEPENDENCIES:
|
|||||||
- ReactCodegen (from `build/generated/ios`)
|
- ReactCodegen (from `build/generated/ios`)
|
||||||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
||||||
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
|
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
|
||||||
|
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
|
||||||
- "RNDateTimePicker (from `../node_modules/@react-native-community/datetimepicker`)"
|
- "RNDateTimePicker (from `../node_modules/@react-native-community/datetimepicker`)"
|
||||||
- "RNFBApp (from `../node_modules/@react-native-firebase/app`)"
|
- "RNFBApp (from `../node_modules/@react-native-firebase/app`)"
|
||||||
- "RNFBDatabase (from `../node_modules/@react-native-firebase/database`)"
|
- "RNFBDatabase (from `../node_modules/@react-native-firebase/database`)"
|
||||||
@@ -2570,6 +2573,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: "../node_modules/react-native/ReactCommon"
|
:path: "../node_modules/react-native/ReactCommon"
|
||||||
RNCAsyncStorage:
|
RNCAsyncStorage:
|
||||||
:path: "../node_modules/@react-native-async-storage/async-storage"
|
:path: "../node_modules/@react-native-async-storage/async-storage"
|
||||||
|
RNCClipboard:
|
||||||
|
:path: "../node_modules/@react-native-clipboard/clipboard"
|
||||||
RNDateTimePicker:
|
RNDateTimePicker:
|
||||||
:path: "../node_modules/@react-native-community/datetimepicker"
|
:path: "../node_modules/@react-native-community/datetimepicker"
|
||||||
RNFBApp:
|
RNFBApp:
|
||||||
@@ -2712,6 +2717,7 @@ SPEC CHECKSUMS:
|
|||||||
ReactCodegen: 272c9bc1a8a917bf557bd9d032a4b3e181c6abfe
|
ReactCodegen: 272c9bc1a8a917bf557bd9d032a4b3e181c6abfe
|
||||||
ReactCommon: 7eb76fcd5133313d8c6a138a5c7dd89f80f189d5
|
ReactCommon: 7eb76fcd5133313d8c6a138a5c7dd89f80f189d5
|
||||||
RNCAsyncStorage: b9f5f78da5d16a853fe3dc22e8268d932fc45a83
|
RNCAsyncStorage: b9f5f78da5d16a853fe3dc22e8268d932fc45a83
|
||||||
|
RNCClipboard: f6679d470d0da2bce2a37b0af7b9e0bf369ecda5
|
||||||
RNDateTimePicker: 60f9e986d61e42169a2716c1b51f1f93dfa82665
|
RNDateTimePicker: 60f9e986d61e42169a2716c1b51f1f93dfa82665
|
||||||
RNFBApp: 12884d3bf9b3a0223efe4a0adce516edf72c4102
|
RNFBApp: 12884d3bf9b3a0223efe4a0adce516edf72c4102
|
||||||
RNFBDatabase: 1e5c4bda4bb47a48820089ddef498f9af21cb52b
|
RNFBDatabase: 1e5c4bda4bb47a48820089ddef498f9af21cb52b
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"@expo/vector-icons": "^14.0.2",
|
"@expo/vector-icons": "^14.0.2",
|
||||||
"@formatjs/intl-getcanonicallocales": "^2.5.5",
|
"@formatjs/intl-getcanonicallocales": "^2.5.5",
|
||||||
"@react-native-async-storage/async-storage": "2.1.2",
|
"@react-native-async-storage/async-storage": "2.1.2",
|
||||||
|
"@react-native-clipboard/clipboard": "^1.16.3",
|
||||||
"@react-native-community/cli": "^19.1.0",
|
"@react-native-community/cli": "^19.1.0",
|
||||||
"@react-native-community/datetimepicker": "8.4.1",
|
"@react-native-community/datetimepicker": "8.4.1",
|
||||||
"@react-native-firebase/app": "^22.4.0",
|
"@react-native-firebase/app": "^22.4.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user