diff --git a/lib/model/product_model.dart b/lib/model/product_model.dart index ac214eb..554bd69 100644 --- a/lib/model/product_model.dart +++ b/lib/model/product_model.dart @@ -1,3 +1,4 @@ + class Product { Product({ this.text, @@ -6,11 +7,16 @@ class Product { this.image, this.seller, this.height, + this.id, + this.dbId }); - factory Product.fromJson(dynamic productData) { + factory Product.fromJson(Map productData) { + // log('prodcut id : ${productData['_id'].runtimeType}'); return Product( - amount: productData['amount'].toString(), + amount: productData['amount'], + id : productData['id'], + dbId: productData['_id'], image: productData['image'].toString() == '' ? 'assets/items/${productData['id']}.png' : productData['image'].toString(), @@ -25,8 +31,10 @@ class Product { final String? text; final String? owner; - final String? amount; + final int? amount; final String? image; final String? seller; final int? height; + final int? id; + final String? dbId; } diff --git a/lib/services/product_service.dart b/lib/services/product_service.dart index ee82230..6d4c2a5 100644 --- a/lib/services/product_service.dart +++ b/lib/services/product_service.dart @@ -15,4 +15,15 @@ class ProductService { ) .toList(); } + + Future getProductDetails(String index) async { + print('index : $index'); + final http.Response response = await http.get( + Uri.parse('https://himanshusharma89-api.herokuapp.com/relic_bazaar/products/$index'), + ); + final Product product = Product.fromJson(json.decode(response.body)); + print(product.text); + return product; + } + } diff --git a/lib/views/cart_view.dart b/lib/views/cart_view.dart index 542b4c6..8dec52f 100644 --- a/lib/views/cart_view.dart +++ b/lib/views/cart_view.dart @@ -3,6 +3,7 @@ import 'package:relic_bazaar/helpers/constants.dart'; import 'package:relic_bazaar/widgets/payment/cart_item.dart'; import 'package:relic_bazaar/widgets/payment/payment_window.dart'; import 'package:relic_bazaar/widgets/retro_button.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class Cart extends StatefulWidget { const Cart({ @@ -17,109 +18,129 @@ class Cart extends StatefulWidget { } class _CartState extends State { + + Future> getMyCart() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + return prefs.getStringList('myCart') ?? []; + } + @override Widget build(BuildContext context) { final double height = MediaQuery.of(context).size.height; final double width = MediaQuery.of(context).size.width; - return Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12, - ), - child: ListView( - children: [ - SizedBox( - height: height * 0.01, - ), - const Text( - 'Your Cart', - style: TextStyle( - fontSize: 30, - color: Colors.white, - fontWeight: FontWeight.w700, + return FutureBuilder>( + future: getMyCart(), + builder: (_ , AsyncSnapshot> snapShot){ + if(snapShot.hasData){ + List myCart = snapShot.data ?? []; + return Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12, ), - textAlign: TextAlign.left, - ), - SizedBox( - height: height * 0.01, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - GestureDetector( - onTap: () { - setState(() { - widget.pageController!.jumpTo(0); - }); - }, - child: RelicBazaarStackedView( - upperColor: Colors.white, - height: height * 0.045, - width: width * 0.4, - borderColor: Colors.white, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: const [ - Icon( - Icons.arrow_back, - size: 20, + child: ListView( + children: [ + SizedBox( + height: height * 0.01, + ), + const Text( + 'Your Cart', + style: TextStyle( + fontSize: 30, + color: Colors.white, + fontWeight: FontWeight.w700, + ), + textAlign: TextAlign.left, + ), + SizedBox( + height: height * 0.01, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () { + setState(() { + widget.pageController!.jumpTo(0); + }); + }, + child: RelicBazaarStackedView( + upperColor: Colors.white, + height: height * 0.045, + width: width * 0.4, + borderColor: Colors.white, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.arrow_back, + size: 20, + ), + Text( + ' back to shop', + style: TextStyle( + fontFamily: 'pix M 8pt', + fontSize: 15, + fontWeight: FontWeight.bold, + color: RelicColors.primaryBlack, + ), + ), + ], + ), ), - Text( - ' back to shop', - style: TextStyle( - fontFamily: 'pix M 8pt', - fontSize: 15, - fontWeight: FontWeight.bold, - color: RelicColors.primaryBlack, + ), + RelicBazaarStackedView( + upperColor: Colors.black, + lowerColor: Colors.white, + height: height * 0.045, + width: width * 0.22, + child: Center( + child: Text( + myCart.length.toString(), + style: const TextStyle( + fontFamily: 'pix M 8pt', + fontSize: 15, + color: Colors.white, + ), + textAlign: TextAlign.center, ), ), - ], - ), + ), + ], + ), + const Divider( + color: Colors.white, + thickness: 0.9, ), - ), - RelicBazaarStackedView( - upperColor: Colors.black, - lowerColor: Colors.white, - height: height * 0.045, - width: width * 0.22, - child: const Center( - child: Text( - '5 items', - style: TextStyle( - fontFamily: 'pix M 8pt', - fontSize: 15, - color: Colors.white, + Column( + children: [ + ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: myCart.length, + itemBuilder: (BuildContext context, int index) { + return CartItem(index : myCart[index], pageController: widget.pageController,); + }, ), - textAlign: TextAlign.center, - ), + Align( + alignment: Alignment.bottomCenter, + child: PaymentWindow(), + ), + SizedBox( + height: height * 0.08, + ), + ], ), - ), - ], - ), - const Divider( - color: Colors.white, - thickness: 0.9, - ), - Column( - children: [ - ListView.builder( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: 5, - itemBuilder: (BuildContext context, int index) { - return CartItem(); - }, - ), - Align( - alignment: Alignment.bottomCenter, - child: PaymentWindow(), - ), - SizedBox( - height: height * 0.08, - ), - ], + ], + ), + ); + } + return const Center( + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(Colors.white), ), - ], - ), + ); + + } ); } } diff --git a/lib/widgets/payment/cart_item.dart b/lib/widgets/payment/cart_item.dart index 0cb352c..628738e 100644 --- a/lib/widgets/payment/cart_item.dart +++ b/lib/widgets/payment/cart_item.dart @@ -1,14 +1,24 @@ import 'package:flutter/material.dart'; +import 'package:relic_bazaar/helpers/constants.dart'; +import 'package:relic_bazaar/model/product_model.dart'; +import 'package:relic_bazaar/services/product_service.dart'; import 'package:relic_bazaar/widgets/retro_button.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:shimmer/shimmer.dart'; class CartItem extends StatefulWidget { + CartItem({required this.index, this.pageController}); + final String index; + final PageController? pageController; @override _CartItemState createState() => _CartItemState(); } class _CartItemState extends State { TextEditingController? controller; - + Product? product; + int quantity = 1; + int itemTotal = 0; @override void initState() { super.initState(); @@ -20,99 +30,198 @@ class _CartItemState extends State { Widget build(BuildContext context) { final double height = MediaQuery.of(context).size.height; final double width = MediaQuery.of(context).size.width; - return Padding( - padding: const EdgeInsets.only(bottom: 10.0), - child: Row( - children: [ - RelicBazaarStackedView( - height: width * 0.3, - width: width * 0.3, - upperColor: Colors.white, - ), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + return Container( + margin: const EdgeInsets.symmetric(vertical: 5), + child: FutureBuilder( + future: ProductService().getProductDetails(widget.index), + builder: (_ , AsyncSnapshot snapShot){ + if(snapShot.hasData){ + Product product = snapShot.data!; + itemTotal = product.amount! * quantity; + return Padding( + padding: const EdgeInsets.only(bottom: 10.0), + child: Row( children: [ - const Text( - 'Product Name', - style: TextStyle( - fontSize: 21, - fontWeight: FontWeight.bold, - color: Colors.white), + RelicBazaarStackedView( + height: width * 0.3, + width: width * 0.3, + upperColor: Colors.white, + child: Image.asset(product.image!), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + product.text ?? 'Product Name', + style: const TextStyle( + fontSize: 21, + fontWeight: FontWeight.bold, + color: Colors.white), + ), + Text( + product.owner ?? 'Product owner', + style: const TextStyle(color: Colors.white), + ), + SizedBox( + height: height * 0.005, + ), + Container( + height: height * 0.04, + width: width * 0.25, + decoration: const BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + offset: Offset(0, 4), + blurRadius: 8, + color: Colors.black26) + ] + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + GestureDetector( + onTap: addQuantity, + child: const Icon(Icons.add), + ), + Expanded( + child: TextField( + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.bold, + ), + readOnly: true, + controller: controller, + decoration: const InputDecoration( + border: InputBorder.none, + isDense: true, + contentPadding: EdgeInsets.all(0)), + )), + GestureDetector( + onTap: subQuantity, + child: const Icon(Icons.remove), + ), + ], + ), + ) + ], + ), + ), ), - const Text( - 'Name', - style: TextStyle(color: Colors.white), + Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + IconButton( + onPressed: () async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + List myCart = prefs.getStringList('myCart') ?? []; + myCart.remove(widget.index); + prefs.setStringList('myCart', myCart); + widget.pageController!.jumpToPage(0); + }, + icon: const Icon(Icons.delete) , color: RelicColors.warningColor,), + Text( + '₹ $itemTotal', + style: const TextStyle( + fontWeight: FontWeight.bold, color: Colors.white, fontSize: 17), + ) + ], ), - SizedBox( - height: height * 0.005, + + ], + ), + ); + } + return Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 120.0, + height: 120.0, + child: Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[100]!, + child: Container( + color: Colors.grey, + ), ), - Container( - // width: 75, - // height: 25, - height: height * 0.04, - width: width * 0.25, - decoration: const BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow( - offset: Offset(0, 4), - blurRadius: 8, - color: Colors.black26) - ]), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - GestureDetector( - onTap: addQuantity, - child: const Icon(Icons.add), + ), + const SizedBox( + width: 20, + ), + Column( + children: [ + Container( + margin: const EdgeInsets.symmetric(vertical: 5), + width: MediaQuery.of(context).size.width * 0.5, + height: 20.0, + child: Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[100]!, + child: Container( + color: Colors.grey, ), - Expanded( - child: TextField( - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 17, - fontWeight: FontWeight.bold, - ), - readOnly: true, - controller: controller, - decoration: const InputDecoration( - border: InputBorder.none, - isDense: true, - contentPadding: EdgeInsets.all(0)), - )), - GestureDetector( - onTap: subQuantity, - child: const Icon(Icons.remove), + ), + ), + Container( + margin: const EdgeInsets.only(bottom: 5), + width: MediaQuery.of(context).size.width * 0.5, + height: 20.0, + child: Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[100]!, + child: Container( + color: Colors.grey, ), - ], + ), ), - ) - ], - ), + Container( + margin: const EdgeInsets.only(bottom: 5), + width: MediaQuery.of(context).size.width * 0.5, + height: 20.0, + child: Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[100]!, + child: Container( + color: Colors.grey, + ), + ), + ), + ], + ), + ], ), - ), - const Text( - '₹65654', - style: TextStyle( - fontWeight: FontWeight.bold, color: Colors.white, fontSize: 17), - ) - ], + ); + + }, + ), ); } void subQuantity() { if (int.parse(controller!.text) > 1) { - controller!.text = (int.parse(controller!.text) - 1).toString(); + controller!.text = (int.parse(controller!.text) - 1).toString(); + setState(() { + quantity = int.parse(controller!.text); + print('quantity : $quantity'); + }); } } void addQuantity() { if (int.parse(controller!.text) < 50) { - controller!.text = (int.parse(controller!.text) + 1).toString(); + controller!.text = (int.parse(controller!.text) + 1).toString(); + setState(() { + quantity = int.parse(controller!.text); + print('quantity : $quantity'); + }); } } -} +} \ No newline at end of file diff --git a/lib/widgets/payment/payment_window.dart b/lib/widgets/payment/payment_window.dart index 40a3930..4e8ed53 100644 --- a/lib/widgets/payment/payment_window.dart +++ b/lib/widgets/payment/payment_window.dart @@ -80,17 +80,18 @@ class _PaymentWindowState extends State { children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: const [ - Text( + children: [ + const Text( 'CART TOTAL', style: TextStyle(fontSize: 17), ), - Text( - '₹35465', - style: TextStyle(fontSize: 17), + const Text( + '1000', + style: const TextStyle(fontSize: 17), ), ], ), + SizedBox( height: height * 0.002, ), @@ -110,7 +111,7 @@ class _PaymentWindowState extends State { ), Padding( padding: - const EdgeInsets.symmetric(horizontal: 10, vertical: 2), + const EdgeInsets.symmetric(horizontal: 10, vertical: 2), child: Column( children: [ SizedBox( @@ -167,7 +168,7 @@ class _PaymentWindowState extends State { padding: const EdgeInsets.all(4.0), child: Row( mainAxisAlignment: - MainAxisAlignment.spaceBetween, + MainAxisAlignment.spaceBetween, children: [ FittedBox( child: Text( @@ -256,7 +257,7 @@ class _PaymentWindowState extends State { padding: const EdgeInsets.all(4.0), child: Row( mainAxisAlignment: - MainAxisAlignment.spaceBetween, + MainAxisAlignment.spaceBetween, children: [ FittedBox( child: Text( @@ -296,14 +297,14 @@ class _PaymentWindowState extends State { ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: const [ - Text( + children: [ + const Text( 'TOTAL', style: TextStyle(fontSize: 17), ), - Text( - '₹35131', - style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), + const Text( + '1000', + style: const TextStyle(fontSize: 25, fontWeight: FontWeight.bold), ), ], ), diff --git a/lib/widgets/product/product_card.dart b/lib/widgets/product/product_card.dart index 28530ae..0d50319 100644 --- a/lib/widgets/product/product_card.dart +++ b/lib/widgets/product/product_card.dart @@ -59,7 +59,7 @@ class ProductCard extends StatelessWidget { height: 20, ), Text( - product!.amount!, + product!.amount!.toString(), style: const TextStyle( fontSize: 18, color: Colors.white, diff --git a/lib/widgets/product/product_page.dart b/lib/widgets/product/product_page.dart index 450d4e5..f7cdd48 100644 --- a/lib/widgets/product/product_page.dart +++ b/lib/widgets/product/product_page.dart @@ -5,6 +5,7 @@ import 'package:relic_bazaar/helpers/ad_state.dart'; import 'package:relic_bazaar/helpers/constants.dart'; import 'package:relic_bazaar/model/product_model.dart'; import 'package:relic_bazaar/widgets/back_button.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import '../../helpers/app_icons.dart'; import '../retro_button.dart'; @@ -19,7 +20,6 @@ class ProductPage extends StatefulWidget { class _ProductPageState extends State { BannerAd? bannerAd; - @override void didChangeDependencies() { final AdState adState = Provider.of(context); @@ -46,24 +46,29 @@ class _ProductPageState extends State { elevation: 0.0, backgroundColor: Colors.transparent, leading: appBarBackButton(context), - actions: const [ - Center( - child: RelicBazaarStackedView( - upperColor: Colors.white, - width: 35, - height: 35, - borderColor: Colors.white, - child: Padding( - padding: EdgeInsets.only(top: 7, left: 6), - child: Icon( - RelicIcons.cart, - size: 32, - color: Colors.black, + actions: [ + InkWell( + onTap: (){ + Navigator.pop(context); + }, + child: const Center( + child: RelicBazaarStackedView( + upperColor: Colors.white, + width: 35, + height: 35, + borderColor: Colors.white, + child: Padding( + padding: EdgeInsets.only(top: 7, left: 6), + child: Icon( + RelicIcons.cart, + size: 32, + color: Colors.black, + ), ), ), ), ), - SizedBox( + const SizedBox( width: 10, ) ], @@ -187,7 +192,7 @@ class _ProductPageState extends State { borderColor: Colors.white, child: Center( child: Text( - widget.product!.amount!, + widget.product!.amount!.toString(), style: const TextStyle( fontWeight: FontWeight.bold, color: RelicColors.primaryColor, @@ -273,28 +278,39 @@ class _ProductPageState extends State { SizedBox( width: width * 0.02, ), - RelicBazaarStackedView( - upperColor: Colors.white, - width: width * 0.35, - height: height * 0.05, - borderColor: Colors.white, - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceAround, - children: const [ - Icon( - Icons.add, - color: RelicColors.primaryColor, - ), - Text( - 'ADD TO CART', - style: TextStyle( - color: RelicColors - .primaryColor, - fontWeight: FontWeight.bold, - fontSize: 15), - ), - ], + InkWell( + onTapDown: (_){ + + }, + onTap: () async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + List myCart = prefs.getStringList('myCart') ?? []; + myCart.add(widget.product!.id!.toString()); + prefs.setStringList('myCart', myCart); + }, + child: RelicBazaarStackedView( + upperColor: Colors.white, + width: width * 0.35, + height: height * 0.05, + borderColor: Colors.white, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceAround, + children: const [ + Icon( + Icons.add, + color: RelicColors.primaryColor, + ), + Text( + 'ADD TO CART', + style: TextStyle( + color: RelicColors + .primaryColor, + fontWeight: FontWeight.bold, + fontSize: 15), + ), + ], + ), ), ) ], diff --git a/pubspec.yaml b/pubspec.yaml index fb815fa..51cf1dc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -34,6 +34,8 @@ dependencies: image_picker: any firebase_storage: ^10.0.3 intl: ^0.17.0 + shared_preferences: + shimmer: ^2.0.0 dev_dependencies: flutter_test: diff --git a/test/widget_test.dart b/test/widget_test.dart index f1c5215..a85b81c 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -30,7 +30,7 @@ void main() { product: Product( text: 'lorem', owner: 'ipsum', - amount: 'dolor', + amount: 0, image: 'assets/items/3.png', seller: 'seller', height: 10, @@ -64,7 +64,7 @@ void main() { child: ProductPage( product: Product( owner: 'owner', - amount: 'amount', + amount: 0, seller: 'seller', height: 10, text: 'test string', @@ -136,7 +136,7 @@ void main() { textDirection: TextDirection.ltr, child: Scaffold( body: MaterialApp( - home: CartItem(), + home: CartItem(index: '1',), ), ), ),