From d583ab0a5c7b86eb520d2d96a4ecccc15fcb6297 Mon Sep 17 00:00:00 2001 From: meylis98 Date: Thu, 9 Mar 2023 02:35:20 +0500 Subject: [PATCH] visible invisible password fields --- lib/common/custom_button.dart | 8 +- lib/common/widgets/custom_text_field.dart | 49 +++- lib/constants/utils.dart | 17 +- .../screens/auth/login/login_screen.dart | 191 ++++++++-------- .../screens/auth/register_screen.dart | 216 +++++++++--------- lib/features/screens/home/home_screen.dart | 7 +- lib/features/screens/home/product.dart | 6 +- lib/features/services/auth_service.dart | 15 ++ lib/main.dart | 10 +- 9 files changed, 292 insertions(+), 227 deletions(-) diff --git a/lib/common/custom_button.dart b/lib/common/custom_button.dart index fd38c1a..abcdbaa 100644 --- a/lib/common/custom_button.dart +++ b/lib/common/custom_button.dart @@ -22,10 +22,16 @@ class CustomButton extends StatelessWidget { return Container( height: GlobalVariables.deviceHeight(context) / 15, width: double.infinity, + decoration: BoxDecoration( + border: Border.all( + color: Colors.transparent, + width: 0, + ), + ), margin: EdgeInsets.symmetric( vertical: 5.adaptedPx(), ), - child: OutlinedButton( + child: TextButton( onPressed: onTap, style: TextButton.styleFrom( backgroundColor: backgroundColor, diff --git a/lib/common/widgets/custom_text_field.dart b/lib/common/widgets/custom_text_field.dart index c95601a..a2d08a0 100644 --- a/lib/common/widgets/custom_text_field.dart +++ b/lib/common/widgets/custom_text_field.dart @@ -3,31 +3,43 @@ import 'package:flutter/material.dart'; import '../../themes/app_theme.dart'; -class CustomTextField extends StatelessWidget { - const CustomTextField({ +class CustomTextField extends StatefulWidget { + CustomTextField({ Key? key, required this.labelText, required this.controller, required this.hintText, required this.obscureText, required this.inputType, + required this.isPassword, }) : super(key: key); final String labelText, hintText; final TextEditingController controller; - final bool obscureText; + bool obscureText, isPassword; final TextInputType inputType; + @override + State createState() => _CustomTextFieldState(); +} + +class _CustomTextFieldState extends State { + void _toggle() { + setState(() { + widget.obscureText = !widget.obscureText; + }); + } + @override Widget build(BuildContext context) { return TextFormField( - controller: controller, - obscureText: obscureText, - keyboardType: inputType, + controller: widget.controller, + obscureText: widget.obscureText, + keyboardType: widget.inputType, cursorColor: AppTheme.lightPrimaryColor, decoration: InputDecoration( - labelText: labelText, - hintText: hintText, + labelText: widget.labelText, + hintText: widget.hintText, focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10.adaptedPx()), borderSide: BorderSide( @@ -46,6 +58,23 @@ class CustomTextField extends StatelessWidget { color: AppTheme.lightTextColor, fontSize: 13.adaptedPx(), ), + suffixIcon: widget.isPassword + ? IconButton( + onPressed: () { + setState(() { + _toggle(); + }); + }, + icon: Icon( + widget.obscureText + ? Icons.visibility_outlined + : Icons.visibility_off_outlined, + ), + ) + : IconButton( + onPressed: () {}, + icon: Container(), + ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(5.adaptedPx()), borderSide: BorderSide( @@ -55,8 +84,8 @@ class CustomTextField extends StatelessWidget { ), ), validator: (value) { - if (value == null || value.isEmpty) { - return 'Enter your $hintText'; + if (value == null || value.length < 8) { + return 'password_length_8'; } return null; }, diff --git a/lib/constants/utils.dart b/lib/constants/utils.dart index bfc9282..06ae726 100644 --- a/lib/constants/utils.dart +++ b/lib/constants/utils.dart @@ -3,14 +3,17 @@ import 'package:flutter/material.dart'; import 'package:sapaly_shop/constants/global_variables.dart'; import 'package:sapaly_shop/themes/app_theme.dart'; -void showSnackBar(BuildContext ctx, - {SnackBar Function(String? content)? snackBar, - String? content, - Color? textColor, - Icon? icon, - Color? backgroundColor, - Duration? duration}) { +void showSnackBar( + BuildContext ctx, { + SnackBar Function(String? content)? snackBar, + String? content, + Color? textColor, + Icon? icon, + Color? backgroundColor, + Duration? duration, +}) { ScaffoldMessenger.of(ctx).hideCurrentSnackBar(); + ScaffoldMessenger.of(ctx).showSnackBar(snackBar == null ? SnackBar( padding: EdgeInsets.symmetric( diff --git a/lib/features/screens/auth/login/login_screen.dart b/lib/features/screens/auth/login/login_screen.dart index f56d556..d484c92 100644 --- a/lib/features/screens/auth/login/login_screen.dart +++ b/lib/features/screens/auth/login/login_screen.dart @@ -49,107 +49,106 @@ class _LoginScreenState extends State { appBar: AppBar( leading: Container(), ), - body: Align( - alignment: Alignment.center, - child: Container( - margin: EdgeInsets.symmetric( - vertical: GlobalVariables.verticalPadding(context) * 2, - horizontal: GlobalVariables.horizontalPadding(context), + body: Container( + margin: EdgeInsets.symmetric( + vertical: GlobalVariables.verticalPadding(context) * 2, + horizontal: GlobalVariables.horizontalPadding(context), + ), + padding: EdgeInsets.symmetric( + vertical: GlobalVariables.verticalPadding(context) / 2, + horizontal: GlobalVariables.horizontalPadding(context), + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.adaptedPx()), + border: Border.all( + width: 2.adaptedPx(), + color: AppTheme.blackColor.withOpacity(0.1), ), - padding: EdgeInsets.symmetric( - vertical: GlobalVariables.verticalPadding(context) / 2, - horizontal: GlobalVariables.horizontalPadding(context), - ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.adaptedPx()), - border: Border.all( - width: 2.adaptedPx(), - color: AppTheme.blackColor.withOpacity(0.1), - ), - ), - height: GlobalVariables.deviceHeight(context) / 1.55, - child: Form( - key: formKey, - child: ListView( - physics: const BouncingScrollPhysics(), - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 30.adaptedPx(), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset( - 'assets/images/sapalyLogo.png', - ), - SizedBox(width: 15.adaptedPx()), - Text( - GlobalVariables.kAppName, - style: Theme.of(context) - .primaryTextTheme - .bodyMedium - ?.copyWith( - color: AppTheme.blackColor, - fontSize: 18.adaptedPx(), - fontWeight: FontWeight.w600, - ), - ) - ], - ), + ), + height: GlobalVariables.deviceHeight(context) / 1.55, + child: Form( + key: formKey, + child: ListView( + physics: const NeverScrollableScrollPhysics(), + children: [ + Padding( + padding: EdgeInsets.symmetric( + vertical: 30.adaptedPx(), ), - Padding( - padding: EdgeInsets.symmetric(vertical: 15.adaptedPx()), - child: CustomTextField( - controller: emailController, - labelText: 'email', - hintText: 'enter_your_email', - obscureText: false, - inputType: TextInputType.emailAddress, - ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/sapalyLogo.png', + ), + SizedBox(width: 15.adaptedPx()), + Text( + GlobalVariables.kAppName, + style: Theme.of(context) + .primaryTextTheme + .bodyMedium + ?.copyWith( + color: AppTheme.blackColor, + fontSize: 18.adaptedPx(), + fontWeight: FontWeight.w600, + ), + ) + ], ), - CustomTextField( - controller: passwordController, - labelText: 'password', - hintText: 'enter_your_password', - obscureText: true, - inputType: TextInputType.visiblePassword, + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 15.adaptedPx()), + child: CustomTextField( + controller: emailController, + labelText: 'email', + hintText: 'enter_your_email', + isPassword: false, + obscureText: false, + inputType: TextInputType.emailAddress, ), - SizedBox(height: 30.adaptedPx()), - CustomButton( - name: 'login', - onTap: () { - if (formKey.currentState!.validate()) { - login(); - } - }, - backgroundColor: AppTheme.lightPrimaryColor, - isMain: true, + ), + CustomTextField( + controller: passwordController, + labelText: 'password', + hintText: 'enter_your_password', + obscureText: true, + isPassword: true, + inputType: TextInputType.visiblePassword, + ), + SizedBox(height: 30.adaptedPx()), + CustomButton( + name: 'login', + onTap: () { + if (formKey.currentState!.validate()) { + login(); + } + }, + backgroundColor: AppTheme.lightPrimaryColor, + isMain: true, + ), + Align( + alignment: Alignment.center, + child: Text( + 'or', + style: Theme.of(context) + .primaryTextTheme + .bodyMedium + ?.copyWith( + fontSize: 15.adaptedPx(), + color: AppTheme.lightTextColor), ), - Align( - alignment: Alignment.center, - child: Text( - 'or', - style: Theme.of(context) - .primaryTextTheme - .bodyMedium - ?.copyWith( - fontSize: 15.adaptedPx(), - color: AppTheme.lightTextColor), - ), - ), - CustomButton( - name: 'register', - onTap: () { - PageNavigator(ctx: context).nextPage( - page: const RegisterScreen(), - ); - }, - backgroundColor: AppTheme.lightTextColor.withOpacity(0.2), - isMain: false, - ), - ], - ), + ), + CustomButton( + name: 'register', + onTap: () { + PageNavigator(ctx: context).nextPage( + page: const RegisterScreen(), + ); + }, + backgroundColor: Colors.grey.withOpacity(0.15), + isMain: false, + ), + ], ), ), ), diff --git a/lib/features/screens/auth/register_screen.dart b/lib/features/screens/auth/register_screen.dart index fc7ec47..eacb30f 100644 --- a/lib/features/screens/auth/register_screen.dart +++ b/lib/features/screens/auth/register_screen.dart @@ -54,123 +54,123 @@ class _LoginScreenState extends State { appBar: AppBar( leading: Container(), ), - body: Align( - alignment: Alignment.center, - child: Container( - margin: EdgeInsets.symmetric( - vertical: GlobalVariables.verticalPadding(context) / 2, - horizontal: GlobalVariables.horizontalPadding(context), + body: Container( + margin: EdgeInsets.symmetric( + vertical: GlobalVariables.verticalPadding(context) / 2, + horizontal: GlobalVariables.horizontalPadding(context), + ), + padding: EdgeInsets.symmetric( + vertical: GlobalVariables.verticalPadding(context) / 2, + horizontal: GlobalVariables.horizontalPadding(context), + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.adaptedPx()), + border: Border.all( + width: 2.adaptedPx(), + color: AppTheme.blackColor.withOpacity(0.1), ), - padding: EdgeInsets.symmetric( - vertical: GlobalVariables.verticalPadding(context) / 2, - horizontal: GlobalVariables.horizontalPadding(context), - ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.adaptedPx()), - border: Border.all( - width: 2.adaptedPx(), - color: AppTheme.blackColor.withOpacity(0.1), - ), - ), - height: GlobalVariables.deviceHeight(context) / 1.5, - child: Form( - key: formKey, - child: ListView( - physics: const BouncingScrollPhysics(), - children: [ - Padding( - padding: EdgeInsets.symmetric( - vertical: 15.adaptedPx(), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset( - 'assets/images/sapalyLogo.png', - ), - SizedBox(width: 15.adaptedPx()), - Text( - GlobalVariables.kAppName, - style: Theme.of(context) - .primaryTextTheme - .bodyMedium - ?.copyWith( - color: AppTheme.blackColor, - fontSize: 18.adaptedPx(), - fontWeight: FontWeight.w600, - ), - ) - ], - ), + ), + height: GlobalVariables.deviceHeight(context) / 1.5, + child: Form( + key: formKey, + child: ListView( + physics: const NeverScrollableScrollPhysics(), + children: [ + Padding( + padding: EdgeInsets.symmetric( + vertical: 15.adaptedPx(), ), - Padding( - padding: EdgeInsets.symmetric(vertical: 15.adaptedPx()), - child: CustomTextField( - controller: emailController, - labelText: 'your_email', - hintText: 'enter_your_email_here', - obscureText: false, - inputType: TextInputType.emailAddress, - ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/sapalyLogo.png', + ), + SizedBox(width: 15.adaptedPx()), + Text( + GlobalVariables.kAppName, + style: Theme.of(context) + .primaryTextTheme + .bodyMedium + ?.copyWith( + color: AppTheme.blackColor, + fontSize: 18.adaptedPx(), + fontWeight: FontWeight.w600, + ), + ) + ], ), - CustomTextField( - controller: phoneController, - labelText: 'your_phone_number', - hintText: '64283513', + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 15.adaptedPx()), + child: CustomTextField( + controller: emailController, + labelText: 'your_email', + hintText: 'enter_your_email_here', obscureText: false, - inputType: TextInputType.phone, + isPassword: false, + inputType: TextInputType.emailAddress, ), - Padding( - padding: EdgeInsets.symmetric(vertical: 15.adaptedPx()), - child: CustomTextField( - controller: passwordController, - labelText: 'your_password', - hintText: 'enter_your_password_here', - obscureText: true, - inputType: TextInputType.visiblePassword, - ), - ), - CustomTextField( - controller: passwordConfirmationController, - labelText: 'repeat_password', - hintText: 'repeat_password_to_confirm', + ), + CustomTextField( + controller: phoneController, + labelText: 'your_phone_number', + hintText: '64283513', + obscureText: false, + isPassword: false, + inputType: TextInputType.phone, + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 15.adaptedPx()), + child: CustomTextField( + controller: passwordController, + labelText: 'your_password', + hintText: 'enter_your_password_here', obscureText: true, + isPassword: true, inputType: TextInputType.visiblePassword, ), - SizedBox(height: 20.adaptedPx()), - CustomButton( - name: 'register', - onTap: () async { - if (formKey.currentState!.validate()) { - register(); - } - }, - isMain: true, - backgroundColor: AppTheme.lightPrimaryColor, + ), + CustomTextField( + controller: passwordConfirmationController, + labelText: 'repeat_password', + hintText: 'repeat_password_to_confirm', + obscureText: true, + isPassword: true, + inputType: TextInputType.visiblePassword, + ), + SizedBox(height: 20.adaptedPx()), + CustomButton( + name: 'register', + onTap: () async { + if (formKey.currentState!.validate()) { + register(); + } + }, + isMain: true, + backgroundColor: AppTheme.lightPrimaryColor, + ), + Align( + alignment: Alignment.center, + child: Text( + 'or', + textAlign: TextAlign.center, + style: + Theme.of(context).primaryTextTheme.bodyMedium?.copyWith( + color: AppTheme.blackColor, + fontSize: 14.adaptedPx(), + ), ), - Align( - alignment: Alignment.center, - child: Text( - 'or', - textAlign: TextAlign.center, - style: - Theme.of(context).primaryTextTheme.bodyMedium?.copyWith( - color: AppTheme.blackColor, - fontSize: 14.adaptedPx(), - ), - ), - ), - CustomButton( - name: 'login', - isMain: false, - onTap: () { - PageNavigator(ctx: context) - .nextPageOnly(page: LoginScreen()); - }, - backgroundColor: AppTheme.lightTextColor.withOpacity(0.150), - ), - ], - ), + ), + CustomButton( + name: 'login', + isMain: false, + onTap: () { + PageNavigator(ctx: context).nextPageOnly(page: LoginScreen()); + }, + backgroundColor: Colors.grey.withOpacity(0.15), + ), + ], ), ), ), diff --git a/lib/features/screens/home/home_screen.dart b/lib/features/screens/home/home_screen.dart index 4e4e60d..864b2d5 100644 --- a/lib/features/screens/home/home_screen.dart +++ b/lib/features/screens/home/home_screen.dart @@ -165,8 +165,11 @@ class _HomeScreenState extends State with TickerProviderStateMixin { ), ] : [ - const Center( - child: CircularProgressIndicator()), + SizedBox( + height: 150.adaptedPx(), + child: const Center( + child: CircularProgressIndicator()), + ), ], options: CarouselOptions( initialPage: 0, diff --git a/lib/features/screens/home/product.dart b/lib/features/screens/home/product.dart index 3e76a58..530fb7d 100644 --- a/lib/features/screens/home/product.dart +++ b/lib/features/screens/home/product.dart @@ -1,3 +1,4 @@ +import 'package:adaptix/adaptix.dart'; import 'package:flutter/material.dart'; import 'package:sapaly_shop/models/product_model.dart'; @@ -41,9 +42,10 @@ class _ProductsState extends State { : GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, - childAspectRatio: 4 / 5, + childAspectRatio: 4 / (4.5), + mainAxisSpacing: 15.adaptedPx(), ), itemCount: products.length, itemBuilder: (context, index) { diff --git a/lib/features/services/auth_service.dart b/lib/features/services/auth_service.dart index 7eeaead..e8ccfc7 100644 --- a/lib/features/services/auth_service.dart +++ b/lib/features/services/auth_service.dart @@ -116,4 +116,19 @@ class AuthService { debugPrint('Register ERROr ${e.toString()}'); } } + + // get user data + Future getUserData({ + required BuildContext context, + }) async { + try { + SharedPreferences prefs = await SharedPreferences.getInstance(); + String? token = prefs.getString('token'); + if (token == null) { + prefs.setString('token', ''); + } + + // await http.post(Uri.parse('$uri')); + } catch (e) {} + } } diff --git a/lib/main.dart b/lib/main.dart index 0178e56..57e2570 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,6 +6,7 @@ import 'package:sapaly_shop/features/screens/dashboard/dashboard.dart'; import 'package:sapaly_shop/features/screens/drawer/sapaly_drawer.dart'; import 'package:sapaly_shop/features/screens/home/home_screen.dart'; import 'package:sapaly_shop/features/screens/auth/login/login_screen.dart'; +import 'package:sapaly_shop/features/services/auth_service.dart'; import 'package:sapaly_shop/providers/user_provider.dart'; import 'package:sapaly_shop/router.dart'; import 'package:sapaly_shop/themes/app_theme.dart'; @@ -30,9 +31,16 @@ Future main() async { ); } -class MyApp extends StatelessWidget { +class MyApp extends StatefulWidget { const MyApp({super.key}); + @override + State createState() => _MyAppState(); +} + +class _MyAppState extends State { + final AuthService service = AuthService(); + @override Widget build(BuildContext context) { return SizeInitializer(