Working auth and added shared notes
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:helpers/helpers/misc_build/build_media.dart';
|
||||
import 'package:helpers/helpers/print.dart';
|
||||
|
||||
import '../../global/api.dart';
|
||||
import '../../global/styles.dart';
|
||||
import '../../global/utils.dart';
|
||||
import '../../global/widgets/ui_button.dart';
|
||||
|
||||
class Login extends ConsumerStatefulWidget {
|
||||
const Login({super.key, required this.formKey, required this.exitNav});
|
||||
|
||||
final GlobalKey<FormState> formKey;
|
||||
final Widget exitNav;
|
||||
|
||||
@override
|
||||
ConsumerState<Login> createState() => _LoginState();
|
||||
}
|
||||
|
||||
class _LoginState extends ConsumerState<Login> {
|
||||
bool usingUsername = false;
|
||||
final emailController = TextEditingController();
|
||||
final usernameController = TextEditingController();
|
||||
final passwordController = TextEditingController();
|
||||
|
||||
final focusNodes = [
|
||||
FocusNode(),
|
||||
FocusNode(),
|
||||
FocusNode(),
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screen = BuildMedia(context).size;
|
||||
return Form(
|
||||
key: widget.formKey,
|
||||
child: Stack(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
const Spacer(),
|
||||
const Text(
|
||||
'Login',
|
||||
style: TextStyle(fontSize: 24),
|
||||
),
|
||||
const Spacer(flex: 2),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(2.0),
|
||||
child: Text(
|
||||
'Username',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
Checkbox(
|
||||
activeColor: Styles.lavender,
|
||||
onChanged: (bool? value) {
|
||||
setState(() => usingUsername = true);
|
||||
},
|
||||
value: usingUsername,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 35,
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(2.0),
|
||||
child: Text(
|
||||
'Email',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
Checkbox(
|
||||
activeColor: Styles.lavender,
|
||||
onChanged: (bool? value) {
|
||||
setState(() => usingUsername = false);
|
||||
},
|
||||
value: !usingUsername,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: !usingUsername
|
||||
? generateTextField(
|
||||
controller: emailController,
|
||||
size: screen,
|
||||
text: 'Email: ',
|
||||
validatorFunc: (s) {
|
||||
if (s != null && s.isNotEmpty && !isEmailValid(s)) {
|
||||
return 'Email entered is invalid';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
index: 0)
|
||||
: generateTextField(
|
||||
controller: usernameController,
|
||||
size: screen,
|
||||
text: 'Username: ',
|
||||
validatorFunc: (s) {
|
||||
if (s == null || s.isEmpty) {
|
||||
return 'Invalid Username';
|
||||
}
|
||||
if (s.length < 3) {
|
||||
return 'Username Not 3 Letters Long';
|
||||
}
|
||||
if (s.length > 20) {
|
||||
return 'Username Too Long';
|
||||
}
|
||||
if (!isUsernameValid(s)) {
|
||||
return 'Letters, Numbers, and ., -, _ Allowed';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
index: 0),
|
||||
),
|
||||
generateTextField(
|
||||
controller: passwordController,
|
||||
size: screen,
|
||||
text: 'Password: ',
|
||||
validatorFunc: (s) {
|
||||
if (s != null && s.length < 6) {
|
||||
return 'Please do a better password (you have to)';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
index: 1,
|
||||
isPassword: true),
|
||||
const Spacer(flex: 2),
|
||||
UiButton(
|
||||
width: screen.width * 0.85 > 400 ? 400 : screen.width * 0.85,
|
||||
showLoading: true,
|
||||
onPressed: () => login(),
|
||||
text: 'Submit',
|
||||
color: Styles.seaweedGreen,
|
||||
),
|
||||
const Spacer(),
|
||||
],
|
||||
),
|
||||
widget.exitNav,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget generateTextField({
|
||||
required String text,
|
||||
String? label,
|
||||
required int index,
|
||||
required TextEditingController controller,
|
||||
isPassword = false,
|
||||
required Size size,
|
||||
required String? Function(String?) validatorFunc,
|
||||
}) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(fontSize: size.width < 350 ? 16 : 20),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Container(
|
||||
decoration: Styles.boxLavenderBubble,
|
||||
width: size.width * 0.5 > 300 ? 300 : size.width * 0.5,
|
||||
child: TextFormField(
|
||||
validator: validatorFunc,
|
||||
controller: controller,
|
||||
decoration: Styles.inputLavenderBubble(labelText: label),
|
||||
obscureText: isPassword,
|
||||
focusNode: focusNodes[index],
|
||||
style: const TextStyle(fontSize: 16),
|
||||
onFieldSubmitted: (_) {
|
||||
if (index != focusNodes.length - 1) {
|
||||
focusNodes[index + 1].requestFocus();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: size.width * 0.05,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future login() async {
|
||||
try {
|
||||
if (widget.formKey.currentState != null &&
|
||||
!widget.formKey.currentState!.validate()) {
|
||||
return;
|
||||
}
|
||||
final data =
|
||||
await ref.read(apiProvider.notifier).post(path: 'auth/login', data: {
|
||||
'username':
|
||||
usernameController.text.isEmpty ? null : usernameController.text,
|
||||
'email': emailController.text.isEmpty ? null : emailController.text,
|
||||
'password': passwordController.text,
|
||||
});
|
||||
|
||||
final bool success = data?['success'] ?? false;
|
||||
showSnack(
|
||||
ref: ref,
|
||||
text: data?['message'] ?? success
|
||||
? 'Login successful'
|
||||
: 'Login unsuccessful',
|
||||
type: !success ? SnackType.error : SnackType.success);
|
||||
printAmber(data);
|
||||
} catch (err, st) {
|
||||
printRed('Error in login: $err\n$st');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user