mirror of
https://github.com/wger-project/flutter.git
synced 2026-02-18 00:17:48 +01:00
271 lines
8.5 KiB
Dart
271 lines
8.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:wger/theme/theme.dart';
|
|
|
|
import '../models/http_exception.dart';
|
|
import '../providers/auth.dart';
|
|
|
|
enum AuthMode { Signup, Login }
|
|
|
|
class AuthScreen extends StatelessWidget {
|
|
static const routeName = '/auth';
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final deviceSize = MediaQuery.of(context).size;
|
|
// final transformConfig = Matrix4.rotationZ(-8 * pi / 180);
|
|
// transformConfig.translate(-10.0);
|
|
return Scaffold(
|
|
// resizeToAvoidBottomInset: false,
|
|
body: Stack(
|
|
children: <Widget>[
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xff222000),
|
|
image: new DecorationImage(
|
|
fit: BoxFit.cover,
|
|
colorFilter: ColorFilter.mode(
|
|
Colors.black.withOpacity(0.2), BlendMode.dstATop),
|
|
image: new AssetImage(
|
|
'assets/images/main.jpg',
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SingleChildScrollView(
|
|
child: Container(
|
|
height: deviceSize.height,
|
|
width: deviceSize.width,
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: <Widget>[
|
|
Flexible(
|
|
child: Container(
|
|
margin: EdgeInsets.only(bottom: 20.0),
|
|
padding:
|
|
EdgeInsets.symmetric(vertical: 8.0, horizontal: 94.0),
|
|
// ..translate(-10.0),
|
|
child: Text(
|
|
'WGER',
|
|
style: TextStyle(
|
|
color: Theme.of(context).accentColor,
|
|
fontSize: 50,
|
|
fontFamily: 'OpenSansBold',
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Flexible(
|
|
flex: deviceSize.width > 600 ? 2 : 1,
|
|
child: AuthCard(),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class AuthCard extends StatefulWidget {
|
|
const AuthCard({
|
|
Key key,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
_AuthCardState createState() => _AuthCardState();
|
|
}
|
|
|
|
class _AuthCardState extends State<AuthCard> {
|
|
final GlobalKey<FormState> _formKey = GlobalKey();
|
|
AuthMode _authMode = AuthMode.Login;
|
|
Map<String, String> _authData = {
|
|
'username': '',
|
|
'email': '',
|
|
'password': '',
|
|
};
|
|
var _isLoading = false;
|
|
final _passwordController = TextEditingController();
|
|
|
|
void _showErrorDialog(String message) {
|
|
showDialog(
|
|
context: context,
|
|
builder: (ctx) => AlertDialog(
|
|
title: Text('An Error Occured!'),
|
|
content: Text(message),
|
|
actions: [
|
|
FlatButton(
|
|
child: Text('Dismiss'),
|
|
onPressed: () {
|
|
Navigator.of(ctx).pop();
|
|
},
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
void _submit() async {
|
|
if (!_formKey.currentState.validate()) {
|
|
// Invalid!
|
|
return;
|
|
}
|
|
_formKey.currentState.save();
|
|
setState(() {
|
|
_isLoading = true;
|
|
});
|
|
try {
|
|
if (_authMode == AuthMode.Login) {
|
|
await Provider.of<Auth>(context, listen: false).signIn(
|
|
_authData['username'],
|
|
_authData['password'],
|
|
);
|
|
} else {
|
|
// await Provider.of<Auth>(context, listen: false)
|
|
// .signUp(_authData['email'], _authData['password']);
|
|
// Sign user up
|
|
}
|
|
} on HttpException catch (error) {
|
|
var errorMessage = 'Authentication Failed';
|
|
|
|
if (error.errors.containsKey('username')) {
|
|
errorMessage = error.errors['username'];
|
|
} else if (error.errors.containsKey('password')) {
|
|
errorMessage = error.errors['password'];
|
|
}
|
|
_showErrorDialog(errorMessage);
|
|
//} finally {
|
|
// var errorMessage = 'Could not authenticate you. Please try again later';
|
|
// _showErrorDialog(errorMessage);
|
|
}
|
|
|
|
setState(() {
|
|
_isLoading = false;
|
|
});
|
|
}
|
|
|
|
void _switchAuthMode() {
|
|
if (_authMode == AuthMode.Login) {
|
|
setState(() {
|
|
_authMode = AuthMode.Signup;
|
|
});
|
|
} else {
|
|
setState(() {
|
|
_authMode = AuthMode.Login;
|
|
});
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final deviceSize = MediaQuery.of(context).size;
|
|
return Card(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(10.0),
|
|
),
|
|
elevation: 8.0,
|
|
child: Container(
|
|
height: _authMode == AuthMode.Signup ? 450 : 260,
|
|
constraints:
|
|
BoxConstraints(minHeight: _authMode == AuthMode.Signup ? 450 : 260),
|
|
width: deviceSize.width * 0.75,
|
|
padding: EdgeInsets.all(16.0),
|
|
child: Form(
|
|
key: _formKey,
|
|
child: SingleChildScrollView(
|
|
child: Column(
|
|
children: <Widget>[
|
|
TextFormField(
|
|
decoration: InputDecoration(labelText: 'Username'),
|
|
keyboardType: TextInputType.emailAddress,
|
|
validator: (value) {
|
|
if (value.isEmpty) {
|
|
return 'Invalid Username!';
|
|
}
|
|
return null;
|
|
},
|
|
onSaved: (value) {
|
|
_authData['username'] = value;
|
|
},
|
|
),
|
|
if (_authMode == AuthMode.Signup)
|
|
TextFormField(
|
|
decoration: InputDecoration(labelText: 'E-Mail'),
|
|
keyboardType: TextInputType.emailAddress,
|
|
validator: (value) {
|
|
if (value.isEmpty || !value.contains('@')) {
|
|
return 'Invalid email!';
|
|
}
|
|
return null;
|
|
},
|
|
onSaved: (value) {
|
|
_authData['email'] = value;
|
|
},
|
|
),
|
|
TextFormField(
|
|
decoration: InputDecoration(labelText: 'Password'),
|
|
obscureText: true,
|
|
controller: _passwordController,
|
|
validator: (value) {
|
|
if (value.isEmpty || value.length < 8) {
|
|
return 'Password is too short!';
|
|
}
|
|
return null;
|
|
},
|
|
onSaved: (value) {
|
|
_authData['password'] = value;
|
|
},
|
|
),
|
|
if (_authMode == AuthMode.Signup)
|
|
TextFormField(
|
|
enabled: _authMode == AuthMode.Signup,
|
|
decoration: InputDecoration(labelText: 'Confirm Password'),
|
|
obscureText: true,
|
|
validator: _authMode == AuthMode.Signup
|
|
? (value) {
|
|
if (value != _passwordController.text) {
|
|
return 'Passwords do not match!';
|
|
}
|
|
return null;
|
|
}
|
|
: null,
|
|
),
|
|
SizedBox(
|
|
height: 20,
|
|
),
|
|
if (_isLoading)
|
|
CircularProgressIndicator()
|
|
else
|
|
RaisedButton(
|
|
child:
|
|
Text(_authMode == AuthMode.Login ? 'LOGIN' : 'SIGN UP'),
|
|
onPressed: _submit,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(30),
|
|
),
|
|
padding:
|
|
EdgeInsets.symmetric(horizontal: 30.0, vertical: 8.0),
|
|
color: wgerPrimaryColor,
|
|
textColor: Theme.of(context).primaryTextTheme.button.color,
|
|
),
|
|
FlatButton(
|
|
child: Text(
|
|
'${_authMode == AuthMode.Login ? 'SIGNUP' : 'LOGIN'} INSTEAD'),
|
|
onPressed: _switchAuthMode,
|
|
padding: EdgeInsets.symmetric(horizontal: 30.0, vertical: 4),
|
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
textColor: wgerPrimaryColor,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|