Browse Source

Mis cambios Sprint 2

JorgeIan 3 years ago
parent
commit
6281cf507b

+ 19
- 2
fast_med_flutter/android/app/build.gradle View File

@@ -26,7 +26,9 @@ apply plugin: 'kotlin-android'
26 26
 apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 27
 
28 28
 android {
29
-    compileSdkVersion 29
29
+    compileSdkVersion 28
30
+    //compile 'com.google.firebase:firebase-auth:10.0.1'
31
+
30 32
 
31 33
     sourceSets {
32 34
         main.java.srcDirs += 'src/main/kotlin'
@@ -37,12 +39,15 @@ android {
37 39
     }
38 40
 
39 41
     defaultConfig {
42
+        multiDexEnabled true
43
+
40 44
         // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 45
         applicationId "com.example.fast_med_flutter"
42 46
         minSdkVersion 16
43
-        targetSdkVersion 29
47
+        targetSdkVersion 28
44 48
         versionCode flutterVersionCode.toInteger()
45 49
         versionName flutterVersionName
50
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
46 51
     }
47 52
 
48 53
     buildTypes {
@@ -59,5 +64,17 @@ flutter {
59 64
 }
60 65
 
61 66
 dependencies {
67
+    implementation 'androidx.multidex:multidex:2.0.1'
62 68
     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
69
+    testImplementation 'junit:junit:4.12'
70
+    androidTestImplementation 'androidx.test:runner:1.1.1'
71
+    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
72
+    implementation platform('com.google.firebase:firebase-bom:25.12.0')
73
+    implementation 'com.google.firebase:firebase-analytics-ktx'
74
+    implementation 'com.google.firebase:firebase-auth-ktx'
75
+    implementation 'com.google.firebase:firebase-firestore-ktx'
76
+
63 77
 }
78
+
79
+
80
+apply plugin: 'com.google.gms.google-services'

+ 40
- 0
fast_med_flutter/android/app/google-services.json View File

@@ -0,0 +1,40 @@
1
+{
2
+  "project_info": {
3
+    "project_number": "874246220025",
4
+    "firebase_url": "https://calendar-flutter-d7b6e.firebaseio.com",
5
+    "project_id": "calendar-flutter-d7b6e",
6
+    "storage_bucket": "calendar-flutter-d7b6e.appspot.com"
7
+  },
8
+  "client": [
9
+    {
10
+      "client_info": {
11
+        "mobilesdk_app_id": "1:874246220025:android:4c604be741056a86019a28",
12
+        "android_client_info": {
13
+          "package_name": "com.example.fast_med_flutter"
14
+        }
15
+      },
16
+      "oauth_client": [
17
+        {
18
+          "client_id": "874246220025-abmjr89mo81oqrrrjd83on3faphkv14r.apps.googleusercontent.com",
19
+          "client_type": 3
20
+        }
21
+      ],
22
+      "api_key": [
23
+        {
24
+          "current_key": "AIzaSyBQ9tzZnjbFvTw-7ROUH-6a8Cb8Ae3Ddn8"
25
+        }
26
+      ],
27
+      "services": {
28
+        "appinvite_service": {
29
+          "other_platform_oauth_client": [
30
+            {
31
+              "client_id": "874246220025-abmjr89mo81oqrrrjd83on3faphkv14r.apps.googleusercontent.com",
32
+              "client_type": 3
33
+            }
34
+          ]
35
+        }
36
+      }
37
+    }
38
+  ],
39
+  "configuration_version": "1"
40
+}

+ 2
- 0
fast_med_flutter/android/build.gradle View File

@@ -8,6 +8,8 @@ buildscript {
8 8
     dependencies {
9 9
         classpath 'com.android.tools.build:gradle:3.5.0'
10 10
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11
+        classpath 'com.google.gms:google-services:4.3.4'
12
+        classpath 'com.google.gms:google-services:3.0.0'
11 13
     }
12 14
 }
13 15
 

+ 14
- 0
fast_med_flutter/android/settings.gradle View File

@@ -9,3 +9,17 @@ localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
9 9
 def flutterSdkPath = properties.getProperty("flutter.sdk")
10 10
 assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 11
 apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12
+
13
+def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
14
+
15
+def plugins = new Properties()
16
+def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
17
+if (pluginsFile.exists()) {
18
+    pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
19
+}
20
+
21
+plugins.each { name, path ->
22
+    def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
23
+    include ":$name"
24
+    project(":$name").projectDir = pluginDirectory
25
+}

+ 1
- 1
fast_med_flutter/lib/main.dart View File

@@ -16,4 +16,4 @@ void main() => runApp(MaterialApp(
16 16
       '/register': (context) => RegisterPage(),
17 17
       '/MyApp': (context) => MyApp(),
18 18
     }
19
-));
19
+));

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

@@ -0,0 +1,36 @@
1
+import 'package:firebase_helpers/firebase_helpers.dart';
2
+
3
+class EventModel extends DatabaseItem{
4
+  final String id;
5
+  final String title;
6
+  final String description;
7
+  final DateTime eventDate;
8
+
9
+  EventModel({this.id,this.title, this.description, this.eventDate}):super(id);
10
+
11
+  factory EventModel.fromMap(Map data) {
12
+    return EventModel(
13
+      title: data['title'],
14
+      description: data['description'],
15
+      eventDate: data['event_date'],
16
+    );
17
+  }
18
+
19
+  factory EventModel.fromDS(String id, Map<String,dynamic> data) {
20
+    return EventModel(
21
+      id: id,
22
+      title: data['title'],
23
+      description: data['description'],
24
+      eventDate: data['event_date'].toDate(),
25
+    );
26
+  }
27
+
28
+  Map<String,dynamic> toMap() {
29
+    return {
30
+      "title":title,
31
+      "description": description,
32
+      "event_date":eventDate,
33
+      "id":id,
34
+    };
35
+  }
36
+}

+ 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());

+ 113
- 302
fast_med_flutter/lib/routes/calendario.dart View File

@@ -1,20 +1,17 @@
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:firebase_core/firebase_core.dart';
4 6
 
5
-// Dias sin Citas Disponibles
6
-final Map<DateTime, List> _holidays = {
7
-  DateTime(2020, 11, 6): ['No Hay Citas'],
8
-  DateTime(2020, 11, 3): ['Dia Elecciones'],
7
+import 'model/event.dart';
9 8
 
10
-};
11
-
12
-void main() {
13
-  initializeDateFormatting().then((_) => runApp(Calendario()));
9
+void main() async{
10
+  WidgetsFlutterBinding.ensureInitialized();
11
+  await Firebase.initializeApp();
12
+  runApp(Calendario());
14 13
 }
15 14
 
16
-
17
-
18 15
 class Calendario extends StatelessWidget {
19 16
   @override
20 17
   Widget build(BuildContext context) {
@@ -23,325 +20,139 @@ class Calendario extends StatelessWidget {
23 20
       theme: ThemeData(
24 21
         primarySwatch: Colors.blue,
25 22
       ),
26
-      home: MyHomePage(title: 'Citas Disponibles'),
23
+      home: MyHomePage(),
24
+      routes: {
25
+        "add_event": (_) => AddEventPage(),
26
+      },
27 27
     );
28 28
   }
29 29
 }
30 30
 
31
-class MyHomePage extends StatefulWidget {
32
-  MyHomePage({Key key, this.title}) : super(key: key);
33 31
 
34
-  final String title;
35 32
 
33
+class MyHomePage extends StatefulWidget {
36 34
   @override
37 35
   _MyHomePageState createState() => _MyHomePageState();
38 36
 }
39 37
 
40
-class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
41
-  Map<DateTime, List> _events;
42
-  List _selectedEvents;
43
-  AnimationController _animationController;
44
-  CalendarController _calendarController;
38
+class _MyHomePageState extends State<MyHomePage> {
39
+  CalendarController _controller;
40
+  Map<DateTime, List<dynamic>> _events;
41
+  List<dynamic> _selectedEvents;
45 42
 
46 43
   @override
47 44
   void initState() {
48 45
     super.initState();
49
-    final _selectedDay = DateTime.now();
50
-
51
-    _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
-
56
-    };
57
-
58
-    _selectedEvents = _events[_selectedDay] ?? [];
59
-    _calendarController = CalendarController();
60
-
61
-    _animationController = AnimationController(
62
-      vsync: this,
63
-      duration: const Duration(milliseconds: 400),
64
-    );
65
-
66
-    _animationController.forward();
67
-  }
68
-
69
-  @override
70
-  void dispose() {
71
-    _animationController.dispose();
72
-    _calendarController.dispose();
73
-    super.dispose();
46
+    _controller = CalendarController();
47
+    _events = {};
48
+    _selectedEvents = [];
74 49
   }
75 50
 
76
-  void _onDaySelected(DateTime day, List events, List holidays) {
77
-    print('CALLBACK: _onDaySelected');
78
-    setState(() {
79
-      _selectedEvents = events;
51
+  Map<DateTime, List<dynamic>> _groupEvents(List<EventModel> events) {
52
+    Map<DateTime,List<dynamic>> data = {};
53
+    events.forEach((event) {
54
+      DateTime date = DateTime(event.eventDate.year, event.eventDate.month,
55
+          event.eventDate.day, 12);
56
+      if(data[date] == null) data[date] = [];
57
+      data[date].add(event);
80 58
     });
81
-  }
82
-
83
-  void _onVisibleDaysChanged(DateTime first, DateTime last, CalendarFormat format) {
84
-    print('CALLBACK: _onVisibleDaysChanged');
85
-  }
86
-
87
-  void _onCalendarCreated(DateTime first, DateTime last, CalendarFormat format) {
88
-    print('CALLBACK: _onCalendarCreated');
59
+    return data;
89 60
   }
90 61
 
91 62
   @override
92 63
   Widget build(BuildContext context) {
93 64
     return Scaffold(
94 65
       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,
143
-      ),
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),
66
+        title: Text('Citas Disponibles'),
176 67
       ),
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),
68
+      body: StreamBuilder<List<EventModel>>(
69
+        // stream: eventDBS.streamList(),
70
+          builder: (context, snapshot) {
71
+            if (snapshot.hasData) {
72
+              List<EventModel> allEvents = snapshot.data;
73
+              if (allEvents.isNotEmpty) {
74
+                _events = _groupEvents(allEvents);
75
+              }
76
+            }
77
+
78
+            return SingleChildScrollView(
79
+              child: Column(
80
+                crossAxisAlignment: CrossAxisAlignment.start,
81
+                children: <Widget>[
82
+                  TableCalendar(
83
+                    events: _events,
84
+                    initialCalendarFormat: CalendarFormat.week,
85
+                    calendarStyle: CalendarStyle(
86
+                        canEventMarkersOverflow: true,
87
+                        todayColor: Colors.orange,
88
+                        selectedColor: Theme
89
+                            .of(context)
90
+                            .primaryColor,
91
+                        todayStyle: TextStyle(
92
+                            fontWeight: FontWeight.bold,
93
+                            fontSize: 18.0,
94
+                            color: Colors.white)),
95
+                    headerStyle: HeaderStyle(
96
+                      centerHeaderTitle: true,
97
+                      formatButtonDecoration: BoxDecoration(
98
+                        color: Colors.orange,
99
+                        borderRadius: BorderRadius.circular(20.0),
100
+                      ),
101
+                      formatButtonTextStyle: TextStyle(color: Colors.white),
102
+                      formatButtonShowsNext: false,
103
+                    ),
104
+                    startingDayOfWeek: StartingDayOfWeek.monday,
105
+
106
+                    builders: CalendarBuilders(
107
+                      selectedDayBuilder: (context, date, events) =>
108
+                          Container(
109
+                              margin: const EdgeInsets.all(4.0),
110
+                              alignment: Alignment.center,
111
+                              decoration: BoxDecoration(
112
+                                  color: Theme
113
+                                      .of(context)
114
+                                      .primaryColor,
115
+                                  borderRadius: BorderRadius.circular(10.0)),
116
+                              child: Text(
117
+                                date.day.toString(),
118
+                                style: TextStyle(color: Colors.white),
119
+                              )),
120
+                      todayDayBuilder: (context, date, events) =>
121
+                          Container(
122
+                              margin: const EdgeInsets.all(4.0),
123
+                              alignment: Alignment.center,
124
+                              decoration: BoxDecoration(
125
+                                  color: Colors.orange,
126
+                                  borderRadius: BorderRadius.circular(10.0)),
127
+                              child: Text(
128
+                                date.day.toString(),
129
+                                style: TextStyle(color: Colors.white),
130
+                              )),
131
+                    ),
132
+                    calendarController: _controller,
133
+                  ),
134
+                  ..._selectedEvents.map((event) =>
135
+                      ListTile(
136
+                        title: Text(event.title),
137
+                        onTap: () {
138
+                          Navigator.push(
139
+                              context,
140
+                              MaterialPageRoute(
141
+                                  builder: (_) =>
142
+                                      EventDetailsPage(
143
+                                        event: event,
144
+                                      )));
145
+                        },
146
+                      )),
147
+                ],
223 148
               ),
224 149
             );
225 150
           }
226
-
227
-          if (holidays.isNotEmpty) {
228
-            children.add(
229
-              Positioned(
230
-                right: -2,
231
-                top: -2,
232
-                child: _buildHolidaysMarker(),
233
-              ),
234
-            );
235
-          }
236
-
237
-          return children;
238
-        },
239 151
       ),
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
-      ),
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
-        ),
152
+      floatingActionButton: FloatingActionButton(
153
+        child: Icon(Icons.add),
154
+        onPressed: () => Navigator.pushNamed(context, 'add_event'),
268 155
       ),
