Browse Source

fix(patroli): Patroli Page

master
farhantock 7 months ago
parent
commit
24676f52a1
  1. 506
      src/screens/patroli/dialogForm.js
  2. 93
      src/screens/patroli/index.js
  3. 260
      src/screens/patroli/report.js

506
src/screens/patroli/dialogForm.js

@ -0,0 +1,506 @@
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 {
BottomSheetModal,
BottomSheetModalProvider,
BottomSheetScrollView
} from '@gorhom/bottom-sheet';
import ImageMarker, { Position, TextBackgroundType } from 'react-native-image-marker';
export default function DialogForm({ route, navigation }) {
const data = [
{
"location_name": "Depo MRT Lebak Bulus PT MRT Jakarta (Perseroda), ",
"location_lat": -6.290149705592755,
"location_lon": 106.77577068583955,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 0,
"children": [
{
"location_name": "Pos TImur",
"location_lat": -6.290149705592755,
"location_lon": 106.77577068583955,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 1,
"day_night_2": 1,
"day_night_do": 2,
"total": 4
},
{
"location_name": "Riksa Ran",
"location_lat": -6.290149705592755,
"location_lon": 106.77577068583955,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 2,
"day_night_2": 2,
"day_night_do": 4,
"total": 8
},
{
"location_name": "Pos Gd A",
"location_lat": -6.290149705592755,
"location_lon": 106.77577068583955,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 2,
"day_night_2": 1,
"day_night_do": 5,
"total": 8
},
{
"location_name": "Pos Gd B",
"location_lat": -6.290149705592755,
"location_lon": 106.77577068583955,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 1,
"day_night_2": 1,
"day_night_do": 1,
"total": 3
},
{
"location_name": "Pos Gd C",
"location_lat": -6.290149705592755,
"location_lon": 106.77577068583955,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 1,
"day_night_2": 1,
"day_night_do": 1,
"total": 3
},
{
"location_name": "Pos JPO",
"location_lat": -6.290149705592755,
"location_lon": 106.77577068583955,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 1,
"day_night_2": 2,
"day_night_do": 1,
"total": 4
},
{
"location_name": "Pos Barat",
"location_lat": -6.290149705592755,
"location_lon": 106.77577068583955,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 1,
"day_night_2": 1,
"day_night_do": 1,
"total": 3
},
{
"location_name": "Patroli",
"location_lat": -6.290149705592755,
"location_lon": 106.77577068583955,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 1,
"day_night_2": 1,
"day_night_do": 1,
"total": 3
}
]
},
{
"location_name": "Receiving Sub Station (RSS) Jl. Taman Sambas",
"location_lat": -6.248884920623913,
"location_lon": 106.79742903090003,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 0,
"children": [
{
"location_name": "Pos RSS Sambas",
"location_lat": -6.248884920623913,
"location_lon": 106.79742903090003,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 2,
"day_night_2": 2,
"day_night_do": 4,
"total": 8
}
]
},
{
"location_name": "Area transisi antara stasiun layang dan bawah tanah",
"location_lat": -6.234288689010968,
"location_lon": 106.7984383166707,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 0,
"children": [
{
"location_name": "Pos Transisi",
"location_lat": -6.234288689010968,
"location_lon": 106.7984383166707,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 2,
"day_night_2": 2,
"day_night_do": 4,
"total": 8
}
]
},
{
"location_name": "Ratangga PT MRT Jakarta (Perseroda), Gedung Wisma Nusantara lantai 21, Jalan M.H. Thamrin Kavling 59, Jakarta Pusat 10350",
"location_lat": -6.193848456812861,
"location_lon": 106.82352714314999,
"office_hour_ns": 0,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 0,
"children": [
{
"location_name": "Ratangga 1",
"location_lat": -6.193848456812861,
"location_lon": 106.82352714314999,
"office_hour_ns": 0,
"office_hour_1": 2,
"office_hour_2": 2,
"office_hour_3": 0,
"office_hour_do": 2,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 6
},
{
"location_name": "Ratangga 2",
"location_lat": -6.193848456812861,
"location_lon": 106.82352714314999,
"office_hour_ns": 0,
"office_hour_1": 2,
"office_hour_2": 2,
"office_hour_3": 0,
"office_hour_do": 2,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 6
},
{
"location_name": "Ratangga 3",
"location_lat": -6.193848456812861,
"location_lon": 106.82352714314999,
"office_hour_ns": 0,
"office_hour_1": 2,
"office_hour_2": 2,
"office_hour_3": 0,
"office_hour_do": 2,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 6
},
{
"location_name": "Ratangga 4",
"location_lat": -6.193848456812861,
"location_lon": 106.82352714314999,
"office_hour_ns": 0,
"office_hour_1": 2,
"office_hour_2": 2,
"office_hour_3": 0,
"office_hour_do": 2,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 6
},
{
"location_name": "Ratangga 5",
"location_lat": -6.193848456812861,
"location_lon": 106.82352714314999,
"office_hour_ns": 0,
"office_hour_1": 2,
"office_hour_2": 2,
"office_hour_3": 0,
"office_hour_do": 2,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 6
},
{
"location_name": "Ratangga 6",
"location_lat": -6.193848456812861,
"location_lon": 106.82352714314999,
"office_hour_ns": 0,
"office_hour_1": 2,
"office_hour_2": 2,
"office_hour_3": 0,
"office_hour_do": 2,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 6
},
{
"location_name": "Ratangga 7",
"location_lat": -6.193848456812861,
"location_lon": 106.82352714314999,
"office_hour_ns": 0,
"office_hour_1": 2,
"office_hour_2": 2,
"office_hour_3": 0,
"office_hour_do": 2,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 6
},
{
"location_name": "Ratangga Pick Hours",
"location_lat": -6.193848456812861,
"location_lon": 106.82352714314999,
"office_hour_ns": 14,
"office_hour_1": 0,
"office_hour_2": 0,
"office_hour_3": 0,
"office_hour_do": 0,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 14
},
{
"location_name": "Danru Walka",
"location_lat": -6.193848456812861,
"location_lon": 106.82352714314999,
"office_hour_ns": 1,
"office_hour_1": 1,
"office_hour_2": 1,
"office_hour_3": 0,
"office_hour_do": 1,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 4
},
{
"location_name": "Wa Danru Walka",
"location_lat": -6.193848456812861,
"location_lon": 106.82352714314999,
"office_hour_ns": 1,
"office_hour_1": 0,
"office_hour_2": 1,
"office_hour_3": 0,
"office_hour_do": 1,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 3
},
{
"location_name": "Patroli Walka ",
"location_lat": -6.193848456812861,
"location_lon": 106.82352714314999,
"office_hour_ns": 1,
"office_hour_1": 1,
"office_hour_2": 1,
"office_hour_3": 0,
"office_hour_do": 1,
"day_night_ns": 0,
"day_night_1": 0,
"day_night_2": 0,
"day_night_do": 0,
"total": 4
}
]
}
]
const snapPoints = useMemo(() => ['25%', '40%'], []);
const bottomSheetModal = useRef(null);
const [area, setArea] = useState('');
const [children, setChildren] = useState([]);
const handleOpenSheet = useCallback(() => {
bottomSheetModal.current?.present();
}, []);
const handleSelectArea = (area) => {
setArea(area.location_name)
setChildren(area.children || []);
bottomSheetModal.current?.dismiss();
};
const renderArea = (data) => (
<View>
<TouchableRipple key={data.location_name} onPress={() => handleSelectArea(data)}>
<List.Item
title={data.location_name}
/>
</TouchableRipple>
</View>
);
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('patrol.list')} />
</Appbar.Header>
<View style={styles.container}>
<TouchableRipple onPress={handleOpenSheet}>
<TextInput
style={{ marginTop: 10, marginBottom: 15, marginHorizontal: 10 }}
dense={true}
editable={false}
value={area}
outlineColor={colors.amethystSmoke}
activeOutlineColor={colors.blue}
mode="outlined"
label='Area Patroli'
placeholder='Area Patroli'
/>
</TouchableRipple>
<ScrollView style={[styles.scrollViewContainer, { backgroundColor: colors.pureWhite }]}>
{children.map((item) => (
<TouchableRipple onPress={() => { navigation.navigate('DialogFormReport') }} rippleColor={colors.pureWhite}>
<Card style={styles.card}>
<Card.Cover source={{ uri: 'https://picsum.photos/700' }} />
<Card.Content style={{ marginTop: 10 }}>
<Text variant="titleLarge" style={{ color: colors.black }}>{item.location_name}</Text>
</Card.Content>
</Card>
</TouchableRipple>
))}
</ScrollView>
</View>
<BottomSheetModalProvider>
<BottomSheetModal
ref={bottomSheetModal}
index={1}
snapPoints={snapPoints}
>
<BottomSheetScrollView contentContainerStyle={styles.scrollView}>
{data.map(item => renderArea(item))}
</BottomSheetScrollView>
</BottomSheetModal>
</BottomSheetModalProvider>
</>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: colors.pureWhite
},
scrollViewContainer: {
flex: 1,
marginVertical: 10,
marginHorizontal: 10,
},
card: {
flex: 1,
marginHorizontal: 8,
marginVertical: 5,
backgroundColor: colors.pureWhite,
},
subText: {
fontSize: 12,
color: colors.blue
},
cardContent: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 10,
},
})

93
src/screens/patroli/index.js

@ -0,0 +1,93 @@
import React, { useEffect, useCallback, useMemo, useState, useRef } from 'react';
import { Card, Text, Avatar, useTheme, IconButton, Appbar, Button, TouchableRipple } from 'react-native-paper';
import { RefreshControl, StyleSheet, View, ScrollView, StatusBar } from 'react-native';
import { colors } from '../../utils/color';
import Icon from 'react-native-vector-icons/AntDesign';
import { strings } from '../../utils/i18n';
export default function PatroliScreen({ route, navigation }) {
const data = [
{ id: 1, date: "Senin, 02-05-2024", startTime: "21:03", endTime: "21:03", title: "Patroli Area 1", description: "Melakukan Patroli pada Area 1", },
{ id: 2, date: "Selasa, 03-05-2024", startTime: "10:15", endTime: "10:15", title: "Patroli Area 2", description: "Melakukan Patroli pada Area 2", },
{ id: 3, date: "Rabu, 04-05-2024", startTime: "15:20", endTime: "15:20", title: "Patroli Area 3", description: "Melakukan Patroli pada Area 3", },
{ id: 4, date: "Kamis, 05-05-2024", startTime: "18:30", endTime: "18:30", title: "Patroli Area 4", description: "Melakukan Patroli pada Area 4", },
{ id: 5, date: "Jumat, 06-05-2024", startTime: "08:00", endTime: "08:00", title: "Patroli Area 5", description: "Melakukan Patroli pada Area 5", },
{ id: 5, date: "Sabtu, 07-05-2024", startTime: "08:00", endTime: "08:00", title: "Patroli Area 6", description: "Melakukan Patroli pada Area 6", },
{ id: 5, date: "Minggu, 08-05-2024", startTime: "08:00", endTime: "08:00", title: "Patroli Area 7", description: "Melakukan Patroli pada Area 7", }
];
return (
<View style={styles.container}>
<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('patrol.title')} />
</Appbar.Header>
<View style={{ width: '100%', marginTop: 10, marginBottom: 5 }}>
<Button icon="plus" style={{ borderRadius: 10, backgroundColor: colors.semiBlue, marginHorizontal: 8, }} textColor={colors.blue} mode="contained-tonal" onPress={() => { navigation.navigate('DialogFormPatroli') }}>
{strings('patrol.add')}
</Button>
</View>
<ScrollView style={{ backgroundColor: colors.pureWhite }}>
{data.map((item) => (
<TouchableRipple onPress={() => { navigation.navigate('DialogFormPatroli') }} rippleColor={colors.pureWhite}>
<Card style={styles.card}>
<Card.Cover source={{ uri: 'https://picsum.photos/700' }} />
<Card.Content style={{ marginTop: 10 }}>
<Text variant="bodyMedium" style={{ color: colors.amethystSmoke }}>{item.date} {item.startTime} - {item.endTime}</Text>
<Text variant="titleLarge" style={{ color: colors.black }}>{item.title}</Text>
<Text variant="bodyMedium" style={{ color: colors.amethystSmoke }}>{item.description}</Text>
</Card.Content>
</Card>
</TouchableRipple>
))}
</ScrollView>
</View >
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20,
backgroundColor: colors.pureWhite
},
Text: {
fontSize: 16,
fontWeight: 'bold',
color: colors.blue
},
card: {
flex: 1,
marginHorizontal: 8,
marginVertical: 5,
backgroundColor: colors.pureWhite,
},
subText: {
fontSize: 12,
color: colors.blue
},
cardContent: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 10,
},
button: {
flex: 1,
margin: 5,
borderRadius: 5
},
row: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 5,
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
padding: 10,
paddingBottom: 20,
},
})

