1import { StackScreenProps } from '@react-navigation/stack';
2import * as Calendar from 'expo-calendar';
3import React from 'react';
4import { Alert, Button, ScrollView, StyleSheet, Text, View } from 'react-native';
5
6interface RowProps {
7  reminder: Calendar.Reminder;
8  getReminder: (reminder: Calendar.Reminder) => void;
9  updateReminder: (reminder: Calendar.Reminder) => void;
10  deleteReminder: (remidnerId: string) => void;
11}
12
13const ReminderRow: React.FunctionComponent<RowProps> = ({
14  reminder,
15  getReminder,
16  updateReminder,
17  deleteReminder,
18}) => (
19  <View style={styles.reminderRow}>
20    <Text style={styles.reminderName}>{reminder.title}</Text>
21    <Text style={styles.reminderData}>{JSON.stringify(reminder)}</Text>
22    <Button onPress={() => getReminder(reminder)} title="Get Reminder Using ID" />
23    <Button onPress={() => updateReminder(reminder)} title="Update Reminder" />
24    <Button onPress={() => deleteReminder(reminder.id!)} title="Delete Reminder" />
25  </View>
26);
27
28interface State {
29  reminders: Calendar.Reminder[];
30}
31
32type Links = {
33  Reminders: { calendar: Calendar.Calendar };
34};
35
36type Props = StackScreenProps<Links, 'Reminders'>;
37
38export default class RemindersScreen extends React.Component<Props, State> {
39  static navigationOptions = {
40    title: 'Reminders',
41  };
42
43  readonly state: State = {
44    reminders: [],
45  };
46
47  componentDidMount() {
48    const { params } = this.props.route;
49    if (params) {
50      this._findReminders(params.calendar.id!);
51    }
52  }
53
54  _findReminders = async (id: string) => {
55    const reminders = await Calendar.getRemindersAsync([id], null, new Date(), new Date());
56    this.setState({ reminders });
57  };
58
59  _addReminder = async () => {
60    const { calendar } = this.props.route.params!;
61    if (!calendar.allowsModifications) {
62      Alert.alert('This calendar does not allow modifications');
63      return;
64    }
65    const timeInOneHour = new Date();
66    timeInOneHour.setHours(timeInOneHour.getHours() + 1);
67    const newReminder = {
68      title: 'do something cool w/ expo',
69      location: '420 Florence St',
70      startDate: new Date(),
71      dueDate: timeInOneHour,
72      notes: 'where do these notes show up',
73    };
74    try {
75      await Calendar.createReminderAsync(calendar.id!, newReminder);
76      Alert.alert('Reminder saved successfully');
77      this._findReminders(calendar.id!);
78    } catch (e) {
79      Alert.alert('Reminder not saved successfully', e.message);
80    }
81  };
82
83  _getReminder = async (reminder: Calendar.Reminder) => {
84    try {
85      const newReminder = await Calendar.getReminderAsync(reminder.id!);
86      Alert.alert('Reminder found using getReminderAsync', JSON.stringify(newReminder));
87    } catch (e) {
88      Alert.alert('Error finding reminder', e.message);
89    }
90  };
91
92  _updateReminder = async (reminder: Calendar.Reminder) => {
93    const { calendar } = this.props.route.params!;
94    if (!calendar.allowsModifications) {
95      Alert.alert('This calendar does not allow modifications');
96      return;
97    }
98    const newReminder = {
99      title: 'updated reminder',
100      startDate: new Date(),
101    };
102    try {
103      await Calendar.updateReminderAsync(reminder.id!, newReminder);
104      Alert.alert('Reminder saved successfully');
105      this._findReminders(calendar.id!);
106    } catch (e) {
107      Alert.alert('Reminder not saved successfully', e.message);
108    }
109  };
110
111  _deleteReminder = async (reminderId: string) => {
112    try {
113      const { calendar } = this.props.route.params!;
114      await Calendar.deleteReminderAsync(reminderId);
115      Alert.alert('Reminder deleted successfully');
116      this._findReminders(calendar.id!);
117    } catch (e) {
118      Alert.alert('Reminder not deleted successfully', e.message);
119    }
120  };
121
122  render() {
123    if (this.state.reminders.length) {
124      return (
125        <ScrollView style={styles.container}>
126          <Button onPress={this._addReminder} title="Add New Reminder" />
127          {this.state.reminders.map((reminder) => (
128            <ReminderRow
129              reminder={reminder}
130              key={reminder.id}
131              getReminder={this._getReminder}
132              updateReminder={this._updateReminder}
133              deleteReminder={this._deleteReminder}
134            />
135          ))}
136        </ScrollView>
137      );
138    }
139
140    return (
141      <View style={{ padding: 10 }}>
142        <Text>This calendar has no reminders.</Text>
143        <Button onPress={this._addReminder} title="Add New Reminder" />
144      </View>
145    );
146  }
147}
148
149const styles = StyleSheet.create({
150  container: {
151    paddingHorizontal: 10,
152    paddingVertical: 16,
153    flex: 1,
154  },
155  reminderRow: {
156    marginBottom: 12,
157  },
158  reminderName: {
159    fontWeight: 'bold',
160    marginBottom: 4,
161  },
162  reminderData: {},
163});
164