diff --git a/lib/main.dart b/lib/main.dart index 99e6a46..4f5aeda 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_ecommerce_app/src/config/route.dart'; import 'package:google_fonts/google_fonts.dart'; import 'src/pages/home_page.dart'; import 'src/themes/theme.dart'; @@ -16,7 +17,7 @@ class MyApp extends StatelessWidget { ), ), debugShowCheckedModeBanner: false , - home: MyHomePage(title: 'Flutter Demo Home Page'), + routes: Routes.getRoute(), ); } } \ No newline at end of file diff --git a/lib/src/config/route.dart b/lib/src/config/route.dart new file mode 100644 index 0000000..993e919 --- /dev/null +++ b/lib/src/config/route.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_ecommerce_app/src/pages/home_page.dart'; +import 'package:flutter_ecommerce_app/src/pages/product_detail.dart'; + +class Routes{ + static Map getRoute(){ + return { + '/': (_) => MyHomePage(), + '/detail': (_) => ProductDetailPage() + }; + } +} \ No newline at end of file diff --git a/lib/src/model/data.dart b/lib/src/model/data.dart index 22ddb11..74bd3a8 100644 --- a/lib/src/model/data.dart +++ b/lib/src/model/data.dart @@ -21,13 +21,16 @@ class AppData { ]; static List categoryList = [ Category(), - Category( - name: "Sneakers", - image: 'assets/shoe_thumb_tilt.png', - isSelected: true), - Category(id:1,name: "Watch", image: 'assets/watch.png'), + Category(id:1,name: "Sneakers",image: 'assets/shoe_thumb_2.png',isSelected: true), Category(id:2,name: "Jacket", image: 'assets/jacket.png'), Category(id:3,name: "Watch", image: 'assets/watch.png'), Category(id:4,name: "Watch", image: 'assets/watch.png'), ]; + static List showThumbnailList = [ + "assets/shoe_thumb_5.png", + "assets/shoe_thumb_1.png", + "assets/shoe_thumb_4.png", + "assets/shoe_thumb_3.png", + ]; + static String description = "Clean lines, versatile and timeless—the people shoe returns with the Nike Air Max 90. Featuring the same iconic Waffle sole, stitched overlays and classic TPU accents you come to love, it lets you walk among the pantheon of Air. ßNothing as fly, nothing as comfortable, nothing as proven. The Nike Air Max 90 stays true to its OG running roots with the iconic Waffle sole, stitched overlays and classic TPU details. Classic colours celebrate your fresh look while Max Air cushioning adds comfort to the journey."; } diff --git a/lib/src/pages/product_detail.dart b/lib/src/pages/product_detail.dart new file mode 100644 index 0000000..5fe5853 --- /dev/null +++ b/lib/src/pages/product_detail.dart @@ -0,0 +1,347 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_ecommerce_app/src/model/category.dart'; +import 'package:flutter_ecommerce_app/src/model/data.dart'; +import 'package:flutter_ecommerce_app/src/themes/light_color.dart'; +import 'package:flutter_ecommerce_app/src/themes/theme.dart'; +import 'package:flutter_ecommerce_app/src/wigets/prduct_icon.dart'; +import 'package:flutter_ecommerce_app/src/wigets/title_text.dart'; + +class ProductDetailPage extends StatefulWidget { + ProductDetailPage({Key key}) : super(key: key); + + @override + _ProductDetailPageState createState() => _ProductDetailPageState(); +} + +class _ProductDetailPageState extends State { + Widget _appBar() { + return Container( + padding: AppTheme.padding, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + Navigator.of(context).pop(); + }, + child: _icon(Icons.arrow_back_ios, + color: Colors.black54, size: 15, padding: 12, isOutLine: true), + ), + _icon(Icons.favorite, + color: LightColor.red, size: 15, padding: 12, isOutLine: false), + ], + ), + ); + } + + Widget _icon(IconData icon, + {Color color = LightColor.iconColor, + double size = 20, + double padding = 10, + bool isOutLine = false}) { + return Container( + height: 40, + width: 40, + padding: EdgeInsets.all(padding), + margin: EdgeInsets.all(padding), + decoration: BoxDecoration( + border: Border.all( + color: LightColor.iconColor, + style: isOutLine ? BorderStyle.solid : BorderStyle.none), + borderRadius: BorderRadius.all(Radius.circular(13)), + color: isOutLine ? Colors.transparent : Theme.of(context).backgroundColor, + boxShadow: [ + BoxShadow( + color: Color(0xfff8f8f8), + blurRadius: 5, + spreadRadius: 10, + offset: Offset(5,5) + ), + ], + ), + child: Icon(icon, color: color, size: size), + ); + } + + Widget _productImage() { + return Stack( + alignment: Alignment.bottomCenter, + children: [ + TitleText( + text: "AIP", + fontSize: 160, + color: LightColor.lightGrey, + ), + Image.asset('assets/show_1.png') + ], + ); + } + + Widget _categoryWidget() { + return Container( + margin: EdgeInsets.symmetric(vertical: 0), + width: AppTheme.fullWidth(context), + height: 80, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: + AppData.showThumbnailList.map((x) => _thumbnail(x)).toList()), + ); + } + + Widget _thumbnail(String image) { + return Container( + height: 40, + width: 50, + margin: EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + border: Border.all( + color: LightColor.grey, + ), + borderRadius: BorderRadius.all( + Radius.circular(13), + ), + // color: Theme.of(context).backgroundColor, + ), + child: Image.asset(image), + ); + } + + Widget _detailWidget() { + return DraggableScrollableSheet( + maxChildSize: .8, + initialChildSize: .53, + minChildSize: .53, + builder: (context, scrollController) { + return Container( + padding: AppTheme.padding, + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(40), + topRight: Radius.circular(40), + ), + color: Colors.white), + child: SingleChildScrollView( + controller: scrollController, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + SizedBox(height: 5), + Container( + alignment: Alignment.center, + child: Container( + width: 50, + height: 5, + decoration: BoxDecoration( + color: LightColor.iconColor, + borderRadius: BorderRadius.all(Radius.circular(10))), + ), + ), + SizedBox(height: 10), + Container( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TitleText(text: "NIKE AIR MAX 200", fontSize: 25), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + TitleText( + text: "\$ ", + fontSize: 18, + color: LightColor.red, + ), + TitleText( + text: "240", + fontSize: 25, + ), + ], + ), + Row( + children: [ + Icon(Icons.star, + color: LightColor.yellowColor, size: 17), + Icon(Icons.star, + color: LightColor.yellowColor, size: 17), + Icon(Icons.star, + color: LightColor.yellowColor, size: 17), + Icon(Icons.star, + color: LightColor.yellowColor, size: 17), + Icon(Icons.star_border, size: 17), + ], + ), + ], + ), + ], + ), + ), + SizedBox( + height: 20, + ), + _availableSize(), + SizedBox( + height: 20, + ), + _availableColor(), + SizedBox( + height: 20, + ), + _description(), + ], + ), + ), + ); + }, + ); + } + + Widget _availableSize() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TitleText( + text: "Available Size", + fontSize: 14, + ), + SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + _sizeWidget("US 6"), + _sizeWidget("US 7", isSelected: true), + _sizeWidget("US 8"), + _sizeWidget("US 9"), + ], + ) + ], + ); + } + + Widget _sizeWidget(String text, + {Color color = LightColor.iconColor, bool isSelected = false}) { + return Container( + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + border: Border.all( + color: LightColor.iconColor, + style: !isSelected ? BorderStyle.solid : BorderStyle.none), + borderRadius: BorderRadius.all(Radius.circular(10)), + color: + isSelected ? LightColor.orange : Theme.of(context).backgroundColor, + ), + child: TitleText( + text: text, + fontSize: 16, + color: isSelected ? LightColor.background : LightColor.titleTextColor, + ), + ); + } + + Widget _availableColor() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TitleText( + text: "Available Size", + fontSize: 14, + ), + SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + _colorWidget(LightColor.yellowColor, isSelected: true), + SizedBox( + width: 30, + ), + _colorWidget(LightColor.lightBlue), + SizedBox( + width: 30, + ), + _colorWidget(LightColor.black), + SizedBox( + width: 30, + ), + _colorWidget(LightColor.red), + SizedBox( + width: 30, + ), + _colorWidget(LightColor.skyBlue), + ], + ) + ], + ); + } + + Widget _colorWidget(Color color, {bool isSelected = false}) { + return CircleAvatar( + radius: 12, + backgroundColor: color.withAlpha(150), + child: isSelected + ? Icon( + Icons.check_circle, + color: color, + size: 18, + ) + : CircleAvatar(radius: 7, backgroundColor: color), + ); + } + + Widget _description() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TitleText( + text: "Available Size", + fontSize: 14, + ), + SizedBox(height: 20), + Text(AppData.description), + ], + ); + } + + FloatingActionButton _flotingButton(){ + return FloatingActionButton( + onPressed: (){}, + backgroundColor: LightColor.orange, + child: Icon(Icons.shopping_basket, color:Theme.of(context).floatingActionButtonTheme.backgroundColor), + ); + } + @override + Widget build(BuildContext context) { + return Scaffold( + floatingActionButton: _flotingButton(), + body: SafeArea( + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + Color(0xfffbfbfb), + Color(0xfff7f7f7), + ], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + )), + child: Stack( + children: [ + Column( + children: [ + _appBar(), + _productImage(), + _categoryWidget(), + ], + ), + _detailWidget() + ], + ), + ), + ), + ); + } +} diff --git a/lib/src/themes/light_color.dart b/lib/src/themes/light_color.dart index d41c2bf..4717fd1 100644 --- a/lib/src/themes/light_color.dart +++ b/lib/src/themes/light_color.dart @@ -18,6 +18,7 @@ class LightColor { static const Color darkgrey = Color(0xff747F8F); static const Color iconColor = Color(0xffa8a09b); + static const Color yellowColor = Color(0xfffbba01); static const Color black = Color(0xff20262C); static const Color lightblack = Color(0xff5F5F60); diff --git a/lib/src/wigets/prduct_icon.dart b/lib/src/wigets/prduct_icon.dart index 3deb9fd..896c5e0 100644 --- a/lib/src/wigets/prduct_icon.dart +++ b/lib/src/wigets/prduct_icon.dart @@ -35,11 +35,10 @@ class ProducIcon extends StatelessWidget { ], ), child: Row( - children: [ model.image != null ? Image.asset(model.image) : SizedBox(), - Container( - + model.name == null ? Container() + : Container( child: TitleText( text: model.name, fontWeight: FontWeight.w700, diff --git a/lib/src/wigets/product_card.dart b/lib/src/wigets/product_card.dart index 38937aa..af99f6a 100644 --- a/lib/src/wigets/product_card.dart +++ b/lib/src/wigets/product_card.dart @@ -25,6 +25,7 @@ class _ProductCardState extends State { Widget build(BuildContext context) { return InkWell( onTap: () { + Navigator.of(context).pushNamed('/detail'); setState(() { // model.isSelected = !model.isSelected; // AppData.productList.forEach((x) {