Skip to content

Commit

Permalink
Merge pull request #90 from pvdthings/fix-members-state-bug
Browse files Browse the repository at this point in the history
Fix members state bug / Clean up providers tech debt / Enhance loading state UX
  • Loading branch information
dillonfagan authored Nov 13, 2024
2 parents 39d8681 + e439920 commit 129fb58
Show file tree
Hide file tree
Showing 34 changed files with 647 additions and 414 deletions.
2 changes: 1 addition & 1 deletion apps/librarian/lib/core/api/models/borrower_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class BorrowerModel {

bool get active => issues.isEmpty;

BorrowerModel({
const BorrowerModel({
required this.id,
required this.name,
required this.issues,
Expand Down
16 changes: 1 addition & 15 deletions apps/librarian/lib/core/data/borrowers_repository.dart
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
import 'package:collection/collection.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:librarian_app/core/api/api.dart' as api;
import 'package:librarian_app/core/api/models/payment_model.dart';

import '../api/models/borrower_model.dart';

class BorrowersRepository extends Notifier<Future<List<BorrowerModel>>> {
@override
Future<List<BorrowerModel>> build() async => await getBorrowers();

class BorrowersRepository {
Future<List<BorrowerModel>> getBorrowers() async {
final response = await api.fetchBorrowers();
return (response.data as List)
.map((json) => BorrowerModel.fromJson(json))
.toList();
}

Future<BorrowerModel?> getBorrower(String id) async {
final borrowers = await state;
return borrowers.firstWhereOrNull((b) => b.id == id);
}

Future<BorrowerModel?> getBorrowerDetails(String id) async {
final response = await api.fetchBorrower(id);
return BorrowerModel.fromJson(response.data as Map<String, dynamic>);
Expand All @@ -29,8 +19,6 @@ class BorrowersRepository extends Notifier<Future<List<BorrowerModel>>> {
Future<bool> updateBorrower(String id, {String? email, String? phone}) async {
try {
await api.updateBorrower(id, email: email, phone: phone);

ref.invalidateSelf();
return true;
} catch (error) {
return false;
Expand All @@ -56,8 +44,6 @@ class BorrowersRepository extends Notifier<Future<List<BorrowerModel>>> {
} catch (error) {
return false;
}

ref.invalidateSelf();
return true;
}
}
11 changes: 1 addition & 10 deletions apps/librarian/lib/core/data/loans_repository.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
import 'package:librarian_app/core/api/api.dart' as API;

import '../api/models/loan_details_model.dart';
import '../api/models/loan_model.dart';

class LoansRepository extends Notifier<Future<List<LoanModel>>> {
@override
Future<List<LoanModel>> build() async => await getLoans();

class LoansRepository {
Future<LoanDetailsModel?> getLoan({
required String id,
required String thingId,
Expand Down Expand Up @@ -40,7 +36,6 @@ class LoansRepository extends Notifier<Future<List<LoanModel>>> {
dueBackDate: dateFormat.format(dueBackDate),
));

ref.invalidateSelf();
return (response.data as Map<String, dynamic>)['id'] as String;
} catch (error) {
return null;
Expand All @@ -58,8 +53,6 @@ class LoansRepository extends Notifier<Future<List<LoanModel>>> {
thingId: thingId,
checkedInDate: dateFormat.format(DateTime.now()),
));

ref.invalidateSelf();
}

Future<void> updateLoan({
Expand All @@ -76,7 +69,5 @@ class LoansRepository extends Notifier<Future<List<LoanModel>>> {
dueBackDate: dateFormat.format(dueBackDate),
notes: notes,
));

ref.invalidateSelf();
}
}
3 changes: 3 additions & 0 deletions apps/librarian/lib/dashboard/pages/dashboard_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:librarian_app/dashboard/providers/create_loan_controller.dart';
import 'package:librarian_app/dashboard/providers/invalidate_module.dart';
import 'package:librarian_app/dashboard/providers/workspace.dart';
import 'package:librarian_app/modules/authentication/providers/auth_service_provider.dart';
import 'package:librarian_app/modules/authentication/providers/user_tray.dart';
Expand Down Expand Up @@ -200,6 +201,7 @@ class _DashboardPageState extends ConsumerState<DashboardPage> {
selectedIndex: _moduleIndex,
onDestinationSelected: (index) {
setState(() => _moduleIndex = index);
invalidateModule(ref, index);
},
leading: menuAnchor,
child: module.desktopLayout,
Expand All @@ -209,6 +211,7 @@ class _DashboardPageState extends ConsumerState<DashboardPage> {
selectedIndex: _moduleIndex,
onDestinationSelected: (index) {
setState(() => _moduleIndex = index);
invalidateModule(ref, index);
},
destinations: const [
NavigationDestination(
Expand Down
26 changes: 26 additions & 0 deletions apps/librarian/lib/dashboard/providers/invalidate_module.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:librarian_app/modules/things/providers/things_repository_provider.dart';
import 'package:librarian_app/providers/loans.dart';
import 'package:librarian_app/providers/members.dart';

void invalidateModule(WidgetRef ref, int index) {
switch (index) {
case loansIndex:
ref.invalidate(loansProvider);
return;
case membersIndex:
ref.invalidate(membersProvider);
case thingsIndex:
case repairIndex:
ref.invalidate(thingsRepositoryProvider);
return;
case actionsIndex:
return;
}
}

const loansIndex = 0;
const membersIndex = 1;
const thingsIndex = 2;
const repairIndex = 3;
const actionsIndex = 4;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:librarian_app/core/api/api.dart';
import 'package:librarian_app/modules/loans/providers/loans_repository_provider.dart';
import 'package:librarian_app/providers/loans.dart';
import 'package:librarian_app/utils/format.dart';

class ActionsService {
Expand All @@ -26,7 +26,7 @@ class ActionsService {

if (result) {
Future.delayed(const Duration(seconds: 2), () {
ref.invalidate(loansRepositoryProvider);
ref.invalidate(loansProvider);
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:librarian_app/core/api/models/borrower_model.dart';
import 'package:librarian_app/modules/members/details/issues.dart';
import 'package:librarian_app/modules/members/providers/borrowers_repository_provider.dart';
import 'package:librarian_app/modules/loans/checkout/stepper/borrower/borrower_search_delegate.dart';
import 'package:librarian_app/providers/members.dart';

Step buildBorrowerStep({
required BuildContext context,
Expand Down Expand Up @@ -35,10 +36,9 @@ Step buildBorrowerStep({
);

if (success) {
ref
.read(borrowersRepositoryProvider.notifier)
.getBorrower(borrower.id)
.then(onBorrowerSelected);
ref.read(membersProvider).then((list) {
return list.firstWhereOrNull((b) => b.id == borrower.id);
}).then(onBorrowerSelected);
}
},
),
Expand Down Expand Up @@ -80,8 +80,8 @@ class _SelectBorrowerTextFieldState
onTap: () {
setState(() => _isLoading = true);

ref.invalidate(borrowersRepositoryProvider);
ref.read(borrowersRepositoryProvider).then((borrowers) async {
ref.invalidate(membersProvider);
ref.read(membersProvider).then((borrowers) async {
return await showSearch(
context: context,
delegate: BorrowerSearchDelegate(borrowers),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:librarian_app/core/api/models/borrower_model.dart';
import 'package:librarian_app/widgets/detail.dart';
Expand All @@ -17,11 +18,13 @@ class CheckoutDetails extends StatelessWidget {
final DateTime dueDate;
final void Function(DateTime newDate) onDueDateUpdated;

DateTime get _twoWeeksAgo => DateTime.now().add(const Duration(days: -14));

void showDateSelection(BuildContext context) async {
showDatePicker(
context: context,
initialDate: dueDate,
firstDate: dueDate,
firstDate: kDebugMode ? _twoWeeksAgo : dueDate,
lastDate: dueDate.add(const Duration(days: 14)),
).then((value) {
if (value == null) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:librarian_app/core/api/api.dart' as api;
import 'package:librarian_app/modules/loans/details/thing_number.dart';
import 'package:librarian_app/modules/loans/providers/loans_repository_provider.dart';
import 'package:librarian_app/providers/loans.dart';
import 'package:librarian_app/widgets/dialogs/general_dialog.dart';

import 'previous_loan_details.dart';
Expand Down Expand Up @@ -44,7 +44,7 @@ class LoanDetailsController {

Future<void> sendReminderEmail({required int loanNumber}) async {
api.sendReminderEmail(loanNumber: loanNumber).then((value) {
ref.invalidate(loansRepositoryProvider);
ref.invalidate(loansProvider);

ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(content: Text('Email was sent')));
Expand Down
56 changes: 30 additions & 26 deletions apps/librarian/lib/modules/loans/details/loan_details_header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ import 'thing_number.dart';
class LoanDetailsHeader extends ConsumerWidget {
const LoanDetailsHeader({
super.key,
required this.loading,
required this.loan,
required this.onSave,
required this.onCheckIn,
});

final bool loading;
final LoanDetailsModel loan;
final void Function(DateTime dueDate, String? notes) onSave;
final void Function() onCheckIn;
final void Function(DateTime dueDate, String? notes)? onSave;
final void Function()? onCheckIn;

@override
Widget build(BuildContext context, WidgetRef ref) {
Expand All @@ -30,14 +32,16 @@ class LoanDetailsHeader extends ConsumerWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
ThingNumber(number: loan.thing.number),
const SizedBox(width: 16),
Text(
loan.thing.name,
style: const TextStyle(fontSize: 24),
),
],
children: loading
? []
: [
ThingNumber(number: loan.thing.number),
const SizedBox(width: 16),
Text(
loan.thing.name,
style: const TextStyle(fontSize: 24),
),
],
),
Row(
children: [
Expand All @@ -49,9 +53,7 @@ class LoanDetailsHeader extends ConsumerWidget {
return EditLoanDialog(
dueDate: loan.dueDate,
notes: loan.notes,
onSavePressed: (newDueDate, notes) {
onSave(newDueDate, notes);
},
onSavePressed: onSave,
);
},
);
Expand Down Expand Up @@ -103,19 +105,21 @@ class LoanDetailsHeader extends ConsumerWidget {
),
const SizedBox(width: 4),
IconButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return CheckinDialog(
thingNumber: loan.thing.number,
onCheckin: () async {
await Future(onCheckIn);
},
);
},
);
},
onPressed: onCheckIn != null
? () {
showDialog(
context: context,
builder: (context) {
return CheckinDialog(
thingNumber: loan.thing.number,
onCheckin: () async {
await Future(onCheckIn!);
},
);
},
);
}
: null,
tooltip: 'Check in',
icon: const Icon(Icons.library_add_check),
),
Expand Down
Loading

0 comments on commit 129fb58

Please sign in to comment.