Skip to content

Commit

Permalink
Save & share interview prep summary
Browse files Browse the repository at this point in the history
  • Loading branch information
cheng-tan committed Sep 28, 2020
1 parent 8933508 commit 1daf346
Show file tree
Hide file tree
Showing 13 changed files with 449 additions and 38 deletions.
154 changes: 154 additions & 0 deletions InterviewPrep/Complete.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import React, {Component} from 'react';
import {
StyleSheet,
Text,
View,
Image,
ScrollView,
TouchableOpacity,
Platform,
} from 'react-native';
import colors from 'assets/colors';
import {strings} from 'locales/i18n';
import SummaryList from './SummaryList';
import Share from 'react-native-share';
import RealmObj from 'realm/realm';
import * as RNFS from 'react-native-fs';

const Buffer = require('buffer').Buffer;

class Complete extends Component {
async export() {
let real = await RealmObj.init();

const locations = real.objects('Location');
const locationCSV = locations.map(location => {
let locationObj = JSON.parse(JSON.stringify(location));
return Object.values(locationObj).map(val => {
return val;
}).join('\t');
}).join('\r\n');

const symptoms = real.objects('Symptoms');
const symptomsCSV = symptoms.map(symptom => {
let symptomsObj = JSON.parse(JSON.stringify(symptom));
return Object.values(symptomsObj).map(val => {
return val;
}).join('\t');
}).join('\r\n');

let locationPath;
let symptomsPath;

try {
let locationURL;
let symptomsURL;
if (Platform.OS === 'android') {
let encodedLocation = new Buffer(JSON.stringify(locationCSV)).toString('base64');
let encodedSymptoms = new Buffer(JSON.stringify(symptomsCSV)).toString('base64');

locationURL = 'data:text/csv;base64,' + encodedLocation;
symptomsURL = 'data:text/csv;base64,' + encodedSymptoms;
} else {
locationPath = RNFS.DocumentDirectoryPath + '/location.csv';
symptomsPath = RNFS.DocumentDirectoryPath + '/symptoms.csv';
try {
await RNFS.unlink(locationPath);
await RNFS.unlink(symptomsPath);
} catch (e) {
// unlink fails if the file doesn't exist, which is fine
}

await RNFS.writeFile(locationPath, locationCSV, 'utf8');
await RNFS.writeFile(symptomsPath, symptomsCSV, 'utf8');
locationURL = 'file://' + locationPath;
symptomsURL = 'file://' + symptomsPath;
}
console.log('dump created successfully');

let res = await Share.open({
urls: [locationURL, symptomsURL],
filename: 'common-circle-dump',
message: strings('export.message'),
failOnCancel: false,
});
console.log('sharing ok:' + JSON.stringify(res));
} catch (e) {
console.log('sharing failed due to: ' + JSON.stringify(e));
}

//delete the file regardless of what happened
if (Platform.OS !== 'android') {
try {
console.log('removing file');
await RNFS.unlink(locationPath);
await RNFS.unlink(symptomsPath);
} catch (e) {
// unlink fails if the file doesn't exist, which is fine
}
}
}

render() {
return (
<ScrollView>
<Image
style={styles.hero}
source={require('assets/health/interview_prep_bg.png')}
/>
<View style={styles.container}>
<Text style={styles.title}>
{strings('interview_prep_complete.title')}
</Text>
<Text style={styles.description}>
{strings('interview_prep_complete.description')}
</Text>
<TouchableOpacity style={styles.send_button} onPress={this.export}>
<Text style={styles.send_button_text}>
{strings('interview_prep_complete.send_btn')}
</Text>
</TouchableOpacity>
</View>
<SummaryList />
</ScrollView>
);
}
}

const styles = StyleSheet.create({
hero: {
width: '100%',
height: 104,
},
container: {
paddingVertical: 20,
paddingHorizontal: 18,
},
title: {
fontSize: 20,
lineHeight: 26,
paddingBottom: 5,
},
description: {
fontSize: 14,
lineHeight: 18,
color: colors.body_copy,
marginBottom: 12,
},
send_button: {
borderRadius: 8,
backgroundColor: colors.primary_theme,
paddingVertical: 15,
alignItems: 'center',
marginBottom: 15,
},
send_button_text: {
fontWeight: '500',
fontSize: 15,
lineHeight: 20,
letterSpacing: -0.24,
color: 'white',
},
});

export default Complete;
161 changes: 148 additions & 13 deletions InterviewPrep/Container.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
StyleSheet,
Text,
TouchableOpacity,
KeyboardAvoidingView,
} from 'react-native';
import colors from 'assets/colors';
import Symptoms from './Symptoms';
Expand All @@ -17,31 +18,112 @@ import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import {updatePageIndex} from './actions.js';
import {strings} from 'locales/i18n';
import Popup from 'views/Popup';
import Input from 'views/Input';
import {addSummary} from 'realm/realmInterviewSummaryTasks';
import DateConverter from 'utils/date';

