farhantock
7 months ago
11 changed files with 1587 additions and 74 deletions
@ -0,0 +1,361 @@
|
||||
import React, { useState, useEffect, useRef, useMemo, useCallback } from 'react'; |
||||
import { List, TouchableRipple, TextInput, Card, Text, Button } from 'react-native-paper'; |
||||
import { View, StyleSheet, ScrollView } from 'react-native'; |
||||
import DateTimePicker from '@react-native-community/datetimepicker'; |
||||
import moment from 'moment'; |
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; |
||||
import { colors } from '../../../utils/color'; |
||||
import { |
||||
BottomSheetModal, |
||||
BottomSheetModalProvider, |
||||
BottomSheetScrollView |
||||
} from '@gorhom/bottom-sheet'; |
||||
import { strings } from '../../../utils/i18n'; |
||||
export default function ChronologyScreen({ route, navigation }) { |
||||
const [chronology, setChronology] = useState('') |
||||
const [incidentRiskPotential, setIncidentRiskPotential] = useState({ impact: "", likelihood: "", value: "", impactDescription: "", likelihoodDescription: "" }) |
||||
const [riskLevel, setRiskLevel] = useState({ level: "", backgroundColor: '', color: '' }) |
||||
const bottomSheetModalImpactRef = useRef(null); |
||||
const bottomSheetModalLikelihoodRef = useRef(null); |
||||
|
||||
const snapPoints = useMemo(() => ['25%', '50%'], []); |
||||
|
||||
const handleOpenImpact = useCallback(() => { |
||||
bottomSheetModalImpactRef.current?.present(); |
||||
}, []); |
||||
|
||||
const handleOpenLikelihood = useCallback(() => { |
||||
bottomSheetModalLikelihoodRef.current?.present(); |
||||
}, []); |
||||
|
||||
|
||||
useEffect(() => { |
||||
if (incidentRiskPotential.impact !== "" && incidentRiskPotential.likelihood !== "") { |
||||
const impactValue = dataSelectImpact.find(item => item.label === incidentRiskPotential.impact)?.value || 0; |
||||
const likelihoodValue = dataSelectLikelihood.find(item => item.label === incidentRiskPotential.likelihood)?.value || 0; |
||||
|
||||
const val = impactValue * likelihoodValue; |
||||
let newRiskLevel, backgroundColor, color; |
||||
if (val >= 1 && val <= 5) { |
||||
backgroundColor = '#E3F8E8' |
||||
color = '#17C13E' |
||||
newRiskLevel = 'Rendah'; |
||||
} else if (val >= 6 && val <= 10) { |
||||
backgroundColor = "#F8DC49" |
||||
color = "white" |
||||
newRiskLevel = 'Sedang'; |
||||
} else if (val >= 11 && val <= 15) { |
||||
backgroundColor = '#FFD9AF' |
||||
color = '#EC9C3D' |
||||
newRiskLevel = 'Tinggi'; |
||||
} else { |
||||
backgroundColor = '#FFC5C3' |
||||
color = '#D9534F' |
||||
newRiskLevel = 'Bencana'; |
||||
} |
||||
|
||||
if (incidentRiskPotential.value !== val.toString() || riskLevel.level !== newRiskLevel || riskLevel.backgroundColor !== backgroundColor || riskLevel.color !== color) { |
||||
setIncidentRiskPotential(prevState => ({ ...prevState, value: val.toString() })); |
||||
setRiskLevel({ level: newRiskLevel, backgroundColor: backgroundColor, color: color }); |
||||
} |
||||
} |
||||
}, [incidentRiskPotential, riskLevel]); |
||||
|
||||
|
||||
|
||||
const handleSelectImpact = (impact) => { |
||||
setIncidentRiskPotential(prevState => ({ |
||||
...prevState, |
||||
impact: impact.label, |
||||
value: impact.value, |
||||
impactDescription: impact.description |
||||
})); |
||||
bottomSheetModalImpactRef.current?.dismiss(); |
||||
}; |
||||
|
||||
const handleSelectLikelihood = (likelihood) => { |
||||
setIncidentRiskPotential(prevState => ({ |
||||
...prevState, |
||||
likelihood: likelihood.label, |
||||
likelihoodDescription: likelihood.description |
||||
})); |
||||
bottomSheetModalLikelihoodRef.current?.dismiss(); |
||||
}; |
||||
|
||||
const dataSelectImpact = [ |
||||
{ label: 'Insignificant', value: 1, description: 'Tidak ada Gangguan Operasional Perusahaan' }, |
||||
{ label: 'Minor', value: 2, description: 'Operasional Perusahaan Terganggu Namun tidak terlalu signifikan dapat berjalan 75%' }, |
||||
{ label: 'Moderate', value: 3, description: 'Operasional Perusahaan Terganggu Namun tidak dapat berjalan 50%' }, |
||||
{ label: 'Major', value: 4, description: 'Operasional Perusahaan Terganggu, Namun tidak dapat berjalan 25%' }, |
||||
{ label: 'Extreme', value: 5, description: 'Operasional Perusahaan Terhenti akibat Gangguan Yang Ada' } |
||||
]; |
||||
|
||||
const dataTranslasiImpact = { |
||||
Insignificant: 'Tidak signifikan', |
||||
Minor: 'Kecil', |
||||
Moderate: 'Sedang', |
||||
Major: 'Besar', |
||||
Extreme: 'Ekstrim', |
||||
} |
||||
|
||||
const dataSelectLikelihood = [ |
||||
{ label: 'Rare', value: 1, description: '< 5%, Terjadi dalam 1x lebih 20 Tahun' }, |
||||
{ label: 'Unlikely', value: 2, description: '5% - 29%, Terjadi dalam 1x dalam setiap 20 Tahun' }, |
||||
{ label: 'Possible', value: 3, description: '30% - 59%, Terjadi dalam 1x dalam setiap 5 Tahun' }, |
||||
{ label: 'Likely', value: 4, description: '60% - 89%, Terjadi dalam 1x dalam setiap tahun' }, |
||||
{ label: 'Almost Certain', value: 5, description: '90%, Terjadi dalam 1x dalam setiap bulan' } |
||||
] |
||||
|
||||
const dataTranslasiLikelihood = { |
||||
Rare: 'Langka', |
||||
Unlikely: 'Jarang', |
||||
Possible: 'Mungkin terjadi', |
||||
Likely: 'Sangat memungkinkan', |
||||
"Almost Certain": 'Sudah pasti', |
||||
} |
||||
|
||||
console.log("incidentRiskPotential", incidentRiskPotential); |
||||
|
||||
const renderImpact = (data) => ( |
||||
<View> |
||||
<TouchableRipple key={dataTranslasiImpact[data.label]} onPress={() => handleSelectImpact(data)}> |
||||
<List.Item |
||||
title={dataTranslasiImpact[data.label]} |
||||
/> |
||||
</TouchableRipple> |
||||
</View> |
||||
); |
||||
const renderLikelihood = (data) => ( |
||||
<View> |
||||
<TouchableRipple key={dataTranslasiLikelihood[data.label]} onPress={() => handleSelectLikelihood(data)}> |
||||
<List.Item |
||||
title={dataTranslasiLikelihood[data.label]} |
||||
/> |
||||
</TouchableRipple> |
||||
</View> |
||||
); |
||||
|
||||
return ( |
||||
<> |
||||
<Card style={{ backgroundColor: colors.semiRed, paddingVertical: 15, paddingHorizontal: 15, marginHorizontal: 8, marginVertical: 5, borderRadius: 5 }}> |
||||
<View> |
||||
<Text variant="bodySmall" style={{ color: colors.beanRed, fontWeight: 'bold', fontSize: 16 }}> |
||||
Kronologis kejadian |
||||
</Text> |
||||
<Text variant="bodySmall" style={{ color: colors.beanRed, fontSize: 12 }}> |
||||
Jelaskan bagaimana terjadinya insiden |
||||
</Text> |
||||
</View> |
||||
</Card> |
||||
<ScrollView> |
||||
<View style={styles.container}> |
||||
<TextInput |
||||
dense={true} |
||||
underlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
label="Kronologis Singkat Kejadian" |
||||
mode="outlined" |
||||
placeholder='Isi kronologis' |
||||
multiline={true} |
||||
numberOfLines={5} |
||||
value={chronology} |
||||
onChangeText={(text) => { |
||||
setChronology(text) |
||||
}} |
||||
/> |
||||
|
||||
<TextInput |
||||
dense={true} |
||||
underlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label="Penjelasan Permasalahan" |
||||
placeholder='Isi Permasalahan' |
||||
multiline={true} |
||||
numberOfLines={5} |
||||
onChangeText={(text) => { |
||||
setChronology(text) |
||||
}} |
||||
/> |
||||
<TouchableRipple onPress={handleOpenImpact}> |
||||
<TextInput |
||||
style={{ marginTop: 10 }} |
||||
dense={true} |
||||
editable={false} |
||||
underlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='Impact' |
||||
value={incidentRiskPotential.impact ? dataTranslasiImpact[incidentRiskPotential.impact] : ''} |
||||
right={<TextInput.Icon icon="chevron-down" onPress={handleOpenImpact} />} |
||||
/> |
||||
</TouchableRipple> |
||||
{incidentRiskPotential.impactDescription && ( |
||||
<Card style={{ backgroundColor: colors.pureWhite, paddingVertical: 15, paddingHorizontal: 15, marginVertical: 5, borderRadius: 5 }}> |
||||
<Text variant="bodySmall" style={{ fontSize: 12 }}> |
||||
{incidentRiskPotential.impactDescription} |
||||
</Text> |
||||
</Card> |
||||
)} |
||||
<TouchableRipple onPress={handleOpenLikelihood}> |
||||
<TextInput |
||||
dense={true} |
||||
editable={false} |
||||
underlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='Likelihood' |
||||
value={incidentRiskPotential.likelihood ? dataTranslasiLikelihood[incidentRiskPotential.likelihood] : ''} |
||||
right={<TextInput.Icon icon="chevron-down" onPress={handleOpenLikelihood} />} |
||||
/> |
||||
</TouchableRipple> |
||||
|
||||
{incidentRiskPotential.likelihoodDescription && ( |
||||
<Card style={{ backgroundColor: colors.pureWhite, paddingVertical: 15, paddingHorizontal: 15, marginVertical: 5, borderRadius: 5 }}> |
||||
<Text variant="bodySmall" style={{ fontSize: 12 }}> |
||||
{incidentRiskPotential.likelihoodDescription} |
||||
</Text> |
||||
</Card> |
||||
)} |
||||
<View style={styles.row}> |
||||
<Card style={{ flex: 1, marginRight: 5, backgroundColor: '#FFC5C3', paddingVertical: 15, paddingHorizontal: 15, marginVertical: 5, borderRadius: 5 }}> |
||||
<Text variant="bodySmall" style={{ fontSize: 12, color: '#D9534F' }}> |
||||
Critical |
||||
</Text> |
||||
</Card> |
||||
<Card style={{ flex: 1, marginLeft: 5, backgroundColor: riskLevel.backgroundColor, paddingVertical: 15, paddingHorizontal: 15, marginVertical: 5, borderRadius: 5 }}> |
||||
<Text variant="bodySmall" style={{ fontSize: 12, color: riskLevel.color }}> |
||||
{riskLevel.level} {incidentRiskPotential.value} |
||||
</Text> |
||||
</Card> |
||||
</View> |
||||
<Text variant="bodySmall" style={{ color: colors.black, fontSize: 14 }}> |
||||
Rencana tindakan pencegahan |
||||
</Text> |
||||
|
||||
<Card elevation={2} style={styles.card}> |
||||
<View style={styles.cardContent}> |
||||
<View style={styles.leftContent}> |
||||
<Icon name="view-list" size={25} color={colors.blue} /> |
||||
</View> |
||||
<View style={styles.midContent}> |
||||
<Text variant="bodySmall" style={styles.subText}>01-03-2024</Text> |
||||
<Text variant="headlineMedium" style={styles.Text}>Farhan</Text> |
||||
<Text variant="bodySmall" style={styles.subText}>Melakukan pengamatan dan patroli area pagar luar Depo MRT</Text> |
||||
</View> |
||||
</View> |
||||
<View style={styles.buttonContainer}> |
||||
<Button mode="outlined" style={styles.button} textColor={colors.beanRed} onPress={() => { navigation.goBack() }} > |
||||
Edit |
||||
</Button> |
||||
<Button mode="contained" style={[styles.button, { backgroundColor: colors.beanRed }]} onPress={() => console.log('Handle Saved')}> |
||||
Hapus |
||||
</Button> |
||||
</View> |
||||
</Card> |
||||
|
||||
{/* color: (typeRiskIncident === 'Critical' ? '#D9534F' : (typeRiskIncident === 'Major' ? '#EC9C3D' : 'black')) */} |
||||
</View> |
||||
</ScrollView> |
||||
<Button icon="plus" style={{ borderRadius: 10, backgroundColor: colors.semiBlue, marginHorizontal: 8, }} textColor={colors.blue} mode="contained-tonal" onPress={() => { navigation.navigate('ContainedActionScreen') }}> |
||||
{strings('incidentReport.containedAction')} |
||||
</Button> |
||||
<BottomSheetModalProvider> |
||||
<BottomSheetModal |
||||
ref={bottomSheetModalImpactRef} |
||||
index={1} |
||||
snapPoints={snapPoints} |
||||
> |
||||
<BottomSheetScrollView contentContainerStyle={styles.scrollView}> |
||||
{dataSelectImpact.map(item => renderImpact(item))} |
||||
</BottomSheetScrollView> |
||||
</BottomSheetModal> |
||||
</BottomSheetModalProvider> |
||||
<BottomSheetModalProvider> |
||||
<BottomSheetModal |
||||
ref={bottomSheetModalLikelihoodRef} |
||||
index={1} |
||||
snapPoints={snapPoints} |
||||
> |
||||
<BottomSheetScrollView contentContainerStyle={styles.scrollView}> |
||||
{dataSelectLikelihood.map(item => renderLikelihood(item))} |
||||
</BottomSheetScrollView> |
||||
</BottomSheetModal> |
||||
</BottomSheetModalProvider> |
||||
</> |
||||
) |
||||
} |
||||
|
||||
const styles = StyleSheet.create({ |
||||
containerModal: { |
||||
flex: 1, |
||||
padding: 24, |
||||
justifyContent: 'center', |
||||
backgroundColor: 'grey', |
||||
}, |
||||
|
||||
contentContainer: { |
||||
flex: 1, |
||||
alignItems: 'center', |
||||
}, |
||||
buttonContainer: { |
||||
flexDirection: 'row', |
||||
justifyContent: 'space-between', |
||||
padding: 10, |
||||
paddingBottom: 20, |
||||
}, |
||||
button: { |
||||
flex: 1, |
||||
margin: 5, |
||||
borderRadius: 5 |
||||
}, |
||||
container: { |
||||
flex: 1, |
||||
marginVertical: 10, |
||||
marginHorizontal: 10 |
||||
}, |
||||
|
||||
Text: { |
||||
fontSize: 16, |
||||
fontWeight: 'bold', |
||||
color: colors.blue |
||||
}, |
||||
card: { |
||||
flex: 1, |
||||
marginHorizontal: 8, |
||||
marginVertical: 5, |
||||
backgroundColor: colors.pureWhite, |
||||
}, |
||||
subText: { |
||||
fontSize: 12, |
||||
color: colors.blue |
||||
}, |
||||
|
||||
row: { |
||||
flexDirection: 'row', |
||||
justifyContent: 'space-between', |
||||
marginBottom: 5 |
||||
}, |
||||
cardContent: { |
||||
flexDirection: 'row', |
||||
justifyContent: 'space-between', |
||||
paddingVertical: 10, |
||||
}, |
||||
leftContent: { |
||||
flex: 1, |
||||
justifyContent: 'center', |
||||
alignItems: 'flex-start', |
||||
marginLeft: 15 |
||||
}, |
||||
midContent: { |
||||
flex: 7, |
||||
justifyContent: 'flex-start', |
||||
alignItems: 'flex-start', |
||||
}, |
||||
rightContent: { |
||||
flex: 1, |
||||
justifyContent: 'center', |
||||
alignItems: 'flex-end', |
||||
marginRight: 15, |
||||
}, |
||||
}); |
@ -0,0 +1,159 @@
|
||||
import React, { useState, useRef, useMemo, useCallback } from 'react'; |
||||
import { TouchableRipple, TextInput, Appbar, List, Button } from 'react-native-paper'; |
||||
import { View, StyleSheet, ScrollView } from 'react-native'; |
||||
import DateTimePicker from '@react-native-community/datetimepicker'; |
||||
import moment from 'moment'; |
||||
import { colors } from '../../../utils/color'; |
||||
import { strings } from '../../../utils/i18n'; |
||||
import { |
||||
BottomSheetModal, |
||||
BottomSheetModalProvider, |
||||
BottomSheetView |
||||
} from '@gorhom/bottom-sheet'; |
||||
|
||||
export default function ReportScreen({ route, navigation }) { |
||||
const [showIncidentDatePicker, setShowIncidentDatePicker] = useState(false); |
||||
const [date, setDate] = useState(''); |
||||
const [status, setStatus] = useState('') |
||||
const bottomSheetModal = useRef(null); |
||||
const showIncidentDatePickerFunc = () => { |
||||
setShowIncidentDatePicker(true); |
||||
}; |
||||
// const snapPoints = useMemo(() => ['10%', ], []);
|
||||
const handleOpenSheet = useCallback(() => { |
||||
bottomSheetModal.current?.present(); |
||||
}, []); |
||||
|
||||
const handleStatus = (data) => { |
||||
setStatus(data) |
||||
bottomSheetModal.current?.dismiss(); |
||||
} |
||||
|
||||
const handleIncidentDateChange = (event, selectedDate) => { |
||||
const currentDate = selectedDate; |
||||
setShowIncidentDatePicker(false); |
||||
setDate(currentDate); |
||||
}; |
||||
return ( |
||||
<> |
||||
<Appbar.Header mode='center-aligned' style={{ backgroundColor: colors.beanRed }}> |
||||
<Appbar.BackAction color={colors.pureWhite} onPress={() => { navigation.goBack() }} /> |
||||
<Appbar.Content color={colors.pureWhite} title='Rencana pencegahan' /> |
||||
</Appbar.Header> |
||||
<View style={styles.container}> |
||||
<ScrollView> |
||||
<TextInput |
||||
dense={true} |
||||
underlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
label="RENCANA TINDAKAN PENCEGAHAN" |
||||
mode="outlined" |
||||
multiline={true} |
||||
numberOfLines={5} |
||||
/> |
||||
|
||||
<TextInput |
||||
style={{ marginTop: 10, marginBottom: 15 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='Who' |
||||
placeholder='Who' |
||||
/> |
||||
<TouchableRipple onPress={showIncidentDatePickerFunc}> |
||||
<TextInput |
||||
style={{ marginBottom: 15 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label=" When" |
||||
value={date ? moment(date).format("DD-MM-YYYY") : ''} |
||||
editable={false} |
||||
right={<TextInput.Icon icon="calendar" onPress={showIncidentDatePickerFunc} />} |
||||
/> |
||||
</TouchableRipple> |
||||
<TouchableRipple onPress={handleOpenSheet}> |
||||
<TextInput |
||||
style={{ marginBottom: 15 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label=" Status" |
||||
value={status ? status : ''} |
||||
editable={false} |
||||
right={<TextInput.Icon icon="list-status" onPress={handleOpenSheet} />} |
||||
/> |
||||
</TouchableRipple> |
||||
</ScrollView > |
||||
</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.beanRed }]} onPress={() => console.log('Handle Saved')}> |
||||
Simpan |
||||
</Button> |
||||
</View> |
||||
|
||||
{ |
||||
showIncidentDatePicker && ( |
||||
<DateTimePicker |
||||
value={date || new Date()} |
||||
mode="date" |
||||
display="default" |
||||
onChange={handleIncidentDateChange} |
||||
/> |
||||
) |
||||
} |
||||
|
||||
<BottomSheetModalProvider> |
||||
<BottomSheetModal |
||||
ref={bottomSheetModal} |
||||
index={0} |
||||
snapPoints={['20%']} |
||||
bottomInset={10} |
||||
detached={true} |
||||
style={{ marginHorizontal: 15 }} |
||||
> |
||||
<BottomSheetView > |
||||
<TouchableRipple onPress={() => handleStatus("Open")}> |
||||
<List.Item |
||||
title="OPEN" |
||||
left={props => <List.Icon {...props} icon="" />} |
||||
/> |
||||
</TouchableRipple> |
||||
<TouchableRipple onPress={() => handleStatus("Close")}> |
||||
<List.Item |
||||
title="CLOSE" |
||||
left={props => <List.Icon {...props} icon="" />} |
||||
/> |
||||
</TouchableRipple> |
||||
</BottomSheetView> |
||||
</BottomSheetModal> |
||||
</BottomSheetModalProvider> |
||||
</> |
||||
) |
||||
} |
||||
|
||||
const styles = StyleSheet.create({ |
||||
container: { |
||||
flex: 1, |
||||
marginVertical: 10, |
||||
marginHorizontal: 10 |
||||
}, |
||||
button: { |
||||
flex: 1, |
||||
margin: 5, |
||||
borderRadius: 5 |
||||
}, |
||||
buttonContainer: { |
||||
flexDirection: 'row', |
||||
justifyContent: 'space-between', |
||||
padding: 10, |
||||
paddingBottom: 20, |
||||
}, |
||||
}); |
@ -0,0 +1,75 @@
|
||||
import React, { useState } from 'react'; |
||||
import { TouchableRipple, Chip, Card, Text } from 'react-native-paper'; |
||||
import { View, StyleSheet, ScrollView } from 'react-native'; |
||||
import DateTimePicker from '@react-native-community/datetimepicker'; |
||||
import moment from 'moment'; |
||||
import { colors } from '../../../utils/color'; |
||||
import { jenisKejadian } from '../../../config/ApiConst' |
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons' |
||||
|
||||
export default function IncidentScreen() { |
||||
const [selectedItems, setSelectedItems] = useState([]); |
||||
const [dataIncidentReport, setDataIncidentReport] = useState(jenisKejadian[0].data) |
||||
const [typeRiskIncident, setTypeRiskIncident] = useState("") |
||||
|
||||
const handleCheckboxChange = (item) => { |
||||
const updatedDataIncidentReport = dataIncidentReport.map(dataItem => { |
||||
if (dataItem.label === item.label) { |
||||
return { ...dataItem, checked: !dataItem.checked }; |
||||
} |
||||
return dataItem; |
||||
}); |
||||
setDataIncidentReport(updatedDataIncidentReport); |
||||
const hasCritical = updatedDataIncidentReport.some(item => item.level === 'Critical' && item.checked); |
||||
setTypeRiskIncident(updatedDataIncidentReport.some(item => item.checked) ? (hasCritical ? 'Critical' : 'Major') : ''); |
||||
}; |
||||
|
||||
|
||||
const isItemSelected = (label) => { |
||||
return dataIncidentReport.some(item => item.label === label && item.checked); |
||||
}; |
||||
|
||||
return ( |
||||
<> |
||||
<Card style={{ backgroundColor: colors.semiRed, paddingVertical: 15, paddingHorizontal: 15, marginHorizontal: 8, marginVertical: 5, borderRadius: 5 }}> |
||||
<View> |
||||
<Text variant="bodySmall" style={{ color: colors.beanRed, fontWeight: 'bold', fontSize: 16 }}> |
||||
Jenis kejadian |
||||
</Text> |
||||
<Text variant="bodySmall" style={{ color: colors.beanRed, fontSize: 12 }}> |
||||
Kejadian apa saja yang terjadi di lokasi, bisa pilih lebih dari satu |
||||
</Text> |
||||
</View> |
||||
</Card> |
||||
<View style={styles.container}> |
||||
<Text variant="bodySmall" style={{ color: colors.black, fontSize: 16 }}> |
||||
Pilih Jenis Kejadian |
||||
</Text> |
||||
<ScrollView style={styles.listData}> |
||||
<View> |
||||
{dataIncidentReport.map(item => ( |
||||
<> |
||||
<Chip |
||||
icon={() => ( |
||||
<Icon name={isItemSelected(item.label) ? 'circle-slice-8' : 'circle-outline'} size={20} color={isItemSelected(item.label) ? colors.pureWhite : colors.blue} /> |
||||
)} textStyle={{ color: isItemSelected(item.label) ? colors.pureWhite : colors.blue }} onPress={() => handleCheckboxChange(item)} style={{ backgroundColor: isItemSelected(item.label) ? colors.beanRed : colors.semiBlue, marginBottom: 5 }}>{item.label}</Chip > |
||||
</> |
||||
))} |
||||
</View> |
||||
</ScrollView > |
||||
</View > |
||||
</> |
||||
) |
||||
} |
||||
|
||||
const styles = StyleSheet.create({ |
||||
container: { |
||||
flex: 1, |
||||
marginVertical: 10, |
||||
marginHorizontal: 10 |
||||
}, |
||||
listData: { |
||||
flex: 1, |
||||
marginTop: 10, |
||||
}, |
||||
}); |
@ -0,0 +1,187 @@
|
||||
import React, { useEffect, useCallback, useMemo, useState, useRef } from 'react'; |
||||
import { TextInput, Card, Checkbox, Text, TouchableRipple } from 'react-native-paper'; |
||||
import { StyleSheet, View, ScrollView } from 'react-native'; |
||||
import { colors } from '../../../utils/color' |
||||
import { useNavigation } from '@react-navigation/native'; |
||||
|
||||
export default function LocationScreen() { |
||||
const navigation = useNavigation(); |
||||
const [selectedProject, setSelectedProject] = useState(null); |
||||
const [area, setArea] = useState({ external: false, internal: false }) |
||||
const handleProjectPress = () => { |
||||
navigation.navigate('SearchPage', { dummyData, onSelect: handleProjectSelect }); |
||||
}; |
||||
|
||||
const handleCheckboxArea = (data) => { |
||||
const { name } = data; |
||||
setArea(prevState => ({ |
||||
...prevState, |
||||
[name]: !prevState[name] |
||||
})); |
||||
setBottomSheetIndex(0); |
||||
}; |
||||
console.log("Area :", area); |
||||
const handleProjectSelect = (project) => { |
||||
setSelectedProject(project); |
||||
}; |
||||
|
||||
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' } |
||||
]; |
||||
|
||||
return ( |
||||
<> |
||||
<Card style={{ backgroundColor: colors.semiRed, paddingVertical: 15, paddingHorizontal: 15, marginHorizontal: 8, marginVertical: 5, borderRadius: 5 }}> |
||||
<View> |
||||
<Text variant="bodySmall" style={{ color: colors.beanRed, fontWeight: 'bold', fontSize: 16 }}> |
||||
Lokasi kejadian |
||||
</Text> |
||||
<Text variant="bodySmall" style={{ color: colors.beanRed, fontSize: 12 }}> |
||||
Harap memasukan lokasi kejadian yang sesuai |
||||
</Text> |
||||
</View> |
||||
</Card> |
||||
<ScrollView> |
||||
<View style={styles.container}> |
||||
<Text variant="bodySmall" style={{ color: colors.black, fontSize: 16, marginBottom: 6 }}> |
||||
Lokasi Kejadian |
||||
</Text> |
||||
<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> |
||||
|
||||
<TextInput |
||||
style={{ marginTop: 10 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='Lokasi Kejadian' |
||||
placeholder='Lokasi Kejadian' |
||||
/> |
||||
|
||||
<TextInput |
||||
style={{ marginTop: 10 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='Sub Lokasi Kejadian' |
||||
placeholder='Sub Lokasi Kejadian' |
||||
|
||||
/> |
||||
<View style={styles.row}> |
||||
<Checkbox |
||||
status={area.internal ? 'checked' : 'unchecked'} |
||||
color={colors.blue} |
||||
uncheckedColor={colors.amethystSmoke} |
||||
onPress={() => handleCheckboxArea({ name: 'internal', checked: !area.internal })} |
||||
/> |
||||
<Text variant="bodySmall" style={{ color: colors.black, fontSize: 14, marginBottom: 6, marginTop: 10 }}> |
||||
Internal (Didalam area/kawasan/parimeter Project) |
||||
</Text> |
||||
</View> |
||||
<View style={styles.row}> |
||||
<Checkbox |
||||
status={area.external ? 'checked' : 'unchecked'} |
||||
color={colors.blue} |
||||
uncheckedColor={colors.amethystSmoke} |
||||
onPress={() => handleCheckboxArea({ name: 'external', checked: !area.external })} |
||||
/> |
||||
<Text variant="bodySmall" style={{ color: colors.black, fontSize: 14, marginBottom: 6, marginTop: 10 }}> |
||||
External (Diluar area/kawasan/parimeter Project) |
||||
</Text> |
||||
</View> |
||||
|
||||
<Text variant="bodySmall" style={{ color: colors.black, fontSize: 16, marginBottom: 6, marginTop: 10 }}> |
||||
Lokasi Pelaporan |
||||
</Text> |
||||
<TouchableRipple onPress={handleProjectPress}> |
||||
<TextInput |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='Pilih Proyek' |
||||
placeholder='Pilih Proyek' |
||||
|
||||
/> |
||||
</TouchableRipple> |
||||
|
||||
<TextInput |
||||
style={{ marginTop: 10 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='Lokasi Laporan' |
||||
placeholder='Lokasi Laporan' |
||||
|
||||
|
||||
/> |
||||
|
||||
<TextInput |
||||
style={{ marginTop: 10 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='Sub Lokasi Laporan' |
||||
placeholder='Sub Lokasi Laporan' |
||||
/> |
||||
</View> |
||||
</ScrollView> |
||||
</> |
||||
) |
||||
} |
||||
|
||||
const styles = StyleSheet.create({ |
||||
container: { |
||||
flex: 1, |
||||
marginVertical: 10, |
||||
marginHorizontal: 10 |
||||
}, |
||||
row: { |
||||
flexDirection: 'row', |
||||
alignItems: 'center', |
||||
marginBottom: 5, |
||||
marginRight: 15, |
||||
marginLeft: 5 |
||||
}, |
||||
}); |
@ -0,0 +1,288 @@
|
||||
import React, { useRef, useCallback, useState, useMemo } from 'react'; |
||||
import { launchCamera, launchImageLibrary } from 'react-native-image-picker'; |
||||
import { |
||||
BottomSheetModal, |
||||
BottomSheetModalProvider, |
||||
BottomSheetView |
||||
} from '@gorhom/bottom-sheet'; |
||||
import ImageMarker, { Position, TextBackgroundType } from 'react-native-image-marker'; |
||||
import { TextInput, IconButton, Button } from 'react-native-paper'; |
||||
import { StyleSheet, View, ScrollView, PermissionsAndroid, Image } from 'react-native'; |
||||
import { colors } from '../../../utils/color'; |
||||
import { strings } from '../../../utils/i18n'; |
||||
import { requestAccessStoragePermission } from '../../../utils/storage'; |
||||
import { getCoords } from '../../../utils/geolocation'; |
||||
|
||||
export default function MediaScreen() { |
||||
const [images, setImages] = useState([]); |
||||
|
||||
const bottomSheetModal = useRef(null); |
||||
|
||||
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 handleOpenSheet = useCallback(() => { |
||||
bottomSheetModal.current?.present(); |
||||
}, []); |
||||
|
||||
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}/presensi/${imageObject.drop_point_id}_${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 handleLaunchGallery = () => { |
||||
let options = { |
||||
mediaType: 'photo', |
||||
includeBase64: true |
||||
}; |
||||
|
||||
launchImageLibrary(options, (response) => { |
||||
if (response.didCancel) { |
||||
} else if (response.error) { |
||||
} else if (response.customButton) { |
||||
} else { |
||||
handleSetImageUri(response.assets[0].uri); |
||||
} |
||||
}); |
||||
bottomSheetModal.current?.dismiss(); |
||||
} |
||||
|
||||
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="contain" |
||||
/> |
||||
<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 ( |
||||
<> |
||||
<Button |
||||
icon="plus" |
||||
style={styles.addButton} |
||||
mode="contained-tonal" |
||||
onPress={handleOpenSheet} |
||||
textColor={colors.blue} |
||||
> |
||||
Tambah Gambar |
||||
</Button> |
||||
|
||||
<ScrollView> |
||||
<View style={styles.container}> |
||||
{renderImages} |
||||
</View> |
||||
</ScrollView> |
||||
<BottomSheetModalProvider> |
||||
<BottomSheetModal |
||||
ref={bottomSheetModal} |
||||
index={0} |
||||
snapPoints={['30%']} |
||||
bottomInset={10} |
||||
detached={true} |
||||
style={styles.bottomSheet} |
||||
> |
||||
<BottomSheetView> |
||||
<View style={styles.sheetButtonContainer}> |
||||
<IconButton |
||||
icon="camera" |
||||
size={50} |
||||
onPress={handleTakePicture} |
||||
/> |
||||
<IconButton |
||||
icon="image" |
||||
size={50} |
||||
onPress={handleLaunchGallery} |
||||
/> |
||||
</View> |
||||
</BottomSheetView> |
||||
</BottomSheetModal> |
||||
</BottomSheetModalProvider> |
||||
</> |
||||
) |
||||
} |
||||
|
||||
const styles = StyleSheet.create({ |
||||
container: { |
||||
flex: 1, |
||||
marginVertical: 10, |
||||
marginHorizontal: 10, |
||||
}, |
||||
imageBlock: { |
||||
marginBottom: 20, |
||||
flexDirection: 'row', |
||||
}, |
||||
imageContainer: { |
||||
flexDirection: 'column', |
||||
alignItems: 'center', |
||||
marginHorizontal: 5 |
||||
}, |
||||
image: { |
||||
width: 100, |
||||
height: 100, |
||||
borderRadius: 7 |
||||
}, |
||||
descriptionInput: { |
||||
flex: 1, |
||||
marginRight: 10, |
||||
}, |
||||
addButton: { |
||||
marginHorizontal: 8, |
||||
marginVertical: 10, |
||||
borderRadius: 10, |
||||
backgroundColor: colors.semiBlue, |
||||
}, |
||||
bottomSheet: { |
||||
marginHorizontal: 15, |
||||
}, |
||||
sheetButtonContainer: { |
||||
flexDirection: 'row', |
||||
justifyContent: 'space-around', |
||||
padding: 10, |
||||
paddingBottom: 20, |
||||
}, |
||||
}); |
@ -0,0 +1,103 @@
|
||||
import React, { useState } from 'react'; |
||||
import { TouchableRipple, TextInput, Card, Text } from 'react-native-paper'; |
||||
import { View, StyleSheet, ScrollView } from 'react-native'; |
||||
import DateTimePicker from '@react-native-community/datetimepicker'; |
||||
import moment from 'moment'; |
||||
import { colors } from '../../../utils/color'; |
||||
|
||||
export default function ReportScreen() { |
||||
|
||||
return ( |
||||
<> |
||||
<Card style={{ backgroundColor: colors.semiRed, paddingVertical: 15, paddingHorizontal: 15, marginHorizontal: 8, marginVertical: 5, borderRadius: 5 }}> |
||||
<View> |
||||
<Text variant="bodySmall" style={{ color: colors.beanRed, fontWeight: 'bold', fontSize: 16 }}> |
||||
Pelapor dan penerima laporan |
||||
</Text> |
||||
<Text variant="bodySmall" style={{ color: colors.beanRed, fontSize: 12 }}> |
||||
Siapa yang membuat laporan dan siapa yang membuat laporan |
||||
</Text> |
||||
</View> |
||||
</Card> |
||||
<ScrollView> |
||||
<View style={styles.container}> |
||||
<Text variant="bodySmall" style={{ color: colors.black, fontSize: 16, marginBottom: 6 }}> |
||||
Pelapor |
||||
</Text> |
||||
<TextInput |
||||
style={{ marginTop: 10 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label=" Nama Pelapor" |
||||
placeholder='Nama' |
||||
|
||||
/> |
||||
|
||||
<TextInput |
||||
style={{ marginTop: 10 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='Posisi/Jabatan' |
||||
placeholder='Posisi/Jabatan' |
||||
|
||||
/> |
||||
|
||||
<TextInput |
||||
style={{ marginTop: 10 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='No Contact' |
||||
placeholder='No Contact' |
||||
/> |
||||
|
||||
<Text variant="bodySmall" style={{ color: colors.black, fontSize: 16, marginBottom: 6, marginTop: 10 }}> |
||||
Penerima Laporan |
||||
</Text> |
||||
|
||||
<TextInput |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='Nama' |
||||
placeholder='Nama' |
||||
/> |
||||
|
||||
<TextInput |
||||
style={{ marginTop: 10 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='Posisi/Jabatan' |
||||
placeholder='Posisi/Jabatan' |
||||
/> |
||||
|
||||
<TextInput |
||||
style={{ marginTop: 10 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label='No Contact' |
||||
placeholder='No Contact' |
||||
/> |
||||
</View> |
||||
</ScrollView> |
||||
</> |
||||
) |
||||
} |
||||
|
||||
const styles = StyleSheet.create({ |
||||
container: { |
||||
flex: 1, |
||||
marginVertical: 10, |
||||
marginHorizontal: 10 |
||||
}, |
||||
}); |
@ -0,0 +1,168 @@
|
||||
import React, { useState } from 'react'; |
||||
import { TouchableRipple, TextInput, Card, Text } from 'react-native-paper'; |
||||
import { View, StyleSheet } from 'react-native'; |
||||
import DateTimePicker from '@react-native-community/datetimepicker'; |
||||
import moment from 'moment'; |
||||
import { colors } from '../../../utils/color'; |
||||
|
||||
export default function TimeScreen() { |
||||
const [incidentDate, setIncidentDate] = useState(''); |
||||
const [incidentTime, setIncidentTime] = useState(''); |
||||
const [reportDate, setReportDate] = useState(''); |
||||
const [reportTime, setReportTime] = useState(''); |
||||
const [showIncidentDatePicker, setShowIncidentDatePicker] = useState(false); |
||||
const [showIncidentTimePicker, setShowIncidentTimePicker] = useState(false); |
||||
const [showReportDatePicker, setShowReportDatePicker] = useState(false); |
||||
const [showReportTimePicker, setShowReportTimePicker] = useState(false); |
||||
|
||||
const handleIncidentDateChange = (event, selectedDate) => { |
||||
const currentDate = selectedDate; |
||||
setShowIncidentDatePicker(false); |
||||
setIncidentDate(currentDate); |
||||
}; |
||||
|
||||
const handleIncidentTimeChange = (event, selectedDate) => { |
||||
const currentDate = selectedDate; |
||||
setShowIncidentTimePicker(false); |
||||
setIncidentTime(currentDate); |
||||
}; |
||||
|
||||
const handleReportDateChange = (event, selectedDate) => { |
||||
const currentDate = selectedDate; |
||||
setShowReportDatePicker(false); |
||||
setReportDate(currentDate); |
||||
}; |
||||
|
||||
const handleReportTimeChange = (event, selectedDate) => { |
||||
const currentDate = selectedDate; |
||||
setShowReportTimePicker(false); |
||||
setReportTime(currentDate); |
||||
}; |
||||
|
||||
const showIncidentDatePickerFunc = () => { |
||||
setShowIncidentDatePicker(true); |
||||
}; |
||||
|
||||
const showIncidentTimePickerFunc = () => { |
||||
setShowIncidentTimePicker(true); |
||||
}; |
||||
|
||||
const showReportDatePickerFunc = () => { |
||||
setShowReportDatePicker(true); |
||||
}; |
||||
|
||||
const showReportTimePickerFunc = () => { |
||||
setShowReportTimePicker(true); |
||||
}; |
||||
|
||||
return ( |
||||
<> |
||||
|
||||
<Card style={{ backgroundColor: colors.semiRed, paddingVertical: 15, paddingHorizontal: 15, marginHorizontal: 8, marginVertical: 5, borderRadius: 5 }}> |
||||
<View> |
||||
<Text variant="bodySmall" style={{ color: colors.beanRed, fontWeight: 'bold', fontSize: 16 }}> |
||||
Laporan Awal Insiden |
||||
</Text> |
||||
<Text variant="bodySmall" style={{ color: colors.beanRed, fontSize: 12 }}> |
||||
Wajib melaporkan maksimal 1x3 jam setelah kejadian |
||||
</Text> |
||||
</View> |
||||
</Card> |
||||
<View style={[styles.container, { backgroundColor: 'pureWhite' }]}> |
||||
<TouchableRipple onPress={showIncidentDatePickerFunc}> |
||||
<TextInput |
||||
style={{ marginBottom: 15 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label=" Tanggal Kejadian" |
||||
value={incidentDate ? moment(incidentDate).format("DD-MM-YYYY") : ''} |
||||
editable={false} |
||||
right={<TextInput.Icon icon="calendar" onPress={showIncidentDatePickerFunc} />} |
||||
/> |
||||
</TouchableRipple> |
||||
<TouchableRipple onPress={showIncidentTimePickerFunc}> |
||||
<TextInput |
||||
style={{ marginBottom: 15 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label="Waktu Kejadian" |
||||
value={incidentTime ? moment(incidentTime).format("HH:m") : ''} |
||||
editable={false} |
||||
right={<TextInput.Icon icon="clock-time-eight-outline" onPress={showIncidentTimePickerFunc} />} |
||||
/> |
||||
</TouchableRipple> |
||||
|
||||
<TouchableRipple onPress={showReportDatePickerFunc}> |
||||
<TextInput |
||||
style={{ marginBottom: 15 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label="Tanggal Laporan" |
||||
value={reportDate ? moment(reportDate).format("DD-MM-YYYY") : ''} |
||||
editable={false} |
||||
right={<TextInput.Icon icon="calendar" onPress={showReportDatePickerFunc} />} |
||||
/> |
||||
</TouchableRipple> |
||||
<TouchableRipple onPress={showReportTimePickerFunc}> |
||||
<TextInput |
||||
style={{ marginBottom: 15 }} |
||||
dense={true} |
||||
outlineColor={colors.amethystSmoke} |
||||
activeOutlineColor={colors.blue} |
||||
mode="outlined" |
||||
label=" Waktu Laporan" |
||||
value={reportTime ? moment(reportTime).format("HH:m") : ''} |
||||
editable={false} |
||||
right={<TextInput.Icon icon="clock-time-eight-outline" onPress={showReportTimePickerFunc} />} |
||||
/> |
||||
</TouchableRipple> |
||||
</View> |
||||
{showIncidentDatePicker && ( |
||||
<DateTimePicker |
||||
value={incidentDate || new Date()} |
||||
mode="date" |
||||
display="default" |
||||
onChange={handleIncidentDateChange} |
||||
/> |
||||
)} |
||||
{showIncidentTimePicker && ( |
||||
<DateTimePicker |
||||
value={incidentTime || new Date()} |
||||
mode="time" |
||||
display="default" |
||||
onChange={handleIncidentTimeChange} |
||||
/> |
||||
)} |
||||
{showReportDatePicker && ( |
||||
<DateTimePicker |
||||
value={reportDate || new Date()} |
||||
mode="date" |
||||
display="default" |
||||
onChange={handleReportDateChange} |
||||
/> |
||||
)} |
||||
{showReportTimePicker && ( |
||||
<DateTimePicker |
||||
value={reportTime || new Date()} |
||||
mode="time" |
||||
display="default" |
||||
onChange={handleReportTimeChange} |
||||
/> |
||||
)} |
||||
</> |
||||
) |
||||
} |
||||
|
||||
const styles = StyleSheet.create({ |
||||
container: { |
||||
flex: 1, |
||||
marginVertical: 10, |
||||
marginHorizontal: 10 |
||||
}, |
||||
}); |
Loading…
Reference in new issue