Skip to content

Instantly share code, notes, and snippets.

@hashirahmad
Created January 6, 2019 19:49
Show Gist options
  • Save hashirahmad/21a0f02877ac6eec81afe08ba969f9f4 to your computer and use it in GitHub Desktop.
Save hashirahmad/21a0f02877ac6eec81afe08ba969f9f4 to your computer and use it in GitHub Desktop.
I have a feeling this is wrong
import React from 'react'
import { List,
Button,
FAB,
Divider,
TextInput,
Snackbar,
Title,
RadioButton,
Switch,
Portal,
Dialog,
Chip
} from 'react-native-paper';
import {
ScrollView,
View,
FlatList,
StyleSheet,
Alert,
SectionList,
SafeAreaView
} from 'react-native'
const _ = require('lodash')
import * as moment from 'moment';
import db from '../../logic/ConfigDB'
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import TagsLogic from '../../logic/TagsRelated'
import Utils from '../../logic/Utils'
export default class Activity extends React.Component {
constructor() {
super()
this.state = {
activityName: '',
groupId: '',
groupName: '',
isDailyGoal: true,
goalCaption: 'Daily goal',
goalHours: '0',
goalMins: '0',
goalError: false,
setGoals: false,
setTags: false,
showTagsDialog: false,
showEditGroupDialog: false,
snackBarVisible: false,
snackBarMessage: '',
tags: [],
activityBeingSaved: false,
activitySelectedTags: [],
activities: []
}
this.activitySelectedTags = []
this.DB = new db()
this.TagsLogic = new TagsLogic()
}
onChangeText = (key, value) => {
this.setState({
[key]: value
})
}
showGroupNames = ({item}) => (
<List.Item
title={item.key}
onPress={this.showAddActivities}
left={props => <List.Icon {...props} icon="folder" />}
right={props => <List.Icon {...props} icon="keyboard-arrow-right" />}
/>
);
setGoals = () => {
this.setState({
setGoals: !this.state.setGoals,
})
}
componentDidMount = async () => {
try {
if (this.DB.db == null) this.DB.db = await this.DB.open()
this.setTagsInState()
this.setActivitiesInState()
this.setState({
groupId: this.props.navigation.getParam('group').groupId,
groupName: this.props.navigation.getParam('group').groupName,
})
} catch( err ) {
console.log('database failed to open', err)
}
}
setTagsInState = () => {
this.TagsLogic.getTags(this.DB.db).then( result => {
for (i in result.tags) { result.tags[i].selected = false }
this.setState({ tags: result.tags })
}).catch( err => {
this.setState({
snackBarMessage: 'There was an error with retriving of tags',
snackBarVisible: true,
})
})
}
setActivitiesInState = () => {
this.DB.run(this.DB.db, 'Select * from "Activity"').then( result => {
this.setState({ activities: result.rows.raw() })
}).catch( err => {
this.setState({
snackBarMessage: 'There was an error with retriving of activities',
snackBarVisible: true,
})
})
}
// Its used for when selecting/unselecting a tag during setting of tags for new activity
selectUnselectTagForActivity = tag => {
let allTags = this.state.tags
let selectedTagIndex = allTags.indexOf(tag)
allTags[selectedTagIndex].selected = !tag.selected
if (tag.selected) this.activitySelectedTags.push(tag)
else this.activitySelectedTags.splice( this.activitySelectedTags.indexOf(tag) )
this.setState({ tags: allTags, activitySelectedTags: this.activitySelectedTags })
}
showTags = ({item}) => (
<Chip style={{marginBottom: 10}}>
{item.key}
</Chip>
);
renderTagsInDialog = () => {
chipTags = []
this.state.tags.map( tag => {
chipTags.push(
<Chip
key={tag.id}
selected={tag.selected}
onPress={() => this.selectUnselectTagForActivity(tag)}
>
{tag.key}
</Chip>
)
})
return (chipTags)
}
editGroupName = () => {
this.DB.run(this.DB.db, 'UPDATE "Group" set groupName = ? where groupId = ?',
[this.state.groupName, this.state.groupId]).then( result => {
this.setState({
snackBarMessage: `Group name successfully updated to "${this.state.groupName}"`,
snackBarVisible: true,
showEditGroupDialog: false
})
}).catch( err => {
this.setState({
snackBarMessage: `Error occurred while updating: ${err}`,
snackBarVisible: true,
showEditGroupDialog: false
})
})
}
saveActivity = () => {
if (Utils.isDuplicateOrEmpty(this.state.activityName, this.state.activities, 'activityName')) {
Alert.alert('Activity name cannot be left empty or be a duplicate')
return
}
this.setState({ activityBeingSaved: true })
let insertSQL = 'INSERT INTO "Activity" (activityName, groupId, goalLength, goalType)'
insertSQL += ' values (?, ?, ?, ?)'
goalLength = moment.duration({ hours: this.state.goalHours, minutes: this.state.goalMins })._milliseconds
this.DB.run(this.DB.db, insertSQL, [
this.state.activityName,
this.state.groupId,
goalLength,
this.state.setGoals ? this.state.isDailyGoal ? 'DAILY' : 'WEEKLY' : 'NA'
]).then( result => {
if (this.state.setTags) {
for (i in this.state.activitySelectedTags) {
let insertSQL = 'INSERT INTO "ActivityTag" (activityId, tagId) values (?,?)'
let tag = this.state.activitySelectedTags[i]
this.DB.run(this.DB.db, insertSQL, [result.insertId, tag.id])
}
}
this.setState({
activityBeingSaved: false,
snackBarMessage: `${this.state.activityName} saved successfully.`,
snackBarVisible: true,
activityName: '',
setGoals: false,
goalMins: '0',
goalHours: '0',
setTags: false,
activitySelectedTags: []
})
}).catch( err => {
this.setState({
activityBeingSaved: false,
snackBarMessage: `Error occured: ${err}`,
snackBarVisible: true
})
})
}
allowValidGoals = (val, maxVal, key) => {
if (val === "") {
this.setState({ [key]: '0' })
} else {
val = parseInt(val)
if (this.state.isDailyGoal) {
maxVal = key === 'goalHours' ? 17 : maxVal
}
if (val > maxVal) {
this.setState({
goalError: true,
[key]: maxVal.toLocaleString(),
})
} else {
this.setState({
goalError: false,
[key]: parseInt(val).toLocaleString()
})
}
}
}
render() {
return (
<View style={{flex: 1, margin: 20}}>
<KeyboardAwareScrollView>
<View style={{flex: 0.95}}>
<TextInput
label='Add activity name'
value={this.state.activityName}
onChangeText={ val => this.onChangeText('activityName', val)}
style={{ flex: 0.85, marginBottom: 10 }}
/>
<View style={styles.rowSpaceBetween}>
<Title>Set goals</Title>
<Switch
value={this.state.setGoals}
onValueChange={() => {
this.setState({
setGoals: !this.state.setGoals,
})
}}
/>
</View>
<View style={{display: this.state.setGoals ? 'flex' : 'none'}}>
<View style={styles.rowSpaceBetween}>
<Title>{this.state.goalCaption}</Title>
<Switch
value={this.state.isDailyGoal}
onValueChange={() => {
this.setState({
isDailyGoal: !this.state.isDailyGoal,
goalCaption: !this.state.isDailyGoal ? 'Daily Goal' : 'Weekly Goal'
})
}}
/>
</View>
<View style={styles.rowSpaceBetween}>
<TextInput
label='Number of hours'
value={this.state.goalHours}
error={this.state.goalError}
keyboardType='number-pad'
onChangeText={ val => this.allowValidGoals(val, 120, 'goalHours')}
style={{ flex: 1 }}
/>
<TextInput
label='Number of mins'
keyboardType='number-pad'
error={this.state.goalError}
value={this.state.goalMins}
onChangeText={ val => this.allowValidGoals(val, 59, 'goalMins')}
style={{ flex: 1 }}
/>
</View>
</View>
<View style={styles.rowSpaceBetween}>
<Title>Tags</Title>
<Switch
value={this.state.setTags}
onValueChange={() => {
if (!this.state.setTags) {
for (i in this.state.tags) this.state.tags[i].selected = false
this.setState({ activitySelectedTags: [] })
this.activitySelectedTags = []
}
this.setState({
showTagsDialog: !this.state.setTags,
setTags: !this.state.setTags,
})
}}
/>
</View>
<View style={{ display: this.state.setTags ? 'flex' : 'none' }}>
<FlatList
renderItem={this.showTags}
data={this.state.activitySelectedTags}
contentContainerStyle={{flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-evenly'}}
/>
</View>
<Button
icon="save"
mode="contained"
loading={this.state.activityBeingSaved}
style={{alignSelf: 'center', width: 90}}
disabled={this.state.activityName === '' ? true : false}
onPress={this.saveActivity}
>
Save
</Button>
<Portal>
<FAB.Group
open={this.state.open}
icon={this.state.open ? 'expand-more' : 'more-horiz'}
actions={[
{ icon: 'delete', label: 'Delete group', onPress: () => console.log('Pressed star')},
{ icon: 'edit', label: 'Edit group', onPress: () => this.setState({ showEditGroupDialog: true }) },
{ icon: 'view-list', label: 'View activies', onPress: () => console.log('Pressed notifications') },
]}
onStateChange={({ open }) => this.setState({ open })}
style={styles.addGroupFab}
onPress={() => {
if (this.state.open) {
}
}}
/>
</Portal>
<Portal>
<Dialog
visible={this.state.showTagsDialog}
onDismiss={() => this.setState({ showTagsDialog: false, setTags: false })}>
<Dialog.Title>Select all applicable tags</Dialog.Title>
<Dialog.Content style={styles.displayTags}>
{ this.renderTagsInDialog() }
</Dialog.Content>
<Dialog.Actions>
<Button onPress={() => this.setState({ showTagsDialog: false })}
>Done
</Button>
</Dialog.Actions>
</Dialog>
</Portal>
<View>
<Portal>
<Dialog
visible={this.state.showEditGroupDialog}
onDismiss={() => this.setState({ showEditGroupDialog: false })}>
<Dialog.Title>Edit group name</Dialog.Title>
<Dialog.Content style={styles.displayTags}>
<TextInput
label='Group name'
value={this.state.groupName}
onChangeText={ val => this.onChangeText('groupName', val)}
style={{ flex: 1 }}
/>
</Dialog.Content>
<Dialog.Actions>
<Button onPress={this.editGroupName}
>Done
</Button>
</Dialog.Actions>
</Dialog>
</Portal>
</View>
</View>
</KeyboardAwareScrollView>
<Snackbar
visible={this.state.snackBarVisible}
style={styles.snackbar}
onDismiss={() => this.setState({ snackBarVisible: false })}
>
{this.state.snackBarMessage}
</Snackbar>
</View>
);
}
}
const styles = StyleSheet.create({
addGroupFab: {
position: 'absolute',
marginBottom: 50,
right: 0,
bottom: 0,
},
rowSpaceBetween: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 10
},
displayTags: {
flexDirection: 'row',
justifyContent: 'space-evenly',
flexWrap: 'wrap'
},
snackbar: {
bottom: 0,
position: 'absolute'
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment