Make the loan details work on mobile
This commit is contained in:
parent
c5aa165424
commit
88c9991e0d
@ -14,6 +14,8 @@ import 'package:okane/ui/pages/transaction_details.dart';
|
||||
import 'package:okane/ui/state/core.dart';
|
||||
import 'package:okane/ui/state/settings.dart';
|
||||
|
||||
import 'ui/pages/loans/loan_details.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
LocaleSettings.useDeviceLocale();
|
||||
@ -66,6 +68,7 @@ class MyApp extends StatelessWidget {
|
||||
"/transactions/details" =>
|
||||
TransactionDetailsPage.mobileRoute,
|
||||
"/budgets/details" => BudgetDetailsPage.mobileRoute,
|
||||
"/loans/details" => LoanDetailsPage.mobileRoute,
|
||||
_ => MaterialPageRoute<void>(
|
||||
builder: (_) => Text("Unknown!!"),
|
||||
),
|
||||
|
@ -112,7 +112,7 @@ final _pages = <OkanePageItem>[
|
||||
Icons.money_outlined,
|
||||
"Loans",
|
||||
LoanListPage(),
|
||||
(_) => LoanDetailsPage(),
|
||||
(_) => LoanDetailsPage(isPage: false),
|
||||
false,
|
||||
),
|
||||
OkanePageItem(
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:grouped_list/grouped_list.dart';
|
||||
import 'package:okane/database/collections/loan.dart';
|
||||
import 'package:okane/database/database.dart';
|
||||
import 'package:okane/ui/pages/loans/add_loan_change.dart';
|
||||
import 'package:okane/ui/state/core.dart';
|
||||
@ -7,91 +9,160 @@ import 'package:okane/ui/utils.dart';
|
||||
import 'package:okane/ui/widgets/image_wrapper.dart';
|
||||
|
||||
class LoanDetailsPage extends StatelessWidget {
|
||||
const LoanDetailsPage({super.key});
|
||||
final bool isPage;
|
||||
|
||||
const LoanDetailsPage({super.key, required this.isPage});
|
||||
|
||||
static MaterialPageRoute<void> get mobileRoute =>
|
||||
MaterialPageRoute(builder: (_) => LoanDetailsPage(isPage: true));
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
BlocBuilder<CoreCubit, CoreState>(
|
||||
builder: (context, state) {
|
||||
if (state.activeLoan == null) {
|
||||
return Text("No loan selected");
|
||||
}
|
||||
|
||||
final loans = state.activeLoan!.changes.toList();
|
||||
final loanSum = loans
|
||||
.map((c) => c.amount)
|
||||
.reduce((acc, val) => acc + val);
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
SliverToBoxAdapter(
|
||||
child: Row(
|
||||
children: [
|
||||
ImageWrapper(
|
||||
title: state.activeLoan!.beneficiary.value!.name,
|
||||
path: state.activeLoan!.beneficiary.value!.imagePath,
|
||||
),
|
||||
Text(state.activeLoan!.beneficiary.value!.name),
|
||||
],
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
if (isPage)
|
||||
SizedBox(
|
||||
height: 50,
|
||||
child: Row(
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.arrow_back),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: BlocBuilder<CoreCubit, CoreState>(
|
||||
builder: (context, state) {
|
||||
if (state.activeLoan == null) {
|
||||
return Text("No loan selected");
|
||||
}
|
||||
|
||||
SliverToBoxAdapter(
|
||||
child: Text("Total: ${formatCurrency(loanSum)}"),
|
||||
),
|
||||
|
||||
SliverToBoxAdapter(
|
||||
child: Row(
|
||||
children: [
|
||||
Text("Loan Transactions"),
|
||||
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
showDialogOrModal(
|
||||
context: context,
|
||||
builder:
|
||||
(_) => AddLoanChangePopup(
|
||||
loan: state.activeLoan!,
|
||||
onDone: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
icon: Icon(Icons.add),
|
||||
final loanChanges = state.activeLoan!.changes.toList();
|
||||
final loanSum =
|
||||
loanChanges.isNotEmpty
|
||||
? loanChanges
|
||||
.map((c) => c.amount)
|
||||
.reduce((acc, val) => acc + val)
|
||||
: 0.0;
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
SliverToBoxAdapter(
|
||||
child: Row(
|
||||
children: [
|
||||
ImageWrapper(
|
||||
title: state.activeLoan!.beneficiary.value!.name,
|
||||
path:
|
||||
state.activeLoan!.beneficiary.value!.imagePath,
|
||||
),
|
||||
Text(state.activeLoan!.beneficiary.value!.name),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
SliverList.builder(
|
||||
itemCount: loans.length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = loans[index];
|
||||
SliverToBoxAdapter(
|
||||
child: Text("Total: ${formatCurrency(loanSum)}"),
|
||||
),
|
||||
|
||||
return ListTile(
|
||||
leading:
|
||||
item.amount > 0
|
||||
? Icon(Icons.add, color: Colors.green)
|
||||
: Icon(Icons.remove, color: Colors.red),
|
||||
title: Text(formatCurrency(item.amount)),
|
||||
trailing: IconButton(
|
||||
icon: Icon(Icons.delete, color: Colors.red),
|
||||
onPressed: () async {
|
||||
state.activeLoan!.changes.remove(item);
|
||||
await deleteLoanChange(item);
|
||||
await upsertLoan(state.activeLoan!);
|
||||
},
|
||||
SliverToBoxAdapter(
|
||||
child: Row(
|
||||
children: [
|
||||
Text("Loan Transactions"),
|
||||
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
showDialogOrModal(
|
||||
context: context,
|
||||
builder:
|
||||
(_) => AddLoanChangePopup(
|
||||
loan: state.activeLoan!,
|
||||
onDone: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
icon: Icon(Icons.add),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
SliverToBoxAdapter(
|
||||
child:
|
||||
loanChanges.isNotEmpty
|
||||
? GroupedListView(
|
||||
elements: loanChanges,
|
||||
shrinkWrap: true,
|
||||
reverse: true,
|
||||
groupBy:
|
||||
(LoanChange loanChange) =>
|
||||
formatDateTime(loanChange.date),
|
||||
groupHeaderBuilder:
|
||||
(item) => Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withAlpha(170),
|
||||
borderRadius: BorderRadius.circular(
|
||||
8,
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(4),
|
||||
child: Text(
|
||||
formatDateTime(item.date),
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
indexedItemBuilder:
|
||||
(ctx, item, idx) => ListTile(
|
||||
leading:
|
||||
item.amount > 0
|
||||
? Icon(
|
||||
Icons.add,
|
||||
color: Colors.green,
|
||||
)
|
||||
: Icon(
|
||||
Icons.remove,
|
||||
color: Colors.red,
|
||||
),
|
||||
title: Text(formatCurrency(item.amount)),
|
||||
trailing: IconButton(
|
||||
icon: Icon(
|
||||
Icons.delete,
|
||||
color: Colors.red,
|
||||
),
|
||||
onPressed: () async {
|
||||
state.activeLoan!.changes.remove(
|
||||
item,
|
||||
);
|
||||
await deleteLoanChange(item);
|
||||
await upsertLoan(state.activeLoan!);
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
: Text("No transactions available"),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:okane/database/database.dart';
|
||||
import 'package:okane/screen.dart';
|
||||
import 'package:okane/ui/pages/loans/add_loan.dart';
|
||||
import 'package:okane/ui/state/core.dart';
|
||||
import 'package:okane/ui/utils.dart';
|
||||
@ -28,6 +29,10 @@ class LoanListPage extends StatelessWidget {
|
||||
),
|
||||
onTap: () {
|
||||
GetIt.I.get<CoreCubit>().setActiveLoan(item);
|
||||
|
||||
if (getScreenSize(context) == ScreenSize.small) {
|
||||
Navigator.of(context).pushNamed("/loans/details");
|
||||
}
|
||||
},
|
||||
trailing: IconButton(
|
||||
onPressed: () async {
|
||||
|
Loading…
Reference in New Issue
Block a user