Compare commits

...

2 Commits

Author SHA1 Message Date
Mirza.Shafique@cloudsolutions.com.sa ed2a1eedc6 subscription 2.0 2 years ago
Mirza.Shafique@cloudsolutions.com.sa be15a74274 subscription 1.0 2 years ago

@ -29,10 +29,12 @@ import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:flutter/material.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/utils/enums.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/select_ad_type_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';
@ -68,6 +70,10 @@ class ProviderAppRoutes {
static const String schedulesList = "/schedulesList";
static const String addSchedule = "/addSchedule";
// Subscriptions
static const String mySubscriptionsPage = "/mySubscriptionsPage";
static const String subscriptionsPage = "/subscriptionsPage";
//Bracnh Duplication
static const String matchServices = "/matchServices";
@ -109,8 +115,9 @@ class ProviderAppRoutes {
AppRoutes.sendOfferPage: (context) => const SendOfferPage(),
//Subscriptions
AppRoutes.mySubscriptionsPage: (context) => const MySubscriptionsPage(),
AppRoutes.subscriptionsPage: (context) => const SubscriptionsPage(),
mySubscriptionsPage: (context) => const MySubscriptionsPage(),
subscriptionsPage: (context) => const SubscriptionsPage(),
AppRoutes.paymentMethodsView: (context) => PaymentMethodsView(paymentType: ModalRoute.of(context)!.settings.arguments as PaymentTypes),
//Services
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/chat_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/request_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/payments_service.dart';
import 'package:mc_common_app/theme/app_theme.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/appointments_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/payment_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/widgets/extensions/extensions_widget.dart';
@ -73,7 +76,8 @@ Future<void> main() async {
),
),
ChangeNotifierProvider<SubscriptionsVM>(
create: (_) => SubscriptionsVM(subscriptionRepo: injector.get<SubscriptionRepo>()),
create: (_) =>
SubscriptionsVM(subscriptionRepo: injector.get<SubscriptionRepo>()),
),
ChangeNotifierProvider<ItemsVM>(
create: (_) => ItemsVM(
@ -114,6 +118,11 @@ Future<void> main() async {
requestRepo: injector.get<RequestRepo>(),
),
),
ChangeNotifierProvider<PaymentVM>(
create: (_) => PaymentVM(
paymentService: injector.get<PaymentService>(),
paymentRepo: injector.get<PaymentsRepo>()),
),
],
child: const MyApp(),
).setupLocale());
@ -135,12 +144,19 @@ class MyApp extends StatelessWidget {
injector.get<AppState>().setAppType(AppType.provider);
AppState().setPostParamsModel(
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(
theme: AppTheme.getTheme(isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar"),
theme: AppTheme.getTheme(
isArabic:
EasyLocalization.of(context)?.locale.languageCode == "ar"),
debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,

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

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

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

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

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

@ -15,49 +15,65 @@ import 'package:easy_localization/easy_localization.dart';
class MyRequestsFragment extends StatelessWidget {
final bool isNeedAppBar;
VoidCallback onBackButtonTapped;
const MyRequestsFragment({super.key, this.isNeedAppBar = true});
MyRequestsFragment(
{super.key, this.isNeedAppBar = true, required this.onBackButtonTapped});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: !isNeedAppBar ? null : CustomAppBar(title: LocaleKeys.myServiceBranches.tr()),
appBar: !isNeedAppBar
? null
: CustomAppBar(
title: LocaleKeys.myServiceBranches.tr(),
onBackButtonTapped: onBackButtonTapped,
),
body: Container(
color: MyColors.backgroundColor,
width: 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(
children: [
16.height,
FiltersList(
filterList: requestsVM.requestsTypeFilterOptions,
onFilterTapped: (index, selectedFilterId) {
requestsVM.applyFilterOnRequestsVM(requestsTypeEnum: selectedFilterId.toRequestTypeStatusEnum());
requestsVM.applyFilterOnRequestsVM(
requestsTypeEnum:
selectedFilterId.toRequestTypeStatusEnum());
},
),
8.height,
Expanded(
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
? const Center(child: CircularProgressIndicator())
: requestsVM.myFilteredRequests.isEmpty
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
"No Requests to show.".toText(fontSize: 16, color: MyColors.lightTextColor),
"No Requests to show.".toText(
fontSize: 16, color: MyColors.lightTextColor),
],
)
: ListView.separated(
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) {
return 16.height;
},
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(
content: const Text("Choose image source"),
actions: [
TextButton(child: const Text("Camera"), onPressed: () => widget.dashboardVM.pickImageFromPhone(context, 0)),
TextButton(child: const Text("Gallery"), onPressed: () => widget.dashboardVM.pickImageFromPhone(context, 1)),
TextButton(
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,
color: MyColors.darkPrimaryColor.withOpacity(0.01),
child: Image.network(
ApiConsts.baseUrlServices + AppState().getUser.data!.userInfo!.userImageUrl.toString(),
ApiConsts.baseUrlServices +
AppState()
.getUser
.data!
.userInfo!
.userImageUrl
.toString(),
),
),
Positioned(
@ -94,11 +106,16 @@ class _CustomDrawerState extends State<CustomDrawer> {
color: Colors.red,
).onPress(() async {
Utils.showLoading(context);
ImageResponse response = await widget.dashboardVM.updateUserImage("");
ImageResponse response =
await widget.dashboardVM.updateUserImage("");
if (response.messageStatus == 1) {
Utils.showToast("Image is Deleted");
setState(() {
AppState().getUser.data!.userInfo!.userImageUrl = response.data;
AppState()
.getUser
.data!
.userInfo!
.userImageUrl = response.data;
});
}
Utils.hideLoading(context);
@ -127,7 +144,12 @@ class _CustomDrawerState extends State<CustomDrawer> {
fontSize: 20,
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(
leading: SvgPicture.asset(MyAssets.nextIcon, color: MyColors.darkPrimaryColor),
leading: SvgPicture.asset(MyAssets.nextIcon,
color: MyColors.darkPrimaryColor),
title: LocaleKeys.defineLicences.tr().toText(fontSize: 12),
onTap: () {
navigateWithName(context, ProviderAppRoutes.defineLicense);
},
),
ListTile(
leading: SvgPicture.asset(MyAssets.nextIcon,
color: MyColors.darkPrimaryColor),
title: "Subscriptions".toText(fontSize: 12),
onTap: () {
navigateWithName(context, ProviderAppRoutes.mySubscriptionsPage);
},
),
ListTile(
leading: Image.asset(
MyAssets.icWorldPng,
@ -159,7 +190,8 @@ class _CustomDrawerState extends State<CustomDrawer> {
),
title: LocaleKeys.english.tr().toText(fontSize: 12),
onTap: () {
if (EasyLocalization.of(context)?.currentLocale?.countryCode == "SA") {
if (EasyLocalization.of(context)?.currentLocale?.countryCode ==
"SA") {
context.setLocale(const Locale("en", "US"));
} else {
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/widgets/button/show_fill_button.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 'map_selection_widget.dart';

@ -76,11 +76,14 @@ class BranchDetailPage extends StatelessWidget {
Row(
children: [
Expanded(
child: titleWidget(MyAssets.icBranches, LocaleKeys.branchInfo.tr()),
child: titleWidget(MyAssets.icBranches,
LocaleKeys.branchInfo.tr()),
),
IconButton(
onPressed: () {
navigateWithName(context, ProviderAppRoutes.defineBranch, arguments: branchData);
navigateWithName(
context, ProviderAppRoutes.defineBranch,
arguments: branchData);
},
icon: SvgPicture.asset(MyAssets.icEdit),
)
@ -88,11 +91,17 @@ class BranchDetailPage extends StatelessWidget {
),
Column(
children: [
showData("${LocaleKeys.country.tr()}:", "branchData.countryName".toString()),
showData("${LocaleKeys.city.tr()}:", "branchData.cityName".toString()),
showData("${LocaleKeys.branchName.tr()}:", branchData.branchName.toString()),
showData("${LocaleKeys.branchDescription.tr()}:", branchData.branchDescription.toString()),
showData("${LocaleKeys.address.tr()}:", branchData.address.toString()),
showData("${LocaleKeys.country.tr()}:",
branchData.countryName.toString()),
showData("${LocaleKeys.city.tr()}:",
branchData.cityName.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(
width: double.infinity,
color: MyColors.darkIconColor,
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 8),
child: Row(
children: [
const Icon(
@ -125,7 +135,9 @@ class BranchDetailPage extends StatelessWidget {
],
),
).onPress(() {
navigateWithName(context, ProviderAppRoutes.schedulesList, arguments: branchData.id.toString());
navigateWithName(
context, ProviderAppRoutes.schedulesList,
arguments: branchData.id.toString());
}),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
@ -152,7 +164,8 @@ class BranchDetailPage extends StatelessWidget {
backgroundColor: MyColors.darkWhiteColor,
width: double.infinity,
paddingAll: 20,
margin: const EdgeInsets.only(left: 20, right: 20, top: 20),
margin:
const EdgeInsets.only(left: 20, right: 20, top: 20),
)
.onPress(() {
navigateWithName(
@ -170,12 +183,17 @@ class BranchDetailPage extends StatelessWidget {
itemBuilder: (context, pIndex) {
return InkWell(
onTap: () {
categories[pIndex].branchId = branchData.id.toString();
categories[pIndex].branchName = branchData.branchName.toString();
navigateWithName(context, ProviderAppRoutes.servicesList, arguments: categories[pIndex]);
categories[pIndex].branchId =
branchData.id.toString();
categories[pIndex].branchName =
branchData.branchName.toString();
navigateWithName(
context, ProviderAppRoutes.servicesList,
arguments: categories[pIndex]);
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
@ -189,12 +207,19 @@ class BranchDetailPage extends StatelessWidget {
8.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Row(
children: [
categories[pIndex].categoryName.toString().toText(fontSize: 16, isBold: true),
categories[pIndex]
.categoryName
.toString()
.toText(
fontSize: 16,
isBold: true),
// Padding(
// padding: const EdgeInsets.all(4.0),
// child: SvgPicture.asset(
@ -204,26 +229,46 @@ class BranchDetailPage extends StatelessWidget {
// ),
// ),
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
),
Row(
children: [
Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
itemBuilder:
(context, index) {
return Container(
child: (EasyLocalization.of(context)?.currentLocale?.countryCode == "SA"
? categories[pIndex].services![index].serviceDescriptionN.toString()
: categories[pIndex].services![index].serviceDescription.toString())
child: (EasyLocalization.of(
context)
?.currentLocale
?.countryCode ==
"SA"
? categories[
pIndex]
.services![
index]
.serviceDescriptionN
.toString()
: categories[
pIndex]
.services![
index]
.serviceDescription
.toString())
.toText(
fontSize: 12,
color: MyColors.lightTextColor,
color: MyColors
.lightTextColor,
isBold: true,
),
);
},
itemCount: categories[pIndex].services?.length,
physics: const NeverScrollableScrollPhysics(),
itemCount: categories[pIndex]
.services
?.length,
physics:
const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
),
@ -236,15 +281,18 @@ class BranchDetailPage extends StatelessWidget {
),
),
],
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment:
MainAxisAlignment.end,
crossAxisAlignment:
CrossAxisAlignment.end,
)
],
)),
],
).toContainer(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 8),
isShadowEnabled: true,
),
);
@ -253,7 +301,8 @@ class BranchDetailPage extends StatelessWidget {
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(20),
separatorBuilder: (BuildContext context, int index) {
separatorBuilder:
(BuildContext context, int index) {
return 12.height;
},
),
@ -278,7 +327,8 @@ class BranchDetailPage extends StatelessWidget {
txtColor: MyColors.darkPrimaryColor,
isFilled: false,
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 {
bool isNeedAppBar;
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
Widget build(BuildContext context) {
@ -56,7 +62,9 @@ class BranchListPage extends StatelessWidget {
Padding(
padding: const EdgeInsets.only(left: 21, right: 21, top: 21),
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(1, "Requested", ""),
@ -74,95 +82,130 @@ class BranchListPage extends StatelessWidget {
} else {
List<BranchDetailModel> branches = [];
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
? Center(child: Text(LocaleKeys.no_branch.tr()))
: ListView.separated(
itemBuilder: (context, index) {
return Row(
children: [
Container(
width: 74,
height: 50,
decoration: const BoxDecoration(
color: MyColors.darkPrimaryColor,
borderRadius: BorderRadius.all(Radius.circular(8)),
return RefreshIndicator(
onRefresh: onRefresh,
child: branches.isEmpty
? Center(child: Text(LocaleKeys.no_branch.tr()))
: ListView.separated(
itemBuilder: (context, index) {
return Row(
children: [
Container(
width: 74,
height: 50,
decoration: const BoxDecoration(
color: MyColors.darkPrimaryColor,
borderRadius:
BorderRadius.all(Radius.circular(8)),
),
padding: const EdgeInsets.all(6),
child: SvgPicture.asset(
MyAssets.icBranches,
color: Colors.white,
),
),
padding: const EdgeInsets.all(6),
child: SvgPicture.asset(
MyAssets.icBranches,
color: Colors.white,
),
),
12.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
const Icon(
Icons.place,
size: 12,
color: MyColors.darkPrimaryColor,
12.width,
Expanded(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Row(
children: [
const Icon(
Icons.place,
size: 12,
color: MyColors.darkPrimaryColor,
),
Geolocator.distanceBetween(
AppState()
.currentLocation
.latitude,
AppState()
.currentLocation
.latitude,
double.parse(branches[index]
.latitude ??
"0"),
double.parse(branches[index]
.longitude ??
"0"))
.toStringAsFixed(2)
.toText(
fontSize: 12,
color:
MyColors.darkPrimaryColor,
)
],
),
Text(
branches[index].branchName ?? "",
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
),
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(fontSize: 10, color: MyColors.grey70Color),
],
LocaleKeys.tapToEdit.tr().toText(
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,
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,
),
],
).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),
);
],
).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 ??
"SA");
},
isSelectAble: branchData == null ? true : false,
list: model.countryDropList,
dropdownValue: model.countryValue,
hint: "${LocaleKeys.chooseCountry.tr()}*",
@ -122,7 +123,7 @@ class DefineBranchPage extends StatelessWidget {
PickLocationPage(
onPickAddress: (double latitude,
double longitude, String address) {
print("tesssgngl "+address);
print("tesssgngl " + address);
model.latitude = latitude;
model.longitude = longitude;
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/models/general_models/m_response.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/utils.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
@ -144,7 +145,7 @@ class _DefineLicensePageState extends State<DefineLicensePage> {
InkWell(
onTap: () async {
bool isPermissionsAvailable = await requestPermissionGranted(context, Permission.storage);
if (isPermissionsAvailable) model.selectFile(index);
if (isPermissionsAvailable) model.selectFile(context,index);
},
child: Container(
width: double.infinity,

@ -334,12 +334,13 @@ class AddSchedulesPage extends StatelessWidget {
context.read<ScheduleVM>().getSchedules(scheduleData.branchId ?? "");
pop(context);
} else {
Utils.showToast(
"Something went wrong while adding services in schedule");
Utils.showToast(servicesResponse.message ?? "");
context.read<ScheduleVM>().getSchedules(scheduleData.branchId ?? "");
pop(context);
}
} else {
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/services_models/item_model.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/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
@ -130,7 +130,7 @@ class _CreateItemPageState extends State<CreateItemPage> {
onTap: () async {
bool isPermissionsAvailable = await requestPermissionGranted(context, Permission.storage);
if (isPermissionsAvailable && model != null) {
itemImage = await model!.selectFile() ?? "";
itemImage = await model!.selectFile(context) ?? "";
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/views/subscriptions/sheet/select_package_sheet.dart';
import 'package:car_provider_app/views/subscriptions/widget/subscriptions_card.dart';
import 'package:flutter/material.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/theme/colors.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/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class MySubscriptionsPage extends StatelessWidget {
@ -13,7 +21,8 @@ class MySubscriptionsPage extends StatelessWidget {
@override
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(
appBar: const CustomAppBar(
title: "My Subscriptions",
@ -21,33 +30,70 @@ class MySubscriptionsPage extends StatelessWidget {
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Consumer<SubscriptionsVM>(builder: (context, model, _) {
return model.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: Column(
children: [
21.height,
ListView.separated(
itemBuilder: (BuildContext context, int index) {
return SubscriptionsCard(
model.allSubscriptions.data![index],
isSubscribed: model.allSubscriptions.data![index].isSubscribed ?? false,
backgroundColor: MyColors.darkIconColor,
);
},
separatorBuilder: (BuildContext context, int index) {
return 21.height;
},
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: model.allSubscriptions.data!.length,
),
21.height,
],
),
);
}),
child: Column(
children: [
Expanded(
child: Consumer<SubscriptionsVM>(builder: (context, model, _) {
return model.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: Column(
children: [
21.height,
ListView.separated(
itemBuilder: (BuildContext context, int index) {
return SubscriptionsCard(
model.allSubscriptions.data![index],
isSubscribed: model.allSubscriptions
.data![index].isSubscribed ??
false,
backgroundColor: MyColors.darkIconColor,
onRenewSubscriptionClick: () {
context
.read<PaymentVM>()
.updateOrderProviderSubscriptionId(
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,
],
),
),
);
}

@ -0,0 +1,122 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class DegradePackageSheet extends StatelessWidget {
const DegradePackageSheet({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"Deactivate the branches & users".toText(
fontSize: 18,
isBold: true,
),
"To select this subscription you need to deactivate your branches and users as this package only supports 1 branch and 2 users per branch. You can reactivate these branches later after upgrading the package"
.toText(
fontSize: 14,
color: MyColors.lightTextColor,
),
12.height,
showBranchList(),
12.height,
],
),
);
}
Widget showBranchList() {
return ListView.separated(
itemBuilder: (context, index) {
return Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
customCheckBox(true),
12.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Olaya Branch".toText(
fontSize: 16,
isBold: true,
),
"3 Users".toText(
fontSize: 10,
color: MyColors.lightTextColor,
),
],
),
),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.keyboard_arrow_down,
),
)
],
),
showUser("Mirza"),
12.height,
showUser("Shafique"),
],
).toContainer(
isShadowEnabled: true,
borderRadius: 0,
paddingAll: 12,
);
},
separatorBuilder: (context, index) {
return 12.height;
},
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: 2,
);
}
Widget showUser(String user) {
return Row(
children: [
const SizedBox(
width: 24,
),
customCheckBox(false),
12.width,
user.toText(fontSize: 14),
],
);
}
Widget customCheckBox(bool isChecked) {
return SizedBox(
height: 18,
width: 18,
child: isChecked
? const Icon(
Icons.done,
color: Colors.white,
size: 14,
)
: const SizedBox(),
).toContainer(
isEnabledBorder: true,
paddingAll: 0,
borderRadius: 0,
borderWidget: 1,
borderColor: MyColors.primaryColor,
backgroundColor: isChecked ? MyColors.primaryColor : Colors.transparent,
);
}
}

@ -0,0 +1,89 @@
import 'package:car_provider_app/views/subscriptions/sheet/degrage_package_sheet.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/bottom_sheet.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class SelectPackageSheet extends StatelessWidget {
const SelectPackageSheet({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"When do you want to upgrade".toText(
fontSize: 19,
isBold: true,
),
12.height,
showPackage(),
12.height,
showPackage(),
12.height,
ShowFillButton(
title: "Upgrade",
maxWidth: double.infinity,
onPressed: () {
showMyBottomSheet(context, child: const DegradePackageSheet());
},
),
12.height,
],
),
);
}
Widget showPackage() {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Checkbox(
value: false,
onChanged: (v) {},
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"Now".toText(
fontSize: 16,
isBold: true,
),
"Your subscription will upgrade now. Affecting from 23 January, 2024"
.toText(
fontSize: 12,
color: MyColors.lightTextColor,
),
12.height,
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"175".toText(
fontSize: 26,
isBold: true,
),
2.width,
"SAR".toText(
color: MyColors.lightTextColor,
fontSize: 16,
),
],
)
],
),
)
],
).toContainer(isShadowEnabled: true);
}
}

@ -1,10 +1,13 @@
import 'package:car_provider_app/view_models/subscriptions_view_model.dart';
import 'package:car_provider_app/views/subscriptions/widget/subscriptions_card.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/models/subscriptions_models/subscription_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/payment_view_model.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/tab/menu_tabs.dart';
@ -47,6 +50,14 @@ class SubscriptionsPage extends StatelessWidget {
return SubscriptionsCard(
model.tempSubscriptions[index],
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) {

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_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/widgets/extensions/extensions_widget.dart';
class SubscriptionsCard extends StatelessWidget {
Subscription subscription;
bool isSubscribed;
Color? backgroundColor;
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
Widget build(BuildContext context) {
textColor = backgroundColor == null ? Colors.black : Colors.white;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: subscription.name.toString().toText(
fontSize: 18,
color: textColor,
),
),
if (isSubscribed)
Row(
children: [
Container(
color: MyColors.white,
padding: const EdgeInsets.all(2),
child: const Icon(
Icons.done,
size: 8,
color: MyColors.primaryColor,
return InkWell(
onTap: isSubscribed
? null
: () {
onRenewSubscriptionClick();
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: subscription.name.toString().toText(
fontSize: 18,
color: textColor,
),
).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)
Row(
children: [
"Upgrade".toText(
fontSize: 14,
color: textColor,
if (isSubscribed)
Row(
children: [
Container(
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,
),
4.width,
Icon(
Icons.arrow_forward,
size: 16,
color: textColor,
)
],
)
],
),
if (isSubscribed)
)
],
),
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: [
"Expires on ${DateHelper.formatAsDayMonthYear(subscription.dateEnd)}".toText(
fontSize: 14,
color: textColor,
),
6.width,
"Renew".toText(
color: MyColors.primaryColor,
fontSize: 14,
textDecoration: TextDecoration.underline,
isBold: true,
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)
Row(
children: [
"Upgrade".toText(
fontSize: 14,
color: textColor,
),
4.width,
Icon(
Icons.arrow_forward,
size: 16,
color: textColor,
)
],
)
],
)
],
).toWhiteContainer(
width: double.infinity,
allPading: 12,
backgroundColor: backgroundColor,
margin: const EdgeInsets.symmetric(
horizontal: 21,
),
if (isSubscribed)
Row(
children: [
"Expires on ${DateHelper.formatAsDayMonthYear(subscription.dateEnd)}"
.toText(
fontSize: 14,
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"
source: hosted
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:
dependency: transitive
description:
@ -173,10 +189,10 @@ packages:
dependency: transitive
description:
name: ffi
sha256: "13a6ccf6a459a125b3fcdb6ec73bd5ff90822e071207c663bfd1f70062d51d18"
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "2.1.0"
file:
dependency: transitive
description:
@ -189,10 +205,10 @@ packages:
dependency: transitive
description:
name: file_picker
sha256: "704259669b5e9cb24e15c11cfcf02caf5f20d30901b3916d60b6d1c2d647035f"
sha256: "4e42aacde3b993c5947467ab640882c56947d9d27342a5b6f2895b23956954a6"
url: "https://pub.dev"
source: hosted
version: "4.6.1"
version: "6.1.1"
flutter:
dependency: "direct main"
description: flutter
@ -273,34 +289,34 @@ packages:
dependency: transitive
description:
name: geocoding
sha256: e1dc0ac56666d9ed1d5a9ae5543ce9eb5986db6209cc7600103487d09192059c
sha256: "06d053a67733d1b9b4267259713913bc2aa750f18b830f0869ff337a8cfa8325"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.2.0"
geocoding_android:
dependency: transitive
description:
name: geocoding_android
sha256: "609db1d71bc364dd9d0616f72a41c01e0c74f3a3807efb85e0d5a67e57baf50f"
sha256: "287a2009cb2c3d3dd2899ba8f3d3e38d9e06905ea429283859bfc3586d4f57fd"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "3.2.0"
geocoding_ios:
dependency: transitive
description:
name: geocoding_ios
sha256: "8f79e380abb640ef4d88baee8bb65390058c802601158d0813dc990b36b189d2"
sha256: "8a39bfb650af55209c42e564036a550b32d029e0733af01dc66c5afea50388d3"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.3.0"
geocoding_platform_interface:
dependency: transitive
description:
name: geocoding_platform_interface
sha256: "8848605d307d844d89937cdb4b8ad7dfa880552078f310fa24d8a460f6dddab4"
sha256: "8c2c8226e5c276594c2e18bfe88b19110ed770aeb7c1ab50ede570be8b92229b"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "3.2.0"
geolocator:
dependency: transitive
description:
@ -648,10 +664,10 @@ packages:
dependency: transitive
description:
name: path_provider_windows
sha256: a34ecd7fb548f8e57321fd8e50d865d266941b54e6c3b7758cf8f37c24116905
sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96"
url: "https://pub.dev"
source: hosted
version: "2.0.7"
version: "2.1.7"
pedantic:
dependency: transitive
description:
@ -1069,10 +1085,18 @@ packages:
dependency: transitive
description:
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"
source: hosted
version: "2.6.1"
version: "1.1.2"
xdg_directories:
dependency: transitive
description:
@ -1090,5 +1114,5 @@ packages:
source: hosted
version: "6.1.0"
sdks:
dart: ">=3.2.0-194.0.dev <4.0.0"
dart: ">=3.2.0 <4.0.0"
flutter: ">=3.10.0"

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

Loading…
Cancel
Save