Browse Source

update

master
Irul24 1 year ago
parent
commit
05546dff2f
  1. 24
      App.tsx
  2. 596
      src/component/collectLinescreen.tsx
  3. 64
      src/component/collectPolygonscreen.tsx
  4. 110
      src/component/collectscreen.tsx
  5. 11
      src/component/draftPDAM.tsx
  6. 3
      src/component/draftPJU.tsx
  7. 644
      src/component/editLinescreen.tsx
  8. 463
      src/component/editPolygonscreen.tsx
  9. 365
      src/component/editscreen.tsx
  10. 3
      src/component/mapCollectPolygonScreen.tsx
  11. 20
      src/component/mapViewLineScreen.tsx
  12. 22
      src/component/mapViewPolygonScreen.tsx
  13. 14
      src/component/mapviewscreen.tsx
  14. 801
      src/component/resendPDAM.tsx
  15. 799
      src/component/resendPJU.tsx

24
App.tsx

@ -46,6 +46,8 @@ import MapViewLineScreen from './src/component/mapViewLineScreen'; @@ -46,6 +46,8 @@ import MapViewLineScreen from './src/component/mapViewLineScreen';
import SettingScreen from './src/component/settingScreen';
import MyAccount from './src/component/myAccount';
import ChangePass from './src/component/changePassword';
import ResendPJU from './src/component/resendPJU';
import ResendPDAM from './src/component/resendPDAM';
import { USER_API_URL } from "../SurveyApp/urlConfig";
import { PermissionsAndroid } from 'react-native';
@ -549,6 +551,28 @@ export const Nav = () => { @@ -549,6 +551,28 @@ export const Nav = () => {
fontSize:20
}
}}/>
<Stack.Screen name="Resend PJU" component={ResendPJU}
options={{
headerStyle: {
backgroundColor: '#34A6F8',
},
headerTintColor: '#FFFFFF',
headerShadowVisible: false,
headerTitleStyle: {
fontSize:20
}
}}/>
<Stack.Screen name="Resend PDAM" component={ResendPDAM}
options={{
headerStyle: {
backgroundColor: '#34A6F8',
},
headerTintColor: '#FFFFFF',
headerShadowVisible: false,
headerTitleStyle: {
fontSize:20
}
}}/>
<Stack.Screen name="Setting" component={SettingScreen}
options={{
headerStyle: {

596
src/component/collectLinescreen.tsx

@ -15,8 +15,7 @@ import turfcenter from '@turf/center'; @@ -15,8 +15,7 @@ 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 {useIsFocused} from '@react-navigation/native';
import { PDAM_API_URL } from "../../urlConfig";
import React from 'react';
@ -26,7 +25,6 @@ type collectLineScreenProps = {route: any,navigation: any}; @@ -26,7 +25,6 @@ type collectLineScreenProps = {route: any,navigation: any};
export default function CollectLineScreen({route,navigation}:collectLineScreenProps) {
console.log("route",route.params);
const apiKey = "JoJs2pcDv5o0yQlQLMfI";
const [basemap, setBasemap] = useState("streets-v2");
const styleURL = `https://api.maptiler.com/maps/${basemap}/style.json?key=${apiKey}`;
@ -37,18 +35,30 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr @@ -37,18 +35,30 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr
{key:'Pipa 10"', value:'Pipa 10"'},
]
const [centerCoords,setCenterCoords] = useState<number[]>([]);
const isFocused = useIsFocused();
const [userID,setUserID] = useState();
useEffect(()=>{
let centCord = turfcenter(points(route.params.coordinates));
console.log('center');
console.log(centCord.geometry.coordinates);
setCenterCoords(centCord.geometry.coordinates);
const unsubscribe = NetInfo.addEventListener((state) => {
setConnected(state.isConnected!)
});
return () => {
unsubscribe();
if(isFocused){
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()
let centCord = turfcenter(points(route.params.coordinates));
// console.log('center');
// console.log(centCord.geometry.coordinates);
setCenterCoords(centCord.geometry.coordinates);
const unsubscribe = NetInfo.addEventListener((state) => {
setConnected(state.isConnected!)
});
return () => {
unsubscribe();
};
};
},[])
},[isFocused])
const ref = useRef();
const [connected, setConnected] = useState(true);
@ -68,7 +78,7 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr @@ -68,7 +78,7 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr
const [pipeTyeError, setPipeTypeError] = useState(false);
const [pipeStatusError, setPipeStatusError] = useState(false);
const [pipeInfoError, setPipeInfoError] = useState(false);
const [ModalAttachment, setModalAttachment] = useState(false);
const [ModalAttachment, setModalAttachment] = useState(false);
const openCameraLib = async () => {
const result = await launchCamera({
@ -198,6 +208,16 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr @@ -198,6 +208,16 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr
status: 0,
body: {},
}
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);
const geom = route.params.coordinates.map((item:any)=>{
return String(item).replace(',',' ')
})
@ -207,7 +227,9 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr @@ -207,7 +227,9 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr
tanggal_installasi: momentDate,
status: checkedStatus,
keterangan: Information,
geom: `MULTILINESTRING((${geom}))`
geom: `MULTILINESTRING((${geom}))`,
created_by: userID,
created_at: localTime
}
await RNFetchBlob.config({
trusty : true
@ -284,298 +306,298 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr @@ -284,298 +306,298 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr
<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}>
<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}
<View key={"background"} style={{backgroundColor:'#FFFFFF',width:'100%',height:'100%',position:'absolute',borderTopRightRadius:50,borderTopLeftRadius:35,paddingTop:25}}>
<ScrollView style={styles.container}>
<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": route.params.coordinates
}
}
]
}}
>
<Camera
centerCoordinate={centerCoords}
zoomLevel={15}
minZoomLevel={5}
maxZoomLevel={20}
<LineLayer
id="linelayer1"
style={{lineColor:'red',lineWidth:3}}
/>
<ShapeSource
id="line"
shape={{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": route.params.coordinates
}
}
]
}}
>
<LineLayer
id="linelayer1"
style={{lineColor:'red',lineWidth:3}}
/>
</ShapeSource>
{
route.params.coordinates.map((item:any,index:number)=>(
<PointAnnotation
children={<></>}
key={index}
id={String(index)}
coordinate={item}
draggable={false}
/>
))
}
</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('PDAM Map Collect', { screen: 'PDAM Map Collect'})}>
<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}>Pipe Name</Text>
<TextInput
style={styles.input}
onChangeText={(text) => {
setPipeName(text)
}}
onChange={()=> {
setPipeNameError(false)
}}
/>
{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}>PJU 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)]
)}
/>
{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
}}
</ShapeSource>
{
route.params.coordinates.map((item:any,index:number)=>(
<PointAnnotation
children={<></>}
key={index}
id={String(index)}
coordinate={item}
draggable={false}
/>
))
}
</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('PDAM Map Collect', { screen: 'PDAM Map Collect'})}>
<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}>Pipe Name</Text>
<TextInput
style={styles.input}
onChangeText={(text) => {
setPipeName(text)
}}
onChange={()=> {
setPipeNameError(false)
}}
/>
<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)
}}
/>
{pipeInfoError ? <Text style={styles.errorInput}>Information is Required!</Text>:null}
</View>
<View
{pipeNameError ? <Text style={styles.errorInput}>Pipe Name is Required!</Text>:null}
</View>
<View
style={{
marginTop: 15
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)]
)}
/>
<View style={{alignSelf:'center'}}>
<Text style={styles.label}>Installation Date</Text>
<TextInput
style={styles.input}
onPress={() => setOpen(true)}
value={String(momentDate)}
{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)}}
/>
<DatePicker
locale='en'
theme='light'
mode='date'
modal
open={open}
date={install_date}
onConfirm={(survey_date) => {
setOpen(false)
setInstallDate(survey_date)
}}
onCancel={() => {
setOpen(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>
<View
{pipeStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null}
</View>
<View
style={{
marginTop: 15
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)
}}
/>
<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
{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>
<Button title='Send' onPress={showDialog} />
<TouchableOpacity style={{width:'100%',height:50,backgroundColor:'#34A6F8',alignItems:'center',justifyContent:'center'}} onPress={showDialog}>
<Text style={{fontSize:18,fontWeight:'bold',color:'#FFFFFF'}}>SEND</Text>
</TouchableOpacity>
</View>
<AwesomeAlert
show={alertOnline}
showProgress={false}
title="Collecting Data"
message="Are you sure for Collecting PDAM data?"
closeOnTouchOutside={false}
closeOnHardwareBackPress={false}
showCancelButton={true}
showConfirmButton={true}
cancelText="No, cancel"
confirmText="Yes, Collect it"
confirmButtonColor="#137997"
onCancelPressed={() => {
handleCancelAlertOnline();
}}
onConfirmPressed={() => {
collectDataOnline();
}}
overlayStyle={{width:'100%'}}
contentContainerStyle={{width:'70%',borderRadius:10}}
titleStyle={{fontSize:20}}
messageStyle={{fontSize:16}}
/>
show={alertOnline}
showProgress={false}
title="Collecting Data"
message="Are you sure for Collecting PDAM data?"
closeOnTouchOutside={false}
closeOnHardwareBackPress={false}
showCancelButton={true}
showConfirmButton={true}
cancelText="No, cancel"
confirmText="Yes, Collect 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>
{/* 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>
</View>
</Modal>
</Modal>
</View>
)
);
};
const styles = StyleSheet.create({

64
src/component/collectPolygonscreen.tsx

@ -16,9 +16,10 @@ const {points,polygon,lineString} = require('@turf/helpers'); @@ -16,9 +16,10 @@ const {points,polygon,lineString} = require('@turf/helpers');
import DocumentPicker from "react-native-document-picker";
import RNFS from 'react-native-fs';
import RNFetchBlob from 'rn-fetch-blob';
import {useIsFocused} from '@react-navigation/native';
import {useAuth} from '../../src/component/authContext';
import { PERMIT_API_URL } from "../../urlConfig";
import React from 'react';
type collectPolygonScreenProps = {route: any,navigation: any};
@ -26,24 +27,36 @@ type collectPolygonScreenProps = {route: any,navigation: any}; @@ -26,24 +27,36 @@ type collectPolygonScreenProps = {route: any,navigation: any};
export default function CollectPolygonScreen({route,navigation}:collectPolygonScreenProps) {
// const { authState } = useAuth();
console.log("route",route.params);
const apiKey = "JoJs2pcDv5o0yQlQLMfI";
const [basemap, setBasemap] = useState("streets-v2");
const styleURL = `https://api.maptiler.com/maps/${basemap}/style.json?key=${apiKey}`;
const [centerCoords,setCenterCoords] = useState<number[]>([]);
const isFocused = useIsFocused();
const [userID,setUserID] = useState();
useEffect(()=>{
let centCord = turfcenter(points(route.params.coordinates));
console.log('center');
console.log(centCord.geometry.coordinates);
setCenterCoords(centCord.geometry.coordinates);
const unsubscribe = NetInfo.addEventListener((state) => {
setConnected(state.isConnected!)
});
return () => {
unsubscribe();
if(isFocused){
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()
let centCord = turfcenter(points(route.params.coordinates));
console.log('center');
console.log(centCord.geometry.coordinates);
setCenterCoords(centCord.geometry.coordinates);
const unsubscribe = NetInfo.addEventListener((state) => {
setConnected(state.isConnected!)
});
return () => {
unsubscribe();
};
};
},[])
},[isFocused])
const ref = useRef();
const [connected, setConnected] = useState(true);
@ -183,6 +196,16 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc @@ -183,6 +196,16 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc
};
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);
const geom = route.params.coordinates.map((item:any)=>{
return String(item).replace(',',' ')
})
@ -194,7 +217,9 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc @@ -194,7 +217,9 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc
company_name: companyName,
location: location,
permit_status: checkedStatus,
geom: `MULTIPOLYGON (((${geom},${String(route.params.coordinates[0]).replace(","," ")})))`
geom: `MULTIPOLYGON (((${geom},${String(route.params.coordinates[0]).replace(","," ")})))`,
created_by: userID,
created_at: localTime
}
console.log(obj);
await RNFetchBlob.config({
@ -296,8 +321,8 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc @@ -296,8 +321,8 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc
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}}>
<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}
@ -440,11 +465,6 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc @@ -440,11 +465,6 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc
:
null
}
<View
style={{
marginTop: 15
}}
/>
<View style={{alignSelf:'center'}}>
<Text style={styles.label}>Location Detail</Text>
<TextInput style={{borderWidth:1,borderRadius:20,padding: 10,color:'#6B5E5E',borderColor:'#A6A6A6',textAlignVertical:'top',width:352,height:135}}
@ -533,7 +553,9 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc @@ -533,7 +553,9 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc
}}
/>
</ScrollView>
<Button title='Send' onPress={showDialog} />
<TouchableOpacity style={{width:'100%',height:50,backgroundColor:'#34A6F8',alignItems:'center',justifyContent:'center'}} onPress={showDialog}>
<Text style={{fontSize:18,fontWeight:'bold',color:'#FFFFFF'}}>SEND</Text>
</TouchableOpacity>
</View>
<AwesomeAlert

110
src/component/collectscreen.tsx

@ -16,7 +16,7 @@ import { @@ -16,7 +16,7 @@ import {
Dimensions
} from 'react-native';
import {useAuth} from '../../src/component/authContext';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import { SelectList } from 'react-native-dropdown-select-list';
import DatePicker from 'react-native-date-picker';
@ -32,6 +32,7 @@ import { RadioButton } from 'react-native-paper'; @@ -32,6 +32,7 @@ import { RadioButton } from 'react-native-paper';
import AwesomeAlert from 'react-native-awesome-alerts';
import RNFetchBlob from 'rn-fetch-blob';
import Modal from "react-native-modal";
import {useIsFocused} from '@react-navigation/native';
import { PJU_API_URL } from "../../urlConfig";
@ -47,6 +48,7 @@ function CollectScreen({route,navigation}: collectScreenProps) { @@ -47,6 +48,7 @@ function CollectScreen({route,navigation}: collectScreenProps) {
const [fileDocument, setFileDocument] = useState([]);
const [currentIndex, setCurrentIndex] = useState(0);
const [connected, setConnected] = useState(true)
// const { authState } = useAuth();
const openCameraLib = async () => {
const result = await launchCamera({
@ -153,36 +155,49 @@ function CollectScreen({route,navigation}: collectScreenProps) { @@ -153,36 +155,49 @@ function CollectScreen({route,navigation}: collectScreenProps) {
const [PJUInfoError, setPJUInfoError] = useState(false);
const [attachmentSuccess, setAttachmentSuccess] = useState(0);
const [ModalAttachment, setModalAttachment] = useState(false);
const [userID,setUserID] = useState();
const isFocused = useIsFocused();
useEffect(()=> {
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 () => {
unsubscribe();
if(isFocused){
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 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()
const unsubscribe = NetInfo.addEventListener((state) => {
setConnected(state.isConnected!)
});
return () => {
unsubscribe();
};
};
},[]);
},[isFocused]);
const collectDataOnline = async() => {
try {
@ -190,6 +205,36 @@ function CollectScreen({route,navigation}: collectScreenProps) { @@ -190,6 +205,36 @@ function CollectScreen({route,navigation}: collectScreenProps) {
status: 0,
body: {},
}
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'
}
]
)
}
});
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`,{
@ -202,7 +247,9 @@ function CollectScreen({route,navigation}: collectScreenProps) { @@ -202,7 +247,9 @@ function CollectScreen({route,navigation}: collectScreenProps) {
tanggal_installasi: momentDate,
status: checkedStatus,
keterangan: pju_info,
geom: `POINT(${fixCoordinate.long} ${fixCoordinate.lat})`
geom: `POINT(${fixCoordinate.long} ${fixCoordinate.lat})`,
created_by: userID,
created_at: localTime
})
).then(async (resp) => {
const json = resp.json()
@ -635,7 +682,9 @@ function CollectScreen({route,navigation}: collectScreenProps) { @@ -635,7 +682,9 @@ function CollectScreen({route,navigation}: collectScreenProps) {
/> */}
</ScrollView>
<Button title='Send' onPress={showDialog} />
<TouchableOpacity style={{width:'100%',height:50,backgroundColor:'#34A6F8',alignItems:'center',justifyContent:'center'}} onPress={showDialog}>
<Text style={{fontSize:18,fontWeight:'bold',color:'#FFFFFF'}}>SEND</Text>
</TouchableOpacity>
</View>
@ -713,7 +762,6 @@ function CollectScreen({route,navigation}: collectScreenProps) { @@ -713,7 +762,6 @@ function CollectScreen({route,navigation}: collectScreenProps) {
<Text style={{fontSize:20,fontWeight:'light',color:'#434343'}}>Choose photo</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
</View>

11
src/component/draftPDAM.tsx

@ -402,15 +402,12 @@ function DraftPDAM({route,navigation}: sendListDataProps) { @@ -402,15 +402,12 @@ function DraftPDAM({route,navigation}: sendListDataProps) {
<MenuOptions customStyles={optionsStyles}>
<MenuOption
onSelect={()=>{
navigation.navigate('Edit',{ screen: 'Edit',data: {
id:item.id,
nama:item.pju_name,
jenis:item.pju_type,
navigation.navigate('Resend PDAM',{ screen: 'Resend PDAM',data: {
nama:item.pipe_name,
jenis:item.pipe_type,
tanggal_installasi:item.installation_date,
status:item.status,
keterangan:item.keterangan,
long:item.long,
lat:item.lat
geom:item.geom
}});
}}
children={

3
src/component/draftPJU.tsx

@ -405,8 +405,7 @@ function DraftPJU({route,navigation}: sendListDataProps) { @@ -405,8 +405,7 @@ function DraftPJU({route,navigation}: sendListDataProps) {
<MenuOptions customStyles={optionsStyles}>
<MenuOption
onSelect={()=>{
navigation.navigate('Edit',{ screen: 'Edit',data: {
id:item.id,
navigation.navigate('Resend PJU',{ screen: 'Resend PJU',data: {
nama:item.pju_name,
jenis:item.pju_type,
tanggal_installasi:item.installation_date,

644
src/component/editLinescreen.tsx

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from 'react';
import {View,Text, StyleSheet, ScrollView, TouchableOpacity, Image, Animated, TextInput, Button, Alert} from 'react-native';
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";
@ -14,6 +14,7 @@ import {useNavigation,NavigationContainer,useIsFocused} from '@react-navigation/ @@ -14,6 +14,7 @@ import {useNavigation,NavigationContainer,useIsFocused} from '@react-navigation/
import turfcenter from '@turf/center';
const {points,polygon,lineString} = require('@turf/helpers');
import RNFetchBlob from 'rn-fetch-blob';
import Modal from "react-native-modal";
@ -26,6 +27,9 @@ type collectLineScreenProps = {route: any,navigation: any}; @@ -26,6 +27,9 @@ type collectLineScreenProps = {route: any,navigation: any};
export default function EditLineScreen({route,navigation}:collectLineScreenProps) {
// console.log("route",route.params);
const {data,coors} = route.params;
console.log("data",data);
const apiKey = "JoJs2pcDv5o0yQlQLMfI";
const [basemap, setBasemap] = useState("streets-v2");
const styleURL = `https://api.maptiler.com/maps/${basemap}/style.json?key=${apiKey}`;
@ -58,18 +62,15 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps @@ -58,18 +62,15 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
const [secondPress,setSecondPress] = useState(false);
const isFocused = useIsFocused();
const [centerCoords,setCenterCoords] = useState<number[]>([]);
const [ModalAttachment, setModalAttachment] = useState(false);
useEffect(()=>{
if (isFocused) {
if (coors === undefined) {
console.log("awal");
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)
@ -130,8 +131,7 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps @@ -130,8 +131,7 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
// error reading value
}
}
}
const fetchData = async () => {
try {
await RNFetchBlob.config({
@ -287,16 +287,14 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps @@ -287,16 +287,14 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
},
JSON.stringify({pdam_id:data.id, file:file.file, mimetype:file.file_type, size:file.fileSize})
).then(async (resp) => {
Alert.alert("Success")
setAlertOnline(false);
navigation.navigate('Property Survey', { screen: 'Property Survey'})
}
)
});
} catch (error) {
console.log(error);
}
}
};
const collectDataOnline = async () => {
try {
const geom = coordinates.map((item:any)=>{
@ -322,6 +320,9 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps @@ -322,6 +320,9 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
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")
@ -369,321 +370,344 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps @@ -369,321 +370,344 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
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}>
<View>
<Text style={styles.label}>Image</Text>
<View style={styles.borderImg}>
<Text style={{justifyContent: 'center', alignItems: 'center', alignSelf: 'center', color: 'black'}}>{imgUrl.length === 0 ? currentIndex :currentIndex+1}/{imgUrl.length}</Text>
<View style={{flexDirection: 'row'}}>
<PrevImg isIndex={currentIndex}/>
<Animated.FlatList
ref={ref}
data={imgUrl}
showsHorizontalScrollIndicator={false}
pagingEnabled
onScroll={e=>{
const x = e.nativeEvent.contentOffset.x;
setCurrentIndex(parseFloat((x/330).toFixed(0)));
}}
horizontal
renderItem={({item,index}) => {
return(
<Animated.Image resizeMode='center' style={{width: 350,
height: 500,
borderRadius: 6,}} source={{uri: `data:image/jpeg;base64,${imgUrl[index]}`}} />
)
}}
/>
<NextImg isIndex={currentIndex}/>
</View>
<View style={styles.btnCameraContainer}>
<TouchableOpacity style={styles.btnCamera} onPress={openCameraLib}>
<Image
source={require('../../assets/icon/camera.png')}
style={styles.buttonImageIconStyle}
/>
</TouchableOpacity>
<TouchableOpacity style={styles.btnCamera} onPress={openLib}>
<Image
source={require('../../assets/icon/gallery.png')}
style={styles.buttonImageIconStyle}
/>
</TouchableOpacity>
</View>
</View>
</View>
<View
style={{
marginTop: 15
}}
/>
{
!loadGeom ?
<View style={{flexDirection:'column'}}>
<MapView
style={{width:'80%',height:160,alignSelf:'center'}}
mapStyle={styleURL}
zoomEnabled={false}
scrollEnabled={false}
>
<Camera
centerCoordinate={centerCoords}
zoomLevel={17}
minZoomLevel={5}
maxZoomLevel={20}
/>
<ShapeSource
id="line"
shape={{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": coordinates
}
}
]
}}
>
<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',paddingTop:10}} 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
}});
{
!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": coordinates
}
}
]
}}
>
<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}
/>
))
}
}>
<View style={{backgroundColor:'#217dd3',flexDirection:'row',width:200,height:30,borderRadius:20,justifyContent:'center'}}>
<Text style={{alignSelf:'center',fontWeight:'bold',fontSize:16,color:'white'}}>View & Change Location</Text>
</View>
</TouchableOpacity>
:
<TouchableOpacity style={{alignSelf:'center',paddingTop:10}} onPress={()=>{navigation.navigate('Map View Line', { screen: 'Map View Line',data: {
</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,coordinates[0]]
geom:coordinates
}});
}
}>
<View style={{backgroundColor:'#217dd3',flexDirection:'row',width:200,height:30,borderRadius:20,justifyContent:'center'}}>
<Text style={{alignSelf:'center',fontWeight:'bold',fontSize:16,color:'white'}}>View & Change Location</Text>
</View>
</TouchableOpacity>
}
}>
<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={{
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}
/>
<View>
<Text style={styles.label}>Pipe Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
<TextInput
style={styles.input}
onChangeText={(text)=>{
setPipeName(text)
}}
onChange={()=> {
setPipeNameError(false)
}}
defaultValue={pipeName}
/>
{pipeNameError ? <Text style={styles.errorInput}>Name is Required!</Text>:null}
</View>
<View
style={{
marginTop: 15
}}
{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}}
/>
<View>
<Text style={styles.label}>Pipe Type <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
<SelectList
search={false}
placeholder="Select Pipe Type"
boxStyles={{borderRadius:50,borderWidth:2}}
inputStyles={{color:'black'}}
dropdownTextStyles={{color:'black'}}
data={Pipe_Type}
setSelected={setselectedPipeType}
onSelect={()=> (
setPipeTypeError(false)
)}
defaultOption={{key:selectedPipeType, value:selectedPipeType}}
/>
{pipeTyeError ? <Text style={styles.errorInput}>Pipe Type is Required!</Text>:null}
{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={{
marginTop: 15
}}
/>
<View>
<Text style={styles.label}>Status <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
<View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton
value="Baik"
status={ checkedStatus === 'Baik' ? 'checked' : 'unchecked' }
onPress={()=>{
setCheckedStatus('Baik');
setPipeStatusError(false);
}}
/>
<Text style={{color:'black'}}>Baik</Text>
</View>
<View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton
value="Rusak"
status={ checkedStatus === 'Rusak' ? 'checked' : 'unchecked' }
onPress={()=>{
setCheckedStatus('Rusak');
setPipeStatusError(false);
}}
/>
<Text style={{color:'black'}}>Rusak</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
style={{
marginTop: 15
}}
</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}
/>
<View>
<Text style={styles.label}>Information <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
<TextInput style={{borderWidth:1,borderRadius:20,padding: 10,color:'black',textAlignVertical:'top'}}
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
}}
{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)}
/>
<View>
<Text style={styles.label}>Installation Date</Text>
<TextInput
style={styles.input}
onPress={() => setOpen(true)}
value={String(momentDate)}
/>
<DatePicker
locale='en'
theme='dark'
mode="date"
modal
open={open}
date={install_date}
onConfirm={(survey_date) => {
setOpen(false)
setInstallDate(survey_date)
}}
onCancel={() => {
setOpen(false)
}}
/>
</View>
<View
style={{
marginTop: 15
}}
<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>
<Button title='Send' onPress={showDialog} />
{/* 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}}
/>
<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({
@ -707,23 +731,25 @@ const styles = StyleSheet.create({ @@ -707,23 +731,25 @@ const styles = StyleSheet.create({
color: 'black'
},
input: {
height: 40,
width:352,
height: 45,
borderWidth: 1,
padding: 10,
borderRadius: 50,
color: 'black'
borderRadius: 10,
color: '#6B5E5E',
borderColor:'#A6A6A6'
},
container: {
flex: 1,
backgroundColor: '#ecf0f1',
padding: 10,
flexGrow: 1
},
mainContainer: {
flex: 1,
},
label: {
fontSize: 21,
color: 'black',
fontSize: 16,
fontWeight:'semibold',
color: '#434343',
// marginBottom: 20
},
title: {

463
src/component/editPolygonscreen.tsx

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from 'react';
import {View,Text, StyleSheet, ScrollView, TouchableOpacity, Image, Animated, TextInput, Button, Alert} from 'react-native';
import {View,Text, StyleSheet, ScrollView, TouchableOpacity, Image, Animated, TextInput, Button, Alert, Pressable, StatusBar, FlatList} from 'react-native';
import {useNavigation,NavigationContainer,useIsFocused} from '@react-navigation/native';
import MapLibreGL from '@maplibre/maplibre-react-native';
import { MapView,ShapeSource,Camera,UserLocation,PointAnnotation,FillLayer,LineLayer,VectorSource } from "@maplibre/maplibre-react-native";
@ -61,8 +61,6 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr @@ -61,8 +61,6 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
const [delay,setDelay] = useState(false);
const [secondPress,setSecondPress] = useState(false);
const isFocused = useIsFocused();
// console.log(isFocused);
useEffect(()=>{
if (isFocused) {
if (coors === undefined) {
@ -108,8 +106,6 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr @@ -108,8 +106,6 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
unsubscribe();
};
},[isFocused])
const openCameraLib = async () => {
const result = await launchCamera({
mediaType: 'photo',
@ -258,6 +254,9 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr @@ -258,6 +254,9 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
const status = resp.respInfo.status
if (status == 201) {
insertAttachment(files)
Alert.alert("Success")
setAlertOnline(false);
navigation.navigate('Inbox Land Permit', { screen: 'Inbox Land Permit'})
}
else {
Alert.alert("Internal Server Error")
@ -283,8 +282,6 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr @@ -283,8 +282,6 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
};
const insertAttachment = async (files: any) => {
try {
files.forEach(async function(file:any){
const url = `${PERMIT_API_URL}/addAttachment`;
await RNFetchBlob.config({
@ -295,14 +292,6 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr @@ -295,14 +292,6 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
JSON.stringify({permit_id:data.id, file:file.file, mimetype:file.file_type, size:file.fileSize})
).then(async(resp) => {
const status = resp.respInfo.status
if(status === 201){
Alert.alert("Success")
navigation.navigate('Property Survey', { screen: 'Property Survey'})
setAlertOnline(false);
}
else{
Alert.alert("Internal Server Error")
}
})
});
} catch (error) {
@ -334,13 +323,10 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr @@ -334,13 +323,10 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
} catch (error) {
console.error(error)
}
}
};
const cek = () => {
console.log(coordinates);
}
};
const getData = async () => {
try {
const url = `${PERMIT_API_URL}/${route.params.data.id}`;
@ -364,75 +350,39 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr @@ -364,75 +350,39 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
// error reading value
}
}
};
const renderItem = ({item,index}:any) => {
return (
<View style={{width:352,height:70,borderRadius:10,borderStyle:'dashed',borderWidth:2,borderCurve:'continuous',borderColor:'#434343',alignItems:'center',justifyContent:'center',flexDirection:'row',columnGap:5}}>
<Text style={{fontSize:20,color:'blue',fontWeight:'bold'}}>{item.name}</Text>
</View>
);
};
return (
<View style={styles.mainContainer}>
<ScrollView style={styles.container}>
<View>
<Text style={styles.label}>Document</Text>
<View style={styles.borderImg}>
<View style={{flexDirection: 'column',padding:20}}>
{fileDocument.map((data, index) =>
<View key={index} style={{flexDirection:'row'}}>
<TextInput
style={{
width: '90%',
height: 40,
borderWidth: 1,
padding: 10,
borderRadius: 50,
color: 'black'
}}
value={data.name}
/>
<TouchableOpacity style={{alignSelf:'flex-end'}} onPress={() => {deleteByIndex(index)}}>
<View style={{flexDirection:'row',alignItems:'center',justifyContent:'center',padding:6}}>
<Image
source={require('../../assets/icon/delete.png')}
style={{width:25,height:25}}
/>
{/* <Text style={{fontSize:18,fontWeight:'bold'}}>View</Text> */}
</View>
</TouchableOpacity>
</View>
)}
</View>
<TouchableOpacity style={{
marginTop:20,
alignItems: 'center',
justifyContent: 'center',
alignSelf: 'center',
width: 100,
height: 40,
bottom:20,
borderRadius: 6,
backgroundColor: '#80CBD3'
}} onPress={uploadFileOnHandler}>
<Image
source={require('../../assets/icon/folder.png')}
style={styles.buttonImageIconStyle}
/>
</TouchableOpacity>
</View>
</View>
<View
style={{
marginTop: 15
}}
/>
<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'}}>
<MapView
style={{width:'80%',height:160,alignSelf:'center'}}
mapStyle={styleURL}
zoomEnabled={false}
scrollEnabled={false}
>
<Camera
<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.length === 0 ? coordinates[0] : centerCoords}
zoomLevel={17}
minZoomLevel={5}
maxZoomLevel={20}
/>
/>
{
!loadGeom ?
@ -486,95 +436,100 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr @@ -486,95 +436,100 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
</PointAnnotation>
))
}
</MapView>
{!secondPress ?
<TouchableOpacity style={{alignSelf:'center',paddingTop:10}} onPress={()=>{navigation.navigate('Map View Polygon', { screen: 'Map View Polygon',data: {
id:data.id,
company_name:companyName,
permit_status:checkedStatus,
location:location,
geom:coordinates
}});
}
}>
<View style={{backgroundColor:'#217dd3',flexDirection:'row',width:200,height:30,borderRadius:20,justifyContent:'center'}}>
<Text style={{alignSelf:'center',fontWeight:'bold',fontSize:16,color:'white'}}>View & Change Location</Text>
</View>
</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 Polygon', {
screen: 'Map View Polygon',
data: {
id:data.id,
company_name:companyName,
permit_status:checkedStatus,
location:location,
geom:coordinates
}
});
}}
>
<Text style={{alignSelf:'center',fontWeight:'semibold',fontSize:16,color:'#434343'}}>Change Location</Text>
</TouchableOpacity>
:
<TouchableOpacity style={{alignSelf:'center',paddingTop:10}} onPress={()=>{navigation.navigate('Map View Polygon', { screen: 'Map View Polygon',data: {
id:data.id,
company_name:companyName,
permit_status:checkedStatus,
location:location,
geom:[...coordinates,coordinates[0]]
}});
}
}>
<View style={{backgroundColor:'#217dd3',flexDirection:'row',width:200,height:30,borderRadius:20,justifyContent:'center'}}>
<Text style={{alignSelf:'center',fontWeight:'bold',fontSize:16,color:'white'}}>View & Change Location</Text>
</View>
<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 Polygon', {
screen: 'Map View Polygon',
data: {
id:data.id,
company_name:companyName,
permit_status:checkedStatus,
location:location,
geom:[...coordinates,coordinates[0]]
}
});
}}
>
<Text style={{alignSelf:'center',fontWeight:'semibold',fontSize:16,color:'#434343'}}>Change Location</Text>
</TouchableOpacity>
}
}
</View>
<View
style={{
marginTop: 15
style={{
marginTop: 15
}}
/>
<View style={{alignSelf:'center'}}>
{/* <Text style={styles.label}>Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */}
<Text style={styles.label}>Company Name</Text>
<TextInput
style={styles.input}
onChangeText={(text) => {
setCompanyName(text)
}}
onChange={()=> {
setCompanyNameError(false)
}}
defaultValue={companyName}
/>
{companyNameError ? <Text style={styles.errorInput}>Company Name is Required!</Text>:null}
</View>
<View
style={{
marginTop: 15
}}
/>
<View>
<Text style={styles.label}>Company Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
<TextInput
style={styles.input}
onChangeText={(text)=>{
setCompanyName(text)
}}
onChange={()=> {
setCompanyNameError(false)
}}
defaultValue={companyName}
<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}>Permit Status</Text>
<View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton
color='#434343'
value="Approved"
status={ checkedStatus === 'Approved' ? 'checked' : 'unchecked' }
onPress={() => {setCheckedStatus('Approved'); setPermitStatusError(false)}}
/>
{companyNameError ? <Text style={styles.errorInput}>Company Name is Required!</Text>:null}
<Text style={{color:"#434343",fontWeight:'semibold',fontSize:16}}>Approved</Text>
</View>
<View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton
color='#434343'
value="Under Review"
status={ checkedStatus === 'Under Review' ? 'checked' : 'unchecked' }
onPress={() => {setCheckedStatus('Under Review'); setPermitStatusError(false); }}
/>
<Text style={{color:"#434343",fontWeight:'semibold',fontSize:16}}>Under Review</Text>
</View>
{permitStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null}
</View>
<View
style={{
marginTop: 15
}}
style={{
marginTop: 60
}}
/>
<View>
<Text style={styles.label}>Permit Status <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
<View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton
value="Approved"
status={ checkedStatus === 'Approved' ? 'checked' : 'unchecked' }
onPress={()=>{
setCheckedStatus('Approved');
setPermitStatusError(false);
}}
/>
<Text style={{color:'black'}}>Approved</Text>
</View>
<View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton
value="Under Review"
status={ checkedStatus === 'Under Review' ? 'checked' : 'unchecked' }
onPress={()=>{
setCheckedStatus('Under Review');
setPermitStatusError(false);
}}
/>
<Text style={{color:'black'}}>Under Review</Text>
</View>
</View>
{permitStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null}
{
checkedStatus === 'Approved' ?
<Animated.View>
<View
style={{
marginTop: 15
}} />
<View>
<View style={{alignSelf:'center'}}>
<Text style={styles.label}>Approved By<Text style={{ color: 'red', fontWeight: 'bold' }}>*</Text></Text>
<TextInput
style={styles.input}
@ -583,90 +538,132 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr @@ -583,90 +538,132 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
} }
/>
</View>
<View
style={{
marginTop: 15
}} />
</Animated.View>
:
null
}
<View
style={{
marginTop: 15
<View style={{alignSelf:'center'}}>
<Text style={styles.label}>Location Detail</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) => {
setLocation(text)
}}
/>
<View>
<Text style={styles.label}>Location Detail <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
<TextInput style={{borderWidth:1,borderRadius:20,padding: 10,color:'black',textAlignVertical:'top'}}
multiline
numberOfLines={5}
maxLength={255}
onChangeText={(text)=>{
setLocation(text)
}}
onChange={()=> {
setLocationError(false)
}}
defaultValue={location}
/>
{locationError ? <Text style={styles.errorInput}>Location is Required!</Text>:null}
onChange={()=> {
setLocationError(false)
}}
defaultValue={location}
/>
{locationError ? <Text style={styles.errorInput}>Information is Required!</Text>:null}
</View>
<View
style={{
marginTop: 15
style={{
marginTop: 15
}}
/>
<View style={{alignSelf:'center'}}>
<Text style={styles.label}>Survey 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>
<Text style={styles.label}>Survey Date</Text>
<TextInput
style={styles.input}
onPress={() => setOpen(true)}
value={String(momentDate)}
/>
<DatePicker
locale='en'
theme='dark'
mode="date"
modal
open={open}
date={install_date}
onConfirm={(survey_date) => {
setOpen(false)
setInstallDate(survey_date)
}}
onCancel={() => {
setOpen(false)
}}
<View style={{alignSelf:'center',width:352}}>
<Text style={styles.label}>Attachment</Text>
<Text style={{fontStyle:'italic',color:'#434343',fontSize:14}}>Lampirkan dokumen</Text>
{
fileDocument.length === 0 ?
<Pressable onPress={uploadFileOnHandler}>
<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/folder.png')}
/>
<Text style={{fontStyle:'italic',color:'#434343'}}>Klik untuk menambahkan dokumen</Text>
</View>
</Pressable>
:
<FlatList
horizontal={true}
showsHorizontalScrollIndicator={false}
scrollEnabled={false}
ListFooterComponent={()=>
<Pressable onPress={uploadFileOnHandler}>
<View style={{width:352,height:70,borderRadius:10,borderStyle:'dashed',borderWidth:2,borderCurve:'continuous',borderColor:'#434343',alignItems:'center',justifyContent:'center'}}>
<Image
source={require('../../assets/icon/folder.png')}
/>
<Text style={{fontStyle:'italic',color:'#434343'}}>Klik untuk menambahkan dokumen</Text>
</View>
</Pressable>
}
contentContainerStyle={{flexDirection:'column',columnGap:25,rowGap:10}}
data={fileDocument}
renderItem={({item,index})=>renderItem({item,index})}
/>
}
</View>
<View
style={{
marginTop: 15
marginTop: 30
}}
/>
</ScrollView>
<Button title='Send' onPress={showDialog} />
<AwesomeAlert
show={alertOnline}
showProgress={false}
title="Updating Data"
message="Are you sure for Updating Permit data?"
closeOnTouchOutside={false}
closeOnHardwareBackPress={false}
showCancelButton={true}
showConfirmButton={true}
cancelText="No, cancel"
confirmText="Yes, Update it"
confirmButtonColor="#137997"
onCancelPressed={() => {
handleCancelAlertOnline();
}}
onConfirmPressed={() => {
collectDataOnline();
// cek()
}}
overlayStyle={{width:'100%'}}
contentContainerStyle={{width:'70%',borderRadius:10}}
titleStyle={{fontSize:20}}
messageStyle={{fontSize:16}}
/>
<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>
<AwesomeAlert
show={alertOnline}
showProgress={false}
title="Updating Data"
message="Are you sure for Updating Permit data?"
closeOnTouchOutside={false}
closeOnHardwareBackPress={false}
showCancelButton={true}
showConfirmButton={true}
cancelText="No, cancel"
confirmText="Yes, Update it"
confirmButtonColor="#137997"
onCancelPressed={() => {
handleCancelAlertOnline();
}}
onConfirmPressed={() => {
collectDataOnline();
// cek()
}}
overlayStyle={{width:'100%'}}
contentContainerStyle={{width:'70%',borderRadius:10}}
titleStyle={{fontSize:20}}
messageStyle={{fontSize:16}}
/>
{/* Offline Mode Alert */}
<AwesomeAlert
@ -717,23 +714,25 @@ const styles = StyleSheet.create({ @@ -717,23 +714,25 @@ const styles = StyleSheet.create({
color: 'black'
},
input: {
height: 40,
width:352,
height: 45,
borderWidth: 1,
padding: 10,
borderRadius: 50,
color: 'black'
borderRadius: 10,
color: '#6B5E5E',
borderColor:'#A6A6A6'
},
container: {
flex: 1,
backgroundColor: '#ecf0f1',
padding: 10,
flexGrow: 1
},
mainContainer: {
flex: 1,
},
label: {
fontSize: 21,
color: 'black',
fontSize: 16,
fontWeight:'semibold',
color: '#434343',
// marginBottom: 20
},
title: {

365
src/component/editscreen.tsx

@ -14,7 +14,8 @@ import { @@ -14,7 +14,8 @@ import {
FlatList,
Dimensions,
Animated,
Alert
Alert,
Pressable
} from 'react-native';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
@ -32,6 +33,7 @@ import { @@ -32,6 +33,7 @@ import {
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";
@ -159,6 +161,8 @@ function EditScreen({route,navigation}: editScreenProps) { @@ -159,6 +161,8 @@ function EditScreen({route,navigation}: editScreenProps) {
const [attach,setAttach] = useState([]);
const [load,setLoad] = useState(true);
const isFocused = useIsFocused();
const [ModalAttachment, setModalAttachment] = useState(false);
useEffect(()=> {
if (isFocused) {
setLong(data.long);
@ -237,7 +241,7 @@ function EditScreen({route,navigation}: editScreenProps) { @@ -237,7 +241,7 @@ function EditScreen({route,navigation}: editScreenProps) {
insertAttachment(files)
Alert.alert("Success")
setAlertOnline(false);
navigation.navigate('Property Survey', { screen: 'Property Survey'})
navigation.navigate('Inbox Penerangan Jalan Umum', { screen: 'Inbox Penerangan Jalan Umum'})
}
else {
Alert.alert("Internal Server Error")
@ -384,77 +388,57 @@ function EditScreen({route,navigation}: editScreenProps) { @@ -384,77 +388,57 @@ function EditScreen({route,navigation}: editScreenProps) {
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}>
<ScrollView style={styles.container}>
<Text style={styles.title}>Edit Survey PJU</Text>
<View>
<Text style={styles.label}>Image</Text>
<View style={styles.borderImg}>
<Text style={{justifyContent: 'center', alignItems: 'center', alignSelf: 'center', color: 'black'}}>{imgUrl.length === 0 ? currentIndex :currentIndex+1}/{imgUrl.length}</Text>
<View style={{flexDirection: 'row'}}>
<PrevImg isIndex={currentIndex}/>
<Animated.FlatList
ref={ref}
data={imgUrl}
showsHorizontalScrollIndicator={false}
pagingEnabled
onScroll={e=>{
const x = e.nativeEvent.contentOffset.x;
setCurrentIndex(parseFloat((x/330).toFixed(0)));
}}
horizontal
renderItem={({item,index}) => {
return(
<Animated.Image resizeMode='contain' style={styles.img} source={{uri: `data:image/jpeg;base64,${imgUrl[index]}`}} />
)
}}/>
<NextImg isIndex={currentIndex}/>
</View>
<View style={styles.btnCameraContainer}>
<TouchableOpacity style={styles.btnCamera} onPress={openCameraLib}>
<Image
source={require('../../assets/icon/camera.png')}
style={styles.buttonImageIconStyle}
/>
</TouchableOpacity>
<TouchableOpacity style={styles.btnCamera} onPress={openLib}>
<Image
source={require('../../assets/icon/gallery.png')}
style={styles.buttonImageIconStyle}
/>
</TouchableOpacity>
</View>
</View>
</View>
<View
style={{
marginTop: 15
}}
/>
<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:'80%',height:160,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}
/>
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>
<TouchableOpacity style={{alignSelf:'center',paddingTop:10}} onPress={()=>navigation.navigate('MapView', { screen: 'MapView',data: {
{/* </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,
@ -464,18 +448,17 @@ function EditScreen({route,navigation}: editScreenProps) { @@ -464,18 +448,17 @@ function EditScreen({route,navigation}: editScreenProps) {
long:long,
lat:lat
}})}>
<View style={{backgroundColor:'#217dd3',flexDirection:'row',width:200,height:30,borderRadius:20,justifyContent:'center'}}>
<Text style={{alignSelf:'center',fontWeight:'bold',fontSize:16,color:'white'}}>View & Change Location</Text>
</View>
</TouchableOpacity>
<Text style={{alignSelf:'center',fontWeight:'semibold',fontSize:16,color:'#434343'}}>Change Location</Text>
</TouchableOpacity>
</View>
<View
style={{
marginTop: 15
}}
/>
<View>
<Text style={styles.label}>Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
<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) => {
@ -493,14 +476,15 @@ function EditScreen({route,navigation}: editScreenProps) { @@ -493,14 +476,15 @@ function EditScreen({route,navigation}: editScreenProps) {
marginTop: 15
}}
/>
<View>
<Text style={styles.label}>PJU Type <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
<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:50,borderWidth:2}}
inputStyles={{color:'black'}}
dropdownTextStyles={{color:'black'}}
boxStyles={{borderRadius:10,borderWidth:1,borderColor:'#A6A6A6',width:352,height:45}}
inputStyles={{color:'#6B5E5E'}}
dropdownTextStyles={{color:'#6B5E5E'}}
data={PJU_Type}
setSelected={setselectedPJUType}
onSelect={()=> (
@ -508,39 +492,44 @@ function EditScreen({route,navigation}: editScreenProps) { @@ -508,39 +492,44 @@ function EditScreen({route,navigation}: editScreenProps) {
)}
defaultOption={{key:selectedPJUType, value:selectedPJUType}}
/>
{PJUTypeError ? <Text style={styles.errorInput}>PJU Type is Required!</Text>:null}
</View>
{PJUTypeError ? <Text style={styles.errorInput}>PJU Type is Required!</Text>:null}
<View
style={{
marginTop: 15
}}
/>
<Text style={styles.label}>Status <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
<View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton
<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:'black'}}>Baik</Text>
</View>
<View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton
value="Rusak"
status={ checkedStatus === 'Rusak' ? 'checked' : 'unchecked' }
onPress={() => {setCheckedStatus('Rusak'); setPJUStatusError(false); }}
/>
<Text style={{color:'black'}}>Rusak</Text>
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>
{PJUStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null}
<View
style={{
marginTop: 15
marginTop: 60
}}
/>
<View>
<Text style={styles.label}>Information <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
<TextInput style={{borderWidth:1,borderRadius:20,padding: 10,color:'black',textAlignVertical:'top'}}
<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}
@ -559,17 +548,17 @@ function EditScreen({route,navigation}: editScreenProps) { @@ -559,17 +548,17 @@ function EditScreen({route,navigation}: editScreenProps) {
marginTop: 15
}}
/>
<View>
<View style={{alignSelf:'center'}}>
<Text style={styles.label}>Installation Date</Text>
<TextInput
style={styles.input}
readOnly={true}
onPress={() => setOpen(true)}
value={String(momentDate)}
/>
<DatePicker
locale='en'
theme='dark'
mode="date"
theme='light'
mode='date'
modal
open={open}
date={install_date}
@ -587,58 +576,114 @@ function EditScreen({route,navigation}: editScreenProps) { @@ -587,58 +576,114 @@ function EditScreen({route,navigation}: editScreenProps) {
marginTop: 15
}}
/>
<View></View>
<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>
<Button title='Update' onPress={showDialog} />
{/* <Button title='Get Local' onPress={getMyObject} />
<Button title='Delete' onPress={removeValue} />
<Button title='GetAll' onPress={getAllKeys} /> */}
<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="Collecting Data"
message="Are you sure for Updating PJU 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 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}}
/>
show={alertOnline}
showProgress={false}
title="Collecting Data"
message="Are you sure for Updating PJU 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 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>
)
}
@ -663,23 +708,25 @@ const styles = StyleSheet.create({ @@ -663,23 +708,25 @@ const styles = StyleSheet.create({
color: 'black'
},
input: {
height: 40,
width:352,
height: 45,
borderWidth: 1,
padding: 10,
borderRadius: 50,
color: 'black'
borderRadius: 10,
color: '#6B5E5E',
borderColor:'#A6A6A6'
},
container: {
flex: 1,
backgroundColor: '#ecf0f1',
padding: 10,
flexGrow: 1
},
mainContainer: {
flex: 1,
},
label: {
fontSize: 21,
color: 'black',
fontSize: 16,
fontWeight:'semibold',
color: '#434343',
// marginBottom: 20
},
title: {

3
src/component/mapCollectPolygonScreen.tsx

@ -121,9 +121,6 @@ function MapCollectPolygonScreen({route,navigation}:MapCollectPolygonProps):Reac @@ -121,9 +121,6 @@ function MapCollectPolygonScreen({route,navigation}:MapCollectPolygonProps):Reac
setZoom(currentZoomLevel);
}
// const ref = useRef();
return(
<View style={{flex:1}}>
<StatusBar backgroundColor="#34A6F8" barStyle={'light-content'} />

20
src/component/mapViewLineScreen.tsx

@ -2,6 +2,7 @@ import React, {useState, useEffect, useRef} from "react"; @@ -2,6 +2,7 @@ import React, {useState, useEffect, useRef} from "react";
import { View, Text, StyleSheet, Alert, TouchableOpacity, Image } 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 {useNavigation,NavigationContainer,useIsFocused} from '@react-navigation/native';
import Geolocation from "@react-native-community/geolocation";
import turfcenter from '@turf/center';
@ -93,23 +94,22 @@ function MapViewLineScreen({route,navigation}:MapViewLineProps):React.JSX.Elemen @@ -93,23 +94,22 @@ function MapViewLineScreen({route,navigation}:MapViewLineProps):React.JSX.Elemen
}
return(
<View style={{flex:1}}>
<MapLibreGL.MapView
<MapView
style={{alignSelf:'stretch',flex:1}}
styleURL={styleURL}
mapStyle={styleURL}
zoomEnabled={true}
onRegionDidChange={(region)=>
setZoom(region.properties.zoomLevel)
}
>
<MapLibreGL.Camera
<Camera
key={"camera"}
centerCoordinate={centerCoords}
allowUpdates={true}
zoomLevel={zoom}
minZoomLevel={5}
maxZoomLevel={20}
/>
<MapLibreGL.ShapeSource
<ShapeSource
id="linestring"
shape={{
"type": "FeatureCollection",
@ -126,13 +126,13 @@ function MapViewLineScreen({route,navigation}:MapViewLineProps):React.JSX.Elemen @@ -126,13 +126,13 @@ function MapViewLineScreen({route,navigation}:MapViewLineProps):React.JSX.Elemen
]
}}
>
<MapLibreGL.LineLayer
<LineLayer
id="linelayer1"
style={{lineColor:'red',lineWidth:1}}
/>
</MapLibreGL.ShapeSource>
</ShapeSource>
<MapLibreGL.UserLocation
<UserLocation
key={"userLoc"}
androidRenderMode='compass'
renderMode='native'
@ -141,7 +141,7 @@ function MapViewLineScreen({route,navigation}:MapViewLineProps):React.JSX.Elemen @@ -141,7 +141,7 @@ function MapViewLineScreen({route,navigation}:MapViewLineProps):React.JSX.Elemen
/>
{
coordinates.map((item:any,index:any)=>(
<MapLibreGL.PointAnnotation
<PointAnnotation
children={<></>}
key={index}
id={String(index)}
@ -154,7 +154,7 @@ function MapViewLineScreen({route,navigation}:MapViewLineProps):React.JSX.Elemen @@ -154,7 +154,7 @@ function MapViewLineScreen({route,navigation}:MapViewLineProps):React.JSX.Elemen
/>
))
}
</MapLibreGL.MapView>
</MapView>
{/* Widget Map */}
<View style={styles.gotoLocate}>

22
src/component/mapViewPolygonScreen.tsx

@ -2,6 +2,7 @@ import React, {useState, useEffect, useRef} from "react"; @@ -2,6 +2,7 @@ import React, {useState, useEffect, useRef} from "react";
import { View, Text, StyleSheet, Alert, TouchableOpacity, Image } 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 {useNavigation,NavigationContainer,useIsFocused} from '@react-navigation/native';
import Geolocation from "@react-native-community/geolocation";
import turfcenter from '@turf/center';
@ -93,23 +94,22 @@ function MapViewPolygonScreen({route,navigation}:MapViewPolygonProps):React.JSX. @@ -93,23 +94,22 @@ function MapViewPolygonScreen({route,navigation}:MapViewPolygonProps):React.JSX.
}
return(
<View style={{flex:1}}>
<MapLibreGL.MapView
<MapView
style={{alignSelf:'stretch',flex:1}}
styleURL={styleURL}
mapStyle={styleURL}
zoomEnabled={true}
onRegionDidChange={(region)=>
setZoom(region.properties.zoomLevel)
}
>
<MapLibreGL.Camera
<Camera
key={"camera"}
centerCoordinate={centerCoords}
allowUpdates={true}
zoomLevel={zoom}
minZoomLevel={5}
maxZoomLevel={20}
/>
<MapLibreGL.ShapeSource
<ShapeSource
id="polygon"
shape={{
"type": "FeatureCollection",
@ -127,20 +127,20 @@ function MapViewPolygonScreen({route,navigation}:MapViewPolygonProps):React.JSX. @@ -127,20 +127,20 @@ function MapViewPolygonScreen({route,navigation}:MapViewPolygonProps):React.JSX.
]
}}
>
<MapLibreGL.LineLayer
<LineLayer
id="linelayer1"
style={{lineColor:'red',lineWidth:1}}
/>
<MapLibreGL.FillLayer
<FillLayer
id="some-fill-feature"
style={{
fillColor: ['interpolate', ['linear'], ['zoom'], 0, '#eeddbb', 2, '#0daa00', 3, '#bbbbee'],
fillOpacity:0.5
}}
/>
</MapLibreGL.ShapeSource>
</ShapeSource>
<MapLibreGL.UserLocation
<UserLocation
key={"userLoc"}
androidRenderMode='compass'
renderMode='native'
@ -149,7 +149,7 @@ function MapViewPolygonScreen({route,navigation}:MapViewPolygonProps):React.JSX. @@ -149,7 +149,7 @@ function MapViewPolygonScreen({route,navigation}:MapViewPolygonProps):React.JSX.
/>
{
coordinates.map((item:any,index:any)=>(
<MapLibreGL.PointAnnotation
<PointAnnotation
children={<></>}
key={index}
id={String(index)}
@ -162,7 +162,7 @@ function MapViewPolygonScreen({route,navigation}:MapViewPolygonProps):React.JSX. @@ -162,7 +162,7 @@ function MapViewPolygonScreen({route,navigation}:MapViewPolygonProps):React.JSX.
/>
))
}
</MapLibreGL.MapView>
</MapView>
{/* Widget Map */}
<View style={styles.gotoLocate}>

14
src/component/mapviewscreen.tsx

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
import React, {useState, useEffect, useRef} from "react";
import MapLibreGL, { PointAnnotation } from '@maplibre/maplibre-react-native';
import MapLibreGL from '@maplibre/maplibre-react-native';
import { MapView,ShapeSource,Camera,UserLocation,PointAnnotation,FillLayer,LineLayer,VectorSource } from "@maplibre/maplibre-react-native";
import {useNavigation,NavigationContainer,useIsFocused} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
@ -253,21 +254,20 @@ function MapViewScreen({route,navigation}: MapViewProps): React.JSX.Element { @@ -253,21 +254,20 @@ function MapViewScreen({route,navigation}: MapViewProps): React.JSX.Element {
</TouchableOpacity>
</View>
{/* Map View */}
<MapLibreGL.MapView
<MapView
style={styles.map}
styleURL={styleURL}
mapStyle={styleURL}
zoomEnabled={true}
attributionPosition={{bottom: 8, right: 8}}
compassEnabled={true}
>
<MapLibreGL.Camera
<Camera
centerCoordinate={currentCoordinate}
minZoomLevel={5}
maxZoomLevel={20}
zoomLevel={zoom}
allowUpdates={true}
/>
<MapLibreGL.PointAnnotation
<PointAnnotation
children={<></>}
key={data.id}
id={data.id}
@ -286,7 +286,7 @@ function MapViewScreen({route,navigation}: MapViewProps): React.JSX.Element { @@ -286,7 +286,7 @@ function MapViewScreen({route,navigation}: MapViewProps): React.JSX.Element {
setFixCoor({long:e.geometry.coordinates[0].toFixed(6),lat:e.geometry.coordinates[1].toFixed(6)})
}}
/>
</MapLibreGL.MapView>
</MapView>
{onDrag ?
<View style={{position:'absolute',width:'100%',bottom:20,justifyContent:'center',alignItems:'center',flexDirection:'row'}}>

801
src/component/resendPDAM.tsx

@ -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',
},
});

799
src/component/resendPJU.tsx

@ -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…
Cancel
Save