improvements

export_module_ui_ux_enhancement_signup
WaseemAbbasi22 3 hours ago
parent fb6dc22c05
commit 7186fb13c0

@ -4,12 +4,12 @@ class URLs {
static const String appReleaseBuildNumber = "40";
// static const host1 = "https://atomsm.hmg.com"; // production url
static const host1 = "https://atomsmdev.hmg.com"; // local DEV url
// static const host1 = "https://atomsmuat.hmg.com"; // local UAT url
// static const host1 = "https://atomsmdev.hmg.com"; // local DEV url
static const host1 = "https://atomsmuat.hmg.com"; // local UAT url
static final String _baseUrl = "$_host/mobile"; // host local UAT
// static final String _baseUrl = "$_host/mobile"; // host local UAT
// static final String _baseUrl = "$_host/v1/mobile"; // new V1 apis
// static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis
static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis
// static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM
// static final String _baseUrl = "$_host/v4/mobile"; // v4 for Demo module
// static final String _baseUrl = "$_host/v5/mobile"; // v5 for data segregation

@ -439,7 +439,7 @@ class MyApp extends StatelessWidget {
CreateDemoRequestPage.id: (_) => CreateDemoRequestPage(),
CleanerSearchFormView.routeName: (_) => const CleanerSearchFormView(),
CleanerSearchListView.routeName: (_) => const CleanerSearchListView(),
DemoRequestFormScreen.routeName: (_) => const DemoRequestFormScreen(),
ApplicationDemoRequestFormScreen.routeName: (_) => const ApplicationDemoRequestFormScreen(),
},
),
),

@ -3,6 +3,7 @@ import 'package:provider/provider.dart';
import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/modules/applicationDemo/enums/otp_method.dart';
import 'package:test_sa/modules/applicationDemo/models/application_demo_request_model.dart';
@ -15,19 +16,20 @@ import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
import 'package:test_sa/new_views/common_widgets/custom_app_bar.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/new_views/common_widgets/multiple_item_drop_down_menu.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
class DemoRequestFormScreen extends StatefulWidget {
class ApplicationDemoRequestFormScreen extends StatefulWidget {
static const String routeName = '/demo_request_form';
const DemoRequestFormScreen({Key? key}) : super(key: key);
const ApplicationDemoRequestFormScreen({Key? key}) : super(key: key);
@override
State<DemoRequestFormScreen> createState() => _DemoRequestFormScreenState();
State<ApplicationDemoRequestFormScreen> createState() => _ApplicationDemoRequestFormScreenState();
}
class _DemoRequestFormScreenState extends State<DemoRequestFormScreen> {
class _ApplicationDemoRequestFormScreenState extends State<ApplicationDemoRequestFormScreen> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _fullNameController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
@ -36,6 +38,8 @@ class _DemoRequestFormScreenState extends State<DemoRequestFormScreen> {
List<ApplicationDemoRoleModel> _selectedRoles = [];
bool _isSubmitting = false;
String? _rolesValidationError;
bool _formSubmitted = false; // Track if form has been submitted
@override
void initState() {
@ -61,12 +65,11 @@ class _DemoRequestFormScreenState extends State<DemoRequestFormScreen> {
final provider = Provider.of<ApplicationDemoRequestProvider>(context);
return Scaffold(
backgroundColor: AppColor.background(context),
appBar: const CustomAppBar(
title: 'Demo Request',
),
backgroundColor: AppColor.scaffoldBackground(context),
appBar: const DefaultAppBar(title: 'Demo Request'),
body: Form(
key: _formKey,
autovalidateMode: AutovalidateMode.disabled,
child: Column(
children: [
Column(
@ -74,53 +77,53 @@ class _DemoRequestFormScreenState extends State<DemoRequestFormScreen> {
children: [
AppTextFormField(
controller: _fullNameController,
labelText: 'Full Name',
hintText: 'Enter your full name',
labelText: 'Full Name *',
textInputType: TextInputType.name,
validator: (value) {
if (value == null || value.isEmpty) return 'Full Name is required';
if (!_formSubmitted && _fullNameController.text.isEmpty) return null;
if (_fullNameController.text.isEmpty) return 'Full Name is required';
return null;
},
),
16.height,
AppTextFormField(
controller: _emailController,
labelText: 'Email Address',
hintText: 'Enter your email address',
labelText: 'Email Address *',
textInputType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) return 'Email is required';
if (!Validator.isEmail(value)) return 'Invalid email format';
if (!_formSubmitted && _emailController.text.isEmpty) return null;
if (_emailController.text.isEmpty) return 'Email is required';
if (!Validator.isEmail(_emailController.text)) return 'Invalid email format';
return null;
},
),
16.height,
AppTextFormField(
controller: _mobileController,
labelText: 'Mobile Number',
hintText: 'Enter your mobile number',
labelText: 'Mobile Number *',
textInputType: TextInputType.phone,
validator: (value) {
if (value == null || value.isEmpty) return 'Mobile Number is required';
if (!Validator.isPhoneNumber(value)) return 'Invalid mobile number';
if (!_formSubmitted && _mobileController.text.isEmpty) return null;
if (_mobileController.text.isEmpty) return 'Mobile Number is required';
if (!Validator.isPhoneNumber(_mobileController.text)) return 'Invalid mobile number';
return null;
},
),
16.height,
AppTextFormField(
controller: _companyNameController,
labelText: 'Company Name',
hintText: 'Enter your company name',
labelText: 'Company Name *',
textInputType: TextInputType.text,
validator: (value) {
if (value == null || value.isEmpty) return 'Company Name is required';
if (!_formSubmitted && _companyNameController.text.isEmpty) return null;
if (_companyNameController.text.isEmpty) return 'Company Name is required';
return null;
},
),
16.height,
MultipleItemDropDownMenu<ApplicationDemoRoleModel, NullableLoadingProvider>(
context: context,
title: 'Select Roles',
title: 'Select Roles *',
initialValue: _selectedRoles,
staticData: provider.roles,
loading: provider.roleLoading,
@ -128,9 +131,20 @@ class _DemoRequestFormScreenState extends State<DemoRequestFormScreen> {
onSelect: (selectedRoles) {
setState(() {
_selectedRoles = selectedRoles ?? [];
_rolesValidationError = null; // Clear error when roles are selected
});
},
),
if (_rolesValidationError != null)
Padding(
padding: const EdgeInsets.only(top: 8, left: 16),
child: Text(
_rolesValidationError!,
style: AppTextStyles.tinyFont.copyWith(
color: AppColor.red30,
),
),
),
],
).paddingAll(16).expanded,
FooterActionButton.footerContainer(
@ -150,14 +164,24 @@ class _DemoRequestFormScreenState extends State<DemoRequestFormScreen> {
}
Future<void> _submitRequest() async {
// Mark form as submitted
setState(() {
_formSubmitted = true;
});
// Validate form fields
if (!_formKey.currentState!.validate()) {
return;
}
// Validate roles selection
if (_selectedRoles.isEmpty) {
context.showConfirmDialog('Please select at least one role');
setState(() {
_rolesValidationError = 'Please select at least one role';
});
return;
}
showDialog(
context: context,
builder: (BuildContext context) {

@ -142,8 +142,8 @@ class _SignUpScreenState extends State<SignUpScreen> {
context: context,
title: "Asset Group",
initialValue: _selectedAssetGroup,
showAsFullScreenDialog: false,
showAsBottomSheet: true,
showAsFullScreenDialog: true,
showAsBottomSheet: false,
onSelect: (value) {
setState(() {
_selectedAssetGroup = value;
@ -170,8 +170,8 @@ class _SignUpScreenState extends State<SignUpScreen> {
context: context,
title: "Company",
initialValue: _selectedCompany,
showAsFullScreenDialog: false,
showAsBottomSheet: true,
showAsFullScreenDialog: true,
showAsBottomSheet: false,
onSelect: (value) {
setState(() {
_selectedCompany = value;
@ -204,14 +204,14 @@ class _SignUpScreenState extends State<SignUpScreen> {
_buildReadOnlyField("Full Name", _fullNameController),
_buildReadOnlyField("Email Address", _emailController),
_buildReadOnlyField("Mobile Number", _mobileController),
_buildReadOnlyField("Site", _siteController),
_buildReadOnlyField("Department", _departmentController),
// _buildReadOnlyField("Site", _siteController),
// _buildReadOnlyField("Department", _departmentController),
16.height,
_buildExtensionField(),
// 16.height,
// _buildSiteDropdown(),
// 16.height,
// _buildDepartmentDropdown(),
16.height,
_buildSiteDropdown(),
16.height,
_buildDepartmentDropdown(),
16.height,
_buildRoleField(),
],
@ -244,11 +244,16 @@ class _SignUpScreenState extends State<SignUpScreen> {
child: AppTextFormField(
controller: _employeeIdController,
labelText: "Employee ID",
hintText: "Enter Employee ID",
textInputType: TextInputType.number,
onChange: (value) {
// Clear validation errors on user interaction
// if (_formKey.currentState != null) {
// _formKey.currentState!.validate();
// }
},
validator: (value) {
if (value == null || value.isEmpty) return "Employee ID is required";
if (!Validator.isNumeric(value)) return "Employee ID must be numeric";
if (_employeeIdController.text.isEmpty) return "Employee ID is required";
// if (!Validator.isNumeric(_employeeIdController.text)) return "Employee ID must be numeric";
return null;
},
),
@ -300,7 +305,6 @@ class _SignUpScreenState extends State<SignUpScreen> {
return AppTextFormField(
controller: _fullNameController,
labelText: "Full Name",
hintText: "Enter Full Name",
validator: (value) {
if (value == null || value.isEmpty) return "Full Name is required";
return null;
@ -312,7 +316,6 @@ class _SignUpScreenState extends State<SignUpScreen> {
return AppTextFormField(
controller: _emailController,
labelText: "Email Address",
hintText: "Enter Email Address",
textInputType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) return "Email is required";
@ -326,7 +329,6 @@ class _SignUpScreenState extends State<SignUpScreen> {
return AppTextFormField(
controller: _mobileController,
labelText: "Mobile Number",
hintText: "Enter Mobile Number",
textInputType: TextInputType.phone,
validator: (value) {
if (value == null || value.isEmpty) return "Mobile Number is required";
@ -340,7 +342,6 @@ class _SignUpScreenState extends State<SignUpScreen> {
return AppTextFormField(
controller: _extensionController,
labelText: "Extension Number",
hintText: "Enter Extension Number (Optional)",
textInputType: TextInputType.number,
validator: (value) {
if (value != null && value.isNotEmpty && !Validator.isNumeric(value)) {
@ -395,7 +396,6 @@ class _SignUpScreenState extends State<SignUpScreen> {
return AppTextFormField(
controller: _roleController,
labelText: "Role",
hintText: "Enter Role",
validator: (value) {
if (value == null || value.isEmpty) return "Role is required";
return null;
@ -527,16 +527,16 @@ class _SignUpScreenState extends State<SignUpScreen> {
}
// Site is mandatory for HMG
// if (_selectedSite == null) {
// Fluttertoast.showToast(msg: "Site is required");
// return;
// }
if (_selectedSite == null) {
Fluttertoast.showToast(msg: "Site is required");
return;
}
//
// // Department is mandatory for HMG
// if (_selectedDepartment == null) {
// Fluttertoast.showToast(msg: "Department is required");
// return;
// }
if (_selectedDepartment == null) {
Fluttertoast.showToast(msg: "Department is required");
return;
}
} else {
// Non-HMG specific validations
@ -628,9 +628,9 @@ class _SignUpScreenState extends State<SignUpScreen> {
extensionNumber: _extensionController.text.isEmpty ? null : _extensionController.text,
// For HMG: send both selected IDs and ERP data
siteId: _selectedSite?.id,
erpSite: _isHMGGroup ? _employeeERPData?.branchCode : null,
// erpSite: _isHMGGroup ? _employeeERPData?.branchCode : null,
departmentId: _selectedDepartment?.id,
erpDepartment: _isHMGGroup ? _employeeERPData?.branchName : null,
// erpDepartment: _isHMGGroup ? _employeeERPData?.branchName : null,
role: _roleController.text,
isFromERP: _isHMGGroup,
);

@ -3,6 +3,7 @@
class SiteRequestModel {
final String? id;
final String requestType;
final String? requestNumber;
final String employeeId;
final String fullName;
final String emailAddress;
@ -23,6 +24,7 @@ class SiteRequestModel {
SiteRequestModel({
this.id,
required this.requestType,
this.requestNumber,
required this.employeeId,
required this.fullName,
required this.emailAddress,
@ -46,6 +48,7 @@ class SiteRequestModel {
return {
'id': id,
'requestType': requestType,
'requestNumber': requestNumber,
'employeeId': employeeId,
'fullName': fullName,
'emailAddress': emailAddress,
@ -72,6 +75,7 @@ class SiteRequestModel {
id: json['id']?.toString() ?? json['requestNumber']?.toString() ?? '',
requestType: _parseRequestType(json),
employeeId: json['employeeId'] ?? '',
requestNumber: json['requestNumber'] ?? '',
fullName: json['userName'] ?? json['fullName'] ?? '',
emailAddress: json['email'] ?? json['emailAddress'] ?? '',
mobileNumber: json['mobileNumber'] ?? '',
@ -112,6 +116,7 @@ class SiteRequestModel {
return SiteRequestModel(
id: id ?? this.id,
requestType: requestType ?? this.requestType,
requestNumber: requestNumber ?? this.requestNumber,
employeeId: employeeId ?? this.employeeId,
fullName: fullName ?? this.fullName,
emailAddress: emailAddress ?? this.emailAddress,

@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/new_models/site.dart';
import 'package:test_sa/models/new_models/department.dart';
@ -95,7 +96,6 @@ class _SiteRequestFormScreenState extends State<SiteRequestFormScreen> {
Widget build(BuildContext context) {
_provider = Provider.of<SiteRequestProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
return Scaffold(
backgroundColor: AppColor.scaffoldBackground(context),
appBar: const DefaultAppBar(title: "Site Request"),
@ -109,34 +109,23 @@ class _SiteRequestFormScreenState extends State<SiteRequestFormScreen> {
child: SingleChildScrollView(
padding: EdgeInsets.all(16.toScreenWidth),
child: Column(
spacing: 12,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildUserInfoCard(),
16.height,
_buildRequestTypeDropdown(),
16.height,
if (_selectedRequestType != null) ...[
if (_isChangeSiteRequest()) ...[
_buildOldSiteDropdown(),
16.height,
// Show replacement containers for each old site
if (_selectedOldSites.isNotEmpty) ...[
Text(
"Site Replacements",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColor.textStyleColor(context),
),
),
8.height,
InfoHeader16Widget("Site Replacements"),
..._buildSiteReplacementContainers(),
],
] else if (_isRemoveSiteRequest()) ...[
_buildRemoveSiteDropdown(),
] else ...[
_buildSiteMultiSelect(),
16.height,
_buildDepartmentMultiSelect(),
],
],
@ -173,8 +162,7 @@ class _SiteRequestFormScreenState extends State<SiteRequestFormScreen> {
title: "Type of Site Request",
initialValue: _selectedRequestType,
staticData: _provider.requestTypes,
showAsFullScreenDialog: false,
showAsBottomSheet: true,
showAsFullScreenDialog: true,
onSelect: (value) async {
setState(() {
_selectedRequestType = value;
@ -211,7 +199,7 @@ class _SiteRequestFormScreenState extends State<SiteRequestFormScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InfoHeader16Widget("Requester Information"),
8.height,
// 8.height,
InfoTextWidget(
label: "Full Name",
value: _provider.getCurrentUserFullName(_userProvider),
@ -299,7 +287,7 @@ class _SiteRequestFormScreenState extends State<SiteRequestFormScreen> {
))
.toList(),
staticData: _provider.userCurrentSites,
showAsBottomSheet: true,
showAsFullScreenDialog: true,
backgroundColor: context.isDark ? AppColor.neutral60 : Colors.white,
showShadow: true,
height: 56.toScreenHeight,
@ -391,15 +379,10 @@ class _SiteRequestFormScreenState extends State<SiteRequestFormScreen> {
return Consumer<SiteProvider>(
builder: (context, siteProvider, child) {
// Get ALL user's current site IDs to exclude from new site selection
final allUserCurrentSiteIds = _provider.userCurrentSites
.map((s) => s.identifier ?? '')
.toSet();
final allUserCurrentSiteIds = _provider.userCurrentSites.map((s) => s.identifier ?? '').toSet();
// Filter out already selected new sites and ALL user's current sites
final alreadySelectedNewSites = _siteReplacements.values
.where((r) => r.newSite != null)
.map((r) => r.newSite!.identifier)
.toSet();
final alreadySelectedNewSites = _siteReplacements.values.where((r) => r.newSite != null).map((r) => r.newSite!.identifier).toSet();
final filteredSites = siteProvider.items.where((site) {
final siteId = site.identifier ?? '';
@ -408,83 +391,53 @@ class _SiteRequestFormScreenState extends State<SiteRequestFormScreen> {
if (allUserCurrentSiteIds.contains(siteId)) return false;
// Exclude already selected new sites (except current one)
if (replacement?.newSite?.identifier != siteId &&
alreadySelectedNewSites.contains(siteId)) {
if (replacement?.newSite?.identifier != siteId && alreadySelectedNewSites.contains(siteId)) {
return false;
}
return true;
}).toList();
return Container(
padding: EdgeInsets.all(16.toScreenWidth),
margin: EdgeInsets.only(bottom: 16.toScreenHeight),
decoration: BoxDecoration(
color: AppColor.background(context),
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: AppColor.neutral40.withValues(alpha: 0.3),
width: 1,
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 12,
children: [
Text(
oldSite.name ?? 'Unknown Site',
style: AppTextStyles.bodyText,
),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Old site name display (simple text only)
Text(
oldSite.name ?? 'Unknown Site',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColor.textStyleColor(context),
),
),
16.height,
// New site single selection
SingleItemDropDownMenu<Site, NullableLoadingProvider>(
context: context,
title: "New Site",
initialValue: replacement?.newSite,
staticData: filteredSites,
showAsBottomSheet: true,
backgroundColor: context.isDark ? AppColor.neutral60 : Colors.white,
showShadow: true,
height: 56.toScreenHeight,
onSelect: (value) {
setState(() {
if (value != null) {
// Remove old site ID from loaded set to allow fetching new departments
if (replacement?.newSite != null) {
final oldNewSiteId = int.tryParse(replacement!.newSite!.identifier ?? '0') ?? 0;
_loadedDepartmentSiteIds.remove(oldNewSiteId);
}
_siteReplacements[oldSiteId] = SiteReplacement(
newSite: value,
departments: [], // Clear departments when new site changes
);
SingleItemDropDownMenu<Site, NullableLoadingProvider>(
context: context,
title: "New Site",
initialValue: replacement?.newSite,
staticData: filteredSites,
showAsFullScreenDialog: true,
backgroundColor: context.isDark ? AppColor.neutral60 : Colors.white,
showShadow: true,
height: 56.toScreenHeight,
onSelect: (value) {
setState(() {
if (value != null) {
// Remove old site ID from loaded set to allow fetching new departments
if (replacement?.newSite != null) {
final oldNewSiteId = int.tryParse(replacement!.newSite!.identifier ?? '0') ?? 0;
_loadedDepartmentSiteIds.remove(oldNewSiteId);
}
});
},
),
16.height,
// Department multi-select based on new site
if (replacement?.newSite != null) ...[
_buildDepartmentDropdownForSite(oldSiteId, replacement!.newSite!),
],
_siteReplacements[oldSiteId] = SiteReplacement(
newSite: value,
departments: [], // Clear departments when new site changes
);
}
});
},
),
if (replacement?.newSite != null) ...[
_buildDepartmentDropdownForSite(oldSiteId, replacement!.newSite!),
],
),
);
],
).toShadowContainer(context);
},
);
}).toList();
@ -515,7 +468,7 @@ class _SiteRequestFormScreenState extends State<SiteRequestFormScreen> {
title: "Departments",
initialValue: replacement?.departments ?? [],
staticData: departmentProvider.items,
showAsBottomSheet: true,
showAsFullScreenDialog: true,
backgroundColor: context.isDark ? AppColor.neutral60 : Colors.white,
showShadow: true,
height: 56.toScreenHeight,

@ -129,16 +129,14 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
return RefreshIndicator(
onRefresh: _refreshData,
child: ListView.builder(
child: ListView.separated(
separatorBuilder: (context, index) => 12.height,
controller: _scrollController,
padding: EdgeInsets.all(16.toScreenWidth),
itemCount: _provider.requestHistory.length + (_provider.isLoadingMore ? 1 : 0),
itemBuilder: (context, index) {
if (index == _provider.requestHistory.length) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 16.toScreenHeight),
child: const Center(child: CircularProgressIndicator()),
);
return const Center(child: CircularProgressIndicator());
}
return _buildRequestCard(_provider.requestHistory[index]);
@ -153,22 +151,18 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildRequestHeader(request),
InfoHeaderWidget("Site Request #${request.id ?? 'N/A'}"),
InfoHeaderWidget("Request No: ${request.requestNumber ?? '-'}"),
_buildUserInfo(request),
// Show old sites if present (for Change Site requests)
if (request.oldSiteNames != null && request.oldSiteNames!.isNotEmpty)
_buildOldSitesSection(request),
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),
if (_hasValidSiteNames(request.siteNames)) _buildSitesSection(request),
// Show old departments if present (for Change Site requests)
if (request.oldDepartmentNames != null && request.oldDepartmentNames!.isNotEmpty)
_buildOldDepartmentsSection(request),
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),
if (_hasValidDepartmentNames(request.departmentNames)) _buildDepartmentsSection(request),
],
).toShadowContainer(context).paddingOnly(bottom: 16);
).toShadowContainer(context);
}
// Helper method to check if site names list has valid (non-null, non-empty) values
@ -178,9 +172,7 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
// 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);
return departmentNames != null && departmentNames.isNotEmpty && departmentNames.any((name) => name.isNotEmpty);
}
Widget _buildRequestHeader(SiteRequestModel request) {
@ -212,7 +204,9 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
InfoTextWidget(label: "Employee ID", value: request.employeeId),
InfoTextWidget(label: "Email", value: request.emailAddress),
InfoTextWidget(label: "Mobile", value: request.mobileNumber, showEmptyValue: true),
if (request.extensionNumber != null && request.extensionNumber!.isNotEmpty) InfoTextWidget(label: "Extension", value: request.extensionNumber!, showEmptyValue: true),
if (request.extensionNumber != null && request.extensionNumber!.isNotEmpty) ...[
InfoTextWidget(label: "Extension", value: request.extensionNumber!, showEmptyValue: true),
],
InfoTextWidget(label: "Role", value: request.role),
],
);
@ -222,13 +216,8 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Old Sites:",
style: TextStyle(
fontSize: 14,
color: AppColor.labelTextStyleColor(context),
fontWeight: FontWeight.w500,
),
InfoTextLabelWidget(
label: "Old Sites:",
),
8.height,
Wrap(
@ -242,9 +231,7 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
Widget _buildSitesSection(SiteRequestModel request) {
// Determine label based on whether old sites exist
final label = (request.oldSiteNames != null && request.oldSiteNames!.isNotEmpty)
? "New Sites:"
: "Sites:";
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();
@ -252,13 +239,8 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: TextStyle(
fontSize: 14,
color: AppColor.labelTextStyleColor(context),
fontWeight: FontWeight.w500,
),
InfoTextLabelWidget(
label: label,
),
8.height,
Wrap(
@ -267,7 +249,7 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
children: validSiteNames.map((site) => _buildChip(site)).toList(),
),
],
).paddingOnly(bottom: 8);
);
}
Widget _buildOldDepartmentsSection(SiteRequestModel request) {
@ -294,9 +276,7 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
Widget _buildDepartmentsSection(SiteRequestModel request) {
// Determine label based on whether old departments exist
final label = (request.oldDepartmentNames != null && request.oldDepartmentNames!.isNotEmpty)
? "New Departments:"
: "Departments:";
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();
@ -324,20 +304,14 @@ class _SiteRequestHistoryScreenState extends State<SiteRequestHistoryScreen> {
Widget _buildChip(String label, {bool isOld = false}) {
return Chip(
backgroundColor: isOld
? AppColor.redStatusColor.withValues(alpha: 0.1)
: AppColor.backgroundTabBarColor(context),
backgroundColor: isOld ? AppColor.redStatusColor.withValues(alpha: 0.1) : AppColor.backgroundTabBarColor(context),
side: BorderSide(
color: isOld
? AppColor.redStatusColor.withValues(alpha: 0.3)
: AppColor.border2Color(context),
color: isOld ? AppColor.redStatusColor.withValues(alpha: 0.3) : AppColor.border2Color(context),
),
label: Text(label),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),
labelStyle: AppTextStyles.tinyFont2.copyWith(
color: isOld
? AppColor.redStatusTextColor
: AppColor.labelTextStyleColor(context),
color: isOld ? AppColor.redStatusTextColor : AppColor.labelTextStyleColor(context),
),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
padding: EdgeInsets.symmetric(horizontal: 8.toScreenWidth, vertical: 4.toScreenHeight),

@ -239,7 +239,7 @@ class _LoginPageState extends State<LoginPage> {
}),
" or ".bodyText(context).custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral50),
"Request a Demo".bodyText(context).custom(color: AppColor.primary10, fontWeight: FontWeight.w600).onPress(() {
Navigator.pushNamed(context, DemoRequestFormScreen.routeName);
Navigator.pushNamed(context, ApplicationDemoRequestFormScreen.routeName);
}),
],
),

@ -59,3 +59,7 @@ class AAlertDialog extends StatelessWidget {
);
}
}

Loading…
Cancel
Save