Advertisement
NotSooFriendly94

work_scree.dart

Apr 27th, 2024
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 34.67 KB | None | 0 0
  1. import 'dart:convert';
  2. import 'dart:io';
  3. //import 'meeting_fin.dart';
  4. import 'package:http/http.dart' as http;
  5. import 'package:flutter/material.dart';
  6. import 'package:intl/intl.dart';
  7. import 'package:shared_preferences/shared_preferences.dart';
  8. import 'package:path_provider/path_provider.dart';
  9. import 'package:flutter_moving_background/flutter_moving_background.dart';
  10. import 'package:task_app_es/host_page.dart';
  11. import 'login_page.dart';
  12. import 'meeting_list_screen.dart';
  13.  
  14. class WorkScreen extends StatefulWidget {
  15.   final String id;
  16.   final String username;
  17.   final String esEmail;
  18.   final String passCode;
  19.   final String deviceID;
  20.   final String jobs;
  21.   final String meetingName;
  22.  
  23.   const WorkScreen(
  24.       {Key? key,
  25.       required this.id,
  26.       required this.username,
  27.       required this.esEmail,
  28.       required this.passCode,
  29.       required this.deviceID,
  30.       required this.meetingName,
  31.       required this.jobs})
  32.       : super(key: key);
  33.  
  34.   @override
  35.   _WorkScreenState createState() => _WorkScreenState();
  36. }
  37.  
  38. class Job {
  39.   final String name;
  40.   final List<String> actions;
  41.  
  42.   Job(this.name, this.actions);
  43. }
  44.  
  45. class _WorkScreenState extends State<WorkScreen> {
  46.   final TextEditingController _meetingNameController = TextEditingController();
  47.   final TextEditingController _jobNameController = TextEditingController();
  48.   final TextEditingController _actionController = TextEditingController();
  49.   String? meetingName;
  50.   String? jobName;
  51.   String? currentAction;
  52.   List<String> actions = [];
  53.   List<Job> jobs = [];
  54.   final ScrollController _scrollController = ScrollController();
  55.   bool _isScrolled = false;
  56.   bool _fadeInCompleted = false;
  57.   bool _meetingOngoing = false; // New variable to track ongoing meeting
  58.   bool _tasksCompleted = false; // New variable to track tasks completion
  59.   bool _showBackArrow = true;
  60.   bool get _isActionInputEmpty => _actionController.text.trim().isEmpty;
  61.  
  62.   @override
  63.   void initState() {
  64.     super.initState();
  65.     print('ID: ${widget.id}');
  66.     print('Username: ${widget.username}');
  67.     print('ES_Email: ${widget.esEmail}');
  68.     print('Passcode: ${widget.passCode}');
  69.     print('Device ID passed over to WorkScreen: ${widget.deviceID}');
  70.     _scrollController.addListener(_onScroll);
  71.     Future.delayed(const Duration(milliseconds: 1000), () {
  72.       _startFadeInAnimation();
  73.     });
  74.   }
  75.  
  76.   @override
  77.   void dispose() {
  78.     _scrollController.removeListener(_onScroll);
  79.     _scrollController.dispose();
  80.     super.dispose();
  81.   }
  82.  
  83.   void _onScroll() {
  84.     setState(() {
  85.       _isScrolled =
  86.           _scrollController.hasClients && _scrollController.offset > 0;
  87.     });
  88.   }
  89.  
  90.   void _loginback() {
  91.     // Only navigate back if there is no ongoing meeting
  92.     if (meetingName == null && !_meetingOngoing) {
  93.       Navigator.push(
  94.         context,
  95.         MaterialPageRoute(
  96.           builder: (context) => HostPage(
  97.             id: widget.id,
  98.             username: widget.username,
  99.             passCode: widget.passCode,
  100.             deviceID: widget.deviceID,
  101.             esEmail: widget.esEmail,
  102.             meetingName: '',
  103.             jobs: '',
  104.           ),
  105.         ),
  106.       );
  107.     }
  108.   }
  109.  
  110.   void _startFadeInAnimation() {
  111.     Future.delayed(const Duration(milliseconds: 1000), () {
  112.       setState(() {
  113.         _fadeInCompleted = true;
  114.       });
  115.     });
  116.   }
  117.  
  118.   void _startMeeting() {
  119.     final String newMeetingName = _meetingNameController.text.trim();
  120.     if (newMeetingName.isNotEmpty) {
  121.       setState(() {
  122.         final now = DateTime.now();
  123.         final formattedDate =
  124.             '$newMeetingName (${DateFormat('dd/MM/yyyy - HH:mm').format(now)})';
  125.         meetingName = formattedDate;
  126.         _meetingOngoing = true; // Set meeting ongoing to true
  127.         _meetingNameController.clear();
  128.       });
  129.     } else {
  130.       // Show a styled Snackbar
  131.       ScaffoldMessenger.of(context).showSnackBar(
  132.         SnackBar(
  133.           behavior: SnackBarBehavior.floating,
  134.           elevation: 0,
  135.           content: Container(
  136.             height: 40,
  137.             alignment: Alignment.center,
  138.             padding: const EdgeInsets.symmetric(horizontal: 16.0),
  139.             decoration: BoxDecoration(
  140.               color: const Color.fromARGB(133, 255, 0, 0),
  141.               borderRadius: BorderRadius.circular(20),
  142.               border: Border.all(color: Colors.white),
  143.             ),
  144.             child: const Text(
  145.               'Please write a meeting name',
  146.               textAlign: TextAlign.center,
  147.               style: TextStyle(
  148.                 color: Colors.white,
  149.                 fontSize: 15,
  150.               ),
  151.             ),
  152.           ),
  153.           duration: const Duration(seconds: 4),
  154.           margin: const EdgeInsets.only(bottom: 20),
  155.         ),
  156.       );
  157.     }
  158.   }
  159.  
  160.   void _addJob() {
  161.     final String newJobName = _jobNameController.text.trim();
  162.     if (newJobName.isNotEmpty) {
  163.       setState(() {
  164.         jobName = newJobName;
  165.         jobs.add(Job(jobName!, [])); // Add job with empty actions list
  166.         _jobNameController.clear();
  167.         _tasksCompleted =
  168.             false; // Reset tasks completion status when adding a new task
  169.       });
  170.     } else {
  171.       // Show a styled Snackbar
  172.       ScaffoldMessenger.of(context).showSnackBar(
  173.         SnackBar(
  174.           behavior: SnackBarBehavior.floating,
  175.           elevation: 0,
  176.           content: Container(
  177.             height: 40,
  178.             alignment: Alignment.center,
  179.             padding: const EdgeInsets.symmetric(horizontal: 16.0),
  180.             decoration: BoxDecoration(
  181.               color: const Color.fromARGB(133, 255, 0, 0),
  182.               borderRadius: BorderRadius.circular(20),
  183.               border: Border.all(color: Colors.white),
  184.             ),
  185.             child: const Text(
  186.               'Please write a job name',
  187.               textAlign: TextAlign.center,
  188.               style: TextStyle(
  189.                 color: Colors.white,
  190.                 fontSize: 15,
  191.               ),
  192.             ),
  193.           ),
  194.           duration: const Duration(seconds: 4),
  195.           margin: const EdgeInsets.only(bottom: 20),
  196.         ),
  197.       );
  198.     }
  199.   }
  200.  
  201.   void _addAction() {
  202.     final newAction = _actionController.text.trim();
  203.     if (newAction.isNotEmpty) {
  204.       setState(() {
  205.         actions.add(newAction);
  206.         _actionController.clear();
  207.       });
  208.     } else {
  209.       // Show a styled Snackbar
  210.       ScaffoldMessenger.of(context).showSnackBar(
  211.         SnackBar(
  212.           behavior: SnackBarBehavior.floating,
  213.           elevation: 0,
  214.           content: Container(
  215.             height: 40,
  216.             alignment: Alignment.center,
  217.             padding: const EdgeInsets.symmetric(horizontal: 16.0),
  218.             decoration: BoxDecoration(
  219.               color: const Color.fromARGB(133, 255, 0, 0),
  220.               borderRadius: BorderRadius.circular(20),
  221.               border: Border.all(color: Colors.white),
  222.             ),
  223.             child: const Text(
  224.               'Please enter an action',
  225.               textAlign: TextAlign.center,
  226.               style: TextStyle(
  227.                 color: Colors.white,
  228.                 fontSize: 15,
  229.               ),
  230.             ),
  231.           ),
  232.           duration: const Duration(seconds: 4),
  233.           margin: const EdgeInsets.only(bottom: 20),
  234.         ),
  235.       );
  236.     }
  237.   }
  238.  
  239.   void _completeActions() {
  240.     if (actions.isNotEmpty &&
  241.         jobName != null &&
  242.         _actionController.text.isEmpty) {
  243.       setState(() {
  244.         for (var job in jobs) {
  245.           if (job.name == jobName) {
  246.             job.actions.addAll(actions);
  247.           }
  248.         }
  249.         jobName = null;
  250.         actions.clear();
  251.         _tasksCompleted = true;
  252.       });
  253.     } else {
  254.       ScaffoldMessenger.of(context).showSnackBar(
  255.         const SnackBar(
  256.           content: Text(
  257.             'Please enter actions before saving or complete the current action',
  258.             style: TextStyle(color: Colors.white),
  259.           ),
  260.           backgroundColor: Colors.red,
  261.           duration: Duration(seconds: 4),
  262.         ),
  263.       );
  264.     }
  265.   }
  266.  
  267.   void _deleteJob(Job job) {
  268.     setState(() {
  269.       jobs.remove(job);
  270.     });
  271.   }
  272.  
  273.   void _editJob(Job job) {
  274.     // Create controllers to manage the text editing for each action
  275.     List<TextEditingController> controllers = List.generate(job.actions.length,
  276.         (index) => TextEditingController(text: job.actions[index]));
  277.  
  278.     showDialog(
  279.       context: context,
  280.       builder: (BuildContext context) {
  281.         return AlertDialog(
  282.           title: const Text('Edit Actions'),
  283.           content: Column(
  284.             mainAxisSize: MainAxisSize.min,
  285.             children: [
  286.               for (int i = 0; i < job.actions.length; i++) ...[
  287.                 TextField(
  288.                   controller: controllers[i],
  289.                   onChanged: (value) {
  290.                     // Update the corresponding action in the job actions list
  291.                     job.actions[i] = value;
  292.                   },
  293.                   onSubmitted: (newValue) {
  294.                     // Do nothing when submitted
  295.                   },
  296.                 ),
  297.                 const SizedBox(height: 10),
  298.               ],
  299.             ],
  300.           ),
  301.           actions: <Widget>[
  302.             TextButton(
  303.               onPressed: () {
  304.                 Navigator.of(context)
  305.                     .pop(); // Close the dialog without saving changes
  306.               },
  307.               child: const Text('CANCEL'),
  308.             ),
  309.             ElevatedButton(
  310.               onPressed: () {
  311.                 // Close the dialog
  312.                 Navigator.of(context).pop();
  313.               },
  314.               child: const Text('SAVE CHANGES'),
  315.             ),
  316.           ],
  317.         );
  318.       },
  319.     );
  320.   }
  321.  
  322.   void _meetingFinished() async {
  323.     if (meetingName != null && _tasksCompleted) {
  324.       // Ensure tasks are completed
  325.       // Sanitize the meeting name to remove invalid characters
  326.       final sanitizedMeetingName = meetingName!
  327.           .replaceAll(RegExp(r'[^\w\s]+'),
  328.               '') // Replace non-alphanumeric characters with empty string
  329.           .replaceAll(RegExp(r'\s+'),
  330.               '_'); // Replace whitespace characters with underscore
  331.       print(sanitizedMeetingName);
  332.       // Prepare list of jobs with completed status set to false
  333.       final List<Map<String, dynamic>> jobsWithStatus = jobs
  334.           .map((job) => {
  335.                 'name': job.name,
  336.                 'actions': job.actions,
  337.                 'completed': false, // Set default completed status to false
  338.               })
  339.           .toList();
  340.  
  341.       // Save meeting details locally
  342.       final SharedPreferences prefs = await SharedPreferences.getInstance();
  343.       final meetingDetails = <String, dynamic>{
  344.         'meetingName': meetingName,
  345.         'jobs': jobsWithStatus, // Use the prepared list with completed status
  346.       };
  347.  
  348.       // Log the JSON data to be saved
  349.       print('JSON data to be saved: ${jsonEncode(meetingDetails)}');
  350.  
  351.       // Save meeting details to SharedPreferences
  352.       await prefs.setString('meetingDetails', jsonEncode(meetingDetails));
  353.  
  354.       // Clear current meeting details and reset state variables
  355.       setState(() {
  356.         meetingName = null;
  357.         jobs.clear();
  358.         _meetingOngoing = false; // Set meeting ongoing to false
  359.         _tasksCompleted = false; // Reset tasks completion status
  360.         _showBackArrow = true; // Show the back arrow
  361.       });
  362.  
  363.       // Send the meeting details to the server
  364.       _sendMeetingDetailsToServer(sanitizedMeetingName, meetingDetails);
  365.     } else {
  366.       // Show a snack bar if meeting name is null or tasks are incomplete
  367.       ScaffoldMessenger.of(context).showSnackBar(
  368.         const SnackBar(
  369.           content: Text(
  370.             'Please start a meeting and complete all tasks before finishing it',
  371.             style: TextStyle(color: Colors.white),
  372.           ),
  373.           backgroundColor: Colors.red,
  374.           duration: Duration(seconds: 4),
  375.         ),
  376.       );
  377.     }
  378.   }
  379.  
  380.   Future<void> _sendMeetingDetailsToServer(
  381.       String sanitizedMeetingName, Map<String, dynamic> meetingDetails) async {
  382.     try {
  383.       print('User_ID: ${widget.id}');
  384.       print('Username: ${widget.username}');
  385.       print('Passcode: ${widget.passCode}');
  386.       print('Meeting_Title: $sanitizedMeetingName');
  387.       print('Meeting_Json: ${jsonEncode(meetingDetails)}');
  388.       print('Device_ID: ${widget.deviceID}');
  389.  
  390.       final response = await http.post(
  391.         Uri.parse('https://notsoofriendly.co.uk/TaskApp_ES/handle_save.php'),
  392.         body: {
  393.           'User_ID': widget.id,
  394.           'Username': widget.username,
  395.           'passCode': widget.passCode,
  396.           'Meeting_Title': sanitizedMeetingName,
  397.           'Meeting_Json': jsonEncode(meetingDetails),
  398.           'Device_ID': widget.deviceID,
  399.         },
  400.       );
  401.  
  402.       if (response.statusCode == 200) {
  403.         // Meeting details successfully sent to the server
  404.         print('Meeting details sent to the server successfully');
  405.       } else {
  406.         // Failed to send meeting details to the server
  407.         print('Failed to send meeting details to the server: ${response.body}');
  408.       }
  409.     } catch (e) {
  410.       // Error occurred while sending meeting details
  411.       print('Error sending meeting details to the server: $e');
  412.     }
  413.   }
  414.  
  415.   // Function to navigate to MeetingListScreen
  416.   void _viewMeetings() {
  417.     if (!_meetingOngoing) {
  418.       // Only navigate if there is no ongoing meeting
  419.       Navigator.push(
  420.         context,
  421.         MaterialPageRoute(
  422.           builder: (context) => MeetingListScreen(
  423.             id: widget.id,
  424.             username: widget.username,
  425.             passCode: widget.passCode,
  426.             deviceID: widget.deviceID,
  427.             esEmail: widget.esEmail,
  428.             meetingName: '',
  429.             jobs: '',
  430.           ),
  431.         ),
  432.       );
  433.     }
  434.   }
  435.  
  436.   @override
  437.   Widget build(BuildContext context) {
  438.     return AnimatedOpacity(
  439.       opacity: _fadeInCompleted ? 1.0 : 0.0,
  440.       duration: const Duration(milliseconds: 1500),
  441.       child: Stack(
  442.         children: [
  443.           SizedBox(
  444.             width: MediaQuery.of(context).size.width,
  445.             height: MediaQuery.of(context).size.height,
  446.             child: const MovingBackground(
  447.               backgroundColor: Colors.transparent,
  448.               circles: [
  449.                 MovingCircle(
  450.                     color: Color.fromARGB(149, 39, 2, 102), blurSigma: 100),
  451.                 MovingCircle(
  452.                     color: Color.fromARGB(118, 217, 0, 255), blurSigma: 170),
  453.                 MovingCircle(
  454.                     color: Color.fromARGB(123, 150, 2, 214), blurSigma: 80),
  455.                 MovingCircle(
  456.                     color: Color.fromARGB(115, 84, 10, 105), blurSigma: 120),
  457.                 MovingCircle(
  458.                     color: Color.fromARGB(129, 213, 128, 255), blurSigma: 60),
  459.                 MovingCircle(
  460.                     color: Color.fromARGB(99, 255, 255, 255), blurSigma: 100),
  461.               ],
  462.             ),
  463.           ),
  464.           Scaffold(
  465.             backgroundColor: Colors.transparent,
  466.             appBar: PreferredSize(
  467.               preferredSize: const Size.fromHeight(90.0),
  468.               child: Column(
  469.                 children: [
  470.                   AppBar(
  471.                     backgroundColor: Colors.transparent,
  472.                     title: Text(
  473.                       meetingName ?? 'Work Screen',
  474.                       style: const TextStyle(
  475.                           color: Color.fromARGB(255, 242, 0, 255),
  476.                           fontSize: 18.0),
  477.                       textAlign: TextAlign.center,
  478.                     ),
  479.                     centerTitle: true,
  480.                     automaticallyImplyLeading: false,
  481.                     leading:
  482.                         _showBackArrow // Show the back arrow only if _showBackArrow is true
  483.                             ? IconButton(
  484.                                 icon: Icon(
  485.                                   Icons.arrow_back,
  486.                                   color: meetingName != null
  487.                                       ? Colors.transparent
  488.                                       : Colors.white,
  489.                                 ),
  490.                                 onPressed: _loginback,
  491.                               )
  492.                             : null,
  493.                   ),
  494.                   if (meetingName != null)
  495.                     Container(
  496.                       alignment: Alignment.center,
  497.                       height: 30.0,
  498.                       width: double.maxFinite,
  499.                       child: ElevatedButton(
  500.                         onPressed: _meetingFinished,
  501.                         style: ButtonStyle(
  502.                           backgroundColor: MaterialStateProperty.all<Color>(
  503.                               _tasksCompleted
  504.                                   ? const Color.fromARGB(106, 4, 155,
  505.                                       255) // Change color to gray if meeting is ongoing
  506.                                   : const Color.fromARGB(
  507.                                       106, 168, 168, 168)), // Default color
  508.                           foregroundColor: MaterialStateProperty.all<Color>(
  509.                               _tasksCompleted
  510.                                   ? const Color.fromARGB(203, 255, 255,
  511.                                       255) // Change color to gray if meeting is ongoing
  512.                                   : const Color.fromARGB(153, 149, 149, 149)),
  513.                           side: MaterialStateProperty.all<BorderSide>(
  514.                               _tasksCompleted
  515.                                   ? const BorderSide(
  516.                                       color: Color.fromARGB(212, 0, 200, 255))
  517.                                   : const BorderSide(
  518.                                       color: Color.fromARGB(255, 0, 100, 128))),
  519.                           shape: MaterialStateProperty.all<OutlinedBorder>(
  520.                             RoundedRectangleBorder(
  521.                               borderRadius: BorderRadius.circular(
  522.                                   15.0), // Adjust the radius as needed
  523.                             ),
  524.                           ),
  525.                         ),
  526.                         child: const Text('Finish and Save Meeting',
  527.                             style: TextStyle(
  528.                                 fontSize: 17.0, fontWeight: FontWeight.w700)),
  529.                       ),
  530.                     ),
  531.                 ],
  532.               ),
  533.             ),
  534.             body: SingleChildScrollView(
  535.               controller: _scrollController,
  536.               child: Padding(
  537.                 padding: const EdgeInsets.all(16.0),
  538.                 child: Column(
  539.                   crossAxisAlignment: CrossAxisAlignment.start,
  540.                   children: [
  541.                     if (meetingName == null) ...[
  542.                       Text(
  543.                         'Hello, ${widget.username},',
  544.                         style: const TextStyle(
  545.                           color: Color.fromARGB(
  546.                               139, 251, 0, 255), // Faint white color
  547.                           fontSize: 18.0,
  548.                           fontStyle: FontStyle.italic,
  549.                         ),
  550.                       ),
  551.                       const SizedBox(
  552.                         height: 30,
  553.                       ),
  554.                       const Text(
  555.                         'Meeting Name',
  556.                         style: TextStyle(
  557.                             color: Color.fromARGB(255, 255, 255, 255),
  558.                             fontSize: 25.0,
  559.                             fontWeight: FontWeight.bold),
  560.                       ),
  561.                       TextField(
  562.                         style: const TextStyle(
  563.                             color: Color.fromARGB(255, 242, 0, 255),
  564.                             fontSize: 20.0,
  565.                             fontWeight: FontWeight.bold),
  566.                         controller: _meetingNameController,
  567.                         textCapitalization: TextCapitalization.words,
  568.                         decoration: const InputDecoration(
  569.                             hintText: 'Enter Meeting Name',
  570.                             hintStyle: TextStyle(
  571.                                 fontSize: 15.0,
  572.                                 color: Color.fromARGB(181, 161, 11, 220))),
  573.                         onSubmitted: (_) {
  574.                           _startMeeting();
  575.                         },
  576.                       ),
  577.                     ],
  578.                     const SizedBox(
  579.                         height:
  580.                             20.0), // Move "Meeting Finished" button below blue meeting name header
  581.                     if (meetingName != null && jobName == null) ...[
  582.                       const Text(
  583.                         'Task to be completed -',
  584.                         style: TextStyle(
  585.                             fontSize: 20.0,
  586.                             color: Colors.white,
  587.                             fontWeight: FontWeight.bold),
  588.                       ),
  589.                       TextField(
  590.                         style: const TextStyle(
  591.                             fontSize: 15.0,
  592.                             color: Color.fromARGB(255, 242, 0, 255)),
  593.                         controller: _jobNameController,
  594.                         textCapitalization: TextCapitalization.words,
  595.                         decoration: const InputDecoration(
  596.                             hintText: 'Enter Task',
  597.                             hintStyle: TextStyle(
  598.                                 fontSize: 15.0,
  599.                                 color: Color.fromARGB(181, 161, 11, 220))),
  600.                         onSubmitted: (_) {
  601.                           _addJob();
  602.                         },
  603.                       ),
  604.                     ],
  605.                     if (jobName != null) ...[
  606.                       const SizedBox(height: 20.0),
  607.                       Text(
  608.                         jobName!,
  609.                         style: const TextStyle(
  610.                             color: Color.fromARGB(255, 0, 179, 255),
  611.                             fontSize: 20.0,
  612.                             fontWeight: FontWeight.bold),
  613.                       ),
  614.                       const SizedBox(height: 10.0),
  615.                       const Text(
  616.                         'Actions Required',
  617.                         style: TextStyle(
  618.                             color: Colors.white,
  619.                             fontSize: 20.0,
  620.                             fontWeight: FontWeight.bold),
  621.                       ),
  622.                       TextField(
  623.                         style: const TextStyle(
  624.                             fontSize: 15.0,
  625.                             color: Color.fromARGB(255, 242, 0, 255)),
  626.                         controller: _actionController,
  627.                         textCapitalization: TextCapitalization.words,
  628.                         decoration: const InputDecoration(
  629.                             hintText: 'Enter Action',
  630.                             hintStyle: TextStyle(
  631.                                 fontSize: 15.0,
  632.                                 color: Color.fromARGB(181, 161, 11, 220))),
  633.                         textInputAction: TextInputAction.done,
  634.                         onChanged: (_) {
  635.                           setState(
  636.                               () {}); // Update button state on text input change
  637.                         },
  638.                         onSubmitted: (_) {
  639.                           _addAction();
  640.                         },
  641.                       ),
  642.                       const SizedBox(height: 40.0),
  643.                       Center(
  644.                         child: ElevatedButton(
  645.                           onPressed: () {
  646.                             if (actions.isNotEmpty &&
  647.                                 (_isActionInputEmpty ||
  648.                                     _actionController.text.trim().isEmpty)) {
  649.                               _completeActions();
  650.                             }
  651.                           },
  652.                           style: ButtonStyle(
  653.                             backgroundColor: MaterialStateProperty.all<Color>(
  654.                               actions.isNotEmpty &&
  655.                                       (_isActionInputEmpty ||
  656.                                           _actionController.text.trim().isEmpty)
  657.                                   ? const Color.fromARGB(106, 4, 155, 255)
  658.                                   : const Color.fromARGB(106, 168, 168, 168),
  659.                             ),
  660.                             foregroundColor: MaterialStateProperty.all<Color>(
  661.                               actions.isNotEmpty &&
  662.                                       (_isActionInputEmpty ||
  663.                                           _actionController.text.trim().isEmpty)
  664.                                   ? const Color.fromARGB(203, 255, 255, 255)
  665.                                   : const Color.fromARGB(153, 149, 149, 149),
  666.                             ),
  667.                             side: MaterialStateProperty.all<BorderSide>(
  668.                               actions.isNotEmpty &&
  669.                                       (_isActionInputEmpty ||
  670.                                           _actionController.text.trim().isEmpty)
  671.                                   ? const BorderSide(
  672.                                       color: Color.fromARGB(212, 0, 200, 255))
  673.                                   : const BorderSide(
  674.                                       color: Color.fromARGB(255, 0, 100, 128)),
  675.                             ),
  676.                             shape: MaterialStateProperty.all<OutlinedBorder>(
  677.                               RoundedRectangleBorder(
  678.                                 borderRadius: BorderRadius.circular(20.0),
  679.                               ),
  680.                             ),
  681.                             minimumSize: MaterialStateProperty.all(
  682.                                 Size(25, 31)), // Set minimum size to 0
  683.                           ),
  684.                           child: const Padding(
  685.                             padding: EdgeInsets.zero, // Remove all padding
  686.                             child: Text(
  687.                               'Save Logged Actions',
  688.                               style: TextStyle(
  689.                                   fontSize: 15.0, fontWeight: FontWeight.w700),
  690.                             ),
  691.                           ),
  692.                         ),
  693.                       ),
  694.                       const SizedBox(height: 50.0),
  695.                       const Text(
  696.                         'Logged Actions:',
  697.                         style: TextStyle(
  698.                             color: Colors.white,
  699.                             fontSize: 20.0,
  700.                             fontWeight: FontWeight.bold),
  701.                       ),
  702.                       const SizedBox(height: 15.0),
  703.                       for (var action in actions) ...[
  704.                         Text(
  705.                           '- $action',
  706.                           style: const TextStyle(
  707.                               color: Color.fromARGB(255, 242, 0, 255),
  708.                               fontSize: 17.0),
  709.                         ),
  710.                       ],
  711.                     ],
  712.                     if (meetingName != null) ...[
  713.                       const SizedBox(height: 80.0),
  714.                       const Text(
  715.                         'Task List:',
  716.                         style: TextStyle(
  717.                           color: Colors.white,
  718.                           fontSize: 20.0,
  719.                           fontWeight: FontWeight.bold,
  720.                         ),
  721.                       ),
  722.                       const SizedBox(height: 20.0),
  723.                       for (var job in jobs) ...[
  724.                         const SizedBox(
  725.                           height: 10.0,
  726.                         ),
  727.                         Dismissible(
  728.                           key: Key(job.name),
  729.                           direction: DismissDirection.horizontal,
  730.                           background: Container(
  731.                             color: Color.fromARGB(132, 11, 145, 255),
  732.                             alignment: Alignment.centerLeft,
  733.                             child: const Padding(
  734.                               padding: EdgeInsets.only(left: 20.0),
  735.                               child: Icon(Icons.edit, color: Colors.white),
  736.                             ),
  737.                           ),
  738.                           secondaryBackground: Container(
  739.                             color: Color.fromARGB(123, 255, 50, 35),
  740.                             alignment: Alignment.centerRight,
  741.                             child: const Padding(
  742.                               padding: EdgeInsets.only(right: 20.0),
  743.                               child: Icon(Icons.delete, color: Colors.white),
  744.                             ),
  745.                           ),
  746.                           confirmDismiss: (direction) async {
  747.                             if (direction == DismissDirection.endToStart) {
  748.                               // Deleting job
  749.                               return await showDialog(
  750.                                 context: context,
  751.                                 builder: (BuildContext context) {
  752.                                   return AlertDialog(
  753.                                     title: const Text('Confirm Delete'),
  754.                                     content: const Text(
  755.                                         'Are you sure you want to delete this job?'),
  756.                                     actions: <Widget>[
  757.                                       TextButton(
  758.                                         onPressed: () =>
  759.                                             Navigator.of(context).pop(false),
  760.                                         child: const Text('CANCEL'),
  761.                                       ),
  762.                                       TextButton(
  763.                                         onPressed: () =>
  764.                                             Navigator.of(context).pop(true),
  765.                                         child: const Text('DELETE'),
  766.                                       ),
  767.                                     ],
  768.                                   );
  769.                                 },
  770.                               );
  771.                             } else {
  772.                               // Editing job
  773.                               _editJob(job);
  774.                               return false;
  775.                             }
  776.                           },
  777.                           onDismissed: (direction) {
  778.                             if (direction == DismissDirection.endToStart) {
  779.                               _deleteJob(job);
  780.                             }
  781.                           },
  782.                           child: ExpansionTile(
  783.                             title: Text(job.name),
  784.                             textColor: Colors.white,
  785.                             collapsedTextColor: Colors.white,
  786.                             collapsedIconColor:
  787.                                 const Color.fromARGB(255, 0, 0, 0),
  788.                             collapsedBackgroundColor:
  789.                                 const Color.fromARGB(77, 4, 155, 255),
  790.                             collapsedShape: RoundedRectangleBorder(
  791.                               borderRadius: BorderRadius.circular(
  792.                                   15.0), // Adjust the radius as needed
  793.                             ),
  794.                             shape: RoundedRectangleBorder(
  795.                               borderRadius: BorderRadius.circular(
  796.                                   15.0), // Adjust the radius as needed
  797.                             ),
  798.                             backgroundColor:
  799.                                 const Color.fromARGB(101, 4, 155, 255),
  800.                             iconColor: const Color.fromARGB(255, 0, 0, 0),
  801.                             children: [
  802.                               for (var action in job.actions) ...[
  803.                                 Text(
  804.                                   '- $action',
  805.                                   style: const TextStyle(
  806.                                       color: Color.fromARGB(255, 255, 255, 255),
  807.                                       fontSize: 15.0),
  808.                                 ),
  809.                                 const SizedBox(height: 15.0)
  810.                               ],
  811.                             ], // Change tile color here
  812.                           ),
  813.                         ),
  814.                       ],
  815.                     ],
  816.                   ],
  817.                 ),
  818.               ),
  819.             ),
  820.             floatingActionButtonLocation:
  821.                 FloatingActionButtonLocation.centerFloat,
  822.             floatingActionButton: AnimatedOpacity(
  823.               opacity: _isScrolled
  824.                   ? 0.35
  825.                   : 1, // Change opacity based on scroll position
  826.               duration: const Duration(
  827.                   milliseconds: 200), // Add duration for a smoother transition
  828.               child: SizedBox(
  829.                 height: 25, // Change the height of the button
  830.                 child: ElevatedButton(
  831.                   onPressed: _viewMeetings,
  832.                   style: ButtonStyle(
  833.                     backgroundColor: MaterialStateProperty.all<Color>(
  834.                         _meetingOngoing
  835.                             ? Color.fromARGB(106, 168, 168,
  836.                                 168) // Change color to gray if meeting is ongoing
  837.                             : const Color.fromARGB(
  838.                                 106, 4, 155, 255)), // Default color
  839.                     foregroundColor: MaterialStateProperty.all<Color>(
  840.                         _meetingOngoing
  841.                             ? Color.fromARGB(153, 149, 149,
  842.                                 149) // Change color to gray if meeting is ongoing
  843.                             : Color.fromARGB(203, 255, 255, 255)),
  844.                     side: MaterialStateProperty.all<BorderSide>(_meetingOngoing
  845.                         ? const BorderSide(
  846.                             color: Color.fromARGB(255, 0, 100, 128))
  847.                         : const BorderSide(
  848.                             color: Color.fromARGB(212, 0, 200, 255))),
  849.  
  850.                     shape: MaterialStateProperty.all<OutlinedBorder>(
  851.                       RoundedRectangleBorder(
  852.                         borderRadius: BorderRadius.circular(
  853.                             10.0), // Adjust the radius as needed
  854.                       ),
  855.                     ),
  856.                   ),
  857.                   child: const Text('View Meetings',
  858.                       style: TextStyle(
  859.                           fontSize: 15.0, fontWeight: FontWeight.bold)),
  860.                 ),
  861.               ),
  862.             ),
  863.           ),
  864.         ],
  865.       ),
  866.     );
  867.   }
  868. }
  869.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement