elektronika/lib/app/pages/product/screen.dart

263 lines
9.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:loader_overlay/loader_overlay.dart';
import '../../../app/app.dart';
import 'widgets/product_image_header.dart';
import 'widgets/product_info.dart';
import 'widgets/product_specification_tab.dart';
import 'widgets/product_sliver_appbar.dart';
class ProductDetailsPage extends StatelessWidget {
final ProductModel model;
ProductDetailsPage({required this.model});
@override
Widget build(BuildContext context) {
return GetX<ProductController>(
init: ProductController(model),
builder: (pc) => Scaffold(
body: pc.state.isLoading.value
? CustomLoader()
: SafeArea(
top: false,
child: LoaderOverlay(
useDefaultLoading: false,
overlayColor: Colors.transparent,
overlayWidget: CustomLoader(),
child: Scaffold(
appBar: CustomAppbarWidget(leading: AppBarBackBtn()),
body: SliverAppBarWithTabBar(model: model, pc: pc),
bottomNavigationBar: Padding(
padding: const EdgeInsets.only(left: 16.0, right: 16, bottom: 16.0, top: 8),
child: ColoredButton(
title: 'add_to_cart'.tr,
callback: () => pc.onAddToCart(context, model),
btnColor: ThemeColor.mainColor,
),
),
),
),
),
),
);
}
List<Widget> buildSimpleProductScreen(ProductModel model) {
return [
SizedBox(height: 20.h),
ProductNameWidget(model: model),
SizedBox(height: 20.h),
ProductImageHeader(images: model.images, model: model),
SizedBox(height: 20.h),
ProductPriceWidget(model: model),
SizedBox(height: 20.h),
AppTheme.appColorDivider,
Container(
color: Colors.amber,
height: 1.sh - 120.h * 2, // 120.h is appbar height
child: ProductSpecificationsWidget(
model: model,
),
),
];
}
List<Widget> buildConfigurableProductScreen(ProductController pc) {
final selectedOption = pc.state.selectedOption.value;
final List<SimpleOption>? simpleOptions = pc.state.simpleAttribute.value?.options;
final selectedSimpleOption = pc.state.selectedSimpleOption.value;
final List<ProductModel>? optionProducts = selectedOption != null ? selectedOption.variants.products : [];
final attrText = pc.state.attribute.value != null ? pc.state.attribute.value!.attribute.name : '';
final attrValue = pc.state.selectedOption.value != null ? pc.state.selectedOption.value!.option : '';
final List<Option> options = pc.state.attribute.value != null ? pc.state.attribute.value!.options : [];
final ProductModel? selectedProduct = pc.state.selectedProduct.value;
final List<Widget> _list = [
SizedBox(height: 20.h),
selectedProduct != null ? ProductNameWidget(model: selectedProduct) : SizedBox.shrink(),
SizedBox(height: 20.h),
selectedProduct != null
? ProductImageHeader(
model: selectedProduct,
images: selectedOption != null
? selectedOption.images
: selectedSimpleOption != null
? selectedSimpleOption.images
: [],
)
: SizedBox.shrink(),
SizedBox(height: 20.h),
// label
selectedOption != null
? Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 4),
child: Row(
children: [
Text(attrText + ':'),
SizedBox(width: 6),
Text(
attrValue,
style: new TextStyle(fontWeight: FontWeight.bold),
),
],
),
)
: SizedBox.shrink(),
// images
selectedOption != null
? SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: mapIndexed(
options,
(index, Option option) => Padding(
padding: const EdgeInsets.only(left: 8.0),
child: GestureDetector(
onTap: () => pc.onSuperAttributeChange(option),
child: Container(
width: 80.h,
height: 80.h,
padding: const EdgeInsets.all(4),
decoration: new BoxDecoration(
// color: Colors.amberAccent,
border: Border.all(
color: option.option == selectedOption.option
? ThemeColor.mainColor
: Colors.grey.withOpacity(0.50),
width: option.option == selectedOption.option ? 2 : 1,
),
borderRadius: BorderRadius.circular(8)),
// padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 4),
margin: const EdgeInsets.symmetric(horizontal: 4, vertical: 4),
child: cachedImageNetwork(
option.images.length > 0 ? option.images.first.originalImageUrl : '',
BoxFit.fill,
const BorderRadius.all(Radius.circular(4.0)),
0.22.sw,
0.15.sh,
),
),
),
),
).toList(),
),
)
: SizedBox.shrink(),
selectedOption != null ? SizedBox(height: 20.h) : SizedBox.shrink(),
selectedProduct != null ? ProductPriceWidget(model: selectedProduct) : SizedBox.shrink(),
SizedBox(height: 20.h),
AppTheme.appColorDivider,
SizedBox(height: 10),
selectedOption != null
? Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w),
child: Text(
selectedOption.variants.attribute!.name,
style: new TextStyle(fontWeight: FontWeight.bold),
),
)
: SizedBox.shrink(),
SizedBox(height: 10),
optionProducts != null
? Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w),
child: Wrap(
children: mapIndexed(
optionProducts,
(index, ProductModel product) => GestureDetector(
onTap: () => pc.onInnerAttributeChange(product),
child: Container(
decoration: new BoxDecoration(
border: Border.all(
color: product.id == selectedProduct?.id
? ThemeColor.mainColor
: Colors.grey.withOpacity(0.50),
width: product.id == selectedProduct?.id ? 2 : 1,
),
borderRadius: BorderRadius.circular(8)),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
margin: EdgeInsets.only(right: 8),
child: Text(product.optionValue ?? ''),
),
),
).toList(),
),
)
: SizedBox.shrink(),
// simple option label
pc.state.simpleAttribute.value != null
? Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w),
child: Text(
pc.state.simpleAttribute.value?.attribute.name ?? '',
style: new TextStyle(
fontWeight: FontWeight.bold,
),
))
: SizedBox.shrink(),
SizedBox(height: 10),
simpleOptions != null
? Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w),
child: Wrap(
children: mapIndexed(
simpleOptions,
(index, SimpleOption option) => GestureDetector(
onTap: () => pc.onSimpleAttributeChange(option),
child: Container(
decoration: new BoxDecoration(
border: Border.all(
color: option.option == selectedSimpleOption?.option
? ThemeColor.mainColor
: Colors.grey.withOpacity(0.50),
width: option.option == selectedSimpleOption?.option ? 2 : 1,
),
borderRadius: BorderRadius.circular(8)),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
margin: EdgeInsets.only(right: 8),
child: Text(option.product.optionValue ?? ''),
),
),
).toList(),
),
)
: SizedBox.shrink(),
SizedBox(height: 10),
AppTheme.appColorDivider,
selectedProduct != null
? Container(
color: Colors.amber,
height: 1.sh - 120.h * 2, // 120.h is appbar height
child: ProductSpecificationsWidget(
model: model,
),
)
: SizedBox.shrink(),
];
return _list;
}
}