You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
359 lines
13 KiB
Dart
359 lines
13 KiB
Dart
import 'package:easy_localization/easy_localization.dart';
|
|
import 'package:easy_localization/src/public_ext.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/painting.dart';
|
|
import 'package:flutter_html/flutter_html.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:mohem_flutter_app/api/monthly_attendance_api_client.dart';
|
|
import 'package:mohem_flutter_app/classes/colors.dart';
|
|
import 'package:mohem_flutter_app/classes/date_uitl.dart';
|
|
import 'package:mohem_flutter_app/classes/utils.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/models/employee_leaves_list.dart';
|
|
import 'package:mohem_flutter_app/models/get_day_hours_type_details_list_model.dart';
|
|
import 'package:mohem_flutter_app/models/get_schedule_shifts_details_list_model.dart';
|
|
import 'package:mohem_flutter_app/models/get_time_card_summary_list_model.dart';
|
|
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
|
|
import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart';
|
|
import 'package:month_picker_dialog_2/month_picker_dialog_2.dart';
|
|
import 'package:pie_chart/pie_chart.dart';
|
|
import 'package:sizer/sizer.dart';
|
|
import 'package:syncfusion_flutter_calendar/calendar.dart';
|
|
|
|
enum LeaveType { ABSENCE, BUSINESS_TRIP, HOLIDAY, NORMAL }
|
|
|
|
class MoeMonthlyAttendanceScreen extends StatefulWidget {
|
|
@override
|
|
State<MoeMonthlyAttendanceScreen> createState() => _MoeMonthlyAttendanceScreenState();
|
|
}
|
|
|
|
class _MoeMonthlyAttendanceScreenState extends State<MoeMonthlyAttendanceScreen> {
|
|
DateTime currentDate = DateTime.now();
|
|
int searchYear = DateTime.now().year;
|
|
final CalendarController _calendarController = CalendarController();
|
|
|
|
List<EmployeeLeavesList> employeeLeavesList = [];
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
getLeavesData(currentDate);
|
|
// callTimeCardAndHourDetails(date.day, searchMonth, searchYear);
|
|
}
|
|
|
|
void getLeavesData(DateTime date) async {
|
|
try {
|
|
Utils.showLoading(context);
|
|
String startDate = '${date.year}-${date.month}-${date.day}';
|
|
int lastday = DateTime(date.year, date.month + 1, 0).day;
|
|
String endDate = '${date.year}-${date.month}-$lastday';
|
|
employeeLeavesList = await MonthlyAttendanceApiClient().getEmployeeLeaves(startDate, endDate);
|
|
Utils.hideLoading(context);
|
|
_calendarController.displayDate = date;
|
|
setState(() {});
|
|
} catch (ex) {
|
|
Utils.hideLoading(context);
|
|
Utils.handleException(ex, context, null);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: Colors.white,
|
|
appBar: AppBarWidget(
|
|
context,
|
|
// title: LocaleKeys.mowadhafhiRequest.tr(),
|
|
title: "",
|
|
// showHomeButton: true,
|
|
),
|
|
body: ListView(
|
|
scrollDirection: Axis.vertical,
|
|
children: [
|
|
Column(
|
|
children: [
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
LocaleKeys.attendance.tr().toText24(isBold: true, color: MyColors.grey3AColor),
|
|
Row(
|
|
children: [
|
|
"${DateFormat("MMMM-yyyy").format(currentDate)}".toText16(color: MyColors.greyACColor),
|
|
const Icon(Icons.keyboard_arrow_down_rounded, color: MyColors.greyACColor),
|
|
],
|
|
).onPress(() async {
|
|
showMonthPicker(
|
|
context: context,
|
|
//locale: EasyLocalization.of(context)?.locale,
|
|
initialDate: currentDate,
|
|
firstDate: DateTime(searchYear - 2),
|
|
lastDate: DateTime.now(),
|
|
confirmText: Text(LocaleKeys.confirm.tr()),
|
|
cancelText: Text(LocaleKeys.cancel.tr()),
|
|
).then((selectedDate) {
|
|
if (selectedDate != null) {
|
|
getLeavesData(selectedDate);
|
|
setState(() {
|
|
currentDate = selectedDate;
|
|
});
|
|
}
|
|
});
|
|
}),
|
|
18.height,
|
|
AspectRatio(aspectRatio: 304 / 244, child: calendarWidget()),
|
|
12.height,
|
|
SizedBox(
|
|
width: double.infinity,
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: [
|
|
showColorItem("Absence", MyColors.pinkDarkColor),
|
|
showColorItem("Business Trip", MyColors.gradiantStartColor),
|
|
showColorItem("Holiday", MyColors.gradiantEndColor),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
).paddingOnly(left: 21, right: 21, top: 21),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget showColorItem(String title, Color color) {
|
|
return Row(
|
|
children: [
|
|
Container(
|
|
width: 20,
|
|
height: 20,
|
|
color: color,
|
|
).circle(2000),
|
|
8.width,
|
|
title.toText12()
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget calendarWidget() {
|
|
return SfCalendar(
|
|
view: CalendarView.month,
|
|
showDatePickerButton: false,
|
|
controller: _calendarController,
|
|
backgroundColor: Colors.white,
|
|
headerHeight: 0,
|
|
viewNavigationMode: ViewNavigationMode.none,
|
|
todayHighlightColor: MyColors.grey3AColor,
|
|
showNavigationArrow: false,
|
|
showCurrentTimeIndicator: false,
|
|
showWeekNumber: false,
|
|
cellBorderColor: Colors.white,
|
|
onTap: (v) {
|
|
dynamic index = v.date?.day;
|
|
if (index != null) {
|
|
index = index - 1;
|
|
}
|
|
EmployeeLeavesList leaves = employeeLeavesList[index];
|
|
if (leaves.leaveType != LeaveType.NORMAL.name) {
|
|
showModalBottomSheet(
|
|
context: context,
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(25.0),
|
|
topRight: Radius.circular(25.0),
|
|
)),
|
|
isScrollControlled: true,
|
|
backgroundColor: MyColors.white,
|
|
builder: (_) {
|
|
return DraggableScrollableSheet(
|
|
maxChildSize: 0.75,
|
|
expand: false,
|
|
initialChildSize: 0.75,
|
|
builder: (_, controller) {
|
|
return Column(
|
|
children: [
|
|
Container(
|
|
width: 49,
|
|
height: 7,
|
|
margin: const EdgeInsets.symmetric(vertical: 10),
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(25),
|
|
color: MyColors.darkGreyColor,
|
|
),
|
|
),
|
|
16.height,
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 40),
|
|
margin: const EdgeInsets.only(left: 20, right: 20),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(
|
|
color: Colors.black,
|
|
),
|
|
borderRadius: BorderRadius.circular(12)),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
DateUtil.getWeekDay(DateUtil.convertStringToDateTime(leaves.eventDate ?? "").weekday).toString().toText14(),
|
|
DateUtil.convertStringToDateTime(leaves.eventDate ?? "").day.toString().toText20(),
|
|
DateUtil.getMonth(DateUtil.convertStringToDateTime(leaves.eventDate ?? "").month).toString().toText14(),
|
|
DateUtil.convertStringToDateTime(leaves.eventDate ?? "").year.toString().toText14(),
|
|
],
|
|
),
|
|
),
|
|
6.height,
|
|
showText(LocaleKeys.leaveType.tr(), leaves.leaveType.toString()),
|
|
// if (leaves.absenceAttendanceTypeName.toString().isNotEmpty)
|
|
// const Divider(
|
|
// color: MyColors.borderCEColor,
|
|
// ),
|
|
// if (leaves.absenceAttendanceTypeName.toString().isNotEmpty) showText(LocaleKeys.attendanceType.tr(), leaves.absenceAttendanceTypeName.toString()),
|
|
const Divider(
|
|
color: MyColors.borderCEColor,
|
|
),
|
|
showText(LocaleKeys.startDateT.tr(), leaves.dateStart.toString()),
|
|
const Divider(
|
|
color: MyColors.borderCEColor,
|
|
),
|
|
showText(LocaleKeys.endDate.tr(), leaves.dateEnd.toString()),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
},
|
|
);
|
|
}
|
|
},
|
|
selectionDecoration: BoxDecoration(
|
|
border: Border.all(color: MyColors.white, width: 1),
|
|
shape: BoxShape.circle,
|
|
),
|
|
dataSource: MeetingDataSource(_getDataSource()),
|
|
// onTap: calendarTapped,
|
|
monthViewSettings: const MonthViewSettings(
|
|
dayFormat: 'EEE',
|
|
showTrailingAndLeadingDates: false,
|
|
showAgenda: false,
|
|
),
|
|
viewHeaderStyle: const ViewHeaderStyle(
|
|
dayTextStyle: TextStyle(color: MyColors.grey3AColor, fontSize: 13, fontWeight: FontWeight.w600),
|
|
),
|
|
monthCellBuilder: (build, details) {
|
|
LeaveType leaveType = LeaveType.NORMAL;
|
|
for (int i = 0; i < employeeLeavesList.length; i++) {
|
|
if (details.date.day == DateUtil.convertSimpleStringDateToDateddMMyyyy(employeeLeavesList[i].eventDate ?? "").day) {
|
|
if (employeeLeavesList[i].leaveType == LeaveType.ABSENCE.name) {
|
|
leaveType = LeaveType.ABSENCE;
|
|
} else if (employeeLeavesList[i].leaveType == LeaveType.BUSINESS_TRIP.name) {
|
|
leaveType = LeaveType.BUSINESS_TRIP;
|
|
} else if (employeeLeavesList[i].leaveType == LeaveType.HOLIDAY.name) {
|
|
leaveType = LeaveType.HOLIDAY;
|
|
}
|
|
}
|
|
}
|
|
return Container(
|
|
margin: const EdgeInsets.all(4),
|
|
decoration: BoxDecoration(
|
|
color: leaveType == LeaveType.ABSENCE
|
|
? MyColors.pinkDarkColor
|
|
: leaveType == LeaveType.BUSINESS_TRIP
|
|
? MyColors.gradiantStartColor
|
|
: leaveType == LeaveType.HOLIDAY
|
|
? MyColors.gradiantEndColor
|
|
: MyColors.white,
|
|
shape: BoxShape.circle,
|
|
border: Border.all(
|
|
color: leaveType == LeaveType.ABSENCE
|
|
? MyColors.pinkDarkColor
|
|
: leaveType == LeaveType.BUSINESS_TRIP
|
|
? MyColors.gradiantStartColor
|
|
: leaveType == LeaveType.HOLIDAY
|
|
? MyColors.gradiantEndColor
|
|
: MyColors.black,
|
|
width: 2,
|
|
),
|
|
),
|
|
alignment: Alignment.center,
|
|
child: Text(
|
|
"${details.date.day}",
|
|
style: TextStyle(fontSize: 13, fontWeight: FontWeight.w500, color: leaveType == LeaveType.NORMAL ? MyColors.black : MyColors.white),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
List<Meeting> _getDataSource() {
|
|
List<Meeting> meetings = <Meeting>[];
|
|
return meetings;
|
|
}
|
|
|
|
Widget showText(String title, String value) {
|
|
return Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
value.toText18(color: MyColors.gradiantEndColor, isBold: true),
|
|
title.toText14(color: MyColors.greyACColor, isBold: false),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class MeetingDataSource extends CalendarDataSource {
|
|
MeetingDataSource(List<Meeting> 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) {
|
|
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;
|
|
}
|