597 lines
30 KiB
Dart
597 lines
30 KiB
Dart
import 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:cached_network_image/cached_network_image.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:taafee_mobile/common/const/const.dart';
|
|
import 'package:taafee_mobile/common/extensions/widget_extension.dart';
|
|
import 'package:taafee_mobile/common/widgets/button.dart';
|
|
import 'package:taafee_mobile/common/widgets/listview.dart';
|
|
import 'package:taafee_mobile/common/widgets/loader.dart';
|
|
import 'package:taafee_mobile/common/widgets/rx_viewer.dart';
|
|
import 'package:taafee_mobile/common/widgets/text.dart';
|
|
import 'package:taafee_mobile/common/widgets/textfiled.dart';
|
|
import 'package:taafee_mobile/core/routing/routing_manager.dart';
|
|
import 'package:taafee_mobile/features/account/presentation_layer/widgets/add_images.dart';
|
|
import 'package:taafee_mobile/features/card/business_logic_layer/card_controller.dart';
|
|
import 'package:taafee_mobile/features/card/data_layer/model/card_model.dart';
|
|
import 'package:taafee_mobile/features/category/business_logic_layer/category_controller.dart';
|
|
import 'package:taafee_mobile/features/home/business_logic_layer/home_controller.dart';
|
|
import '../../../../common/widgets/drop_down.dart';
|
|
import '../../../../common/widgets/header_screen.dart';
|
|
import '../../../../common/widgets/toast.dart';
|
|
import '../../../../core/utils/utils.dart';
|
|
import 'package:lottie/lottie.dart';
|
|
|
|
import '../../../category/data_layer/model/category.dart';
|
|
import '../../../home/data_layer/model/city.dart';
|
|
|
|
// ignore: must_be_immutable
|
|
class AddCardScreen extends StatelessWidget {
|
|
final CategoryController categoryController = Get.find<CategoryController>();
|
|
final HomeController homeController = Get.find<HomeController>();
|
|
final CardController cardController = Get.find<CardController>();
|
|
final _formKey = GlobalKey<FormState>();
|
|
Timer? debouncer;
|
|
CardModel? cardModel = Get.arguments;
|
|
AddCardScreen({
|
|
super.key,
|
|
});
|
|
|
|
void load() {
|
|
categoryController.searchCategories();
|
|
cardController.cardModel.value.images = [];
|
|
cardController.editCardModel.value.images = [];
|
|
cardController.changeNetworkImages([]);
|
|
Future.wait(
|
|
[categoryController.searchCategories(), homeController.getCities()])
|
|
.then((value) {
|
|
if (cardModel != null) {
|
|
cardController.changeNetworkImages(cardModel!.cardImages);
|
|
cardController.editCardModel.value.cardId = cardModel!.id;
|
|
} else {
|
|
cardController.cardModel.value.categoryId = 0;
|
|
cardController.editCardModel.value.cityId = 0;
|
|
}
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
load();
|
|
return Scaffold(
|
|
backgroundColor: AppColors.backGroundColor,
|
|
body: SingleChildScrollView(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
HeaderScreen(cardModel != null ? "Edit card".tr : "add_new_card".tr)
|
|
.paddingOnly(top: 30),
|
|
Container(
|
|
margin: const EdgeInsets.symmetric(vertical: 10),
|
|
width: Get.width,
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(4),
|
|
),
|
|
child: Form(
|
|
key: _formKey,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
if (Responsive.isTablet())
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
TextFieldWidget(
|
|
initValue: cardModel != null ? cardModel!.name : '',
|
|
onChange: (value) {
|
|
cardController.cardModel.value.name = value;
|
|
cardController.editCardModel.value.name = value;
|
|
},
|
|
keyboardType: TextInputType.text,
|
|
label: "name".tr,
|
|
validate: (value) {
|
|
if (value == null || value.isEmpty) {
|
|
return "please_enter_the_name".tr;
|
|
}
|
|
return null;
|
|
},
|
|
).paddingOnly(top: 20, bottom: 6),
|
|
Container(
|
|
height: 50,
|
|
alignment: Alignment.center,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(5),
|
|
border: Border.all(color: AppColors.borderColor),
|
|
),
|
|
child: RxViewer(
|
|
customLoader: const SizedBox(
|
|
width: 20,
|
|
height: 20,
|
|
child: CircularProgressIndicator()),
|
|
rxFuture: categoryController.searchCategoriesState,
|
|
child: () => DropDownWidget<CategoryModel>(
|
|
margin: const EdgeInsets.only(left: 12),
|
|
padding: const EdgeInsets.only(bottom: 5),
|
|
item: categoryController.searchCategoriesState.result,
|
|
onChanged: (value) {
|
|
cardController.cardModel.value.categoryId =
|
|
value!.id;
|
|
cardController.editCardModel.value.categoryId =
|
|
value.id;
|
|
},
|
|
selectItem: cardModel != null
|
|
? categoryController
|
|
.getCategoryById(cardModel!.categoryId)
|
|
: CategoryModel.zero(),
|
|
compareFunction: (p0, p1) {
|
|
return p0.compare(p1);
|
|
},
|
|
toStr: (value) {
|
|
return value.name;
|
|
},
|
|
),
|
|
),
|
|
).paddingSymmetric(vertical: 8),
|
|
Container(
|
|
height: 50,
|
|
alignment: Alignment.center,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(5),
|
|
border: Border.all(color: AppColors.borderColor),
|
|
),
|
|
child: RxViewer(
|
|
customLoader: const SizedBox(
|
|
width: 20,
|
|
height: 20,
|
|
child: CircularProgressIndicator()),
|
|
rxFuture: homeController.cityState,
|
|
child: () => DropDownWidget<CityModel>(
|
|
padding: const EdgeInsets.only(bottom: 5),
|
|
margin: const EdgeInsets.only(left: 12),
|
|
item: homeController.cityState.result,
|
|
onChanged: (value) {
|
|
cardController.cardModel.value.cityId = value!.id;
|
|
cardController.editCardModel.value.cityId =
|
|
value.id;
|
|
},
|
|
selectItem: cardModel != null
|
|
? cardModel!.cityModel
|
|
: CityModel.zero(),
|
|
compareFunction: (p0, p1) {
|
|
return p0.compare(p1);
|
|
},
|
|
toStr: (value) {
|
|
return value.name;
|
|
},
|
|
),
|
|
),
|
|
).paddingSymmetric(vertical: 8),
|
|
TextFieldWidget(
|
|
initValue:
|
|
cardModel != null ? cardModel!.phoneNumber : '',
|
|
prefix: SvgPicture.asset("assets/icons/phone.svg")
|
|
.paddingSymmetric(horizontal: 5),
|
|
onChange: (value) {
|
|
cardController.cardModel.value.phoneNumber = value;
|
|
cardController.editCardModel.value.phoneNumber = value;
|
|
},
|
|
keyboardType: TextInputType.phone,
|
|
label: "phone_number".tr,
|
|
validate: (value) {
|
|
if (value == null || value.isEmpty) {
|
|
return "please_enter_the_phone_number".tr;
|
|
}
|
|
return null;
|
|
},
|
|
).paddingSymmetric(vertical: 6),
|
|
TextFieldWidget(
|
|
initValue: cardModel != null ? cardModel!.address : '',
|
|
suffixText: "optional".tr,
|
|
suffix: null,
|
|
prefix: SvgPicture.asset("assets/icons/location.svg")
|
|
.paddingSymmetric(horizontal: 5),
|
|
onChange: (value) {
|
|
cardController.cardModel.value.address = value;
|
|
cardController.editCardModel.value.address = value;
|
|
},
|
|
keyboardType: TextInputType.text,
|
|
label: "address".tr,
|
|
validate: (value) {
|
|
return null;
|
|
},
|
|
).paddingSymmetric(vertical: 6),
|
|
TextFieldWidget(
|
|
initValue: cardModel != null ? cardModel!.postalCode : '',
|
|
suffixText: "optional".tr,
|
|
onChange: (value) {
|
|
cardController.cardModel.value.postalCode = value;
|
|
cardController.editCardModel.value.postalCode = value;
|
|
},
|
|
keyboardType: TextInputType.text,
|
|
label: "postal_code".tr,
|
|
validate: (value) {
|
|
return null;
|
|
},
|
|
).paddingSymmetric(vertical: 6),
|
|
TextFieldWidget(
|
|
initValue: cardModel != null ? cardModel!.website : '',
|
|
onChange: (value) {
|
|
cardController.cardModel.value.webSite = value;
|
|
cardController.editCardModel.value.webSite = value;
|
|
},
|
|
keyboardType: TextInputType.emailAddress,
|
|
label: "website".tr,
|
|
validate: (value) {
|
|
if (value == null || value.isEmpty) {
|
|
return "please_enter_the_website".tr;
|
|
}
|
|
return null;
|
|
},
|
|
).paddingSymmetric(vertical: 6),
|
|
TextFieldWidget(
|
|
initValue: cardModel != null ? cardModel!.services : '',
|
|
onChange: (value) {
|
|
cardController.cardModel.value.service = value;
|
|
cardController.editCardModel.value.service = value;
|
|
},
|
|
keyboardType: TextInputType.text,
|
|
label: "service".tr,
|
|
validate: (value) {
|
|
if (value == null || value.isEmpty) {
|
|
return "please_enter_the_service".tr;
|
|
}
|
|
return null;
|
|
},
|
|
).paddingSymmetric(vertical: 6),
|
|
TextFieldWidget(
|
|
initValue:
|
|
cardModel != null ? cardModel!.additionalData : '',
|
|
maxLines: 5,
|
|
height: 125,
|
|
onChange: (value) {
|
|
cardController.cardModel.value.additionalData = value;
|
|
cardController.editCardModel.value.additionalData =
|
|
value;
|
|
},
|
|
keyboardType: TextInputType.multiline,
|
|
label: "more_details".tr,
|
|
validate: (value) {
|
|
if (value == null || value.isEmpty) {
|
|
return "please_enter_the_details".tr;
|
|
}
|
|
return null;
|
|
},
|
|
).paddingSymmetric(vertical: 6),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
RegularTextWidget(
|
|
"images".tr,
|
|
fontSize: 14,
|
|
),
|
|
RegularTextWidget(
|
|
"optional".tr,
|
|
fontSize: 14,
|
|
)
|
|
],
|
|
),
|
|
cardModel == null
|
|
? Obx(() {
|
|
return SizedBox(
|
|
height: Get.height * .2,
|
|
child: ListViewWidget(
|
|
scrollDirection: Axis.horizontal,
|
|
physics: const BouncingScrollPhysics(),
|
|
itemCount: cardController
|
|
.cardModel.value.images!.isEmpty
|
|
? 1
|
|
: cardController
|
|
.cardModel.value.images!.length +
|
|
1,
|
|
childBuilder: (index) {
|
|
if (index == 0 ||
|
|
cardController
|
|
.cardModel.value.images!.isEmpty) {
|
|
// return const AddImagesWidget();
|
|
return const AddImagesWidget()
|
|
.onTap(() async {
|
|
await Utils.pickImage(context)
|
|
.then((value) async {
|
|
value?.forEach((element) async {
|
|
File? file = await element.file;
|
|
if (file != null) {
|
|
cardController
|
|
.addImagesToList(file);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
} else {
|
|
return Container(
|
|
margin: const EdgeInsets.only(
|
|
bottom: 15, top: 7, right: 5),
|
|
width: Get.width * .32,
|
|
height: Get.height * .2,
|
|
decoration: BoxDecoration(
|
|
border: Border.all(
|
|
color: Colors.transparent),
|
|
borderRadius:
|
|
BorderRadius.circular(6),
|
|
image: DecorationImage(
|
|
image: FileImage(
|
|
cardController.cardModel.value
|
|
.images![index - 1],
|
|
),
|
|
fit: BoxFit.cover),
|
|
),
|
|
child: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: SvgPicture.asset(
|
|
'assets/icons/x.svg',
|
|
colorFilter: const ColorFilter.mode(
|
|
Colors.grey, BlendMode.srcIn),
|
|
).onTap(() {
|
|
cardController
|
|
.removeImageFromNewCard(
|
|
index - 1);
|
|
}),
|
|
),
|
|
);
|
|
}
|
|
}),
|
|
);
|
|
// : Container();
|
|
})
|
|
: SizedBox(
|
|
height: Get.height * .2,
|
|
child: SingleChildScrollView(
|
|
scrollDirection: Axis.horizontal,
|
|
child: Row(
|
|
children: [
|
|
const AddImagesWidget().onTap(() async {
|
|
await Utils.pickImage(context)
|
|
.then((value) async {
|
|
value?.forEach((element) async {
|
|
File? file = await element.file;
|
|
if (file != null) {
|
|
cardController
|
|
.editCardModel.value.images!
|
|
.add(file);
|
|
}
|
|
});
|
|
});
|
|
Future.delayed(const Duration(seconds: 1),
|
|
() {
|
|
cardController.uploadImages(
|
|
onSuccess: (p0) {
|
|
cardController
|
|
.updateNetworkImages(cardModel!.id);
|
|
homeController.readUser();
|
|
cardController.getMyCards(
|
|
homeController.user.value!.id);
|
|
});
|
|
});
|
|
}),
|
|
Obx(() {
|
|
return Visibility(
|
|
visible:
|
|
cardController.addImagesState.loading,
|
|
child: ListViewWidget(
|
|
scrollDirection: Axis.horizontal,
|
|
physics:
|
|
const BouncingScrollPhysics(),
|
|
itemCount: 4,
|
|
childBuilder: (index) {
|
|
return Loader(
|
|
width: Get.width * .32,
|
|
height: Get.height * .2,
|
|
);
|
|
}),
|
|
);
|
|
}),
|
|
Obx(() {
|
|
return Visibility(
|
|
visible: cardController
|
|
.cardModelNetworkImages.isNotEmpty,
|
|
child: Obx(
|
|
() => ListViewWidget(
|
|
scrollDirection: Axis.horizontal,
|
|
physics:
|
|
const BouncingScrollPhysics(),
|
|
itemCount: cardController
|
|
.cardModelNetworkImages
|
|
.length,
|
|
childBuilder: (index) {
|
|
return Obx(() => (cardController
|
|
.deleteImageState
|
|
.loading ||
|
|
cardController
|
|
.networkImagesState
|
|
.loading)
|
|
? Loader(
|
|
width: Get.width * .32,
|
|
height: Get.height * .2,
|
|
)
|
|
: Container(
|
|
margin: const EdgeInsets
|
|
.only(
|
|
bottom: 15,
|
|
top: 7,
|
|
right: 5),
|
|
width: Get.width * .32,
|
|
height: Get.height * .2,
|
|
decoration:
|
|
BoxDecoration(
|
|
border: Border.all(
|
|
color: Colors
|
|
.transparent),
|
|
borderRadius:
|
|
BorderRadius
|
|
.circular(6),
|
|
image: DecorationImage(
|
|
image: CachedNetworkImageProvider(Domain
|
|
.domain +
|
|
cardController
|
|
.cardModelNetworkImages[
|
|
index]
|
|
.url
|
|
.substring(
|
|
6)),
|
|
fit:
|
|
BoxFit.cover),
|
|
),
|
|
child: Align(
|
|
alignment:
|
|
Alignment.topLeft,
|
|
child:
|
|
SvgPicture.asset(
|
|
'assets/icons/x.svg',
|
|
colorFilter:
|
|
const ColorFilter
|
|
.mode(
|
|
Colors.grey,
|
|
BlendMode
|
|
.srcIn),
|
|
).onTap(() {
|
|
cardController.deleteImage(
|
|
cardController
|
|
.cardModelNetworkImages[
|
|
index]
|
|
.id,
|
|
cardId:
|
|
cardModel!
|
|
.id,
|
|
onSuccess:
|
|
(value) {
|
|
homeController
|
|
.readUser();
|
|
cardController
|
|
.getMyCards(
|
|
homeController
|
|
.user
|
|
.value!
|
|
.id);
|
|
});
|
|
}),
|
|
),
|
|
));
|
|
}),
|
|
));
|
|
}),
|
|
],
|
|
),
|
|
),
|
|
)
|
|
],
|
|
).paddingSymmetric(horizontal: 30),
|
|
),
|
|
),
|
|
if (cardModel != null)
|
|
Obx(() {
|
|
return ButtonWidget(
|
|
onTap: () {
|
|
cardController.deleteCard(cardModel!.id,
|
|
onSuccess: (value) {
|
|
homeController.readUser();
|
|
cardController.getMyCards(homeController.user.value!.id);
|
|
RoutingManager.back();
|
|
showMessageDialog(
|
|
'the_card_has_been_deleted_successfully'.tr);
|
|
});
|
|
},
|
|
title: 'delete_card'.tr,
|
|
isLoading: cardController.deleteCardState.loading,
|
|
color: AppColors.redColor,
|
|
textColor: Colors.white,
|
|
).paddingSymmetric(vertical: 10);
|
|
}),
|
|
cardModel == null
|
|
? Obx(() {
|
|
return ButtonWidget(
|
|
isLoading: cardController.addCardState.loading,
|
|
onTap: () {
|
|
if (_formKey.currentState!.validate()) {
|
|
cardController.addCard(
|
|
onSuccess: (p0) {
|
|
homeController.readUser();
|
|
cardController
|
|
.getMyCards(homeController.user.value!.id);
|
|
|
|
homeController.readUser();
|
|
cardController
|
|
.getMyCards(homeController.user.value!.id);
|
|
RoutingManager.back();
|
|
showMessageDialog(
|
|
"the_card_has_been_added_successfully".tr);
|
|
},
|
|
);
|
|
}
|
|
},
|
|
title: "add_card".tr,
|
|
textColor: AppColors.textColor,
|
|
).paddingOnly(bottom: 20);
|
|
})
|
|
: Obx(() {
|
|
return ButtonWidget(
|
|
isLoading: cardController.editCardState.loading,
|
|
onTap: () {
|
|
if (_formKey.currentState!.validate()) {
|
|
cardController.editCard(
|
|
cardModel!.id,
|
|
onSuccess: (p0) async {
|
|
homeController.readUser();
|
|
cardController
|
|
.getMyCards(homeController.user.value!.id);
|
|
cardController.cardState.result.clear();
|
|
cardController.getCards(onConnectionError: (e) {
|
|
Toast.showToast('no_internert_connection'.tr);
|
|
});
|
|
RoutingManager.back();
|
|
showMessageDialog(
|
|
"the_card_has_been_edited_successfully".tr);
|
|
},
|
|
);
|
|
}
|
|
},
|
|
title: "save_changes".tr,
|
|
textColor: AppColors.textColor,
|
|
).paddingOnly(bottom: 20);
|
|
})
|
|
],
|
|
).paddingSymmetric(horizontal: 19),
|
|
).paddingSymmetric(
|
|
horizontal: Responsive.isTablet() ? Get.width * 0.1 : 0),
|
|
).makeSafeArea();
|
|
}
|
|
}
|
|
|
|
showMessageDialog(String message) {
|
|
Get.defaultDialog(
|
|
radius: 12,
|
|
title: '',
|
|
contentPadding: EdgeInsets.zero,
|
|
content: SizedBox(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Lottie.asset(
|
|
'assets/animations/Add Successfuly.json',
|
|
repeat: false,
|
|
),
|
|
MediumTextWidget(
|
|
message,
|
|
textAlign: TextAlign.center,
|
|
fontSize: Responsive.isTablet() ? 28 : 18,
|
|
).paddingOnly(top: 10, bottom: 20).paddingSymmetric(
|
|
horizontal: Responsive.isTablet() ? 32 : 4,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|