Explorar el Código

Merge remote-tracking branch 'origin/Sprint1Jorge' into sprint1

Oniel Mendez hace 4 años
padre
commit
6371131537

+ 19
- 2
fast_med_flutter/android/app/build.gradle Ver fichero

@@ -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 Ver fichero

@@ -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 Ver fichero

@@ -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 Ver fichero

@@ -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 Ver fichero

@@ -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 Ver fichero

@@ -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
+}

+ 43
- 34
fast_med_flutter/lib/routes/calendario.dart Ver fichero

@@ -2,19 +2,22 @@ import 'package:flutter/material.dart';
2 2
 import 'package:intl/date_symbol_data_local.dart';
3 3
 import 'package:table_calendar/table_calendar.dart';
4 4
 
5
-// Dias sin Citas Disponibles
5
+// Dias de Citas No Disponibles
6 6
 final Map<DateTime, List> _holidays = {
7 7
   DateTime(2020, 11, 6): ['No Hay Citas'],
8 8
   DateTime(2020, 11, 3): ['Dia Elecciones'],
9
+  DateTime(2020,12,25): ['Chrismas'],
10
+  DateTime(2020,12,31): ['Despedida del anyo nuevo'],
9 11
 
10 12
 };
11 13
 
14
+//Iniciar la Seccion de las Citas
12 15
 void main() {
13 16
   initializeDateFormatting().then((_) => runApp(Calendario()));
14 17
 }
15 18
 
16 19
 
