Browse Source

update

master
Irul24 1 year ago
parent
commit
05546dff2f
  1. 24
      App.tsx
  2. 46
      src/component/collectLinescreen.tsx
  3. 42
      src/component/collectPolygonscreen.tsx
  4. 62
      src/component/collectscreen.tsx
  5. 11
      src/component/draftPDAM.tsx
  6. 3
      src/component/draftPJU.tsx
  7. 242
      src/component/editLinescreen.tsx
  8. 257
      src/component/editPolygonscreen.tsx
  9. 217
      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';
import SettingScreen from './src/component/settingScreen'; import SettingScreen from './src/component/settingScreen';
import MyAccount from './src/component/myAccount'; import MyAccount from './src/component/myAccount';
import ChangePass from './src/component/changePassword'; 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 { USER_API_URL } from "../SurveyApp/urlConfig";
import { PermissionsAndroid } from 'react-native'; import { PermissionsAndroid } from 'react-native';
@ -549,6 +551,28 @@ export const Nav = () => {
fontSize:20 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} <Stack.Screen name="Setting" component={SettingScreen}
options={{ options={{
headerStyle: { headerStyle: {

46
src/component/collectLinescreen.tsx

@ -15,8 +15,7 @@ import turfcenter from '@turf/center';
const {points,polygon,lineString} = require('@turf/helpers'); const {points,polygon,lineString} = require('@turf/helpers');
import RNFetchBlob from 'rn-fetch-blob'; import RNFetchBlob from 'rn-fetch-blob';
import Modal from "react-native-modal"; import Modal from "react-native-modal";
import {useIsFocused} from '@react-navigation/native';
import { PDAM_API_URL } from "../../urlConfig"; import { PDAM_API_URL } from "../../urlConfig";
import React from 'react'; import React from 'react';
@ -26,7 +25,6 @@ type collectLineScreenProps = {route: any,navigation: any};
export default function CollectLineScreen({route,navigation}:collectLineScreenProps) { export default function CollectLineScreen({route,navigation}:collectLineScreenProps) {
console.log("route",route.params); console.log("route",route.params);
const apiKey = "JoJs2pcDv5o0yQlQLMfI"; const apiKey = "JoJs2pcDv5o0yQlQLMfI";
const [basemap, setBasemap] = useState("streets-v2"); const [basemap, setBasemap] = useState("streets-v2");
const styleURL = `https://api.maptiler.com/maps/${basemap}/style.json?key=${apiKey}`; const styleURL = `https://api.maptiler.com/maps/${basemap}/style.json?key=${apiKey}`;
@ -37,10 +35,21 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr
{key:'Pipa 10"', value:'Pipa 10"'}, {key:'Pipa 10"', value:'Pipa 10"'},
] ]
const [centerCoords,setCenterCoords] = useState<number[]>([]); const [centerCoords,setCenterCoords] = useState<number[]>([]);
const isFocused = useIsFocused();
const [userID,setUserID] = useState();
useEffect(()=>{ useEffect(()=>{
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)); let centCord = turfcenter(points(route.params.coordinates));
console.log('center'); // console.log('center');
console.log(centCord.geometry.coordinates); // console.log(centCord.geometry.coordinates);
setCenterCoords(centCord.geometry.coordinates); setCenterCoords(centCord.geometry.coordinates);
const unsubscribe = NetInfo.addEventListener((state) => { const unsubscribe = NetInfo.addEventListener((state) => {
setConnected(state.isConnected!) setConnected(state.isConnected!)
@ -48,7 +57,8 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr
return () => { return () => {
unsubscribe(); unsubscribe();
}; };
},[]) };
},[isFocused])
const ref = useRef(); const ref = useRef();
const [connected, setConnected] = useState(true); const [connected, setConnected] = useState(true);
@ -198,6 +208,16 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr
status: 0, status: 0,
body: {}, 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)=>{ const geom = route.params.coordinates.map((item:any)=>{
return String(item).replace(',',' ') return String(item).replace(',',' ')
}) })
@ -207,7 +227,9 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr
tanggal_installasi: momentDate, tanggal_installasi: momentDate,
status: checkedStatus, status: checkedStatus,
keterangan: Information, keterangan: Information,
geom: `MULTILINESTRING((${geom}))` geom: `MULTILINESTRING((${geom}))`,
created_by: userID,
created_at: localTime
} }
await RNFetchBlob.config({ await RNFetchBlob.config({
trusty : true trusty : true
@ -365,7 +387,7 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr
/> />
<View style={{alignSelf:'center'}}> <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 style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */}
<Text style={styles.label}>PJU Type</Text> <Text style={styles.label}>Pipe Type</Text>
<SelectList <SelectList
search={false} search={false}
placeholder="Select Pipe Type" placeholder="Select Pipe Type"
@ -500,9 +522,10 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr
}} }}
/> />
</ScrollView> </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> </View>
<AwesomeAlert <AwesomeAlert
show={alertOnline} show={alertOnline}
showProgress={false} showProgress={false}
@ -571,11 +594,10 @@ export default function CollectLineScreen({route,navigation}:collectLineScreenPr
<Text style={{fontSize:20,fontWeight:'light',color:'#434343'}}>Choose photo</Text> <Text style={{fontSize:20,fontWeight:'light',color:'#434343'}}>Choose photo</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
</View> </View>
</Modal> </Modal>
</View> </View>
) );
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({

42
src/component/collectPolygonscreen.tsx

@ -16,9 +16,10 @@ const {points,polygon,lineString} = require('@turf/helpers');
import DocumentPicker from "react-native-document-picker"; import DocumentPicker from "react-native-document-picker";
import RNFS from 'react-native-fs'; import RNFS from 'react-native-fs';
import RNFetchBlob from 'rn-fetch-blob'; 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 { PERMIT_API_URL } from "../../urlConfig";
import React from 'react'; import React from 'react';
type collectPolygonScreenProps = {route: any,navigation: any}; type collectPolygonScreenProps = {route: any,navigation: any};
@ -26,13 +27,24 @@ type collectPolygonScreenProps = {route: any,navigation: any};
export default function CollectPolygonScreen({route,navigation}:collectPolygonScreenProps) { export default function CollectPolygonScreen({route,navigation}:collectPolygonScreenProps) {
// const { authState } = useAuth();
console.log("route",route.params); console.log("route",route.params);
const apiKey = "JoJs2pcDv5o0yQlQLMfI"; const apiKey = "JoJs2pcDv5o0yQlQLMfI";
const [basemap, setBasemap] = useState("streets-v2"); const [basemap, setBasemap] = useState("streets-v2");
const styleURL = `https://api.maptiler.com/maps/${basemap}/style.json?key=${apiKey}`; const styleURL = `https://api.maptiler.com/maps/${basemap}/style.json?key=${apiKey}`;
const [centerCoords,setCenterCoords] = useState<number[]>([]); const [centerCoords,setCenterCoords] = useState<number[]>([]);
const isFocused = useIsFocused();
const [userID,setUserID] = useState();
useEffect(()=>{ useEffect(()=>{
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)); let centCord = turfcenter(points(route.params.coordinates));
console.log('center'); console.log('center');
console.log(centCord.geometry.coordinates); console.log(centCord.geometry.coordinates);
@ -43,7 +55,8 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc
return () => { return () => {
unsubscribe(); unsubscribe();
}; };
},[]) };
},[isFocused])
const ref = useRef(); const ref = useRef();
const [connected, setConnected] = useState(true); const [connected, setConnected] = useState(true);
@ -183,6 +196,16 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc
}; };
const collectDataOnline = async () => { const collectDataOnline = async () => {
try { 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)=>{ const geom = route.params.coordinates.map((item:any)=>{
return String(item).replace(',',' ') return String(item).replace(',',' ')
}) })
@ -194,7 +217,9 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc
company_name: companyName, company_name: companyName,
location: location, location: location,
permit_status: checkedStatus, 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); console.log(obj);
await RNFetchBlob.config({ await RNFetchBlob.config({
@ -440,11 +465,6 @@ export default function CollectPolygonScreen({route,navigation}:collectPolygonSc
: :
null null
} }
<View
style={{
marginTop: 15
}}
/>
<View style={{alignSelf:'center'}}> <View style={{alignSelf:'center'}}>
<Text style={styles.label}>Location Detail</Text> <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}} <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
}} }}
/> />
</ScrollView> </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> </View>
<AwesomeAlert <AwesomeAlert

