Commit 54d96eda authored by Ilham Maulana's avatar Ilham Maulana 💻

fix: routing and redirecting using go router

parent b64ad857
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
...@@ -26,13 +27,41 @@ class _LibraryApp extends State<LibraryApp> { ...@@ -26,13 +27,41 @@ class _LibraryApp extends State<LibraryApp> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
const title = 'Library App'; const title = 'Library App';
final router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) =>
Provider.of<AuthProvider>(context).isAuthenticated
? const ListScreen()
: const LoginScreen(),
),
GoRoute(
path: '/sign-up',
builder: (context, state) =>
Provider.of<AuthProvider>(context).isAuthenticated
? const ListScreen()
: const SignUpScreen(),
),
GoRoute(
path: '/reset-password',
builder: (context, state) => const ResetPasswordScreen(),
),
GoRoute(
path: '/confirm-reset-password',
builder: (context, state) => const ConfirmResetPasswordScreen(),
),
],
);
return MultiProvider( return MultiProvider(
providers: [ providers: [
ChangeNotifierProvider(create: (context) => AuthProvider()), ChangeNotifierProvider(create: (context) => AuthProvider()),
ChangeNotifierProvider(create: (context) => NavigationsProvider()), ChangeNotifierProvider(create: (context) => NavigationsProvider()),
ChangeNotifierProvider(create: (context) => BookProvider()), ChangeNotifierProvider(create: (context) => BookProvider()),
], ],
child: MaterialApp( child: MaterialApp.router(
routerConfig: router,
title: title, title: title,
theme: ThemeData( theme: ThemeData(
textTheme: GoogleFonts.poppinsTextTheme(), textTheme: GoogleFonts.poppinsTextTheme(),
...@@ -41,13 +70,6 @@ class _LibraryApp extends State<LibraryApp> { ...@@ -41,13 +70,6 @@ class _LibraryApp extends State<LibraryApp> {
), ),
useMaterial3: true, useMaterial3: true,
), ),
home: Consumer<AuthProvider>(
builder: (context, authProvider, child) {
final isAuthenticated = authProvider.isAuthenticated;
return isAuthenticated ? const ListScreen() : const LoginScreen();
},
),
scrollBehavior: AdaptiveScrollBehavior(), scrollBehavior: AdaptiveScrollBehavior(),
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
), ),
......
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/widgets.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:library_app/src/models/token.dart'; import 'package:library_app/src/models/token.dart';
...@@ -41,7 +43,8 @@ class AuthProvider with ChangeNotifier { ...@@ -41,7 +43,8 @@ class AuthProvider with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
Future<void> signIn(String username, String password) async { Future<void> signIn(
BuildContext context, String username, String password) async {
try { try {
setLoading(true); setLoading(true);
final response = await http.post( final response = await http.post(
...@@ -57,6 +60,7 @@ class AuthProvider with ChangeNotifier { ...@@ -57,6 +60,7 @@ class AuthProvider with ChangeNotifier {
isAuthenticated = true; isAuthenticated = true;
invalidUsernameOrPassword = false; invalidUsernameOrPassword = false;
debugPrint("Login successful $token"); debugPrint("Login successful $token");
} else if (response.statusCode == 401) { } else if (response.statusCode == 401) {
invalidUsernameOrPassword = true; invalidUsernameOrPassword = true;
...@@ -67,10 +71,11 @@ class AuthProvider with ChangeNotifier { ...@@ -67,10 +71,11 @@ class AuthProvider with ChangeNotifier {
debugPrint("Login failed $code"); debugPrint("Login failed $code");
} }
setLoading(true); setLoading(false);
notifyListeners(); notifyListeners();
} catch (error) { } catch (error) {
debugPrint("Login failed $error"); debugPrint("Login failed $error");
setLoading(false);
} }
} }
...@@ -113,7 +118,8 @@ class AuthProvider with ChangeNotifier { ...@@ -113,7 +118,8 @@ class AuthProvider with ChangeNotifier {
} }
} }
Future<void> signUp(String username, String email, String password) async { Future<void> signUp(BuildContext context, String username, String email,
String password) async {
try { try {
setLoading(true); setLoading(true);
final body = { final body = {
...@@ -133,6 +139,9 @@ class AuthProvider with ChangeNotifier { ...@@ -133,6 +139,9 @@ class AuthProvider with ChangeNotifier {
storeAccessToken(token); storeAccessToken(token);
isAuthenticated = true; isAuthenticated = true;
if (context.mounted) {
context.go("/");
}
debugPrint("Signup successful $token"); debugPrint("Signup successful $token");
} else { } else {
debugPrint( debugPrint(
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:library_app/src/providers/auth_provider.dart'; import 'package:library_app/src/providers/auth_provider.dart';
import 'package:library_app/src/widgets/forms/login_form.dart'; import 'package:library_app/src/widgets/forms/login_form.dart';
...@@ -7,27 +8,44 @@ import 'package:library_app/src/widgets/forms/reset_password_form.dart'; ...@@ -7,27 +8,44 @@ import 'package:library_app/src/widgets/forms/reset_password_form.dart';
import 'package:library_app/src/widgets/forms/sign_up_form.dart'; import 'package:library_app/src/widgets/forms/sign_up_form.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class FormScreen extends StatelessWidget { class FormScreen extends StatefulWidget {
final String title; final String title;
final Widget body; final Widget body;
final List<Widget>? action; final List<Widget>? action;
final bool? withBackButton; final bool? withBackButton;
final String? backRoute;
const FormScreen({ const FormScreen({
super.key, super.key,
required this.title, required this.title,
required this.body, required this.body,
this.backRoute,
this.action, this.action,
this.withBackButton, this.withBackButton,
}); });
@override
State<FormScreen> createState() => _FormScreen();
}
class _FormScreen extends State<FormScreen> {
String get title => widget.title;
Widget get body => widget.body;
List<Widget>? get action => widget.action;
bool? get withBackButton => widget.withBackButton;
String? get backRoute => widget.backRoute;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final bool withBack = withBackButton != null ? withBackButton! : true; final bool withBack = withBackButton != null ? withBackButton! : true;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(title), title: Text(title),
leading: withBack ? const BackButton() : null, leading: withBack
? BackButton(
onPressed: () => context.push(backRoute ?? ""),
)
: null,
actions: action, actions: action,
), ),
body: ListView( body: ListView(
...@@ -68,6 +86,7 @@ class SignUpScreen extends StatelessWidget { ...@@ -68,6 +86,7 @@ class SignUpScreen extends StatelessWidget {
return FormScreen( return FormScreen(
title: title, title: title,
backRoute: "/",
body: const SignUpForm(), body: const SignUpForm(),
); );
} }
...@@ -82,6 +101,7 @@ class ResetPasswordScreen extends StatelessWidget { ...@@ -82,6 +101,7 @@ class ResetPasswordScreen extends StatelessWidget {
return FormScreen( return FormScreen(
title: title, title: title,
backRoute: "/",
body: const ResetPasswordForm(), body: const ResetPasswordForm(),
); );
} }
...@@ -96,6 +116,7 @@ class ConfirmResetPasswordScreen extends StatelessWidget { ...@@ -96,6 +116,7 @@ class ConfirmResetPasswordScreen extends StatelessWidget {
return FormScreen( return FormScreen(
title: title, title: title,
withBackButton: false,
body: const ConfirmResetPasswordForm(), body: const ConfirmResetPasswordForm(),
); );
} }
...@@ -110,11 +131,25 @@ class ProfileEditScreen extends StatelessWidget { ...@@ -110,11 +131,25 @@ class ProfileEditScreen extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
String title = "Edit Profile"; String title = "Edit Profile";
return Consumer<AuthProvider>(builder: (context, authProvider, child) { return Scaffold(
return FormScreen( appBar: AppBar(
title: title, title: Text(title),
body: ProfileEditForm(user: authProvider.user), leading: BackButton(
); onPressed: () => context.pop(),
}); ),
),
body: Consumer<AuthProvider>(
builder: (context, authProvider, child) {
return ListView(children: [
Container(
width: double.infinity,
padding:
const EdgeInsets.symmetric(horizontal: 20.0, vertical: 40.0),
child: ProfileEditForm(user: authProvider.user),
),
]);
},
),
);
} }
} }
...@@ -4,9 +4,14 @@ import 'package:library_app/src/screens/list/admin_list_screen.dart'; ...@@ -4,9 +4,14 @@ import 'package:library_app/src/screens/list/admin_list_screen.dart';
import 'package:library_app/src/screens/list/member_list_screen.dart'; import 'package:library_app/src/screens/list/member_list_screen.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ListScreen extends StatelessWidget { class ListScreen extends StatefulWidget {
const ListScreen({super.key}); const ListScreen({super.key});
@override
State<ListScreen> createState() => _ListScreen();
}
class _ListScreen extends State<ListScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final user = Provider.of<AuthProvider>(context).user; final user = Provider.of<AuthProvider>(context).user;
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import 'package:library_app/src/providers/auth_provider.dart'; import 'package:library_app/src/providers/auth_provider.dart';
import 'package:library_app/src/screens/form_screen.dart';
import 'package:library_app/src/widgets/loading.dart'; import 'package:library_app/src/widgets/loading.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
...@@ -130,6 +130,7 @@ class _LoginForm extends State<LoginForm> { ...@@ -130,6 +130,7 @@ class _LoginForm extends State<LoginForm> {
onPressed: () { onPressed: () {
if (_formKey.currentState!.validate()) {} if (_formKey.currentState!.validate()) {}
authProvider.signIn( authProvider.signIn(
context,
usernameController.text, usernameController.text,
passwordController.text, passwordController.text,
); );
...@@ -143,24 +144,14 @@ class _LoginForm extends State<LoginForm> { ...@@ -143,24 +144,14 @@ class _LoginForm extends State<LoginForm> {
width: double.infinity, width: double.infinity,
child: TextButton( child: TextButton(
child: const Text("Sign Up"), child: const Text("Sign Up"),
onPressed: () { onPressed: () => context.go("/sign-up"),
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const SignUpScreen(),
),
);
},
), ),
), ),
SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
child: TextButton( child: TextButton(
child: const Text("Forgot Password"), child: const Text("Forgot Password"),
onPressed: () { onPressed: () => context.go("/reset-password"),
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const ResetPasswordScreen(),
));
},
), ),
), ),
], ],
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import 'package:library_app/src/providers/auth_provider.dart'; import 'package:library_app/src/providers/auth_provider.dart';
import 'package:library_app/src/screens/form_screen.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class SignUpForm extends StatefulWidget { class SignUpForm extends StatefulWidget {
...@@ -131,6 +131,7 @@ class _SignUpForm extends State<SignUpForm> { ...@@ -131,6 +131,7 @@ class _SignUpForm extends State<SignUpForm> {
onPressed: () { onPressed: () {
if (_formKey.currentState!.validate()) {} if (_formKey.currentState!.validate()) {}
authProvider.signUp( authProvider.signUp(
context,
usernameController.text, usernameController.text,
emailController.text, emailController.text,
passwordController.text, passwordController.text,
...@@ -143,13 +144,7 @@ class _SignUpForm extends State<SignUpForm> { ...@@ -143,13 +144,7 @@ class _SignUpForm extends State<SignUpForm> {
width: double.infinity, width: double.infinity,
child: TextButton( child: TextButton(
child: const Text("Login"), child: const Text("Login"),
onPressed: () { onPressed: () => context.go("/"),
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const LoginScreen(),
),
);
},
), ),
), ),
], ],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment