subscription 1.0

mirza_dev
Mirza.Shafique@cloudsolutions.com.sa 2 years ago
parent 9c190bd730
commit be15a74274

@ -29,10 +29,12 @@ import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/views/advertisement/ads_detail_view.dart'; import 'package:mc_common_app/views/advertisement/ads_detail_view.dart';
import 'package:mc_common_app/views/advertisement/create_ad_view.dart'; import 'package:mc_common_app/views/advertisement/create_ad_view.dart';
import 'package:mc_common_app/views/advertisement/select_ad_type_view.dart'; import 'package:mc_common_app/views/advertisement/select_ad_type_view.dart';
import 'package:mc_common_app/views/chat/chat_view.dart'; import 'package:mc_common_app/views/chat/chat_view.dart';
import 'package:mc_common_app/views/payments/payment_methods_view.dart';
import '../views/dashboard/dashboard_page.dart'; import '../views/dashboard/dashboard_page.dart';
@ -68,6 +70,10 @@ class ProviderAppRoutes {
static const String schedulesList = "/schedulesList"; static const String schedulesList = "/schedulesList";
static const String addSchedule = "/addSchedule"; static const String addSchedule = "/addSchedule";
// Subscriptions
static const String mySubscriptionsPage = "/mySubscriptionsPage";
static const String subscriptionsPage = "/subscriptionsPage";
//Bracnh Duplication //Bracnh Duplication
static const String matchServices = "/matchServices"; static const String matchServices = "/matchServices";
@ -109,8 +115,9 @@ class ProviderAppRoutes {
AppRoutes.sendOfferPage: (context) => const SendOfferPage(), AppRoutes.sendOfferPage: (context) => const SendOfferPage(),
//Subscriptions //Subscriptions
AppRoutes.mySubscriptionsPage: (context) => const MySubscriptionsPage(), mySubscriptionsPage: (context) => const MySubscriptionsPage(),
AppRoutes.subscriptionsPage: (context) => const SubscriptionsPage(), subscriptionsPage: (context) => const SubscriptionsPage(),
AppRoutes.paymentMethodsView: (context) => PaymentMethodsView(paymentType: ModalRoute.of(context)!.settings.arguments as PaymentTypes),
//Services //Services
dealerUser: (context) => dealerUser: (context) =>

@ -20,16 +20,19 @@ import 'package:mc_common_app/repositories/ads_repo.dart';
import 'package:mc_common_app/repositories/appointment_repo.dart'; import 'package:mc_common_app/repositories/appointment_repo.dart';
import 'package:mc_common_app/repositories/chat_repo.dart'; import 'package:mc_common_app/repositories/chat_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/repositories/payments_repo.dart';
import 'package:mc_common_app/repositories/provider_repo.dart'; import 'package:mc_common_app/repositories/provider_repo.dart';
import 'package:mc_common_app/repositories/request_repo.dart'; import 'package:mc_common_app/repositories/request_repo.dart';
import 'package:mc_common_app/repositories/user_repo.dart'; import 'package:mc_common_app/repositories/user_repo.dart';
import 'package:mc_common_app/services/common_services.dart'; import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/services/payments_service.dart';
import 'package:mc_common_app/theme/app_theme.dart'; import 'package:mc_common_app/theme/app_theme.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/view_models/base_view_model.dart'; import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart'; import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:mc_common_app/view_models/payment_view_model.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart'; import 'package:mc_common_app/view_models/requests_view_model.dart';
import 'package:mc_common_app/view_models/user_view_model.dart'; import 'package:mc_common_app/view_models/user_view_model.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
@ -73,7 +76,8 @@ Future<void> main() async {
), ),
), ),
ChangeNotifierProvider<SubscriptionsVM>( ChangeNotifierProvider<SubscriptionsVM>(
create: (_) => SubscriptionsVM(subscriptionRepo: injector.get<SubscriptionRepo>()), create: (_) =>
SubscriptionsVM(subscriptionRepo: injector.get<SubscriptionRepo>()),
), ),
ChangeNotifierProvider<ItemsVM>( ChangeNotifierProvider<ItemsVM>(
create: (_) => ItemsVM( create: (_) => ItemsVM(
@ -114,6 +118,11 @@ Future<void> main() async {
requestRepo: injector.get<RequestRepo>(), requestRepo: injector.get<RequestRepo>(),
), ),
), ),
ChangeNotifierProvider<PaymentVM>(
create: (_) => PaymentVM(
paymentService: injector.get<PaymentService>(),
paymentRepo: injector.get<PaymentsRepo>()),
),
], ],
child: const MyApp(), child: const MyApp(),
).setupLocale()); ).setupLocale());
@ -135,12 +144,19 @@ class MyApp extends StatelessWidget {
injector.get<AppState>().setAppType(AppType.provider); injector.get<AppState>().setAppType(AppType.provider);
AppState().setPostParamsModel( AppState().setPostParamsModel(
PostParamsModel( PostParamsModel(
languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2, languageID:
EasyLocalization.of(context)?.locale.languageCode == "ar"
? 1
: 2,
), ),
); );
ThemeData data = AppTheme.getTheme(isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar"); ThemeData data = AppTheme.getTheme(
isArabic:
EasyLocalization.of(context)?.locale.languageCode == "ar");
return MaterialApp( return MaterialApp(
theme: AppTheme.getTheme(isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar"), theme: AppTheme.getTheme(
isArabic:
EasyLocalization.of(context)?.locale.languageCode == "ar"),
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates, localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales, supportedLocales: context.supportedLocales,

@ -1,6 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:car_provider_app/repositories/items_repo.dart'; import 'package:car_provider_app/repositories/items_repo.dart';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/models/general_models/m_response.dart'; import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/services_models/item_model.dart'; import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/services/common_services.dart'; import 'package:mc_common_app/services/common_services.dart';
@ -20,8 +21,8 @@ class ItemsVM extends BaseVM {
//Items //Items
ItemModel? serviceItems; ItemModel? serviceItems;
Future<String?> selectFile() async { Future<String?> selectFile(BuildContext context) async {
File? file = await commonServices.pickFile(fileType: FileType.image); File? file = await commonServices.pickFile(context,fileType: FileType.image);
if (file != null) { if (file != null) {
int sizeInBytes = file.lengthSync(); int sizeInBytes = file.lengthSync();

@ -240,6 +240,7 @@ import 'dart:io';
import 'package:car_provider_app/repositories/branch_repo.dart'; import 'package:car_provider_app/repositories/branch_repo.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/models/general_models/m_response.dart'; import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
@ -297,8 +298,9 @@ class ServiceVM extends BaseVM {
setState(ViewState.idle); setState(ViewState.idle);
} }
Future<void> selectFile(int index) async { Future<void> selectFile(BuildContext context,int index) async {
final File? file = await commonServices.pickFile( final File? file = await commonServices.pickFile(
context,
fileType: FileType.custom, fileType: FileType.custom,
allowedExtensions: ['png', 'pdf', 'jpeg'], allowedExtensions: ['png', 'pdf', 'jpeg'],
); );
@ -348,12 +350,15 @@ class ServiceVM extends BaseVM {
Future<void> getAllCountriesList( Future<void> getAllCountriesList(
BranchDetailModel? branchData, String countryCode) async { BranchDetailModel? branchData, String countryCode) async {
cities = null;
country = null;
setState(ViewState.busy); setState(ViewState.busy);
resetValues(); resetValues();
country = await commonRepo.getAllCountries(); country = await commonRepo.getAllCountries();
country!.data?.forEach((element) { country!.data?.forEach((element) {
if (branchData != null && branchData.id != null) { if (branchData != null && branchData.id != null) {
if (element.id == branchData.countryID) { if (element.id == branchData.countryID) {
countryId = element.id ?? -1;
countryValue = DropValue( countryValue = DropValue(
element.id ?? 0, element.id ?? 0,
countryCode == "SA" countryCode == "SA"
@ -382,10 +387,10 @@ class ServiceVM extends BaseVM {
Future<void> getAllCities( Future<void> getAllCities(
BranchDetailModel? branchData, String countryCode) async { BranchDetailModel? branchData, String countryCode) async {
setState(ViewState.busy); setState(ViewState.busy);
citiesDropList=[]; citiesDropList = [];
cities = null; cities = null;
cityId = -1; cityId = -1;
cityValue=null; cityValue = null;
cities = await commonRepo.getAllCites(countryId.toString()); cities = await commonRepo.getAllCites(countryId.toString());
cities!.data?.forEach((element) { cities!.data?.forEach((element) {
if (branchData != null && branchData.id != null) { if (branchData != null && branchData.id != null) {
@ -512,7 +517,7 @@ class ServiceVM extends BaseVM {
Future<void> fetchProviderServices(String branchID, String categoryId) async { Future<void> fetchProviderServices(String branchID, String categoryId) async {
servicesDropList = []; servicesDropList = [];
services=null; services = null;
setState(ViewState.busy); setState(ViewState.busy);
services = await branchRepo.fetchProviderServices(branchID, categoryId); services = await branchRepo.fetchProviderServices(branchID, categoryId);

@ -55,16 +55,16 @@ class _DashboardPageState extends State<DashboardPage> {
context.read<ServiceVM>().getBranchAndServices(); context.read<ServiceVM>().getBranchAndServices();
AdVM adVm = Provider.of<AdVM>(context, listen: false); AdVM adVm = Provider.of<AdVM>(context, listen: false);
AppointmentsVM appointmentsVM = AppointmentsVM appointmentsVM =
Provider.of<AppointmentsVM>(context, listen: false); Provider.of<AppointmentsVM>(context, listen: false);
if (appointmentsVM.myAppointments.isEmpty) { if (appointmentsVM.myAppointments.isEmpty) {
await appointmentsVM.getProviderMyAppointments({ await appointmentsVM.getProviderMyAppointments({
"ServiceProviderID": injector "ServiceProviderID": injector
.get<AppState>() .get<AppState>()
.getUser .getUser
.data .data
?.userInfo ?.userInfo
?.providerId ?.providerId
.toString() ?? .toString() ??
"0" "0"
}); });
} }
@ -75,7 +75,8 @@ class _DashboardPageState extends State<DashboardPage> {
if (adVm.exploreAds.isEmpty) { if (adVm.exploreAds.isEmpty) {
await adVm.getExploreAds(); await adVm.getExploreAds();
} if (adVm.vehicleTypes.isEmpty) { }
if (adVm.vehicleTypes.isEmpty) {
await adVm.getVehicleTypes(); await adVm.getVehicleTypes();
} }
@ -88,7 +89,6 @@ class _DashboardPageState extends State<DashboardPage> {
} }
// await chatVM.buildHubConnection(context); // await chatVM.buildHubConnection(context);
} }
@override @override
@ -98,11 +98,17 @@ class _DashboardPageState extends State<DashboardPage> {
onBackButtonTapped: () { onBackButtonTapped: () {
dashboardVM.updateIndex(2); dashboardVM.updateIndex(2);
}, },
onRefresh: () async {
context.read<ServiceVM>().getBranchAndServices();
},
), ),
BranchAppointmentFragment( BranchAppointmentFragment(
onBackButtonTapped: () { onBackButtonTapped: () {
dashboardVM.updateIndex(2); dashboardVM.updateIndex(2);
}, },
onRefresh: () async {
context.read<ServiceVM>().getBranchAndServices();
},
), ),
HomeFragment( HomeFragment(
onTap: () { onTap: () {
@ -120,7 +126,11 @@ class _DashboardPageState extends State<DashboardPage> {
dashboardVM.updateIndex(2); dashboardVM.updateIndex(2);
}, },
), ),
const MyRequestsFragment(), MyRequestsFragment(
onBackButtonTapped: () {
dashboardVM.updateIndex(2);
},
),
]; ];
return Scaffold( return Scaffold(

@ -24,10 +24,14 @@ import 'package:flutter_svg/flutter_svg.dart';
class BranchAppointmentFragment extends StatelessWidget { class BranchAppointmentFragment extends StatelessWidget {
bool isNeedAppBar; bool isNeedAppBar;
VoidCallback onBackButtonTapped; VoidCallback onBackButtonTapped;
RefreshCallback onRefresh;
BranchAppointmentFragment( BranchAppointmentFragment({
{Key? key, this.isNeedAppBar = true, required this.onBackButtonTapped}) Key? key,
: super(key: key); this.isNeedAppBar = true,
required this.onBackButtonTapped,
required this.onRefresh,
}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -71,93 +75,96 @@ class BranchAppointmentFragment extends StatelessWidget {
model.selectedBranchStatus == element.statusId) model.selectedBranchStatus == element.statusId)
.toList(); .toList();
} }
return branches.isEmpty return RefreshIndicator(
? Center(child: Text(LocaleKeys.no_branch.tr())) onRefresh: onRefresh,
: ListView.separated( child: branches.isEmpty
itemBuilder: (context, index) { ? Center(child: Text(LocaleKeys.no_branch.tr()))
return Row( : ListView.separated(
children: [ itemBuilder: (context, index) {
Container( return Row(
width: 74, children: [
height: 50, Container(
decoration: const BoxDecoration( width: 74,
color: MyColors.darkPrimaryColor, height: 50,
borderRadius: decoration: const BoxDecoration(
BorderRadius.all(Radius.circular(8)), color: MyColors.darkPrimaryColor,
borderRadius:
BorderRadius.all(Radius.circular(8)),
),
padding: const EdgeInsets.all(6),
child: SvgPicture.asset(
MyAssets.icBranches,
color: Colors.white,
),
), ),
padding: const EdgeInsets.all(6), 12.width,
child: SvgPicture.asset( Expanded(
MyAssets.icBranches, child: Column(
color: Colors.white, crossAxisAlignment:
), CrossAxisAlignment.start,
), mainAxisAlignment:
12.width, MainAxisAlignment.start,
Expanded( children: [
child: Column( Row(
crossAxisAlignment: children: [
CrossAxisAlignment.start, const Icon(
mainAxisAlignment: Icons.place,
MainAxisAlignment.start, size: 12,
children: [ color: MyColors.darkPrimaryColor,
Row( ),
children: [ Geolocator.distanceBetween(
const Icon( AppState()
Icons.place, .currentLocation
size: 12, .latitude,
color: MyColors.darkPrimaryColor, 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,
), ),
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 view".toText(
"Tap to view".toText( fontSize: 10,
fontSize: 10, color: MyColors.grey70Color),
color: MyColors.grey70Color), ],
], ),
), ),
), 12.width,
12.width, ],
], ).toContainer().onPress(() async {
).toContainer().onPress(() async { branches[index].countryID =
branches[index].countryID = model.branches!.data!.countryID;
model.branches!.data!.countryID; branches[index].countryName =
branches[index].countryName = model.branches!.data!.countryName;
model.branches!.data!.countryName; navigateWithName(
navigateWithName( context, ProviderAppRoutes.appointment,
context, ProviderAppRoutes.appointment, arguments: branches[index]);
arguments: branches[index]); });
}); },
}, separatorBuilder: (context, index) {
separatorBuilder: (context, index) { return 12.height;
return 12.height; },
}, itemCount: branches.length,
itemCount: branches.length, padding: const EdgeInsets.all(12),
padding: const EdgeInsets.all(12), ),
); );
} }
}, },
), ),

@ -64,97 +64,95 @@ class HomeFragment extends StatelessWidget {
height: double.infinity, height: double.infinity,
child: RefreshIndicator( child: RefreshIndicator(
onRefresh: onRefresh, onRefresh: onRefresh,
child: SingleChildScrollView( child: ListView(
child: Column( children: [
children: [ ViewAllWidget(
ViewAllWidget( title: 'Upcoming Appointment',
title: 'Upcoming Appointment', subTitle: 'View All',
subTitle: 'View All', onSubtitleTapped: () {},
onSubtitleTapped: () {}, ).horPaddingMain(),
).horPaddingMain(), // const AppointmentSliderWidget().horPaddingMain(),
// const AppointmentSliderWidget().horPaddingMain(), CustomerAppointmentSliderWidget(
CustomerAppointmentSliderWidget( myUpComingAppointments:
myUpComingAppointments: context.read<AppointmentsVM>().myUpComingAppointments,
context.read<AppointmentsVM>().myUpComingAppointments, isNeedToShowEmptyMessage: true,
isNeedToShowEmptyMessage: true, onAppointmentClick: () {
onAppointmentClick: (){ // navigateWithName(
// navigateWithName( // context, ProviderAppRoutes.appointment,
// context, ProviderAppRoutes.appointment, // arguments: branches[index]);
// arguments: branches[index]); },
}, ),
), 21.height,
21.height, ViewAllWidget(
ViewAllWidget( title: 'My Branches',
title: 'My Branches', subTitle: 'View All',
subTitle: 'View All', onSubtitleTapped: () {},
onSubtitleTapped: () {}, ).horPaddingMain(),
).horPaddingMain(), const ServiceProviderWidget().horPaddingMain(),
const ServiceProviderWidget().horPaddingMain(), Consumer(
Consumer( builder: (BuildContext context, AdVM adVM, Widget? child) {
builder: (BuildContext context, AdVM adVM, Widget? child) { if (adVM.state == ViewState.busy) {
if (adVM.state == ViewState.busy) { return const Center(child: CircularProgressIndicator());
return const Center(child: CircularProgressIndicator()); } else {
} else { return Column(
return Column( children: [
children: [ if (adVM.myActiveAdsForHome.isNotEmpty) ...[
if (adVM.myActiveAdsForHome.isNotEmpty) ...[ Column(
Column( children: [
children: [ 15.height,
15.height, ViewAllWidget(
ViewAllWidget( title: "My Active Ads",
title: "My Active Ads", subTitle: "View All",
subTitle: "View All", onSubtitleTapped: () {
onSubtitleTapped: () { // context.read<DashboardVM>().onNavbarTapped(3);
// context.read<DashboardVM>().onNavbarTapped(3); // context.read<AdVM>().updateIsExploreAds(false);
// context.read<AdVM>().updateIsExploreAds(false); },
}, ).horPaddingMain(),
).horPaddingMain(), BuildAdsList(
BuildAdsList( shouldShowAdStatus: true,
shouldShowAdStatus: true, isAdsFragment: false,
isAdsFragment: false, adsList: adVM.myActiveAdsForHome,
adsList: adVM.myActiveAdsForHome, scrollPhysics:
scrollPhysics: const NeverScrollableScrollPhysics(),
const NeverScrollableScrollPhysics(), ),
), ],
], )
)
],
if (adVM.exploreAds.isNotEmpty) ...[
Column(
children: [
15.height,
ViewAllWidget(
title: "My Recommended Ads",
subTitle: "View All",
onSubtitleTapped: () {
// context.read<DashboardVM>().onNavbarTapped(3);
// context.read<AdVM>().updateIsExploreAds(true);
// context.read<AdVM>().applyFilterOnExploreAds(index: 0);
},
).horPaddingMain(),
BuildAdsList(
shouldShowAdStatus: false,
adsList: adVM.exploreAds.length >= 3
? adVM.exploreAds.take(3).toList()
: adVM.exploreAds,
isAdsFragment: false,
scrollPhysics:
const NeverScrollableScrollPhysics(),
),
],
)
]
], ],
); if (adVM.exploreAds.isNotEmpty) ...[
} Column(
}, children: [
), 15.height,
21.height, ViewAllWidget(
// const AdWidget( title: "My Recommended Ads",
// count: 4, subTitle: "View All",
// ), onSubtitleTapped: () {
], // context.read<DashboardVM>().onNavbarTapped(3);
), // context.read<AdVM>().updateIsExploreAds(true);
// context.read<AdVM>().applyFilterOnExploreAds(index: 0);
},
).horPaddingMain(),
BuildAdsList(
shouldShowAdStatus: false,
adsList: adVM.exploreAds.length >= 3
? adVM.exploreAds.take(3).toList()
: adVM.exploreAds,
isAdsFragment: false,
scrollPhysics:
const NeverScrollableScrollPhysics(),
),
],
)
]
],
);
}
},
),
21.height,
// const AdWidget(
// count: 4,
// ),
],
), ),
), ),
), ),

@ -15,49 +15,65 @@ import 'package:easy_localization/easy_localization.dart';
class MyRequestsFragment extends StatelessWidget { class MyRequestsFragment extends StatelessWidget {
final bool isNeedAppBar; final bool isNeedAppBar;
VoidCallback onBackButtonTapped;
const MyRequestsFragment({super.key, this.isNeedAppBar = true}); MyRequestsFragment(
{super.key, this.isNeedAppBar = true, required this.onBackButtonTapped});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: !isNeedAppBar ? null : CustomAppBar(title: LocaleKeys.myServiceBranches.tr()), appBar: !isNeedAppBar
? null
: CustomAppBar(
title: LocaleKeys.myServiceBranches.tr(),
onBackButtonTapped: onBackButtonTapped,
),
body: Container( body: Container(
color: MyColors.backgroundColor, color: MyColors.backgroundColor,
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
child: Consumer(builder: (BuildContext context, RequestsVM requestsVM, Widget? child) { child: Consumer(builder:
(BuildContext context, RequestsVM requestsVM, Widget? child) {
return Column( return Column(
children: [ children: [
16.height, 16.height,
FiltersList( FiltersList(
filterList: requestsVM.requestsTypeFilterOptions, filterList: requestsVM.requestsTypeFilterOptions,
onFilterTapped: (index, selectedFilterId) { onFilterTapped: (index, selectedFilterId) {
requestsVM.applyFilterOnRequestsVM(requestsTypeEnum: selectedFilterId.toRequestTypeStatusEnum()); requestsVM.applyFilterOnRequestsVM(
requestsTypeEnum:
selectedFilterId.toRequestTypeStatusEnum());
}, },
), ),
8.height, 8.height,
Expanded( Expanded(
child: RefreshIndicator( child: RefreshIndicator(
onRefresh: () async => await requestsVM.getRequests(isNeedToRebuild: true, appType: AppType.provider), onRefresh: () async => await requestsVM.getRequests(
isNeedToRebuild: true, appType: AppType.provider),
child: requestsVM.state == ViewState.busy child: requestsVM.state == ViewState.busy
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: requestsVM.myFilteredRequests.isEmpty : requestsVM.myFilteredRequests.isEmpty
? Column( ? Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
"No Requests to show.".toText(fontSize: 16, color: MyColors.lightTextColor), "No Requests to show.".toText(
fontSize: 16, color: MyColors.lightTextColor),
], ],
) )
: ListView.separated( : ListView.separated(
itemBuilder: (context, index) { itemBuilder: (context, index) {
return RequestItem(request: requestsVM.myFilteredRequests[index], appType: AppType.provider, requestIndex: index); return RequestItem(
request: requestsVM.myFilteredRequests[index],
appType: AppType.provider,
requestIndex: index);
}, },
separatorBuilder: (context, index) { separatorBuilder: (context, index) {
return 16.height; return 16.height;
}, },
itemCount: requestsVM.myFilteredRequests.length, itemCount: requestsVM.myFilteredRequests.length,
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16, top: 8), padding: const EdgeInsets.only(
left: 16, right: 16, bottom: 16, top: 8),
), ),
)) ))
], ],

@ -35,8 +35,14 @@ class _CustomDrawerState extends State<CustomDrawer> {
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
content: const Text("Choose image source"), content: const Text("Choose image source"),
actions: [ actions: [
TextButton(child: const Text("Camera"), onPressed: () => widget.dashboardVM.pickImageFromPhone(context, 0)), TextButton(
TextButton(child: const Text("Gallery"), onPressed: () => widget.dashboardVM.pickImageFromPhone(context, 1)), child: const Text("Camera"),
onPressed: () =>
widget.dashboardVM.pickImageFromPhone(context, 0)),
TextButton(
child: const Text("Gallery"),
onPressed: () =>
widget.dashboardVM.pickImageFromPhone(context, 1)),
], ],
), ),
); );
@ -54,7 +60,13 @@ class _CustomDrawerState extends State<CustomDrawer> {
height: 200, height: 200,
color: MyColors.darkPrimaryColor.withOpacity(0.01), color: MyColors.darkPrimaryColor.withOpacity(0.01),
child: Image.network( child: Image.network(
ApiConsts.baseUrlServices + AppState().getUser.data!.userInfo!.userImageUrl.toString(), ApiConsts.baseUrlServices +
AppState()
.getUser
.data!
.userInfo!
.userImageUrl
.toString(),
), ),
), ),
Positioned( Positioned(
@ -94,11 +106,16 @@ class _CustomDrawerState extends State<CustomDrawer> {
color: Colors.red, color: Colors.red,
).onPress(() async { ).onPress(() async {
Utils.showLoading(context); Utils.showLoading(context);
ImageResponse response = await widget.dashboardVM.updateUserImage(""); ImageResponse response =
await widget.dashboardVM.updateUserImage("");
if (response.messageStatus == 1) { if (response.messageStatus == 1) {
Utils.showToast("Image is Deleted"); Utils.showToast("Image is Deleted");
setState(() { setState(() {
AppState().getUser.data!.userInfo!.userImageUrl = response.data; AppState()
.getUser
.data!
.userInfo!
.userImageUrl = response.data;
}); });
} }
Utils.hideLoading(context); Utils.hideLoading(context);
@ -127,7 +144,12 @@ class _CustomDrawerState extends State<CustomDrawer> {
fontSize: 20, fontSize: 20,
letterSpacing: -1.44, letterSpacing: -1.44,
), ),
AppState().getUser.data!.userInfo!.roleName!.toText(fontSize: 10), AppState()
.getUser
.data!
.userInfo!
.roleName!
.toText(fontSize: 10),
], ],
), ),
), ),
@ -144,12 +166,21 @@ class _CustomDrawerState extends State<CustomDrawer> {
), ),
), ),
ListTile( ListTile(
leading: SvgPicture.asset(MyAssets.nextIcon, color: MyColors.darkPrimaryColor), leading: SvgPicture.asset(MyAssets.nextIcon,
color: MyColors.darkPrimaryColor),
title: LocaleKeys.defineLicences.tr().toText(fontSize: 12), title: LocaleKeys.defineLicences.tr().toText(fontSize: 12),
onTap: () { onTap: () {
navigateWithName(context, ProviderAppRoutes.defineLicense); navigateWithName(context, ProviderAppRoutes.defineLicense);
}, },
), ),
ListTile(
leading: SvgPicture.asset(MyAssets.nextIcon,
color: MyColors.darkPrimaryColor),
title: "Subscriptions".toText(fontSize: 12),
onTap: () {
navigateWithName(context, ProviderAppRoutes.mySubscriptionsPage);
},
),
ListTile( ListTile(
leading: Image.asset( leading: Image.asset(
MyAssets.icWorldPng, MyAssets.icWorldPng,
@ -159,7 +190,8 @@ class _CustomDrawerState extends State<CustomDrawer> {
), ),
title: LocaleKeys.english.tr().toText(fontSize: 12), title: LocaleKeys.english.tr().toText(fontSize: 12),
onTap: () { onTap: () {
if (EasyLocalization.of(context)?.currentLocale?.countryCode == "SA") { if (EasyLocalization.of(context)?.currentLocale?.countryCode ==
"SA") {
context.setLocale(const Locale("en", "US")); context.setLocale(const Locale("en", "US"));
} else { } else {
context.setLocale(const Locale('ar', 'SA')); context.setLocale(const Locale('ar', 'SA'));

@ -9,7 +9,7 @@ import 'package:car_provider_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/utils/navigator.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/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:geocoding/geocoding.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'map_selection_widget.dart'; import 'map_selection_widget.dart';

@ -76,11 +76,14 @@ class BranchDetailPage extends StatelessWidget {
Row( Row(
children: [ children: [
Expanded( Expanded(
child: titleWidget(MyAssets.icBranches, LocaleKeys.branchInfo.tr()), child: titleWidget(MyAssets.icBranches,
LocaleKeys.branchInfo.tr()),
), ),
IconButton( IconButton(
onPressed: () { onPressed: () {
navigateWithName(context, ProviderAppRoutes.defineBranch, arguments: branchData); navigateWithName(
context, ProviderAppRoutes.defineBranch,
arguments: branchData);
}, },
icon: SvgPicture.asset(MyAssets.icEdit), icon: SvgPicture.asset(MyAssets.icEdit),
) )
@ -88,11 +91,17 @@ class BranchDetailPage extends StatelessWidget {
), ),
Column( Column(
children: [ children: [
showData("${LocaleKeys.country.tr()}:", "branchData.countryName".toString()), showData("${LocaleKeys.country.tr()}:",
showData("${LocaleKeys.city.tr()}:", "branchData.cityName".toString()), branchData.countryName.toString()),
showData("${LocaleKeys.branchName.tr()}:", branchData.branchName.toString()), showData("${LocaleKeys.city.tr()}:",
showData("${LocaleKeys.branchDescription.tr()}:", branchData.branchDescription.toString()), branchData.cityName.toString()),
showData("${LocaleKeys.address.tr()}:", branchData.address.toString()), showData("${LocaleKeys.branchName.tr()}:",
branchData.branchName.toString()),
showData(
"${LocaleKeys.branchDescription.tr()}:",
branchData.branchDescription.toString()),
showData("${LocaleKeys.address.tr()}:",
branchData.address.toString()),
], ],
), ),
], ],
@ -101,7 +110,8 @@ class BranchDetailPage extends StatelessWidget {
Container( Container(
width: double.infinity, width: double.infinity,
color: MyColors.darkIconColor, color: MyColors.darkIconColor,
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 8),
child: Row( child: Row(
children: [ children: [
const Icon( const Icon(
@ -125,7 +135,9 @@ class BranchDetailPage extends StatelessWidget {
], ],
), ),
).onPress(() { ).onPress(() {
navigateWithName(context, ProviderAppRoutes.schedulesList, arguments: branchData.id.toString()); navigateWithName(
context, ProviderAppRoutes.schedulesList,
arguments: branchData.id.toString());
}), }),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
@ -152,7 +164,8 @@ class BranchDetailPage extends StatelessWidget {
backgroundColor: MyColors.darkWhiteColor, backgroundColor: MyColors.darkWhiteColor,
width: double.infinity, width: double.infinity,
paddingAll: 20, paddingAll: 20,
margin: const EdgeInsets.only(left: 20, right: 20, top: 20), margin:
const EdgeInsets.only(left: 20, right: 20, top: 20),
) )
.onPress(() { .onPress(() {
navigateWithName( navigateWithName(
@ -170,12 +183,17 @@ class BranchDetailPage extends StatelessWidget {
itemBuilder: (context, pIndex) { itemBuilder: (context, pIndex) {
return InkWell( return InkWell(
onTap: () { onTap: () {
categories[pIndex].branchId = branchData.id.toString(); categories[pIndex].branchId =
categories[pIndex].branchName = branchData.branchName.toString(); branchData.id.toString();
navigateWithName(context, ProviderAppRoutes.servicesList, arguments: categories[pIndex]); categories[pIndex].branchName =
branchData.branchName.toString();
navigateWithName(
context, ProviderAppRoutes.servicesList,
arguments: categories[pIndex]);
}, },
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Padding( Padding(
@ -189,12 +207,19 @@ class BranchDetailPage extends StatelessWidget {
8.width, 8.width,
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment:
mainAxisAlignment: MainAxisAlignment.start, CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [ children: [
Row( Row(
children: [ children: [
categories[pIndex].categoryName.toString().toText(fontSize: 16, isBold: true), categories[pIndex]
.categoryName
.toString()
.toText(
fontSize: 16,
isBold: true),
// Padding( // Padding(
// padding: const EdgeInsets.all(4.0), // padding: const EdgeInsets.all(4.0),
// child: SvgPicture.asset( // child: SvgPicture.asset(
@ -204,26 +229,46 @@ class BranchDetailPage extends StatelessWidget {
// ), // ),
// ), // ),
], ],
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment:
MainAxisAlignment.spaceBetween,
), ),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: ListView.builder( child: ListView.builder(
itemBuilder: (context, index) { itemBuilder:
(context, index) {
return Container( return Container(
child: (EasyLocalization.of(context)?.currentLocale?.countryCode == "SA" child: (EasyLocalization.of(
? categories[pIndex].services![index].serviceDescriptionN.toString() context)
: categories[pIndex].services![index].serviceDescription.toString()) ?.currentLocale
?.countryCode ==
"SA"
? categories[
pIndex]
.services![
index]
.serviceDescriptionN
.toString()
: categories[
pIndex]
.services![
index]
.serviceDescription
.toString())
.toText( .toText(
fontSize: 12, fontSize: 12,
color: MyColors.lightTextColor, color: MyColors
.lightTextColor,
isBold: true, isBold: true,
), ),
); );
}, },
itemCount: categories[pIndex].services?.length, itemCount: categories[pIndex]
physics: const NeverScrollableScrollPhysics(), .services
?.length,
physics:
const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
), ),
@ -236,15 +281,18 @@ class BranchDetailPage extends StatelessWidget {
), ),
), ),
], ],
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment:
crossAxisAlignment: CrossAxisAlignment.end, MainAxisAlignment.end,
crossAxisAlignment:
CrossAxisAlignment.end,
) )
], ],
)), )),
], ],
).toContainer( ).toContainer(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 8),
isShadowEnabled: true, isShadowEnabled: true,
), ),
); );
@ -253,7 +301,8 @@ class BranchDetailPage extends StatelessWidget {
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
separatorBuilder: (BuildContext context, int index) { separatorBuilder:
(BuildContext context, int index) {
return 12.height; return 12.height;
}, },
), ),
@ -278,7 +327,8 @@ class BranchDetailPage extends StatelessWidget {
txtColor: MyColors.darkPrimaryColor, txtColor: MyColors.darkPrimaryColor,
isFilled: false, isFilled: false,
onPressed: () { onPressed: () {
navigateWithName(context, ProviderAppRoutes.dealerUser, arguments: branchData.id.toString()); navigateWithName(context, ProviderAppRoutes.dealerUser,
arguments: branchData.id.toString());
}, },
), ),
), ),

@ -27,8 +27,14 @@ import 'package:provider/provider.dart';
class BranchListPage extends StatelessWidget { class BranchListPage extends StatelessWidget {
bool isNeedAppBar; bool isNeedAppBar;
VoidCallback onBackButtonTapped; VoidCallback onBackButtonTapped;
RefreshCallback onRefresh;
BranchListPage({Key? key, this.isNeedAppBar = true, required this.onBackButtonTapped}) : super(key: key); BranchListPage(
{Key? key,
this.isNeedAppBar = true,
required this.onRefresh,
required this.onBackButtonTapped})
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -56,7 +62,9 @@ class BranchListPage extends StatelessWidget {
Padding( Padding(
padding: const EdgeInsets.only(left: 21, right: 21, top: 21), padding: const EdgeInsets.only(left: 21, right: 21, top: 21),
child: RoleTypeTab( child: RoleTypeTab(
context.watch<ServiceVM>().selectedBranchStatus == 3 ? 0 : context.watch<ServiceVM>().selectedBranchStatus, context.watch<ServiceVM>().selectedBranchStatus == 3
? 0
: context.watch<ServiceVM>().selectedBranchStatus,
[ [
DropValue(3, "Active", ""), DropValue(3, "Active", ""),
DropValue(1, "Requested", ""), DropValue(1, "Requested", ""),
@ -74,95 +82,130 @@ class BranchListPage extends StatelessWidget {
} else { } else {
List<BranchDetailModel> branches = []; List<BranchDetailModel> branches = [];
if (model.branches!.data != null) { if (model.branches!.data != null) {
branches = model.branches!.data!.serviceProviderBranch!.where((element) => model.selectedBranchStatus == element.statusId).toList(); branches = model.branches!.data!.serviceProviderBranch!
.where((element) =>
model.selectedBranchStatus == element.statusId)
.toList();
} }
return branches.isEmpty return RefreshIndicator(
? Center(child: Text(LocaleKeys.no_branch.tr())) onRefresh: onRefresh,
: ListView.separated( child: branches.isEmpty
itemBuilder: (context, index) { ? Center(child: Text(LocaleKeys.no_branch.tr()))
return Row( : ListView.separated(
children: [ itemBuilder: (context, index) {
Container( return Row(
width: 74, children: [
height: 50, Container(
decoration: const BoxDecoration( width: 74,
color: MyColors.darkPrimaryColor, height: 50,
borderRadius: BorderRadius.all(Radius.circular(8)), 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,
),
), ),
padding: const EdgeInsets.all(6), 12.width,
child: SvgPicture.asset( Expanded(
MyAssets.icBranches, child: Column(
color: Colors.white, crossAxisAlignment:
), CrossAxisAlignment.start,
), mainAxisAlignment:
12.width, MainAxisAlignment.start,
Expanded( children: [
child: Column( Row(
crossAxisAlignment: CrossAxisAlignment.start, children: [
mainAxisAlignment: MainAxisAlignment.start, const Icon(
children: [ Icons.place,
Row( size: 12,
children: [ color: MyColors.darkPrimaryColor,
const Icon( ),
Icons.place, Geolocator.distanceBetween(
size: 12, AppState()
color: MyColors.darkPrimaryColor, .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,
), ),
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,
), ),
), LocaleKeys.tapToEdit.tr().toText(
LocaleKeys.tapToEdit.tr().toText(fontSize: 10, color: MyColors.grey70Color), fontSize: 10,
], color: MyColors.grey70Color),
],
),
),
12.width,
IconButton(
onPressed: () async {
Utils.showLoading(context);
MResponse res = await model.updateBranch(
branches[index].id ?? 0,
branches[index].branchName ?? "",
branches[index].branchDescription ??
"",
branches[index].cityId.toString(),
branches[index].address ?? "",
branches[index].latitude.toString(),
branches[index].longitude.toString(),
isNeedToDelete: false);
Utils.hideLoading(context);
if (res.messageStatus == 1) {
Utils.showToast(
LocaleKeys.branch_deleted.tr());
model.setState(ViewState.idle);
} else {
Utils.showToast(res.message ?? "");
}
},
icon: const Icon(Icons.delete),
color: Colors.red,
),
const Icon(
Icons.arrow_forward_rounded,
size: 16,
), ),
), ],
12.width, ).toContainer().onPress(() async {
IconButton( branches[index].countryID =
onPressed: () async { model.branches!.data!.countryID;
Utils.showLoading(context); branches[index].countryName =
MResponse res = await model.updateBranch(branches[index].id ?? 0, branches[index].branchName ?? "", branches[index].branchDescription ?? "", model.branches!.data!.countryName;
branches[index].cityId.toString(), branches[index].address ?? "", branches[index].latitude.toString(), branches[index].longitude.toString(), navigateWithName(
isNeedToDelete: false); context, ProviderAppRoutes.branchDetail,
Utils.hideLoading(context); arguments: branches[index]);
if (res.messageStatus == 1) { });
Utils.showToast(LocaleKeys.branch_deleted.tr()); },
model.setState(ViewState.idle); separatorBuilder: (context, index) {
} else { return 12.height;
Utils.showToast(res.message ?? ""); },
} itemCount: branches.length,
}, padding: const EdgeInsets.all(12),
icon: const Icon(Icons.delete), ),
color: Colors.red, );
),
const Icon(
Icons.arrow_forward_rounded,
size: 16,
),
],
).toContainer().onPress(() async {
branches[index].countryID = model.branches!.data!.countryID;
branches[index].countryName = model.branches!.data!.countryName;
navigateWithName(context, ProviderAppRoutes.branchDetail, arguments: branches[index]);
});
},
separatorBuilder: (context, index) {
return 12.height;
},
itemCount: branches.length,
padding: const EdgeInsets.all(12),
);
} }
}, },
), ),

@ -62,6 +62,7 @@ class DefineBranchPage extends StatelessWidget {
?.countryCode ?? ?.countryCode ??
"SA"); "SA");
}, },
isSelectAble: branchData == null ? true : false,
list: model.countryDropList, list: model.countryDropList,
dropdownValue: model.countryValue, dropdownValue: model.countryValue,
hint: "${LocaleKeys.chooseCountry.tr()}*", hint: "${LocaleKeys.chooseCountry.tr()}*",
@ -122,7 +123,7 @@ class DefineBranchPage extends StatelessWidget {
PickLocationPage( PickLocationPage(
onPickAddress: (double latitude, onPickAddress: (double latitude,
double longitude, String address) { double longitude, String address) {
print("tesssgngl "+address); print("tesssgngl " + address);
model.latitude = latitude; model.latitude = latitude;
model.longitude = longitude; model.longitude = longitude;
model.address = address; model.address = address;

@ -8,7 +8,8 @@ import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/general_models/m_response.dart'; import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/AppPermissionHandler.dart'; import 'package:mc_common_app/utils/app_permission_handler.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
@ -144,7 +145,7 @@ class _DefineLicensePageState extends State<DefineLicensePage> {
InkWell( InkWell(
onTap: () async { onTap: () async {
bool isPermissionsAvailable = await requestPermissionGranted(context, Permission.storage); bool isPermissionsAvailable = await requestPermissionGranted(context, Permission.storage);
if (isPermissionsAvailable) model.selectFile(index); if (isPermissionsAvailable) model.selectFile(context,index);
}, },
child: Container( child: Container(
width: double.infinity, width: double.infinity,

@ -334,12 +334,13 @@ class AddSchedulesPage extends StatelessWidget {
context.read<ScheduleVM>().getSchedules(scheduleData.branchId ?? ""); context.read<ScheduleVM>().getSchedules(scheduleData.branchId ?? "");
pop(context); pop(context);
} else { } else {
Utils.showToast( Utils.showToast(servicesResponse.message ?? "");
"Something went wrong while adding services in schedule"); context.read<ScheduleVM>().getSchedules(scheduleData.branchId ?? "");
pop(context);
} }
} else { } else {
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.showToast("Something went wrong"); Utils.showToast(scheduleResponse.message??"");
} }
} }

@ -7,7 +7,7 @@ import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/general_models/m_response.dart'; import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/services_models/item_model.dart'; import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/AppPermissionHandler.dart'; import 'package:mc_common_app/utils/app_permission_handler.dart';
import 'package:mc_common_app/utils/date_helper.dart'; import 'package:mc_common_app/utils/date_helper.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
@ -130,7 +130,7 @@ class _CreateItemPageState extends State<CreateItemPage> {
onTap: () async { onTap: () async {
bool isPermissionsAvailable = await requestPermissionGranted(context, Permission.storage); bool isPermissionsAvailable = await requestPermissionGranted(context, Permission.storage);
if (isPermissionsAvailable && model != null) { if (isPermissionsAvailable && model != null) {
itemImage = await model!.selectFile() ?? ""; itemImage = await model!.selectFile(context) ?? "";
setState(() {}); setState(() {});
} }
}, },

@ -1,11 +1,19 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/view_models/subscriptions_view_model.dart'; import 'package:car_provider_app/view_models/subscriptions_view_model.dart';
import 'package:car_provider_app/views/subscriptions/sheet/select_package_sheet.dart';
import 'package:car_provider_app/views/subscriptions/widget/subscriptions_card.dart'; import 'package:car_provider_app/views/subscriptions/widget/subscriptions_card.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/payment_view_model.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/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class MySubscriptionsPage extends StatelessWidget { class MySubscriptionsPage extends StatelessWidget {
@ -13,7 +21,8 @@ class MySubscriptionsPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
context.read<SubscriptionsVM>().getMySubscriptions(AppState().getUser.data?.userInfo?.providerId.toString() ?? ""); context.read<SubscriptionsVM>().getMySubscriptions(
AppState().getUser.data?.userInfo?.providerId.toString() ?? "");
return Scaffold( return Scaffold(
appBar: const CustomAppBar( appBar: const CustomAppBar(
title: "My Subscriptions", title: "My Subscriptions",
@ -21,33 +30,70 @@ class MySubscriptionsPage extends StatelessWidget {
body: SizedBox( body: SizedBox(
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
child: Consumer<SubscriptionsVM>(builder: (context, model, _) { child: Column(
return model.state == ViewState.busy children: [
? const Center(child: CircularProgressIndicator()) Expanded(
: SingleChildScrollView( child: Consumer<SubscriptionsVM>(builder: (context, model, _) {
child: Column( return model.state == ViewState.busy
children: [ ? const Center(child: CircularProgressIndicator())
21.height, : SingleChildScrollView(
ListView.separated( child: Column(
itemBuilder: (BuildContext context, int index) { children: [
return SubscriptionsCard( 21.height,
model.allSubscriptions.data![index], ListView.separated(
isSubscribed: model.allSubscriptions.data![index].isSubscribed ?? false, itemBuilder: (BuildContext context, int index) {
backgroundColor: MyColors.darkIconColor, return SubscriptionsCard(
); model.allSubscriptions.data![index],
}, isSubscribed: model.allSubscriptions
separatorBuilder: (BuildContext context, int index) { .data![index].isSubscribed ??
return 21.height; false,
}, backgroundColor: MyColors.darkIconColor,
physics: const NeverScrollableScrollPhysics(), onRenewSubscriptionClick: () {
shrinkWrap: true, context
itemCount: model.allSubscriptions.data!.length, .read<PaymentVM>()
), .updateOrderProviderSubscriptionId(
21.height, id: model.allSubscriptions
], .data![index].id ??
), 0);
); navigateWithName(
}), context,
AppRoutes.paymentMethodsView,
arguments: PaymentTypes.subscription,
);
},
).onPress(
() {
showMyBottomSheet(context,
child: const SelectPackageSheet());
},
);
},
separatorBuilder:
(BuildContext context, int index) {
return 21.height;
},
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: model.allSubscriptions.data!.length,
),
21.height,
],
),
);
}),
),
21.height,
ShowFillButton(
title: "Modify Package",
maxWidth: double.infinity,
margin: const EdgeInsets.symmetric(horizontal: 21),
onPressed: () {
navigateWithName(context, ProviderAppRoutes.subscriptionsPage);
},
),
21.height,
],
),
), ),
); );
} }

@ -1,10 +1,13 @@
import 'package:car_provider_app/view_models/subscriptions_view_model.dart'; import 'package:car_provider_app/view_models/subscriptions_view_model.dart';
import 'package:car_provider_app/views/subscriptions/widget/subscriptions_card.dart'; import 'package:car_provider_app/views/subscriptions/widget/subscriptions_card.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/models/subscriptions_models/subscription_model.dart'; import 'package:mc_common_app/models/subscriptions_models/subscription_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/payment_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; 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/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/tab/menu_tabs.dart'; import 'package:mc_common_app/widgets/tab/menu_tabs.dart';
@ -47,6 +50,14 @@ class SubscriptionsPage extends StatelessWidget {
return SubscriptionsCard( return SubscriptionsCard(
model.tempSubscriptions[index], model.tempSubscriptions[index],
isSubscribed: model.tempSubscriptions[index].isSubscribed ?? false, isSubscribed: model.tempSubscriptions[index].isSubscribed ?? false,
onRenewSubscriptionClick: () {
context.read<PaymentVM>().updateOrderProviderSubscriptionId(id: model.tempSubscriptions[index].id??0);
navigateWithName(
context,
AppRoutes.paymentMethodsView,
arguments: PaymentTypes.subscription,
);
},
); );
}, },
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (BuildContext context, int index) {

@ -1,4 +1,3 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
@ -7,123 +6,142 @@ import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/date_helper.dart'; import 'package:mc_common_app/utils/date_helper.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class SubscriptionsCard extends StatelessWidget { class SubscriptionsCard extends StatelessWidget {
Subscription subscription; Subscription subscription;
bool isSubscribed; bool isSubscribed;
Color? backgroundColor; Color? backgroundColor;
late Color textColor; late Color textColor;
Function onRenewSubscriptionClick;
SubscriptionsCard(this.subscription, {Key? key, this.isSubscribed = false, this.backgroundColor}) : super(key: key); SubscriptionsCard(this.subscription,
{Key? key,
this.isSubscribed = false,
this.backgroundColor,
required this.onRenewSubscriptionClick})
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
textColor = backgroundColor == null ? Colors.black : Colors.white; textColor = backgroundColor == null ? Colors.black : Colors.white;
return Column( return InkWell(
crossAxisAlignment: CrossAxisAlignment.start, onTap: isSubscribed
children: [ ? null
Row( : () {
children: [ onRenewSubscriptionClick();
Expanded( },
child: subscription.name.toString().toText( child: Column(
fontSize: 18, crossAxisAlignment: CrossAxisAlignment.start,
color: textColor, children: [
), Row(
), children: [
if (isSubscribed) Expanded(
Row( child: subscription.name.toString().toText(
children: [ fontSize: 18,
Container( color: textColor,
color: MyColors.white,
padding: const EdgeInsets.all(2),
child: const Icon(
Icons.done,
size: 8,
color: MyColors.primaryColor,
), ),
).toCircle(
borderRadius: 122,
),
6.width,
"Subscribed".toText(color: Colors.white, isBold: true)
],
).toContainer(
backgroundColor: MyColors.primaryColor,
borderRadius: 20,
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 3,
),
)
],
),
6.height,
showItem("Ads:", subscription.numberOfAds.toString()),
showItem("Users:", subscription.numberOfSubUsers.toString()),
showItem("Branches:", subscription.numberOfBranches.toString()),
14.height,
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
subscription.price.toString().toText(
fontSize: 26,
isBold: true,
color: textColor,
),
2.width,
"${subscription.currency}/Month".toText(
color: MyColors.lightTextColor,
fontSize: 16,
),
],
), ),
), if (isSubscribed)
if (!isSubscribed) Row(
Row( children: [
children: [ Container(
"Upgrade".toText( color: MyColors.white,
fontSize: 14, padding: const EdgeInsets.all(2),
color: textColor, child: const Icon(
Icons.done,
size: 8,
color: MyColors.primaryColor,
),
).toCircle(
borderRadius: 122,
),
6.width,
"Subscribed".toText(color: Colors.white, isBold: true)
],
).toContainer(
backgroundColor: MyColors.primaryColor,
borderRadius: 20,
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 3,
), ),
4.width, )
Icon( ],
Icons.arrow_forward, ),
size: 16, 6.height,
color: textColor, showItem("Ads:", subscription.numberOfAds.toString()),
) showItem("Users:", subscription.numberOfSubUsers.toString()),
], showItem("Branches:", subscription.numberOfBranches.toString()),
) 14.height,
],
),
if (isSubscribed)
Row( Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
"Expires on ${DateHelper.formatAsDayMonthYear(subscription.dateEnd)}".toText( Expanded(
fontSize: 14, child: Row(
color: textColor, mainAxisAlignment: MainAxisAlignment.start,
), crossAxisAlignment: CrossAxisAlignment.end,
6.width, children: [
"Renew".toText( subscription.price.toString().toText(
color: MyColors.primaryColor, fontSize: 26,
fontSize: 14, isBold: true,
textDecoration: TextDecoration.underline, color: textColor,
isBold: true, ),
2.width,
"${subscription.currency}/Month".toText(
color: MyColors.lightTextColor,
fontSize: 16,
),
],
),
), ),
if (!isSubscribed)
Row(
children: [
"Upgrade".toText(
fontSize: 14,
color: textColor,
),
4.width,
Icon(
Icons.arrow_forward,
size: 16,
color: textColor,
)
],
)
], ],
) ),
], if (isSubscribed)
).toWhiteContainer( Row(
width: double.infinity, children: [
allPading: 12, "Expires on ${DateHelper.formatAsDayMonthYear(subscription.dateEnd)}"
backgroundColor: backgroundColor, .toText(
margin: const EdgeInsets.symmetric( fontSize: 14,
horizontal: 21, color: textColor,
),
Row(
children: [
6.width,
"Renew".toText(
color: MyColors.primaryColor,
fontSize: 14,
textDecoration: TextDecoration.underline,
isBold: true,
),
],
).onPress(() {
onRenewSubscriptionClick();
}),
],
)
],
).toWhiteContainer(
width: double.infinity,
allPading: 12,
backgroundColor: backgroundColor,
margin: const EdgeInsets.symmetric(
horizontal: 21,
),
), ),
); );
} }

@ -129,6 +129,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.5" version: "1.0.5"
device_info_plus:
dependency: transitive
description:
name: device_info_plus
sha256: "77f757b789ff68e4eaf9c56d1752309bd9f7ad557cb105b938a7f8eb89e59110"
url: "https://pub.dev"
source: hosted
version: "9.1.2"
device_info_plus_platform_interface:
dependency: transitive
description:
name: device_info_plus_platform_interface
sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64
url: "https://pub.dev"
source: hosted
version: "7.0.0"
dropdown_button2: dropdown_button2:
dependency: transitive dependency: transitive
description: description:
@ -173,10 +189,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: ffi name: ffi
sha256: "13a6ccf6a459a125b3fcdb6ec73bd5ff90822e071207c663bfd1f70062d51d18" sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "2.1.0"
file: file:
dependency: transitive dependency: transitive
description: description:
@ -189,10 +205,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: file_picker name: file_picker
sha256: "704259669b5e9cb24e15c11cfcf02caf5f20d30901b3916d60b6d1c2d647035f" sha256: "4e42aacde3b993c5947467ab640882c56947d9d27342a5b6f2895b23956954a6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.6.1" version: "6.1.1"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -273,34 +289,34 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: geocoding name: geocoding
sha256: e1dc0ac56666d9ed1d5a9ae5543ce9eb5986db6209cc7600103487d09192059c sha256: "06d053a67733d1b9b4267259713913bc2aa750f18b830f0869ff337a8cfa8325"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.2.0"
geocoding_android: geocoding_android:
dependency: transitive dependency: transitive
description: description:
name: geocoding_android name: geocoding_android
sha256: "609db1d71bc364dd9d0616f72a41c01e0c74f3a3807efb85e0d5a67e57baf50f" sha256: "287a2009cb2c3d3dd2899ba8f3d3e38d9e06905ea429283859bfc3586d4f57fd"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "3.2.0"
geocoding_ios: geocoding_ios:
dependency: transitive dependency: transitive
description: description:
name: geocoding_ios name: geocoding_ios
sha256: "8f79e380abb640ef4d88baee8bb65390058c802601158d0813dc990b36b189d2" sha256: "8a39bfb650af55209c42e564036a550b32d029e0733af01dc66c5afea50388d3"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.3.0"
geocoding_platform_interface: geocoding_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: geocoding_platform_interface name: geocoding_platform_interface
sha256: "8848605d307d844d89937cdb4b8ad7dfa880552078f310fa24d8a460f6dddab4" sha256: "8c2c8226e5c276594c2e18bfe88b19110ed770aeb7c1ab50ede570be8b92229b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.1" version: "3.2.0"
geolocator: geolocator:
dependency: transitive dependency: transitive
description: description:
@ -648,10 +664,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: path_provider_windows name: path_provider_windows
sha256: a34ecd7fb548f8e57321fd8e50d865d266941b54e6c3b7758cf8f37c24116905 sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.7" version: "2.1.7"
pedantic: pedantic:
dependency: transitive dependency: transitive
description: description:
@ -1069,10 +1085,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
sha256: c0e3a4f7be7dae51d8f152230b86627e3397c1ba8c3fa58e63d44a9f3edc9cef sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
url: "https://pub.dev"
source: hosted
version: "5.2.0"
win32_registry:
dependency: transitive
description:
name: win32_registry
sha256: "41fd8a189940d8696b1b810efb9abcf60827b6cbfab90b0c43e8439e3a39d85a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.6.1" version: "1.1.2"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
@ -1090,5 +1114,5 @@ packages:
source: hosted source: hosted
version: "6.1.0" version: "6.1.0"
sdks: sdks:
dart: ">=3.2.0-194.0.dev <4.0.0" dart: ">=3.2.0 <4.0.0"
flutter: ">=3.10.0" flutter: ">=3.10.0"

@ -34,6 +34,7 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
# mc_common_app: # mc_common_app:
## git: https://gitlab.com/mirza.shafique/car_common_app.git ## git: https://gitlab.com/mirza.shafique/car_common_app.git
# path: C:/Users/mirza.shafique/AndroidStudioProjects/mc_common_app # path: C:/Users/mirza.shafique/AndroidStudioProjects/mc_common_app

Loading…
Cancel
Save