Compare commits

...

11 Commits

Author SHA1 Message Date
Faiz Hashmi 0ed41736b2 Quick Fixes 10 months ago
Faiz Hashmi f9b559fe23 Merge branch 'aamir_dev' into faiz_development 10 months ago
Faiz Hashmi 6fb586c3b4 Quick Fixes 10 months ago
Aamir Muhammad 648b3b9764 fixes 10 months ago
Faiz Hashmi 8a93c82b22 Quick Fixes 10 months ago
Faiz Hashmi 8bed0df13a Merge remote-tracking branch 'origin/faiz_dev' into faiz_development 10 months ago
Faiz Hashmi 02bf2d6b2f Quick Fixes 10 months ago
Faiz Hashmi 40500614d3 Merge remote-tracking branch 'origin/faiz_dev' into faiz_development 10 months ago
Faiz Hashmi 44ae05f9e7 Quick Fixes 10 months ago
Faiz Hashmi b621556158 Quick Fixes 10 months ago
Aamir Muhammad ea54455fdc fixes 10 months ago

@ -16,10 +16,29 @@
or higher if your app targets Android 14 (API level 34) or higher. -->
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
<queries>
<!-- If your app checks for SMS support -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="sms" />
</intent>
<!-- If your app checks for call support -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="tel" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="mailto" />
</intent>
</queries>
<application
android:icon="@mipmap/ic_launcher"
android:extractNativeLibs="true"
android:icon="@mipmap/ic_launcher"
android:label="Provider">
<activity
android:name=".MainActivity"
@ -56,6 +75,7 @@
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8" />

@ -48,6 +48,7 @@ post_install do |installer|
'PERMISSION_LOCATION=1',
'PERMISSION_LOCATION_WHENINUSE=0',
'PERMISSION_NOTIFICATIONS=1',
'PERMISSION_MEDIA_LIBRARY=1',
]
end
end

