Created
March 5, 2021 00:30
-
-
Save ricbermo/dc8c54f611f294e33fe87b66028f8e38 to your computer and use it in GitHub Desktop.
Flutter Code Review
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
final authRepositoryProvider = StateNotifierProvider<AuthNotifier>( | |
(ref) => AuthNotifier(ref.read), | |
); | |
class AuthNotifier extends StateNotifier<AuthState> { | |
final Reader _read; | |
AuthNotifier(this._read) : super(const AuthState()) { | |
loadUser(); | |
} | |
Future<bool> signup({ | |
String firstName, | |
String lastName, | |
String email, | |
String password, | |
}) async { | |
try { | |
state = state.copyWith(isLoading: true); | |
final response = await _read(dioProvider).post( | |
'/sign_up', | |
data: { | |
"user": { | |
"email": email, | |
"password": password, | |
"first_name": firstName, | |
"last_name": lastName, | |
}, | |
}, | |
); | |
_setAuthValues(response); | |
return response.statusCode == 200; | |
} on DioError catch (err) { | |
final message = err.response?.statusMessage ?? 'Something went wrong!'; | |
_setErrorMessage(message); | |
return false; | |
} on SocketException catch (_) { | |
const message = 'Please check your connection.'; | |
_setErrorMessage(message); | |
return false; | |
} | |
} | |
void _setErrorMessage(String message) { | |
state = state.copyWith( | |
isLoading: false, | |
errorMessage: message, | |
); | |
} | |
Future<void> _setAuthValues(Response response, [String token]) async { | |
final data = Map<String, dynamic>.from( | |
response.data, | |
); | |
final jsonAPI = Japx.decode(data); | |
final userFromApi = User.fromMap(jsonAPI['data']); | |
final _token = response?.headers?.value('authorization') ?? token; | |
final SharedPreferences prefs = await SharedPreferences.getInstance(); | |
prefs.setString(kTokenKey, _token); | |
state = state.copyWith( | |
isLoading: false, | |
currentUser: userFromApi, | |
authToken: _token, | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@freezed | |
abstract class AuthState with _$AuthState { | |
const factory AuthState({ | |
@Default(false) bool isLoading, | |
@Default('') String errorMessage, | |
@Default('') String authToken, | |
User currentUser, | |
}) = _AuthState; | |
const AuthState._(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SignUpForm extends HookWidget { | |
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); | |
@override | |
Widget build(BuildContext context) { | |
final textStyle = Theme.of(context).textTheme.subtitle1; | |
final firstNameController = useTextEditingController(); | |
final lastNameController = useTextEditingController(); | |
final emailController = useTextEditingController(); | |
final passwordController = useTextEditingController(); | |
final signupProvider = useProvider(authRepositoryProvider.state); | |
return Form( | |
key: _formKey, | |
child: Column( | |
children: [ | |
Input( | |
label: 'First Name', | |
icon: const Icon(Icons.person, size: 25), | |
validator: firstNameValidator, | |
controller: firstNameController, | |
), | |
SizedBox(height: getProportionateScreenHeight(28)), | |
Input( | |
label: 'Last Name', | |
icon: const Icon(Icons.person, size: 25), | |
validator: lastNameValidator, | |
controller: lastNameController, | |
), | |
SizedBox(height: getProportionateScreenHeight(28)), | |
Input( | |
label: 'Email', | |
icon: const Icon(Icons.email, size: 26), | |
validator: emailValidator, | |
controller: emailController, | |
), | |
SizedBox(height: getProportionateScreenHeight(28)), | |
Input( | |
label: 'Password', | |
icon: const Icon(Icons.lock, size: 25), | |
isPassword: true, | |
validator: passwordValidator, | |
controller: passwordController, | |
), | |
SizedBox(height: getProportionateScreenHeight(28)), | |
SizedBox( | |
width: double.infinity, | |
child: TextButton( | |
onPressed: !signupProvider?.isLoading | |
? () async { | |
if (_formKey.currentState.validate()) { | |
EasyLoading.show(status: 'Signing Up...'); | |
final response = | |
await context.read(authRepositoryProvider).signup( | |
firstName: firstNameController.text?.trim(), | |
lastName: lastNameController.text?.trim(), | |
email: emailController.text?.trim(), | |
password: passwordController.text?.trim(), | |
); | |
EasyLoading.dismiss(); | |
if (response) { | |
_formKey.currentState.reset(); | |
HomeRoute(skip: true).show(context); | |
} | |
} | |
} | |
: null, | |
child: const Text('SIGN UP'), | |
), | |
), | |
SizedBox( | |
width: double.infinity, | |
child: OutlinedButton( | |
onPressed: () { | |
HomeRoute(skip: true).show(context); | |
}, | |
child: const Text('CONTINUE AS A GUEST'), | |
), | |
), | |
SizedBox(height: getProportionateScreenHeight(32)), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Text( | |
'Do you have an account?', | |
style: textStyle.copyWith( | |
color: kTextColor, | |
), | |
), | |
const SizedBox(width: 8), | |
GestureDetector( | |
onTap: () { | |
LoginRoute().show(context); | |
}, | |
child: Text( | |
'Log In', | |
style: textStyle.copyWith( | |
color: kPrimaryColor, | |
), | |
), | |
), | |
], | |
) | |
], | |
), | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:json_annotation/json_annotation.dart'; | |
part 'user.g.dart'; | |
@JsonSerializable(nullable: false) | |
class User { | |
final int id; | |
final String firstName; | |
final String lastName; | |
final String email; | |
final String password; | |
const User({ | |
this.id, | |
this.firstName, | |
this.lastName, | |
this.password, | |
this.email, | |
}); | |
factory User.fromMap(Map<String, dynamic> json) => _$UserFromJson(json); | |
Map<String, dynamic> toMap() => _$UserToJson(this); | |
@override | |
String toString() { | |
return "$firstName $lastName"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment