From 429054d5545c5ec12c1fe2b751ff9b1589b54c27 Mon Sep 17 00:00:00 2001 From: Muhammed Abu Shadi Date: Thu, 26 May 2022 13:29:25 +0300 Subject: [PATCH 1/3] fixed bugs and add new features --- lib/core/routs.dart | 4 + lib/core/widgets/Custom_search_field.dart | 32 +++++ lib/core/widgets/custom_button.dart | 2 + .../widgets/custom_icon_btn_with_counter.dart | 62 +++++++++ lib/core/widgets/custom_icon_button.dart | 24 ++++ lib/core/widgets/custom_soical_icon.dart | 2 + lib/core/widgets/custom_text_form_field.dart | 3 + lib/core/widgets/form_error.dart | 4 +- .../presentation/manger/models/product.dart | 103 +++++++++++++++ .../widgets/complete_profile_body.dart | 6 +- .../complete_registeration_form_body.dart | 2 - .../forgetPassowrd/forget_password_view.dart | 2 + .../widgets/forget_password_body.dart | 2 + .../widgets/forget_password_form_body.dart | 6 +- .../presentation/pages/login/login_view.dart | 2 + .../pages/login/widgets/login_form_body.dart | 2 + .../pages/login/widgets/login_view_body.dart | 2 + .../auth/presentation/pages/otp/otp_view.dart | 2 + .../pages/otp/widgets/otp_body_view.dart | 4 +- .../pages/otp/widgets/otp_form_body.dart | 8 +- .../registration/registeration_view.dart | 2 + .../widgets/registeration_form_body.dart | 5 +- .../widgets/registration_body_view.dart | 4 +- .../pages/success/succes_login_view.dart | 2 +- .../success/widgets/success_login_body.dart | 11 +- lib/features/home/home_view.dart | 14 ++ lib/features/home/widgets/home_body_view.dart | 37 ++++++ .../home/widgets/home_categories_options.dart | 76 +++++++++++ .../home/widgets/home_discount_banner.dart | 31 +++++ .../home/widgets/home_header_content.dart | 34 +++++ .../home/widgets/home_product_card.dart | 124 ++++++++++++++++++ .../home_section_scrollable_items.dart | 36 +++++ .../home/widgets/home_special_offer_card.dart | 122 +++++++++++++++++ lib/features/onBoarding/on_boarding_view.dart | 2 + .../widgets/on_boarding_content_body.dart | 2 + lib/features/productDetails/product_view.dart | 32 +++++ .../widgets/product_details_body.dart | 12 ++ .../splash/widgets/splash_view_body.dart | 1 - lib/main.dart | 2 +- pubspec.yaml | 4 +- 40 files changed, 804 insertions(+), 23 deletions(-) create mode 100644 lib/core/widgets/Custom_search_field.dart create mode 100644 lib/core/widgets/custom_icon_btn_with_counter.dart create mode 100644 lib/core/widgets/custom_icon_button.dart create mode 100644 lib/features/auth/presentation/manger/models/product.dart create mode 100644 lib/features/home/home_view.dart create mode 100644 lib/features/home/widgets/home_body_view.dart create mode 100644 lib/features/home/widgets/home_categories_options.dart create mode 100644 lib/features/home/widgets/home_discount_banner.dart create mode 100644 lib/features/home/widgets/home_header_content.dart create mode 100644 lib/features/home/widgets/home_product_card.dart create mode 100644 lib/features/home/widgets/home_section_scrollable_items.dart create mode 100644 lib/features/home/widgets/home_special_offer_card.dart create mode 100644 lib/features/productDetails/product_view.dart create mode 100644 lib/features/productDetails/widgets/product_details_body.dart diff --git a/lib/core/routs.dart b/lib/core/routs.dart index 74780d5..93a89d6 100644 --- a/lib/core/routs.dart +++ b/lib/core/routs.dart @@ -3,7 +3,9 @@ import 'package:ecommerce/features/auth/presentation/pages/login/login_view.dart import 'package:ecommerce/features/auth/presentation/pages/otp/otp_view.dart'; import 'package:ecommerce/features/auth/presentation/pages/registration/registeration_view.dart'; import 'package:flutter/widgets.dart'; +import '../features/home/home_view.dart'; import '../features/onBoarding/on_boarding_view.dart'; +import '../features/productDetails/product_view.dart'; import '../features/splash/splash_view.dart'; final Map routes = { @@ -13,4 +15,6 @@ final Map routes = { ForgetPasswordView.routName:(ctx)=> const ForgetPasswordView(), RegistrationView.routName:(ctx)=>const RegistrationView(), OtpView.routName:(ctx)=>const OtpView(), + HomeView.routName:(ctx)=>const HomeView(), + ProductDetailsView.routName:(ctx)=>const ProductDetailsView(), }; diff --git a/lib/core/widgets/Custom_search_field.dart b/lib/core/widgets/Custom_search_field.dart new file mode 100644 index 0000000..8cef77e --- /dev/null +++ b/lib/core/widgets/Custom_search_field.dart @@ -0,0 +1,32 @@ +// ignore_for_file: file_names, use_key_in_widget_constructors + +import 'package:flutter/material.dart'; +import '../constants.dart'; +import '../utils/size_config.dart'; + +class BuildSearchProduct extends StatelessWidget { + const BuildSearchProduct({Key? key}) ; + + @override + Widget build(BuildContext context) { + return Container( + width: SizeConfig.screenWidth * 0.6, + decoration: BoxDecoration( + color: kSecondaryColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(20)), + child: TextField( + onChanged: (value) { + //search value + }, + decoration: InputDecoration( + enabledBorder: InputBorder.none, + focusedBorder: InputBorder.none, + hintText: "Search Product", + prefixIcon: const Icon(Icons.search), + contentPadding: EdgeInsets.symmetric( + horizontal: getProportionateScreenWidth(20), + vertical: getProportionateScreenWidth(10))), + ), + ); + } +} diff --git a/lib/core/widgets/custom_button.dart b/lib/core/widgets/custom_button.dart index 86b37a0..e5fb923 100644 --- a/lib/core/widgets/custom_button.dart +++ b/lib/core/widgets/custom_button.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:flutter/material.dart'; import '../constants.dart'; diff --git a/lib/core/widgets/custom_icon_btn_with_counter.dart b/lib/core/widgets/custom_icon_btn_with_counter.dart new file mode 100644 index 0000000..4e72aea --- /dev/null +++ b/lib/core/widgets/custom_icon_btn_with_counter.dart @@ -0,0 +1,62 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +import '../constants.dart'; +import '../utils/size_config.dart'; + +class CustomIconBtnWithCounter extends StatelessWidget { + const CustomIconBtnWithCounter({ + Key? key,required this.onTap,required this.iconPath,this.numOfItems = 0, + }); + final GestureTapCallback? onTap; + final String? iconPath; + final int? numOfItems; + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(50), + child: Stack( + children: [ + Container( + padding: EdgeInsets.all(getProportionateScreenWidth(12)), + width: getProportionateScreenWidth(46), + height: getProportionateScreenWidth(46), + decoration: BoxDecoration( + color: kSecondaryColor.withOpacity(0.1), + shape: BoxShape.circle, + ), + child: SvgPicture.asset(iconPath!), + ), + if(numOfItems!=0) + Positioned( + top: -2, + right: -1, + child: Container( + width: getProportionateScreenWidth(16), + height: getProportionateScreenWidth(16), + decoration: BoxDecoration( + color: const Color(0xffff4848), + shape: BoxShape.circle, + border: Border.all(width: 1.5, color: Colors.white), + ), + child: Text( + "$numOfItems", + style: TextStyle( + color: Colors.white, + height: 1.3, + fontSize: getProportionateScreenWidth(10), + fontWeight: FontWeight.bold + ), + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/core/widgets/custom_icon_button.dart b/lib/core/widgets/custom_icon_button.dart new file mode 100644 index 0000000..7226ba9 --- /dev/null +++ b/lib/core/widgets/custom_icon_button.dart @@ -0,0 +1,24 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:flutter/material.dart'; + +import '../../../../../core/utils/size_config.dart'; + +class CustomIconButton extends StatelessWidget { + const CustomIconButton({Key? key,required this.iconData,required this.onTap}); + final IconData? iconData; + final GestureTapCallback? onTap; + @override + Widget build(BuildContext context) { + return SizedBox( + height: getProportionateScreenWidth(40), + width: getProportionateScreenWidth(40), + child: MaterialButton( + padding: EdgeInsets.zero, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(55)), + onPressed: onTap, + child: Icon(iconData!), + ), + ); + } +} diff --git a/lib/core/widgets/custom_soical_icon.dart b/lib/core/widgets/custom_soical_icon.dart index 87f0d77..e27029c 100644 --- a/lib/core/widgets/custom_soical_icon.dart +++ b/lib/core/widgets/custom_soical_icon.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/core/utils/size_config.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; diff --git a/lib/core/widgets/custom_text_form_field.dart b/lib/core/widgets/custom_text_form_field.dart index 7c70916..1b6fc54 100644 --- a/lib/core/widgets/custom_text_form_field.dart +++ b/lib/core/widgets/custom_text_form_field.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/core/utils/size_config.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -37,6 +39,7 @@ class _TextFormFieldContentState extends State { } else { return null; } + return null; }, decoration: InputDecoration( labelText: widget.labelTxt, diff --git a/lib/core/widgets/form_error.dart b/lib/core/widgets/form_error.dart index e503b93..bf39db2 100644 --- a/lib/core/widgets/form_error.dart +++ b/lib/core/widgets/form_error.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -6,7 +8,7 @@ class FormError extends StatelessWidget { const FormError({ Key? key, required this.errors, - }) : super(key: key); + }); final List errors; diff --git a/lib/features/auth/presentation/manger/models/product.dart b/lib/features/auth/presentation/manger/models/product.dart new file mode 100644 index 0000000..e0c42ad --- /dev/null +++ b/lib/features/auth/presentation/manger/models/product.dart @@ -0,0 +1,103 @@ +import 'package:flutter/material.dart'; + +class Product { + final int id; + final String title, description; + final List images; + final List colors; + final double rating, price; + final bool isFavourite, isPopular; + + Product({ + required this.id, + required this.images, + required this.colors, + this.rating = 0.0, + this.isFavourite = false, + this.isPopular = false, + required this.title, + required this.price, + required this.description, + }); +} + +// Our demo Products + +List demoProducts = [ + Product( + id: 1, + images: [ + "assets/images/ps4_console_white_1.png", + "assets/images/ps4_console_white_2.png", + "assets/images/ps4_console_white_3.png", + "assets/images/ps4_console_white_4.png", + ], + colors: [ + const Color(0xFFF6625E), + const Color(0xFF836DB8), + const Color(0xFFDECB9C), + Colors.white, + ], + title: "Wireless Controller for PS4™", + price: 64.99, + description: description, + rating: 4.8, + isFavourite: true, + isPopular: true, + ), + Product( + id: 2, + images: [ + "assets/images/Image Popular Product 2.png", + ], + colors: [ + const Color(0xFFF6625E), + const Color(0xFF836DB8), + const Color(0xFFDECB9C), + Colors.white, + ], + title: "Nike Sport White - Man Pant", + price: 50.5, + description: description, + rating: 4.1, + isPopular: true, + ), + Product( + id: 3, + images: [ + "assets/images/glap.png", + ], + colors: [ + const Color(0xFFF6625E), + const Color(0xFF836DB8), + const Color(0xFFDECB9C), + Colors.white, + ], + title: "Gloves XC Omega - Polygon", + price: 36.55, + description: description, + rating: 4.1, + isFavourite: true, + isPopular: true, + ), + Product( + id: 4, + images: [ + "assets/images/wireless headset.png", + ], + colors: [ + const Color(0xFFF6625E), + const Color(0xFF836DB8), + const Color(0xFFDECB9C), + Colors.white, + ], + title: "Logitech Head", + price: 20.20, + description: description, + rating: 4.1, + isFavourite: true, + ), +]; + +const String description = + "Wireless Controller for PS4™ gives you what you want in your gaming from over precision control your games to sharing …"; \ No newline at end of file diff --git a/lib/features/auth/presentation/pages/completeProfile/widgets/complete_profile_body.dart b/lib/features/auth/presentation/pages/completeProfile/widgets/complete_profile_body.dart index 657ee6a..13fdd26 100644 --- a/lib/features/auth/presentation/pages/completeProfile/widgets/complete_profile_body.dart +++ b/lib/features/auth/presentation/pages/completeProfile/widgets/complete_profile_body.dart @@ -1,7 +1,7 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/features/auth/presentation/pages/completeProfile/widgets/complete_registeration_form_body.dart'; -import 'package:ecommerce/features/auth/presentation/pages/registration/widgets/registeration_form_body.dart'; import 'package:flutter/material.dart'; - import '../../../../../../core/utils/size_config.dart'; import '../../login/widgets/login_view_body.dart'; @@ -28,7 +28,7 @@ class _CompleteProfileBodyState extends State { buildText("Complete Profile", Colors.black, getProportionateScreenWidth(28), FontWeight.bold), buildText( - "Complete your details \n or continue with social media accounts", + "Complete your productDetails \n or continue with social media accounts", Colors.black54, getProportionateScreenWidth(10), FontWeight.w500), diff --git a/lib/features/auth/presentation/pages/completeProfile/widgets/complete_registeration_form_body.dart b/lib/features/auth/presentation/pages/completeProfile/widgets/complete_registeration_form_body.dart index ad2503d..fa8c986 100644 --- a/lib/features/auth/presentation/pages/completeProfile/widgets/complete_registeration_form_body.dart +++ b/lib/features/auth/presentation/pages/completeProfile/widgets/complete_registeration_form_body.dart @@ -1,8 +1,6 @@ import 'package:ecommerce/features/auth/presentation/pages/otp/otp_view.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:get/get_navigation/src/routes/transitions_type.dart'; - import '../../../../../../core/constants.dart'; import '../../../../../../core/utils/size_config.dart'; import '../../../../../../core/widgets/custom_button.dart'; diff --git a/lib/features/auth/presentation/pages/forgetPassowrd/forget_password_view.dart b/lib/features/auth/presentation/pages/forgetPassowrd/forget_password_view.dart index fd97bee..77d4fa2 100644 --- a/lib/features/auth/presentation/pages/forgetPassowrd/forget_password_view.dart +++ b/lib/features/auth/presentation/pages/forgetPassowrd/forget_password_view.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/features/auth/presentation/pages/forgetPassowrd/widgets/forget_password_body.dart'; import 'package:flutter/material.dart'; diff --git a/lib/features/auth/presentation/pages/forgetPassowrd/widgets/forget_password_body.dart b/lib/features/auth/presentation/pages/forgetPassowrd/widgets/forget_password_body.dart index 08c6641..e697de8 100644 --- a/lib/features/auth/presentation/pages/forgetPassowrd/widgets/forget_password_body.dart +++ b/lib/features/auth/presentation/pages/forgetPassowrd/widgets/forget_password_body.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:flutter/material.dart'; import '../../../../../../core/utils/size_config.dart'; diff --git a/lib/features/auth/presentation/pages/forgetPassowrd/widgets/forget_password_form_body.dart b/lib/features/auth/presentation/pages/forgetPassowrd/widgets/forget_password_form_body.dart index 54b4ba7..0ea309a 100644 --- a/lib/features/auth/presentation/pages/forgetPassowrd/widgets/forget_password_form_body.dart +++ b/lib/features/auth/presentation/pages/forgetPassowrd/widgets/forget_password_form_body.dart @@ -1,7 +1,7 @@ +// ignore_for_file: use_key_in_widget_constructors, library_private_types_in_public_api + import 'package:ecommerce/core/widgets/custom_button.dart'; -import 'package:ecommerce/features/auth/presentation/pages/success/succes_login_view.dart'; import 'package:flutter/material.dart'; -import 'package:get/get.dart'; import '../../../../../../core/constants.dart'; import '../../../../../../core/utils/size_config.dart'; import '../../../../../../core/widgets/custom_suffix_icon.dart'; @@ -100,7 +100,7 @@ class _ForgotPasswordFormBodyState extends State { // If you are using latest version of flutter then lable text and hint text shown like this // if you r using flutter less then 1.20.* then maybe this is not working properly floatingLabelBehavior: FloatingLabelBehavior.always, - suffixIcon: CustomSuffixIcon(svgIcon: "assets/icons/Lock.svg"), + suffixIcon: const CustomSuffixIcon(svgIcon: "assets/icons/Lock.svg"), ), ); } diff --git a/lib/features/auth/presentation/pages/login/login_view.dart b/lib/features/auth/presentation/pages/login/login_view.dart index 21e58ee..dee03ce 100644 --- a/lib/features/auth/presentation/pages/login/login_view.dart +++ b/lib/features/auth/presentation/pages/login/login_view.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/features/auth/presentation/pages/login/widgets/login_view_body.dart'; import 'package:flutter/material.dart'; diff --git a/lib/features/auth/presentation/pages/login/widgets/login_form_body.dart b/lib/features/auth/presentation/pages/login/widgets/login_form_body.dart index df15724..83623f2 100644 --- a/lib/features/auth/presentation/pages/login/widgets/login_form_body.dart +++ b/lib/features/auth/presentation/pages/login/widgets/login_form_body.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/core/constants.dart'; import 'package:ecommerce/core/utils/size_config.dart'; import 'package:ecommerce/core/widgets/custom_button.dart'; diff --git a/lib/features/auth/presentation/pages/login/widgets/login_view_body.dart b/lib/features/auth/presentation/pages/login/widgets/login_view_body.dart index 6942785..b2147cf 100644 --- a/lib/features/auth/presentation/pages/login/widgets/login_view_body.dart +++ b/lib/features/auth/presentation/pages/login/widgets/login_view_body.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/core/constants.dart'; import 'package:ecommerce/core/utils/size_config.dart'; import 'package:ecommerce/core/widgets/custom_soical_icon.dart'; diff --git a/lib/features/auth/presentation/pages/otp/otp_view.dart b/lib/features/auth/presentation/pages/otp/otp_view.dart index 63d88c2..3a6ab78 100644 --- a/lib/features/auth/presentation/pages/otp/otp_view.dart +++ b/lib/features/auth/presentation/pages/otp/otp_view.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/features/auth/presentation/pages/otp/widgets/otp_body_view.dart'; import 'package:flutter/material.dart'; diff --git a/lib/features/auth/presentation/pages/otp/widgets/otp_body_view.dart b/lib/features/auth/presentation/pages/otp/widgets/otp_body_view.dart index 309c3b4..6c033c9 100644 --- a/lib/features/auth/presentation/pages/otp/widgets/otp_body_view.dart +++ b/lib/features/auth/presentation/pages/otp/widgets/otp_body_view.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/core/constants.dart'; import 'package:ecommerce/features/auth/presentation/pages/otp/otp_view.dart'; import 'package:flutter/material.dart'; @@ -48,7 +50,7 @@ class _OtpBodyViewState extends State { ], ), SizedBox(height: SizeConfig.screenHeight * 0.04), - OtpFormBody(), + const OtpFormBody(), SizedBox(height: SizeConfig.screenHeight * 0.06), Row( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/features/auth/presentation/pages/otp/widgets/otp_form_body.dart b/lib/features/auth/presentation/pages/otp/widgets/otp_form_body.dart index e5d2121..6630b0c 100644 --- a/lib/features/auth/presentation/pages/otp/widgets/otp_form_body.dart +++ b/lib/features/auth/presentation/pages/otp/widgets/otp_form_body.dart @@ -1,8 +1,12 @@ +// ignore_for_file: library_private_types_in_public_api + import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import '../../../../../../core/constants.dart'; import '../../../../../../core/utils/size_config.dart'; import '../../../../../../core/widgets/custom_button.dart'; +import '../../../../../home/home_view.dart'; class OtpFormBody extends StatefulWidget { const OtpFormBody({ @@ -112,7 +116,9 @@ class _OtpFormBodyState extends State { height: getProportionateScreenHeight(56), child: CustomGeneralButton( textButton: "Continue", - onTap: () {}, + onTap: () { + Get.to(const HomeView(),transition: Transition.fade ); + }, ), ) ], diff --git a/lib/features/auth/presentation/pages/registration/registeration_view.dart b/lib/features/auth/presentation/pages/registration/registeration_view.dart index b228546..7912a92 100644 --- a/lib/features/auth/presentation/pages/registration/registeration_view.dart +++ b/lib/features/auth/presentation/pages/registration/registeration_view.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/features/auth/presentation/pages/registration/widgets/registration_body_view.dart'; import 'package:flutter/material.dart'; class RegistrationView extends StatelessWidget { diff --git a/lib/features/auth/presentation/pages/registration/widgets/registeration_form_body.dart b/lib/features/auth/presentation/pages/registration/widgets/registeration_form_body.dart index 8737493..6a3071d 100644 --- a/lib/features/auth/presentation/pages/registration/widgets/registeration_form_body.dart +++ b/lib/features/auth/presentation/pages/registration/widgets/registeration_form_body.dart @@ -1,4 +1,5 @@ -import 'package:ecommerce/features/auth/presentation/pages/completeProfile/complete_profile_view.dart'; +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/features/auth/presentation/pages/otp/otp_view.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -7,7 +8,7 @@ import '../../../../../../core/utils/size_config.dart'; import '../../../../../../core/widgets/custom_button.dart'; import '../../../../../../core/widgets/custom_suffix_icon.dart'; import '../../../../../../core/widgets/form_error.dart'; -import '../../success/succes_login_view.dart'; + class RegistrationFormBody extends StatefulWidget { const RegistrationFormBody({Key? key}); diff --git a/lib/features/auth/presentation/pages/registration/widgets/registration_body_view.dart b/lib/features/auth/presentation/pages/registration/widgets/registration_body_view.dart index 6dd19cd..0bc3cd8 100644 --- a/lib/features/auth/presentation/pages/registration/widgets/registration_body_view.dart +++ b/lib/features/auth/presentation/pages/registration/widgets/registration_body_view.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/features/auth/presentation/pages/registration/widgets/registeration_form_body.dart'; import 'package:flutter/material.dart'; import '../../../../../../core/utils/size_config.dart'; @@ -52,7 +54,7 @@ class _RegistrationViewBodyState extends State { buildText("Register Account", Colors.black, getProportionateScreenWidth(28), FontWeight.bold), buildText( - "Complete your details \n or continue with social media accounts", + "Complete your productDetails \n or continue with social media accounts", Colors.black54, getProportionateScreenWidth(10), FontWeight.w500), diff --git a/lib/features/auth/presentation/pages/success/succes_login_view.dart b/lib/features/auth/presentation/pages/success/succes_login_view.dart index 9622d41..88e9c72 100644 --- a/lib/features/auth/presentation/pages/success/succes_login_view.dart +++ b/lib/features/auth/presentation/pages/success/succes_login_view.dart @@ -8,7 +8,7 @@ class SuccessLoginView extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - leading: SizedBox(), + leading: const SizedBox(), centerTitle: true, title: const Text("Login Success"), ), diff --git a/lib/features/auth/presentation/pages/success/widgets/success_login_body.dart b/lib/features/auth/presentation/pages/success/widgets/success_login_body.dart index e0b6569..de52295 100644 --- a/lib/features/auth/presentation/pages/success/widgets/success_login_body.dart +++ b/lib/features/auth/presentation/pages/success/widgets/success_login_body.dart @@ -1,12 +1,15 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/core/utils/size_config.dart'; -import 'package:ecommerce/features/auth/presentation/pages/login/login_view.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../../../../../core/widgets/custom_button.dart'; +import '../../../../../home/home_view.dart'; class SuccessLoginBody extends StatelessWidget { const SuccessLoginBody({Key? key}); + @override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, @@ -28,18 +31,18 @@ class SuccessLoginBody extends StatelessWidget { color: Colors.black, ), ), - Spacer(), + const Spacer(), SizedBox( width: SizeConfig.screenWidth * 0.6, height: getProportionateScreenHeight(56), child: CustomGeneralButton( textButton: "Back to home", onTap: () { - Get.to(() => const LoginView(), transition: Transition.fade); + Get.to(() => const HomeView(), transition: Transition.fade); }, ), ), - Spacer(), + const Spacer(), ], ); } diff --git a/lib/features/home/home_view.dart b/lib/features/home/home_view.dart new file mode 100644 index 0000000..c2e0c50 --- /dev/null +++ b/lib/features/home/home_view.dart @@ -0,0 +1,14 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:ecommerce/features/home/widgets/home_body_view.dart'; +import 'package:flutter/material.dart'; + +class HomeView extends StatelessWidget { + const HomeView({Key? key}); + static const routName="/Home"; + + @override + Widget build(BuildContext context) { + return const Scaffold(body: HomeBodyView()); + } +} diff --git a/lib/features/home/widgets/home_body_view.dart b/lib/features/home/widgets/home_body_view.dart new file mode 100644 index 0000000..d9c7dd1 --- /dev/null +++ b/lib/features/home/widgets/home_body_view.dart @@ -0,0 +1,37 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:ecommerce/core/utils/size_config.dart'; +import 'package:flutter/material.dart'; +import 'home_discount_banner.dart'; +import 'home_header_content.dart'; +import 'home_product_card.dart'; +import 'home_categories_options.dart'; +import 'home_special_offer_card.dart'; + +class HomeBodyView extends StatelessWidget { + const HomeBodyView({Key? key}); + + @override + Widget build(BuildContext context) { + return SafeArea( + child: SingleChildScrollView( + child: Column( + children: [ + SizedBox(height: getProportionateScreenWidth(10)), + const HomeHeader(), + SizedBox(height: getProportionateScreenWidth(10)), + const HomeDiscountBanner(), + SizedBox(height: getProportionateScreenWidth(10)), + const HomeCategoriesOptions(), + SizedBox(height: getProportionateScreenWidth(10)), + const SpecialOfferCardWithText(), + SizedBox(height: getProportionateScreenWidth(10)), + const ProductCardWithText(), + SizedBox(height: getProportionateScreenWidth(10)), + ], + ), + )); + } +} + + diff --git a/lib/features/home/widgets/home_categories_options.dart b/lib/features/home/widgets/home_categories_options.dart new file mode 100644 index 0000000..e3f113f --- /dev/null +++ b/lib/features/home/widgets/home_categories_options.dart @@ -0,0 +1,76 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:ecommerce/core/utils/size_config.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class HomeCategoriesOptions extends StatelessWidget { + const HomeCategoriesOptions({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + List> categories = [ + {"icon": "assets/icons/Flash Icon.svg", "text": "Flash Deal"}, + {"icon": "assets/icons/Bill Icon.svg", "text": "Bill"}, + {"icon": "assets/icons/Game Icon.svg", "text": "Game"}, + {"icon": "assets/icons/Gift Icon.svg", "text": "Daily"}, + {"icon": "assets/icons/Discover.svg", "text": "More"}, + ]; + return Padding( + padding: EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(20)), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ...List.generate( + categories.length, + (index) => CategoriesOptionsCard( + icon: categories[index]["icon"], + text: categories[index]["text"], + onTap: () { + // + }), + ), + ], + ), + ); + } +} + +class CategoriesOptionsCard extends StatelessWidget { + const CategoriesOptionsCard({ + Key? key, + required this.icon, + required this.text, + required this.onTap, + }); + + final String? icon, text; + final GestureTapCallback? onTap; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: SizedBox( + width: getProportionateScreenWidth(55), + child: Column( + children: [ + AspectRatio( + aspectRatio: 1, + child: Container( + padding: EdgeInsets.all(getProportionateScreenWidth(12)), + decoration: BoxDecoration( + color: const Color(0xFFFFECDF), + borderRadius: BorderRadius.circular(10)), + child: SvgPicture.asset(icon!), + ), + ), + const SizedBox(height: 5), + SizedBox( height: getProportionateScreenWidth(20),child: Text(text!, textAlign: TextAlign.center)), + ], + ), + ), + ); + } +} diff --git a/lib/features/home/widgets/home_discount_banner.dart b/lib/features/home/widgets/home_discount_banner.dart new file mode 100644 index 0000000..26f45a7 --- /dev/null +++ b/lib/features/home/widgets/home_discount_banner.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; + +import '../../../../../../core/utils/size_config.dart'; + +class HomeDiscountBanner extends StatelessWidget { + const HomeDiscountBanner({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.symmetric( + horizontal: getProportionateScreenWidth(20)), + padding: EdgeInsets.symmetric( + horizontal: getProportionateScreenWidth(20), + vertical: getProportionateScreenWidth(15)), + width: double.infinity, + //height: 90, + decoration: BoxDecoration( + color: const Color( + 0xff4a3298, + ), + borderRadius: BorderRadius.circular(20)), + child: const Text.rich(TextSpan( + text: "A Summer Surprise \n", + style: TextStyle(color: Colors.white), + children: [ + TextSpan(text: "Cashback 20%",style: TextStyle(fontSize: 24,fontWeight: FontWeight.bold)), + ])), + ); + } +} diff --git a/lib/features/home/widgets/home_header_content.dart b/lib/features/home/widgets/home_header_content.dart new file mode 100644 index 0000000..e81b189 --- /dev/null +++ b/lib/features/home/widgets/home_header_content.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +import '../../../../../../core/utils/size_config.dart'; +import '../../../../../../core/widgets/Custom_search_field.dart'; +import '../../../../../../core/widgets/custom_icon_btn_with_counter.dart'; + +class HomeHeader extends StatelessWidget { + const HomeHeader({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric( + horizontal: getProportionateScreenWidth(20), + vertical: getProportionateScreenWidth(5)), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const BuildSearchProduct(), + CustomIconBtnWithCounter( + onTap: () {}, + iconPath: "assets/icons/Cart Icon.svg", + //numOfItems: 3, + ), + CustomIconBtnWithCounter( + onTap: () {}, + iconPath: "assets/icons/Bell.svg", + numOfItems: 3, + ), + ], + ), + ); + } +} diff --git a/lib/features/home/widgets/home_product_card.dart b/lib/features/home/widgets/home_product_card.dart new file mode 100644 index 0000000..e64c76c --- /dev/null +++ b/lib/features/home/widgets/home_product_card.dart @@ -0,0 +1,124 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import '../../auth/presentation/manger/models/product.dart'; +import '../../productDetails/product_view.dart'; +import 'home_section_scrollable_items.dart'; +import '../../../../../../core/constants.dart'; +import '../../../../../../core/utils/size_config.dart'; + + +class ProductCardWithText extends StatelessWidget { + const ProductCardWithText({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column(children: [ + SectionScrollableItems( + text: 'Popular Products', + onTap: () {}, + ), + SizedBox(height: getProportionateScreenWidth(10)), + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + ...List.generate(demoProducts.length, + (index) => ProductCard(product: demoProducts[index], onTap: () { + Get.to(const ProductDetailsView(),transition: Transition.fade,arguments: demoProducts[index]); + },)), + SizedBox(width: getProportionateScreenWidth(20)), + ], + ), + ), + ],); + } +} + + + +class ProductCard extends StatelessWidget { + const ProductCard({ + Key? key, + this.width = 140.0, + this.aspectRation = 1.02, + required this.product,required this.onTap, + }); + + final double? width, aspectRation; + final Product? product; + final GestureTapCallback? onTap; + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.only(left: getProportionateScreenWidth(20)), + child: GestureDetector( + onTap: onTap, + child: SizedBox( + width: getProportionateScreenWidth(width!), + height: getProportionateScreenWidth(220), + child: Column( + children: [ + AspectRatio( + aspectRatio: aspectRation!, + child: Container( + padding: EdgeInsets.all(getProportionateScreenWidth(20)), + decoration: BoxDecoration( + color: kSecondaryColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(15), + ), + child: Image.asset(product!.images[0]), + ), + ), + const SizedBox(height: 5), + SizedBox( + height: getProportionateScreenWidth(40), + child: Text( + product!.title, + style: const TextStyle(color: Colors.black), + maxLines: 2, + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "\$${product!.price}", + style: TextStyle( + fontWeight: FontWeight.w600, + color: kPrimaryColor, + fontSize: getProportionateScreenWidth(15)), + maxLines: 2, + ), + InkWell( + onTap: () {}, + borderRadius: BorderRadius.circular(50), + child: Container( + padding: EdgeInsets.all(getProportionateScreenWidth(8)), + width: getProportionateScreenWidth(28), + height: getProportionateScreenWidth(28), + decoration: BoxDecoration( + color: product!.isFavourite + ? kPrimaryColor.withOpacity(0.15) + : kSecondaryColor.withOpacity(0.1), + shape: BoxShape.circle, + ), + child: SvgPicture.asset( + "assets/icons/Heart Icon_2.svg", + color: product!.isFavourite + ? const Color(0xffff4848) + : const Color(0xffdbdee4), + ), + ), + ), + ], + ) + ], + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/features/home/widgets/home_section_scrollable_items.dart b/lib/features/home/widgets/home_section_scrollable_items.dart new file mode 100644 index 0000000..ed92ad8 --- /dev/null +++ b/lib/features/home/widgets/home_section_scrollable_items.dart @@ -0,0 +1,36 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:flutter/material.dart'; +import '../../../../../../core/utils/size_config.dart'; + +class SectionScrollableItems extends StatelessWidget { + const SectionScrollableItems({ + Key? key,required this.text,required this.onTap, + }); + final String? text; + final GestureTapCallback? onTap; + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(20)), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + text!, + style: TextStyle( + fontSize: getProportionateScreenWidth(18), + color: Colors.black), + ), + GestureDetector( + onTap: onTap, + child: const Text( + "See More", + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/features/home/widgets/home_special_offer_card.dart b/lib/features/home/widgets/home_special_offer_card.dart new file mode 100644 index 0000000..cec1690 --- /dev/null +++ b/lib/features/home/widgets/home_special_offer_card.dart @@ -0,0 +1,122 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:flutter/material.dart'; +import '../../../../../../core/utils/size_config.dart'; +import 'home_section_scrollable_items.dart'; + +class SpecialOfferCardWithText extends StatelessWidget { + const SpecialOfferCardWithText({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + SectionScrollableItems( + text: 'Special for you', + onTap: () {}, + ), + SizedBox(height: getProportionateScreenWidth(10)), + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + SpecialOfferCard( + numbOfBrands: 18, + onTap: () {}, + category: 'Smart Phone', + image: 'assets/images/Image Banner 2.png', + ), + SpecialOfferCard( + numbOfBrands: 18, + onTap: () {}, + category: 'Smart Phone', + image: 'assets/images/Image Banner 3.png', + ), + SpecialOfferCard( + numbOfBrands: 18, + onTap: () {}, + category: 'Smart Phone', + image: 'assets/images/Image Banner 2.png', + ), + ], + ), + ), + ], + ); + } +} + +class SpecialOfferCard extends StatelessWidget { + const SpecialOfferCard({ + Key? key, + required this.category, + required this.image, + required this.numbOfBrands, + required this.onTap, + }); + + final String? category, image; + final int? numbOfBrands; + final GestureTapCallback? onTap; + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.only( + left: getProportionateScreenWidth(10), + right: getProportionateScreenWidth(10)), + child: SizedBox( + height: getProportionateScreenWidth(100), + width: getProportionateScreenWidth(242), + child: Stack( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(20), + child: Stack( + children: [ + Image.asset( + image!, + fit: BoxFit.cover, + ), + Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + const Color(0xFF343434).withOpacity(0.4), + const Color(0xFF343434).withOpacity(0.15), + ], + ), + ), + ), + Padding( + padding: EdgeInsets.symmetric( + horizontal: getProportionateScreenWidth(15), + vertical: getProportionateScreenWidth(10)), + child: Text.rich( + TextSpan( + style: const TextStyle(color: Colors.white), + children: [ + TextSpan( + text: "$category\n", + style: TextStyle( + fontSize: getProportionateScreenWidth(18), + fontWeight: FontWeight.bold), + ), + TextSpan( + text: "$numbOfBrands Brands", + ), + ], + ), + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/features/onBoarding/on_boarding_view.dart b/lib/features/onBoarding/on_boarding_view.dart index 3b181a2..5b32c3f 100644 --- a/lib/features/onBoarding/on_boarding_view.dart +++ b/lib/features/onBoarding/on_boarding_view.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:ecommerce/core/utils/size_config.dart'; import 'package:ecommerce/features/onBoarding/widgets/on_boarding_body.dart'; import 'package:flutter/material.dart'; diff --git a/lib/features/onBoarding/widgets/on_boarding_content_body.dart b/lib/features/onBoarding/widgets/on_boarding_content_body.dart index de642a1..d544ed2 100644 --- a/lib/features/onBoarding/widgets/on_boarding_content_body.dart +++ b/lib/features/onBoarding/widgets/on_boarding_content_body.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_key_in_widget_constructors + import 'package:flutter/material.dart'; import '../../../../core/constants.dart'; diff --git a/lib/features/productDetails/product_view.dart b/lib/features/productDetails/product_view.dart new file mode 100644 index 0000000..7b07762 --- /dev/null +++ b/lib/features/productDetails/product_view.dart @@ -0,0 +1,32 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:ecommerce/features/auth/presentation/manger/models/product.dart'; +import 'package:flutter/material.dart'; +import '../../core/widgets/custom_icon_button.dart'; +import 'widgets/product_details_body.dart'; + + +class ProductDetailsView extends StatelessWidget { + const ProductDetailsView({Key? key}); + + static const routName = "/ProductDetails"; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xfff5f6f9), + appBar: AppBar( + backgroundColor: Colors.transparent, + leading: CustomIconButton(iconData: Icons.arrow_back, onTap: () { Navigator.pop(context); },), + ), + body: const ProductDetailsBody(), + ); + } + +} + +class ProductDetailsArguments { + final Product? product; + + ProductDetailsArguments({required this.product}); +} diff --git a/lib/features/productDetails/widgets/product_details_body.dart b/lib/features/productDetails/widgets/product_details_body.dart new file mode 100644 index 0000000..c5ac474 --- /dev/null +++ b/lib/features/productDetails/widgets/product_details_body.dart @@ -0,0 +1,12 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:flutter/material.dart'; + +class ProductDetailsBody extends StatelessWidget { + const ProductDetailsBody({Key? key}) ; + + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/lib/features/splash/widgets/splash_view_body.dart b/lib/features/splash/widgets/splash_view_body.dart index 089221a..0c4512e 100644 --- a/lib/features/splash/widgets/splash_view_body.dart +++ b/lib/features/splash/widgets/splash_view_body.dart @@ -1,5 +1,4 @@ import 'package:ecommerce/core/constants.dart'; -import 'package:ecommerce/core/utils/size_config.dart'; import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; diff --git a/lib/main.dart b/lib/main.dart index 82c0f46..f93ebc3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,7 +4,7 @@ import 'core/routs.dart'; import 'core/utils/theme_data.dart'; void main() { - runApp(MyApp()); + runApp(const MyApp()); } class MyApp extends StatelessWidget { diff --git a/pubspec.yaml b/pubspec.yaml index b3b9b56..bac0991 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,7 +35,7 @@ flutter: # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware - # For details regarding adding assets from package dependencies, see + # For productDetails regarding adding assets from package dependencies, see # https://flutter.dev/assets-and-images/#from-packages # To add custom fonts to your application, add a fonts section here, @@ -57,5 +57,5 @@ flutter: # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # - # For details regarding fonts from package dependencies, + # For productDetails regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages From 372e1ac5b01d95ad3e97197656222f07399b54be Mon Sep 17 00:00:00 2001 From: Muhammed Abu Shadi Date: Thu, 26 May 2022 16:47:43 +0300 Subject: [PATCH 2/3] Add product details screens --- lib/core/widgets/custom_app_bar.dart | 73 +++++++++++++++ lib/core/widgets/custom_icon_button.dart | 42 +++++++-- .../home/widgets/home_product_card.dart | 54 ++++++----- lib/features/productDetails/product_view.dart | 19 ++-- .../widgets/product_colored_dots.dart | 40 +++++++++ .../widgets/product_container_colored.dart | 34 +++++++ .../widgets/product_details_body.dart | 50 ++++++++++- .../widgets/product_image_body.dart | 67 ++++++++++++++ .../widgets/product_item_details_body.dart | 90 +++++++++++++++++++ .../product_rounded_conatiner_body.dart | 29 ++++++ 10 files changed, 454 insertions(+), 44 deletions(-) create mode 100644 lib/core/widgets/custom_app_bar.dart create mode 100644 lib/features/productDetails/widgets/product_colored_dots.dart create mode 100644 lib/features/productDetails/widgets/product_container_colored.dart create mode 100644 lib/features/productDetails/widgets/product_image_body.dart create mode 100644 lib/features/productDetails/widgets/product_item_details_body.dart create mode 100644 lib/features/productDetails/widgets/product_rounded_conatiner_body.dart diff --git a/lib/core/widgets/custom_app_bar.dart b/lib/core/widgets/custom_app_bar.dart new file mode 100644 index 0000000..9e4ce18 --- /dev/null +++ b/lib/core/widgets/custom_app_bar.dart @@ -0,0 +1,73 @@ +// ignore_for_file: prefer_const_constructors_in_immutables, use_key_in_widget_constructors + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import '../constants.dart'; +import '../utils/size_config.dart'; + +class CustomAppBar extends StatelessWidget { + final double rating; + + CustomAppBar({required this.rating}); + + // AppBar().preferredSize.height provide us the height that appy on our app bar + Size get preferredSize => Size.fromHeight(AppBar().preferredSize.height); + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Padding( + padding: + EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(20)), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(top: 5), + child: SizedBox( + height: getProportionateScreenWidth(40), + width: getProportionateScreenWidth(40), + child: TextButton( + style: TextButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(60), + ), + primary: kPrimaryColor, + backgroundColor: Colors.white, + padding: EdgeInsets.zero, + ), + onPressed: () => Navigator.pop(context), + child: SvgPicture.asset( + "assets/icons/Back ICon.svg", + height: 15, + ), + ), + ), + ), + const Spacer(), + Container( + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 5), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(14), + ), + child: Row( + children: [ + Text( + "$rating", + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(width: 5), + SvgPicture.asset("assets/icons/Star Icon.svg"), + ], + ), + ) + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/core/widgets/custom_icon_button.dart b/lib/core/widgets/custom_icon_button.dart index 7226ba9..af02921 100644 --- a/lib/core/widgets/custom_icon_button.dart +++ b/lib/core/widgets/custom_icon_button.dart @@ -3,21 +3,45 @@ import 'package:flutter/material.dart'; import '../../../../../core/utils/size_config.dart'; +import '../constants.dart'; class CustomIconButton extends StatelessWidget { - const CustomIconButton({Key? key,required this.iconData,required this.onTap}); - final IconData? iconData; - final GestureTapCallback? onTap; + const CustomIconButton( + {Key? key, + required this.icon, + required this.press, + this.showShadow = false,}); + + final IconData icon; + final GestureTapCancelCallback press; + final bool showShadow; + @override Widget build(BuildContext context) { - return SizedBox( + return Container( height: getProportionateScreenWidth(40), width: getProportionateScreenWidth(40), - child: MaterialButton( - padding: EdgeInsets.zero, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(55)), - onPressed: onTap, - child: Icon(iconData!), + decoration: BoxDecoration( + shape: BoxShape.circle, + boxShadow: [ + if (showShadow) + BoxShadow( + offset: const Offset(0, 6), + blurRadius: 10, + color: const Color(0xFFB0B0B0).withOpacity(0.2), + ), + ], + ), + child: TextButton( + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + primary: kPrimaryColor, + backgroundColor: Colors.white, + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(50)), + ), + onPressed: press, + child: Icon(icon), ), ); } diff --git a/lib/features/home/widgets/home_product_card.dart b/lib/features/home/widgets/home_product_card.dart index e64c76c..34dd80e 100644 --- a/lib/features/home/widgets/home_product_card.dart +++ b/lib/features/home/widgets/home_product_card.dart @@ -9,47 +9,55 @@ import 'home_section_scrollable_items.dart'; import '../../../../../../core/constants.dart'; import '../../../../../../core/utils/size_config.dart'; - class ProductCardWithText extends StatelessWidget { const ProductCardWithText({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return Column(children: [ - SectionScrollableItems( - text: 'Popular Products', - onTap: () {}, - ), - SizedBox(height: getProportionateScreenWidth(10)), - SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - children: [ - ...List.generate(demoProducts.length, - (index) => ProductCard(product: demoProducts[index], onTap: () { - Get.to(const ProductDetailsView(),transition: Transition.fade,arguments: demoProducts[index]); - },)), - SizedBox(width: getProportionateScreenWidth(20)), - ], + return Column( + children: [ + SectionScrollableItems( + text: 'Popular Products', + onTap: () {}, ), - ), - ],); + SizedBox(height: getProportionateScreenWidth(10)), + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + ...List.generate( + demoProducts.length, + (index) => ProductCard( + product: demoProducts[index], + onTap: () { + Get.to(() => const ProductDetailsView(), + transition: Transition.fade, + arguments: ProductDetailsArguments( + product: demoProducts[index])); + }, + )), + SizedBox(width: getProportionateScreenWidth(20)), + ], + ), + ), + ], + ); } } - - class ProductCard extends StatelessWidget { const ProductCard({ Key? key, this.width = 140.0, this.aspectRation = 1.02, - required this.product,required this.onTap, + required this.product, + required this.onTap, }); final double? width, aspectRation; final Product? product; final GestureTapCallback? onTap; + @override Widget build(BuildContext context) { return Padding( @@ -121,4 +129,4 @@ class ProductCard extends StatelessWidget { ), ); } -} \ No newline at end of file +} diff --git a/lib/features/productDetails/product_view.dart b/lib/features/productDetails/product_view.dart index 7b07762..d95d7f2 100644 --- a/lib/features/productDetails/product_view.dart +++ b/lib/features/productDetails/product_view.dart @@ -1,11 +1,9 @@ // ignore_for_file: use_key_in_widget_constructors - import 'package:ecommerce/features/auth/presentation/manger/models/product.dart'; import 'package:flutter/material.dart'; -import '../../core/widgets/custom_icon_button.dart'; +import '../../core/widgets/custom_app_bar.dart'; import 'widgets/product_details_body.dart'; - class ProductDetailsView extends StatelessWidget { const ProductDetailsView({Key? key}); @@ -13,16 +11,17 @@ class ProductDetailsView extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: const Color(0xfff5f6f9), - appBar: AppBar( - backgroundColor: Colors.transparent, - leading: CustomIconButton(iconData: Icons.arrow_back, onTap: () { Navigator.pop(context); },), + final ProductDetailsArguments arguments = + ModalRoute.of(context)!.settings.arguments as ProductDetailsArguments; + return Scaffold( + backgroundColor: const Color(0xFFF5F6F9), + appBar: PreferredSize( + preferredSize: Size.fromHeight(AppBar().preferredSize.height), + child: CustomAppBar(rating: arguments.product!.rating), ), - body: const ProductDetailsBody(), + body: ProductDetailsBody(product: arguments.product,), ); } - } class ProductDetailsArguments { diff --git a/lib/features/productDetails/widgets/product_colored_dots.dart b/lib/features/productDetails/widgets/product_colored_dots.dart new file mode 100644 index 0000000..ce33d1c --- /dev/null +++ b/lib/features/productDetails/widgets/product_colored_dots.dart @@ -0,0 +1,40 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:ecommerce/features/productDetails/widgets/product_container_colored.dart'; +import 'package:flutter/material.dart'; +import '../../../core/utils/size_config.dart'; +import '../../../core/widgets/custom_icon_button.dart'; +import '../../auth/presentation/manger/models/product.dart'; + +class ProductColoredDots extends StatelessWidget { + const ProductColoredDots({ + Key? key, + required this.product, + }); + + final Product? product; + + @override + Widget build(BuildContext context) { + int isColorSelected = 0; + return Padding( + padding: + EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(15)), + child: Row( + children: [ + ...List.generate( + product!.colors.length, + (index) => BuildColoredContainer( + color: product!.colors[index], + isSelected: isColorSelected == index, + ), + ), + const Spacer(), + CustomIconButton(icon: Icons.add, press: (){}), + const SizedBox(width: 5), + CustomIconButton(icon: Icons.remove, press: (){}), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/features/productDetails/widgets/product_container_colored.dart b/lib/features/productDetails/widgets/product_container_colored.dart new file mode 100644 index 0000000..0476256 --- /dev/null +++ b/lib/features/productDetails/widgets/product_container_colored.dart @@ -0,0 +1,34 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:flutter/material.dart'; +import '../../../core/constants.dart'; +import '../../../core/utils/size_config.dart'; + +class BuildColoredContainer extends StatelessWidget { + const BuildColoredContainer({ + Key? key, + required this.color, + this.isSelected = false, + }); + + final Color? color; + final bool? isSelected; + + @override + Widget build(BuildContext context) { + return Container( + width: getProportionateScreenWidth(40), + height: getProportionateScreenWidth(40), + padding: const EdgeInsets.all(8), + margin: const EdgeInsets.only(right: 4), + decoration: BoxDecoration( + shape: BoxShape.circle, + border: + Border.all(color: isSelected! ? kPrimaryColor : Colors.transparent), + ), + child: DecoratedBox( + decoration: BoxDecoration(color: color!, shape: BoxShape.circle), + ), + ); + } +} \ No newline at end of file diff --git a/lib/features/productDetails/widgets/product_details_body.dart b/lib/features/productDetails/widgets/product_details_body.dart index c5ac474..d5bb97b 100644 --- a/lib/features/productDetails/widgets/product_details_body.dart +++ b/lib/features/productDetails/widgets/product_details_body.dart @@ -1,12 +1,58 @@ // ignore_for_file: use_key_in_widget_constructors +import 'package:ecommerce/core/utils/size_config.dart'; +import 'package:ecommerce/core/widgets/custom_button.dart'; +import 'package:ecommerce/features/auth/presentation/manger/models/product.dart'; +import 'package:ecommerce/features/productDetails/widgets/product_colored_dots.dart'; +import 'package:ecommerce/features/productDetails/widgets/product_image_body.dart'; +import 'package:ecommerce/features/productDetails/widgets/product_item_details_body.dart'; +import 'package:ecommerce/features/productDetails/widgets/product_rounded_conatiner_body.dart'; import 'package:flutter/material.dart'; class ProductDetailsBody extends StatelessWidget { - const ProductDetailsBody({Key? key}) ; + const ProductDetailsBody({Key? key, required this.product}); + + final Product? product; @override Widget build(BuildContext context) { - return Container(); + return Column( + children: [ + ProductImages(product: product), + RoundedContainer( + color: Colors.white, + widget: SingleChildScrollView( + child: Column( + children: [ + ProductDetails( + product: product, + onTap: () {}, + ), + RoundedContainer( + color: const Color(0xfff6f7f9), + widget: Column( + children: [ + ProductColoredDots(product: product), + RoundedContainer( + color: Colors.white, + widget: Padding( + padding: EdgeInsets.only( + top: getProportionateScreenWidth(10), + left: SizeConfig.screenWidth * 0.15, + right: SizeConfig.screenWidth * 0.15), + child: SizedBox( + height: getProportionateScreenWidth(50), + child: CustomGeneralButton( + textButton: "Add To Chart", onTap: () {})), + ), + ) + ], + )) + ], + ), + ), + ), + ], + ); } } diff --git a/lib/features/productDetails/widgets/product_image_body.dart b/lib/features/productDetails/widgets/product_image_body.dart new file mode 100644 index 0000000..0fb738e --- /dev/null +++ b/lib/features/productDetails/widgets/product_image_body.dart @@ -0,0 +1,67 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:flutter/material.dart'; +import '../../../core/constants.dart'; +import '../../../core/utils/size_config.dart'; +import '../../auth/presentation/manger/models/product.dart'; + +class ProductImages extends StatefulWidget { + const ProductImages({ + Key? key, + required this.product, + }); + + final Product? product; + + @override + State createState() => _ProductImagesState(); +} + +class _ProductImagesState extends State { + int selectedImage = 0; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + SizedBox( + width: getProportionateScreenWidth(120), + child: AspectRatio( + aspectRatio: 1, + child: Image.asset(widget.product!.images[selectedImage]), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ...List.generate(widget.product!.images.length, + (index) => buildPreviewSmallImage(index)) + ], + ), + ], + ); + } + + GestureDetector buildPreviewSmallImage(int index) { + return GestureDetector( + onTap: (){ + setState((){ + selectedImage = index; + }); + }, + child: Container( + margin: EdgeInsets.only(right: getProportionateScreenWidth(15)), + padding: EdgeInsets.all(getProportionateScreenHeight(8)), + height: getProportionateScreenWidth(48), + width: getProportionateScreenWidth(48), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + border: Border.all( + color: + selectedImage == index ? kPrimaryColor : Colors.transparent)), + child: Image.asset(widget.product!.images[index]), + ), + ); + } +} diff --git a/lib/features/productDetails/widgets/product_item_details_body.dart b/lib/features/productDetails/widgets/product_item_details_body.dart new file mode 100644 index 0000000..e8e56a0 --- /dev/null +++ b/lib/features/productDetails/widgets/product_item_details_body.dart @@ -0,0 +1,90 @@ + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import '../../../core/constants.dart'; +import '../../../core/utils/size_config.dart'; +import '../../auth/presentation/manger/models/product.dart'; + +class ProductDetails extends StatelessWidget { + const ProductDetails({ + Key? key, + required this.product,required this.onTap, + }) : super(key: key); + + final Product? product; + final GestureTapCallback? onTap; + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.symmetric( + horizontal: getProportionateScreenWidth(20)), + child: Text( + product!.title, + style: Theme.of(context).textTheme.headline6, + ), + ), + const SizedBox(height: 5), + Align( + alignment: Alignment.centerRight, + child: Container( + padding: EdgeInsets.all(getProportionateScreenWidth(15)), + width: getProportionateScreenWidth(64), + decoration: BoxDecoration( + color: product!.isFavourite + ? const Color(0xffffe6e6) + : const Color(0xfff5f6f9), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(40), + bottomLeft: Radius.circular(40)), + ), + child: SvgPicture.asset( + "assets/icons/Heart Icon_2.svg", + color: product!.isFavourite + ? const Color(0xffff4848) + : const Color(0xffd8dee4), + ), + ), + ), + const SizedBox(height: 5), + Padding( + padding: EdgeInsets.only( + left: getProportionateScreenWidth(15), + right: getProportionateScreenWidth(74), + ), + child: Text( + product!.description, + maxLines: 3, + ), + ), + Padding( + padding: EdgeInsets.symmetric( + horizontal: getProportionateScreenWidth(15), + vertical: getProportionateScreenWidth(5)), + child: GestureDetector( + onTap: onTap, + child: Row( + children: const [ + Text( + "See More Details", + style: TextStyle( + color: kPrimaryColor, fontWeight: FontWeight.w600), + ), + SizedBox( + width: 5, + ), + Icon( + Icons.arrow_forward_ios, + color: kPrimaryColor, + size: 12, + ), + ], + ), + ), + ), + ], + ); + } +} \ No newline at end of file diff --git a/lib/features/productDetails/widgets/product_rounded_conatiner_body.dart b/lib/features/productDetails/widgets/product_rounded_conatiner_body.dart new file mode 100644 index 0000000..8228e20 --- /dev/null +++ b/lib/features/productDetails/widgets/product_rounded_conatiner_body.dart @@ -0,0 +1,29 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:flutter/material.dart'; +import '../../../core/utils/size_config.dart'; + +class RoundedContainer extends StatelessWidget { + const RoundedContainer({ + Key? key, + required this.color, + required this.widget, + }); + + final Color? color; + final Widget? widget; + + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.only(top: getProportionateScreenWidth(20)), + padding: EdgeInsets.only(top: getProportionateScreenWidth(20)), + width: double.infinity, + decoration: BoxDecoration( + color: color!, + borderRadius: const BorderRadius.only( + topRight: Radius.circular(40), topLeft: Radius.circular(40))), + child: widget!, + ); + } +} \ No newline at end of file From 8c5d0a5d5519a5dab61a33ccc1e484ececebd7cd Mon Sep 17 00:00:00 2001 From: Muhammed Abu Shadi Date: Thu, 26 May 2022 19:46:16 +0300 Subject: [PATCH 3/3] Add Cart screens --- lib/core/routs.dart | 12 +- .../auth/presentation/manger/models/cart.dart | 16 +++ lib/features/cart/cart_view.dart | 115 ++++++++++++++++++ .../cart/widgets/cart_item_card_body.dart | 62 ++++++++++ lib/features/cart/widgets/cart_view_body.dart | 51 ++++++++ .../home/widgets/home_header_content.dart | 6 +- 6 files changed, 256 insertions(+), 6 deletions(-) create mode 100644 lib/features/auth/presentation/manger/models/cart.dart create mode 100644 lib/features/cart/cart_view.dart create mode 100644 lib/features/cart/widgets/cart_item_card_body.dart create mode 100644 lib/features/cart/widgets/cart_view_body.dart diff --git a/lib/core/routs.dart b/lib/core/routs.dart index 93a89d6..4fcb30c 100644 --- a/lib/core/routs.dart +++ b/lib/core/routs.dart @@ -2,6 +2,7 @@ import 'package:ecommerce/features/auth/presentation/pages/forgetPassowrd/forget import 'package:ecommerce/features/auth/presentation/pages/login/login_view.dart'; import 'package:ecommerce/features/auth/presentation/pages/otp/otp_view.dart'; import 'package:ecommerce/features/auth/presentation/pages/registration/registeration_view.dart'; +import 'package:ecommerce/features/cart/cart_view.dart'; import 'package:flutter/widgets.dart'; import '../features/home/home_view.dart'; import '../features/onBoarding/on_boarding_view.dart'; @@ -12,9 +13,10 @@ final Map routes = { '/': (ctx) => const SplashView(), OnBoardingView.routName: (ctx) => const OnBoardingView(), LoginView.routName: (ctx) => const LoginView(), - ForgetPasswordView.routName:(ctx)=> const ForgetPasswordView(), - RegistrationView.routName:(ctx)=>const RegistrationView(), - OtpView.routName:(ctx)=>const OtpView(), - HomeView.routName:(ctx)=>const HomeView(), - ProductDetailsView.routName:(ctx)=>const ProductDetailsView(), + ForgetPasswordView.routName: (ctx) => const ForgetPasswordView(), + RegistrationView.routName: (ctx) => const RegistrationView(), + OtpView.routName: (ctx) => const OtpView(), + HomeView.routName: (ctx) => const HomeView(), + ProductDetailsView.routName: (ctx) => const ProductDetailsView(), + CartView.routName: (ctx) => const CartView(), }; diff --git a/lib/features/auth/presentation/manger/models/cart.dart b/lib/features/auth/presentation/manger/models/cart.dart new file mode 100644 index 0000000..74804b0 --- /dev/null +++ b/lib/features/auth/presentation/manger/models/cart.dart @@ -0,0 +1,16 @@ +import 'Product.dart'; + +class Cart { + final Product product; + final int numOfItem; + + Cart({required this.product, required this.numOfItem}); +} + +// Demo data for our cart + +List demoCarts = [ + Cart(product: demoProducts[0], numOfItem: 2), + Cart(product: demoProducts[1], numOfItem: 1), + Cart(product: demoProducts[3], numOfItem: 1), +]; \ No newline at end of file diff --git a/lib/features/cart/cart_view.dart b/lib/features/cart/cart_view.dart new file mode 100644 index 0000000..c1799b2 --- /dev/null +++ b/lib/features/cart/cart_view.dart @@ -0,0 +1,115 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:ecommerce/core/constants.dart'; +import 'package:ecommerce/core/utils/size_config.dart'; +import 'package:ecommerce/core/widgets/custom_button.dart'; +import 'package:ecommerce/features/auth/presentation/manger/models/cart.dart'; +import 'package:ecommerce/features/cart/widgets/cart_view_body.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class CartView extends StatelessWidget { + const CartView({Key? key}); + + static const routName = "/cart"; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: buildCartAppBar(context), + body: const CartViewBody(), + bottomNavigationBar: const CheckOurCard(), + ); + } + + AppBar buildCartAppBar(BuildContext context) { + return AppBar( + title: Column( + children: [ + const Text( + "Your Cart", + style: TextStyle(color: Colors.black), + ), + Text( + "${demoCarts.length} Items ", + style: Theme.of(context).textTheme.caption, + ), + ], + ), + centerTitle: true, + ); + } +} + +class CheckOurCard extends StatelessWidget { + const CheckOurCard({ + Key? key, + }); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.symmetric( + horizontal: getProportionateScreenWidth(30), + vertical: getProportionateScreenWidth(15)), + //height: 174, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(40), + topRight: Radius.circular(40), + ), + boxShadow: [ + BoxShadow( + offset: const Offset(0, -15), + blurRadius: 20, + color: const Color(0xffdadada).withOpacity(0.15), + ), + ], + ), + child: SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Container( + padding: const EdgeInsets.all(10), + height: getProportionateScreenWidth(40), + width: getProportionateScreenWidth(40), + decoration: BoxDecoration( + color: const Color(0xfff5f6f9), + borderRadius: BorderRadius.circular(10), + ), + child: SvgPicture.asset("assets/icons/receipt.svg"), + ), + const Spacer(), + const Text("Add voucher code"), + const SizedBox(width: 10), + const Icon(Icons.arrow_forward_ios, size: 12, color: kTextColor) + ], + ), + SizedBox(height: getProportionateScreenWidth(20)), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text.rich( + TextSpan(text: "\$ 337.5"), + style: TextStyle(fontSize: 16, color: Colors.black), + ), + SizedBox( + width: getProportionateScreenWidth(190), + height: getProportionateScreenWidth(50), + child: CustomGeneralButton( + textButton: 'Check Out', + onTap: () {}, + ), + ), + ], + ), + ], + ), + ), + ); + } +} diff --git a/lib/features/cart/widgets/cart_item_card_body.dart b/lib/features/cart/widgets/cart_item_card_body.dart new file mode 100644 index 0000000..82bb640 --- /dev/null +++ b/lib/features/cart/widgets/cart_item_card_body.dart @@ -0,0 +1,62 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:ecommerce/core/constants.dart'; +import 'package:flutter/material.dart'; +import '../../../core/utils/size_config.dart'; +import '../../auth/presentation/manger/models/cart.dart'; + +class CartItemCard extends StatelessWidget { + const CartItemCard({ + Key? key, + required this.cart + }); + final Cart? cart; + @override + Widget build(BuildContext context) { + return Row( + children: [ + SizedBox( + width: getProportionateScreenWidth(88), + child: AspectRatio( + aspectRatio: 1.5, + child: Container( + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: const Color(0xfff5f6f9), + borderRadius: BorderRadius.circular(15)), + child: Image.asset(cart!.product.images[0]), + ), + ), + ), + SizedBox( + width: getProportionateScreenWidth(20), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + cart!.product.title, + style: const TextStyle(fontSize: 16, color: Colors.black), + maxLines: 2, + ), + const SizedBox(height: 10), + Text.rich( + TextSpan( + text: "\$${cart!.product.price}", + style: const TextStyle( + fontWeight: FontWeight.w400, + color: kPrimaryColor, + ), + children: [ + TextSpan( + text: " x${cart!.numOfItem}", + style: const TextStyle(color: kTextColor)), + ], + ), + ), + ], + ), + ], + ); + } +} diff --git a/lib/features/cart/widgets/cart_view_body.dart b/lib/features/cart/widgets/cart_view_body.dart new file mode 100644 index 0000000..dd50638 --- /dev/null +++ b/lib/features/cart/widgets/cart_view_body.dart @@ -0,0 +1,51 @@ +// ignore_for_file: use_key_in_widget_constructors + +import 'package:ecommerce/core/utils/size_config.dart'; +import 'package:ecommerce/features/auth/presentation/manger/models/cart.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import 'cart_item_card_body.dart'; + +class CartViewBody extends StatefulWidget { + const CartViewBody({Key? key}); + + @override + State createState() => _CartViewBodyState(); +} + +class _CartViewBodyState extends State { + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(20)), + child: ListView.builder(itemCount: demoCarts.length,itemBuilder: (context,index)=> + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Dismissible( + key: Key(demoCarts[index].product.id.toString()), + direction: DismissDirection.endToStart, + background: Container( + padding: const EdgeInsets.symmetric(horizontal: 20), + decoration: BoxDecoration( + color: const Color(0xffffe6e6), + borderRadius: BorderRadius.circular(15)), + child: Row( + children: [ + const Spacer(), + SvgPicture.asset("assets/icons/Trash.svg") + ], + ), + ), + onDismissed: (direction){ + setState((){ + demoCarts.removeAt(index); + }); + }, + child: CartItemCard(cart: demoCarts[index]), + ), + ), + ), + ); + } +} diff --git a/lib/features/home/widgets/home_header_content.dart b/lib/features/home/widgets/home_header_content.dart index e81b189..12d834f 100644 --- a/lib/features/home/widgets/home_header_content.dart +++ b/lib/features/home/widgets/home_header_content.dart @@ -1,4 +1,6 @@ +import 'package:ecommerce/features/cart/cart_view.dart'; import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import '../../../../../../core/utils/size_config.dart'; import '../../../../../../core/widgets/Custom_search_field.dart'; @@ -18,7 +20,9 @@ class HomeHeader extends StatelessWidget { children: [ const BuildSearchProduct(), CustomIconBtnWithCounter( - onTap: () {}, + onTap: () { + Get.to(()=>const CartView(),transition: Transition.fade); + }, iconPath: "assets/icons/Cart Icon.svg", //numOfItems: 3, ),