Provider Dealer User Implemented
parent
01dd0cfcb4
commit
5727836f3a
@ -0,0 +1,159 @@
|
|||||||
|
import 'package:car_provider_app/views/settings/branch/dealer/widget/add_phone_num_wiget.dart';
|
||||||
|
import 'package:car_provider_app/views/settings/branch/dealer/widget/assign_dealer_user_sheet.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
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/models/m_response.dart';
|
||||||
|
import 'package:mc_common_app/models/user/branch_user.dart';
|
||||||
|
import 'package:mc_common_app/theme/colors.dart';
|
||||||
|
import 'package:mc_common_app/utils/enums.dart';
|
||||||
|
import 'package:mc_common_app/utils/utils.dart';
|
||||||
|
import 'package:mc_common_app/widgets/bottom_sheet.dart';
|
||||||
|
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
|
||||||
|
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
|
||||||
|
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../../../view_models/service_view_model.dart';
|
||||||
|
|
||||||
|
class DealerUserPage extends StatefulWidget {
|
||||||
|
String branchId;
|
||||||
|
|
||||||
|
DealerUserPage(this.branchId, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DealerUserPage> createState() => _DealerUserPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DealerUserPageState extends State<DealerUserPage> {
|
||||||
|
late ServiceVM provider;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
provider = Provider.of<ServiceVM>(context, listen: false);
|
||||||
|
getBranchUsers();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getBranchUsers() {
|
||||||
|
provider.getBranchUsers({
|
||||||
|
// "id": services!.data![i].id,
|
||||||
|
"ServiceProviderBranchID": widget.branchId,
|
||||||
|
"ServiceProviderID": AppState().getUser.data?.userInfo?.providerId.toString() ?? ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: const CustomAppBar(
|
||||||
|
title: "Dealer User",
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Consumer<ServiceVM>(builder: (context, model, _) {
|
||||||
|
if (model.state == ViewState.busy) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else {
|
||||||
|
if (model.branchUserList.isEmpty) {
|
||||||
|
return const Center(child: Text("No User Added Yet"));
|
||||||
|
} else {
|
||||||
|
return ListView.separated(
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return dealerUsersWidget(model, index);
|
||||||
|
},
|
||||||
|
separatorBuilder: (context, index) {
|
||||||
|
return 12.height;
|
||||||
|
},
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
itemCount: model.branchUserList.length,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 1,
|
||||||
|
color: Colors.grey[100],
|
||||||
|
),
|
||||||
|
ShowFillButton(
|
||||||
|
title: "Assign Dealer User",
|
||||||
|
maxWidth: double.infinity,
|
||||||
|
onPressed: () {
|
||||||
|
showMyBottomSheet(
|
||||||
|
context,
|
||||||
|
child: AssignDealerUserSheet(
|
||||||
|
branchId: widget.branchId,
|
||||||
|
callBackFunc: () {
|
||||||
|
getBranchUsers();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
).paddingAll(12),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget dealerUsersWidget(ServiceVM model, int index) {
|
||||||
|
return Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
("${model.branchUserList[index].firstName} ${model.branchUserList[index].lastName}").toText(fontSize: 16, isBold: true),
|
||||||
|
8.height,
|
||||||
|
itemWidget("Role", "Dealer User"),
|
||||||
|
itemWidget("Email", model.branchUserList[index].email),
|
||||||
|
itemWidget("Phone", model.branchUserList[index].mobileNo)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
4.width,
|
||||||
|
IconButton(
|
||||||
|
onPressed: () async {
|
||||||
|
var map = {
|
||||||
|
"id": model.branchUserList[index].id,
|
||||||
|
"dealershipUserID": model.branchUserList[index].dealershipUserID,
|
||||||
|
"serviceProviderBranchID": widget.branchId,
|
||||||
|
"isActive": false,
|
||||||
|
};
|
||||||
|
Utils.showLoading(context);
|
||||||
|
MResponse response = await provider.removeDealerFromBranch(map);
|
||||||
|
Utils.hideLoading(context);
|
||||||
|
if (response.messageStatus == 1) {
|
||||||
|
getBranchUsers();
|
||||||
|
} else {
|
||||||
|
Utils.showToast(response.message.toString());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.delete_outline),
|
||||||
|
),
|
||||||
|
|
||||||
|
],
|
||||||
|
).toWhiteContainer(
|
||||||
|
width: double.infinity,
|
||||||
|
borderRadius: 12,
|
||||||
|
pading: const EdgeInsets.only(left: 14, right: 2, top: 12, bottom: 12),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget itemWidget(String title, String value) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
(title + ": ").toText(isBold: true, color: MyColors.lightTextColor),
|
||||||
|
value.toText(isBold: true),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,135 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:car_provider_app/generated/locale_keys.g.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||||
|
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||||
|
import 'package:mc_common_app/models/user/country.dart';
|
||||||
|
import 'package:mc_common_app/theme/colors.dart';
|
||||||
|
import 'package:mc_common_app/utils/navigator.dart';
|
||||||
|
import 'package:mc_common_app/utils/utils.dart';
|
||||||
|
import 'package:mc_common_app/view_models/user_view_model.dart';
|
||||||
|
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
|
||||||
|
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
|
||||||
|
import 'package:mc_common_app/widgets/tab/login_email_tab.dart';
|
||||||
|
import 'package:mc_common_app/widgets/txt_field.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class AddPhoneNumWidget extends StatefulWidget {
|
||||||
|
const AddPhoneNumWidget({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AddPhoneNumWidget> createState() => _AddPhoneNumWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AddPhoneNumWidgetState extends State<AddPhoneNumWidget> {
|
||||||
|
String phoneNum = "", countryCode = "";
|
||||||
|
late UserVM userVM;
|
||||||
|
Country? _country;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
scheduleMicrotask(() {
|
||||||
|
userVM = Provider.of(context, listen: false);
|
||||||
|
getCountryList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getCountryList() async {
|
||||||
|
_country = await userVM.getAllCountries();
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
"Enter Phone Number".toText(fontSize: 16, isBold: true),
|
||||||
|
8.height,
|
||||||
|
getCountry(context),
|
||||||
|
8.height,
|
||||||
|
TxtField(
|
||||||
|
keyboardType: TextInputType.phone,
|
||||||
|
hint: "546758594",
|
||||||
|
value: phoneNum,
|
||||||
|
isSidePaddingZero: true,
|
||||||
|
onChanged: (v) {
|
||||||
|
phoneNum = v;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
16.height,
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ShowFillButton(
|
||||||
|
title: "Cancel",
|
||||||
|
backgroundColor: MyColors.greyButtonColor,
|
||||||
|
txtColor: Colors.black,
|
||||||
|
onPressed: () {
|
||||||
|
pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
12.width,
|
||||||
|
Expanded(
|
||||||
|
child: ShowFillButton(
|
||||||
|
title: "Send OTP",
|
||||||
|
onPressed: () {
|
||||||
|
//User Role: Dealer|Manager for a branch
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
|
if (validation())
|
||||||
|
userVM.performBasicOtpRegisterPage(context, countryCode: countryCode, phoneNum: phoneNum, role: 7, isNeedToPassToken: true, reloadPage: () {
|
||||||
|
pop(context);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget getCountry(BuildContext context) {
|
||||||
|
if (_country != null) {
|
||||||
|
List<DropValue> dropList = [];
|
||||||
|
_country!.data?.forEach((element) {
|
||||||
|
dropList.add(DropValue(element.id ?? 0, (element.countryName ?? "") + " " + (element.countryCode ?? ""), element.countryCode ?? ""));
|
||||||
|
});
|
||||||
|
return DropdownField((DropValue value) {
|
||||||
|
countryCode = value.subValue;
|
||||||
|
}, list: dropList, hint: LocaleKeys.selectCountryCode.tr());
|
||||||
|
} else {
|
||||||
|
return const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validation() {
|
||||||
|
bool isValid = true;
|
||||||
|
if (countryCode.isEmpty) {
|
||||||
|
Utils.showToast(LocaleKeys.selectCountryCode.tr());
|
||||||
|
//("Please select Country Code");
|
||||||
|
isValid = false;
|
||||||
|
} else if (phoneNum.isEmpty) {
|
||||||
|
Utils.showToast(LocaleKeys.addPhoneNo.tr());
|
||||||
|
//("Please add Phone No");
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,189 @@
|
|||||||
|
import 'package:car_provider_app/view_models/service_view_model.dart';
|
||||||
|
import 'package:car_provider_app/views/settings/branch/dealer/widget/add_phone_num_wiget.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
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/models/m_response.dart';
|
||||||
|
import 'package:mc_common_app/theme/colors.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';
|
||||||
|
import 'package:mc_common_app/widgets/bottom_sheet.dart';
|
||||||
|
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
|
||||||
|
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class AssignDealerUserSheet extends StatefulWidget {
|
||||||
|
String branchId;
|
||||||
|
VoidCallback callBackFunc;
|
||||||
|
|
||||||
|
AssignDealerUserSheet({required this.branchId, required this.callBackFunc, Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AssignDealerUserSheet> createState() => _AssignDealerUserSheetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AssignDealerUserSheetState extends State<AssignDealerUserSheet> {
|
||||||
|
late ServiceVM provider;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
provider = Provider.of<ServiceVM>(context, listen: false);
|
||||||
|
getBranchUsers();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getBranchUsers() {
|
||||||
|
provider.getAllProviderDealers({
|
||||||
|
// "id": services!.data![i].id,
|
||||||
|
"ServiceProviderBranchID": widget.branchId,
|
||||||
|
"ServiceProviderID": AppState().getUser.data?.userInfo?.providerId.toString() ?? ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: MediaQuery.of(context).size.height / 1.2,
|
||||||
|
color: Colors.white,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Consumer<ServiceVM>(builder: (context, model, _) {
|
||||||
|
if (model.state == ViewState.busy) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else {
|
||||||
|
if (model.allProviderDealersList.isEmpty) {
|
||||||
|
return const Center(child: Text("No User Added Yet"));
|
||||||
|
} else {
|
||||||
|
return ListView.separated(
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return dealerUsersWidget(model, index);
|
||||||
|
},
|
||||||
|
separatorBuilder: (context, index) {
|
||||||
|
return 12.height;
|
||||||
|
},
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
itemCount: model.allProviderDealersList.length,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 1,
|
||||||
|
color: Colors.grey[100],
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
ShowFillButton(
|
||||||
|
title: "Assign Dealer User",
|
||||||
|
maxWidth: double.infinity,
|
||||||
|
onPressed: () async {
|
||||||
|
if (validation()) {
|
||||||
|
Utils.showLoading(context);
|
||||||
|
List<int> userIds = [];
|
||||||
|
for (var element in provider.allProviderDealersList) {
|
||||||
|
if (element.isBranchUser) {
|
||||||
|
userIds.add(element.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var map = {
|
||||||
|
"dealershipUserIDs": userIds,
|
||||||
|
"serviceProviderBranchID": widget.branchId,
|
||||||
|
};
|
||||||
|
MResponse 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: "+ Create New User",
|
||||||
|
maxWidth: double.infinity,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
borderColor: MyColors.darkPrimaryColor,
|
||||||
|
txtColor: MyColors.darkPrimaryColor,
|
||||||
|
isFilled: false,
|
||||||
|
onPressed: () {
|
||||||
|
showMyBottomSheet(
|
||||||
|
context,
|
||||||
|
isDismissible: false,
|
||||||
|
child: const AddPhoneNumWidget(),
|
||||||
|
callBackFunc: () {
|
||||||
|
getBranchUsers();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
).paddingAll(12),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget dealerUsersWidget(ServiceVM model, int index) {
|
||||||
|
return Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Checkbox(
|
||||||
|
value: model.allProviderDealersList[index].isBranchUser,
|
||||||
|
onChanged: (v) {
|
||||||
|
model.allProviderDealersList[index].isBranchUser = v ?? false;
|
||||||
|
model.notifyListeners();
|
||||||
|
}),
|
||||||
|
4.width,
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
("${model.allProviderDealersList[index].firstName} ${model.allProviderDealersList[index].lastName}").toText(fontSize: 16, isBold: true),
|
||||||
|
8.height,
|
||||||
|
itemWidget("Role", "Dealer User"),
|
||||||
|
itemWidget("Email", model.allProviderDealersList[index].email),
|
||||||
|
itemWidget("Phone", model.allProviderDealersList[index].mobileNo)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).toWhiteContainer(
|
||||||
|
width: double.infinity,
|
||||||
|
borderRadius: 12,
|
||||||
|
pading: const EdgeInsets.symmetric(horizontal: 6, vertical: 12),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget itemWidget(String title, String value) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
(title + ": ").toText(isBold: true, color: MyColors.lightTextColor),
|
||||||
|
value.toText(isBold: true),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validation() {
|
||||||
|
bool isValid = false;
|
||||||
|
provider.allProviderDealersList.forEach((element) {
|
||||||
|
if (element.isBranchUser) {
|
||||||
|
isValid = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,192 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:car_provider_app/view_models/service_view_model.dart';
|
||||||
|
import 'package:car_provider_app/views/settings/services/duplication/sheet/approved_branches_list_sheet.dart';
|
||||||
|
import 'package:car_provider_app/views/settings/services/duplication/sheet/items_selection_sheet.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mc_common_app/classes/consts.dart';
|
||||||
|
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||||
|
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:mc_common_app/models/m_response.dart';
|
||||||
|
import 'package:mc_common_app/models/services/item_model.dart';
|
||||||
|
import 'package:mc_common_app/theme/colors.dart';
|
||||||
|
import 'package:mc_common_app/utils/navigator.dart';
|
||||||
|
import 'package:mc_common_app/utils/utils.dart';
|
||||||
|
import 'package:mc_common_app/widgets/bottom_sheet.dart';
|
||||||
|
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
|
||||||
|
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
|
||||||
|
import 'package:mc_common_app/widgets/dropdown/dropdown_text.dart';
|
||||||
|
import 'package:mc_common_app/widgets/empty_widget.dart';
|
||||||
|
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class MatchedServicesPage extends StatefulWidget {
|
||||||
|
MatchServicesArguments? matchServicesArguments;
|
||||||
|
|
||||||
|
MatchedServicesPage(this.matchServicesArguments, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MatchedServicesPage> createState() => _MatchedServicesPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MatchedServicesPageState extends State<MatchedServicesPage> {
|
||||||
|
late ServiceVM serviceVM;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
serviceVM = Provider.of<ServiceVM>(context, listen: false);
|
||||||
|
getMatchedServices();
|
||||||
|
}
|
||||||
|
|
||||||
|
getMatchedServices() {
|
||||||
|
serviceVM.getAllMatchedServices(widget.matchServicesArguments!.oldBranch, widget.matchServicesArguments!.newBranch, widget.matchServicesArguments!.categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
print(widget.matchServicesArguments!.oldBranch);
|
||||||
|
print(widget.matchServicesArguments!.newBranch);
|
||||||
|
print(widget.matchServicesArguments!.categoryId);
|
||||||
|
return Scaffold(
|
||||||
|
appBar: const CustomAppBar(
|
||||||
|
title: "Select Services",
|
||||||
|
),
|
||||||
|
body: SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: double.infinity,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
DropDownText(widget.matchServicesArguments!.oldBranchName).toContainer(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 14,
|
||||||
|
right: 14,
|
||||||
|
top: 21,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
12.height,
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Checkbox(
|
||||||
|
value: context.watch<ServiceVM>().isAllSelected,
|
||||||
|
onChanged: (v) {
|
||||||
|
serviceVM.selectAllServices(v ?? false);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
"Select All".toText(
|
||||||
|
isBold: true,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: "Unselect All".toText(
|
||||||
|
color: MyColors.primaryColor,
|
||||||
|
isUnderLine: true,
|
||||||
|
isBold: true,
|
||||||
|
),
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 14, vertical: 7),
|
||||||
|
).onPress(() {
|
||||||
|
serviceVM.selectAllServices(false);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
12.height,
|
||||||
|
Expanded(
|
||||||
|
child: Consumer<ServiceVM>(builder: (context, model, _) {
|
||||||
|
if (model.matchedServices == null) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (model.matchedServices!.isEmpty) {
|
||||||
|
return const EmptyWidget();
|
||||||
|
}
|
||||||
|
return ListView.separated(
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Checkbox(
|
||||||
|
value: model.matchedServices![index].isExpandedOrSelected,
|
||||||
|
onChanged: (v) {
|
||||||
|
if (model.matchedServices![index].serviceItems!.isEmpty) {
|
||||||
|
Utils.showToast("No Items Available in this service");
|
||||||
|
} else {
|
||||||
|
model.matchedServices![index].isExpandedOrSelected = v ?? false;
|
||||||
|
model.updateServiceItem(index, model.matchedServices![index].isExpandedOrSelected);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
model.matchedServices![index].serviceDescription.toString().toText(fontSize: 16, isBold: true),
|
||||||
|
"${model.matchedServices![index].serviceItems!.where((c) => c.isUpdateOrSelected == true).length} items selected out of ${model.matchedServices![index].serviceItems!.length}"
|
||||||
|
.toText(color: MyColors.lightTextColor)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SvgPicture.asset(
|
||||||
|
MyAssets.icEdit,
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).toWhiteContainer(width: double.infinity, allPading: 8).onPress(
|
||||||
|
() {
|
||||||
|
showMyBottomSheet(
|
||||||
|
context,
|
||||||
|
child: ItemsSelectionSheet(
|
||||||
|
model.matchedServices![index].serviceItems ?? [],
|
||||||
|
onItemCopied: (List<ItemData> selected) {
|
||||||
|
model.copyItems(index, selected);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (context, index) {
|
||||||
|
return 8.height;
|
||||||
|
},
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 14),
|
||||||
|
itemCount: model.matchedServices!.length,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
12.height,
|
||||||
|
ShowFillButton(
|
||||||
|
title: "Copy Selected Services",
|
||||||
|
maxWidth: double.infinity,
|
||||||
|
margin: const EdgeInsets.all(14),
|
||||||
|
onPressed: () async {
|
||||||
|
Utils.showLoading(context);
|
||||||
|
List<int> items = [];
|
||||||
|
for (var element in serviceVM.matchedServices!) {
|
||||||
|
items.addAll(element.serviceItems!.where((e) => e.isUpdateOrSelected == true).map((e) => e.id ?? 0).toList());
|
||||||
|
}
|
||||||
|
Map<String, dynamic> map = {
|
||||||
|
"providerBranchID": widget.matchServicesArguments!.newBranch.toString(),
|
||||||
|
"serviceItems": items,
|
||||||
|
};
|
||||||
|
print(jsonEncode(map));
|
||||||
|
MResponse mResponse = await serviceVM.duplicateItems(map);
|
||||||
|
Utils.hideLoading(context);
|
||||||
|
Utils.showToast(mResponse.message ?? "");
|
||||||
|
pop(context);
|
||||||
|
pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,141 @@
|
|||||||
|
import 'package:car_provider_app/config/provider_routes.dart';
|
||||||
|
import 'package:car_provider_app/view_models/service_view_model.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mc_common_app/classes/app_state.dart';
|
||||||
|
import 'package:mc_common_app/classes/consts.dart';
|
||||||
|
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||||
|
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||||
|
import 'package:mc_common_app/generated/locale_keys.g.dart';
|
||||||
|
import 'package:mc_common_app/models/services/branch_model.dart';
|
||||||
|
import 'package:mc_common_app/theme/colors.dart';
|
||||||
|
import 'package:mc_common_app/utils/enums.dart';
|
||||||
|
import 'package:mc_common_app/utils/navigator.dart';
|
||||||
|
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:geolocator/geolocator.dart';
|
||||||
|
|
||||||
|
class MatchServicesArguments {
|
||||||
|
int oldBranch, newBranch, categoryId;
|
||||||
|
String oldBranchName;
|
||||||
|
|
||||||
|
MatchServicesArguments({required this.oldBranch, required this.oldBranchName, required this.newBranch, required this.categoryId});
|
||||||
|
}
|
||||||
|
|
||||||
|
class ApprovedBranchesListSheet extends StatelessWidget {
|
||||||
|
int newBranch, categoryId;
|
||||||
|
|
||||||
|
ApprovedBranchesListSheet({required this.newBranch, required this.categoryId, Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
height: MediaQuery.of(context).size.height / 1.2,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
"Select Branch".toText(fontSize: 20, isBold: true),
|
||||||
|
"Select the branch to copy their items to this branch. You can modify the selection at any time.".toText(
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
12.height,
|
||||||
|
Expanded(
|
||||||
|
child: Consumer<ServiceVM>(
|
||||||
|
builder: (context, model, _) {
|
||||||
|
if (model.state == ViewState.busy) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else {
|
||||||
|
List<BranchModel> branches = [];
|
||||||
|
if (model.branches!.data != null) {
|
||||||
|
branches = model.branches!.data!.serviceProviderBranch!.where((element) => model.selectedBranchStatus == element.statusId).toList();
|
||||||
|
}
|
||||||
|
return branches.isEmpty
|
||||||
|
? Center(child: Text(LocaleKeys.no_branch.tr()))
|
||||||
|
: ListView.separated(
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 74,
|
||||||
|
height: 50,
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: MyColors.darkPrimaryColor,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(6),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
MyAssets.icBranches,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
12.width,
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.place,
|
||||||
|
size: 12,
|
||||||
|
color: MyColors.darkPrimaryColor,
|
||||||
|
),
|
||||||
|
Geolocator.distanceBetween(AppState().currentLocation.latitude, AppState().currentLocation.latitude, double.parse(branches[index].latitude ?? "0"),
|
||||||
|
double.parse(branches[index].longitude ?? "0"))
|
||||||
|
.toStringAsFixed(2)
|
||||||
|
.toText(
|
||||||
|
fontSize: 12,
|
||||||
|
color: MyColors.darkPrimaryColor,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
branches[index].branchName ?? "",
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
"Tap to select".toText(fontSize: 10, color: MyColors.grey70Color),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
12.width,
|
||||||
|
const Icon(
|
||||||
|
Icons.arrow_forward_rounded,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).toContainer(isShadowEnabled: true).onPress(() async {
|
||||||
|
// branches[index].countryID = model.branchs!.data!.countryID;
|
||||||
|
// branches[index].countryName = model.branchs!.data!.countryName;
|
||||||
|
navigateWithName(
|
||||||
|
context,
|
||||||
|
ProviderAppRoutes.matchServices,
|
||||||
|
arguments: MatchServicesArguments(
|
||||||
|
oldBranch: branches[index].id ?? 0,
|
||||||
|
oldBranchName: branches[index].branchName ?? "",
|
||||||
|
newBranch: newBranch,
|
||||||
|
categoryId: categoryId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
separatorBuilder: (context, index) {
|
||||||
|
return 12.height;
|
||||||
|
},
|
||||||
|
itemCount: branches.length,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,156 @@
|
|||||||
|
import 'package:car_provider_app/view_models/service_view_model.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||||
|
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||||
|
import 'package:mc_common_app/models/services/item_model.dart';
|
||||||
|
import 'package:mc_common_app/theme/colors.dart';
|
||||||
|
import 'package:mc_common_app/utils/navigator.dart';
|
||||||
|
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
|
||||||
|
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||||
|
import 'package:mc_common_app/widgets/txt_field.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class ItemsSelectionSheet extends StatefulWidget {
|
||||||
|
final List<ItemData> serviceItems;
|
||||||
|
final Function(List<ItemData>) onItemCopied;
|
||||||
|
|
||||||
|
const ItemsSelectionSheet(this.serviceItems, {required this.onItemCopied, Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ItemsSelectionSheet> createState() => _ItemsSelectionSheetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ItemsSelectionSheetState extends State<ItemsSelectionSheet> {
|
||||||
|
bool isAllItemsSelected = false;
|
||||||
|
List<ItemData>? tempItems;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
//tempItems=List.from(widget.serviceItems);
|
||||||
|
// tempItems=[...widget.serviceItems];
|
||||||
|
//tempItems.addAll(widget.serviceItems);
|
||||||
|
tempItems = widget.serviceItems
|
||||||
|
.map(
|
||||||
|
(item) => ItemData.fromJson(item.toJson())
|
||||||
|
|
||||||
|
// ItemData(
|
||||||
|
// id: item.id,
|
||||||
|
// name: item.name,
|
||||||
|
// price: item.price,
|
||||||
|
// manufactureDate: item.manufactureDate,
|
||||||
|
// description: item.description,
|
||||||
|
// pictureUrl: item.pictureUrl,
|
||||||
|
// companyId: item.companyId,
|
||||||
|
// serviceProviderServiceId: item.serviceProviderServiceId,
|
||||||
|
// isActive: item.isActive,
|
||||||
|
// isAllowAppointment: item.isAllowAppointment,
|
||||||
|
// isAppointmentCompanyLoc: item.isAppointmentCompanyLoc,
|
||||||
|
// isAppointmentCustomerLoc: item.isAppointmentCompanyLoc,
|
||||||
|
// isUpdateOrSelected: item.isUpdateOrSelected,
|
||||||
|
// ),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
height: MediaQuery.of(context).size.height / 1.2,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
"Select Items To Copy".toText(fontSize: 16, isBold: true),
|
||||||
|
12.height,
|
||||||
|
TxtField(
|
||||||
|
hint: "Search Items",
|
||||||
|
onChanged: (v) {},
|
||||||
|
),
|
||||||
|
6.height,
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Checkbox(
|
||||||
|
// value: context.watch<ServiceVM>().isAllSelected,
|
||||||
|
value: isAllItemsSelected,
|
||||||
|
onChanged: (v) {
|
||||||
|
isAllItemsSelected = v ?? false;
|
||||||
|
selectAllTempItems(v ?? false);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
"Select All".toText(
|
||||||
|
isBold: true,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: "Unselect All".toText(
|
||||||
|
color: MyColors.primaryColor,
|
||||||
|
isUnderLine: true,
|
||||||
|
isBold: true,
|
||||||
|
),
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 14, vertical: 7),
|
||||||
|
).onPress(() {
|
||||||
|
isAllItemsSelected = false;
|
||||||
|
selectAllTempItems(false);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: ListView.separated(
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Checkbox(
|
||||||
|
value: tempItems![index].isUpdateOrSelected,
|
||||||
|
onChanged: (v) {
|
||||||
|
isAllItemsSelected = false;
|
||||||
|
updateTempItem(index, v ?? false);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: tempItems![index].name.toString().toText(fontSize: 16, isBold: true),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (context, index) {
|
||||||
|
return const Divider();
|
||||||
|
},
|
||||||
|
itemCount: tempItems!.length,
|
||||||
|
).toWhiteContainer(width: double.infinity),
|
||||||
|
),
|
||||||
|
12.height,
|
||||||
|
ShowFillButton(
|
||||||
|
title: "Copy Selected Item",
|
||||||
|
maxWidth: double.infinity,
|
||||||
|
onPressed: () {
|
||||||
|
widget.onItemCopied(tempItems ?? []);
|
||||||
|
pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
selectAllTempItems(bool value) {
|
||||||
|
for (var element in tempItems ?? []) {
|
||||||
|
element.isUpdateOrSelected = value;
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTempItem(int index, bool value) {
|
||||||
|
tempItems![index].isUpdateOrSelected = value;
|
||||||
|
setState(() {});
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue