|
|
|
|
@ -8,6 +8,7 @@ import 'package:mc_common_app/classes/app_state.dart';
|
|
|
|
|
import 'package:mc_common_app/extensions/int_extensions.dart';
|
|
|
|
|
import 'package:mc_common_app/extensions/string_extensions.dart';
|
|
|
|
|
import 'package:mc_common_app/theme/colors.dart';
|
|
|
|
|
import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart';
|
|
|
|
|
import 'package:mc_common_app/utils/enums.dart';
|
|
|
|
|
import 'package:mc_common_app/utils/navigator.dart';
|
|
|
|
|
import 'package:mc_common_app/utils/utils.dart';
|
|
|
|
|
@ -29,7 +30,10 @@ class AssignDealerUserSheet extends StatefulWidget {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _AssignDealerUserSheetState extends State<AssignDealerUserSheet> {
|
|
|
|
|
late ServiceVM provider;
|
|
|
|
|
ServiceVM? provider;
|
|
|
|
|
|
|
|
|
|
// Track initially assigned users to detect removals
|
|
|
|
|
Set<int> initiallyAssignedUserIds = {};
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void initState() {
|
|
|
|
|
@ -40,11 +44,163 @@ class _AssignDealerUserSheetState extends State<AssignDealerUserSheet> {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getBranchUsers() {
|
|
|
|
|
provider.getAllProviderDealers({
|
|
|
|
|
getBranchUsers() async {
|
|
|
|
|
if (provider == null) return;
|
|
|
|
|
|
|
|
|
|
await provider!.getAllProviderDealers({
|
|
|
|
|
"ServiceProviderBranchID": widget.branchId,
|
|
|
|
|
"ServiceProviderID": AppState().getUser.data?.userInfo?.providerId.toString() ?? "",
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Store initially assigned user IDs
|
|
|
|
|
initiallyAssignedUserIds.clear();
|
|
|
|
|
for (var user in provider!.allProviderDealersList) {
|
|
|
|
|
if (user.isBranchUser ?? false) {
|
|
|
|
|
initiallyAssignedUserIds.add(user.id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
setState(() {});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle checkbox changes
|
|
|
|
|
Future<void> onUserSelectionChanged(int userId, bool? newValue) async {
|
|
|
|
|
if (provider == null) return;
|
|
|
|
|
|
|
|
|
|
final user = provider!.allProviderDealersList.firstWhere((u) => u.id == userId);
|
|
|
|
|
final wasInitiallyAssigned = initiallyAssignedUserIds.contains(userId);
|
|
|
|
|
|
|
|
|
|
if (newValue == true && !wasInitiallyAssigned) {
|
|
|
|
|
// User is checking a new dealer - show assign confirmation
|
|
|
|
|
showAssignConfirmation(userId);
|
|
|
|
|
} else if (newValue == false && wasInitiallyAssigned) {
|
|
|
|
|
// User is unchecking an assigned dealer - show remove confirmation
|
|
|
|
|
showRemoveConfirmation(userId);
|
|
|
|
|
} else {
|
|
|
|
|
// Just toggle for non-initially-assigned users
|
|
|
|
|
user.isBranchUser = newValue ?? false;
|
|
|
|
|
provider!.notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Show confirmation bottom sheet for assigning a dealer
|
|
|
|
|
void showAssignConfirmation(int userId) {
|
|
|
|
|
actionConfirmationBottomSheet(
|
|
|
|
|
context: context,
|
|
|
|
|
title: LocaleKeys.assignDealerUser.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
|
|
|
|
|
subtitle: LocaleKeys.confirmAssignDealerUser.tr(),
|
|
|
|
|
actionButtonYes: Expanded(
|
|
|
|
|
child: ShowFillButton(
|
|
|
|
|
maxHeight: 55,
|
|
|
|
|
title: LocaleKeys.yes.tr(),
|
|
|
|
|
fontSize: 15,
|
|
|
|
|
onPressed: () async {
|
|
|
|
|
Navigator.pop(context);
|
|
|
|
|
await assignUser(userId);
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
actionButtonNo: Expanded(
|
|
|
|
|
child: ShowFillButton(
|
|
|
|
|
maxHeight: 55,
|
|
|
|
|
isFilled: false,
|
|
|
|
|
borderColor: MyColors.darkPrimaryColor,
|
|
|
|
|
title: LocaleKeys.no.tr(),
|
|
|
|
|
txtColor: MyColors.darkPrimaryColor,
|
|
|
|
|
fontSize: 15,
|
|
|
|
|
onPressed: () {
|
|
|
|
|
Navigator.pop(context);
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Show confirmation bottom sheet for removing a dealer
|
|
|
|
|
void showRemoveConfirmation(int userId) {
|
|
|
|
|
actionConfirmationBottomSheet(
|
|
|
|
|
context: context,
|
|
|
|
|
title: LocaleKeys.removeDealerUser.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
|
|
|
|
|
subtitle: LocaleKeys.confirmRemoveDealerUser.tr(),
|
|
|
|
|
actionButtonYes: Expanded(
|
|
|
|
|
child: ShowFillButton(
|
|
|
|
|
maxHeight: 55,
|
|
|
|
|
title: LocaleKeys.yes.tr(),
|
|
|
|
|
fontSize: 15,
|
|
|
|
|
backgroundColor: Colors.red,
|
|
|
|
|
onPressed: () async {
|
|
|
|
|
Navigator.pop(context);
|
|
|
|
|
await removeUser(userId);
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
actionButtonNo: Expanded(
|
|
|
|
|
child: ShowFillButton(
|
|
|
|
|
maxHeight: 55,
|
|
|
|
|
isFilled: false,
|
|
|
|
|
borderColor: MyColors.darkPrimaryColor,
|
|
|
|
|
title: LocaleKeys.no.tr(),
|
|
|
|
|
txtColor: MyColors.darkPrimaryColor,
|
|
|
|
|
fontSize: 15,
|
|
|
|
|
onPressed: () {
|
|
|
|
|
Navigator.pop(context);
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Assign a single user
|
|
|
|
|
Future<void> assignUser(int userId) async {
|
|
|
|
|
if (provider == null) return;
|
|
|
|
|
|
|
|
|
|
Utils.showLoading(context);
|
|
|
|
|
|
|
|
|
|
var map = {
|
|
|
|
|
"dealershipUserIDs": [userId],
|
|
|
|
|
"serviceProviderBranchID": widget.branchId,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GenericRespModel response = await provider!.assignDealerToBranch(map);
|
|
|
|
|
Utils.hideLoading(context);
|
|
|
|
|
|
|
|
|
|
if (response.messageStatus == 1) {
|
|
|
|
|
Utils.showToast(response.message.toString());
|
|
|
|
|
await getBranchUsers(); // Refresh the list
|
|
|
|
|
widget.callBackFunc();
|
|
|
|
|
} else {
|
|
|
|
|
Utils.showToast(response.message.toString());
|
|
|
|
|
// Revert checkbox on error
|
|
|
|
|
final user = provider!.allProviderDealersList.firstWhere((u) => u.id == userId);
|
|
|
|
|
user.isBranchUser = false;
|
|
|
|
|
provider!.notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove a single user
|
|
|
|
|
Future<void> removeUser(int userId) async {
|
|
|
|
|
if (provider == null) return;
|
|
|
|
|
|
|
|
|
|
Utils.showLoading(context);
|
|
|
|
|
|
|
|
|
|
var map = {
|
|
|
|
|
"dealershipUserIDs": [userId],
|
|
|
|
|
"serviceProviderBranchID": widget.branchId,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GenericRespModel response = await provider!.removeDealerFromBranch(map);
|
|
|
|
|
Utils.hideLoading(context);
|
|
|
|
|
|
|
|
|
|
if (response.messageStatus == 1) {
|
|
|
|
|
Utils.showToast(response.message.toString());
|
|
|
|
|
await getBranchUsers(); // Refresh the list
|
|
|
|
|
widget.callBackFunc();
|
|
|
|
|
} else {
|
|
|
|
|
Utils.showToast(response.message.toString());
|
|
|
|
|
// Revert checkbox on error
|
|
|
|
|
final user = provider!.allProviderDealersList.firstWhere((u) => u.id == userId);
|
|
|
|
|
user.isBranchUser = true;
|
|
|
|
|
provider!.notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
@ -82,55 +238,20 @@ class _AssignDealerUserSheetState extends State<AssignDealerUserSheet> {
|
|
|
|
|
height: 1,
|
|
|
|
|
color: Colors.grey[100],
|
|
|
|
|
),
|
|
|
|
|
Column(
|
|
|
|
|
children: [
|
|
|
|
|
ShowFillButton(
|
|
|
|
|
title: LocaleKeys.assignDealerUser.tr(),
|
|
|
|
|
maxWidth: double.infinity,
|
|
|
|
|
maxHeight: 55,
|
|
|
|
|
fontSize: 15,
|
|
|
|
|
onPressed: () async {
|
|
|
|
|
if (validation()) {
|
|
|
|
|
Utils.showLoading(context);
|
|
|
|
|
List<int> userIds = [];
|
|
|
|
|
for (var element in provider.allProviderDealersList) {
|
|
|
|
|
if (element.isBranchUser ?? false) {
|
|
|
|
|
userIds.add(element.id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var map = {
|
|
|
|
|
"dealershipUserIDs": userIds,
|
|
|
|
|
"serviceProviderBranchID": widget.branchId,
|
|
|
|
|
};
|
|
|
|
|
GenericRespModel response = await provider.assignDealerToBranch(map);
|
|
|
|
|
Utils.hideLoading(context);
|
|
|
|
|
if (response.messageStatus == 1) {
|
|
|
|
|
Utils.showToast(response.message.toString());
|
|
|
|
|
pop(context);
|
|
|
|
|
widget.callBackFunc();
|
|
|
|
|
} else {
|
|
|
|
|
Utils.showToast(response.message.toString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
12.height,
|
|
|
|
|
ShowFillButton(
|
|
|
|
|
title: ("+ ${LocaleKeys.createNewUser.tr()}"),
|
|
|
|
|
maxWidth: double.infinity,
|
|
|
|
|
maxHeight: 55,
|
|
|
|
|
fontSize: 15,
|
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
|
borderColor: MyColors.darkPrimaryColor,
|
|
|
|
|
txtColor: MyColors.darkPrimaryColor,
|
|
|
|
|
isFilled: false,
|
|
|
|
|
onPressed: () {
|
|
|
|
|
context.read<DashboardVMProvider>().checkUserSubscription(SubscriptionActionTypeEnum.users, context, callback: () {
|
|
|
|
|
getBranchUsers();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
ShowFillButton(
|
|
|
|
|
title: ("+ ${LocaleKeys.createNewUser.tr()}"),
|
|
|
|
|
maxWidth: double.infinity,
|
|
|
|
|
maxHeight: 55,
|
|
|
|
|
fontSize: 15,
|
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
|
borderColor: MyColors.darkPrimaryColor,
|
|
|
|
|
txtColor: MyColors.darkPrimaryColor,
|
|
|
|
|
isFilled: false,
|
|
|
|
|
onPressed: () {
|
|
|
|
|
context.read<DashboardVMProvider>().checkUserSubscription(SubscriptionActionTypeEnum.users, context, callback: () {
|
|
|
|
|
getBranchUsers();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
@ -145,11 +266,7 @@ class _AssignDealerUserSheetState extends State<AssignDealerUserSheet> {
|
|
|
|
|
Checkbox(
|
|
|
|
|
value: model.allProviderDealersList[index].isBranchUser,
|
|
|
|
|
onChanged: (v) {
|
|
|
|
|
for (var element in model.allProviderDealersList) {
|
|
|
|
|
element.isBranchUser = false;
|
|
|
|
|
}
|
|
|
|
|
model.allProviderDealersList[index].isBranchUser = v ?? false;
|
|
|
|
|
model.notifyListeners();
|
|
|
|
|
onUserSelectionChanged(model.allProviderDealersList[index].id, v);
|
|
|
|
|
},
|
|
|
|
|
visualDensity: VisualDensity.comfortable,
|
|
|
|
|
),
|
|
|
|
|
@ -185,14 +302,5 @@ class _AssignDealerUserSheetState extends State<AssignDealerUserSheet> {
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool validation() {
|
|
|
|
|
bool isValid = false;
|
|
|
|
|
for (var element in provider.allProviderDealersList) {
|
|
|
|
|
if (element.isBranchUser ?? false) {
|
|
|
|
|
isValid = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return isValid;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|