260
src/screens/patroli/report.js

@ -0,0 +1,260 @@
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 ImageMarker, { Position, TextBackgroundType } from 'react-native-image-marker';
export default function DialogFormReport({ route, navigation }) {
const [images, setImages] = useState([]);
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);
}
bottomSheetModal.current?.dismiss();
};
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}/patroli/${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}>
<View style={styles.imageContainer}>
<Image
source={{ uri: image.uri }}
style={styles.image}
resizeMode="cover"
/>
<IconButton
iconColor={colors.beanRed}
icon="delete"
style={styles.deleteButton}
size={30}
onPress={() => handleDeleteImage(index)}
/>
</View>
<TextInput
mode='outlined'
style={styles.descriptionInput}
outlineColor={colors.amethystSmoke}
activeOutlineColor={colors.blue}
placeholder="Deskripsi gambar"
label="Deskripsi gambar"
multiline={true}
value={image.description}
onChangeText={(text) => {
const updatedImages = [...images];
updatedImages[index].description = text;
setImages(updatedImages);
}}
/>
</View>
)), [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('patrol.add')} />
</Appbar.Header>
<View style={styles.container}>
<Button
icon="plus"
style={styles.addButton}
mode="contained-tonal"
onPress={handleTakePicture}
textColor={colors.blue}
>
Tambah Gambar
</Button>
<ScrollView>
<View style={styles.scrollViewContainer}>
{renderImages}
</View>
</ScrollView>
<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>
</>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: colors.pureWhite
},
addButton: {
marginVertical: 5,
marginHorizontal: 5,
borderRadius: 10,
backgroundColor: colors.semiBlue,
},
imageBlock: {
marginBottom: 10,
flexDirection: 'row',
},
imageContainer: {
flexDirection: 'column',
alignItems: 'center',
},
image: {
width: 100,
height: 100,
borderRadius: 7
},
descriptionInput: {
flex: 1
},
scrollViewContainer: {
flex: 1,
marginVertical: 10,
marginHorizontal: 10,
},
button: {
flex: 1,
margin: 5,
borderRadius: 5
},
row: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 5,
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
padding: 10,
paddingBottom: 20,
},
})
Loading…
Cancel
Save