import 'dart:convert'; import 'dart:developer'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:onufitness/constants/api_endpoints.dart'; import 'package:onufitness/constants/api_enum_constant.dart'; import 'package:onufitness/screens/echoboard/controllers/echoboard_controller.dart'; import 'package:onufitness/services/api_services/base_api_services.dart'; import 'package:onufitness/utils/custom_sneakbar.dart'; class PollController extends GetxController { //........................................................ final questionController = TextEditingController(); final RxList optionControllers = [ TextEditingController(), TextEditingController(), ].obs; // State variables..................................................... final RxBool isLoading = false.obs; final RxString errorMessage = ''.obs; final RxInt postTypeID = 1.obs; final RxInt postVisibilityID = 1.obs; // Post visibility options............................................. final List> visibilityOptions = [ { 'id': ApiEnum.publicPostVisibilityID, 'name': 'Public', 'icon': Icons.public, 'description': 'Anyone can see', }, { 'id': ApiEnum.privatePostVisibilityID, 'name': 'Private', 'icon': Icons.lock, 'description': 'Share with me', }, { 'id': 3, 'name': 'Connections', 'icon': Icons.people, 'description': 'Selected Connections', }, ]; @override void onClose() { questionController.dispose(); for (var controller in optionControllers) { controller.dispose(); } super.onClose(); } // Add a new option field.................................. void addOptionField() { if (optionControllers.length < 5) { optionControllers.add(TextEditingController()); } } // Remove an option field..................................................... void removeOptionField(int index) { if (optionControllers.length > 2) { final controller = optionControllers[index]; optionControllers.removeAt(index); controller.dispose(); } } // Set visibility ID..................................................... void setVisibility(int id) { postVisibilityID.value = id; } // Reset the form..................................................... void resetForm() { questionController.clear(); for (var controller in optionControllers) { controller.clear(); } postVisibilityID.value = 1; errorMessage.value = ''; // Reset options to default two...................................... final currentLength = optionControllers.length; if (currentLength > 2) { for (int i = 2; i < currentLength; i++) { optionControllers[i].dispose(); } optionControllers.value = [optionControllers[0], optionControllers[1]]; } } // Validate the form..................................................... bool validateForm() { if (questionController.text.trim().isEmpty) { errorMessage.value = 'Please enter a question'; return false; } // Check options - we need at least 2 valid options int validOptions = 0; for (var controller in optionControllers) { if (controller.text.trim().isNotEmpty) { validOptions++; } } if (validOptions < 2) { errorMessage.value = 'Please enter at least 2 options'; return false; } return true; } //............................................................................ // Create poll API call....................................................... //............................................................................. Future createPoll({int tribeIdForTribeEchoboard = 0}) async { final echoBoardController = Get.find(); bool ret = false; if (!validateForm()) { return false; } errorMessage.value = ''; isLoading.value = true; try { final Map requestBody = tribeIdForTribeEchoboard == 0 ? { 'question': questionController.text.trim(), 'postTypeID': ApiEnum.pollPostTypeID, 'postVisibilityID': postVisibilityID.value, "deviceTypeID": Platform.isAndroid ? ApiEnum.androidDeviceTypeID : ApiEnum.iosDeviceTypeID, 'isTribe': false, // Hard code, key will remove in future 'tribeID': 0, // Hard code, key will remove in future 'options': optionControllers .where( (controller) => controller.text.trim().isNotEmpty, ) .map((controller) => controller.text.trim()) .toList(), "ExclusiveConnectionsJson": jsonEncode( echoBoardController.selectedConnections, ), } : { 'question': questionController.text.trim(), 'postTypeID': ApiEnum.pollPostTypeID, "deviceTypeID": Platform.isAndroid ? ApiEnum.androidDeviceTypeID : ApiEnum.iosDeviceTypeID, 'tribeID': tribeIdForTribeEchoboard, 'options': optionControllers .where( (controller) => controller.text.trim().isNotEmpty, ) .map((controller) => controller.text.trim()) .toList(), }; final url = tribeIdForTribeEchoboard != 0 ? ApiUrl.createTribePollPost : ApiUrl.createPollPost; log("Creating poll with body: ${jsonEncode(requestBody)}"); var response = await ApiBase.postRequest( extendedURL: url, body: requestBody, ); log("Response StatusCode ----->> ${response.statusCode.toString()}"); if (response.statusCode == 200 || response.statusCode == 201) { ret = true; customSnackbar( title: "Success", message: "Poll created successfully!", duration: 1, ); resetForm(); } else { ret = false; customSnackbar( title: "Error", message: "Failed to create poll. Please try again after sometime", ); } } catch (e) { ret = false; log("Catch from createPoll: ${e.toString()}"); customSnackbar( title: "Error", message: "Failed to create poll. Please try again after sometime", ); } finally { isLoading.value = false; } return ret; } }