17
-
20
+//Inicio del Area de las Citas Disponibles
18 21
 class Calendario extends StatelessWidget {
19 22
   @override
20 23
   Widget build(BuildContext context) {
@@ -37,26 +40,30 @@ class MyHomePage extends StatefulWidget {
37 40
   _MyHomePageState createState() => _MyHomePageState();
38 41
 }
39 42
 
43
+//Definimos los controladores del Calendario
40 44
 class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
41 45
   Map<DateTime, List> _events;
42 46
   List _selectedEvents;
43 47
   AnimationController _animationController;
44 48
   CalendarController _calendarController;
49
+  Map<DateTime,List<dynamic>> _events2;
45 50
 
51
+//Definimos el dia elegido
46 52
   @override
47 53
   void initState() {
48 54
     super.initState();
49 55
     final _selectedDay = DateTime.now();
50 56
 
51 57
     _events = {
52
-
58
+    //Ejemplos de Citas Previamente Hechas de Prueba Para los Recordatorios
53 59
       _selectedDay.add(Duration(days: 3)): Set.from([ 'Cita Cardiologo', 'Cita Dentista']).toList(),
54 60
       _selectedDay.add(Duration(days: 22)): ['Cita Cardiologo', 'Cita Dentista'],
55 61
 
56 62
     };
57
-
63
+    //Dias de Citas Seleccionados como Recordatorio
58 64
     _selectedEvents = _events[_selectedDay] ?? [];
59 65
     _calendarController = CalendarController();
66
+    _events2 = {};
60 67
 
61 68
     _animationController = AnimationController(
62 69
       vsync: this,
@@ -66,13 +73,31 @@ class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
66 73
     _animationController.forward();
67 74
   }
68 75
 
76
+  Map<String,dynamic> encodeMap(Map<DateTime,dynamic> map) {
77
+    Map<String,dynamic> newMap = {};
78
+    map.forEach((key,value) {
79
+      newMap[key.toString()] = map[key];
80
+    });
81
+    return newMap;
82
+  }
83
+
84
+  Map<DateTime,dynamic> decodeMap(Map<String,dynamic> map) {
85
+    Map<DateTime,dynamic> newMap = {};
86
+    map.forEach((key,value) {
87
+      newMap[DateTime.parse(key)] = map[key];
88
+    });
89
+    return newMap;
90
+  }
91
+
92
+
93
+
69 94
   @override
70 95
   void dispose() {
71 96
     _animationController.dispose();
72 97
     _calendarController.dispose();
73 98
     super.dispose();
74 99
   }
75
-
100
+//Acciones definidas cuando se elige un dia en particular para ver si esta disponible o no
76 101
   void _onDaySelected(DateTime day, List events, List holidays) {
77 102
     print('CALLBACK: _onDaySelected');
78 103
     setState(() {
@@ -87,7 +112,7 @@ class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
87 112
   void _onCalendarCreated(DateTime first, DateTime last, CalendarFormat format) {
88 113
     print('CALLBACK: _onCalendarCreated');
89 114
   }
90
-
115
+//Definimos el "look" del area de las citas
91 116
   @override
92 117
   Widget build(BuildContext context) {
93 118
     return Scaffold(
@@ -97,9 +122,10 @@ class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
97 122
       body: Column(
98 123
         mainAxisSize: MainAxisSize.max,
99 124
         children: <Widget>[
100
-          // Switch out 2 lines below to play with TableCalendar's settings
101
-          //-----------------------
102
-          _buildTableCalendar(),
125
+
126
+          _buildTableCalendar(
127
+
128
+          ),
103 129
           // _buildTableCalendarWithBuilders(),
104 130
           const SizedBox(height: 8.0),
105 131
           _buildButtons(),
@@ -109,26 +135,8 @@ class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
109 135
       ),
110 136
     );
111 137
   }
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 138
 
131
-  // Simple TableCalendar configuration (using Styles)
139
+  // Simple configuracion de la Tabla de Calendario usando estilos
132 140
   Widget _buildTableCalendar() {
133 141
     return TableCalendar(
134 142
       calendarController: _calendarController,
@@ -153,9 +161,8 @@ class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
153 161
       onCalendarCreated: _onCalendarCreated,
154 162
     );
155 163
   }
156
-
157
-  // More advanced TableCalendar configuration (using Builders & Styles)
158
-  Widget _buildTableCalendarWithBuilders() {
164
+  // Configuraciones detalladas del area de citas como definir dias, meses, etc.
165
+  Widget buildTableCalendarWithBuilders() {
159 166
     return TableCalendar(
160 167
       locale: 'pl_PL',
161 168
       calendarController: _calendarController,
@@ -169,6 +176,7 @@ class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
169 176
         CalendarFormat.month: '',
170 177
         CalendarFormat.week: '',
171 178
       },
179
+      //Colores de los dias seleccionados
172 180
       calendarStyle: CalendarStyle(
173 181
         outsideDaysVisible: false,
174 182
         weekendStyle: TextStyle().copyWith(color: Colors.blue),
@@ -183,6 +191,7 @@ class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
183 191
       ),
184 192
       builders: CalendarBuilders(
185 193
         selectedDayBuilder: (context, date, _) {
194
+          //Animacion del Calendario al cambiar el mes
186 195
           return FadeTransition(
187 196
             opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController),
188 197
             child: Container(
@@ -245,7 +254,7 @@ class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
245 254
       onCalendarCreated: _onCalendarCreated,
246 255
     );
247 256
   }
248
-
257
+//Marcador de eventos (aparece debajo de los dias)
249 258
   Widget _buildEventsMarker(DateTime date, List events) {
250 259
     return AnimatedContainer(
251 260
       duration: const Duration(milliseconds: 300),
@@ -279,7 +288,7 @@ class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
279 288
 
280 289
   Widget _buildButtons() {
281 290
     final dateTime = _events.keys.elementAt(_events.length - 2);
282
-
291
+  //Definimos formato del calendario (mes, 2 semanas, semana)
283 292
     return Column(
284 293
       children: <Widget>[
285 294
         Row(
@@ -326,7 +335,7 @@ class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
326 335
     );
327 336
   }
328 337
 
329
-
338
+  //Muestra las citas ya creadas
330 339
   Widget _buildEventList() {
331 340
     return ListView(
332 341
       children: _selectedEvents

+ 1
- 1
fast_med_flutter/lib/routes/home.dart Ver fichero

@@ -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 Ver fichero

@@ -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 Ver fichero

@@ -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
 

+ 62
- 0
fast_med_flutter/lib/widgets/date_time_picker_widget.dart Ver fichero

@@ -0,0 +1,62 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:intl/intl.dart';
3
+
4
+class DateTimePickerWidget extends StatefulWidget {
5
+  @override
6
+  _DateTimePickerWidgetState createState() => _DateTimePickerWidgetState();
7
+}
8
+
9
+class _DateTimePickerWidgetState extends State<DateTimePickerWidget> {
10
+  DateTime selectedDate = DateTime.now();
11
+
12
+  final DateFormat dateFormat = DateFormat('yyyy-MM-dd HH:mm');
13
+
14
+  @override
15
+  Widget build(BuildContext context) {
16
+    return Column(
17
+      mainAxisAlignment: MainAxisAlignment.center,
18
+      children: <Widget>[
19
+        Text(dateFormat.format(selectedDate)),
20
+        RaisedButton(
21
+          child: Text('Choose new date time'),
22
+          onPressed: () async {
23
+            final selectedDate = await _selectDateTime(context);
24
+            if (selectedDate == null) return;
25
+
26
+            print(selectedDate);
27
+
28
+            final selectedTime = await _selectTime(context);
29
+            if (selectedTime == null) return;
30
+            print(selectedTime);
31
+
32
+            setState(() {
33
+              this.selectedDate = DateTime(
34
+                selectedDate.year,
35
+                selectedDate.month,
36
+                selectedDate.day,
37
+                selectedTime.hour,
38
+                selectedTime.minute,
39
+              );
40
+            });
41
+          },
42
+        ),
43
+      ],
44
+    );
45
+  }
46
+
47
+  Future<TimeOfDay> _selectTime(BuildContext context) {
48
+    final now = DateTime.now();
49
+
50
+    return showTimePicker(
51
+      context: context,
52
+      initialTime: TimeOfDay(hour: now.hour, minute: now.minute),
53
+    );
54
+  }
55
+
56
+  Future<DateTime> _selectDateTime(BuildContext context) => showDatePicker(
57
+        context: context,
58
+        initialDate: DateTime.now().add(Duration(seconds: 1)),
59
+        firstDate: DateTime.now(),
60
+        lastDate: DateTime(2100),
61
+      );
62
+}

+ 35
- 0
fast_med_flutter/lib/widgets/date_time_picker_widget2.dart Ver fichero

@@ -0,0 +1,35 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:intl/intl.dart';
3
+import 'package:fast_med_flutter/widgets/notifcation_dialog.dart';
4
+
5
+class DateTimePickerWidget2 extends StatefulWidget {
6
+  @override
7
+  _DateTimePickerWidget2State createState() => _DateTimePickerWidget2State();
8
+}
9
+
10
+class _DateTimePickerWidget2State extends State<DateTimePickerWidget2> {
11
+  DateTime selectedDate = DateTime.now();
12
+
13
+  final DateFormat dateFormat = DateFormat('yyyy-MM-dd HH:mm');
14
+
15
+  @override
16
+  Widget build(BuildContext context) {
17
+    return Column(
18
+      mainAxisAlignment: MainAxisAlignment.center,
19
+      children: <Widget>[
20
+        Text(dateFormat.format(selectedDate)),
21
+        RaisedButton(
22
+          child: Text('Choose new date time'),
23
+          onPressed: () async {
24
+            showDateTimeDialog(context, initialDate: selectedDate,
25
+                onSelectedDate: (selectedDate) {
26
+              setState(() {
27
+                this.selectedDate = selectedDate;
28
+              });
29
+            });
30
+          },
31
+        ),
32
+      ],
33
+    );
34
+  }
35
+}

+ 132
- 0
fast_med_flutter/lib/widgets/notifcation_dialog.dart Ver fichero

@@ -0,0 +1,132 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:intl/intl.dart';
3
+
4
+Future<TimeOfDay> _selectTime(BuildContext context,
5
+    {@required DateTime initialDate}) {
6
+  final now = DateTime.now();
7
+
8
+  return showTimePicker(
9
+    context: context,
10
+    initialTime: TimeOfDay(hour: initialDate.hour, minute: initialDate.minute),
11
+  );
12
+}
13
+
14
+Future<DateTime> _selectDateTime(BuildContext context,
15
+    {@required DateTime initialDate}) {
16
+  final now = DateTime.now();
17
+  final newestDate = initialDate.isAfter(now) ? initialDate : now;
18
+
19
+  return showDatePicker(
20
+    context: context,
21
+    initialDate: newestDate.add(Duration(seconds: 1)),
22
+    firstDate: now,
23
+    lastDate: DateTime(2100),
24
+  );
25
+}
26
+
27
+Dialog showDateTimeDialog(
28
+  BuildContext context, {
29
+  @required ValueChanged<DateTime> onSelectedDate,
30
+  @required DateTime initialDate,
31
+}) {
32
+  final dialog = Dialog(
33
+    child: DateTimeDialog(
34
+        onSelectedDate: onSelectedDate, initialDate: initialDate),
35
+  );
36
+
37
+  showDialog(context: context, builder: (BuildContext context) => dialog);
38
+}
39
+
40
+class DateTimeDialog extends StatefulWidget {
41
+  final ValueChanged<DateTime> onSelectedDate;
42
+  final DateTime initialDate;
43
+
44
+  const DateTimeDialog({
45
+    @required this.onSelectedDate,
46
+    @required this.initialDate,
47
+    Key key,
48
+  }) : super(key: key);
49
+  @override
50
+  _DateTimeDialogState createState() => _DateTimeDialogState();
51
+}
52
+
53
+class _DateTimeDialogState extends State<DateTimeDialog> {
54
+  DateTime selectedDate;
55
+
56
+  @override
57
+  void initState() {
58
+    super.initState();
59
+
60
+    selectedDate = widget.initialDate;
61
+  }
62
+
63
+  @override
64
+  Widget build(BuildContext context) => Padding(
65
+        padding: const EdgeInsets.all(16),
66
+        child: Column(
67
+          mainAxisAlignment: MainAxisAlignment.center,
68
+          mainAxisSize: MainAxisSize.min,
69
+          children: <Widget>[
70
+            Text(
71
+              'Select time',
72
+              style: Theme.of(context).textTheme.title,
73
+            ),
74
+            const SizedBox(height: 16),
75
+            Row(
76
+              mainAxisAlignment: MainAxisAlignment.center,
77
+              children: <Widget>[
78
+                RaisedButton(
79
+                  child: Text(DateFormat('yyyy-MM-dd').format(selectedDate)),
80
+                  onPressed: () async {
81
+                    final date = await _selectDateTime(context,
82
+                        initialDate: selectedDate);
83
+                    if (date == null) return;
84
+
85
+                    setState(() {
86
+                      selectedDate = DateTime(
87
+                        date.year,
88
+                        date.month,
89
+                        date.day,
90
+                        selectedDate.hour,
91
+                        selectedDate.minute,
92
+                      );
93
+                    });
94
+
95
+                    widget.onSelectedDate(selectedDate);
96
+                  },
97
+                ),
98
+                const SizedBox(width: 8),
99
+                RaisedButton(
100
+                  child: Text(DateFormat('HH:mm').format(selectedDate)),
101
+                  onPressed: () async {
102
+                    final time =
103
+                        await _selectTime(context, initialDate: selectedDate);
104
+                    if (time == null) return;
105
+
106
+                    setState(() {
107
+                      selectedDate = DateTime(
108
+                        selectedDate.year,
109
+                        selectedDate.month,
110
+                        selectedDate.day,
111
+                        time.hour,
112
+                        time.minute,
113
+                      );
114
+                    });
115
+
116
+                    widget.onSelectedDate(selectedDate);
117
+                  },
118
+                ),
119
+              ],
120
+            ),
121
+            const SizedBox(height: 16),
122
+            OutlineButton(
123
+              child: Text('Schedule!'),
124
+              onPressed: () {
125
+                Navigator.of(context).pop();
126
+              },
127
+              highlightColor: Colors.orange,
128
+            ),
129
+          ],
130
+        ),
131
+      );
132
+}

+ 148
- 3
fast_med_flutter/pubspec.lock Ver fichero

@@ -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 Ver fichero

@@ -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