Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
L
library-app-flutter
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ilham Maulana
library-app-flutter
Commits
4c625184
Commit
4c625184
authored
Jul 31, 2024
by
Ilham Maulana
💻
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: filter member loan widgets
parent
8424e274
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
129 additions
and
86 deletions
+129
-86
loan.dart
lib/src/models/loan.dart
+11
-0
auth_provider.dart
lib/src/providers/auth_provider.dart
+25
-2
loan_list.dart
lib/src/widgets/loans/loan_list.dart
+93
-84
No files found.
lib/src/models/loan.dart
View file @
4c625184
...
...
@@ -14,4 +14,15 @@ class Loan {
this
.
remainingDays
,
this
.
isOverdue
,
);
factory
Loan
.
fromJson
(
Map
<
String
,
dynamic
>
data
)
{
final
book
=
Book
.
fromJson
(
data
[
"book_detail"
]);
return
Loan
(
book
,
data
[
"loan_date"
],
data
[
"due_date"
],
data
[
"remaining_loan_time"
],
data
[
"is_overdue"
],
);
}
}
lib/src/providers/auth_provider.dart
View file @
4c625184
...
...
@@ -5,6 +5,7 @@ import 'package:http/http.dart' as http;
import
'package:library_app/src/models/token.dart'
;
import
'package:library_app/src/models/user.dart'
;
// Flutter: make memberLoans adjustable to be filtered to near outstanding loan and overdued loan
class
AuthProvider
with
ChangeNotifier
{
String
baseUrl
=
'http://localhost:8000/api/v1'
;
...
...
@@ -14,6 +15,9 @@ class AuthProvider with ChangeNotifier {
bool
invalidUsernameOrPassword
=
false
;
List
<
dynamic
>?
memberLoans
;
bool
filterByUpcoming
=
false
;
bool
filterByOverdued
=
false
;
Future
<
void
>
signIn
(
String
username
,
String
password
)
async
{
try
{
final
response
=
await
http
.
post
(
...
...
@@ -157,10 +161,19 @@ class AuthProvider with ChangeNotifier {
}
}
Future
<
void
>
getMemberLoan
(
int
id
)
async
{
Future
<
void
>
getMemberLoan
()
async
{
String
url
=
'
$baseUrl
/members/
${user?.accountId}
/loans/'
;
if
(
filterByUpcoming
)
{
url
+=
'?near_outstanding=True'
;
}
else
if
(
filterByOverdued
)
{
url
+=
'?overdue=True'
;
}
else
{
null
;
}
try
{
final
response
=
await
http
.
get
(
Uri
.
parse
(
'
$baseUrl
/members/
$id
/loans/'
),
Uri
.
parse
(
url
),
headers:
{
'Content-Type'
:
'application/json'
,
'Authorization'
:
'Bearer
${token?.key}
'
...
...
@@ -181,6 +194,16 @@ class AuthProvider with ChangeNotifier {
}
}
void
setFilterUpcoming
()
{
filterByUpcoming
=
!
filterByUpcoming
;
notifyListeners
();
}
void
setFilterOverdued
()
{
filterByOverdued
=
!
filterByOverdued
;
notifyListeners
();
}
Future
<
void
>
createMemberLoan
(
int
memberId
,
int
bookId
,
int
loanDay
)
async
{
final
now
=
DateTime
.
now
();
final
dueDate
=
now
.
add
(
Duration
(
days:
loanDay
));
...
...
lib/src/widgets/loans/loan_list.dart
View file @
4c625184
...
...
@@ -18,18 +18,16 @@ class _LoanList extends State<LoanList> {
@override
void
initState
()
{
super
.
initState
();
Provider
.
of
<
AuthProvider
>(
context
,
listen:
false
)
.
getMemberLoan
(
widget
.
memberId
);
Provider
.
of
<
AuthProvider
>(
context
,
listen:
false
).
getMemberLoan
();
}
@override
Widget
build
(
BuildContext
context
)
{
return
Consumer
<
AuthProvider
>(
builder:
(
context
,
authProvider
,
child
)
{
if
(
authProvider
.
memberLoans
!=
null
)
{
final
Iterable
<
Loan
>
loans
=
authProvider
.
memberLoans
!.
map
(
var
loans
=
authProvider
.
memberLoans
!.
map
(
(
loan
)
{
Map
<
String
,
dynamic
>
bookMap
=
loan
[
"book_detail"
];
final
book
=
Book
.
fromJson
(
bookMap
);
var
book
=
Book
.
fromJson
(
loan
[
"book_detail"
]);
return
Loan
(
book
,
loan
[
"loan_date"
],
...
...
@@ -39,6 +37,7 @@ class _LoanList extends State<LoanList> {
);
},
);
return
NestedScrollView
(
headerSliverBuilder:
(
BuildContext
context
,
bool
innerBoxIsScrolled
)
{
return
[
const
TopAppBar
(
title:
"Book Loans"
)];
...
...
@@ -78,97 +77,107 @@ class _TopAppBar extends State<TopAppBar> {
@override
Widget
build
(
BuildContext
context
)
{
final
screenSize
=
MediaQuery
.
of
(
context
).
size
;
return
SliverAppBar
(
title:
Text
(
showWidget
?
""
:
title
),
actions:
[
Row
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
[
IconButton
(
onPressed:
()
{
setState
(()
{
showWidget
=
!
showWidget
;
});
},
icon:
Icon
(
showWidget
?
Icons
.
close
:
Icons
.
filter_alt_outlined
),
),
Offstage
(
offstage:
!
showWidget
,
child:
Row
(
children:
[
FilledButton
(
style:
TextButton
.
styleFrom
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
screenSize
.
width
*
0.04
,
vertical:
screenSize
.
width
*
0.02
),
return
Consumer
<
AuthProvider
>(
builder:
(
context
,
authBuilder
,
child
)
{
return
SliverAppBar
(
title:
Text
(
showWidget
?
""
:
title
),
actions:
[
Row
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
[
IconButton
(
onPressed:
()
{
setState
(()
{
showWidget
=
!
showWidget
;
});
},
icon:
Icon
(
showWidget
?
Icons
.
close
:
Icons
.
filter_alt_outlined
,
),
),
Offstage
(
offstage:
!
showWidget
,
child:
const
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
Row
(
children:
[
Text
(
"Upcoming"
),
SwitchToUpcoming
()],
),
onPressed:
()
{},
child:
const
Text
(
'Near Outstanding'
),
),
const
SizedBox
(
width:
8.0
,
),
FilledButton
(
style:
TextButton
.
styleFrom
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
screenSize
.
width
*
0.04
,
vertical:
screenSize
.
width
*
0.02
),
SizedBox
(
width:
20.0
,
),
onPressed:
()
{},
child:
const
Text
(
'Overdued'
,
Row
(
children:
[
Text
(
"Overdue"
),
SwitchToOverdued
()],
),
)
,
]
,
)
,
)
,
]
,
)
,
]
,
elevation:
10.0
,
automaticallyImplyLeading:
false
,
expandedHeight:
50
,
floating
:
true
,
snap:
true
,
);
]
,
)
,
)
]
,
)
,
]
,
elevation:
10.0
,
automaticallyImplyLeading:
false
,
expandedHeight:
50
,
floating:
true
,
snap
:
true
,
);
}
);
}
}
class
LoanTypeFilter
extends
StatelessWidget
implements
PreferredSizeWidget
{
final
double
sizeAppBar
=
50.0
;
class
SwitchToUpcoming
extends
StatefulWidget
{
const
SwitchToUpcoming
({
super
.
key
});
@override
State
<
SwitchToUpcoming
>
createState
()
=>
_SwitchToUpcoming
();
}
class
_SwitchToUpcoming
extends
State
<
SwitchToUpcoming
>
{
@override
Widget
build
(
BuildContext
context
)
{
return
Consumer
<
AuthProvider
>(
builder:
(
context
,
authProvider
,
child
)
{
return
Switch
(
value:
authProvider
.
filterByUpcoming
,
onChanged:
(
bool
value
)
{
setState
(()
{
authProvider
.
setFilterUpcoming
();
if
(
authProvider
.
filterByUpcoming
&&
authProvider
.
filterByOverdued
)
{
authProvider
.
setFilterOverdued
();
}
authProvider
.
getMemberLoan
();
});
},
);
});
}
}
const
LoanTypeFilter
({
super
.
key
});
class
SwitchToOverdued
extends
StatefulWidget
{
const
SwitchToOverdued
({
super
.
key
});
@override
Size
get
preferredSize
=>
Size
.
fromHeight
(
sizeAppBar
);
State
<
SwitchToOverdued
>
createState
()
=>
_SwitchToOverdued
();
}
class
_SwitchToOverdued
extends
State
<
SwitchToOverdued
>
{
@override
Widget
build
(
BuildContext
context
)
{
return
Column
(
children:
[
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
20.0
,
vertical:
10.0
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
const
SizedBox
(
width:
10.0
),
SizedBox
(
height:
30.0
,
child:
OutlinedButton
(
onPressed:
()
{},
child:
const
Text
(
"Near Overdue"
)),
),
const
SizedBox
(
width:
10.0
),
SizedBox
(
height:
30.0
,
child:
OutlinedButton
(
onPressed:
()
{},
child:
const
Text
(
"Overdue"
)),
),
],
),
),
],
return
Consumer
<
AuthProvider
>(
builder:
(
context
,
authProvider
,
child
)
{
return
Switch
(
value:
authProvider
.
filterByOverdued
,
onChanged:
(
bool
value
)
{
setState
(()
{
authProvider
.
setFilterOverdued
();
if
(
authProvider
.
filterByUpcoming
&&
authProvider
.
filterByOverdued
)
{
authProvider
.
setFilterUpcoming
();
}
authProvider
.
getMemberLoan
();
});
},
);
},
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment