mobdr/lib/ui/home/photo_detail.dart

486 lines
15 KiB
Dart

import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:mobdr/config/constant.dart';
import 'package:mobdr/config/global_style.dart';
import 'package:mobdr/main.dart';
import 'package:mobdr/ui/general/chat_us.dart';
import 'package:mobdr/ui/general/notification.dart';
import 'package:mobdr/ui/home/product_category.dart';
import 'package:mobdr/ui/home/photo_tag.dart';
import 'package:mobdr/ui/home/search.dart';
import 'package:mobdr/ui/reusable/reusable_widget.dart';
import 'package:mobdr/ui/shopping_cart/tab_shopping_cart.dart';
import 'package:mobdr/ui/reusable/global_function.dart';
import 'package:mobdr/db/box_photo.dart';
class PhotoDetailPage extends StatefulWidget {
// variables corresponding to the data parameters
final int id;
final String name;
final String image;
final String tags;
final double price;
final int photo;
final double rating;
final int review;
final int sale;
final String date;
// Requiring data parameters
const PhotoDetailPage(
{Key? key,
this.id = 0,
this.name = '',
this.image = '',
this.tags = '',
this.price = 24,
this.photo = 1,
this.rating = 4,
this.review = 45,
this.sale = 63,
this.date = ''})
: super(key: key);
@override
_PhotoDetailPageState createState() => _PhotoDetailPageState();
}
class _PhotoDetailPageState extends State<PhotoDetailPage> {
// initialize global function and reusable widget
final _globalFunction = GlobalFunction();
final _reusableWidget = ReusableWidget();
bool _isLoading = true;
String _errorMessage = '';
// Typology list
late List<String> _typologyList = [];
int _typologyIndex = 0;
List<String> _chickenParts = [];
int _maxChickenParts = 2;
// shopping cart count
int _shoppingCartCount = 3;
late String tags = "";
late List<String> tagList = [];
late Photo _photo;
@override
void initState() {
super.initState();
loadData(widget.id).then((_) {
setState(() {
_isLoading = false;
});
});
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
if (_isLoading) {
return Center(child: CircularProgressIndicator());
} else if (_errorMessage.isNotEmpty) {
return Center(
child: AlertDialog(
title: Text("Erreur"),
content: Text("La photo est introuvable"),
actions: <Widget>[
TextButton(
child: Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
);
}
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(
color: GlobalStyle.appBarIconThemeColor,
),
elevation: GlobalStyle.appBarElevation,
titleSpacing: 0.0,
// create search text field in the app bar
title: Container(
margin: EdgeInsets.only(right: 16),
child: TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) => Colors.grey[100]!,
),
overlayColor: MaterialStateProperty.all(Colors.transparent),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
)),
),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => SearchPage()));
},
child: Row(
children: [
SizedBox(width: 8),
Icon(Icons.search, color: Colors.grey[500], size: 18),
SizedBox(width: 8),
Text(
'Search Product',
style: TextStyle(
fontSize: 13,
color: Colors.grey[600],
fontWeight: FontWeight.normal),
)
],
)),
),
backgroundColor: GlobalStyle.appBarBackgroundColor,
systemOverlayStyle: GlobalStyle.appBarSystemOverlayStyle,
actions: [
IconButton(
padding: EdgeInsets.all(0),
constraints: BoxConstraints(),
icon: _customShoppingCart(_shoppingCartCount),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TabShoppingCartPage()));
}),
IconButton(
icon: _reusableWidget.customNotifIcon(
count: 8, notifColor: BLACK_GREY),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NotificationPage()));
}),
],
bottom: _reusableWidget.bottomAppBar(),
),
body: WillPopScope(
onWillPop: () {
Navigator.pop(context);
return Future.value(true);
},
child: Column(
children: [
Flexible(
child: ListView(
children: [
Image.file(File(widget.image), fit: BoxFit.cover),
//_createProductSlider(),
_buildPhotoTypology(),
_buildPhotoVisibility(),
_buildPhotoTag(context),
SizedBox(height: 16)
],
),
),
Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(0.0, 1.0), //(x,y)
blurRadius: 2.0,
),
],
),
child: Row(
children: [
Container(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChatUsPage()));
},
child: ClipOval(
child: Container(
color: SOFT_BLUE,
padding: EdgeInsets.all(9),
child: Icon(Icons.chat,
color: Colors.white, size: 16)),
),
),
),
SizedBox(
width: 10,
),
Expanded(
child: GestureDetector(
onTap: () {
setState(() {
_shoppingCartCount++;
});
Fluttertoast.showToast(
msg: 'Item has been added to Shopping Cart',
toastLength: Toast.LENGTH_LONG);
},
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
margin: EdgeInsets.only(right: 8),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 1, color: SOFT_BLUE),
borderRadius: BorderRadius.all(Radius.circular(
10) // <--- border radius here
)),
child: Text('Add to Shopping Cart',
style: TextStyle(
color: SOFT_BLUE,
fontWeight: FontWeight.bold)),
),
),
),
],
),
)
],
),
));
}
Widget _customShoppingCart(int count) {
return Stack(
children: <Widget>[
Icon(Icons.shopping_cart, color: BLACK_GREY),
Positioned(
right: 0,
child: Container(
padding: EdgeInsets.all(1),
decoration: BoxDecoration(
color: ASSENT_COLOR,
borderRadius: BorderRadius.circular(10),
),
constraints: BoxConstraints(
minWidth: 14,
minHeight: 14,
),
child: Center(
child: Text(
count.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 8,
),
textAlign: TextAlign.center,
),
),
),
)
],
);
}
Widget _buildPhotoTypology() {
return Container(
margin: EdgeInsets.only(top: 12),
padding: EdgeInsets.all(16),
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Typologie', style: GlobalStyle.sectionTitle),
SizedBox(
height: 16,
),
Wrap(
children: List.generate(_typologyList.length, (index) {
return radioSize(_typologyList[index], index);
}),
),
],
));
}
Widget radioSize(String txt, int index) {
return GestureDetector(
onTap: () {
setState(() {
_typologyIndex = index;
});
},
child: Container(
padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
margin: EdgeInsets.only(right: 8, top: 8),
decoration: BoxDecoration(
color: _typologyIndex == index ? SOFT_BLUE : Colors.white,
border: Border.all(
width: 1,
color: _typologyIndex == index ? SOFT_BLUE : Colors.grey[300]!),
borderRadius: BorderRadius.all(
Radius.circular(10) // <--- border radius here
)),
child: Text(txt,
style: TextStyle(
color: _typologyIndex == index ? Colors.white : CHARCOAL)),
),
);
}
// TODO changer chicken
Widget _checboxChicken({value = 'breast', primaryText = 'Chicken Breast'}) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
setState(() {
if (_chickenParts.contains(value)) {
_chickenParts.remove(value);
} else {
if (_chickenParts.length < _maxChickenParts) {
_chickenParts.add(value);
}
}
});
},
child: Row(
children: [
Container(
decoration: BoxDecoration(
border: Border.all(
width: 1,
color: (_chickenParts.contains(value))
? PRIMARY_COLOR
: BLACK77),
borderRadius: BorderRadius.all(Radius.circular(4.0)),
),
child: Padding(
padding: const EdgeInsets.all(2),
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 _buildPhotoVisibility() {
return Container(
margin: EdgeInsets.only(top: 12),
padding: EdgeInsets.all(16),
color: Colors.white,
child: Column(
children: [
Row(
children: [
Text('Visibility', style: GlobalStyle.sectionTitle),
],
),
SizedBox(height: 16),
_checboxChicken(value: 'public', primaryText: 'Public'),
Divider(
height: 32,
color: Colors.grey[400],
),
_checboxChicken(value: 'principal', primaryText: 'Principal')
],
),
);
}
Widget _buildPhotoTag(BuildContext context) {
return GestureDetector(
onTap: () async {
// Navigation to the PhotoTagPage
final newTags = await Navigator.push<List<String>>(
context,
MaterialPageRoute(
builder: (context) =>
PhotoTagPage(photoId: this._photo.id, currentTags: tagList),
),
);
// Checking changes made to tags
if (newTags != null && !listEquals(tagList, newTags)) {
setState(() {
tagList = newTags;
});
}
},
child: Container(
margin: EdgeInsets.only(top: 12),
padding: EdgeInsets.all(16),
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text('Tags', style: GlobalStyle.sectionTitle),
],
),
Wrap(
spacing: 8.0,
runSpacing: 8.0,
alignment: WrapAlignment.start,
children: tagList.map((tag) {
return Chip(
label: Text(tag),
backgroundColor: Colors.grey[300],
);
}).toList(),
),
],
),
),
);
}
/// data initialization on loading.
Future<void> loadData(int photoId) async {
try {
// photo typologies initialization
_typologyList = objectbox.getPhotoTypologiesLabels();
// get photo object
_photo = objectbox.getPhotoById(photoId)!;
// photo tag initialization
tags = _photo.tags;
tagList = tags.isEmpty ? [] : tags.split(",");
} catch (e) {
// set errorMessage for debug
_errorMessage = 'Error loading photo: $e';
}
}
}