Add initial mobile app prototypes and staff payments feature

Introduces the first versions of client and staff mobile application prototypes, including platform-specific assets, screens, and configuration for Android, iOS, macOS, Linux, and Windows. Adds documentation, AI prompt guides, and a new staff payments feature module with repository, use cases, and presentation logic. Also includes generated localization files and supporting resources for both client and staff apps.
This commit is contained in:
Achintha Isuru
2026-01-25 17:01:18 -05:00
parent 0b043ed91e
commit 19959a2b3f
468 changed files with 71399 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
import 'package:krow_data_connect/krow_data_connect.dart';
import 'package:krow_domain/krow_domain.dart';
import '../../domain/repositories/payments_repository.dart';
class PaymentsRepositoryImpl implements PaymentsRepository {
final FinancialRepositoryMock financialRepository;
PaymentsRepositoryImpl({required this.financialRepository});
@override
Future<List<StaffPayment>> getPayments() async {
// TODO: Get actual logged in staff ID
return await financialRepository.getStaffPayments('staff_1');
}
}

View File

@@ -1,3 +1,4 @@
<<<<<<< Updated upstream
import '../entities/payment_summary.dart';
import '../entities/payment_transaction.dart';
@@ -7,4 +8,11 @@ abstract class PaymentsRepository {
/// Fetches the list of recent payment transactions (history).
Future<List<PaymentTransaction>> getPaymentHistory(String period);
=======
import 'package:krow_domain/krow_domain.dart';
abstract class PaymentsRepository {
/// Fetches the list of payments.
Future<List<StaffPayment>> getPayments();
>>>>>>> Stashed changes
}

View File

@@ -1,12 +1,27 @@
<<<<<<< Updated upstream
import '../entities/payment_transaction.dart';
import '../repositories/payments_repository.dart';
class GetPaymentHistoryUseCase {
=======
import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart';
import '../repositories/payments_repository.dart';
class GetPaymentHistoryUseCase extends UseCase<String, List<StaffPayment>> {
>>>>>>> Stashed changes
final PaymentsRepository repository;
GetPaymentHistoryUseCase(this.repository);
<<<<<<< Updated upstream
Future<List<PaymentTransaction>> call({String period = 'week'}) async {
return await repository.getPaymentHistory(period);
=======
@override
Future<List<StaffPayment>> call(String period) async {
// TODO: Implement filtering by period
return await repository.getPayments();
>>>>>>> Stashed changes
}
}

View File

@@ -1,12 +1,26 @@
<<<<<<< Updated upstream
import '../entities/payment_summary.dart';
import '../repositories/payments_repository.dart';
class GetPaymentSummaryUseCase {
=======
import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart';
import '../repositories/payments_repository.dart';
class GetPaymentSummaryUseCase extends NoInputUseCase<List<StaffPayment>> {
>>>>>>> Stashed changes
final PaymentsRepository repository;
GetPaymentSummaryUseCase(this.repository);
<<<<<<< Updated upstream
Future<PaymentSummary> call() async {
return await repository.getPaymentSummary();
=======
@override
Future<List<StaffPayment>> call() async {
return await repository.getPayments();
>>>>>>> Stashed changes
}
}

View File

@@ -1,18 +1,31 @@
import 'package:flutter_modular/flutter_modular.dart';
<<<<<<< Updated upstream
import 'domain/repositories/payments_repository.dart';
import 'domain/usecases/get_payment_summary_usecase.dart';
import 'domain/usecases/get_payment_history_usecase.dart';
import 'data/datasources/payments_remote_datasource.dart';
import 'data/datasources/payments_mock_datasource.dart';
import 'data/repositories/payments_repository_impl.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';
import 'data/repositories_impl/payments_repository_impl.dart';
>>>>>>> Stashed changes
import 'presentation/blocs/payments/payments_bloc.dart';
import 'presentation/pages/payments_page.dart';
class StaffPaymentsModule extends Module {
@override
void binds(Injector i) {
<<<<<<< Updated upstream
// Data Sources
i.add<PaymentsRemoteDataSource>(PaymentsMockDataSource.new);
=======
// Data Connect Mocks
i.add<FinancialRepositoryMock>(FinancialRepositoryMock.new);
>>>>>>> Stashed changes
// Repositories
i.add<PaymentsRepository>(PaymentsRepositoryImpl.new);

View File

@@ -1,8 +1,15 @@
import 'package:flutter_bloc/flutter_bloc.dart';
<<<<<<< Updated upstream
import '../../../domain/entities/payment_summary.dart';
import '../../../domain/entities/payment_transaction.dart';
import '../../../domain/usecases/get_payment_summary_usecase.dart';
import '../../../domain/usecases/get_payment_history_usecase.dart';
=======
import 'package:krow_domain/krow_domain.dart';
import '../../../domain/usecases/get_payment_summary_usecase.dart';
import '../../../domain/usecases/get_payment_history_usecase.dart';
import '../../models/payment_stats.dart';
>>>>>>> Stashed changes
import 'payments_event.dart';
import 'payments_state.dart';
@@ -24,10 +31,19 @@ class PaymentsBloc extends Bloc<PaymentsEvent, PaymentsState> {
) async {
emit(PaymentsLoading());
try {
<<<<<<< Updated upstream
final PaymentSummary summary = await getPaymentSummary();
final List<PaymentTransaction> history = await getPaymentHistory(period: 'week');
emit(PaymentsLoaded(
summary: summary,
=======
final List<StaffPayment> allPayments = await getPaymentSummary();
final PaymentStats stats = _calculateStats(allPayments);
final List<StaffPayment> history = await getPaymentHistory('week');
emit(PaymentsLoaded(
summary: stats,
>>>>>>> Stashed changes
history: history,
activePeriod: 'week',
));
@@ -44,10 +60,15 @@ class PaymentsBloc extends Bloc<PaymentsEvent, PaymentsState> {
if (currentState is PaymentsLoaded) {
if (currentState.activePeriod == event.period) return;
<<<<<<< Updated upstream
// Optimistic update or set loading state if expecting delay
// For now, we'll keep the current data and fetch new history
try {
final List<PaymentTransaction> newHistory = await getPaymentHistory(period: event.period);
=======
try {
final List<StaffPayment> newHistory = await getPaymentHistory(event.period);
>>>>>>> Stashed changes
emit(currentState.copyWith(
history: newHistory,
activePeriod: event.period,
@@ -57,4 +78,41 @@ class PaymentsBloc extends Bloc<PaymentsEvent, PaymentsState> {
}
}
}
<<<<<<< Updated upstream
=======
PaymentStats _calculateStats(List<StaffPayment> payments) {
double total = 0;
double pending = 0;
double weekly = 0;
double monthly = 0;
final DateTime now = DateTime.now();
for (final StaffPayment p in payments) {
// Assuming all payments count towards total history
total += p.amount;
if (p.status == PaymentStatus.pending) {
pending += p.amount;
}
if (p.paidAt != null) {
if (now.difference(p.paidAt!).inDays < 7) {
weekly += p.amount;
}
if (now.month == p.paidAt!.month && now.year == p.paidAt!.year) {
monthly += p.amount;
}
}
}
return PaymentStats(
totalEarnings: total,
pendingEarnings: pending,
weeklyEarnings: weekly,
monthlyEarnings: monthly,
);
}
>>>>>>> Stashed changes
}

View File

@@ -1,6 +1,11 @@
import 'package:equatable/equatable.dart';
<<<<<<< Updated upstream
import '../../../domain/entities/payment_summary.dart';
import '../../../domain/entities/payment_transaction.dart';
=======
import 'package:krow_domain/krow_domain.dart';
import '../../models/payment_stats.dart';
>>>>>>> Stashed changes
abstract class PaymentsState extends Equatable {
const PaymentsState();
@@ -14,8 +19,13 @@ class PaymentsInitial extends PaymentsState {}
class PaymentsLoading extends PaymentsState {}
class PaymentsLoaded extends PaymentsState {
<<<<<<< Updated upstream
final PaymentSummary summary;
final List<PaymentTransaction> history;
=======
final PaymentStats summary;
final List<StaffPayment> history;
>>>>>>> Stashed changes
final String activePeriod;
const PaymentsLoaded({
@@ -25,8 +35,13 @@ class PaymentsLoaded extends PaymentsState {
});
PaymentsLoaded copyWith({
<<<<<<< Updated upstream
PaymentSummary? summary,
List<PaymentTransaction>? history,
=======
PaymentStats? summary,
List<StaffPayment>? history,
>>>>>>> Stashed changes
String? activePeriod,
}) {
return PaymentsLoaded(

View File

@@ -0,0 +1,23 @@
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,
this.monthlyEarnings = 0.0,
this.pendingEarnings = 0.0,
this.totalEarnings = 0.0,
});
@override
List<Object?> get props => [
weeklyEarnings,
monthlyEarnings,
pendingEarnings,
totalEarnings,
];
}

View File

@@ -3,7 +3,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:lucide_icons/lucide_icons.dart';
import 'package:intl/intl.dart';
<<<<<<< Updated upstream
import '../../domain/entities/payment_transaction.dart';
=======
import 'package:krow_domain/krow_domain.dart';
>>>>>>> Stashed changes
import '../blocs/payments/payments_bloc.dart';
import '../blocs/payments/payments_event.dart';
import '../blocs/payments/payments_state.dart';
@@ -177,11 +181,16 @@ class _PaymentsPageState extends State<PaymentsPage> {
),
const SizedBox(height: 12),
Column(
<<<<<<< Updated upstream
children: state.history.map((PaymentTransaction payment) {
=======
children: state.history.map((StaffPayment payment) {
>>>>>>> Stashed changes
return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: PaymentHistoryItem(
amount: payment.amount,
<<<<<<< Updated upstream
title: payment.title,
location: payment.location,
address: payment.address,
@@ -190,6 +199,16 @@ class _PaymentsPageState extends State<PaymentsPage> {
hours: payment.hours,
rate: payment.rate,
status: payment.status,
=======
title: 'Assignment ${payment.assignmentId}',
location: 'Location', // TODO: Fetch from assignment
address: '',
date: payment.paidAt != null ? DateFormat('E, MMM d').format(payment.paidAt!) : 'Pending',
workedTime: '00:00 - 00:00', // TODO: Fetch from assignment
hours: 0,
rate: 0,
status: payment.status.toString().split('.').last,
>>>>>>> Stashed changes
),
);
}).toList(),

View File

@@ -2,9 +2,16 @@ name: staff_payments
description: Staff Payments feature
version: 0.0.1
publish_to: 'none'
<<<<<<< Updated upstream
environment:
sdk: '>=3.0.0 <4.0.0'
=======
resolution: workspace
environment:
sdk: '>=3.10.0 <4.0.0'
>>>>>>> Stashed changes
flutter: ">=3.0.0"
dependencies:
@@ -21,6 +28,11 @@ dependencies:
path: ../../../core_localization
krow_domain:
path: ../../../domain
<<<<<<< Updated upstream
=======
krow_core:
path: ../../../core
>>>>>>> Stashed changes
dev_dependencies:
flutter_test: