......@@ -167,7 +167,7 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
LayoutBuilder(
builder: (context, constraints) {
return Padding(
padding: const EdgeInsets.all(14),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 10),
child: Consumer<HrmAccessiblePagesProvider>(
builder: (context, provider, child) {
if (provider.isLoading) {
......@@ -190,9 +190,9 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: (constraints.maxWidth / 180).floor().clamp(2, 4),
crossAxisSpacing: 8.5,
mainAxisSpacing: 16,
childAspectRatio: 1.7,
crossAxisSpacing: 1,
mainAxisSpacing: 2,
childAspectRatio: 1.8,
),
itemBuilder: (context, index) {
final page = pages[index];
......@@ -343,9 +343,9 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
case "Tour Bill List":
return "assets/svg/hrm/tourExp.svg";
case "Team Leave Request Approval":
return "assets/svg/hrm/leaveApplication.svg";
return "assets/svg/hrm/logout_ic.svg";
case "Team Attendance Approval":
return "assets/svg/hrm/attendanceList.svg";
return "assets/svg/hrm/check_ic.svg";
default:
return "assets/svg/hrm/groupIc.svg";
}
......
......@@ -71,29 +71,31 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
if (response == null) {
return const Center(child: Text("No data available"));
}
debugPrint("==================requestDetails: ${response.requestDetails?.approvalStatus}");
debugPrint("==================requestDetails: ${widget.tourBillId}");
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/// Header Card at the very top
_expenseHeaderCard(
title: response.requestDetails?.placeOfVisit ?? "Tour",
date: response.tourExpenses?.fromDate ?? "-",
date: response.requestDetails?.appliedDate ?? "-",
status: (response.requestDetails?.approvalStatus?.isNotEmpty ?? false)
? response.requestDetails!.approvalStatus!
: "No Status",
details: [
{"key": "TL Pending Approval Amount", "value": "-"},
{"key": "Total Approved Amount", "value": response.tourExpenses?.appliedAmount ?? "-"},
{"key": "Total Balance Amount", "value": "-"},
{"key": "HR Expiring Amount (Within 24Hrs)", "value": "-"},
{"key": "HR Pending Approval Amount", "value": "-"},
{"key": "Total Disbursed Amount", "value": "-"},
{"key": "Employee", "value": response.requestDetails!.employeeName!},
{"key": "Approved By TL", "value": response.requestDetails!.tlApprovedBy!},
{"key": "TL Approval Amount", "value": response.requestDetails!.tlApprovedAmount!},
{"key": "TL Remarks", "value": response.requestDetails!.tlRemarks!},
{"key": "Approved By HR", "value": response.requestDetails!.hrApprovedBy!},
{"key": "HR Approval Amount", "value": response.requestDetails!.hrApprovedAmount!},
{"key": "TL Remarks", "value": response.requestDetails!.tlRemarks!},
{"key": "Total Approved Amount", "value": response.requestDetails?.approvedAmount ?? "-"},
{"key": "Total Balance Amount", "value": response.requestDetails!.appliedAmount!},
{"key": "Type", "value": response.requestDetails!.type!},
],
),
const SizedBox(height: 16),
......@@ -113,15 +115,15 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
const SizedBox(height: 8),
SizedBox(
height: 220, // adjust height to match your card
height: 321, // adjust height to match your card
child: ListView(
scrollDirection: Axis.horizontal,
padding: EdgeInsets.symmetric( // horizontal margin for centering
padding: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.05,
),
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.85,
width: MediaQuery.of(context).size.width * 0.90,
child: _tourExpenseCard(
employeeName: response.requestDetails?.employeeName ?? "-",
placeOfVisit: response.requestDetails?.placeOfVisit ?? "-",
......@@ -132,6 +134,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
remarks: response.tourExpenses?.extraNote ?? "-",
),
),
],
),
),
......@@ -173,6 +176,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
amount: t.fare ?? "0",
from: t.froma ?? "-",
to: t.toa ?? "-",
imageUrl: t.imageDirFilePath ?? "",
onViewTap: () {
debugPrint("Open: ${t.imageDirFilePath}");
//Fileviewer(fileName: "", fileUrl: t.imageDirFilePath.toString())
......@@ -236,6 +240,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
amount: h.amount ?? "0",
fromDate: h.fromDate ?? "-",
toDate: h.toDate ?? "-",
imageUrl: h.imageDirFilePath ?? "",
onViewTap: () {
debugPrint("Open: ${h.imageDirFilePath}");
Navigator.push(
......@@ -296,6 +301,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
description: o.otherDesc ?? "-",
amount: o.otherAmount ?? "0",
date: o.otherDate ?? "-",
imageUrl: o.imageDirFilePath ?? "",
onViewTap: () {
debugPrint("Open: ${o.imageDirFilePath}");
Navigator.push(
......@@ -346,7 +352,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
}) {
// paste your same implementation here
return Container(
margin: const EdgeInsets.only(bottom: 16),
margin: const EdgeInsets.only(bottom: 10),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
......@@ -415,6 +421,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
required String amount,
required String from,
required String to,
required imageUrl,
required VoidCallback onViewTap,
}) {
// paste your travel card code here
......@@ -444,7 +451,9 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
radius: 20,
backgroundColor: const Color(0xffFFF3E0),
child: SvgPicture.asset(
"assets/svg/hrm/travel_ic.svg",
_getTravelIcon(travelType),
width: 28,
height: 28,
),
),
const SizedBox(width: 8),
......@@ -474,7 +483,8 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
const SizedBox(height: 2),
_buildKeyValue("To", to),
const SizedBox(height: 2),
_buildKeyValue("Image", "View", isLink: true, onTap: onViewTap),
if ( imageUrl != null && imageUrl!.isNotEmpty)
_buildKeyValue("Image", "View", isLink: true, onTap: onViewTap),
],
),
);
......@@ -485,6 +495,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
required String amount,
required String fromDate,
required String toDate,
required imageUrl,
required VoidCallback onViewTap,
}) {
// paste your hotel card code here
......@@ -546,6 +557,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
const SizedBox(height: 2),
_buildKeyValue("To", toDate),
const SizedBox(height: 2),
if ( imageUrl != null && imageUrl!.isNotEmpty)
_buildKeyValue("Image", "View", isLink: true, onTap: onViewTap),
],
),
......@@ -556,6 +568,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
required String description,
required String amount,
required String date,
required imageUrl,
required VoidCallback onViewTap,
}) {
// paste your other expense card code here
......@@ -616,6 +629,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
const SizedBox(height: 2),
_buildKeyValue("Description", description),
const SizedBox(height: 2),
if ( imageUrl != null && imageUrl!.isNotEmpty)
_buildKeyValue("Image", "View", isLink: true, onTap: onViewTap),
],
),
......@@ -863,6 +877,27 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen>{
},
);
}
///travel icons
String _getTravelIcon(String? travelType) {
switch (travelType?.toLowerCase()) {
case "flight":
return "assets/svg/hrm/airplane_ic.svg";
case "train":
return "assets/svg/hrm/train_ic.svg";
case "bus":
return "assets/svg/hrm/bus_ic.svg";
case "car":
return "assets/svg/hrm/car_ic.svg";
case "auto":
return "assets/svg/hrm/truck_ic.svg";
case "bike":
return "assets/svg/hrm/motorcycle_ic.svg";
default:
return "assets/svg/hrm/travel_ic.svg"; // fallback
}
}
/// Avatar color generator
Color _getStatusBgColor(value) {
var color = AppColors.approved_bg_color;
......
......@@ -315,6 +315,18 @@ class _PendingcomplaintsState extends State<Pendingcomplaints> {
fontSize: 14,
),
),
Text(
"#${provider.technician_complaint_list[index].engineNo}",
maxLines: 1,
overflow:
TextOverflow.ellipsis,
style: TextStyle(
color: Color(
0xFF818181,
),
fontSize: 14,
),
),
],
),
),
......@@ -335,30 +347,30 @@ class _PendingcomplaintsState extends State<Pendingcomplaints> {
),
),
),
Expanded(
flex: 1,
child: InkResponse(
onTap: () {
_showOptionsSheet(
context,
provider
.technician_complaint_list[index]
.companyName,
provider
.technician_complaint_list[index]
.genId,
provider
.technician_complaint_list[index]
.complaintId,
);
},
child: SvgPicture.asset(
"assets/svg/ic_more.svg",
height: 30,
),
),
),
// Expanded(
// flex: 1,
// child: InkResponse(
// onTap: () {
// _showOptionsSheet(
// context,
// provider
// .technician_complaint_list[index]
// .companyName,
//
// provider
// .technician_complaint_list[index]
// .genId,
// provider
// .technician_complaint_list[index]
// .complaintId,
// );
// },
// child: SvgPicture.asset(
// "assets/svg/ic_more.svg",
// height: 30,
// ),
// ),
// ),
],
),
......
......@@ -115,7 +115,7 @@ class _VisitdetailsState extends State<Visitdetails> {
bottomRight: Radius.circular(30),
),
),
elevation: 2,
elevation: 0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
......
......@@ -26,6 +26,7 @@ import 'package:generp/Models/crmModels/crmProspectDetailsResponse.dart';
import 'package:generp/Models/financeModels/addDirectPaymentResponse.dart';
import 'package:generp/Models/financeModels/paymentRequisitionPaymentsListResponse.dart';
import 'package:generp/Models/hrmModels/attendanceRequestListResponse.dart';
import 'package:generp/Models/hrmModels/jobDescriptionResponse.dart';
import 'package:generp/Models/hrmModels/leaveApplicationDetailsResponse.dart';
import 'package:generp/Models/hrmModels/leaveApplicationLIstResponse.dart';
import 'package:generp/Models/hrmModels/rewardListResponse.dart';
......@@ -4965,6 +4966,31 @@ class ApiCalling {
return null;
}
}
static Future<jobDescriptionResponse?> jobDescriptAPI(
empId,
session,
) async {
try {
Map<String, String> data = {
'session_id': (session).toString(),
'emp_id': (empId).toString(),
};
final res = await post(data, JobDesciptionUrl, {});
if (res != null) {
print(data);
debugPrint(res.body);
return jobDescriptionResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint('hello bev=bug $e ');
return null;
}
}
static Future<hrmAccessiblePagesResponse?> hrmAccessiblePagesAPI(
empId,
session,
......@@ -5295,7 +5321,7 @@ class ApiCalling {
if (file.path.isNotEmpty) {
request.files.add(
await http.MultipartFile.fromPath(
"hotel_images[]",
"hotel_image[]",
file.path,
),
);
......@@ -5309,7 +5335,7 @@ class ApiCalling {
if (file.path.isNotEmpty) {
request.files.add(
await http.MultipartFile.fromPath(
"travel_images[]",
"travel_image[]",
file.path,
),
);
......@@ -5323,7 +5349,7 @@ class ApiCalling {
if (file.path.isNotEmpty) {
request.files.add(
await http.MultipartFile.fromPath(
"other_images[]",
"other_image[]",
file.path,
),
);
......
......@@ -590,6 +590,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.12.0"
flutter_html:
dependency: "direct main"
description:
name: flutter_html
sha256: "38a2fd702ffdf3243fb7441ab58aa1bc7e6922d95a50db76534de8260638558d"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
flutter_image_compress:
dependency: "direct main"
description:
......@@ -1200,6 +1208,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.1.1"
list_counter:
dependency: transitive
description:
name: list_counter
sha256: c447ae3dfcd1c55f0152867090e67e219d42fe6d4f2807db4bbe8b8d69912237
url: "https://pub.dev"
source: hosted
version: "1.0.2"
location:
dependency: "direct main"
description:
......
......@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.101+109
version: 1.0.103+111
environment:
sdk: ^3.7.2
......@@ -91,6 +91,7 @@ dependencies:
build_web_compilers: ^4.0.4
graphview: ^1.2.0
file_picker: ^8.0.0
flutter_html: ^3.0.0
dev_dependencies:
flutter_test:
......