281 lines
7.1 KiB
JavaScript
281 lines
7.1 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import {
|
|
ScrollView,
|
|
View,
|
|
Text,
|
|
TextInput,
|
|
TouchableOpacity,
|
|
StyleSheet,
|
|
Alert,
|
|
Image,
|
|
} from "react-native";
|
|
import { Ionicons } from "@expo/vector-icons"; // Icon library for the media buttons
|
|
import * as ImagePicker from "expo-image-picker"; // For picking images
|
|
import * as MediaLibrary from "expo-media-library"; // For accessing media library
|
|
import { Video } from "expo-av"; // For displaying videos
|
|
|
|
const KontribusiScreen = ({ navigation, route }) => {
|
|
const {
|
|
judulPengaduan = "Sampah berantakan",
|
|
tempatPengaduan = "Jl Raya Madiun Nganjuk",
|
|
} = route?.params || {};
|
|
|
|
const [catatan, setCatatan] = useState("");
|
|
const [photo, setPhoto] = useState(null);
|
|
const [video, setVideo] = useState(null);
|
|
|
|
// Request permissions for camera and media library
|
|
useEffect(() => {
|
|
const requestPermissions = async () => {
|
|
// Request permission for media library (Images and Videos)
|
|
const { status: mediaStatus } =
|
|
await ImagePicker.requestMediaLibraryPermissionsAsync();
|
|
if (mediaStatus !== "granted") {
|
|
Alert.alert(
|
|
"Permission required",
|
|
"You need to grant permission to access your media library."
|
|
);
|
|
}
|
|
|
|
// Optionally, you can also request permission for camera
|
|
const { status: cameraStatus } =
|
|
await ImagePicker.requestCameraPermissionsAsync();
|
|
if (cameraStatus !== "granted") {
|
|
Alert.alert(
|
|
"Permission required",
|
|
"You need to grant permission to use the camera."
|
|
);
|
|
}
|
|
};
|
|
requestPermissions();
|
|
}, []);
|
|
|
|
// Function to pick image
|
|
const pickImage = async () => {
|
|
let result = await ImagePicker.launchImageLibraryAsync({
|
|
mediaTypes: ImagePicker.MediaTypeOptions.Images,
|
|
allowsEditing: true,
|
|
aspect: [4, 3],
|
|
quality: 1,
|
|
});
|
|
|
|
if (!result.canceled) {
|
|
setPhoto(result.assets[0].uri); // Set the selected photo URI
|
|
} else {
|
|
Alert.alert("Tambah foto dibatalkan.");
|
|
}
|
|
};
|
|
|
|
// Function to pick video
|
|
const pickVideo = async () => {
|
|
let result = await ImagePicker.launchImageLibraryAsync({
|
|
mediaTypes: ImagePicker.MediaTypeOptions.Videos,
|
|
allowsEditing: true,
|
|
quality: 1,
|
|
});
|
|
|
|
if (!result.canceled) {
|
|
setVideo(result.assets[0].uri); // Set the selected video URI
|
|
} else {
|
|
Alert.alert("Pemilihan video dibatalkan.");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<ScrollView style={styles.container}>
|
|
{/* Title and Back Button */}
|
|
<View style={styles.header}>
|
|
<TouchableOpacity
|
|
style={styles.backButton}
|
|
onPress={() => navigation.goBack()}
|
|
>
|
|
<Ionicons name="arrow-back" size={24} color="#000" />
|
|
</TouchableOpacity>
|
|
<Text style={styles.title}>KONTRIBUSI SEKARANG</Text>
|
|
</View>
|
|
|
|
{/* Contribution Info Container */}
|
|
<View style={styles.contributionContainer}>
|
|
<View style={styles.infoBox}>
|
|
<Text style={styles.infoText1}>{judulPengaduan}</Text>
|
|
<Text style={styles.infoText2}>{tempatPengaduan}</Text>
|
|
</View>
|
|
|
|
{/* Add Media Row (Foto & Video) */}
|
|
<View style={styles.mediaRow}>
|
|
<TouchableOpacity style={styles.mediaButton} onPress={pickImage}>
|
|
<Ionicons name="image-outline" size={30} color="#2D572C" />
|
|
<Text style={styles.mediaButtonText}>Tambah Foto</Text>
|
|
</TouchableOpacity>
|
|
<TouchableOpacity style={styles.mediaButton} onPress={pickVideo}>
|
|
<Ionicons name="videocam-outline" size={30} color="#2D572C" />
|
|
<Text style={styles.mediaButtonText}>Tambah Video</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
|
|
{/* Display selected photo */}
|
|
{photo && (
|
|
<Image source={{ uri: photo }} style={styles.mediaThumbnail} />
|
|
)}
|
|
|
|
{/* Display selected video */}
|
|
{video && (
|
|
<Video
|
|
source={{ uri: video }}
|
|
style={styles.mediaThumbnail}
|
|
useNativeControls
|
|
resizeMode="contain"
|
|
isLooping
|
|
/>
|
|
)}
|
|
|
|
{/* Catatan (Note Input) */}
|
|
<TextInput
|
|
style={styles.input}
|
|
placeholder="Catatan"
|
|
multiline
|
|
value={catatan}
|
|
onChangeText={setCatatan}
|
|
/>
|
|
</View>
|
|
|
|
{/* Koin Message */}
|
|
<Text style={styles.koinText}>Dapatkan +520 Koin</Text>
|
|
|
|
{/* Post Button at Bottom */}
|
|
<TouchableOpacity
|
|
style={styles.postButton}
|
|
onPress={() => navigation.navigate("KontribusiBerhasil")}
|
|
>
|
|
<Text style={styles.postButtonText}>Posting</Text>
|
|
</TouchableOpacity>
|
|
</ScrollView>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: "#f9f9f9",
|
|
},
|
|
header: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
padding: 15,
|
|
backgroundColor: "#fff",
|
|
borderBottomLeftRadius: 20,
|
|
borderBottomRightRadius: 20,
|
|
},
|
|
backButton: {
|
|
marginRight: 15,
|
|
marginTop: 40,
|
|
},
|
|
title: {
|
|
fontSize: 22,
|
|
color: "#000",
|
|
fontWeight: "bold",
|
|
flex: 1,
|
|
textAlign: "left",
|
|
marginTop: 40,
|
|
},
|
|
contributionContainer: {
|
|
padding: 20,
|
|
backgroundColor: "#fff",
|
|
marginBottom: 20,
|
|
borderRadius: 12,
|
|
shadowColor: "#000",
|
|
shadowOpacity: 0.1,
|
|
shadowOffset: { width: 0, height: 4 },
|
|
shadowRadius: 4,
|
|
},
|
|
infoBox: {
|
|
marginBottom: 20,
|
|
},
|
|
infoText1: {
|
|
fontSize: 22,
|
|
color: "#333",
|
|
fontWeight: "700",
|
|
marginBottom: 5,
|
|
},
|
|
infoText2: {
|
|
fontSize: 18,
|
|
color: "#777",
|
|
fontWeight: "400",
|
|
},
|
|
mediaRow: {
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
marginBottom: 25,
|
|
},
|
|
mediaButton: {
|
|
alignItems: "center",
|
|
flex: 1,
|
|
padding: 15,
|
|
backgroundColor: "#E8F5E9",
|
|
borderRadius: 10,
|
|
marginHorizontal: 10,
|
|
borderWidth: 1,
|
|
borderColor: "#2D572C",
|
|
shadowColor: "#000",
|
|
shadowOpacity: 0.1,
|
|
shadowOffset: { width: 0, height: 3 },
|
|
shadowRadius: 5,
|
|
elevation: 3,
|
|
},
|
|
mediaButtonText: {
|
|
fontSize: 14,
|
|
color: "#2D572C",
|
|
marginTop: 5,
|
|
},
|
|
input: {
|
|
height: 100,
|
|
borderColor: "#2D572C",
|
|
borderWidth: 1,
|
|
borderRadius: 8,
|
|
padding: 12,
|
|
fontSize: 16,
|
|
marginBottom: 15,
|
|
backgroundColor: "#fff",
|
|
shadowColor: "#000",
|
|
shadowOpacity: 0.1,
|
|
shadowOffset: { width: 0, height: 2 },
|
|
shadowRadius: 5,
|
|
elevation: 2,
|
|
},
|
|
koinText: {
|
|
fontSize: 18,
|
|
fontWeight: "bold",
|
|
textAlign: "center",
|
|
color: "#2D572C",
|
|
marginBottom: 20,
|
|
},
|
|
postButton: {
|
|
backgroundColor: "#2D572C",
|
|
paddingVertical: 15,
|
|
borderRadius: 10,
|
|
marginBottom: 20,
|
|
alignItems: "center",
|
|
width: "90%",
|
|
alignSelf: "center",
|
|
shadowColor: "#000",
|
|
shadowOpacity: 0.1,
|
|
shadowOffset: { width: 0, height: 5 },
|
|
shadowRadius: 8,
|
|
elevation: 5,
|
|
},
|
|
postButtonText: {
|
|
fontSize: 18,
|
|
color: "#fff",
|
|
fontWeight: "bold",
|
|
},
|
|
mediaThumbnail: {
|
|
width: 300, // Adjust size for visibility
|
|
height: 200, // Adjust size for visibility
|
|
marginVertical: 10,
|
|
borderRadius: 8,
|
|
backgroundColor: "#f0f0f0",
|
|
},
|
|
});
|
|
|
|
export default KontribusiScreen;
|