Files
mobile-darmasaba/components/project/sectionFile.tsx
amaliadwiy 99c81f6f0d upd: env
Deskripsi;
- env storage
- env db firebase url

No Issues
2025-08-21 12:16:39 +08:00

201 lines
7.2 KiB
TypeScript

import { ConstEnv } from "@/constants/ConstEnv";
import Styles from "@/constants/Styles";
import { apiDeleteFileProject, apiGetProjectOne } from "@/lib/api";
import { setUpdateProject } from "@/lib/projectUpdate";
import { useAuthSession } from "@/providers/AuthProvider";
import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons";
import * as FileSystem from 'expo-file-system';
import { startActivityAsync } from 'expo-intent-launcher';
import { useLocalSearchParams } from "expo-router";
import * as Sharing from 'expo-sharing';
import { useEffect, useState } from "react";
import { Alert, Platform, View } from "react-native";
import * as mime from 'react-native-mime-types';
import Toast from "react-native-toast-message";
import { useDispatch, useSelector } from "react-redux";
import AlertKonfirmasi from "../alertKonfirmasi";
import BorderBottomItem from "../borderBottomItem";
import DrawerBottom from "../drawerBottom";
import MenuItemRow from "../menuItemRow";
import ModalLoading from "../modalLoading";
import Skeleton from "../skeleton";
import Text from "../Text";
type Props = {
id: string
name: string
extension: string
idStorage: string
}
export default function SectionFile({ status, member, refreshing }: { status: number | undefined, member: boolean, refreshing?: boolean }) {
const entityUser = useSelector((state: any) => state.user)
const [isModal, setModal] = useState(false)
const { token, decryptToken } = useAuthSession();
const { id } = useLocalSearchParams<{ id: string }>();
const [data, setData] = useState<Props[]>([]);
const update = useSelector((state: any) => state.projectUpdate)
const dispatch = useDispatch()
const [loading, setLoading] = useState(true)
const arrSkeleton = Array.from({ length: 3 })
const [selectFile, setSelectFile] = useState<Props | null>(null)
const [loadingOpen, setLoadingOpen] = useState(false)
async function handleLoad(loading: boolean) {
try {
setLoading(loading)
const hasil = await decryptToken(String(token?.current));
const response = await apiGetProjectOne({
user: hasil,
cat: "file",
id: id,
});
setData(response.data);
} catch (error) {
console.error(error);
} finally {
setLoading(false)
}
}
useEffect(() => {
handleLoad(false);
}, [update.file]);
useEffect(() => {
if (refreshing)
handleLoad(false);
}, [refreshing]);
useEffect(() => {
handleLoad(true);
}, []);
async function handleDelete() {
try {
const hasil = await decryptToken(String(token?.current));
const response = await apiDeleteFileProject({ user: hasil }, String(selectFile?.id));
if (response.success) {
Toast.show({ type: 'small', text1: 'Berhasil menghapus file', })
dispatch(setUpdateProject({ ...update, file: !update.file }))
} else {
Toast.show({ type: 'small', text1: response.message, })
}
} catch (error) {
console.error(error);
Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
} finally {
setModal(false)
}
}
const openFile = () => {
setModal(false)
setLoadingOpen(true)
let remoteUrl = ConstEnv.url_storage + '/files/' + selectFile?.idStorage;
const fileName = selectFile?.name + '.' + selectFile?.extension;
let localPath = `${FileSystem.documentDirectory}/${fileName}`;
const mimeType = mime.lookup(fileName)
FileSystem.downloadAsync(remoteUrl, localPath).then(async ({ uri }) => {
const contentURL = await FileSystem.getContentUriAsync(uri);
try {
if (Platform.OS == 'android') {
// open with android intent
await startActivityAsync(
'android.intent.action.VIEW',
{
data: contentURL,
flags: 1,
type: mimeType as string,
}
);
// or
// Sharing.shareAsync(localPath);
} else if (Platform.OS == 'ios') {
Sharing.shareAsync(localPath);
}
} catch (error) {
Alert.alert('INFO', 'Gagal membuka file, tidak ada aplikasi yang dapat membuka file ini');
} finally {
setLoadingOpen(false)
}
});
};
return (
<>
<ModalLoading isVisible={loadingOpen} setVisible={setLoadingOpen} />
<View style={[Styles.mb15]}>
<Text style={[Styles.textDefaultSemiBold, Styles.mv05]}>File</Text>
<View style={[Styles.wrapPaper]}>
{
loading ?
arrSkeleton.map((item, index) => {
return (
<Skeleton key={index} width={100} height={40} widthType="percent" borderRadius={10} />
)
})
:
data.length > 0 ?
data.map((item, index) => {
return (
<BorderBottomItem
key={index}
borderType="all"
icon={<MaterialCommunityIcons name="file-outline" size={25} color="black" />}
title={item.name + '.' + item.extension}
titleWeight="normal"
onPress={() => { setSelectFile(item); setModal(true) }}
width={65}
/>
)
})
:
<Text style={[Styles.textDefault, Styles.cGray, { textAlign: 'center' }]}>Tidak ada file</Text>
}
</View>
</View>
<DrawerBottom animation="slide" isVisible={isModal} setVisible={setModal} title="Menu">
<View style={Styles.rowItemsCenter}>
<MenuItemRow
icon={<MaterialCommunityIcons name="file-eye" color="black" size={25} />}
title="Lihat / Share"
onPress={() => {
openFile()
}}
/>
{
!member && (entityUser.role == "user" || entityUser.role == "coadmin") ? <></>
:
<MenuItemRow
icon={<Ionicons name="trash" color="black" size={25} />}
title="Hapus"
disabled={status == 3}
onPress={() => {
if (status == 3) return
setModal(false)
AlertKonfirmasi({
title: 'Konfirmasi',
desc: 'Apakah Anda yakin ingin menghapus file ini? File yang dihapus tidak dapat dikembalikan',
onPress: () => {
handleDelete()
}
})
}}
/>
}
</View>
</DrawerBottom>
</>
)
}