refactor: centralize data connect error handling and resolve build issues across applications

This commit addresses several critical issues across the mobile monorepo:

1. Centralized Error Handling: Integrated DataErrorHandler mixin into all repository implementations, ensuring consistent mapping of Data Connect exceptions to domain AppExceptions.
2. Build Stabilization: Fixed numerous type mismatches, parameter signature errors in widgets (e.g., google_places_flutter itemBuilder), and naming conflicts (StaffSession, FirebaseAuth).
3. Code Quality: Applied 'dart fix' across all modified packages and manually cleared debug print statements and UI clutter.
4. Mono-repo alignment: Standardized Data Connect usage and aliasing ('dc.') for better maintainability.

Signed-off-by: Suriya <suriya@tenext.in>
This commit is contained in:
2026-02-06 13:28:57 +05:30
parent e0636e46a3
commit 5e7bf0d5c0
150 changed files with 1506 additions and 2547 deletions

View File

@@ -1,22 +1,22 @@
import 'package:firebase_data_connect/firebase_data_connect.dart';
import 'package:krow_data_connect/krow_data_connect.dart' as dc;
import 'package:krow_data_connect/src/session/staff_session_store.dart';
import 'package:krow_domain/krow_domain.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_auth/firebase_auth.dart' as firebase_auth;
import 'package:krow_core/core.dart';
import '../../domain/repositories/payments_repository.dart';
class PaymentsRepositoryImpl implements PaymentsRepository {
final dc.ExampleConnector _dataConnect;
final FirebaseAuth _auth = FirebaseAuth.instance;
PaymentsRepositoryImpl() : _dataConnect = dc.ExampleConnector.instance;
final dc.ExampleConnector _dataConnect;
final firebase_auth.FirebaseAuth _auth = firebase_auth.FirebaseAuth.instance;
String? _cachedStaffId;
Future<String> _getStaffId() async {
// 1. Check Session Store
final StaffSession? session = StaffSessionStore.instance.session;
final dc.StaffSession? session = dc.StaffSessionStore.instance.session;
if (session?.staff?.id != null) {
return session!.staff!.id;
}
@@ -25,13 +25,13 @@ class PaymentsRepositoryImpl implements PaymentsRepository {
if (_cachedStaffId != null) return _cachedStaffId!;
// 3. Fetch from Data Connect using Firebase UID
final user = _auth.currentUser;
final firebase_auth.User? user = _auth.currentUser;
if (user == null) {
throw Exception('User is not authenticated');
}
try {
final response = await _dataConnect.getStaffByUserId(userId: user.uid).execute();
final QueryResult<dc.GetStaffByUserIdData, dc.GetStaffByUserIdVariables> response = await _dataConnect.getStaffByUserId(userId: user.uid).execute();
if (response.data.staffs.isNotEmpty) {
_cachedStaffId = response.data.staffs.first.id;
return _cachedStaffId!;
@@ -66,9 +66,7 @@ class PaymentsRepositoryImpl implements PaymentsRepository {
} catch (_) {}
try {
if (dt == null) {
dt = DateTime.tryParse(t.toString());
}
dt ??= DateTime.tryParse(t.toString());
} catch (_) {}
}

View File

@@ -2,11 +2,11 @@ import 'package:krow_core/core.dart';
/// Arguments for getting payment history.
class GetPaymentHistoryArguments extends UseCaseArgument {
const GetPaymentHistoryArguments(this.period);
/// The period to filter by (e.g., "monthly", "weekly").
final String period;
const GetPaymentHistoryArguments(this.period);
@override
List<Object?> get props => [period];
List<Object?> get props => <Object?>[period];
}

View File

@@ -7,10 +7,10 @@ import '../repositories/payments_repository.dart';
///
/// This use case delegates the data retrieval to [PaymentsRepository].
class GetPaymentHistoryUseCase extends UseCase<GetPaymentHistoryArguments, List<StaffPayment>> {
final PaymentsRepository repository;
/// Creates a [GetPaymentHistoryUseCase].
GetPaymentHistoryUseCase(this.repository);
final PaymentsRepository repository;
@override
Future<List<StaffPayment>> call(GetPaymentHistoryArguments arguments) async {

View File

@@ -4,10 +4,10 @@ import '../repositories/payments_repository.dart';
/// Use case to retrieve payment summary information.
class GetPaymentSummaryUseCase extends NoInputUseCase<PaymentSummary> {
final PaymentsRepository repository;
/// Creates a [GetPaymentSummaryUseCase].
GetPaymentSummaryUseCase(this.repository);
final PaymentsRepository repository;
@override
Future<PaymentSummary> call() async {

View File

@@ -1,6 +1,6 @@
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:krow_core/core.dart';
import 'package:krow_data_connect/krow_data_connect.dart';
import 'domain/repositories/payments_repository.dart';
import 'domain/usecases/get_payment_summary_usecase.dart';
import 'domain/usecases/get_payment_history_usecase.dart';
@@ -26,7 +26,7 @@ class StaffPaymentsModule extends Module {
void routes(RouteManager r) {
r.child(
StaffPaths.childRoute(StaffPaths.payments, StaffPaths.payments),
child: (context) => const PaymentsPage(),
child: (BuildContext context) => const PaymentsPage(),
);
}
}

View File

@@ -7,8 +7,6 @@ import 'payments_event.dart';
import 'payments_state.dart';
class PaymentsBloc extends Bloc<PaymentsEvent, PaymentsState> {
final GetPaymentSummaryUseCase getPaymentSummary;
final GetPaymentHistoryUseCase getPaymentHistory;
PaymentsBloc({
required this.getPaymentSummary,
@@ -17,6 +15,8 @@ class PaymentsBloc extends Bloc<PaymentsEvent, PaymentsState> {
on<LoadPaymentsEvent>(_onLoadPayments);
on<ChangePeriodEvent>(_onChangePeriod);
}
final GetPaymentSummaryUseCase getPaymentSummary;
final GetPaymentHistoryUseCase getPaymentHistory;
Future<void> _onLoadPayments(
LoadPaymentsEvent event,

View File

@@ -1,20 +1,19 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
abstract class PaymentsEvent extends Equatable {
const PaymentsEvent();
@override
List<Object?> get props => [];
List<Object?> get props => <Object?>[];
}
class LoadPaymentsEvent extends PaymentsEvent {}
class ChangePeriodEvent extends PaymentsEvent {
final String period;
const ChangePeriodEvent(this.period);
final String period;
@override
List<Object?> get props => [period];
List<Object?> get props => <Object?>[period];
}

View File

@@ -5,7 +5,7 @@ abstract class PaymentsState extends Equatable {
const PaymentsState();
@override
List<Object?> get props => [];
List<Object?> get props => <Object?>[];
}
class PaymentsInitial extends PaymentsState {}
@@ -13,15 +13,15 @@ class PaymentsInitial extends PaymentsState {}
class PaymentsLoading extends PaymentsState {}
class PaymentsLoaded extends PaymentsState {
final PaymentSummary summary;
final List<StaffPayment> history;
final String activePeriod;
const PaymentsLoaded({
required this.summary,
required this.history,
this.activePeriod = 'week',
});
final PaymentSummary summary;
final List<StaffPayment> history;
final String activePeriod;
PaymentsLoaded copyWith({
PaymentSummary? summary,
@@ -36,14 +36,14 @@ class PaymentsLoaded extends PaymentsState {
}
@override
List<Object?> get props => [summary, history, activePeriod];
List<Object?> get props => <Object?>[summary, history, activePeriod];
}
class PaymentsError extends PaymentsState {
final String message;
const PaymentsError(this.message);
final String message;
@override
List<Object?> get props => [message];
List<Object?> get props => <Object?>[message];
}

View File

@@ -1,10 +1,6 @@
import 'package:equatable/equatable.dart';
class PaymentStats extends Equatable {
final double weeklyEarnings;
final double monthlyEarnings;
final double pendingEarnings;
final double totalEarnings;
const PaymentStats({
this.weeklyEarnings = 0.0,
@@ -12,9 +8,13 @@ class PaymentStats extends Equatable {
this.pendingEarnings = 0.0,
this.totalEarnings = 0.0,
});
final double weeklyEarnings;
final double monthlyEarnings;
final double pendingEarnings;
final double totalEarnings;
@override
List<Object?> get props => [
List<Object?> get props => <Object?>[
weeklyEarnings,
monthlyEarnings,
pendingEarnings,

View File

@@ -177,7 +177,7 @@ class _PaymentsPageState extends State<PaymentsPage> {
// Recent Payments
if (state.history.isNotEmpty) Column(
children: [
children: <Widget>[
const Text(
"Recent Payments",
style: TextStyle(

View File

@@ -4,21 +4,21 @@ import 'package:intl/intl.dart';
import 'package:krow_domain/krow_domain.dart';
class EarningsGraph extends StatelessWidget {
final List<StaffPayment> payments;
final String period;
const EarningsGraph({
super.key,
required this.payments,
required this.period,
});
final List<StaffPayment> payments;
final String period;
@override
Widget build(BuildContext context) {
// Basic data processing for the graph
// We'll aggregate payments by date
final validPayments = payments.where((p) => p.paidAt != null).toList()
..sort((a, b) => a.paidAt!.compareTo(b.paidAt!));
final List<StaffPayment> validPayments = payments.where((StaffPayment p) => p.paidAt != null).toList()
..sort((StaffPayment a, StaffPayment b) => a.paidAt!.compareTo(b.paidAt!));
// If no data, show empty state or simple placeholder
if (validPayments.isEmpty) {
@@ -32,9 +32,9 @@ class EarningsGraph extends StatelessWidget {
);
}
final spots = _generateSpots(validPayments);
final maxX = spots.isNotEmpty ? spots.last.x : 0.0;
final maxY = spots.isNotEmpty ? spots.map((s) => s.y).reduce((a, b) => a > b ? a : b) : 0.0;
final List<FlSpot> spots = _generateSpots(validPayments);
final double maxX = spots.isNotEmpty ? spots.last.x : 0.0;
final double maxY = spots.isNotEmpty ? spots.map((FlSpot s) => s.y).reduce((double a, double b) => a > b ? a : b) : 0.0;
return Container(
height: 220,
@@ -42,7 +42,7 @@ class EarningsGraph extends StatelessWidget {
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black.withOpacity(0.05),
offset: const Offset(0, 4),
@@ -52,7 +52,7 @@ class EarningsGraph extends StatelessWidget {
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
children: <Widget>[
const Text(
"Earnings Trend",
style: TextStyle(
@@ -70,10 +70,10 @@ class EarningsGraph extends StatelessWidget {
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: (value, meta) {
getTitlesWidget: (double value, TitleMeta meta) {
// Simple logic to show a few dates
if (value % 2 != 0) return const SizedBox();
final index = value.toInt();
final int index = value.toInt();
if (index >= 0 && index < validPayments.length) {
return Padding(
padding: const EdgeInsets.only(top: 8.0),
@@ -92,7 +92,7 @@ class EarningsGraph extends StatelessWidget {
rightTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
),
borderData: FlBorderData(show: false),
lineBarsData: [
lineBarsData: <LineChartBarData>[
LineChartBarData(
spots: spots,
isCurved: true,
@@ -121,7 +121,7 @@ class EarningsGraph extends StatelessWidget {
List<FlSpot> _generateSpots(List<StaffPayment> data) {
// Generate spots based on index in the list for simplicity in this demo
// Real implementation would map to actual dates on X-axis
return List.generate(data.length, (index) {
return List.generate(data.length, (int index) {
return FlSpot(index.toDouble(), data[index].amount);
});
}

View File

@@ -2,15 +2,6 @@ import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart';
class PaymentHistoryItem extends StatelessWidget {
final double amount;
final String title;
final String location;
final String address;
final String date;
final String workedTime;
final int hours;
final double rate;
final String status;
const PaymentHistoryItem({
super.key,
@@ -24,6 +15,15 @@ class PaymentHistoryItem extends StatelessWidget {
required this.rate,
required this.status,
});
final double amount;
final String title;
final String location;
final String address;
final String date;
final String workedTime;
final int hours;
final double rate;
final String status;
@override
Widget build(BuildContext context) {
@@ -32,7 +32,7 @@ class PaymentHistoryItem extends StatelessWidget {
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 2,
@@ -42,10 +42,10 @@ class PaymentHistoryItem extends StatelessWidget {
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
children: <Widget>[
// Status Badge
Row(
children: [
children: <Widget>[
Container(
width: 6,
height: 6,
@@ -70,7 +70,7 @@ class PaymentHistoryItem extends StatelessWidget {
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
children: <Widget>[
// Icon
Container(
width: 44,
@@ -90,15 +90,15 @@ class PaymentHistoryItem extends StatelessWidget {
// Content
Expanded(
child: Column(
children: [
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
children: <Widget>[
Text(
title,
style: const TextStyle(
@@ -119,7 +119,7 @@ class PaymentHistoryItem extends StatelessWidget {
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
children: <Widget>[
Text(
"\$${amount.toStringAsFixed(0)}",
style: const TextStyle(
@@ -143,7 +143,7 @@ class PaymentHistoryItem extends StatelessWidget {
// Date and Time
Row(
children: [
children: <Widget>[
const Icon(
LucideIcons.calendar,
size: 12,
@@ -177,7 +177,7 @@ class PaymentHistoryItem extends StatelessWidget {
// Address
Row(
children: [
children: <Widget>[
const Icon(
LucideIcons.mapPin,
size: 12,

View File

@@ -1,11 +1,6 @@
import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart';
class PaymentStatsCard extends StatelessWidget {
final IconData icon;
final Color iconColor;
final String label;
final String amount;
const PaymentStatsCard({
super.key,
@@ -14,6 +9,10 @@ class PaymentStatsCard extends StatelessWidget {
required this.label,
required this.amount,
});
final IconData icon;
final Color iconColor;
final String label;
final String amount;
@override
Widget build(BuildContext context) {
@@ -22,7 +21,7 @@ class PaymentStatsCard extends StatelessWidget {
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 2,
@@ -32,9 +31,9 @@ class PaymentStatsCard extends StatelessWidget {
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
children: <Widget>[
Row(
children: [
children: <Widget>[
Icon(icon, size: 16, color: iconColor),
const SizedBox(width: 8),
Text(

View File

@@ -2,14 +2,14 @@ import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart';
class PendingPayCard extends StatelessWidget {
final double amount;
final VoidCallback onCashOut;
const PendingPayCard({
super.key,
required this.amount,
required this.onCashOut,
});
final double amount;
final VoidCallback onCashOut;
@override
Widget build(BuildContext context) {
@@ -17,12 +17,12 @@ class PendingPayCard extends StatelessWidget {
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFFEFF6FF), Color(0xFFEFF6FF)], // blue-50 to blue-50
colors: <Color>[Color(0xFFEFF6FF), Color(0xFFEFF6FF)], // blue-50 to blue-50
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(16),
boxShadow: [
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 2,
@@ -32,9 +32,9 @@ class PendingPayCard extends StatelessWidget {
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
children: <Widget>[
Row(
children: [
children: <Widget>[
Container(
width: 40,
height: 40,
@@ -51,7 +51,7 @@ class PendingPayCard extends StatelessWidget {
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
children: <Widget>[
const Text(
"Pending",
style: TextStyle(