Browse Source

Sprint 3

Ultimos toques del sprint 3
JorgeIan 3 years ago
parent
commit
2569ee7c9d

+ 1
- 1
fast_med_flutter/android/app/build.gradle View File

@@ -39,7 +39,7 @@ android {
39 39
     defaultConfig {
40 40
         // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 41
         applicationId "com.example.fast_med_flutter"
42
-        minSdkVersion 16
42
+        minSdkVersion 23
43 43
         targetSdkVersion 29
44 44
         versionCode flutterVersionCode.toInteger()
45 45
         versionName flutterVersionName

+ 66
- 0
fast_med_flutter/lib/model/event.dart View File

@@ -0,0 +1,66 @@
1
+import 'package:firebase_helpers/firebase_helpers.dart';
2
+
3
+//En esta Area definimos todas las variables y parametros utilizadas en las
4
+//funciones de los otros files.
5
+
6
+//Son las mismas variables usadas para enviar al servidor y recibir de vuelta
7
+// a la aplicacion.
8
+
9
+class EventModel extends DatabaseItem{
10
+  final String id;
11
+  final String title;
12
+  final String description;
13
+  final DateTime eventDate;
14
+  final String name;
15
+  final String number;
16
+  final String reason;
17
+  final DateTime eventTime;
18
+
19
+
20
+  EventModel({this.id,this.title, this.description, this.eventDate, this.name, this.number, this.reason, this.eventTime}):super(id);
21
+
22
+  factory EventModel.fromMap(Map data) {
23
+    return EventModel(
24
+      title: data['title'],
25
+      description: data['description'],
26
+      name: data['name'],
27
+      number: data['number'],
28
+      reason: data['reason'],
29
+      eventDate: data['event_date'],
30
+      eventTime: data['event_time'],
31
+    );
32
+  }
33
+
34
+  factory EventModel.fromDS(String id, Map<String,dynamic> data) {
35
+    return EventModel(
36
+      id: id,
37
+      title: data['title'],
38
+      description: data['description'],
39
+      number: data['number'],
40
+      reason: data['reason'],
41
+      eventDate: data['event_date'].toDate(),
42
+      eventTime: data['event_time'].toTime(),
43
+    );
44
+  }
45
+
46
+  final Map<DateTime, List> _holidays = {
47
+    DateTime(2020, 11, 6): ['No Hay Citas'],
48
+    DateTime(2020, 11, 3): ['Dia Elecciones'],
49
+    DateTime(2020, 12, 25): ['Chrismas'],
50
+    DateTime(2020, 12, 31): ['Despedida del anyo nuevo'],
51
+  };
52
+
53
+
54
+  Map<String,dynamic> toMap() {
55
+    return {
56
+      "title":title,
57
+      "description": description,
58
+      "event_date":eventDate,
59
+      "id":id,
60
+      "name":name,
61
+      "number":number,
62
+      "reason":reason,
63
+      "event_time":eventTime,
64
+    };
65
+  }
66
+}

+ 6
- 0
fast_med_flutter/lib/res/event_firestore_service.dart View File

@@ -0,0 +1,6 @@
1
+import 'package:firebase_helpers/firebase_helpers.dart';
2
+import '../model/event.dart';
3
+
4
+DatabaseService<EventModel> eventDBS = DatabaseService<EventModel>
5
+  ("events",fromDS: (id,data) => EventModel.fromDS(id, data), toMap:
6
+    (event) => event.toMap());

+ 159
- 277
fast_med_flutter/lib/routes/calendario.dart View File

@@ -1,19 +1,36 @@
1 1
 import 'package:flutter/material.dart';
2
-import 'package:intl/date_symbol_data_local.dart';
2
+import 'package:fast_med_flutter/ui/pages/add_event.dart';
3
+import 'package:fast_med_flutter/ui/pages/view_event.dart';
3 4
 import 'package:table_calendar/table_calendar.dart';
5
+import 'package:http/http.dart' as http;
6
+
7
+import 'package:fast_med_flutter/model/event.dart';
8
+
9
+// Dias de Citas No Disponibles
4 10
 
5
-// Dias sin Citas Disponibles
6 11
 final Map<DateTime, List> _holidays = {
7 12
   DateTime(2020, 11, 6): ['No Hay Citas'],
8 13
   DateTime(2020, 11, 3): ['Dia Elecciones'],
9
-
14
+  DateTime(2020, 12, 25): ['Christmas'],
15
+  DateTime(2020, 12, 31): ['Despedida del anyo nuevo'],
16
+  DateTime(2021, 01, 01): ['Anyo Nuevo'],
10 17
 };
11 18
 
12
-void main() {
13
-  initializeDateFormatting().then((_) => runApp(Calendario()));
14
-}
19
+//Iniciar la Seccion de las Citas
20
+
21
+void main() async{
15 22
 
23
+  //Comunicacion con el servidor antes de iniciar el app
16 24
 
25
+  var url = 'https://ada.uprrp.edu/~jorge.lopez19/FastMed/API/InsertEvent.php';
26
+  WidgetsFlutterBinding.ensureInitialized();
27
+  final data = await http.post(url, body: {
28
+  });
29
+  runApp(Calendario());
30
+
31
+}
32
+
33
+//Inicio del Area de las Citas Disponibles
17 34
 
18 35
 class Calendario extends StatelessWidget {
19 36
   @override
@@ -23,56 +40,72 @@ class Calendario extends StatelessWidget {
23 40
       theme: ThemeData(
24 41
         primarySwatch: Colors.blue,
25 42
       ),
26
-      home: MyHomePage(title: 'Citas Disponibles'),
43
+      home: MyHomePage(),
44
+      routes: {
45
+        "add_event": (_) => AddEventPage(),
46
+      },
27 47
     );
28 48
   }
29 49
 }
30 50
 
31
-class MyHomePage extends StatefulWidget {
32
-  MyHomePage({Key key, this.title}) : super(key: key);
33 51
 
34
-  final String title;
52
+// Define el homepage para el area de citas
35 53
 
54
+class MyHomePage extends StatefulWidget {
36 55
   @override
37 56
   _MyHomePageState createState() => _MyHomePageState();
38 57
 }
39 58
 
40
-class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
41
-  Map<DateTime, List> _events;
42
-  List _selectedEvents;
43
-  AnimationController _animationController;
44
-  CalendarController _calendarController;
59
+class _MyHomePageState extends State<MyHomePage> {
60
+  CalendarController _controller;
61
+  Map<DateTime, List<dynamic>> _events;
62
+  List<dynamic> _selectedEvents;
45 63
 
46 64
   @override
47 65
   void initState() {
48 66
     super.initState();
49 67
     final _selectedDay = DateTime.now();
50
-
68
+    _controller = CalendarController();
51 69
     _events = {
52
-
53
-      _selectedDay.add(Duration(days: 3)): Set.from([ 'Cita Cardiologo', 'Cita Dentista']).toList(),
54
-      _selectedDay.add(Duration(days: 22)): ['Cita Cardiologo', 'Cita Dentista'],
55
-
70
+      //Ejemplos de Citas Previamente Hechas de Prueba Para los Recordatorios
71
+      _selectedDay.add(Duration(days: 3)): Set.from(
72
+          [ 'Cita Cardiologo', 'Cita Dentista']).toList(),
73
+      _selectedDay.add(Duration(days: 22)): [
74
+        'Cita Cardiologo',
75
+        'Cita Dentista'
76
+      ],
56 77
     };
57
-
58 78
     _selectedEvents = _events[_selectedDay] ?? [];
59
-    _calendarController = CalendarController();
60
-
61
-    _animationController = AnimationController(
62
-      vsync: this,
63
-      duration: const Duration(milliseconds: 400),
64
-    );
79
+    void _onDaySelected(DateTime day, List events, List holidays) {
80
+      print('CALLBACK: _onDaySelected');
81
+      setState(() {
82
+        _selectedEvents = _events[_selectedDay] ?? [];
83
+      });
84
+    }
85
+  }
65 86
 
66
-    _animationController.forward();
87
+  Map<String, dynamic> encodeMap(Map<DateTime, dynamic> map) {
88
+    Map<String, dynamic> newMap = {};
89
+    map.forEach((key, value) {
90
+      newMap[key.toString()] = map[key];
91
+    });
92
+    return newMap;
67 93
   }
68 94
 
69
-  @override
70
-  void dispose() {
71
-    _animationController.dispose();
72
-    _calendarController.dispose();
73
-    super.dispose();
95
+  Map<DateTime, List<dynamic>> _groupEvents(List<EventModel> events) {
96
+    Map<DateTime, List<dynamic>> data = {};
97
+    events.forEach((event) {
98
+      DateTime date = DateTime(event.eventDate.year, event.eventDate.month,
99
+          event.eventDate.day, 12);
100
+      if (data[date] == null) data[date] = [];
101
+      data[date].add(event);
102
+    });
103
+    return data;
74 104
   }
75 105
 
106
+
107
+  @override
108
+//Marca en el calendario los dias que no esta disponibles para hacer horarios
76 109
   void _onDaySelected(DateTime day, List events, List holidays) {
77 110
     print('CALLBACK: _onDaySelected');
78 111
     setState(() {
@@ -80,268 +113,117 @@ class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
80 113
     });
81 114
   }
82 115
 
83
-  void _onVisibleDaysChanged(DateTime first, DateTime last, CalendarFormat format) {
116
+  void _onVisibleDaysChanged(DateTime first, DateTime last,
117
+      CalendarFormat format) {
84 118
     print('CALLBACK: _onVisibleDaysChanged');
85 119
   }
86 120
 
87
-  void _onCalendarCreated(DateTime first, DateTime last, CalendarFormat format) {
121
+  void _onCalendarCreated(DateTime first, DateTime last,
122
+      CalendarFormat format) {
88 123
     print('CALLBACK: _onCalendarCreated');
89 124
   }
90 125
 
126
+//Definimos los detalles del area de las citas
91 127
   @override
92 128
   Widget build(BuildContext context) {
93 129
     return Scaffold(
94 130
       appBar: AppBar(
95
-        title: Text(widget.title),
96
-      ),
97
-      body: Column(
98
-        mainAxisSize: MainAxisSize.max,
99
-        children: <Widget>[
100
-          // Switch out 2 lines below to play with TableCalendar's settings
101
-          //-----------------------
102
-          _buildTableCalendar(),
103
-          // _buildTableCalendarWithBuilders(),
104
-          const SizedBox(height: 8.0),
105
-          _buildButtons(),
106
-          const SizedBox(height: 8.0),
107
-          Expanded(child: _buildEventList()),
108
-        ],
109
-      ),
110
-    );
111
-  }
112
-  //Back button
113
-  Widget BackButton(BuildContext context){
114
-    return InkWell(
115
-      onTap: (){
116
-        Navigator.pop(context);
117
-      },
118
-      child: Row(
119
-          children: <Widget>[
120
-            Container(
121
-              padding: EdgeInsets.only(left: 0, top:10, bottom: 10),
122
-              child: Icon(Icons.arrow_back_ios, color: Colors.black),
123
-            ),
124
-            Text("Black",
125
-                style: TextStyle(fontSize: 12, fontWeight: FontWeight.w500))
126
-          ]
127
-      ),
128
-    );
129
-  }
130
-
131
-  // Simple TableCalendar configuration (using Styles)
132
-  Widget _buildTableCalendar() {
133
-    return TableCalendar(
134
-      calendarController: _calendarController,
135
-      events: _events,
136
-      holidays: _holidays,
137
-      startingDayOfWeek: StartingDayOfWeek.monday,
138
-      calendarStyle: CalendarStyle(
139
-        selectedColor: Colors.lightBlueAccent,
140
-        todayColor: Colors.blueAccent,
141
-        markersColor: Colors.brown,
142
-        outsideDaysVisible: false,
131
+        title: Text('Citas Disponibles'),
143 132
       ),
144
-      headerStyle: HeaderStyle(
145
-        formatButtonTextStyle: TextStyle().copyWith(color: Colors.white, fontSize: 15.0),
146
-        formatButtonDecoration: BoxDecoration(
147
-          color: Colors.lightBlue,
148
-          borderRadius: BorderRadius.circular(16.0),
149
-        ),
150
-      ),
151
-      onDaySelected: _onDaySelected,
152
-      onVisibleDaysChanged: _onVisibleDaysChanged,
153
-      onCalendarCreated: _onCalendarCreated,
154
-    );
155
-  }
156
-
157
-  // More advanced TableCalendar configuration (using Builders & Styles)
158
-  Widget _buildTableCalendarWithBuilders() {
159
-    return TableCalendar(
160
-      locale: 'pl_PL',
161
-      calendarController: _calendarController,
162
-      events: _events,
163
-      holidays: _holidays,
164
-      initialCalendarFormat: CalendarFormat.month,
165
-      formatAnimation: FormatAnimation.slide,
166
-      startingDayOfWeek: StartingDayOfWeek.sunday,
167
-      availableGestures: AvailableGestures.all,
168
-      availableCalendarFormats: const {
169
-        CalendarFormat.month: '',
170
-        CalendarFormat.week: '',
171
-      },
172
-      calendarStyle: CalendarStyle(
173
-        outsideDaysVisible: false,
174
-        weekendStyle: TextStyle().copyWith(color: Colors.blue),
175
-        holidayStyle: TextStyle().copyWith(color: Colors.blue),
176
-      ),
177
-      daysOfWeekStyle: DaysOfWeekStyle(
178
-        weekendStyle: TextStyle().copyWith(color: Colors.blue),
179
-      ),
180
-      headerStyle: HeaderStyle(
181
-        centerHeaderTitle: true,
182
-        formatButtonVisible: false,
183
-      ),
184
-      builders: CalendarBuilders(
185
-        selectedDayBuilder: (context, date, _) {
186
-          return FadeTransition(
187
-            opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController),
188
-            child: Container(
189
-              margin: const EdgeInsets.all(4.0),
190
-              padding: const EdgeInsets.only(top: 5.0, left: 6.0),
191
-              color: Colors.green,
192
-              width: 100,
193
-              height: 100,
194
-              child: Text(
195
-                '${date.day}',
196
-                style: TextStyle().copyWith(fontSize: 16.0),
197
-              ),
198
-            ),
199
-          );
200
-        },
201
-        todayDayBuilder: (context, date, _) {
202
-          return Container(
203
-            margin: const EdgeInsets.all(4.0),
204
-            padding: const EdgeInsets.only(top: 5.0, left: 6.0),
205
-            color: Colors.amber,
206
-            width: 100,
207
-            height: 100,
208
-            child: Text(
209
-              '${date.day}',
210
-              style: TextStyle().copyWith(fontSize: 16.0),
211
-            ),
212
-          );
213
-        },
214
-        markersBuilder: (context, date, events, holidays) {
215
-          final children = <Widget>[];
216
-
217
-          if (events.isNotEmpty) {
218
-            children.add(
219
-              Positioned(
220
-                right: 1,
221
-                bottom: 1,
222
-                child: _buildEventsMarker(date, events),
223
-              ),
224
-            );
225
-          }
226
-
227
-          if (holidays.isNotEmpty) {
228
-            children.add(
229
-              Positioned(
230
-                right: -2,
231
-                top: -2,
232
-                child: _buildHolidaysMarker(),
133
+      body: StreamBuilder<List<EventModel>>(
134
+        // stream: eventDBS.streamList(),
135
+          builder: (context, snapshot) {
136
+            if (snapshot.hasData) {
137
+              List<EventModel> allEvents = snapshot.data;
138
+              if (allEvents.isNotEmpty) {
139
+                _events = _groupEvents(allEvents);
140
+              }
141
+            }
142
+
143
+            return SingleChildScrollView(
144
+              child: Column(
145
+                crossAxisAlignment: CrossAxisAlignment.start,
146
+                children: <Widget>[
147
+                  TableCalendar(
148
+                    events: _events,
149
+                    holidays: _holidays,
150
+                    initialCalendarFormat: CalendarFormat.month,
151
+                    calendarStyle: CalendarStyle(
152
+                        canEventMarkersOverflow: true,
153
+                        todayColor: Colors.orange,
154
+                        selectedColor: Theme
155
+                            .of(context)
156
+                            .primaryColor,
157
+                        todayStyle: TextStyle(
158
+                            fontWeight: FontWeight.bold,
159
+                            fontSize: 18.0,
160
+                            color: Colors.white)),
161
+                    headerStyle: HeaderStyle(
162
+                      centerHeaderTitle: true,
163
+                      formatButtonDecoration: BoxDecoration(
164
+                        color: Colors.orange,
165
+                        borderRadius: BorderRadius.circular(20.0),
166
+                      ),
167
+                      formatButtonTextStyle: TextStyle(color: Colors.white),
168
+                      formatButtonShowsNext: false,
169
+                    ),
170
+                    startingDayOfWeek: StartingDayOfWeek.monday,
171
+                    onVisibleDaysChanged: _onVisibleDaysChanged,
172
+                    onCalendarCreated: _onCalendarCreated,
173
+
174
+                    builders: CalendarBuilders(
175
+                      selectedDayBuilder: (context, date, events) =>
176
+                          Container(
177
+                              margin: const EdgeInsets.all(4.0),
178
+                              alignment: Alignment.center,
179
+                              decoration: BoxDecoration(
180
+                                  color: Theme
181
+                                      .of(context)
182
+                                      .primaryColor,
183
+                                  borderRadius: BorderRadius.circular(10.0)),
184
+                              child: Text(
185
+                                date.day.toString(),
186
+                                style: TextStyle(color: Colors.white),
187
+                              )),
188
+                      todayDayBuilder: (context, date, events) =>
189
+                          Container(
190
+                              margin: const EdgeInsets.all(4.0),
191
+                              alignment: Alignment.center,
192
+                              decoration: BoxDecoration(
193
+                                  color: Colors.orange,
194
+                                  borderRadius: BorderRadius.circular(10.0)),
195
+                              child: Text(
196
+                                date.day.toString(),
197
+                                style: TextStyle(color: Colors.white),
198
+                              )),
199
+                    ),
200
+                    calendarController: _controller,
201
+                  ),
202
+                  ..._selectedEvents.map((event) =>
203
+                      ListTile(
204
+                        title: Text(event.title),
205
+                        onTap: () {
206
+                          Navigator.push(
207
+                              context,
208
+                              MaterialPageRoute(
209
+                                  builder: (_) =>
210
+                                      EventDetailsPage(
211
+                                        event: event,
212
+                                      )));
213
+                        },
214
+                      )),
215
+                ],
233 216
               ),
234 217
             );
235 218
           }
236
-
237
-          return children;
238
-        },
239
-      ),
240
-      onDaySelected: (date, events, holidays) {
241
-        _onDaySelected(date, events, holidays);
242
-        _animationController.forward(from: 0.0);
243
-      },
244
-      onVisibleDaysChanged: _onVisibleDaysChanged,
245
-      onCalendarCreated: _onCalendarCreated,
246
-    );
247
-  }
248
-
249
-  Widget _buildEventsMarker(DateTime date, List events) {
250
-    return AnimatedContainer(
251
-      duration: const Duration(milliseconds: 300),
252
-      decoration: BoxDecoration(
253
-        shape: BoxShape.rectangle,
254
-        color: _calendarController.isSelected(date)
255
-            ? Colors.brown[500]
256
-            : _calendarController.isToday(date) ? Colors.brown : Colors.blue,
257 219
       ),
258
-      width: 16.0,
259
-      height: 16.0,
260
-      child: Center(
261
-        child: Text(
262
-          '${events.length}',
263
-          style: TextStyle().copyWith(
264
-            color: Colors.green,
265
-            fontSize: 12.0,
266
-          ),
267
-        ),
220
+      floatingActionButton: FloatingActionButton(
221
+        child: Icon(Icons.add),
222
+        onPressed: () => Navigator.pushNamed(context, 'add_event'),
268 223
       ),
269 224
     );
270 225
   }
226
+}
271 227
 
272
-  Widget _buildHolidaysMarker() {
273
-    return Icon(
274
-      Icons.add_box,
275
-      size: 20.0,
276
-      color: Colors.blueGrey,
277
-    );
278
-  }
279
-
280
-  Widget _buildButtons() {
281
-    final dateTime = _events.keys.elementAt(_events.length - 2);
282
-
283
-    return Column(
284
-      children: <Widget>[
285
-        Row(
286
-          mainAxisSize: MainAxisSize.max,
287
-          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
288
-          children: <Widget>[
289
-            RaisedButton(
290
-              child: Text('Mes'),
291
-              onPressed: () {
292
-                setState(() {
293
-                  _calendarController.setCalendarFormat(CalendarFormat.month);
294
-                });
295
-              },
296
-            ),
297
-            RaisedButton(
298
-              child: Text('2 Semanas'),
299
-              onPressed: () {
300
-                setState(() {
301
-                  _calendarController.setCalendarFormat(CalendarFormat.twoWeeks);
302
-                });
303
-              },
304
-            ),
305
-            RaisedButton(
306
-              child: Text('Semana'),
307
-              onPressed: () {
308
-                setState(() {
309
-                  _calendarController.setCalendarFormat(CalendarFormat.week);
310
-                });
311
-              },
312
-            ),
313
-          ],
314
-        ),
315
-        const SizedBox(height: 8.0),
316
-        RaisedButton(
317
-          child: Text('Recuerde Cita ${dateTime.day}-${dateTime.month}-${dateTime.year}'),
318
-          onPressed: () {
319
-            _calendarController.setSelectedDay(
320
-              DateTime(dateTime.year, dateTime.month, dateTime.day),
321
-              runCallback: true,
322
-            );
323
-          },
324
-        ),
325
-      ],
326
-    );
327
-  }
328 228
 
329 229
 
330
-  Widget _buildEventList() {
331
-    return ListView(
332
-      children: _selectedEvents
333
-          .map((event) => Container(
334
-        decoration: BoxDecoration(
335
-          border: Border.all(width: 0.8),
336
-          borderRadius: BorderRadius.circular(12.0),
337
-        ),
338
-        margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
339
-        child: ListTile(
340
-          title: Text(event.toString()),
341
-          onTap: () => print('$event tapped!'),
342
-        ),
343
-      ))
344
-          .toList(),
345
-    );
346
-  }
347
-}

+ 231
- 0
fast_med_flutter/lib/ui/pages/add_event.dart View File

@@ -0,0 +1,231 @@
1
+import 'package:fast_med_flutter/model/event.dart';
2
+import 'package:flutter/material.dart';
3
+import 'package:fast_med_flutter/res/event_firestore_service.dart';
4
+import 'package:http/http.dart' as http;
5
+import 'dart:async';
6
+
7
+class AddEventPage extends StatefulWidget {
8
+  final EventModel note;
9
+
10
+  const AddEventPage({Key key, this.note}) : super(key: key);
11
+
12
+  @override
13
+  _AddEventPageState createState() => _AddEventPageState();
14
+}
15
+
16
+//Controles de cada Evento que usaremos en todos los files
17
+
18
+class _AddEventPageState extends State<AddEventPage> {
19
+  TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
20
+  TextEditingController _title;
21
+  TextEditingController _description;
22
+  TextEditingController _number;
23
+  TextEditingController _name;
24
+  TextEditingController _reason;
25
+
26
+
27
+  DateTime _eventDate;
28
+  DateTime _eventTime;
29
+  DateTime selectedDate = DateTime.now();
30
+  List data;
31
+  List holidays;
32
+  final _formKey = GlobalKey<FormState>();
33
+  final _key = GlobalKey<ScaffoldState>();
34
+  bool processing;
35
+
36
+  @override
37
+  void initState() {
38
+    super.initState();
39
+    _title = TextEditingController(text: widget.note != null ? widget.note.title : "");
40
+    _description = TextEditingController(text:  widget.note != null ? widget.note.description : "");
41
+    _name = TextEditingController(text:  widget.note != null ? widget.note.name : "");
42
+    _number = TextEditingController(text:  widget.note != null ? widget.note.number : "");
43
+    _reason = TextEditingController(text:  widget.note != null ? widget.note.reason : "");
44
+    _eventDate = DateTime.now();
45
+    _eventTime = DateTime.now();
46
+    processing = false;
47
+  }
48
+
49
+// Definimos el Formulario con cada parametro para crear la cita
50
+
51
+  @override
52
+  Widget build(BuildContext context) {
53
+    return Scaffold(
54
+      appBar: AppBar(
55
+        title: Text(widget.note != null ? "Edit Note" : "Crear Su Cita"),
56
+      ),
57
+      key: _key,
58
+      body: Form(
59
+        key: _formKey,
60
+        child: Container(
61
+          alignment: Alignment.center,
62
+          child: ListView(
63
+            children: <Widget>[
64
+
65
+              // Area donde paciente anota su nombre. Si esta vacio no lo acepta.
66
+
67
+              Padding(
68
+                padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
69
+                child: TextFormField(
70
+                  controller: _name,
71
+                  validator: (value) =>
72
+                      (value.isEmpty) ? "Favor Anotar Nombre del Paciente" : null,
73
+                  style: style,
74
+                  decoration: InputDecoration(
75
+                      labelText: "Nombre completo del paciente",
76
+                      filled: true,
77
+                      fillColor: Colors.white,
78
+                      border: OutlineInputBorder(borderRadius: BorderRadius.circular(10))),
79
+                ),
80
+              ),
81
+
82
+              //Area donde el paciente debe anotar su numero de telefono. Si esta vacio no lo acepta.
83
+
84
+              Padding(
85
+                padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
86
+                child: TextFormField(
87
+                  controller: _number,
88
+                  validator: (value) =>
89
+                  (value.isEmpty) ? "Favor Anotar Numero de Telefono" : null,
90
+                  style: style,
91
+                  decoration: InputDecoration(
92
+                      labelText: "Numero de Telefono",
93
+                      border: OutlineInputBorder(borderRadius: BorderRadius.circular(10))),
94
+                ),
95
+              ),
96
+
97
+              //Area donde el paciente explica la razon de su cita medica. Si esta vacio no lo acepta
98
+
99
+              Padding(
100
+                padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
101
+                child: TextFormField(
102
+                  controller: _reason,
103
+                  minLines: 3,
104
+                  maxLines: 5,
105
+                  validator: (value) =>
106
+                      (value.isEmpty) ? "Favor Explicar Razon Para La Cita" : null,
107
+                  style: style,
108
+                  decoration: InputDecoration(
109
+                      labelText: "Razones para su cita",
110
+                      border: OutlineInputBorder(borderRadius: BorderRadius.circular(10))),
111
+                ),
112
+              ),
113
+              const SizedBox(height: 10.0),
114
+
115
+              //Area donde el paciente puede cambiar la fecha para la cita
116
+
117
+              ListTile(
118
+                title: Text("Date (YYYY-MM-DD)"),
119
+                subtitle: Text("${_eventDate.year} - ${_eventDate.month} - ${_eventDate.day}"),
120
+                onTap: ()async{
121
+                  DateTime picked = await showDatePicker(context: context, initialDate: _eventDate, firstDate: DateTime(_eventDate.year-5), lastDate: DateTime(_eventDate.year+5));
122
+                  if(picked != null) {
123
+                    setState(() {
124
+                      _eventDate = picked;
125
+                    });
126
+                  }
127
+                },
128
+              ),
129
+
130
+              //Area donde el paciente puede elegir y cambiar la hora para la cita
131
+
132
+              ListTile(
133
+                title: Text("Time (HH: mm)"),
134
+                subtitle: Text("${_eventDate.hour} - ${_eventDate.minute} - ${_eventDate.second}"),
135
+                onTap: ()async{
136
+                 final selectedTime = await _selectTime(context);
137
+                 if (selectedTime == null) return;
138
+                  print(selectedTime);
139
+
140
+                setState(() {
141
+                this.selectedDate = DateTime(
142
+                selectedTime.hour,
143
+                selectedTime.minute,
144
+                );
145
+                    });
146
+                  }
147
+                  ),
148
+              SizedBox(height: 10.0),
149
+
150
+              //Se define el envio de los parametros al usar el boton de Crear la Cita
151
+
152
+              processing
153
+                  ? Center(child: CircularProgressIndicator())
154
+                  : Padding(
155
+                padding: const EdgeInsets.symmetric(horizontal: 16.0),
156
+                child: Material(
157
+                  elevation: 5.0,
158
+                  borderRadius: BorderRadius.circular(30.0),
159
+                  color: Theme.of(context).primaryColor,
160
+                  child: MaterialButton(
161
+                    onPressed: () async {
162
+                      if (_formKey.currentState.validate()) {
163
+                        setState(() {
164
+                          processing = true;
165
+                        });
166
+                        if(widget.note != null) {
167
+                          await eventDBS.updateData(widget.note.id,{
168
+
169
+
170
+                          "title": _title.text,
171
+                          "number": _number.text,
172
+                          "reason": _reason.text,
173
+                          "event_date": widget.note.eventDate,
174
+                          "time": widget.note.eventTime,
175
+                          });
176
+                        }else{
177
+                          await eventDBS.createItem(EventModel(
178
+                              title: _title.text,
179
+                              description: _description.text,
180
+                              name: _name.text,
181
+                              number: _number.text,
182
+                              reason: _reason.text,
183
+                              eventDate: _eventDate
184
+
185
+                          ));
186
+                        }
187
+                        Navigator.pop(context);
188
+                        setState(() {
189
+                          processing = false;
190
+                        });
191
+                      }
192
+                    },
193
+                    child: Text(
194
+                      "Crear Su Cita Ahora",
195
+                      style: style.copyWith(
196
+                          color: Colors.white,
197
+                          fontWeight: FontWeight.bold),
198
+                    ),
199
+                  ),
200
+                ),
201
+              ),
202
+            ],
203
+          ),
204
+        ),
205
+      ),
206
+    );
207
+  }
208
+
209
+
210
+  @override
211
+  void dispose() {
212
+    _title.dispose();
213
+    _description.dispose();
214
+    _name.dispose();
215
+    _number.dispose();
216
+    _reason.dispose();
217
+    super.dispose();
218
+  }
219
+}
220
+
221
+// Funcionalidades para poder seleccionar horarios
222
+
223
+Future<TimeOfDay> _selectTime(BuildContext context) {
224
+  final now = DateTime.now();
225
+
226
+  return showTimePicker(
227
+    context: context,
228
+    initialTime: TimeOfDay(hour: now.hour, minute: now.minute),
229
+  );
230
+}
231
+

+ 30
- 0
fast_med_flutter/lib/ui/pages/view_event.dart View File

@@ -0,0 +1,30 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:fast_med_flutter/model/event.dart';
3
+
4
+// Implementacion para ver recordatorios de citas creadas
5
+
6
+class EventDetailsPage extends StatelessWidget {
7
+  final EventModel event;
8
+
9
+  const EventDetailsPage({Key key, this.event}) : super(key: key);
10
+
11
+  @override
12
+  Widget build(BuildContext context){
13
+    return Scaffold(
14
+      appBar: AppBar(
15
+        title: Text('Note details'),
16
+      ),
17
+      body: SingleChildScrollView(
18
+        padding: const EdgeInsets.all(16.0),
19
+        child: Column(
20
+          crossAxisAlignment: CrossAxisAlignment.start,
21
+          children: <Widget>[
22
+            Text(event.title, style: Theme.of(context).textTheme.display1,),
23
+            SizedBox(height: 20.0),
24
+            Text(event.description)
25
+          ],
26
+        ),
27
+      ),
28
+    );
29
+  }
30
+}

+ 75
- 0
fast_med_flutter/pubspec.lock View File

@@ -36,6 +36,27 @@ packages:
36 36
       url: "https://pub.dartlang.org"
37 37
     source: hosted
38 38
     version: "1.1.0-nullsafety.1"
39
+  cloud_firestore:
40
+    dependency: "direct main"
41
+    description:
42
+      name: cloud_firestore
43
+      url: "https://pub.dartlang.org"
44
+    source: hosted
45
+    version: "0.13.7"
46
+  cloud_firestore_platform_interface:
47
+    dependency: transitive
48
+    description:
49
+      name: cloud_firestore_platform_interface
50
+      url: "https://pub.dartlang.org"
51
+    source: hosted
52
+    version: "1.1.2"
53
+  cloud_firestore_web:
54
+    dependency: transitive
55
+    description:
56
+      name: cloud_firestore_web
57
+      url: "https://pub.dartlang.org"
58
+    source: hosted
59
+    version: "0.1.1+2"
39 60
   collection:
40 61
     dependency: transitive
41 62
     description:
@@ -85,6 +106,48 @@ packages:
85 106
       url: "https://pub.dartlang.org"
86 107
     source: hosted
87 108
     version: "5.2.1"
109
+  firebase:
110
+    dependency: transitive
111
+    description:
112
+      name: firebase
113
+      url: "https://pub.dartlang.org"
114
+    source: hosted
115
+    version: "7.3.3"
116
+  firebase_core:
117
+    dependency: transitive
118
+    description:
119
+      name: firebase_core
120
+      url: "https://pub.dartlang.org"
121
+    source: hosted
122
+    version: "0.4.5"
123
+  firebase_core_platform_interface:
124
+    dependency: transitive
125
+    description:
126
+      name: firebase_core_platform_interface
127
+      url: "https://pub.dartlang.org"
128
+    source: hosted
129
+    version: "1.0.4"
130
+  firebase_core_web:
131
+    dependency: transitive
132
+    description:
133
+      name: firebase_core_web
134
+      url: "https://pub.dartlang.org"
135
+    source: hosted
136
+    version: "0.1.1+2"
137
+  firebase_helpers:
138
+    dependency: "direct main"
139
+    description:
140
+      name: firebase_helpers
141
+      url: "https://pub.dartlang.org"
142
+    source: hosted
143
+    version: "0.1.11"
144
+  firebase_storage:
145
+    dependency: transitive
146
+    description:
147
+      name: firebase_storage
148
+      url: "https://pub.dartlang.org"
149
+    source: hosted
150
+    version: "3.1.6"
88 151
   flushbar:
89 152
     dependency: transitive
90 153
     description:
@@ -109,6 +172,11 @@ packages:
109 172
     description: flutter
110 173
     source: sdk
111 174
     version: "0.0.0"
175
+  flutter_web_plugins:
176
+    dependency: transitive
177
+    description: flutter
178
+    source: sdk
179
+    version: "0.0.0"
112 180
   font_awesome_flutter:
113 181
     dependency: transitive
114 182
     description:
@@ -144,6 +212,13 @@ packages:
144 212
       url: "https://pub.dartlang.org"
145 213
     source: hosted
146 214
     version: "0.16.1"
215
+  js:
216
+    dependency: transitive
217
+    description:
218
+      name: js
219
+      url: "https://pub.dartlang.org"
220
+    source: hosted
221
+    version: "0.6.2"
147 222
   matcher:
148 223
     dependency: transitive
149 224
     description:

+ 3
- 0
fast_med_flutter/pubspec.yaml View File

@@ -24,6 +24,9 @@ dependencies:
24 24
   flutter:
25 25
     sdk: flutter
26 26
 
27
+  firebase_helpers: ^0.1.8
28
+  cloud_firestore: ^0.13.5
29
+
27 30
 
28 31
   # The following adds the Cupertino Icons font to your application.
29 32
   # Use with the CupertinoIcons class for iOS style icons.