Untitled
unknown
plain_text
a year ago
28 kB
3
Indexable
import { autorun, IReactionDisposer, computed } from 'mobx';
import { inject, observer } from "mobx-react";
import moment, { localeData } from 'moment';
import 'moment/locale/id';
import { Badge, Box, FlatList, Flex, HStack, Modal, Pressable, Spacer, Spinner, Text, Toast, View, Icon, Input, Radio, Checkbox } from 'native-base';
import React from 'react';
import { Dimensions, Image, KeyboardAvoidingView, Platform, RefreshControl, SafeAreaView, ScrollView, StyleSheet, TouchableOpacity } from 'react-native';
import { Picker } from '@react-native-picker/picker';
import { NavigationProp } from '@react-navigation/native';
import assets from '../../../assets/assets';
import VisitStore from '../../../stores/domain/visit.store';
import variable from '../../../theme/variables/platform'
import FA5Icon from 'react-native-vector-icons/FontAwesome5';
import { AdultFallScreeningsViewModel, ChildFallScreeningsViewModel, IcpcViewModel, VisitInitialAssessmentsViewModel } from '../../../models/visit.models';
import { Button } from '../../widgets';
import { conciousnessLevelOptions, PracticeUtil, screeningAdultQuestions, screeningChildQuestions, sickNessLevelOptions, visitInitialAssessmentsQuestions } from '../../../helpers/practice-utils';
import Slider from '@react-native-community/slider';
import { RadioButton } from 'react-native-paper';
moment.locale('id');
export interface Props {
visitStore?: VisitStore;
navigation?: NavigationProp<any, any>;
}
export interface State {
keadaanSakit: number;
kesadaran: number;
skalaNyeri: any;
screeningJatuh: boolean;
screeningAsesmen: boolean;
screeningAnswer1: number | null;
screeningAnswer2: number | null;
screeningAnswer3: number | null;
screeningAnswer4: number | null;
screeningAnswer5: number | null;
screeningAnswer6: number | null;
screeningAsesAnswer1: number | null;
screeningAsesAnswer2: number | null;
screeningAsesAnswer3: number | null;
screeningAsesAnswer4: number | null;
screeningAsesAnswer5: number | null;
screeningAsesAnswer6: number | null;
screeningValue: number | null;
keluhanModal: boolean;
}
@inject('visitStore')
@observer
export default class PemeriksaanAwalComponent extends React.Component<Props, State> {
errorReactionDisposer: IReactionDisposer | null = null;
constructor(props: Readonly<Props>) {
super(props);
this.state = {
keadaanSakit: 0,
kesadaran: 0,
skalaNyeri: null,
screeningJatuh: false,
screeningAsesmen: false,
screeningAnswer1: 0,
screeningAnswer2: 0,
screeningAnswer3: 0,
screeningAnswer4: 0,
screeningAnswer5: 0,
screeningAnswer6: 0,
screeningAsesAnswer1: 0,
screeningAsesAnswer2: 0,
screeningAsesAnswer3: 0,
screeningAsesAnswer4: 0,
screeningAsesAnswer5: 0,
screeningAsesAnswer6: 0,
screeningValue: -1,
keluhanModal: false,
}
}
async componentDidMount() {
if (!this.state.screeningAnswer1 && this.props.visitStore!.screeningAdult != null) { await this.setState({ screeningAnswer1: this.props.visitStore!.screeningAdult?.fall_history }) }
if (!this.state.screeningAnswer2 && this.props.visitStore!.screeningAdult != null) { await this.setState({ screeningAnswer2: this.props.visitStore!.screeningAdult?.secondary_diagnostic }) }
if (!this.state.screeningAnswer3 && this.props.visitStore!.screeningAdult != null) { await this.setState({ screeningAnswer3: this.props.visitStore!.screeningAdult?.walking_aid }) }
if (!this.state.screeningAnswer4 && this.props.visitStore!.screeningAdult != null) { await this.setState({ screeningAnswer4: this.props.visitStore!.screeningAdult?.intravena }) }
if (!this.state.screeningAnswer5 && this.props.visitStore!.screeningAdult != null) { await this.setState({ screeningAnswer5: this.props.visitStore!.screeningAdult?.walking_style }) }
if (!this.state.screeningAnswer6 && this.props.visitStore!.screeningAdult != null) { await this.setState({ screeningAnswer6: this.props.visitStore!.screeningAdult?.mental_status }) }
if (this.props.visitStore!.visitInitialAssessments?.result != 0) { await this.setState({}) }
this.errorReactionDisposer = autorun(() => {
if (this.props.visitStore!.error) {
Toast.show({
title: this.props.visitStore!.error,
duration: 3000,
placement: "top",
});
this.props.visitStore!.setError(null);
}
});
}
componentWillUnmount(): void {
this.props.visitStore!.setKeluhanReason(null)
this.props.visitStore!.setKeluhanReasonData(null)
}
resetChoice(): void {
this.setState({ screeningAnswer1: 0, screeningAnswer2: 0, screeningAnswer3: 0, screeningAnswer4: 0, screeningAnswer5: 0, screeningAnswer6: 0 })
}
async calculateTotalValue(): Promise<void> {
await this.setState({ screeningValue: 0 }, async () => {
if (this.props.visitStore?.visit?.patient_age != null && this.state.screeningValue !== null) {
if (this.props.visitStore?.visit?.patient_age >= 18) {
const result = PracticeUtil.getAdultFallScreenings(this.props.visitStore?.visit?.patient_age, this.props.visitStore!.screeningAdult!, this.state.screeningAnswer1!, this.state.screeningAnswer2!, this.state.screeningAnswer3!, this.state.screeningAnswer4!, this.state.screeningAnswer5!, this.state.screeningAnswer6!);
await this.setState({ screeningValue: result.total_score })
await this.props.visitStore!.setScreeningAdult(result);
} else if (this.props.visitStore?.visit?.patient_age < 18 && this.state.screeningValue !== null) {
const result = PracticeUtil.getChildFallScreenings(this.props.visitStore?.visit?.patient_age, this.props.visitStore!.screeningChild!, this.state.screeningAnswer1!, this.state.screeningAnswer2!, this.state.screeningAnswer3!, this.state.screeningAnswer4!, this.state.screeningAnswer5!, this.state.screeningAnswer6!);
await this.setState({ screeningValue: result.total_score })
await this.props.visitStore!.setScreeningChild(result);
}
}
})
}
async searchList(searchValue: string): Promise<void> {
await this.props.visitStore!.getIcpc(searchValue)
}
renderReason(data: IcpcViewModel, index: number) {
const isLastItem = index === (this.props.visitStore!.keluhanReasonData?.length ?? 0) - 1;
return (
<View>
{(this.props.visitStore!.keluhanReasonData && this.props.visitStore!.keluhanReasonData.length > 0)
? (
<View style={{ width: '100%', borderBottomWidth: isLastItem ? 0 : 1, marginVertical: 8 }}>
<TouchableOpacity
style={{ width: '100%' }}
onPress={() => {
this.props.visitStore!.setComplaint_icpc_id(data.id)
this.props.visitStore!.setKeluhanReason(data.name)
this.props.visitStore!.setComplaint_icpc_name(data.name)
this.setState({ keluhanModal: false })
}}
>
<Text style={{ fontFamily: 'Poppins', fontSize: 14, fontWeight: '400', marginBottom: 8 }}>{data.icpc_code} - {data.name}</Text>
</TouchableOpacity>
</View>
)
: null
}
</View>
)
}
async setAsesmenValue(): Promise<void> {
const result = PracticeUtil.getVisitInitialAssessments(
this.props.visitStore!.visit?.id || 0,
this.props.visitStore!.visitInitialAssessments!,
this.state.screeningAsesAnswer1!,
this.state.screeningAsesAnswer2!,
this.state.screeningAsesAnswer3!,
this.state.screeningAsesAnswer4!,
this.state.screeningAsesAnswer5!,
this.state.screeningAsesAnswer6!,
);
// set visit initial assessments to store
await this.props.visitStore!.setVisitInitialAssessments(result)
}
render() {
let screeningValue: any = -1
if (this.props.visitStore?.visit?.patient_age !== null && this.props.visitStore?.visit?.patient_age !== undefined && this.props.visitStore?.visit?.patient_age >= 18) {
screeningValue = (this.state.screeningValue === -1 && this.props.visitStore!.screeningAdult?.total_score !== 0) ? this.props.visitStore?.screeningAdult?.total_score : this.state.screeningValue;
} else {
screeningValue = (this.state.screeningValue === -1 && this.props.visitStore!.screeningChild?.total_score !== 0) ? this.props.visitStore!.screeningChild?.total_score : this.state.screeningValue;
}
return (
<View style={{ flex: 1, backgroundColor: variable.brandWhite }}>
<ScrollView style={{ flex: 1, backgroundColor: variable.brandWhite, paddingTop: 10 }} showsVerticalScrollIndicator={false}>
<View style={{ flexDirection: 'column', gap: 10 }}>
{/* Keluhan Utama (ICPC) */}
<View style={styles.inputContainer}>
<Text style={styles.inputLabel}>Keluhan Utama (ICPC)</Text>
<Input
onChange={(value) => {
this.props.visitStore!.setKeluhanReason(value.nativeEvent.text)
if (value.nativeEvent.text.length >= 3) {
this.setState({ keluhanModal: true })
this.searchList(value.nativeEvent.text);
} else {
this.setState({ keluhanModal: false })
this.searchList('')
}
}}
value={this.props.visitStore!.keluhanReason ? this.props.visitStore!.keluhanReason.toString() : undefined}
style={{ width: '100%' }} variant={'outline'}
backgroundColor={variable.white}
borderColor={variable.brandNeutral30}
focusOutlineColor={variable.brandNeutral30}
borderBottomRightRadius={(this.state.keluhanModal && (this.props.visitStore!.keluhanReasonData && this.props.visitStore!.keluhanReasonData?.length > 0 || (this.props.visitStore!.keluhanReason?.length || 0) > 0)) ? 0 : 4}
borderBottomLeftRadius={(this.state.keluhanModal && (this.props.visitStore!.keluhanReasonData && this.props.visitStore!.keluhanReasonData?.length > 0 || (this.props.visitStore!.keluhanReason?.length || 0) > 0)) ? 0 : 4}
placeholder='Keluhan Utama'
/>
<View style={styles.selectResultWrapper}>
{this.state.keluhanModal && (
<View style={styles.selectResultContainer}>
{this.props.visitStore!.isLoadingKeluhan ? (
<Spinner color={variable.brandNeutral70} />
) : this.props?.visitStore?.keluhanReasonData?.[0]?.id == null ? (
<Text style={styles.selectResultTextNoData}>Tidak ada Data</Text>
) : (
<FlatList
style={{ flex: 1 }}
data={this.props.visitStore!.keluhanReasonData || undefined}
renderItem={({ item, index }) => this.renderReason(item, index)}
keyExtractor={(item) => item?.id.toString()}
showsVerticalScrollIndicator={false}
nestedScrollEnabled={true}
maxHeight={'xs'}
/>
)}
</View>
)}
</View>
</View>
{/* Asesmen Awal */}
<View style={styles.inputContainer}>
<Text style={styles.inputLabel}>Asesmen Awal</Text>
<View style={styles.inputAssessmentContainer}>
<Button
onPress={() => this.setState({ screeningAsesmen: true })}
variant='outline'
>
Ases
</Button>
<View style={[styles.assessmentStatusContainer, { backgroundColor: PracticeUtil.generateAssessmentResultColor(this.props.visitStore!.visitInitialAssessments?.result) }]}>
<Text style={styles.assessmentStatusText}>{PracticeUtil.generateAssessmentResultText(this.props.visitStore!.visitInitialAssessments?.result)}</Text>
</View>
</View>
</View>
{/* Keadaan Sakit */}
<View style={styles.inputContainer}>
<Text style={styles.inputLabel}>Keadaan Sakit</Text>
<RadioButton.Group
onValueChange={(value) => this.props.visitStore!.setSickness_level_id(parseInt(value))}
value={this.props.visitStore!.sickness_level_id ? this.props.visitStore!.sickness_level_id.toString() : ''}
>
{sickNessLevelOptions.map((item, index) => (
<View key={index} style={{ flexDirection: 'row', alignItems: 'center' }}>
<RadioButton value={item.id.toString()} color='#0059DB' />
<TouchableOpacity onPress={() => this.props.visitStore!.setSickness_level_id(item?.id)}>
<Text>{item.label}</Text>
</TouchableOpacity>
</View>
))}
</RadioButton.Group>
</View>
{/* Kesadaran */}
<View style={styles.inputContainer}>
<Text style={styles.inputLabel}>Kesadaran</Text>
<RadioButton.Group
onValueChange={(value) => this.props.visitStore!.setConciousness_level_id(parseInt(value))}
value={this.props.visitStore!.conciousness_level_id ? this.props.visitStore!.conciousness_level_id?.toString() : ''}
>
{conciousnessLevelOptions.map((item, index) => (
<View key={index} style={{ flexDirection: 'row', alignItems: 'center' }}>
<RadioButton value={item.id.toString()} color='#0059DB' />
<TouchableOpacity onPress={() => this.props.visitStore!.setConciousness_level_id(item?.id)}>
<Text>{item.label}</Text>
</TouchableOpacity>
</View>
))}
</RadioButton.Group>
</View>
{/* Skrining Risiko Jatuh */}
<View style={styles.inputContainer}>
<Text style={styles.inputLabel}>Skrining Risiko Jatuh</Text>
<View style={styles.inputAssessmentContainer}>
<Button
onPress={() => this.setState({ screeningJatuh: true })}
variant='outline'
>
Skrining
</Button>
<View style={[styles.assessmentStatusContainer, { backgroundColor: PracticeUtil.getFallScreeningResultColor(screeningValue, this.props.visitStore?.visit?.patient_age) }]}>
<Text style={styles.assessmentStatusText}>{PracticeUtil.getFallScreeningResultText(screeningValue, this.props.visitStore?.visit?.patient_age)}</Text>
</View>
</View>
</View>
{/* Skala Nyeri */}
<View style={styles.inputContainer}>
<Text style={styles.inputLabel}>Skala Nyeri</Text>
<Checkbox
value='skalaNyeri'
isChecked={this.props.visitStore!.pain_scale === null}
onChange={(value) => {
if (value) {
this.setState({ skalaNyeri: null })
this.props.visitStore!.setPain_scale(null)
} else {
this.setState({ skalaNyeri: 0 })
this.props.visitStore!.setPain_scale(0)
}
}}
colorScheme={'blue'}
ml={2}
>
Tidak Ditanya
</Checkbox>
<Slider
style={styles.sliderPainScale}
minimumValue={0}
maximumValue={10}
step={1}
value={this.props.visitStore!.pain_scale || -1}
onValueChange={(value) => {
this.setState({ skalaNyeri: value })
this.props.visitStore!.setPain_scale(value)
}}
disabled={this.props.visitStore!.pain_scale === null}
minimumTrackTintColor='blue'
thumbTintColor='blue'
/>
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'center' }}>
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((item, index) => (
<Text key={index} style={{ fontFamily: 'Poppins', fontSize: 14, textAlign: 'center', color: variable.brandNeutral70, width: '9.09%' }}>{item}</Text>
))}
</View>
<View style={[styles.assessmentStatusContainer, { backgroundColor: PracticeUtil.getPainScaleColor(this.props.visitStore!.pain_scale), alignSelf: 'flex-end', marginTop: 8 }]}>
<Text style={styles.assessmentStatusText}>{PracticeUtil.getPainScaleText(this.props.visitStore!.pain_scale)}</Text>
</View>
</View>
</View>
<View style={{ height: 80 }}></View>
</ScrollView>
<Modal
isOpen={this.state.screeningJatuh}
onClose={() => this.setState({ screeningJatuh: false })}
size={'lg'}
>
<Modal.Content>
<Modal.CloseButton />
<Modal.Header>
{this.props.visitStore?.visit?.patient_age && this.props.visitStore?.visit?.patient_age >= 18 ? 'Skrining Risiko Jatuh - Skala Morse' : 'Skrining Risiko Jatuh Anak - Skala Jatuh Humpty Dumpty'}
</Modal.Header>
<Modal.Body px={5} py={4} _scrollview={{ showsVerticalScrollIndicator: false }}>
<View style={styles.modalQuestionBodyContainer}>
{this.props.visitStore?.visit?.patient_age && this.props.visitStore?.visit?.patient_age >= 18 ? (
screeningAdultQuestions.map((item, index) => (
<View key={index} style={styles.modalQuestionWrapper}>
<View style={{ flexDirection: 'row' }}>
<Text style={styles.modalQuestionText}>{index + 1}. </Text>
<Text style={styles.modalQuestionText}>{item.question}</Text>
</View>
<RadioButton.Group
onValueChange={(value) => {
const answer = parseInt(value);
this.setState({ [`screeningAnswer${item.id}`]: answer });
}}
value={this.state[`screeningAnswer${item.id}`] !== 0 ? this.state[`screeningAnswer${item.id}`].toString() : this.props.visitStore!.screeningAdult?.[item.name]?.toString()}
>
{item.answers.map((option, index) => (
<View key={index} style={{ flexDirection: 'row', alignItems: 'center' }}>
<RadioButton value={option.id.toString()} color="#0059DB" />
<TouchableOpacity onPress={() => this.setState({ [`screeningAnswer${item.id}`]: option.id })}>
<Text>{option.answer}</Text>
</TouchableOpacity>
</View>
))}
</RadioButton.Group>
</View>
))
) : (
screeningChildQuestions.map((item, index) => (
<View key={index} style={styles.modalQuestionWrapper}>
<View style={{ flexDirection: 'row' }}>
<Text style={styles.modalQuestionText}>{index + 1}. </Text>
<Text style={styles.modalQuestionText}>{item.question}</Text>
</View>
<RadioButton.Group
onValueChange={(value) => {
const answer = parseInt(value);
this.setState({ [`screeningAnswer${item.id}`]: answer });
}}
value={this.state[`screeningAnswer${item.id}`] !== 0 ? this.state[`screeningAnswer${item.id}`].toString() : this.props.visitStore!.screeningChild?.[item.name]?.toString()}
>
{item.answers.map((option, index) => (
<View key={index} style={{ flexDirection: 'row', alignItems: 'center' }}>
<RadioButton value={option.id.toString()} color="#0059DB" />
<TouchableOpacity onPress={() => this.setState({ [`screeningAnswer${item.id}`]: option.id })}>
<Text>{option.answer}</Text>
</TouchableOpacity>
</View>
))}
</RadioButton.Group>
</View>
))
)}
<Button
onPress={() => {
this.setState({ screeningJatuh: false, screeningValue: 0 })
this.calculateTotalValue()
}}
>
Simpan
</Button>
</View>
</Modal.Body>
</Modal.Content>
</Modal>
<Modal
isOpen={this.state.screeningAsesmen}
onClose={() => this.setState({ screeningAsesmen: false })}
size={'lg'}
>
<Modal.Content>
<Modal.CloseButton />
<Modal.Header>Asesmen Awal Pasien</Modal.Header>
<Modal.Body px={5} py={4} _scrollview={{ showsVerticalScrollIndicator: false }}>
{/* <View style={styles.modalQuestionBodyContainer}>
{visitInitialAssessmentsQuestions.map((item, index) => (
<View key={index} style={styles.modalQuestionWrapper}>
<View style={{ flexDirection: 'row' }}>
<Text style={styles.modalQuestionText}>{index + 1}. </Text>
<Text style={styles.modalQuestionText}>{item.question}</Text>
</View>
<Radio.Group
name={item.question}
value={this.state[`screeningAsesAnswer${item.id}`] != 0 ? this.state[`screeningAsesAnswer${item.id}`]?.toString() : this.props.visitStore!.visitInitialAssessments?.[item.name]?.toString()}
colorScheme={'blue'}
space={2}
onChange={(value) => {
switch (item.id) {
case 1:
this.setState({ screeningAsesAnswer1: parseInt(value) });
break
case 2:
this.setState({ screeningAsesAnswer2: parseInt(value) });
break
case 3:
this.setState({ screeningAsesAnswer3: parseInt(value) });
break
case 4:
this.setState({ screeningAsesAnswer4: parseInt(value) });
break
case 5:
this.setState({ screeningAsesAnswer5: parseInt(value) });
break
case 6:
this.setState({ screeningAsesAnswer6: parseInt(value) });
break
default:
break
}
}}
>
{item.answers.map((option, index) => (
<Radio key={index} value={option.id.toString()} size={'sm'}>
{option.answer}
</Radio>
))}
</Radio.Group>
</View>
))}
<Button
onPress={() => {
this.setState({ screeningAsesmen: false })
this.setAsesmenValue()
}}
>
Simpan
</Button>
</View> */}
<View style={styles.modalQuestionBodyContainer}>
{visitInitialAssessmentsQuestions.map((item, index) => (
<View key={index} style={styles.modalQuestionWrapper}>
<View style={{ flexDirection: 'row' }}>
<Text style={styles.modalQuestionText}>{index + 1}. </Text>
<Text style={styles.modalQuestionText}>{item.question}</Text>
</View>
<RadioButton.Group
onValueChange={(value) => {
const answer = parseInt(value);
this.setState({ [`screeningAsesAnswer${item.id}`]: answer });
}}
value={this.state[`screeningAsesAnswer${item.id}`] !== 0 ? this.state[`screeningAsesAnswer${item.id}`].toString() : this.props.visitStore!.visitInitialAssessments?.[item.name]?.toString()}
>
{item.answers.map((option, index) => (
<View key={index} style={{ flexDirection: 'row', alignItems: 'center' }}>
<RadioButton value={option.id.toString()} color="#0059DB" />
<TouchableOpacity onPress={() => this.setState({ [`screeningAsesAnswer${item.id}`]: option.id })}>
<Text>{option.answer}</Text>
</TouchableOpacity>
</View>
))}
</RadioButton.Group>
</View>
))}
<Button
onPress={() => {
this.setState({ screeningAsesmen: false });
this.setAsesmenValue();
}}
>
Simpan
</Button>
</View>
</Modal.Body>
</Modal.Content>
</Modal>
</View>
);
}
}
const styles = StyleSheet.create({
inputContainer: {
position: 'relative',
gap: 4,
marginHorizontal: 16,
},
inputLabel: {
fontFamily: 'Poppins',
fontSize: variable.textSM,
color: variable.brandNeutral70,
},
inputAssessmentContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
width: '100%',
},
selectResultWrapper: {
width: '100%',
position: 'absolute',
backgroundColor: variable.brandNeutral10,
top: 80,
zIndex: 1,
},
selectResultContainer: {
borderWidth: 1,
borderRadius: 4,
paddingHorizontal: 12,
paddingVertical: 8,
borderColor: variable.brandNeutral30,
flex: 1,
minHeight: 42,
},
selectResultTextNoData: {
fontFamily: 'Poppins',
fontSize: 12,
fontWeight: '400',
color: variable.brandNeutral70,
height: 20,
textAlign: 'center',
},
assessmentStatusContainer: {
justifyContent: 'center',
alignItems: 'center',
padding: 10,
},
assessmentStatusText: {
fontFamily: 'Poppins',
fontSize: variable.textSM,
fontWeight: '400',
color: variable.white,
},
modalQuestionBodyContainer: {
gap: 20,
},
modalQuestionWrapper: {
flexDirection: 'column',
gap: 4,
width: '90%',
},
modalQuestionText: {
fontFamily: 'Poppins',
fontSize: variable.textSM,
fontWeight: '700',
},
sliderPainScale: {
flex: 1,
marginLeft: Platform.select({ ios: 15, android: 0 }), // please kindly check on ios
marginRight: Platform.select({ ios: 15, android: 0 }), // please kindly check on ios
},
})Editor is loading...
Leave a Comment