import ' dart:async ' ;
import ' package:flutter/material.dart ' ;
import ' package:mc_common_app/classes/app_state.dart ' ;
import ' package:mc_common_app/classes/consts.dart ' ;
import ' package:mc_common_app/config/dependencies.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/advertisment_models/ad_details_model.dart ' ;
import ' package:mc_common_app/models/advertisment_models/special_service_model.dart ' ;
import ' package:mc_common_app/models/general/widgets_models.dart ' ;
import ' package:mc_common_app/theme/colors.dart ' ;
import ' package:mc_common_app/utils/dialogs_and_bottomsheets.dart ' ;
import ' package:mc_common_app/utils/enums.dart ' ;
import ' package:mc_common_app/utils/navigator.dart ' ;
import ' package:mc_common_app/utils/utils.dart ' ;
import ' package:mc_common_app/view_models/ad_view_model.dart ' ;
import ' package:mc_common_app/view_models/payment_view_model.dart ' ;
import ' package:mc_common_app/views/advertisement/ad_duration_selection_sheet_content.dart ' ;
import ' package:mc_common_app/views/advertisement/ads_images_slider.dart ' ;
import ' package:mc_common_app/views/appointments/widgets/custom_calender_widget.dart ' ;
import ' package:mc_common_app/widgets/bottom_sheet.dart ' ;
import ' package:mc_common_app/widgets/button/show_fill_button.dart ' ;
import ' package:mc_common_app/widgets/common_widgets/app_bar.dart ' ;
import ' package:mc_common_app/widgets/common_widgets/info_bottom_sheet.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 ' ;
import ' package:mc_common_app/widgets/txt_field.dart ' ;
import ' package:provider/provider.dart ' ;
class AdsDetailView extends StatefulWidget {
final AdDetailsModel adDetails ;
const AdsDetailView ( { Key ? key , required this . adDetails } ) : super ( key: key ) ;
@ override
State < AdsDetailView > createState ( ) = > _AdsDetailViewState ( ) ;
}
class _AdsDetailViewState extends State < AdsDetailView > {
@ override
void initState ( ) {
scheduleMicrotask ( ( ) {
onAdDetailsLoaded ( ) ;
} ) ;
super . initState ( ) ;
}
Future < void > onAdDetailsLoaded ( ) async {
context . read < PaymentVM > ( ) . updateCurrentAdId ( id: widget . adDetails . id ! ) ;
if ( ( widget . adDetails . isMyAd ? ? false ) & & ( widget . adDetails . adPostStatus = = AdPostStatus . reserved ) ) {
await context . read < AdVM > ( ) . getAdBankingAccountInfo ( adId: widget . adDetails . id ! ) ;
}
}
void deleteAdBottomSheet ( BuildContext context ) {
AdVM adVM = context . read < AdVM > ( ) ;
return actionConfirmationBottomSheet (
context: context ,
title: " Do you want to delete the ad? " . toText ( fontSize: 28 , isBold: true , letterSpacing: - 1.44 ) ,
subtitle: " Your ad will be permanently deleted and you cannot undo this action. " ,
actionButtonYes: Expanded (
child: ShowFillButton (
maxHeight: 55 ,
title: " Yes " ,
fontSize: 15 ,
onPressed: ( ) {
Navigator . pop ( context ) ;
adVM . deleteMyAd ( context , adId: widget . adDetails . id ! ) ;
} ,
) ,
) ,
actionButtonNo: Expanded (
child: ShowFillButton (
maxHeight: 55 ,
isFilled: false ,
borderColor: MyColors . darkPrimaryColor ,
title: " No " ,
txtColor: MyColors . darkPrimaryColor ,
fontSize: 15 ,
onPressed: ( ) {
Navigator . pop ( context ) ;
} ,
) ,
) ,
) ;
}
@ override
Widget build ( BuildContext context ) {
return Scaffold (
appBar: CustomAppBar (
title: " Ads " ,
profileImageUrl: MyAssets . bnCar ,
isRemoveBackButton: false ,
isDrawerEnabled: false ,
actions: [
( ( widget . adDetails . isMyAd ? ? false ) & & ( widget . adDetails . adPostStatus ! = AdPostStatus . reserved )
? IconButton (
icon: const Icon ( Icons . delete_outline , color: MyColors . redColor ) ,
onPressed: ( ) {
return deleteAdBottomSheet ( context ) ;
} ,
)
: IconButton (
icon: const Icon ( Icons . chat_outlined , color: Colors . black ) ,
onPressed: ( ) { } ,
) )
. toContainer (
margin: const EdgeInsets . fromLTRB ( 0 , 8 , 21 , 8 ) ,
paddingAll: 0 ,
padding: const EdgeInsets . only ( right: 21 ) ,
borderRadius: 100 ,
borderColor: MyColors . lightGreyEFColor ,
isEnabledBorder: true ,
height: 40 ,
width: 42 ,
)
] ,
onTap: ( ) { } ,
) ,
body: Container (
padding: const EdgeInsets . only ( bottom: 10 , left: 21 , right: 21 ) ,
child: Column (
children: [
Expanded (
child: ListView (
children: [
Column (
mainAxisSize: MainAxisSize . min ,
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
CarouselWithIndicatorDemo ( vehicleImages: widget . adDetails . vehicle ! . image ! ) ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" ${ widget . adDetails . vehicle ! . vehicleTitle } | ${ widget . adDetails . vehicle ! . color ! . label } " . toText ( fontSize: 18 , isBold: true ) ,
( widget . adDetails . vehicle ! . cityName ? ? " " ) . toText ( fontSize: 10 , isBold: true , color: MyColors . lightTextColor ) ,
] ,
) ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
Row (
children: [
" Model: " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor ) ,
" ${ widget . adDetails . vehicle ! . modelyear ! . label } " . toText (
fontSize: 14 ,
isBold: true ,
) ,
] ,
) ,
" ${ widget . adDetails . vehicle ! . countryID } " . toText ( fontSize: 10 , isBold: true , color: MyColors . lightTextColor ) ,
] ,
) ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
Row (
children: [
" Mileage: " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor ) ,
" ${ widget . adDetails . vehicle ! . mileage ! . mileageEnd } Km " . toText (
fontSize: 14 ,
isBold: true ,
) ,
] ,
) ,
widget . adDetails . createdOn ! = null
? DateTime . parse ( widget . adDetails . createdOn ! ) . getTimeAgo ( ) . toText ( fontSize: 10 , isBold: true , color: MyColors . lightTextColor )
: const SizedBox ( ) ,
] ,
) ,
Row (
children: [
" Transmission: " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor ) ,
" ${ widget . adDetails . vehicle ! . transmission ! . label } " . toText (
fontSize: 14 ,
isBold: true ,
) ,
] ,
) ,
8. height ,
" Description: " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor ) ,
" ${ widget . adDetails . vehicle ! . vehicleDescription } " . toText (
fontSize: 14 ,
isBold: true ,
) ,
if ( widget . adDetails . isMyAd ? ? false ) . . . [
8. height ,
" Demand: " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor ) ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
widget . adDetails . vehicle ! . demandAmount ! . toInt ( ) . toString ( ) . toText ( fontSize: 30 , height: 1.2 , isBold: true ) ,
" SAR " . toText ( fontSize: 15 , isBold: true , color: MyColors . lightTextColor ) . paddingOnly ( bottom: 5 ) ,
] ,
) ,
if ( widget . adDetails . adPostStatus = = AdPostStatus . expired ) . . . [
8. height ,
const Divider ( thickness: 1 , height: 1 ) ,
8. height ,
" Your Ad Duration time is over. " . toText (
color: MyColors . redColor ,
fontSize: 12 ,
isItalic: true ,
) ,
] ,
]
] ,
) . toWhiteContainer ( width: double . infinity , allPading: 12 ) ,
12. height ,
Consumer ( builder: ( BuildContext context , AdVM adVM , Widget ? child ) {
if ( adVM . adsBankDetailsModel ! = null ) {
return Column (
mainAxisSize: MainAxisSize . min ,
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
" Bank Details " . toText ( fontSize: 18 , isBold: true ) ,
// Row(
// children: [
// "Full Name: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
// "${widget.adDetails.vehicle!.vehicleDescription}".toText(
// fontSize: 14,
// isBold: true,
// ),
// ],
// ),
Row (
children: [
" Bank Name: " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor ) ,
( adVM . adsBankDetailsModel ! . bankName ? ? " " ) . toText (
fontSize: 14 ,
isBold: true ,
) ,
] ,
) ,
Row (
children: [
" IBAN: " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor ) ,
( adVM . adsBankDetailsModel ! . iban ? ? " " ) . toText (
fontSize: 14 ,
isBold: true ,
) ,
] ,
) ,
] ,
) . toWhiteContainer ( width: double . infinity , allPading: 12 ) ;
}
return const SizedBox . shrink ( ) ;
} )
] ,
) ,
) ,
SizedBox (
child: Column (
children: [
if ( ! ( widget . adDetails . isMyAd ? ? false ) ) . . . [
const Divider ( thickness: 1 , height: 1 ) ,
18. height ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
widget . adDetails . vehicle ! . demandAmount ! . toInt ( ) . toString ( ) . toText ( fontSize: 30 , isBold: true ) ,
" SAR " . toText ( fontSize: 15 , isBold: true , color: MyColors . lightTextColor ) . paddingOnly ( bottom: 5 ) ,
] ,
) ,
14. height ,
] ,
widget . adDetails . isMyAd ? ? false ? BuildAdDetailsActionButtonForMyAds ( adDetailsModel: widget . adDetails ) : BuildAdDetailsActionButtonForExploreAds ( adDetailsModel: widget . adDetails ) ,
] ,
) ,
)
] ,
) ,
) ,
) ;
}
}
class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
final AdDetailsModel adDetailsModel ;
const BuildAdDetailsActionButtonForExploreAds ( { Key ? key , required this . adDetailsModel } ) : super ( key: key ) ;
void reserveAdPriceBreakDownClicked ( BuildContext context , AdDetailsModel adDetailsModel ) {
showModalBottomSheet (
context: context ,
isScrollControlled: true ,
enableDrag: true ,
builder: ( BuildContext context ) {
return InfoBottomSheet (
title: " Reserve Ad " . toText ( fontSize: 24 , isBold: true ) ,
description: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" Reservation Amounts " . toText ( fontSize: 16 , isBold: true ) ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
" ${ adDetailsModel . reservePrice } " . toText ( fontSize: 19 , isBold: true ) ,
2. width ,
" SAR " . toText ( color: MyColors . lightTextColor , fontSize: 10 , isBold: true ) . paddingOnly ( bottom: 3 ) ,
] ,
)
] ,
) ,
const Divider ( ) ,
" Below Amount that you will pay later " . toText ( fontSize: 12 ) ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
" Car Price " . toText ( fontSize: 16 , isBold: true ) ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
" ${ adDetailsModel . vehicle ! . demandAmount ? ? 0.0 } " . toText ( fontSize: 19 , isBold: true ) ,
2. width ,
" SAR " . toText ( color: MyColors . lightTextColor , fontSize: 10 , isBold: true ) . paddingOnly ( bottom: 3 ) ,
] ,
)
] ,
) ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
mainAxisAlignment: MainAxisAlignment . end ,
children: [
" VAT Excluded " . toText ( fontSize: 10 , isBold: true ) ,
] ,
) ,
const Divider ( ) ,
" Special Services " . toText ( fontSize: 16 , isBold: true ) ,
5. height ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" Car insurance Service " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor , fontWeight: FontWeight . w500 ) ,
" To be Decided " . toText ( fontSize: 12 , isBold: true ) ,
] ,
) ,
5. height ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" Registration & Car Plates " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor ) ,
" To be Decided " . toText ( fontSize: 12 , isBold: true ) ,
] ,
) ,
5. height ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" Home Delivery Service " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor ) ,
" To be Decided " . toText ( fontSize: 12 , isBold: true ) ,
] ,
) ,
12. height ,
" Special service charges will be added based on desired insurance and delivery Location " . toText ( fontSize: 12 ) ,
30. height ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" Total Amount " . toText ( fontSize: 16 , isBold: true ) ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
" ${ ( adDetailsModel . vehicle ! . demandAmount ? ? 0.0 ) } " . toText ( fontSize: 19 , isBold: true ) ,
2. width ,
" SAR " . toText ( color: MyColors . lightTextColor , fontSize: 10 , isBold: true ) . paddingOnly ( bottom: 3 ) ,
] ,
)
] ,
) ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
mainAxisAlignment: MainAxisAlignment . end ,
children: [
" Estimated " . toText ( fontSize: 10 , isBold: true ) ,
] ,
) ,
44. height ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
const Icon (
Icons . warning ,
color: MyColors . adPendingStatusColor ,
size: 19 ,
) . paddingOnly ( bottom: 2 ) ,
3. width ,
" Some services are mandatory while reserving the Ad. " . toText (
color: MyColors . adPendingStatusColor ,
fontSize: 12 ,
isItalic: true ,
) ,
] ,
) ,
15. height ,
Row (
children: [
Expanded (
child: ShowFillButton (
maxHeight: 55 ,
title: " Complete Reservation " ,
onPressed: ( ) {
Navigator . pop ( context ) ;
navigateWithName ( context , AppRoutes . paymentMethodsView , arguments: PaymentTypes . adReserve ) ;
} ,
) ,
) ,
] ,
) ,
19. height ,
] ,
) ) ;
} ) ;
}
Widget reserveAdAction ( BuildContext context , AdDetailsModel adDetailsModel ) {
return Row (
children: [
Expanded (
child: ShowFillButton (
maxHeight: 55 ,
title: " Reserve Ad " ,
onPressed: ( ) {
reserveAdPriceBreakDownClicked ( context , adDetailsModel ) ;
// navigateWithName(context, AppRoutes.paymentMethodsView);
} ,
) ,
) ,
if ( adDetailsModel . whatsAppNo ! = null ) . . . [
8. width ,
Container (
height: 55 ,
width: 55 ,
alignment: Alignment . center ,
decoration: BoxDecoration ( border: Border . all ( color: MyColors . black , width: 2 ) ) ,
//TODO: It Will be replaced by a WhatsApp Icon
child: const Icon ( Icons . message , color: MyColors . black ) ,
) . onPress ( ( ) {
Utils . openNumberViaWhatsApp ( phoneNumber: adDetailsModel . whatsAppNo ? ? " " ) ;
} ) ,
] ,
if ( adDetailsModel . phoneNo ! = null ) . . . [
8. width ,
Container (
height: 55 ,
width: 55 ,
alignment: Alignment . center ,
decoration: BoxDecoration ( border: Border . all ( color: MyColors . black , width: 2 ) ) ,
child: const Icon ( Icons . phone , color: MyColors . black ) ,
) . onPress ( ( ) {
Utils . openNumberViaCaller ( phoneNumber: adDetailsModel . phoneNo ? ? " " ) ;
} ) ,
]
] ,
) ;
}
Widget defaultActionForProviderAndCustomer ( BuildContext context , AdDetailsModel adDetailsModel ) {
return ( adDetailsModel . phoneNo = = null )
? Row (
children: [
Expanded (
child: ShowFillButton (
maxHeight: 55 ,
title: " Contact " ,
fontSize: 18 ,
isBold: false ,
iconWidget: const Padding (
padding: EdgeInsets . only ( right: 10 ) ,
child: Icon ( Icons . phone , color: MyColors . white , size: 24 ) ,
) ,
onPressed: ( ) {
Utils . openNumberViaCaller ( phoneNumber: adDetailsModel . phoneNo ? ? " " ) ;
} ,
) ,
) ,
if ( adDetailsModel . whatsAppNo = = null ) . . . [
8. width ,
Container (
height: 55 ,
width: 55 ,
alignment: Alignment . center ,
decoration: BoxDecoration ( border: Border . all ( color: MyColors . black , width: 2 ) ) ,
//TODO: It Will be replaced by a WhatsApp Icon
child: const Icon ( Icons . message , color: MyColors . black ) ,
) . onPress ( ( ) {
Utils . openNumberViaWhatsApp ( phoneNumber: adDetailsModel . whatsAppNo ? ? " " ) ;
} ) ,
] ,
] ,
)
: const SizedBox . shrink ( ) ;
}
@ override
Widget build ( BuildContext context ) {
switch ( adDetailsModel . createdByRoleEnum ! ) {
case CreatedByRoleEnum . customer:
case CreatedByRoleEnum . provider:
return defaultActionForProviderAndCustomer ( context , adDetailsModel ) ;
case CreatedByRoleEnum . admin:
return reserveAdAction ( context , adDetailsModel ) ;
case CreatedByRoleEnum . allAds:
return const SizedBox . shrink ( ) ;
}
}
}
class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
final AdDetailsModel adDetailsModel ;
const BuildAdDetailsActionButtonForMyAds ( { Key ? key , required this . adDetailsModel } ) : super ( key: key ) ;
void onBookPhotographyServiceClicked ( BuildContext context , { required AdDetailsModel adDetailsModel } ) async {
AdVM adVM = context . read < AdVM > ( ) ;
if ( adVM . photoOfficeSelectedId . selectedId = = - 1 ) {
adVM . getPhotographyServiceScheduleListByOffices ( latitude: 46.703430 , longitude: 24.625720 , isNeedToRebuild: true ) ; // TODO: These Lat Long need to be dynamic
}
return showModalBottomSheet (
context: context ,
isScrollControlled: true ,
enableDrag: true ,
builder: ( BuildContext context ) {
return Consumer ( builder: ( BuildContext context , AdVM adVM , Widget ? child ) {
return InfoBottomSheet (
title: " Set Date and Time " . toText ( fontSize: 28 , isBold: true , letterSpacing: - 1.44 , height: 1.2 ) ,
description: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
25. height ,
adVM . state = = ViewState . busy
? const Center ( child: CircularProgressIndicator ( ) )
: Builder (
builder: ( context ) {
List < DropValue > vehicleCitiesDrop = [ ] ;
for ( int i = 0 ; i < adVM . photoSSSchedulesByOffices . length ; i + + ) {
var element = adVM . photoSSSchedulesByOffices [ i ] ;
vehicleCitiesDrop . add ( DropValue ( element . photoOfficeID ? . toInt ( ) ? ? 0 , element . photoOfficeName ? ? " " , i . toString ( ) ) ) ;
}
return DropdownField (
( DropValue value ) = > adVM . updatePhotoOfficeSelectedId ( SelectionModel ( selectedId: value . id , selectedOption: value . value , itemPrice: value . subValue ) ) ,
// here the item price is the index of the selected option
list: vehicleCitiesDrop ,
dropdownValue: adVM . photoOfficeSelectedId . selectedId ! = - 1 ? DropValue ( adVM . photoOfficeSelectedId . selectedId , adVM . photoOfficeSelectedId . selectedOption , " " ) : null ,
hint: " Select Office " ,
errorValue: adVM . photoOfficeSelectedId . errorValue ,
) ;
} ,
) ,
if ( adVM . photoOfficeSelectedId . selectedId ! = - 1 ) . . . [
9. height ,
CustomCalenderAppointmentWidget (
customTimeDateSlotList: adVM . selectedPhotoSSSchedulesByOffice . customTimeDateSlotList ? ? [ ] ,
onDateSelected: ( dateIndex ) = > adVM . updateSelectedPhotoOfficeAppointmentDate ( dateIndex: dateIndex ) ,
selectedCustomTimeDateSlotModel: adVM . selectedPhotoSSSchedulesByOffice . selectedCustomTimeDateSlotModel ,
) ,
if ( adVM . selectedPhotoSSSchedulesByOffice . selectedCustomTimeDateSlotModel ! = null & & adVM . selectedPhotoSSSchedulesByOffice . selectedCustomTimeDateSlotModel ! . date ! = null ) . . . [
5. height ,
Row (
mainAxisAlignment: MainAxisAlignment . start ,
children: [
( " Available Slots " ) . toText ( fontSize: 14 , isBold: true ) ,
] ,
) ,
5. height ,
SizedBox (
width: double . infinity ,
child: BuildTimeSlots (
timeSlots: adVM . selectedPhotoSSSchedulesByOffice . customTimeDateSlotList ! [ adVM . selectedPhotoSSSchedulesByOffice . selectedDateIndex ! ] . availableSlots ? ? [ ] ,
onPressed: ( slotIndex ) = > adVM . updateSelectedAppointmentSlotByDate ( slotIndex: slotIndex ) ,
) ,
) ,
20. height ,
] ,
5. height ,
Row (
children: [
Expanded (
child: ShowFillButton (
maxHeight: 55 ,
title: " Book and Pay " ,
fontSize: 15 ,
onPressed: ( ) {
adVM . onAdSSBookAppointmentPressed ( context , adDetailsModel: adDetailsModel , adsSpecialServiceID: 1 ) ; //1 for photography Service
} ,
) ,
) ,
] ,
) ,
] ,
19. height ,
] ,
) ) ;
} ) ;
} ,
) ;
}
void reserveAdPriceBreakDownClicked ( BuildContext context ) {
showModalBottomSheet (
context: context ,
isScrollControlled: true ,
enableDrag: true ,
builder: ( BuildContext context ) {
return InfoBottomSheet (
title: " Reserve Ad " . toText ( fontSize: 24 , isBold: true ) ,
description: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" Reservation Amounts " . toText ( fontSize: 16 , isBold: true ) ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
" 500 " . toText ( fontSize: 19 , isBold: true ) ,
2. width ,
" SAR " . toText ( color: MyColors . lightTextColor , fontSize: 10 , isBold: true ) . paddingOnly ( bottom: 3 ) ,
] ,
)
] ,
) ,
const Divider ( ) ,
" Below Amount that you will pay later " . toText ( fontSize: 12 ) ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
" Car Price " . toText ( fontSize: 16 , isBold: true ) ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
" 30,000 " . toText ( fontSize: 19 , isBold: true ) ,
2. width ,
" SAR " . toText ( color: MyColors . lightTextColor , fontSize: 10 , isBold: true ) . paddingOnly ( bottom: 3 ) ,
] ,
)
] ,
) ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" Tax " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor ) ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
" 4,500 " . toText ( fontSize: 16 , isBold: true ) ,
2. width ,
" SAR " . toText ( color: MyColors . lightTextColor , fontSize: 10 , isBold: true ) . paddingOnly ( bottom: 0 ) ,
] ,
)
] ,
) ,
const Divider ( ) ,
" Special Services " . toText ( fontSize: 16 , isBold: true ) ,
5. height ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" Car insurance Service " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor , fontWeight: FontWeight . w500 ) ,
" To be Decided " . toText ( fontSize: 12 , isBold: true ) ,
] ,
) ,
5. height ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" Registration & Car Plates " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor ) ,
" To be Decided " . toText ( fontSize: 12 , isBold: true ) ,
] ,
) ,
5. height ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" Home Delivery Service " . toText ( fontSize: 14 , isBold: true , color: MyColors . lightTextColor ) ,
" To be Decided " . toText ( fontSize: 12 , isBold: true ) ,
] ,
) ,
12. height ,
" Special service charges will be added based on desired insurance and delivery Location " . toText ( fontSize: 12 ) ,
30. height ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
" Total Amount " . toText ( fontSize: 16 , isBold: true ) ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
" 34,500 " . toText ( fontSize: 19 , isBold: true ) ,
2. width ,
" SAR " . toText ( color: MyColors . lightTextColor , fontSize: 10 , isBold: true ) . paddingOnly ( bottom: 3 ) ,
] ,
)
] ,
) ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
mainAxisAlignment: MainAxisAlignment . end ,
children: [
" Estimated " . toText ( fontSize: 10 , isBold: true ) ,
] ,
) ,
44. height ,
Row (
crossAxisAlignment: CrossAxisAlignment . end ,
children: [
const Icon (
Icons . warning ,
color: MyColors . adPendingStatusColor ,
size: 19 ,
) . paddingOnly ( bottom: 2 ) ,
3. width ,
" Some services are mandatory while reserving the Ad. " . toText (
color: MyColors . adPendingStatusColor ,
fontSize: 12 ,
isItalic: true ,
) ,
] ,
) ,
15. height ,
Row (
children: [
Expanded (
child: ShowFillButton (
maxHeight: 55 ,
title: " Complete Reservation " ,
onPressed: ( ) {
Navigator . pop ( context ) ;
navigateWithName ( context , AppRoutes . paymentMethodsView ) ;
} ,
) ,
) ,
] ,
) ,
19. height ,
] ,
) ) ;
} ) ;
}
Widget pendingForReviewAction ( { required String pendingText } ) {
return Column (
crossAxisAlignment: CrossAxisAlignment . center ,
children: [
Row (
children: [
Expanded (
child: ShowFillButton (
backgroundColor: MyColors . grey98Color . withOpacity ( 0.3 ) ,
txtColor: MyColors . lightTextColor ,
maxHeight: 55 ,
title: pendingText ,
isBold: false ,
onPressed: ( ) { } ,
) ,
) ,
] ,
) ,
] ,
) ;
}
Widget pendingForPaymentAction ( BuildContext context , { required AdDetailsModel ad } ) {
SpecialServiceModelForAds ? photoSpecialServiceModel ;
for ( var element in ad . specialservice ! ) {
if ( element . specialServiceID = = 1 ) {
photoSpecialServiceModel = element ;
}
}
bool payButtonStatus = photoSpecialServiceModel ! = null & & photoSpecialServiceModel . appointmentStatusId = = 0 ;
return Column (
crossAxisAlignment: CrossAxisAlignment . center ,
children: [
if ( photoSpecialServiceModel ! = null & & photoSpecialServiceModel . appointmentStatusId = = 0 ) . . . [
Row (
children: [
Expanded (
child: ShowFillButton (
isFilled: false ,
borderColor: MyColors . darkPrimaryColor ,
maxHeight: 55 ,
title: " Book ${ photoSpecialServiceModel . name } " ,
txtColor: MyColors . darkPrimaryColor ,
onPressed: ( ) {
onBookPhotographyServiceClicked ( context , adDetailsModel: adDetailsModel ) ;
} ,
) ,
) ,
] ,
) ,
8. height ,
] ,
Row (
children: [
Expanded (
child: ShowFillButton (
maxHeight: 55 ,
backgroundColor: payButtonStatus ? MyColors . grey98Color . withOpacity ( 0.3 ) : MyColors . darkPrimaryColor ,
txtColor: payButtonStatus ? MyColors . lightTextColor : MyColors . white ,
isBold: false ,
title: " Pay Now " ,
onPressed: ( ) {
if ( photoSpecialServiceModel = = null ) {
navigateWithName ( context , AppRoutes . paymentMethodsView , arguments: PaymentTypes . ads ) ;
}
} ,
) ,
) ,
] ,
) ,
] ,
) ;
}
Widget markAsSoldAction ( BuildContext context ) {
AdVM adVM = context . read < AdVM > ( ) ;
return Column (
crossAxisAlignment: CrossAxisAlignment . center ,
children: [
Row (
children: [
Expanded (
child: ShowFillButton (
maxHeight: 55 ,
title: " Mark As Sold " ,
isBold: false ,
onPressed: ( ) {
adVM . markAdAsSold ( context , adId: adDetailsModel . id ! ) ;
} ,
) ,
) ,
] ,
) ,
8. height ,
Row (
children: [
Expanded (
child: ShowFillButton (
isFilled: false ,
borderColor: MyColors . redColor ,
maxHeight: 55 ,
title: " Deactivate Ad " ,
txtColor: MyColors . redColor ,
onPressed: ( ) {
return actionConfirmationBottomSheet (
context: context ,
title: " Do you want to the Deactivate this Ad? " . toText ( fontSize: 28 , isBold: true , letterSpacing: - 1.44 ) ,
subtitle: " We will stop showing this ad to the buyers. " ,
actionButtonYes: Expanded (
child: ShowFillButton (
maxHeight: 55 ,
title: " Yes " ,
fontSize: 15 ,
onPressed: ( ) {
Navigator . pop ( context ) ;
adVM . deactivateTheAd ( context , adId: adDetailsModel . id ! ) ;
} ,
) ,
) ,
actionButtonNo: Expanded (
child: ShowFillButton (
maxHeight: 55 ,
isFilled: false ,
borderColor: MyColors . darkPrimaryColor ,
title: " No " ,
txtColor: MyColors . darkPrimaryColor ,
fontSize: 15 ,
onPressed: ( ) {
Navigator . pop ( context ) ;
} ,
) ,
) ,
) ;
} ,
) ,
) ,
] ,
) ,
] ,
) ;
}
Future buildCancelReservationBottomSheet ( BuildContext context , { required AdDetailsModel adDetails } ) {
return showModalBottomSheet (
context: context ,
isScrollControlled: true ,
enableDrag: true ,
builder: ( BuildContext context ) {
return InfoBottomSheet (
title: " Cancel Reservation " . toText ( fontSize: 28 , isBold: true , letterSpacing: - 1.44 ) ,
description: Padding (
padding: EdgeInsets . only ( bottom: MediaQuery . of ( context ) . viewInsets . bottom ) ,
child: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
12. height ,
TxtField (
maxLines: 5 ,
value: " " ,
errorValue: " " ,
keyboardType: TextInputType . text ,
hint: " Reason for cancellation " ,
onChanged: ( v ) = > ( ) { } ,
) ,
] ,
) ,
25. height ,
ShowFillButton (
title: " Submit " ,
onPressed: ( ) {
Navigator . pop ( context ) ;
AdVM adVM = context . read < AdVM > ( ) ;
return actionConfirmationBottomSheet (
context: context ,
title: " Do you want to cancel the reservation? " . toText ( fontSize: 28 , isBold: true , letterSpacing: - 1.44 ) ,
subtitle: " Your ad reservation will be cancelled and this ad will be again visible to everyone to buy. " ,
actionButtonYes: Expanded (
child: ShowFillButton (
maxHeight: 55 ,
title: " Yes " ,
fontSize: 15 ,
onPressed: ( ) {
Navigator . pop ( context ) ;
adVM . cancelMyAdReservation ( context , adId: adDetails . id ! ) ;
} ,
) ,
) ,
actionButtonNo: Expanded (
child: ShowFillButton (
maxHeight: 55 ,
isFilled: false ,
borderColor: MyColors . darkPrimaryColor ,
title: " No " ,
txtColor: MyColors . darkPrimaryColor ,
fontSize: 15 ,
onPressed: ( ) {
Navigator . pop ( context ) ;
} ,
) ,
) ,
) ;
} ,
maxWidth: double . infinity ,
) ,
19. height ,
] ,
) ,
) ) ;
} ,
) ;
}
Widget cancelReservationAction ( BuildContext context , { required AdDetailsModel adDetails } ) {
return Row (
children: [
Expanded (
child: ShowFillButton (
borderColor: MyColors . redColor ,
txtColor: MyColors . redColor ,
isFilled: false ,
fontSize: 16 ,
maxHeight: 55 ,
title: " Cancel Reservation " ,
onPressed: ( ) {
buildCancelReservationBottomSheet ( context , adDetails: adDetails ) ;
} ) ,
) ,
] ,
) ;
}
Widget expiredAdAction ( BuildContext context ) {
return Row (
children: [
Expanded (
child: ShowFillButton (
fontSize: 16 ,
maxHeight: 55 ,
title: " Extend Ad " ,
onPressed: ( ) {
final AdVM adVM = context . read < AdVM > ( ) ;
return actionConfirmationBottomSheet (
context: context ,
title: " Do you want to update the Ad Details? " . toText ( fontSize: 28 , isBold: true , letterSpacing: - 1.44 ) ,
subtitle: " You can change the ad duration and details before extending the ad. " ,
actionButtonYes: Expanded (
child: ShowFillButton (
maxHeight: 55 ,
title: " Yes " ,
fontSize: 15 ,
onPressed: ( ) {
Navigator . pop ( context ) ;
adVM . updateSelectionVehicleTypeId (
SelectionModel ( selectedId: adDetailsModel . vehicle ! . vehicleType ! , selectedOption: ( adDetailsModel . vehicle ! . vehicleType ! ) . toVehicleTypeString ( ) , errorValue: " " ) ,
) ;
showMyBottomSheet ( context , child: const AdDurationSelectionSheetContent ( isFromExtendAd: true , isUpdateAdSelected: true ) ) ;
} ,
) ,
) ,
actionButtonNo: Expanded (
child: ShowFillButton (
maxHeight: 55 ,
isFilled: false ,
borderColor: MyColors . darkPrimaryColor ,
title: " No " ,
txtColor: MyColors . darkPrimaryColor ,
fontSize: 15 ,
onPressed: ( ) {
adVM . updateSelectionVehicleTypeId (
SelectionModel ( selectedId: adDetailsModel . vehicle ! . vehicleType ! , selectedOption: ( adDetailsModel . vehicle ! . vehicleType ! ) . toVehicleTypeString ( ) , errorValue: " " ) ,
) ;
showMyBottomSheet ( context , child: const AdDurationSelectionSheetContent ( isFromExtendAd: true , isUpdateAdSelected: false ) ) ;
} ,
) ,
) ,
) ;
} ,
) ,
) ,
] ,
) ;
}
@ override
Widget build ( BuildContext context ) {
switch ( adDetailsModel . adPostStatus ! ) {
case AdPostStatus . pendingForPayment:
return pendingForPaymentAction ( context , ad: adDetailsModel ) ;
case AdPostStatus . active:
return markAsSoldAction ( context ) ;
case AdPostStatus . reserved:
return cancelReservationAction ( context , adDetails: adDetailsModel ) ;
case AdPostStatus . buyingService:
case AdPostStatus . reserveCancel:
case AdPostStatus . rejected:
case AdPostStatus . cancelled:
case AdPostStatus . pendingForPost:
return pendingForReviewAction ( pendingText: " Waiting for admin to post " ) ;
case AdPostStatus . pendingForReview:
return pendingForReviewAction ( pendingText: " Waiting for Admins Approval " ) ;
case AdPostStatus . sold:
case AdPostStatus . expired:
return expiredAdAction ( context ) ;
case AdPostStatus . allAds:
break ;
}
return const SizedBox . shrink ( ) ;
}
}