@ -27,6 +27,8 @@ import 'package:mc_common_app/views/appointments/appointments_filter_view.dart';
import 'package:mc_common_app/views/setting_options/provider_accepted_requests_view.dart';
class ProviderAppRoutes {
static final Map<String, WidgetBuilder> routes = {
//Home page
AppRoutes.dashboard: (context) => DashboardView(dashboardRouteEnum: (ModalRoute.of(context)!.settings.arguments ?? DashboardRouteEnum.none) as DashboardRouteEnum),

@ -140,14 +140,16 @@ Future<void> main() async {
),
),
ChangeNotifierProvider<ShippingManagementVM>(
create: (_) => ShippingManagementVM(
shippingRepo: injector.get<ShippingRepo>(),
commonRepo: injector.get<CommonRepo>(),
)),
create: (_) => ShippingManagementVM(
shippingRepo: injector.get<ShippingRepo>(),
commonRepo: injector.get<CommonRepo>(),
),
),
ChangeNotifierProvider<SettingOptionsVM>(
create: (_) => SettingOptionsVM(
settingOptionsRepo: injector.get<SettingOptionsRepo>(),
)),
create: (_) => SettingOptionsVM(
settingOptionsRepo: injector.get<SettingOptionsRepo>(),
),
),
],
child: const MyApp(),
).setupLocale());
@ -164,22 +166,18 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
return Sizer(
builder: (context, orientation, deviceType) {
injector.get<AppState>().setAppType(AppType.provider);
AppState().setPostParamsModel(
PostParamsModel(
languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2,
),
PostParamsModel(languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2),
);
// ThemeData data = AppTheme.getTheme(isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar");
return MaterialApp(
theme: AppTheme.getTheme(isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar"),
debugShowCheckedModeBanner: false,
navigatorKey: navigatorKey,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,

@ -1,9 +1,11 @@
import 'dart:async';
import 'dart:developer';
import 'package:car_provider_app/main.dart';
import 'package:car_provider_app/views/dashboard/widget/general_appointment_widget.dart';
import 'package:car_provider_app/views/branch_management/schedule/widgets/chips_picker_item.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/view_models/service_view_model.dart';
@ -26,6 +28,7 @@ import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/empty_widget.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';
import 'package:easy_localization/easy_localization.dart';
@ -107,102 +110,162 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
),
12.height,
Consumer<ServiceVM>(
builder: (context, serviceVm, _) {
builder: (context, ServiceVM serviceVm, _) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.selectServicestoAdd.tr().toText(
fontSize: 18,
isBold: true,
),
12.height,
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
serviceVm.categoryDropList.isNotEmpty
? DropdownField(
(DropValue value) async {
category = value;
service = null;
serviceVm.fetchProviderServices(widget.appointmentListModel.branchId.toString(), value.id.toString());
},
dropdownValue: category,
list: serviceVm.categoryDropList,
hint: LocaleKeys.selectServiceCategory.tr(),
)
: const Center(
child: CircularProgressIndicator(),
),
12.height,
serviceVm.servicesDropList.isNotEmpty
? DropdownField(
(DropValue value) {
service = value;
pickedItems = null;
serviceVm.setState(ViewState.idle);
openItemsSelectionBottomSheet();
},
dropdownValue: service,
list: serviceVm.servicesDropList,
hint: LocaleKeys.defineServices.tr(),
)
: category == null
? Container()
: serviceVm.services != null && serviceVm.servicesDropList.isEmpty
? EmptyWidget(text: LocaleKeys.noServicesAvailable.tr())
: const CircularProgressIndicator(),
12.height,
(service != null && pickedItems != null && pickedItems!.isNotEmpty)
? ChipsPickerItem(
hint: LocaleKeys.selectItems.tr(),
itemsList: [...pickedItems ?? []],
onClick: () {
openItemsSelectionBottomSheet();
},
)
: service != null
? EmptyWidget(text: LocaleKeys.noItemSelectedYet.tr())
: const SizedBox(),
if ((service != null && pickedItems != null && pickedItems!.isNotEmpty))
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
16.height,
LocaleKeys.totalAdditionalAmount.tr().toText(
fontSize: 14,
isBold: true,
color: MyColors.lightTextColor,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
totalPrice.toString().toText(
fontSize: 29,
isBold: true,
),
2.width,
LocaleKeys.sar
.tr()
.toText(
fontSize: 16,
isBold: true,
color: MyColors.lightTextColor,
)
.paddingOnly(bottom: 5),
],
),
10.height,
],
),
],
LocaleKeys.customService.tr().toText(fontSize: 18),
8.width,
Center(
child: Checkbox(
value: serviceVm.customServiceEnabledStatus,
onChanged: (value) {
serviceVm.updateCustomServiceEnabledStatus(value ?? false); // update the status
},
activeColor: MyColors.darkPrimaryColor,
checkColor: MyColors.white,
fillColor: serviceVm.customServiceEnabledStatus ? WidgetStateProperty.all(MyColors.darkPrimaryColor) : WidgetStateProperty.all(MyColors.white),
),
),
],
).toWhiteContainer(width: double.infinity, allPading: 12),
),
5.height,
if (serviceVm.customServiceEnabledStatus) ...[
LocaleKeys.addServiceDetails.tr().toText(fontSize: 16),
12.height,
Column(
children: [
8.height,
TxtField(
value: serviceVm.customServiceTitle,
errorValue: serviceVm.customServiceTitleError,
hint: LocaleKeys.serviceName.tr(),
onChanged: (v) => serviceVm.updateCustomServiceTitle(v),
),
8.height,
TxtField(
postfixWidget: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
LocaleKeys.sar.tr().toText(fontWeight: MyFonts.Medium, fontSize: 15, color: borderColor, textAlign: TextAlign.center),
],
),
value: serviceVm.customServicePrice,
errorValue: serviceVm.customServicePriceError,
keyboardType: TextInputType.number,
numbersOnly: true,
hint: LocaleKeys.price.tr(),
onChanged: (v) => serviceVm.updateCustomServicePrice(v),
),
8.height,
TxtField(
postfixWidget: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
"%".toText(fontWeight: MyFonts.Medium, fontSize: 15, color: borderColor, textAlign: TextAlign.center),
],
),
isNeedClickAll: true,
isBackgroundEnabled: true,
hint: '',
onTap: () {},
value: serviceVm.customerServiceTax,
errorValue: '',
keyboardType: TextInputType.number,
numbersOnly: true,
onChanged: (v) => serviceVm.updateCustomerServiceTax(v),
),
],
),
] else ...[
LocaleKeys.selectServiceDetails.tr().toText(fontSize: 16),
12.height,
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
serviceVm.categoryDropList.isNotEmpty
? DropdownField(
(DropValue value) async {
category = value;
service = null;
serviceVm.fetchProviderServices(widget.appointmentListModel.branchId.toString(), value.id.toString());
},
dropdownValue: category,
list: serviceVm.categoryDropList,
hint: LocaleKeys.selectServiceCategory.tr(),
)
: const Center(
child: CircularProgressIndicator(),
),
12.height,
serviceVm.servicesDropList.isNotEmpty
? DropdownField(
(DropValue value) {
service = value;
pickedItems = null;
serviceVm.setState(ViewState.idle);
openItemsSelectionBottomSheet();
},
dropdownValue: service,
list: serviceVm.servicesDropList,
hint: LocaleKeys.defineServices.tr(),
)
: category == null
? Container()
: serviceVm.services != null && serviceVm.servicesDropList.isEmpty
? EmptyWidget(text: LocaleKeys.noServicesAvailable.tr())
: const CircularProgressIndicator(),
12.height,
(service != null && pickedItems != null && pickedItems!.isNotEmpty)
? ChipsPickerItem(
hint: LocaleKeys.selectItems.tr(),
itemsList: [...pickedItems ?? []],
onClick: () {
openItemsSelectionBottomSheet();
},
)
: service != null
? EmptyWidget(text: LocaleKeys.noItemSelectedYet.tr())
: const SizedBox(),
if ((service != null && pickedItems != null && pickedItems!.isNotEmpty))
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
16.height,
LocaleKeys.totalAdditionalAmount.tr().toText(
fontSize: 14,
isBold: true,
color: MyColors.lightTextColor,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
totalPrice.toString().toText(
fontSize: 29,
isBold: true,
),
2.width,
LocaleKeys.sar
.tr()
.toText(
fontSize: 16,
isBold: true,
color: MyColors.lightTextColor,
)
.paddingOnly(bottom: 5),
],
),
10.height,
],
),
],
),
],
],
);
).toWhiteContainer(width: double.infinity, allPading: 12);
},
),
55.height,
@ -226,6 +289,7 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
if (pickedItems != null && pickedItems!.isNotEmpty) {
pickedItems!.clear();
}
serviceVM!.resetCustomServiceForm();
pop(context);
},
),
@ -236,29 +300,56 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
title: LocaleKeys.add.tr(),
maxWidth: double.infinity,
onPressed: () async {
if (pickedItems != null && pickedItems!.isNotEmpty) {
List<int> items = [];
pickedItems?.forEach((element) {
items.add(element.id);
});
Map<String, dynamic> postParams = {};
if (serviceVM!.customServiceEnabledStatus) {
if (serviceVM!.isCustomServiceDetailValidated()) {
postParams = {
"providerBranchID": widget.appointmentListModel.branchId,
"appointmentID": widget.appointmentListModel.id,
"serviceItemsFreeText": [
{
"name": serviceVM!.customServiceTitle,
"price": serviceVM!.customServicePrice,
"tax": serviceVM!.customerServiceTax,
}
],
};
} else {
return;
}
} else {
if (pickedItems != null && pickedItems!.isNotEmpty) {
List<int> items = [];
pickedItems?.forEach((element) {
items.add(element.id);
});
postParams = {
"providerBranchID": widget.appointmentListModel.branchId,
"appointmentID": widget.appointmentListModel.id,
"serviceItemID": items,
};
} else {
Utils.showToast(LocaleKeys.pleaseSelectItems.tr());
return;
}
}
try {
Utils.showLoading(context);
var postParams = {
"providerBranchID": widget.appointmentListModel.branchId,
"appointmentID": widget.appointmentListModel.id,
"serviceItemID": items,
};
GenericRespModel res = await serviceVM!.addNewServiceInAppointment(postParams);
_updateAppointment(context, widget.appointmentListModel.branchId ?? 0);
Utils.hideLoading(context);
if (res.messageStatus == 1) {
serviceVM!.resetCustomServiceForm();
_updateAppointment(context, widget.appointmentListModel.branchId ?? 0);
Utils.showToast(LocaleKeys.itemsAddedSuccessfully.tr());
pop(context);
pop(context);
} else {
Utils.showToast(res.message.toString());
}
} else {
Utils.showToast(LocaleKeys.pleaseSelectItems.tr());
} catch (e) {
Utils.showToast(e.toString());
Utils.hideLoading(context);
}
},
),
@ -273,6 +364,10 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
}
Future<void> _updateAppointment(BuildContext context, int branchId) async {
await context.read<AppointmentsVM>().getMyAppointmentsForProvider(branchID: branchId);
await context.read<AppointmentsVM>().applyFilterOnAppointmentsVMForProviders(
branchID: branchId,
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true,
);
}
}

