Files
Regroup/lib/Main_Screens/Community_HomePage/PostScreen.dart
Shubham Shetty ef0c761b95 Merge pull request #137 from WDI-Ideas/managegroups
manage groups in communities completed and changes for create post us…
2024-08-22 12:14:34 +05:30

1400 lines
56 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:dotted_border/dotted_border.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart' hide MultipartFile, FormData;
import 'package:regroup/Common/CommonGlassmorphism.dart';
import 'package:regroup/Common/base_manager.dart';
import 'package:regroup/Feed%20Module/Main_Screens/Community/Model/communitylistModel.dart'
as communitylist;
import 'package:regroup/Feed%20Module/Main_Screens/Community/Model/tagsmainModel.dart';
import 'package:regroup/Feed%20Module/Main_Screens/Community/view_model/postApi.dart';
import 'package:regroup/Feed%20Module/Main_Screens/Community/view_model/postinList.dart';
import 'package:regroup/Global.dart';
import 'package:regroup/Utils/Common/CommonAppbar.dart';
import 'package:regroup/Utils/Common/CommonDropdown.dart';
import 'package:regroup/Utils/Common/CustomNextButton.dart';
import 'package:regroup/Utils/Common/CustomTextformfield.dart';
import 'package:regroup/Utils/Common/ImageUpload.dart';
import 'package:regroup/Utils/Common/sized_box.dart';
import 'package:regroup/Utils/colors.dart';
import 'package:regroup/Utils/dialogs.dart';
import 'package:regroup/Utils/texts.dart';
import 'package:regroup/resources/routes/route_name.dart';
import 'package:remove_emoji_input_formatter/remove_emoji_input_formatter.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:path/path.dart' as path;
class PostScreen extends StatefulWidget {
const PostScreen({super.key});
@override
State<PostScreen> createState() => _PostScreenState();
}
class _PostScreenState extends State<PostScreen> {
List<File?> bannerPath = [];
bool isbannerAdded = false;
var selectedContainerIndices = <int>{}.obs;
void toggleSelectedIndex(int index) {
if (selectedContainerIndices.contains(index)) {
selectedContainerIndices.remove(index);
} else {
selectedContainerIndices.add(index);
}
}
TextEditingController captioncontroller = TextEditingController();
TextEditingController ctatitilecontroller = TextEditingController();
TextEditingController ctalinkcontroller = TextEditingController();
bool _isSecondDropdownEnabled = false;
communitylist.CommunityListModel? communityModel;
List<communitylist.Data> postcommunity = [];
List<String> _postindrop = [];
List<String> _postindropimages = [];
Future<void> fetchCommunitylist() async {
CommunityLsitApi abilityLsitAPI = CommunityLsitApi();
ResponseData<dynamic> response = await abilityLsitAPI.getPostinList();
if (response.status == ResponseStatus.SUCCESS) {
communityModel =
communitylist.CommunityListModel.fromJson(response.data!);
setState(() {
postcommunity = communityModel!.data ?? []; // Store the fetched cities
_postindrop = postcommunity
.map((platform) => platform.community!.communityName.toString())
.toList();
_postindropimages = postcommunity
.map((platform) =>
platform.community!.communityProfilePhoto.toString())
.toList();
});
log(postcommunity.toString());
// Check if there are no communities and show a toast message
if (_postindrop.isEmpty) {
utils.showToast('Please join a community to post.');
}
} else {
print('Failed to fetch abilities');
}
}
List<int> selectedabilityid = [];
int? communityid;
String? _selectedPostType;
int? posttagtype;
bool isCommunitySelected = false;
void getCatIdFromName(List<String> selectedAbilities) {
selectedabilityid.clear(); // Clear existing selections
for (var name in selectedAbilities) {
for (var i = 0; i < postcommunity.length; i++) {
if (name == postcommunity[i].community!.communityName) {
selectedabilityid.add(postcommunity[i].community!.id!);
communityid = postcommunity[i].community!.id!;
setState(() {
_selectedPostType = null;
_isSecondDropdownEnabled = false;
});
// Fetch tags for the selected community
// fetchPopularTags(communityid!, tagtype!);
// _isSecondDropdownEnabled = true;
// if (tagtype != null) {
// fetchPopularTags(communityid!, tagtype!);
// _isSecondDropdownEnabled = true;
// }
break; // Assuming each name is unique, we break after finding a match
}
}
}
print('Selected IDs: $selectedabilityid');
}
List<Data> tags = []; // Change the type to List<Data>
Future<void> fetchPopularTags(int communityId, int tagtype) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
token = prefs.getString('access-token');
String basicAuth = 'Basic ' +
base64.encode(utf8
.encode('RegroupUserName:71%@L%es^bUX94`J9XT*@bh,._WWM{\$%^^&&'));
try {
final response = await Dio().get(
// 'https://regroup.betadelivery.com/api/v1/fetch-popular-tags?manage_community_xid=$communityId&name=',
'https://regroup.betadelivery.com/api/v1/fetch-popular-tags?manage_community_xid=$communityId&is_special=$tagtype&name=',
options: Options(
headers: {'authorization': basicAuth, 'access-token': token},
));
if (response.statusCode == 200) {
List<dynamic> data = response.data['data'];
// Map the data to a list of Data objects
tags = data.map((tag) => Data.fromJson(tag)).toList();
// Now you can use the tags for your dropdown or any other purpose
setState(() {}); // Trigger a rebuild to update the UI
} else {
print('Failed to fetch tags');
}
} catch (e) {
print('Error: $e');
}
}
List<int> selectedpopularid = [];
void getPopularIdFromName(List<String> selectedTagNames) {
selectedpopularid.clear(); // Clear existing selections
for (var name in selectedTagNames) {
for (var i = 0; i < tags.length; i++) {
if (name == tags[i].name) {
selectedpopularid.add(tags[i].id!);
break; // Assuming each name is unique, we break after finding a match
}
}
}
// You can now use the selectedpopularid list as needed
print('Selected IDs: $selectedpopularid');
}
@override
void initState() {
// TODO: implement initState
fetchCommunitylist();
super.initState();
}
String _selectedPostas = '';
void _onItemSelected(String value) {
setState(() {
_selectedPostas = value;
});
}
TextEditingController _tagController = TextEditingController();
tagUploadata() async {
utils.loader();
Map<String, dynamic> updata = {
'manage_community_xid': communityid,
"name": _tagController.text,
};
final data = await Communitypostmethod().postCreatedTag(updata);
if (data.status == ResponseStatus.SUCCESS) {
Get.back();
print("Tag created done");
_tagController.clear();
utils.showToast(data.message);
final tagData = data.data;
// Create a Data object and add it to createdtags
final newTag = CreateData(
id: tagData['data']["id"],
name: tagData['data']["name"],
);
setState(() {
createdtags.add(newTag);
selectedpopularid
.add(newTag.id); // Add the new tag ID to selectedpopularid
});
} else {
Get.back();
print("tag not created");
return utils.showToast(data.message);
}
}
void _showCreateTagDialog() {
showDialog(
barrierDismissible: false,
// barrierColor: Colors.transparent,
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: const Color(0xFF222935).withOpacity(0.9),
title: const Text(
"Add Tag",
style: TextStyle(color: Colors.white),
),
content: TextField(
style: const TextStyle(color: Colors.white),
controller: _tagController,
decoration: const InputDecoration(
labelText: "Tag",
labelStyle: TextStyle(color: AppColors.white),
disabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.black),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.black)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.black)),
),
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text("Cancel", style: TextStyle(color: AppColors.white)),
),
TextButton(
onPressed: () async {
tagUploadata();
Navigator.of(context).pop();
},
child: const Text("Submit", style: TextStyle(color: AppColors.white)),
),
],
);
},
);
}
List<CreateData> createdtags = [];
Widget buildSelectedTags() {
return Wrap(
spacing: 8.0,
runSpacing: 4.0,
children: createdtags
.where((tag) => selectedpopularid.contains(tag.id))
.map((tag) {
return Chip(
label:
Text('#${tag.name}', style: const TextStyle(color: Colors.white)),
backgroundColor: const Color(0xFFD90B2E).withOpacity(0.9),
side: const BorderSide(color: Colors.black),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.r),
side: const BorderSide(width: 1, color: Colors.white)),
onDeleted: () {
setState(() {
selectedpopularid.remove(tag.id);
createdtags.removeWhere((t) => t.id == tag.id);
print(selectedpopularid
.toString()); // Remove the tag from createdtags
});
},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
padding: const EdgeInsets.symmetric(horizontal: 16),
);
}).toList(),
);
}
bool isValidWebBannerLink(String link) {
RegExp urlRegExp = RegExp(
r"^(http(s)?://)?"
r"((([a-zA-Z0-9-]+)\.)+[a-zA-Z]{2,}|"
r"((\d{1,3}\.){3}\d{1,3}))"
r"(:\d{1,5})?(/([a-zA-Z0-9-._?,'+&%\$#=~])*)?$",
);
return urlRegExp.hasMatch(link);
}
indiUploadata() async {
utils.loader();
List<MultipartFile> medialist = [];
for (var file in bannerPath.where((file) => file != null)) {
medialist.add(
await MultipartFile.fromFile(
file!.path,
filename: path.basename(file.path),
),
);
}
String selectedtags = '[${selectedpopularid.join(',')}]';
print('Selected tags: $selectedtags');
FormData formdata = FormData.fromMap({
"caption": captioncontroller.text,
"file": medialist[0],
"post_in": communityid,
"manage_tags_xids": selectedtags,
"post_as": _selectedPostas,
"is_announcement": posttagtype
});
final data = await Communitypostmethod().postUpload(formdata);
if (data.status == ResponseStatus.SUCCESS) {
Get.back();
print("post done");
successdialog();
return utils.showToast(data.message);
} else {
Get.back();
print("post not done");
return utils.showToast(data.message);
}
}
busUploadata() async {
utils.loader();
List<MultipartFile> medialist = [];
for (var file in bannerPath.where((file) => file != null)) {
medialist.add(
await MultipartFile.fromFile(
file!.path,
filename: path.basename(file.path),
),
);
}
String selectedtags = '[${selectedpopularid.join(',')}]';
print('Selected tags: $selectedtags');
FormData formdata = FormData.fromMap({
"caption": captioncontroller.text,
"file": medialist[0],
"post_in": communityid,
"manage_tags_xids": selectedtags,
"post_as": _selectedPostas,
"cta_title": ctatitilecontroller.text,
"cta_link": ctalinkcontroller.text,
"is_announcement": posttagtype
});
final data = await Communitypostmethod().postUpload(formdata);
if (data.status == ResponseStatus.SUCCESS) {
Get.back();
print("post done");
successdialog();
return utils.showToast(data.message);
} else {
Get.back();
print("post not done");
return utils.showToast(data.message);
}
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(
backgroundColor: const Color(0xFF222935),
extendBody: true,
resizeToAvoidBottomInset: false,
appBar: const CommonAppbar(
titleTxt: "Create a post",
),
body: Stack(children: [
Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/png/Ellipse 1496.png"),
fit: BoxFit.fill)),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
sizedBoxHeight(20.h),
text16w400_FCFCFC("Post in"),
sizedBoxHeight(18.h),
CustomDropDownCheckBoxPostNew(
header: "Select post in",
title: "",
listData: _postindrop,
onItemSelected:
// getCatIdFromName,
(List<String> selectedAbilities) {
getCatIdFromName(selectedAbilities);
isCommunitySelected = true;
},
// (p0) {},
images: _postindropimages,
leadingImage: const SizedBox(),
),
sizedBoxHeight(20.h),
// sizedBoxHeight(20.h),
text16w400_FCFCFC("Post type"),
sizedBoxHeight(18.h),
CustomRadioListTile(
title: 'Regular',
subtitle:
'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
value: 'Regular',
groupValue: _selectedPostType,
onChanged: (String? value) {
if (isCommunitySelected && communityid != null) {
setState(() {
_selectedPostType = value!;
posttagtype = 0;
fetchPopularTags(communityid!,
posttagtype!); // Call the API after both selections
_isSecondDropdownEnabled = true;
});
} else {
utils.showToast('Please select a community first.');
}
},
activeColor: Color(0XFFD90B2E),
),
CustomRadioListTile(
title: 'Announcement',
subtitle:
'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
value: 'Announcement',
groupValue: _selectedPostType,
onChanged: (String? value) {
if (isCommunitySelected && communityid != null) {
setState(() {
_selectedPostType = value!;
posttagtype = 1;
fetchPopularTags(communityid!,
posttagtype!); // Call the API after both selections
_isSecondDropdownEnabled = true;
});
} else {
utils.showToast('Please select a community first.');
}
},
activeColor: Color(0XFFD90B2E),
),
sizedBoxHeight(38.h),
// text16w400_FCFCFC("Caption"),
// sizedBoxHeight(18.h),
CustomTextFormField2(
maxlines: 3,
hintText: "Enter caption",
validator: (value) {
if (value!.isEmpty) {
return 'Enter caption';
}
return null;
},
inputFormatters: [
// LengthLimitingTextInputFormatter(20),
RemoveEmojiInputFormatter(),
// FilteringTextInputFormatter.allow(RegExp('[a-zA-Z ]'))
],
textEditingController: captioncontroller,
),
sizedBoxHeight(25.h),
text16w400_FCFCFC("Media"),
sizedBoxHeight(18.h),
DottedBorder(
strokeWidth: 1,
dashPattern: const [7, 4],
borderType: BorderType.RRect,
radius: Radius.circular(14.r),
color: const Color(0xFF434A53),
child: commonGlassUI(
width: double.infinity,
height: 339.h,
borderRadius: BorderRadius.circular(10.r),
borderColor: Colors.transparent,
customWidget: bannerPath.isNotEmpty && isbannerAdded
? Stack(children: [
Image.file(
bannerPath[0]!,
fit: BoxFit.cover,
width: double.infinity,
),
Positioned(
right: 5,
bottom: 5,
child: GestureDetector(
onTap: () {
bannerPath.clear();
isbannerAdded = false;
setState(() {});
},
child: Container(
width: 27,
height: 27,
decoration: ShapeDecoration(
color: const Color(0xFF7E7E7E),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(
5)),
),
child: const Icon(
Icons.delete_outline_outlined,
color: Colors.white,
))),
),
])
: GestureDetector(
onTap: () {
ImageUploadBottomSheet().showModal(
context,
false,
(result) {
if (result != null &&
result.isNotEmpty) {
var file = File(result);
// Check if the file size exceeds 10 MB
int fileSizeInBytes =
file.lengthSync();
double fileSizeInMB =
fileSizeInBytes / (1024 * 1024);
if (fileSizeInMB > 10) {
// Show toast message if the file size exceeds 10 MB
utils.showToast(
"The selected file is too large. Max file size is 10 MB.");
} else {
// Clear the existing image and add the new one
bannerPath.clear();
bannerPath.add(file);
isbannerAdded = true;
setState(() {});
}
} else {
// Handle case where no image is selected
bannerPath.clear();
isbannerAdded = false;
setState(() {});
}
if (Platform.isAndroid) {
Get.back();
}
},
);
},
child: Padding(
padding:
EdgeInsets.symmetric(vertical: 16.h),
child: Center(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Image.asset(
"assets/images/png/bi_download.png",
height: 36.h,
width: 36.w,
),
sizedBoxHeight(10.h),
text14w400_FCFCFC("Upload image"),
sizedBoxHeight(8.h),
text8w400_8A8A8A(
"Allowed file extensions: jpg, png, gif Max file size: 10 MB"),
],
),
),
),
)),
),
sizedBoxHeight(25.h),
text16w400_FCFCFC("Interest"),
sizedBoxHeight(18.h),
_isSecondDropdownEnabled == true
? CustomDropDownPopularTag(
tags: tags,
onItemSelected: (selectedTags) {
List<String> selectedTagNames = selectedTags
.map((tag) => tag.name!)
.toList();
getPopularIdFromName(selectedTagNames);
// Handle selected tags here
},
isFirstDropdownSelected: _isSecondDropdownEnabled,
)
:
// SizedBox(),
Center(
child:
// isCommunitySelected == true
// ? text14400white('Select post type')
// :
text14400white('No Interests')),
sizedBoxHeight(25.h),
_isSecondDropdownEnabled == true
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildSelectedTags(),
sizedBoxHeight(10.h),
GestureDetector(
onTap: () {
_showCreateTagDialog();
},
child: Container(
height: 35,
width: 178.w,
decoration: BoxDecoration(
color: const Color(0xFFFFFFFF)
.withOpacity(0.2),
borderRadius: BorderRadius.circular(30),
border: Border.all(
color: const Color(0xFFD90B2E),
width: 1)),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20),
child: Center(
child: text14w400_FCFCFC(
'+create new interest')),
),
),
),
],
)
: const SizedBox(),
sizedBoxHeight(25.h),
globalAccountType == '1'
? const SizedBox()
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
text16w400_FCFCFC("CTA Title"),
sizedBoxHeight(18.h),
CustomTextFormField(
// maxlines: 3,
hintText: "Enter cta title",
validator: (value) {
if (value!.isEmpty) {
return 'Enter cta title';
}
return null;
},
inputFormatters: [
// LengthLimitingTextInputFormatter(20),
RemoveEmojiInputFormatter(),
FilteringTextInputFormatter.allow(
RegExp('[a-zA-Z ]'))
],
textEditingController: ctatitilecontroller,
),
sizedBoxHeight(25.h),
text16w400_FCFCFC("CTA Link"),
sizedBoxHeight(18.h),
CustomTextFormField(
// maxlines: 3,
hintText: "Enter cta link",
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a web banner link.';
} else if (!isValidWebBannerLink(value)) {
return 'Please enter a valid web banner link.';
}
return null;
},
inputFormatters: [
// LengthLimitingTextInputFormatter(20),
RemoveEmojiInputFormatter(),
// FilteringTextInputFormatter.allow(
// RegExp('[a-zA-Z ]'))
],
textEditingController: ctalinkcontroller,
),
],
),
sizedBoxHeight(25.h),
text16w400_FCFCFC("Post as"),
sizedBoxHeight(18.h),
CustomDropDownRadio(
header: "Select post as",
title: "",
listData: const ['Individual', 'Anonymous'],
onItemSelected: _onItemSelected,
leadingImage: const SizedBox()),
sizedBoxHeight(25.h),
sizedBoxHeight(40.h),
CustomButton(
text: 'Submit post',
onPressed: () {
if (globalAccountType == '1') {
// Condition for account type 1
if (selectedabilityid.isEmpty ||
selectedpopularid.isEmpty ||
captioncontroller.text.isEmpty ||
_selectedPostas.isEmpty ||
posttagtype.isBlank!) {
print('Tags selected are $selectedpopularid');
print(
'Community selected are $selectedabilityid');
print('Post as selected are $_selectedPostas');
utils.showToast('Please fill all fields');
} else if (bannerPath.isEmpty) {
utils.showToast('Please add a media image');
} else {
print('Tags selected are $selectedpopularid');
print(
'Community selected are $selectedabilityid');
print('Post as selected are $_selectedPostas');
indiUploadata();
// indisuccess();
}
} else if (globalAccountType == '2') {
// Condition for account type 2
// You can define different validation criteria here for account type 2
if (selectedabilityid.isEmpty ||
selectedpopularid.isEmpty ||
captioncontroller.text.isEmpty ||
_selectedPostas.isEmpty ||
ctalinkcontroller.text.isEmpty ||
ctatitilecontroller.text.isEmpty ||
posttagtype.isBlank!) {
print('Tags selected are $selectedpopularid');
print(
'Community selected are $selectedabilityid');
utils.showToast('Please fill all fields');
} else if (bannerPath.isEmpty) {
utils.showToast('Please add a media image');
} else {
print('Tags selected are $selectedpopularid');
print(
'Community selected are $selectedabilityid');
busUploadata();
}
} else {
utils.showToast('Unknown account type');
}
},
),
sizedBoxHeight(150.h),
]),
),
),
])),
);
}
void successdialog() {
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return AlertDialog(
insetPadding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
contentPadding: const EdgeInsets.fromLTRB(24, 8, 24, 24),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(14.r))),
backgroundColor: const Color(0xFF222935),
content: Padding(
padding: EdgeInsets.symmetric(horizontal: 30.w),
child: Column(mainAxisSize: MainAxisSize.min, children: [
sizedBoxHeight(20.h),
Image.asset(
'assets/images/png/Frame 1000004082.png',
width: 199.w,
height: 158.h,
),
sizedBoxHeight(20.h),
text18w500Center_FCFCFC(
'Your post has been succesfully uploaded'),
sizedBoxHeight(20.h),
InkWell(
onTap: () {
Get.toNamed(RouteName.mainscreen, arguments: 0);
},
child: Container(
height: 35.h,
width: 216.w,
decoration: BoxDecoration(
border: Border.all(
color: const Color(0xFF434A53), width: 1),
gradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color.fromRGBO(255, 255, 255, 0.054),
Color.fromRGBO(255, 255, 255, 0.072),
],
stops: [0.0233, 1.0],
transform: GradientRotation(271.14 *
(3.141592653589793 /
180)), // Converting degrees to radians
),
borderRadius: BorderRadius.circular(30.r),
),
child: Center(child: text14w400_FCFCFC('View post')),
),
),
sizedBoxHeight(40.h)
])));
},
);
}
void successBottomsheet() {
Get.bottomSheet(Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14.r),
color: const Color(0xFF222935)),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30.w),
child: Column(mainAxisSize: MainAxisSize.min, children: [
sizedBoxHeight(20.h),
Image.asset(
'assets/images/png/Frame 1000004082.png',
width: 199.w,
height: 158.h,
),
sizedBoxHeight(20.h),
text18w500Center_FCFCFC(
'Your post has been succesfully uploaded'),
sizedBoxHeight(20.h),
InkWell(
onTap: () {
Get.toNamed(RouteName.mainscreen, arguments: 0);
},
child: Container(
height: 35.h,
width: 216.w,
decoration: BoxDecoration(
border:
Border.all(color: const Color(0xFF434A53), width: 1),
gradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color.fromRGBO(255, 255, 255, 0.054),
Color.fromRGBO(255, 255, 255, 0.072),
],
stops: [0.0233, 1.0],
transform: GradientRotation(271.14 *
(3.141592653589793 /
180)), // Converting degrees to radians
),
borderRadius: BorderRadius.circular(30.r),
),
child: Center(child: text14w400_FCFCFC('Check out')),
),
),
sizedBoxHeight(40.h)
]))));
}
Widget containerTile({
required String text,
required int index,
}) {
return Obx(() {
return GestureDetector(
onTap: () {
toggleSelectedIndex(index);
},
child: Container(
height: 35,
decoration: BoxDecoration(
color: selectedContainerIndices.contains(index)
? const Color(0xFFD90B2E).withOpacity(0.4)
: const Color(0xFFFFFFFF).withOpacity(0.2),
borderRadius: BorderRadius.circular(30),
border: Border.all(color: const Color(0xFFD90B2E), width: 1)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Center(child: text14w400_FCFCFC(text)),
),
),
);
});
}
}
class CustomDropDownCheckBoxPostNew extends StatefulWidget {
const CustomDropDownCheckBoxPostNew({
Key? key,
required this.header,
required this.title,
required this.listData,
required this.onItemSelected,
required this.images,
required this.leadingImage,
}) : super(key: key);
final String header;
final String title;
final List<String> listData;
final Function(List<String>) onItemSelected;
final List<String>? images;
final Widget? leadingImage;
@override
State<CustomDropDownCheckBoxPostNew> createState() =>
_CustomDropDownCheckBoxPostNewState();
}
class _CustomDropDownCheckBoxPostNewState
extends State<CustomDropDownCheckBoxPostNew> {
RxBool onDropTap = false.obs;
RxString selectedValue =
''.obs; // Use a single string to track the selected value
@override
Widget build(BuildContext context) {
return Obx(
() => Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
onDropTap.value = !onDropTap.value;
},
child: Container(
width: double.infinity,
padding: EdgeInsets.only(
top: 14.0, bottom: 14.0, right: 22.w, left: 12.w),
decoration: BoxDecoration(
color: const Color(0xFFFFFFFF).withOpacity(0.10),
borderRadius: onDropTap.value
? BorderRadius.vertical(top: Radius.circular(30.r))
: BorderRadius.circular(30.r),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFFffffff).withOpacity(0.50),
const Color(0xFFFFFFFF).withOpacity(0.50),
],
),
border: Border.all(color: const Color(0xFF434A53)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Row(
children: [
if (widget.leadingImage != null) widget.leadingImage!,
SizedBox(width: 16.w),
Expanded(
child: Text(
selectedValue.value.isEmpty
? widget.header
: selectedValue.value,
style: TextStyle(
color: Colors.white,
fontSize: 16.sp,
fontFamily: 'Helvetica',
fontWeight: FontWeight.w400,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
),
onDropTap.value
? Image.asset('assets/images/png/arrowup.png')
: Image.asset('assets/images/png/arrowdown.png'),
],
),
),
),
if (onDropTap.value)
Container(
width: double.infinity,
height: 250.h,
decoration: BoxDecoration(
color: const Color(0xFFFFFFFF).withOpacity(0.10),
borderRadius:
BorderRadius.vertical(bottom: Radius.circular(30.r)),
border: Border.all(color: const Color(0xFF434A53)),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFFffffff).withOpacity(0.50),
const Color(0xFFFFFFFF).withOpacity(0.50),
],
),
),
child: widget.listData.isEmpty
? Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
child: Center(
child: Text(
'No communities available',
style: TextStyle(
color: Colors.white,
fontSize: 16.sp,
fontFamily: 'Helvetica',
fontWeight: FontWeight.w400,
),
),
),
)
: ListView.builder(
shrinkWrap: true,
physics: ScrollPhysics(),
itemCount: widget.listData.length,
itemBuilder: (context, index) {
String item = widget.listData[index];
String image = widget.images![index];
return InkWell(
onTap: () {
setState(() {
selectedValue.value =
item; // Set the selected value
onDropTap.value = false; // Close the dropdown
});
widget.onItemSelected(
[item]); // Pass the selected item
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
child: Row(
children: [
Container(
width: 40.w,
height: 40.h,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(8.r),
image: image.isEmpty
? null
: DecorationImage(
image: NetworkImage(image),
fit: BoxFit.cover,
)),
),
SizedBox(width: 8.w),
Expanded(
child: Text(
item,
style: TextStyle(
color: Colors.white,
fontSize: 16.sp,
fontFamily: 'hiragino',
fontWeight: FontWeight.w500,
),
overflow: TextOverflow.ellipsis,
),
),
Checkbox(
side: const BorderSide(
color: Color(0xFF434A53)),
value: selectedValue.value ==
item, // Check if item is selected
activeColor: const Color(0xFF434A53),
checkColor: Colors.white,
onChanged: (bool? value) {
if (value == true) {
setState(() {
selectedValue.value =
item; // Set the selected value
onDropTap.value =
false; // Close the dropdown
});
widget.onItemSelected(
[item]); // Pass the selected item
}
},
),
],
),
),
if (index != widget.listData.length - 1)
const Divider(
thickness: 1, color: Color(0xFF434A53)),
],
),
);
},
),
),
],
),
);
}
}
class CustomDropDownPopularTag extends StatefulWidget {
final List<Data> tags;
final Function(List<Data>) onItemSelected;
final bool isFirstDropdownSelected;
CustomDropDownPopularTag({
required this.tags,
required this.onItemSelected,
required this.isFirstDropdownSelected,
});
@override
_CustomDropDownPopularTagState createState() =>
_CustomDropDownPopularTagState();
}
class _CustomDropDownPopularTagState extends State<CustomDropDownPopularTag> {
RxBool onDropTap = false.obs;
RxList<Data> selectedTags = <Data>[].obs;
RxList<Data> filteredTags = <Data>[].obs;
TextEditingController textEditingController = TextEditingController();
@override
void initState() {
super.initState();
filteredTags.value = widget.tags;
textEditingController.addListener(filterTags);
}
@override
void didUpdateWidget(CustomDropDownPopularTag oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.tags != oldWidget.tags) {
// Clear the selected tags and update the filtered tags when tags change
selectedTags.clear();
filteredTags.value = widget.tags;
}
}
void _handleDropdownTap() {
if (widget.isFirstDropdownSelected) {
onDropTap.value = !onDropTap.value;
} else {
utils.showToast('Please select an item from the first dropdown.');
}
}
void filterTags() {
String query = textEditingController.text.toLowerCase();
if (query.isNotEmpty) {
filteredTags.value = widget.tags
.where((tag) =>
tag.name!.toLowerCase().contains(query) &&
!selectedTags.contains(tag))
.toList();
} else {
filteredTags.value =
widget.tags.where((tag) => !selectedTags.contains(tag)).toList();
}
onDropTap.value = filteredTags.isNotEmpty;
}
@override
Widget build(BuildContext context) {
return Obx(
() => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Dropdown Search Input
Container(
width: double.infinity,
height: 50,
padding: const EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration(
color: const Color(0xFFFFFFFF).withOpacity(0.10),
borderRadius: onDropTap.value && filteredTags.isNotEmpty
? const BorderRadius.vertical(
top: Radius.circular(30),
)
: BorderRadius.circular(30),
border: Border.all(color: const Color(0xFF434A53)),
),
child: Center(
child: TextFormField(
controller: textEditingController,
style: const TextStyle(
fontSize: 16,
color: Colors.white,
fontFamily: 'Helvetica',
),
cursorColor: Colors.red,
obscureText: false,
decoration: InputDecoration(
hintText: 'Search Tags',
hintStyle: const TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.w400,
fontFamily: 'Helvetica',
),
suffixIcon: GestureDetector(
onTap: _handleDropdownTap,
child: SizedBox(
height: 20,
width: 20,
child: Center(
child: Icon(
onDropTap.value
? Icons.arrow_drop_up
: Icons.arrow_drop_down,
color: Colors.white,
),
),
),
),
border: InputBorder.none,
),
onTap: _handleDropdownTap),
),
),
// Dropdown List
if (onDropTap.value && filteredTags.isNotEmpty)
Container(
height: 250.h,
width: double.infinity,
decoration: BoxDecoration(
color: const Color(0xFFFFFFFF).withOpacity(0.10),
borderRadius: const BorderRadius.vertical(
bottom: Radius.circular(30),
),
border: Border.all(color: const Color(0xFF434A53)),
),
child: ListView.builder(
shrinkWrap: true,
physics: ScrollPhysics(),
itemCount: filteredTags.length,
itemBuilder: (context, index) {
return InkWell(
onTap: () {
Data selectedItem = filteredTags[index];
if (selectedTags.contains(selectedItem)) {
selectedTags.remove(selectedItem);
} else {
selectedTags.add(selectedItem);
}
textEditingController.clear();
widget.onItemSelected(selectedTags.toList());
filterTags(); // Update the filtered list
},
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
children: [
Text(
filteredTags[index].name!,
style: const TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w400,
fontFamily: 'Helvetica',
),
),
const Spacer(),
Text(
'Popularity: ${filteredTags[index].tagPopularity}',
style: const TextStyle(
color: Colors.white70,
fontSize: 12,
),
),
],
),
),
);
},
),
),
sizedBoxHeight(20.h),
// Selected Tags Displayed as Chips
if (selectedTags.isNotEmpty)
Wrap(
spacing: 8.0,
runSpacing: 4.0,
children: selectedTags.map((tag) {
return Chip(
label: Text('#${tag.name!}',
style: const TextStyle(color: Colors.white)),
backgroundColor: const Color(0xFFD90B2E).withOpacity(0.9),
side: const BorderSide(color: Colors.black),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.r),
side: const BorderSide(width: 1, color: Colors.white)),
onDeleted: () {
selectedTags.remove(tag);
widget.onItemSelected(selectedTags.toList());
filterTags(); // Update the filtered list after removing a tag
},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
padding: const EdgeInsets.symmetric(horizontal: 16),
);
}).toList(),
),
],
),
);
}
}
class CreateData {
final int id;
final String name;
CreateData({required this.id, required this.name});
}
class CustomRadioListTile extends StatelessWidget {
final String title;
final String subtitle;
final String value;
final String? groupValue;
final ValueChanged<String?> onChanged;
final Color activeColor;
const CustomRadioListTile({
Key? key,
required this.title,
required this.subtitle,
required this.value,
required this.groupValue,
required this.onChanged,
required this.activeColor,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
onChanged(value);
},
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: Transform.translate(
offset: Offset(0, -10),
child: Transform.scale(
scale: 1.5,
child: Radio<String>(
value: value,
groupValue: groupValue,
onChanged: onChanged,
activeColor: activeColor,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
),
),
title: text18w400white(title),
subtitle: text14400white(subtitle),
),
);
}
}