diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml
index 3cbabd7..bf0c95e 100644
--- a/.idea/libraries/Flutter_Plugins.xml
+++ b/.idea/libraries/Flutter_Plugins.xml
@@ -58,6 +58,9 @@
+
+
+
diff --git a/.idea/runConfigurations/development.xml b/.idea/runConfigurations/development.xml
new file mode 100644
index 0000000..07b02c6
--- /dev/null
+++ b/.idea/runConfigurations/development.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/runConfigurations/production.xml b/.idea/runConfigurations/production.xml
new file mode 100644
index 0000000..1c5c774
--- /dev/null
+++ b/.idea/runConfigurations/production.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/runConfigurations/staging.xml b/.idea/runConfigurations/staging.xml
new file mode 100644
index 0000000..f979a68
--- /dev/null
+++ b/.idea/runConfigurations/staging.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
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.
+
+| | | |
+|-|-|-|
+| | |
+| | |
+| | | |
+
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.
| | | |
|-|-|-|
| | |
-| | |
-| | | |
+| | |
+| | | |
## Application Feature: Child Side
diff --git a/android/app/build.gradle b/android/app/build.gradle
index e224b11..9408c2d 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -36,7 +36,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
- compileSdkVersion 33
+ compileSdkVersion 34
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 2070d06..f9e0506 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -7,15 +7,15 @@
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
-
-
-
+
+
+
+
+
+
+
createState() => _TimesUpAppState();
-}
-
-class _TimesUpAppState extends State with WidgetsBindingObserver {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
@@ -24,6 +20,7 @@ class _TimesUpAppState extends State with WidgetsBindingObserver {
return MaterialApp(
debugShowCheckedModeBanner: false,
+ locale: Provider.of(context).locale,
title: Strings.appName,
theme: AppTheme.lightTheme,
darkTheme: AppTheme.darkTheme,
diff --git a/lib/sign_in/phone_sign_bloc_based.dart b/lib/app/config/android_config.dart
similarity index 100%
rename from lib/sign_in/phone_sign_bloc_based.dart
rename to lib/app/config/android_config.dart
diff --git a/lib/app/bloc/child_side_bloc.dart b/lib/app/features/child_side/bloc/child_side_bloc.dart
similarity index 100%
rename from lib/app/bloc/child_side_bloc.dart
rename to lib/app/features/child_side/bloc/child_side_bloc.dart
diff --git a/lib/app/bloc/child_side_event.dart b/lib/app/features/child_side/bloc/child_side_event.dart
similarity index 100%
rename from lib/app/bloc/child_side_event.dart
rename to lib/app/features/child_side/bloc/child_side_event.dart
diff --git a/lib/app/bloc/child_side_state.dart b/lib/app/features/child_side/bloc/child_side_state.dart
similarity index 100%
rename from lib/app/bloc/child_side_state.dart
rename to lib/app/features/child_side/bloc/child_side_state.dart
diff --git a/lib/app/pages/child_page.dart b/lib/app/features/child_side/child_page.dart
similarity index 91%
rename from lib/app/pages/child_page.dart
rename to lib/app/features/child_side/child_page.dart
index ccd7642..3ce20db 100644
--- a/lib/app/pages/child_page.dart
+++ b/lib/app/features/child_side/child_page.dart
@@ -7,18 +7,19 @@ import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart';
-import 'package:times_up_flutter/app/bloc/child_side_bloc.dart';
+import 'package:times_up_flutter/app/features/child_side/bloc/child_side_bloc.dart';
+import 'package:times_up_flutter/app/features/child_side/set_child_page.dart';
+import 'package:times_up_flutter/app/features/landing_page.dart';
import 'package:times_up_flutter/app/helpers/parsing_extension.dart';
-import 'package:times_up_flutter/app/landing_page.dart';
-import 'package:times_up_flutter/app/pages/set_child_page.dart';
-import 'package:times_up_flutter/common_widgets/jh_display_text.dart';
-import 'package:times_up_flutter/common_widgets/jh_empty_content.dart';
import 'package:times_up_flutter/models/child_model/child_model.dart';
import 'package:times_up_flutter/models/notification_model/notification_model.dart';
import 'package:times_up_flutter/services/app_usage_service.dart';
import 'package:times_up_flutter/services/database.dart';
import 'package:times_up_flutter/services/geo_locator_service.dart';
import 'package:times_up_flutter/theme/theme.dart';
+import 'package:times_up_flutter/widgets/jh_display_text.dart';
+import 'package:times_up_flutter/widgets/jh_empty_content.dart';
+import 'package:times_up_flutter/widgets/show_logger.dart';
class ChildPage extends StatefulWidget {
const ChildPage({
@@ -66,11 +67,23 @@ class _ChildPageState extends State with WidgetsBindingObserver {
Navigator.pop(context);
}
+ @override
+ void initState() {
+ super.initState();
+ WidgetsBinding.instance.addObserver(this);
+ }
+
+ @override
+ void dispose() {
+ WidgetsBinding.instance.removeObserver(this);
+ super.dispose();
+ }
+
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
- Timer.periodic(const Duration(minutes: 5), (timer) {
- widget.database
- ?.liveUpdateChild(widget.child!, timer.tick, widget.appUsage);
+ Timer.periodic(const Duration(seconds: 5), (timer) async {
+ await widget.database?.liveUpdateChild(widget.child!, widget.appUsage);
+ JHLogger.$.d('${timer.tick} - $state');
});
super.didChangeAppLifecycleState(state);
}
@@ -202,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 {
@@ -236,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/pages/set_child_page.dart b/lib/app/features/child_side/set_child_page.dart
similarity index 89%
rename from lib/app/pages/set_child_page.dart
rename to lib/app/features/child_side/set_child_page.dart
index a6f334f..19de91a 100644
--- a/lib/app/pages/set_child_page.dart
+++ b/lib/app/features/child_side/set_child_page.dart
@@ -4,16 +4,16 @@ import 'package:battery_plus/battery_plus.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
+import 'package:times_up_flutter/app/features/child_side/child_page.dart';
import 'package:times_up_flutter/app/helpers/parsing_extension.dart';
-import 'package:times_up_flutter/app/pages/child_page.dart';
-import 'package:times_up_flutter/common_widgets/jh_display_text.dart';
-import 'package:times_up_flutter/common_widgets/jh_form_submit_button.dart';
-import 'package:times_up_flutter/common_widgets/show_alert_dialog.dart';
-import 'package:times_up_flutter/common_widgets/show_logger.dart';
import 'package:times_up_flutter/models/child_model/child_model.dart';
import 'package:times_up_flutter/services/app_usage_service.dart';
import 'package:times_up_flutter/services/database.dart';
import 'package:times_up_flutter/services/geo_locator_service.dart';
+import 'package:times_up_flutter/widgets/jh_display_text.dart';
+import 'package:times_up_flutter/widgets/jh_form_submit_button.dart';
+import 'package:times_up_flutter/widgets/show_alert_dialog.dart';
+import 'package:times_up_flutter/widgets/show_logger.dart';
enum AppState { loading, complete }
@@ -56,26 +56,27 @@ class _SetChildPageState extends State {
}
Future _submit(String name, String key, BuildContext context) async {
- final database = Provider.of(context, listen: false);
+ final databaseStore = Provider.of(context, listen: false);
final geo = Provider.of(context, listen: false);
- final apps = Provider.of(context, listen: false);
+ final appUsage = Provider.of(context, listen: false);
final position = await geo.getInitialLocation();
final battery = await Battery().batteryLevel;
+
try {
- final response = await database.getUserCurrentChild(
+ final response = await databaseStore.getUserCurrentChild(
key,
- apps,
+ appUsage,
GeoPoint(position.latitude, position.longitude),
battery: battery.toString(),
);
- JHLogger.$.d('RESPONSE : $response');
+
try {
if (mounted) {
await Navigator.of(context).pushReplacement(
MaterialPageRoute(
fullscreenDialog: true,
builder: (context) =>
- ChildPage.create(context, database, response),
+ ChildPage.create(context, databaseStore, response),
),
);
}
diff --git a/lib/app/landing_page.dart b/lib/app/features/landing_page.dart
similarity index 90%
rename from lib/app/landing_page.dart
rename to lib/app/features/landing_page.dart
index 02be44e..dc5fe72 100644
--- a/lib/app/landing_page.dart
+++ b/lib/app/features/landing_page.dart
@@ -2,15 +2,15 @@ import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:showcaseview/showcaseview.dart';
-import 'package:times_up_flutter/app/pages/parent_page.dart';
-import 'package:times_up_flutter/app/pages/set_child_page.dart';
-import 'package:times_up_flutter/common_widgets/jh_loading_widget.dart';
+import 'package:times_up_flutter/app/features/child_side/set_child_page.dart';
+import 'package:times_up_flutter/app/features/parent_side/parent_page.dart';
+import 'package:times_up_flutter/app/features/sign_in/sign_in_page.dart';
import 'package:times_up_flutter/services/app_usage_service.dart';
import 'package:times_up_flutter/services/auth.dart';
import 'package:times_up_flutter/services/database.dart';
import 'package:times_up_flutter/services/geo_locator_service.dart';
import 'package:times_up_flutter/services/shared_preferences.dart';
-import 'package:times_up_flutter/sign_in/sign_in_page.dart';
+import 'package:times_up_flutter/widgets/jh_loading_widget.dart';
enum AppSide { parent, child }
@@ -32,7 +32,7 @@ class _LandingPageState extends State {
}
Future _setFlagParentOrChild() async {
- final isParent = await SharedPreference().getParentOrChild();
+ final isParent = await CacheService.getParentOrChild();
setState(() {
isParent ? _side = AppSide.parent : _side = AppSide.child;
});
diff --git a/lib/app/features/parent_side/app_list_page.dart b/lib/app/features/parent_side/app_list_page.dart
new file mode 100644
index 0000000..bd91364
--- /dev/null
+++ b/lib/app/features/parent_side/app_list_page.dart
@@ -0,0 +1,88 @@
+import 'package:flutter/material.dart';
+import 'package:times_up_flutter/app/helpers/parsing_extension.dart';
+import 'package:times_up_flutter/models/child_model/child_model.dart';
+
+class AppListPage extends StatelessWidget {
+ const AppListPage({
+ required this.childModel,
+ Key? key,
+ }) : super(key: key);
+
+ final ChildModel childModel;
+
+ static Future show(BuildContext context, ChildModel model) async {
+ await Navigator.of(context).push(
+ PageRouteBuilder(
+ pageBuilder: (context, animation, secondaryAnimation) {
+ return AppListPage(childModel: model);
+ },
+ transitionsBuilder: (context, animation, secondaryAnimation, child) {
+ const begin = Offset(1, 0);
+ const end = Offset.zero;
+ const curve = Curves.easeInOut;
+ final tween =
+ Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
+ final offsetAnimation = animation.drive(tween);
+ return SlideTransition(
+ position: offsetAnimation,
+ child: child,
+ );
+ },
+ transitionDuration: const Duration(milliseconds: 400),
+ ),
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final themeData = Theme.of(context);
+
+ return Scaffold(
+ appBar: AppBar(
+ leading: IconButton(
+ icon: const Icon(Icons.chevron_left),
+ onPressed: () => Navigator.of(context).pop(),
+ ),
+ elevation: 0,
+ backgroundColor: themeData.scaffoldBackgroundColor,
+ ),
+ body: ListView.builder(
+ physics: const BouncingScrollPhysics(
+ decelerationRate: ScrollDecelerationRate.fast,
+ ),
+ itemCount: childModel.appsUsageModel.length,
+ itemBuilder: (context, index) {
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ ListTile(
+ leading: childModel.appsUsageModel[index].appIcon != null
+ ? Image.memory(
+ childModel.appsUsageModel[index].appIcon!,
+ height: 35,
+ )
+ : const Icon(Icons.android),
+ title: Text(
+ childModel.appsUsageModel[index].appName,
+ style: TextStyle(
+ fontSize: 15,
+ fontWeight: FontWeight.bold,
+ color: themeData.dividerColor,
+ ),
+ ),
+ trailing: Text(
+ childModel.appsUsageModel[index].usage.toString().t(),
+ style: TextStyle(
+ fontSize: 14,
+ fontWeight: FontWeight.w600,
+ color: themeData.dividerColor,
+ ),
+ ),
+ ),
+ ],
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/lib/app/pages/child_details_page.dart b/lib/app/features/parent_side/child_details_page.dart
similarity index 58%
rename from lib/app/pages/child_details_page.dart
rename to lib/app/features/parent_side/child_details_page.dart
index d5bfb94..21340a6 100644
--- a/lib/app/pages/child_details_page.dart
+++ b/lib/app/features/parent_side/child_details_page.dart
@@ -9,23 +9,23 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:share_plus/share_plus.dart';
+import 'package:times_up_flutter/app/features/parent_side/app_list_page.dart';
import 'package:times_up_flutter/app/helpers/parsing_extension.dart';
-import 'package:times_up_flutter/common_widgets/jh_bar_chart.dart';
-import 'package:times_up_flutter/common_widgets/jh_battery_widget.dart';
-import 'package:times_up_flutter/common_widgets/jh_custom_button.dart';
-import 'package:times_up_flutter/common_widgets/jh_display_text.dart';
-import 'package:times_up_flutter/common_widgets/jh_empty_content.dart';
-import 'package:times_up_flutter/common_widgets/jh_feature_widget.dart';
-import 'package:times_up_flutter/common_widgets/jh_header_widget.dart';
-import 'package:times_up_flutter/common_widgets/show_alert_dialog.dart';
-import 'package:times_up_flutter/common_widgets/show_bottom_sheet.dart';
-import 'package:times_up_flutter/common_widgets/show_exeption_alert.dart';
-import 'package:times_up_flutter/common_widgets/show_logger.dart';
import 'package:times_up_flutter/l10n/l10n.dart';
import 'package:times_up_flutter/models/child_model/child_model.dart';
import 'package:times_up_flutter/models/notification_model/notification_model.dart';
import 'package:times_up_flutter/services/database.dart';
import 'package:times_up_flutter/theme/theme.dart';
+import 'package:times_up_flutter/widgets/jh_battery_widget.dart';
+import 'package:times_up_flutter/widgets/jh_custom_button.dart';
+import 'package:times_up_flutter/widgets/jh_display_text.dart';
+import 'package:times_up_flutter/widgets/jh_empty_content.dart';
+import 'package:times_up_flutter/widgets/jh_header_widget.dart';
+import 'package:times_up_flutter/widgets/jh_line_chart.dart';
+import 'package:times_up_flutter/widgets/show_alert_dialog.dart';
+import 'package:times_up_flutter/widgets/show_bottom_sheet.dart';
+import 'package:times_up_flutter/widgets/show_exeption_alert.dart';
+import 'package:times_up_flutter/widgets/show_logger.dart';
class ChildDetailsPage extends StatefulWidget {
const ChildDetailsPage({
@@ -39,10 +39,25 @@ class ChildDetailsPage extends StatefulWidget {
static Future show(BuildContext context, ChildModel model) async {
final database = Provider.of(context, listen: false);
+
await Navigator.of(context).push(
- MaterialPageRoute(
- builder: (context) =>
- ChildDetailsPage(database: database, childModel: model),
+ PageRouteBuilder(
+ pageBuilder: (context, animation, secondaryAnimation) {
+ return ChildDetailsPage(database: database, childModel: model);
+ },
+ transitionsBuilder: (context, animation, secondaryAnimation, child) {
+ const begin = Offset(1, 0);
+ const end = Offset.zero;
+ const curve = Curves.easeInOut;
+ final tween =
+ Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
+ final offsetAnimation = animation.drive(tween);
+ return SlideTransition(
+ position: offsetAnimation,
+ child: child,
+ );
+ },
+ transitionDuration: const Duration(milliseconds: 400),
),
);
}
@@ -113,16 +128,52 @@ class _ChildDetailsPageState extends State
return [
SliverAppBar(
actions: [
- if (model.image != null)
- Row(
- children: [
- ClipOval(
- child: Image.network(model.image!),
+ 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',
+ ),
+ ),
+ const Spacer(),
+ ],
+ ),
+ ),
+ ),
+ child: ClipOval(
+ child: model.image != null
+ ? Image.network(model.image!)
+ : const Icon(Icons.person),
).p4,
- ],
- )
- else
- const SizedBox.shrink(),
+ ),
+ ],
+ ),
],
elevation: 0.5,
shadowColor: CustomColors.indigoLight,
@@ -136,13 +187,6 @@ class _ChildDetailsPageState extends State
iconTheme: const IconThemeData(color: Colors.red),
backgroundColor: themeData.scaffoldBackgroundColor,
expandedHeight: 50,
- shape: ContinuousRectangleBorder(
- side: BorderSide(
- color: !value
- ? themeData.scaffoldBackgroundColor
- : CustomColors.indigoLight.withOpacity(0.5),
- ),
- ),
pinned: true,
floating: true,
),
@@ -214,77 +258,19 @@ class _ChildDetailsPageState extends State
margin: const EdgeInsets.symmetric(horizontal: 8),
height: 205,
width: double.infinity,
- child: model.appsUsageModel.isNotEmpty
- ? JHAppUsageChart(
- isEmpty: false,
- name: model.name,
- )
- : JHAppUsageChart(
- isEmpty: true,
- name: model.name,
- ),
+ child: JHLineChart(model: model),
),
],
).vTopP(20),
- HeaderWidget(
- title: AppLocalizations.of(context)
- .sendNotificationToYourChildDevice,
- subtitle: 'Push the button ',
- ),
- 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',
- ),
- ),
- const Spacer(),
- ],
- ),
- ),
- ),
- child: const JHFeatureWidget(
- title: 'Send Notification',
- icon: Icons.wifi_tethering_error_sharp,
- ),
- ),
- _AppUsedList(
- model: model,
- ),
+ _AppUsedList(model: model).vP16,
JHCustomButton(
title: 'Delete Child',
- backgroundColor: Colors.transparent,
- borderColor: Colors.red,
- textColor: Colors.red,
+ backgroundColor: Colors.red,
onPress: () async => _confirmDelete(
context,
widget.childModel,
),
- ).vTopP(50),
+ ).vTopP(70),
]),
),
],
@@ -327,9 +313,11 @@ class _ChildDetailsPageState extends State
title: ' Hey ${model.name}',
body: 'Here is a new message',
message: content,
+ timeStamp: DateTime.now(),
),
model,
);
+ Navigator.of(context).pop();
if (!mounted) return;
await showAlertDialog(
context,
@@ -358,65 +346,82 @@ class _AppUsedList extends StatelessWidget {
@override
Widget build(BuildContext context) {
final themeData = Theme.of(context);
- return SingleChildScrollView(
- child: ScrollConfiguration(
- behavior: const ScrollBehavior().copyWith(overscroll: false),
- child: Column(
- children: [
- if (model.appsUsageModel.isNotEmpty)
- const HeaderWidget(
- title: 'Summary of used apps',
- subtitle: 'Click for more details',
- )
- else
- const SizedBox.shrink().vP16,
- if (model.appsUsageModel.isNotEmpty)
- ListView.builder(
- physics: const NeverScrollableScrollPhysics(),
- shrinkWrap: true,
- itemCount: model.appsUsageModel.length,
- itemBuilder: (context, index) {
- return Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- ListTile(
- leading: model.appsUsageModel[index].appIcon != null
- ? Image.memory(
- model.appsUsageModel[index].appIcon!,
- height: 35,
- )
- : const Icon(Icons.android),
- title: Text(
- model.appsUsageModel[index].appName,
- style: TextStyle(
- fontSize: 15,
- fontWeight: FontWeight.bold,
- color: themeData.dividerColor,
- ),
- ),
- trailing: Text(
- model.appsUsageModel[index].usage.toString().t(),
- style: TextStyle(
- fontSize: 14,
- fontWeight: FontWeight.w600,
- color: themeData.dividerColor,
- ),
- ),
- ),
- ],
- );
- },
- )
- else
- const JHEmptyContent(
- message: 'Seems like you have not set up the child device \n',
- title: 'Set up the child device',
- fontSizeMessage: 8,
- fontSizeTitle: 12,
+ return Column(
+ children: [
+ if (model.appsUsageModel.isNotEmpty)
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ const SizedBox(
+ width: 300,
+ child: HeaderWidget(
+ title: 'Summary of used apps',
+ subtitle: 'Click for more details',
+ ),
),
- ],
- ),
- ),
+ TextButton(
+ child: Text(
+ 'See all',
+ style: TextStyle(
+ decoration: TextDecoration.underline,
+ color: CustomColors.indigoLight,
+ fontSize: 13,
+ ),
+ ),
+ onPressed: () => AppListPage.show(context, model),
+ ),
+ ],
+ )
+ else
+ const SizedBox.shrink().vP16,
+ if (model.appsUsageModel.isNotEmpty)
+ ListView.builder(
+ padding: EdgeInsets.zero,
+ physics: const NeverScrollableScrollPhysics(),
+ shrinkWrap: true,
+ itemCount: model.appsUsageModel.length > 5
+ ? 5
+ : (model.appsUsageModel.length * 0.20).toInt(),
+ itemBuilder: (context, index) {
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ ListTile(
+ leading: model.appsUsageModel[index].appIcon != null
+ ? Image.memory(
+ model.appsUsageModel[index].appIcon!,
+ height: 35,
+ )
+ : const Icon(Icons.android),
+ title: Text(
+ model.appsUsageModel[index].appName,
+ style: TextStyle(
+ fontSize: 15,
+ fontWeight: FontWeight.bold,
+ color: themeData.dividerColor,
+ ),
+ ),
+ trailing: Text(
+ model.appsUsageModel[index].usage.toString().t(),
+ style: TextStyle(
+ fontSize: 14,
+ fontWeight: FontWeight.w600,
+ color: themeData.dividerColor,
+ ),
+ ),
+ ),
+ ],
+ );
+ },
+ )
+ else
+ const JHEmptyContent(
+ message: 'Seems like you have not set up the child device \n',
+ title: 'Set up the child device',
+ fontSizeMessage: 8,
+ fontSizeTitle: 12,
+ ),
+ ],
);
}
}
diff --git a/lib/app/pages/edit_child_page.dart b/lib/app/features/parent_side/edit_child_page.dart
similarity index 79%
rename from lib/app/pages/edit_child_page.dart
rename to lib/app/features/parent_side/edit_child_page.dart
index bf5bacc..302aefd 100644
--- a/lib/app/pages/edit_child_page.dart
+++ b/lib/app/features/parent_side/edit_child_page.dart
@@ -6,14 +6,14 @@ import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as path;
-import 'package:times_up_flutter/common_widgets/jh_custom_raised_button.dart';
-import 'package:times_up_flutter/common_widgets/jh_display_text.dart';
-import 'package:times_up_flutter/common_widgets/show_alert_dialog.dart';
-import 'package:times_up_flutter/common_widgets/show_exeption_alert.dart';
-import 'package:times_up_flutter/common_widgets/show_logger.dart';
import 'package:times_up_flutter/models/child_model/child_model.dart';
import 'package:times_up_flutter/services/database.dart';
import 'package:times_up_flutter/theme/theme.dart';
+import 'package:times_up_flutter/widgets/jh_custom_raised_button.dart';
+import 'package:times_up_flutter/widgets/jh_display_text.dart';
+import 'package:times_up_flutter/widgets/show_alert_dialog.dart';
+import 'package:times_up_flutter/widgets/show_exeption_alert.dart';
+import 'package:times_up_flutter/widgets/show_logger.dart';
import 'package:uuid/uuid.dart';
enum AppState { loading, complete }
@@ -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 {
@@ -128,7 +129,7 @@ class _EditChildPageState extends State {
await showAlertDialog(
context,
title: ' Name already used',
- content: 'Please choose a different job name',
+ content: 'Please choose a different child name',
defaultActionText: 'OK',
);
}
@@ -162,6 +163,19 @@ class _EditChildPageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
+ resizeToAvoidBottomInset: false,
+ floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
+ floatingActionButton: JHCustomRaisedButton(
+ width: MediaQuery.of(context).size.width * 0.80,
+ onPressed: () async => _submit(_imageFile),
+ color: CustomColors.indigoDark,
+ child: JHDisplayText(
+ text: 'Save',
+ style: TextStyle(
+ color: Theme.of(context).scaffoldBackgroundColor,
+ ),
+ ),
+ ).vP16,
backgroundColor:
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.9),
appBar: AppBar(
@@ -183,15 +197,14 @@ class _EditChildPageState extends State {
Widget _buildContents() {
return !isSavedPressed
- ? SingleChildScrollView(
- child: Padding(
- padding: const EdgeInsets.all(16),
- child: Card(
- child: Padding(
- padding: const EdgeInsets.all(16),
- child: _buildForm(),
- ),
- ),
+ ? SizedBox(
+ height: MediaQuery.of(context).size.height,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ _buildForm().p(32),
+ const Spacer(),
+ ],
),
)
: const Center(child: CircularProgressIndicator());
@@ -236,7 +249,7 @@ class _EditChildPageState extends State {
),
onPressed: _getLocalImage,
child: const JHDisplayText(
- text: 'Upload',
+ text: 'Import ',
style: TextStyle(color: Colors.white),
),
),
@@ -258,15 +271,6 @@ class _EditChildPageState extends State {
enabled: appState == AppState.complete || false,
onSaved: (value) => _email = value,
),
- JHCustomRaisedButton(
- width: 200,
- onPressed: () async => _submit(_imageFile),
- color: Colors.indigo,
- child: const JHDisplayText(
- text: 'Save',
- style: TextStyle(color: Colors.white),
- ),
- ).vTopP(24)
];
}
diff --git a/lib/app/features/parent_side/language/language_notififier.dart b/lib/app/features/parent_side/language/language_notififier.dart
new file mode 100644
index 0000000..b3d9af4
--- /dev/null
+++ b/lib/app/features/parent_side/language/language_notififier.dart
@@ -0,0 +1,77 @@
+import 'dart:ui';
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/services.dart';
+import 'package:times_up_flutter/services/shared_preferences.dart';
+
+class LanguageNotifier extends ChangeNotifier {
+ late String _selectedLanguage = '🇺🇸 English';
+ late Locale _locale = const Locale('en');
+
+ String get selectedLanguage => _selectedLanguage;
+ Locale get locale => _locale;
+
+ List languages = [
+ '🇺🇸 English',
+ '🇫🇷 Français',
+ '🇪🇸 Español',
+ '🇹🇷 Turkish',
+ '🇩🇪 Deutsch',
+ ];
+
+ Future initLocalization() async {
+ _locale = await CacheService.getLocale();
+ _setLanguageString();
+ languages
+ ..insert(languages.indexOf(_selectedLanguage), _selectedLanguage)
+ ..removeWhere((element) => element == _selectedLanguage);
+ notifyListeners();
+ }
+
+ void selectLanguage(String language) {
+ languages.insert(languages.indexOf(language), _selectedLanguage);
+ _selectedLanguage = language;
+ languages.removeWhere((element) => element == _selectedLanguage);
+ _locale = setLocale(_selectedLanguage);
+ CacheService.setLocale(value: _locale);
+ HapticFeedback.heavyImpact();
+ notifyListeners();
+ }
+
+ void _setLanguageString() {
+ switch (_locale.languageCode) {
+ case 'en':
+ _selectedLanguage = '🇺🇸 English';
+ break;
+ case 'fr':
+ _selectedLanguage = '🇫🇷 Français';
+ break;
+ case 'es':
+ _selectedLanguage = '🇪🇸 Español';
+ break;
+ case 'de':
+ _selectedLanguage = '🇩🇪 Deutsch';
+ break;
+ case 'tr':
+ _selectedLanguage = '🇹🇷 Turkish';
+ break;
+ }
+ }
+
+ Locale setLocale(String selectedLanguage) {
+ switch (selectedLanguage) {
+ case '🇫🇷 Français':
+ return const Locale('fr');
+ case '🇺🇸 English':
+ return const Locale('en');
+ case '🇪🇸 Español':
+ return const Locale('es');
+ case '🇹🇷 Turkish':
+ return const Locale('tr');
+ case '🇩🇪 Deutsch':
+ return const Locale('de');
+ default:
+ return const Locale('en');
+ }
+ }
+}
diff --git a/lib/app/features/parent_side/language/language_page.dart b/lib/app/features/parent_side/language/language_page.dart
new file mode 100644
index 0000000..a56d237
--- /dev/null
+++ b/lib/app/features/parent_side/language/language_page.dart
@@ -0,0 +1,129 @@
+// ignore_for_file: library_private_types_in_public_api
+
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+import 'package:times_up_flutter/app/features/parent_side/language/language_notififier.dart';
+import 'package:times_up_flutter/services/auth.dart';
+import 'package:times_up_flutter/theme/theme.dart';
+import 'package:times_up_flutter/widgets/jh_display_text.dart';
+
+class LanguagePage extends StatefulWidget {
+ const LanguagePage({
+ required this.auth,
+ required this.languageModel,
+ Key? key,
+ }) : super(key: key);
+ final AuthBase auth;
+ final LanguageNotifier languageModel;
+
+ static Widget create(
+ BuildContext context,
+ AuthBase auth,
+ ) {
+ return Consumer(
+ builder: (BuildContext context, value, Widget? child) => LanguagePage(
+ auth: auth,
+ languageModel: value,
+ ),
+ );
+ }
+
+ @override
+ _LanguagePageState createState() => _LanguagePageState();
+}
+
+class _LanguagePageState extends State {
+ @override
+ void initState() {
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final color = Theme.of(context).brightness == Brightness.dark
+ ? Colors.white
+ : CustomColors.indigoDark;
+
+ return Scaffold(
+ body: NestedScrollView(
+ headerSliverBuilder: (BuildContext context, value) {
+ return [
+ SliverAppBar(
+ elevation: 0.5,
+ shadowColor: CustomColors.indigoLight,
+ iconTheme: IconThemeData(color: color),
+ backgroundColor: Theme.of(context).scaffoldBackgroundColor,
+ expandedHeight: 50,
+ pinned: true,
+ floating: true,
+ )
+ ];
+ },
+ body: ScrollConfiguration(
+ behavior: const ScrollBehavior().copyWith(overscroll: false),
+ child: CustomScrollView(
+ slivers: [
+ SliverToBoxAdapter(
+ child: JHDisplayText(
+ text: 'Languages',
+ style: TextStyle(
+ color: color,
+ fontWeight: FontWeight.w700,
+ ),
+ fontSize: 32,
+ maxFontSize: 34,
+ ).hP16,
+ ),
+ const SliverPadding(padding: EdgeInsets.only(top: 50)),
+ SliverToBoxAdapter(
+ child: Card(
+ margin: const EdgeInsets.symmetric(horizontal: 50),
+ color: CustomColors.indigoLight,
+ child: Center(
+ child: SizedBox(
+ height: 60,
+ child: Center(
+ child: JHDisplayText(
+ text: widget.languageModel.selectedLanguage,
+ style: TextStyles.title,
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ SliverList(
+ delegate: SliverChildListDelegate([
+ SingleChildScrollView(
+ child: SizedBox(
+ height: 1000,
+ child: ListView.separated(
+ itemCount: 4,
+ itemBuilder: (builder, index) => GestureDetector(
+ onTap: () => widget.languageModel.selectLanguage(
+ widget.languageModel.languages[index],
+ ),
+ child: JHDisplayText(
+ text: widget.languageModel.languages[index],
+ style: TextStyles.title,
+ ).p(8),
+ ),
+ separatorBuilder: (BuildContext context, int index) =>
+ const Divider(
+ thickness: 1,
+ indent: 20,
+ endIndent: 20,
+ color: Colors.grey,
+ ).p4,
+ ),
+ ),
+ ),
+ ]),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/app/config/geo_full.dart b/lib/app/features/parent_side/map_page.dart
similarity index 93%
rename from lib/app/config/geo_full.dart
rename to lib/app/features/parent_side/map_page.dart
index 15bc992..e7b3f21 100644
--- a/lib/app/config/geo_full.dart
+++ b/lib/app/features/parent_side/map_page.dart
@@ -8,19 +8,19 @@ import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:provider/provider.dart';
-import 'package:times_up_flutter/common_widgets/jh_animated_green_dot.dart';
-import 'package:times_up_flutter/common_widgets/jh_display_text.dart';
-import 'package:times_up_flutter/common_widgets/jh_header_widget.dart';
-import 'package:times_up_flutter/common_widgets/jh_pin_marker.dart';
+import 'package:times_up_flutter/app/helpers/marker_generator_helper.dart';
import 'package:times_up_flutter/services/auth.dart';
import 'package:times_up_flutter/services/database.dart';
import 'package:times_up_flutter/services/geo_locator_service.dart';
-import 'package:times_up_flutter/services/marker_generator_service.dart';
import 'package:times_up_flutter/theme/theme.dart';
import 'package:times_up_flutter/utils/constants.dart';
+import 'package:times_up_flutter/widgets/jh_animated_green_dot.dart';
+import 'package:times_up_flutter/widgets/jh_display_text.dart';
+import 'package:times_up_flutter/widgets/jh_header_widget.dart';
+import 'package:times_up_flutter/widgets/jh_pin_marker.dart';
-class GeoFull extends StatefulWidget {
- const GeoFull(
+class MapView extends StatefulWidget {
+ const MapView(
this.initialPosition,
this.database,
this.auth,
@@ -46,7 +46,7 @@ class GeoFull extends StatefulWidget {
listen: false,
);
- return GeoFull(
+ return MapView(
position,
database,
auth,
@@ -56,10 +56,10 @@ class GeoFull extends StatefulWidget {
}
@override
- State createState() => _GeoFullState();
+ State createState() => _MapViewState();
}
-class _GeoFullState extends State with SingleTickerProviderStateMixin {
+class _MapViewState extends State with SingleTickerProviderStateMixin {
final Completer _controller = Completer();
late final AnimationController _animationController;
final _scaffoldKey = GlobalKey();
diff --git a/lib/app/pages/notification_page.dart b/lib/app/features/parent_side/notification_page.dart
similarity index 65%
rename from lib/app/pages/notification_page.dart
rename to lib/app/features/parent_side/notification_page.dart
index 1bba60e..48e2522 100644
--- a/lib/app/pages/notification_page.dart
+++ b/lib/app/features/parent_side/notification_page.dart
@@ -4,17 +4,19 @@ import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:line_awesome_flutter/line_awesome_flutter.dart';
import 'package:provider/provider.dart';
-import 'package:times_up_flutter/common_widgets/jh_display_text.dart';
-import 'package:times_up_flutter/common_widgets/jh_loading_widget.dart';
-import 'package:times_up_flutter/common_widgets/show_exeption_alert.dart';
+import 'package:times_up_flutter/app/helpers/parsing_extension.dart';
import 'package:times_up_flutter/models/notification_model/notification_model.dart';
import 'package:times_up_flutter/services/auth.dart';
import 'package:times_up_flutter/services/database.dart';
import 'package:times_up_flutter/services/notification_service.dart';
import 'package:times_up_flutter/theme/theme.dart';
+import 'package:times_up_flutter/widgets/jh_display_text.dart';
+import 'package:times_up_flutter/widgets/jh_loading_widget.dart';
+import 'package:times_up_flutter/widgets/show_exeption_alert.dart';
enum AppState { loaded, empty }
+//
class NotificationPage extends StatefulWidget {
const NotificationPage({
required this.auth,
@@ -49,7 +51,8 @@ class _NotificationPageState extends State {
Future _delete(BuildContext context, NotificationModel model) async {
try {
- await widget.database?.deleteNotification(model.id!);
+ await widget.database
+ ?.deleteNotification(model.timeStamp!.toIso8601String());
} on FirebaseException catch (e) {
await showExceptionAlertDialog(
context,
@@ -63,34 +66,22 @@ class _NotificationPageState extends State {
void initState() {
super.initState();
widget.auth.setToken();
- widget.notification?.configureFirebaseMessaging();
}
@override
Widget build(BuildContext context) {
+ final color = Theme.of(context).brightness == Brightness.dark
+ ? Colors.white
+ : CustomColors.indigoDark;
return NestedScrollView(
headerSliverBuilder: (BuildContext context, value) {
return [
SliverAppBar(
elevation: 0.5,
shadowColor: CustomColors.indigoLight,
- title: const JHDisplayText(
- text: 'Notifications',
- style: TextStyle(
- color: Colors.indigo,
- fontWeight: FontWeight.w900,
- ),
- ),
iconTheme: const IconThemeData(color: Colors.red),
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
expandedHeight: 50,
- shape: ContinuousRectangleBorder(
- side: BorderSide(
- color: !value
- ? Theme.of(context).scaffoldBackgroundColor
- : CustomColors.indigoLight.withOpacity(0.5),
- ),
- ),
pinned: true,
floating: true,
)
@@ -100,6 +91,28 @@ class _NotificationPageState extends State {
behavior: const ScrollBehavior().copyWith(overscroll: false),
child: CustomScrollView(
slivers: [
+ SliverToBoxAdapter(
+ child: JHDisplayText(
+ text: 'Notifications',
+ style: TextStyle(
+ color: color,
+ fontWeight: FontWeight.w700,
+ ),
+ fontSize: 32,
+ maxFontSize: 34,
+ ).hP16,
+ ),
+ SliverToBoxAdapter(
+ child: JHDisplayText(
+ text: 'slide from right to left to dismiss',
+ style: TextStyle(
+ color: Colors.grey.withOpacity(0.5),
+ fontWeight: FontWeight.w400,
+ ),
+ fontSize: 12,
+ maxFontSize: 14,
+ ).hP16,
+ ),
SliverList(
delegate: SliverChildListDelegate([
SingleChildScrollView(
@@ -114,9 +127,15 @@ class _NotificationPageState extends State {
}
Widget _buildStreamNotification(BuildContext context) {
+ final color = Theme.of(context).brightness == Brightness.dark
+ ? Colors.white
+ : CustomColors.indigoDark;
return StreamBuilder>(
stream: widget.database?.notificationStream(),
builder: (BuildContext context, snapshot) {
+ if (snapshot.connectionState == ConnectionState.waiting) {
+ return const SizedBox.shrink();
+ }
if (snapshot.hasData) {
final data = snapshot.data;
@@ -152,28 +171,34 @@ class _NotificationPageState extends State {
});
},
direction: DismissDirection.endToStart,
- child: Card(
- color: CustomColors.indigoLight,
- child: Padding(
- padding: const EdgeInsets.all(8),
- child: ListTile(
- title: JHDisplayText(
- text: data[index].title ?? 'No title available',
- style: const TextStyle(
- fontWeight: FontWeight.w600,
- color: Colors.white,
- fontSize: 16,
- ),
- ),
- trailing: JHDisplayText(
- text:
- data[index].message ?? 'No message available',
- style: const TextStyle(
- fontWeight: FontWeight.w600,
- color: Colors.white,
- fontSize: 16,
- ),
- ),
+ child: ListTile(
+ contentPadding:
+ const EdgeInsets.symmetric(horizontal: 10),
+ subtitle: JHDisplayText(
+ textAlign: TextAlign.start,
+ text: convertToFormattedString(
+ data[index].timeStamp,
+ ),
+ style: const TextStyle(
+ fontWeight: FontWeight.w400,
+ color: Colors.grey,
+ fontSize: 14,
+ ),
+ ),
+ title: JHDisplayText(
+ text: data[index].title ?? 'No title available',
+ style: TextStyle(
+ fontWeight: FontWeight.w600,
+ color: color,
+ fontSize: 16,
+ ),
+ ),
+ trailing: JHDisplayText(
+ text: data[index].message ?? 'No message available',
+ style: TextStyle(
+ fontWeight: FontWeight.w600,
+ color: color,
+ fontSize: 16,
),
),
),
diff --git a/lib/app/pages/parent_page.dart b/lib/app/features/parent_side/parent_page.dart
similarity index 51%
rename from lib/app/pages/parent_page.dart
rename to lib/app/features/parent_side/parent_page.dart
index b3910cc..587effa 100644
--- a/lib/app/pages/parent_page.dart
+++ b/lib/app/features/parent_side/parent_page.dart
@@ -6,21 +6,12 @@ import 'package:geolocator/geolocator.dart';
import 'package:line_awesome_flutter/line_awesome_flutter.dart';
import 'package:provider/provider.dart';
import 'package:showcaseview/showcaseview.dart';
-import 'package:times_up_flutter/app/config/geo_full.dart';
+import 'package:times_up_flutter/app/features/parent_side/child_details_page.dart';
+import 'package:times_up_flutter/app/features/parent_side/edit_child_page.dart';
+import 'package:times_up_flutter/app/features/parent_side/map_page.dart';
+import 'package:times_up_flutter/app/features/parent_side/notification_page.dart';
+import 'package:times_up_flutter/app/features/parent_side/setting_page.dart';
import 'package:times_up_flutter/app/helpers/parsing_extension.dart';
-import 'package:times_up_flutter/app/pages/child_details_page.dart';
-import 'package:times_up_flutter/app/pages/edit_child_page.dart';
-import 'package:times_up_flutter/app/pages/notification_page.dart';
-import 'package:times_up_flutter/app/pages/setting_page.dart';
-import 'package:times_up_flutter/common_widgets/child_horizontal_view.dart';
-import 'package:times_up_flutter/common_widgets/jh_display_text.dart';
-import 'package:times_up_flutter/common_widgets/jh_empty_content.dart';
-import 'package:times_up_flutter/common_widgets/jh_header.dart';
-import 'package:times_up_flutter/common_widgets/jh_header_widget.dart';
-import 'package:times_up_flutter/common_widgets/jh_info_row_widget.dart';
-import 'package:times_up_flutter/common_widgets/jh_loading_widget.dart';
-import 'package:times_up_flutter/common_widgets/jh_summary_tile.dart';
-import 'package:times_up_flutter/common_widgets/show_logger.dart';
import 'package:times_up_flutter/l10n/l10n.dart';
import 'package:times_up_flutter/models/child_model/child_model.dart';
import 'package:times_up_flutter/services/api_path.dart';
@@ -32,6 +23,15 @@ import 'package:times_up_flutter/services/notification_service.dart';
import 'package:times_up_flutter/services/shared_preferences.dart';
import 'package:times_up_flutter/theme/theme.dart';
import 'package:times_up_flutter/utils/data.dart';
+import 'package:times_up_flutter/widgets/child_horizontal_view.dart';
+import 'package:times_up_flutter/widgets/jh_display_text.dart';
+import 'package:times_up_flutter/widgets/jh_empty_content.dart';
+import 'package:times_up_flutter/widgets/jh_header.dart';
+import 'package:times_up_flutter/widgets/jh_header_widget.dart';
+import 'package:times_up_flutter/widgets/jh_info_row_widget.dart';
+import 'package:times_up_flutter/widgets/jh_shimmer_map.dart';
+import 'package:times_up_flutter/widgets/jh_summary_tile.dart';
+import 'package:times_up_flutter/widgets/show_logger.dart';
typedef ValueList = List