From 81c46b01b8bd9da4ef33ecca931f979061253517 Mon Sep 17 00:00:00 2001 From: Mike Zamayias <29067825+mzamayias@users.noreply.github.com> Date: Sun, 23 Jan 2022 23:04:29 +0200 Subject: [PATCH] phones are showing! --- lib/pages/pages.dart | 2 +- lib/pages/phones/phones_page_view.dart | 15 -- lib/pages/phones/view/phones_page_view.dart | 167 ++++++++++++++++++ .../widgets/phone_specifications_card.dart | 100 +++++++++++ .../view/widgets/specification_field.dart | 33 ++++ .../view_model/phones_page_view_model.dart | 12 ++ lib/services/firestore_service.dart | 24 +-- 7 files changed, 325 insertions(+), 28 deletions(-) delete mode 100644 lib/pages/phones/phones_page_view.dart create mode 100644 lib/pages/phones/view/phones_page_view.dart create mode 100644 lib/pages/phones/view/widgets/phone_specifications_card.dart create mode 100644 lib/pages/phones/view/widgets/specification_field.dart create mode 100644 lib/pages/phones/view_model/phones_page_view_model.dart diff --git a/lib/pages/pages.dart b/lib/pages/pages.dart index b73ce89..35b7112 100644 --- a/lib/pages/pages.dart +++ b/lib/pages/pages.dart @@ -3,7 +3,7 @@ import 'cart/cart_page_view.dart'; import 'contact_us/contact_us_page_view.dart'; import 'home/home_page_view.dart'; import 'orders/orders_page_view.dart'; -import 'phones/phones_page_view.dart'; +import 'phones/view/phones_page_view.dart'; import 'sign_in/view/sign_in_page_view.dart'; import 'sign_up/view/sign_up_page_view.dart'; diff --git a/lib/pages/phones/phones_page_view.dart b/lib/pages/phones/phones_page_view.dart deleted file mode 100644 index 9ec4da4..0000000 --- a/lib/pages/phones/phones_page_view.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:flutter/material.dart'; - -class PhonesPageView extends StatelessWidget { - const PhonesPageView({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Center( - child: Text( - 'Phones Page', - style: Theme.of(context).textTheme.headline4, - ), - ); - } -} diff --git a/lib/pages/phones/view/phones_page_view.dart b/lib/pages/phones/view/phones_page_view.dart new file mode 100644 index 0000000..8a8c128 --- /dev/null +++ b/lib/pages/phones/view/phones_page_view.dart @@ -0,0 +1,167 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_ecommerce_website_demo/models/phone/phone_model.dart'; +import 'package:flutter_ecommerce_website_demo/pages/phones/view/widgets/phone_specifications_card.dart'; +import 'package:flutter_ecommerce_website_demo/pages/phones/view_model/phones_page_view_model.dart'; +import 'package:flutter_ecommerce_website_demo/services/firestore_service.dart'; +import 'package:responsive_builder/responsive_builder.dart'; +import 'package:stacked/stacked.dart'; + +import '../../../locator.dart'; + +class PhonesPageView extends StatelessWidget { + const PhonesPageView({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return StreamBuilder>( + stream: locator().readPhones, + builder: ( + BuildContext context, + AsyncSnapshot> snapshot, + ) { + return ViewModelBuilder.reactive( + viewModelBuilder: () => PhonesPageViewModel(), + builder: ( + BuildContext context, + PhonesPageViewModel model, + Widget? child, + ) { + List _phoneCards = []; + int _middle = _phoneCards.length ~/ 2; + if (snapshot.hasData) { + if (snapshot.data != null) { + model.setPhoneModels(snapshot.data!); + model.setPhoneModels(snapshot.data!); + _phoneCards = List.generate( + model.phoneModels.length, + (index) => PhoneSpecificationsCard( + phone: model.phoneModels[index], + ), + ); + _middle = _phoneCards.length ~/ 2; + } else { + _phoneCards = [ + Center( + child: Text( + 'No Phones', + style: Theme.of(context).textTheme.headline6, + ), + ), + ]; + } + } else if (snapshot.hasError) { + _phoneCards = [ + const Center( + child: Icon( + Icons.error_outline_rounded, + color: Colors.red, + ), + ) + ]; + } else { + _phoneCards = [ + const Center( + child: CircularProgressIndicator(), + ), + ]; + } + return ResponsiveBuilder( + builder: ( + BuildContext context, + SizingInformation sizingInformation, + ) { + return SingleChildScrollView( + child: Align( + alignment: Alignment.topCenter, + child: AnimatedContainer( + constraints: sizingInformation.isDesktop + ? const BoxConstraints(maxWidth: 1200) + : BoxConstraints( + maxWidth: sizingInformation.screenSize.width, + ), + duration: const Duration(milliseconds: 60), + padding: sizingInformation.isDesktop + ? const EdgeInsets.symmetric(horizontal: 90) + : const EdgeInsets.symmetric(horizontal: 30), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Browse Phones', + style: Theme.of(context).textTheme.headline2, + softWrap: true, + overflow: TextOverflow.visible, + ), + if (sizingInformation.isDesktop) + Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: + _phoneCards.sublist(0, _middle).map( + (item) { + return Padding( + padding: const EdgeInsets.symmetric( + vertical: 9, + ), + child: item, + ); + }, + ).toList(), + ), + ), + const SizedBox(width: 18), + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: + _phoneCards.sublist(_middle).map( + (item) { + return Padding( + padding: const EdgeInsets.symmetric( + vertical: 9, + ), + child: item, + ); + }, + ).toList(), + ), + ), + ], + ) + else + ..._phoneCards, + ].map( + (item) { + return Padding( + padding: + const EdgeInsets.symmetric(vertical: 9), + child: item, + ); + }, + ).toList(), + ), + ), + ), + ); + }, + ); + }, + ); + }); + } +} diff --git a/lib/pages/phones/view/widgets/phone_specifications_card.dart b/lib/pages/phones/view/widgets/phone_specifications_card.dart new file mode 100644 index 0000000..6c65dca --- /dev/null +++ b/lib/pages/phones/view/widgets/phone_specifications_card.dart @@ -0,0 +1,100 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; + +import '../../../../models/phone/phone_model.dart'; +import 'specification_field.dart'; + +class PhoneSpecificationsCard extends StatelessWidget { + const PhoneSpecificationsCard({ + Key? key, + required this.phone, + }) : super(key: key); + + final PhoneModel phone; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 6), + child: Card( + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + child: Padding( + padding: const EdgeInsets.all(21), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + CachedNetworkImage( + imageUrl: phone.imageUrl, + placeholder: (context, url) => + const CircularProgressIndicator(), + errorWidget: (context, url, error) => Icon( + Icons.error, + color: Colors.red.shade700, + ), + fit: BoxFit.contain, + ), + Flexible( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // model + SpecificationField( + fieldName: 'Model', + fieldValue: phone.model, + ), + // soc + SpecificationField( + fieldName: 'Soc', + fieldValue: phone.soc, + ), + // ram + SpecificationField( + fieldName: 'Ram', + fieldValue: '${phone.ram} GB', + ), + // storage + SpecificationField( + fieldName: 'Storage', + fieldValue: phone.storage, + ), + // screen size + SpecificationField( + fieldName: 'Screen size', + fieldValue: '${phone.screenSize} inch', + ), + // camera + SpecificationField( + fieldName: 'Camera', + fieldValue: phone.camera, + ), + // sar + SpecificationField( + fieldName: 'SAR', + fieldValue: '${phone.sar} W/kg', + ), + // price + SpecificationField( + fieldName: 'Price', + fieldValue: '€${phone.price}', + ), + // quantity + SpecificationField( + fieldName: 'Stock', + fieldValue: '${phone.stock}', + ), + ], + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/phones/view/widgets/specification_field.dart b/lib/pages/phones/view/widgets/specification_field.dart new file mode 100644 index 0000000..660da11 --- /dev/null +++ b/lib/pages/phones/view/widgets/specification_field.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; + +class SpecificationField extends StatelessWidget { + final String fieldName; + final String fieldValue; + + const SpecificationField({ + Key? key, + required this.fieldName, + required this.fieldValue, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Flexible( + child: SelectableText.rich( + TextSpan( + children: [ + TextSpan( + text: '$fieldName ', + style: const TextStyle( + fontWeight: FontWeight.w900, color: Colors.orange), + ), + TextSpan( + text: fieldValue, + ), + ], + ), + textAlign: TextAlign.left, + ), + ); + } +} diff --git a/lib/pages/phones/view_model/phones_page_view_model.dart b/lib/pages/phones/view_model/phones_page_view_model.dart new file mode 100644 index 0000000..e5eee25 --- /dev/null +++ b/lib/pages/phones/view_model/phones_page_view_model.dart @@ -0,0 +1,12 @@ +import 'package:flutter_ecommerce_website_demo/models/phone/phone_model.dart'; +import 'package:stacked/stacked.dart'; + +class PhonesPageViewModel extends BaseViewModel { + List _phoneModels = []; + + List get phoneModels => _phoneModels; + + void setPhoneModels(List phoneModels) { + _phoneModels = phoneModels; + } +} diff --git a/lib/services/firestore_service.dart b/lib/services/firestore_service.dart index 5dd1e34..1f2cc48 100644 --- a/lib/services/firestore_service.dart +++ b/lib/services/firestore_service.dart @@ -96,16 +96,16 @@ class FirestoreService { // return userCollection.doc(uid).snapshots(); // } - // // Read Phone Catalog - // Stream?> get readPhones { - // return phoneCollection.snapshots().map( - // (snapshot) { - // return snapshot.docs.map( - // (doc) { - // return PhoneModel.fromDocument(doc); - // }, - // ).toList(); - // }, - // ); - // } + // Read Phone Catalog + Stream> get readPhones { + return phoneCollection.snapshots().map( + (snapshot) { + return snapshot.docs.map( + (doc) { + return PhoneModel.fromDocument(doc); + }, + ).toList(); + }, + ); + } }