From 927db8774964a46eb08f357856f17a7c70f88ac0 Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Wed, 30 Jul 2025 10:39:54 +0800 Subject: [PATCH] Component Add: - upload button : masih percobaan Utils: Add: - file validasi untuk upload file Pakage Add: - expo-document-picker - expo-file-system ## No Issue --- app/(application)/coba/index.tsx | 39 ++++++++-- app/(application)/coba/upload-button.tsx | 99 ++++++++++++++++++++++++ bun.lock | 4 + package.json | 2 + utils/fileValidation.ts | 34 ++++++++ 5 files changed, 172 insertions(+), 6 deletions(-) create mode 100644 app/(application)/coba/upload-button.tsx create mode 100644 utils/fileValidation.ts diff --git a/app/(application)/coba/index.tsx b/app/(application)/coba/index.tsx index 65e2c9e..3731644 100644 --- a/app/(application)/coba/index.tsx +++ b/app/(application)/coba/index.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ import React from "react"; import { View, @@ -11,6 +12,8 @@ import { Ionicons } from "@expo/vector-icons"; import { router, Stack } from "expo-router"; import EventDetailScreen from "./double-scroll"; import LeftButtonCustom from "@/components/Button/BackButton"; +import CustomUploadButton from "./upload-button"; +import { SafeAreaView } from "react-native-safe-area-context"; const { width } = Dimensions.get("window"); @@ -117,14 +120,38 @@ const CustomTabNavigator = () => { const ActiveComponent = getActiveComponent(); + const handleImageUpload = (file: any) => { + console.log("Gambar dipilih:", file); + // Upload ke server + }; + + const handlePdfOrPngUpload = (file: any) => { + console.log("PDF atau PNG dipilih:", file); + }; + return ( <> - - + + + + + + + {/* Hanya PDF atau PNG */} + + // // {/* Content Area */} diff --git a/app/(application)/coba/upload-button.tsx b/app/(application)/coba/upload-button.tsx new file mode 100644 index 0000000..494d014 --- /dev/null +++ b/app/(application)/coba/upload-button.tsx @@ -0,0 +1,99 @@ +// components/CustomUploadButton.tsx +import React from 'react'; +import { Button, Alert, View, StyleSheet } from 'react-native'; +import * as DocumentPicker from 'expo-document-picker'; +import { isValidFileType, getMimeType } from '../../../utils/fileValidation'; + +interface UploadButtonProps { + allowedExtensions: string[]; + buttonTitle?: string; + onFileSelected?: (file: { + uri: string; + name: string; + size: number | null; + mimeType: string; + }) => void; +} + +const CustomUploadButton: React.FC = ({ + allowedExtensions, + buttonTitle = 'Pilih File', + onFileSelected, +}) => { + const handlePickFile = async () => { + try { + // Coba filter dengan MIME type jika memungkinkan + const typeFilter = getMimeTypeFilter(allowedExtensions); + + const result = await DocumentPicker.getDocumentAsync({ + type: typeFilter, // Ini membantu memfilter di UI pemilih + copyToCacheDirectory: true, + }); + + if (result.canceled) { + Alert.alert('Dibatalkan', 'Tidak ada file yang dipilih.'); + return; + } + + const file = result.assets[0]; + const { uri, name, size } = file; + + // Validasi ekstensi secara manual (cadangan jika MIME tidak akurat) + if (!isValidFileType(name, allowedExtensions)) { + Alert.alert( + 'Format Tidak Didukung', + `Hanya file dengan ekstensi berikut yang diperbolehkan: ${allowedExtensions.join(', ')}` + ); + return; + } + + const mimeType = getMimeType(name); + + // Kirim data file ke komponen induk + if (onFileSelected) { + onFileSelected({ uri, name, size: size || null, mimeType }); + } + + Alert.alert('Berhasil', `File ${name} berhasil dipilih!`); + } catch (error) { + console.error('Error picking file:', error); + Alert.alert('Error', 'Terjadi kesalahan saat memilih file.'); + } + }; + + return ( + +