diff --git a/.gitignore b/.gitignore
index c9d575d..d2805ed 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,3 +36,6 @@ yarn-error.*
*.tsbuildinfo
app-example
+
+x.ts
+x.sh
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index b85249e..2351808 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -5,6 +5,7 @@
+
diff --git a/app/(application)/banner/create.tsx b/app/(application)/banner/create.tsx
index 485681f..9369a79 100644
--- a/app/(application)/banner/create.tsx
+++ b/app/(application)/banner/create.tsx
@@ -11,6 +11,13 @@ import { router, Stack } from "expo-router";
import { useState } from "react";
import { Image, Platform, Pressable, SafeAreaView, ScrollView, Text, View } from "react-native";
import { useDispatch } from "react-redux";
+import * as FileSystem from 'expo-file-system';
+import axios from "axios";
+import ReactNativeBlobUtil from 'react-native-blob-util';
+import FormData from 'form-data';
+
+const debug = true
+
export default function CreateBanner() {
const { decryptToken, token } = useAuthSession()
@@ -20,39 +27,80 @@ export default function CreateBanner() {
const [title, setTitle] = useState('')
const pickImageAsync = async () => {
+ kirim()
+ return
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['images'],
allowsEditing: false,
quality: 1,
});
+ const formData = new FormData()
+ formData.append('file', result.assets![0].uri)
+
+ if (debug) console.log("[mengirim gambar]")
+ const res = await fetch("http://10.0.2.2:3000/api/v2/test", {
+ method: "POST",
+ body: formData,
+
+ });
+
+ console.log("[res]", await res.json())
+
+ if (debug) console.log("[pickImageAsync]")
+
if (!result.canceled) {
- setSelectedImage(result.assets[0].uri);
- setImgForm(result.assets[0])
+ if (result.assets?.[0].uri) {
+ // setSelectedImage(result.assets[0].uri);
+ // setImgForm(result.assets[0])
+
+ const formData = new FormData()
+ formData.append('file', result.assets[0].uri)
+
+ if (debug) console.log("[mengirim gambar]")
+ const res = await fetch("http://10.0.2.2:3000/api/v2/test", {
+ method: "POST",
+ body: formData,
+
+ });
+
+ console.log("[res]", await res.json())
+
+ } else {
+ if (debug) console.log("[pickImageAsync]", 'Tidak ada gambar yang dipilih');
+ alert('Tidak ada gambar yang dipilih');
+ }
+ console.log("[imgForm]", imgForm)
} else {
+ if (debug) console.log("[pickImageAsync]", 'Tidak ada gambar yang dipilih');
alert('Tidak ada gambar yang dipilih');
}
+
+
};
- console.log(imgForm)
+
+
const handleCreateEntity = async () => {
- const hasil = await decryptToken(String(token?.current))
- const fd = new FormData()
- fd.append("file", JSON.stringify({
- uri: imgForm.uri,
- type: imgForm.mimeType,
- name: imgForm.fileName,
- size: imgForm.fileSize,
- }))
- fd.append("data", JSON.stringify(
- {
- title: title,
- user: hasil
- }
- ))
- const createdEntity = await apiCreateBanner(fd);
- // console.log('cliene',createdEntity)
+ // const hasil = await decryptToken(String(token?.current))
+ // const fd = new FormData()
+
+
+ // fd.append("file", JSON.stringify({
+ // uri: imgForm.uri,
+ // type: imgForm.mimeType,
+ // name: imgForm.fileName,
+ // size: imgForm.fileSize,
+ // }))
+ // fd.append("data", JSON.stringify(
+ // {
+ // title: title,
+ // user: hasil
+ // }
+ // ))
+ // const createdEntity = await apiCreateBanner(fd);
+ // console.log("[createdEntity]", createdEntity)
// dispatch(addEntity(createdEntity));
};
@@ -89,4 +137,66 @@ export default function CreateBanner() {
)
-}
\ No newline at end of file
+}
+
+const requestPermission = async () => {
+ if (Platform.OS !== 'web') {
+ const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
+ if (status !== 'granted') {
+ alert('Maaf, kami membutuhkan izin untuk mengakses galeri!');
+ return false;
+ }
+ return true;
+ }
+ return true;
+};
+
+
+async function kirim() {
+ const hasPermission = await requestPermission();
+
+ if (!hasPermission) {
+ return;
+ }
+
+ let result = await ImagePicker.launchImageLibraryAsync({
+ mediaTypes: ImagePicker.MediaTypeOptions.Images,
+ aspect: [4, 3],
+ quality: 0.8,
+ });
+
+ if (!result.canceled) {
+ const uri = result.assets[0].uri;
+ console.log("Selected image URI:", uri);
+
+ try {
+
+ const base64Data = await ReactNativeBlobUtil.fs.readFile(uri, 'base64');
+
+ // Convert base64 to Blob
+ const blob = new Blob([base64Data], { type: 'image/jpeg' });
+
+ const formData = new FormData();
+ formData.append('file', blob);
+ formData.append('name', 'bg.png');
+
+
+ console.log("Sending FormData with file URI...");
+
+ // Kirim request tanpa header Content-Type
+ const response = await fetch("http://10.0.2.2:3000/api/v2/test", {
+ method: 'POST',
+ body: formData as any,
+ });
+
+ // console.log("Response status:", response.status);
+
+ } catch (error: any) {
+ console.error('Error uploading image:', error);
+ return null;
+ }
+ }
+ return null;
+}
+
+
diff --git a/bun.lockb b/bun.lockb
index 1bbd813..e52edf2 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/package.json b/package.json
index e7828ab..fd81163 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
"@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/native": "^7.0.14",
"@reduxjs/toolkit": "^2.7.0",
+ "@types/formidable": "^3.4.5",
"axios": "^1.8.4",
"crypto-es": "^2.1.0",
"crypto-js": "^3.1.9-1",
@@ -28,6 +29,7 @@
"expo-blur": "~14.0.3",
"expo-constants": "~17.0.7",
"expo-document-picker": "^13.0.3",
+ "expo-file-system": "~18.0.12",
"expo-font": "~13.0.4",
"expo-haptics": "~14.0.1",
"expo-image-picker": "~16.0.6",
@@ -40,10 +42,13 @@
"expo-symbols": "~0.2.2",
"expo-system-ui": "~4.0.8",
"expo-web-browser": "~14.0.2",
+ "form-data": "^4.0.2",
+ "formidable": "^3.5.4",
"moment": "^2.30.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-native": "0.76.7",
+ "react-native-blob-util": "^0.21.2",
"react-native-confirmation-code-field": "^7.4.0",
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "~2.20.2",
@@ -51,6 +56,7 @@
"react-native-modal": "^14.0.0-rc.1",
"react-native-reanimated": "~3.16.1",
"react-native-reanimated-carousel": "^4.0.2",
+ "react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "4.12.0",
"react-native-screens": "~4.4.0",
"react-native-svg": "15.8.0",