diff --git a/assets/icons/search_icon.svg b/assets/icons/search_icon.svg
new file mode 100644
index 0000000..f490a60
--- /dev/null
+++ b/assets/icons/search_icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json
index c4861e1..1b6217e 100644
--- a/assets/langs/ar-SA.json
+++ b/assets/langs/ar-SA.json
@@ -169,5 +169,7 @@
"accessories_modifications": "الملحقات والتعديلات",
"my_recent_providers": "مزودي الخدمة الجدد",
"my_active_ads": "إعلاناتي النشطة",
- "recommended_Ads": "الإعلانات الموصى بها"
+ "recommended_Ads": "الإعلانات الموصى بها",
+ "location": "موقع"
+
}
\ No newline at end of file
diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json
index 575756a..a499d5b 100644
--- a/assets/langs/en-US.json
+++ b/assets/langs/en-US.json
@@ -169,5 +169,8 @@
"accessories_modifications": "Accessories and Modifications",
"my_recent_providers": "My Recent Service Providers",
"my_active_ads": "My Active Ads",
- "recommended_Ads": "Recommended Ads"
+ "recommended_Ads": "Recommended Ads",
+ "select_services": "Select services you want",
+ "location": "Location"
+
}
\ No newline at end of file
diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart
index 972c57c..52b2a01 100644
--- a/lib/classes/consts.dart
+++ b/lib/classes/consts.dart
@@ -109,6 +109,8 @@ class MyAssets {
static String icNotification = "${assetPath}images/ic_notification.svg";
static String logo = "${assetPath}images/logo.svg";
static String splashLogo = "${assetPath}images/splash_logo.svg";
+ static String searchIcon = "${assetPath}icons/search_icon.svg";
+
//PNG
static String icWorldPng = "${assetPath}images/ic_world.png";
diff --git a/lib/config/routes.dart b/lib/config/routes.dart
index 6e1d741..6ccf08d 100644
--- a/lib/config/routes.dart
+++ b/lib/config/routes.dart
@@ -51,6 +51,8 @@ class AppRoutes {
static const String editAccountPage = "/editAccoundPage";
static const String dashboard = "/dashboard";
+ static const String bookProviderAppView = "/bookProviderAppView";
+ static const String appointmentDetailView = "/appointmentDetailView";
diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart
index ac17df6..ce15754 100644
--- a/lib/extensions/string_extensions.dart
+++ b/lib/extensions/string_extensions.dart
@@ -1,10 +1,19 @@
-
import 'package:flutter/cupertino.dart';
import 'package:intl/intl.dart';
import 'package:mc_common_app/theme/colors.dart';
extension EmailValidator on String {
- Widget toText({Color? color, bool isBold = false, double? fontSize, bool isUnderLine = false, TextDecoration? textDecoration, double letterSpacing = -0.4, TextAlign? textAlign, double? height}) =>
+ Widget toText({
+ Color? color,
+ bool isSemiBold = false,
+ bool isBold = false,
+ double? fontSize,
+ bool isUnderLine = false,
+ TextDecoration? textDecoration,
+ double letterSpacing = -0.4,
+ TextAlign? textAlign,
+ double? height,
+ }) =>
Text(
this,
textAlign: textAlign,
@@ -18,7 +27,6 @@ extension EmailValidator on String {
),
);
-
bool isValidEmail() {
return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this);
}
diff --git a/lib/views/user/forget_password_page.dart b/lib/views/user/forget_password_page.dart
index fedc92d..761dd5c 100644
--- a/lib/views/user/forget_password_page.dart
+++ b/lib/views/user/forget_password_page.dart
@@ -50,7 +50,7 @@ class _ForgetPasswordPageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
- appBar: CustomAppBar( isRemoveBackButton: true, title: LocaleKeys.changePassword.tr()),
+ appBar: CustomAppBar(isRemoveBackButton: true, title: LocaleKeys.changePassword.tr()),
body: Container(
width: double.infinity,
height: double.infinity,
@@ -135,9 +135,11 @@ class _ForgetPasswordPageState extends State {
Widget getCountry() {
if (_country != null) {
List dropList = [];
- _country!.data?.forEach((element) {
- dropList.add(DropValue(element.id ?? 0, (element.countryName ?? "") + " " + (element.countryCode ?? ""), element.countryCode ?? ""));
- });
+ _country!.data?.forEach(
+ (element) {
+ dropList.add(DropValue(element.id ?? 0, "${element.countryName ?? ""} ${element.countryCode ?? ""}", element.countryCode ?? ""));
+ },
+ );
return Padding(
padding: const EdgeInsets.all(2.0),
child: DropdownField((DropValue value) {
diff --git a/lib/widgets/common_widgets/app_bar.dart b/lib/widgets/common_widgets/app_bar.dart
index bb41f49..31f8fb3 100644
--- a/lib/widgets/common_widgets/app_bar.dart
+++ b/lib/widgets/common_widgets/app_bar.dart
@@ -91,6 +91,7 @@ class CustomAppBar extends StatelessWidget with PreferredSizeWidget {
@override
Widget build(BuildContext context) {
return AppBar(
+ automaticallyImplyLeading: false,
leadingWidth: 100,
backgroundColor: backgroundColor ?? appBackgroundColor,
elevation: elevation ?? 0,
diff --git a/lib/widgets/common_widgets/categories_list.dart b/lib/widgets/common_widgets/categories_list.dart
new file mode 100644
index 0000000..5ddbc0a
--- /dev/null
+++ b/lib/widgets/common_widgets/categories_list.dart
@@ -0,0 +1,44 @@
+import 'package:flutter/material.dart';
+import 'package:mc_common_app/extensions/string_extensions.dart';
+import 'package:mc_common_app/theme/colors.dart';
+
+
+class CategoriesList extends StatelessWidget {
+ // We will pass a list here!
+ final String name;
+ final Function() onTapped;
+ const CategoriesList({Key? key, required this.name, required this.onTapped}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ height: 37,
+ width: double.infinity,
+ child: ListView.builder(
+ padding: const EdgeInsets.only(left: 12),
+ itemCount: 20,
+ scrollDirection: Axis.horizontal,
+ itemBuilder: (BuildContext context, int index) {
+ return InkWell(
+ onTap: onTapped,
+ child: Container(
+ alignment: Alignment.center,
+ padding: const EdgeInsets.symmetric(horizontal: 8),
+ margin: const EdgeInsets.symmetric(horizontal: 8),
+ decoration: BoxDecoration(
+ color: index < 1 ? MyColors.darkIconColor : null,
+ border: Border.all(
+ color: index < 1 ? MyColors.darkIconColor : MyColors.primaryColor,
+ width: 2,
+ ),
+ ),
+ child: name.toText(
+ fontSize: 12,
+ color: index < 1 ? MyColors.white : null,
+ ),
+ ),
+ );
+ }),
+ );
+ }
+}
diff --git a/lib/widgets/common_widgets/custom_button.dart b/lib/widgets/common_widgets/custom_button.dart
new file mode 100644
index 0000000..469dfc0
--- /dev/null
+++ b/lib/widgets/common_widgets/custom_button.dart
@@ -0,0 +1,38 @@
+import 'package:flutter/material.dart';
+import 'package:mc_common_app/extensions/string_extensions.dart';
+import 'package:mc_common_app/theme/colors.dart';
+
+class CustomButton extends StatelessWidget {
+ final Function() onTapped;
+ final Color? backgroundColor;
+ final String buttonText;
+ final double? textFontSize;
+
+ final Color textColor;
+ final bool? isIcon;
+ final double? buttonHeight;
+
+ const CustomButton({
+ Key? key,
+ required this.onTapped,
+ required this.buttonText,
+ this.isIcon = false,
+ this.backgroundColor = MyColors.primaryColor,
+ this.textColor = MyColors.white,
+ this.buttonHeight = 55,
+ this.textFontSize = 15,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ height: buttonHeight,
+ color: backgroundColor,
+ alignment: Alignment.center,
+ child: InkWell(
+ onTap: onTapped,
+ child: buttonText.toText(fontSize: textFontSize, color: textColor),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/common_widgets/customer_appointment_slider_widget.dart b/lib/widgets/common_widgets/customer_appointment_slider_widget.dart
index 16a100f..0c9f995 100644
--- a/lib/widgets/common_widgets/customer_appointment_slider_widget.dart
+++ b/lib/widgets/common_widgets/customer_appointment_slider_widget.dart
@@ -1,5 +1,6 @@
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
@@ -9,61 +10,6 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class CustomerAppointmentSliderWidget extends StatelessWidget {
const CustomerAppointmentSliderWidget({Key? key}) : super(key: key);
- Widget buildAppointmentContainerForCustomer() {
- return Container(
- margin: const EdgeInsets.only(bottom: 21, left: 21, right: 21, top: 7),
- child: Column(
- children: [
- Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Image.asset(
- MyAssets.bnCar,
- width: 56,
- height: 56,
- fit: BoxFit.fill,
- ).toCircle(borderRadius: 100),
- 8.width,
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- mainAxisAlignment: MainAxisAlignment.start,
- children: [
- "Al Aziz Service Station".toText(color: MyColors.black, isBold: true, fontSize: 16),
- Row(
- children: [
- MyAssets.miniClock.buildSvg(height: 12),
- 2.width,
- "08:00 to 08:30 25 July, 2023".toText(
- color: MyColors.lightTextColor,
- fontSize: 12,
- ),
- ],
- ),
- 9.height,
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- crossAxisAlignment: CrossAxisAlignment.end,
- children: [
- "Appointment Details".toText(
- color: MyColors.primaryColor,
- isUnderLine: true,
- isBold: true,
- fontSize: 14,
- ),
- const Icon(Icons.arrow_forward),
- ],
- ),
- ],
- ),
- ),
- ],
- ),
- ],
- ).toWhiteContainer(width: double.infinity, allPading: 12),
- );
- }
-
@override
Widget build(BuildContext context) {
return CarouselSlider.builder(
@@ -80,7 +26,7 @@ class CustomerAppointmentSliderWidget extends StatelessWidget {
// },
),
itemCount: 10,
- itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) => buildAppointmentContainerForCustomer(),
+ itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) => const BuildAppointmentContainerForCustomer(isForHome: true),
);
}
@@ -101,3 +47,106 @@ class CustomerAppointmentSliderWidget extends StatelessWidget {
);
}
}
+
+class BuildAppointmentContainerForCustomer extends StatelessWidget {
+ final bool? isForHome;
+
+ const BuildAppointmentContainerForCustomer({Key? key, this.isForHome = false}) : super(key: key);
+
+ Widget showServices(String title, String icon) {
+ return Row(
+ children: [
+ SvgPicture.asset(icon),
+ 8.width,
+ title.toText(
+ fontSize: 14,
+ isBold: true,
+ ),
+ ],
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: const EdgeInsets.only(bottom: 21, left: 21, right: 21, top: 7),
+ child: Column(
+ children: [
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ isForHome != null && isForHome!
+ ? Image.asset(
+ MyAssets.bnCar,
+ width: 56,
+ height: 56,
+ fit: BoxFit.fill,
+ ).toCircle(borderRadius: 100)
+ : Image.asset(
+ MyAssets.bnCar,
+ width: 80,
+ height: 85,
+ fit: BoxFit.cover,
+ ),
+ 8.width,
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ "Al Aziz Service Station".toText(color: MyColors.black, isBold: true, fontSize: 16),
+ Row(
+ children: [
+ MyAssets.miniClock.buildSvg(height: 12),
+ 2.width,
+ "08:00 to 08:30 25 July, 2023".toText(
+ color: MyColors.lightTextColor,
+ fontSize: 12,
+ ),
+ ],
+ ),
+ 9.height,
+ isForHome != null && isForHome!
+ ? Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ "Appointment Details".toText(
+ color: MyColors.primaryColor,
+ isUnderLine: true,
+ isBold: true,
+ fontSize: 14,
+ ),
+ const Icon(Icons.arrow_forward),
+ ],
+ )
+ : Row(
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ Expanded(
+ child: Column(
+ children: [
+ showServices("Maintenance", MyAssets.maintenanceIcon),
+ 2.height,
+ showServices(
+ "Accessories and Modification",
+ MyAssets.modificationsIcon,
+ ),
+ ],
+ ),
+ ),
+ const Icon(
+ Icons.arrow_forward,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ],
+ ).toWhiteContainer(width: double.infinity, allPading: 12),
+ );
+ }
+}
diff --git a/lib/widgets/common_widgets/provider_appointment_slider_widget.dart b/lib/widgets/common_widgets/provider_appointment_slider_widget.dart
index da4da92..98b93e1 100644
--- a/lib/widgets/common_widgets/provider_appointment_slider_widget.dart
+++ b/lib/widgets/common_widgets/provider_appointment_slider_widget.dart
@@ -10,7 +10,48 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class ProviderAppointmentSliderWidget extends StatelessWidget {
const ProviderAppointmentSliderWidget({Key? key}) : super(key: key);
- Widget buildAppointmentContainerForProvider() {
+
+ @override
+ Widget build(BuildContext context) {
+ return CarouselSlider.builder(
+ options: CarouselOptions(
+ height: 160,
+ viewportFraction: 1.0,
+ enlargeCenterPage: false,
+ enableInfiniteScroll: false,
+ //
+ // onPageChanged: (index) {
+ // setState(() {
+ // _current = index;
+ // });
+ // },
+ ),
+ itemCount: 10,
+ itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) => const BuildAppointmentContainerForProvider(),
+ );
+ }
+
+
+}
+
+class BuildAppointmentContainerForProvider extends StatelessWidget {
+ const BuildAppointmentContainerForProvider({Key? key}) : super(key: key);
+
+ Widget showServices(String title, String icon) {
+ return Row(
+ children: [
+ SvgPicture.asset(icon),
+ 8.width,
+ title.toText(
+ fontSize: 14,
+ isBold: true,
+ ),
+ ],
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 21, left: 21, right: 21, top: 7),
child: Column(
@@ -43,13 +84,13 @@ class ProviderAppointmentSliderWidget extends StatelessWidget {
),
),
"1+ Requests".toText(fontSize: 10).toContainer(
- borderRadius: 15,
- backgroundColor: MyColors.lightGreyEAColor,
- padding: const EdgeInsets.symmetric(
- vertical: 6,
- horizontal: 12,
- ),
- ),
+ borderRadius: 15,
+ backgroundColor: MyColors.lightGreyEAColor,
+ padding: const EdgeInsets.symmetric(
+ vertical: 6,
+ horizontal: 12,
+ ),
+ ),
],
),
8.height,
@@ -74,37 +115,5 @@ class ProviderAppointmentSliderWidget extends StatelessWidget {
).toWhiteContainer(width: double.infinity, allPading: 12),
);
}
-
- @override
- Widget build(BuildContext context) {
- return CarouselSlider.builder(
- options: CarouselOptions(
- height: 160,
- viewportFraction: 1.0,
- enlargeCenterPage: false,
- enableInfiniteScroll: false,
- //
- // onPageChanged: (index) {
- // setState(() {
- // _current = index;
- // });
- // },
- ),
- itemCount: 10,
- itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) => buildAppointmentContainerForProvider(),
- );
- }
-
- Widget showServices(String title, String icon) {
- return Row(
- children: [
- SvgPicture.asset(icon),
- 8.width,
- title.toText(
- fontSize: 14,
- isBold: true,
- ),
- ],
- );
- }
}
+
diff --git a/lib/widgets/common_widgets/provider_details_card.dart b/lib/widgets/common_widgets/provider_details_card.dart
new file mode 100644
index 0000000..159ea99
--- /dev/null
+++ b/lib/widgets/common_widgets/provider_details_card.dart
@@ -0,0 +1,118 @@
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+import 'package:mc_common_app/classes/consts.dart';
+import 'package:mc_common_app/extensions/int_extensions.dart';
+import 'package:mc_common_app/extensions/string_extensions.dart';
+import 'package:mc_common_app/generated/locale_keys.g.dart';
+import 'package:mc_common_app/theme/colors.dart';
+import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
+
+class ProviderDetailsCard extends StatelessWidget {
+ final String providerImageUrl;
+ final String providerName;
+ final String providerLocation;
+ final String providerRatings;
+ final Function() onCardTapped;
+
+ const ProviderDetailsCard({
+ Key? key,
+ required this.providerImageUrl,
+ required this.providerName,
+ required this.providerRatings,
+ required this.providerLocation,
+ required this.onCardTapped,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.only(
+ bottom: 10,
+ left: 21,
+ right: 21,
+ ),
+ child: Row(
+ children: [
+ Image.asset(
+ providerImageUrl,
+ width: 80,
+ height: 85,
+ fit: BoxFit.cover,
+ ),
+ 12.width,
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ providerName.toText(fontSize: 16, isBold: true),
+ Row(
+ children: [
+ LocaleKeys.location.tr().toText(color: MyColors.lightTextColor, fontSize: 12),
+ 2.width,
+ ":$providerLocation".toText(fontSize: 12),
+ ],
+ ),
+ ],
+ ),
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ providerRatings.toText(
+ isUnderLine: true,
+ isBold: true,
+ fontSize: 12,
+ ),
+ 2.width,
+ MyAssets.starIcon.buildSvg(width: 12),
+ ],
+ ),
+ ],
+ ),
+ 8.height,
+ Row(
+ children: [
+ Expanded(
+ child: Column(
+ children: [
+ Row(
+ children: [
+ MyAssets.maintenanceIcon.buildSvg(),
+ 8.width,
+ LocaleKeys.maintenance.tr().toText(
+ fontSize: 14,
+ isBold: true,
+ ),
+ ],
+ ),
+ Row(
+ children: [
+ MyAssets.modificationsIcon.buildSvg(),
+ 8.width,
+ LocaleKeys.accessories_modifications.tr().toText(
+ fontSize: 14,
+ isBold: true,
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ],
+ ).onPress(onCardTapped).toWhiteContainer(width: double.infinity, allPading: 12));
+ }
+}
diff --git a/lib/widgets/extensions/extensions_widget.dart b/lib/widgets/extensions/extensions_widget.dart
index 4cfcd1b..0ca7bfb 100644
--- a/lib/widgets/extensions/extensions_widget.dart
+++ b/lib/widgets/extensions/extensions_widget.dart
@@ -89,6 +89,20 @@ extension ImageExt on Image {
}
}
+extension ActionIcon on Widget {
+ Widget toCircleContainer() {
+ return Container(
+ height: 44,
+ width: 44,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ border: Border.all(color: MyColors.lightTextColor),
+ ),
+ child: this,
+ );
+ }
+}
+
extension WidgetExt on Widget {
Widget toWidget() {
return this;
diff --git a/pubspec.yaml b/pubspec.yaml
index b426b6e..1f4ccf5 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -34,6 +34,7 @@ dependencies:
url_launcher: ^6.1.7
badges: ^3.0.2
carousel_slider: ^4.2.1
+ dropdown_button2: ^2.0.0
# google