Browse Source

feat(register):create register Page

master
farhantock 7 months ago
parent
commit
248347cd99
  1. 460
      src/screens/registerPage/index.js

460
src/screens/registerPage/index.js

@ -0,0 +1,460 @@
import React, { useEffect, useCallback, useMemo, useState, useRef } from 'react';
import { StatusBar } from 'react-native';
import { Button, IconButton, Text, Appbar, TextInput, TouchableRipple, Card, List } from 'react-native-paper';
import { StyleSheet, View, ScrollView, PermissionsAndroid, Image } from 'react-native';
import { colors } from '../../utils/color';
import { strings } from '../../utils/i18n';
import { launchCamera } from 'react-native-image-picker';
import { requestAccessStoragePermission } from '../../utils/storage';
import { getCoords } from '../../utils/geolocation';
import { useNavigation } from '@react-navigation/native';
import {
BottomSheetModal,
BottomSheetModalProvider,
BottomSheetView
} from '@gorhom/bottom-sheet';
import RNFS from 'react-native-fs';
import ImageMarker, { Position, TextBackgroundType } from 'react-native-image-marker';
import DateTimePicker from '@react-native-community/datetimepicker';
import moment from 'moment';
export default function DialogForm() {
const navigation = useNavigation();
const [images, setImages] = useState([]);
const [selectedImageUri, setSelectedImageUri] = useState(null);
const bottomSheetImage = useRef(null);
const [selectedProject, setSelectedProject] = useState(null);
const [area, setArea] = useState({ external: false, internal: false })
const [showExpDatePicker, setShowExpDatePicker] = useState(false);
const [expDate, setExpDate] = useState('');
const bottomSheetModal = useRef(null);
const handleOpenSheet = useCallback(() => {
bottomSheetModal.current?.present();
}, []);
const handleProjectPress = () => {
navigation.navigate('SearchPage', { dummyData, onSelect: handleProjectSelect });
};
const handleProjectSelect = (project) => {
setSelectedProject(project);
};
const handleExpDateChange = (event, selectedDate) => {
const currentDate = selectedDate;
setShowExpDatePicker(false);
setExpDate(currentDate);
};
const showExpDatePickerFunc = () => {
setShowExpDatePicker(true);
};
const handleOpenSheetImage = useCallback((uri) => {
setSelectedImageUri(uri);
bottomSheetImage.current?.present();
}, []);
const manpower = [
{ id: '2', status: "Sakit", position: "Guard", name: "ibnu", date: '2024-02-10', timeIn: '08:15', timeOut: '17:30' },
{ id: '3', status: "Cuti", position: "Guard", name: "ardhi", date: '2024-02-11', timeIn: '08:10', timeOut: '17:20' },
{ id: '4', status: "", position: "Admin", name: "hana", date: '2024-02-12', timeIn: '08:10', timeOut: '17:20' },
{ id: '5', status: "", position: "Guard", name: "satori", date: '2024-02-13', timeIn: '08:10', timeOut: '17:20' },
{ id: '6', status: "", position: "Guard", name: "khaidir", date: '2024-02-14', timeIn: '08:10', timeOut: '17:20' },
];
const dummyData = [
{ id: '1', name: 'MRT', icn: 'test1', sicn: 'test"1' },
{ id: '2', name: 'PLN', icn: 'test1', sicn: 'test"1' },
{ id: '3', name: 'Pertamina', icn: 'test1', sicn: 'test"1' },
{ id: '4', name: 'MD Entertaiment', icn: 'test1', sicn: 'test"1' },
{ id: '5', name: 'Jhonny', icn: 'test1', sicn: 'test"1' },
{ id: '6', name: 'AIA', icn: 'test1', sicn: 'test"1' },
{ id: '7', name: 'PLN Pulogadung', icn: 'test1', sicn: 'test"1' },
{ id: '8', name: 'Google', icn: 'test1', sicn: 'test"1' },
{ id: '9', name: 'Amazon', icn: 'test1', sicn: 'test"1' },
{ id: '10', name: 'Microsoft', icn: 'test1', sicn: 'test"1' },
{ id: '11', name: 'Facebook', icn: 'test1', sicn: 'test"1' },
{ id: '12', name: 'Apple', icn: 'test1', sicn: 'test"1' },
{ id: '13', name: 'Tesla', icn: 'test1', sicn: 'test"1' },
{ id: '14', name: 'Netflix', icn: 'test1', sicn: 'test"1' },
{ id: '15', name: 'Twitter', icn: 'test1', sicn: 'test"1' },
{ id: '16', name: 'LinkedIn', icn: 'test1', sicn: 'test"1' },
{ id: '17', name: 'Instagram', icn: 'test1', sicn: 'test"1' },
{ id: '18', name: 'Snapchat', icn: 'test1', sicn: 'test"1' },
{ id: '19', name: 'WhatsApp', icn: 'test1', sicn: 'test"1' },
{ id: '20', name: 'Uber', icn: 'test1', sicn: 'test"1' },
{ id: '21', name: 'Airbnb', icn: 'test1', sicn: 'test"1' },
{ id: '22', name: 'Spotify', icn: 'test1', sicn: 'test"1' },
{ id: '23', name: 'Pinterest', icn: 'test1', sicn: 'test"1' },
{ id: '24', name: 'Reddit', icn: 'test1', sicn: 'test"1' },
{ id: '25', name: 'Dropbox', icn: 'test1', sicn: 'test"1' },
{ id: '26', name: 'Zoom', icn: 'test1', sicn: 'test"1' },
{ id: '27', name: 'Etsy' }
];
const handleSetImageUri = (uri, description) => {
const newImage = { uri: uri, description: description || "" };
setImages(prevImages => [...prevImages, newImage]);
}
const handleDeleteImage = (index) => {
const updatedImages = [...images];
updatedImages.splice(index, 1);
setImages(updatedImages);
};
const handleTakePicture = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: strings('takePicture.cameraPermissionTitle'),
message: strings('takePicture.cameraPermissionMessage'),
buttonNeutral: strings('takePicture.cameraPermissionBtnNeutral'),
buttonNegative: strings('takePicture.cameraPermissionBtnCancel'),
buttonPositive: strings('takePicture.cameraPermissionBtnPositive'),
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
handleLaunchCamera()
} else {
}
} catch (err) {
console.warn(err);
}
};
const handleLaunchCamera = () => {
let options = {
storageOptions: {
skipBackup: true,
path: 'images',
},
cameraType: 'front',
maxWidth: 768,
maxHeight: 1024,
saveToPhotos: false,
includeBase64: true
};
launchCamera(options, (response) => {
if (response.didCancel) {
} else if (response.error) {
} else if (response.customButton) {
} else {
if (response.assets && response.assets.length > 0) {
handleSetImageUri(response.assets[0].uri);
getCoords(loc => {
if (loc) {
let imageObject = {
"image_uri": response.assets[0].uri,
"image_blob": response.assets[0].base64,
"lat": loc.lat,
"lon": loc.lon
}
addOverlay(imageObject)
}
})
}
}
});
}
const addOverlay = async (imageObject) => {
try {
const timestamp = new Date().toLocaleString();
const location = { latitude: imageObject.lat, longitude: imageObject.lon };
const overlayText = `${timestamp}\nLatitude: ${location.latitude}\nLongitude: ${location.longitude}`;
if (imageObject.image_uri) {
const markedImage = await ImageMarker.markText({
backgroundImage: {
src: { uri: imageObject.image_uri }
},
watermarkTexts: [{
text: overlayText,
positionOptions: {
position: Position.bottomLeft,
},
style: {
color: '#ffffff',
fontSize: 8,
fontName: 'Arial',
textBackgroundStyle: {
padding: 10,
type: TextBackgroundType.none,
color: '#00000080'
}
},
}],
position: 'bottomLeft',
color: '#ffffff',
fontName: 'Arial-BoldMT',
fontSize: 16,
scale: 1,
});
await saveToTemporaryFolder(markedImage, imageObject);
}
} catch (error) {
console.error('Error adding overlay:', error);
}
}
const saveToTemporaryFolder = async (markedImage, imageObject) => {
try {
const tempPath = `file://${RNFS.TemporaryDirectoryPath}/KTA/${moment().format('YYYYMMDDHHmmss')}.jpg`;
if (!requestAccessStoragePermission()) {
return;
}
await RNFS.copyFile(markedImage, tempPath);
const imageBase64 = await RNFS.readFile(tempPath, 'base64');
storePhoto(imageObject.user_id, imageObject.drop_point_id, tempPath, imageBase64, imageObject.lat, imageObject.lon)
reloadPhotos();
} catch (error) {
console.error('Error saving image to temporary folder:', error);
}
}
const renderImages = useMemo(() => images.map((image, index) => (
<>
<View key={index} style={styles.imageBlock}>
<TouchableRipple onPress={() => { handleOpenSheetImage(image.uri) }}>
<View style={styles.imageContainer}>
<Image
source={{ uri: image.uri }}
style={styles.image}
resizeMode="cover"
/>
</View>
</TouchableRipple>
</View>
<Button icon="delete" style={{ borderRadius: 10, backgroundColor: colors.semiRed, marginHorizontal: 5, marginBottom: 10 }} textColor={colors.beanRed} mode="contained-tonal" onPress={() => handleDeleteImage(index)}>
{strings('global.delete')}
</Button>
</>
)), [images]);
return (
<>
<StatusBar backgroundColor={colors.blue} barStyle='light-content' translucent={true} />
<Appbar.Header mode='center-aligned' style={{ backgroundColor: colors.blue, elevation: 4 }}>
<Appbar.BackAction color={colors.pureWhite} onPress={() => { navigation.goBack() }} />
<Appbar.Content titleStyle={{ fontWeight: 'bold' }} color={colors.pureWhite} title={strings('global.register')} />
</Appbar.Header>
<View style={{ flex: 1, backgroundColor: colors.pureWhite }}>
<View style={styles.container}>
<ScrollView style={[styles.scrollViewContainer, { backgroundColor: colors.pureWhite }]}>
<TouchableRipple onPress={handleProjectPress}>
<TextInput
dense={true}
outlineColor={colors.amethystSmoke}
activeOutlineColor={colors.blue}
mode="outlined"
editable={false}
label='Pilih Proyek'
placeholder='Pilih Proyek'
value={selectedProject ? selectedProject.name : ''}
right={<TextInput.Icon icon="chevron-down" />}
/>
</TouchableRipple>
<TouchableRipple rippleColor={colors.pureWhite} onPress={handleOpenSheet}>
<TextInput
style={{ marginTop: 10 }}
dense={true}
editable={false}
value=''
outlineColor={colors.amethystSmoke}
activeOutlineColor={colors.blue}
mode="outlined"
label='Shift'
placeholder='Shift'
right={<TextInput.Icon icon="chevron-down" />}
/>
</TouchableRipple>
<TouchableRipple rippleColor={colors.pureWhite} onPress={handleOpenSheet}>
<TextInput
style={{ marginTop: 10 }}
dense={true}
editable={false}
value=''
outlineColor={colors.amethystSmoke}
activeOutlineColor={colors.blue}
mode="outlined"
label='Jabatan'
placeholder='Jabatan'
right={<TextInput.Icon icon="chevron-down" />}
/>
</TouchableRipple>
<TouchableRipple rippleColor={colors.pureWhite} onPress={handleOpenSheet}>
<TextInput
style={{ marginTop: 10 }}
dense={true}
editable={false}
value=''
outlineColor={colors.amethystSmoke}
activeOutlineColor={colors.blue}
mode="outlined"
label='Area'
placeholder='Area'
right={<TextInput.Icon icon="chevron-down" />}
/>
</TouchableRipple>
<TouchableRipple rippleColor={colors.pureWhite} onPress={handleOpenSheet}>
<TextInput
style={{ marginTop: 10 }}
dense={true}
editable={false}
value=''
outlineColor={colors.amethystSmoke}
activeOutlineColor={colors.blue}
mode="outlined"
label='Pos'
placeholder='Pos'
right={<TextInput.Icon icon="chevron-down" />}
/>
</TouchableRipple>
<TouchableRipple rippleColor={colors.pureWhite} onPress={showExpDatePickerFunc}>
<TextInput
style={{ marginTop: 10 }}
dense={true}
editable={false}
value={expDate ? moment(expDate).format("DD-MM-YYYY") : ''}
outlineColor={colors.amethystSmoke}
activeOutlineColor={colors.blue}
mode="outlined"
label='Masa Berlaku KTA'
placeholder='Masa Berlaku KTA'
/>
</TouchableRipple>
{renderImages}
</ScrollView>
<View style={{ width: '100%', marginTop: 10, marginBottom: 5 }}>
<Button icon="camera-plus" style={{ borderRadius: 10, backgroundColor: colors.semiBlue, paddingVertical: 5, marginHorizontal: 5, }} textColor={colors.blue} mode="contained-tonal" onPress={handleTakePicture}>
{strings('global.addImage')}
</Button>
</View>
</View >
<View style={styles.buttonContainer}>
<Button mode="outlined" style={styles.button} textColor={colors.mistBlue} onPress={() => { navigation.goBack() }} >
Kembali
</Button>
<Button mode="contained" style={[styles.button, { backgroundColor: colors.blue }]} onPress={() => console.log('Handle Saved')}>
Simpan
</Button>
</View>
</View >
<BottomSheetModalProvider>
<BottomSheetModal
ref={bottomSheetModal}
index={0}
snapPoints={['30%']}
bottomInset={10}
detached={true}
style={{ marginHorizontal: 15 }}
>
<BottomSheetView >
<TouchableRipple onPress={() => console.log("pagi")}>
<List.Item
title="PAGI"
left={props => <List.Icon {...props} icon="" />}
/>
</TouchableRipple>
<TouchableRipple onPress={() => console.log("siang")}>
<List.Item
title="SIANG"
left={props => <List.Icon {...props} icon="" />}
/>
</TouchableRipple>
<TouchableRipple onPress={() => console.log("malem")}>
<List.Item
title="MALEM"
left={props => <List.Icon {...props} icon="" />}
/>
</TouchableRipple>
</BottomSheetView>
</BottomSheetModal>
<BottomSheetModal
ref={bottomSheetImage}
index={0}
snapPoints={['50%']}
>
<BottomSheetView style={{ alignItems: 'center' }} >
<Image
source={{ uri: selectedImageUri }}
style={styles.imageDetail}
resizeMode="cover"
/>
</BottomSheetView>
</BottomSheetModal>
</BottomSheetModalProvider>
{showExpDatePicker && (
<DateTimePicker
value={expDate || new Date()}
mode="date"
display="default"
onChange={handleExpDateChange}
/>
)}
</>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginHorizontal: 10
},
scrollViewContainer: {
flex: 1,
marginVertical: 10,
},
card: {
flex: 1,
marginHorizontal: 8,
marginVertical: 5,
backgroundColor: colors.pureWhite,
},
subText: {
fontSize: 12,
color: colors.blue
},
button: {
flex: 1,
margin: 5,
borderRadius: 5
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
padding: 10,
paddingBottom: 20,
backgroundColor: colors.pureWhite,
},
imageBlock: {
marginTop: 10,
marginBottom: 10,
alignItems: 'center',
},
imageContainer: {
flexDirection: 'row',
alignItems: 'center',
},
image: {
width: 330,
height: 150,
borderRadius: 7
},
imageDetail: {
width: 330,
height: 300,
borderRadius: 7
}
})
Loading…
Cancel
Save