fix: unignore flutter coverage folders and tracking them

This commit is contained in:
2026-02-20 19:23:06 +05:30
parent 8849bf2273
commit 24835f127e
6 changed files with 254 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
import 'package:intl/intl.dart';
import 'package:krow_data_connect/krow_data_connect.dart' as dc;
import 'package:krow_domain/krow_domain.dart';
import '../../domain/repositories/coverage_connector_repository.dart';
/// Implementation of [CoverageConnectorRepository].
class CoverageConnectorRepositoryImpl implements CoverageConnectorRepository {
CoverageConnectorRepositoryImpl({
dc.DataConnectService? service,
}) : _service = service ?? dc.DataConnectService.instance;
final dc.DataConnectService _service;
@override
Future<List<CoverageShift>> getShiftsForDate({
required String businessId,
required DateTime date,
}) async {
return _service.run(() async {
final DateTime start = DateTime(date.year, date.month, date.day);
final DateTime end = DateTime(date.year, date.month, date.day, 23, 59, 59, 999);
final shiftRolesResult = await _service.connector
.listShiftRolesByBusinessAndDateRange(
businessId: businessId,
start: _service.toTimestamp(start),
end: _service.toTimestamp(end),
)
.execute();
final applicationsResult = await _service.connector
.listStaffsApplicationsByBusinessForDay(
businessId: businessId,
dayStart: _service.toTimestamp(start),
dayEnd: _service.toTimestamp(end),
)
.execute();
return _mapCoverageShifts(
shiftRolesResult.data.shiftRoles,
applicationsResult.data.applications,
date,
);
});
}
List<CoverageShift> _mapCoverageShifts(
List<dynamic> shiftRoles,
List<dynamic> applications,
DateTime date,
) {
if (shiftRoles.isEmpty && applications.isEmpty) return [];
final Map<String, _CoverageGroup> groups = {};
for (final sr in shiftRoles) {
final String key = '${sr.shiftId}:${sr.roleId}';
final startTime = _service.toDateTime(sr.startTime);
groups[key] = _CoverageGroup(
shiftId: sr.shiftId,
roleId: sr.roleId,
title: sr.role.name,
location: sr.shift.location ?? sr.shift.locationAddress ?? '',
startTime: startTime != null ? DateFormat('HH:mm').format(startTime) : '00:00',
workersNeeded: sr.count,
date: _service.toDateTime(sr.shift.date) ?? date,
workers: [],
);
}
for (final app in applications) {
final String key = '${app.shiftId}:${app.roleId}';
if (!groups.containsKey(key)) {
final startTime = _service.toDateTime(app.shiftRole.startTime);
groups[key] = _CoverageGroup(
shiftId: app.shiftId,
roleId: app.roleId,
title: app.shiftRole.role.name,
location: app.shiftRole.shift.location ?? app.shiftRole.shift.locationAddress ?? '',
startTime: startTime != null ? DateFormat('HH:mm').format(startTime) : '00:00',
workersNeeded: app.shiftRole.count,
date: _service.toDateTime(app.shiftRole.shift.date) ?? date,
workers: [],
);
}
final checkIn = _service.toDateTime(app.checkInTime);
groups[key]!.workers.add(
CoverageWorker(
name: app.staff.fullName,
status: _mapWorkerStatus(app.status.stringValue),
checkInTime: checkIn != null ? DateFormat('HH:mm').format(checkIn) : null,
),
);
}
return groups.values
.map((g) => CoverageShift(
id: '${g.shiftId}:${g.roleId}',
title: g.title,
location: g.location,
startTime: g.startTime,
workersNeeded: g.workersNeeded,
date: g.date,
workers: g.workers,
))
.toList();
}
CoverageWorkerStatus _mapWorkerStatus(String status) {
switch (status) {
case 'PENDING':
return CoverageWorkerStatus.pending;
case 'REJECTED':
return CoverageWorkerStatus.rejected;
case 'CONFIRMED':
return CoverageWorkerStatus.confirmed;
case 'CHECKED_IN':
return CoverageWorkerStatus.checkedIn;
case 'CHECKED_OUT':
return CoverageWorkerStatus.checkedOut;
case 'LATE':
return CoverageWorkerStatus.late;
case 'NO_SHOW':
return CoverageWorkerStatus.noShow;
case 'COMPLETED':
return CoverageWorkerStatus.completed;
default:
return CoverageWorkerStatus.pending;
}
}
}
class _CoverageGroup {
_CoverageGroup({
required this.shiftId,
required this.roleId,
required this.title,
required this.location,
required this.startTime,
required this.workersNeeded,
required this.date,
required this.workers,
});
final String shiftId;
final String roleId;
final String title;
final String location;
final String startTime;
final int workersNeeded;
final DateTime date;
final List<CoverageWorker> workers;
}

View File

@@ -0,0 +1,12 @@
import 'package:krow_domain/krow_domain.dart';
/// Repository interface for coverage connector operations.
///
/// This acts as a buffer layer between the domain repository and the Data Connect SDK.
abstract interface class CoverageConnectorRepository {
/// Fetches coverage data for a specific date and business.
Future<List<CoverageShift>> getShiftsForDate({
required String businessId,
required DateTime date,
});
}

View File

@@ -0,0 +1,31 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../domain/repositories/reports_repository.dart';
import 'coverage_event.dart';
import 'coverage_state.dart';
class CoverageBloc extends Bloc<CoverageEvent, CoverageState> {
final ReportsRepository _reportsRepository;
CoverageBloc({required ReportsRepository reportsRepository})
: _reportsRepository = reportsRepository,
super(CoverageInitial()) {
on<LoadCoverageReport>(_onLoadCoverageReport);
}
Future<void> _onLoadCoverageReport(
LoadCoverageReport event,
Emitter<CoverageState> emit,
) async {
emit(CoverageLoading());
try {
final report = await _reportsRepository.getCoverageReport(
businessId: event.businessId,
startDate: event.startDate,
endDate: event.endDate,
);
emit(CoverageLoaded(report));
} catch (e) {
emit(CoverageError(e.toString()));
}
}
}

View File

@@ -0,0 +1,23 @@
import 'package:equatable/equatable.dart';
abstract class CoverageEvent extends Equatable {
const CoverageEvent();
@override
List<Object?> get props => [];
}
class LoadCoverageReport extends CoverageEvent {
final String? businessId;
final DateTime startDate;
final DateTime endDate;
const LoadCoverageReport({
this.businessId,
required this.startDate,
required this.endDate,
});
@override
List<Object?> get props => [businessId, startDate, endDate];
}

View File

@@ -0,0 +1,31 @@
import 'package:equatable/equatable.dart';
import 'package:krow_domain/krow_domain.dart';
abstract class CoverageState extends Equatable {
const CoverageState();
@override
List<Object?> get props => [];
}
class CoverageInitial extends CoverageState {}
class CoverageLoading extends CoverageState {}
class CoverageLoaded extends CoverageState {
final CoverageReport report;
const CoverageLoaded(this.report);
@override
List<Object?> get props => [report];
}
class CoverageError extends CoverageState {
final String message;
const CoverageError(this.message);
@override
List<Object?> get props => [message];
}