From f29905c0baf127ead148024b13e0ed09acd50440 Mon Sep 17 00:00:00 2001 From: Sergey Dmitriev <51058739+0niel@users.noreply.github.com> Date: Wed, 19 Apr 2023 22:43:37 +0300 Subject: [PATCH] ui: Update attendance and fix null-error --- lib/data/datasources/user_remote.dart | 12 +- .../profile/profile_attendance_page.dart | 117 ++++++++++++++---- .../profile/widgets/attendance_card.dart | 2 +- 3 files changed, 100 insertions(+), 31 deletions(-) diff --git a/lib/data/datasources/user_remote.dart b/lib/data/datasources/user_remote.dart index 79c19270..ee757051 100644 --- a/lib/data/datasources/user_remote.dart +++ b/lib/data/datasources/user_remote.dart @@ -250,12 +250,16 @@ class UserRemoteDataImpl implements UserRemoteData { if (jsonResponse["ROWS"] != null) { Map.from(jsonResponse["ROWS"]).forEach((date, row) { if (row.containsKey("START")) { - attendance.add( - AttendanceModel.fromJson(row["START"]).copyWith(date: date)); + if (row["START"] != null) { + attendance.add( + AttendanceModel.fromJson(row["START"]).copyWith(date: date)); + } } if (row.containsKey("END")) { - attendance - .add(AttendanceModel.fromJson(row["END"]).copyWith(date: date)); + if (row["END"] != null) { + attendance.add( + AttendanceModel.fromJson(row["END"]).copyWith(date: date)); + } } }); } diff --git a/lib/presentation/pages/profile/profile_attendance_page.dart b/lib/presentation/pages/profile/profile_attendance_page.dart index 4cdf05aa..cc28155a 100644 --- a/lib/presentation/pages/profile/profile_attendance_page.dart +++ b/lib/presentation/pages/profile/profile_attendance_page.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:get/get.dart'; +import 'package:rtu_mirea_app/domain/entities/attendance.dart'; import 'package:rtu_mirea_app/presentation/bloc/attendance_bloc/attendance_bloc.dart'; import 'package:rtu_mirea_app/presentation/bloc/user_bloc/user_bloc.dart'; import 'package:rtu_mirea_app/presentation/pages/profile/widgets/attendance_card.dart'; @@ -34,6 +36,94 @@ class _ProfileAttendancePageState extends State { return res; } + List> _groupAttendanceByDate(List attendance) { + final Map> groupedAttendance = {}; + for (var element in attendance) { + if (groupedAttendance.containsKey(element.date)) { + groupedAttendance[element.date]!.add(element); + } else { + groupedAttendance[element.date] = [element]; + } + } + + final List> result = []; + + final dateFormat = DateFormat('dd.MM.yyyy HH:mm:ss'); + + groupedAttendance.forEach((key, value) { + value.sort((a, b) { + final aDateTime = dateFormat.parse('${a.date} ${a.time}'); + final bDateTime = dateFormat.parse('${b.date} ${b.time}'); + + return aDateTime.compareTo(bDateTime); + }); + + final List entryExitAttendance = []; + + Attendance? entryAttendance; + Attendance? exitAttendance; + + for (final element in value) { + if (element.eventType == 'Вход' && entryAttendance == null) { + entryAttendance = element; + } else if (element.eventType == 'Выход') { + exitAttendance = element; + } + } + + if (entryAttendance != null) { + entryExitAttendance.add(entryAttendance!); + } + if (exitAttendance != null) { + entryExitAttendance.add(exitAttendance!); + } + result.add(entryExitAttendance); + }); + + return result; + } + + Widget _buildAttendanceList(List attendance) { + final List> groupedAttendance = + _groupAttendanceByDate(attendance); + return Expanded( + child: Column( + children: [ + const SizedBox(height: 8), + Text('Дней посещено: ${groupedAttendance.length}', + style: AppTextStyle.body), + const SizedBox(height: 8), + Expanded( + child: ListView.builder( + itemCount: groupedAttendance.length, + itemBuilder: (context, index) { + return Padding( + padding: + const EdgeInsets.symmetric(vertical: 16, horizontal: 24), + child: Column(children: [ + AttendanceCard( + type: groupedAttendance[index][0].eventType, + date: groupedAttendance[index][0].date, + time: groupedAttendance[index][0].time, + ), + if (groupedAttendance[index].length > 1) ...[ + const SizedBox(height: 8), + AttendanceCard( + type: groupedAttendance[index][1].eventType, + date: groupedAttendance[index][1].date, + time: groupedAttendance[index][1].time, + ), + ], + ]), + ); + }, + ), + ), + ], + ), + ); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -92,32 +182,7 @@ class _ProfileAttendancePageState extends State { child: Center(child: CircularProgressIndicator())) else if (state is AttendanceLoaded && state.attendance.isNotEmpty) - Expanded( - child: Column( - children: [ - const SizedBox(height: 8), - Text('Дней посещено: ${state.visitsCount}', - style: AppTextStyle.body), - const SizedBox(height: 8), - Expanded( - child: ListView.builder( - itemCount: state.attendance.length, - itemBuilder: (context, index) { - return Padding( - padding: const EdgeInsets.symmetric( - vertical: 16, horizontal: 24), - child: AttendanceCard( - type: state.attendance[index].eventType, - date: state.attendance[index].date, - time: state.attendance[index].time, - ), - ); - }, - ), - ), - ], - ), - ), + _buildAttendanceList(state.attendance), if (state is AttendanceLoaded && state.attendance.isEmpty) Expanded( child: Center( diff --git a/lib/presentation/pages/profile/widgets/attendance_card.dart b/lib/presentation/pages/profile/widgets/attendance_card.dart index 7213e159..d98ae016 100644 --- a/lib/presentation/pages/profile/widgets/attendance_card.dart +++ b/lib/presentation/pages/profile/widgets/attendance_card.dart @@ -54,7 +54,7 @@ class AttendanceCard extends StatelessWidget { alignment: Alignment.center, child: type == "Вход" ? const Icon(FontAwesomeIcons.rightToBracket, size: 15) - : const Icon(FontAwesomeIcons.rightToBracket, size: 15), + : const Icon(FontAwesomeIcons.rightFromBracket, size: 15), ), ), const SizedBox(width: 55.50),