proxibuy/lib/presentation/pages/comment_page.dart

273 lines
10 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image_picker/image_picker.dart';
import 'package:proxibuy/core/config/app_colors.dart';
import 'package:proxibuy/core/gen/assets.gen.dart';
import 'package:proxibuy/presentation/comment/bloc/comment_bloc.dart';
import 'package:proxibuy/presentation/comment/bloc/comment_event.dart';
import 'package:proxibuy/presentation/comment/bloc/comment_state.dart';
import 'package:proxibuy/presentation/pages/offers_page.dart';
class CommentPage extends StatefulWidget {
final String discountId;
const CommentPage({super.key, required this.discountId});
@override
State<CommentPage> createState() => _CommentPageState();
}
class _CommentPageState extends State<CommentPage> {
final _commentController = TextEditingController();
double _rating = 0.0;
final List<File> _images = [];
final ImagePicker _picker = ImagePicker();
@override
void dispose() {
_commentController.dispose();
super.dispose();
}
void _pickImage(ImageSource source) async {
if (_images.length >= 2) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('شما فقط می‌توانید ۲ عکس اضافه کنید.')),
);
return;
}
final pickedFile = await _picker.pickImage(source: source, imageQuality: 80);
if (pickedFile != null) {
setState(() {
_images.add(File(pickedFile.path));
});
}
}
void _showImageSourceActionSheet() {
showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20.0)),
),
builder: (context) {
return SafeArea(
child: Wrap(
children: <Widget>[
ListTile(
leading: const Icon(Icons.photo_library, color: AppColors.primary),
title: const Text('انتخاب از گالری'),
onTap: () {
Navigator.of(context).pop();
_pickImage(ImageSource.gallery);
},
),
ListTile(
leading: const Icon(Icons.camera_alt, color: AppColors.primary),
title: const Text('گرفتن عکس با دوربین'),
onTap: () {
Navigator.of(context).pop();
_pickImage(ImageSource.camera);
},
),
],
),
);
},
);
}
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => CommentBloc(),
child: Scaffold(
body: Stack(
children: [
Positioned.fill(
child: Image.asset(Assets.images.userinfo.path, fit: BoxFit.cover),
),
DraggableScrollableSheet(
initialChildSize: 0.65,
minChildSize: 0.65,
maxChildSize: 0.65,
builder: (context, scrollController) {
return Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(32)),
),
child: SingleChildScrollView(
controller: scrollController,
padding: const EdgeInsets.all(24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Container(
width: 50,
height: 5,
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.5),
borderRadius: BorderRadius.circular(12),
),
),
),
const SizedBox(height: 24),
const Text(
'خریدت با موفقیت انجام شد. منتظر دیدار دوباره‌ات هستیم. لطفا نظرت رو در مورد این تخفیف بهمون بگو.',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
height: 1.5,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 24),
Center(
child: RatingBar.builder(
initialRating: 0,
minRating: 1,
direction: Axis.horizontal,
itemCount: 5,
itemPadding: const EdgeInsets.symmetric(horizontal: 15.0),
itemBuilder: (context, _) => Icon(
Icons.star,
color: Colors.amber.shade700,
),
onRatingUpdate: (rating) => setState(() => _rating = rating),
),
),
const SizedBox(height: 24),
TextField(
controller: _commentController,
maxLines: 4,
textAlign: TextAlign.right,
decoration: InputDecoration(
labelText: "گوشمون به شماست",
hintText: "نظراتت رو بگو...",
alignLabelWithHint: true,
suffixIcon: Padding(
padding: const EdgeInsets.all(12.0),
child: IconButton(
icon: SvgPicture.asset(
Assets.icons.galleryAdd.path,
color: _images.length >= 2 ? Colors.grey : AppColors.primary,
),
onPressed: _images.length >= 2 ? null : _showImageSourceActionSheet,
),
),
),
),
const SizedBox(height: 16),
if (_images.isNotEmpty)
SizedBox(
height: 80,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: _images.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(left: 8.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(12.0),
child: Image.file(
_images[index],
width: 80,
height: 80,
fit: BoxFit.cover,
),
),
);
},
),
),
const SizedBox(height: 24),
_buildActionButtons(),
],
),
),
);
},
),
],
),
),
);
}
Widget _buildActionButtons() {
return BlocConsumer<CommentBloc, CommentState>(
listener: (context, state) {
if (state is CommentSubmissionSuccess) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('نظر شما با موفقیت ثبت شد. ممنونیم!'),
backgroundColor: Colors.green,
),
);
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (_) => const OffersPage()),
(route) => false,
);
} else if (state is CommentSubmissionFailure) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(state.error), backgroundColor: Colors.red),
);
}
},
builder: (context, state) {
final isLoading = state is CommentSubmitting;
return Column(
children: [
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: isLoading
? null
: () {
context.read<CommentBloc>().add(
SubmitComment(
discountId: widget.discountId,
text: _commentController.text,
score: _rating,
images: _images,
),
);
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.confirm,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(50)),
),
child: isLoading
? const SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(color: Colors.white),
)
: const Text('ارسال'),
),
),
const SizedBox(height: 12),
TextButton(
onPressed: isLoading
? null
: () {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (_) => const OffersPage()),
(route) => false,
);
},
child: const Text('رد شدن', style: TextStyle(color: Colors.black)),
),
],
);
},
);
}
}