441 lines
19 KiB
Dart
441 lines
19 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:onufitness/constants/asset_constants.dart';
|
|
import 'package:onufitness/constants/color_constant.dart';
|
|
import 'package:onufitness/constants/string_constant.dart';
|
|
import 'package:onufitness/constants/text_constant.dart';
|
|
import 'package:onufitness/screens/rise/models/get_challenges_response_model.dart';
|
|
import 'package:onufitness/utils/helper_function.dart';
|
|
import 'package:onufitness/widgets/Buttons/custom_submit_button.dart';
|
|
|
|
class ChallengeCard extends StatelessWidget {
|
|
final String tabName;
|
|
final String title;
|
|
final String category;
|
|
final String participants;
|
|
final String? imageUrl;
|
|
final Color? actionColor;
|
|
final List<Participant>? participantImages;
|
|
final VoidCallback? onJoinPressed;
|
|
final VoidCallback? onAddPeoplePressed;
|
|
final VoidCallback? onWatchVideoPressed;
|
|
final VoidCallback? onUpdatePrivacyPressed;
|
|
RxList<int>? isLoading;
|
|
final int? challengeID;
|
|
bool isChallengeJoined;
|
|
bool isChallengeStarted;
|
|
|
|
ChallengeCard({
|
|
super.key,
|
|
required this.tabName,
|
|
required this.title,
|
|
required this.category,
|
|
required this.participants,
|
|
required this.imageUrl,
|
|
this.actionColor,
|
|
this.participantImages,
|
|
this.onJoinPressed,
|
|
this.onAddPeoplePressed,
|
|
this.onWatchVideoPressed,
|
|
this.onUpdatePrivacyPressed,
|
|
this.isLoading,
|
|
this.challengeID,
|
|
required this.isChallengeStarted,
|
|
required this.isChallengeJoined,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Card(
|
|
color: Colors.white,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.r)),
|
|
margin: EdgeInsets.only(bottom: 16.h),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Stack(
|
|
children: [
|
|
ClipRRect(
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(16.r)),
|
|
child:
|
|
imageUrl != null && imageUrl!.isNotEmpty
|
|
? Image.network(
|
|
imageUrl!,
|
|
width: double.infinity,
|
|
height: 150.h,
|
|
fit: BoxFit.cover,
|
|
loadingBuilder: (context, child, loadingProgress) {
|
|
if (loadingProgress == null) {
|
|
return child;
|
|
}
|
|
return Container(
|
|
width: double.infinity,
|
|
height: 150.h,
|
|
color: Colors.grey[100],
|
|
child: Center(
|
|
child: CircularProgressIndicator(
|
|
value:
|
|
loadingProgress.expectedTotalBytes != null
|
|
? loadingProgress
|
|
.cumulativeBytesLoaded /
|
|
loadingProgress
|
|
.expectedTotalBytes!
|
|
: null,
|
|
valueColor: AlwaysStoppedAnimation<Color>(
|
|
Colors.grey[400]!,
|
|
),
|
|
strokeWidth: 2.0,
|
|
),
|
|
),
|
|
);
|
|
},
|
|
errorBuilder: (context, error, stackTrace) {
|
|
return defaultBannerImage(
|
|
context: context,
|
|
title: title,
|
|
);
|
|
},
|
|
)
|
|
: defaultBannerImage(context: context, title: title),
|
|
),
|
|
|
|
// Privacy Settings Button (only for created tab)
|
|
if (tabName == riseCreatedByMeTab)
|
|
Positioned(
|
|
top: 10.h,
|
|
right: 10.w,
|
|
child: Material(
|
|
color: Colors.black.withValues(alpha: 0.6),
|
|
shape: CircleBorder(),
|
|
child: InkWell(
|
|
onTap: onUpdatePrivacyPressed,
|
|
customBorder: CircleBorder(),
|
|
child: Padding(
|
|
padding: EdgeInsets.all(8.w),
|
|
child: Icon(
|
|
Icons.edit,
|
|
color: Colors.white,
|
|
size: 20.sp,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
|
|
Padding(
|
|
padding: EdgeInsets.all(16.w),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
if (tabName == riseCreatedByMeTab || tabName == riseJoinedTab)
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 7,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
title,
|
|
style: TextStyle(
|
|
fontSize: regularSizeText,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
maxLines: 2,
|
|
),
|
|
SizedBox(height: 4.h),
|
|
Text(
|
|
category,
|
|
style: TextStyle(
|
|
fontSize: smallSizeText,
|
|
color: greyTextColor1,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
SizedBox(height: 12.h),
|
|
],
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 2,
|
|
child: SizedBox(
|
|
height: 40.h,
|
|
width: 100.w,
|
|
child: Stack(
|
|
children: List.generate(
|
|
participantImages != null
|
|
? participantImages!.length.clamp(0, 3)
|
|
: 0,
|
|
(index) {
|
|
final imageUrl =
|
|
participantImages![index].profilePicture;
|
|
return Positioned(
|
|
left: (index * 20).w,
|
|
child: Container(
|
|
height: isTablet ? 35.h : 30.h,
|
|
width: isTablet ? 35.w : 30.h,
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
border: Border.all(
|
|
color: Colors.white,
|
|
width: 2,
|
|
),
|
|
image: DecorationImage(
|
|
image:
|
|
imageUrl != null &&
|
|
imageUrl.isNotEmpty
|
|
? NetworkImage(imageUrl)
|
|
: const AssetImage(
|
|
AssetConstants
|
|
.dummyUserImage,
|
|
)
|
|
as ImageProvider,
|
|
fit: BoxFit.cover,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
if (tabName == riseExploreTabUpcoming ||
|
|
tabName == riseExploreTabOngoing)
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
title,
|
|
style: TextStyle(
|
|
fontSize: isTablet ? smallSizeText : regularSizeText,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
maxLines: 2,
|
|
),
|
|
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 7,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
SizedBox(height: 4.h),
|
|
Text(
|
|
tabName == riseExploreTabOngoing
|
|
? "$category • $participants"
|
|
: category,
|
|
style: TextStyle(
|
|
color: Color(darkGreyColor),
|
|
fontSize: smallSizeText,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
maxLines: 3,
|
|
),
|
|
SizedBox(height: 10.h),
|
|
],
|
|
),
|
|
),
|
|
if (tabName == riseExploreTabOngoing ||
|
|
tabName == riseExploreTabUpcoming)
|
|
if ((isChallengeJoined == false))
|
|
Expanded(
|
|
flex: 3,
|
|
child:
|
|
isLoading != null && challengeID != null
|
|
? Obx(
|
|
() => CustomSubmitButton(
|
|
isLoading: isLoading!.contains(
|
|
challengeID!,
|
|
),
|
|
height: 30.h,
|
|
backgroundColor: Color(
|
|
primaryColor,
|
|
),
|
|
text: "Join",
|
|
textColor: Colors.black,
|
|
fontSize:
|
|
isTablet
|
|
? verySmallSizeText
|
|
: verySmallSizeText,
|
|
fontWeight: FontWeight.w600,
|
|
onPressed: () {
|
|
if (onJoinPressed != null) {
|
|
onJoinPressed!();
|
|
}
|
|
},
|
|
),
|
|
)
|
|
: CustomSubmitButton(
|
|
isLoading: false,
|
|
height: 30.h,
|
|
backgroundColor: Color(primaryColor),
|
|
text: "Join",
|
|
textColor: Colors.black,
|
|
fontSize:
|
|
isTablet
|
|
? verySmallSizeText
|
|
: verySmallSizeText,
|
|
fontWeight: FontWeight.w600,
|
|
onPressed: () {
|
|
if (onJoinPressed != null) {
|
|
onJoinPressed!();
|
|
}
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
if (tabName == riseCreatedByMeTab || tabName == riseJoinedTab)
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text(
|
|
"$participants Participants",
|
|
style: TextStyle(
|
|
color: Color(darkGreyColor),
|
|
fontSize: verySmallSizeText,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
),
|
|
SizedBox(width: 5.w),
|
|
if (tabName == riseCreatedByMeTab)
|
|
if (isChallengeJoined == false)
|
|
Expanded(
|
|
flex: 1,
|
|
child:
|
|
isLoading != null && challengeID != null
|
|
? Obx(
|
|
() => CustomSubmitButton(
|
|
isLoading: isLoading!.contains(
|
|
challengeID!,
|
|
),
|
|
height: 30.h,
|
|
backgroundColor: Color(primaryColor),
|
|
text: "Join",
|
|
textColor: Colors.black,
|
|
fontSize:
|
|
isTablet
|
|
? verySmallSizeText
|
|
: verySmallSizeText,
|
|
fontWeight: FontWeight.w600,
|
|
onPressed: () {
|
|
if (onJoinPressed != null) {
|
|
onJoinPressed!();
|
|
}
|
|
},
|
|
),
|
|
)
|
|
: CustomSubmitButton(
|
|
isLoading: false,
|
|
height: 30.h,
|
|
backgroundColor: Color(primaryColor),
|
|
text: "Join",
|
|
textColor: Colors.black,
|
|
fontSize:
|
|
isTablet
|
|
? verySmallSizeText
|
|
: verySmallSizeText,
|
|
fontWeight: FontWeight.w600,
|
|
onPressed: () {
|
|
if (onJoinPressed != null) {
|
|
onJoinPressed!();
|
|
}
|
|
},
|
|
),
|
|
),
|
|
SizedBox(width: 5.w),
|
|
|
|
if (tabName == riseCreatedByMeTab)
|
|
Expanded(
|
|
flex: 2,
|
|
child: CustomSubmitButton(
|
|
height: 35.h,
|
|
backgroundColor: Colors.black,
|
|
text: "Add People",
|
|
fontSize: verySmallSizeText,
|
|
onPressed: () {
|
|
if (onAddPeoplePressed != null) {
|
|
onAddPeoplePressed!();
|
|
}
|
|
},
|
|
),
|
|
),
|
|
|
|
if (tabName == riseJoinedTab)
|
|
Expanded(
|
|
flex: 2,
|
|
child: CustomSubmitButton(
|
|
height: 35.h,
|
|
backgroundColor: Color(
|
|
buttonBackgroundDarkGeryColor,
|
|
),
|
|
text: "Watch Video",
|
|
fontSize: verySmallSizeText,
|
|
onPressed: () {
|
|
if (onWatchVideoPressed != null) {
|
|
onWatchVideoPressed!();
|
|
}
|
|
},
|
|
icon: Icon(
|
|
Icons.play_circle_filled,
|
|
color: Colors.white,
|
|
size: smallSizeText,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
Widget defaultBannerImage({
|
|
required BuildContext context,
|
|
required String title,
|
|
}) {
|
|
return Container(
|
|
width: double.infinity,
|
|
height: 150.h,
|
|
decoration: BoxDecoration(
|
|
gradient: LinearGradient(
|
|
colors: [Colors.white, Color(primaryColor).withValues(alpha: 0.5)],
|
|
begin: Alignment.topLeft,
|
|
end: Alignment.bottomRight,
|
|
),
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(16.r)),
|
|
),
|
|
child: Center(
|
|
child: Text(
|
|
title.isNotEmpty ? title[0].toUpperCase() : '',
|
|
style: TextStyle(
|
|
fontSize: 60.sp,
|
|
fontWeight: FontWeight.bold,
|
|
color: Colors.white,
|
|
shadows: [
|
|
Shadow(blurRadius: 4, color: Colors.black26, offset: Offset(2, 2)),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|