Commit 97cb09f8 authored by Sai Srinivas's avatar Sai Srinivas
Browse files

Profile and some more changes

parent b8c2cae9
......@@ -25,7 +25,7 @@ android {
applicationId = "in.webgrid.genrentals"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = 23
minSdk = flutter.minSdkVersion
targetSdk = 36
versionCode = flutter.versionCode
versionName = flutter.versionName
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:label="Gen Rentals"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true"
android:enableOnBackInvokedCallback="true"> <!-- Fixed: Removed extra quote and corrected placement -->
android:enableOnBackInvokedCallback="true">
<activity
android:name=".MainActivity"
android:exported="true"
......@@ -34,8 +36,7 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
......
class BillDetailsResponse {
int? error;
BillDetails? billDetails;
String? message;
BillDetailsResponse({this.error, this.billDetails, this.message});
BillDetailsResponse.fromJson(Map<String, dynamic> json) {
error = json['error'];
billDetails = json['bill_details'] != null
? new BillDetails.fromJson(json['bill_details'])
: null;
message = json['message'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['error'] = this.error;
if (this.billDetails != null) {
data['bill_details'] = this.billDetails!.toJson();
}
data['message'] = this.message;
return data;
}
}
class BillDetails {
String? id;
String? billNumber;
String? orderId;
String? narration;
String? basicPrice;
String? cgst;
String? sgst;
String? igst;
String? totalPrice;
String? empId;
String? billDate;
String? datetime;
String? delEmp;
String? isExist;
String? remarks;
String? product;
String? orderNumber;
String? billPaid;
String? paidDate;
BillDetails(
{this.id,
this.billNumber,
this.orderId,
this.narration,
this.basicPrice,
this.cgst,
this.sgst,
this.igst,
this.totalPrice,
this.empId,
this.billDate,
this.datetime,
this.delEmp,
this.isExist,
this.remarks,
this.product,
this.orderNumber,
this.billPaid,
this.paidDate});
BillDetails.fromJson(Map<String, dynamic> json) {
id = json['id'];
billNumber = json['bill_number'];
orderId = json['order_id'];
narration = json['narration'];
basicPrice = json['basic_price'];
cgst = json['cgst'];
sgst = json['sgst'];
igst = json['igst'];
totalPrice = json['total_price'];
empId = json['emp_id'];
billDate = json['bill_date'];
datetime = json['datetime'];
delEmp = json['del_emp'];
isExist = json['is_exist'];
remarks = json['remarks'];
product = json['product'];
orderNumber = json['order_number'];
billPaid = json['bill_paid'];
paidDate = json['paid_date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['bill_number'] = this.billNumber;
data['order_id'] = this.orderId;
data['narration'] = this.narration;
data['basic_price'] = this.basicPrice;
data['cgst'] = this.cgst;
data['sgst'] = this.sgst;
data['igst'] = this.igst;
data['total_price'] = this.totalPrice;
data['emp_id'] = this.empId;
data['bill_date'] = this.billDate;
data['datetime'] = this.datetime;
data['del_emp'] = this.delEmp;
data['is_exist'] = this.isExist;
data['remarks'] = this.remarks;
data['product'] = this.product;
data['order_number'] = this.orderNumber;
data['bill_paid'] = this.billPaid;
data['paid_date'] = this.paidDate;
return data;
}
}
class BillListResponse {
int? error;
List<Bills>? bills;
LatestBill? latestBill;
String? message;
int? sessionExists;
BillListResponse(
{this.error,
this.bills,
this.latestBill,
this.message,
this.sessionExists});
BillListResponse.fromJson(Map<String, dynamic> json) {
error = json['error'];
if (json['bills'] != null) {
bills = <Bills>[];
json['bills'].forEach((v) {
bills!.add(new Bills.fromJson(v));
});
}
latestBill = json['latest_bill'] != null
? new LatestBill.fromJson(json['latest_bill'])
: null;
message = json['message'];
sessionExists = json['session_exists'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['error'] = this.error;
if (this.bills != null) {
data['bills'] = this.bills!.map((v) => v.toJson()).toList();
}
if (this.latestBill != null) {
data['latest_bill'] = this.latestBill!.toJson();
}
data['message'] = this.message;
data['session_exists'] = this.sessionExists;
return data;
}
}
class Bills {
String? id;
String? billNumber;
String? orderId;
String? narration;
String? totalPrice;
String? billDate;
Bills(
{this.id,
this.billNumber,
this.orderId,
this.narration,
this.totalPrice,
this.billDate});
Bills.fromJson(Map<String, dynamic> json) {
id = json['id'];
billNumber = json['bill_number'];
orderId = json['order_id'];
narration = json['narration'];
totalPrice = json['total_price'];
billDate = json['bill_date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['bill_number'] = this.billNumber;
data['order_id'] = this.orderId;
data['narration'] = this.narration;
data['total_price'] = this.totalPrice;
data['bill_date'] = this.billDate;
return data;
}
}
class LatestBill {
String? id;
String? billNumber;
String? orderId;
String? narration;
String? totalPrice;
String? billDate;
String? billPaid;
LatestBill(
{this.id,
this.billNumber,
this.orderId,
this.narration,
this.totalPrice,
this.billDate,
this.billPaid});
LatestBill.fromJson(Map<String, dynamic> json) {
id = json['id'];
billNumber = json['bill_number'];
orderId = json['order_id'];
narration = json['narration'];
totalPrice = json['total_price'];
billDate = json['bill_date'];
billPaid = json['bill_paid'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['bill_number'] = this.billNumber;
data['order_id'] = this.orderId;
data['narration'] = this.narration;
data['total_price'] = this.totalPrice;
data['bill_date'] = this.billDate;
data['bill_paid'] = this.billPaid;
return data;
}
}
......@@ -2,6 +2,7 @@ class CommonResponse {
int? error;
int? balance;
String? message;
String? filePath;
CommonResponse({this.error, this.balance, this.message});
......@@ -9,6 +10,7 @@ class CommonResponse {
error = int.tryParse(json['error']?.toString() ?? '');
balance = int.tryParse(json['balance']?.toString() ?? '');
message = json['message']?.toString();
filePath = json['file_path']?.toString();
}
Map<String, dynamic> toJson() {
......@@ -16,6 +18,7 @@ class CommonResponse {
'error': error,
'balance': balance,
'message': message,
'file_path': filePath,
};
}
}
......
class PaymentReceiptDetailsResponse {
int? error;
ReceiptDetails? receiptDetails;
String? message;
int? sessionExists;
PaymentReceiptDetailsResponse(
{this.error, this.receiptDetails, this.message, this.sessionExists});
PaymentReceiptDetailsResponse.fromJson(Map<String, dynamic> json) {
error = json['error'];
receiptDetails = json['receipt_details'] != null
? new ReceiptDetails.fromJson(json['receipt_details'])
: null;
message = json['message'];
sessionExists = json['session_exists'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['error'] = this.error;
if (this.receiptDetails != null) {
data['receipt_details'] = this.receiptDetails!.toJson();
}
data['message'] = this.message;
data['session_exists'] = this.sessionExists;
return data;
}
}
class ReceiptDetails {
String? id;
String? accId;
String? billId;
String? narration;
String? cAmount;
String? dAmount;
String? atype;
String? type;
String? mode;
String? refNo;
String? empId;
String? datetime;
String? prDate;
String? depositedTo;
String? delEmp;
String? delDatetime;
String? isExist;
String? isJv;
ReceiptDetails(
{this.id,
this.accId,
this.billId,
this.narration,
this.cAmount,
this.dAmount,
this.atype,
this.type,
this.mode,
this.refNo,
this.empId,
this.datetime,
this.prDate,
this.depositedTo,
this.delEmp,
this.delDatetime,
this.isExist,
this.isJv});
ReceiptDetails.fromJson(Map<String, dynamic> json) {
id = json['id'];
accId = json['acc_id'];
billId = json['bill_id'];
narration = json['narration'];
cAmount = json['c_amount'];
dAmount = json['d_amount'];
atype = json['atype'];
type = json['type'];
mode = json['mode'];
refNo = json['ref_no'];
empId = json['emp_id'];
datetime = json['datetime'];
prDate = json['pr_date'];
depositedTo = json['deposited_to'];
delEmp = json['del_emp'];
delDatetime = json['del_datetime'];
isExist = json['is_exist'];
isJv = json['is_jv'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['acc_id'] = this.accId;
data['bill_id'] = this.billId;
data['narration'] = this.narration;
data['c_amount'] = this.cAmount;
data['d_amount'] = this.dAmount;
data['atype'] = this.atype;
data['type'] = this.type;
data['mode'] = this.mode;
data['ref_no'] = this.refNo;
data['emp_id'] = this.empId;
data['datetime'] = this.datetime;
data['pr_date'] = this.prDate;
data['deposited_to'] = this.depositedTo;
data['del_emp'] = this.delEmp;
data['del_datetime'] = this.delDatetime;
data['is_exist'] = this.isExist;
data['is_jv'] = this.isJv;
return data;
}
}
class BillListResponse {
List<Bills>? bills;
int? error;
String? message;
BillListResponse({this.bills, this.error, this.message});
BillListResponse.fromJson(Map<String, dynamic> json) {
if (json['bills'] != null) {
bills = <Bills>[];
json['bills'].forEach((v) {
bills!.add(new Bills.fromJson(v));
});
}
error = json['error'];
message = json['message'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.bills != null) {
data['bills'] = this.bills!.map((v) => v.toJson()).toList();
}
data['error'] = this.error;
data['message'] = this.message;
return data;
}
}
class Bills {
String? datetime;
String? billNarration;
String? totalAmount;
String? billId;
String? type;
Bills(
{this.datetime,
this.billNarration,
this.totalAmount,
this.billId,
this.type});
Bills.fromJson(Map<String, dynamic> json) {
datetime = json['datetime'];
billNarration = json['bill_narration'];
totalAmount = json['total_amount'];
billId = json['bill_id'];
type = json['type'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['datetime'] = this.datetime;
data['bill_narration'] = this.billNarration;
data['total_amount'] = this.totalAmount;
data['bill_id'] = this.billId;
data['type'] = this.type;
return data;
}
}
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:gen_rentals/Services/api_calling.dart';
import 'package:gen_rentals/Utility/CustomSnackbar.dart';
import '../Models/BillsModels/BillDetailsResponse.dart';
import '../Models/BillsModels/billListResponse.dart';
import 'package:path_provider/path_provider.dart'; //
import 'package:open_filex/open_filex.dart';
import '../Services/api_post_request.dart'; //
class BillProvider extends ChangeNotifier {
bool _isLoading = false;
BillListResponse? _billListResponse;
bool get isLoading => _isLoading;
BillListResponse? get billListResponse => _billListResponse;
List<Bills> get bills => _billListResponse?.bills ?? [];
LatestBill? get latestBill => _billListResponse?.latestBill;
/// Fetch Bill List
Future<void> fetchBillList(
String sessionId, String orderId, String accId) async {
try {
_isLoading = true;
notifyListeners();
final response = await ApiCalling.fetchBillListApi(
sessionId,
orderId,
accId,
);
if (response != null && response.error == 0) {
_billListResponse = response;
} else {
_billListResponse = null;
debugPrint("❌ API Error: ${response?.message}");
}
} catch (e) {
debugPrint("❌ Exception in BillProvider: $e");
_billListResponse = null;
} finally {
_isLoading = false;
notifyListeners();
}
}
/// Clear Data
void clearData() {
_billListResponse = null;
notifyListeners();
}
/// Bill Details
BillDetails? _billDetails;
BillDetails? get billDetails => _billDetails;
bool _isDetailsLoading = false;
bool get isDetailsLoading => _isDetailsLoading;
/// Error message (optional)
String? _errorMessage;
String? get errorMessage => _errorMessage;
/// Fetch details for a specific bill
Future<void> fetchBillDetails(String sessionId, String accId, String billId) async {
try {
_isDetailsLoading = true;
_errorMessage = null;
notifyListeners();
final response = await ApiCalling.fetchBillDetailsApi(sessionId, accId, billId);
if (response != null && response.error == 0) {
_billDetails = response.billDetails;
} else {
_errorMessage = response?.message ?? "Unable to load bill details";
}
} catch (e) {
_errorMessage = e.toString();
debugPrint("❌ Error (fetchBillDetails): $e");
} finally {
_isDetailsLoading = false;
notifyListeners();
}
}
/// Clear bill details (optional, if you navigate away from details screen)
void clearBillDetails() {
_billDetails = null;
notifyListeners();
}
bool _isDownloading = false;
bool get isDownloading => _isDownloading;
void setDownloading(bool value) {
_isDownloading = value;
notifyListeners();
}
/// 🧾 Download Bill
Future<void> downloadBill(BuildContext context,
String sessionId, String billId, String accId) async {
setDownloading(true);
try {
// Step 1: Call billDownloadApi to get file path
final res = await ApiCalling.billDownloadApi(sessionId, billId, accId);
if (res == null || res.error != 0 || res.filePath == null) {
// showToast(res?.message ?? "Download failed");
setDownloading(false);
return;
}
final fileUrl = res.filePath!;
final dir = await getApplicationDocumentsDirectory();
final savePath = '${dir.path}/receipt_${billId}.pdf';
// Step 2: Download file
final success = await downloadFile(fileUrl, savePath);
if (success) {
CustomSnackBar.showSuccess(
context: context,
message: "File downloaded successfully!"
);
// showToast("File downloaded successfully!");
await OpenFilex.open(savePath);
} else {
CustomSnackBar.showError(
context: context,
message: "Failed to download file"
);
// showToast("Failed to download file");
}
} catch (e) {
debugPrint("❌ Bill download error: $e");
CustomSnackBar.showError(
context: context,
message: "Error downloading file"
);
// showToast("Error downloading file");
} finally {
setDownloading(false);
}
}
/// File Downloader
Future<bool> downloadFile(String apiUrl, String savePath) async {
try {
final response = await get(apiUrl, {}); // Using your get() helper
if (response != null && response.statusCode == 200) {
final file = File(savePath);
await file.writeAsBytes(response.bodyBytes);
return true;
} else {
debugPrint("❌ Failed to download file: ${response?.statusCode}");
return false;
}
} catch (e) {
debugPrint("❌ File download error: $e");
return false;
}
}
}
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:gen_rentals/Screens/HelpScreens/HelpScreen.dart';
import 'package:gen_rentals/Screens/HelpScreens/TicketChatScreen.dart';
import 'package:gen_rentals/Services/api_calling.dart';
import '../Models/HelpAndEnquiryModels/TicketChatDisplayResponse.dart';
import '../Models/HelpAndEnquiryModels/ticketListResponse.dart';
import '../Utility/CustomSnackbar.dart';
import 'package:http/http.dart' as http;
import 'dart:io';
import 'package:path/path.dart' as path;
class HelpAndEnquiryProvider extends ChangeNotifier {
bool _isLoading = false;
......@@ -174,18 +178,28 @@ class HelpAndEnquiryProvider extends ChangeNotifier {
}) async {
_setSending(true);
try {
// ✅ Convert List<File> to List<MultipartFile>
List<http.MultipartFile> multipartImages = [];
for (var file in images) {
final multipartFile = await http.MultipartFile.fromPath(
'images[]', // <-- must match your backend field name
file.path,
filename: path.basename(file.path),
);
multipartImages.add(multipartFile);
}
final response = await ApiCalling.addMessageApi(
sessionId,
accId,
ticketId,
msgText,
images,
multipartImages,
);
// Check if widget is still mounted before showing dialogs
if (!context.mounted) return;
if (response != null || response?.error == 0) {
if (response != null && response?.error == 0) {
CustomSnackBar.showSuccess(
context: context,
message: response?.message ?? "Message sent successfully!",
......@@ -236,6 +250,7 @@ class HelpAndEnquiryProvider extends ChangeNotifier {
required String type,
required String description,
required String orderId,
required String otherReason,
required List<File> images,
}) async {
_setCreatingTicket(true);
......@@ -246,15 +261,24 @@ class HelpAndEnquiryProvider extends ChangeNotifier {
type,
description,
orderId,
otherReason,
images,
);
if (response != null && response.error == "0") {
CustomSnackBar.showInfo(
// Check if widget is still mounted before showing dialogs
if (!context.mounted) return;
if (response != null && response?.error == 0) {
CustomSnackBar.showSuccess(
context: context,
message: response.message ?? "Ticket created successfully!",
message: response?.message ?? "Ticket created successfully!",
);
Navigator.pop(context); // close bottom sheet or dialog if open
//Navigator.pop(context); // close bottom sheet or dialog if open
if (context.mounted) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HelpScreen(sessionId: sessionId, accId: accId))
);
}
} else {
CustomSnackBar.showError(
......
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:gen_rentals/Services/api_calling.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'dart:io';
import '../Models/CommonResponse.dart';
class RentalProvider extends ChangeNotifier {
FetchMobileResponse? _response;
FetchMobileResponse? otpResponse;
......@@ -82,6 +86,68 @@ class RentalProvider extends ChangeNotifier {
return {};
}
bool _isLoggingOut = false;
bool get isLoggingOut => _isLoggingOut;
CommonResponse? _logoutResponse;
CommonResponse? get logoutResponse => _logoutResponse;
/// 🔹 Set loading state
void _setLoggingOut(bool value) {
_isLoggingOut = value;
notifyListeners();
}
/// 🔹 Call logout API
Future<void> logout(
BuildContext context,
String accId,
String sessionId,
Map<String, String> deviceDetails,
) async {
try {
_setLoggingOut(true);
log("📡 Calling Logout API...");
final response =
await ApiCalling.logoutApi(accId, sessionId, deviceDetails);
_logoutResponse = response;
_setLoggingOut(false);
if (response != null && response.error == 0) {
log("✅ Logout successful: ${response.message}");
// Clear user data if needed
// await SharedPrefHelper.clearAll();
// Show toast/snackbar
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(response.message ?? "Logout successful"),
backgroundColor: Colors.green,
),
);
// Navigate to login screen
// Navigator.pushNamedAndRemoveUntil(context, '/login', (_) => false);
} else {
log("❌ Logout failed: ${response?.message}");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(response?.message ?? "Logout failed"),
backgroundColor: Colors.red,
),
);
}
} catch (e) {
_setLoggingOut(false);
log("🚨 Logout Error: $e");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Something went wrong: $e")),
);
}
}
}
......
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:gen_rentals/Services/api_calling.dart';
import '../Models/TransactionsResponse.dart';
import 'package:path_provider/path_provider.dart'; //
import 'package:open_filex/open_filex.dart';
import '../Models/TransactionModels/PaymentReceiptDetailsResponse.dart';
import '../Models/TransactionModels/TransactionsResponse.dart';
import '../Services/api_post_request.dart';
import '../Utility/CustomSnackbar.dart';
class TransactionsProvider with ChangeNotifier {
bool _isLoading = false;
......@@ -45,4 +50,124 @@ class TransactionsProvider with ChangeNotifier {
_transactionsResponse = null;
notifyListeners();
}
ReceiptDetails? _receiptDetails;
ReceiptDetails? get receiptDetails => _receiptDetails;
/// Fetch payment receipt details
Future<void> fetchPaymentReceiptDetails(
String sessionId, String accId, String ledgerId) async {
_isLoading = true;
notifyListeners();
try {
final response = await ApiCalling.fetchPaymentReceiptDetailsApi(
sessionId,
accId,
ledgerId,
);
if (response != null && response.error == 0) {
_receiptDetails = response.receiptDetails;
log("✅ Payment Receipt Fetched: ${_receiptDetails?.id}");
} else {
log("⚠️ Payment Receipt Error: ${response?.message}");
}
} catch (e) {
log("❌ Provider Error (fetchPaymentReceiptDetails): $e");
} finally {
_isLoading = false;
notifyListeners();
}
}
/// Clear old data
void clearData() {
_receiptDetails = null;
notifyListeners();
}
bool _isDownloading = false;
bool get isDownloading => _isDownloading;
void setDownloading(bool value) {
_isDownloading = value;
notifyListeners();
}
/// Download Payment Receipt
Future<void> downloadPaymentReceipt(
BuildContext context,
String sessionId,
String ledgerId,
String accId,
) async {
setDownloading(true);
try {
// Step 1: Call paymentReceiptDownloadApi to get file URL/path
final res = await ApiCalling.paymentReceiptDownloadApi(sessionId, ledgerId, accId);
if (res == null || res.error != 0 || res.filePath == null) {
CustomSnackBar.showError(
context: context,
message: res?.message ?? "Download failed",
);
setDownloading(false);
return;
}
final fileUrl = res.filePath!;
final dir = await getApplicationDocumentsDirectory();
final savePath = '${dir.path}/payment_receipt_$ledgerId.pdf';
// Step 2: Download file using helper
final success = await downloadFile(fileUrl, savePath);
if (success) {
CustomSnackBar.showSuccess(
context: context,
message: "Payment receipt downloaded successfully!",
);
await OpenFilex.open(savePath);
} else {
CustomSnackBar.showError(
context: context,
message: "Failed to download payment receipt",
);
}
} catch (e) {
debugPrint("❌ Payment receipt download error: $e");
CustomSnackBar.showError(
context: context,
message: "Error downloading payment receipt",
);
} finally {
setDownloading(false);
}
}
/// File Downloader
Future<bool> downloadFile(String apiUrl, String savePath) async {
try {
final response = await get(apiUrl, {}); // Using your shared GET helper
if (response != null && response.statusCode == 200) {
final file = File(savePath);
await file.writeAsBytes(response.bodyBytes);
return true;
} else {
debugPrint("❌ Failed to download file: ${response?.statusCode}");
return false;
}
} catch (e) {
debugPrint("❌ File download error: $e");
return false;
}
}
}
class BillDetailsResponse {
List<BillDetails>? billDetails;
int? error;
String? message;
BillDetailsResponse({this.billDetails, this.error, this.message});
BillDetailsResponse.fromJson(Map<String, dynamic> json) {
if (json['bill_details'] != null) {
billDetails = <BillDetails>[];
json['bill_details'].forEach((v) {
billDetails!.add(new BillDetails.fromJson(v));
});
}
error = json['error'];
message = json['message'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.billDetails != null) {
data['bill_details'] = this.billDetails!.map((v) => v.toJson()).toList();
}
data['error'] = this.error;
data['message'] = this.message;
return data;
}
}
class BillDetails {
String? totalAmount;
String? raisedOn;
String? billNarration;
String? billId;
String? orderId;
BillDetails(
{this.totalAmount,
this.raisedOn,
this.billNarration,
this.billId,
this.orderId});
BillDetails.fromJson(Map<String, dynamic> json) {
totalAmount = json['total_amount'];
raisedOn = json['raised_on'];
billNarration = json['bill_narration'];
billId = json['bill_id'];
orderId = json['order_id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['total_amount'] = this.totalAmount;
data['raised_on'] = this.raisedOn;
data['bill_narration'] = this.billNarration;
data['bill_id'] = this.billId;
data['order_id'] = this.orderId;
return data;
}
}
This diff is collapsed.
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:gen_rentals/Models/BillsModels/BillDetailsResponse.dart';
import 'package:gen_rentals/Utility/AppColors.dart';
import 'package:gen_rentals/Utility/Reusablewidgets.dart';
import 'package:provider/provider.dart';
import '../../Notifier/BillProvider.dart';
import '../DashboardScreen.dart';
import 'BillDetailScreen.dart';
class BillDetailListScreen extends StatefulWidget {
final String sessionId;
final String accId;
final String orderId;
BillDetailListScreen({
super.key,
required this.sessionId,
required this.accId,
required this.orderId,
});
@override
State<BillDetailListScreen> createState() => _BillDetailListScreenState();
}
class _BillDetailListScreenState extends State<BillDetailListScreen> {
@override
void initState() {
super.initState();
Future.microtask(() {
final provider = Provider.of<BillProvider>(context, listen: false);
provider.fetchBillList(widget.sessionId, widget.orderId, widget.accId);
});
}
@override
Widget build(BuildContext context) {
return Consumer<BillProvider>(
builder: (context, provider, _) {
if (provider.isLoading) {
return const Scaffold(
body: Center(child: CircularProgressIndicator()),
);
}
final latest = provider.latestBill;
final bills = provider.bills;
return SafeArea(
top: false,
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
title: Row(
children: [
InkResponse(
onTap: () => Navigator.pop(context, true),
child: SvgPicture.asset(
"assets/svg/continue_left_ic.svg",
height: 25,
),
),
const SizedBox(width: 10),
const Text(
"Bill List",
style: TextStyle(
fontSize: 16,
fontFamily: "Plus Jakarta Sans",
fontWeight: FontWeight.w400,
color: Colors.black87,
),
),
],
),
),
backgroundColor: AppColors.backgroundRegular,
body: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 14),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SectionHeading(
title: 'Latest Bill',
textStyle: TextStyle(
fontFamily: "Poppins",
color: AppColors.normalText,
fontSize: 14,
fontWeight: FontWeight.w500,
),
padding:
const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
),
const SizedBox(height: 12),
// ✅ Latest Bill Card
if (latest != null)
InkResponse(
onTap: () {
if (latest.billPaid == "Yes") {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => BillDetailScreen(
sessionId: widget.sessionId,
accId: widget.accId,
billId: latest.id.toString()))
);
}
},
child: Container(
width: double.infinity,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
gradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFFE9FFDD),
Color(0xFFB5FFD1),
],
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"₹${latest.totalPrice ?? '0'}",
style: TextStyle(
fontFamily: "Poppins",
color: AppColors.cardAmountText,
fontSize: 34,
fontWeight: FontWeight.w500,
),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 6),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
),
child: Stack(
children: [
if(latest.billPaid == "Yes")
Row(
children: [
SvgPicture.asset(
"assets/svg/success_ic.svg",
height: 18,
width: 18,
),
const SizedBox(width: 6),
Text(
"Bill Paid",
style: const TextStyle(
fontFamily: "Poppins",
color: Color(0xFF212121),
fontSize: 14,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
),
),
],
),
// Pending
if(latest.billPaid == "No")
InkResponse(
onTap: () => showPaymentBottomSheet(context, payBill: "1299", payTotal: "4218"),
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: Color(0xE0008CDE),
borderRadius: BorderRadius.circular(14),
),
child: Text(
"Pay Now",
style: TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
),
),
],
),
),
],
),
const SizedBox(height: 16),
Container(
height: 1,
color: const Color(0xFF777777).withOpacity(0.3),
),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Invoice raised against",
style: TextStyle(
fontFamily: "Poppins",
fontStyle: FontStyle.normal,
color: AppColors.normalText,
fontWeight: FontWeight.w400,
fontSize: 14,
),
),
Text(
"#${latest.id ?? '-'}",
style: TextStyle(
fontFamily: "Poppins",
fontStyle: FontStyle.normal,
color: AppColors.amountText,
fontWeight: FontWeight.w400,
fontSize: 14,
),
),
],
),
const SizedBox(height: 4),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Order ID: ${latest.orderId ?? '-'}",
style: TextStyle(
fontFamily: "Poppins",
fontStyle: FontStyle.normal,
color: AppColors.normalText,
fontWeight: FontWeight.w400,
fontSize: 14,
),
),
Text(
latest.billDate ?? '',
style: TextStyle(
fontStyle: FontStyle.normal,
fontFamily: "Poppins",
color: AppColors.normalText,
fontWeight: FontWeight.w400,
fontSize: 14,
),
),
],
),
],
),
),
)
else
const Center(child: Text("No Latest Bill Found")),
const SizedBox(height: 24),
SectionHeading(
title: 'All Previous Bills',
textStyle: TextStyle(
fontFamily: "Poppins",
color: AppColors.normalText,
fontSize: 14,
fontWeight: FontWeight.w500,
),
padding:
const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
),
const SizedBox(height: 8),
// ✅ Bill List
Expanded(
child: bills.isEmpty
? const Center(child: Text("No Previous Bills"))
: ListView.separated(
itemCount: bills.length,
separatorBuilder: (_, __) =>
const SizedBox(height: 8),
itemBuilder: (context, index) {
final bill = bills[index];
return InkResponse(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => BillDetailScreen(
sessionId: widget.sessionId,
accId: widget.accId,
billId: latest!.id.toString(),
),)
);
},
child: _buildBillItem(
orderId: "#${bill.id ?? ''}",
fromDate: bill.billDate ?? '',
toDate: bill.billDate ?? '',
amount: bill.totalPrice ?? '0',
),
);
},
),
),
],
),
),
),
);
},
);
}
Widget _buildBillItem({
String orderId = "#1253",
String title = "Invoice raised against",
required String fromDate,
required String toDate,
required String amount,
}) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
decoration: BoxDecoration(
color: Colors.grey.shade50,
borderRadius: BorderRadius.circular(18),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
orderId,
style: TextStyle(
fontFamily: "Poppins",
color: AppColors.amountText,
fontWeight: FontWeight.w400,
fontStyle: FontStyle.normal,
fontSize: 14,
),
),
const SizedBox(height: 2),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
title,
style: TextStyle(
fontFamily: "Poppins",
color: AppColors.normalText,
fontWeight: FontWeight.w400,
fontStyle: FontStyle.normal,
fontSize: 14,
),
),
Text(
fromDate,
style: TextStyle(
fontFamily: "Poppins",
color: AppColors.subtitleText,
fontSize: 12,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
),
),
],
),
const SizedBox(height: 2),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Order ID : ${orderId.replaceAll('#', '')}",
style: TextStyle(
fontFamily: "Poppins",
color: AppColors.normalText,
fontWeight: FontWeight.w400,
fontStyle: FontStyle.normal,
fontSize: 14,
),
),
Text(
"₹$amount",
style: TextStyle(
fontFamily: "Poppins",
color: AppColors.cardAmountText,
fontSize: 14,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
),
),
],
),
],
),
);
}
void showPaymentBottomSheet(
BuildContext context, {
String? payTotal = "4218",
String? payBill = "2018",
}) {
showModalBottomSheet(
context: context,
isScrollControlled: true, // This is important
backgroundColor: Colors.transparent,
isDismissible: true,
enableDrag: true,
builder: (BuildContext context) {
return PaymentBottomSheetContent(
payTotal: payTotal,
payBill: payBill,
billFlag: true,
partFlag: false,
);
},
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';
import '../../Notifier/BillProvider.dart';
import '../../Utility/AppColors.dart';
import '../../Utility/Reusablewidgets.dart';
class BillDetailScreen extends StatefulWidget {
final String sessionId;
final String accId;
final String billId;
const BillDetailScreen({
super.key,
required this.sessionId,
required this.accId,
required this.billId,
});
@override
State<BillDetailScreen> createState() => _BillDetailScreenState();
}
class _BillDetailScreenState extends State<BillDetailScreen> {
@override
void initState() {
super.initState();
Future.microtask(() {
final provider = Provider.of<BillProvider>(context, listen: false);
provider.fetchBillDetails(widget.sessionId, widget.accId, "15068");
});
}
@override
Widget build(BuildContext context) {
return Consumer<BillProvider>(
builder: (context, provider, _) {
if (provider.isDetailsLoading) {
return const Scaffold(
body: Center(child: CircularProgressIndicator()
),
);
}
final details = provider.billDetails;
if (details == null) {
return Scaffold(
body: Center(
child: Text(
provider.errorMessage ?? "No details found",
style: const TextStyle(fontSize: 16),
),
),
);
}
return SafeArea(
top: false,
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
elevation: 0,
title: Row(
children: [
InkResponse(
onTap: () => Navigator.pop(context, true),
child: SvgPicture.asset(
"assets/svg/continue_left_ic.svg",
height: 28,
),
),
const SizedBox(width: 10),
const Text(
"Bill Details",
style: TextStyle(
fontSize: 16,
fontFamily: "Plus Jakarta Sans",
fontWeight: FontWeight.w600,
color: Colors.black87,
),
),
],
),
),
backgroundColor: AppColors.backgroundRegular,
body: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// ✅ Green Tick Circle
Container(
height: 70,
width: 70,
decoration: const BoxDecoration(
color: Color(0xFFDFF8E1),
shape: BoxShape.circle,
),
child: const Icon(
Icons.check_circle,
color: Colors.green,
size: 50,
),
),
const SizedBox(height: 16),
// Bill Paid Title
const Text(
"Bill Paid",
style: TextStyle(
fontSize: 24,
fontFamily: "Poppins",
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
),
),
const SizedBox(height: 6),
// Total Amount
Text(
"₹${details.totalPrice ?? "0"}",
style: const TextStyle(
fontSize: 34,
fontFamily: "Poppins",
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 24),
Divider(color: Colors.grey.shade300),
const SizedBox(height: 10),
// Payment Details
Align(
alignment: Alignment.centerLeft,
child: Text(
"Payment Details",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.black87,
),
),
),
const SizedBox(height: 10),
_buildRow("Date", "${details.paidDate ?? ''}",
highlight: true),
// _buildRow(
// "Date",
// details.billDate != null
// ? DateFormat("d MMM, yyyy").format(
// DateTime.parse(details.billDate!),
// )
// : "-",
// ),
const SizedBox(height: 14),
// Product Details
Align(
alignment: Alignment.centerLeft,
child: Text(
"Products",
style: TextStyle(
fontSize: 14,
fontFamily: "Plus Jakarta Sans",
fontWeight: FontWeight.w600,
color: Colors.grey.shade800,
),
),
),
const SizedBox(height: 8),
_buildRow(details.product ?? "N/A", "₹${details.basicPrice ?? "0"}"),
const SizedBox(height: 8),
_buildRow("Sub Total", "₹${details.basicPrice ?? "0"}"),
_buildRow("Gross Amount", "₹${details.totalPrice ?? "0"}"),
_buildRow("SGST", details.sgst ?? "0"),
_buildRow("CGST", details.cgst ?? "0"),
_buildRow("IGST", details.igst ?? "0"),
const Divider(height: 30),
_buildRow(
"Total",
"₹${details.totalPrice ?? "0"}",
isBold: true,
),
const SizedBox(height: 40),
// Download Button
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: provider.isDownloading
? null
: () {
provider.downloadBill(
context,
widget.sessionId,
widget.billId,
widget.accId,
);
},
icon: provider.isDownloading
? const SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(
color: Colors.white,
strokeWidth: 2,
),
)
: const Icon(Icons.download, color: Colors.white),
label: Text(
provider.isDownloading
? "Downloading..."
: "Download Receipt",
style: const TextStyle(
fontSize: 16,
fontFamily: "Plus Jakarta Sans",
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.amountText,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
padding: const EdgeInsets.symmetric(vertical: 14),
),
),
),
],
),
),
),
);
},
);
}
/// Helper Row Widget
Widget _buildRow(String title, String value,
{bool isBold = false, bool highlight = false}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 7,
child: Text(
title,
maxLines: 2,
style: TextStyle(
fontSize: 14,
fontFamily: "Plus Jakarta Sans",
color: AppColors.subtitleText,
fontWeight: FontWeight.w400,
),
),
),
Text(
value,
style: TextStyle(
fontSize: 14,
fontFamily: "Plus Jakarta Sans",
fontWeight: isBold ? FontWeight.w700 : FontWeight.w400,
color: highlight
? AppColors.normalText
: Colors.grey.shade900,
),
),
],
),
);
}
}
......@@ -4,7 +4,7 @@ import 'package:gen_rentals/Screens/HelpScreens/EnquiryScreen.dart';
import 'package:gen_rentals/Screens/HelpScreens/HelpScreen.dart';
import 'package:gen_rentals/Screens/ProductsDetailScreen.dart';
import 'package:gen_rentals/Screens/ProfileScreen.dart';
import 'package:gen_rentals/Screens/TransactionsScreen.dart';
import 'package:gen_rentals/Screens/TransactionScreens/TransactionsScreen.dart';
import 'package:gen_rentals/Utility/AppColors.dart';
import 'package:gen_rentals/Utility/Reusablewidgets.dart';
import 'package:provider/provider.dart';
......@@ -410,14 +410,14 @@ class _DashboardScreenState extends State<DashboardScreen> {
),
],
),
const SizedBox(height: 24),
const SizedBox(height: 28),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SvgPicture.asset(
"assets/svg/requirements.svg",
height: 58,
width: 58,
height: 60,
width: 60,
),
],
),
......@@ -427,7 +427,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
),
),
const SizedBox(width: 10),
const SizedBox(width: 5),
// Side cards column
Expanded(
......@@ -437,7 +437,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
// Have Complaints card
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
......@@ -472,7 +472,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
child: Text(
"Need Help?",
style: TextStyle(
fontFamily: "Poppins",
fontFamily: "PoppinsBold",
color: Color(0xFF008CDE),
fontSize: 14,
fontWeight: FontWeight.w400,
......@@ -522,7 +522,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
},
child: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
......@@ -969,14 +969,14 @@ class _DashboardScreenState extends State<DashboardScreen> {
switch (color) {
case "Red":
return const LinearGradient(
colors: [Color(0xFFFFE0E0), Color(0xFFFFC0C0)],
colors: [Color(0xFFFFEBEB), Color(0xFFFFEBEB)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
case "Green":
default:
return const LinearGradient(
colors: [Color(0xFFE9FFDD), Color(0xFFB5FFD1)],
colors: [Color(0xFFE5FFE2), Color(0xFFE5FFE2)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
......@@ -1026,7 +1026,8 @@ class _DashboardScreenState extends State<DashboardScreen> {
return PaymentBottomSheetContent(
payTotal: payTotal,
payBill: payBill,
flag: false,
billFlag: false,
partFlag: true,
);
},
);
......@@ -1039,13 +1040,15 @@ class _DashboardScreenState extends State<DashboardScreen> {
class PaymentBottomSheetContent extends StatefulWidget {
final String? payTotal;
final String? payBill;
final bool flag;
final bool billFlag;
final bool partFlag;
const PaymentBottomSheetContent({
super.key,
this.payTotal,
this.payBill,
required this.flag,
required this.billFlag,
required this.partFlag,
});
@override
......@@ -1249,7 +1252,7 @@ class _PaymentBottomSheetContentState extends State<PaymentBottomSheetContent> {
),
// Pay Bill
if (widget.flag == true)
if (widget.billFlag == true)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
......@@ -1283,6 +1286,7 @@ class _PaymentBottomSheetContentState extends State<PaymentBottomSheetContent> {
),
// Part Payment
if (widget.partFlag == true)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
......
......@@ -111,13 +111,13 @@ class _HelpTicketScreenState extends State<HelpTicketScreen> {
),
Container(
padding:
const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
const EdgeInsets.symmetric(horizontal: 18, vertical: 10),
decoration: BoxDecoration(
color: Colors.blue.shade50,
color: Color(0xFFE0F4FF),
borderRadius: BorderRadius.circular(10),
),
child: const Text(
"order #1235",
child: Text(
"order #${ widget.orderId}",
style: TextStyle(
fontSize: 12,
fontFamily: "Plus Jakarta Sans",
......@@ -363,36 +363,49 @@ class _HelpTicketScreenState extends State<HelpTicketScreen> {
Future<void> _submitTicket() async {
final issue = _issueController.text.trim();
final otherReason = _otherReasonController.text.trim();
if (issue.isEmpty) {
CustomSnackBar.showWarning(
context: context,
message: "Please describe your issue"
context: context,
message: "Please describe your issue",
);
return;
}
if (_selectedReason == 'Other Issues' && otherReason.isEmpty) {
CustomSnackBar.showWarning(
context: context,
message: "Please enter your reason"
context: context,
message: "Please enter your reason",
);
return;
}
// Determine the reason type based on selected reason
String reason;
if (_selectedReason == "Payment Issues") {
reason = "Payment";
} else if (_selectedReason == "Bill Related Issues") {
reason = "Bill";
} else {
reason = "Other";
}
// If user selected "Other Issues", use the custom reason text
final customReason = _selectedReason == 'Other Issues' ? otherReason : null;
debugPrint("Reason ========= $reason");
final helpProvider =
Provider.of<HelpAndEnquiryProvider>(context, listen: false);
final reason =
_selectedReason == 'Other Issues' ? otherReason : _selectedReason;
debugPrint("Reason========= $reason");
await helpProvider.createTicket(
sessionId: widget.sessionId,
accId: widget.accId,
type: reason,
description: issue,
orderId: "1235",
otherReason: customReason.toString(),
images: _selectedImages,
context: context,
);
......
......@@ -158,7 +158,13 @@ class _HelpScreenState extends State<HelpScreen> {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => OrderHelpScreen(sessionId: widget.sessionId, accId: widget.accId))
);
).then((_) {
final provider = Provider.of<HelpAndEnquiryProvider>(context, listen: false);
provider.fetchTicketList(
sessionId: widget.sessionId,
accId: widget.accId,
);
});
},
child: Container(
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 14),
......@@ -289,7 +295,13 @@ class _HelpScreenState extends State<HelpScreen> {
status: "Closed",
),
),
);
).then((_) {
final provider = Provider.of<HelpAndEnquiryProvider>(context, listen: false);
provider.fetchTicketList(
sessionId: widget.sessionId,
accId: widget.accId,
);
});
},
),
);
......@@ -335,20 +347,20 @@ class CommonListItem extends StatelessWidget {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"#${orderId}",
style: TextStyle(
fontSize: 12,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
color: AppColors.subtitleText,
),
),
SizedBox(width: 10,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"#${orderId}",
style: TextStyle(
fontSize: 12,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
color: AppColors.subtitleText,
),
),
Text(
title,
style: TextStyle(
......@@ -377,7 +389,7 @@ class CommonListItem extends StatelessWidget {
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: Colors.green.withOpacity(0.2),
color: Color(0xFFD7FFD2),
borderRadius: BorderRadius.circular(6),
),
child: Text(
......
......@@ -416,21 +416,20 @@ class _OrderHelpScreenState extends State<OrderHelpScreen> {
switch (color) {
case "Red":
return const LinearGradient(
colors: [Color(0xFFFFE0E0), Color(0xFFFFC0C0)],
colors: [Color(0xFFFFEBEB), Color(0xFFFFEBEB)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
case "Green":
default:
return const LinearGradient(
colors: [Color(0xFFE9FFDD), Color(0xFFB5FFD1)],
colors: [Color(0xFFE5FFE2), Color(0xFFE5FFE2)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
}
}
void _showReasonBottomSheet(
Orders product,
) {
......@@ -524,7 +523,14 @@ class _OrderHelpScreenState extends State<OrderHelpScreen> {
accId: widget.accId,
orderId: orderId,
))
);
).then((_) {
final provider = Provider.of<HelpAndEnquiryProvider>(context, listen: false);
provider.fetchTicketList(
sessionId: widget.sessionId,
accId: widget.accId,
);
});
},
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 1),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment