|
|
|
@ -67,7 +67,13 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Future<void> _refreshData() async {
|
|
|
|
Future<void> _refreshData() async {
|
|
|
|
|
|
|
|
setState(() {
|
|
|
|
|
|
|
|
_isLoadingData = true;
|
|
|
|
|
|
|
|
});
|
|
|
|
await _provider.refreshSiteRequests(userProvider: _userProvider);
|
|
|
|
await _provider.refreshSiteRequests(userProvider: _userProvider);
|
|
|
|
|
|
|
|
if (mounted) {
|
|
|
|
|
|
|
|
setState(() => _isLoadingData = false);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
@ -149,21 +155,42 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
|
|
|
|
_buildRequestHeader(request),
|
|
|
|
_buildRequestHeader(request),
|
|
|
|
InfoHeaderWidget("Site Request #${request.id ?? 'N/A'}"),
|
|
|
|
InfoHeaderWidget("Site Request #${request.id ?? 'N/A'}"),
|
|
|
|
_buildUserInfo(request),
|
|
|
|
_buildUserInfo(request),
|
|
|
|
|
|
|
|
// Show old sites if present (for Change Site requests)
|
|
|
|
|
|
|
|
if (request.oldSiteNames != null && request.oldSiteNames!.isNotEmpty)
|
|
|
|
|
|
|
|
_buildOldSitesSection(request),
|
|
|
|
|
|
|
|
// Show new/current sites only if they are not empty and not all null
|
|
|
|
|
|
|
|
if (_hasValidSiteNames(request.siteNames))
|
|
|
|
_buildSitesSection(request),
|
|
|
|
_buildSitesSection(request),
|
|
|
|
if (request.departmentNames != null && request.departmentNames!.isNotEmpty)
|
|
|
|
// Show old departments if present (for Change Site requests)
|
|
|
|
|
|
|
|
if (request.oldDepartmentNames != null && request.oldDepartmentNames!.isNotEmpty)
|
|
|
|
|
|
|
|
_buildOldDepartmentsSection(request),
|
|
|
|
|
|
|
|
// Show new departments only if they are not empty and not all null
|
|
|
|
|
|
|
|
if (_hasValidDepartmentNames(request.departmentNames))
|
|
|
|
_buildDepartmentsSection(request),
|
|
|
|
_buildDepartmentsSection(request),
|
|
|
|
],
|
|
|
|
],
|
|
|
|
).toShadowContainer(context).paddingOnly(bottom: 16);
|
|
|
|
).toShadowContainer(context).paddingOnly(bottom: 16);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Helper method to check if site names list has valid (non-null, non-empty) values
|
|
|
|
|
|
|
|
bool _hasValidSiteNames(List<String> siteNames) {
|
|
|
|
|
|
|
|
return siteNames.isNotEmpty && siteNames.any((name) => name.isNotEmpty);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Helper method to check if department names list has valid (non-null, non-empty) values
|
|
|
|
|
|
|
|
bool _hasValidDepartmentNames(List<String>? departmentNames) {
|
|
|
|
|
|
|
|
return departmentNames != null &&
|
|
|
|
|
|
|
|
departmentNames.isNotEmpty &&
|
|
|
|
|
|
|
|
departmentNames.any((name) => name.isNotEmpty);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Widget _buildRequestHeader(SiteRequestModel request) {
|
|
|
|
Widget _buildRequestHeader(SiteRequestModel request) {
|
|
|
|
return Row(
|
|
|
|
return Row(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
|
|
|
children: [
|
|
|
|
StatusLabel(
|
|
|
|
StatusLabel(
|
|
|
|
label: request.status,
|
|
|
|
label: request.status,
|
|
|
|
textColor: _getStatusTextColor(request.status),
|
|
|
|
textColor: _getStatusTextColor(request.status ?? ''),
|
|
|
|
backgroundColor: _getStatusColor(request.status),
|
|
|
|
backgroundColor: _getStatusColor(request.status ?? ''),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
8.width,
|
|
|
|
8.width,
|
|
|
|
StatusLabel(
|
|
|
|
StatusLabel(
|
|
|
|
@ -185,19 +212,70 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
|
|
|
|
InfoTextWidget(label: "Employee ID", value: request.employeeId),
|
|
|
|
InfoTextWidget(label: "Employee ID", value: request.employeeId),
|
|
|
|
InfoTextWidget(label: "Email", value: request.emailAddress),
|
|
|
|
InfoTextWidget(label: "Email", value: request.emailAddress),
|
|
|
|
InfoTextWidget(label: "Mobile", value: request.mobileNumber, showEmptyValue: true),
|
|
|
|
InfoTextWidget(label: "Mobile", value: request.mobileNumber, showEmptyValue: true),
|
|
|
|
if (request.extensionNumber != null && request.extensionNumber!.isNotEmpty)
|
|
|
|
if (request.extensionNumber != null && request.extensionNumber!.isNotEmpty) InfoTextWidget(label: "Extension", value: request.extensionNumber!, showEmptyValue: true),
|
|
|
|
InfoTextWidget(label: "Extension", value: request.extensionNumber!, showEmptyValue: true),
|
|
|
|
|
|
|
|
InfoTextWidget(label: "Role", value: request.role),
|
|
|
|
InfoTextWidget(label: "Role", value: request.role),
|
|
|
|
],
|
|
|
|
],
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Widget _buildOldSitesSection(SiteRequestModel request) {
|
|
|
|
|
|
|
|
return Column(
|
|
|
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
|
|
|
children: [
|
|
|
|
|
|
|
|
Text(
|
|
|
|
|
|
|
|
"Old Sites:",
|
|
|
|
|
|
|
|
style: TextStyle(
|
|
|
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
|
|
|
color: AppColor.labelTextStyleColor(context),
|
|
|
|
|
|
|
|
fontWeight: FontWeight.w500,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
8.height,
|
|
|
|
|
|
|
|
Wrap(
|
|
|
|
|
|
|
|
runSpacing: 4.toScreenHeight,
|
|
|
|
|
|
|
|
spacing: 4.toScreenWidth,
|
|
|
|
|
|
|
|
children: request.oldSiteNames!.map((site) => _buildChip(site, isOld: true)).toList(),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
).paddingOnly(bottom: 8);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Widget _buildSitesSection(SiteRequestModel request) {
|
|
|
|
Widget _buildSitesSection(SiteRequestModel request) {
|
|
|
|
|
|
|
|
// Determine label based on whether old sites exist
|
|
|
|
|
|
|
|
final label = (request.oldSiteNames != null && request.oldSiteNames!.isNotEmpty)
|
|
|
|
|
|
|
|
? "New Sites:"
|
|
|
|
|
|
|
|
: "Sites:";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Filter out null or empty site names
|
|
|
|
|
|
|
|
final validSiteNames = request.siteNames.where((site) => site.isNotEmpty).toList();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Column(
|
|
|
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
|
|
|
children: [
|
|
|
|
|
|
|
|
Text(
|
|
|
|
|
|
|
|
label,
|
|
|
|
|
|
|
|
style: TextStyle(
|
|
|
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
|
|
|
color: AppColor.labelTextStyleColor(context),
|
|
|
|
|
|
|
|
fontWeight: FontWeight.w500,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
8.height,
|
|
|
|
|
|
|
|
Wrap(
|
|
|
|
|
|
|
|
runSpacing: 4.toScreenHeight,
|
|
|
|
|
|
|
|
spacing: 4.toScreenWidth,
|
|
|
|
|
|
|
|
children: validSiteNames.map((site) => _buildChip(site)).toList(),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
).paddingOnly(bottom: 8);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Widget _buildOldDepartmentsSection(SiteRequestModel request) {
|
|
|
|
return Column(
|
|
|
|
return Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
Text(
|
|
|
|
"Sites:",
|
|
|
|
"Old Departments:",
|
|
|
|
style: TextStyle(
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: 14,
|
|
|
|
fontSize: 14,
|
|
|
|
color: AppColor.labelTextStyleColor(context),
|
|
|
|
color: AppColor.labelTextStyleColor(context),
|
|
|
|
@ -208,18 +286,26 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
|
|
|
|
Wrap(
|
|
|
|
Wrap(
|
|
|
|
runSpacing: 4.toScreenHeight,
|
|
|
|
runSpacing: 4.toScreenHeight,
|
|
|
|
spacing: 4.toScreenWidth,
|
|
|
|
spacing: 4.toScreenWidth,
|
|
|
|
children: request.siteNames.map((site) => _buildChip(site)).toList(),
|
|
|
|
children: request.oldDepartmentNames!.map((dept) => _buildChip(dept, isOld: true)).toList(),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
],
|
|
|
|
).paddingOnly(bottom: 8);
|
|
|
|
).paddingOnly(bottom: 8);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Widget _buildDepartmentsSection(SiteRequestModel request) {
|
|
|
|
Widget _buildDepartmentsSection(SiteRequestModel request) {
|
|
|
|
|
|
|
|
// Determine label based on whether old departments exist
|
|
|
|
|
|
|
|
final label = (request.oldDepartmentNames != null && request.oldDepartmentNames!.isNotEmpty)
|
|
|
|
|
|
|
|
? "New Departments:"
|
|
|
|
|
|
|
|
: "Departments:";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Filter out null or empty department names
|
|
|
|
|
|
|
|
final validDepartmentNames = request.departmentNames!.where((dept) => dept.isNotEmpty).toList();
|
|
|
|
|
|
|
|
|
|
|
|
return Column(
|
|
|
|
return Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
Text(
|
|
|
|
"Departments:",
|
|
|
|
label,
|
|
|
|
style: TextStyle(
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: 14,
|
|
|
|
fontSize: 14,
|
|
|
|
color: AppColor.labelTextStyleColor(context),
|
|
|
|
color: AppColor.labelTextStyleColor(context),
|
|
|
|
@ -230,20 +316,28 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
|
|
|
|
Wrap(
|
|
|
|
Wrap(
|
|
|
|
runSpacing: 4.toScreenHeight,
|
|
|
|
runSpacing: 4.toScreenHeight,
|
|
|
|
spacing: 4.toScreenWidth,
|
|
|
|
spacing: 4.toScreenWidth,
|
|
|
|
children: request.departmentNames!.map((dept) => _buildChip(dept)).toList(),
|
|
|
|
children: validDepartmentNames.map((dept) => _buildChip(dept)).toList(),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
],
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Widget _buildChip(String label) {
|
|
|
|
Widget _buildChip(String label, {bool isOld = false}) {
|
|
|
|
return Chip(
|
|
|
|
return Chip(
|
|
|
|
backgroundColor: AppColor.backgroundTabBarColor(context),
|
|
|
|
backgroundColor: isOld
|
|
|
|
side: BorderSide(color: AppColor.border2Color(context)),
|
|
|
|
? AppColor.redStatusColor.withValues(alpha: 0.1)
|
|
|
|
|
|
|
|
: AppColor.backgroundTabBarColor(context),
|
|
|
|
|
|
|
|
side: BorderSide(
|
|
|
|
|
|
|
|
color: isOld
|
|
|
|
|
|
|
|
? AppColor.redStatusColor.withValues(alpha: 0.3)
|
|
|
|
|
|
|
|
: AppColor.border2Color(context),
|
|
|
|
|
|
|
|
),
|
|
|
|
label: Text(label),
|
|
|
|
label: Text(label),
|
|
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),
|
|
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),
|
|
|
|
labelStyle: AppTextStyles.tinyFont2.copyWith(
|
|
|
|
labelStyle: AppTextStyles.tinyFont2.copyWith(
|
|
|
|
color: AppColor.labelTextStyleColor(context),
|
|
|
|
color: isOld
|
|
|
|
|
|
|
|
? AppColor.redStatusTextColor
|
|
|
|
|
|
|
|
: AppColor.labelTextStyleColor(context),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
|
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
|
|
padding: EdgeInsets.symmetric(horizontal: 8.toScreenWidth, vertical: 4.toScreenHeight),
|
|
|
|
padding: EdgeInsets.symmetric(horizontal: 8.toScreenWidth, vertical: 4.toScreenHeight),
|
|
|
|
|