2026-01-13 11:36:24 +05:30

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)),
],
),
),
),
);
}