소스 검색

Merge remote-tracking branch 'origin/Sprint2Jorge' into sprint2

Oniel Mendez 3 년 전
부모
커밋
0a98d02ff1

+ 19
- 2
fast_med_flutter/android/app/build.gradle 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -20,4 +20,4 @@ void main() => runApp(MaterialApp(
20 20
           '/MyApp': (context) => MyApp(),
21 21
           '/album': (context) => album(),
22 22
     }
23
-));
23
+));

+ 36
- 0
fast_med_flutter/lib/model/event.dart 파일 보기

@@ -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 파일 보기

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

+ 155
- 288
fast_med_flutter/lib/routes/calendario.dart 파일 보기

@@ -1,19 +1,25 @@
1
+import 'dart:convert';
1 2
 import 'package:flutter/material.dart';
2
-import 'package:intl/date_symbol_data_local.dart';
3
+import 'package:shared_preferences/shared_preferences.dart';
3 4
 import 'package:table_calendar/table_calendar.dart';
5
+import 'package:fast_med_flutter/ui/pages/add_event.dart';
6
+import 'model/event.dart';
4 7
 
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'],
8
+// Dias de Citas No Disponibles
9 9
 
10
+final Map<DateTime, List> _holidays = {
11
+DateTime(2020, 11, 6): ['No Hay Citas'],
12
+DateTime(2020, 11, 3): ['Dia Elecciones'],
13
+DateTime(2020,12,25): ['Chrismas'],
14
+DateTime(2020,12,31): ['Despedida del anyo nuevo'],
15
+  DateTime(2021,1,1): ['Anyo nuevo'],
10 16
 };
11 17
 
12
-void main() {
13
-  initializeDateFormatting().then((_) => runApp(Calendario()));
14
-}
18
+//Iniciar la Seccion de las Citas
15 19
 
20
+void main() => runApp(Calendario());
16 21
 
22
+//Inicio del Area de las Citas Disponibles
17 23
 
18 24
 class Calendario extends StatelessWidget {
19 25
   @override
@@ -23,325 +29,186 @@ class Calendario extends StatelessWidget {
23 29
       theme: ThemeData(
24 30
         primarySwatch: Colors.blue,
25 31
       ),
26
-      home: MyHomePage(title: 'Citas Disponibles'),
32
+      home: MyHomePage(),
33
+      routes:{
34
+        "add_event": (_) => AddEventPage(),
35
+      },
27 36
     );
28 37
   }
29 38
 }
30 39
 
31 40
 class MyHomePage extends StatefulWidget {
32
-  MyHomePage({Key key, this.title}) : super(key: key);
33
-
34
-  final String title;
35
-
36 41
   @override
37
-  _MyHomePageState createState() => _MyHomePageState();
42
+  _HomePageState createState() => _HomePageState();
38 43
 }
39 44
 