class InterviewPrepContainer extends Component {
constructor() {
super();
this.state = {
index: 0,
savePopupOn: false,
enableContinue: false,
confirmText: '',
};
}

handleCallback = (field, _, val) => {
if (val.toLowerCase() === 'i confirm') {
this.setState({
enableContinue: true,
});
} else {
this.setState({
enableContinue: false,
});
}
};

render() {
const {pageIndex} = this.props.prepData;

const {enableContinue, index} = this.state;
return (
<ScrollView>
<StepIndicatorContainer index={this.state.index} />
<Popup
visible={this.state.savePopupOn}
handleModalClose={this.handleModalClose}>
<KeyboardAvoidingView
style={styles.save_form_container}
behavior={'padding'}>
<Text style={styles.title}>
{strings('interview_prep_save_consent_form.title')}
</Text>
<Text style={styles.description}>
{strings('interview_prep_save_consent_form.description')}
</Text>
<Text style={styles.confirm_label}>
{strings('interview_prep_save_consent_form.confirm_label')}
</Text>
<View style={styles.confirm_box}>
<Input
name={''}
value={this.state.confirmText}
field={'confirm_box'}
handleCallback={this.handleCallback}
customStyle={
this.state.enableContinue
? [styles.confirm_input, styles.active_confirm_input]
: styles.confirm_input
}
/>
</View>
<TouchableOpacity
style={[styles.consent_form_btn, styles.continue_btn]}
disabled={!enableContinue}
onPress={() => {
addSummary(DateConverter.getUTCUnixTime());
this.setState({savePopupOn: false}, () => {
this.props.updatePageIndex({
field: 'pageIndex',
value: pageIndex + 1,
});
});
}}>
<Text
style={
enableContinue
? [styles.consent_form_btn_text, styles.active]
: [styles.consent_form_btn_text, styles.disabled]
}>
{strings('interview_prep_save_consent_form.continue_btn')}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.consent_form_btn}
onPress={() => {
this.setState({
savePopupOn: false,
});
}}>
<Text style={styles.consent_form_btn_text}>
{strings('interview_prep_save_consent_form.no_thanks_btn')}
</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
</Popup>
{index <= 3 && <StepIndicatorContainer index={index} />}
{
{
0: <Symptoms />,
1: <Locations />,
2: <People />,
3: <Summary />,
}[this.state.index]
}[index]
}
<View style={styles.button_group}>
{this.state.index < 3 && (
{index < 3 && (
<TouchableOpacity
style={styles.button}
onPress={() => {
Expand All @@ -52,27 +134,27 @@ class InterviewPrepContainer extends Component {
<Text style={styles.button_text}>{strings('next.btn_text')}</Text>
</TouchableOpacity>
)}
{this.state.index === 3 && (
{index === 3 && (
<TouchableOpacity
style={styles.button}
onPress={() => {
this.props.handleModalClose();
this.setState({savePopupOn: true});
}}>
<Text style={styles.button_text}>{strings('save.text')}</Text>
</TouchableOpacity>
)}
<TouchableOpacity
style={[styles.button, styles.previous]}
onPress={() => {
if (this.state.index > 0) {
this.setState({
index: this.state.index - 1,
});
} else {
if (index === 0) {
this.props.updatePageIndex({
field: 'pageIndex',
value: pageIndex - 1,
});
} else if (index > 0 && index <= 3) {
this.setState({
index: index - 1,
});
}
}}>
<Text style={[styles.button_text, styles.previous_text]}>
Expand All @@ -99,8 +181,10 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
title: {
paddingLeft: 20,
fontSize: 24,
paddingHorizontal: 24,
paddingVertical: 20,
fontSize: 20,
lineHeight: 28,
color: colors.section_title,
fontWeight: '500',
},
Expand Down Expand Up @@ -128,6 +212,57 @@ const styles = StyleSheet.create({
previous_text: {
color: colors.section_title,
},
save_form_container: {
backgroundColor: 'white',
borderRadius: 8,
},
description: {
fontSize: 16,
lineHeight: 22,
paddingHorizontal: 24,
},
confirm_label: {
fontSize: 16,
fontWeight: '400',
lineHeight: 24,
paddingTop: 20,
paddingHorizontal: 24,
},
confirm_box: {
marginHorizontal: 24,
paddingTop: 13,
paddingBottom: 30,
},
consent_form_btn: {
paddingVertical: 19,
alignItems: 'center',
},
consent_form_btn_text: {
fontWeight: '500',
fontSize: 14,
lineHeight: 16,
letterSpacing: 0.5,
textTransform: 'capitalize',
},
continue_btn: {
borderBottomWidth: 1,
borderBottomColor: colors.card_border,
borderTopWidth: 1,
borderTopColor: colors.card_border,
},
confirm_input: {
backgroundColor: colors.fill_off,
borderBottomColor: colors.gray_icon,
},
active_confirm_input: {
borderBottomColor: colors.primary_theme,
},
active: {
color: colors.primary_theme,
},
disabled: {
color: '#ACACAC',
},
});

InterviewPrepContainer.propTypes = {
Expand Down
Loading

0 comments on commit 1daf346

Please sign in to comment.