From cc52ace681ab19969b5740fd7965deba822a4851 Mon Sep 17 00:00:00 2001 From: Kouhakouu Date: Sun, 24 Nov 2024 22:45:39 +0700 Subject: [PATCH] Revert "change login & register UI" --- .../presentation/login_page.dart | 106 ++++++--- .../presentation/register_page.dart | 28 ++- .../presentation/resident_info_page.dart | 201 ++++++++---------- 3 files changed, 167 insertions(+), 168 deletions(-) diff --git a/lib/features/.authentication/presentation/login_page.dart b/lib/features/.authentication/presentation/login_page.dart index 66459a9..0f0ead2 100644 --- a/lib/features/.authentication/presentation/login_page.dart +++ b/lib/features/.authentication/presentation/login_page.dart @@ -25,14 +25,9 @@ class _LoginPageState extends State { bool isLoading = false; String? message; - bool _submitted = false; // Add this line // Hàm xử lý đăng nhập Future handleLogin() async { - setState(() { - _submitted = true; // Update the submitted flag - }); - if (!_formKey.currentState!.validate()) { return; } @@ -179,13 +174,6 @@ class _LoginPageState extends State { // Hàm chuyển hướng đến trang đăng ký void navigateToRegister() { - setState(() { - message = null; - _submitted = false; // Reset the submitted flag - _formKey.currentState?.reset(); - emailController.clear(); - passwordController.clear(); - }); Navigator.push( context, MaterialPageRoute( @@ -212,13 +200,76 @@ class _LoginPageState extends State { ), ), ), - // ... (Các widget Positioned khác không thay đổi) + // Thêm nhiều bong bóng nền hơn + Positioned( + top: -50, + left: -50, + child: Container( + width: 250, // đường kính của bubble + height: 250, + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + colors: [Color.fromRGBO(161, 214, 178, 0.25), Color.fromRGBO(241, 243, 194, 0.75)], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + ), + ), + Positioned( + bottom: -100, + right: -50, + child: Container( + width: 200, // đường kính của bubble + height: 200, + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + colors: [Color.fromRGBO(161, 214, 178, 1), Color.fromRGBO(241, 243, 194, 1)], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + ), + ), + Positioned( + top: 120, + right: 50, + child: Container( + width: 150, // đường kính của bubble + height: 150, + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + colors: [Color.fromRGBO(161, 214, 178, 0.75), Color.fromRGBO(241, 243, 194, 0.25)], + begin: Alignment.topRight, + end: Alignment.bottomLeft, + ), + ), + ), + ), + Positioned( + bottom: 100, + right: 500, + child: Container( + width: 300, // đường kính của bubble + height: 300, + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + colors: [Color.fromRGBO(161, 214, 178, 0.75), Color.fromRGBO(241, 243, 194, 0.25)], + begin: Alignment.topCenter, + end: Alignment.centerRight, + ), + ), + ), + ), // Nội dung chính Center( child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Container( - height: isMobile ? double.infinity : 600, width: isMobile ? double.infinity : 800, // Độ rộng tùy theo thiết bị padding: const EdgeInsets.all(24), decoration: BoxDecoration( @@ -236,24 +287,11 @@ class _LoginPageState extends State { ? buildLoginForm() : IntrinsicHeight( child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Bên trái: Form đăng nhập Expanded( flex: 1, - child: Center( - // Thêm Center để căn giữa theo chiều dọc - child: buildLoginForm(), - ), - /* - Hoặc sử dụng Column: - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - buildLoginForm(), - ], - ), - */ + child: buildLoginForm(), ), const SizedBox(width: 32), // Bên phải: Chào mừng @@ -346,6 +384,7 @@ class _LoginPageState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ + const SizedBox(height: 50), const Text( 'ĐĂNG NHẬP', style: TextStyle( @@ -354,14 +393,12 @@ class _LoginPageState extends State { color: Colors.green, ), ), - const SizedBox(height: 15), + const SizedBox(height: 24), TextFormField( controller: emailController, - autovalidateMode: _submitted ? AutovalidateMode.onUserInteraction : AutovalidateMode.disabled, decoration: InputDecoration( prefixIcon: const Icon(Icons.email), labelText: 'Email', - helperText: ' ', // Dự trữ không gian cho thông báo lỗi border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), @@ -377,10 +414,9 @@ class _LoginPageState extends State { return null; }, ), - const SizedBox(height: 5), + const SizedBox(height: 16), TextFormField( controller: passwordController, - autovalidateMode: _submitted ? AutovalidateMode.onUserInteraction : AutovalidateMode.disabled, decoration: InputDecoration( prefixIcon: const Icon(Icons.lock), labelText: 'Mật khẩu', @@ -399,6 +435,7 @@ class _LoginPageState extends State { return null; }, ), + const SizedBox(height: 5), Align( alignment: Alignment.centerRight, child: TextButton( @@ -442,7 +479,7 @@ class _LoginPageState extends State { ), ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), // Nút Đăng Ký với viền gradient và nền trắng Container( width: double.infinity, @@ -479,6 +516,7 @@ class _LoginPageState extends State { ), ), ), + const SizedBox(height: 50), ], ), ); diff --git a/lib/features/.authentication/presentation/register_page.dart b/lib/features/.authentication/presentation/register_page.dart index 838766d..c03d0f0 100644 --- a/lib/features/.authentication/presentation/register_page.dart +++ b/lib/features/.authentication/presentation/register_page.dart @@ -19,7 +19,7 @@ class _RegisterPageState extends State { final TextEditingController emailController = TextEditingController(); final TextEditingController passwordController = TextEditingController(); - String selectedRole = 'resident'; // Mặc định là 'Cư Dân' + String selectedRole = 'resident'; // Mặc định là 'Cư dân' bool isLoading = false; String? message; @@ -94,7 +94,7 @@ class _RegisterPageState extends State { top: -50, left: -50, child: Container( - width: 250, // Đường kính của bubble + width: 250, // đường kính của bubble height: 250, decoration: const BoxDecoration( shape: BoxShape.circle, @@ -110,7 +110,7 @@ class _RegisterPageState extends State { bottom: -100, right: -50, child: Container( - width: 200, // Đường kính của bubble + width: 200, // đường kính của bubble height: 200, decoration: const BoxDecoration( shape: BoxShape.circle, @@ -126,7 +126,7 @@ class _RegisterPageState extends State { top: 120, right: 50, child: Container( - width: 150, // Đường kính của bubble + width: 150, // đường kính của bubble height: 150, decoration: const BoxDecoration( shape: BoxShape.circle, @@ -142,7 +142,7 @@ class _RegisterPageState extends State { bottom: 100, right: 500, child: Container( - width: 300, // Đường kính của bubble + width: 300, // đường kính của bubble height: 300, decoration: const BoxDecoration( shape: BoxShape.circle, @@ -159,7 +159,6 @@ class _RegisterPageState extends State { child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Container( - height: isMobile ? double.infinity : 600, width: isMobile ? double.infinity : 800, // Độ rộng tùy theo thiết bị padding: const EdgeInsets.all(24), decoration: BoxDecoration( @@ -177,14 +176,11 @@ class _RegisterPageState extends State { ? buildRegisterForm() : IntrinsicHeight( child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Bên trái: Form đăng ký Expanded( flex: 1, - child: Center( - child: buildRegisterForm(), - ), + child: buildRegisterForm(), ), const SizedBox(width: 32), // Bên phải: Chào mừng @@ -277,6 +273,7 @@ class _RegisterPageState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ + const SizedBox(height: 50), const Text( 'ĐĂNG KÝ', style: TextStyle( @@ -285,13 +282,12 @@ class _RegisterPageState extends State { color: Colors.green, ), ), - const SizedBox(height: 15), + const SizedBox(height: 24), TextFormField( controller: emailController, decoration: InputDecoration( prefixIcon: const Icon(Icons.email), labelText: 'Email', - helperText: ' ', // Dự trữ không gian cho thông báo lỗi border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), @@ -307,13 +303,12 @@ class _RegisterPageState extends State { return null; }, ), - const SizedBox(height: 5), + const SizedBox(height: 16), TextFormField( controller: passwordController, decoration: InputDecoration( prefixIcon: const Icon(Icons.lock), labelText: 'Mật khẩu', - helperText: ' ', // Dự trữ không gian cho thông báo lỗi border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), @@ -329,7 +324,7 @@ class _RegisterPageState extends State { return null; }, ), - const SizedBox(height: 5), + const SizedBox(height: 16), DropdownButtonFormField( value: selectedRole, decoration: InputDecoration( @@ -386,7 +381,7 @@ class _RegisterPageState extends State { ), ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), // Nút Quay lại Đăng Nhập với viền gradient và nền trắng Container( width: double.infinity, @@ -425,6 +420,7 @@ class _RegisterPageState extends State { ), ), ), + const SizedBox(height: 50), ], ), ); diff --git a/lib/features/.authentication/presentation/resident_info_page.dart b/lib/features/.authentication/presentation/resident_info_page.dart index 17316ec..6fd0c99 100644 --- a/lib/features/.authentication/presentation/resident_info_page.dart +++ b/lib/features/.authentication/presentation/resident_info_page.dart @@ -123,12 +123,7 @@ class _ResidentInfoPageState extends State { Future logout() async { // Thực hiện logout nếu cần (ví dụ: xóa token, dữ liệu cục bộ) // Sau đó chuyển hướng về trang đăng nhập - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => LoginPage(authService: widget.authService), - ), - ); + Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => LoginPage(authService: widget.authService))); } @override @@ -219,8 +214,7 @@ class _ResidentInfoPageState extends State { child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Container( - height: isMobile ? double.infinity : 600, - width: isMobile ? double.infinity : 800, + width: isMobile ? double.infinity : 800, // Độ rộng tùy theo thiết bị padding: const EdgeInsets.all(24), decoration: BoxDecoration( color: Colors.white.withOpacity(0.9), @@ -237,7 +231,6 @@ class _ResidentInfoPageState extends State { ? buildRegisterForm() : IntrinsicHeight( child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Bên trái: Form nhập thông tin cư dân Expanded( @@ -259,7 +252,7 @@ class _ResidentInfoPageState extends State { borderRadius: BorderRadius.circular(16), ), child: const Align( - alignment: Alignment.center, + alignment: Alignment.center, // Căn lề trái child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, @@ -293,10 +286,7 @@ class _ResidentInfoPageState extends State { child: Container( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), decoration: BoxDecoration(color: message!.contains('thành công') ? Colors.green : Colors.red, borderRadius: BorderRadius.circular(8)), - child: Text( - message!, - style: const TextStyle(color: Colors.white), - ), + child: Text(message!, style: const TextStyle(color: Colors.white)), ), ), ), @@ -322,19 +312,17 @@ class _ResidentInfoPageState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ - const SizedBox(height: 15), const Text( 'THÔNG TIN CƯ DÂN', - style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold, color: Colors.green), + style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold, color: Colors.green), ), - const SizedBox(height: 15), + const SizedBox(height: 24), // Họ và Tên TextFormField( controller: fullNameController, decoration: InputDecoration( prefixIcon: const Icon(Icons.person), labelText: 'Họ và Tên', - helperText: ' ', // Dự trữ không gian cho thông báo lỗi border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), validator: (value) { @@ -344,7 +332,31 @@ class _ResidentInfoPageState extends State { return null; }, ), - const SizedBox(height: 5), + const SizedBox(height: 16), + // Giới tính + DropdownButtonFormField( + value: selectedGender, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.transgender), + labelText: 'Giới tính', + border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), + ), + items: ['Nam', 'Nữ', 'Khác'].map((String value) { + return DropdownMenuItem(value: value, child: Text(value)); + }).toList(), + onChanged: (String? newValue) { + setState(() { + selectedGender = newValue!; + }); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Vui lòng chọn giới tính.'; + } + return null; + }, + ), + const SizedBox(height: 16), // Ngày sinh (GestureDetector với TextFormField) GestureDetector( onTap: selectDOB, @@ -354,7 +366,6 @@ class _ResidentInfoPageState extends State { decoration: InputDecoration( prefixIcon: const Icon(Icons.calendar_today), labelText: 'Ngày tháng năm sinh (DD/MM/YYYY)', - helperText: ' ', // Dự trữ không gian cho thông báo lỗi suffixIcon: const Icon(Icons.calendar_today), border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), @@ -367,67 +378,29 @@ class _ResidentInfoPageState extends State { ), ), ), - const SizedBox(height: 5), - // Giới tính và Số điện thoại trên cùng một hàng - Row( - children: [ - // Giới tính - Expanded( - flex: 45, - child: DropdownButtonFormField( - value: selectedGender, - decoration: InputDecoration( - prefixIcon: const Icon(Icons.transgender), - labelText: 'Giới tính', - helperText: ' ', // Dự trữ không gian cho thông báo lỗi - border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), - ), - items: ['Nam', 'Nữ', 'Khác'].map((String value) { - return DropdownMenuItem(value: value, child: Text(value)); - }).toList(), - onChanged: (String? newValue) { - setState(() { - selectedGender = newValue!; - }); - }, - validator: (value) { - if (value == null || value.isEmpty) { - return 'Vui lòng chọn giới tính.'; - } - return null; - }, - ), - ), - const SizedBox(width: 15), // Khoảng cách giữa hai ô - // Số điện thoại - Expanded( - flex: 55, - child: TextFormField( - controller: phoneController, - decoration: InputDecoration( - prefixIcon: const Icon(Icons.phone), - labelText: 'Số điện thoại', - helperText: ' ', // Dự trữ không gian cho thông báo lỗi - border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), - ), - keyboardType: TextInputType.phone, - validator: (value) { - if (value == null || value.isEmpty) return 'Vui lòng nhập số điện thoại.'; - if (!RegExp(r'^[0-9]{10,15}$').hasMatch(value)) return 'Số điện thoại không hợp lệ.'; - return null; - }, - ), - ), - ], + const SizedBox(height: 16), + // Số điện thoại + TextFormField( + controller: phoneController, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.phone), + labelText: 'Số điện thoại', + border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), + ), + keyboardType: TextInputType.phone, + validator: (value) { + if (value == null || value.isEmpty) return 'Vui lòng nhập số điện thoại.'; + if (!RegExp(r'^[0-9]{10,15}$').hasMatch(value)) return 'Số điện thoại không hợp lệ.'; + return null; + }, ), - const SizedBox(height: 5), + const SizedBox(height: 16), // Số ID TextFormField( controller: idController, decoration: InputDecoration( prefixIcon: const Icon(Icons.card_membership), labelText: 'Số CCCD/CMND/Hộ chiếu', - helperText: ' ', // Dự trữ không gian cho thông báo lỗi border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), validator: (value) { @@ -435,58 +408,50 @@ class _ResidentInfoPageState extends State { return null; }, ), - const SizedBox(height: 5), - // Tầng và Số căn hộ trên cùng một hàng - Row( - children: [ - Expanded( - child: TextFormField( - controller: floorController, - decoration: InputDecoration( - prefixIcon: const Icon(Icons.layers), - labelText: 'Tầng', - helperText: ' ', // Dự trữ không gian cho thông báo lỗi - border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), - ), - keyboardType: TextInputType.number, - validator: (value) { - if (value == null || value.isEmpty) return 'Vui lòng nhập tầng.'; - if (int.tryParse(value) == null) return 'Tầng phải là số.'; - return null; - }, - ), - ), - const SizedBox(width: 15), // Khoảng cách giữa hai ô - Expanded( - child: TextFormField( - controller: apartmentNumberController, - decoration: InputDecoration( - prefixIcon: const Icon(Icons.home), - labelText: 'Số căn hộ', - helperText: ' ', // Dự trữ không gian cho thông báo lỗi - border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), - ), - keyboardType: TextInputType.number, - validator: (value) { - if (value == null || value.isEmpty) return 'Vui lòng nhập số căn hộ.'; - if (int.tryParse(value) == null) return 'Số căn hộ phải là số.'; - return null; - }, - ), - ), - ], + const SizedBox(height: 16), + // Tầng + TextFormField( + controller: floorController, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.layers), + labelText: 'Tầng', + border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), + ), + keyboardType: TextInputType.number, + validator: (value) { + if (value == null || value.isEmpty) return 'Vui lòng nhập tầng.'; + if (int.tryParse(value) == null) return 'Tầng phải là số.'; + return null; + }, + ), + const SizedBox(height: 16), + // Số căn hộ + TextFormField( + controller: apartmentNumberController, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.home), + labelText: 'Số căn hộ', + border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), + ), + keyboardType: TextInputType.number, + validator: (value) { + if (value == null || value.isEmpty) return 'Vui lòng nhập số căn hộ.'; + if (int.tryParse(value) == null) return 'Số căn hộ phải là số.'; + return null; + }, ), + const SizedBox(height: 12), // Thông báo if (message != null) Text( message!, style: TextStyle(color: message!.contains('thành công') ? Colors.green : Colors.red), ), - const SizedBox(height: 5), + const SizedBox(height: 24), // Nút Gửi Thông Tin với Gradient Container( width: double.infinity, - decoration: BoxDecoration(gradient: const LinearGradient(colors: [Color.fromARGB(255, 119, 198, 122), Color.fromARGB(255, 252, 242, 150)], begin: Alignment.topLeft, end: Alignment.bottomRight), borderRadius: BorderRadius.circular(8)), + decoration: BoxDecoration(gradient: const LinearGradient(colors: [Color.fromARGB(255, 119, 198, 122), Color.fromARGB(255, 252, 242, 150)]), borderRadius: BorderRadius.circular(8)), child: ElevatedButton( onPressed: submitInfo, style: ElevatedButton.styleFrom( @@ -501,12 +466,12 @@ class _ResidentInfoPageState extends State { ), ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), // Nút Quay lại Đăng Nhập với viền gradient và nền trắng Container( width: double.infinity, decoration: BoxDecoration( - gradient: const LinearGradient(colors: [Color.fromARGB(255, 119, 198, 122), Color.fromARGB(255, 252, 242, 150)], begin: Alignment.topLeft, end: Alignment.bottomRight), + gradient: const LinearGradient(colors: [Color.fromARGB(255, 119, 198, 122), Color.fromARGB(255, 252, 242, 150)]), borderRadius: BorderRadius.circular(8), ), child: Padding(