refactor of usecases

This commit is contained in:
2026-02-23 17:18:50 +05:30
parent 56666ece30
commit 13f8003bda
37 changed files with 1563 additions and 105 deletions

View File

@@ -11,6 +11,7 @@ import 'domain/usecases/get_savings_amount.dart';
import 'domain/usecases/get_spending_breakdown.dart';
import 'presentation/blocs/billing_bloc.dart';
import 'presentation/pages/billing_page.dart';
import 'presentation/pages/timesheets_page.dart';
/// Modular module for the billing feature.
class BillingModule extends Module {
@@ -45,5 +46,6 @@ class BillingModule extends Module {
@override
void routes(RouteManager r) {
r.child(ClientPaths.childRoute(ClientPaths.billing, ClientPaths.billing), child: (_) => const BillingPage());
r.child('/timesheets', child: (_) => const ClientTimesheetsPage());
}
}

View File

@@ -227,6 +227,13 @@ class _BillingViewState extends State<BillingView> {
crossAxisAlignment: CrossAxisAlignment.start,
spacing: UiConstants.space4,
children: <Widget>[
UiButton.primary(
text: 'View Pending Timesheets',
leadingIcon: UiIcons.clock,
onPressed: () => Modular.to.pushNamed('${ClientPaths.billing}/timesheets'),
fullWidth: true,
),
const SizedBox(height: UiConstants.space2),
if (state.pendingInvoices.isNotEmpty) ...<Widget>[
PendingInvoicesSection(invoices: state.pendingInvoices),
],

View File

@@ -0,0 +1,85 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:core_localization/core_localization.dart';
class ClientTimesheetsPage extends StatelessWidget {
const ClientTimesheetsPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(context.t.client_billing.timesheets.title),
elevation: 0,
backgroundColor: UiColors.white,
foregroundColor: UiColors.primary,
),
body: ListView.separated(
padding: const EdgeInsets.all(UiConstants.space5),
itemCount: 3,
separatorBuilder: (context, index) => const SizedBox(height: 16),
itemBuilder: (context, index) {
final workers = ['Sarah Miller', 'David Chen', 'Mike Ross'];
final roles = ['Cashier', 'Stocker', 'Event Support'];
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: UiColors.white,
borderRadius: UiConstants.radiusLg,
border: Border.all(color: UiColors.separatorPrimary),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(workers[index], style: UiTypography.body2b.textPrimary),
Text('\$84.00', style: UiTypography.body2b.primary),
],
),
Text(roles[index], style: UiTypography.footnote2r.textSecondary),
const SizedBox(height: 12),
Row(
children: [
const Icon(UiIcons.clock, size: 14, color: UiColors.iconSecondary),
const SizedBox(width: 6),
Text('09:00 AM - 05:00 PM (8h)', style: UiTypography.footnote2r.textSecondary),
],
),
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: UiButton.secondary(
text: context.t.client_billing.timesheets.decline_button,
style: OutlinedButton.styleFrom(
foregroundColor: UiColors.destructive,
side: const BorderSide(color: UiColors.destructive),
),
onPressed: () {},
),
),
const SizedBox(width: 12),
Expanded(
child: UiButton.primary(
text: context.t.client_billing.timesheets.approve_button,
onPressed: () {
UiSnackbar.show(
context,
message: context.t.client_billing.timesheets.approved_message,
type: UiSnackbarType.success,
);
},
),
),
],
),
],
),
);
},
),
);
}
}

View File

@@ -99,7 +99,7 @@ class _SpendingBreakdownCardState extends State<SpendingBreakdownCard>
onTap: (int index) {
final BillingPeriod period =
index == 0 ? BillingPeriod.week : BillingPeriod.month;
context.read<BillingBloc>().add(
ReadContext(context).read<BillingBloc>().add(
BillingPeriodChanged(period),
);
},