feat: photo_detail tag
parent
ed37fed45d
commit
2562328146
|
|
@ -165,4 +165,10 @@ class GlobalStyle {
|
||||||
|
|
||||||
static const Icon iconTime =
|
static const Icon iconTime =
|
||||||
Icon(Icons.access_time, size: 14, color: SOFT_GREY);
|
Icon(Icons.access_time, size: 14, color: SOFT_GREY);
|
||||||
|
|
||||||
|
static const TextStyle detailFoodOptions =
|
||||||
|
TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.bold);
|
||||||
|
|
||||||
|
static const TextStyle detailFoodSubOptions =
|
||||||
|
TextStyle(color: BLACK77, fontSize: 12);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ class ObjectBox {
|
||||||
etabBox.removeAll();
|
etabBox.removeAll();
|
||||||
concurrentBox.removeAll();
|
concurrentBox.removeAll();
|
||||||
visiteBox.removeAll();
|
visiteBox.removeAll();
|
||||||
visiteTagBox.removeAll();
|
//visiteTagBox.removeAll();
|
||||||
//photoBox.removeAll();
|
//photoBox.removeAll();
|
||||||
//photoTypologyBox.removeAll();
|
//photoTypologyBox.removeAll();
|
||||||
|
|
||||||
|
|
@ -336,6 +336,15 @@ class ObjectBox {
|
||||||
store.box<VisiteTag>().put(_VisiteTag);
|
store.box<VisiteTag>().put(_VisiteTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> getVisiteTagsLabels() {
|
||||||
|
final query = visiteTagBox
|
||||||
|
.query(VisiteTag_.langage.equals('fr'))
|
||||||
|
.order(VisiteTag_.libelle)
|
||||||
|
.build();
|
||||||
|
final visiteTags = query.find();
|
||||||
|
return visiteTags.map((VisiteTag) => VisiteTag.libelle).toList();
|
||||||
|
}
|
||||||
|
|
||||||
int getVisiteTagCount() {
|
int getVisiteTagCount() {
|
||||||
return visiteTagBox.count();
|
return visiteTagBox.count();
|
||||||
}
|
}
|
||||||
|
|
@ -437,6 +446,14 @@ class ObjectBox {
|
||||||
store.box<PhotoTypology>().put(_PhotoTypology);
|
store.box<PhotoTypology>().put(_PhotoTypology);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> getPhotoTypologiesLabels() {
|
||||||
|
final query = photoTypologyBox.query().order(PhotoTypology_.ordre).build();
|
||||||
|
final photoTypologies = query.find();
|
||||||
|
return photoTypologies
|
||||||
|
.map((photoTypology) => photoTypology.libelle)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
Stream<List<PhotoTypology>> getPhotoTypologies() {
|
Stream<List<PhotoTypology>> getPhotoTypologies() {
|
||||||
// Query for all Typologies, sorted by their order.
|
// Query for all Typologies, sorted by their order.
|
||||||
// https://docs.objectbox.io/queries
|
// https://docs.objectbox.io/queries
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,19 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:carousel_slider/carousel_slider.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
|
import 'package:filter_list/filter_list.dart';
|
||||||
|
|
||||||
import 'package:mobdr/config/constant.dart';
|
import 'package:mobdr/config/constant.dart';
|
||||||
import 'package:mobdr/config/global_style.dart';
|
import 'package:mobdr/config/global_style.dart';
|
||||||
import 'package:mobdr/model/related_product_model.dart';
|
import 'package:mobdr/main.dart';
|
||||||
import 'package:mobdr/model/review_model.dart';
|
|
||||||
import 'package:mobdr/ui/general/chat_us.dart';
|
import 'package:mobdr/ui/general/chat_us.dart';
|
||||||
import 'package:mobdr/ui/general/notification.dart';
|
import 'package:mobdr/ui/general/notification.dart';
|
||||||
import 'package:mobdr/ui/general/product_detail/delivery_estimated.dart';
|
|
||||||
import 'package:mobdr/ui/general/product_detail/product_description.dart';
|
|
||||||
import 'package:mobdr/ui/general/product_detail/product_review.dart';
|
|
||||||
import 'package:mobdr/ui/home/product_category.dart';
|
import 'package:mobdr/ui/home/product_category.dart';
|
||||||
import 'package:mobdr/ui/home/search.dart';
|
import 'package:mobdr/ui/home/search.dart';
|
||||||
import 'package:mobdr/ui/reusable/reusable_widget.dart';
|
import 'package:mobdr/ui/reusable/reusable_widget.dart';
|
||||||
import 'package:mobdr/ui/shopping_cart/tab_shopping_cart.dart';
|
import 'package:mobdr/ui/shopping_cart/tab_shopping_cart.dart';
|
||||||
import 'package:mobdr/ui/reusable/cache_image_network.dart';
|
|
||||||
import 'package:mobdr/ui/reusable/global_function.dart';
|
import 'package:mobdr/ui/reusable/global_function.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
|
||||||
|
|
||||||
class PhotoDetailPage extends StatefulWidget {
|
class PhotoDetailPage extends StatefulWidget {
|
||||||
final String name;
|
final String name;
|
||||||
|
|
@ -50,40 +46,22 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
final _globalFunction = GlobalFunction();
|
final _globalFunction = GlobalFunction();
|
||||||
final _reusableWidget = ReusableWidget();
|
final _reusableWidget = ReusableWidget();
|
||||||
|
|
||||||
final List<String> _imgProductSlider = [];
|
// Typology list
|
||||||
int _currentImageSlider = 0;
|
List<String> _typologyList = objectbox.getPhotoTypologiesLabels();
|
||||||
|
int _typologyIndex = 0;
|
||||||
|
|
||||||
// size data
|
List<String> _chickenParts = [];
|
||||||
List<String> _sizeList = ['XS', 'S', 'M', 'L', 'XL', 'XXL'];
|
int _maxChickenParts = 2;
|
||||||
int _sizeIndex = 0;
|
|
||||||
|
|
||||||
// color data
|
|
||||||
List<String> _colorList = [
|
|
||||||
'Red',
|
|
||||||
'Black',
|
|
||||||
'Green',
|
|
||||||
'White',
|
|
||||||
'Blue',
|
|
||||||
'Yellow',
|
|
||||||
'Pink'
|
|
||||||
];
|
|
||||||
int _colorIndex = 0;
|
|
||||||
|
|
||||||
// wishlist
|
|
||||||
bool _isLove = false;
|
|
||||||
|
|
||||||
// shopping cart count
|
// shopping cart count
|
||||||
int _shoppingCartCount = 3;
|
int _shoppingCartCount = 3;
|
||||||
|
|
||||||
|
// tag(s) list
|
||||||
|
final List<String> tagsList = objectbox.getVisiteTagsLabels();
|
||||||
|
List<String> selectedTagsList = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
// image slider for the product
|
|
||||||
_imgProductSlider.add(widget.image);
|
|
||||||
_imgProductSlider.add(widget.image);
|
|
||||||
_imgProductSlider.add(widget.image);
|
|
||||||
_imgProductSlider.add(widget.image);
|
|
||||||
_imgProductSlider.add(widget.image);
|
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,7 +72,6 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final double boxImageSize = (MediaQuery.of(context).size.width / 3);
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
iconTheme: IconThemeData(
|
iconTheme: IconThemeData(
|
||||||
|
|
@ -171,13 +148,9 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
children: [
|
children: [
|
||||||
Image.file(File(widget.image), fit: BoxFit.cover),
|
Image.file(File(widget.image), fit: BoxFit.cover),
|
||||||
//_createProductSlider(),
|
//_createProductSlider(),
|
||||||
_createProductPriceTitleEtc(),
|
_buildPhotoTypology(),
|
||||||
_createProductVariant(),
|
_buildPhotoVisibility(),
|
||||||
_createDeliveryEstimated(),
|
_buildPhotoTag(),
|
||||||
_createProductInformation(),
|
|
||||||
_createProductDescription(),
|
|
||||||
_createProductRelated(boxImageSize),
|
|
||||||
_createProductReview(),
|
|
||||||
SizedBox(height: 16)
|
SizedBox(height: 16)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -283,108 +256,7 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _createProductSlider() {
|
Widget _buildPhotoTypology() {
|
||||||
return Stack(
|
|
||||||
children: [
|
|
||||||
CarouselSlider(
|
|
||||||
items: _imgProductSlider
|
|
||||||
.map((item) => Container(
|
|
||||||
child:
|
|
||||||
buildCacheNetworkImage(width: 0, height: 0, url: item),
|
|
||||||
))
|
|
||||||
.toList(),
|
|
||||||
options: CarouselOptions(
|
|
||||||
aspectRatio: 1,
|
|
||||||
viewportFraction: 1.0,
|
|
||||||
autoPlay: false,
|
|
||||||
enlargeCenterPage: false,
|
|
||||||
onPageChanged: (index, reason) {
|
|
||||||
setState(() {
|
|
||||||
_currentImageSlider = index;
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
bottom: 16,
|
|
||||||
left: 16,
|
|
||||||
child: Container(
|
|
||||||
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: SOFT_BLUE, borderRadius: BorderRadius.circular(4)),
|
|
||||||
child: Text(
|
|
||||||
(_currentImageSlider + 1).toString() +
|
|
||||||
'/' +
|
|
||||||
_imgProductSlider.length.toString(),
|
|
||||||
style: TextStyle(color: Colors.white, fontSize: 11)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _createProductPriceTitleEtc() {
|
|
||||||
return Container(
|
|
||||||
color: Colors.white,
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(widget.photo.toString() + ' photo(s)',
|
|
||||||
style: GlobalStyle.detailProductPrice),
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
if (_isLove == true) {
|
|
||||||
_isLove = false;
|
|
||||||
Fluttertoast.showToast(
|
|
||||||
msg: "La photo n'est plus taguée comme favorite",
|
|
||||||
toastLength: Toast.LENGTH_LONG);
|
|
||||||
} else {
|
|
||||||
Fluttertoast.showToast(
|
|
||||||
msg: "La photo est taguée comme favorite",
|
|
||||||
toastLength: Toast.LENGTH_LONG);
|
|
||||||
_isLove = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: Icon(Icons.favorite,
|
|
||||||
color: _isLove == true ? ASSENT_COLOR : BLACK_GREY,
|
|
||||||
size: 28),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 12),
|
|
||||||
Text(widget.name,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
)),
|
|
||||||
SizedBox(height: 12),
|
|
||||||
IntrinsicHeight(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Text(widget.date,
|
|
||||||
style: TextStyle(fontSize: 13, color: BLACK_GREY)),
|
|
||||||
VerticalDivider(
|
|
||||||
width: 30,
|
|
||||||
thickness: 1,
|
|
||||||
color: Colors.grey[300],
|
|
||||||
),
|
|
||||||
Icon(Icons.location_on, color: SOFT_GREY, size: 16),
|
|
||||||
Text('Brooklyn',
|
|
||||||
style: TextStyle(fontSize: 13, color: SOFT_GREY))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _createProductVariant() {
|
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.only(top: 12),
|
margin: EdgeInsets.only(top: 12),
|
||||||
padding: EdgeInsets.all(16),
|
padding: EdgeInsets.all(16),
|
||||||
|
|
@ -392,37 +264,13 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text('Variant', style: GlobalStyle.sectionTitle),
|
Text('Typologie', style: GlobalStyle.sectionTitle),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 16,
|
height: 16,
|
||||||
),
|
),
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text('Size : ',
|
|
||||||
style: TextStyle(color: BLACK_GREY, fontSize: 14)),
|
|
||||||
Text(_sizeList[_sizeIndex],
|
|
||||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Wrap(
|
Wrap(
|
||||||
children: List.generate(_sizeList.length, (index) {
|
children: List.generate(_typologyList.length, (index) {
|
||||||
return radioSize(_sizeList[index], index);
|
return radioSize(_typologyList[index], index);
|
||||||
}),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text('Color : ',
|
|
||||||
style: TextStyle(color: BLACK_GREY, fontSize: 14)),
|
|
||||||
Text(_colorList[_colorIndex],
|
|
||||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Wrap(
|
|
||||||
children: List.generate(_colorList.length, (index) {
|
|
||||||
return radioColor(_colorList[index], index);
|
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -433,101 +281,105 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_sizeIndex = index;
|
_typologyIndex = index;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
|
padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
|
||||||
margin: EdgeInsets.only(right: 8, top: 8),
|
margin: EdgeInsets.only(right: 8, top: 8),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: _sizeIndex == index ? SOFT_BLUE : Colors.white,
|
color: _typologyIndex == index ? SOFT_BLUE : Colors.white,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
width: 1,
|
width: 1,
|
||||||
color: _sizeIndex == index ? SOFT_BLUE : Colors.grey[300]!),
|
color: _typologyIndex == index ? SOFT_BLUE : Colors.grey[300]!),
|
||||||
borderRadius: BorderRadius.all(
|
borderRadius: BorderRadius.all(
|
||||||
Radius.circular(10) // <--- border radius here
|
Radius.circular(10) // <--- border radius here
|
||||||
)),
|
)),
|
||||||
child: Text(txt,
|
child: Text(txt,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: _sizeIndex == index ? Colors.white : CHARCOAL)),
|
color: _typologyIndex == index ? Colors.white : CHARCOAL)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget radioColor(String txt, int index) {
|
Widget _checboxChicken({value = 'breast', primaryText = 'Chicken Breast'}) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
|
behavior: HitTestBehavior.translucent,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_colorIndex = index;
|
if (_chickenParts.contains(value)) {
|
||||||
|
_chickenParts.remove(value);
|
||||||
|
} else {
|
||||||
|
if (_chickenParts.length < _maxChickenParts) {
|
||||||
|
_chickenParts.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Row(
|
||||||
padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
|
children: [
|
||||||
margin: EdgeInsets.only(right: 8, top: 8),
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: _colorIndex == index ? SOFT_BLUE : Colors.white,
|
border: Border.all(
|
||||||
border: Border.all(
|
width: 1,
|
||||||
width: 1,
|
color: (_chickenParts.contains(value))
|
||||||
color: _colorIndex == index ? SOFT_BLUE : Colors.grey[300]!),
|
? PRIMARY_COLOR
|
||||||
borderRadius: BorderRadius.all(
|
: BLACK77),
|
||||||
Radius.circular(10) // <--- border radius here
|
borderRadius: BorderRadius.all(Radius.circular(4.0)),
|
||||||
)),
|
),
|
||||||
child: Text(txt,
|
child: Padding(
|
||||||
style: TextStyle(
|
padding: const EdgeInsets.all(2),
|
||||||
color: _colorIndex == index ? Colors.white : CHARCOAL)),
|
child: (_chickenParts.contains(value))
|
||||||
|
? Icon(
|
||||||
|
Icons.check,
|
||||||
|
size: 12.0,
|
||||||
|
color: PRIMARY_COLOR,
|
||||||
|
)
|
||||||
|
: Icon(
|
||||||
|
Icons.check_box_outline_blank,
|
||||||
|
size: 12.0,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 16),
|
||||||
|
Text(primaryText,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: BLACK77,
|
||||||
|
fontWeight: (_chickenParts.contains(value))
|
||||||
|
? FontWeight.bold
|
||||||
|
: FontWeight.normal)),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _createDeliveryEstimated() {
|
Widget _buildPhotoVisibility() {
|
||||||
return GestureDetector(
|
return Container(
|
||||||
onTap: () {
|
margin: EdgeInsets.only(top: 12),
|
||||||
Navigator.push(context,
|
padding: EdgeInsets.all(16),
|
||||||
MaterialPageRoute(builder: (context) => DeliveryEstimatedPage()));
|
color: Colors.white,
|
||||||
},
|
child: Column(
|
||||||
child: Container(
|
children: [
|
||||||
margin: EdgeInsets.only(top: 12),
|
Row(
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
color: Colors.white,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
children: [
|
||||||
Flexible(
|
Text('Visibility', style: GlobalStyle.sectionTitle),
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text('Delivery', style: GlobalStyle.sectionTitle),
|
|
||||||
SizedBox(
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
RichText(
|
|
||||||
text: new TextSpan(
|
|
||||||
// Note: Styles for TextSpans must be explicitly defined.
|
|
||||||
// Child text spans will inherit styles from parent
|
|
||||||
style: new TextStyle(
|
|
||||||
fontSize: 15.5,
|
|
||||||
color: BLACK_GREY,
|
|
||||||
),
|
|
||||||
children: <TextSpan>[
|
|
||||||
new TextSpan(
|
|
||||||
text:
|
|
||||||
'Calculate the estimated cost for shipping goods to '),
|
|
||||||
new TextSpan(
|
|
||||||
text: 'West New York, NJ',
|
|
||||||
style:
|
|
||||||
new TextStyle(fontWeight: FontWeight.bold)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Icon(Icons.chevron_right, size: 36, color: CHARCOAL)
|
|
||||||
],
|
],
|
||||||
)),
|
),
|
||||||
|
SizedBox(height: 16),
|
||||||
|
_checboxChicken(value: 'public', primaryText: 'Public'),
|
||||||
|
Divider(
|
||||||
|
height: 32,
|
||||||
|
color: Colors.grey[400],
|
||||||
|
),
|
||||||
|
_checboxChicken(value: 'principal', primaryText: 'Principal')
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _createProductInformation() {
|
Widget _buildPhotoTag() {
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.only(top: 12),
|
margin: EdgeInsets.only(top: 12),
|
||||||
padding: EdgeInsets.all(16),
|
padding: EdgeInsets.all(16),
|
||||||
|
|
@ -535,261 +387,66 @@ class _PhotoDetailPageState extends State<PhotoDetailPage> {
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text('Information', style: GlobalStyle.sectionTitle),
|
Text("Tags sélectionnés:"),
|
||||||
SizedBox(
|
SizedBox(height: 8),
|
||||||
height: 16,
|
selectedTagsList.isEmpty
|
||||||
),
|
? Text("Aucun tag sélectionné.")
|
||||||
Row(
|
: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text('Weight', style: TextStyle(color: BLACK_GREY)),
|
|
||||||
Text('300 Gram', style: TextStyle(color: BLACK_GREY))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text('Condition', style: TextStyle(color: BLACK_GREY)),
|
|
||||||
Text('Second', style: TextStyle(color: BLACK_GREY))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text('Category', style: TextStyle(color: BLACK_GREY)),
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => ProductCategoryPage(
|
|
||||||
categoryId: 3, categoryName: 'Electronic')));
|
|
||||||
},
|
|
||||||
child: Text('Electronic', style: TextStyle(color: SOFT_BLUE)),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _createProductDescription() {
|
|
||||||
return Container(
|
|
||||||
margin: EdgeInsets.only(top: 12),
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
color: Colors.white,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text('Description',
|
|
||||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
|
|
||||||
SizedBox(
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nQuisque tortor tortor, ultrices id scelerisque a, elementum id elit. Maecenas feugiat tellus sed augue malesuada, id tempus ex sodales.'),
|
|
||||||
SizedBox(
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => ProductDescriptionPage(
|
|
||||||
name: widget.name, image: widget.image)));
|
|
||||||
},
|
|
||||||
child: Center(
|
|
||||||
child: Text('Read More', style: TextStyle(color: SOFT_BLUE)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _createProductRelated(boxImageSize) {
|
|
||||||
return Container(
|
|
||||||
margin: EdgeInsets.only(top: 12),
|
|
||||||
padding: EdgeInsets.only(bottom: 16),
|
|
||||||
color: Colors.white,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
margin: EdgeInsets.all(16),
|
|
||||||
child: Text('Related Product', style: GlobalStyle.sectionTitle),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
height: boxImageSize *
|
|
||||||
GlobalStyle.horizontalProductHeightMultiplication,
|
|
||||||
child: ListView.builder(
|
|
||||||
padding: EdgeInsets.only(left: 12, right: 12),
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
itemCount: relatedProductData.length,
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
return Container(
|
|
||||||
width: boxImageSize + 10,
|
|
||||||
child: Card(
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
elevation: 2,
|
|
||||||
color: Colors.white,
|
|
||||||
child: GestureDetector(
|
|
||||||
behavior: HitTestBehavior.translucent,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => PhotoDetailPage(
|
|
||||||
name: relatedProductData[index].name,
|
|
||||||
image: relatedProductData[index].image,
|
|
||||||
price: relatedProductData[index].price,
|
|
||||||
rating: relatedProductData[index].rating,
|
|
||||||
review: relatedProductData[index].review,
|
|
||||||
sale: 36)));
|
|
||||||
},
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
ClipRRect(
|
|
||||||
borderRadius: BorderRadius.only(
|
|
||||||
topLeft: Radius.circular(10),
|
|
||||||
topRight: Radius.circular(10)),
|
|
||||||
child: buildCacheNetworkImage(
|
|
||||||
width: boxImageSize + 10,
|
|
||||||
height: boxImageSize + 10,
|
|
||||||
url: relatedProductData[index].image)),
|
|
||||||
Container(
|
|
||||||
margin: EdgeInsets.fromLTRB(8, 8, 8, 8),
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
relatedProductData[index].name,
|
|
||||||
style: GlobalStyle.productName,
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
margin: EdgeInsets.only(top: 5),
|
|
||||||
child: Text(
|
|
||||||
'\$ ' +
|
|
||||||
_globalFunction
|
|
||||||
.removeDecimalZeroFormat(
|
|
||||||
relatedProductData[index]
|
|
||||||
.price),
|
|
||||||
style: GlobalStyle.productPrice),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
margin: EdgeInsets.only(top: 5),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
_reusableWidget.createRatingBar(
|
|
||||||
rating: relatedProductData[index]
|
|
||||||
.rating,
|
|
||||||
size: 12),
|
|
||||||
Text(
|
|
||||||
'(' +
|
|
||||||
relatedProductData[index]
|
|
||||||
.review
|
|
||||||
.toString() +
|
|
||||||
')',
|
|
||||||
style:
|
|
||||||
GlobalStyle.productTotalReview)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _createProductReview() {
|
|
||||||
return Container(
|
|
||||||
margin: EdgeInsets.only(top: 12),
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
color: Colors.white,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text('Review', style: GlobalStyle.sectionTitle),
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => ProductReviewPage()));
|
|
||||||
},
|
|
||||||
child: Text('View All',
|
|
||||||
style: GlobalStyle.viewAll.copyWith(color: SOFT_BLUE),
|
|
||||||
textAlign: TextAlign.end),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 8,
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
_reusableWidget.createRatingBar(
|
|
||||||
rating: widget.rating, size: 12),
|
|
||||||
Text('(' + widget.review.toString() + ')',
|
|
||||||
style: TextStyle(fontSize: 11, color: SOFT_GREY))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: List.generate(reviewData.length, (index) {
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
Divider(
|
|
||||||
height: 32,
|
|
||||||
color: Colors.grey[400],
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: tagsList.map((tag) => Text("- $tag")).toList(),
|
||||||
Text(reviewData[index].date,
|
),
|
||||||
style: TextStyle(fontSize: 13, color: SOFT_GREY)),
|
SizedBox(height: 16),
|
||||||
SizedBox(height: 4),
|
ElevatedButton(
|
||||||
Row(
|
onPressed: () => _openTagSelectionDialog(),
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
child: Text("Modifier"),
|
||||||
children: [
|
),
|
||||||
Text(reviewData[index].name,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14, fontWeight: FontWeight.bold)),
|
|
||||||
_reusableWidget.createRatingBar(
|
|
||||||
rating: reviewData[index].rating, size: 12),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 4),
|
|
||||||
Text(reviewData[index].review)
|
|
||||||
],
|
|
||||||
))
|
|
||||||
],
|
|
||||||
);
|
|
||||||
})),
|
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _openTagSelectionDialog() async {
|
||||||
|
await FilterListDialog.display<String>(
|
||||||
|
context,
|
||||||
|
hideSelectedTextCount: true,
|
||||||
|
themeData: FilterListThemeData(context),
|
||||||
|
headlineText: 'Select Users',
|
||||||
|
height: 500,
|
||||||
|
listData: tagsList,
|
||||||
|
selectedListData: selectedTagsList,
|
||||||
|
choiceChipLabel: (item) => item,
|
||||||
|
validateSelectedItem: (list, val) => list!.contains(val),
|
||||||
|
controlButtons: [ControlButtonType.All, ControlButtonType.Reset],
|
||||||
|
onItemSearch: (user, query) {
|
||||||
|
/// When search query change in search bar then this method will be called
|
||||||
|
///
|
||||||
|
/// Check if items contains query
|
||||||
|
return user.toLowerCase().contains(query.toLowerCase());
|
||||||
|
},
|
||||||
|
|
||||||
|
onApplyButtonClick: (list) {
|
||||||
|
setState(() {
|
||||||
|
selectedTagsList = list!;
|
||||||
|
});
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
|
||||||
|
/// uncomment below code to create custom choice chip
|
||||||
|
/*
|
||||||
|
choiceChipBuilder: (context, item, isSelected) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: isSelected! ? Colors.blue[300]! : Colors.grey[300]!,
|
||||||
|
)),
|
||||||
|
child: Text(
|
||||||
|
item,
|
||||||
|
style: TextStyle(
|
||||||
|
color: isSelected ? Colors.blue[300] : Colors.grey[500]),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},*/
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.4"
|
version: "6.1.4"
|
||||||
|
filter_list:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: filter_list
|
||||||
|
sha256: "2d80d6d19beb7847c1176e8bf6fe06d302b23eb7d1bf48c231dd730409ff9b4d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -55,9 +55,12 @@ dependencies:
|
||||||
permission_handler: 10.2.0
|
permission_handler: 10.2.0
|
||||||
image: ^4.0.15
|
image: ^4.0.15
|
||||||
|
|
||||||
|
# https://pub.dev/packages/filter_list/install
|
||||||
|
filter_list: ^1.0.2
|
||||||
|
|
||||||
flutter_cache_manager: ^3.3.0
|
flutter_cache_manager: ^3.3.0
|
||||||
|
|
||||||
#https://pub.dev/packages/intl
|
# https://pub.dev/packages/intl
|
||||||
intl: 0.17.0
|
intl: 0.17.0
|
||||||
|
|
||||||
carousel_slider: 4.2.1
|
carousel_slider: 4.2.1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue