// 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/text_constant.dart'; // import 'package:onufitness/screens/goals/controllers/goal_controller.dart'; // import 'package:onufitness/screens/goals/models/get_all_goals_response_model.dart'; // import 'package:onufitness/utils/custom_sneakbar.dart'; // import 'package:onufitness/widgets/Buttons/custom_submit_button.dart'; // class PerformanceInputBottomSheet extends StatefulWidget { // final List tasks; // const PerformanceInputBottomSheet({super.key, required this.tasks}); // @override // State createState() => // _PerformanceInputBottomSheetState(); // } // class _PerformanceInputBottomSheetState // extends State { // final goalController = Get.find(); // final _formKey = GlobalKey(); // Task? currentlySelectedTaskFromDropdown; // List uniqueTasks = []; // @override // void initState() { // super.initState(); // initializeUniqueTasks(); // resetForm(); // } // void initializeUniqueTasks() { // // Remove duplicates and create unique list // Set seenTaskIds = {}; // uniqueTasks.clear(); // for (final task in widget.tasks) { // if (task.goalTaskId != null && !seenTaskIds.contains(task.goalTaskId)) { // uniqueTasks.add(task); // seenTaskIds.add(task.goalTaskId!); // } // } // } // void resetForm() { // currentlySelectedTaskFromDropdown = null; // goalController.clearForm(); // } // bool validateForm() { // if (!_formKey.currentState!.validate()) { // return false; // } // if (currentlySelectedTaskFromDropdown == null) { // customSnackbar( // title: "Empty Field", // message: "Please select a task", // duration: 2, // ); // return false; // } // if (goalController.selectedDate.value == null) { // customSnackbar( // title: 'Empty Field', // message: 'Please select a date', // duration: 2, // ); // return false; // } // if (goalController.valueController.text.trim().isEmpty) { // customSnackbar( // title: 'Empty Field', // message: 'Please enter a value', // duration: 2, // ); // return false; // } // final value = double.tryParse(goalController.valueController.text.trim()); // if (value == null || value <= 0) { // customSnackbar( // title: 'Empty Field', // message: 'Please enter a valid positive number', // duration: 2, // ); // return false; // } // return true; // } // Future handleSubmit() async { // if (!validateForm()) { // return; // } // try { // final success = await goalController.inputGoalTask(); // if (success) { // goalController.fetchAllJoinedGoals(isRefresh: true); // if (mounted) { // Future.delayed(Duration(milliseconds: 500), () { // Get.back(); // }); // } // } // } catch (e) { // customSnackbar( // title: 'Error', // message: 'Something went wrong. Please try again.', // duration: 2, // ); // } // } // @override // Widget build(BuildContext context) { // return Container( // decoration: BoxDecoration( // color: Colors.white, // borderRadius: BorderRadius.vertical(top: Radius.circular(20.r)), // ), // child: Padding( // padding: EdgeInsets.all(20.sp), // child: Form( // key: _formKey, // child: SingleChildScrollView( // child: Column( // mainAxisSize: MainAxisSize.min, // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // Center( // child: Container( // height: 4.h, // width: 40.w, // decoration: BoxDecoration( // color: Color(darkGreyColor), // borderRadius: BorderRadius.circular(2.r), // ), // ), // ), // SizedBox(height: 20.h), // Text( // 'Input Your Performance', // style: TextStyle( // fontSize: largeSizeText, // fontWeight: FontWeight.bold, // color: Colors.black, // ), // ), // SizedBox(height: 24.h), // GestureDetector( // onTap: () => goalController.selectDate(context), // child: Container( // width: double.infinity, // padding: EdgeInsets.symmetric( // horizontal: 16.w, // vertical: 16.h, // ), // decoration: BoxDecoration( // color: textFieldFillColor, // borderRadius: BorderRadius.circular(12.r), // border: Border.all( // color: // goalController.selectedDate.value == null // ? Colors.red.withValues(alpha: 0.3) // : lightGreyColor, // ), // ), // child: Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, // children: [ // Obx( // () => Text( // goalController.showSelectedDateToUI.value.isEmpty // ? 'Select Date' // : goalController.showSelectedDateToUI.value, // style: TextStyle( // fontSize: regularSizeText, // color: // goalController // .showSelectedDateToUI // .value // .isEmpty // ? Color(darkGreyColor) // : Colors.black, // ), // ), // ), // Icon( // Icons.calendar_today, // color: Color(darkGreyColor), // size: 20.sp, // ), // ], // ), // ), // ), // SizedBox(height: 20.h), // Container( // width: double.infinity, // padding: EdgeInsets.symmetric( // horizontal: 16.w, // vertical: 4.h, // ), // decoration: BoxDecoration( // color: textFieldFillColor, // borderRadius: BorderRadius.circular(12.r), // border: Border.all( // color: // currentlySelectedTaskFromDropdown == null // ? Colors.red.withValues(alpha: 0.3) // : lightGreyColor, // ), // ), // child: DropdownButtonHideUnderline( // child: DropdownButton( // isExpanded: true, // value: currentlySelectedTaskFromDropdown, // hint: Text( // 'Select Task', // style: TextStyle( // fontSize: regularSizeText, // color: Color(darkGreyColor), // ), // ), // icon: Icon( // Icons.keyboard_arrow_down, // color: Color(darkGreyColor), // size: 24.sp, // ), // style: TextStyle( // fontSize: regularSizeText, // color: Colors.black, // ), // items: // uniqueTasks.map((Task task) { // return DropdownMenuItem( // value: task, // // child: Column( // // crossAxisAlignment: CrossAxisAlignment.start, // // mainAxisSize: MainAxisSize.min, // // children: [ // // Text( // // task.taskTitle ?? 'Untitled Task', // // style: TextStyle( // // fontSize: regularSizeText, // // color: Colors.black, // // fontWeight: FontWeight.w400, // // ), // // ), // // ], // // ), // child: Text( // task.taskTitle ?? 'Untitled Task', // style: TextStyle( // fontSize: regularSizeText, // color: Colors.black, // fontWeight: FontWeight.w400, // ), // ), // ); // }).toList(), // onChanged: (Task? newValue) { // if (newValue != null) { // setState(() { // currentlySelectedTaskFromDropdown = newValue; // }); // goalController.updateSelectedTask(newValue); // } // }, // dropdownColor: Colors.white, // borderRadius: BorderRadius.circular(12.r), // ), // ), // ), // SizedBox(height: 20.h), // Container( // width: double.infinity, // padding: EdgeInsets.symmetric( // horizontal: 16.w, // vertical: 16.h, // ), // decoration: BoxDecoration( // color: textFieldFillColor, // borderRadius: BorderRadius.circular(12.r), // border: Border.all(color: lightGreyColor), // ), // child: Text( // currentlySelectedTaskFromDropdown?.taskUnit ?? 'Unit', // style: TextStyle( // fontSize: regularSizeText, // color: // currentlySelectedTaskFromDropdown == null // ? Color(darkGreyColor) // : Colors.black, // ), // ), // ), // SizedBox(height: 20.h), // Container( // width: double.infinity, // decoration: BoxDecoration( // color: textFieldFillColor, // borderRadius: BorderRadius.circular(12.r), // border: Border.all(color: lightGreyColor), // ), // child: TextFormField( // controller: goalController.valueController, // keyboardType: TextInputType.numberWithOptions( // decimal: true, // ), // style: TextStyle( // fontSize: regularSizeText, // color: Colors.black, // ), // decoration: InputDecoration( // hintText: 'Enter value', // hintStyle: TextStyle( // color: Color(darkGreyColor), // fontSize: regularSizeText, // ), // border: InputBorder.none, // contentPadding: EdgeInsets.symmetric( // horizontal: 16.w, // vertical: 16.h, // ), // ), // validator: (value) { // if (value == null || value.trim().isEmpty) { // return 'Please enter a value'; // } // final numValue = double.tryParse(value.trim()); // if (numValue == null || numValue <= 0) { // return 'Please enter a valid positive number'; // } // return null; // }, // ), // ), // SizedBox(height: 32.h), // Obx( // () => CustomSubmitButton( // isLoading: goalController.isInputLoading.value, // text: "Submit", // onPressed: handleSubmit, // ), // ), // ], // ), // ), // ), // ), // ); // } // } //.......Above one is with Task Dropdown, Below one is with Task BottomSheet....................................................................................... 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/text_constant.dart'; import 'package:onufitness/screens/goals/controllers/goal_controller.dart'; import 'package:onufitness/screens/goals/models/get_all_goals_response_model.dart'; import 'package:onufitness/utils/custom_sneakbar.dart'; import 'package:onufitness/widgets/Buttons/custom_submit_button.dart'; class PerformanceInputBottomSheet extends StatefulWidget { final List tasks; const PerformanceInputBottomSheet({super.key, required this.tasks}); @override State createState() => _PerformanceInputBottomSheetState(); } class _PerformanceInputBottomSheetState extends State { final goalController = Get.find(); final _formKey = GlobalKey(); Task? selectedTask; late List uniqueTasks; @override void initState() { super.initState(); _initializeData(); } void _initializeData() { final seenIds = {}; uniqueTasks = widget.tasks .where( (task) => task.goalTaskId != null && seenIds.add(task.goalTaskId!), ) .toList(); goalController.clearForm(); } bool _validateAndShowError() { if (!_formKey.currentState!.validate()) return false; final validations = [ (selectedTask == null, "Please select a task"), (goalController.selectedDate.value == null, "Please select a date"), ( goalController.valueController.text.trim().isEmpty, "Please enter a value", ), ]; for (final (condition, message) in validations) { if (condition) { customSnackbar(title: "Empty Field", message: message, duration: 2); return false; } } return true; } Future _handleSubmit() async { if (!_validateAndShowError()) return; try { if (await goalController.inputGoalTask()) { goalController.fetchAllJoinedGoals(isRefresh: true); if (mounted) Future.delayed(500.milliseconds, Get.back); } } catch (e) { customSnackbar( title: 'Error', message: 'Something went wrong. Please try again.', duration: 2, ); } } Widget _buildDropdownField() { return GestureDetector( onTap: () => _showTaskPicker(), child: Container( width: double.infinity, padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), decoration: BoxDecoration( color: textFieldFillColor, borderRadius: BorderRadius.circular(12.r), border: Border.all( color: selectedTask == null ? Colors.red.withValues(alpha: 0.3) : lightGreyColor, ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( selectedTask?.taskTitle ?? 'Select Task', style: TextStyle( fontSize: regularSizeText, color: selectedTask == null ? Color(darkGreyColor) : Colors.black, ), overflow: TextOverflow.ellipsis, ), ), Icon( Icons.keyboard_arrow_down, color: Color(darkGreyColor), size: 24.sp, ), ], ), ), ); } Widget _buildRadioButton({required bool isSelected}) { return Container( width: 20.sp, height: 20.sp, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: isSelected ? Theme.of(context).primaryColor : Color(darkGreyColor).withValues(alpha: 0.4), width: 2.0, ), color: Colors.white, ), child: isSelected ? Center( child: Container( width: 10.sp, height: 10.sp, decoration: BoxDecoration( shape: BoxShape.circle, color: Theme.of(context).primaryColor, ), ), ) : null, ); } void _showTaskPicker() { showModalBottomSheet( context: context, backgroundColor: Colors.transparent, isScrollControlled: true, useSafeArea: false, builder: (context) => Container( constraints: BoxConstraints( maxHeight: MediaQuery.of(context).size.height * 0.6, minHeight: 250.h, ), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(24.r)), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.1), blurRadius: 10, offset: Offset(0, -5), ), ], ), child: Column( mainAxisSize: MainAxisSize.min, children: [ // Handle Container( margin: EdgeInsets.only(top: 12.h), height: 4.h, width: 40.w, decoration: BoxDecoration( color: Color(darkGreyColor).withValues(alpha: 0.3), borderRadius: BorderRadius.circular(2.r), ), ), // Header Container( padding: EdgeInsets.symmetric( horizontal: 20.w, vertical: 20.h, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Select Task', style: TextStyle( fontSize: largeSizeText, fontWeight: FontWeight.bold, color: Colors.black, ), ), GestureDetector( onTap: () => Navigator.pop(context), child: Container( padding: EdgeInsets.all(8.sp), decoration: BoxDecoration( color: Color(darkGreyColor).withValues(alpha: 0.1), borderRadius: BorderRadius.circular(20.r), ), child: Icon( Icons.close, size: 20.sp, color: Color(darkGreyColor), ), ), ), ], ), ), // Divider Container( height: 1, color: Color(darkGreyColor).withValues(alpha: 0.1), ), // Task List Flexible( child: ListView.separated( padding: EdgeInsets.symmetric(vertical: 8.h), itemCount: uniqueTasks.length, separatorBuilder: (context, index) => Container( height: 1, margin: EdgeInsets.symmetric(horizontal: 20.w), color: Color(darkGreyColor).withValues(alpha: 0.05), ), itemBuilder: (context, index) { final task = uniqueTasks[index]; final isSelected = selectedTask?.goalTaskId == task.goalTaskId; return InkWell( onTap: () { setState(() => selectedTask = task); goalController.updateSelectedTask(task); Navigator.pop(context); }, child: Container( padding: EdgeInsets.symmetric( horizontal: 20.w, vertical: 16.h, ), color: isSelected ? Theme.of( context, ).primaryColor.withValues(alpha: 0.05) : Colors.transparent, child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( task.taskTitle ?? 'Untitled Task', style: TextStyle( fontSize: regularSizeText, fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400, color: isSelected ? Theme.of(context).primaryColor : Colors.black, ), ), if (task.taskUnit?.isNotEmpty == true) ...[ SizedBox(height: 4.h), Text( 'Unit: ${task.taskUnit}', style: TextStyle( fontSize: smallSizeText, color: Color(darkGreyColor), ), ), ], ], ), ), SizedBox(width: 12.w), _buildRadioButton(isSelected: isSelected), ], ), ), ); }, ), ), ], ), ), ); } @override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.end, children: [ Container( constraints: BoxConstraints( maxHeight: MediaQuery.of(context).size.height * 0.9, ), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(20.r)), ), child: Padding( padding: EdgeInsets.all(20.sp), child: Form( key: _formKey, child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Handle Center( child: Container( height: 4.h, width: 40.w, decoration: BoxDecoration( color: Color(darkGreyColor), borderRadius: BorderRadius.circular(2.r), ), ), ), SizedBox(height: 20.h), // Title Text( 'Input Your Performance', style: TextStyle( fontSize: largeSizeText, fontWeight: FontWeight.bold, ), ), SizedBox(height: 24.h), // Date Selector GestureDetector( onTap: () => goalController.selectDate(context), child: Container( width: double.infinity, padding: EdgeInsets.symmetric( horizontal: 16.w, vertical: 16.h, ), decoration: BoxDecoration( color: textFieldFillColor, borderRadius: BorderRadius.circular(12.r), border: Border.all( color: goalController.selectedDate.value == null ? Colors.red.withValues(alpha: 0.3) : lightGreyColor, ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Obx( () => Text( goalController .showSelectedDateToUI .value .isEmpty ? 'Select Date' : goalController.showSelectedDateToUI.value, style: TextStyle( fontSize: regularSizeText, color: goalController .showSelectedDateToUI .value .isEmpty ? Color(darkGreyColor) : Colors.black, ), ), ), Icon( Icons.calendar_today, color: Color(darkGreyColor), size: 20.sp, ), ], ), ), ), SizedBox(height: 20.h), // Task Dropdown (Custom) _buildDropdownField(), SizedBox(height: 20.h), // Unit Display Container( width: double.infinity, padding: EdgeInsets.symmetric( horizontal: 16.w, vertical: 16.h, ), decoration: BoxDecoration( color: textFieldFillColor, borderRadius: BorderRadius.circular(12.r), border: Border.all(color: lightGreyColor), ), child: Text( selectedTask?.taskUnit ?? 'Unit', style: TextStyle( fontSize: regularSizeText, color: selectedTask == null ? Color(darkGreyColor) : Colors.black, ), ), ), SizedBox(height: 20.h), // Value Input TextFormField( controller: goalController.valueController, keyboardType: const TextInputType.numberWithOptions( decimal: true, ), style: TextStyle( fontSize: regularSizeText, color: Colors.black, ), decoration: InputDecoration( hintText: 'Enter value', hintStyle: TextStyle( color: Color(darkGreyColor), fontSize: regularSizeText, ), filled: true, fillColor: textFieldFillColor, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), borderSide: BorderSide(color: lightGreyColor), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), borderSide: BorderSide(color: lightGreyColor), ), contentPadding: EdgeInsets.symmetric( horizontal: 16.w, vertical: 16.h, ), ), validator: (value) { if (value?.trim().isEmpty ?? true) { return 'Please enter a value'; } if (double.tryParse(value!.trim()) == null || double.parse(value.trim()) <= 0) { return 'Please enter a valid positive number'; } return null; }, ), SizedBox(height: 32.h), // Submit Button Obx( () => CustomSubmitButton( isLoading: goalController.isInputLoading.value, text: "Submit", onPressed: _handleSubmit, ), ), ], ), ), ), ), ), Container( padding: EdgeInsetsDirectional.only( bottom: MediaQuery.of(context).viewPadding.bottom, ), color: Colors.white, ), ], ); } }