|
@@ -1,3 +1,4 @@
|
|
|
+import 'package:cpt_services/modules/services/service_repair_detail/service_repair_detail_state.dart';
|
|
|
import 'package:cs_resources/generated/assets.dart';
|
|
|
import 'package:cs_resources/theme/app_colors_theme.dart';
|
|
|
import 'package:domain/entity/garage_sale_rent_detail_entity.dart';
|
|
@@ -17,6 +18,7 @@ import 'package:shared/utils/size_config.dart';
|
|
|
import 'package:widgets/ext/ex_widget.dart';
|
|
|
import 'package:widgets/load_state_layout.dart';
|
|
|
import 'package:widgets/my_appbar.dart';
|
|
|
+import 'package:widgets/my_button.dart';
|
|
|
import 'package:widgets/my_like_button.dart';
|
|
|
import 'package:widgets/my_load_image.dart';
|
|
|
import 'package:widgets/my_text_view.dart';
|
|
@@ -47,13 +49,10 @@ class ServiceRepairDetailPage extends HookConsumerWidget {
|
|
|
final state = ref.watch(serviceRepairDetailVmProvider);
|
|
|
final vm = ref.read(serviceRepairDetailVmProvider.notifier);
|
|
|
final String pageTitle = 'Repair Details';
|
|
|
- GlobalKey _likeButtonKey = GlobalKey<MyLikeButtonState>();
|
|
|
|
|
|
- GarageSaleRentDetailEntity? detailInfo = state.datas?? null;
|
|
|
- String title = detailInfo?.title?? '';
|
|
|
- int price = detailInfo?.price?? 0;
|
|
|
+ Map<String, dynamic>? detailInfo = state.datas?? {};
|
|
|
|
|
|
- String contactType = detailInfo?.contact??'';
|
|
|
+ String contactType = detailInfo?['contact']??'';
|
|
|
|
|
|
String description = '';
|
|
|
|
|
@@ -104,259 +103,216 @@ class ServiceRepairDetailPage extends HookConsumerWidget {
|
|
|
SliverList(
|
|
|
delegate: SliverChildBuilderDelegate(
|
|
|
(context, index){
|
|
|
- return detailInfo !=null? _buildContentBox(context, ref, detailInfo): Container();
|
|
|
+ return _buildContentBox(context, ref, detailInfo!, state, vm);
|
|
|
},
|
|
|
childCount: 1
|
|
|
),
|
|
|
)
|
|
|
],
|
|
|
),
|
|
|
- Visibility(
|
|
|
- visible: state.loadingState == LoadState.State_Success,
|
|
|
- child: Visibility(
|
|
|
- visible: vm.isContactWhatsApp(contactType),
|
|
|
- child: _buildWhatsApp(context, ref,
|
|
|
- title:title,
|
|
|
- price:price,
|
|
|
- contactType:contactType,
|
|
|
- description:description,
|
|
|
- ),
|
|
|
- ),
|
|
|
- ),
|
|
|
]
|
|
|
),
|
|
|
),
|
|
|
),
|
|
|
- // 底部联系信息
|
|
|
- Visibility(
|
|
|
- visible: state.loadingState == LoadState.State_Success,
|
|
|
- child: detailInfo !=null ? _buildBottomConcatInfo(context, ref, _likeButtonKey,
|
|
|
- title:title,
|
|
|
- price:price,
|
|
|
- contactType:contactType,
|
|
|
- description:description,
|
|
|
- detailInfo:detailInfo,
|
|
|
- ): Container(),
|
|
|
- )
|
|
|
],
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- Widget _buildWhatsApp(BuildContext context, WidgetRef ref, {required String title, required int price, required String contactType, required String description}) {
|
|
|
- final vm = ref.read(serviceRepairDetailVmProvider.notifier);
|
|
|
- return Positioned(
|
|
|
- right: 15.5,
|
|
|
- bottom: 42,
|
|
|
- child: InkWell(
|
|
|
- onTap: () {
|
|
|
- // 点击了whatsapp
|
|
|
- vm.handlerClickWhatsapp(context, contactType, title, price);
|
|
|
- },
|
|
|
- child: const MyAssetImage(Assets.communityWhatsAPP, width: 57,height: 57,),
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
|
|
|
- Widget _buildContentBox(BuildContext context, WidgetRef ref, GarageSaleRentDetailEntity detailInfo) {
|
|
|
- List<String> resources = detailInfo.resources??[];
|
|
|
- String goods_img = resources[0]??'';
|
|
|
- String title = detailInfo.title??'';
|
|
|
- int price = detailInfo.price??0;
|
|
|
- String contactType = '';
|
|
|
- String description = detailInfo.description??'';
|
|
|
- CarouselSliderController buttonCarouselController = CarouselSliderController();
|
|
|
+ Widget _buildContentBox(BuildContext context, WidgetRef ref, Map<String, dynamic>? detailInfo, ServiceRepairDetailState state, ServiceRepairDetailVm vm) {
|
|
|
+ // List<String> resources = detailInfo?['resources'].cast<String>()??[];
|
|
|
+ // String title = detailInfo?['title']??'';
|
|
|
+ double score = detailInfo?['score']?? 5.0;
|
|
|
+ // String description = detailInfo?['description']??'';
|
|
|
+
|
|
|
return Column(
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
children: [
|
|
|
- // 图片
|
|
|
- SizedBox(
|
|
|
- width: SizeConfig().screenWidth,
|
|
|
- height: 173.5,
|
|
|
- child: CarouselSlider(
|
|
|
- // items: [MyLoadImage(goods_img)] ,
|
|
|
- items: resources.map((resource) => MyLoadImage(
|
|
|
- resource,
|
|
|
- fit: BoxFit.cover, // 确保图片覆盖整个区域
|
|
|
- width: SizeConfig().screenWidth, // 确保图片宽度与屏幕宽度一致
|
|
|
- height: 173.5, // 确保图片高度与 CarouselSlider 高度一致
|
|
|
- ).onTap((){
|
|
|
- ImagePreviewEngine.multipleImagePreview(
|
|
|
- context,
|
|
|
- resources,
|
|
|
- heroes: List.generate(resources.length, (index) => resources[index]),
|
|
|
- onLongPressAction: (url) {}
|
|
|
- );
|
|
|
- })
|
|
|
- ).toList(),
|
|
|
- carouselController: buttonCarouselController,
|
|
|
- options: CarouselOptions(
|
|
|
- autoPlay: false,
|
|
|
- enlargeCenterPage: true,
|
|
|
- viewportFraction: 1,
|
|
|
- initialPage: 0,
|
|
|
- ),
|
|
|
- ),
|
|
|
- ),
|
|
|
Column(
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
children: [
|
|
|
- // 标题
|
|
|
- Padding(
|
|
|
- padding: const EdgeInsets.only(left: 16, right: 16, top: 16,),
|
|
|
- child: title.isNotEmpty? MyTextView( title, fontSize: 18, isFontMedium: true, textColor: context.appColors.textBlack,):const SizedBox.shrink(),
|
|
|
+ // 评分
|
|
|
+ Column(
|
|
|
+ children: [
|
|
|
+ Container(
|
|
|
+ width: double.infinity,
|
|
|
+ padding: const EdgeInsets.only(left: 16, right: 16, top: 16,bottom: 16),
|
|
|
+ color: context.appColors.whiteBG,
|
|
|
+ child: Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ MyTextView(
|
|
|
+ "House Cleaning Services",
|
|
|
+ textColor: context.appColors.textBlack,
|
|
|
+ fontSize: 18,
|
|
|
+ isFontBold: true,
|
|
|
+ marginBottom: 5,
|
|
|
+ ),
|
|
|
+ Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.start,
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
+ children: [
|
|
|
+ AnimatedRatingStars(
|
|
|
+ initialRating: score,
|
|
|
+ onChanged: (rating) {
|
|
|
+ },
|
|
|
+ readOnly: true,
|
|
|
+ displayRatingValue: true, // Display the rating value
|
|
|
+ interactiveTooltips: true, // Allow toggling half-star state
|
|
|
+ customFilledIcon: Icons.star,
|
|
|
+ customHalfFilledIcon: Icons.star_half,
|
|
|
+ customEmptyIcon: Icons.star_border,
|
|
|
+ filledColor: ColorUtils.string2Color("#FF0000"),
|
|
|
+ starSize: 16.5,
|
|
|
+ animationDuration: const Duration(milliseconds: 0),
|
|
|
+ animationCurve: Curves.easeInOut,
|
|
|
+ ),
|
|
|
+ MyTextView(
|
|
|
+ "${score}",
|
|
|
+ textColor: context.appColors.textBlack,
|
|
|
+ fontSize: 16,
|
|
|
+ isFontMedium: true,
|
|
|
+ marginLeft: 15,
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ MyTextView(
|
|
|
+ "HONG YE GROUP PTE LTD",
|
|
|
+ textColor: context.appColors.textDarkGray999,
|
|
|
+ fontSize: 12,
|
|
|
+ isFontRegular: true,
|
|
|
+ marginTop: 10,
|
|
|
+ marginBottom: 5,
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
),
|
|
|
- // 价格
|
|
|
- Padding(
|
|
|
- padding: const EdgeInsets.only(left: 16, right: 16, top: 10),
|
|
|
- child: price!=null? MyTextView( '$price', fontSize: 24, isFontMedium: true, textColor: context.appColors.textBlack,):const SizedBox.shrink(),
|
|
|
+ // profile信息
|
|
|
+ Container(
|
|
|
+ width: double.infinity,
|
|
|
+ margin: const EdgeInsets.only(left: 0, right: 0, top: 5, bottom: 0),
|
|
|
+ padding: const EdgeInsets.only(left: 10, right: 10, top: 18.5, bottom: 18.5),
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ color: context.appColors.whiteBG,
|
|
|
+ ),
|
|
|
+ child: _buildOrderProfile(context, state, vm),
|
|
|
+ ),
|
|
|
+ // quote 按钮
|
|
|
+ Container(
|
|
|
+ width: double.infinity,
|
|
|
+ padding: const EdgeInsets.only(left: 16, right: 16, top: 20,bottom: 20),
|
|
|
+ color: Colors.transparent,
|
|
|
+ child: Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ Center(
|
|
|
+ child: MyButton(
|
|
|
+ text: "Get A Quote",
|
|
|
+ textColor: context.appColors.textWhite,
|
|
|
+ backgroundColor: context.appColors.textPrimary,
|
|
|
+ fontSize: 15,
|
|
|
+ minWidth: 310,
|
|
|
+ minHeight: 44.5,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ onPressed: () {
|
|
|
+ vm.handlerClickQuoteBtn(context, id, serviceTypeCode);
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Center(
|
|
|
+ child: MyTextView(
|
|
|
+ 'The merchant will contact you as soon as possible. Please keep your phone open',
|
|
|
+ textColor: context.appColors.textBlack,
|
|
|
+ fontSize: 14,
|
|
|
+ isFontRegular: true,
|
|
|
+ marginTop: 17,
|
|
|
+ // boxWidth: 330,
|
|
|
+ marginLeft: 20,
|
|
|
+ marginRight: 20,
|
|
|
+ textAlign: TextAlign.center,
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ ]
|
|
|
+ )
|
|
|
),
|
|
|
- // 内容
|
|
|
+ // 介绍图
|
|
|
Padding(
|
|
|
- padding: const EdgeInsets.only(left: 16, right: 16, top: 16),
|
|
|
- child: description.isNotEmpty? MyTextView( description, fontSize: 17, isFontRegular: true, textColor: context.appColors.textBlack,):const SizedBox.shrink(),
|
|
|
+ padding: const EdgeInsets.only(left: 16, right: 16, top: 16),
|
|
|
+ child: Column(
|
|
|
+ children: List.generate(2, (index) {
|
|
|
+ // 创建一个映射来关联字符串和资源
|
|
|
+ final Map<String, String> assetMap = {
|
|
|
+ 'serviceDetail01': Assets.serviceRepairDetail01,
|
|
|
+ 'serviceDetail02': Assets.serviceRepairDetail02,
|
|
|
+ };
|
|
|
+ String curDetailStr = 'serviceDetail0${(index + 1)}';
|
|
|
+ Log.d("curDetailStr $curDetailStr");
|
|
|
+ return MyAssetImage(
|
|
|
+ assetMap[curDetailStr]!,
|
|
|
+ width: SizeConfig().screenWidth,
|
|
|
+ fit: BoxFit.cover,
|
|
|
+ );
|
|
|
+ }).toList(),
|
|
|
+ )
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
-
|
|
|
]
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- Widget _buildBottomConcatInfo(
|
|
|
- BuildContext context,
|
|
|
- WidgetRef ref,
|
|
|
- likeButtonKey,
|
|
|
- {
|
|
|
- required String title,
|
|
|
- required int price,
|
|
|
- required String contactType,
|
|
|
- required String description,
|
|
|
- required GarageSaleRentDetailEntity detailInfo,
|
|
|
- }
|
|
|
- ) {
|
|
|
- final vm = ref.read(serviceRepairDetailVmProvider.notifier);
|
|
|
-
|
|
|
- GarageSaleRentDetailAccount account = detailInfo.account?? GarageSaleRentDetailAccount();
|
|
|
-
|
|
|
- Log.d("0000000 ${detailInfo.likesCount}");
|
|
|
- String publisher = account.name??'-';
|
|
|
- String publisherAvatar = account.avatar??'-';
|
|
|
-
|
|
|
- String contactType = detailInfo.contact??'';
|
|
|
- String publisherTime = detailInfo.createdAt??'-';
|
|
|
- int? likes_count = detailInfo.likesCount??0;
|
|
|
- Log.d("666666 ${likes_count}");
|
|
|
-
|
|
|
-
|
|
|
- final _likes_count = useState<int>(likes_count!);
|
|
|
- final _isLiked = useState<bool>(false);
|
|
|
- Log.d("4344 ${_likes_count.value}");
|
|
|
-
|
|
|
-
|
|
|
- return Container(
|
|
|
- height: 50,
|
|
|
- color: ColorUtils.string2Color('#4161D0'),
|
|
|
- child: Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.center,
|
|
|
- children: [
|
|
|
- Expanded(
|
|
|
- child: Row(
|
|
|
- crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
+ Widget _buildOrderProfile(BuildContext context, ServiceRepairDetailState state, ServiceRepairDetailVm vm,) {
|
|
|
+ return Column(
|
|
|
+ children: [
|
|
|
+ Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.start,
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ const MyAssetImage(
|
|
|
+ Assets.serviceLocationIcon,
|
|
|
+ width: 15,
|
|
|
+ height: 17.5,
|
|
|
+ ),
|
|
|
+ const SizedBox(
|
|
|
+ width: 10,
|
|
|
+ ),
|
|
|
+ Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
children: [
|
|
|
- SizedBox.fromSize(size: const Size(15, 0)),
|
|
|
- MyLoadImage(
|
|
|
- publisherAvatar,
|
|
|
- width: 29,
|
|
|
- height: 29,
|
|
|
- isCircle: true,
|
|
|
+ MyTextView(
|
|
|
+ '705 Qiming Huijin Building',
|
|
|
+ fontSize: 17,
|
|
|
+ isFontBold: true,
|
|
|
+ textColor: context.appColors.textBlack,
|
|
|
+ marginBottom: 5,
|
|
|
),
|
|
|
- SizedBox.fromSize(size: const Size(10, 0)),
|
|
|
- Column(
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
- mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.start,
|
|
|
children: [
|
|
|
- MyTextView(publisher, fontSize:12, textColor: context.appColors.textWhite, isFontMedium: true,),
|
|
|
- MyTextView(publisherTime, fontSize:10, textColor: context.appColors.textWhite, isFontRegular: true, marginTop: 4,)
|
|
|
+ MyTextView(
|
|
|
+ 'Sundy',
|
|
|
+ fontSize: 14,
|
|
|
+ textColor: context.appColors.textDarkGray999,
|
|
|
+ isFontRegular: true,
|
|
|
+ ),
|
|
|
+ MyTextView(
|
|
|
+ '+6588991122',
|
|
|
+ fontSize: 14,
|
|
|
+ textColor: context.appColors.textDarkGray999,
|
|
|
+ isFontRegular: true,
|
|
|
+ marginLeft: 10,
|
|
|
+ ),
|
|
|
],
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
- ),
|
|
|
- Expanded(
|
|
|
- child: Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.end,
|
|
|
- crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
- children: [
|
|
|
- Container(
|
|
|
- alignment: Alignment.center,
|
|
|
- padding: const EdgeInsets.only(left:5, right: 0,top:5,bottom: 5),
|
|
|
- child: Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.center,
|
|
|
- children: [
|
|
|
- MyLikeButton(
|
|
|
- key: likeButtonKey,
|
|
|
- isLiked: _isLiked.value,
|
|
|
- isCustomIcon: true,
|
|
|
- customIconUnActiveAssets: Assets.communityCollection,
|
|
|
- customIconActiveAssets: Assets.communityLikeActive,
|
|
|
- // customIconWidth: 18,
|
|
|
- // customIconHeight: 18,
|
|
|
- onLike: () async {
|
|
|
- Log.d('点击了like button');
|
|
|
- int id = detailInfo!.id as int;
|
|
|
- final isSuccess = await vm.handlerClickCollection(context, id, true);
|
|
|
- if(isSuccess!=null && isSuccess){
|
|
|
- // 成功
|
|
|
- if(_isLiked.value){
|
|
|
- Log.d("取消点赞");
|
|
|
- _likes_count.value--;
|
|
|
- _isLiked.value = false;
|
|
|
- }else {
|
|
|
- Log.d("点赞");
|
|
|
- _likes_count.value++;
|
|
|
- _isLiked.value = true;
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- ),
|
|
|
- MyTextView(
|
|
|
- "${_likes_count.value}",
|
|
|
- fontSize: 18,
|
|
|
- textColor: Colors.white,
|
|
|
- isFontRegular: true,
|
|
|
- marginLeft: 5,
|
|
|
- marginRight: 15,
|
|
|
- onClick: (){
|
|
|
- final state = likeButtonKey.currentState;
|
|
|
- state?.triggerTap();
|
|
|
- },
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- // const MyAssetImage(Assets.communityCollection, width: 18,height: 18,),
|
|
|
- Visibility(
|
|
|
- visible: vm.isContactMobile(contactType),
|
|
|
- child: Row(
|
|
|
- children: [
|
|
|
- const SizedBox(width: 4,),
|
|
|
- const MyAssetImage(
|
|
|
- Assets.communityPhone,
|
|
|
- width: 21.5,
|
|
|
- height: 18,
|
|
|
- ).onTap((){
|
|
|
- vm.handlerClickMobile(context, contactType);
|
|
|
- }),
|
|
|
- const SizedBox(width: 15,),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
}
|