@ -55,28 +55,26 @@ class AppointmentDetailListPage extends StatelessWidget {
return ListView.separated(
itemBuilder: (context, index) {
if (customerID == 0) {
customerID = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].customerID ?? 0;
customerID = appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].customerID ?? 0;
}
if (customerName.isEmpty) {
customerName = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].customerName ?? "";
customerName = appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].customerName ?? "";
}
return GeneralAppointmentWidget(
appointmentListModel: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index],
appointmentListModel: appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index],
isNeedTotalPayment: true,
isNeedToShowAppointmentStatus: true,
isNeedToShowMergeStatus: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].isMerged ?? false,
isNeedToShowMergeStatus: appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].isMerged ?? false,
onTap: () {
appointmentsVM.selectedAppointmentId = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].id ?? 0;
appointmentsVM.selectedAppointmentId = appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].id ?? 0;
appointmentsVM.selectedAppointmentSubIndex = index;
navigateWithName(context, AppRoutes.updateAppointmentPage,
arguments: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index]);
arguments: appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index]);
},
);
},
separatorBuilder: (context, snapchat) {
return 21.height;
},
itemCount: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList!.length,
separatorBuilder: (context, snapchat) => 21.height,
itemCount: appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList!.length,
padding: const EdgeInsets.all(21),
);
}

@ -1,9 +1,5 @@
import 'dart:async';
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/views/dashboard/widget/general_appointment_widget.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependency_injection.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
@ -14,7 +10,7 @@ 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/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:mc_common_app/widgets/common_widgets/filters_list.dart';
import 'package:mc_common_app/widgets/empty_widget.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:flutter/material.dart';
@ -40,12 +36,16 @@ class _AppointmentPageState extends State<AppointmentPage> {
GlobalKey<RefreshIndicatorState> refreshIndicatorKey = GlobalKey<RefreshIndicatorState>();
Future<void> _pullRefresh(BuildContext context) async {
await appointmentsVM.getAppointmentSlotsInfo(
context: context,
branchID: widget.branch.id!,
isNeedToRebuild: true,
);
await appointmentsVM.getAppointmentsBasedOnFiltersForProviders(branchID: widget.branch.id!);
var futures = <Future<void>>[
appointmentsVM.getAppointmentSlotsInfo(branchID: widget.branch.id!),
appointmentsVM.applyFilterOnAppointmentsVMForProviders(
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true,
),
];
// Wait for both futures to complete
await Future.wait(futures);
}
@override
@ -88,69 +88,79 @@ class _AppointmentPageState extends State<AppointmentPage> {
width: double.infinity,
height: double.infinity,
child: Consumer(builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
if (appointmentsVM.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());
} else {
return RefreshIndicator(
onRefresh: () => _pullRefresh(context),
key: refreshIndicatorKey,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
progressWidget(context, appointmentsVM),
FiltersList(
filterList: appointmentsVM.appointmentsFilterOptions,
padding: const EdgeInsets.symmetric(horizontal: 18),
onFilterTapped: (index, selectedFilterId) {
appointmentsVM.applyFilterOnAppointmentsVM(
appointmentStatusEnum: selectedFilterId.toAppointmentStatusEnum(),
isNeedCustomerFilter: true,
);
},
return RefreshIndicator(
onRefresh: () => _pullRefresh(context),
key: refreshIndicatorKey,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
slotDetailsWidget(context, appointmentsVM),
FiltersList(
filterList: appointmentsVM.appointmentsFilterOptions,
padding: const EdgeInsets.symmetric(horizontal: 18),
onFilterTapped: (index, selectedFilterId) {
if (appointmentsVM.isAppointmentLoading) {
return;
}
appointmentsVM.applyFilterOnAppointmentsVMForProviders(
appointmentStatusEnum: selectedFilterId.toAppointmentStatusEnum(),
isNeedCustomerFilter: true,
);
},
),
if (appointmentsVM.isAppointmentLoading) ...[
const Column(
children: [
SizedBox(height: 50),
Center(child: CircularProgressIndicator()),
],
),
if (appointmentsVM.myFilteredAppointments2.isEmpty)
EmptyWidget(
spacerWidget: const SizedBox(height: 25),
text: LocaleKeys.noAppointmentFound.tr(),
)
else ...[
ListView.separated(
itemBuilder: (context, index) {
return GeneralAppointmentWidget(
isNeedToShowItems: true,
appointmentListModel: appointmentsVM.myFilteredAppointments2[index],
isNeedTotalPayment: false,
onTap: () {
appointmentsVM.selectedAppointmentIndex = index;
navigateWithName(
context,
AppRoutes.appointmentDetailList,
// arguments: appointmentsVM
// .myFilteredAppointments2[index]
// .customerAppointmentList,
] else
...[
if (appointmentsVM.myFilteredAppointmentsForProvider.isEmpty)
EmptyWidget(
spacerWidget: const SizedBox(height: 25),
text: LocaleKeys.noAppointmentFound.tr(),
)
else
...[
ListView.separated(
itemBuilder: (context, index) {
return GeneralAppointmentWidget(
isNeedToShowItems: true,
appointmentListModel: appointmentsVM.myFilteredAppointmentsForProvider[index],
isNeedTotalPayment: false,
onTap: () {
appointmentsVM.selectedAppointmentIndex = index;
navigateWithName(
context,
AppRoutes.appointmentDetailList,
);
},
);
},
);
},
separatorBuilder: (context, snapchat) => 21.height,
itemCount: appointmentsVM.myFilteredAppointments2.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(21),
),
separatorBuilder: (context, snapchat) => 21.height,
itemCount: appointmentsVM.myFilteredAppointmentsForProvider.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(21),
),
],
],
],
),
],
),
);
}
),
);
}),
),
);
}
Widget progressWidget(BuildContext context, AppointmentsVM appointmentsVM) {
Widget slotDetailsWidget(BuildContext context, AppointmentsVM appointmentsVM) {
if (appointmentsVM.isSlotsLoading) {
return const SizedBox(height: 200, child: Center(child: CircularProgressIndicator()));
}
double percent = 0.0;
if (appointmentsVM.appointmentSlots != null) {
percent = appointmentsVM.appointmentSlots!.occupiedSlots / appointmentsVM.appointmentSlots!.totalSlots;
@ -161,9 +171,9 @@ class _AppointmentPageState extends State<AppointmentPage> {
children: [
Expanded(
child: LocaleKeys.slotsOverview.tr().toText(
fontSize: 16,
fontWeight: FontWeight.bold,
),
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
@ -184,14 +194,13 @@ class _AppointmentPageState extends State<AppointmentPage> {
vertical: 6,
),
)
.onPress(() async {
String date = await Utils.pickDateFromDatePicker(
context,
firstDate: null,
);
appointmentsVM.selectedDateForAppointments = date;
_pullRefresh(context);
}),
.onPress(
() async {
String date = await Utils.pickDateFromDatePicker(context, firstDate: DateTime(2023));
appointmentsVM.selectedDateForAppointments = date;
await appointmentsVM.getAppointmentSlotsInfo(branchID: widget.branch.id!);
},
),
],
),
24.height,
@ -209,15 +218,15 @@ class _AppointmentPageState extends State<AppointmentPage> {
color: MyColors.lightGreyEAColor,
),
4.width,
(LocaleKeys.empty.tr() + ":").toText(
("${LocaleKeys.empty.tr()}:").toText(
fontSize: 8,
color: Colors.white,
),
(appointmentsVM.appointmentSlots?.emptySlots ?? 0).toString().toText(
fontSize: 9,
fontWeight: FontWeight.bold,
color: Colors.white,
),
fontSize: 9,
fontWeight: FontWeight.bold,
color: Colors.white,
),
],
).toContainer(
backgroundColor: MyColors.darkIconColor,
@ -231,15 +240,15 @@ class _AppointmentPageState extends State<AppointmentPage> {
color: MyColors.darkPrimaryColor,
),
4.width,
(LocaleKeys.occupied.tr() + ":").toText(
("${LocaleKeys.occupied.tr()}:").toText(
fontSize: 8,
color: Colors.white,
),
(appointmentsVM.appointmentSlots?.occupiedSlots ?? 0).toString().toText(
fontSize: 9,
fontWeight: FontWeight.bold,
color: Colors.white,
),
fontSize: 9,
fontWeight: FontWeight.bold,
color: Colors.white,
),
],
).toContainer(
backgroundColor: MyColors.darkIconColor,
@ -255,13 +264,13 @@ class _AppointmentPageState extends State<AppointmentPage> {
mainAxisAlignment: MainAxisAlignment.center,
children: [
LocaleKeys.totalSlots.tr().toText(
fontSize: 13,
fontWeight: FontWeight.bold,
),
fontSize: 13,
fontWeight: FontWeight.bold,
),
(appointmentsVM.appointmentSlots?.totalSlots ?? 0).toString().toText(
fontSize: 24,
fontWeight: FontWeight.bold,
),
fontSize: 24,
fontWeight: FontWeight.bold,
),
],
),
backgroundColor: MyColors.lightGreyEAColor,

@ -42,7 +42,7 @@ class MergeAppointmentListPage extends StatelessWidget {
: ListView.separated(
itemBuilder: (context, index) {
return GeneralAppointmentWidget(
appointmentListModel: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index],
appointmentListModel: appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index],
isNeedTotalPayment: true,
isSelectable: true,
isNeedToShowAppointmentStatus: true,
@ -55,7 +55,7 @@ class MergeAppointmentListPage extends StatelessWidget {
separatorBuilder: (context, snapchat) {
return 21.height;
},
itemCount: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList!.length,
itemCount: appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList!.length,
padding: const EdgeInsets.all(21),
),
),
@ -72,14 +72,14 @@ class MergeAppointmentListPage extends StatelessWidget {
Utils.showLoading(context);
List<int> appointmentIDs = [];
for (var element in appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList!) {
for (var element in appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList!) {
if (element.isSelected ?? false) {
appointmentIDs.add(element.id ?? 0);
}
}
Map<String, dynamic> map = {
"serviceProviderID": injector.get<AppState>().getUser.data?.userInfo?.providerId.toString() ?? "0",
"serviceProviderBranchID": appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].branchId,
"serviceProviderBranchID": appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].branchId,
"serviceAppointmentIDs": appointmentIDs
};
@ -89,7 +89,7 @@ class MergeAppointmentListPage extends StatelessWidget {
if (response.messageStatus == 1) {
Utils.showToast(LocaleKeys.appointmentMergeSuccessfully.tr());
_updateAppointment(context, appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].branchId ?? 0);
_updateAppointment(context, appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].branchId ?? 0);
pop(context);
pop(context);
@ -111,6 +111,10 @@ class MergeAppointmentListPage extends StatelessWidget {
}
Future<void> _updateAppointment(BuildContext context, int branchId) async {
await context.read<AppointmentsVM>().getMyAppointmentsForProvider(branchID: branchId);
await context.read<AppointmentsVM>().applyFilterOnAppointmentsVMForProviders(
branchID: branchId,
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true,
);
}
}

