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