import 'dart:convert'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../../common/settings.dart'; import '../paln_requests_model.dart'; class PlanRequestsScreen extends StatefulWidget { const PlanRequestsScreen({super.key}); @override State createState() => _PlanRequestsScreenState(); } class _PlanRequestsScreenState extends State { bool isPlanRequestsDataLoading = false; List planRequestsList = []; List acceptedPlans = []; List rejectedPlans = []; @override void initState() { super.initState(); getAcceptedPlansFromSupplier(); } /// API CALL Future getAcceptedPlansFromSupplier() async { isPlanRequestsDataLoading = true; var response = await AppSettings.getAcceptedPlansFromSupplier(); var json = jsonDecode(response); setState(() { planRequestsList = (json['data'] as List) .map((model) => PlanRequestModel.fromJson(model)) .toList(); groupPlansByStatus(); isPlanRequestsDataLoading = false; }); } /// GROUP DATA void groupPlansByStatus() { acceptedPlans = planRequestsList .where((plan) => plan.status.toLowerCase() == "accepted") .toList(); rejectedPlans = planRequestsList .where((plan) => plan.status.toLowerCase() == "rejected") .toList(); } /// TIME BADGE String getOrderTimeOnly(String orderTimeStr) { if (orderTimeStr.isEmpty) return ""; try { final format = DateFormat("dd-MM-yyyy HH:mm"); final orderTime = format.parse(orderTimeStr); final now = DateTime.now(); final difference = now.difference(orderTime); if (difference.inDays < 2) { return "New"; } else if (difference.inDays < 10) { final remaining = 10 - difference.inDays; return "Expires in ${remaining}d"; } else { return "Expired"; } } catch (e) { return ""; } } /// PLAN CARD Widget planCard(PlanRequestModel plan) { final statusTime = getOrderTimeOnly(plan.acceptedTime); Color statusColor = Color(0xFF1D7AFC); if (statusTime == "Expired") { statusColor = Color(0xFF757575); } int totalOrders = plan.dates.length; double biddingPrice = double.tryParse(plan.biddingPrice) ?? 0; double totalAmount = totalOrders * biddingPrice; return Padding( padding: EdgeInsets.all(10), child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: Color(0XFF1D7AFC)), ), child: Padding( padding: EdgeInsets.all(14), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ /// SUPPLIER + BADGE Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( plan.supplierName, style: fontTextStyle( 14, Color(0XFF343637), FontWeight.w600), ), if (statusTime.isNotEmpty) Container( padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( color: statusColor, borderRadius: BorderRadius.circular(4), ), child: Text( statusTime, style: fontTextStyle( 10, Colors.white, FontWeight.w500), ), ) ], ), SizedBox(height: 6), /// ADDRESS Text( plan.displayAddress, style: fontTextStyle( 10, Color(0XFF646566), FontWeight.w400), ), SizedBox(height: 4), /// DATE RANGE Text( "${plan.startDate} to ${plan.endDate}", style: fontTextStyle( 10, Color(0XFF646566), FontWeight.w400), ), SizedBox(height: 12), /// WATER TYPE Container( padding: EdgeInsets.symmetric(horizontal: 6, vertical: 3), decoration: BoxDecoration( color: plan.typeofwater.toLowerCase() == "bore water" ? Color(0xFF8877DD) : Color(0xFFCA86B0), borderRadius: BorderRadius.circular(4), ), child: AutoSizeText( capitalizeFirst(plan.typeofwater), style: fontTextStyle( 12, Colors.white, FontWeight.w400), ), ), SizedBox(height: 8), /// ACTUAL PRICE Row( children: [ Text( "Actual Price: ", style: fontTextStyle( 12, Color(0XFF646566), FontWeight.w400), ), Text( "₹${AppSettings.formDouble(plan.quotedAmount)}/${plan.capacity}", style: fontTextStyle( 12, Color(0XFF515253), FontWeight.w600), ) ], ), /// BIDDING PRICE Row( children: [ Text( "Bidding Price: ", style: fontTextStyle( 12, Color(0XFF646566), FontWeight.w400), ), Text( "₹${AppSettings.formDouble(plan.biddingPrice)}/${plan.capacity}", style: fontTextStyle( 12, Color(0XFF515253), FontWeight.w600), ) ], ), /// FREQUENCY Row( children: [ Text( "Frequency: ", style: fontTextStyle( 12, Color(0XFF646566), FontWeight.w400), ), Text( "${plan.frequency}/week", style: fontTextStyle( 12, Color(0XFF2D2E30), FontWeight.w600), ) ], ), SizedBox(height: 10), /// PAYMENT TYPE Row( children: [ Text( "Payment Type: ", style: fontTextStyle( 12, Color(0XFF646566), FontWeight.w400), ), Text( plan.paymentType, style: fontTextStyle( 12, Color(0XFF515253), FontWeight.w600), ) ], ), /// ADVANCE / CREDIT if (plan.paymentType != "after_delivery") Row( children: [ Text( plan.paymentType == "credit" ? "Credit Limit: " : "Advance Amount: ", style: fontTextStyle( 12, Color(0XFF646566), FontWeight.w400), ), Text( plan.advanceAmount, style: fontTextStyle( 12, Color(0XFF515253), FontWeight.w600), ) ], ), SizedBox(height: 10), /// TOTAL PLAN AMOUNT Text.rich( TextSpan( children: [ TextSpan( text: "Total amount for this plan orders ", style: fontTextStyle( 12, Color(0xFF939495), FontWeight.w400, ), ), TextSpan( text: "$totalOrders × ${biddingPrice.toStringAsFixed(0)} = ₹${totalAmount.toStringAsFixed(0)}", style: fontTextStyle( 12, Color(0xFF515253), FontWeight.w500, ), ), ], ), ), ], ), ), ), ); } /// UI @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: AppSettings.supplierAppBarWithoutActions( "Plan Requests", context), body: isPlanRequestsDataLoading ? Center( child: CircularProgressIndicator( color: primaryColor, strokeWidth: 5, )) : planRequestsList.isEmpty ? Center( child: Text( "No Data Available", style: fontTextStyle( 12, Colors.black, FontWeight.w500), ), ) : ListView( children: [ /// NEW REQUESTS Padding( padding: EdgeInsets.all(10), child: Text( "PLAN REQUESTS", style: fontTextStyle( 10, Color(0XFF646566), FontWeight.w400), ), ), ...acceptedPlans .map((plan) => planCard(plan)) .toList(), /// REJECTED if (rejectedPlans.isNotEmpty) ...[ Padding( padding: EdgeInsets.all(10), child: Text( "REJECTED REQUESTS", style: fontTextStyle( 10, Color(0XFF646566), FontWeight.w400), ), ), ...rejectedPlans .map((plan) => planCard(plan)) .toList() ] ], ), ); } }