From 0cd37ce0fa85534cab38205418a94d9df6c2e282 Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Sun, 3 Apr 2022 13:13:28 +0300 Subject: [PATCH] fix calendar --- assets/langs/ar-SA.json | 1 + assets/langs/en-US.json | 1 + lib/classes/colors.dart | 9 + lib/config/routes.dart | 17 + lib/extensions/string_extensions.dart | 9 + lib/extensions/widget_extensions.dart | 2 + lib/generated/codegen_loader.g.dart | 2 + lib/ui/attendance/monthly_attendance.dart | 671 ++++++++++++++++++ .../attendence_details_bottom_sheet.dart | 228 ++++++ lib/ui/landing/dashboard.dart | 13 +- pubspec.lock | 86 ++- pubspec.yaml | 4 + 12 files changed, 1020 insertions(+), 23 deletions(-) create mode 100644 lib/ui/attendance/monthly_attendance.dart create mode 100644 lib/ui/bottom_sheets/attendence_details_bottom_sheet.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 1d9e8bc..9c9b933 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -49,6 +49,7 @@ "loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول", "changePassword": "تغيير كلمة المرور", "itemsForSale": "سلع للبيع", + "attendanceDetails": "تفاصيل الحضور", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 9c812ce..538c567 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -49,6 +49,7 @@ "loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number", "changePassword": "Change Password", "itemsForSale": "Items for Sale", + "attendanceDetails": "Attendence Details", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart index 2e5eaef..2a34a05 100644 --- a/lib/classes/colors.dart +++ b/lib/classes/colors.dart @@ -25,4 +25,13 @@ class MyColors { static const Color white = Color(0xffffffff); static const Color green = Color(0xffffffff); static const Color borderColor = Color(0xffE8E8E8); + static const Color grey67Color = Color(0xff676767); + static const Color whiteColor = Color(0xFFEEEEEE); + static const Color greenColor = Color(0xff1FA269); + static const Color lightGreenColor = Color(0xff2AB2AB); + static const Color darkGreyColor = Color(0xff464646); + static const Color greyA5Color = Color(0xffA5A5A5); + static const Color blackColor = Color(0xff000014); + static const Color grey3AColor = Color(0xff2E303A); + static const Color darkColor = Color(0xff000015); } diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 39a4ebc..4ca0181 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -7,6 +7,8 @@ import 'package:mohem_flutter_app/ui/login/new_password_screen.dart'; import 'package:mohem_flutter_app/ui/login/verify_login_screen.dart'; import 'package:mohem_flutter_app/ui/work_list/missing_swipe/missing_swipe_screen.dart'; import 'package:mohem_flutter_app/ui/work_list/work_list_screen.dart'; +import 'package:mohem_flutter_app/ui/bottom_sheets/attendence_details_bottom_sheet.dart'; +import 'package:mohem_flutter_app/ui/attendance/monthly_attendance.dart'; class AppRoutes { static const String splash = "/splash"; @@ -21,10 +23,18 @@ class AppRoutes { static const String todayAttendance = "/todayAttendance"; static const String initialRoute = login; + //Work List static const String workList = "/workList"; static const String missingSwipe = "/missingSwipe"; + //Attendance + static const String attendance = "/attendance"; + static const String monthlyAttendance = "/monthlyAttendance"; + + //Bottom Sheet + static const String attendanceDetailsBottomSheet = "/attendanceDetailsBottomSheet"; + static final Map routes = { login: (context) => LoginScreen(), verifyLogin: (context) => VerifyLoginScreen(), @@ -33,8 +43,15 @@ class AppRoutes { forgotPassword: (context) => ForgotPasswordScreen(), todayAttendance: (context) => TodayAttendanceScreen(), + //Work List workList: (context) => WorkListScreen(), missingSwipe: (context) => MissingSwipeScreen(), + + //Attendance + monthlyAttendance: (context) => MonthlyAttendance(), + + //Bottom Sheet + attendanceDetailsBottomSheet: (context) => AttendenceDetailsBottomSheet(), }; } diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 9db4829..e80cdeb 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -51,6 +51,10 @@ extension EmailValidator on String { this, style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 17, letterSpacing: -0.68, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); + Widget toText20({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(fontSize: 20, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4), + ); Widget toText22({Color? color, bool isBold = false}) => Text( this, @@ -67,6 +71,11 @@ extension EmailValidator on String { style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), ); + Widget toText44({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 44, letterSpacing: -2.64, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + bool isValidEmail() { return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this); } diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index 787894d..030fa50 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -4,6 +4,8 @@ import 'package:flutter/widgets.dart'; extension WidgetExtensions on Widget { Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this); + Widget get expanded => Expanded(child: this); + Widget paddingAll(double _value) => Padding(padding: EdgeInsets.all(_value), child: this); Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) => diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index b43f3bd..23003fe 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -65,6 +65,7 @@ class CodegenLoader extends AssetLoader{ "loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول", "changePassword": "تغيير كلمة المرور", "itemsForSale": "سلع للبيع", + "attendanceDetails": "تفاصيل الحضور", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", @@ -154,6 +155,7 @@ static const Map en_US = { "loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number", "changePassword": "Change Password", "itemsForSale": "Items for Sale", + "attendanceDetails": "Attendence Details", "msg": "Hello {} in the {} world ", "msg_named": "{} are written in the {lang} language", "clickMe": "Click me", diff --git a/lib/ui/attendance/monthly_attendance.dart b/lib/ui/attendance/monthly_attendance.dart new file mode 100644 index 0000000..ff370a3 --- /dev/null +++ b/lib/ui/attendance/monthly_attendance.dart @@ -0,0 +1,671 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/painting.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart'; +import 'package:syncfusion_flutter_calendar/calendar.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:pie_chart/pie_chart.dart'; + +class MonthlyAttendance extends StatefulWidget { + MonthlyAttendance({Key? key}) : super(key: key); + + @override + _MonthlyAttendanceState createState() { + return _MonthlyAttendanceState(); + } +} + +class _MonthlyAttendanceState extends State { + bool isPresent = true; + bool isAbsent = true; + bool isMissingDays = true; + bool isOffDays = true; + + @override + void initState() { + super.initState(); + } + + Map dataMap = { + "Present": 65, + "Absent": 35, + }; + + final List _colorList = [Color(0xff2AB2AB), Color(0xff202529)]; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: MyColors.white, + leading: IconButton( + icon: const Icon( + Icons.arrow_back_ios, + color: MyColors.backgroundBlackColor, + ), + onPressed: () => Navigator.pop(context), + ), + ), + backgroundColor: Colors.white, + body: ListView( + scrollDirection: Axis.vertical, + children: [ + Column( + children: [ + 20.height, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Attendance".toText24(isBold: true, color: MyColors.darkIconColor), + Row( + children: [ + "June 13, 2021".toText16(color: MyColors.greyACColor), + const Icon(Icons.keyboard_arrow_down_rounded, color: MyColors.greyACColor), + ], + ).onPress(() { + showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(2021), + lastDate: DateTime(2025), + builder: (context, child) { + return Theme( + data: ThemeData.dark().copyWith( + colorScheme: const ColorScheme.dark( + primary: MyColors.lightGreenColor, + onPrimary: MyColors.white, + surface: MyColors.lightGreenColor, + onSurface: MyColors.darkTextColor, + ), + dialogBackgroundColor: Colors.white, + ), + child: child!, + ); + }, + ); + }) + ], + ).paddingOnly(left: 21, right: 21), + 18.height, + AspectRatio(aspectRatio: 333 / 270, child: calenderWidget()).paddingOnly(left: 21, right: 21), + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + optionUI("Schedule\nDays", "16"), + 6.width, + optionUI("Off\nDays", "0"), + 6.width, + optionUI("Non\nAnalyzed", "0"), + 6.width, + optionUI("Shortage\nHour", "6"), + ], + ).paddingOnly(left: 21, right: 21), + 35.height, + Container( + width: double.infinity, + height: 227, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: const BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), + boxShadow: [ + BoxShadow( + offset: const Offset(0, 2), + blurRadius: 26, + color: MyColors.darkColor.withOpacity(0.1), + ), + ], + ), + child: Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + children: [ + "Attendance".toText12(isBold: true, color: MyColors.grey3AColor), + "Stats".toText24(isBold: true, color: MyColors.grey3AColor), + ], + ).paddingOnly(left: 21, top: 29, bottom: 36), + Row( + children: [ + Container( + height: 9, + width: 9, + decoration: BoxDecoration( + color: MyColors.lightGreenColor, + borderRadius: BorderRadius.circular(100), + ), + ), + Container( + margin: const EdgeInsets.only(left: 5, right: 5), + child: "PRESENT 16".toText16(isBold: true, color: MyColors.lightGreenColor), + ), + ], + ).paddingOnly(left: 21, right: 23), + 8.height, + Row( + children: [ + Container( + height: 9, + width: 9, + decoration: BoxDecoration( + color: MyColors.backgroundBlackColor, + borderRadius: BorderRadius.circular(100), + ), + ), + Container( + margin: const EdgeInsets.only(left: 5, right: 5), + child: "ABSENT 04".toText16( + isBold: true, + color: MyColors.backgroundBlackColor, + ), + ) + ], + ).paddingOnly(left: 21, top: 8), + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 169, + height: 170, + child: PieChart( + dataMap: dataMap, + animationDuration: const Duration(milliseconds: 800), + chartLegendSpacing: 0, + chartRadius: MediaQuery.of(context).size.width / 5.2, + colorList: _colorList, + initialAngleInDegree: 0, + chartType: ChartType.ring, + ringStrokeWidth: 80, + legendOptions: const LegendOptions( + showLegendsInRow: false, + showLegends: false, + ), + chartValuesOptions: const ChartValuesOptions( + showChartValueBackground: false, + showChartValues: true, + showChartValuesInPercentage: true, + showChartValuesOutside: false, + decimalPlaces: 1, + chartValueStyle: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + color: MyColors.white, + )), + ), + ), + ], + ).paddingOnly(left: 65, top: 27, right: 21, bottom: 28), + ], + ), + ), + ], + ), + ], + ), + ); + } + + Widget optionUI(String title, String value) { + return AspectRatio( + aspectRatio: 1 / 1, + child: Container( + padding: const EdgeInsets.only(top: 10, left: 8, right: 8, bottom: 10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + offset: const Offset(0, 1), + blurRadius: 15, + color: MyColors.darkColor.withOpacity(0.1), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [title.toText10(color: MyColors.darkTextColor).expanded, value.toText20(color: MyColors.darkTextColor)], + ), + ), + ).expanded; + } + + Widget calenderWidget() { + return SfCalendar( + view: CalendarView.month, + headerHeight: 0, + todayHighlightColor: MyColors.grey3AColor, + viewHeaderStyle: const ViewHeaderStyle( + dayTextStyle: TextStyle(color: MyColors.grey3AColor, fontSize: 13, fontWeight: FontWeight.w600), + ), + monthCellBuilder: (cxt, build) { + int val = build.date.day % 4; + isPresent = val == 0; + isAbsent = val == 1; + isMissingDays = val == 2; + isOffDays = val == 3; + if (isPresent) { + return Container( + margin: const EdgeInsets.all(4), + decoration: BoxDecoration( + gradient: const LinearGradient( + transform: GradientRotation(.46), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [MyColors.gradiantEndColor, MyColors.gradiantStartColor], + ), + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + offset: const Offset(0, 2), + blurRadius: 26, + color: MyColors.blackColor.withOpacity(0.100), + ), + ], + ), + alignment: Alignment.center, + child: Text( + "${build.date.day}", + style: const TextStyle( + fontSize: 13, + fontWeight: FontWeight.w500, + color: MyColors.white, + ), + ), + ); + } else if (isAbsent) { + return Container( + margin: const EdgeInsets.all(4), + decoration: BoxDecoration( + color: MyColors.backgroundBlackColor, + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + offset: const Offset(0, 2), + blurRadius: 26, + color: MyColors.blackColor.withOpacity(0.100), + ), + ], + ), + alignment: Alignment.center, + child: Text( + "${build.date.day}", + style: const TextStyle( + fontSize: 13, + fontWeight: FontWeight.w500, + color: MyColors.white, + ), + ), + ); + } else if (isMissingDays) { + return Container( + margin: const EdgeInsets.all(4), + decoration: BoxDecoration( + border: Border.all(color: MyColors.backgroundBlackColor, width: 2.0, style: BorderStyle.solid), //Border.all + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + offset: const Offset(0, 2), + blurRadius: 26, + color: MyColors.blackColor.withOpacity(0.100), + ), + ], + ), + alignment: Alignment.center, + child: Text( + "${build.date.day}", + style: const TextStyle( + fontSize: 13, + fontWeight: FontWeight.w500, + color: Color(0xff1F2428), + ), + ), + ); + } else if (isOffDays) { + return Container( + margin: const EdgeInsets.all(4), + decoration: BoxDecoration( + color: MyColors.greyACColor.withOpacity(.12), + shape: BoxShape.circle, + ), + alignment: Alignment.center, + child: Text( + "${build.date.day}", + style: const TextStyle( + fontSize: 13, + fontWeight: FontWeight.w500, + color: MyColors.greyA5Color, + ), + ), + ); + } else { + return Container(); + } + }, + monthViewSettings: const MonthViewSettings( + dayFormat: 'EEE', + showTrailingAndLeadingDates: false, + appointmentDisplayMode: MonthAppointmentDisplayMode.appointment, + showAgenda: false, + navigationDirection: MonthNavigationDirection.horizontal, + monthCellStyle: MonthCellStyle( + textStyle: TextStyle( + fontStyle: FontStyle.normal, + fontSize: 13, + color: Colors.white, + ), + ), + ), + showNavigationArrow: false, + showDatePickerButton: false, + showCurrentTimeIndicator: false, + showWeekNumber: false, + cellBorderColor: Colors.white, + selectionDecoration: BoxDecoration( + border: Border.all(color: MyColors.white, width: 10), + borderRadius: const BorderRadius.all(Radius.circular(100)), + shape: BoxShape.circle, + ), + dataSource: MeetingDataSource(_getDataSource()), + onTap: calendarTapped, + ); + } + + void calendarTapped(CalendarTapDetails details) { + showModalBottomSheet( + context: context, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)), + isScrollControlled: true, + backgroundColor: MyColors.backgroundBlackColor, + builder: (_) { + return DraggableScrollableSheet( + maxChildSize: 0.9, + expand: false, + builder: (_, controller) { + return Column( + children: [ + Container( + width: 75, + height: 7, + margin: const EdgeInsets.symmetric(vertical: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: MyColors.darkGreyColor, + ), + ), + Expanded( + child: ListView.builder( + controller: controller, + itemCount: 1, + itemBuilder: (_, i) => Container( + decoration: const BoxDecoration( + borderRadius: BorderRadius.vertical( + top: Radius.circular(35.0), + ), + color: MyColors.backgroundBlackColor, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column(children: [ + "June 13, 2021".toText24(isBold: true, color: Colors.white), + LocaleKeys.attendanceDetails.tr().toText16(color: MyColors.lightGreyEFColor), + 21.height, + ]).paddingOnly(top: 25, left: 21, right: 21, bottom: 10), + Center( + child: CircularStepProgressBar( + totalSteps: 16 * 4, + currentStep: 16, + width: 210, + height: 210, + selectedColor: MyColors.gradiantEndColor, + unselectedColor: MyColors.grey70Color, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + "99%".toText44(color: Colors.white, isBold: true), + "Completed".tr().toText11(color: MyColors.greyACColor), + 19.height, + "Shift Time".tr().toText11(color: MyColors.greyACColor), + "08:00 - 17:00".toText22(color: Colors.white, isBold: true), + ], + ), + ), + ), + ), + Container( + padding: const EdgeInsets.only(top: 20, bottom: 20), + ), + Stack( + children: [ + Container( + height: 5, + padding: const EdgeInsets.only(top: 24, bottom: 24), + color: MyColors.backgroundBlackColor, + ), + Container( + width: double.infinity, + decoration: const BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), + padding: const EdgeInsets.only(left: 21, right: 21, top: 28, bottom: 24), + child: Column( + children: [ + Row( + children: [ + Container( + margin: const EdgeInsets.only(right: 30, left: 15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Actual Check In ".tr().toText11( + color: MyColors.grey67Color, + ), + 8.height, + "08:27".toText22(color: Colors.black, isBold: true), + ], + ), + ), + 40.width, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Actual Check Out".tr().toText11( + color: MyColors.grey67Color, + ), + 8.height, + "18:20".toText22(color: Colors.black, isBold: true), + ], + ), + ], + ), + 25.height, + const Divider( + height: 1, + thickness: 1, + color: MyColors.whiteColor, + ), + 25.height, + Row( + children: [ + Container( + margin: const EdgeInsets.only(right: 30, left: 15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Approved Check In".tr().toText11( + color: MyColors.grey67Color, + ), + 8.height, + "09:27".toText22(color: MyColors.greenColor, isBold: true), + ], + ), + ), + 30.width, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Approved Check Out".tr().toText11( + color: MyColors.grey67Color, + ), + 8.height, + "18:20".toText22(color: MyColors.greenColor, isBold: true), + ], + ), + ], + ), + 25.height, + const Divider( + height: 1, + thickness: 1, + color: MyColors.whiteColor, + ), + 25.height, + Row( + children: [ + Container( + margin: const EdgeInsets.only(right: 30, left: 15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Late In".tr().toText11( + color: MyColors.grey67Color, + ), + 8.height, + "00:27".toText22(color: MyColors.redColor, isBold: true), + ], + ), + ), + 80.width, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Excess".tr().toText11( + color: MyColors.grey67Color, + ), + 8.height, + "00:00".toText22(color: Colors.black, isBold: true), + ], + ), + ], + ), + 25.height, + const Divider( + height: 1, + thickness: 1, + color: MyColors.whiteColor, + ), + 25.height, + Row( + children: [ + Container( + margin: const EdgeInsets.only(right: 30, left: 15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Shortage".tr().toText11( + color: MyColors.grey67Color, + ), + 8.height, + "00:00".toText22(color: Colors.black, isBold: true), + ], + ), + ), + 80.width, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Early Out".tr().toText11( + color: MyColors.grey67Color, + ), + 8.height, + "00:00".toText22(color: Colors.black, isBold: true), + ], + ), + ], + ), + ], + ), + ), + ], + ), + ], + ), + ), + ), + ), + ], + ); + }, + ); + }, + ); + } + + List _getDataSource() { + final List meetings = []; + + // _events.forEach((key, value) { + // final DateTime startTime = DateTime(key.year, key.month, key.day, 21, 0, 0); + // final DateTime endTime = DateTime(key.year, key.month, key.day, 22, 0, 0); + // meetings.add(Meeting("", startTime, endTime, MyColors.backgroundBlackColor, false)); + // }); + return meetings; + } +} + +class MeetingDataSource extends CalendarDataSource { + MeetingDataSource(List source) { + appointments = source; + } + + @override + DateTime getStartTime(int index) { + return _getMeetingData(index).from; + } + + @override + DateTime getEndTime(int index) { + return _getMeetingData(index).to; + } + + @override + String getSubject(int index) { + return _getMeetingData(index).eventName; + } + + @override + Color getColor(int index) { + return _getMeetingData(index).background; + } + + @override + bool isAllDay(int index) { + return _getMeetingData(index).isAllDay; + } + + Meeting _getMeetingData(int index) { + final dynamic meeting = appointments; + Meeting meetingData; + if (meeting is Meeting) { + meetingData = meeting; + } + return meeting; + } +} + +class Meeting { + Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay); + + String eventName; + DateTime from; + DateTime to; + Color background; + bool isAllDay; +} diff --git a/lib/ui/bottom_sheets/attendence_details_bottom_sheet.dart b/lib/ui/bottom_sheets/attendence_details_bottom_sheet.dart new file mode 100644 index 0000000..4c42d6c --- /dev/null +++ b/lib/ui/bottom_sheets/attendence_details_bottom_sheet.dart @@ -0,0 +1,228 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart'; + +class AttendenceDetailsBottomSheet extends StatefulWidget { + + AttendenceDetailsBottomSheet({Key? key}) : super(key: key); + + @override + _AttendenceDetailsBottomSheetState createState() => _AttendenceDetailsBottomSheetState(); +} + +class _AttendenceDetailsBottomSheetState extends State { + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + bottomSheet:BottomSheet( + + onClosing: () => print("not getting called"), + builder: (_) => Container( + color: Colors.red, + height: MediaQuery.of(context).size.height*0.9, + child: Column( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.vertical( top: Radius.circular(25.0),), + color: MyColors.backgroundBlackColor, + ), + margin:EdgeInsets.only(top: 45) , + padding: EdgeInsets.only(left: 11, right: 11, bottom: 21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Padding( + padding: const EdgeInsets.all(10), + child: Container( + margin:EdgeInsets.only(top: 5) , + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(35.0),), + color: Color(0xff464646), + ), + width: 80, + height: 6, + ), + ), + ), + Container( + padding: EdgeInsets.only(top: 25,left: 11, right: 11, bottom: 10), + child: Column(children: [ + "June 13, 2021".toText24(isBold: true, color: Colors.white), + LocaleKeys.attendanceDetails.tr().toText16(color: Color(0xffACACAC)), + // LocaleKeys.timeLeftToday.tr().toText16(color: Color(0xffACACAC)), + 21.height, + ] ), + ), + Center( + child: CircularStepProgressBar( + totalSteps: 16 * 4, + currentStep: 16, + width: 210, + height: 210, + selectedColor: MyColors.gradiantEndColor, + unselectedColor: MyColors.grey70Color, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + "99%".toText32(color: Colors.white, isBold: true), + "Completed".tr().toText12(color: MyColors.greyACColor), + 19.height, + "Shift Time".tr().toText12(color: MyColors.greyACColor), + "08:00 - 17:00".toText22(color: Colors.white, isBold: true), + ], + ), + ), + ), + ), + ], + ), + ), + Stack( + children: [ + Container( + height: 32, + // padding: EdgeInsets.only(top: 24, bottom: 24), + color: MyColors.backgroundBlackColor, + ), + Container( + width: double.infinity, + decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), + margin: EdgeInsets.only(top: 10), + padding: EdgeInsets.only(left: 21, right: 21, top: 24, bottom: 24), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children:[ + Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + "Actual Check In ".tr().toText12(color: MyColors.black), + ], + ), + SizedBox(height: 8,), + Row( + children: [ + "08:27".toText22(color: Colors.black, isBold: true), + ], + ), + SizedBox(height: 30,), + Row( + children: [ + "Approved Check In".tr().toText12(color: MyColors.black), + ], + ), + SizedBox(height: 8,), + Row( + children: [ + "09:27".toText22(color: Color(0xff1FA269), isBold: true), + ], + ), + SizedBox(height: 30,), + Row( + children: [ + "Late In".tr().toText12(color: MyColors.black), + ], + ), + SizedBox(height: 8,), + Row( + children: [ + "00:27".toText22(color: Color(0xffD02127), isBold: true), + ], + ), + SizedBox(height: 30,), + Row( + children: [ "Shortage".tr().toText12(color: MyColors.black), + ] ), + SizedBox(height: 8,), + Row( + children: [ + "00:00".toText22(color: Colors.black, isBold: true),], + ), + ], + ), + ], + ), + Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + "Actual Check Out".tr().toText12(color: MyColors.black), + ], + ), + SizedBox(height: 8,), + Row( + children: [ + "18:20".toText22(color: Colors.black, isBold: true),], + ), + SizedBox(height: 30,), + Row( + children: [ "Approved Check Out".tr().toText12(color: MyColors.black), + ], + ), + SizedBox(height: 8,), + Row( + children: [ + "18:20".toText22(color: Color(0xff1FA269), isBold: true),], + ), + SizedBox(height: 30,), + Row( + children: ["Excess".tr().toText12(color: MyColors.black), + ], + ), + SizedBox(height: 8,), + Row( + children: [ + "00:00".toText22(color: Colors.black, isBold: true),], + ), + SizedBox(height: 30,), + Row( + children: ["Early Out".tr().toText12(color: MyColors.black), + ], + ), + SizedBox(height: 8,), + Row( + children: [ + "00:00".toText22(color: Colors.black, isBold: true),], + ), + ], + ), + ], + ), + ] ), + ), + ]), + ], + ), + ) + )); + + } + + +} diff --git a/lib/ui/landing/dashboard.dart b/lib/ui/landing/dashboard.dart index 2c8367a..feb405d 100644 --- a/lib/ui/landing/dashboard.dart +++ b/lib/ui/landing/dashboard.dart @@ -9,6 +9,10 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; +import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart'; + + + class Dashboard extends StatefulWidget { Dashboard({Key? key}) : super(key: key); @@ -407,7 +411,10 @@ class _DashboardState extends State { .tr() .toText12(isUnderLine: true), ], - ).paddingOnly(left: 21, right: 21), + ).paddingOnly(left: 21, right: 21).onPress(() { + Navigator.pushNamed( + context, AppRoutes.monthlyAttendance); + }), SizedBox( height: 103 + 33, child: ListView.separated( @@ -464,4 +471,8 @@ class _DashboardState extends State { ), ); } + + + + } diff --git a/pubspec.lock b/pubspec.lock index 56d2f3f..414fd74 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -14,7 +14,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.1" + version: "2.8.2" boolean_selector: dependency: transitive description: @@ -28,7 +28,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" charcode: dependency: transitive description: @@ -104,6 +104,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_calendar_carousel: + dependency: "direct main" + description: + name: flutter_calendar_carousel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" flutter_lints: dependency: "direct dev" description: @@ -129,7 +136,7 @@ packages: name: flutter_svg url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.0.3" flutter_test: dependency: "direct dev" description: flutter @@ -195,14 +202,14 @@ packages: name: local_auth url: "https://pub.dartlang.org" source: hosted - version: "1.1.9" + version: "1.1.10" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10" + version: "0.12.11" meta: dependency: transitive description: @@ -251,7 +258,7 @@ packages: name: path_provider_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.9" + version: "2.0.11" path_provider_ios: dependency: transitive description: @@ -265,28 +272,28 @@ packages: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "2.1.5" path_provider_macos: dependency: transitive description: name: path_provider_macos url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.0.3" path_provider_windows: dependency: transitive description: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" permission_handler: dependency: "direct main" description: @@ -308,6 +315,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.4.0" + pie_chart: + dependency: "direct main" + description: + name: pie_chart + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.0" platform: dependency: transitive description: @@ -321,7 +335,7 @@ packages: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.1.2" process: dependency: transitive description: @@ -335,35 +349,35 @@ packages: name: provider url: "https://pub.dartlang.org" source: hosted - version: "6.0.1" + version: "6.0.2" shared_preferences: dependency: transitive description: name: shared_preferences url: "https://pub.dartlang.org" source: hosted - version: "2.0.11" + version: "2.0.12" shared_preferences_android: dependency: transitive description: name: shared_preferences_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.9" + version: "2.0.10" shared_preferences_ios: dependency: transitive description: name: shared_preferences_ios url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.0.9" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.4" shared_preferences_macos: dependency: transitive description: @@ -384,14 +398,14 @@ packages: name: shared_preferences_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.4" sizer: dependency: "direct main" description: @@ -432,6 +446,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + syncfusion_flutter_calendar: + dependency: "direct main" + description: + name: syncfusion_flutter_calendar + url: "https://pub.dartlang.org" + source: hosted + version: "19.4.48" + syncfusion_flutter_core: + dependency: transitive + description: + name: syncfusion_flutter_core + url: "https://pub.dartlang.org" + source: hosted + version: "19.4.48" + syncfusion_flutter_datepicker: + dependency: transitive + description: + name: syncfusion_flutter_datepicker + url: "https://pub.dartlang.org" + source: hosted + version: "19.4.48" term_glyph: dependency: transitive description: @@ -445,7 +480,14 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.2" + version: "0.4.3" + timezone: + dependency: transitive + description: + name: timezone + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.0" typed_data: dependency: transitive description: @@ -466,14 +508,14 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" win32: dependency: transitive description: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.3.1" + version: "2.3.9" xdg_directories: dependency: transitive description: @@ -489,5 +531,5 @@ packages: source: hosted version: "5.3.1" sdks: - dart: ">=2.14.0 <3.0.0" + dart: ">=2.15.0 <3.0.0" flutter: ">=2.5.0" diff --git a/pubspec.yaml b/pubspec.yaml index dfbb0eb..bd299c5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -44,6 +44,10 @@ dependencies: sizer: ^2.0.15 local_auth: ^1.1.9 fluttertoast: ^8.0.8 + syncfusion_flutter_calendar: ^19.4.48 + flutter_calendar_carousel: ^2.1.0 + pie_chart: ^5.1.0 + dev_dependencies: