211 lines
8.5 KiB
Dart
211 lines
8.5 KiB
Dart
import 'package:awesome_snackbar_content/awesome_snackbar_content.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:get/get.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/controllers/rise_controller.dart';
|
|
import 'package:onufitness/screens/rise/views/detailed_rise_screen.dart';
|
|
import 'package:onufitness/screens/rise/widgets/challenge_card.dart';
|
|
import 'package:onufitness/screens/rise/widgets/watch_video_popup.dart';
|
|
import 'package:onufitness/widgets/others/new_custom_sneakbar.dart';
|
|
|
|
class JoinedTab extends StatelessWidget {
|
|
JoinedTab({super.key});
|
|
final RiseController controller = Get.find<RiseController>();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return GestureDetector(
|
|
onTap: () {
|
|
FocusScope.of(context).unfocus();
|
|
},
|
|
|
|
child: Column(
|
|
children: [
|
|
// Search Bar
|
|
Container(
|
|
margin: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(12.r),
|
|
),
|
|
child: TextField(
|
|
controller: controller.joinedSearchController,
|
|
textInputAction: TextInputAction.search,
|
|
onSubmitted: (value) {
|
|
FocusScope.of(context).unfocus();
|
|
},
|
|
onChanged: (value) {
|
|
controller.joinedSearchText.value = value;
|
|
},
|
|
decoration: InputDecoration(
|
|
hintText: 'Search joined challenges...',
|
|
hintStyle: TextStyle(
|
|
color: lightGreyColor,
|
|
fontSize: smallSizeText,
|
|
),
|
|
prefixIcon: Icon(
|
|
Icons.search,
|
|
color: lightGreyColor,
|
|
size: 20.sp,
|
|
),
|
|
suffixIcon: Obx(
|
|
() =>
|
|
controller.joinedSearchText.value.isNotEmpty
|
|
? IconButton(
|
|
icon: Icon(Icons.clear, color: Colors.grey),
|
|
onPressed: () {
|
|
controller.clearJoinedSearch();
|
|
FocusScope.of(context).unfocus();
|
|
},
|
|
)
|
|
: SizedBox(),
|
|
),
|
|
|
|
enabledBorder: OutlineInputBorder(
|
|
borderSide: BorderSide(color: lightGreyColor),
|
|
borderRadius: BorderRadius.circular(8.r),
|
|
),
|
|
focusedBorder: OutlineInputBorder(
|
|
borderSide: BorderSide(color: lightGreyColor),
|
|
borderRadius: BorderRadius.circular(8.r),
|
|
),
|
|
contentPadding: EdgeInsets.symmetric(
|
|
horizontal: 16.w,
|
|
vertical: 12.h,
|
|
),
|
|
filled: true,
|
|
fillColor: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
|
|
// Content
|
|
Expanded(
|
|
child: Obx(() {
|
|
if (controller.isJoinedLoading.value &&
|
|
controller.joinedChallenges.isEmpty) {
|
|
return Center(child: CircularProgressIndicator());
|
|
}
|
|
|
|
if (controller.joinedChallenges.isEmpty) {
|
|
return RefreshIndicator(
|
|
onRefresh: () async {
|
|
controller.refreshJoinedChallenges();
|
|
},
|
|
child: SingleChildScrollView(
|
|
physics: AlwaysScrollableScrollPhysics(),
|
|
child: SizedBox(
|
|
height: 0.6.sh,
|
|
child: Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(
|
|
Icons.group_outlined,
|
|
size: 64.w,
|
|
color: Colors.grey,
|
|
),
|
|
SizedBox(height: 16.h),
|
|
Text(
|
|
'No joined challenges found',
|
|
style: TextStyle(
|
|
fontSize: 16.sp,
|
|
color: Colors.grey[600],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
return RefreshIndicator(
|
|
onRefresh: () async {
|
|
controller.refreshJoinedChallenges();
|
|
},
|
|
child: ListView.builder(
|
|
padding: EdgeInsets.symmetric(horizontal: 16.w),
|
|
itemCount:
|
|
controller.joinedChallenges.length +
|
|
(controller.joinedHasMoreData.value ? 1 : 0),
|
|
itemBuilder: (context, index) {
|
|
if (index == controller.joinedChallenges.length) {
|
|
if (controller.isJoinedLoading.value) {
|
|
return Padding(
|
|
padding: EdgeInsets.all(16.w),
|
|
child: Center(child: CircularProgressIndicator()),
|
|
);
|
|
} else {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
controller.loadMoreJoinedChallenges();
|
|
});
|
|
return SizedBox();
|
|
}
|
|
}
|
|
|
|
final challenge = controller.joinedChallenges[index];
|
|
return Padding(
|
|
padding: EdgeInsets.only(bottom: 16.h),
|
|
child: InkWell(
|
|
onTap: () {
|
|
Get.to(
|
|
() => ChallengeDetailsScreen(
|
|
index: index,
|
|
challengeItem: challenge,
|
|
riseController: controller,
|
|
),
|
|
);
|
|
},
|
|
child: ChallengeCard(
|
|
tabName: riseJoinedTab,
|
|
title: challenge.challengeTitle ?? 'Challenge',
|
|
category: challenge.fitnessGoalTitle ?? 'Fitness',
|
|
participants: '${challenge.totalParticipants ?? 0}',
|
|
imageUrl: challenge.challengeImageName,
|
|
participantImages: challenge.participants,
|
|
isChallengeJoined: challenge.isChallengeJoined!,
|
|
isChallengeStarted: challenge.isChallengeStarted!,
|
|
onWatchVideoPressed: () {
|
|
if (challenge.challengeVideoName != null &&
|
|
challenge.challengeVideoName!.isNotEmpty) {
|
|
showDialog(
|
|
context: context,
|
|
barrierDismissible: true,
|
|
builder: (BuildContext context) {
|
|
return ChallengeVideoPopup(
|
|
videoUrl: challenge.challengeVideoName!,
|
|
title:
|
|
challenge.challengeTitle ?? 'Challenge',
|
|
);
|
|
},
|
|
);
|
|
} else {
|
|
AwesomeCustomSnackbar.show(
|
|
context: context,
|
|
title: 'Action Not Allowed',
|
|
message:
|
|
'Video not available for this challenge',
|
|
contentType: ContentType.failure,
|
|
duration: Duration(seconds: 1),
|
|
);
|
|
}
|
|
},
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|