diff --git a/assets/images/1.png b/assets/images/1.png new file mode 100644 index 0000000..055a1f4 Binary files /dev/null and b/assets/images/1.png differ diff --git a/assets/images/10.png b/assets/images/10.png new file mode 100644 index 0000000..b017aa9 Binary files /dev/null and b/assets/images/10.png differ diff --git a/assets/images/2.png b/assets/images/2.png new file mode 100644 index 0000000..61ba398 Binary files /dev/null and b/assets/images/2.png differ diff --git a/assets/images/3.png b/assets/images/3.png new file mode 100644 index 0000000..80a458e Binary files /dev/null and b/assets/images/3.png differ diff --git a/assets/images/4.png b/assets/images/4.png new file mode 100644 index 0000000..956aa88 Binary files /dev/null and b/assets/images/4.png differ diff --git a/assets/images/5.png b/assets/images/5.png new file mode 100644 index 0000000..9cfddef Binary files /dev/null and b/assets/images/5.png differ diff --git a/assets/images/6.png b/assets/images/6.png new file mode 100644 index 0000000..96482ff Binary files /dev/null and b/assets/images/6.png differ diff --git a/assets/images/7.png b/assets/images/7.png new file mode 100644 index 0000000..4f7fd44 Binary files /dev/null and b/assets/images/7.png differ diff --git a/assets/images/8.png b/assets/images/8.png new file mode 100644 index 0000000..9ae7122 Binary files /dev/null and b/assets/images/8.png differ diff --git a/assets/images/9.png b/assets/images/9.png new file mode 100644 index 0000000..7983245 Binary files /dev/null and b/assets/images/9.png differ diff --git a/assets/images/back.jpg b/assets/images/back.jpg new file mode 100644 index 0000000..d6b3f91 Binary files /dev/null and b/assets/images/back.jpg differ diff --git a/assets/images/color.png b/assets/images/color.png new file mode 100644 index 0000000..f852fa2 Binary files /dev/null and b/assets/images/color.png differ diff --git a/assets/images/splashImage.png b/assets/images/splashImage.png new file mode 100644 index 0000000..dc2c4f1 Binary files /dev/null and b/assets/images/splashImage.png differ diff --git a/assets/images/study.png b/assets/images/study.png new file mode 100644 index 0000000..b017aa9 Binary files /dev/null and b/assets/images/study.png differ diff --git a/lib/app_theme.dart b/lib/app_theme.dart index 88dbcc9..8b5382d 100644 --- a/lib/app_theme.dart +++ b/lib/app_theme.dart @@ -4,7 +4,7 @@ import 'package:sk_base_mobile/util/screen_adaper_util.dart'; class AppTheme { AppTheme._(); static const Color primaryColor = Color(0xFFC89607); - static Color primaryColorLight = primaryColor.withOpacity(0.7); + static const Color primaryColorLight = Color.fromARGB(255, 255, 206, 70); static Color primaryColorDark = Color.fromRGBO( primaryColor.red, primaryColor.green, @@ -21,6 +21,8 @@ class AppTheme { static const Color snackbarWarningBackgroudColor = Colors.orange; static Color barrierColor = Colors.black.withOpacity(0.5); static const String fontName = 'NotoSans'; + static const Color activeNavigationBarColor = primaryColor; + static const Color notActiveNavigationBarColor = Colors.grey; } final theme = ThemeData( diff --git a/lib/constants/bg_color.dart b/lib/constants/bg_color.dart new file mode 100644 index 0000000..72ead68 --- /dev/null +++ b/lib/constants/bg_color.dart @@ -0,0 +1,13 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; + +const lightAccentBlue = Color(0xFF92E2FF); +const darkAccentBlue = Color(0xFF1DBEF9); +const lightOrange = Color(0xFFFFD099); +const darkOrange = Color(0xFFFE9B48); +const lightBlue = Color(0xFF7395CF); +const darkBlue = Color(0xFF3C5073); +const neviBlue = Color(0xFF45597A); +const darkestBlue = Color(0xFF1E2843); +const defaultPadding = 20.0; diff --git a/lib/constants/data.dart b/lib/constants/data.dart index dd615e3..816c044 100644 --- a/lib/constants/data.dart +++ b/lib/constants/data.dart @@ -1,3 +1,8 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; + class Data { static const parkDetail = { "elephant": { @@ -90,4 +95,45 @@ class Data { 'swan': 899, 'squirrel': 399 }; + + Map images = { + '0': 'assets/images/1.png', + '1': 'assets/images/2.png', + '2': 'assets/images/3.png', + '3': 'assets/images/4.png', + '4': 'assets/images/5.png', + '5': 'assets/images/6.png', + '6': 'assets/images/7.png', + '7': 'assets/images/8.png', + '8': 'assets/images/9.png', + '9': 'assets/images/10.png', + }; + List colors = [ + lightBlue, + lightAccentBlue, + darkAccentBlue, + darkOrange, + lightOrange, + Colors.pinkAccent, + Colors.purpleAccent, + Colors.greenAccent, + neviBlue, + Colors.tealAccent + ]; + List tags = [ + 'Study', + 'Productive', + 'Work', + 'Personal', + 'Health', + 'Home', + 'Errands', + 'Social', + 'Finance', + 'Hobby', + 'Family', + 'Self-care', + 'Tech', + 'Creative', + ]; } diff --git a/lib/constants/router.dart b/lib/constants/router.dart index 9fef4f0..b2d8785 100644 --- a/lib/constants/router.dart +++ b/lib/constants/router.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; import 'package:sk_base_mobile/screens/login/login.dart'; -import '../screens/landing/zt_landing.dart'; +import '../screens/landing/landing.dart'; import '../screens/mine/useinfo/userinfo.dart'; class RouteConfig { diff --git a/lib/db_helper/dbHelper.dart b/lib/db_helper/dbHelper.dart new file mode 100644 index 0000000..b2bc0c5 --- /dev/null +++ b/lib/db_helper/dbHelper.dart @@ -0,0 +1,60 @@ +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:sk_base_mobile/models/task_model.dart'; +import 'package:sk_base_mobile/util/util.dart'; +import 'package:sqflite/sqflite.dart'; +import 'package:path/path.dart'; +import 'package:path_provider/path_provider.dart'; + +class DbHelper { + Database? _db; + Future get db async { + if (_db != null) { + return _db; + } + final directory = Platform.isAndroid + ? await getExternalStorageDirectory() + : await getApplicationSupportDirectory(); + String path = join(directory!.path, 'db'); + var db = await openDatabase( + path, + version: 1, + onCreate: (db, version) { + db.execute( + "CREATE TABLE Tasks(key TEXT PRIMARY KEY,title TEXT,category TEXT,description TEXT,image TEXT,date TEXT,startTime TEXT,periority TEXT,show TEXT,endTime TEXT,status,TEXT)"); + }, + ); + return db; + } + + Future insert(TaskModel model) async { + var dbClient = await db; + dbClient!.insert('Tasks', model.toMap()).then((value) {}); + return model; + } + + Future delete(String id, String table) async { + var dbClient = await db; + return await dbClient! + .delete(table, where: 'key = ?', whereArgs: [id]).then((value) { + SnackBarUtil().success( + 'Deleted', + message: 'Task is removed successfully', + ); + return value; + }); + } + + Future update(String id, String key, String value) async { + var dbClient = await db; + return await dbClient! + .update('Tasks', {key: value}, where: 'key = ?', whereArgs: [id]); + } + + Future> getData() async { + var dbClient = await db; + final List> queryResult = + await dbClient!.query('Tasks'); + return queryResult.map((e) => TaskModel.fromMap(e)).toList(); + } +} diff --git a/lib/models/task_model.dart b/lib/models/task_model.dart new file mode 100644 index 0000000..6e89ff5 --- /dev/null +++ b/lib/models/task_model.dart @@ -0,0 +1,58 @@ +import 'dart:core'; + +class TaskModel { + String? key; + String? title; + String? category; + String? description; + String? image; + String? periority; + String? startTime; + String? endTime; + String? date; + String? show; + String? status; + + TaskModel( + { required this.key, + required this.startTime, + required this.endTime, + required this.date, + required this.periority, + required this.description, + required this.category, + required this.title, + required this.image, + required this.show, + required this.status}); + + TaskModel.fromMap(Map res) { + key = res['key']; + title = res['title']; + category = res['category']; + description = res['description']; + image = res['image']; + periority = res['periority']; + show = res['show']; + startTime = res['startTime']; + endTime = res['endTime']; + date = res['date']; + status=res['status']; + } + + Map toMap() { + return { + 'key': key, + 'title': title, + 'category': category, + 'description': description, + 'image': image, + 'periority': periority, + 'startTime': startTime, + 'endTime': endTime, + 'date': date, + 'show': show, + 'status' : status, + }; + } +} \ No newline at end of file diff --git a/lib/screens/home/components/change_button_roe.dart b/lib/screens/home/components/change_button_roe.dart new file mode 100644 index 0000000..0a0b55b --- /dev/null +++ b/lib/screens/home/components/change_button_roe.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/screens/home/components/change_icon.dart'; +import 'package:sk_base_mobile/screens/home/components/today_button.dart'; +import 'package:sk_base_mobile/screens/home/home_controller.dart'; + +class ChangeButtonRow extends StatelessWidget { + ChangeButtonRow({super.key}); + final controller = Get.put(HomeController()); + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric( + horizontal: MediaQuery.sizeOf(context).width * 0.06), + child: Row( + children: [ + TodayButton(), + Spacer(), + InkWell( + onTap: () => controller.onMoveBack(), + child: ChangeIconButton( + icon: Icon( + Icons.arrow_back_ios_rounded, + color: Colors.white, + size: 15, + ))), + SizedBox( + width: defaultPadding / 2, + ), + InkWell( + onTap: () => controller.onMoveNextPage(), + child: ChangeIconButton( + icon: Icon( + Icons.arrow_forward_ios_rounded, + color: Colors.white, + size: 15, + ))), + ], + ), + ); + } +} diff --git a/lib/screens/home/components/change_icon.dart b/lib/screens/home/components/change_icon.dart new file mode 100644 index 0000000..880fc5e --- /dev/null +++ b/lib/screens/home/components/change_icon.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; + +class ChangeIconButton extends StatelessWidget { + const ChangeIconButton({super.key, required this.icon}); + final Widget icon; + @override + Widget build(BuildContext context) { + return Container( + height: 40, + width: 40, + alignment: Alignment.center, + decoration: + BoxDecoration(shape: BoxShape.circle, color: neviBlue, boxShadow: [ + BoxShadow( + color: neviBlue.withOpacity(.3), + offset: Offset(0, 10), + blurRadius: 10) + ]), + child: icon, + ); + } +} diff --git a/lib/screens/home/components/custom_app_bar.dart b/lib/screens/home/components/custom_app_bar.dart new file mode 100644 index 0000000..966cf27 --- /dev/null +++ b/lib/screens/home/components/custom_app_bar.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/screens/home/home_controller.dart'; +import 'package:sk_base_mobile/util/screen_adaper_util.dart'; + +class CustomAppBar extends StatelessWidget { + CustomAppBar({super.key}); + final controller = Get.put(HomeController()); + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 30), + child: Row( + children: [ + if (ScreenAdaper.isLandspace()) Spacer(), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Hello,', + style: Theme.of(context).textTheme.titleMedium!.copyWith( + color: Colors.black87, + fontWeight: FontWeight.w400, + height: 0, + letterSpacing: 2, + fontSize: 18), + ), + Obx( + () => Text( + controller.name.value, + style: Theme.of(context).textTheme.titleMedium!.copyWith( + color: Colors.black, + fontWeight: FontWeight.bold, + letterSpacing: 2, + height: 0, + fontSize: 25), + ), + ) + ], + ), + const Spacer( + flex: 10, + ), + Container( + height: 50, + width: 50, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: darkAccentBlue, + boxShadow: const [ + BoxShadow( + color: lightAccentBlue, + blurRadius: 20, + offset: Offset(0, 10)) + ]), + child: const Icon( + Icons.account_circle_outlined, + color: Colors.white, + ), + ), + if (ScreenAdaper.isLandspace()) const Spacer(), + ], + ), + ); + } +} diff --git a/lib/screens/home/components/date_container.dart b/lib/screens/home/components/date_container.dart new file mode 100644 index 0000000..7fca533 --- /dev/null +++ b/lib/screens/home/components/date_container.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/screens/home/home_controller.dart'; +import 'dates.dart'; + +class DateContainer extends StatelessWidget { + final int index; + DateContainer({super.key, required this.index}); + final controller = Get.put(HomeController()); + @override + Widget build(BuildContext context) { + var size = MediaQuery.sizeOf(context); + return Obx(() => AnimatedContainer( + duration: const Duration(milliseconds: 200), + height: 110, + width: 70, + margin: EdgeInsets.only(left: size.width * 0.05), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20), + gradient: controller.currentIndex.value == index + ? const LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [lightOrange, darkOrange]) + : null, + boxShadow: [ + controller.currentIndex.value == index + ? const BoxShadow( + color: lightOrange, offset: Offset(0, 10), blurRadius: 20) + : const BoxShadow( + color: Colors.black12, + offset: Offset(0, 10), + blurRadius: 20) + ]), + child: Dates(index: index))); + } +} diff --git a/lib/screens/home/components/dates.dart b/lib/screens/home/components/dates.dart new file mode 100644 index 0000000..4aca05d --- /dev/null +++ b/lib/screens/home/components/dates.dart @@ -0,0 +1,55 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/screens/home/home_controller.dart'; +import 'package:sk_base_mobile/util/util.dart'; + +class Dates extends StatelessWidget { + Dates({super.key, required this.index}); + final int index; + final controller = Get.put(HomeController()); + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Obx( + () => Text( + DateUtil.getMonth(DateTime.now().add(Duration(days: index))), + style: TextStyle( + color: controller.currentIndex.value == index + ? Colors.white + : Colors.black, + fontWeight: FontWeight.bold, + fontSize: 13, + height: 0), + ), + ), + Obx( + () => Text( + DateUtil.getDate(DateTime.now().add(Duration(days: index))), + style: TextStyle( + color: controller.currentIndex.value == index + ? Colors.white + : Colors.black, + fontWeight: FontWeight.bold, + fontSize: 26, + height: 0), + ), + ), + Obx( + () => Text( + DateUtil.getDay(DateTime.now().add(Duration(days: index))), + style: TextStyle( + color: controller.currentIndex.value == index + ? Colors.white + : Colors.black, + fontWeight: FontWeight.bold, + fontSize: 13), + ), + ) + ], + ); + } +} diff --git a/lib/screens/home/components/responsive.dart b/lib/screens/home/components/responsive.dart new file mode 100644 index 0000000..39f2adf --- /dev/null +++ b/lib/screens/home/components/responsive.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; + +class Responsive extends StatelessWidget { + const Responsive({super.key, required this.tablet, required this.mobile, required this.largeTablet}); + final Widget tablet; + final Widget mobile; + final Widget largeTablet; + + static bool isTablet(BuildContext context){ + return MediaQuery.sizeOf(context).width>500; + } + + static bool isLargeTablet(BuildContext context){ + return MediaQuery.sizeOf(context).width>1000; + } + + @override + Widget build(BuildContext context) { + var size=MediaQuery.sizeOf(context); + if(size.width >1000){ + return largeTablet; + } + else if(size.width >500){ + return tablet; + }else{ + return mobile; + } + } +} diff --git a/lib/screens/home/components/task_detail_col.dart b/lib/screens/home/components/task_detail_col.dart new file mode 100644 index 0000000..f611635 --- /dev/null +++ b/lib/screens/home/components/task_detail_col.dart @@ -0,0 +1,68 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/constants/data.dart'; +import 'package:sk_base_mobile/screens/home/home_controller.dart'; + +class TaskTitle extends StatelessWidget { + TaskTitle({super.key, required this.index, required this.ind}); + final int index; + final int ind; + final int randomColor1 = Random().nextInt(9); + final int randomColor2 = Random().nextInt(9); + final controller = Get.put(HomeController()); + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + controller.list[ind][index].title, + style: const TextStyle( + color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), + ), + Text( + '${controller.list[ind][index].startTime} - ${controller.list[ind][index].endTime}', + style: const TextStyle( + color: Colors.grey, fontWeight: FontWeight.w300, fontSize: 12), + ), + const SizedBox( + height: defaultPadding / 2, + ), + Row( + children: [ + Container( + alignment: Alignment.center, + padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 10), + decoration: BoxDecoration( + color: Data().colors[randomColor1].withOpacity(.5), + borderRadius: BorderRadius.circular(10), + ), + child: Text( + Data().tags[Random().nextInt(13)], + style: TextStyle(color: Data().colors[randomColor1]), + ), + ), + const SizedBox( + width: defaultPadding / 2, + ), + Container( + alignment: Alignment.center, + padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 10), + decoration: BoxDecoration( + color: Data().colors[randomColor2].withOpacity(.5), + borderRadius: BorderRadius.circular(10)), + child: Text( + Data().tags[Random().nextInt(13)], + style: TextStyle(color: Data().colors[randomColor2]), + ), + ) + ], + ), + ], + ); + } +} diff --git a/lib/screens/home/components/task_detail_container.dart b/lib/screens/home/components/task_detail_container.dart new file mode 100644 index 0000000..4f7f6e0 --- /dev/null +++ b/lib/screens/home/components/task_detail_container.dart @@ -0,0 +1,153 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/constants/data.dart'; +import 'package:sk_base_mobile/screens/home/components/task_detail_col.dart'; +import 'package:sk_base_mobile/screens/home/home_controller.dart'; +import 'package:sk_base_mobile/util/util.dart'; + +class TaskDetailContainer extends StatelessWidget { + TaskDetailContainer({super.key, required this.index, required this.ind}); + final int index; + final int ind; + final controller = Get.put(HomeController()); + @override + Widget build(BuildContext context) { + return Dismissible( + key: UniqueKey(), + confirmDismiss: (direction) async { + return await ModalUtil.showWarningDialog( + 'Remove Task', 'Are you sure to remove this task', 'Confirm', () { + controller.db.delete(controller.list[ind][index].key, 'Tasks'); + controller.list[ind].remove(controller.list[ind][index]); + }); + }, + child: Container( + margin: const EdgeInsets.symmetric(vertical: 10, horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration(boxShadow: [ + BoxShadow( + color: lightAccentBlue.withOpacity(.5), + offset: Offset(0, 5), + blurRadius: 10), + ], color: Colors.white, borderRadius: BorderRadius.circular(30)), + child: Row( + children: [ + Image.asset( + Data().images[controller.list[ind][index].image], + height: 100, + width: 100, + ), + const Spacer( + flex: 1, + ), + TaskTitle(index: index, ind: ind), + const Spacer( + flex: 2, + ), + controller.list[ind][index].status == 'complete' + ? Container( + height: 40, + width: 40, + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + lightOrange, + darkOrange, + ]), + boxShadow: [ + BoxShadow( + color: lightOrange, + offset: Offset(0, 10), + blurRadius: 10) + ]), + child: const Icon( + Icons.done, + color: Colors.white, + ), + ) + : Align( + alignment: Alignment.topRight, + child: Padding( + padding: const EdgeInsets.only(top: 20), + child: PopupMenuButton( + onSelected: (value) => controller.onTaskComplete( + value, + index, + ind, + controller.list[ind][index].key, + context), + surfaceTintColor: Colors.white, + padding: EdgeInsets.zero, + icon: const Icon( + Icons.more_vert_rounded, + color: Colors.grey, + size: 24, + ), + shape: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide.none, + ), + itemBuilder: (context) { + return [ + const PopupMenuItem( + height: 25, + value: 1, + child: Row( + children: [ + Icon( + Icons.edit_note, + color: Colors.orange, + size: 14, + ), + SizedBox( + width: defaultPadding / 2, + ), + Text('Edit') + ], + )), + const PopupMenuItem( + height: 25, + value: 2, + child: Row( + children: [ + Icon( + Icons.delete_outline, + color: Colors.orange, + size: 14, + ), + SizedBox( + width: defaultPadding / 2, + ), + Text('Delete') + ], + )), + const PopupMenuItem( + height: 25, + value: 3, + child: Row( + children: [ + Icon( + Icons.done_all_outlined, + color: Colors.orange, + size: 14, + ), + SizedBox( + width: defaultPadding / 2, + ), + Text('Complete') + ], + )), + ]; + }, + )), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/home/components/task_list.dart b/lib/screens/home/components/task_list.dart new file mode 100644 index 0000000..152f591 --- /dev/null +++ b/lib/screens/home/components/task_list.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/screens/home/components/responsive.dart'; +import 'package:sk_base_mobile/screens/home/components/task_detail_container.dart'; +import 'package:sk_base_mobile/screens/home/home_controller.dart'; + +class TaskList extends StatelessWidget { + const TaskList({super.key, required this.index}); + final int index; + @override + Widget build(BuildContext context) { + return Responsive( + tablet: Grid( + crossAsis: 2, + ratio: 3, + ind: index, + ), + largeTablet: Grid( + crossAsis: 3, + ratio: 3, + ind: index, + ), + mobile: Grid( + ratio: 3, + crossAsis: 1, + ind: index, + )); + } +} + +class Grid extends StatelessWidget { + final int crossAsis; + final double ratio; + final int ind; + final controller = Get.put(HomeController()); + Grid( + {super.key, + required this.crossAsis, + required this.ratio, + required this.ind}); + @override + Widget build(BuildContext context) { + return Obx(() => controller.list[ind].isEmpty + ? const Center( + child: Text( + 'No Task Today', + style: + TextStyle(color: Colors.black, fontWeight: FontWeight.bold), + ), + ) + : GridView.builder( + padding: const EdgeInsets.only(top: 40), + itemCount: controller.list[ind].length, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: crossAsis, childAspectRatio: ratio), + itemBuilder: (context, index) { + return TaskDetailContainer( + index: index, + ind: ind, + ); + }, + )); + } +} diff --git a/lib/screens/home/components/task_page_View.dart b/lib/screens/home/components/task_page_View.dart new file mode 100644 index 0000000..d9af6ff --- /dev/null +++ b/lib/screens/home/components/task_page_View.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/screens/home/components/task_list.dart'; +import 'package:sk_base_mobile/screens/home/home_controller.dart'; + +class TaskPageView extends StatelessWidget { + TaskPageView({super.key}); + final controller = Get.put(HomeController()); + @override + Widget build(BuildContext context) { + return PageView( + physics: const NeverScrollableScrollPhysics(), + controller: controller.pageController, + children: const [ + TaskList( + index: 0, + ), + TaskList( + index: 1, + ), + TaskList( + index: 2, + ), + TaskList( + index: 3, + ), + TaskList( + index: 4, + ), + TaskList( + index: 5, + ), + TaskList( + index: 6, + ), + ], + ); + } +} diff --git a/lib/screens/home/components/task_page_holder.dart b/lib/screens/home/components/task_page_holder.dart new file mode 100644 index 0000000..308f996 --- /dev/null +++ b/lib/screens/home/components/task_page_holder.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; +import 'package:sk_base_mobile/screens/home/components/change_button_roe.dart'; +import 'package:sk_base_mobile/screens/home/components/task_page_View.dart'; + +class TaskPageBody extends StatelessWidget { + const TaskPageBody({super.key}); + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Positioned.fill( + child: Container( + margin: const EdgeInsets.only(top: 25), + decoration: BoxDecoration( + borderRadius: const BorderRadius.only( + topRight: Radius.circular(40), topLeft: Radius.circular(40)), + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.white.withOpacity(.6), + Colors.white.withOpacity(.5), + Colors.white.withOpacity(.4), + Colors.white.withOpacity(.3), + Colors.white.withOpacity(.2), + Colors.white.withOpacity(.0), + Colors.white.withOpacity(.0), + Colors.white.withOpacity(.0), + Colors.white.withOpacity(.0), + Colors.white.withOpacity(.0), + ])), + child: TaskPageView(), + )), + ChangeButtonRow(), + ], + ); + } +} diff --git a/lib/screens/home/components/today_button.dart b/lib/screens/home/components/today_button.dart new file mode 100644 index 0000000..c3f26aa --- /dev/null +++ b/lib/screens/home/components/today_button.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/screens/home/home_controller.dart'; + +class TodayButton extends StatelessWidget { + const TodayButton({super.key}); + + @override + Widget build(BuildContext context) { + final controller = Get.put(HomeController()); + return InkWell( + borderRadius: BorderRadius.circular(30), + onTap: () => controller.pageController.animateToPage(0, + duration: Duration(milliseconds: 300), curve: Curves.easeIn), + child: Container( + height: 50, + width: 150, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(30), + boxShadow: const [ + BoxShadow( + color: lightAccentBlue, offset: Offset(0, 5), blurRadius: 20) + ], + gradient: const LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [lightAccentBlue, darkAccentBlue])), + child: const Text( + 'Today', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + ), + ); + } +} diff --git a/lib/screens/home/components/upper_body.dart b/lib/screens/home/components/upper_body.dart new file mode 100644 index 0000000..ee7e7fb --- /dev/null +++ b/lib/screens/home/components/upper_body.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/screens/home/components/custom_app_bar.dart'; +import 'package:sk_base_mobile/screens/home/components/date_container.dart'; +import 'package:sk_base_mobile/screens/home/home_controller.dart'; + +class UperBody extends StatelessWidget { + UperBody({super.key}); + final controller = Get.put(HomeController()); + @override + Widget build(BuildContext context) { + return Column( + children: [ + const SizedBox( + height: defaultPadding, + ), + CustomAppBar(), + SizedBox( + height: 150, + child: ListView.builder( + controller: controller.scrollController, + itemCount: 7, + shrinkWrap: true, + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.only(bottom: 30, top: defaultPadding), + itemBuilder: (context, index) { + return InkWell( + borderRadius: BorderRadius.circular(20), + onTap: () => controller.setIndex(index), + child: DateContainer(index: index), + ); + }, + ), + ), + ], + ); + } +} diff --git a/lib/screens/home/home.dart b/lib/screens/home/home.dart index 7adc960..ff0a004 100644 --- a/lib/screens/home/home.dart +++ b/lib/screens/home/home.dart @@ -1,13 +1,20 @@ import 'package:flutter/material.dart'; +import 'package:sk_base_mobile/screens/home/components/task_page_holder.dart'; +import 'package:sk_base_mobile/screens/home/components/upper_body.dart'; class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: Text('首页')), - body: SizedBox(child: Text('sss')), + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + UperBody(), + const Expanded( + child: TaskPageBody(), + ), + ], ); } } diff --git a/lib/screens/home/home_controller.dart b/lib/screens/home/home_controller.dart new file mode 100644 index 0000000..0d3e42e --- /dev/null +++ b/lib/screens/home/home_controller.dart @@ -0,0 +1,107 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/db_helper/dbHelper.dart'; +import 'package:sk_base_mobile/util/modal.util.dart'; + +class HomeController extends GetxController { + RxMap userData = {}.obs; + RxString name = ''.obs; + RxInt currentIndex = 0.obs; + final PageController pageController = PageController(); + final DateTime dateTime = DateTime.now(); + final DbHelper db = DbHelper(); + List list = [ + [].obs, + [].obs, + [].obs, + [].obs, + [].obs, + [].obs, + [].obs, + ].obs; + RxInt barIndex = 0.obs; + RxList model = [].obs; + final ScrollController scrollController = ScrollController(); + + HomeController() { + if (userData['NAME'] == null) { + getUserData(); + } + } + + getUserData() async { + getName(); + } + + getName() {} + + getTasks() async { + db.getData().then((value) { + model.value = value; + getSepretLists(); + }); + } + + setIndex(int value) { + pageController.animateToPage(value, + duration: const Duration(milliseconds: 300), curve: Curves.easeIn); + currentIndex.value = value; + } + + getDateAccordingTabs(int value) {} + getSepretLists() { + // List> tempList = []; + // for (int i = 0; i < 7; i++) { + // RxList tempList1 = [].obs; + // tempList1.clear(); + // for (int j = 0; j < model.length; j++) { + // if (model[j].date == getDateAccordingTabs(i)) { + // tempList1.add(model[j]); + // } + // } + // tempList.add(tempList1); + // } + // list = tempList; + } + + onMoveNextPage() { + if (currentIndex.value < 7) { + setIndex(currentIndex.value + 1); + } + } + + onMoveBack() { + if (currentIndex.value > 0) { + setIndex(currentIndex.value - 1); + } + } + + onTaskComplete( + int value, int index, int ind, String key, BuildContext context) { + switch (value) { + case 3: + { + ModalUtil.showWarningDialog('Complete Task', + 'This task will be marked as completed', 'Confirm', () { + list[ind][index].status = 'complete'; + list[ind].add(''); + list[ind].remove(''); + db.update(key, 'status', 'complete'); + }); + } + case 2: + { + ModalUtil.showWarningDialog( + 'Delete Task', 'Are you want to sure to remove', 'Confirm', () { + list[ind].remove(list[ind][index]); + db.delete( + key, + 'Tasks', + ); + }); + } + } + } +} diff --git a/lib/screens/landing/landing.dart b/lib/screens/landing/landing.dart new file mode 100644 index 0000000..4204186 --- /dev/null +++ b/lib/screens/landing/landing.dart @@ -0,0 +1,29 @@ +// import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/screens/landing/landing_controller.dart'; +import 'package:sk_base_mobile/widgets/back_decoration.dart'; +import 'package:sk_base_mobile/widgets/bottom_nav_bar.dart'; +import 'package:sk_base_mobile/widgets/floating_action.dart'; + +class LandingPage extends StatelessWidget { + LandingPage({super.key}); + final controller = Get.put(LandingController()); + + @override + Widget build(BuildContext context) { + return Material( + child: Stack(children: [ + const BackColors(), + SafeArea( + child: Scaffold( + floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, + floatingActionButton: const FloatingButton(), + bottomNavigationBar: BottomNavBar(), + backgroundColor: Colors.transparent, + body: Obx(() => controller.pages[controller.currentIndex.value]), + )) + ])); + } +} diff --git a/lib/screens/landing/landing_controller.dart b/lib/screens/landing/landing_controller.dart new file mode 100644 index 0000000..66c82b4 --- /dev/null +++ b/lib/screens/landing/landing_controller.dart @@ -0,0 +1,119 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/models/app_bottom_nav_item.dart'; +import 'package:sk_base_mobile/services/app_info.service.dart'; + +class LandingController extends GetxController { + RxMap userData = {}.obs; + RxString name = ''.obs; + RxInt currentIndex = 0.obs; + final PageController pageController = PageController(); + final DateTime dateTime = DateTime.now(); + + List iconList = [Icons.home_max, Icons.person_outline_rounded]; + List list = [ + [].obs, + [].obs, + [].obs, + [].obs, + [].obs, + [].obs, + [].obs, + ].obs; + RxList model = [].obs; + final ScrollController scrollController = ScrollController(); + RxList bottomNavItems = RxList([]); + List pages = []; + + @override + onInit() { + super.onInit(); + List roleWithBottomNavItems = + AppInfoService.to.bottomNavItems!; + bottomNavItems.assignAll(roleWithBottomNavItems + .map((e) => BottomNavigationBarItem( + icon: e.icon, activeIcon: e.activeIcon, label: e.label)) + .toList()); + pages = roleWithBottomNavItems.map((e) => e.page!).toList(); + } + + getUserData() async { + getName(); + } + + getName() { + // name.value = userData['NAME']; + } + + getTasks() async { + // db.getData().then((value) { + // model.value = value; + // getSepretLists(); + // }); + } + + setIndex(int value) { + pageController.animateToPage(value, + duration: const Duration(milliseconds: 300), curve: Curves.easeIn); + currentIndex.value = value; + } + + // getDateAccordingTabs(int value) { + // return '${Utils.addPrefix(dateTime.add(Duration(days: value)).day.toString())}/${Utils.addPrefix(dateTime.add(Duration(days: value)).month.toString())}/${Utils.addPrefix(dateTime.add(Duration(days: value)).year.toString())}'; + // } + + getSepretLists() { + // List> tempList = []; + // for (int i = 0; i < 7; i++) { + // RxList tempList1 = [].obs; + // tempList1.clear(); + // for (int j = 0; j < model.length; j++) { + // if (model[j].date == getDateAccordingTabs(i)) { + // tempList1.add(model[j]); + // } + // } + // tempList.add(tempList1); + // } + // list = tempList; + } + + onMoveNextPage() { + if (currentIndex.value < 7) { + setIndex(currentIndex.value + 1); + } + } + + onMoveBack() { + if (currentIndex.value > 0) { + setIndex(currentIndex.value - 1); + } + } + + onTaskComplete( + int value, int index, int ind, String key, BuildContext context) { + // switch (value) { + // case 3: + // { + // Utils.showWarningDialog(context, 'Complete Task', + // 'This task will be marked as completed', 'Confirm', () { + // list[ind][index].status = 'complete'; + // list[ind].add(''); + // list[ind].remove(''); + // db.update(key, 'status', 'complete'); + // }); + // } + // case 2: + // { + // Utils.showWarningDialog(context, 'Delete Task', + // 'Are you want to sure to remove', 'Confirm', () { + // list[ind].remove(list[ind][index]); + // db.delete( + // key, + // 'Tasks', + // ); + // }); + // } + // } + } +} diff --git a/lib/screens/landing/zt_landing.dart b/lib/screens/landing/zt_landing.dart deleted file mode 100644 index 827f476..0000000 --- a/lib/screens/landing/zt_landing.dart +++ /dev/null @@ -1,63 +0,0 @@ -// import 'dart:io'; - -import 'dart:io'; -import 'package:flutter/material.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; -import '../../models/app_bottom_nav_item.dart'; -import '../../services/app_info.service.dart'; -import '../../util/util.dart'; - -class LandingPage extends StatefulWidget { - LandingPage({Key? key}) : super(key: key); - - @override - _LandingPageState createState() => _LandingPageState(); -} - -class _LandingPageState extends State { - int _selectedLanding = 0; - - List bottomNavItems = []; - List pages = []; - - @override - Widget build(BuildContext context) { - // ScreenUtil.init( - // BoxConstraints( - // maxWidth: MediaQuery.of(context).size.width, - // maxHeight: MediaQuery.of(context).size.height), - // designSize: const Size(414, 896), - // orientation: Orientation.portrait, - // context: context, - // ); - List roleWithBottomNavItems = - AppInfoService.to.bottomNavItems!; - bottomNavItems = roleWithBottomNavItems - .map((e) => BottomNavigationBarItem( - icon: e.icon, activeIcon: e.activeIcon, label: e.label)) - .toList(); - pages = roleWithBottomNavItems.map((e) => e.page!).toList(); - return Scaffold( - bottomNavigationBar: BottomNavigationBar( - iconSize: ScreenAdaper.sp(40), - type: BottomNavigationBarType.fixed, - items: bottomNavItems, - showSelectedLabels: true, - showUnselectedLabels: true, - currentIndex: _selectedLanding, - onTap: (landing) { - _onItemTapped(landing); - }, - ), - body: pages[_selectedLanding], - ); - } - - void _onItemTapped(int landing) { - if (landing != _selectedLanding) { - setState(() { - _selectedLanding = landing; - }); - } - } -} diff --git a/lib/screens/new_task/components/category_input.dart b/lib/screens/new_task/components/category_input.dart new file mode 100644 index 0000000..d915900 --- /dev/null +++ b/lib/screens/new_task/components/category_input.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/screens/new_task/components/text_input.dart'; +import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; + +class CategoryInput extends StatelessWidget { + CategoryInput({super.key}); + + final controller = Get.put(NewTaskController()); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: defaultPadding / 2, + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Text( + 'Category', + style: + TextStyle(color: Colors.black, fontWeight: FontWeight.bold), + ), + ), + Obx( + () => TextInputField( + controller: controller.category.value, + hint: 'Select Category', + focus: controller.categoryFocus.value, + onTap: () => controller.setCategoryFocus(), + ), + ) + ], + ), + ); + } +} diff --git a/lib/screens/new_task/components/date_time.dart b/lib/screens/new_task/components/date_time.dart new file mode 100644 index 0000000..a1be71a --- /dev/null +++ b/lib/screens/new_task/components/date_time.dart @@ -0,0 +1,110 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; + +class DateTimeInput extends StatelessWidget { + DateTimeInput({super.key}); + + final controller = Get.put(NewTaskController()); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20), + child: Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Date', + style: + TextStyle(color: Colors.black, fontWeight: FontWeight.bold), + ), + const SizedBox( + height: defaultPadding / 2, + ), + InkWell( + onTap: () => controller.showDatePick(context), + child: Obx(() => DateTimeContainer( + text: controller.selectedDate.isEmpty + ? 'dd/mm/yyyy' + : controller.selectedDate.value))) + ], + ), + const Spacer(), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'S-Time', + style: + TextStyle(color: Colors.black, fontWeight: FontWeight.bold), + ), + const SizedBox( + height: defaultPadding / 2, + ), + InkWell( + onTap: () => controller.picStartTime(context), + child: Obx(() => DateTimeContainer( + text: controller.startTime.isEmpty + ? "hh:mm:a" + : controller.startTime.value))) + ], + ), + const Spacer(), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'E-Time', + style: + TextStyle(color: Colors.black, fontWeight: FontWeight.bold), + ), + const SizedBox( + height: defaultPadding / 2, + ), + InkWell( + onTap: () => controller.picEndTime(context), + child: Obx(() => DateTimeContainer( + text: controller.endTime.isEmpty + ? "hh:mm:a" + : controller.endTime.value))) + ], + ), + ], + ), + ); + } +} + +class DateTimeContainer extends StatelessWidget { + const DateTimeContainer({super.key, required this.text}); + + final String text; + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), + decoration: BoxDecoration( + color: Colors.grey.withOpacity(.2), + borderRadius: BorderRadius.circular(20), + ), + child: Row( + children: [ + Icon( + Icons.date_range, + color: darkBlue, + size: 16, + ), + SizedBox( + width: defaultPadding / 4, + ), + Text(text), + ], + ), + ); + } +} diff --git a/lib/screens/new_task/components/description_input.dart b/lib/screens/new_task/components/description_input.dart new file mode 100644 index 0000000..def06a2 --- /dev/null +++ b/lib/screens/new_task/components/description_input.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/screens/new_task/components/text_input.dart'; +import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; + +class DescriptionInput extends StatelessWidget { + final controller = Get.put(NewTaskController()); + DescriptionInput({super.key}); + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: defaultPadding / 2, + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Text( + 'Description', + style: + TextStyle(color: Colors.black, fontWeight: FontWeight.bold), + ), + ), + Obx(() => TextInputField( + controller: controller.description.value, + hint: 'Description (Optional)', + focus: controller.descriptionFocus.value, + onTap: () => controller.setDescriptionFocus(), + )) + ], + ), + ); + } +} diff --git a/lib/screens/new_task/components/illustration_list.dart b/lib/screens/new_task/components/illustration_list.dart new file mode 100644 index 0000000..d326756 --- /dev/null +++ b/lib/screens/new_task/components/illustration_list.dart @@ -0,0 +1,99 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/constants/constants.dart'; +import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; + +class SelectImageList extends StatelessWidget { + SelectImageList({super.key}); + final controller = Get.put(NewTaskController()); + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: defaultPadding, + ), + Align( + alignment: Alignment.topCenter, + child: Container( + height: 4, + width: 100, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + gradient: + const LinearGradient(colors: [lightOrange, darkOrange])), + ), + ), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + child: Text( + 'Illustrations', + style: TextStyle( + color: Colors.black, fontWeight: FontWeight.w600, fontSize: 20), + ), + ), + SizedBox( + height: 120, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: 10, + itemBuilder: (context, index) { + return GestureDetector( + onTap: () { + controller.changeImage(index); + }, + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + children: [ + Obx( + () => AnimatedContainer( + duration: const Duration(milliseconds: 300), + padding: const EdgeInsets.all(2), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + gradient: + controller.selectedImage.value == index + ? const LinearGradient(colors: [ + lightAccentBlue, + lightAccentBlue, + ]) + : null, + boxShadow: + controller.selectedImage.value == index + ? const [ + BoxShadow( + color: lightAccentBlue, + blurRadius: 10, + offset: Offset(0, 5), + ), + ] + : null), + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20)), + child: Image.asset( + Data().images['$index'], + height: 80, + width: 80, + ))), + ), + Obx( + () => controller.selectedImage.value == index + ? const Icon(Icons.keyboard_arrow_up, + color: Colors.orange) + : const SizedBox(), + ) + ], + )), + ); + }, + ), + ), + ], + ); + } +} diff --git a/lib/screens/new_task/components/lable_input.dart b/lib/screens/new_task/components/lable_input.dart new file mode 100644 index 0000000..2f35b7a --- /dev/null +++ b/lib/screens/new_task/components/lable_input.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/screens/new_task/components/periority_container.dart'; +import 'package:sk_base_mobile/screens/new_task/components/text_input.dart'; +import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; + +class LabelInput extends StatelessWidget { + LabelInput({super.key}); + final controller = Get.put(NewTaskController()); + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Lable', + style: TextStyle( + color: Colors.black, fontWeight: FontWeight.bold), + ), + const SizedBox( + height: defaultPadding / 2, + ), + Obx( + () => TextInputField( + controller: controller.label.value, + hint: 'Enter Label', + onTap: () => controller.setLabelFocus(), + focus: controller.labelFocus.value), + ), + ], + ), + ), + const SizedBox( + width: defaultPadding, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Periority', + style: + TextStyle(color: Colors.black, fontWeight: FontWeight.bold), + ), + const SizedBox( + height: defaultPadding / 2, + ), + Row( + children: [ + Obx( + () => InkWell( + onTap: () => controller.lowPeriority.value = true, + child: PeriorityContainer( + text: 'Low', + selected: controller.lowPeriority.value)), + ), + const SizedBox( + width: defaultPadding / 2, + ), + Obx( + () => InkWell( + onTap: () => controller.lowPeriority.value = false, + child: PeriorityContainer( + text: 'High', + selected: !controller.lowPeriority.value)), + ) + ], + ) + ], + ), + ], + ), + ); + } +} diff --git a/lib/screens/new_task/components/periority_container.dart b/lib/screens/new_task/components/periority_container.dart new file mode 100644 index 0000000..df0d9e3 --- /dev/null +++ b/lib/screens/new_task/components/periority_container.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; + +class PeriorityContainer extends StatelessWidget { + final String text; + final bool selected; + + const PeriorityContainer( + {super.key, required this.text, required this.selected}); + + @override + Widget build(BuildContext context) { + return AnimatedContainer( + duration: Duration(milliseconds: 300), + padding: EdgeInsets.all(selected ? 3 : 0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(30), + color: selected ? Colors.orange : Colors.black12), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + decoration: BoxDecoration( + color: selected ? Colors.white : Colors.transparent, + borderRadius: BorderRadius.circular(30), + ), + child: Text( + text, + style: TextStyle(color: darkAccentBlue, fontWeight: FontWeight.bold), + ), + ), + ); + } +} diff --git a/lib/screens/new_task/components/task_button.dart b/lib/screens/new_task/components/task_button.dart new file mode 100644 index 0000000..3cc20e8 --- /dev/null +++ b/lib/screens/new_task/components/task_button.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; + +class CreateTaskButton extends StatelessWidget { + CreateTaskButton({super.key}); + final controller = Get.put(NewTaskController()); + @override + Widget build(BuildContext context) { + return Container( + height: 60, + alignment: Alignment.center, + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + topRight: Radius.circular(80), topLeft: Radius.circular(80)), + gradient: LinearGradient(colors: [ + lightOrange, + darkOrange, + darkOrange, + ])), + child: Obx( + () => controller.loading.value + ? Container( + height: 15, + width: 15, + child: const CircularProgressIndicator( + color: Colors.white, + ), + ) + : const Text( + 'Create Task', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 16), + ), + )); + } +} diff --git a/lib/screens/new_task/components/text_input.dart b/lib/screens/new_task/components/text_input.dart new file mode 100644 index 0000000..495864e --- /dev/null +++ b/lib/screens/new_task/components/text_input.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; + +class TextInputField extends StatelessWidget { + final TextEditingController controller; + final String hint; + final bool focus; + final VoidCallback onTap; + TextInputField( + {super.key, + required this.controller, + required this.hint, + required this.focus, + required this.onTap}); + final taskController = Get.put(NewTaskController()); + @override + Widget build(BuildContext context) { + return AnimatedContainer( + duration: const Duration(milliseconds: 300), + height: 50, + width: double.infinity, + padding: EdgeInsets.all(focus ? 2 : 1), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: focus ? darkOrange : Colors.grey), + child: TextFormField( + controller: controller, + onTapOutside: (event) { + FocusScope.of(context).unfocus(); + taskController.onTapOutside(); + }, + onTap: onTap, + decoration: InputDecoration( + contentPadding: EdgeInsets.symmetric(horizontal: 20), + hintText: hint, + fillColor: Colors.white, + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide.none), + hintStyle: TextStyle(color: Colors.grey, fontSize: 12), + ), + ), + ); + } +} diff --git a/lib/screens/new_task/new_task.dart b/lib/screens/new_task/new_task.dart new file mode 100644 index 0000000..f287ff8 --- /dev/null +++ b/lib/screens/new_task/new_task.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/screens/new_task/components/category_input.dart'; +import 'package:sk_base_mobile/screens/new_task/components/date_time.dart'; +import 'package:sk_base_mobile/screens/new_task/components/description_input.dart'; +import 'package:sk_base_mobile/screens/new_task/components/illustration_list.dart'; +import 'package:sk_base_mobile/screens/new_task/components/lable_input.dart'; +import 'package:sk_base_mobile/screens/new_task/components/task_button.dart'; +import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; +import 'package:sk_base_mobile/screens/home/components/responsive.dart'; + +class NewTask extends StatelessWidget { + NewTask({super.key}); + + final controller = Get.put(NewTaskController()); + + @override + Widget build(BuildContext context) { + return ClipRRect( + borderRadius: const BorderRadius.only( + topLeft: Radius.circular( + 30, + ), + topRight: Radius.circular(30)), + child: Container( + height: 650, + width: Responsive.isLargeTablet(context) + ? MediaQuery.sizeOf(context).width / 2.5 + : Responsive.isTablet(context) + ? MediaQuery.sizeOf(context).width / 1.6 + : MediaQuery.sizeOf(context).width, + decoration: const BoxDecoration( + color: Colors.white, + ), + child: Stack( + children: [ + Positioned.fill( + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SelectImageList(), + LabelInput(), + CategoryInput(), + DescriptionInput(), + DateTimeInput(), + ], + ), + ), + ), + GestureDetector( + onTap: () => controller.insertTask(context), + child: CreateTaskButton()) + ], + )) + ], + )), + ); + } +} diff --git a/lib/screens/new_task/new_task_controller.dart b/lib/screens/new_task/new_task_controller.dart new file mode 100644 index 0000000..ed28c87 --- /dev/null +++ b/lib/screens/new_task/new_task_controller.dart @@ -0,0 +1,143 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/db_helper/dbHelper.dart'; +import 'package:sk_base_mobile/models/task_model.dart'; +import 'package:sk_base_mobile/screens/home/home_controller.dart'; +import 'package:sk_base_mobile/util/util.dart'; + +class NewTaskController extends GetxController { + DateTime? pickedDate; + final DbHelper db = DbHelper(); + RxInt selectedImage = 0.obs; + RxBool lowPeriority = false.obs; + RxBool labelFocus = false.obs; + RxBool categoryFocus = false.obs; + RxBool descriptionFocus = false.obs; + RxString selectedDate = ''.obs; + RxString startTime = ''.obs; + RxString endTime = ''.obs; + RxBool loading = false.obs; + final homeController = Get.put(HomeController()); + final label = TextEditingController().obs; + final description = TextEditingController().obs; + final category = TextEditingController().obs; + + picStartTime(BuildContext context) async { + var picker = + await showTimePicker(context: context, initialTime: TimeOfDay.now()); + if (picker != null) { + startTime.value = + '${DateUtil.addPrefix(picker.hourOfPeriod.toString())}:${DateUtil.addPrefix(picker.minute.toString())}:${picker.period.name.toUpperCase()}'; + } + } + + picEndTime(BuildContext context) async { + var picker = + await showTimePicker(context: context, initialTime: TimeOfDay.now()); + if (picker != null) { + endTime.value = + '${DateUtil.addPrefix(picker.hourOfPeriod.toString())}:${DateUtil.addPrefix(picker.minute.toString())}:${picker.period.name.toUpperCase()}'; + } + } + + showDatePick(BuildContext context) async { + var picker = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime.now(), + lastDate: DateTime.now().add(const Duration(days: 7))); + if (picker != null) { + pickedDate = picker; + selectedDate.value = + '${DateUtil.addPrefix(picker.day.toString())}/${DateUtil.addPrefix(picker.month.toString())}/${picker.year}'; + } + } + + changeImage(int index) { + selectedImage.value = index; + } + + setLabelFocus() { + labelFocus.value = true; + categoryFocus.value = false; + descriptionFocus.value = false; + } + + setCategoryFocus() { + labelFocus.value = false; + categoryFocus.value = true; + descriptionFocus.value = false; + } + + setDescriptionFocus() { + labelFocus.value = false; + categoryFocus.value = false; + descriptionFocus.value = true; + } + + onTapOutside() { + labelFocus.value = false; + categoryFocus.value = false; + descriptionFocus.value = false; + } + + insertTask(BuildContext context) { + if (label.value.text.toString().isEmpty) { + SnackBarUtil().warning( + 'Warning', + message: 'Enter valid label', + ); + return; + } + if (category.value.text.toString().isEmpty) { + SnackBarUtil().warning( + 'Warning', + message: 'Enter Correct Category', + ); + return; + } + if (selectedDate.isEmpty) { + // selectedDate.value = + // '${Utils.addPrefix(DateTime.now().day.toString())}/${Utils.addPrefix(DateTime.now().month.toString())}/${Utils.addPrefix(DateTime.now().year.toString())}'; + showDatePick(context); + } + if (startTime.isEmpty) { + picStartTime(context); + return; + } + if (endTime.isEmpty) { + picEndTime(context); + return; + } + loading.value = true; + + db + .insert(TaskModel( + key: DateTime.now().microsecondsSinceEpoch.toString(), + startTime: startTime.value, + endTime: endTime.value, + date: selectedDate.value, + periority: lowPeriority.value ? 'Low' : 'High', + description: description.value.text.toString(), + category: category.value.text.toString(), + title: label.value.text.toString(), + image: selectedImage.value.toString(), + show: 'yes', + status: 'unComplete')) + .then((value) { + Duration dif = pickedDate!.difference(DateTime( + DateTime.now().year, DateTime.now().month, DateTime.now().day)); + homeController.list[dif.inDays].add(value); + Timer(const Duration(seconds: 1), () { + loading.value = false; + Get.back(); + SnackBarUtil().success( + 'Successful', + message: 'Task is created', + ); + }); + }); + } +} diff --git a/lib/util/date.util.dart b/lib/util/date.util.dart new file mode 100644 index 0000000..4b72731 --- /dev/null +++ b/lib/util/date.util.dart @@ -0,0 +1,28 @@ +import 'package:date_format/date_format.dart'; + +class DateUtil { + static String getMonth(DateTime date) { + String formattedDate = formatDate(date, ['MMM']); + return formattedDate; + } + + static String getDate(DateTime date) { + String formattedDate = formatDate(date, ['d']); + if (formattedDate.length == 1) { + formattedDate = '0$formattedDate'; + } + return formattedDate; + } + + static String getDay(DateTime date) { + String formattedDate = formatDate(date, ['EEE']); + return formattedDate; + } + + static String addPrefix(String string) { + if (string.length == 1) { + string = '0$string'; + } + return string; + } +} diff --git a/lib/util/modal.util.dart b/lib/util/modal.util.dart new file mode 100644 index 0000000..51de6e3 --- /dev/null +++ b/lib/util/modal.util.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:get/get.dart'; + +class ModalUtil { + static Future showWarningDialog( + String title, String msg, String button, VoidCallback onConfirm) async { + bool confirmed = false; + await showDialog( + context: Get.overlayContext!, + builder: (context) { + return AlertDialog( + title: Text(title), + content: Text(msg), + actions: [ + TextButton( + child: const Text( + 'Cancel', + style: TextStyle(color: Colors.black), + ), + onPressed: () { + Navigator.of(context).pop(); + confirmed = false; + }, + ), + TextButton( + child: Text( + button, + style: TextStyle(color: Colors.orange), + ), + onPressed: () { + onConfirm(); + Navigator.pop(context); + confirmed = true; + }, + ), + ], + ); + }, + ); + return confirmed; + } +} diff --git a/lib/util/util.dart b/lib/util/util.dart index 003df36..e5a4a74 100644 --- a/lib/util/util.dart +++ b/lib/util/util.dart @@ -6,3 +6,5 @@ export 'media_util.dart'; export 'photo_picker_util.dart'; export 'screen_adaper_util.dart'; export 'validator_util.dart'; +export 'date.util.dart'; +export 'modal.util.dart'; diff --git a/lib/widgets/back_decoration.dart b/lib/widgets/back_decoration.dart new file mode 100644 index 0000000..28e4441 --- /dev/null +++ b/lib/widgets/back_decoration.dart @@ -0,0 +1,165 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/util/screen_adaper_util.dart'; + +class BackColors extends StatelessWidget { + const BackColors({super.key}); + @override + Widget build(BuildContext context) { + var size = MediaQuery.sizeOf(context); + return Container( + color: Colors.white, + margin: EdgeInsets.only(top: 30), + child: Stack( + children: [ + Positioned( + top: 100, + child: Container( + height: size.height * 0.5, + width: size.width * 0.5, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(30), + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.centerRight, + colors: [ + lightOrange.withOpacity(.0), + lightOrange.withOpacity(.1), + lightOrange.withOpacity(.2), + lightOrange.withOpacity(.3), + lightOrange.withOpacity(.4), + lightOrange.withOpacity(.4), + lightOrange.withOpacity(.3), + lightOrange.withOpacity(.2), + lightOrange.withOpacity(.1), + lightOrange.withOpacity(0), + ])), + )), + Positioned( + top: 100, + right: -50, + child: Container( + height: size.height * 0.5, + width: size.width * 0.3, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(30), + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.centerRight, + colors: [ + lightOrange.withOpacity(.0), + lightOrange.withOpacity(.1), + lightOrange.withOpacity(.2), + lightOrange.withOpacity(.3), + lightOrange.withOpacity(.2), + lightOrange.withOpacity(.1), + lightOrange.withOpacity(0), + ])), + )), + Positioned( + bottom: 100, + right: -50, + child: Container( + height: size.height * 0.5, + width: size.width * 0.6, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.centerRight, + colors: [ + lightAccentBlue.withOpacity(.0), + lightAccentBlue.withOpacity(.1), + lightAccentBlue.withOpacity(.2), + lightAccentBlue.withOpacity(.3), + lightAccentBlue.withOpacity(.4), + lightAccentBlue.withOpacity(.4), + lightAccentBlue.withOpacity(.3), + lightAccentBlue.withOpacity(.2), + lightAccentBlue.withOpacity(.1), + lightAccentBlue.withOpacity(0), + ])), + )), + Positioned( + bottom: -30, + child: Container( + height: size.height * 0.3, + width: size.width * 0.6, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.centerRight, + colors: [ + lightAccentBlue.withOpacity(.0), + lightAccentBlue.withOpacity(.1), + lightAccentBlue.withOpacity(.2), + lightAccentBlue.withOpacity(.3), + lightAccentBlue.withOpacity(.4), + lightAccentBlue.withOpacity(.4), + lightAccentBlue.withOpacity(.3), + lightAccentBlue.withOpacity(.2), + lightAccentBlue.withOpacity(.1), + lightAccentBlue.withOpacity(0), + ])), + )), + Positioned( + bottom: 1, + left: 1, + top: !ScreenAdaper.isLandspace() ? 100 : 200, + right: 1, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.centerRight, + colors: [ + Colors.pinkAccent.withOpacity(.0), + Colors.pinkAccent.withOpacity(.1), + Colors.pinkAccent.withOpacity(.2), + Colors.pinkAccent.withOpacity(.3), + Colors.pinkAccent.withOpacity(.4), + Colors.pinkAccent.withOpacity(.4), + Colors.pinkAccent.withOpacity(.3), + Colors.pinkAccent.withOpacity(.2), + Colors.pinkAccent.withOpacity(.1), + Colors.pinkAccent.withOpacity(0), + ])), + )), + Positioned( + bottom: 1, + right: 1, + child: Container( + height: size.height * 0.3, + width: size.width * 0.6, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.centerRight, + colors: [ + Colors.greenAccent.withOpacity(.0), + Colors.greenAccent.withOpacity(.1), + Colors.greenAccent.withOpacity(.2), + Colors.greenAccent.withOpacity(.3), + Colors.greenAccent.withOpacity(.4), + Colors.greenAccent.withOpacity(.4), + Colors.greenAccent.withOpacity(.3), + Colors.greenAccent.withOpacity(.2), + Colors.greenAccent.withOpacity(.1), + Colors.greenAccent.withOpacity(0), + ])), + )), + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaY: 30, sigmaX: 30), + child: SizedBox(), + )), + ], + ), + ); + } +} diff --git a/lib/widgets/bottom_nav_bar.dart b/lib/widgets/bottom_nav_bar.dart new file mode 100644 index 0000000..43262fd --- /dev/null +++ b/lib/widgets/bottom_nav_bar.dart @@ -0,0 +1,64 @@ +import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:sk_base_mobile/app_theme.dart'; +import 'package:sk_base_mobile/screens/landing/landing_controller.dart'; +import 'package:sk_base_mobile/util/screen_adaper_util.dart'; +import 'package:auto_size_text/auto_size_text.dart'; + +class BottomNavBar extends StatelessWidget { + BottomNavBar({super.key}); + final controller = Get.put(LandingController()); + final autoSizeGroup = AutoSizeGroup(); + @override + Widget build(BuildContext context) { + return Obx( + () => AnimatedBottomNavigationBar.builder( + itemCount: controller.pages.length, + elevation: ScreenAdaper.height(30), + height: ScreenAdaper.height(80), + activeIndex: controller.currentIndex.value, + gapLocation: GapLocation.center, + notchSmoothness: NotchSmoothness.verySmoothEdge, + leftCornerRadius: ScreenAdaper.sp(25), + rightCornerRadius: ScreenAdaper.sp(25), + onTap: (index) { + controller.currentIndex.value = index; + }, + tabBuilder: (int index, bool isActive) { + final color = isActive + ? AppTheme.activeNavigationBarColor + : AppTheme.notActiveNavigationBarColor; + return Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + controller.iconList[index], + size: ScreenAdaper.sp(40), + color: color, + ), + AutoSizeText( + controller.bottomNavItems[index].label, + maxLines: 1, + style: TextStyle(color: color, fontSize: ScreenAdaper.sp(20)), + group: autoSizeGroup, + ), + ], + ); + }, + ), + ); + } +} +// BottomNavigationBar( +// iconSize: ScreenAdaper.sp(40), +// type: BottomNavigationBarType.fixed, +// items: bottomNavItems, +// showSelectedLabels: true, +// showUnselectedLabels: true, +// currentIndex: _selectedLanding, +// onTap: (landing) { +// _onItemTapped(landing); +// }, +// ) \ No newline at end of file diff --git a/lib/widgets/floating_action.dart b/lib/widgets/floating_action.dart new file mode 100644 index 0000000..618d4b2 --- /dev/null +++ b/lib/widgets/floating_action.dart @@ -0,0 +1,73 @@ +import 'package:flutter/material.dart'; +import 'package:sk_base_mobile/app_theme.dart'; +import 'package:sk_base_mobile/constants/bg_color.dart'; +import 'package:sk_base_mobile/screens/home/components/responsive.dart'; +import 'package:sk_base_mobile/screens/new_task/new_task.dart'; +import 'package:sk_base_mobile/util/screen_adaper_util.dart'; + +class FloatingButton extends StatelessWidget { + const FloatingButton({super.key}); + + @override + Widget build(BuildContext context) { + return InkWell( + borderRadius: BorderRadius.circular(ScreenAdaper.sp(50)), + onTap: () { + Responsive.isTablet(context) + ? showGeneralDialog( + context: context, + barrierLabel: "Barrier", + barrierDismissible: true, + barrierColor: Colors.black.withOpacity(0.5), + transitionDuration: const Duration(milliseconds: 400), + pageBuilder: (_, __, ___) { + return Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(30), + child: Material(child: NewTask()), + ), + ); + }, + transitionBuilder: (_, anim, __, child) { + Tween tween; + + tween = Tween(begin: const Offset(0, -1), end: Offset.zero); + + return SlideTransition( + position: tween.animate( + CurvedAnimation(parent: anim, curve: Curves.easeInOut), + ), + // child: FadeTransition( + // opacity: anim, + // child: child, + // ), + child: child, + ); + }, + ) + : showModalBottomSheet( + elevation: 0, + isScrollControlled: true, + backgroundColor: Colors.white, + context: context, + builder: (context) { + return NewTask(); + }, + ); + }, + child: Container( + height: ScreenAdaper.height(100), + width: ScreenAdaper.height(100), + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + colors: [AppTheme.primaryColorLight, AppTheme.primaryColor])), + child: Icon( + Icons.add, + color: Colors.white, + size: ScreenAdaper.sp(40), + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 91c1cab..45d4862 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + animated_bottom_navigation_bar: + dependency: "direct main" + description: + name: animated_bottom_navigation_bar + sha256: "2b04a2ae4b0742669e60ddf309467d6a354cefd2d0cd20f4737b1efaf9834cda" + url: "https://pub.dev" + source: hosted + version: "1.3.3" ansicolor: dependency: transitive description: @@ -33,6 +41,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" + auto_size_text: + dependency: "direct main" + description: + name: auto_size_text + sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599" + url: "https://pub.dev" + source: hosted + version: "3.0.0" boolean_selector: dependency: transitive description: @@ -489,7 +505,7 @@ packages: source: hosted version: "2.0.2" path: - dependency: transitive + dependency: "direct main" description: name: path sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" @@ -497,7 +513,7 @@ packages: source: hosted version: "1.8.3" path_provider: - dependency: transitive + dependency: "direct main" description: name: path_provider sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b @@ -718,7 +734,7 @@ packages: source: hosted version: "7.0.0" sqflite: - dependency: transitive + dependency: "direct main" description: name: sqflite sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6 diff --git a/pubspec.yaml b/pubspec.yaml index 99bf8fe..1246d6a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -51,6 +51,11 @@ dependencies: permission_handler: ^11.3.0 crypto: ^3.0.3 date_format: ^2.0.7 + animated_bottom_navigation_bar: ^1.3.3 + auto_size_text: ^3.0.0 + sqflite: ^2.3.2 + path: ^1.8.3 + path_provider: ^2.1.2 dev_dependencies: