├── README.md
├── __tests__
└── App.js
├── app.json
├── demo.gif
├── index.js
├── package.json
└── src
├── Components
├── DateBarItem.js
├── EditModal.js
└── TodoItem.js
├── helper
├── Array.js
├── Date.js
└── Language.js
└── screens
├── Add.js
└── Home.js
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-todo
2 | Very lightweight and smooth design todo app with react-native
3 |
4 |
5 | ## How to install ?
6 | ``` bash
7 | # Install necessary packages
8 | yarn install
9 |
10 | # Create android&ios folder
11 | react-native eject
12 |
13 | # Update native files
14 | react-native link
15 |
16 | # Run app on emulator
17 | react-native run-android
18 | react-native run-ios
19 | ```
20 |
21 | ## Demo
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/__tests__/App.js:
--------------------------------------------------------------------------------
1 | import 'react-native';
2 | import React from 'react';
3 | import App from '../App';
4 |
5 | // Note: test renderer must be required after react-native.
6 | import renderer from 'react-test-renderer';
7 |
8 | it('renders correctly', () => {
9 | const tree = renderer.create(
10 |
11 | );
12 | });
13 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Todo",
3 | "displayName": "Todo"
4 | }
--------------------------------------------------------------------------------
/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/irfansener/react-native-todo/5370bd3e87afc88fbdb206942d597ae4288bcf73/demo.gif
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry } from 'react-native';
2 | import App from './src/screens/Home';
3 |
4 | AppRegistry.registerComponent('Todo', () => App);
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Todo",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "node node_modules/react-native/local-cli/cli.js start",
7 | "test": "jest"
8 | },
9 | "dependencies": {
10 | "native-base": "^2.3.9",
11 | "react": "16.2.0",
12 | "react-native": "0.53.0",
13 | "react-native-modal": "^5.0.1",
14 | "react-native-modal-datetime-picker": "^4.13.0"
15 | },
16 | "devDependencies": {
17 | "babel-jest": "22.2.2",
18 | "babel-preset-react-native": "4.0.0",
19 | "jest": "22.2.2",
20 | "react-test-renderer": "16.2.0"
21 | },
22 | "jest": {
23 | "preset": "react-native"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Components/DateBarItem.js:
--------------------------------------------------------------------------------
1 | //import liraries
2 | import React, { Component } from 'react';
3 | import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
4 | import DateHelper from '../helper/Date';
5 |
6 | // create a component
7 | class DateBarItem extends Component {
8 | constructor(props) {
9 | super(props);
10 | this.state = {
11 | now: props.now.getUTCDate(),
12 | date: props.date.item.date,
13 | }
14 | }
15 | componentWillReceiveProps(props) {
16 | this.setState({ now: props.now.getUTCDate() });
17 | }
18 | isSelect() {
19 | if (this.state.now == this.state.date.getUTCDate()) {
20 | const style = { color: 'black' };
21 | return style;
22 | }
23 | }
24 | setDate() {
25 | this.props.setDate(this.state.date)
26 | }
27 | render() {
28 | return (
29 | this.setDate()}>
30 |
34 | {this.state.date.getDate()}
35 | {DateHelper.getDayName(this.state.date, false)}
36 |
37 |
38 | );
39 | }
40 | }
41 |
42 | // define your styles
43 | const styles = StyleSheet.create({
44 | perDay: {
45 | width: 42,
46 | display: 'flex',
47 | flexDirection: 'column',
48 | },
49 | daySmInt: {
50 | color: '#C75F46',
51 | fontSize: 18,
52 | textAlign: 'center'
53 | },
54 | daySmString: {
55 | color: '#C75F46',
56 | fontSize: 14,
57 | textAlign: 'center'
58 | },
59 | });
60 |
61 | //make this component available to the app
62 | export default DateBarItem;
63 |
--------------------------------------------------------------------------------
/src/Components/EditModal.js:
--------------------------------------------------------------------------------
1 | //import liraries
2 | import React, { Component } from 'react';
3 | import { View, Text, StyleSheet, Button, TextInput, TouchableOpacity, AsyncStorage, Alert } from 'react-native';
4 | import DateTimePicker from 'react-native-modal-datetime-picker';
5 | import DateHelper from '../helper/Date';
6 | import ArrayHelper from '../helper/Array';
7 | import _ from '../helper/Language';
8 |
9 | // create a component
10 | class EditModal extends Component {
11 | constructor(props) {
12 | super(props);
13 | this.state = {
14 | id: props.id,
15 | name: '',
16 | location: '',
17 | time: '',
18 | date: '',
19 | datePickerVisible: false,
20 | timePickerVisible: false,
21 | }
22 | }
23 | componentWillMount() {
24 | AsyncStorage.getItem('list').then(data => {
25 | let array = JSON.parse(data);
26 | const index = ArrayHelper.find(array, this.state.id);
27 | const { name, location, time, date } = array[index];
28 | this.setState({ name, location, time, date });
29 | })
30 | }
31 | addNewTodo() {
32 | if (this.state.name.length < 1) {
33 | Alert.alert(_('nameRequired'));
34 | }
35 | else {
36 | const { name, location, time, date } = this.state;
37 | AsyncStorage.getItem('list').then(data => {
38 | let newArray = JSON.parse(data);
39 | const index = ArrayHelper.find(newArray, this.state.id);
40 | newArray[index].name = name;
41 | newArray[index].location = location;
42 | newArray[index].time = time;
43 | newArray[index].date = date;
44 | const upData = JSON.stringify(newArray);
45 | AsyncStorage.setItem('list', upData);
46 | this.props.updateData();
47 | this.props.closeModal();
48 | })
49 | }
50 | }
51 | onClosePicker() {
52 | this.setState({ datePickerVisible: false, timePickerVisible: false })
53 | }
54 | render() {
55 | return (
56 |
57 |
58 | {_('editTask')}
59 | this.setState({ name })}
62 | value={this.state.name}
63 | placeholder={_('taskName')}
64 | returnKeyType="next"
65 | selectTextOnFocus={true}
66 | onSubmitEditing={() => this.location.focus()}
67 | />
68 | this.setState({ location })}
71 | value={this.state.location}
72 | placeholder={_('location')}
73 | returnKeyType="next"
74 | onSubmitEditing={() => this.setState({ datePickerVisible: true })}
75 | ref={(input) => this.location = input}
76 | />
77 |
78 | this.setState({ datePickerVisible: true })}>
79 |
80 | {this.state.date}
81 |
82 |
83 | this.setState({ timePickerVisible: true })}>
84 |
85 | {this.state.time ? this.state.time : _('hour')}
86 |
87 |
88 |
89 | this.addNewTodo()}>
90 | {_('edit')}
91 |
92 | this.setState({ date: DateHelper.getDate(date) })}
95 | onCancel={() => this.onClosePicker()}
96 | mode="date"
97 | />
98 | this.setState({ time: DateHelper.getTime(time) })}
101 | onCancel={() => this.onClosePicker()}
102 | mode="time"
103 | />
104 |
105 |
106 | );
107 | }
108 | }
109 |
110 | // define your styles
111 | const styles = StyleSheet.create({
112 | modalContainer: {
113 | flex: 1,
114 | justifyContent: 'center',
115 | alignItems: 'center',
116 | borderRadius: 10,
117 | },
118 | innerContainer: {
119 | backgroundColor: "white",
120 | height: 300,
121 | width: '90%',
122 | borderRadius: 10,
123 | padding: 20
124 | },
125 | h1: {
126 | color: 'black',
127 | fontSize: 18,
128 | marginTop: 10,
129 | marginBottom: 10,
130 | marginLeft: 10
131 | },
132 | input: {
133 | borderBottomColor: 'gray',
134 | color: 'black',
135 | fontWeight: '800',
136 | fontSize: 18
137 | },
138 | addButton: {
139 | backgroundColor: '#ee7659',
140 | color: 'white',
141 | fontWeight: '600',
142 | textAlign: 'center',
143 | lineHeight: 45,
144 | fontSize: 18,
145 | width: '90%',
146 | marginTop: 20,
147 | marginLeft: '5%',
148 | borderRadius: 25
149 | },
150 | dateTime: {
151 | flexDirection: 'row',
152 | justifyContent: 'space-around'
153 | },
154 | dateTimeInput: {
155 | width: 90,
156 | height: 40,
157 | fontWeight: '500',
158 | textAlign: 'center',
159 | textAlignVertical: 'center',
160 | borderBottomColor: 'black',
161 | borderBottomWidth: 1
162 | }
163 | });
164 |
165 | //make this component available to the app
166 | export default EditModal;
167 |
--------------------------------------------------------------------------------
/src/Components/TodoItem.js:
--------------------------------------------------------------------------------
1 | //import liraries
2 | import React, { Component } from 'react';
3 | import { View, Text, StyleSheet, TouchableOpacity, Dimensions, Alert } from 'react-native';
4 | import { SwipeRow, Button, Icon } from 'native-base';
5 | import DateHelper from '../helper/Date';
6 | import _ from '../helper/Language';
7 |
8 | const { width, height } = Dimensions.get('window');
9 | class TodoItem extends Component {
10 | constructor(props) {
11 | super(props);
12 | this.state = {
13 | stateText: _('loading'),
14 | stateColor: 'black',
15 | borderBottomColor: 'grey',
16 | }
17 | }
18 | componentWillReceiveProps() {
19 | // State 0 bekliyor, 1 tamamlandi, 2 iptal edildi
20 | if (this.props.item.state === 0) {
21 | this.setState({ stateText: ' ', stateColor: '#202824', borderBottomColor: '#EAEAEA' });
22 | }
23 | if (this.props.item.state === 1) {
24 | this.setState({ stateText: _('done'), stateColor: '#7ED221', borderBottomColor: '#7ED221' });
25 | }
26 | if (this.props.item.state === 2) {
27 | this.setState({ stateText: _('cancel'), stateColor: '#DE0A0A', borderBottomColor: '#DE0A0A' });
28 | }
29 | }
30 | componentWillMount() {
31 | // State 0 bekliyor, 1 tamamlandi, 2 iptal edildi
32 | if (this.props.item.state === 0) {
33 | this.setState({ stateText: ' ', stateColor: '#202824', borderBottomColor: '#EAEAEA' });
34 | }
35 | if (this.props.item.state === 1) {
36 | this.setState({ stateText: _('done'), stateColor: '#7ED221', borderBottomColor: '#7ED221' });
37 | }
38 | if (this.props.item.state === 2) {
39 | this.setState({ stateText: _('cancel'), stateColor: '#DE0A0A', borderBottomColor: '#DE0A0A' });
40 | }
41 | }
42 | render() {
43 | return (
44 |
45 | this.props.changeState(this.props.item.id)} >
50 |
51 | {DateHelper.getMonthName(this.props.item.date)} {this.props.item.time}
52 |
53 | {this.props.item.name}
54 | {this.props.item.location ? {this.props.item.location} : null}
55 |
56 |
57 |
58 | {this.state.stateText}
59 |
60 | •
61 |
62 |
63 |
64 |
65 | }
66 | right={
67 |
70 | }
71 | left={
72 |
75 | }
76 | />
77 |
78 | );
79 | }
80 | }
81 |
82 | // define your styles
83 | const styles = StyleSheet.create({
84 | perList: {
85 | display: 'flex',
86 | flexDirection: 'column',
87 | },
88 | listTop: {
89 | flexDirection: 'row',
90 | marginLeft: 15,
91 | },
92 | date: {
93 | fontWeight: '400',
94 | width: width / 4
95 | },
96 | time: {
97 | fontWeight: '400',
98 | maxWidth: width / 5
99 | },
100 | locationAndName: {
101 | flexDirection: 'column'
102 | },
103 | text: {
104 | fontWeight: '400',
105 | width: width / 2
106 | },
107 | locationText: {
108 | fontWeight: '400',
109 | fontSize: 12,
110 | width: width / 2,
111 | height: 16
112 | },
113 | listBottom: {
114 | flexDirection: 'row',
115 | marginLeft: 15,
116 | marginTop: 10
117 | },
118 | state: {
119 | width: width / 4
120 | },
121 | lineRow: {
122 | marginTop: -15,
123 | width: width
124 | },
125 | dot: {
126 | fontSize: 38
127 | },
128 | line: {
129 | borderBottomColor: 'black',
130 | borderBottomWidth: 1,
131 | marginLeft: 10,
132 | marginTop: calc(),
133 | }
134 | });
135 | function calc() {
136 | const hep = Dimensions.get('screen').height;
137 | if (hep < 533) {
138 | return -35 - ((500 - hep) / 50)
139 | } else {
140 | return -35 + ((hep - 500) / 50)
141 | }
142 | }
143 |
144 | //make this component available to the app
145 | export default TodoItem;
146 |
--------------------------------------------------------------------------------
/src/helper/Array.js:
--------------------------------------------------------------------------------
1 | class ArrayHelper {
2 | find(array, element) {
3 | let index = "";
4 | array.forEach((data, num) => {
5 | if (data.id === element)
6 | index = num;
7 | });
8 | if (index !== -1)
9 | return index;
10 | }
11 | search(array, element) {
12 | let index = "";
13 | array.forEach((data, num) => {
14 | data.forEach((inside) => {
15 | if (inside === element)
16 | index = num;
17 | })
18 | });
19 | const returnValue = typeof index === "number" ? true : false;
20 | return returnValue;
21 | }
22 | delete(array, element) {
23 | let index = "";
24 | array.forEach((data, num) => {
25 | if (data.id === element)
26 | index = num;
27 | });
28 | if (index !== -1)
29 | return array.splice(index, 1);
30 | }
31 | sortDate(array, element) {
32 | let index = "";
33 | let newArray= Array();
34 | array.forEach((data, num) => {
35 | if (data.date === element)
36 | newArray.push(array[num]);
37 | });
38 | return newArray;
39 | }
40 |
41 | }
42 |
43 | const exporDefault = new ArrayHelper();
44 | export default exporDefault;
45 |
--------------------------------------------------------------------------------
/src/helper/Date.js:
--------------------------------------------------------------------------------
1 | import _ from './Language';
2 | class DateHelper {
3 | getDate(date) {
4 | let dd = date.getDate();
5 | let mm = date.getMonth() + 1; //January is 0!
6 |
7 | const yyyy = date.getFullYear();
8 | const value = dd + '/' + mm + '/' + yyyy;
9 | return value;
10 | }
11 | getTime(date) {
12 | let hh = date.getHours();
13 | let ii = date.getMinutes();
14 | if (ii < 10) {
15 | ii = '0' + ii;
16 | }
17 | const value = hh + ':' + ii;
18 | return value;
19 | }
20 | getMonthName(date) {
21 | let data = date.split('/');
22 | const day = data[0];
23 | const month = Number(data[1]);
24 | let monthName;
25 | switch (month) {
26 | case 1:
27 | monthName = _('january');
28 | break;
29 | case 2:
30 | monthName = _('february');
31 | break;
32 | case 3:
33 | monthName = _('march');
34 | break;
35 | case 4:
36 | monthName = _('april');
37 | break;
38 | case 5:
39 | monthName = _('may');
40 | break;
41 | case 6:
42 | monthName = _('june');
43 | break;
44 | case 7:
45 | monthName = _('july');
46 | break;
47 | case 8:
48 | monthName = _('august');
49 | break;
50 | case 9:
51 | monthName = _('september');
52 | break;
53 | case 10:
54 | monthName = _('october');
55 | break;
56 | case 11:
57 | monthName = _('november');
58 | break;
59 | case 12:
60 | monthName = _('december');
61 | }
62 | return `${day} ${monthName}`;
63 | }
64 | getDayName(date, fullName = true) {
65 | let day;
66 | if (fullName) {
67 | switch (date.getDay()) {
68 | case 0:
69 | day = _('sunday');
70 | break;
71 | case 1:
72 | day = _('monday');
73 | break;
74 | case 2:
75 | day = _('tuesday');
76 | break;
77 | case 3:
78 | day = _('wednesday');
79 | break;
80 | case 4:
81 | day = _('thursday');
82 | break;
83 | case 5:
84 | day = _('friday');
85 | break;
86 | case 6:
87 | day = _('saturday');
88 | }
89 | } else {
90 | switch (date.getDay()) {
91 | case 0:
92 | day = _('sun');
93 | break;
94 | case 1:
95 | day = _('mon');
96 | break;
97 | case 2:
98 | day = _('tue');
99 | break;
100 | case 3:
101 | day = _('wed');
102 | break;
103 | case 4:
104 | day = _('thu');
105 | break;
106 | case 5:
107 | day = _('fri');
108 | break;
109 | case 6:
110 | day = _('sat');
111 | }
112 | }
113 | return day;
114 | }
115 | }
116 |
117 | const date = new DateHelper();
118 | export default date;
--------------------------------------------------------------------------------
/src/helper/Language.js:
--------------------------------------------------------------------------------
1 | import { NativeModules } from "react-native";
2 | let langRegionLocale = "en_US";
3 | langRegionLocale = NativeModules.I18nManager.localeIdentifier || "";
4 | let langCode = langRegionLocale.substring(0, 2); // get first two characters
5 |
6 | function Language(value) {
7 | const lang = {
8 | en: {
9 | tooWork: 'A lot of work to do today.',
10 | letsDone: "Lets do it.",
11 | noWork: "Relax or have fun.",
12 | toDo: 'To Do',
13 | daysNoWork: ' there is no work you need to do ',
14 | addNewTask: 'Add New Task',
15 | editTask: 'Edit task',
16 | nameRequired: 'Task name can not be empty !',
17 | taskName: "Task Name",
18 | location: "Location",
19 | hour: 'Hour',
20 | add: 'Add',
21 | edit: 'Edit',
22 | loading: 'Loading',
23 | done: 'Done',
24 | cancel: 'Cancel',
25 | january: 'January',
26 | february: 'February',
27 | march: 'March',
28 | april: 'April',
29 | may: 'May',
30 | june: 'June',
31 | july: 'July',
32 | august: 'August',
33 | september: 'September',
34 | october: 'October',
35 | november: 'November',
36 | december: 'December',
37 | sunday: 'Sunday',
38 | monday: 'Monday',
39 | tuesday: 'Tuesday',
40 | wednesday: 'Wednesday',
41 | thursday: 'Thursday',
42 | friday: 'Friday',
43 | saturday: 'Saturday',
44 | sun: 'Sun',
45 | mon: 'Mon',
46 | tue: 'Tue',
47 | wed: 'Web',
48 | thu: 'Thu',
49 | fri: 'Fri',
50 | sat: 'Sat'
51 | },
52 | tr: {
53 | tooWork: 'Bugün yapılacak çok iş var.',
54 | letsDone: "Hadi bitirelim şu işi.",
55 | noWork: "Rahatla,dinlen ya da eğlen.",
56 | toDo: 'Yapılacaklar',
57 | daysNoWork: 'günü yapmanız gereken hiçbir şey yok.',
58 | addNewTask: 'Yeni Görev Ekle',
59 | editTask: 'Görevi Düzenle',
60 | nameRequired: 'Görev adı boş bırakılamaz !',
61 | taskName: "Görev Adı",
62 | location: "Mekan",
63 | hour: 'Saat',
64 | add: 'Ekle',
65 | edit: 'Düzenle',
66 | loading: 'Bekliyor',
67 | done: 'Tamamlandı',
68 | cancel: 'İptal edildi',
69 | january: 'Ocak',
70 | february: 'Şubat',
71 | march: 'Mart',
72 | april: 'Nisan',
73 | may: 'Mayıs',
74 | june: 'Haziran',
75 | july: 'Temmuz',
76 | august: 'Ağustos',
77 | september: 'Eylül',
78 | october: 'Ekim',
79 | november: 'Kasım',
80 | december: 'Aralık',
81 | sunday: 'Pazar',
82 | monday: 'Pazartesi',
83 | tuesday: 'Salı',
84 | wednesday: 'Çarşamba',
85 | thursday: 'Perşembe',
86 | friday: 'Cuma',
87 | saturday: 'Cumartesi',
88 | sun: 'Paz',
89 | mon: 'Pzt',
90 | tue: 'sal',
91 | wed: 'Çar',
92 | thu: 'Sal',
93 | fri: 'Cum',
94 | sat: 'Cmt'
95 | }
96 | }
97 | const isAvailableLang = langCode === 'tr' || langCode === 'en';
98 | const returnValue = isAvailableLang ? eval(`lang.${langCode}.${value}`) : eval(`lang.en.${value}`);
99 | return returnValue;
100 | }
101 |
102 | export default Language;
--------------------------------------------------------------------------------
/src/screens/Add.js:
--------------------------------------------------------------------------------
1 | //import liraries
2 | import React, { Component } from 'react';
3 | import { View, Text, StyleSheet, Button, TextInput, TouchableOpacity, AsyncStorage, Alert } from 'react-native';
4 | import DateTimePicker from 'react-native-modal-datetime-picker';
5 | import DateHelper from '../helper/Date';
6 | import _ from '../helper/Language';
7 |
8 | // create a component
9 | class Add extends Component {
10 | constructor(props) {
11 | super(props);
12 | this.state = {
13 | name: '',
14 | location: '',
15 | time: '',
16 | date: DateHelper.getDate(new Date()),
17 | datePickerVisible: false,
18 | timePickerVisible: false,
19 | }
20 | }
21 | addNewTodo() {
22 | if (this.state.name.length < 1) {
23 | Alert.alert(_('nameRequired'));
24 | }
25 | else {
26 | const timeStamp = Math.floor(Date.now());
27 | const id = Number(timeStamp);
28 | const state = 0;
29 | const { name, location, time, date } = this.state;
30 | AsyncStorage.getItem('list').then(data => {
31 | let newArray = Array();
32 | if (data !== null) {
33 | newArray = JSON.parse(data);
34 | }
35 | newArray.push({ id, name, location, time, date, state });
36 | const upData = JSON.stringify(newArray);
37 | AsyncStorage.setItem('list', upData);
38 | this.props.closeModal();
39 | })
40 | }
41 | }
42 | onClosePicker() {
43 | this.setState({ datePickerVisible: false, timePickerVisible: false })
44 | }
45 | render() {
46 | return (
47 |
48 |
49 | {_('addNewTask')}
50 | this.setState({ name })}
53 | placeholder={_('taskName')}
54 | returnKeyType="next"
55 | selectTextOnFocus={true}
56 | onSubmitEditing={() => this.location.focus()}
57 | />
58 | this.setState({ location })}
61 | placeholder={_('location')}
62 | returnKeyType="next"
63 | onSubmitEditing={() => this.setState({ datePickerVisible: true })}
64 | ref={(input) => this.location = input}
65 | />
66 |
67 | this.setState({ datePickerVisible: true })}>
68 |
69 | {this.state.date}
70 |
71 |
72 | this.setState({ timePickerVisible: true })}>
73 |
74 | {this.state.time ? this.state.time : _('hour')}
75 |
76 |
77 |
78 | this.addNewTodo()}>
79 | {_('add')}
80 |
81 | this.setState({ date: DateHelper.getDate(date) })}
84 | onCancel={() => this.onClosePicker()}
85 | mode="date"
86 | />
87 | this.setState({ time: DateHelper.getTime(time) })}
90 | onCancel={() => this.onClosePicker()}
91 | mode="time"
92 | />
93 |
94 |
95 | );
96 | }
97 | }
98 |
99 | // define your styles
100 | const styles = StyleSheet.create({
101 | modalContainer: {
102 | flex: 1,
103 | justifyContent: 'center',
104 | alignItems: 'center',
105 | borderRadius: 10,
106 | },
107 | innerContainer: {
108 | backgroundColor: "white",
109 | height: 300,
110 | width: '90%',
111 | borderRadius: 10,
112 | padding: 20
113 | },
114 | h1: {
115 | color: 'black',
116 | fontSize: 18,
117 | marginTop: 10,
118 | marginBottom: 10,
119 | marginLeft: 10
120 | },
121 | input: {
122 | borderBottomColor: 'gray',
123 | color: 'black',
124 | fontWeight: '800',
125 | fontSize: 18
126 | },
127 | addButton: {
128 | backgroundColor: '#ee7659',
129 | color: 'white',
130 | fontWeight: '600',
131 | textAlign: 'center',
132 | lineHeight: 45,
133 | fontSize: 18,
134 | width: '90%',
135 | marginTop: 20,
136 | marginLeft: '5%',
137 | borderRadius: 25
138 | },
139 | dateTime: {
140 | flexDirection: 'row',
141 | justifyContent: 'space-around'
142 | },
143 | dateTimeInput: {
144 | width: 90,
145 | height: 40,
146 | fontWeight: '500',
147 | textAlign: 'center',
148 | textAlignVertical: 'center',
149 | borderBottomColor: 'black',
150 | borderBottomWidth: 1
151 | }
152 | });
153 |
154 | //make this component available to the app
155 | export default Add;
156 |
--------------------------------------------------------------------------------
/src/screens/Home.js:
--------------------------------------------------------------------------------
1 | //import liraries
2 | import React, { Component } from 'react';
3 | import { View, Text, StyleSheet, TouchableOpacity, StatusBar, AsyncStorage, FlatList, ScrollView, Touc, TouchableNativeFeedback, ActivityIndicator } from 'react-native';
4 | import Add from './Add';
5 | import TodoItem from '../Components/TodoItem';
6 | import Helper from '../helper/Array';
7 | import DateHelper from '../helper/Date';
8 | import Modal from 'react-native-modal';
9 | import EditModal from '../Components/EditModal';
10 | import DateBarItem from '../Components/DateBarItem';
11 | import _ from '../helper/Language';
12 |
13 | // create a component
14 | class Home extends Component {
15 | constructor(props) {
16 | super(props);
17 | this.state = {
18 | addModalVis: false,
19 | editModalVis: false,
20 | editId: null,
21 | data: [],
22 | date: new Date(),
23 | loading: true
24 | }
25 | }
26 | componentDidMount() {
27 | this.updateData(true);
28 | this.returnCalendar();
29 | }
30 | openModal() {
31 | this.setState({ addModalVis: true });
32 | }
33 | closeModal() {
34 | this.setState({ addModalVis: false });
35 | this.updateData();
36 | }
37 | updateData(first = false) {
38 | AsyncStorage.getItem('list').then(snapshot => {
39 | if (snapshot === null) {
40 | this.setState({loading:false})
41 | return;
42 | }
43 | const data = JSON.parse(snapshot);
44 | const nowDate = DateHelper.getDate(this.state.date);
45 | const val = Helper.sortDate(data, nowDate);
46 | this.setState({ data: val, loading: false })
47 | if (first) {
48 | setTimeout(() => {
49 | const x = this.state.date.getUTCDate() * 30;
50 | this.scroll.scrollTo({ x, y: 1, animated: false });
51 | }, 500)
52 | }
53 | })
54 | }
55 | deleteTodo(id) {
56 | Helper.delete(this.state.data, id);
57 | const newData = JSON.stringify(this.state.data);
58 | AsyncStorage.setItem('list', newData);
59 | this.updateData();
60 | }
61 | changeState(id) {
62 | const { data } = this.state;
63 | const index = Helper.find(data, id);
64 | const oldState = Number(data[index].state);
65 | let newState;
66 | switch (oldState) {
67 | case 0:
68 | newState = 1;
69 | break;
70 | case 1:
71 | newState = 2;
72 | break;
73 | case 2:
74 | newState = 0;
75 | break;
76 | }
77 | data[index].state = newState;
78 | const asynPushData = JSON.stringify(data);
79 | AsyncStorage.setItem('list', asynPushData);
80 | this.updateData();
81 | }
82 | editTodo(id) {
83 | this.setState({ editId: id, editModalVis: true })
84 | }
85 | returnCalendar() {
86 | let array = Array();
87 | const now = new Date();
88 | const year = now.getFullYear();
89 | const month = now.getMonth();
90 | const lastDay = new Date(year, month + 1, 0).getUTCDate();
91 | for (let i = 0; i < lastDay; i++) {
92 | var tomorrow = new Date(year, month, 1);
93 | tomorrow.setDate(tomorrow.getDate() + i);
94 | array.push({ date: tomorrow });
95 | }
96 | this.setState({ array })
97 | }
98 | changeDate(date) {
99 | this.setState({ date })
100 | const index = date.getUTCDate();
101 | let x = index * 12;
102 | if (index > 7)
103 | x = index * 25;
104 | if (index > 13)
105 | x = index * 30
106 | if (index > 18)
107 | x = index * 35
108 | this.scroll.scrollTo({ x, y: 1, animated: true });
109 | this.updateData()
110 | }
111 | goHome() {
112 | this.setState({ date: new Date() })
113 | this.updateData()
114 | }
115 | render() {
116 | return (
117 |
118 |
122 |
123 |
124 | this.goHome()}>
125 | {this.state.date.getDate()}
126 |
127 |
128 | {DateHelper.getMonthName(DateHelper.getDate(this.state.date)).split(' ')[1]}
129 | {DateHelper.getDayName(this.state.date)} 2017
130 |
131 | this.openModal()}>
132 | +
133 |
134 |
135 |
136 | {this.state.data.length > 1 ? _('tooWork') : this.state.data.length === 1 ? _('letsDone') : _('noWork')}
137 |
138 | this.scroll = ref} >
139 | this.changeDate(date)} />}
143 | keyExtractor={(item, index) => index.toString()}
144 | horizontal={true}
145 | />
146 |
147 |
148 | {this.state.loading ? :
149 |
150 | {this.state.data.length > 0 ? {_('toDo')} :
151 | {this.state.date.getDate()} {DateHelper.getMonthName(DateHelper.getDate(this.state.date)).split(' ')[1]} {_('daysNoWork')}
152 | }
153 | this.editTodo(id)} deleteTodo={(id) => this.deleteTodo(id)} changeState={(id) => this.changeState(id)} />}
156 | keyExtractor={(item, index) => item.id.toString()}
157 | />
158 | }
159 | this.setState({ addModalVis: false })}
166 | onBackdropPress={() => this.setState({ addModalVis: false })}
167 | onSwipe={() => this.setState({ addModalVis: false })}
168 | swipeDirection="down"
169 | >
170 | this.closeModal()} visible={this.state.addModalVis} />
171 |
172 | this.setState({ editModalVis: false })}
179 | onBackdropPress={() => this.setState({ editModalVis: false })}
180 | onSwipe={() => this.setState({ editModalVis: false })}
181 | swipeDirection="down"
182 | >
183 | this.updateData()} closeModal={() => this.setState({ editModalVis: false })} visible={this.state.editModalVis} id={this.state.editId} />
184 |
185 |
186 | );
187 | }
188 | }
189 |
190 | // define your styles
191 | const styles = StyleSheet.create({
192 | container: {
193 | flex: 1,
194 | backgroundColor: '#ee7659',
195 | },
196 | top: {
197 | display: 'flex',
198 | flexDirection: 'column',
199 | marginTop: 10,
200 | marginLeft: 30,
201 | elevation: 2,
202 | },
203 | currentDate: {
204 | display: 'flex',
205 | flexDirection: 'row',
206 | justifyContent: 'space-around'
207 | },
208 | dayNumber: {
209 | fontFamily: 'Effra',
210 | fontSize: 52,
211 | fontWeight: '400',
212 | color: 'white',
213 | flexGrow: 1
214 | },
215 | month: {
216 | display: 'flex',
217 | flexDirection: 'column',
218 | marginTop: 15,
219 | flexGrow: 8
220 | },
221 | dayString: {
222 | fontFamily: 'Effra',
223 | fontSize: 16,
224 | fontWeight: '400',
225 | color: '#FFFEFE'
226 | },
227 | addItem: {
228 | backgroundColor: 'white',
229 | color: '#f27455',
230 | fontSize: 30,
231 | marginTop: 15,
232 | marginRight: 25,
233 | textAlign: 'center',
234 | width: 48,
235 | height: 48,
236 | borderRadius: 29,
237 | textAlignVertical: 'center',
238 | elevation: 2,
239 | },
240 | lineString: {
241 | color: 'white',
242 | marginTop: 5,
243 | marginBottom: 15,
244 | fontSize: 14
245 | },
246 | calendar: {
247 | flexDirection: 'row',
248 | marginLeft: -10,
249 | marginBottom: 30
250 | },
251 | bottom: {
252 | backgroundColor: 'white',
253 | flex: 1
254 | },
255 | h1: {
256 | fontSize: 24,
257 | marginLeft: 20,
258 | marginTop: 20,
259 | marginBottom: 20,
260 | fontWeight: '600',
261 | color: '#202824'
262 | },
263 | nothing: {
264 | fontSize: 18,
265 | padding: 20,
266 | textAlign: 'center'
267 | }
268 | });
269 |
270 | //make this component available to the app
271 | export default Home;
272 |
--------------------------------------------------------------------------------