269 156
     );
270 157
   }
271
-
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
-
329
-
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
-}
158
+}

+ 1
- 1
fast_med_flutter/lib/routes/home.dart View File

@@ -35,7 +35,7 @@ class _HomeState extends State<Home>{
35 35
               onPressed: (){
36 36
                 Navigator.pushNamed(context, '/calendario');
37 37
               },
38
-              child: Text('Calendario',
38
+              child: Text('Buscar Citas',
39 39
                 style: TextStyle(fontSize: 36),
40 40
               ),
41 41
               color: Colors.purple,

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

@@ -0,0 +1,36 @@
1
+import 'package:firebase_helpers/firebase_helpers.dart';
2
+
3
+class EventModel extends DatabaseItem{
4
+  final String id;
5
+  final String title;
6
+  final String description;
7
+  final DateTime eventDate;
8
+
9
+  EventModel({this.id,this.title, this.description, this.eventDate}):super(id);
10
+
11
+  factory EventModel.fromMap(Map data) {
12
+    return EventModel(
13
+      title: data['title'],
14
+      description: data['description'],
15
+      eventDate: data['event_date'],
16
+    );
17
+  }
18
+
19
+  factory EventModel.fromDS(String id, Map<String,dynamic> data) {
20
+    return EventModel(
21
+      id: id,
22
+      title: data['title'],
23
+      description: data['description'],
24
+      eventDate: data['event_date'].toDate(),
25
+    );
26
+  }
27
+
28
+  Map<String,dynamic> toMap() {
29
+    return {
30
+      "title":title,
31
+      "description": description,
32
+      "event_date":eventDate,
33
+      "id":id,
34
+    };
35
+  }
36
+}

+ 0
- 1
fast_med_flutter/lib/routes/register.dart View File

@@ -11,7 +11,6 @@ import 'package:google_fonts/google_fonts.dart';
11 11
 //
12 12
 
13 13
 class RegisterPage extends StatefulWidget{
14
-  
15 14
   RegisterPage({Key key, this.title}) : super(key: key);
16 15
   final String title;
17 16
 

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

@@ -0,0 +1,143 @@
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
+
5
+class AddEventPage extends StatefulWidget {
6
+  final EventModel note;
7
+
8
+  const AddEventPage({Key key, this.note}) : super(key: key);
9
+
10
+  @override
11
+  _AddEventPageState createState() => _AddEventPageState();
12
+}
13
+
14
+class _AddEventPageState extends State<AddEventPage> {
15
+  TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
16
+  TextEditingController _title;
17
+  TextEditingController _description;
18
+  DateTime _eventDate;
19
+  final _formKey = GlobalKey<FormState>();
20
+  final _key = GlobalKey<ScaffoldState>();
21
+  bool processing;
22
+
23
+  @override
24
+  void initState() {
25
+    super.initState();
26
+    _title = TextEditingController(text: widget.note != null ? widget.note.title : "");
27
+    _description = TextEditingController(text:  widget.note != null ? widget.note.description : "");
28
+    _eventDate = DateTime.now();
29
+    processing = false;
30
+  }
31
+
32
+  @override
33
+  Widget build(BuildContext context) {
34
+    return Scaffold(
35
+      appBar: AppBar(
36
+        title: Text(widget.note != null ? "Edit Note" : "Crear Su Cita"),
37
+      ),
38
+      key: _key,
39
+      body: Form(
40
+        key: _formKey,
41
+        child: Container(
42
+          alignment: Alignment.center,
43
+          child: ListView(
44
+            children: <Widget>[
45
+              Padding(
46
+                padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
47
+                child: TextFormField(
48
+                  controller: _title,
49
+                  validator: (value) =>
50
+                      (value.isEmpty) ? "Favor Anotar Nombre del Paciente" : null,
51
+                  style: style,
52
+                  decoration: InputDecoration(
53
+                      labelText: "Nombre completo del paciente",
54
+                      filled: true,
55
+                      fillColor: Colors.white,
56
+                      border: OutlineInputBorder(borderRadius: BorderRadius.circular(10))),
57
+                ),
58
+              ),
59
+              Padding(
60
+                padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
61
+                child: TextFormField(
62
+                  controller: _description,
63
+                  minLines: 3,
64
+                  maxLines: 5,
65
+                  validator: (value) =>
66
+                      (value.isEmpty) ? "Favor Explicar Razon Para La Cita" : null,
67
+                  style: style,
68
+                  decoration: InputDecoration(
69
+                      labelText: "Razones para su cita",
70
+                      border: OutlineInputBorder(borderRadius: BorderRadius.circular(10))),
71
+                ),
72
+              ),
73
+              const SizedBox(height: 10.0),
74
+              ListTile(
75
+                title: Text("Date (YYYY-MM-DD)"),
76
+                subtitle: Text("${_eventDate.year} - ${_eventDate.month} - ${_eventDate.day}"),
77
+                onTap: ()async{
78
+                  DateTime picked = await showDatePicker(context: context, initialDate: _eventDate, firstDate: DateTime(_eventDate.year-5), lastDate: DateTime(_eventDate.year+5));
79
+                  if(picked != null) {
80
+                    setState(() {
81
+                      _eventDate = picked;
82
+                    });
83
+                  }
84
+                },
85
+              ),
86
+
87
+              SizedBox(height: 10.0),
88
+              processing
89
+                  ? Center(child: CircularProgressIndicator())
90
+                  : Padding(
91
+                      padding: const EdgeInsets.symmetric(horizontal: 16.0),
92
+                      child: Material(
93
+                        elevation: 5.0,
94
+                        borderRadius: BorderRadius.circular(30.0),
95
+                        color: Theme.of(context).primaryColor,
96
+                        child: MaterialButton(
97
+                          onPressed: () async {
98
+                            if (_formKey.currentState.validate()) {
99
+                              setState(() {
100
+                                processing = true;
101
+                              });
102
+                              if(widget.note != null) {
103
+                                await eventDBS.updateData(widget.note.id,{
104
+                                  "title": _title.text,
105
+                                  "description": _description.text,
106
+                                  "event_date": widget.note.eventDate
107
+                                });
108
+                              }else{
109
+                                await eventDBS.createItem(EventModel(
110
+                                  title: _title.text,
111
+                                  description: _description.text,
112
+                                  eventDate: _eventDate
113
+                                ));
114
+                              }
115
+                              Navigator.pop(context);
116
+                              setState(() {
117
+                                processing = false;
118
+                              });
119
+                            }
120
+                          },
121
+                          child: Text(
122
+                            "Crear Su Cita Ahora",
123
+                            style: style.copyWith(
124
+                                color: Colors.white,
125
+                                fontWeight: FontWeight.bold),
126
+                          ),
127
+                        ),
128
+                      ),
129
+                    ),
130
+            ],
131
+          ),
132
+        ),
133
+      ),
134
+    );
135
+  }
136
+
137
+  @override
138
+  void dispose() {
139
+    _title.dispose();
140
+    _description.dispose();
141
+    super.dispose();
142
+  }
143
+}

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

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

+ 148
- 3
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.14.3+1"
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: "2.2.0"
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.2.1+1"
39 60
   collection:
40 61
     dependency: transitive
41 62
     description:
@@ -85,6 +106,76 @@ packages:
85 106
       url: "https://pub.dartlang.org"
86 107
     source: hosted
87 108
     version: "5.2.1"
109
+  firebase_auth:
110
+    dependency: "direct main"
111
+    description:
112
+      name: firebase_auth
113
+      url: "https://pub.dartlang.org"
114
+    source: hosted
115
+    version: "0.18.3+1"
116
+  firebase_auth_platform_interface:
117
+    dependency: transitive
118
+    description:
119
+      name: firebase_auth_platform_interface
120
+      url: "https://pub.dartlang.org"
121
+    source: hosted
122
+    version: "2.1.3"
123
+  firebase_auth_web:
124
+    dependency: transitive
125
+    description:
126
+      name: firebase_auth_web
127
+      url: "https://pub.dartlang.org"
128
+    source: hosted
129
+    version: "0.3.2+1"
130
+  firebase_core:
131
+    dependency: "direct main"
132
+    description:
133
+      name: firebase_core
134
+      url: "https://pub.dartlang.org"
135
+    source: hosted
136
+    version: "0.5.2+1"
137
+  firebase_core_platform_interface:
138
+    dependency: transitive
139
+    description:
140
+      name: firebase_core_platform_interface
141
+      url: "https://pub.dartlang.org"
142
+    source: hosted
143
+    version: "2.1.0"
144
+  firebase_core_web:
145
+    dependency: transitive
146
+    description:
147
+      name: firebase_core_web
148
+      url: "https://pub.dartlang.org"
149
+    source: hosted
150
+    version: "0.2.1+1"
151
+  firebase_helpers:
152
+    dependency: "direct main"
153
+    description:
154
+      name: firebase_helpers
155
+      url: "https://pub.dartlang.org"
156
+    source: hosted
157
+    version: "0.2.2"
158
+  firebase_storage:
159
+    dependency: transitive
160
+    description:
161
+      name: firebase_storage
162
+      url: "https://pub.dartlang.org"
163
+    source: hosted
164
+    version: "5.1.0"
165
+  firebase_storage_platform_interface:
166
+    dependency: transitive
167
+    description:
168
+      name: firebase_storage_platform_interface
169
+      url: "https://pub.dartlang.org"
170
+    source: hosted
171
+    version: "1.0.1"
172
+  firebase_storage_web:
173
+    dependency: transitive
174
+    description:
175
+      name: firebase_storage_web
176
+      url: "https://pub.dartlang.org"
177
+    source: hosted
178
+    version: "0.1.1"
88 179
   flushbar:
89 180
     dependency: transitive
90 181
     description:
@@ -109,6 +200,11 @@ packages:
109 200
     description: flutter
110 201
     source: sdk
111 202
     version: "0.0.0"
203
+  flutter_web_plugins:
204
+    dependency: transitive
205
+    description: flutter
206
+    source: sdk
207
+    version: "0.0.0"
112 208
   font_awesome_flutter:
113 209
     dependency: transitive
114 210
     description:
@@ -144,6 +240,13 @@ packages:
144 240
       url: "https://pub.dartlang.org"
145 241
     source: hosted
146 242
     version: "0.16.1"
243
+  js:
244
+    dependency: transitive
245
+    description:
246
+      name: js
247
+      url: "https://pub.dartlang.org"
248
+    source: hosted
249
+    version: "0.6.2"
147 250
   matcher:
148 251
     dependency: transitive
149 252
     description:
@@ -249,6 +352,48 @@ packages:
249 352
       url: "https://pub.dartlang.org"
250 353
     source: hosted
251 354
     version: "2.1.5"
355
+  shared_preferences:
356
+    dependency: "direct main"
357
+    description:
358
+      name: shared_preferences
359
+      url: "https://pub.dartlang.org"
360
+    source: hosted
361
+    version: "0.5.12+4"
362
+  shared_preferences_linux:
363
+    dependency: transitive
364
+    description:
365
+      name: shared_preferences_linux
366
+      url: "https://pub.dartlang.org"
367
+    source: hosted
368
+    version: "0.0.2+4"
369
+  shared_preferences_macos:
370
+    dependency: transitive
371
+    description:
372
+      name: shared_preferences_macos
373
+      url: "https://pub.dartlang.org"
374
+    source: hosted
375
+    version: "0.0.1+11"
376
+  shared_preferences_platform_interface:
377
+    dependency: transitive
378
+    description:
379
+      name: shared_preferences_platform_interface
380
+      url: "https://pub.dartlang.org"
381
+    source: hosted
382
+    version: "1.0.4"
383
+  shared_preferences_web:
384
+    dependency: transitive
385
+    description:
386
+      name: shared_preferences_web
387
+      url: "https://pub.dartlang.org"
388
+    source: hosted
389
+    version: "0.1.2+7"
390
+  shared_preferences_windows:
391
+    dependency: transitive
392
+    description:
393
+      name: shared_preferences_windows
394
+      url: "https://pub.dartlang.org"
395
+    source: hosted
396
+    version: "0.0.1+3"
252 397
   simple_gesture_detector:
253 398
     dependency: transitive
254 399
     description:
@@ -295,7 +440,7 @@ packages:
295 440
       name: table_calendar
296 441
       url: "https://pub.dartlang.org"
297 442
     source: hosted
298
-    version: "2.3.0"
443
+    version: "2.3.1"
299 444
   term_glyph:
300 445
     dependency: transitive
301 446
     description:
@@ -337,7 +482,7 @@ packages:
337 482
       name: win32
338 483
       url: "https://pub.dartlang.org"
339 484
     source: hosted
340
-    version: "1.7.3"
485
+    version: "1.7.4"
341 486
   xdg_directories:
342 487
     dependency: transitive
343 488
     description:
@@ -347,4 +492,4 @@ packages:
347 492
     version: "0.1.2"
348 493
 sdks:
349 494
   dart: ">=2.10.0-110 <2.11.0"
350
-  flutter: ">=1.17.0 <2.0.0"
495
+  flutter: ">=1.20.0 <2.0.0"

+ 7
- 1
fast_med_flutter/pubspec.yaml View File

@@ -24,11 +24,17 @@ dependencies:
24 24
   flutter:
25 25
     sdk: flutter
26 26
 
27
+  firebase_helpers: ^0.2.0
28
+  firebase_auth: ^0.18.0+1
29
+  cloud_firestore: ^0.14.0
30
+  firebase_core: ^0.5.0
31
+  #cloud_firestore: ^0.14.0
27 32
 
28 33
   # The following adds the Cupertino Icons font to your application.
29 34
   # Use with the CupertinoIcons class for iOS style icons.
30 35
   cupertino_icons: ^1.0.0
31
-  table_calendar: ^2,0,1
36
+  table_calendar: ^2.2.3
37
+  shared_preferences: ^0.5.4+5
32 38
   flutter_login: ^1.0.14
33 39
   google_fonts: ^1.1.1
34 40