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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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()
]
],
),
);
}
}