402 lines
22 KiB
Dart
402 lines
22 KiB
Dart
import 'package:bookmywages/consts_widgets/app_assets.dart';
|
|
import 'package:bookmywages/consts_widgets/app_colors.dart';
|
|
import 'package:bookmywages/routers/consts_router.dart';
|
|
import 'package:bookmywages/viewmodel/api_controller.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import 'package:cached_network_image/cached_network_image.dart';
|
|
import 'package:get/get.dart';
|
|
|
|
class MostPopluarViewall extends ConsumerStatefulWidget {
|
|
const MostPopluarViewall({super.key});
|
|
|
|
@override
|
|
ConsumerState<MostPopluarViewall> createState() => _MostPopluarViewallState();
|
|
}
|
|
|
|
class _MostPopluarViewallState extends ConsumerState<MostPopluarViewall> {
|
|
bool _isValidCompleteUrl(String? url) {
|
|
if (url == null || url.isEmpty) return false;
|
|
try {
|
|
final uri = Uri.parse(url);
|
|
return uri.isAbsolute && uri.path.isNotEmpty;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final popularServicesAsync = ref.watch(mostPopularProvider('0'));
|
|
|
|
return Scaffold(
|
|
backgroundColor: AppColors.secondprimary,
|
|
body: SafeArea(
|
|
child: popularServicesAsync.when(
|
|
loading: () => const Center(child: CircularProgressIndicator()),
|
|
error: (error, stack) => Center(child: Text('Error: $error')),
|
|
data: (services) {
|
|
if (services.isEmpty) {
|
|
return const Padding(
|
|
padding: EdgeInsets.all(8.0),
|
|
child: Center(
|
|
child: Text("No services available for this category"),
|
|
),
|
|
);
|
|
}
|
|
|
|
return CustomScrollView(
|
|
slivers: [
|
|
SliverToBoxAdapter(
|
|
child: Stack(
|
|
alignment: Alignment.center,
|
|
children: [
|
|
Align(
|
|
alignment: Alignment.centerLeft,
|
|
child: IconButton(
|
|
icon: const Icon(Icons.arrow_back_ios),
|
|
onPressed: () => Navigator.pop(context),
|
|
),
|
|
),
|
|
const Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 16.0),
|
|
child: Text(
|
|
"Most popular service",
|
|
style: TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
SliverPadding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
sliver: SliverGrid(
|
|
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
|
|
maxCrossAxisExtent: MediaQuery.of(context).size.width / 2,
|
|
mainAxisSpacing: 10,
|
|
crossAxisSpacing: 10,
|
|
childAspectRatio: 0.74,
|
|
),
|
|
delegate: SliverChildBuilderDelegate((context, index) {
|
|
final service = services[index];
|
|
return LayoutBuilder(
|
|
builder: (context, constraints) {
|
|
return Container(
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFFFCFAFA),
|
|
borderRadius: BorderRadius.circular(20),
|
|
border: Border.all(
|
|
color: const Color(0xFFE3E3E3),
|
|
width: 1,
|
|
),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
// Service image with CachedNetworkImage
|
|
ClipRRect(
|
|
borderRadius: const BorderRadius.vertical(
|
|
top: Radius.circular(19),
|
|
),
|
|
child: SizedBox(
|
|
height: constraints.maxWidth * 0.6,
|
|
width: double.infinity,
|
|
child:
|
|
_isValidCompleteUrl(
|
|
service.images1?.first,
|
|
)
|
|
? CachedNetworkImage(
|
|
imageUrl: service.images1!.first,
|
|
width: double.infinity,
|
|
height: constraints.maxWidth * 0.6,
|
|
fit: BoxFit.cover,
|
|
placeholder: (context, url) =>
|
|
Container(
|
|
color: Colors.grey[200],
|
|
child: const Center(
|
|
child:
|
|
CircularProgressIndicator(
|
|
strokeWidth: 2,
|
|
),
|
|
),
|
|
),
|
|
errorWidget:
|
|
(context, url, error) =>
|
|
Image.asset(
|
|
AppAssets.cleaning,
|
|
width: double.infinity,
|
|
height:
|
|
constraints.maxWidth *
|
|
0.6,
|
|
fit: BoxFit.cover,
|
|
),
|
|
)
|
|
: Image.asset(
|
|
AppAssets.cleaning,
|
|
width: double.infinity,
|
|
height: constraints.maxWidth * 0.6,
|
|
fit: BoxFit.cover,
|
|
),
|
|
),
|
|
),
|
|
|
|
// Rest of your widget code remains the same...
|
|
Align(
|
|
alignment: Alignment.centerRight,
|
|
child: Container(
|
|
height: 30,
|
|
width: 80,
|
|
transform: Matrix4.translationValues(
|
|
-10,
|
|
-15,
|
|
0,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: Colors.blue,
|
|
borderRadius: BorderRadius.circular(20),
|
|
border: Border.all(
|
|
color: Colors.white,
|
|
width: 1.5,
|
|
),
|
|
),
|
|
child: Center(
|
|
child: FittedBox(
|
|
fit: BoxFit.scaleDown,
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: 4,
|
|
),
|
|
child: Text(
|
|
'Rs.${service.amount ?? "N/A"}',
|
|
style: const TextStyle(
|
|
fontFamily: 'Gilroy-Bold',
|
|
fontWeight: FontWeight.w400,
|
|
fontSize: 16.86,
|
|
height: 1.0,
|
|
letterSpacing: 0.02,
|
|
color: Color(0xFFFCFAFA),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
|
|
// Service details
|
|
Expanded(
|
|
child: Padding(
|
|
padding: const EdgeInsets.fromLTRB(
|
|
8,
|
|
0,
|
|
8,
|
|
8,
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceBetween,
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.start,
|
|
children: [
|
|
Expanded(
|
|
child: Text(
|
|
service.serviceName ??
|
|
'Service',
|
|
style: const TextStyle(
|
|
fontFamily: 'Gilroy-Medium',
|
|
fontWeight: FontWeight.w700,
|
|
fontSize: 15.02,
|
|
height: 1.0,
|
|
letterSpacing: 0.0,
|
|
),
|
|
maxLines: 2,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
const Icon(
|
|
Icons.star,
|
|
color: Colors.orange,
|
|
size: 18,
|
|
),
|
|
const SizedBox(width: 2),
|
|
Text(
|
|
service.averageReview
|
|
?.toString() ??
|
|
'0.0',
|
|
style: const TextStyle(
|
|
fontFamily: 'SF UI Display',
|
|
fontWeight: FontWeight.w600,
|
|
fontSize: 14,
|
|
height: 1.0,
|
|
letterSpacing: -0.5,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 8),
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Flexible(
|
|
child: Container(
|
|
width: double.infinity,
|
|
padding: const EdgeInsets.all(
|
|
4,
|
|
),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(
|
|
color: AppColors.lightGrey,
|
|
),
|
|
color: Colors.white,
|
|
borderRadius:
|
|
BorderRadius.circular(12),
|
|
),
|
|
child: Row(
|
|
mainAxisSize:
|
|
MainAxisSize.min,
|
|
children: [
|
|
_isValidCompleteUrl(
|
|
service.profilePic1,
|
|
)
|
|
? CircleAvatar(
|
|
radius: 15,
|
|
backgroundImage:
|
|
CachedNetworkImageProvider(
|
|
service
|
|
.profilePic1!,
|
|
),
|
|
)
|
|
: const CircleAvatar(
|
|
radius: 15,
|
|
backgroundImage:
|
|
AssetImage(
|
|
AppAssets
|
|
.login,
|
|
),
|
|
),
|
|
const SizedBox(width: 4),
|
|
Flexible(
|
|
child: Column(
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment
|
|
.start,
|
|
mainAxisSize:
|
|
MainAxisSize.min,
|
|
children: [
|
|
Text(
|
|
service.vendorName ??
|
|
'Vendor',
|
|
style: const TextStyle(
|
|
fontFamily:
|
|
'Gilroy-Medium',
|
|
fontWeight:
|
|
FontWeight
|
|
.w400,
|
|
fontSize: 11.75,
|
|
height: 1.0,
|
|
letterSpacing:
|
|
0.0,
|
|
color: Color(
|
|
0xFF353434,
|
|
),
|
|
),
|
|
maxLines: 1,
|
|
overflow:
|
|
TextOverflow
|
|
.ellipsis,
|
|
),
|
|
const SizedBox(
|
|
height: 2,
|
|
),
|
|
Text(
|
|
service.serviceName ??
|
|
'Service',
|
|
style: const TextStyle(
|
|
fontFamily:
|
|
'Gilroy-Regular',
|
|
fontWeight:
|
|
FontWeight
|
|
.w400,
|
|
fontSize: 11.75,
|
|
height: 1.0,
|
|
letterSpacing:
|
|
0.0,
|
|
color: Color(
|
|
0xFF717171,
|
|
),
|
|
),
|
|
maxLines: 1,
|
|
overflow:
|
|
TextOverflow
|
|
.ellipsis,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(width: 4),
|
|
GestureDetector(
|
|
onTap: () {
|
|
Get.toNamed(
|
|
RouterConts.detailserivce,
|
|
arguments: service.id,
|
|
);
|
|
},
|
|
child: Container(
|
|
padding: const EdgeInsets.all(
|
|
8,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: AppColors.primary,
|
|
borderRadius:
|
|
BorderRadius.circular(12),
|
|
),
|
|
child: const Icon(
|
|
Icons
|
|
.arrow_forward_ios_rounded,
|
|
size: 16,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}, childCount: services.length),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|