40
-class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
41
-  Map<DateTime, List> _events;
42
-  List _selectedEvents;
43
-  AnimationController _animationController;
44
-  CalendarController _calendarController;
45
-
46
-  @override
47
-  void initState() {
48
-    super.initState();
49
-    final _selectedDay = DateTime.now();
45
+//Definimos los controladores del Calendario
50 46
 
51
-    _events = {
47
+class _HomePageState extends State<MyHomePage> {
48
+  CalendarController _controller;
49
+  Map<DateTime, List<dynamic>> _events;
50
+  List<dynamic> _selectedEvents;
51
+  TextEditingController _eventController;
52
+  SharedPreferences prefs;
52 53
 
53
-      _selectedDay.add(Duration(days: 3)): Set.from([ 'Cita Cardiologo', 'Cita Dentista']).toList(),
54
-      _selectedDay.add(Duration(days: 22)): ['Cita Cardiologo', 'Cita Dentista'],
55 54
 
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 55
 
69 56
   @override
70
-  void dispose() {
71
-    _animationController.dispose();
72
-    _calendarController.dispose();
73
-    super.dispose();
57
+  void initState() {
58
+    super.initState();
59
+    _controller = CalendarController();
60
+    _eventController = TextEditingController();
61
+    _events = {};
62
+    _selectedEvents = [];
63
+    final _selectedDay = DateTime.now();
64
+    initPrefs();
74 65
   }
75 66
 
76
-  void _onDaySelected(DateTime day, List events, List holidays) {
77
-    print('CALLBACK: _onDaySelected');
67
+  initPrefs() async {
68
+    prefs = await SharedPreferences.getInstance();
78 69
     setState(() {
79
-      _selectedEvents = events;
70
+      _events = Map<DateTime, List<dynamic>>.from(
71
+          decodeMap(json.decode(prefs.getString("events") ?? "{}")));
72
+    });
73
+  }
74
+  // Definimos las fechas en la area de citas
75
+
76
+  Map<DateTime, List<dynamic>> _groupEvents(List<EventModel> events) {
77
+    Map<DateTime,List<dynamic>> data = {};
78
+    events.forEach((event) {
79
+      DateTime date = DateTime(event.eventDate.year, event.eventDate.month,
80
+          event.eventDate.day, 12);
81
+      if(data[date] == null) data[date] = [];
82
+      data[date].add(event);
80 83
     });
84
+    return data;
81 85
   }
82 86
 
83
-  void _onVisibleDaysChanged(DateTime first, DateTime last, CalendarFormat format) {
84
-    print('CALLBACK: _onVisibleDaysChanged');
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;
85 93
   }
86 94
 
87
-  void _onCalendarCreated(DateTime first, DateTime last, CalendarFormat format) {
88
-    print('CALLBACK: _onCalendarCreated');
95
+  Map<DateTime, dynamic> decodeMap(Map<String, dynamic> map) {
96
+    Map<DateTime, dynamic> newMap = {};
97
+    map.forEach((key, value) {
98
+      newMap[DateTime.parse(key)] = map[key];
99
+    });
100
+    return newMap;
89 101
   }
90 102
 
103
+
104
+//Definimos el estilo del area de las Citas Disponibles.
105
+  //En este ejemplo, el calendario comenzara mostrandose por meses.
91 106
   @override
92 107
   Widget build(BuildContext context) {
93 108
     return Scaffold(
94 109
       appBar: AppBar(
95
-        title: Text(widget.title),
110
+        title: Text('Citas Disponibles'),
96 111
       ),
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(
112
+      body: SingleChildScrollView(
113
+        child: Column(
114
+          crossAxisAlignment: CrossAxisAlignment.start,
119 115
           children: <Widget>[
120
-            Container(
121
-              padding: EdgeInsets.only(left: 0, top:10, bottom: 10),
122
-              child: Icon(Icons.arrow_back_ios, color: Colors.black),
116
+            TableCalendar(
117
+              events: _events,
118
+              holidays: _holidays,
119
+              initialCalendarFormat: CalendarFormat.month,
120
+              calendarStyle: CalendarStyle(
121
+                  canEventMarkersOverflow: true,
122
+                  todayColor: Colors.orange,
123
+                  selectedColor: Theme.of(context).primaryColor,
124
+                  todayStyle: TextStyle(
125
+                      fontWeight: FontWeight.bold,
126
+                      fontSize: 18.0,
127
+                      color: Colors.white)),
128
+              headerStyle: HeaderStyle(
129
+                centerHeaderTitle: true,
130
+                formatButtonDecoration: BoxDecoration(
131
+                  color: Colors.orange,
132
+                  borderRadius: BorderRadius.circular(20.0),
133
+                ),
134
+                formatButtonTextStyle: TextStyle(color: Colors.white),
135
+                formatButtonShowsNext: false,
136
+              ),
137
+              startingDayOfWeek: StartingDayOfWeek.monday,
138
+
139
+              builders: CalendarBuilders(
140
+                selectedDayBuilder: (context, date, events) => Container(
141
+                    margin: const EdgeInsets.all(4.0),
142
+                    alignment: Alignment.center,
143
+                    decoration: BoxDecoration(
144
+                        color: Theme.of(context).primaryColor,
145
+                        borderRadius: BorderRadius.circular(10.0)),
146
+                    child: Text(
147
+                      date.day.toString(),
148
+                      style: TextStyle(color: Colors.white),
149
+                    )),
150
+                todayDayBuilder: (context, date, events) => Container(
151
+                    margin: const EdgeInsets.all(4.0),
152
+                    alignment: Alignment.center,
153
+                    decoration: BoxDecoration(
154
+                        color: Colors.orange,
155
+                        borderRadius: BorderRadius.circular(10.0)),
156
+                    child: Text(
157
+                      date.day.toString(),
158
+                      style: TextStyle(color: Colors.white),
159
+                    )),
160
+              ),
161
+              calendarController: _controller,
123 162
             ),
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),
163
+            ..._selectedEvents.map((event) => ListTile(
164
+              title: Text(event),
165
+            )),
166
+          ],
149 167
         ),
150 168
       ),
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),
169
+      floatingActionButton: FloatingActionButton(
170
+        child: Icon(Icons.add),
171
+        onPressed: _showAddDialog,
179 172
       ),
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(),
233
-              ),
234
-            );
235
-          }
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 173
     );
247 174
   }
248 175
 
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,
176
+  //Definimos el boton para crear Citas.
177
+
178
+  _showAddDialog() async {
179
+    await showDialog(
180
+        context: context,
181
+        builder: (context) => AlertDialog(
182
+          content: TextField(
183
+            controller: _eventController,
184
+            decoration: InputDecoration(
185
+                labelText: "Razon para crear su cita",
186
+                filled: true,
187
+                fillColor: Colors.white,
188
+                border: OutlineInputBorder(borderRadius: BorderRadius.circular(10))),
266 189
           ),
267
-        ),
268
-      ),
269
-    );
270
-  }
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'),
190
+          actions: <Widget>[
191
+            FlatButton(
192
+              child: Text("Crear Su Cita Ahora"),
299 193
               onPressed: () {
300
-                setState(() {
301
-                  _calendarController.setCalendarFormat(CalendarFormat.twoWeeks);
302
-                });
194
+                if (_eventController.text.isEmpty) return;
195
+                if (_events[_controller.selectedDay] != null) {
196
+                  _events[_controller.selectedDay]
197
+                      .add(_eventController.text);
198
+                } else {
199
+                  _events[_controller.selectedDay] = [
200
+                    _eventController.text
201
+                  ];
202
+                }
203
+                prefs.setString("events", json.encode(encodeMap(_events)));
204
+                _eventController.clear();
205
+                Navigator.pop(context);
303 206
               },
304
-            ),
305
-            RaisedButton(
306
-              child: Text('Semana'),
307
-              onPressed: () {
308
-                setState(() {
309
-                  _calendarController.setCalendarFormat(CalendarFormat.week);
310
-                });
311
-              },
312
-            ),
207
+            )
313 208
           ],
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
-    );
209
+        ));
210
+    setState(() {
211
+      _selectedEvents = _events[_controller.selectedDay];
212
+    });
346 213
   }
347 214
 }

+ 67
- 12
fast_med_flutter/lib/routes/home.dart 파일 보기

@@ -21,18 +21,73 @@ class _HomeState extends State<Home>{
21 21
         child: ListView(
22 22
           //mainAxisAlignment: MainAxisAlignment.spaceEvenly,
23 23
           children: [
24
-            newButton(context,'/verOficinas','Ver Oficinas'),
25
-            spaceBetween(),
26
-            // newButton(context,'/calendario','Calendario'),
27
-            // spaceBetween(),
28
-            // newButton(context,'/register','Register'),
29
-            // spaceBetween(),
30
-            // newButton(context,'/welcome','Welcome'),
31
-            // spaceBetween(),
32
-            // newButton(context,'/MyApp','MyApp'),
33
-            // spaceBetween(),
34
-            // newButton(context,'/album','Ver Oficinas 2: electr'),
35
-            // spaceBetween(),
24
+
25
+          //estos dos estaban sin comentar originalmente
26
+          //newButton(context,'/verOficinas','Ver Oficinas'),
27
+          //spaceBetween(),
28
+
29
+          //aqui comienza lo que merge
30
+            new FlatButton(
31
+              minWidth: 300.0,
32
+              height: 100.0,
33
+              onPressed: (){
34
+                Navigator.pushNamed(context, '/verOficinas');
35
+              },
36
+              child: Text('Ver Oficinas',
37
+                style: TextStyle(fontSize: 36),
38
+              ),
39
+              color: Colors.purple,
40
+
41
+            ),
42
+            new FlatButton(
43
+              minWidth: 300.0,
44
+              height: 100.0,
45
+              onPressed: (){
46
+                Navigator.pushNamed(context, '/calendario');
47
+              },
48
+              child: Text('Buscar Citas',
49
+                style: TextStyle(fontSize: 36),
50
+              ),
51
+              color: Colors.purple,
52
+
53
+            ),
54
+            new FlatButton(
55
+              minWidth: 300.0,
56
+              height: 100.0,
57
+              onPressed: (){
58
+                Navigator.pushNamed(context, '/register');
59
+              },
60
+              child: Text('register',
61
+                style: TextStyle(fontSize: 36),
62
+              ),
63
+              color: Colors.purple,
64
+
65
+            ),
66
+            new FlatButton(
67
+              minWidth: 300.0,
68
+              height: 100.0,
69
+              onPressed: (){
70
+                Navigator.pushNamed(context, '/welcome');
71
+              },
72
+              child: Text('welcome',
73
+                style: TextStyle(fontSize: 36),
74
+              ),
75
+              color: Colors.purple,
76
+
77
+            ),
78
+            new FlatButton(
79
+              minWidth: 300.0,
80
+              height: 100.0,
81
+              onPressed: (){
82
+                Navigator.pushNamed(context, '/MyApp');
83
+              },
84
+              child: Text('MyApp',
85
+                style: TextStyle(fontSize: 36),
86
+              ),
87
+              color: Colors.purple,
88
+
89
+            ),
90
+            //aqui termina lo que merge
36 91
             ],
37 92
         ),
38 93
 

+ 38
- 0
fast_med_flutter/lib/routes/model/event.dart 파일 보기

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

+ 0
- 1
fast_med_flutter/lib/routes/register.dart 파일 보기

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

+ 145
- 0
fast_med_flutter/lib/ui/pages/add_event.dart 파일 보기

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

+ 62
- 0
fast_med_flutter/lib/widgets/date_time_picker_widget.dart 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

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

+ 0
- 33
hector/main.dart 파일 보기

@@ -1,33 +0,0 @@
1
-
2
-import 'package:flutter/cupertino.dart';
3
-import 'package:flutter_login/flutter_login.dart';
4
-import 'package:flutter/material.dart';
5
-import 'package:google_fonts/google_fonts.dart';
6
-import 'register.dart';
7
-import 'welcome.dart';
8
-
9
-// import 'dashboard_screen.dart';
10
-
11
-
12
-
13
-void main() =>  runApp(MyApp());
14
-
15
-
16
-
17
-class MyApp extends StatelessWidget{
18
-  
19
-  static const String title = "FastMed";
20
-
21
-  @override
22
-  Widget build(BuildContext context){
23
-    final textTheme = Theme.of(context).textTheme;
24
-    return MaterialApp(
25
-      title: title,
26
-      theme: ThemeData(
27
-        textTheme: GoogleFonts.cabinTextTheme(textTheme),
28
-        ),
29
-      home: WelcomePage(),
30
-    );
31
-  }
32
-
33
-}

+ 0
- 161
hector/register.dart 파일 보기

@@ -1,161 +0,0 @@
1
-import 'package:flutter_login/flutter_login.dart';
2
-import 'package:flutter/material.dart';
3
-import 'package:google_fonts/google_fonts.dart';
4
-
5
-//
6
-//Still to add: 
7
-//  Email verification, that the input has "@" and "."
8
-//  Send email and password to database
9
-//
10
-//
11
-//
12
-
13
-class RegisterPage extends StatefulWidget{
14
-  
15
-  RegisterPage({Key key, this.title}) : super(key: key);
16
-  final String title;
17
-
18
-  @override
19
-  _RegisterPageState createState() => _RegisterPageState();
20
-}
21
-
22
-class _RegisterPageState extends State<RegisterPage> {
23
-
24
-  TextEditingController email;
25
-  TextEditingController password;
26
-  TextEditingController confirmpass;
27
-
28
-  // Future<List> send_data() async {
29
-  //   final data = await
30
-  // }
31
-
32
-  String _SamePass(){
33
-    if(password == confirmpass){
34
-      return "Same password";
35
-    }
36
-    else{
37
-      return "Different passwords";
38
-    }
39
-  }
40
-
41
-  Widget _BackButton(BuildContext context){
42
-    return InkWell(
43
-      onTap: (){
44
-        Navigator.pop(context);
45
-      },
46
-      child: Row(
47
-        children: <Widget>[
48
-          Container(
49
-            padding: EdgeInsets.only(left: 0, top: 10, bottom: 10),
50
-            child: Icon(Icons.arrow_back_ios, color: Colors.black),
51
-          ),
52
-          Text("Back",
53
-          style: TextStyle(fontSize: 12, fontWeight: FontWeight.w500))
54
-        ]
55
-      ),
56
-    );
57
-  }
58
-
59
-  Widget _SubmitButton(BuildContext context){
60
-    return InkWell(
61
-       onTap: (){
62
-
63
-       },
64
-      child: Container(
65
-        padding: EdgeInsets.symmetric(vertical: 10),
66
-        width: 250,
67
-        alignment: Alignment.center,
68
-        decoration: BoxDecoration(
69
-          color: Colors.red,
70
-          borderRadius: BorderRadius.circular(30),
71
-        ),
72
-        child: Text(
73
-          "Submit",
74
-          style: TextStyle(fontSize: 22, color: Colors.white),
75
-        ),
76
-      ),
77
-    );
78
-  }
79
-
80
-  Widget _EntryField(String title, TextEditingController controller, {bool pass = false}){
81
-    return Container(
82
-      padding: EdgeInsets.only(left: 0, top: 10, bottom: 10),
83
-      child: Column(
84
-        crossAxisAlignment: CrossAxisAlignment.start,
85
-      
86
-        children: <Widget> [
87
-          Text(
88
-            title,
89
-            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
90
-          ),
91
-          SizedBox(
92
-            height: 30
93
-          ),
94
-          TextField(
95
-            controller: controller,
96
-            obscureText: pass,
97
-            decoration: InputDecoration(
98
-              border: (
99
-                  UnderlineInputBorder()
100
-              ),
101
-            ),
102
-          )
103
-        ]
104
-      ),
105
-      
106
-    );
107
-  }
108
-
109
-  Widget _Fills(){
110
-    return Column(
111
-      children: <Widget> [
112
-      _EntryField("Email", email),
113
-      _EntryField("Password", password, pass: true),
114
-      _EntryField("Confirm Password", confirmpass, pass: true)
115
-    
116
-    ]
117
-    );
118
-  }
119
-
120
-//add column or stack
121
-  @override
122
-  Widget build(BuildContext context) {
123
-    final height = MediaQuery.of(context).size.height;
124
-    return Scaffold(
125
-      body: Container(
126
-        height: height,
127
-        child: Stack(
128
-          
129
-          children: <Widget>[
130
-            Container(
131
-              padding: EdgeInsets.symmetric(horizontal: 20),
132
-              child: SingleChildScrollView(
133
-                child: Column(
134
-                  crossAxisAlignment: CrossAxisAlignment.center,
135
-                  mainAxisAlignment: MainAxisAlignment.center,
136
-                  children: <Widget>[
137
-                     SizedBox(
138
-                      height: 200,
139
-                    ),
140
-                    _Fills(),
141
-                    //Add code to verify if password and confirm password match
142
-                    SizedBox(
143
-                      height: 20,
144
-                    ),
145
-                    _SubmitButton(context),
146
-                  ],
147
-                ),
148
-              )
149
-            ),
150
-            Positioned(
151
-            top: 12, left: 20, child: _BackButton(context),
152
-          ),
153
-          ],
154
-          
155
-        ),
156
-      )
157
-    );
158
-  }
159
-    
160
-}
161
-

+ 0
- 201
hector/welcome.dart 파일 보기

@@ -1,201 +0,0 @@
1
-
2
-
3
-import 'package:flutter_login/flutter_login.dart';
4
-import 'package:flutter/material.dart';
5
-import 'package:google_fonts/google_fonts.dart';
6
-import 'register.dart';
7
-
8
-
9
-
10
-
11
-
12
-class WelcomePage extends StatefulWidget {
13
-  WelcomePage({Key key, this.title}) : super(key: key);
14
-
15
-  final String title;
16
-
17
-  @override
18
-  _WelcomePageState createState() => _WelcomePageState();
19
-}
20
-
21
-class _WelcomePageState extends State<WelcomePage> {
22
-
23
-  TextEditingController email;
24
-  TextEditingController password;
25
-
26
-  Widget _message(BuildContext context){
27
-    return RichText(
28
-      textAlign: TextAlign.center,
29
-      text: TextSpan(
30
-          text: "Don't have an account?",
31
-          style: GoogleFonts.cabin(
32
-              fontSize: 18,
33
-              color: Colors.black
34
-          )
35
-      ),
36
-    );
37
-  }
38
-
39
-  Widget _title(BuildContext context){
40
-    return RichText(
41
-      textAlign: TextAlign.center,
42
-      text: TextSpan(
43
-          text: "Welcome to FastMed",
44
-          style: GoogleFonts.cabin(
45
-              fontSize: 30,
46
-              color: Colors.red
47
-          )
48
-      ),
49
-    );
50
-
51
-  }
52
-
53
-  Widget _LoginField(String title, TextEditingController controller, {bool pass = false}){
54
-    return Container(
55
-      padding: EdgeInsets.only(left: 0, top: 10, bottom: 10),
56
-      child: Column(
57
-          crossAxisAlignment: CrossAxisAlignment.start,
58
-
59
-          children: <Widget> [
60
-            Text(
61
-              title,
62
-              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
63
-            ),
64
-            SizedBox(
65
-                height: 30
66
-            ),
67
-            TextField(
68
-              controller: controller,
69
-              obscureText: pass,
70
-              decoration: InputDecoration(
71
-                border: (
72
-                    UnderlineInputBorder(
73
-
74
-                    )
75
-                ),
76
-              ),
77
-            ),
78
-          ]
79
-      ),
80
-
81
-    );
82
-  }
83
-
84
-  Widget _Fills(){
85
-    return Column(
86
-        children: <Widget> [
87
-          _LoginField("Email", email),
88
-          _LoginField("Password", password, pass: true),
89
-
90
-        ]
91
-    );
92
-  }
93
-
94
-
95
-
96
-  // Widget _LogInButton(BuildContext context){
97
-  //   return InkWell(
98
-  //     // onTap: () {
99
-  //     //   Navigator.push(context, MaterialPageRoute(builder: (context)) => __LoginPage())
100
-  //     // },
101
-  //     child: Container(
102
-  //       // width: MediaQuery.of(context).size.width,
103
-  //       width: 200,
104
-  //       // height: ,
105
-  //       padding: EdgeInsets.symmetric(vertical:8),
106
-  //       alignment: Alignment.center,
107
-  //       decoration: BoxDecoration(
108
-  //         color: Colors.red,
109
-  //         // shape:
110
-  //
111
-  //         borderRadius: BorderRadius.circular(30),
112
-  //       ),
113
-  //       child: Text(
114
-  //         "Login",
115
-  //         style: TextStyle(fontSize: 25, color: Colors.white),
116
-  //       ),
117
-  //
118
-  //     )
119
-  //   );
120
-  // }
121
-
122
-  Widget _RegisterButton(BuildContext context){
123
-    return InkWell(
124
-        onTap: () {
125
-          Navigator.push(
126
-              context, MaterialPageRoute(builder: (context) => RegisterPage()));
127
-        },
128
-        child: Container(
129
-          // width: MediaQuery.of(context).size.width,
130
-          width: 180,
131
-          padding: EdgeInsets.symmetric(vertical:8),
132
-          alignment: Alignment.center,
133
-          decoration: BoxDecoration(
134
-            color: Colors.red,
135
-            // shape:
136
-
137
-            borderRadius: BorderRadius.circular(30),
138
-          ),
139
-          child: Text(
140
-            "Register",
141
-            style: TextStyle(fontSize: 22, color: Colors.white),
142
-          ),
143
-
144
-        )
145
-    );
146
-  }
147
-
148
-  @override
149
-  Widget build(BuildContext context) {
150
-    final height = MediaQuery.of(context).size.height;
151
-    return Scaffold(
152
-        body: Container(
153
-          height: height,
154
-          child:Container(
155
-            width: MediaQuery.of(context).size.width,
156
-            padding: EdgeInsets.symmetric(horizontal: 20),
157
-            // height: MediaQuery.of(context).size.height,
158
-            decoration: BoxDecoration(
159
-                borderRadius: BorderRadius.all(Radius.circular(4)),
160
-                boxShadow: [
161
-                  BoxShadow(
162
-                      color: Colors.white,
163
-                      offset: Offset(0,3),
164
-                      blurRadius: 5,
165
-                      spreadRadius: 2)
166
-                ]
167
-
168
-            ),
169
-            child: SingleChildScrollView(
170
-                child: Column(
171
-                  crossAxisAlignment: CrossAxisAlignment.center,
172
-                  mainAxisAlignment: MainAxisAlignment.center,
173
-                  children: <Widget> [
174
-                    SizedBox(
175
-                      height: 80,
176
-                    ),
177
-                    _title(context),
178
-                    SizedBox(
179
-                      height: 150,
180
-                    ),
181
-                    // _LogInButton(context),
182
-                    _Fills(),
183
-                    SizedBox(
184
-                      height: 60,
185
-                    ),
186
-                    _message(context),
187
-                    SizedBox(
188
-                      height: 10,
189
-                    ),
190
-                    _RegisterButton(context),
191
-                    SizedBox(
192
-                      height: 10,
193
-                    )
194
-                  ],
195
-                )
196
-            ),
197
-          ),
198
-        )
199
-    );
200
-  }
201
-}