Feat: Login Screen design
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:kmobile/features/auth/screens/mpin_screen.dart';
|
||||
import '../controllers/auth_cubit.dart';
|
||||
import '../controllers/auth_state.dart';
|
||||
import '../../dashboard/screens/dashboard_screen.dart';
|
||||
@@ -13,30 +14,34 @@ class LoginScreen extends StatefulWidget {
|
||||
|
||||
class LoginScreenState extends State<LoginScreen> {
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
final _usernameController = TextEditingController();
|
||||
final _customerNumberController = TextEditingController();
|
||||
final _passwordController = TextEditingController();
|
||||
bool _obscurePassword = true;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_usernameController.dispose();
|
||||
_customerNumberController.dispose();
|
||||
_passwordController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _submitForm() {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
context.read<AuthCubit>().login(
|
||||
_usernameController.text.trim(),
|
||||
_passwordController.text,
|
||||
);
|
||||
}
|
||||
// if (_formKey.currentState!.validate()) {
|
||||
// context.read<AuthCubit>().login(
|
||||
// _customerNumberController.text.trim(),
|
||||
// _passwordController.text,
|
||||
// );
|
||||
// }
|
||||
|
||||
Navigator.of(context).pushReplacement(
|
||||
MaterialPageRoute(builder: (context) => const MPinScreen()),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Login')),
|
||||
// appBar: AppBar(title: const Text('Login')),
|
||||
body: BlocConsumer<AuthCubit, AuthState>(
|
||||
listener: (context, state) {
|
||||
if (state is Authenticated) {
|
||||
@@ -56,19 +61,35 @@ class LoginScreenState extends State<LoginScreen> {
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
// crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Bank logo or app branding
|
||||
const FlutterLogo(size: 80),
|
||||
const FlutterLogo(size: 100),
|
||||
const SizedBox(height: 16),
|
||||
// Title
|
||||
const Text(
|
||||
'KCCB',
|
||||
style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold, color: Colors.blue),
|
||||
),
|
||||
const SizedBox(height: 48),
|
||||
|
||||
TextFormField(
|
||||
controller: _usernameController,
|
||||
controller: _customerNumberController,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Username',
|
||||
prefixIcon: Icon(Icons.person),
|
||||
labelText: 'Customer Number',
|
||||
// prefixIcon: Icon(Icons.person),
|
||||
border: OutlineInputBorder(),
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.black),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||
),
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
textInputAction: TextInputAction.next,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
@@ -83,8 +104,17 @@ class LoginScreenState extends State<LoginScreen> {
|
||||
controller: _passwordController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Password',
|
||||
prefixIcon: const Icon(Icons.lock),
|
||||
// prefixIcon: const Icon(Icons.lock),
|
||||
border: const OutlineInputBorder(),
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
enabledBorder: const OutlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.black),
|
||||
),
|
||||
focusedBorder: const OutlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||
),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(
|
||||
_obscurePassword
|
||||
@@ -107,43 +137,72 @@ class LoginScreenState extends State<LoginScreen> {
|
||||
},
|
||||
),
|
||||
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
// Navigate to forgot password screen
|
||||
},
|
||||
child: const Text('Forgot Password?'),
|
||||
),
|
||||
),
|
||||
// Align(
|
||||
// alignment: Alignment.centerRight,
|
||||
// child: TextButton(
|
||||
// onPressed: () {
|
||||
// // Navigate to forgot password screen
|
||||
// },
|
||||
// child: const Text('Forgot Password?'),
|
||||
// ),
|
||||
// ),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
ElevatedButton(
|
||||
onPressed: state is AuthLoading ? null : _submitForm,
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
child: state is AuthLoading
|
||||
? const CircularProgressIndicator()
|
||||
: const Text('LOGIN', style: TextStyle(fontSize: 16)),
|
||||
),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Registration option
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Text("Don't have an account?"),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
// Navigate to registration screen
|
||||
},
|
||||
child: const Text('Register'),
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: ElevatedButton(
|
||||
onPressed: state is AuthLoading ? null : _submitForm,
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: const StadiumBorder(),
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: Colors.blueAccent,
|
||||
side: const BorderSide(color: Colors.black, width: 1),
|
||||
elevation: 0
|
||||
),
|
||||
],
|
||||
child: state is AuthLoading
|
||||
? const CircularProgressIndicator()
|
||||
: const Text('Login', style: TextStyle(fontSize: 16),),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 15),
|
||||
|
||||
// OR Divider
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: Divider()),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Text('OR'),
|
||||
),
|
||||
Expanded(child: Divider()),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 25),
|
||||
|
||||
// Register Button
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
// Handle register
|
||||
},
|
||||
style: OutlinedButton.styleFrom(
|
||||
shape: const StadiumBorder(),
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
backgroundColor: Colors.lightBlue[100],
|
||||
foregroundColor: Colors.black
|
||||
),
|
||||
child: const Text('Register'),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
|
Reference in New Issue
Block a user