upd: dokumen divisi
Deskripsi: -get all dokumen - select dokumen - tambah folder - upload file - rename dokumen - hapus dokumen - informasi dokumen - move blm selsai NO Issues
This commit is contained in:
@@ -1,54 +1,150 @@
|
||||
import Styles from "@/constants/Styles"
|
||||
import { MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons"
|
||||
import { useState } from "react"
|
||||
import { ToastAndroid, View } from "react-native"
|
||||
import ButtonMenuHeader from "../buttonMenuHeader"
|
||||
import DrawerBottom from "../drawerBottom"
|
||||
import { InputForm } from "../inputForm"
|
||||
import MenuItemRow from "../menuItemRow"
|
||||
import ModalFloat from "../modalFloat"
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiCreateFolderDocument, apiUploadFileDocument } from "@/lib/api";
|
||||
import { setUpdateDokumen } from "@/lib/dokumenUpdate";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import { MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons";
|
||||
import * as DocumentPicker from "expo-document-picker";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import { ToastAndroid, View } from "react-native";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import ButtonMenuHeader from "../buttonMenuHeader";
|
||||
import DrawerBottom from "../drawerBottom";
|
||||
import { InputForm } from "../inputForm";
|
||||
import MenuItemRow from "../menuItemRow";
|
||||
import ModalFloat from "../modalFloat";
|
||||
|
||||
type Props = {
|
||||
id: string | string[] | undefined | null
|
||||
}
|
||||
export default function HeaderRightDocument({ path }: { path: string }) {
|
||||
const [isVisible, setVisible] = useState(false);
|
||||
const [newFolder, setNewFolder] = useState(false);
|
||||
const { id } = useLocalSearchParams<{ id: string }>();
|
||||
const [name, setName] = useState("");
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const dispatch = useDispatch()
|
||||
const update = useSelector((state: any) => state.dokumenUpdate)
|
||||
|
||||
async function handleCreateFolder() {
|
||||
try {
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
const response = await apiCreateFolderDocument({ user: hasil, name, path, idDivision: id })
|
||||
if (response.success) {
|
||||
ToastAndroid.show("Berhasil membuat folder baru", ToastAndroid.SHORT)
|
||||
dispatch(setUpdateDokumen(!update))
|
||||
} else {
|
||||
ToastAndroid.show(response.message, ToastAndroid.SHORT)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
ToastAndroid.show("Terjadi kesalahan", ToastAndroid.SHORT)
|
||||
} finally {
|
||||
setNewFolder(false)
|
||||
}
|
||||
}
|
||||
|
||||
const pickDocumentAsync = async () => {
|
||||
let result = await DocumentPicker.getDocumentAsync({
|
||||
type: ["*/*"],
|
||||
multiple: false,
|
||||
});
|
||||
if (!result.canceled) {
|
||||
if (result.assets?.[0].uri) {
|
||||
handleUploadFile(result.assets?.[0])
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function handleUploadFile(file: any) {
|
||||
try {
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
const fd = new FormData()
|
||||
fd.append("file", {
|
||||
uri: file.uri,
|
||||
type: "application/octet-stream",
|
||||
name: file.name,
|
||||
} as any);
|
||||
|
||||
fd.append(
|
||||
"data",
|
||||
JSON.stringify({
|
||||
idPath: path,
|
||||
idDivision: id,
|
||||
user: hasil,
|
||||
})
|
||||
);
|
||||
|
||||
const response = await apiUploadFileDocument({ data: fd })
|
||||
if (response.success) {
|
||||
ToastAndroid.show("Berhasil mengunggah file", ToastAndroid.SHORT)
|
||||
dispatch(setUpdateDokumen(!update))
|
||||
} else {
|
||||
ToastAndroid.show(response.message, ToastAndroid.SHORT)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
ToastAndroid.show("Terjadi kesalahan", ToastAndroid.SHORT)
|
||||
} finally {
|
||||
setVisible(false)
|
||||
}
|
||||
}
|
||||
|
||||
export default function HeaderRightDocument({ id }: Props) {
|
||||
const [isVisible, setVisible] = useState(false)
|
||||
const [newFolder, setNewFolder] = useState(false)
|
||||
|
||||
return (
|
||||
<>
|
||||
<ButtonMenuHeader onPress={() => { setVisible(true) }} />
|
||||
<DrawerBottom animation="slide" isVisible={isVisible} setVisible={setVisible} title="Menu">
|
||||
<ButtonMenuHeader
|
||||
onPress={() => {
|
||||
setVisible(true);
|
||||
}}
|
||||
/>
|
||||
<DrawerBottom
|
||||
animation="slide"
|
||||
isVisible={isVisible}
|
||||
setVisible={setVisible}
|
||||
title="Menu"
|
||||
>
|
||||
<View style={Styles.rowItemsCenter}>
|
||||
<MenuItemRow
|
||||
icon={<MaterialCommunityIcons name="folder-open" color="black" size={25} />}
|
||||
icon={
|
||||
<MaterialCommunityIcons
|
||||
name="folder-open"
|
||||
color="black"
|
||||
size={25}
|
||||
/>
|
||||
}
|
||||
title="Tambah Dokumen"
|
||||
onPress={() => {
|
||||
setVisible(false)
|
||||
setNewFolder(true)
|
||||
setVisible(false);
|
||||
setNewFolder(true);
|
||||
}}
|
||||
/>
|
||||
|
||||
<MenuItemRow
|
||||
icon={<MaterialIcons name="upload-file" color="black" size={25} />}
|
||||
title="Upload File"
|
||||
onPress={() => {
|
||||
setVisible(false)
|
||||
}}
|
||||
onPress={pickDocumentAsync}
|
||||
/>
|
||||
</View>
|
||||
</DrawerBottom>
|
||||
<ModalFloat title="Buat Folder Baru" isVisible={newFolder} setVisible={setNewFolder}
|
||||
<ModalFloat
|
||||
title="Buat Folder Baru"
|
||||
isVisible={newFolder}
|
||||
setVisible={setNewFolder}
|
||||
disableSubmit={name == ""}
|
||||
onSubmit={() => {
|
||||
setNewFolder(false)
|
||||
ToastAndroid.show('Berhasil membuat folder baru', ToastAndroid.SHORT)
|
||||
}}>
|
||||
handleCreateFolder()
|
||||
}}
|
||||
>
|
||||
<View>
|
||||
<InputForm type="default" placeholder="Nama Folder" required label="Nama Folder" />
|
||||
<InputForm
|
||||
type="default"
|
||||
placeholder="Nama Folder"
|
||||
required
|
||||
label="Nama Folder"
|
||||
onChange={(value: string) => {
|
||||
setName(value);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</ModalFloat>
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@ export default function ItemFile({ category, checked, dateTime, title, onChecked
|
||||
|
||||
</Pressable>
|
||||
<View style={[Styles.rowSpaceBetween, { flex: 1, alignItems: 'center' }]}>
|
||||
<Pressable style={[Styles.ml10]} onPress={onPress}>
|
||||
<Text style={[Styles.textDefault]}>{title}</Text>
|
||||
<Pressable style={[Styles.ml10, {flex:1},]} onPress={onPress}>
|
||||
<Text style={[Styles.textDefault]} numberOfLines={1} ellipsizeMode="tail">{title}</Text>
|
||||
<Text style={[Styles.textInformation]}>{dateTime}</Text>
|
||||
</Pressable>
|
||||
<Pressable onPress={onChecked}>
|
||||
|
||||
@@ -208,7 +208,7 @@ export default function MenuBottomSelectDocument({ onDone }: Props) {
|
||||
setShare(false)
|
||||
}}
|
||||
/>
|
||||
<ModalSalinMove open={isMoveCopy} close={setMoveCopy} category={valMoveCopy} />
|
||||
<ModalSalinMove open={isMoveCopy} close={setMoveCopy} category={valMoveCopy} onConfirm={(value: string) => { }} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
96
components/document/modalInformasi.tsx
Normal file
96
components/document/modalInformasi.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiGetDocumentInformasi } from "@/lib/api";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Pressable, ScrollView, Text, View } from "react-native";
|
||||
import { useSharedValue } from "react-native-reanimated";
|
||||
import ItemAccordion from "../itemAccordion";
|
||||
import ItemDetailMember from "../itemDetailMember";
|
||||
|
||||
type Props = {
|
||||
category: string,
|
||||
name: string,
|
||||
extension: string,
|
||||
createdAt: string,
|
||||
path: string,
|
||||
division: string,
|
||||
createdBy: string
|
||||
}
|
||||
|
||||
type PropsShare = {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export default function ModalInformasi({ data }: { data: any }) {
|
||||
const open = useSharedValue(false)
|
||||
const [dataInformasi, setDataInformasi] = useState<Props>()
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const [dataShare, setDataShare] = useState<PropsShare[]>([])
|
||||
|
||||
async function handleInformasi() {
|
||||
try {
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
const response = await apiGetDocumentInformasi({ user: hasil, item: data.id, cat: 'lainnya' })
|
||||
setDataInformasi(response.data)
|
||||
|
||||
const responseShare = await apiGetDocumentInformasi({ user: hasil, item: data.id, cat: 'share' })
|
||||
setDataShare(responseShare.data)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
handleInformasi()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={[Styles.contentItemCenter, Styles.mb10]}>
|
||||
{
|
||||
dataInformasi?.extension == 'folder'
|
||||
?
|
||||
<Ionicons name="folder-open-sharp" color={'#f9cc40'} size={80} />
|
||||
:
|
||||
<Ionicons name="document-text-sharp" color={'#9fcff8'} size={80} />
|
||||
}
|
||||
</View>
|
||||
|
||||
<View>
|
||||
<ItemDetailMember category="dokumen" value={dataInformasi?.category == 'FOLDER' ? dataInformasi?.name : `${dataInformasi?.name}.${dataInformasi?.extension}`} border />
|
||||
<ItemDetailMember category="type" value={dataInformasi?.category} border />
|
||||
<ItemDetailMember category="location" value={dataInformasi?.path} border />
|
||||
<ItemDetailMember category="owner" value={dataInformasi?.division} border />
|
||||
<ItemDetailMember category="calendar" value={dataInformasi?.createdAt} border />
|
||||
<Pressable style={[Styles.rowSpaceBetween, Styles.rowItemsCenter, Styles.wrapItemBorderBottom]} onPress={() => { open.value = !open.value; }}>
|
||||
<View style={[Styles.rowItemsCenter]}>
|
||||
<MaterialCommunityIcons name="share-variant-outline" size={22} color="black" style={[Styles.mr10]} />
|
||||
<Text style={[Styles.textDefault]}>Telah dibagikan ke divisi</Text>
|
||||
</View>
|
||||
<MaterialCommunityIcons name="chevron-down" size={22} color="black" />
|
||||
</Pressable>
|
||||
<ItemAccordion isExpanded={open} viewKey="Accordion" duration={500}>
|
||||
<ScrollView style={[Styles.w100, { height: 200 }]} >
|
||||
{
|
||||
dataShare.length > 0 ? (
|
||||
dataShare.map((item, index) => (
|
||||
<View key={index} style={[Styles.rowOnly, Styles.ml10, Styles.mt02]}>
|
||||
<MaterialCommunityIcons name="account-group-outline" size={22} color="black" style={[Styles.mr10]} />
|
||||
<Text style={[Styles.textDefault]}>{item.name}</Text>
|
||||
</View>
|
||||
))
|
||||
)
|
||||
: (
|
||||
<View style={[Styles.ml10, Styles.mt02]}>
|
||||
<Text style={[Styles.textDefault, Styles.cGray, { textAlign: 'center' }]}>Tidak ada data</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
</ScrollView>
|
||||
</ItemAccordion>
|
||||
</View>
|
||||
</>
|
||||
)
|
||||
}
|
||||
111
components/document/modalMore.tsx
Normal file
111
components/document/modalMore.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiMoveDocument } from "@/lib/api";
|
||||
import { setUpdateDokumen } from "@/lib/dokumenUpdate";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ToastAndroid, View } from "react-native";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import DrawerBottom from "../drawerBottom";
|
||||
import MenuItemRow from "../menuItemRow";
|
||||
import ModalInformasi from "./modalInformasi";
|
||||
import ModalSalinMove from "./modalSalinMove";
|
||||
|
||||
type Props = {
|
||||
idStorage: string;
|
||||
id: string;
|
||||
name: string;
|
||||
extension: string;
|
||||
category: string;
|
||||
path: string;
|
||||
share: boolean;
|
||||
createdBy: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export default function ModalMore({ onClose, data, share }: { onClose: () => void, data: Props[], share: boolean }) {
|
||||
const [isInformasi, setInformasi] = useState(false)
|
||||
const [isCut, setIsCut] = useState(false)
|
||||
const [isCopy, setIsCopy] = useState(false)
|
||||
const [forbidCopy, setForbidCopy] = useState(true)
|
||||
const [nFileSelected, setNFileSelected] = useState(0)
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const dispatch = useDispatch()
|
||||
const update = useSelector((state: any) => state.dokumenUpdate)
|
||||
const [isMoveCopy, setMoveCopy] = useState(false)
|
||||
|
||||
function cekFileSelected() {
|
||||
const cek = data.some((i: any) => i.category == "FOLDER")
|
||||
setForbidCopy(cek)
|
||||
setNFileSelected(data.length)
|
||||
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
cekFileSelected()
|
||||
}, [data])
|
||||
|
||||
async function handleMove(path: string) {
|
||||
try {
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
const response = await apiMoveDocument({ user: hasil, dataItem: data, path })
|
||||
if (response.success) {
|
||||
ToastAndroid.show("Berhasil memindahkan file", ToastAndroid.SHORT)
|
||||
dispatch(setUpdateDokumen(!update))
|
||||
} else {
|
||||
ToastAndroid.show(response.message, ToastAndroid.SHORT)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
ToastAndroid.show("Terjadi kesalahan", ToastAndroid.SHORT)
|
||||
} finally {
|
||||
setMoveCopy(false)
|
||||
onClose()
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={Styles.rowItemsCenter}>
|
||||
{
|
||||
!share &&
|
||||
<MenuItemRow
|
||||
icon={<MaterialCommunityIcons name="folder-move-outline" color="black" size={25} />}
|
||||
title="Pindah"
|
||||
onPress={() => {
|
||||
setMoveCopy(true)
|
||||
}}
|
||||
/>
|
||||
}
|
||||
{
|
||||
!forbidCopy &&
|
||||
<MenuItemRow
|
||||
icon={<MaterialCommunityIcons name="folder-multiple-outline" color="black" size={25} />}
|
||||
title="Salin"
|
||||
onPress={() => {
|
||||
// handleMoveCopy('copy')
|
||||
}}
|
||||
/>
|
||||
}
|
||||
{
|
||||
nFileSelected == 1 &&
|
||||
<MenuItemRow
|
||||
icon={<MaterialCommunityIcons name="information-variant" color="black" size={25} />}
|
||||
title="Informasi"
|
||||
onPress={() => {
|
||||
// onClose()
|
||||
setInformasi(true)
|
||||
}}
|
||||
/>
|
||||
}
|
||||
</View>
|
||||
|
||||
<DrawerBottom animation="slide" isVisible={isInformasi} setVisible={setInformasi} title="Informasi Dokumen" height={80}>
|
||||
<ModalInformasi data={data[0]} />
|
||||
</DrawerBottom>
|
||||
|
||||
<ModalSalinMove open={isMoveCopy} close={() => setMoveCopy(false)} category={'move'} onConfirm={(value: string) => handleMove(value)} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
import Styles from "@/constants/Styles"
|
||||
import { apiGetDocument } from "@/lib/api"
|
||||
import { useAuthSession } from "@/providers/AuthProvider"
|
||||
import { AntDesign, Ionicons } from "@expo/vector-icons"
|
||||
import { useLocalSearchParams } from "expo-router"
|
||||
import { useEffect, useState } from "react"
|
||||
import { Pressable, Text, View } from "react-native"
|
||||
import BorderBottomItem from "../borderBottomItem"
|
||||
import DrawerBottom from "../drawerBottom"
|
||||
@@ -8,41 +12,92 @@ type Props = {
|
||||
open: boolean
|
||||
close: (value: boolean) => void
|
||||
category: 'copy' | 'move'
|
||||
onConfirm: (value: string) => void
|
||||
}
|
||||
|
||||
export default function ModalSalinMove({ open, close, category, }: Props) {
|
||||
type DataProps = {
|
||||
id: string;
|
||||
category: string;
|
||||
name: string;
|
||||
extension: string;
|
||||
idStorage: string;
|
||||
path: string;
|
||||
createdBy: string;
|
||||
share: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
type PropsPath = {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export default function ModalSalinMove({ open, close, category, onConfirm }: Props) {
|
||||
const [data, setData] = useState<DataProps[]>([])
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const [path, setPath] = useState('home')
|
||||
const { id } = useLocalSearchParams<{ id: string }>();
|
||||
const [dataJalur, setDataJalur] = useState<PropsPath[]>([])
|
||||
|
||||
async function getData() {
|
||||
try {
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
const response = await apiGetDocument({ user: hasil, path, division: id, category: 'folder' })
|
||||
if (response.success) {
|
||||
setData(response.data)
|
||||
setDataJalur(response.jalur)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getData()
|
||||
}, [path])
|
||||
|
||||
return (
|
||||
<DrawerBottom animation="slide" isVisible={open} setVisible={close} title={category == 'copy' ? 'Pilih Lokasi Salin' : 'Pilih Lokasi Pemindahan'} height={75}>
|
||||
<View style={[Styles.rowItemsCenter, Styles.mv05]}>
|
||||
<Text> home </Text>
|
||||
<AntDesign name="right" style={[Styles.mh05, Styles.mt02]} />
|
||||
<Text> folder 1 </Text>
|
||||
{
|
||||
dataJalur.map((item, index) => (
|
||||
<Pressable
|
||||
key={index}
|
||||
style={[Styles.rowItemsCenter]}
|
||||
onPress={() => {
|
||||
setPath(item.id);
|
||||
}}
|
||||
>
|
||||
{item.id != "home" && (
|
||||
<AntDesign name="right" style={[Styles.mh05, Styles.mt02]} />
|
||||
)}
|
||||
<Text> {item.name} </Text>
|
||||
</Pressable>
|
||||
))
|
||||
}
|
||||
</View>
|
||||
<View>
|
||||
<BorderBottomItem
|
||||
borderType="bottom"
|
||||
icon={<Ionicons name="folder-open-sharp" color={'#f9cc40'} size={30} />}
|
||||
title="Folder 1"
|
||||
titleWeight="normal"
|
||||
/>
|
||||
<BorderBottomItem
|
||||
borderType="bottom"
|
||||
icon={<Ionicons name="folder-open-sharp" color={'#f9cc40'} size={30} />}
|
||||
title="Folder 2"
|
||||
titleWeight="normal"
|
||||
/>
|
||||
<BorderBottomItem
|
||||
borderType="bottom"
|
||||
icon={<Ionicons name="folder-open-sharp" color={'#f9cc40'} size={30} />}
|
||||
title="Folder 3"
|
||||
titleWeight="normal"
|
||||
/>
|
||||
{
|
||||
data.map((item, index) => (
|
||||
<BorderBottomItem
|
||||
key={index}
|
||||
borderType="bottom"
|
||||
icon={<Ionicons name="folder-open-sharp" color={'#f9cc40'} size={30} />}
|
||||
title={item.name}
|
||||
titleWeight="normal"
|
||||
onPress={() => {
|
||||
setPath(item.id);
|
||||
}}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</View>
|
||||
<View style={[Styles.rowOnly, Styles.mt15, Styles.absolute0]}>
|
||||
<Pressable style={[Styles.pv05, Styles.borderRight, { width: '50%' }]} onPress={() => { close }}>
|
||||
<Pressable style={[Styles.pv05, Styles.borderRight, { width: '50%' }]} onPress={() => close(false)}>
|
||||
<Text style={[Styles.textDefaultSemiBold, { textAlign: 'center' }]}>BATAL</Text>
|
||||
</Pressable>
|
||||
<Pressable style={[Styles.pv05, { width: '50%' }]} onPress={() => { }}>
|
||||
<Pressable style={[Styles.pv05, { width: '50%' }]} onPress={() => onConfirm(path)}>
|
||||
<Text style={[Styles.textDefaultSemiBold, { textAlign: 'center' }]}>{category == 'copy' ? 'SALIN' : 'PINDAH'}</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
|
||||
@@ -35,7 +35,7 @@ const data = {
|
||||
icon: <MaterialCommunityIcons name="gender-male-female" size={22} color="black" style={[Styles.mr10]} />
|
||||
},
|
||||
dokumen: {
|
||||
label: 'Nama Dokumen',
|
||||
label: 'Dokumen',
|
||||
icon: <MaterialCommunityIcons name="file-document-outline" size={22} color="black" style={[Styles.mr10]} />
|
||||
},
|
||||
type: {
|
||||
@@ -68,7 +68,7 @@ export default function ItemDetailMember({ category, value, border }: Props) {
|
||||
{data[category].icon}
|
||||
<Text style={[Styles.textDefault]}>{data[category].label}</Text>
|
||||
</View>
|
||||
<Text style={[Styles.textDefault]}>{value}</Text>
|
||||
<Text style={[Styles.textDefault, Styles.w60, { textAlign: 'right' }]} numberOfLines={1} ellipsizeMode="tail">{value}</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -8,9 +8,10 @@ type Props = {
|
||||
title?: string
|
||||
children: React.ReactNode
|
||||
onSubmit: () => void
|
||||
disableSubmit?: boolean
|
||||
}
|
||||
|
||||
export default function ModalFloat({ isVisible, setVisible, title, children, onSubmit }: Props) {
|
||||
export default function ModalFloat({ isVisible, setVisible, title, children, onSubmit, disableSubmit }: Props) {
|
||||
return (
|
||||
<Modal
|
||||
animationIn={"fadeIn"}
|
||||
@@ -30,8 +31,8 @@ export default function ModalFloat({ isVisible, setVisible, title, children, onS
|
||||
<Pressable style={[Styles.ph15, Styles.pv05, Styles.round10, Styles.mr10]} onPress={() => { setVisible(false) }}>
|
||||
<Text style={[Styles.textDefault]}>Batal</Text>
|
||||
</Pressable>
|
||||
<Pressable style={[Styles.ph15, Styles.pv05, Styles.round10]} onPress={onSubmit}>
|
||||
<Text style={[Styles.textDefault]}>Simpan</Text>
|
||||
<Pressable style={[Styles.ph15, Styles.pv05, Styles.round10]} onPress={onSubmit} disabled={disableSubmit}>
|
||||
<Text style={[Styles.textDefault, disableSubmit && Styles.cGray]}>Simpan</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
Reference in New Issue
Block a user