You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

369 lines
10 KiB

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<PlanRequestsScreen> createState() => _PlanRequestsScreenState();
}
class _PlanRequestsScreenState extends State<PlanRequestsScreen> {
bool isPlanRequestsDataLoading = false;
List<PlanRequestModel> planRequestsList = [];
List<PlanRequestModel> acceptedPlans = [];
List<PlanRequestModel> rejectedPlans = [];
@override
void initState() {
super.initState();
getAcceptedPlansFromSupplier();
}
/// API CALL
Future<void> 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()
]
],
),
);
}
}