diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..4002c20 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,32 @@ +## How to Contribute + +1. **Read The Branch naming convention** + > How to name a branch + +2. **Fork and Clone the Project** + ```bash + git clone https://github.com/JordyHers-org/Times-up-flutter.git + cd Times-up-flutter/ + ``` + +3. **Install Flutter Version** + > Install FVM via Homebrew and use Flutter version 3.7.12. + ```bash + + brew install fvm + fvm install 3.7.12 + ``` + +4. **Request Firebase Options File** + > Request the Firebase options file from the Project Owner and place it in the appropriate location. From discord server +Jordyhers [Discord- JordyHers](https://discord.gg/e4ppDx9Zcy) + +5. **Extra** + > For child's pictures feel free to use any of the pictures available. + +| | | | +|-|-|-| +| Neymar | Momo | Gareth +| Titi | Bruyne | Kylian +| Leo | Sally | Harry | + diff --git a/README.md b/README.md index 658406e..dec0439 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,8 @@ settled for user, and doesn't collect data for third parties companies. | | | | |-|-|-| | Onboarding | Sign_in_page | child_list_page -| ChildDetailsPage | ChildNotificationRemoval | GuidedTour -| NotificationSending | ChildLocation | settings_page | +| ChildDetailsPage | ChildNotificationRemoval | GuidedTour +| NotificationSending | ChildLocation | settings_page | ## Application Feature: Child Side diff --git a/lib/app/features/child_side/child_page.dart b/lib/app/features/child_side/child_page.dart index ac42efb..3ce20db 100644 --- a/lib/app/features/child_side/child_page.dart +++ b/lib/app/features/child_side/child_page.dart @@ -215,7 +215,7 @@ class _ChildPageState extends State with WidgetsBindingObserver { } else if (state is ChildSideFetching) { return _buildLoading(); } else if (state is ChildSideNotification) { - return _buildNotification(); + return _buildNotification(widget.child!); } else if (state is ChildSideAppList) { return _buildAppList(widget.appUsage); } else { @@ -249,9 +249,9 @@ class _ChildPageState extends State with WidgetsBindingObserver { ); } - Widget _buildNotification() { + Widget _buildNotification(ChildModel child) { return StreamBuilder>( - stream: widget.database!.notificationStream(childId: ''), + stream: widget.database!.notificationStream(childId: child.id), builder: (BuildContext context, snapshot) { if (snapshot.hasData) { final data = snapshot.data; diff --git a/lib/app/features/parent_side/child_details_page.dart b/lib/app/features/parent_side/child_details_page.dart index 93ef68e..13f491a 100644 --- a/lib/app/features/parent_side/child_details_page.dart +++ b/lib/app/features/parent_side/child_details_page.dart @@ -128,53 +128,52 @@ class _ChildDetailsPageState extends State return [ SliverAppBar( actions: [ - if (model.image != null) - Row( - children: [ - GestureDetector( - onTap: () => showCustomBottomSheet( - context, - animationController: _animationController, - child: Container( - decoration: BoxDecoration( - color: themeData.scaffoldBackgroundColor, - ), - height: 200, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const Spacer(), - JHCustomButton( - title: ' Bed Time', - backgroundColor: Colors.indigo, - onPress: () async => _sendNotification( - context, - model, - 'Hey Go to bed Now', - ), + Row( + children: [ + GestureDetector( + onTap: () => showCustomBottomSheet( + context, + animationController: _animationController, + child: Container( + decoration: BoxDecoration( + color: themeData.scaffoldBackgroundColor, + ), + height: 200, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Spacer(), + JHCustomButton( + title: ' Bed Time', + backgroundColor: Colors.indigo, + onPress: () async => _sendNotification( + context, + model, + 'Hey Go to bed Now', ), - JHCustomButton( - title: 'Homework Time', - backgroundColor: CustomColors.indigoLight, - onPress: () async => _sendNotification( - context, - model, - 'Homework Time', - ), + ), + JHCustomButton( + title: 'Homework Time', + backgroundColor: CustomColors.indigoLight, + onPress: () async => _sendNotification( + context, + model, + 'Homework Time', ), - const Spacer(), - ], - ), + ), + const Spacer(), + ], ), ), - child: ClipOval( - child: Image.network(model.image!), - ).p4, ), - ], - ) - else - const SizedBox.shrink(), + child: ClipOval( + child: model.image != null + ? Image.network(model.image!) + : const Icon(Icons.person), + ).p4, + ), + ], + ), ], elevation: 0.5, shadowColor: CustomColors.indigoLight, diff --git a/lib/app/features/parent_side/edit_child_page.dart b/lib/app/features/parent_side/edit_child_page.dart index 5fdafbd..302aefd 100644 --- a/lib/app/features/parent_side/edit_child_page.dart +++ b/lib/app/features/parent_side/edit_child_page.dart @@ -89,32 +89,33 @@ class _EditChildPageState extends State { Future _submit(XFile? localFile) async { if (appState == AppState.loading) return; if (_validateAndSaveForm()) { - if (localFile == null) return; setState(() { appState = AppState.loading; }); id = uuid.v4().substring(0, 8).toUpperCase(); - try { - final fileExtension = path.extension(localFile.path); - JHLogger.$.d(fileExtension); + if(localFile!=null) { + try { + final fileExtension = path.extension(localFile.path); + JHLogger.$.d(fileExtension); - final firebaseStorageRef = FirebaseStorage.instance - .ref() - .child('Child/"$id"/$id$fileExtension'); + final firebaseStorageRef = FirebaseStorage.instance + .ref() + .child('Child/"$id"/$id$fileExtension'); - await firebaseStorageRef - .putFile(File(localFile.path)) - .catchError((Function onError) { - JHLogger.$.e(onError); - // ignore: return_of_invalid_type_from_catch_error - return false; - }); - final url = await firebaseStorageRef.getDownloadURL(); - _imageURL = url; - JHLogger.$.d('download url: $url'); - } catch (e) { - JHLogger.$.d('...skipping image upload'); + await firebaseStorageRef + .putFile(File(localFile.path)) + .catchError((Function onError) { + JHLogger.$.e(onError); + // ignore: return_of_invalid_type_from_catch_error + return false; + }); + final url = await firebaseStorageRef.getDownloadURL(); + _imageURL = url; + JHLogger.$.d('download url: $url'); + } catch (e) { + JHLogger.$.d('...skipping image upload'); + } } try { diff --git a/lib/app/features/parent_side/notification_page.dart b/lib/app/features/parent_side/notification_page.dart index ed60d70..48e2522 100644 --- a/lib/app/features/parent_side/notification_page.dart +++ b/lib/app/features/parent_side/notification_page.dart @@ -177,7 +177,7 @@ class _NotificationPageState extends State { subtitle: JHDisplayText( textAlign: TextAlign.start, text: convertToFormattedString( - data[index].timeStamp.toString(), + data[index].timeStamp, ), style: const TextStyle( fontWeight: FontWeight.w400, diff --git a/lib/app/helpers/parsing_extension.dart b/lib/app/helpers/parsing_extension.dart index 3f61ca7..2d90ad0 100644 --- a/lib/app/helpers/parsing_extension.dart +++ b/lib/app/helpers/parsing_extension.dart @@ -148,8 +148,8 @@ int getRandom(int maxValue) { return minRange + random.nextInt(maxRange - minRange + 1); } -String convertToFormattedString(String input) { - final dateTime = DateTime.parse(input); - final formattedDate = DateFormat('MMMM d y HH:mma').format(dateTime); +String convertToFormattedString(DateTime? dateTime) { + final formattedDate = + dateTime != null ? DateFormat('MMMM d y hh:mm a').format(dateTime) : ''; return formattedDate; } diff --git a/lib/services/firestore_service.dart b/lib/services/firestore_service.dart index 537bdcb..bb0ecea 100644 --- a/lib/services/firestore_service.dart +++ b/lib/services/firestore_service.dart @@ -2,6 +2,9 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_storage/firebase_storage.dart'; +import 'package:flutter/foundation.dart'; +import 'package:times_up_flutter/models/notification_model/notification_model.dart'; + import 'package:times_up_flutter/widgets/show_logger.dart'; typedef QueryBuilder = T Function(Map data); @@ -114,6 +117,7 @@ class FireStoreService { Stream> notificationStream({ required String path, required T Function(Map data, String documentId) builder, + String? childId, Function(Query query)? queryBuilder, int Function(T lhs, T rhs)? sort, }) { @@ -122,10 +126,15 @@ class FireStoreService { query = queryBuilder(query) as CollectionReference>; } final snapshots = query.snapshots(); + return snapshots.map((snapshot) { final result = snapshot.docs .map((snapshot) => builder(snapshot.data(), snapshot.id)) - .where((value) => value != null) + .where( + (value) => + value != null && + (childId == null || (value as NotificationModel).id == childId), + ) .toList(); if (sort != null) { result.sort(sort);