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/core.dart';
|
||||||
import 'package:okane/ui/state/settings.dart';
|
import 'package:okane/ui/state/settings.dart';
|
||||||
|
|
||||||
|
import 'ui/pages/loans/loan_details.dart';
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
LocaleSettings.useDeviceLocale();
|
LocaleSettings.useDeviceLocale();
|
||||||
@ -66,6 +68,7 @@ class MyApp extends StatelessWidget {
|
|||||||
"/transactions/details" =>
|
"/transactions/details" =>
|
||||||
TransactionDetailsPage.mobileRoute,
|
TransactionDetailsPage.mobileRoute,
|
||||||
"/budgets/details" => BudgetDetailsPage.mobileRoute,
|
"/budgets/details" => BudgetDetailsPage.mobileRoute,
|
||||||
|
"/loans/details" => LoanDetailsPage.mobileRoute,
|
||||||
_ => MaterialPageRoute<void>(
|
_ => MaterialPageRoute<void>(
|
||||||
builder: (_) => Text("Unknown!!"),
|
builder: (_) => Text("Unknown!!"),
|
||||||
),
|
),
|
||||||
|
@ -112,7 +112,7 @@ final _pages = <OkanePageItem>[
|
|||||||
Icons.money_outlined,
|
Icons.money_outlined,
|
||||||
"Loans",
|
"Loans",
|
||||||
LoanListPage(),
|
LoanListPage(),
|
||||||
(_) => LoanDetailsPage(),
|
(_) => LoanDetailsPage(isPage: false),
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
OkanePageItem(
|
OkanePageItem(
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.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/database/database.dart';
|
||||||
import 'package:okane/ui/pages/loans/add_loan_change.dart';
|
import 'package:okane/ui/pages/loans/add_loan_change.dart';
|
||||||
import 'package:okane/ui/state/core.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';
|
import 'package:okane/ui/widgets/image_wrapper.dart';
|
||||||
|
|
||||||
class LoanDetailsPage extends StatelessWidget {
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Stack(
|
return Scaffold(
|
||||||
children: [
|
body: Column(
|
||||||
BlocBuilder<CoreCubit, CoreState>(
|
children: [
|
||||||
builder: (context, state) {
|
if (isPage)
|
||||||
if (state.activeLoan == null) {
|
SizedBox(
|
||||||
return Text("No loan selected");
|
height: 50,
|
||||||
}
|
child: Row(
|
||||||
|
children: [
|
||||||
final loans = state.activeLoan!.changes.toList();
|
IconButton(
|
||||||
final loanSum = loans
|
icon: Icon(Icons.arrow_back),
|
||||||
.map((c) => c.amount)
|
onPressed: () {
|
||||||
.reduce((acc, val) => acc + val);
|
Navigator.of(context).pop();
|
||||||
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),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: BlocBuilder<CoreCubit, CoreState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state.activeLoan == null) {
|
||||||
|
return Text("No loan selected");
|
||||||
|
}
|
||||||
|
|
||||||
SliverToBoxAdapter(
|
final loanChanges = state.activeLoan!.changes.toList();
|
||||||
child: Text("Total: ${formatCurrency(loanSum)}"),
|
final loanSum =
|
||||||
),
|
loanChanges.isNotEmpty
|
||||||
|
? loanChanges
|
||||||
SliverToBoxAdapter(
|
.map((c) => c.amount)
|
||||||
child: Row(
|
.reduce((acc, val) => acc + val)
|
||||||
children: [
|
: 0.0;
|
||||||
Text("Loan Transactions"),
|
return CustomScrollView(
|
||||||
|
slivers: [
|
||||||
IconButton(
|
SliverToBoxAdapter(
|
||||||
onPressed: () {
|
child: Row(
|
||||||
showDialogOrModal(
|
children: [
|
||||||
context: context,
|
ImageWrapper(
|
||||||
builder:
|
title: state.activeLoan!.beneficiary.value!.name,
|
||||||
(_) => AddLoanChangePopup(
|
path:
|
||||||
loan: state.activeLoan!,
|
state.activeLoan!.beneficiary.value!.imagePath,
|
||||||
onDone: () {
|
),
|
||||||
Navigator.of(context).pop();
|
Text(state.activeLoan!.beneficiary.value!.name),
|
||||||
},
|
],
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
icon: Icon(Icons.add),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
SliverList.builder(
|
SliverToBoxAdapter(
|
||||||
itemCount: loans.length,
|
child: Text("Total: ${formatCurrency(loanSum)}"),
|
||||||
itemBuilder: (context, index) {
|
),
|
||||||
final item = loans[index];
|
|
||||||
|
|
||||||
return ListTile(
|
SliverToBoxAdapter(
|
||||||
leading:
|
child: Row(
|
||||||
item.amount > 0
|
children: [
|
||||||
? Icon(Icons.add, color: Colors.green)
|
Text("Loan Transactions"),
|
||||||
: Icon(Icons.remove, color: Colors.red),
|
|
||||||
title: Text(formatCurrency(item.amount)),
|
IconButton(
|
||||||
trailing: IconButton(
|
onPressed: () {
|
||||||
icon: Icon(Icons.delete, color: Colors.red),
|
showDialogOrModal(
|
||||||
onPressed: () async {
|
context: context,
|
||||||
state.activeLoan!.changes.remove(item);
|
builder:
|
||||||
await deleteLoanChange(item);
|
(_) => AddLoanChangePopup(
|
||||||
await upsertLoan(state.activeLoan!);
|
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:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
import 'package:okane/database/database.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/pages/loans/add_loan.dart';
|
||||||
import 'package:okane/ui/state/core.dart';
|
import 'package:okane/ui/state/core.dart';
|
||||||
import 'package:okane/ui/utils.dart';
|
import 'package:okane/ui/utils.dart';
|
||||||
@ -28,6 +29,10 @@ class LoanListPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
GetIt.I.get<CoreCubit>().setActiveLoan(item);
|
GetIt.I.get<CoreCubit>().setActiveLoan(item);
|
||||||
|
|
||||||
|
if (getScreenSize(context) == ScreenSize.small) {
|
||||||
|
Navigator.of(context).pushNamed("/loans/details");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
trailing: IconButton(
|
trailing: IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
|
Loading…
Reference in New Issue
Block a user