@ -37,7 +37,7 @@ class _UpdateAppointmentPageState extends State<UpdateAppointmentPage> {
width: double.infinity,
height: double.infinity,
child: Consumer(builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
appointmentListModel = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![appointmentsVM.selectedAppointmentSubIndex];
appointmentListModel = appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![appointmentsVM.selectedAppointmentSubIndex];
if (appointmentsVM.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());
} else {
@ -313,6 +313,10 @@ class _UpdateAppointmentPageState extends State<UpdateAppointmentPage> {
}
Future<void> _updateAppointment(BuildContext context, int branchId) async {
await context.read<AppointmentsVM>().getMyAppointmentsForProvider(branchID: branchId);
await context.read<AppointmentsVM>().applyFilterOnAppointmentsVMForProviders(
branchID: branchId,
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true,
);
}
}

@ -60,7 +60,9 @@ class _BranchDetailPageState extends State<BranchDetailPage> {
bool validation(BuildContext context) {
bool isValid = false;
for (var element in context.read<ServiceVM>().allProviderDealersList) {
for (var element in context
.read<ServiceVM>()
.allProviderDealersList) {
if (element.isBranchUser ?? false) {
isValid = true;
}
@ -112,6 +114,7 @@ class _BranchDetailPageState extends State<BranchDetailPage> {
onPressed: () async {
showMyBottomSheet(
context,
isScrollControlled: true,
child: AssignDealerUserSheet(
branchId: widget.branchData.id.toString(),
callBackFunc: () {
@ -170,43 +173,46 @@ class _BranchDetailPageState extends State<BranchDetailPage> {
8.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
serviceVM.categories[pIndex].categoryName.toString().toText(fontSize: 16),
],
),
8.height,
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
return Container(
child: (EasyLocalization.of(context)?.currentLocale?.countryCode == "SA"
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
serviceVM.categories[pIndex].categoryName.toString().toText(fontSize: 16),
],
),
8.height,
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
return Container(
child: (EasyLocalization
.of(context)
?.currentLocale
?.countryCode == "SA"
? serviceVM.categories[pIndex].services![index].serviceDescriptionN.toString()
: serviceVM.categories[pIndex].services![index].serviceDescription.toString())
.toText(
fontSize: 12,
color: MyColors.lightTextColor,
),
);
},
itemCount: serviceVM.categories[pIndex].services?.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
),
),
.toText(
fontSize: 12,
color: MyColors.lightTextColor,
),
);
},
itemCount: serviceVM.categories[pIndex].services?.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
),
),
],
).withArrow(isArrowEnabled: true)
],
).withArrow(isArrowEnabled: true)
],
)),
)),
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
@ -281,27 +287,29 @@ class _BranchDetailPageState extends State<BranchDetailPage> {
8.width,
Expanded(
child: LocaleKeys.setorEditBranchSchedule.tr().toText(
isUnderLine: true,
fontSize: 12,
color: Colors.white,
decorationColor: MyColors.white,
),
isUnderLine: true,
fontSize: 12,
color: Colors.white,
decorationColor: MyColors.white,
),
),
],
)
.withArrow(
isArrowEnabled: true,
color: Colors.white,
arrowWidth: 16.16,
arrowHeight: 11.75,
)
isArrowEnabled: true,
color: Colors.white,
arrowWidth: 16.16,
arrowHeight: 11.75,
)
.margin(right: 5),
).onPress(() {
if (widget.branchData.branchStatus == BranchStatusEnum.pending || widget.branchData.branchStatus == BranchStatusEnum.rejected) {
Utils.showToast(LocaleKeys.waitForBranchVerification.tr());
return;
}
context.read<ScheduleVM>().currentSelectedBranchName = widget.branchData.branchName.toString();
context
.read<ScheduleVM>()
.currentSelectedBranchName = widget.branchData.branchName.toString();
navigateWithName(context, AppRoutes.schedulesList, arguments: widget.branchData.id.toString());
}),
10.height,
@ -332,7 +340,7 @@ class _BranchDetailPageState extends State<BranchDetailPage> {
)).horPaddingMain(),
// Row(
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,Assign
// children: [
// const Icon(
// Icons.add,
@ -363,38 +371,39 @@ class _BranchDetailPageState extends State<BranchDetailPage> {
const Center(
child: CircularProgressIndicator(),
),
] else ...[
ListView.separated(
itemBuilder: (context, pIndex) {
return buildServiceTileWidget(pIndex, serviceVM).onPress(() {
serviceVM.categories[pIndex].branchId = widget.branchData.id.toString();
serviceVM.categories[pIndex].branchName = widget.branchData.branchName.toString();
// CategoryData categoryData = serviceVM.categories[pIndex];
serviceVM.applyFilterOnBranchServices(serviceStatusEnum: ServiceStatusEnum.approvedOrActive);
] else
...[
ListView.separated(
itemBuilder: (context, pIndex) {
return buildServiceTileWidget(pIndex, serviceVM).onPress(() {
serviceVM.categories[pIndex].branchId = widget.branchData.id.toString();
serviceVM.categories[pIndex].branchName = widget.branchData.branchName.toString();
// CategoryData categoryData = serviceVM.categories[pIndex];
serviceVM.applyFilterOnBranchServices(serviceStatusEnum: ServiceStatusEnum.approvedOrActive);
CategoryData categoryData = CategoryData(
id: serviceVM.categories[pIndex].id,
branchId: serviceVM.categories[pIndex].branchId,
branchName: serviceVM.categories[pIndex].branchName,
categoryName: serviceVM.categories[pIndex].categoryName,
categoryNameN: serviceVM.categories[pIndex].categoryNameN,
serviceCategoryIconUrl: serviceVM.categories[pIndex].serviceCategoryIconUrl,
serviceCategoryImageUrl: serviceVM.categories[pIndex].serviceCategoryImageUrl,
services: [],
);
CategoryData categoryData = CategoryData(
id: serviceVM.categories[pIndex].id,
branchId: serviceVM.categories[pIndex].branchId,
branchName: serviceVM.categories[pIndex].branchName,
categoryName: serviceVM.categories[pIndex].categoryName,
categoryNameN: serviceVM.categories[pIndex].categoryNameN,
serviceCategoryIconUrl: serviceVM.categories[pIndex].serviceCategoryIconUrl,
serviceCategoryImageUrl: serviceVM.categories[pIndex].serviceCategoryImageUrl,
services: [],
);
navigateWithName(context, AppRoutes.servicesList, arguments: categoryData);
});
},
itemCount: serviceVM.categories.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(20),
separatorBuilder: (BuildContext context, int index) {
return 12.height;
},
),
],
navigateWithName(context, AppRoutes.servicesList, arguments: categoryData);
});
},
itemCount: serviceVM.categories.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(20),
separatorBuilder: (BuildContext context, int index) {
return 12.height;
},
),
],
12.height,
],
),

