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:
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
];
|
||||
}
|
||||
@@ -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(),
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user