62
src/component/collectscreen.tsx

@ -16,7 +16,7 @@ import {
Dimensions Dimensions
} from 'react-native'; } from 'react-native';
import {useAuth} from '../../src/component/authContext';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker'; import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import { SelectList } from 'react-native-dropdown-select-list'; import { SelectList } from 'react-native-dropdown-select-list';
import DatePicker from 'react-native-date-picker'; import DatePicker from 'react-native-date-picker';
@ -32,6 +32,7 @@ import { RadioButton } from 'react-native-paper';
import AwesomeAlert from 'react-native-awesome-alerts'; import AwesomeAlert from 'react-native-awesome-alerts';
import RNFetchBlob from 'rn-fetch-blob'; import RNFetchBlob from 'rn-fetch-blob';
import Modal from "react-native-modal"; import Modal from "react-native-modal";
import {useIsFocused} from '@react-navigation/native';
import { PJU_API_URL } from "../../urlConfig"; import { PJU_API_URL } from "../../urlConfig";
@ -47,6 +48,7 @@ function CollectScreen({route,navigation}: collectScreenProps) {
const [fileDocument, setFileDocument] = useState([]); const [fileDocument, setFileDocument] = useState([]);
const [currentIndex, setCurrentIndex] = useState(0); const [currentIndex, setCurrentIndex] = useState(0);
const [connected, setConnected] = useState(true) const [connected, setConnected] = useState(true)
// const { authState } = useAuth();
const openCameraLib = async () => { const openCameraLib = async () => {
const result = await launchCamera({ const result = await launchCamera({
@ -153,8 +155,10 @@ function CollectScreen({route,navigation}: collectScreenProps) {
const [PJUInfoError, setPJUInfoError] = useState(false); const [PJUInfoError, setPJUInfoError] = useState(false);
const [attachmentSuccess, setAttachmentSuccess] = useState(0); const [attachmentSuccess, setAttachmentSuccess] = useState(0);
const [ModalAttachment, setModalAttachment] = useState(false); const [ModalAttachment, setModalAttachment] = useState(false);
const [userID,setUserID] = useState();
const isFocused = useIsFocused();
useEffect(()=> { useEffect(()=> {
if(isFocused){
navigation.addListener('beforeRemove', (e:any)=> { navigation.addListener('beforeRemove', (e:any)=> {
console.log("Event",e); console.log("Event",e);
if (e.data.action.type !== "NAVIGATE"){ if (e.data.action.type !== "NAVIGATE"){
@ -174,15 +178,26 @@ function CollectScreen({route,navigation}: collectScreenProps) {
] ]
) )
} }
}) });
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) => { const unsubscribe = NetInfo.addEventListener((state) => {
setConnected(state.isConnected!) setConnected(state.isConnected!)
}); });
return () => { return () => {
unsubscribe(); unsubscribe();
}; };
};
},[]);
},[isFocused]);
const collectDataOnline = async() => { const collectDataOnline = async() => {
try { try {
@ -190,6 +205,36 @@ function CollectScreen({route,navigation}: collectScreenProps) {
status: 0, status: 0,
body: {}, 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({ await RNFetchBlob.config({
trusty : true trusty : true
}).fetch('POST', `${PJU_API_URL}/addData`,{ }).fetch('POST', `${PJU_API_URL}/addData`,{
@ -202,7 +247,9 @@ function CollectScreen({route,navigation}: collectScreenProps) {
tanggal_installasi: momentDate, tanggal_installasi: momentDate,
status: checkedStatus, status: checkedStatus,
keterangan: pju_info, keterangan: pju_info,
geom: `POINT(${fixCoordinate.long} ${fixCoordinate.lat})` geom: `POINT(${fixCoordinate.long} ${fixCoordinate.lat})`,
created_by: userID,
created_at: localTime
}) })
).then(async (resp) => { ).then(async (resp) => {
const json = resp.json() const json = resp.json()
@ -635,7 +682,9 @@ function CollectScreen({route,navigation}: collectScreenProps) {
/> */} /> */}
</ScrollView> </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> </View>
@ -713,7 +762,6 @@ function CollectScreen({route,navigation}: collectScreenProps) {
<Text style={{fontSize:20,fontWeight:'light',color:'#434343'}}>Choose photo</Text> <Text style={{fontSize:20,fontWeight:'light',color:'#434343'}}>Choose photo</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
</View> </View>
</Modal> </Modal>
</View> </View>

11
src/component/draftPDAM.tsx

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

3
src/component/draftPJU.tsx

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

242
src/component/editLinescreen.tsx

@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from 'react'; 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 MapLibreGL from '@maplibre/maplibre-react-native';
import { MapView,ShapeSource,Camera,UserLocation,PointAnnotation,FillLayer,LineLayer,VectorSource } 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/
import turfcenter from '@turf/center'; import turfcenter from '@turf/center';
const {points,polygon,lineString} = require('@turf/helpers'); const {points,polygon,lineString} = require('@turf/helpers');
import RNFetchBlob from 'rn-fetch-blob'; import RNFetchBlob from 'rn-fetch-blob';
import Modal from "react-native-modal";
@ -26,6 +27,9 @@ type collectLineScreenProps = {route: any,navigation: any};
export default function EditLineScreen({route,navigation}:collectLineScreenProps) { export default function EditLineScreen({route,navigation}:collectLineScreenProps) {
// console.log("route",route.params); // console.log("route",route.params);
const {data,coors} = route.params; const {data,coors} = route.params;
console.log("data",data);
const apiKey = "JoJs2pcDv5o0yQlQLMfI"; const apiKey = "JoJs2pcDv5o0yQlQLMfI";
const [basemap, setBasemap] = useState("streets-v2"); const [basemap, setBasemap] = useState("streets-v2");
const styleURL = `https://api.maptiler.com/maps/${basemap}/style.json?key=${apiKey}`; const styleURL = `https://api.maptiler.com/maps/${basemap}/style.json?key=${apiKey}`;
@ -58,18 +62,15 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
const [secondPress,setSecondPress] = useState(false); const [secondPress,setSecondPress] = useState(false);
const isFocused = useIsFocused(); const isFocused = useIsFocused();
const [centerCoords,setCenterCoords] = useState<number[]>([]); const [centerCoords,setCenterCoords] = useState<number[]>([]);
const [ModalAttachment, setModalAttachment] = useState(false);
useEffect(()=>{ useEffect(()=>{
if (isFocused) { if (isFocused) {
if (coors === undefined) { if (coors === undefined) {
console.log("awal");
getData() getData()
fetchData() fetchData()
} }
else{ else{
console.log("kedua",coors);
let centCord = turfcenter(points(coors)); let centCord = turfcenter(points(coors));
console.log("center kedua",centCord);
setCenterCoords(centCord.geometry.coordinates); setCenterCoords(centCord.geometry.coordinates);
setLoadGeom(false); setLoadGeom(false);
setCoordinates(coors) setCoordinates(coors)
@ -131,7 +132,6 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
// error reading value // error reading value
} }
} }
const fetchData = async () => { const fetchData = async () => {
try { try {
await RNFetchBlob.config({ await RNFetchBlob.config({
@ -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}) JSON.stringify({pdam_id:data.id, file:file.file, mimetype:file.file_type, size:file.fileSize})
).then(async (resp) => { ).then(async (resp) => {
Alert.alert("Success")
setAlertOnline(false);
navigation.navigate('Property Survey', { screen: 'Property Survey'})
} }
) )
}); });
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
} };
const collectDataOnline = async () => { const collectDataOnline = async () => {
try { try {
const geom = coordinates.map((item:any)=>{ const geom = coordinates.map((item:any)=>{
@ -322,6 +320,9 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
const status = resp.respInfo.status const status = resp.respInfo.status
if (status == 201) { if (status == 201) {
insertAttachment(files) insertAttachment(files)
Alert.alert("Success")
setAlertOnline(false);
navigation.navigate('Inbox Pipa PDAM', { screen: 'Inbox Pipa PDAM'})
} }
else { else {
Alert.alert("Internal Server Error") Alert.alert("Internal Server Error")
@ -369,68 +370,35 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
const collectDataOffline = () => { const collectDataOffline = () => {
setAlertOnline(false); setAlertOnline(false);
}; };
const renderItem = ({item,index}:any) => {
return ( return (
<View style={styles.mainContainer}> <View key={index} style={{width:100,height:100,borderRadius:10,borderWidth:1,borderStyle:"dashed",flexDirection:'row'}}>
<ScrollView style={styles.container}> <Image style={{width: '100%',height: '100%',borderRadius:10}}
<View> source={{uri: `data:image/jpeg;base64,${imgUrl[index]}`}}
<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>
<View style={styles.btnCameraContainer}> );
<TouchableOpacity style={styles.btnCamera} onPress={openCameraLib}> };
<Image return (
source={require('../../assets/icon/camera.png')} <View style={styles.mainContainer}>
style={styles.buttonImageIconStyle} <StatusBar backgroundColor="#34A6F8" barStyle={'light-content'} />
/> <View key={"mainBackground"} style={{backgroundColor:'#34A6F8',width:'100%',height:'93%'}} />
</TouchableOpacity> <View key={"background"} style={{backgroundColor:'#FFFFFF',width:'100%',height:'100%',position:'absolute',borderTopRightRadius:50,borderTopLeftRadius:35,paddingTop:25}}>
<TouchableOpacity style={styles.btnCamera} onPress={openLib}> <ScrollView style={styles.container}>
<Image
source={require('../../assets/icon/gallery.png')}
style={styles.buttonImageIconStyle}
/>
</TouchableOpacity>
</View>
</View>
</View>
<View
style={{
marginTop: 15
}}
/>
{ {
!loadGeom ? !loadGeom ?
<View style={{flexDirection:'column'}}> <View style={{flexDirection:'column'}}>
<MapView <MapView
style={{width:'80%',height:160,alignSelf:'center'}} style={{width:352,height:200,borderWidth:1,borderColor:'#A6A6A6',overflow:'hidden',alignSelf:'center',borderTopRightRadius:10,borderTopLeftRadius:10}}
mapStyle={styleURL} mapStyle={styleURL}
rotateEnabled={false}
zoomEnabled={false} zoomEnabled={false}
pitchEnabled={false}
scrollEnabled={false} scrollEnabled={false}
> >
<Camera <Camera
centerCoordinate={centerCoords} centerCoordinate={centerCoords}
zoomLevel={17} zoomLevel={15}
minZoomLevel={5} minZoomLevel={5}
maxZoomLevel={20} maxZoomLevel={20}
/> />
@ -468,7 +436,7 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
} }
</MapView> </MapView>
{!secondPress ? {!secondPress ?
<TouchableOpacity style={{alignSelf:'center',paddingTop:10}} onPress={()=>{navigation.navigate('Map View Line', { screen: 'Map View Line',data: { <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, id:data.id,
pipe_name:pipeName, pipe_name:pipeName,
pipe_type:selectedPipeType, pipe_type:selectedPipeType,
@ -479,12 +447,10 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
}}); }});
} }
}> }>
<View style={{backgroundColor:'#217dd3',flexDirection:'row',width:200,height:30,borderRadius:20,justifyContent:'center'}}> <Text style={{alignSelf:'center',fontWeight:'semibold',fontSize:16,color:'#434343'}}>Change Location</Text>
<Text style={{alignSelf:'center',fontWeight:'bold',fontSize:16,color:'white'}}>View & Change Location</Text>
</View>
</TouchableOpacity> </TouchableOpacity>
: :
<TouchableOpacity style={{alignSelf:'center',paddingTop:10}} onPress={()=>{navigation.navigate('Map View Line', { screen: 'Map View Line',data: { <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, id:data.id,
pipe_name:pipeName, pipe_name:pipeName,
pipe_type:selectedPipeType, pipe_type:selectedPipeType,
@ -495,23 +461,21 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
}}); }});
} }
}> }>
<View style={{backgroundColor:'#217dd3',flexDirection:'row',width:200,height:30,borderRadius:20,justifyContent:'center'}}> <Text style={{alignSelf:'center',fontWeight:'semibold',fontSize:16,color:'#434343'}}>Change Location</Text>
<Text style={{alignSelf:'center',fontWeight:'bold',fontSize:16,color:'white'}}>View & Change Location</Text>
</View>
</TouchableOpacity> </TouchableOpacity>
} }
</View> </View>
: :
null null
} }
<View <View
style={{ style={{
marginTop: 15 marginTop: 15
}} }}
/> />
<View> <View style={{alignSelf:'center'}}>
<Text style={styles.label}>Pipe Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> {/* <Text style={styles.label}>Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */}
<Text style={styles.label}>Pipe Name</Text>
<TextInput <TextInput
style={styles.input} style={styles.input}
onChangeText={(text)=>{ onChangeText={(text)=>{
@ -522,25 +486,26 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
}} }}
defaultValue={pipeName} defaultValue={pipeName}
/> />
{pipeNameError ? <Text style={styles.errorInput}>Name is Required!</Text>:null} {pipeNameError ? <Text style={styles.errorInput}>Pipe Name is Required!</Text>:null}
</View> </View>
<View <View
style={{ style={{
marginTop: 15 marginTop: 15
}} }}
/> />
<View> <View style={{alignSelf:'center'}}>
<Text style={styles.label}>Pipe Type <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> {/* <Text style={styles.label}>PJU Type <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */}
<Text style={styles.label}>Pipe Type</Text>
<SelectList <SelectList
search={false} search={false}
placeholder="Select Pipe Type" placeholder="Select Pipe Type"
boxStyles={{borderRadius:50,borderWidth:2}} boxStyles={{borderRadius:10,borderWidth:1,borderColor:'#A6A6A6',width:352,height:45}}
inputStyles={{color:'black'}} inputStyles={{color:'#6B5E5E'}}
dropdownTextStyles={{color:'black'}} dropdownTextStyles={{color:'#6B5E5E'}}
data={Pipe_Type} data={Pipe_Type}
setSelected={setselectedPipeType} setSelected={setselectedPipeType}
onSelect={()=> ( onSelect={()=> (
setPipeTypeError(false) [setPipeTypeError(false)]
)} )}
defaultOption={{key:selectedPipeType, value:selectedPipeType}} defaultOption={{key:selectedPipeType, value:selectedPipeType}}
/> />
@ -551,44 +516,41 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
marginTop: 15 marginTop: 15
}} }}
/> />
<View> <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 style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */}
<Text style={styles.label}>Status</Text>
<View style={{flexDirection:'row',alignItems:'center'}}> <View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton <RadioButton
color='#434343'
value="Baik" value="Baik"
status={ checkedStatus === 'Baik' ? 'checked' : 'unchecked' } status={ checkedStatus === 'Baik' ? 'checked' : 'unchecked' }
onPress={()=>{ onPress={() => {setCheckedStatus('Baik'); setPipeStatusError(false)}}
setCheckedStatus('Baik');
setPipeStatusError(false);
}}
/> />
<Text style={{color:'black'}}>Baik</Text> <Text style={{color:"#434343",fontWeight:'semibold',fontSize:16}}>Baik</Text>
</View> </View>
<View style={{flexDirection:'row',alignItems:'center'}}> <View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton <RadioButton
color='#434343'
value="Rusak" value="Rusak"
status={ checkedStatus === 'Rusak' ? 'checked' : 'unchecked' } status={ checkedStatus === 'Rusak' ? 'checked' : 'unchecked' }
onPress={()=>{ onPress={() => {setCheckedStatus('Rusak'); setPipeStatusError(false); }}
setCheckedStatus('Rusak');
setPipeStatusError(false);
}}
/> />
<Text style={{color:'black'}}>Rusak</Text> <Text style={{color:"#434343",fontWeight:'semibold',fontSize:16}}>Rusak</Text>
</View>
</View> </View>
{pipeStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null} {pipeStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null}
</View>
<View <View
style={{ style={{
marginTop: 15 marginTop: 60
}} }}
/> />
<View> <View style={{alignSelf:'center'}}>
<Text style={styles.label}>Information <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> <Text style={styles.label}>Information</Text>
<TextInput style={{borderWidth:1,borderRadius:20,padding: 10,color:'black',textAlignVertical:'top'}} <TextInput style={{borderWidth:1,borderRadius:20,padding: 10,color:'#6B5E5E',borderColor:'#A6A6A6',textAlignVertical:'top',width:352,height:135}}
multiline multiline
numberOfLines={5} numberOfLines={5}
maxLength={255} maxLength={255}
onChangeText={(text)=>{ onChangeText={(text) => {
setInformation(text) setInformation(text)
}} }}
onChange={()=> { onChange={()=> {
@ -603,7 +565,7 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
marginTop: 15 marginTop: 15
}} }}
/> />
<View> <View style={{alignSelf:'center'}}>
<Text style={styles.label}>Installation Date</Text> <Text style={styles.label}>Installation Date</Text>
<TextInput <TextInput
style={styles.input} style={styles.input}
@ -612,8 +574,8 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
/> />
<DatePicker <DatePicker
locale='en' locale='en'
theme='dark' theme='light'
mode="date" mode='date'
modal modal
open={open} open={open}
date={install_date} date={install_date}
@ -631,8 +593,49 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
marginTop: 15 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> </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'}}>UPDATE</Text>
</TouchableOpacity>
</View>
{/* Online Mode Alert */} {/* Online Mode Alert */}
<AwesomeAlert <AwesomeAlert
show={alertOnline} show={alertOnline}
@ -657,7 +660,6 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
titleStyle={{fontSize:20}} titleStyle={{fontSize:20}}
messageStyle={{fontSize:16}} messageStyle={{fontSize:16}}
/> />
{/* Offline Mode Alert */} {/* Offline Mode Alert */}
<AwesomeAlert <AwesomeAlert
show={alertOffline} show={alertOffline}
@ -682,8 +684,30 @@ export default function EditLineScreen({route,navigation}:collectLineScreenProps
titleStyle={{fontSize:20}} titleStyle={{fontSize:20}}
messageStyle={{fontSize:16}} 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>
) <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({ const styles = StyleSheet.create({
@ -707,23 +731,25 @@ const styles = StyleSheet.create({
color: 'black' color: 'black'
}, },
input: { input: {
height: 40, width:352,
height: 45,
borderWidth: 1, borderWidth: 1,
padding: 10, padding: 10,
borderRadius: 50, borderRadius: 10,
color: 'black' color: '#6B5E5E',
borderColor:'#A6A6A6'
}, },
container: { container: {
flex: 1,
backgroundColor: '#ecf0f1',
padding: 10, padding: 10,
flexGrow: 1
}, },
mainContainer: { mainContainer: {
flex: 1, flex: 1,
}, },
label: { label: {
fontSize: 21, fontSize: 16,
color: 'black', fontWeight:'semibold',
color: '#434343',
// marginBottom: 20 // marginBottom: 20
}, },
title: { title: {

257
src/component/editPolygonscreen.tsx

@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from 'react'; 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 {useNavigation,NavigationContainer,useIsFocused} from '@react-navigation/native';
import MapLibreGL 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 { MapView,ShapeSource,Camera,UserLocation,PointAnnotation,FillLayer,LineLayer,VectorSource } from "@maplibre/maplibre-react-native";
@ -61,8 +61,6 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
const [delay,setDelay] = useState(false); const [delay,setDelay] = useState(false);
const [secondPress,setSecondPress] = useState(false); const [secondPress,setSecondPress] = useState(false);
const isFocused = useIsFocused(); const isFocused = useIsFocused();
// console.log(isFocused);
useEffect(()=>{ useEffect(()=>{
if (isFocused) { if (isFocused) {
if (coors === undefined) { if (coors === undefined) {
@ -108,8 +106,6 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
unsubscribe(); unsubscribe();
}; };
},[isFocused]) },[isFocused])
const openCameraLib = async () => { const openCameraLib = async () => {
const result = await launchCamera({ const result = await launchCamera({
mediaType: 'photo', mediaType: 'photo',
@ -258,6 +254,9 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
const status = resp.respInfo.status const status = resp.respInfo.status
if (status == 201) { if (status == 201) {
insertAttachment(files) insertAttachment(files)
Alert.alert("Success")
setAlertOnline(false);
navigation.navigate('Inbox Land Permit', { screen: 'Inbox Land Permit'})
} }
else { else {
Alert.alert("Internal Server Error") Alert.alert("Internal Server Error")
@ -283,8 +282,6 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
}; };
const insertAttachment = async (files: any) => { const insertAttachment = async (files: any) => {
try { try {
files.forEach(async function(file:any){ files.forEach(async function(file:any){
const url = `${PERMIT_API_URL}/addAttachment`; const url = `${PERMIT_API_URL}/addAttachment`;
await RNFetchBlob.config({ await RNFetchBlob.config({
@ -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}) JSON.stringify({permit_id:data.id, file:file.file, mimetype:file.file_type, size:file.fileSize})
).then(async(resp) => { ).then(async(resp) => {
const status = resp.respInfo.status 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) { } catch (error) {
@ -334,13 +323,10 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
} catch (error) { } catch (error) {
console.error(error) console.error(error)
} }
} };
const cek = () => { const cek = () => {
console.log(coordinates); console.log(coordinates);
};
}
const getData = async () => { const getData = async () => {
try { try {
const url = `${PERMIT_API_URL}/${route.params.data.id}`; const url = `${PERMIT_API_URL}/${route.params.data.id}`;
@ -364,67 +350,31 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
// error reading value // error reading value
} }
} };
const renderItem = ({item,index}:any) => {
return ( return (
<View style={styles.mainContainer}> <View style={{width:352,height:70,borderRadius:10,borderStyle:'dashed',borderWidth:2,borderCurve:'continuous',borderColor:'#434343',alignItems:'center',justifyContent:'center',flexDirection:'row',columnGap:5}}>
<ScrollView style={styles.container}> <Text style={{fontSize:20,color:'blue',fontWeight:'bold'}}>{item.name}</Text>
<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>
<View );
style={{ };
marginTop: 15 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'}}> <View style={{flexDirection:'column'}}>
<MapView <MapView
style={{width:'80%',height:160,alignSelf:'center'}} style={{width:352,height:200,borderWidth:1,borderColor:'#A6A6A6',overflow:'hidden',alignSelf:'center',borderTopRightRadius:10,borderTopLeftRadius:10}}
mapStyle={styleURL} mapStyle={styleURL}
rotateEnabled={false}
zoomEnabled={false} zoomEnabled={false}
pitchEnabled={false}
scrollEnabled={false} scrollEnabled={false}
> >
<Camera <Camera
@ -488,32 +438,38 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
} }
</MapView> </MapView>
{!secondPress ? {!secondPress ?
<TouchableOpacity style={{alignSelf:'center',paddingTop:10}} onPress={()=>{navigation.navigate('Map View Polygon', { screen: 'Map View Polygon',data: { <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, id:data.id,
company_name:companyName, company_name:companyName,
permit_status:checkedStatus, permit_status:checkedStatus,
location:location, location:location,
geom:coordinates 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> <Text style={{alignSelf:'center',fontWeight:'semibold',fontSize:16,color:'#434343'}}>Change Location</Text>
</TouchableOpacity> </TouchableOpacity>
: :
<TouchableOpacity style={{alignSelf:'center',paddingTop:10}} onPress={()=>{navigation.navigate('Map View Polygon', { screen: 'Map View Polygon',data: { <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, id:data.id,
company_name:companyName, company_name:companyName,
permit_status:checkedStatus, permit_status:checkedStatus,
location:location, location:location,
geom:[...coordinates,coordinates[0]] 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> <Text style={{alignSelf:'center',fontWeight:'semibold',fontSize:16,color:'#434343'}}>Change Location</Text>
</TouchableOpacity> </TouchableOpacity>
} }
</View> </View>
@ -522,11 +478,12 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
marginTop: 15 marginTop: 15
}} }}
/> />
<View> <View style={{alignSelf:'center'}}>
<Text style={styles.label}>Company Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> {/* <Text style={styles.label}>Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */}
<Text style={styles.label}>Company Name</Text>
<TextInput <TextInput
style={styles.input} style={styles.input}
onChangeText={(text)=>{ onChangeText={(text) => {
setCompanyName(text) setCompanyName(text)
}} }}
onChange={()=> { onChange={()=> {
@ -541,40 +498,38 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
marginTop: 15 marginTop: 15
}} }}
/> />
<View> <View style={{alignSelf:'center',width:352,height:45}}>
<Text style={styles.label}>Permit Status <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> {/* <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'}}> <View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton <RadioButton
color='#434343'
value="Approved" value="Approved"
status={ checkedStatus === 'Approved' ? 'checked' : 'unchecked' } status={ checkedStatus === 'Approved' ? 'checked' : 'unchecked' }
onPress={()=>{ onPress={() => {setCheckedStatus('Approved'); setPermitStatusError(false)}}
setCheckedStatus('Approved');
setPermitStatusError(false);
}}
/> />
<Text style={{color:'black'}}>Approved</Text> <Text style={{color:"#434343",fontWeight:'semibold',fontSize:16}}>Approved</Text>
</View> </View>
<View style={{flexDirection:'row',alignItems:'center'}}> <View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton <RadioButton
color='#434343'
value="Under Review" value="Under Review"
status={ checkedStatus === 'Under Review' ? 'checked' : 'unchecked' } status={ checkedStatus === 'Under Review' ? 'checked' : 'unchecked' }
onPress={()=>{ onPress={() => {setCheckedStatus('Under Review'); setPermitStatusError(false); }}
setCheckedStatus('Under Review');
setPermitStatusError(false);
}}
/> />
<Text style={{color:'black'}}>Under Review</Text> <Text style={{color:"#434343",fontWeight:'semibold',fontSize:16}}>Under Review</Text>
</View>
</View> </View>
{permitStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null} {permitStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null}
</View>
<View
style={{
marginTop: 60
}}
/>
{ {
checkedStatus === 'Approved' ? checkedStatus === 'Approved' ?
<Animated.View> <Animated.View>
<View <View style={{alignSelf:'center'}}>
style={{
marginTop: 15
}} />
<View>
<Text style={styles.label}>Approved By<Text style={{ color: 'red', fontWeight: 'bold' }}>*</Text></Text> <Text style={styles.label}>Approved By<Text style={{ color: 'red', fontWeight: 'bold' }}>*</Text></Text>
<TextInput <TextInput
style={styles.input} style={styles.input}
@ -583,22 +538,21 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
} } } }
/> />
</View> </View>
<View
style={{
marginTop: 15
}} />
</Animated.View> </Animated.View>
: :
null null
} }
<View <View style={{alignSelf:'center'}}>
style={{ <Text style={styles.label}>Location Detail</Text>
marginTop: 15 <TextInput style={{borderWidth:1,borderRadius:20,padding: 10,color:'#6B5E5E',borderColor:'#A6A6A6',textAlignVertical:'top',width:352,height:135}}
}}
/>
<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 multiline
numberOfLines={5} numberOfLines={5}
maxLength={255} maxLength={255}
onChangeText={(text)=>{ onChangeText={(text) => {
setLocation(text) setLocation(text)
}} }}
onChange={()=> { onChange={()=> {
@ -606,14 +560,14 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
}} }}
defaultValue={location} defaultValue={location}
/> />
{locationError ? <Text style={styles.errorInput}>Location is Required!</Text>:null} {locationError ? <Text style={styles.errorInput}>Information is Required!</Text>:null}
</View> </View>
<View <View
style={{ style={{
marginTop: 15 marginTop: 15
}} }}
/> />
<View> <View style={{alignSelf:'center'}}>
<Text style={styles.label}>Survey Date</Text> <Text style={styles.label}>Survey Date</Text>
<TextInput <TextInput
style={styles.input} style={styles.input}
@ -622,8 +576,8 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
/> />
<DatePicker <DatePicker
locale='en' locale='en'
theme='dark' theme='light'
mode="date" mode='date'
modal modal
open={open} open={open}
date={install_date} date={install_date}
@ -641,8 +595,51 @@ export default function EditPolygonScreen({route,navigation}:EditPolygonScreenPr
marginTop: 15 marginTop: 15
}} }}
/> />
<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: 30
}}
/>
</ScrollView> </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'}}>UPDATE</Text>
</TouchableOpacity>
</View>
<AwesomeAlert <AwesomeAlert
show={alertOnline} show={alertOnline}
showProgress={false} showProgress={false}
@ -717,23 +714,25 @@ const styles = StyleSheet.create({
color: 'black' color: 'black'
}, },
input: { input: {
height: 40, width:352,
height: 45,
borderWidth: 1, borderWidth: 1,
padding: 10, padding: 10,
borderRadius: 50, borderRadius: 10,
color: 'black' color: '#6B5E5E',
borderColor:'#A6A6A6'
}, },
container: { container: {
flex: 1,
backgroundColor: '#ecf0f1',
padding: 10, padding: 10,
flexGrow: 1
}, },
mainContainer: { mainContainer: {
flex: 1, flex: 1,
}, },
label: { label: {
fontSize: 21, fontSize: 16,
color: 'black', fontWeight:'semibold',
color: '#434343',
// marginBottom: 20 // marginBottom: 20
}, },
title: { title: {

217
src/component/editscreen.tsx

@ -14,7 +14,8 @@ import {
FlatList, FlatList,
Dimensions, Dimensions,
Animated, Animated,
Alert Alert,
Pressable
} from 'react-native'; } from 'react-native';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker'; import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
@ -32,6 +33,7 @@ import {
import AwesomeAlert from 'react-native-awesome-alerts'; import AwesomeAlert from 'react-native-awesome-alerts';
import {useNavigation,NavigationContainer,useIsFocused} from '@react-navigation/native'; import {useNavigation,NavigationContainer,useIsFocused} from '@react-navigation/native';
import RNFetchBlob from 'rn-fetch-blob'; import RNFetchBlob from 'rn-fetch-blob';
import Modal from "react-native-modal";
import { PJU_API_URL } from "../../urlConfig"; import { PJU_API_URL } from "../../urlConfig";
@ -159,6 +161,8 @@ function EditScreen({route,navigation}: editScreenProps) {
const [attach,setAttach] = useState([]); const [attach,setAttach] = useState([]);
const [load,setLoad] = useState(true); const [load,setLoad] = useState(true);
const isFocused = useIsFocused(); const isFocused = useIsFocused();
const [ModalAttachment, setModalAttachment] = useState(false);
useEffect(()=> { useEffect(()=> {
if (isFocused) { if (isFocused) {
setLong(data.long); setLong(data.long);
@ -237,7 +241,7 @@ function EditScreen({route,navigation}: editScreenProps) {
insertAttachment(files) insertAttachment(files)
Alert.alert("Success") Alert.alert("Success")
setAlertOnline(false); setAlertOnline(false);
navigation.navigate('Property Survey', { screen: 'Property Survey'}) navigation.navigate('Inbox Penerangan Jalan Umum', { screen: 'Inbox Penerangan Jalan Umum'})
} }
else { else {
Alert.alert("Internal Server Error") Alert.alert("Internal Server Error")
@ -384,57 +388,36 @@ function EditScreen({route,navigation}: editScreenProps) {
const handleCancelAlertOffline = () => { const handleCancelAlertOffline = () => {
setAlertOffline(false); 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( return(
<View style={styles.mainContainer}> <View style={styles.mainContainer}>
<ScrollView style={styles.container}> <StatusBar backgroundColor="#34A6F8" barStyle={'light-content'} />
<Text style={styles.title}>Edit Survey PJU</Text> <View key={"mainBackground"} style={{backgroundColor:'#34A6F8',width:'100%',height:'93%'}} />
<View> <View key={"background"} style={{backgroundColor:'#FFFFFF',width:'100%',height:'100%',position:'absolute',borderTopRightRadius:50,borderTopLeftRadius:35,paddingTop:25}}>
<Text style={styles.label}>Image</Text> <ScrollView
<View style={styles.borderImg}> horizontal={false}
<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} showsHorizontalScrollIndicator={false}
pagingEnabled nestedScrollEnabled={true}
onScroll={e=>{ style={styles.container}>
const x = e.nativeEvent.contentOffset.x; <View style={{flexDirection:'column'}}>
setCurrentIndex(parseFloat((x/330).toFixed(0))); {/* <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'}}>
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 <Image
source={require('../../assets/icon/gallery.png')} source={require('../../assets/icon/findmyloc.png')}
style={styles.buttonImageIconStyle}
/> />
</TouchableOpacity> <Text style={{fontSize:14,fontWeight:'semibold',color:'#434343'}}>{lat},</Text>
</View> <Text style={{fontSize:14,fontWeight:'semibold',color:'#434343'}}>{long}</Text>
</View> </View>
</View>
<View
style={{
marginTop: 15
}}
/>
<View style={{flexDirection:'column'}}>
<MapView <MapView
style={{width:'80%',height:160,alignSelf:'center'}} style={{width:352,height:200,borderWidth:1,borderColor:'#A6A6A6',overflow:'hidden',alignSelf:'center'}}
mapStyle={styleURL} mapStyle={styleURL}
rotateEnabled={false} rotateEnabled={false}
zoomEnabled={false} zoomEnabled={false}
@ -454,7 +437,8 @@ function EditScreen({route,navigation}: editScreenProps) {
maxZoomLevel={20} maxZoomLevel={20}
/> />
</MapView> </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, id:data.id,
nama:pju_name, nama:pju_name,
jenis:selectedPJUType, jenis:selectedPJUType,
@ -464,9 +448,7 @@ function EditScreen({route,navigation}: editScreenProps) {
long:long, long:long,
lat:lat lat:lat
}})}> }})}>
<View style={{backgroundColor:'#217dd3',flexDirection:'row',width:200,height:30,borderRadius:20,justifyContent:'center'}}> <Text style={{alignSelf:'center',fontWeight:'semibold',fontSize:16,color:'#434343'}}>Change Location</Text>
<Text style={{alignSelf:'center',fontWeight:'bold',fontSize:16,color:'white'}}>View & Change Location</Text>
</View>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<View <View
@ -474,8 +456,9 @@ function EditScreen({route,navigation}: editScreenProps) {
marginTop: 15 marginTop: 15
}} }}
/> />
<View> <View style={{alignSelf:'center'}}>
<Text style={styles.label}>Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> {/* <Text style={styles.label}>Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */}
<Text style={styles.label}>Name</Text>
<TextInput <TextInput
style={styles.input} style={styles.input}
onChangeText={(text) => { onChangeText={(text) => {
@ -493,14 +476,15 @@ function EditScreen({route,navigation}: editScreenProps) {
marginTop: 15 marginTop: 15
}} }}
/> />
<View> <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 style={{color:'red',fontWeight:'bold'}}>*</Text></Text> */}
<Text style={styles.label}>PJU Type</Text>
<SelectList <SelectList
search={false} search={false}
placeholder="Select PJU Type" placeholder="Select PJU Type"
boxStyles={{borderRadius:50,borderWidth:2}} boxStyles={{borderRadius:10,borderWidth:1,borderColor:'#A6A6A6',width:352,height:45}}
inputStyles={{color:'black'}} inputStyles={{color:'#6B5E5E'}}
dropdownTextStyles={{color:'black'}} dropdownTextStyles={{color:'#6B5E5E'}}
data={PJU_Type} data={PJU_Type}
setSelected={setselectedPJUType} setSelected={setselectedPJUType}
onSelect={()=> ( onSelect={()=> (
@ -508,39 +492,44 @@ function EditScreen({route,navigation}: editScreenProps) {
)} )}
defaultOption={{key:selectedPJUType, value:selectedPJUType}} defaultOption={{key:selectedPJUType, value:selectedPJUType}}
/> />
{PJUTypeError ? <Text style={styles.errorInput}>PJU Type is Required!</Text>:null}
</View> </View>
{PJUTypeError ? <Text style={styles.errorInput}>PJU Type is Required!</Text>:null}
<View <View
style={{ style={{
marginTop: 15 marginTop: 15
}} }}
/> />
<Text style={styles.label}>Status <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> <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'}}> <View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton <RadioButton
color='#434343'
value="Baik" value="Baik"
status={ checkedStatus === 'Baik' ? 'checked' : 'unchecked' } status={ checkedStatus === 'Baik' ? 'checked' : 'unchecked' }
onPress={() => {setCheckedStatus('Baik'); setPJUStatusError(false);}} onPress={() => {setCheckedStatus('Baik'); setPJUStatusError(false)}}
/> />
<Text style={{color:'black'}}>Baik</Text> <Text style={{color:"#434343",fontWeight:'semibold',fontSize:16}}>Baik</Text>
</View> </View>
<View style={{flexDirection:'row',alignItems:'center'}}> <View style={{flexDirection:'row',alignItems:'center'}}>
<RadioButton <RadioButton
color='#434343'
value="Rusak" value="Rusak"
status={ checkedStatus === 'Rusak' ? 'checked' : 'unchecked' } status={ checkedStatus === 'Rusak' ? 'checked' : 'unchecked' }
onPress={() => {setCheckedStatus('Rusak'); setPJUStatusError(false); }} onPress={() => {setCheckedStatus('Rusak'); setPJUStatusError(false); }}
/> />
<Text style={{color:'black'}}>Rusak</Text> <Text style={{color:"#434343",fontWeight:'semibold',fontSize:16}}>Rusak</Text>
</View> </View>
{PJUStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null} {PJUStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null}
</View>
<View <View
style={{ style={{
marginTop: 15 marginTop: 60
}} }}
/> />
<View> <View style={{alignSelf:'center'}}>
<Text style={styles.label}>Information <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text> <Text style={styles.label}>Information</Text>
<TextInput style={{borderWidth:1,borderRadius:20,padding: 10,color:'black',textAlignVertical:'top'}} <TextInput style={{borderWidth:1,borderRadius:20,padding: 10,color:'#6B5E5E',borderColor:'#A6A6A6',textAlignVertical:'top',width:352,height:135}}
multiline multiline
numberOfLines={5} numberOfLines={5}
maxLength={255} maxLength={255}
@ -559,17 +548,17 @@ function EditScreen({route,navigation}: editScreenProps) {
marginTop: 15 marginTop: 15
}} }}
/> />
<View> <View style={{alignSelf:'center'}}>
<Text style={styles.label}>Installation Date</Text> <Text style={styles.label}>Installation Date</Text>
<TextInput <TextInput
style={styles.input} style={styles.input}
readOnly={true} onPress={() => setOpen(true)}
value={String(momentDate)} value={String(momentDate)}
/> />
<DatePicker <DatePicker
locale='en' locale='en'
theme='dark' theme='light'
mode="date" mode='date'
modal modal
open={open} open={open}
date={install_date} date={install_date}
@ -587,14 +576,49 @@ function EditScreen({route,navigation}: editScreenProps) {
marginTop: 15 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> </ScrollView>
<Button title='Update' onPress={showDialog} /> <TouchableOpacity style={{width:'100%',height:50,backgroundColor:'#34A6F8',alignItems:'center',justifyContent:'center'}} onPress={showDialog}>
{/* <Button title='Get Local' onPress={getMyObject} /> <Text style={{fontSize:18,fontWeight:'bold',color:'#FFFFFF'}}>UPDATE</Text>
<Button title='Delete' onPress={removeValue} /> </TouchableOpacity>
<Button title='GetAll' onPress={getAllKeys} /> */} </View>
{/* Online Mode Alert */} {/* Online Mode Alert */}
<AwesomeAlert <AwesomeAlert
show={alertOnline} show={alertOnline}
@ -619,7 +643,6 @@ function EditScreen({route,navigation}: editScreenProps) {
titleStyle={{fontSize:20}} titleStyle={{fontSize:20}}
messageStyle={{fontSize:16}} messageStyle={{fontSize:16}}
/> />
{/* Offline Mode Alert */} {/* Offline Mode Alert */}
<AwesomeAlert <AwesomeAlert
show={alertOffline} show={alertOffline}
@ -639,6 +662,28 @@ function EditScreen({route,navigation}: editScreenProps) {
titleStyle={{fontSize:20}} titleStyle={{fontSize:20}}
messageStyle={{fontSize:16}} 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> </View>
) )
} }
@ -663,23 +708,25 @@ const styles = StyleSheet.create({
color: 'black' color: 'black'
}, },
input: { input: {
height: 40, width:352,
height: 45,
borderWidth: 1, borderWidth: 1,
padding: 10, padding: 10,
borderRadius: 50, borderRadius: 10,
color: 'black' color: '#6B5E5E',
borderColor:'#A6A6A6'
}, },
container: { container: {
flex: 1,
backgroundColor: '#ecf0f1',
padding: 10, padding: 10,
flexGrow: 1
}, },
mainContainer: { mainContainer: {
flex: 1, flex: 1,
}, },
label: { label: {
fontSize: 21, fontSize: 16,
color: 'black', fontWeight:'semibold',
color: '#434343',
// marginBottom: 20 // marginBottom: 20
}, },
title: { title: {

3
src/component/mapCollectPolygonScreen.tsx

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

20
src/component/mapViewLineScreen.tsx

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

22
src/component/mapViewPolygonScreen.tsx

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

14
src/component/mapviewscreen.tsx

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

801
src/component/resendPDAM.tsx

@ -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 @@
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