@ -179,6 +179,7 @@ class _DefineBranchViewState extends State<DefineBranchView> {
onTap: () => serviceVM.pickMultipleImages(),
text: LocaleKeys.attachImage.tr(),
icon: MyAssets.attachmentIcon.buildSvg(),
extensions: GlobalConsts.allowedFileExtensions,
),
],
if (serviceVM.branchImageError != "") ...[

@ -184,10 +184,13 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
initial: tomorrowDate,
firstDate: DateTime.now(),
);
if (scheduleID != null) {
endDate = "";
}
if (endDate.isNotEmpty) {
DateTime sDate = DateTime.parse(startDate);
DateTime eDate = DateTime.parse(endDate);
DateTime sDate = DateHelper.parseStringToDate(startDate);
DateTime eDate = DateHelper.parseStringToDate(endDate);
if (sDate.isAfter(eDate)) {
startDate = "";
@ -215,18 +218,24 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
Utils.showToast(LocaleKeys.pleaseEnterStartDateFirst.tr());
return;
} else {
sDate = DateTime.parse(startDate);
// sDate = DateTime.parse(startDate);
sDate = DateHelper.parseStringToDate(startDate);
firstDate = sDate.add(const Duration(days: 1)).subtract(
Duration(hours: DateTime.now().hour, minutes: DateTime.now().minute, seconds: DateTime.now().second, microseconds: DateTime.now().microsecond),
);
}
if (startDate != null && startDate.isNotEmpty) {
tomorrowDate = firstDate;
}
//
endDate = await Utils.pickDateFromDatePicker(
context,
initial: tomorrowDate,
firstDate: firstDate ?? tomorrowDate,
);
DateTime eDate = DateTime.parse(endDate);
DateTime eDate = DateHelper.parseStringToDate(endDate);
if (!eDate.isAfter(sDate)) {
endDate = "";
@ -259,6 +268,7 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
Expanded(
child: TxtField(
hint: LocaleKeys.shiftStartTime.tr(),
maxLines: 1,
postfixWidget: const Icon(
Icons.access_time_filled_outlined,
size: 16,
@ -286,6 +296,7 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
Expanded(
child: TxtField(
hint: LocaleKeys.shiftEndTime.tr(),
maxLines: 1,
postfixWidget: const Icon(
Icons.access_time_filled_outlined,
size: 16,

@ -23,7 +23,7 @@ import 'package:easy_localization/easy_localization.dart';
class SchedulesListPage extends StatefulWidget {
final String? branchId;
const SchedulesListPage(this.branchId, {Key? key}) : super(key: key);
const SchedulesListPage(this.branchId, {super.key});
@override
State<SchedulesListPage> createState() => _SchedulesListPageState();

@ -149,6 +149,7 @@ class _CreateItemPageState extends State<CreateItemPage> {
},
text: LocaleKeys.attachImage.tr(),
icon: MyAssets.attachmentIcon.buildSvg(),
extensions: GlobalConsts.allowedFileExtensions,
)
],
20.height,

@ -374,38 +374,46 @@ class _CreateServicesPage3State extends State<CreateServicesPage3> {
}
}
Future<bool> updateServiceStatus(BuildContext context, bool value) async {
Future<bool> updateServiceStatus(BuildContext context, bool isServiceActive) async {
try {
final serviceVM = context.read<ServiceVM>();
List<AppointmentBasicDetailsModel> list = await serviceVM.getAppointmentsByServiceID(
context: context,
branchId: int.parse(widget.branchModel!.branchId),
serviceId: widget.branchModel!.serviceProviderService!.serviceProviderServiceId!,
);
List<int> providerServiceIds = [];
providerServiceIds.add(widget.branchModel!.serviceProviderService!.serviceProviderServiceId!);
List<AppointmentBasicDetailsModel> list = [];
if (!isServiceActive) {
list = await serviceVM.getAppointmentsByCategoryOrService(
context: context,
branchId: int.parse(widget.branchModel!.branchId),
serviceId: widget.branchModel!.serviceProviderService!.serviceProviderServiceId!,
categoryId: -1, // -1 means it check appointment by by service
);
}
if (list.isEmpty) {
List<int> providerServiceIds = [];
providerServiceIds.add(widget.branchModel!.serviceProviderService!.serviceProviderServiceId!);
bool status = await serviceVM.updateServiceStatus(
context: context,
serviceStatusEnum: value ? ServiceStatusEnum.approvedOrActive : ServiceStatusEnum.deactivated,
serviceStatusEnum: isServiceActive ? ServiceStatusEnum.approvedOrActive : ServiceStatusEnum.deactivated,
branchId: int.parse(widget.branchModel!.branchId),
providerServiceIds: providerServiceIds,
);
return status;
} else {
serviceVM.buildDealNotCompletedBottomSheetOptions(
serviceVM.cannotDeactivateServiceOrCategoryBottomSheet(
mainContext: context,
appointments: list,
branchName: widget.branchModel!.branchName,
isService: true,
);
return !isServiceActive;
}
return value;
} catch (e) {
Utils.hideLoading(context);
log(e.toString());
Utils.showToast(e.toString());
return value;
return !isServiceActive;
}
}
}

@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:developer';
import 'package:car_provider_app/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
@ -11,6 +10,7 @@ import 'package:mc_common_app/config/routes.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/appointments_models/appointment_basic_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/models/services_models/service_model.dart';
import 'package:mc_common_app/theme/colors.dart';
@ -20,10 +20,8 @@ import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/service_view_model.dart';
import 'package:mc_common_app/widgets/bottom_sheet.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/common_widgets/filters_list.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/tab/role_type_tab.dart';
import 'package:provider/provider.dart';
class CreateBranchModel {
@ -105,7 +103,7 @@ class _ServicesListPageState extends State<ServicesListPage> {
),
8.width,
Expanded(
flex: 10,
flex: 8,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
@ -117,18 +115,20 @@ class _ServicesListPageState extends State<ServicesListPage> {
],
),
// 5.height,
Container(
child: ("${LocaleKeys.branchName.tr()}: ${categoryData.branchName}").toText(
fontSize: 12,
color: MyColors.lightTextColor,
),
Row(
children: [
Flexible(
child: ("${LocaleKeys.branchName.tr()}: ${categoryData.branchName}").toText(
fontSize: 12,
color: MyColors.lightTextColor,
),
),
],
),
if (categoryData.services != null) ...[
Container(
child: ("${LocaleKeys.totalNumberOfServices.tr()} ${categoryData.services!.length}").toText(
fontSize: 12,
color: MyColors.lightTextColor,
),
("${LocaleKeys.totalNumberOfServices.tr()} ${categoryData.services!.length}").toText(
fontSize: 12,
color: MyColors.lightTextColor,
),
],
],
@ -137,9 +137,10 @@ class _ServicesListPageState extends State<ServicesListPage> {
Expanded(
flex: 4,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
LocaleKeys.active.tr().toText(fontSize: 16),
8.width,
5.height,
Container(
width: 50,
height: 30,
@ -161,6 +162,7 @@ class _ServicesListPageState extends State<ServicesListPage> {
isCategoryActive: value,
categoryId: categoryData.id!,
branchId: int.parse(categoryData.branchId!),
branchName: categoryData.branchName ?? "",
);
if (status) {
@ -179,17 +181,36 @@ class _ServicesListPageState extends State<ServicesListPage> {
).toWhiteContainer(width: double.infinity, allPading: 12);
}
Future<bool> updateCategoryStatus({required bool isCategoryActive, required int categoryId, required int branchId}) async {
log("isCategoryActive: $isCategoryActive");
final serviceVM = context.read<ServiceVM>();
bool status = await serviceVM.updateCategoryStatus(
context: context,
serviceStatusEnum: isCategoryActive ? ServiceStatusEnum.approvedOrActive : ServiceStatusEnum.deactivated,
branchId: branchId,
categoryId: categoryId,
);
return status;
Future<bool> updateCategoryStatus({required bool isCategoryActive, required int categoryId, required int branchId, required String branchName}) async {
try {
final serviceVM = context.read<ServiceVM>();
List<AppointmentBasicDetailsModel> list = [];
if (isCategoryActive) {
list = await serviceVM.getAppointmentsByCategoryOrService(
context: context,
branchId: branchId,
serviceId: -1, // -1 means check appointment by CategoryId
categoryId: categoryId,
);
}
if (list.isEmpty) {
bool status = await serviceVM.updateCategoryStatus(
context: context,
serviceStatusEnum: isCategoryActive ? ServiceStatusEnum.approvedOrActive : ServiceStatusEnum.deactivated,
branchId: branchId,
categoryId: categoryId,
);
return status;
} else {
serviceVM.cannotDeactivateServiceOrCategoryBottomSheet(mainContext: context, appointments: list, branchName: branchName, isService: false);
return !isCategoryActive;
}
} catch (e) {
Utils.hideLoading(context);
log(e.toString());
Utils.showToast(e.toString());
return !isCategoryActive;
}
}
@override

@ -1,222 +0,0 @@
// import 'package:car_provider_app/config/provider_routes.dart';
// import 'package:car_provider_app/views/dashboard/widget/general_appointment_widget.dart';
// import 'package:mc_common_app/classes/app_state.dart';
// import 'package:mc_common_app/config/dependency_injection.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/theme/colors.dart';
// import 'package:mc_common_app/utils/date_helper.dart';
// import 'package:mc_common_app/utils/navigator.dart';
// import 'package:mc_common_app/utils/utils.dart';
// import 'package:mc_common_app/view_models/appointments_view_model.dart';
// import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
// import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
// import 'package:flutter/material.dart';
// import 'package:mc_common_app/extensions/int_extensions.dart';
// import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
// import 'package:percent_indicator/percent_indicator.dart';
// import 'package:provider/provider.dart';
// import 'package:easy_localization/easy_localization.dart';
//
// class AppointmentFragment extends StatelessWidget {
// String date = "";
// final VoidCallback onBackButtonTapped;
//
// AppointmentFragment({Key? key, required this.onBackButtonTapped}) : super(key: key);
//
// GlobalKey<RefreshIndicatorState> refreshIndicatorKey = GlobalKey<RefreshIndicatorState>();
//
// Future<void> _pullRefresh(BuildContext context) async {
// await context.read<AppointmentsVM>().getMyAppointmentsForProvider({"ServiceProviderID": injector.get<AppState>().getUser.data?.userInfo?.providerId.toString() ?? "0"});
// }
//
// @override
// Widget build(BuildContext context) {
// date = DateHelper.formatAsDayMonthYear(DateTime.now());
// return Scaffold(
// appBar: CustomAppBar(
// //profileImageUrl: MyAssets.carBanner,
// title: LocaleKeys.appointments.tr(),
// onBackButtonTapped: onBackButtonTapped,
// actions: [
// IconButton(
// onPressed: () {},
// icon: const Icon(Icons.search),
// ),
// 10.width,
// ],
// ),
// body: SizedBox(
// width: double.infinity,
// height: double.infinity,
// child: Consumer(builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
// return RefreshIndicator(
// onRefresh: () => _pullRefresh(context),
// key: refreshIndicatorKey,
// child: SingleChildScrollView(
// physics: const AlwaysScrollableScrollPhysics(),
// child: Column(
// children: [
// progressWidget(context),
// FiltersList(
// filterList: appointmentsVM.appointmentsFilterOptions,
// padding: const EdgeInsets.symmetric(horizontal: 18),
// onFilterTapped: (index, selectedFilterId) {
// appointmentsVM.applyFilterOnAppointmentsVM(
// appointmentStatusEnum: selectedFilterId.toAppointmentStatusEnum(),
// );
// },
// ),
// ListView.separated(
// itemBuilder: (context, index) {
// return AppointmentSliderWidget(
// appointmentListModel: appointmentsVM.myFilteredAppointments2[index],
// isNeedTotalPayment: false,
// onTap: () {
// navigateWithName(
// context,
// ProviderAppRoutes.appointmentDetailList,
// arguments: appointmentsVM.myFilteredAppointments2[index].customerAppointmentList,
// );
// },
// );
// },
// separatorBuilder: (context, snapchat) {
// return 21.height;
// },
// itemCount: appointmentsVM.myFilteredAppointments2.length,
// physics: const NeverScrollableScrollPhysics(),
// shrinkWrap: true,
// padding: const EdgeInsets.all(21),
// ),
// ],
// ),
// ),
// );
// }),
// ),
// );
// }
//
// Widget progressWidget(BuildContext context) {
// return Column(
// children: [
// Row(
// children: [
// Expanded(
// child: "Slots Overview".toText(
// fontSize: 16,
// fontWeight: FontWeight.bold,
// ),
// ),
// Row(
// children: [
// date.toText(
// fontWeight: FontWeight.bold,
// ),
// const Icon(
// Icons.keyboard_arrow_down_outlined,
// size: 16,
// ),
// ],
// )
// .toContainer(
// backgroundColor: MyColors.lightGreyEAColor,
// borderRadius: 100,
// padding: const EdgeInsets.symmetric(
// horizontal: 12,
// vertical: 6,
// ),
// )
// .onPress(() async {
// date = await Utils.pickDateFromDatePicker(
// context,
// firstDate: null,
// );
// context.read<AppointmentsVM>().notifyListeners();
// }),
// ],
// ),
// 24.height,
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Row(
// children: [
// Container(
// width: 14,
// height: 14,
// color: MyColors.lightGreyEAColor,
// ),
// 4.width,
// "Empty: ".toText(
// fontSize: 8,
// color: Colors.white,
// ),
// "8".toText(
// fontSize: 9,
// fontWeight: FontWeight.bold,
// color: Colors.white,
// ),
// ],
// ).toContainer(
// backgroundColor: MyColors.darkIconColor,
// ),
// 8.height,
// Row(
// children: [
// Container(
// width: 14,
// height: 14,
// color: MyColors.darkPrimaryColor,
// ),
// 4.width,
// "Occupied: ".toText(
// fontSize: 8,
// color: Colors.white,
// ),
// "54".toText(
// fontSize: 9,
// fontWeight: FontWeight.bold,
// color: Colors.white,
// ),
// ],
// ).toContainer(
// backgroundColor: MyColors.darkIconColor,
// ),
// ],
// ),
// CircularPercentIndicator(
// radius: 60.0,
// lineWidth: 12.0,
// percent: 0.7,
// circularStrokeCap: CircularStrokeCap.round,
// center: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// "Total Slots".toText(
// fontSize: 13,
// fontWeight: FontWeight.bold,
// ),
// "24".toText(
// fontSize: 24,
// fontWeight: FontWeight.bold,
// ),
// ],
// ),
// backgroundColor: MyColors.lightGreyEAColor,
// progressColor: MyColors.darkPrimaryColor,
// ),
// ],
// )
// ],
// ).toWhiteContainer(
// width: double.infinity,
// pading: const EdgeInsets.all(12),
// margin: const EdgeInsets.all(21),
// );
// }
// }

@ -231,7 +231,7 @@ class GeneralAppointmentWidget extends StatelessWidget {
),
),
if (!isNeedTotalPayment)
if (appointmentListModel.customerAppointmentList!.length > 1)
if (appointmentListModel.customerAppointmentList != null && appointmentListModel.customerAppointmentList!.length > 1)
"${appointmentListModel.customerAppointmentList!.length - 1}+ Appointments".toText(fontSize: 8).toContainer(
borderRadius: 15,
backgroundColor: MyColors.lightGreyEAColor,

@ -15,7 +15,7 @@ import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class ServiceProviderWidget extends StatelessWidget {
const ServiceProviderWidget({Key? key}) : super(key: key);
const ServiceProviderWidget({super.key});
@override
Widget build(BuildContext context) {

@ -41,8 +41,8 @@ dependencies:
mc_common_app:
# path: D:\Development\car_common_app
path: /Users/aamir/StudioProjects/car_common_app
# path: /Users/faizhashmi/Development/Projects/MyProjects/CloudSolutions/car_common_app
path: /Volumes/Data/Projects/Flutter/car_common_app
# path: /Users/aamir/StudioProjects/car_common_app

Loading…
Cancel
Save