
Replaces print statements with debugPrint across the application to prevent logging in release builds. Removes unused imports and variables for minor code cleanup.
219 lines
8.3 KiB
Dart
219 lines
8.3 KiB
Dart
import 'package:barcode_scanner/components/primary_button_component.dart';
|
|
import 'package:barcode_scanner/pages/login_page/login_page_model.dart';
|
|
import 'package:barcode_scanner/router/go_router_builder.dart';
|
|
import 'package:barcode_scanner/themes/app_theme.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
class LoginPage extends ConsumerStatefulWidget {
|
|
const LoginPage({super.key});
|
|
|
|
@override
|
|
ConsumerState<ConsumerStatefulWidget> createState() => _LoginPageState();
|
|
}
|
|
|
|
class _LoginPageState extends ConsumerState<LoginPage> {
|
|
final TextEditingController email = TextEditingController(
|
|
text: "user@yopmail.com",
|
|
);
|
|
final TextEditingController password = TextEditingController(
|
|
text: "password",
|
|
);
|
|
|
|
final _formKey = GlobalKey<FormState>();
|
|
bool obscureText = true;
|
|
|
|
@override
|
|
void dispose() {
|
|
email.dispose();
|
|
password.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: AppTheme.of(context).primaryBackground,
|
|
appBar: AppBar(
|
|
title: Text(
|
|
'BarcodeScan',
|
|
textAlign: TextAlign.center,
|
|
style: AppTheme.of(context).titleLarge,
|
|
),
|
|
centerTitle: true,
|
|
backgroundColor: AppTheme.of(context).primaryBackground,
|
|
elevation: 0,
|
|
),
|
|
body: Align(
|
|
alignment: Alignment.topCenter,
|
|
child: ConstrainedBox(
|
|
constraints: const BoxConstraints(maxWidth: 400),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(24),
|
|
child: SingleChildScrollView(
|
|
child: Form(
|
|
key: _formKey,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
const SizedBox(height: 32),
|
|
Text(
|
|
'Welcome Back',
|
|
style: AppTheme.of(context).titleLarge,
|
|
),
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
'Fill out the information below in order to access your account.',
|
|
style: AppTheme.of(context).bodyMedium.override(
|
|
color: AppTheme.of(context).secondaryText,
|
|
),
|
|
),
|
|
const SizedBox(height: 24),
|
|
|
|
/// Email
|
|
TextFormField(
|
|
decoration: InputDecoration(
|
|
labelText: 'Email',
|
|
filled: true,
|
|
fillColor: AppTheme.of(context).secondaryBackground,
|
|
border: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12),
|
|
borderSide: BorderSide.none,
|
|
),
|
|
),
|
|
controller: email,
|
|
validator: (value) {
|
|
if (value == null || value.isEmpty) {
|
|
return 'Email is required';
|
|
} else if (!RegExp(
|
|
r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$',
|
|
).hasMatch(value)) {
|
|
return 'Enter a valid email';
|
|
}
|
|
return null;
|
|
},
|
|
),
|
|
const SizedBox(height: 16),
|
|
|
|
/// Password
|
|
TextFormField(
|
|
obscureText: obscureText,
|
|
decoration: InputDecoration(
|
|
labelText: 'Password',
|
|
filled: true,
|
|
fillColor: AppTheme.of(context).secondaryBackground,
|
|
suffixIcon: IconButton(
|
|
onPressed: () {
|
|
setState(() {
|
|
obscureText = !obscureText;
|
|
});
|
|
},
|
|
icon: obscureText
|
|
? Icon(Icons.visibility_off)
|
|
: Icon(Icons.visibility),
|
|
),
|
|
border: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12),
|
|
borderSide: BorderSide.none,
|
|
),
|
|
),
|
|
controller: password,
|
|
validator: (value) {
|
|
if (value == null || value.isEmpty) {
|
|
return 'Password is required';
|
|
} else if (value.length < 6) {
|
|
return 'Password must be at least 6 characters';
|
|
}
|
|
return null;
|
|
},
|
|
),
|
|
const SizedBox(height: 24),
|
|
|
|
/// Sign In button
|
|
Consumer(
|
|
builder: (context, ref, child) {
|
|
final state = ref.watch(loginPageModelProvider);
|
|
return PrimaryButtonComponent(
|
|
loading: state.loading,
|
|
onPressed: () {
|
|
ref
|
|
.read(loginPageModelProvider.notifier)
|
|
.signIn(
|
|
email: email.text,
|
|
password: password.text,
|
|
onSuccess: () {
|
|
WidgetsBinding.instance
|
|
.addPostFrameCallback((timeStamp) {
|
|
SplashRoute().go(context);
|
|
});
|
|
},
|
|
);
|
|
},
|
|
text: 'Sign In',
|
|
);
|
|
},
|
|
),
|
|
const SizedBox(height: 16),
|
|
|
|
/// Divider text
|
|
// Center(
|
|
// child: Text(
|
|
// 'Or sign in with',
|
|
// style: TextStyle(color: Colors.grey[700]),
|
|
// ),
|
|
// ),
|
|
const SizedBox(height: 16),
|
|
|
|
// /// Google Button
|
|
// OutlinedButton.icon(
|
|
// icon: const FaIcon(FontAwesomeIcons.google),
|
|
// label: const Text('Continue with Google'),
|
|
// onPressed: () {},
|
|
// style: OutlinedButton.styleFrom(
|
|
// padding: const EdgeInsets.symmetric(vertical: 16),
|
|
// side: const BorderSide(color: Colors.grey),
|
|
// shape: RoundedRectangleBorder(
|
|
// borderRadius: BorderRadius.circular(12),
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// const SizedBox(height: 12),
|
|
|
|
// /// Apple Button
|
|
// OutlinedButton.icon(
|
|
// icon: const FaIcon(FontAwesomeIcons.apple),
|
|
// label: const Text('Continue with Apple'),
|
|
// onPressed: () {},
|
|
// style: OutlinedButton.styleFrom(
|
|
// padding: const EdgeInsets.symmetric(vertical: 16),
|
|
// side: const BorderSide(color: Colors.grey),
|
|
// shape: RoundedRectangleBorder(
|
|
// borderRadius: BorderRadius.circular(12),
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// const SizedBox(height: 24),
|
|
|
|
/// Forgot Password
|
|
TextButton(
|
|
onPressed: () {},
|
|
child: Text(
|
|
'Forgot Password?',
|
|
style: TextStyle(
|
|
color: AppTheme.of(context).primaryText,
|
|
),
|
|
),
|
|
),
|
|
|
|
const SizedBox(height: 24),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|