onufitness_mobile/lib/screens/echoboard/views/friend_request_screen.dart
2026-01-13 11:36:24 +05:30

382 lines
16 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:onufitness/constants/api_enum_constant.dart';
import 'package:onufitness/constants/color_constant.dart';
import 'package:onufitness/constants/text_constant.dart';
import 'package:onufitness/routes/route_constant.dart';
import 'package:onufitness/screens/echoboard/controllers/connection_and_tribe_controller.dart';
import 'package:onufitness/screens/echoboard/controllers/profile_controller.dart';
import 'package:onufitness/screens/echoboard/widget/friend_request_send_user_card.dart';
import 'package:onufitness/screens/echoboard/widget/invitation_card.dart';
import 'package:onufitness/screens/echoboard/widget/pagination_widget.dart';
import 'package:onufitness/widgets/appbars/custom_appbar.dart';
class FriendRequestScreen extends StatefulWidget {
final bool isFriendTab;
const FriendRequestScreen({super.key, this.isFriendTab = false});
@override
State<FriendRequestScreen> createState() => _FriendRequestScreenState();
}
class _FriendRequestScreenState extends State<FriendRequestScreen> {
late final SocialConnectionController controller;
late final ProfileController profileController;
@override
void initState() {
super.initState();
// Get existing controller or create new one
if (!Get.isRegistered<SocialConnectionController>()) {
Get.put(SocialConnectionController());
}
controller = Get.find<SocialConnectionController>();
if (!Get.isRegistered<ProfileController>()) {
Get.put(ProfileController());
}
profileController = Get.find<ProfileController>();
// Load data for current tab after widget builds
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
// If we're not already on the correct tab, switch to it
if (controller.currentTab.value != "Invitations" &&
widget.isFriendTab == false) {
controller.changeTab("Invitations");
} else {
// Just refresh current data
controller.clearCurrentTabData();
controller.searchUsers();
}
}
});
}
void _navigateToFriendsList() {
controller.currentTab.value = "Friends";
controller.clearSearch();
}
@override
Widget build(BuildContext context) {
return PopScope(
canPop: true,
onPopInvokedWithResult: (didPop, result) {
// Clean up search state when leaving
controller.searchValue.value = "";
controller.searchController.clear();
},
child: Container(
color: Colors.white,
child: SafeArea(
child: Scaffold(
appBar: CustomAppBar(
title: "Connections",
leading: IconButton(
onPressed: () {
controller.searchValue.value = "";
controller.searchController.clear();
Get.back();
},
icon: const Icon(Icons.arrow_back_ios),
),
textColor: appbarTextColor,
backgroundColor: Colors.white,
titleFontSize: appBarHeardingText,
actions: [
Padding(
padding: EdgeInsets.only(right: 12.w),
child: Container(
decoration: BoxDecoration(
color: Color(primaryColor),
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.15),
blurRadius: 3,
offset: const Offset(0, 3),
),
],
),
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(12),
onTap: () {
Get.toNamed(RouteConstant.viewTribeScreen);
},
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 16.w,
vertical: 12.h,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.groups_rounded,
color: appbarTextColor,
size: mediumSizeText,
),
SizedBox(width: 8.w),
Text(
"Tribes",
style: TextStyle(
color: appbarTextColor,
fontWeight: FontWeight.w700,
fontSize: verySmallSizeText,
letterSpacing: 0.3,
),
),
],
),
),
),
),
),
),
],
),
body: Column(
children: [
// Tab selector
Padding(
padding: EdgeInsets.all(15.sp),
child: Obx(
() => Row(
children: [
Expanded(
child: InkWell(
onTap: () => controller.changeTab("Invitations"),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 12),
decoration: BoxDecoration(
color:
controller.currentTab.value == "Invitations"
? Colors.black
: Colors.white,
borderRadius: BorderRadius.circular(25),
border: Border.all(color: Colors.grey.shade300),
),
child: Center(
child: Text(
"Invitations",
style: TextStyle(
color:
controller.currentTab.value ==
"Invitations"
? Colors.white
: Colors.black,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
const SizedBox(width: 10),
Expanded(
child: InkWell(
onTap: () => controller.changeTab("Friends"),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 12),
decoration: BoxDecoration(
color:
controller.currentTab.value == "Friends"
? Colors.black
: Colors.white,
borderRadius: BorderRadius.circular(25),
border: Border.all(color: Colors.grey.shade300),
),
child: Center(
child: Text(
"Friends",
style: TextStyle(
color:
controller.currentTab.value == "Friends"
? Colors.white
: Colors.black,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
const SizedBox(width: 10),
InkWell(
onTap: () {
Get.toNamed(
RouteConstant.userListViewScreenForTribe,
);
_navigateToFriendsList();
},
child: Row(
children: [
Icon(Icons.add, size: regularSizeText),
const SizedBox(width: 5),
Text(
"Create tribe",
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: smallSizeText,
),
),
],
),
),
],
),
),
),
// Search Field
Padding(
padding: EdgeInsets.symmetric(horizontal: 15.sp),
child: TextField(
controller: controller.searchController,
decoration: InputDecoration(
hintText: 'Search for members',
hintStyle: TextStyle(
fontWeight: FontWeight.w600,
color: greyBorderColor,
),
prefixIcon: const Padding(
padding: EdgeInsets.only(left: 20),
child: Icon(Icons.search),
),
suffixIcon: IconButton(
icon: const Padding(
padding: EdgeInsets.only(right: 10),
child: Icon(Icons.close),
),
onPressed: () {
controller.clearSearch();
},
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide.none,
),
filled: true,
fillColor: textFieldFillColor,
),
onChanged: (value) => controller.onSearchChanged(value),
onSubmitted: (_) {
controller.clearCurrentTabData();
controller.searchUsers();
},
),
),
const SizedBox(height: 10),
// User List
Expanded(
child: Obx(() {
if (controller.isLoading.value) {
return const Center(
child: CircularProgressIndicator(color: Colors.black),
);
}
final users = controller.usersData.value?.data?.items;
if (users == null || users.isEmpty) {
return Center(
child: Text(
controller.currentTab.value == "Invitations"
? 'No invitation requests'
: 'No friends found',
style: TextStyle(
fontSize: regularSizeText,
color: Colors.grey[600],
),
),
);
}
return ListView.builder(
itemCount: users.length,
padding: const EdgeInsets.all(10),
itemBuilder: (context, index) {
final user = users[index];
// Show different UI based on the current tab
if (controller.currentTab.value == "Invitations") {
return InkWell(
onTap: () {
if (user.userId != null) {
profileController.selectedUserId.value =
user.userId.toString();
Get.toNamed(
RouteConstant.userSocialProfileScreen,
);
}
},
child: InvitationCard(
user: user,
onAccept: () async {
await controller.respondToConnectionRequest(
user.userId!,
ApiEnum.accepted,
);
},
onReject: () async {
await controller.respondToConnectionRequest(
user.userId!,
ApiEnum.rejected,
);
},
loadingIds:
controller.responseToInvitationLoading,
),
);
} else {
return InkWell(
onTap: () {
if (user.userId != null) {
profileController.selectedUserId.value =
user.userId.toString();
Get.toNamed(
RouteConstant.userSocialProfileScreen,
);
}
},
child: ConnectUserCard(
user: user,
onConnect: () async {
if (user.userId != null) {
await controller.sendConnectionRequest(
user.userId!,
);
}
},
connectionStatus:
user.connectionStatus ?? 'Accepted',
loadingContains:
controller.sendConnectionRequestLoading,
isYourFriend: true,
),
);
}
},
);
}),
),
//Pagination widget.....................................................
showsUserListPagination(controller),
//......................................................................
],
),
),
),
),
);
}
}