import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:niogu_ecommerce_v1/core/constant/app_color.dart'; import 'package:niogu_ecommerce_v1/core/constant/app_font_size.dart'; import 'package:niogu_ecommerce_v1/core/errors/exceptions.dart'; import 'package:niogu_ecommerce_v1/core/providers/app_provider.dart'; import 'package:niogu_ecommerce_v1/core/utils/log_message.dart'; import 'package:niogu_ecommerce_v1/core/widgets/custom_snackbar.dart'; import 'package:niogu_ecommerce_v1/features/home/presentation/providers/home_provider.dart'; import 'package:niogu_ecommerce_v1/features/order/domain/entities/order.dart'; import 'package:niogu_ecommerce_v1/features/order/presentation/providers/order_provider.dart'; import 'package:sizer/sizer.dart'; class RatingScreen extends ConsumerStatefulWidget { final String orderId; final List products; const RatingScreen({ super.key, required this.orderId, required this.products, }); @override ConsumerState createState() => _RatingScreenState(); } class _RatingScreenState extends ConsumerState { late final List _products; final Map _ratings = {}; final Map _controllers = {}; @override void initState() { super.initState(); _products = widget.products; for (int i = 0; i < _products.length; i++) { _ratings[i] = 5; _controllers[i] = TextEditingController(); } } @override void dispose() { // TODO: implement dispose for (int i = 0; i < _products.length; i++) { _controllers[i]?.dispose(); } super.dispose(); } String _getRatingLabel(int rating) { if (rating == 1) return "Sangat Buruk"; if (rating == 2) return "Buruk"; if (rating == 3) return "Cukup"; if (rating == 4) return "Puas"; return "Sangat Puas"; } Future _reviewProduct() async { final customerId = ref.read(currentCustomerIdProvider); final List reviews = []; for (int i = 0; i < _products.length; i++) { final product = _products[i]; final rating = _ratings[i] ?? 5; final comment = _controllers[i]?.text; reviews.add( ProductReview( customerId: customerId!, productVariantId: product.id, rating: rating, comment: comment, ), ); } try { await ref .read(orderControllerProvider.notifier) .reviewProduct(widget.orderId, reviews); if (!mounted) return; await ref.read(orderReportControllerProvider.notifier).refresh(); await ref.read(homeControllerProvider.notifier).refresh(); CustomSnackbar.showSuccess(context, "Berhasil menilai pesanan"); context.pop(); } on ServerException catch (e, st) { LogMessage.log.e(e.toString(), error: e, stackTrace: st); CustomSnackbar.showError(context, "Terjadi kesalahan koneksi"); } } @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { final orderState = ref.watch(orderControllerProvider); final isLoading = orderState.isLoading; return SafeArea( top: false, bottom: true, right: false, left: false, child: Scaffold( backgroundColor: const Color(0xFFF8F9FA), appBar: AppBar( backgroundColor: Colors.white, elevation: 0, centerTitle: true, leading: IconButton( icon: Icon( Icons.arrow_back, size: 7.w, color: AppColor.primaryColor, ), onPressed: () => context.pop(), ), title: Text( "Nilai Produk", style: TextStyle( color: Colors.black, fontSize: AppFontSize.medium.sp, fontWeight: FontWeight.bold, ), ), ), body: Column( children: [ Expanded( child: ListView.builder( padding: EdgeInsets.all(4.w), itemCount: _products.length, itemBuilder: (context, index) { return _buildRatingCard(index); }, ), ), _buildSubmitButton(isLoading), ], ), ), ); }, ); } Widget _buildRatingCard(int index) { final controller = _controllers[index]; final product = _products[index]; final rating = _ratings[index]; return Container( margin: EdgeInsets.only(bottom: 2.h), padding: EdgeInsets.all(4.w), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(3.w), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.03), blurRadius: 10, offset: const Offset(0, 5), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ CachedNetworkImage( imageUrl: product.image ?? 'error', imageBuilder: (context, imageProvider) { return Container( width: 15.w, height: 15.w, decoration: BoxDecoration( color: Colors.grey.shade100, borderRadius: BorderRadius.circular(2.w), image: DecorationImage( image: imageProvider, fit: BoxFit.cover, ), ), ); }, errorWidget: (context, url, error) { return Container( width: 15.w, height: 15.w, decoration: BoxDecoration( color: Colors.grey.shade100, borderRadius: BorderRadius.circular(2.w), ), child: Icon( Icons.image, color: Colors.grey.shade300, size: 5.w, ), ); }, ), SizedBox(width: 3.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( product.name, style: TextStyle( fontWeight: FontWeight.bold, fontSize: AppFontSize.small.sp, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), if (product.variantName != null) ...[ SizedBox(height: 0.75.h), Text( product.variantName!, style: TextStyle( color: Colors.grey.shade700, fontSize: (AppFontSize.small - 1.25).sp, ), ), ], ], ), ), ], ), Divider(height: 4.h, color: Colors.grey.shade300), Center( child: Column( children: [ Text( _getRatingLabel(rating!), style: TextStyle( fontWeight: FontWeight.bold, color: AppColor.primaryColor, fontSize: (AppFontSize.small + 1).sp, ), ), SizedBox(height: 1.h), Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(5, (starIndex) { return GestureDetector( onTap: () => setState(() => _ratings[index] = starIndex + 1), child: Icon( starIndex < rating ? Icons.star : Icons.star_border, color: Colors.orange, size: 7.w, ), ); }), ), ], ), ), SizedBox(height: 3.h), TextField( controller: controller, maxLines: 6, style: TextStyle(fontSize: (AppFontSize.small - 1.25).sp), decoration: InputDecoration( hintText: "Bagikan penilaianmu tentang produk ini...", hintStyle: TextStyle(fontSize: (AppFontSize.small - 1.25).sp), filled: true, fillColor: Colors.grey.shade50, border: OutlineInputBorder( borderRadius: BorderRadius.circular(2.w), borderSide: BorderSide.none, ), ), ), ], ), ); } Widget _buildSubmitButton(bool isLoading) { return Container( padding: EdgeInsets.all(4.w), decoration: BoxDecoration( color: Colors.white, boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 5)], ), child: SafeArea( child: SizedBox( width: double.infinity, child: ElevatedButton( onPressed: isLoading ? null : _reviewProduct, style: ElevatedButton.styleFrom( backgroundColor: AppColor.primaryColor, padding: EdgeInsets.symmetric(vertical: 1.8.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(2.w), ), disabledBackgroundColor: Colors.grey.shade300, ), child: Text( "Kirim Penilaian", style: TextStyle( fontWeight: FontWeight.bold, fontSize: AppFontSize.medium.sp, color: Colors.white, ), ), ), ), ), ); } }