Untitled
unknown
plain_text
5 months ago
28 kB
1
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