Compare commits
42 Commits
main
...
mirza_deve
| Author | SHA1 | Date |
|---|---|---|
|
|
a8a7a87108 | 2 years ago |
|
|
08f6c55a10 | 2 years ago |
|
|
e79ad123fd | 2 years ago |
|
|
2b640c5624 | 2 years ago |
|
|
c7953189e3 | 2 years ago |
|
|
f510711768 | 2 years ago |
|
|
8fbd859005 | 2 years ago |
|
|
37ce6494dd | 2 years ago |
|
|
657d3bbd6a | 2 years ago |
|
|
711be7f5da | 2 years ago |
|
|
39d2add60f | 2 years ago |
|
|
13100cafce | 2 years ago |
|
|
a47cae92f2 | 2 years ago |
|
|
54fd8736c7 | 2 years ago |
|
|
9638deea3d | 2 years ago |
|
|
937a1db5d9 | 2 years ago |
|
|
2dd1952b20 | 2 years ago |
|
|
120dc86309 | 2 years ago |
|
|
7163c6c1ba | 2 years ago |
|
|
5bc5ca8954 | 2 years ago |
|
|
1c78b0e134 | 2 years ago |
|
|
fa35392611 | 2 years ago |
|
|
045ccc6f70 | 2 years ago |
|
|
ce9aab8db7 | 2 years ago |
|
|
e6c6c127f0 | 2 years ago |
|
|
533952e14e | 2 years ago |
|
|
436befd111 | 2 years ago |
|
|
83287f3b37 | 2 years ago |
|
|
f0130d189a | 2 years ago |
|
|
ab723b4b97 | 2 years ago |
|
|
8bc13dff34 | 2 years ago |
|
|
9499c902a8 | 2 years ago |
|
|
694567653a | 2 years ago |
|
|
e39c697ed0 | 2 years ago |
|
|
86c9419484 | 2 years ago |
|
|
0c9d4dfa7d | 2 years ago |
|
|
274e407fa9 | 2 years ago |
|
|
3f0178e1cd | 2 years ago |
|
|
4ccbf361fe | 2 years ago |
|
|
3390112aa3 | 2 years ago |
|
|
50baaacb74 | 2 years ago |
|
|
237911d711 | 2 years ago |
@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="29.159" height="24.616" viewBox="0 0 29.159 24.616">
|
||||
<g id="promotion" transform="translate(-2 -3.116)">
|
||||
<path id="Path_4626" data-name="Path 4626" d="M26.785,3.408a.292.292,0,0,0-.417-.263L11.455,10.236h.021V20.442h-.021l14.913,7.092a.292.292,0,0,0,.417-.263ZM10.019,20.078V10.6H6.544A4.644,4.644,0,0,0,2,15.339a4.722,4.722,0,0,0,3.191,4.525l2.395,7.663a.292.292,0,0,0,.278.2h3.945a.292.292,0,0,0,.278-.378L9.814,20.078ZM7.728,16.068a.729.729,0,0,0,.729-.729v-.208a.729.729,0,0,0-.729-.729H6.686a.729.729,0,0,0-.729.729v.208a.729.729,0,0,0,.729.729Z" transform="translate(0 0)" fill="#767676" fill-rule="evenodd"/>
|
||||
<path id="Path_4627" data-name="Path 4627" d="M22.29,17.715a5.1,5.1,0,0,0,0-9.224ZM20.832,8.052a5.1,5.1,0,1,0,0,10.1Z" transform="translate(5.953 2.236)" fill="#767676" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 878 B |
@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="25.034" height="25.034" viewBox="0 0 25.034 25.034">
|
||||
<g id="weekly-calendar-page-symbol" transform="translate(139)">
|
||||
<path id="Path_4379" data-name="Path 4379" d="M22.53,0H2.5A2.511,2.511,0,0,0,0,2.5V22.53a2.512,2.512,0,0,0,2.5,2.5H22.53a2.512,2.512,0,0,0,2.5-2.5V2.5A2.511,2.511,0,0,0,22.53,0ZM6.756,22.031H2.921V18.62H6.756v3.411Zm0-4.555H2.921v-3.41H6.756v3.41ZM6.467,3.794A1.063,1.063,0,1,1,7.529,2.731,1.062,1.062,0,0,1,6.467,3.794Zm5.406,18.237H8.039V18.62h3.834Zm0-4.555H8.039v-3.41h3.834Zm0-4.552H8.039V9.514h3.834ZM11.455,2.731a1.062,1.062,0,1,1,1.062,1.062A1.062,1.062,0,0,1,11.455,2.731Zm5.54,14.745H13.159v-3.41H17v3.41Zm0-4.552H13.159V9.514H17v3.41ZM17.5,2.731a1.062,1.062,0,1,1,1.062,1.062A1.062,1.062,0,0,1,17.5,2.731Zm4.609,14.745H18.278v-3.41h3.835Zm0-4.552H18.278V9.514h3.835Z" transform="translate(-139)" fill="#767676"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 908 B |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="25.409" height="25.409" viewBox="0 0 25.409 25.409">
|
||||
<path id="close_3_" data-name="close (3)" d="M10.63,9.119l7-7A1.164,1.164,0,1,0,15.98.477l-7,7-7-7A1.164,1.164,0,0,0,.341,2.123l7,7-7,7a1.164,1.164,0,1,0,1.646,1.646l7-7,7,7a1.164,1.164,0,1,0,1.646-1.646Zm0,0" transform="translate(-0.096 12.609) rotate(-45)" fill="#fff"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 382 B |
@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="23.889" height="10.642" viewBox="0 0 23.889 10.642">
|
||||
<g id="Group_8170" data-name="Group 8170" transform="translate(-61.5 -50.884)">
|
||||
<path id="Path_66" data-name="Path 66" d="M4.5,18H19.3" transform="translate(58.5 42.025)" fill="none" stroke="#2e303a" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
|
||||
<path id="Path_67" data-name="Path 67" d="M4.5,9H25.389" transform="translate(58.5 43.384)" fill="none" stroke="#2e303a" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 577 B |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="28.123" height="26.245" viewBox="0 0 28.123 26.245">
|
||||
<path id="XMLID_219_" d="M28.984,15.637A2.077,2.077,0,0,1,27.025,17h-.716V27.309a.938.938,0,0,1-.937.937H19.748V21.685a4.687,4.687,0,0,0-9.374,0v6.562H4.749a.938.938,0,0,1-.937-.937V17H3.095a2.1,2.1,0,0,1-1.378-3.675L12.665,2.955a3.486,3.486,0,0,1,4.792,0L28.431,13.347A2.066,2.066,0,0,1,28.984,15.637Z" transform="translate(-0.999 -2.001)" fill="#273139"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 467 B |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="8.852" height="8.852" viewBox="0 0 8.852 8.852">
|
||||
<path id="clock_7_" data-name="clock (7)" d="M4.426,0A4.426,4.426,0,1,0,8.852,4.426,4.431,4.431,0,0,0,4.426,0Zm2.1,6.715a.368.368,0,0,1-.521,0L4.165,4.871a.367.367,0,0,1-.108-.261v-2.4a.369.369,0,1,1,.738,0V4.458L6.531,6.194A.368.368,0,0,1,6.531,6.715Zm0,0" fill="#a9a9a9"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 380 B |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12.375" height="9" viewBox="0 0 12.375 9">
|
||||
<path id="next_3_" data-name="next (3)" d="M13.21,8.1,9.273,4.165a.562.562,0,1,0-.8.8l2.977,2.977H1.563a.562.562,0,1,0,0,1.125h9.892L8.477,12.04a.562.562,0,1,0,.8.8L13.21,8.9a.563.563,0,0,0,0-.8Z" transform="translate(-1 -4)" fill="#06161c"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 342 B |
@ -0,0 +1,6 @@
|
||||
<svg id="bell_2_" data-name="bell (2)" xmlns="http://www.w3.org/2000/svg" width="20.255" height="22.097" viewBox="0 0 20.255 22.097">
|
||||
<path id="Path_4605" data-name="Path 4605" d="M358.833,25.324a.921.921,0,0,1-.921-.921,9.606,9.606,0,0,0-2.831-6.836.921.921,0,0,1,1.3-1.3,11.433,11.433,0,0,1,3.371,8.138A.921.921,0,0,1,358.833,25.324Zm0,0" transform="translate(-339.499 -15.305)" fill="#28323a"/>
|
||||
<path id="Path_4606" data-name="Path 4606" d="M.921,25.324A.921.921,0,0,1,0,24.4a11.434,11.434,0,0,1,3.371-8.138.921.921,0,0,1,1.3,1.3A9.6,9.6,0,0,0,1.841,24.4.921.921,0,0,1,.921,25.324Zm0,0" transform="translate(0 -15.305)" fill="#28323a"/>
|
||||
<path id="Path_4607" data-name="Path 4607" d="M39.174,15.572a6.167,6.167,0,0,1-2.19-4.719V8.286A6.45,6.45,0,0,0,31.46,1.915V.921a.921.921,0,0,0-1.841,0v.994a6.449,6.449,0,0,0-5.524,6.371v2.567a6.174,6.174,0,0,1-2.2,4.726,1.611,1.611,0,0,0,1.048,2.835H38.135a1.611,1.611,0,0,0,1.039-2.842Zm0,0" transform="translate(-20.411)" fill="#28323a"/>
|
||||
<path id="Path_4608" data-name="Path 4608" d="M159.672,450.762A3.458,3.458,0,0,0,163.054,448h-6.765A3.458,3.458,0,0,0,159.672,450.762Zm0,0" transform="translate(-149.544 -428.665)" fill="#28323a"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="25.783" height="30.979" viewBox="0 0 25.783 30.979">
|
||||
<g id="automobile-with-wrench" transform="translate(-30.265)">
|
||||
<path id="Path_4647" data-name="Path 4647" d="M106.524,16.93c2.071,0,6.941-2.493,6.941-8.465,0-.833-.02-1.638-.089-2.4a7.177,7.177,0,0,0-1.182-3.839C111.214.845,109.5,0,106.524,0s-4.69.844-5.669,2.227a7.175,7.175,0,0,0-1.183,3.84c-.069.76-.089,1.565-.089,2.4C99.583,14.437,104.452,16.93,106.524,16.93ZM108.789,3.1l-.506,1.277a5.736,5.736,0,0,0-3.52,0L104.258,3.1A7.109,7.109,0,0,1,108.789,3.1ZM100.615,7.17c.08.175.42.847.946.91.6.073,1.608-2.141,4.963-2.146s4.358,2.219,4.963,2.146c.526-.063.866-.735.946-.91.016.429.022.862.022,1.3a7.548,7.548,0,0,1-2.37,5.732,6.062,6.062,0,0,1-3.56,1.723,6.062,6.062,0,0,1-3.56-1.723,7.547,7.547,0,0,1-2.371-5.732C100.593,8.032,100.6,7.6,100.615,7.17Z" transform="translate(-63.367)" fill="#767676"/>
|
||||
<path id="Path_4648" data-name="Path 4648" d="M56.042,197.513c-.354-2.2-1.084-5.041-2.547-6.05-1-.689-4.486-2.552-5.974-3.347L47.5,188.1a.486.486,0,0,0-.53.046,6.325,6.325,0,0,1-2.539,1.226.486.486,0,0,0-.349.3l-.921,2.429-.922-2.429a.486.486,0,0,0-.349-.3,6.324,6.324,0,0,1-2.539-1.226.487.487,0,0,0-.53-.046c-1.471.786-5,2.687-5.995,3.357-1.684,1.135-2.421,5.241-2.551,6.053a.488.488,0,0,0,.022.24c.036.1.593,1.544,3.379,2.7a1.384,1.384,0,0,1,.615-.442,1.374,1.374,0,0,1-.749-1.955,4.071,4.071,0,0,1,6.959-.316h5.316a4.079,4.079,0,0,1,3.38-1.808h0a4.079,4.079,0,0,1,3.575,2.112A1.374,1.374,0,0,1,52.025,200a1.382,1.382,0,0,1,.624.448c2.779-1.16,3.335-2.6,3.371-2.7A.49.49,0,0,0,56.042,197.513Z" transform="translate(0 -171.901)" fill="#767676"/>
|
||||
<path id="Path_4649" data-name="Path 4649" d="M97.425,297.952h0l-2.561,0a4.839,4.839,0,0,1,0-2.244l2.561,0a.173.173,0,0,0,.151-.257,2.872,2.872,0,0,0-5.184.319H85.634a2.869,2.869,0,0,0-5.185-.31.173.173,0,0,0,.152.256h0l2.561,0a4.839,4.839,0,0,1,0,2.244l-2.561,0a.173.173,0,0,0-.151.256,2.873,2.873,0,0,0,2.517,1.489h0a2.871,2.871,0,0,0,2.663-1.808h6.753a2.876,2.876,0,0,0,2.665,1.808h0a2.874,2.874,0,0,0,2.517-1.5.173.173,0,0,0-.152-.256Z" transform="translate(-45.857 -268.725)" fill="#767676"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="25.211" height="20.945" viewBox="0 0 25.211 20.945">
|
||||
<path id="menu_6_" data-name="menu (6)" d="M-.551,81.687H21.76a1.772,1.772,0,0,1,0,3.484H-.551A1.617,1.617,0,0,1-2,83.429a1.617,1.617,0,0,1,1.45-1.742ZM21.76,83.193H-.551a.219.219,0,0,0-.2.236.219.219,0,0,0,.2.236H21.76a.24.24,0,0,0,0-.473ZM-.551,72.957H21.76a1.772,1.772,0,0,1,0,3.484H-.551A1.617,1.617,0,0,1-2,74.7a1.617,1.617,0,0,1,1.45-1.742ZM21.76,74.462H-.551a.219.219,0,0,0-.2.236.219.219,0,0,0,.2.236H21.76a.24.24,0,0,0,0-.473ZM-.551,90.418H21.76a1.772,1.772,0,0,1,0,3.484H-.551A1.617,1.617,0,0,1-2,92.16a1.617,1.617,0,0,1,1.45-1.742ZM21.76,91.923H-.551a.219.219,0,0,0-.2.236.219.219,0,0,0,.2.236H21.76a.24.24,0,0,0,0-.473ZM-.551,74.935H21.76a.24.24,0,0,0,0-.473H-.551a.219.219,0,0,0-.2.236.219.219,0,0,0,.2.236ZM21.76,83.193H-.551a.219.219,0,0,0-.2.236.219.219,0,0,0,.2.236H21.76a.24.24,0,0,0,0-.473Zm0,8.731H-.551a.219.219,0,0,0-.2.236.219.219,0,0,0,.2.236H21.76a.24.24,0,0,0,0-.473Z" transform="translate(2.001 -72.956)" fill="#767676" fill-rule="evenodd"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -1,8 +1,8 @@
|
||||
|
||||
import 'package:mc_common_app/config/dependencies.dart';
|
||||
|
||||
class CustomerDependencies {
|
||||
static void addDependencies() {
|
||||
AppDependencies.addDependencies();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,102 +0,0 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
|
||||
import 'package:mc_common_app/models/provider_category_model.dart';
|
||||
import 'package:mc_common_app/models/provider_service_model.dart';
|
||||
import 'package:mc_common_app/models/widgets_models.dart';
|
||||
import 'package:mc_common_app/repositories/common_repo.dart';
|
||||
import 'package:mc_common_app/services/common_services.dart';
|
||||
|
||||
class AppointmentsVM extends ChangeNotifier {
|
||||
final CommonRepo commonRepo;
|
||||
final CommonAppServices commonServices;
|
||||
|
||||
AppointmentsVM({required this.commonServices, required this.commonRepo});
|
||||
|
||||
bool isFetchingLists = false;
|
||||
|
||||
List<AppointmentListModel> myAppointments = [];
|
||||
List<FilterListModel> appointmentsFilterOptions = [];
|
||||
|
||||
bool isFetchingServices = false;
|
||||
|
||||
List<ProviderCategoryModel> providerCategories = [];
|
||||
|
||||
bool isHomeTapped = false;
|
||||
|
||||
void updateIsHomeTapped(bool value) {
|
||||
isHomeTapped = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
String pickedHomeLocation = "";
|
||||
|
||||
void updatePickedHomeLocation(String value) {
|
||||
pickedHomeLocation = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
SelectionModel providerCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
|
||||
void updateProviderCategoryId(SelectionModel id) async {
|
||||
providerCategoryId = id;
|
||||
await getProviderServices(id.selectedId);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
List<ProviderServiceModel> providerServices = [];
|
||||
|
||||
SelectionModel providerServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
|
||||
void updateProviderServiceId(SelectionModel id) async {
|
||||
providerServiceId = id;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void getProviderCategories() async {
|
||||
notifyListeners();
|
||||
providerCategories = await commonRepo.getProviderServiceCategories();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
getProviderServices(int categoryId) async {
|
||||
providerServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
isHomeTapped = false;
|
||||
pickedHomeLocation = "";
|
||||
if (categoryId != -1) {
|
||||
isFetchingServices = true;
|
||||
notifyListeners();
|
||||
providerServices = await commonRepo.getProviderServices(categoryId: categoryId);
|
||||
isFetchingServices = false;
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
populateAppointmentsFilterList() {
|
||||
appointmentsFilterOptions.clear();
|
||||
appointmentsFilterOptions = [
|
||||
FilterListModel(title: "All Appointments", isSelected: true, id: -1),
|
||||
FilterListModel(title: "Booked", isSelected: false, id: 1),
|
||||
FilterListModel(title: "Confirmed", isSelected: false, id: 2),
|
||||
FilterListModel(title: "Arrived", isSelected: false, id: 3),
|
||||
FilterListModel(title: "Cancelled", isSelected: false, id: 4),
|
||||
];
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
applyFilterOnAppointmentsVM({required int index}) {
|
||||
if (appointmentsFilterOptions.isEmpty) return;
|
||||
for (var value in appointmentsFilterOptions) {
|
||||
value.isSelected = false;
|
||||
}
|
||||
appointmentsFilterOptions[index].isSelected = true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> getMyAppointments() async {
|
||||
isFetchingLists = true;
|
||||
myAppointments = await commonRepo.getMyAppointments();
|
||||
isFetchingLists = false;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
import 'dart:io';
|
||||
import 'package:mc_common_app/classes/app_state.dart';
|
||||
import 'package:mc_common_app/generated/locale_keys.g.dart';
|
||||
import 'package:mc_common_app/models/user/image_response.dart';
|
||||
import 'package:mc_common_app/repositories/user_repo.dart';
|
||||
import 'package:mc_common_app/services/common_services.dart';
|
||||
import 'package:mc_common_app/utils/utils.dart';
|
||||
import 'package:mc_common_app/view_models/base_view_model.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
class DashboardVM extends BaseVM {
|
||||
final CommonAppServices commonServices;
|
||||
final UserRepo userRepo;
|
||||
|
||||
DashboardVM({required this.commonServices, required this.userRepo});
|
||||
|
||||
String pickedImage = "";
|
||||
|
||||
int selectedNavbarBarIndex = 2;
|
||||
|
||||
void onNavbarTapped(int index) {
|
||||
selectedNavbarBarIndex = index;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void pickImageFromPhone(BuildContext context, int sourceFlag) async {
|
||||
final File? pickedImageFile = await commonServices.pickImageFromPhone(sourceFlag);
|
||||
if (pickedImageFile == null) {
|
||||
return;
|
||||
}
|
||||
int sizeInBytes = pickedImageFile.lengthSync();
|
||||
if (sizeInBytes > 1000) {
|
||||
Utils.showToast(LocaleKeys.fileLarger.tr());
|
||||
return;
|
||||
} else {
|
||||
String image64 = Utils.convertFileToBase64(pickedImageFile);
|
||||
|
||||
Utils.showLoading(context);
|
||||
ImageResponse response = await userRepo.updateUserImage(image64);
|
||||
Utils.hideLoading(context);
|
||||
Navigator.pop(context);
|
||||
if (response.messageStatus == 1) {
|
||||
Utils.showToast(LocaleKeys.imageUploaded.tr());
|
||||
AppState().getUser.data!.userInfo!.userImageUrl = response.data;
|
||||
} else {
|
||||
Utils.showToast(response.message ?? "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<ImageResponse> updateUserImage(String image) async {
|
||||
return await userRepo.updateUserImage(image);
|
||||
}
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:mc_common_app/models/widgets_models.dart';
|
||||
import 'package:mc_common_app/repositories/common_repo.dart';
|
||||
import 'package:mc_common_app/services/common_services.dart';
|
||||
|
||||
class ProvidersVM extends ChangeNotifier {
|
||||
final CommonRepo commonRepo;
|
||||
final CommonAppServices commonServices;
|
||||
|
||||
ProvidersVM({required this.commonServices, required this.commonRepo});
|
||||
|
||||
List<FilterListModel> providersFilterOptions = [];
|
||||
|
||||
populateProvidersFilterList() {
|
||||
providersFilterOptions.clear();
|
||||
providersFilterOptions = [
|
||||
FilterListModel(title: "All Providers", isSelected: true, id: -1),
|
||||
FilterListModel(title: "Maintenance", isSelected: false, id: 0),
|
||||
FilterListModel(title: "Oil Service", isSelected: false, id: 1),
|
||||
FilterListModel(title: "Accessories", isSelected: false, id: 2),
|
||||
FilterListModel(title: "Tire Service", isSelected: false, id: 3),
|
||||
FilterListModel(title: "Dent and Paint", isSelected: false, id: 4),
|
||||
];
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
applyFilterOnProviders({required int index}) {
|
||||
if (providersFilterOptions.isEmpty) return;
|
||||
for (var value in providersFilterOptions) {
|
||||
value.isSelected = false;
|
||||
}
|
||||
providersFilterOptions[index].isSelected = true;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
@ -1,128 +0,0 @@
|
||||
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/models/appointments_models/appointment_list_model.dart';
|
||||
import 'package:mc_common_app/theme/colors.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/card_button_with_icon.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
|
||||
class AppointmentDetailView extends StatelessWidget {
|
||||
AppointmentListModel appointmentListModel;
|
||||
|
||||
AppointmentDetailView({Key? key, required this.appointmentListModel}) : super(key: key);
|
||||
|
||||
final List<String> servicesList = [
|
||||
"Mechanic",
|
||||
"Electrician",
|
||||
" Car Denting",
|
||||
"Oil Change",
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: "Appointment",
|
||||
profileImageUrl: MyAssets.bnCar,
|
||||
isRemoveBackButton: false,
|
||||
isDrawerEnabled: false,
|
||||
),
|
||||
body: Container(
|
||||
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
|
||||
child: Stack(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
appointmentListModel.providerName!.toText(fontSize: 18, isBold: true),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
MyAssets.miniClockDark.buildSvg(
|
||||
height: 10,
|
||||
width: 10,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
10.width,
|
||||
"${appointmentListModel.duration ?? ""} ${appointmentListModel.appointmentDate!.toFormattedDateWithoutTime()}".toText(fontSize: 12, isBold: true, color: MyColors.lightTextColor),
|
||||
],
|
||||
),
|
||||
13.height,
|
||||
Row(
|
||||
children: [
|
||||
MyAssets.maintenanceIcon.buildSvg(
|
||||
height: 10,
|
||||
width: 10,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
10.width,
|
||||
"Maintenance".toText(fontSize: 18, isBold: true),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: servicesList
|
||||
.map((e) => e
|
||||
.toText(
|
||||
textAlign: TextAlign.start,
|
||||
fontSize: 13,
|
||||
isBold: true,
|
||||
color: MyColors.lightTextColor,
|
||||
)
|
||||
.paddingOnly(bottom: 5))
|
||||
.toList(),
|
||||
).paddingOnly(left: 15),
|
||||
15.height,
|
||||
Row(
|
||||
children: [
|
||||
CardButtonWithIcon(
|
||||
title: "Reschedule Appointment",
|
||||
onCardTapped: () {},
|
||||
icon: MyAssets.scheduleAppointmentIcon.buildSvg(),
|
||||
),
|
||||
10.width,
|
||||
CardButtonWithIcon(
|
||||
title: "Pay for Appointment",
|
||||
onCardTapped: () {},
|
||||
icon: MyAssets.creditCardIcon.buildSvg(),
|
||||
),
|
||||
],
|
||||
),
|
||||
15.height,
|
||||
],
|
||||
).toWhiteContainer(width: double.infinity, allPading: 12),
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ShowFillButton(
|
||||
maxHeight: 55,
|
||||
title: "Cancel",
|
||||
onPressed: () {},
|
||||
backgroundColor: MyColors.redColor,
|
||||
),
|
||||
),
|
||||
if (appointmentListModel.appointmentStatusID == 1) ...[
|
||||
12.width,
|
||||
Expanded(
|
||||
child: ShowFillButton(
|
||||
maxHeight: 55,
|
||||
title: "Confirm",
|
||||
onPressed: () {},
|
||||
backgroundColor: MyColors.greenColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,325 +0,0 @@
|
||||
import 'package:car_customer_app/view_models/appointments_view_model.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/models/widgets_models.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/views/advertisement/custom_add_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/dropdown/dropdow_field.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
import 'package:mc_common_app/widgets/txt_field.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class BookAppointmentServicesView extends StatelessWidget {
|
||||
const BookAppointmentServicesView({Key? key}) : super(key: key);
|
||||
|
||||
void openTheAddServiceBottomSheet(BuildContext context) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
enableDrag: true,
|
||||
builder: (BuildContext context) {
|
||||
AppointmentsVM appointmentsVM = context.watch<AppointmentsVM>();
|
||||
return SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.85,
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.all(8),
|
||||
height: 8,
|
||||
width: 60,
|
||||
decoration: const BoxDecoration(color: MyColors.lightTextColor, borderRadius: BorderRadius.all(Radius.circular(20))),
|
||||
),
|
||||
12.height,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
"Select Category".toText(fontSize: 24, isBold: true),
|
||||
],
|
||||
),
|
||||
30.height,
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: [
|
||||
Builder(
|
||||
builder: (context) {
|
||||
List<DropValue> serviceCategories = [];
|
||||
for (var element in appointmentsVM.providerCategories) {
|
||||
if (!element.isSelected!) {
|
||||
serviceCategories.add(DropValue(element.id?.toInt() ?? 0, element.categoryName ?? "", ""));
|
||||
}
|
||||
}
|
||||
return DropdownField(
|
||||
(DropValue value) => appointmentsVM.updateProviderCategoryId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
|
||||
list: serviceCategories,
|
||||
hint: "Select Category",
|
||||
dropdownValue: appointmentsVM.providerCategoryId.selectedId != -1
|
||||
? DropValue(appointmentsVM.providerCategoryId.selectedId, appointmentsVM.providerCategoryId.selectedOption, "")
|
||||
: null,
|
||||
);
|
||||
},
|
||||
),
|
||||
if (appointmentsVM.isFetchingServices) ...[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [const CircularProgressIndicator().paddingAll(10)],
|
||||
),
|
||||
] else if (appointmentsVM.providerServices.isNotEmpty) ...[
|
||||
8.height,
|
||||
Builder(
|
||||
builder: (context) {
|
||||
List<DropValue> serviceCategories = [];
|
||||
for (var element in appointmentsVM.providerServices) {
|
||||
if (!element.isSelected!) {
|
||||
serviceCategories.add(DropValue(element.id?.toInt() ?? 0, element.id.toString(), ""));
|
||||
}
|
||||
}
|
||||
return DropdownField(
|
||||
(DropValue value) => appointmentsVM.updateProviderServiceId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
|
||||
list: serviceCategories,
|
||||
hint: "Select Services",
|
||||
dropdownValue: appointmentsVM.providerServiceId.selectedId != -1
|
||||
? DropValue(appointmentsVM.providerServiceId.selectedId, appointmentsVM.providerServiceId.selectedOption, "")
|
||||
: null,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
if (appointmentsVM.providerServiceId.selectedId != -1 && !appointmentsVM.isFetchingServices) ...[
|
||||
16.height,
|
||||
Row(
|
||||
children: [
|
||||
"Select Service Location".toText(
|
||||
fontSize: 16,
|
||||
isBold: true,
|
||||
color: MyColors.black,
|
||||
),
|
||||
],
|
||||
),
|
||||
8.height,
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ShowFillButton(
|
||||
isFilled: appointmentsVM.isHomeTapped,
|
||||
maxHeight: 48,
|
||||
title: "Home",
|
||||
txtColor: appointmentsVM.isHomeTapped ? MyColors.white : MyColors.darkTextColor,
|
||||
onPressed: () => appointmentsVM.updateIsHomeTapped(true),
|
||||
),
|
||||
),
|
||||
12.width,
|
||||
Expanded(
|
||||
child: ShowFillButton(
|
||||
isFilled: !appointmentsVM.isHomeTapped,
|
||||
txtColor: !appointmentsVM.isHomeTapped ? MyColors.white : MyColors.darkTextColor,
|
||||
maxHeight: 48,
|
||||
title: "Workshop",
|
||||
onPressed: () => appointmentsVM.updateIsHomeTapped(false),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (appointmentsVM.isHomeTapped) ...[
|
||||
8.height,
|
||||
TxtField(
|
||||
hint: 'Pick Home Location',
|
||||
value: appointmentsVM.pickedHomeLocation,
|
||||
isNeedClickAll: true,
|
||||
postfixData: Icons.location_on,
|
||||
postFixDataColor: MyColors.darkTextColor,
|
||||
onTap: () {
|
||||
//TODO: open the place picked to pick the location and save it in provider.
|
||||
appointmentsVM.updatePickedHomeLocation("PM58+F97, Al Olaya, Riyadh 12333");
|
||||
},
|
||||
),
|
||||
14.height,
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.warning,
|
||||
color: MyColors.adPendingStatusColor,
|
||||
size: 19,
|
||||
).paddingOnly(bottom: 2),
|
||||
3.width,
|
||||
"Some services are not available on home location.".toText(
|
||||
color: MyColors.adPendingStatusColor,
|
||||
fontSize: 12,
|
||||
isItalic: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
if (appointmentsVM.isHomeTapped && !appointmentsVM.isFetchingServices) ...[
|
||||
const Divider(thickness: 1, height: 1),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
// TODO: This Price will be decided according to the service selected
|
||||
150.toString().toText(fontSize: 30, isBold: true),
|
||||
"SAR".toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5),
|
||||
],
|
||||
),
|
||||
"These charges are additional to the actual service charges. For heavy items the charges may vary.".toText(fontSize: 12, color: MyColors.lightTextColor),
|
||||
22.height,
|
||||
],
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: ShowFillButton(
|
||||
maxHeight: 55,
|
||||
title: "Next",
|
||||
onPressed: () {},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
).paddingOnly(bottom: 20)
|
||||
],
|
||||
)).horPaddingMain();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: "Book Appointment",
|
||||
isRemoveBackButton: false,
|
||||
isDrawerEnabled: false,
|
||||
actions: [MyAssets.searchIcon.buildSvg().paddingOnly(right: 21)],
|
||||
onBackButtonTapped: () => Navigator.pop(context),
|
||||
),
|
||||
body: Consumer(
|
||||
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
21.height,
|
||||
CustomAddButton(
|
||||
onTap: () => {openTheAddServiceBottomSheet(context)},
|
||||
text: "Add Services",
|
||||
icon: Container(
|
||||
height: 24,
|
||||
width: 24,
|
||||
decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor),
|
||||
child: const Icon(Icons.add, color: MyColors.white),
|
||||
),
|
||||
),
|
||||
// 20.height,
|
||||
// ListView.builder(
|
||||
// physics: const NeverScrollableScrollPhysics(),
|
||||
// shrinkWrap: true,
|
||||
// itemCount: adVM.specialServiceCards.length,
|
||||
// itemBuilder: (BuildContext context, int index) {
|
||||
// SpecialServiceCard specialServicesCard = adVM.specialServiceCards[index];
|
||||
// return Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Column(
|
||||
// children: [
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// Expanded(
|
||||
// child: specialServicesCard.serviceSelectedId!.selectedOption.toText(fontSize: 16, isBold: true),
|
||||
// ),
|
||||
// Align(
|
||||
// alignment: Alignment.topRight,
|
||||
// child: MyAssets.closeWithOrangeBg.buildSvg(
|
||||
// fit: BoxFit.fill,
|
||||
// height: 30,
|
||||
// width: 30,
|
||||
// ),
|
||||
// ).onPress(() => adVM.removeSpecialServiceCard(index))
|
||||
// ],
|
||||
// ),
|
||||
// Builder(builder: (context) {
|
||||
// return Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// if (specialServicesCard.serviceSelectedId!.selectedId != 1 && specialServicesCard.serviceSelectedId!.selectedId != 3) ...[
|
||||
// // Row(
|
||||
// // crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// // children: [
|
||||
// // "Duration: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
// // (specialServicesCard.duration ?? "").toText(fontSize: 12, isBold: true).expand(),
|
||||
// // ],
|
||||
// // ),
|
||||
// 8.height,
|
||||
// Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// "Description: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
// (specialServicesCard.description ?? "").toText(fontSize: 12, isBold: true).expand(),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// if (specialServicesCard.serviceSelectedId!.selectedId == 1 || specialServicesCard.serviceSelectedId!.selectedId == 3) ...[
|
||||
// Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// const Icon(
|
||||
// weight: 2,
|
||||
// Icons.location_on_outlined,
|
||||
// color: MyColors.primaryColor,
|
||||
// size: 17,
|
||||
// ),
|
||||
// "${specialServicesCard.duration} km".toText(fontSize: 10, color: MyColors.primaryColor),
|
||||
// ],
|
||||
// ),
|
||||
// 8.height,
|
||||
// Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// "Branch Address: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
// (specialServicesCard.address ?? "").toText(fontSize: 12, isBold: true).expand(),
|
||||
// ],
|
||||
// ),
|
||||
// Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// "Appointment Time: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
// "${specialServicesCard.serviceDate} - ${specialServicesCard.serviceTime}".toText(fontSize: 12, isBold: true).expand(),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// 6.height,
|
||||
// Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.end,
|
||||
// children: [
|
||||
// (specialServicesCard.serviceSelectedId!.itemPrice).toText(fontSize: 20, isBold: true),
|
||||
// 2.width,
|
||||
// "SAR".toText(color: MyColors.lightTextColor, fontSize: 14),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }),
|
||||
// 3.height,
|
||||
// const Divider(thickness: 1.5)
|
||||
// ],
|
||||
// ),
|
||||
// 10.height,
|
||||
// ],
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
],
|
||||
);
|
||||
},
|
||||
).horPaddingMain());
|
||||
}
|
||||
}
|
||||
@ -1,168 +0,0 @@
|
||||
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/theme/colors.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/provider_details_card.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/time_slots.dart';
|
||||
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
|
||||
class BookProviderAppView extends StatefulWidget {
|
||||
const BookProviderAppView({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<BookProviderAppView> createState() => _BookProviderAppViewState();
|
||||
}
|
||||
|
||||
class _BookProviderAppViewState extends State<BookProviderAppView> {
|
||||
bool isReview = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: "Appointment",
|
||||
profileImageUrl: MyAssets.bnCar,
|
||||
isRemoveBackButton: false,
|
||||
isDrawerEnabled: false,
|
||||
),
|
||||
body: Container(
|
||||
color: MyColors.backgroundColor,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: [
|
||||
ProviderDetailsCard(
|
||||
onCardTapped: () {},
|
||||
providerImageUrl: MyAssets.bnCar,
|
||||
providerLocation: "3km",
|
||||
providerName: "Al Ahmed Maintenance",
|
||||
providerRatings: "4.9",
|
||||
),
|
||||
12.height,
|
||||
isReview ? ReviewAppointmentSection() : ServicesSelectionSection(),
|
||||
10.height,
|
||||
],
|
||||
),
|
||||
),
|
||||
10.height,
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
|
||||
child: ShowFillButton(
|
||||
title: "Book Appointment",
|
||||
maxWidth: double.infinity,
|
||||
onPressed: () {
|
||||
isReview = !isReview;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ServicesSelectionSection extends StatelessWidget {
|
||||
const ServicesSelectionSection({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<DropValue> dropList = [
|
||||
DropValue(0, "Maintenance", ""),
|
||||
DropValue(1, "Car Wash", ""),
|
||||
DropValue(2, "Monthly Checkup", ""),
|
||||
DropValue(3, "Friendly Visit", ""),
|
||||
DropValue(4, "Muftaa", ""),
|
||||
];
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
"Select services you want".toText(fontSize: 18, isBold: true),
|
||||
8.height,
|
||||
DropdownField(
|
||||
(DropValue value) {},
|
||||
list: dropList,
|
||||
hint: "Select service type",
|
||||
),
|
||||
8.height,
|
||||
DropdownField(
|
||||
(DropValue value) {},
|
||||
list: dropList,
|
||||
hint: "Select service type",
|
||||
),
|
||||
8.height,
|
||||
DropdownField(
|
||||
(DropValue value) {},
|
||||
list: dropList,
|
||||
hint: "Select service type",
|
||||
),
|
||||
22.height,
|
||||
"Select date and time".toText(fontSize: 18, isBold: true),
|
||||
8.height,
|
||||
DropdownField(
|
||||
(DropValue value) {},
|
||||
list: dropList,
|
||||
hint: "Select service type",
|
||||
),
|
||||
22.height,
|
||||
"Available slots".toText(fontSize: 15, isBold: true),
|
||||
8.height,
|
||||
BuildTimeSlots(onPressed: (index) {}, timeSlots: []),
|
||||
22.height,
|
||||
"Total Amount".toText(fontSize: 18, isBold: true),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
"3000".toText(fontSize: 20, isBold: true),
|
||||
"SAR".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
|
||||
],
|
||||
),
|
||||
10.height,
|
||||
],
|
||||
).toWhiteContainer(width: double.infinity, allPading: 12),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ReviewAppointmentSection extends StatelessWidget {
|
||||
const ReviewAppointmentSection({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
"Review Appointment".toText(fontSize: 18, isBold: true),
|
||||
15.height,
|
||||
"Services".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
|
||||
"Car Engine Check".toText(fontSize: 18, isBold: true),
|
||||
13.height,
|
||||
"Date and Time".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
|
||||
"2 Feb, 2023 at 09:00am".toText(fontSize: 18, isBold: true),
|
||||
13.height,
|
||||
"Total Amount".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
"3000".toText(fontSize: 20, isBold: true),
|
||||
"SAR".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
|
||||
],
|
||||
),
|
||||
100.height,
|
||||
],
|
||||
).toWhiteContainer(width: double.infinity, allPading: 12),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,199 +0,0 @@
|
||||
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/config/routes.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/navigator.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
|
||||
class CustomerAppointmentSliderWidget extends StatelessWidget {
|
||||
final List<AppointmentListModel> myUpComingAppointments;
|
||||
|
||||
const CustomerAppointmentSliderWidget({Key? key, required this.myUpComingAppointments}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (myUpComingAppointments.isEmpty) {
|
||||
return InkWell(
|
||||
child: Container(
|
||||
height: 86,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
height: 24,
|
||||
width: 24,
|
||||
decoration: BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor),
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: MyColors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
"Add New Appointment".toText(
|
||||
fontSize: 15,
|
||||
isBold: true,
|
||||
color: MyColors.lightTextColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
).toWhiteContainer(width: double.infinity, margin: EdgeInsets.symmetric(horizontal: 21, vertical: 10));
|
||||
}
|
||||
return CarouselSlider.builder(
|
||||
options: CarouselOptions(
|
||||
height: 140,
|
||||
viewportFraction: 1.0,
|
||||
enlargeCenterPage: false,
|
||||
enableInfiniteScroll: false,
|
||||
),
|
||||
itemCount: myUpComingAppointments.length,
|
||||
itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) => BuildAppointmentContainerForCustomer(
|
||||
isForHome: true,
|
||||
appointmentListModel: myUpComingAppointments[itemIndex],
|
||||
onTapped: () => navigateWithName(context, AppRoutes.appointmentDetailView, arguments: myUpComingAppointments[itemIndex]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class BuildAppointmentContainerForCustomer extends StatelessWidget {
|
||||
final bool? isForHome;
|
||||
final AppointmentListModel? appointmentListModel;
|
||||
final Function() onTapped;
|
||||
|
||||
const BuildAppointmentContainerForCustomer({Key? key, this.isForHome = false, required this.onTapped, required this.appointmentListModel}) : super(key: key);
|
||||
|
||||
Widget showServices(String title, String icon, {bool isMoreText = false}) {
|
||||
return Row(
|
||||
children: [
|
||||
if (icon != "") ...[
|
||||
SvgPicture.asset(icon),
|
||||
8.width,
|
||||
],
|
||||
Flexible(
|
||||
child: title.toText(
|
||||
fontSize: 12,
|
||||
isBold: true,
|
||||
color: isMoreText ? MyColors.primaryColor : MyColors.black,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> buildServicesFromAppointment({required AppointmentListModel appointmentListModel}) {
|
||||
if (appointmentListModel.serviceAppointmentItems == null || appointmentListModel.serviceAppointmentItems!.isEmpty) {
|
||||
return [SizedBox()];
|
||||
}
|
||||
|
||||
if (appointmentListModel.serviceAppointmentItems!.length == 1) {
|
||||
return [
|
||||
showServices(
|
||||
appointmentListModel.serviceAppointmentItems![0].serviceItemName!,
|
||||
MyAssets.modificationsIcon,
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
List<Widget> servicesList = List.generate(
|
||||
2,
|
||||
(index) => showServices(
|
||||
appointmentListModel.serviceAppointmentItems![index].serviceItemName!,
|
||||
MyAssets.modificationsIcon,
|
||||
),
|
||||
);
|
||||
|
||||
if (appointmentListModel.serviceAppointmentItems!.length > 1) {
|
||||
servicesList.add(
|
||||
showServices(
|
||||
"+ ${appointmentListModel.serviceAppointmentItems!.length - 1} More",
|
||||
"",
|
||||
isMoreText: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
return servicesList;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
|
||||
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: [
|
||||
(appointmentListModel!.providerName ?? "").toText(color: MyColors.black, isBold: true, fontSize: 16),
|
||||
Row(
|
||||
children: [
|
||||
MyAssets.miniClock.buildSvg(height: 12),
|
||||
2.width,
|
||||
"${appointmentListModel!.duration ?? ""} ${appointmentListModel!.appointmentDate!.toFormattedDateWithoutTime()}".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: buildServicesFromAppointment(appointmentListModel: appointmentListModel!),
|
||||
),
|
||||
),
|
||||
const Icon(
|
||||
Icons.arrow_forward,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
).onPress(onTapped).toWhiteContainer(width: double.infinity, allPading: 12),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
import 'package:mc_common_app/view_models/appointments_view_model.dart';
|
||||
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/config/routes.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/generated/locale_keys.g.dart';
|
||||
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/utils/navigator.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/provider_details_card.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class BranchesFragment extends StatelessWidget {
|
||||
const BranchesFragment({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: MyColors.backgroundColor,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Consumer(
|
||||
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
|
||||
return Column(
|
||||
children: [
|
||||
16.height,
|
||||
FiltersList(
|
||||
filterList: appointmentsVM.providersFilterOptions,
|
||||
onFilterTapped: (index, selectedFilterId) => appointmentsVM.applyFilterOnProviders(index: index),
|
||||
),
|
||||
16.height,
|
||||
Expanded(
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
context.read<AppointmentsVM>().getAllNearBranches(isNeedToRebuild: true);
|
||||
},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height / 1.37,
|
||||
child: appointmentsVM.state == ViewState.busy
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: appointmentsVM.nearbyBranches.isEmpty
|
||||
? Center(child: LocaleKeys.no_branch.tr().toText(fontSize: 16, color: MyColors.lightTextColor))
|
||||
: ListView.separated(
|
||||
itemCount: appointmentsVM.nearbyBranches.length,
|
||||
itemBuilder: (context, index) {
|
||||
BranchDetailModel branchDetailModel = appointmentsVM.nearbyBranches[index];
|
||||
|
||||
return ProviderDetailsCard(
|
||||
onCardTapped: () {
|
||||
navigateWithName(context, AppRoutes.branchDetailPage, arguments: branchDetailModel);
|
||||
},
|
||||
providerImageUrl: MyAssets.bnCar,
|
||||
title: branchDetailModel.branchName ?? "",
|
||||
providerLocation: branchDetailModel.distanceKm.toString() + " KM",
|
||||
providerName: branchDetailModel.serviceProviderName ?? "",
|
||||
providerRatings: "4.9",
|
||||
services: branchDetailModel.branchServices,
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return 12.height;
|
||||
},
|
||||
padding: const EdgeInsets.all(12),
|
||||
)),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
import 'package:mc_common_app/view_models/requests_view_model.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/string_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/views/requests/widget/request_item.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class MyRequestsFragment extends StatelessWidget {
|
||||
const MyRequestsFragment({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
color: MyColors.backgroundColor,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
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());
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
Expanded(
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () async => await requestsVM.getRequests(isNeedToRebuild: true, appType: AppType.customer),
|
||||
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),
|
||||
],
|
||||
)
|
||||
: ListView.separated(
|
||||
itemBuilder: (context, index) {
|
||||
return RequestItem(request: requestsVM.myFilteredRequests[index], appType: AppType.customer);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return 16.height;
|
||||
},
|
||||
itemCount: requestsVM.myFilteredRequests.length,
|
||||
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16, top: 8),
|
||||
),
|
||||
))
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () => navigateWithName(context, AppRoutes.createRequestPage),
|
||||
backgroundColor: MyColors.darkPrimaryColor,
|
||||
child: const Icon(
|
||||
Icons.add,
|
||||
color: MyColors.white,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,60 +1,60 @@
|
||||
import 'package:car_customer_app/view_models/appointments_view_model.dart';
|
||||
import 'package:car_customer_app/view_models/providers_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/classes/consts.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/navigator.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/provider_details_card.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class ProvidersFragment extends StatelessWidget {
|
||||
const ProvidersFragment({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: MyColors.backgroundColor,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Consumer(
|
||||
builder: (BuildContext context, ProvidersVM providersVM, Widget? child) {
|
||||
return Column(
|
||||
children: [
|
||||
16.height,
|
||||
FiltersList(
|
||||
filterList: providersVM.providersFilterOptions,
|
||||
onFilterTapped: (index, selectedFilterId) => providersVM.applyFilterOnProviders(index: index),
|
||||
),
|
||||
16.height,
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: 30,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return ProviderDetailsCard(
|
||||
onCardTapped: () {
|
||||
if (context.read<AppointmentsVM>().providerCategories.isEmpty) {
|
||||
context.read<AppointmentsVM>().getProviderCategories();
|
||||
}
|
||||
navigateWithName(context, AppRoutes.bookAppointmenServicesView);
|
||||
},
|
||||
providerImageUrl: MyAssets.bnCar,
|
||||
providerLocation: " 3km",
|
||||
providerName: "Al Ahmed Maintenance",
|
||||
providerRatings: "4.9",
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
// import 'package:car_customer_app/view_models/appointments_view_model.dart';
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:mc_common_app/classes/consts.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/navigator.dart';
|
||||
// import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
|
||||
// import 'package:mc_common_app/widgets/common_widgets/provider_details_card.dart';
|
||||
// import 'package:provider/provider.dart';
|
||||
//
|
||||
// class ProvidersFragment extends StatelessWidget {
|
||||
// const ProvidersFragment({Key? key}) : super(key: key);
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return Container(
|
||||
// color: MyColors.backgroundColor,
|
||||
// width: double.infinity,
|
||||
// height: double.infinity,
|
||||
// child: Consumer(
|
||||
// builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
|
||||
// return Column(
|
||||
// children: [
|
||||
// 16.height,
|
||||
// FiltersList(
|
||||
// filterList: appointmentsVM.providersFilterOptions,
|
||||
// onFilterTapped: (index, selectedFilterId) => appointmentsVM.applyFilterOnProviders(index: index),
|
||||
// ),
|
||||
// 16.height,
|
||||
// Expanded(
|
||||
// child: Container(
|
||||
// child: ListView.builder(
|
||||
// shrinkWrap: true,
|
||||
// itemCount: 30,
|
||||
// itemBuilder: (BuildContext context, int index) {
|
||||
// return ProviderDetailsCard(
|
||||
// onCardTapped: () {
|
||||
// if (context.read<AppointmentsVM>().branchCategories.isEmpty) {
|
||||
// context.read<AppointmentsVM>().getBranchCategories();
|
||||
// }
|
||||
// navigateWithName(context, AppRoutes.bookAppointmenServicesView);
|
||||
// },
|
||||
// providerImageUrl: MyAssets.bnCar,
|
||||
// title: "",
|
||||
// providerLocation: " 3km",
|
||||
// providerName: "Al Ahmed Maintenance",
|
||||
// providerRatings: "4.9",
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SettingsFragment extends StatelessWidget {
|
||||
const SettingsFragment({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,111 @@
|
||||
|
||||
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 AdWidget extends StatelessWidget {
|
||||
final int count;
|
||||
|
||||
const AdWidget({Key? key, required this.count}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView.builder(
|
||||
itemCount: count,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 15),
|
||||
child: buildAdContainer(),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget buildAdContainer() {
|
||||
return Row(
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/images/bn_car.jpeg",
|
||||
width: 80,
|
||||
height: 80,
|
||||
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: [
|
||||
"Toyota Crolla".toText(fontSize: 16, isBold: true),
|
||||
Row(
|
||||
children: [
|
||||
"Model:".toText(
|
||||
color: MyColors.lightTextColor,
|
||||
),
|
||||
2.width,
|
||||
"2019".toText(),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
"Mileage:".toText(
|
||||
color: MyColors.lightTextColor,
|
||||
),
|
||||
2.width,
|
||||
"73,000 km".toText(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
"Riyadh".toText(
|
||||
color: MyColors.lightTextColor,
|
||||
),
|
||||
"9 Hours Ago".toText(
|
||||
color: MyColors.lightTextColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
8.height,
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
"30,000".toText(fontSize: 16, isBold: true),
|
||||
2.width,
|
||||
"SAR:".toText(
|
||||
color: MyColors.lightTextColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Icon(Icons.arrow_forward)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
).toWhiteContainer(width: double.infinity, allPading: 12);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
|
||||
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 AppointmentSliderWidget extends StatelessWidget {
|
||||
const AppointmentSliderWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
"Olaya Brach".toText(
|
||||
color: MyColors.lightTextColor,
|
||||
isBold: true,
|
||||
),
|
||||
"Abdullah Alhbas".toText(
|
||||
isBold: true,
|
||||
fontSize: 14,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
"Appt. On:".toText(
|
||||
color: MyColors.lightTextColor,
|
||||
),
|
||||
2.width,
|
||||
"19-Mar-2023 11:48 AM".toText(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
"1+ Requests".toText(fontSize: 10).toContainer(
|
||||
borderRadius: 15,
|
||||
backgroundColor: MyColors.lightGreyEAColor,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 6,
|
||||
horizontal: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
8.height,
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
showServices("Maintenance"),
|
||||
2.height,
|
||||
showServices("Accessories and Modification"),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Icon(
|
||||
Icons.arrow_forward,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
).toWhiteContainer(width: double.infinity, allPading: 0);
|
||||
}
|
||||
|
||||
Widget showServices(String title) {
|
||||
return Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.ac_unit,
|
||||
color: MyColors.primaryColor,
|
||||
size: 18,
|
||||
),
|
||||
8.width,
|
||||
title.toText(
|
||||
fontSize: 14,
|
||||
isBold: true,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
|
||||
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/widgets/extensions/extensions_widget.dart';
|
||||
|
||||
class ServiceProviderWidget extends StatelessWidget {
|
||||
const ServiceProviderWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
height: 150,
|
||||
child: ListView.builder(
|
||||
itemCount: 9,
|
||||
scrollDirection: Axis.horizontal,
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return SizedBox(
|
||||
width: 90,
|
||||
child: Column(
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/images/bn_car.jpeg",
|
||||
width: 80,
|
||||
height: 80,
|
||||
fit: BoxFit.cover,
|
||||
).toCircle(borderRadius: 100),
|
||||
8.height,
|
||||
"Olaya Branch".toText(fontSize: 14, isBold: true, textAlign: TextAlign.center),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
|
||||
class ViewAllWidget extends StatelessWidget {
|
||||
final String title;
|
||||
final String subTitle;
|
||||
|
||||
const ViewAllWidget({Key? key, required this.title, required this.subTitle}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: title.toText(isBold: true, fontSize: 18)),
|
||||
subTitle.toText(
|
||||
fontSize: 11,
|
||||
isBold: true,
|
||||
color: MyColors.primaryColor,
|
||||
textDecoration: TextDecoration.underline,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,223 @@
|
||||
import 'package:mc_common_app/view_models/appointments_view_model.dart';
|
||||
import 'package:car_customer_app/views/provider/sheet/items_list_sheet.dart';
|
||||
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/config/routes.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/generated/locale_keys.g.dart';
|
||||
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/navigator.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 BranchDetailPage extends StatefulWidget {
|
||||
final BranchDetailModel branchDetailModel;
|
||||
|
||||
BranchDetailPage({required this.branchDetailModel});
|
||||
|
||||
@override
|
||||
State<BranchDetailPage> createState() => _BranchDetailPageState();
|
||||
}
|
||||
|
||||
class _BranchDetailPageState extends State<BranchDetailPage> {
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
if (widget.branchDetailModel.branchServices!.length > 0) widget.branchDetailModel.branchServices?.first.isExpandedOrSelected = true;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: "Branch Detail",
|
||||
onBackButtonTapped: () {
|
||||
context.read<AppointmentsVM>().resetCategorySelectionBottomSheet();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.all(21),
|
||||
child: Column(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Image.asset(MyAssets.bnCar),
|
||||
12.height,
|
||||
"${widget.branchDetailModel.branchName} | ${widget.branchDetailModel.serviceProviderName}".toString().toText(
|
||||
fontSize: 16,
|
||||
isBold: true,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
(LocaleKeys.location.tr() + ":").toText(color: MyColors.lightTextColor, fontSize: 12),
|
||||
4.width,
|
||||
(widget.branchDetailModel.distanceKm.toString() + " km").toText(fontSize: 12, isBold: true),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
("Time" + ":").toText(color: MyColors.lightTextColor, fontSize: 12),
|
||||
4.width,
|
||||
"${widget.branchDetailModel.openTime} - ${widget.branchDetailModel.closeTime}".toText(fontSize: 12, isBold: true),
|
||||
],
|
||||
),
|
||||
2.height,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
//TODO: Needs to implement url launcher
|
||||
"Open Map Location".toText(
|
||||
fontSize: 12,
|
||||
isBold: true,
|
||||
color: MyColors.primaryColor,
|
||||
isUnderLine: true,
|
||||
),
|
||||
4.width,
|
||||
Image.asset(
|
||||
MyAssets.icRightUpPng,
|
||||
height: 6,
|
||||
width: 6,
|
||||
color: MyColors.primaryColor,
|
||||
),
|
||||
],
|
||||
).padding(EdgeInsets.symmetric(vertical: 6, horizontal: 2)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
"Provider Profile".toText(
|
||||
fontSize: 12,
|
||||
isBold: true,
|
||||
color: MyColors.primaryColor,
|
||||
isUnderLine: true,
|
||||
),
|
||||
2.width,
|
||||
Icon(
|
||||
Icons.arrow_forward,
|
||||
size: 12,
|
||||
color: MyColors.primaryColor,
|
||||
),
|
||||
],
|
||||
)
|
||||
.padding(EdgeInsets.symmetric(vertical: 6, horizontal: 2))
|
||||
.onPress(() => navigateWithName(context, AppRoutes.providerProfilePage, arguments: widget.branchDetailModel.serviceProviderId)),
|
||||
],
|
||||
),
|
||||
20.height,
|
||||
"Services Offer".toText(
|
||||
fontSize: 16,
|
||||
color: MyColors.lightTextColor,
|
||||
isBold: true,
|
||||
),
|
||||
if (widget.branchDetailModel.branchServices!.length == 0) "No Services Available".toText(fontSize: 12, isBold: true),
|
||||
showServicesList(),
|
||||
],
|
||||
).toWhiteContainer(
|
||||
width: double.infinity,
|
||||
allPading: 12,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
ShowFillButton(
|
||||
title: "Book Appointment",
|
||||
maxWidth: double.infinity,
|
||||
margin: EdgeInsets.all(21),
|
||||
onPressed: () {
|
||||
navigateWithName(context, AppRoutes.bookAppointmenServicesView);
|
||||
context.read<AppointmentsVM>().updateSelectedBranch(widget.branchDetailModel);
|
||||
},
|
||||
).toContainer(paddingAll: 0, backgroundColor: Colors.white),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget showServicesList() {
|
||||
return ListView.separated(
|
||||
itemBuilder: (context, index) {
|
||||
return ExpansionTile(
|
||||
tilePadding: EdgeInsets.zero,
|
||||
title: (widget.branchDetailModel.branchServices![index].serviceDescription ?? "").toText(
|
||||
fontSize: 16,
|
||||
isBold: true,
|
||||
),
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
showItem("Allowing home service:", (widget.branchDetailModel.branchServices![index].isAllowAppointment ?? false) ? "Yes" : "No", valueColor: Colors.green),
|
||||
showItem("Home service range", widget.branchDetailModel.branchServices![index].customerLocationRange.toString() + "KM"),
|
||||
showItem("Charges per KM", widget.branchDetailModel.branchServices![index].customerLocationRange.toString() + "SAR"),
|
||||
8.height,
|
||||
((widget.branchDetailModel.branchServices![index].itemsCount != null && widget.branchDetailModel.branchServices![index].itemsCount! > 0)
|
||||
? widget.branchDetailModel.branchServices![index].itemsCount.toString() + " items"
|
||||
: "No" + " items")
|
||||
.toText(
|
||||
fontSize: 12,
|
||||
isBold: true,
|
||||
color: MyColors.primaryColor,
|
||||
isUnderLine: true,
|
||||
),
|
||||
20.height,
|
||||
],
|
||||
).onPress(() {
|
||||
if (widget.branchDetailModel.branchServices![index].itemsCount != null && widget.branchDetailModel.branchServices![index].itemsCount! > 0) {
|
||||
showMyBottomSheet(context, child: ItemsListSheet(widget.branchDetailModel.branchServices![index].serviceProviderServiceId ?? 0));
|
||||
}
|
||||
}),
|
||||
],
|
||||
onExpansionChanged: (value) {
|
||||
setState(() {
|
||||
widget.branchDetailModel.branchServices![index].isExpandedOrSelected = value;
|
||||
});
|
||||
},
|
||||
backgroundColor: Colors.transparent,
|
||||
collapsedBackgroundColor: Colors.transparent,
|
||||
initiallyExpanded: widget.branchDetailModel.branchServices![index].isExpandedOrSelected,
|
||||
trailing: widget.branchDetailModel.branchServices![index].isExpandedOrSelected ? Icon(Icons.keyboard_arrow_up) : Icon(Icons.keyboard_arrow_down),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return Divider(
|
||||
height: 1,
|
||||
);
|
||||
},
|
||||
itemCount: widget.branchDetailModel.branchServices!.length,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
);
|
||||
}
|
||||
|
||||
Widget showItem(String item, String value, {Color valueColor = Colors.black}) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
item.toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
4.width,
|
||||
value.toText(fontSize: 12, color: valueColor, isBold: true),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
import 'package:mc_common_app/view_models/appointments_view_model.dart';
|
||||
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/config/routes.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/generated/locale_keys.g.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/navigator.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/provider_details_card.dart';
|
||||
import 'package:mc_common_app/widgets/empty_widget.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class ProviderProfilePage extends StatefulWidget {
|
||||
final int providerId;
|
||||
|
||||
ProviderProfilePage({required this.providerId});
|
||||
|
||||
@override
|
||||
State<ProviderProfilePage> createState() => _ProviderProfilePageState();
|
||||
}
|
||||
|
||||
class _ProviderProfilePageState extends State<ProviderProfilePage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
context.read<AppointmentsVM>().getBranchAndServices(widget.providerId);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: "Provider Details",
|
||||
),
|
||||
body: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
padding: EdgeInsets.all(21),
|
||||
child: Consumer<AppointmentsVM>(
|
||||
builder: (context, model, _) {
|
||||
return model.providerProfileModel == null
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: model.providerProfileModel == null
|
||||
? const EmptyWidget()
|
||||
: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
//TODO: company logo/banner not added form provider app yet
|
||||
Image.asset(MyAssets.bnCar),
|
||||
12.height,
|
||||
model.providerProfileModel!.companyName.toString().toText(
|
||||
fontSize: 16,
|
||||
isBold: true,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
("Mowater Member Since:").toText(color: MyColors.lightTextColor, fontSize: 12),
|
||||
4.width,
|
||||
//TODO: date is missing from API side
|
||||
"2023".toText(fontSize: 12, isBold: true),
|
||||
],
|
||||
),
|
||||
4.height,
|
||||
//TODO: company description not added form provider app yet
|
||||
// model.providerModel!.data!.companyDescription!.toText(color: MyColors.lightTextColor, fontSize: 12),
|
||||
"Some description about the provider and their years of experience and their reputation".toText(color: MyColors.lightTextColor, fontSize: 12),
|
||||
],
|
||||
).toWhiteContainer(
|
||||
width: double.infinity,
|
||||
allPading: 12,
|
||||
),
|
||||
12.height,
|
||||
model.providerProfileModel!.serviceProviderBranch == null
|
||||
? const Center(child: Text("No Branch Found"))
|
||||
: model.providerProfileModel!.serviceProviderBranch!.isEmpty
|
||||
? Center(child: Text(LocaleKeys.no_branch.tr()))
|
||||
: ListView.separated(
|
||||
itemBuilder: (context, index) {
|
||||
return ProviderDetailsCard(
|
||||
onCardTapped: () {
|
||||
navigateWithName(context, AppRoutes.branchDetailPage, arguments: model.providerProfileModel!.serviceProviderBranch![index]);
|
||||
},
|
||||
providerImageUrl: MyAssets.bnCar,
|
||||
title: model.providerProfileModel!.serviceProviderBranch![index].branchName ?? "",
|
||||
providerLocation: model.providerProfileModel!.serviceProviderBranch![index].distanceKm.toString() + " KM",
|
||||
providerName: model.providerProfileModel!.serviceProviderBranch![index].serviceProviderName ?? "",
|
||||
providerRatings: "4.9",
|
||||
services: model.providerProfileModel!.serviceProviderBranch![index].branchServices,
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return 12.height;
|
||||
},
|
||||
itemCount: model.providerProfileModel!.serviceProviderBranch!.length,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
import 'package:mc_common_app/models/services_models/item_model.dart';
|
||||
import 'package:mc_common_app/view_models/appointments_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/widgets/empty_widget.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class ItemsListSheet extends StatefulWidget {
|
||||
final int serviceId;
|
||||
|
||||
ItemsListSheet(this.serviceId);
|
||||
|
||||
@override
|
||||
State<ItemsListSheet> createState() => _ItemsListSheetState();
|
||||
}
|
||||
|
||||
class _ItemsListSheetState extends State<ItemsListSheet> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
context.read<AppointmentsVM>().getServiceItems(widget.serviceId);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: MediaQuery.of(context).size.height / 1.2,
|
||||
child: Consumer<AppointmentsVM>(
|
||||
builder: (context, appointmentsVM, _) {
|
||||
return appointmentsVM.serviceItemsFromApi.isEmpty
|
||||
? const EmptyWidget()
|
||||
: ListView.separated(
|
||||
itemCount: appointmentsVM.serviceItemsFromApi.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
ItemData serviceItemModel = appointmentsVM.serviceItemsFromApi[index];
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
serviceItemModel.name.toString().toText(fontSize: 16, isBold: true),
|
||||
4.height,
|
||||
showItem("Available for appointment:", (serviceItemModel.isAllowAppointment ?? false) ? "Yes" : "No", valueColor: Colors.green),
|
||||
showItem("Allowing Workshop service:", (serviceItemModel.isAppointmentCompanyLoc ?? false) ? "Yes" : "No", valueColor: Colors.green),
|
||||
showItem("Allowing home service:", (serviceItemModel.isAppointmentCustomerLoc ?? false) ? "Yes" : "No", valueColor: Colors.green),
|
||||
12.height,
|
||||
"Service Amount".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
serviceItemModel.price!.toText(fontSize: 22, isBold: true),
|
||||
2.width,
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 4),
|
||||
child: "SAR".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.all(4.0),
|
||||
// child: SvgPicture.asset(
|
||||
// MyAssets.icEdit,
|
||||
// width: 16,
|
||||
// height: 16,
|
||||
// ),
|
||||
// )
|
||||
],
|
||||
),
|
||||
).toWhiteContainer(width: double.infinity, allPading: 12);
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return 12.height;
|
||||
},
|
||||
padding: const EdgeInsets.all(20),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget showItem(String item, String value, {Color valueColor = Colors.black}) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
item.toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
4.width,
|
||||
value.toText(fontSize: 12, color: valueColor, isBold: true),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||