15 changed files with 2860 additions and 1079 deletions
@ -0,0 +1,801 @@
@@ -0,0 +1,801 @@
|
||||
import { useEffect, useRef, useState } from 'react'; |
||||
import {View,Text, StyleSheet, ScrollView, TouchableOpacity, Image, Animated, TextInput, Button, Alert, Pressable, StatusBar, FlatList} from 'react-native'; |
||||
|
||||
import MapLibreGL from '@maplibre/maplibre-react-native'; |
||||
import { MapView,ShapeSource,Camera,UserLocation,PointAnnotation,FillLayer,LineLayer,VectorSource } from "@maplibre/maplibre-react-native"; |
||||
import { SelectList } from 'react-native-dropdown-select-list'; |
||||
import { RadioButton } from 'react-native-paper'; |
||||
import DatePicker from 'react-native-date-picker'; |
||||
import Moment from 'moment'; |
||||
import { launchCamera, launchImageLibrary } from 'react-native-image-picker'; |
||||
import NetInfo from "@react-native-community/netinfo"; |
||||
import AwesomeAlert from 'react-native-awesome-alerts'; |
||||
import {useNavigation,NavigationContainer,useIsFocused} from '@react-navigation/native'; |
||||
import turfcenter from '@turf/center'; |
||||
const {points,polygon,lineString} = require('@turf/helpers'); |
||||
import RNFetchBlob from 'rn-fetch-blob'; |
||||
import Modal from "react-native-modal"; |
||||
|
||||
|
||||
|
||||
import { PDAM_API_URL } from "../../urlConfig"; |
||||
import React from 'react'; |
||||
type collectLineScreenProps = {route: any,navigation: any}; |
||||
|
||||
|
||||
|
||||
export default function ResendPDAM({route,navigation}:collectLineScreenProps) { |
||||
// console.log("route",route.params);
|
||||
const {data,coors} = route.params; |
||||
const apiKey = "JoJs2pcDv5o0yQlQLMfI"; |
||||
const [basemap, setBasemap] = useState("streets-v2"); |
||||
const styleURL = `https://api.maptiler.com/maps/${basemap}/style.json?key=${apiKey}`; |
||||
const Pipe_Type = [ |
||||
{key:'Pipa 24"', value:'Pipa 24"'}, |
||||
{key:'Pipa 20"', value:'Pipa 20"'}, |
||||
{key:'Pipa 16"', value:'Pipa 16"'}, |
||||
{key:'Pipa 10"', value:'Pipa 10"'}, |
||||
] |
||||
const ref = useRef(); |
||||
const [connected, setConnected] = useState(true); |
||||
const [currentIndex, setCurrentIndex] = useState(0); |
||||
const [imgUrl, setImgUrl] = useState([]); |
||||
const [files, setFiles] = useState([]); |
||||
const [pipeName, setPipeName] = useState(data.nama); |
||||
const [selectedPipeType, setselectedPipeType] = useState(data.jenis); |
||||
const [checkedStatus, setCheckedStatus] = useState(data.status); |
||||
const [Information, setInformation] = useState(data.keterangan); |
||||
const [open, setOpen] = useState(false); |
||||
const [install_date, setInstallDate] = useState(new Date(data.tanggal_installasi)); |
||||
const momentDate = Moment(install_date).format('YYYY-MM-DD'); |
||||
const [alertOnline, setAlertOnline] = useState(false); |
||||
const [alertOffline, setAlertOffline] = useState(false); |
||||
const [pipeNameError, setPipeNameError] = useState(false); |
||||
const [pipeTyeError, setPipeTypeError] = useState(false); |
||||
const [pipeStatusError, setPipeStatusError] = useState(false); |
||||
const [pipeInfoError, setPipeInfoError] = useState(false); |
||||
const [coordinates,setCoordinates] = useState([]); |
||||
const [loadGeom,setLoadGeom] = useState(true); |
||||
const [secondPress,setSecondPress] = useState(false); |
||||
const isFocused = useIsFocused(); |
||||
const [centerCoords,setCenterCoords] = useState<number[]>([]); |
||||
const [ModalAttachment, setModalAttachment] = useState(false); |
||||
useEffect(()=>{ |
||||
if (isFocused) { |
||||
console.log(data); |
||||
if (coors === undefined) { |
||||
getData() |
||||
fetchData() |
||||
} |
||||
else{ |
||||
console.log("kedua",coors); |
||||
let centCord = turfcenter(points(coors)); |
||||
console.log("center kedua",centCord); |
||||
setCenterCoords(centCord.geometry.coordinates); |
||||
setLoadGeom(false); |
||||
setCoordinates(coors) |
||||
setSecondPress(true) |
||||
} |
||||
} |
||||
const unmount = navigation.addListener('beforeRemove', (e:any)=> { |
||||
console.log("Event",e); |
||||
if (e.data.action.type !== "NAVIGATE"){ |
||||
e.preventDefault(); |
||||
Alert.alert( |
||||
'Unsave Case', |
||||
'There are unsave case. Please chose what you want.', |
||||
[ |
||||
{ |
||||
text: 'Ok', |
||||
onPress: () => navigation.dispatch(e.data.action) |
||||
}, |
||||
{ |
||||
text: 'Continue', |
||||
style: 'cancel' |
||||
} |
||||
] |
||||
) |
||||
} |
||||
}) |
||||
const unsubscribe = NetInfo.addEventListener((state) => { |
||||
setConnected(state.isConnected!) |
||||
}); |
||||
return () => { |
||||
unmount(); |
||||
unsubscribe(); |
||||
}; |
||||
|
||||
},[isFocused]) |
||||
const getData = async () => { |
||||
try { |
||||
const url = `${PDAM_API_URL}/${route.params.data.id}`; |
||||
await RNFetchBlob.config({ |
||||
trusty : true |
||||
}).fetch('GET', url |
||||
).then(async (resp) => { |
||||
const json = resp.json(); |
||||
const arr = json.map((item:any)=>{ |
||||
// console.log(item.long);
|
||||
|
||||
setCoordinates(oldArray => [...oldArray,[Number(item.long),Number(item.lat)]]) |
||||
return [Number(item.long),Number(item.lat)] |
||||
}) |
||||
let centCord = turfcenter(points(arr)); |
||||
console.log("center pertama",centCord.geometry.coordinates); |
||||
setCenterCoords(centCord.geometry.coordinates); |
||||
setLoadGeom(false); |
||||
} |
||||
) |
||||
} catch (e) { |
||||
console.log("error",e); |
||||
|
||||
// error reading value
|
||||
} |
||||
} |
||||
const fetchData = async () => { |
||||
try { |
||||
await RNFetchBlob.config({ |
||||
trusty : true |
||||
}).fetch('POST', `${PDAM_API_URL}/getAttachment`,{ |
||||
"Content-Type": "application/json", |
||||
}, |
||||
JSON.stringify({ |
||||
id:data.id |
||||
}) |
||||
).then(async (resp) => { |
||||
const json = resp.json() |
||||
json?.forEach(asset => { |
||||
setImgUrl(oldArray => [...oldArray,asset.file]); |
||||
}); |
||||
}) |
||||
|
||||
} catch (error) { |
||||
console.error('Error fetching data:', error); |
||||
} |
||||
}; |
||||
const openCameraLib = async () => { |
||||
const result = await launchCamera({ |
||||
mediaType: 'photo', |
||||
quality: 1, |
||||
includeBase64: true, |
||||
saveToPhotos: true |
||||
}); |
||||
const newObj = { |
||||
file_type: result?.assets![0]?.type, |
||||
file: result?.assets![0]?.base64, |
||||
fileSize: result?.assets![0]?.fileSize, |
||||
} |
||||
setFiles([...files,newObj]); |
||||
setImgUrl([...imgUrl,result?.assets![0]?.base64]); |
||||
}; |
||||
const openLib = async () => { |
||||
const result = await launchImageLibrary({ |
||||
quality: 1, |
||||
mediaType: 'photo', |
||||
selectionLimit: 0, |
||||
includeExtra: true, |
||||
includeBase64: true |
||||
}); |
||||
result?.assets?.forEach(asset => { |
||||
const newObj = { |
||||
file_type: asset.type, |
||||
file: asset.base64, |
||||
fileSize: asset.fileSize |
||||
} |
||||
setFiles(oldArray => [...oldArray,newObj]); |
||||
setImgUrl(oldArray => [...oldArray,asset.base64]); |
||||
}); |
||||
}; |
||||
const PrevImg = ({isIndex}) => { |
||||
if(isIndex===0){ |
||||
return ( |
||||
<TouchableOpacity disabled style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} onPress={()=> { |
||||
setCurrentIndex(currentIndex-1) |
||||
ref.current.scrollToIndex({ |
||||
animated: true, |
||||
index: currentIndex-1 |
||||
}); |
||||
}}> |
||||
<Image style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} source={require('../../assets/icon/left-arrow.png')} /> |
||||
</TouchableOpacity> |
||||
) |
||||
} |
||||
return ( |
||||
<TouchableOpacity style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} onPress={()=> { |
||||
setCurrentIndex(currentIndex-1) |
||||
ref.current.scrollToIndex({ |
||||
animated: true, |
||||
index: currentIndex-1 |
||||
}); |
||||
}}> |
||||
<Image style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} source={require('../../assets/icon/left-arrow.png')} /> |
||||
</TouchableOpacity> |
||||
) |
||||
}; |
||||
const NextImg = ({isIndex}) => { |
||||
if(isIndex===imgUrl.length-1){ |
||||
return ( |
||||
<TouchableOpacity disabled style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} onPress={()=> { |
||||
setCurrentIndex(currentIndex+1) |
||||
ref.current.scrollToIndex({ |
||||
animated: true, |
||||
index: currentIndex+1 |
||||
}); |
||||
}}> |
||||
<Image style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} source={require('../../assets/icon/right-arrow.png')} /> |
||||
</TouchableOpacity> |
||||
) |
||||
} |
||||
return ( |
||||
<TouchableOpacity style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} onPress={()=> { |
||||
setCurrentIndex(currentIndex+1) |
||||
ref.current.scrollToIndex({ |
||||
animated: true, |
||||
index: currentIndex+1 |
||||
}); |
||||
}}> |
||||
<Image style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} source={require('../../assets/icon/right-arrow.png')} /> |
||||
</TouchableOpacity> |
||||
) |
||||
}; |
||||
const showDialog = () => { |
||||
console.log("coor",coordinates); |
||||
if(!pipeName){ |
||||
setPipeNameError(true) |
||||
}else{ |
||||
setPipeNameError(false) |
||||
} |
||||
if(!selectedPipeType){ |
||||
setPipeTypeError(true) |
||||
}else{ |
||||
setPipeTypeError(false) |
||||
} |
||||
if(!checkedStatus){ |
||||
setPipeStatusError(true) |
||||
}else{ |
||||
setPipeStatusError(false) |
||||
} |
||||
if(!Information){ |
||||
setPipeInfoError(true) |
||||
}else{ |
||||
setPipeInfoError(false) |
||||
} |
||||
if(!pipeName || !selectedPipeType || !checkedStatus || !Information) { |
||||
return false |
||||
} |
||||
if(connected){ |
||||
setAlertOnline(true); |
||||
} |
||||
else{ |
||||
setAlertOffline(true) |
||||
} |
||||
}; |
||||
const handleCancelAlertOnline = () => { |
||||
setAlertOnline(false); |
||||
}; |
||||
const handleCancelAlertOffline = () => { |
||||
setAlertOffline(false); |
||||
}; |
||||
const insertAttachment = (files: any) => { |
||||
try { |
||||
files.forEach(async function(file:any) { |
||||
const url = `${PDAM_API_URL}/addAttachment`; |
||||
await RNFetchBlob.config({ |
||||
trusty : true |
||||
}).fetch('POST', url,{ |
||||
"Content-Type": "application/json", |
||||
}, |
||||
JSON.stringify({pdam_id:data.id, file:file.file, mimetype:file.file_type, size:file.fileSize}) |
||||
).then(async (resp) => { |
||||
|
||||
} |
||||
) |
||||
}); |
||||
} catch (error) { |
||||
console.log(error); |
||||
} |
||||
}; |
||||
const collectDataOnline = async () => { |
||||
try { |
||||
const geom = coordinates.map((item:any)=>{ |
||||
return String(item).replace(',',' ') |
||||
}); |
||||
const obj = { |
||||
nama: pipeName, |
||||
jenis: selectedPipeType, |
||||
tanggal_installasi: momentDate, |
||||
status: checkedStatus, |
||||
keterangan: Information, |
||||
geom: `MULTILINESTRING((${geom}))`, |
||||
id:data.id |
||||
}; |
||||
const url = `${PDAM_API_URL}/updateData`; |
||||
await RNFetchBlob.config({ |
||||
trusty : true |
||||
}).fetch('POST', url,{ |
||||
"Content-Type": "application/json", |
||||
}, |
||||
JSON.stringify(obj) |
||||
).then(async (resp) => { |
||||
const status = resp.respInfo.status |
||||
if (status == 201) { |
||||
insertAttachment(files) |
||||
Alert.alert("Success") |
||||
setAlertOnline(false); |
||||
navigation.navigate('Inbox Pipa PDAM', { screen: 'Inbox Pipa PDAM'}) |
||||
} |
||||
else { |
||||
Alert.alert("Internal Server Error") |
||||
} |
||||
} |
||||
|
||||
) |
||||
|
||||
} catch (error) { |
||||
|
||||
} |
||||
// const geom = coordinates.map((item:any)=>{
|
||||
// return String(item).replace(',',' ')
|
||||
// })
|
||||
// // console.log("geom",geom);
|
||||
|
||||
// const obj = {
|
||||
// nama: pipeName,
|
||||
// jenis: selectedPipeType,
|
||||
// tanggal_installasi: momentDate,
|
||||
// status: checkedStatus,
|
||||
// keterangan: Information,
|
||||
// geom: `MULTILINESTRING((${geom}))`,
|
||||
// id:data.id
|
||||
// }
|
||||
// console.log(obj);
|
||||
|
||||
// let result = await fetch(`${PDAM_API_URL}/updateData`, {
|
||||
// method: "POST",
|
||||
// headers: {
|
||||
// "Content-Type": "application/json"
|
||||
// },
|
||||
// body: JSON.stringify(obj)
|
||||
// })
|
||||
|
||||
// // const json = await result.json();
|
||||
// const status = result.status
|
||||
// if (status == 201) {
|
||||
// insertAttachment(files)
|
||||
// }
|
||||
// else {
|
||||
// Alert.alert("Internal Server Error")
|
||||
// }
|
||||
}; |
||||
const collectDataOffline = () => { |
||||
setAlertOnline(false); |
||||
}; |
||||
const renderItem = ({item,index}:any) => { |
||||
return ( |
||||
<View key={index} style={{width:100,height:100,borderRadius:10,borderWidth:1,borderStyle:"dashed",flexDirection:'row'}}> |
||||
<Image style={{width: '100%',height: '100%',borderRadius:10}} |
||||
source={{uri: `data:image/jpeg;base64,${imgUrl[index]}`}} |
||||
/> |
||||
</View> |
||||
); |
||||
}; |
||||
return ( |
||||
<View style={styles.mainContainer}> |
||||
<StatusBar backgroundColor="#34A6F8" barStyle={'light-content'} /> |
||||
<View key={"mainBackground"} style={{backgroundColor:'#34A6F8',width:'100%',height:'93%'}} /> |
||||
<View key={"background"} style={{backgroundColor:'#FFFFFF',width:'100%',height:'100%',position:'absolute',borderTopRightRadius:50,borderTopLeftRadius:35,paddingTop:25}}> |
||||
<ScrollView style={styles.container}> |
||||
{ |
||||
!loadGeom ? |
||||
<View style={{flexDirection:'column'}}> |
||||
<MapView |
||||
style={{width:352,height:200,borderWidth:1,borderColor:'#A6A6A6',overflow:'hidden',alignSelf:'center',borderTopRightRadius:10,borderTopLeftRadius:10}} |
||||
mapStyle={styleURL} |
||||
rotateEnabled={false} |
||||
zoomEnabled={false} |
||||
pitchEnabled={false} |
||||
scrollEnabled={false} |
||||
> |
||||
<Camera
|
||||
centerCoordinate={centerCoords} |
||||
zoomLevel={15} |
||||
minZoomLevel={5} |
||||
maxZoomLevel={20} |
||||
/> |
||||
<ShapeSource |
||||
id="line" |
||||
shape={{ |
||||
"type": "FeatureCollection", |
||||
"features": [ |
||||
{ |
||||
"type": "Feature", |
||||
"properties": {}, |
||||
"geometry": { |
||||
"type": "LineString", |
||||
"coordinates": [data.geom] |
||||
} |
||||
} |
||||
] |
||||
}} |
||||
> |
||||
<LineLayer
|
||||
id="linelayer1" |
||||
style={{lineColor:'red',lineWidth:3}} |
||||
/> |
||||
</ShapeSource> |
||||
{ |
||||
coordinates.map((item:any,index:number)=>( |
||||
<PointAnnotation |
||||
children={<></>} |
||||
key={index} |
||||
id={String(index)} |
||||
coordinate={item} |
||||
draggable={false} |
||||
/> |
||||
)) |
||||
} |
||||
</MapView> |
||||
{!secondPress ? |
||||
<TouchableOpacity style={{alignSelf:'center',backgroundColor:'#F9F9F9',width:352,height:50,borderBottomLeftRadius:10,borderBottomRightRadius:10,justifyContent:'center',borderWidth:1,borderColor:'#A6A6A6'}} onPress={()=>{navigation.navigate('Map View Line', { screen: 'Map View Line',data: { |
||||
id:data.id, |
||||
pipe_name:pipeName, |
||||
pipe_type:selectedPipeType, |
||||
tanggal_installasi: momentDate, |
||||
status: checkedStatus, |
||||
keterangan: Information, |
||||
geom:coordinates |
||||
}}); |
||||
} |
||||
}> |
||||
<Text style={{alignSelf:'center',fontWeight:'semibold',fontSize:16,color:'#434343'}}>Change Location</Text> |
||||
</TouchableOpacity> |
||||
: |
||||
<TouchableOpacity style={{alignSelf:'center',backgroundColor:'#F9F9F9',width:352,height:50,borderBottomLeftRadius:10,borderBottomRightRadius:10,justifyContent:'center',borderWidth:1,borderColor:'#A6A6A6'}} onPress={()=>{navigation.navigate('Map View Line', { screen: 'Map View Line',data: { |
||||
id:data.id, |
||||
pipe_name:pipeName, |
||||
pipe_type:selectedPipeType, |
||||
tanggal_installasi: momentDate, |
||||
status: checkedStatus, |
||||
keterangan: Information, |
||||
geom:[...coordinates,coordinates[0]] |
||||
}}); |
||||
} |
||||
}> |
||||
<Text style={{alignSelf:'center',fontWeight:'semibold',fontSize:16,color:'#434343'}}>Change Location</Text> |
||||
</TouchableOpacity> |
||||
} |
||||
</View> |
||||
: |
||||
null |
||||
} |
||||
<View |
||||
style={{ |
||||
marginTop: 15 |
||||
}} |
||||
/> |
||||
<View style={{alignSelf:'center'}}> |
||||
{/* <Text style={styles.label}>Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */} |
||||
<Text style={styles.label}>Pipe Name</Text> |
||||
<TextInput |
||||
style={styles.input} |
||||
onChangeText={(text)=>{ |
||||
setPipeName(text) |
||||
}} |
||||
onChange={()=> { |
||||
setPipeNameError(false) |
||||
}} |
||||
defaultValue={pipeName} |
||||
/> |
||||
{pipeNameError ? <Text style={styles.errorInput}>Pipe Name is Required!</Text>:null} |
||||
</View> |
||||
<View |
||||
style={{ |
||||
marginTop: 15 |
||||
}} |
||||
/> |
||||
<View style={{alignSelf:'center'}}> |
||||
{/* <Text style={styles.label}>PJU Type <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */} |
||||
<Text style={styles.label}>Pipe Type</Text> |
||||
<SelectList |
||||
search={false} |
||||
placeholder="Select Pipe Type" |
||||
boxStyles={{borderRadius:10,borderWidth:1,borderColor:'#A6A6A6',width:352,height:45}} |
||||
inputStyles={{color:'#6B5E5E'}} |
||||
dropdownTextStyles={{color:'#6B5E5E'}} |
||||
data={Pipe_Type} |
||||
setSelected={setselectedPipeType} |
||||
onSelect={()=> ( |
||||
[setPipeTypeError(false)] |
||||
)} |
||||
defaultOption={{key:selectedPipeType, value:selectedPipeType}} |
||||
/> |
||||
{pipeTyeError ? <Text style={styles.errorInput}>Pipe Type is Required!</Text>:null} |
||||
</View> |
||||
<View |
||||
style={{ |
||||
marginTop: 15 |
||||
}} |
||||
/> |
||||
<View style={{alignSelf:'center',width:352,height:45}}> |
||||
{/* <Text style={styles.label}>Status<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */} |
||||
<Text style={styles.label}>Status</Text> |
||||
<View style={{flexDirection:'row',alignItems:'center'}}> |
||||
<RadioButton |
||||
color='#434343' |
||||
value="Baik" |
||||
status={ checkedStatus === 'Baik' ? 'checked' : 'unchecked' } |
||||
onPress={() => {setCheckedStatus('Baik'); setPipeStatusError(false)}} |
||||
/> |
||||
<Text style={{color:"#434343",fontWeight:'semibold',fontSize:16}}>Baik</Text> |
||||
</View> |
||||
<View style={{flexDirection:'row',alignItems:'center'}}> |
||||
<RadioButton |
||||
color='#434343' |
||||
value="Rusak" |
||||
status={ checkedStatus === 'Rusak' ? 'checked' : 'unchecked' } |
||||
onPress={() => {setCheckedStatus('Rusak'); setPipeStatusError(false); }} |
||||
/> |
||||
<Text style={{color:"#434343",fontWeight:'semibold',fontSize:16}}>Rusak</Text> |
||||
</View> |
||||
{pipeStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null} |
||||
</View> |
||||
<View |
||||
style={{ |
||||
marginTop: 60 |
||||
}} |
||||
/> |
||||
<View style={{alignSelf:'center'}}> |
||||
<Text style={styles.label}>Information</Text> |
||||
<TextInput style={{borderWidth:1,borderRadius:20,padding: 10,color:'#6B5E5E',borderColor:'#A6A6A6',textAlignVertical:'top',width:352,height:135}} |
||||
multiline |
||||
numberOfLines={5} |
||||
maxLength={255} |
||||
onChangeText={(text) => { |
||||
setInformation(text) |
||||
}} |
||||
onChange={()=> { |
||||
setPipeInfoError(false) |
||||
}} |
||||
defaultValue={Information} |
||||
/> |
||||
{pipeInfoError ? <Text style={styles.errorInput}>Information is Required!</Text>:null} |
||||
</View> |
||||
<View |
||||
style={{ |
||||
marginTop: 15 |
||||
}} |
||||
/> |
||||
<View style={{alignSelf:'center'}}> |
||||
<Text style={styles.label}>Installation Date</Text> |
||||
<TextInput |
||||
style={styles.input} |
||||
onPress={() => setOpen(true)} |
||||
value={String(momentDate)} |
||||
/> |
||||
<DatePicker |
||||
locale='en' |
||||
theme='light' |
||||
mode='date' |
||||
modal |
||||
open={open} |
||||
date={install_date} |
||||
onConfirm={(survey_date) => { |
||||
setOpen(false) |
||||
setInstallDate(survey_date) |
||||
}} |
||||
onCancel={() => { |
||||
setOpen(false) |
||||
}} |
||||
/> |
||||
</View> |
||||
<View |
||||
style={{ |
||||
marginTop: 15 |
||||
}} |
||||
/> |
||||
<View style={{alignSelf:'center',width:352}}> |
||||
<Text style={styles.label}>Attachment</Text> |
||||
<Text style={{fontStyle:'italic',color:'#434343',fontSize:14}}>Lampirkan foto / gambar</Text> |
||||
{
|
||||
imgUrl.length === 0 ? |
||||
<Pressable onPress={()=>setModalAttachment(true)}> |
||||
<View style={{width:352,height:70,borderRadius:10,borderStyle:'dashed',borderWidth:2,borderCurve:'continuous',borderColor:'#434343',alignItems:'center',justifyContent:'center',flexDirection:'row',columnGap:5}}> |
||||
<Image |
||||
source={require('../../assets/icon/camorlib.png')} |
||||
/> |
||||
<Text style={{fontStyle:'italic',color:'#434343'}}>Klik untuk menambahkan foto / gambar</Text> |
||||
</View> |
||||
</Pressable> |
||||
: |
||||
<FlatList |
||||
horizontal={false} |
||||
showsHorizontalScrollIndicator={false} |
||||
scrollEnabled={false} |
||||
ListFooterComponent={()=> |
||||
<Pressable onPress={()=>setModalAttachment(true)}> |
||||
<View style={{width:100,height:100,borderRadius:10,borderWidth:1,borderStyle:"dashed",flexDirection:'row',alignItems:'center',justifyContent:'center'}}> |
||||
<Image |
||||
source={require('../../assets/icon/camorlib.png')} |
||||
/> |
||||
</View> |
||||
</Pressable> |
||||
} |
||||
contentContainerStyle={{flexDirection:'row',flexWrap:'wrap',columnGap:25,rowGap:10}} |
||||
data={imgUrl} |
||||
renderItem={({item,index})=>renderItem({item,index})} |
||||
/> |
||||
} |
||||
</View> |
||||
<View |
||||
style={{ |
||||
marginTop: 30 |
||||
}} |
||||
/> |
||||
</ScrollView> |
||||
<TouchableOpacity style={{width:'100%',height:50,backgroundColor:'#34A6F8',alignItems:'center',justifyContent:'center'}} onPress={showDialog}> |
||||
<Text style={{fontSize:18,fontWeight:'bold',color:'#FFFFFF'}}>UPDATE</Text> |
||||
</TouchableOpacity> |
||||
</View> |
||||
{/* Online Mode Alert */} |
||||
<AwesomeAlert |
||||
show={alertOnline} |
||||
showProgress={false} |
||||
title="Updating Data" |
||||
message="Are you sure for Updating PDAM data?" |
||||
closeOnTouchOutside={false} |
||||
closeOnHardwareBackPress={false} |
||||
showCancelButton={true} |
||||
showConfirmButton={true} |
||||
cancelText="No, cancel" |
||||
confirmText="Yes, Update it" |
||||
confirmButtonColor="#137997" |
||||
onCancelPressed={() => { |
||||
handleCancelAlertOnline(); |
||||
}} |
||||
onConfirmPressed={() => { |
||||
collectDataOnline(); |
||||
}} |
||||
overlayStyle={{width:'100%'}} |
||||
contentContainerStyle={{width:'70%',borderRadius:10}} |
||||
titleStyle={{fontSize:20}} |
||||
messageStyle={{fontSize:16}} |
||||
/> |
||||
{/* Offline Mode Alert */} |
||||
<AwesomeAlert |
||||
show={alertOffline} |
||||
showProgress={false} |
||||
title="You are offline" |
||||
message="You want to add data to the draft?" |
||||
closeOnTouchOutside={false} |
||||
closeOnHardwareBackPress={false} |
||||
showCancelButton={true} |
||||
showConfirmButton={true} |
||||
cancelText="No, cancel" |
||||
confirmText="Yes, Add it" |
||||
confirmButtonColor="#DD6B55" |
||||
onCancelPressed={() => { |
||||
handleCancelAlertOffline(); |
||||
}} |
||||
onConfirmPressed={() => { |
||||
collectDataOffline(); |
||||
}} |
||||
overlayStyle={{width:'100%'}} |
||||
contentContainerStyle={{width:'70%',borderRadius:10}} |
||||
titleStyle={{fontSize:20}} |
||||
messageStyle={{fontSize:16}} |
||||
/> |
||||
<Modal isVisible={ModalAttachment} animationIn={'fadeInUp'} animationOut={'fadeOutDown'} backdropOpacity={0} onBackdropPress={()=>setModalAttachment(false)} style={{top:'18%',alignSelf:'center'}}> |
||||
<View key={"modal container"} style={{width:330,height:220,backgroundColor:'#F9F9F9',borderRadius:25,borderWidth:1,borderColor:'#A6A6A6'}}> |
||||
<View style={{flexDirection:'row',alignItems:'center',justifyContent:'space-between',paddingLeft:30,paddingTop:20,paddingRight:10}}> |
||||
<Text style={{fontSize:20,fontWeight:'semibold',color: '#434343',}}> |
||||
Select Mode |
||||
</Text> |
||||
<Pressable onPress={()=>setModalAttachment(false)} style={{alignSelf:'flex-end',padding:10}}> |
||||
<Image style={{tintColor:'#434343'}} |
||||
source={require('../../assets/icon/x.png')} |
||||
/> |
||||
</Pressable> |
||||
</View> |
||||
<View style={{padding:30}}> |
||||
<TouchableOpacity onPress={()=>{openCameraLib(),setModalAttachment(false)}} style={{height:50,backgroundColor:'#FFFFFF',alignItems:'center',justifyContent:'center',borderTopLeftRadius:10,borderTopRightRadius:10,borderWidth:1,borderColor:'#A6A6A6'}}> |
||||
<Text style={{fontSize:20,fontWeight:'light',color:'#434343'}}>Take photo</Text> |
||||
</TouchableOpacity> |
||||
<TouchableOpacity onPress={()=>{openLib(),setModalAttachment(false)}} style={{height:50,backgroundColor:'#FFFFFF',alignItems:'center',justifyContent:'center',borderBottomLeftRadius:10,borderBottomRightRadius:10,borderWidth:1,borderColor:'#A6A6A6'}}> |
||||
<Text style={{fontSize:20,fontWeight:'light',color:'#434343'}}>Choose photo</Text> |
||||
</TouchableOpacity> |
||||
</View> |
||||
</View> |
||||
</Modal> |
||||
</View> |
||||
); |
||||
}; |
||||
|
||||
const styles = StyleSheet.create({ |
||||
errorInput: { |
||||
color: 'red', |
||||
marginLeft: 20 |
||||
}, |
||||
inputLong: { |
||||
height: 40, |
||||
borderWidth: 1, |
||||
padding: 10, |
||||
width: 180, |
||||
marginRight: 20 |
||||
}, |
||||
inputLat: { |
||||
height: 40, |
||||
borderWidth: 1, |
||||
padding: 10, |
||||
borderRadius: 50, |
||||
width: 180, |
||||
color: 'black' |
||||
}, |
||||
input: { |
||||
width:352, |
||||
height: 45, |
||||
borderWidth: 1, |
||||
padding: 10, |
||||
borderRadius: 10, |
||||
color: '#6B5E5E', |
||||
borderColor:'#A6A6A6' |
||||
}, |
||||
container: { |
||||
padding: 10, |
||||
flexGrow: 1 |
||||
}, |
||||
mainContainer: { |
||||
flex: 1, |
||||
}, |
||||
label: { |
||||
fontSize: 16, |
||||
fontWeight:'semibold', |
||||
color: '#434343', |
||||
// marginBottom: 20
|
||||
}, |
||||
title: { |
||||
alignItems: 'center', |
||||
justifyContent: 'center', |
||||
alignSelf: 'center', |
||||
fontWeight: 'bold', |
||||
fontSize: 22, |
||||
color: 'black', |
||||
marginBottom: 10 |
||||
}, |
||||
borderImg: { |
||||
borderColor: 'black', |
||||
borderWidth: 1, |
||||
borderRadius: 20, |
||||
}, |
||||
img: { |
||||
width: 295, |
||||
height: 500, |
||||
borderRadius: 6, |
||||
}, |
||||
btnCameraContainer: { |
||||
flexDirection: 'row', |
||||
justifyContent: 'space-around', |
||||
top:10, |
||||
|
||||
}, |
||||
btnCamera: { |
||||
alignItems: 'center', |
||||
justifyContent: 'center', |
||||
alignSelf: 'center', |
||||
width: 100, |
||||
height: 40, |
||||
bottom:20, |
||||
borderRadius: 6, |
||||
backgroundColor: '#80CBD3' |
||||
}, |
||||
textBtn: { |
||||
color: '#fff' |
||||
}, |
||||
buttonImageIconStyle: { |
||||
padding: 10, |
||||
margin: 5, |
||||
height: 25, |
||||
width: 25, |
||||
resizeMode: 'stretch', |
||||
}, |
||||
}); |
||||
|
||||
@ -0,0 +1,799 @@
@@ -0,0 +1,799 @@
|
||||
import React, { useEffect, useRef, useState, useCallback } from 'react'; |
||||
|
||||
import { |
||||
TextInput, |
||||
Button, |
||||
PermissionsAndroid, |
||||
StatusBar, |
||||
StyleSheet, |
||||
Text, |
||||
View, |
||||
Image, |
||||
TouchableOpacity, |
||||
ScrollView, |
||||
FlatList, |
||||
Dimensions, |
||||
Animated, |
||||
Alert, |
||||
Pressable |
||||
} from 'react-native'; |
||||
|
||||
import { launchCamera, launchImageLibrary } from 'react-native-image-picker'; |
||||
import { SelectList } from 'react-native-dropdown-select-list'; |
||||
import DatePicker from 'react-native-date-picker'; |
||||
import AsyncStorage from '@react-native-async-storage/async-storage'; |
||||
import DocumentPicker from "react-native-document-picker"; |
||||
import NetInfo from "@react-native-community/netinfo"; |
||||
import RNFS from 'react-native-fs'; |
||||
|
||||
import MapLibreGL from '@maplibre/maplibre-react-native'; |
||||
import { MapView,ShapeSource,Camera,UserLocation,PointAnnotation,FillLayer,LineLayer,VectorSource } from "@maplibre/maplibre-react-native"; |
||||
import Moment from 'moment'; |
||||
import { RadioButton } from 'react-native-paper'; |
||||
import AwesomeAlert from 'react-native-awesome-alerts'; |
||||
import {useNavigation,NavigationContainer,useIsFocused} from '@react-navigation/native'; |
||||
import RNFetchBlob from 'rn-fetch-blob'; |
||||
import Modal from "react-native-modal"; |
||||
|
||||
import { PJU_API_URL } from "../../urlConfig"; |
||||
|
||||
type editScreenProps = {route: any,navigation: any}; |
||||
|
||||
function ResendPJU({route,navigation}: editScreenProps) { |
||||
const apiKey = "JoJs2pcDv5o0yQlQLMfI"; |
||||
const [basemap, setBasemap] = useState("streets-v2"); |
||||
const styleURL = `https://api.maptiler.com/maps/${basemap}/style.json?key=${apiKey}`; |
||||
const {data,fixCoordinate} = route.params; |
||||
const [imgUrl, setImgUrl] = useState([]); |
||||
const [files, setFiles] = useState([]); |
||||
const [fileDocument, setFileDocument] = useState([]); |
||||
const [currentIndex, setCurrentIndex] = useState(0); |
||||
const [connected, setConnected] = useState(true) |
||||
console.log("coor",{"long":data.long,"lat":data.lat}); |
||||
|
||||
|
||||
const openCameraLib = async () => { |
||||
const result = await launchCamera({ |
||||
mediaType: 'photo', |
||||
quality: 1, |
||||
includeBase64: true |
||||
}); |
||||
|
||||
const newObj = { |
||||
file_type: result?.assets![0]?.type, |
||||
file: result?.assets![0]?.base64, |
||||
fileSize: result?.assets![0]?.fileSize, |
||||
} |
||||
setFiles([...files,newObj]); |
||||
setImgUrl([...imgUrl,result?.assets[0]?.base64]); |
||||
}; |
||||
const openLib = async () => { |
||||
const result = await launchImageLibrary({ |
||||
quality: 1, |
||||
mediaType: 'photo', |
||||
selectionLimit: 0, |
||||
includeExtra: true, |
||||
includeBase64: true |
||||
}); |
||||
result?.assets?.forEach(asset => { |
||||
const newObj = { |
||||
file_type: asset.type, |
||||
file: asset.base64, |
||||
fileSize: asset.fileSize |
||||
} |
||||
setFiles(oldArray => [...oldArray,newObj]); |
||||
setImgUrl(oldArray => [...oldArray,asset.base64]); |
||||
}); |
||||
}; |
||||
const PrevImg = ({isIndex}) => { |
||||
if(isIndex===0){ |
||||
return ( |
||||
<TouchableOpacity disabled style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} onPress={()=> { |
||||
setCurrentIndex(currentIndex-1) |
||||
ref.current.scrollToIndex({ |
||||
animated: true, |
||||
index: currentIndex-1 |
||||
}); |
||||
}}> |
||||
<Image style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} source={require('../../assets/icon/left-arrow.png')} /> |
||||
</TouchableOpacity> |
||||
) |
||||
} |
||||
return ( |
||||
<TouchableOpacity style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} onPress={()=> { |
||||
setCurrentIndex(currentIndex-1) |
||||
ref.current.scrollToIndex({ |
||||
animated: true, |
||||
index: currentIndex-1 |
||||
}); |
||||
}}> |
||||
<Image style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} source={require('../../assets/icon/left-arrow.png')} /> |
||||
</TouchableOpacity> |
||||
) |
||||
}; |
||||
const NextImg = ({isIndex}) => { |
||||
if(isIndex===imgUrl.length-1){ |
||||
return ( |
||||
<TouchableOpacity disabled style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} onPress={()=> { |
||||
setCurrentIndex(currentIndex+1) |
||||
ref.current.scrollToIndex({ |
||||
animated: true, |
||||
index: currentIndex+1 |
||||
}); |
||||
}}> |
||||
<Image style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} source={require('../../assets/icon/right-arrow.png')} /> |
||||
</TouchableOpacity> |
||||
) |
||||
} |
||||
return ( |
||||
<TouchableOpacity style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} onPress={()=> { |
||||
setCurrentIndex(currentIndex+1) |
||||
ref.current.scrollToIndex({ |
||||
animated: true, |
||||
index: currentIndex+1 |
||||
}); |
||||
}}> |
||||
<Image style={{justifyContent:'center',alignItems:'center',alignSelf:'center'}} source={require('../../assets/icon/right-arrow.png')} /> |
||||
</TouchableOpacity> |
||||
) |
||||
}; |
||||
const PJU_Type = [ |
||||
{key:'Lampu 20 W', value:'Lampu 20 W'}, |
||||
{key:'Lampu 15 W', value:'Lampu 15 W'}, |
||||
{key:'Lampu 10 W', value:'Lampu 10 W'}, |
||||
{key:'Lampu 5 W', value:'Lampu 5 W'}, |
||||
] |
||||
const ref = useRef(); |
||||
const [open, setOpen] = useState(false) |
||||
const [pju_name, setPJUname] = useState(data.nama); |
||||
const [selectedPJUType, setselectedPJUType] = useState(data.jenis); |
||||
const [pju_info, setPJUinfo] = useState(data.keterangan); |
||||
const [checkedStatus, setCheckedStatus] = useState(data.status); |
||||
const [install_date, setInstallDate] = useState(new Date(data.tanggal_installasi)); |
||||
const momentDate = Moment(install_date).format('YYYY-MM-DD') |
||||
const [attachmentImgError, setattachmentImgError] = useState(false); |
||||
const [pjuNameError, setPJUNameError] = useState(false); |
||||
const [PJUTypeError, setPJUTypeError] = useState(false); |
||||
const [PJUStatusError, setPJUStatusError] = useState(false); |
||||
const [PJUInfoError, setPJUInfoError] = useState(false); |
||||
const [long,setLong] = useState(); |
||||
const [lat,setLat] = useState(); |
||||
const [attach,setAttach] = useState([]); |
||||
const [load,setLoad] = useState(true); |
||||
const isFocused = useIsFocused(); |
||||
const [ModalAttachment, setModalAttachment] = useState(false); |
||||
const [userID,setUserID] = useState(); |
||||
|
||||
useEffect(()=> { |
||||
if (isFocused) { |
||||
setLong(data.long); |
||||
setLat(data.lat); |
||||
const getKey = async () =>{ |
||||
const jsonValue = await AsyncStorage.getItem('USER_DATA') |
||||
console.log(JSON.parse(jsonValue!)); |
||||
const data = JSON.parse(jsonValue!); |
||||
console.log("user_data",data.id); |
||||
setUserID(data.id) |
||||
}; |
||||
getKey(); |
||||
fetchData(); |
||||
const unmount = navigation.addListener('beforeRemove', (e:any)=> { |
||||
console.log("Event",e); |
||||
if (e.data.action.type !== "NAVIGATE"){ |
||||
e.preventDefault(); |
||||
Alert.alert( |
||||
'Unsave Case', |
||||
'There are unsave case. Please chose what you want.', |
||||
[ |
||||
{ |
||||
text: 'Ok', |
||||
onPress: () => navigation.dispatch(e.data.action) |
||||
}, |
||||
{ |
||||
text: 'Continue', |
||||
style: 'cancel' |
||||
} |
||||
] |
||||
) |
||||
} |
||||
}) |
||||
const unsubscribe = NetInfo.addEventListener((state) => { |
||||
setConnected(state.isConnected!) |
||||
}); |
||||
return () => { |
||||
unmount() |
||||
unsubscribe(); |
||||
}; |
||||
} |
||||
},[isFocused]); |
||||
|
||||
const fetchData = async () => { |
||||
try { |
||||
await RNFetchBlob.config({ |
||||
trusty : true |
||||
}).fetch('POST', `${PJU_API_URL}/getAttachment`,{ |
||||
"Content-Type": "application/json", |
||||
}, |
||||
JSON.stringify({ |
||||
id:data.id |
||||
}) |
||||
).then(async (resp) => { |
||||
const json = resp.json() |
||||
json?.forEach(asset => { |
||||
setImgUrl(oldArray => [...oldArray,asset.file]); |
||||
}); |
||||
}) |
||||
|
||||
} catch (error) { |
||||
console.error('Error fetching data:', error); |
||||
} |
||||
}; |
||||
const collectDataOnline = async() => { |
||||
try { |
||||
let date = new Date(); |
||||
const milliseconds = Date.UTC( |
||||
date.getFullYear(), |
||||
date.getMonth(), |
||||
date.getDate(), |
||||
date.getHours(), |
||||
date.getMinutes(), |
||||
date.getSeconds(), |
||||
); |
||||
const localTime = new Date(milliseconds); |
||||
await RNFetchBlob.config({ |
||||
trusty : true |
||||
}).fetch('POST', `${PJU_API_URL}/addData`,{ |
||||
"Content-Type": "application/json", |
||||
}, |
||||
JSON.stringify({ |
||||
nama: pju_name, |
||||
jenis: selectedPJUType, |
||||
tanggal_installasi: momentDate, |
||||
status: checkedStatus, |
||||
keterangan: pju_info, |
||||
geom: `POINT(${data.long} ${data.lat})`, |
||||
created_by: userID, |
||||
created_at: localTime |
||||
}) |
||||
).then(async (resp) => { |
||||
const status = resp.respInfo.status |
||||
if (status == 201) { |
||||
insertAttachment(files) |
||||
Alert.alert("Success") |
||||
setAlertOnline(false); |
||||
navigation.navigate('Draft Penerangan Jalan Umum', { screen: 'Draft Penerangan Jalan Umum'}) |
||||
} |
||||
else { |
||||
Alert.alert("Internal Server Error") |
||||
} |
||||
}) |
||||
} catch (error) { |
||||
|
||||
} |
||||
} |
||||
const getMyObject = async () => { |
||||
try { |
||||
const jsonValue = await AsyncStorage.getItem('draft') |
||||
console.log(JSON.parse(jsonValue!)); |
||||
|
||||
// return jsonValue != null ? JSON.parse(jsonValue) : null
|
||||
} catch(e) { |
||||
// read error
|
||||
} |
||||
} |
||||
const removeValue = async () => { |
||||
try { |
||||
await AsyncStorage.removeItem('Test by mobile / Lampu 20 W / 2024-11-14 / Baik / draftJPU') |
||||
} catch(e) { |
||||
// remove error
|
||||
} |
||||
} |
||||
const getAllKeys = async () => { |
||||
// let keys = []
|
||||
try { |
||||
const keys = await AsyncStorage.getAllKeys() |
||||
console.log(keys); |
||||
|
||||
} catch(e) { |
||||
// read key error
|
||||
} |
||||
// example console.log result:
|
||||
// ['@MyApp_user', '@MyApp_key']
|
||||
} |
||||
const insertAttachment = (files: any) => { |
||||
try { |
||||
files.forEach(async function(file:any) { |
||||
const url = `${PJU_API_URL}/addAttachment`; |
||||
await RNFetchBlob.config({ |
||||
trusty : true |
||||
}).fetch('POST', url,{ |
||||
"Content-Type": "application/json", |
||||
}, |
||||
JSON.stringify({pju_id:data.id, file:file.file, mimetype:file.file_type, size:file.fileSize}) |
||||
).then(async (resp) => { |
||||
const status = resp.respInfo.status |
||||
} |
||||
) |
||||
}); |
||||
} catch (error) { |
||||
console.log(error); |
||||
} |
||||
// files.forEach(async function(file:any){
|
||||
// const url = `${PJU_API_URL}/addAttachment`;
|
||||
// let result = await fetch(url, {
|
||||
// method: "POST",
|
||||
// headers: {
|
||||
// "Content-Type": "application/json"
|
||||
// },
|
||||
// body: JSON.stringify({pju_id:data.id, file:file.file, mimetype:file.file_type, size:file.fileSize})
|
||||
// })
|
||||
// if (result.status == 201) {
|
||||
// Alert.alert("Success")
|
||||
// setAlertOnline(false);
|
||||
// navigation.navigate('Property Survey', { screen: 'Property Survey'})
|
||||
// }
|
||||
// });
|
||||
} |
||||
const uploadFileOnHandler = async () => { |
||||
try { |
||||
const pickedFile = await DocumentPicker.pickSingle({ |
||||
type: [DocumentPicker.types.allFiles], |
||||
// allowMultiSelection:true
|
||||
}) |
||||
await RNFS.readFile(pickedFile.uri, 'base64').then(data => { |
||||
console.log('base64', data); |
||||
let your_bytes = btoa(data); |
||||
const newObj = { |
||||
file_type: pickedFile.type, |
||||
file: your_bytes |
||||
} |
||||
setFiles([...files,newObj]); |
||||
setFileDocument([...fileDocument,pickedFile]); |
||||
}); |
||||
} catch (error) { |
||||
console.error(error) |
||||
} |
||||
} |
||||
const deleteByIndex = (index:number) => { |
||||
setFileDocument(oldValues => { |
||||
return oldValues.filter((_: any, i: number) => i !== index) |
||||
}) |
||||
} |
||||
const [alertOnline, setAlertOnline] = useState(false); |
||||
const [alertOffline, setAlertOffline] = useState(false); |
||||
const showDialog = () => { |
||||
// if (imgUrl.length === 0) {
|
||||
// setattachmentImgError(true);
|
||||
// }
|
||||
// else{
|
||||
// setattachmentImgError(false);
|
||||
// }
|
||||
if (!pju_name) { |
||||
setPJUNameError(true); |
||||
} |
||||
else{ |
||||
setPJUNameError(false); |
||||
} |
||||
if (!selectedPJUType) { |
||||
setPJUTypeError(true); |
||||
} |
||||
else{ |
||||
setPJUTypeError(false); |
||||
} |
||||
if (!checkedStatus) { |
||||
setPJUStatusError(true); |
||||
} |
||||
else{ |
||||
setPJUStatusError(false); |
||||
} |
||||
if (!pju_info) { |
||||
setPJUInfoError(true); |
||||
} |
||||
else{ |
||||
setPJUInfoError(false); |
||||
} |
||||
if(!pju_name || !pju_info || !selectedPJUType || !checkedStatus) { |
||||
return false |
||||
} |
||||
if(connected){ |
||||
setAlertOnline(true); |
||||
} |
||||
else{ |
||||
setAlertOffline(true) |
||||
} |
||||
}; |
||||
const handleCancelAlertOnline = () => { |
||||
setAlertOnline(false); |
||||
}; |
||||
const handleCancelAlertOffline = () => { |
||||
setAlertOffline(false); |
||||
}; |
||||
const renderItem = ({item,index}:any) => { |
||||
return ( |
||||
<View key={index} style={{width:100,height:100,borderRadius:10,borderWidth:1,borderStyle:"dashed",flexDirection:'row'}}> |
||||
<Image style={{width: '100%',height: '100%',borderRadius:10}} |
||||
source={{uri: `data:image/jpeg;base64,${imgUrl[index]}`}} |
||||
/> |
||||
</View> |
||||
); |
||||
}; |
||||
return( |
||||
<View style={styles.mainContainer}> |
||||
<StatusBar backgroundColor="#34A6F8" barStyle={'light-content'} /> |
||||
<View key={"mainBackground"} style={{backgroundColor:'#34A6F8',width:'100%',height:'93%'}} /> |
||||
<View key={"background"} style={{backgroundColor:'#FFFFFF',width:'100%',height:'100%',position:'absolute',borderTopRightRadius:50,borderTopLeftRadius:35,paddingTop:25}}> |
||||
<ScrollView
|
||||
horizontal={false} |
||||
showsHorizontalScrollIndicator={false} |
||||
nestedScrollEnabled={true} |
||||
style={styles.container}> |
||||
<View style={{flexDirection:'column'}}> |
||||
{/* <Pressable onPress={()=>navigation.navigate('PJU Map Collect', { screen: 'PJU Map Collect'})} style={{alignItems:'center'}}> */} |
||||
<View style={{height:40,width:352,borderTopRightRadius:10,borderTopLeftRadius:10,borderWidth:1,borderColor:'#A6A6A6',backgroundColor:'#F9F9F9',justifyContent:'flex-start',flexDirection:'row',alignItems:'center',columnGap:5,alignSelf:'center'}}> |
||||
<Image |
||||
source={require('../../assets/icon/findmyloc.png')} |
||||
/> |
||||
<Text style={{fontSize:14,fontWeight:'semibold',color:'#434343'}}>{lat},</Text> |
||||
<Text style={{fontSize:14,fontWeight:'semibold',color:'#434343'}}>{long}</Text> |
||||
</View> |
||||
<MapView |
||||
style={{width:352,height:200,borderWidth:1,borderColor:'#A6A6A6',overflow:'hidden',alignSelf:'center'}} |
||||
mapStyle={styleURL} |
||||
rotateEnabled={false} |
||||
zoomEnabled={false} |
||||
attributionPosition={{bottom: 8, right: 8}} |
||||
scrollEnabled={false} |
||||
> |
||||
<PointAnnotation |
||||
children={<></>} |
||||
id={"pjuCoordinate"} |
||||
coordinate={[long, lat]} |
||||
/> |
||||
<Camera |
||||
centerCoordinate={[long, lat]} |
||||
allowUpdates={true} |
||||
zoomLevel={15} |
||||
minZoomLevel={5} |
||||
maxZoomLevel={20} |
||||
/> |
||||
</MapView> |
||||
{/* </Pressable> */} |
||||
<TouchableOpacity style={{alignSelf:'center',backgroundColor:'#F9F9F9',width:352,height:50,borderBottomLeftRadius:10,borderBottomRightRadius:10,justifyContent:'center',borderWidth:1,borderColor:'#A6A6A6'}} onPress={()=>navigation.navigate('MapView', { screen: 'MapView',data: { |
||||
id:data.id, |
||||
nama:pju_name, |
||||
jenis:selectedPJUType, |
||||
tanggal_installasi:momentDate, |
||||
status:checkedStatus, |
||||
keterangan:pju_info, |
||||
long:long, |
||||
lat:lat |
||||
}})}> |
||||
<Text style={{alignSelf:'center',fontWeight:'semibold',fontSize:16,color:'#434343'}}>Change Location</Text> |
||||
</TouchableOpacity> |
||||
</View> |
||||
<View |
||||
style={{ |
||||
marginTop: 15 |
||||
}} |
||||
/> |
||||
<View style={{alignSelf:'center'}}> |
||||
{/* <Text style={styles.label}>Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */} |
||||
<Text style={styles.label}>Name</Text> |
||||
<TextInput |
||||
style={styles.input} |
||||
onChangeText={(text) => { |
||||
setPJUname(text) |
||||
}} |
||||
onChange={()=> { |
||||
setPJUNameError(false) |
||||
}} |
||||
defaultValue={pju_name} |
||||
/> |
||||
{pjuNameError ? <Text style={styles.errorInput}>Name is Required!</Text>:null} |
||||
</View> |
||||
<View |
||||
style={{ |
||||
marginTop: 15 |
||||
}} |
||||
/> |
||||
<View style={{alignSelf:'center'}}> |
||||
{/* <Text style={styles.label}>PJU Type <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */} |
||||
<Text style={styles.label}>PJU Type</Text> |
||||
<SelectList |
||||
search={false} |
||||
placeholder="Select PJU Type" |
||||
boxStyles={{borderRadius:10,borderWidth:1,borderColor:'#A6A6A6',width:352,height:45}} |
||||
inputStyles={{color:'#6B5E5E'}} |
||||
dropdownTextStyles={{color:'#6B5E5E'}} |
||||
data={PJU_Type} |
||||
setSelected={setselectedPJUType} |
||||
onSelect={()=> ( |
||||
[setPJUTypeError(false)] |
||||
)} |
||||
defaultOption={{key:selectedPJUType, value:selectedPJUType}} |
||||
/> |
||||
</View> |
||||
{PJUTypeError ? <Text style={styles.errorInput}>PJU Type is Required!</Text>:null} |
||||
<View |
||||
style={{ |
||||
marginTop: 15 |
||||
}} |
||||
/> |
||||
<View style={{alignSelf:'center',width:352,height:45}}> |
||||
{/* <Text style={styles.label}>Status<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */} |
||||
<Text style={styles.label}>Status</Text> |
||||
<View style={{flexDirection:'row',alignItems:'center'}}> |
||||
<RadioButton |
||||
color='#434343' |
||||
value="Baik" |
||||
status={ checkedStatus === 'Baik' ? 'checked' : 'unchecked' } |
||||
onPress={() => {setCheckedStatus('Baik'); setPJUStatusError(false)}} |
||||
/> |
||||
<Text style={{color:"#434343",fontWeight:'semibold',fontSize:16}}>Baik</Text> |
||||
</View> |
||||
<View style={{flexDirection:'row',alignItems:'center'}}> |
||||
<RadioButton |
||||
color='#434343' |
||||
value="Rusak" |
||||
status={ checkedStatus === 'Rusak' ? 'checked' : 'unchecked' } |
||||
onPress={() => {setCheckedStatus('Rusak'); setPJUStatusError(false); }} |
||||
/> |
||||
<Text style={{color:"#434343",fontWeight:'semibold',fontSize:16}}>Rusak</Text> |
||||
</View> |
||||
{PJUStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null} |
||||
</View> |
||||
<View |
||||
style={{ |
||||
marginTop: 60 |
||||
}} |
||||
/> |
||||
<View style={{alignSelf:'center'}}> |
||||
<Text style={styles.label}>Information</Text> |
||||
<TextInput style={{borderWidth:1,borderRadius:20,padding: 10,color:'#6B5E5E',borderColor:'#A6A6A6',textAlignVertical:'top',width:352,height:135}} |
||||
multiline |
||||
numberOfLines={5} |
||||
maxLength={255} |
||||
onChangeText={(text) => { |
||||
setPJUinfo(text) |
||||
}} |
||||
onChange={()=> { |
||||
setPJUInfoError(false) |
||||
}} |
||||
defaultValue={pju_info} |
||||
/> |
||||
{PJUInfoError ? <Text style={styles.errorInput}>Information is Required!</Text>:null} |
||||
</View> |
||||
<View |
||||
style={{ |
||||
marginTop: 15 |
||||
}} |
||||
/> |
||||
<View style={{alignSelf:'center'}}> |
||||
<Text style={styles.label}>Installation Date</Text> |
||||
<TextInput |
||||
style={styles.input} |
||||
onPress={() => setOpen(true)} |
||||
value={String(momentDate)} |
||||
/> |
||||
<DatePicker |
||||
locale='en' |
||||
theme='light' |
||||
mode='date' |
||||
modal |
||||
open={open} |
||||
date={install_date} |
||||
onConfirm={(survey_date) => { |
||||
setOpen(false) |
||||
setInstallDate(survey_date) |
||||
}} |
||||
onCancel={() => { |
||||
setOpen(false) |
||||
}} |
||||
/> |
||||
</View> |
||||
<View |
||||
style={{ |
||||
marginTop: 15 |
||||
}} |
||||
/> |
||||
<View style={{alignSelf:'center',width:352}}> |
||||
<Text style={styles.label}>Attachment</Text> |
||||
<Text style={{fontStyle:'italic',color:'#434343',fontSize:14}}>Lampirkan foto / gambar</Text> |
||||
{
|
||||
imgUrl.length === 0 ? |
||||
<Pressable onPress={()=>setModalAttachment(true)}> |
||||
<View style={{width:352,height:70,borderRadius:10,borderStyle:'dashed',borderWidth:2,borderCurve:'continuous',borderColor:'#434343',alignItems:'center',justifyContent:'center',flexDirection:'row',columnGap:5}}> |
||||
<Image |
||||
source={require('../../assets/icon/camorlib.png')} |
||||
/> |
||||
<Text style={{fontStyle:'italic',color:'#434343'}}>Klik untuk menambahkan foto / gambar</Text> |
||||
</View> |
||||
</Pressable> |
||||
: |
||||
<FlatList |
||||
horizontal={false} |
||||
showsHorizontalScrollIndicator={false} |
||||
scrollEnabled={false} |
||||
ListFooterComponent={()=> |
||||
<Pressable onPress={()=>setModalAttachment(true)}> |
||||
<View style={{width:100,height:100,borderRadius:10,borderWidth:1,borderStyle:"dashed",flexDirection:'row',alignItems:'center',justifyContent:'center'}}> |
||||
<Image |
||||
source={require('../../assets/icon/camorlib.png')} |
||||
/> |
||||
</View> |
||||
</Pressable> |
||||
} |
||||
contentContainerStyle={{flexDirection:'row',flexWrap:'wrap',columnGap:25,rowGap:10}} |
||||
data={imgUrl} |
||||
renderItem={({item,index})=>renderItem({item,index})} |
||||
/> |
||||
} |
||||
</View> |
||||
<View |
||||
style={{ |
||||
marginTop: 30 |
||||
}} |
||||
/> |
||||
</ScrollView> |
||||
<TouchableOpacity style={{width:'100%',height:50,backgroundColor:'#34A6F8',alignItems:'center',justifyContent:'center'}} onPress={showDialog}> |
||||
<Text style={{fontSize:18,fontWeight:'bold',color:'#FFFFFF'}}>RESEND</Text> |
||||
</TouchableOpacity> |
||||
</View> |
||||
{/* Online Mode Alert */} |
||||
<AwesomeAlert |
||||
show={alertOnline} |
||||
showProgress={false} |
||||
title="Collecting Data" |
||||
message="Are you sure for Add New PJU data?" |
||||
closeOnTouchOutside={false} |
||||
closeOnHardwareBackPress={false} |
||||
showCancelButton={true} |
||||
showConfirmButton={true} |
||||
cancelText="No, cancel" |
||||
confirmText="Yes, Add it" |
||||
confirmButtonColor="#137997" |
||||
onCancelPressed={() => { |
||||
handleCancelAlertOnline(); |
||||
}} |
||||
onConfirmPressed={() => { |
||||
collectDataOnline(); |
||||
}} |
||||
overlayStyle={{width:'100%'}} |
||||
contentContainerStyle={{width:'70%',borderRadius:10}} |
||||
titleStyle={{fontSize:20}} |
||||
messageStyle={{fontSize:16}} |
||||
/> |
||||
{/* Offline Mode Alert */} |
||||
<AwesomeAlert |
||||
show={alertOffline} |
||||
showProgress={false} |
||||
title="You are offline" |
||||
message="You need connection for editing data." |
||||
closeOnTouchOutside={false} |
||||
closeOnHardwareBackPress={false} |
||||
showConfirmButton={true} |
||||
confirmText="Ok" |
||||
confirmButtonColor="#DD6B55" |
||||
onConfirmPressed={() => { |
||||
setAlertOffline(false); |
||||
}} |
||||
overlayStyle={{width:'100%'}} |
||||
contentContainerStyle={{width:'70%',borderRadius:10}} |
||||
titleStyle={{fontSize:20}} |
||||
messageStyle={{fontSize:16}} |
||||
/> |
||||
<Modal isVisible={ModalAttachment} animationIn={'fadeInUp'} animationOut={'fadeOutDown'} backdropOpacity={0} onBackdropPress={()=>setModalAttachment(false)} style={{top:'18%',alignSelf:'center'}}> |
||||
<View key={"modal container"} style={{width:330,height:220,backgroundColor:'#F9F9F9',borderRadius:25,borderWidth:1,borderColor:'#A6A6A6'}}> |
||||
<View style={{flexDirection:'row',alignItems:'center',justifyContent:'space-between',paddingLeft:30,paddingTop:20,paddingRight:10}}> |
||||
<Text style={{fontSize:20,fontWeight:'semibold',color: '#434343',}}> |
||||
Select Mode |
||||
</Text> |
||||
<Pressable onPress={()=>setModalAttachment(false)} style={{alignSelf:'flex-end',padding:10}}> |
||||
<Image style={{tintColor:'#434343'}} |
||||
source={require('../../assets/icon/x.png')} |
||||
/> |
||||
</Pressable> |
||||
</View> |
||||
<View style={{padding:30}}> |
||||
<TouchableOpacity onPress={()=>{openCameraLib(),setModalAttachment(false)}} style={{height:50,backgroundColor:'#FFFFFF',alignItems:'center',justifyContent:'center',borderTopLeftRadius:10,borderTopRightRadius:10,borderWidth:1,borderColor:'#A6A6A6'}}> |
||||
<Text style={{fontSize:20,fontWeight:'light',color:'#434343'}}>Take photo</Text> |
||||
</TouchableOpacity> |
||||
<TouchableOpacity onPress={()=>{openLib(),setModalAttachment(false)}} style={{height:50,backgroundColor:'#FFFFFF',alignItems:'center',justifyContent:'center',borderBottomLeftRadius:10,borderBottomRightRadius:10,borderWidth:1,borderColor:'#A6A6A6'}}> |
||||
<Text style={{fontSize:20,fontWeight:'light',color:'#434343'}}>Choose photo</Text> |
||||
</TouchableOpacity> |
||||
</View> |
||||
</View> |
||||
</Modal> |
||||
</View> |
||||
) |
||||
} |
||||
const styles = StyleSheet.create({ |
||||
errorInput: { |
||||
color: 'red', |
||||
marginLeft: 20 |
||||
}, |
||||
inputLong: { |
||||
height: 40, |
||||
borderWidth: 1, |
||||
padding: 10, |
||||
width: 180, |
||||
marginRight: 20 |
||||
}, |
||||
inputLat: { |
||||
height: 40, |
||||
borderWidth: 1, |
||||
padding: 10, |
||||
borderRadius: 50, |
||||
width: 180, |
||||
color: 'black' |
||||
}, |
||||
input: { |
||||
width:352, |
||||
height: 45, |
||||
borderWidth: 1, |
||||
padding: 10, |
||||
borderRadius: 10, |
||||
color: '#6B5E5E', |
||||
borderColor:'#A6A6A6' |
||||
}, |
||||
container: { |
||||
padding: 10, |
||||
flexGrow: 1 |
||||
}, |
||||
mainContainer: { |
||||
flex: 1, |
||||
}, |
||||
label: { |
||||
fontSize: 16, |
||||
fontWeight:'semibold', |
||||
color: '#434343', |
||||
// marginBottom: 20
|
||||
}, |
||||
title: { |
||||
alignItems: 'center', |
||||
justifyContent: 'center', |
||||
alignSelf: 'center', |
||||
fontWeight: 'bold', |
||||
fontSize: 22, |
||||
color: 'black', |
||||
marginBottom: 10 |
||||
}, |
||||
borderImg: { |
||||
borderColor: 'black', |
||||
borderWidth: 1, |
||||
borderRadius: 20, |
||||
}, |
||||
img: { |
||||
width: 330, |
||||
height: 500, |
||||
borderRadius: 6, |
||||
}, |
||||
btnCameraContainer: { |
||||
flexDirection: 'row', |
||||
justifyContent: 'space-around', |
||||
top:10, |
||||
|
||||
}, |
||||
btnCamera: { |
||||
alignItems: 'center', |
||||
justifyContent: 'center', |
||||
alignSelf: 'center', |
||||
width: 100, |
||||
height: 40, |
||||
bottom:20, |
||||
borderRadius: 6, |
||||
backgroundColor: '#80CBD3' |
||||
}, |
||||
textBtn: { |
||||
color: '#fff' |
||||
}, |
||||
buttonImageIconStyle: { |
||||
padding: 10, |
||||
margin: 5, |
||||
height: 25, |
||||
width: 25, |
||||
resizeMode: 'stretch', |
||||
}, |
||||
}); |
||||
|
||||
export default ResendPJU; |
||||
Loading…
Reference in new issue