import 'package:flutter/material.dart'; import '../../../../api/marianumcloud/talk/create_poll/create_poll.dart'; import '../../../../api/marianumcloud/talk/create_poll/create_poll_params.dart'; import '../../../../api/marianumcloud/talk/get_poll/get_poll_state_response.dart'; import '../../../../widget/async_action_button.dart'; import '../../../../widget/demo_restricted.dart'; import '../../../../widget/details_bottom_sheet.dart'; /// Opens the poll creation form. On success the server posts the poll message /// into the chat itself, so the caller only needs to refresh via [onCreated]. void showPollCreateSheet( BuildContext context, { required String token, required VoidCallback onCreated, }) { showDetailsBottomSheet( context, header: const ListTile( leading: Icon(Icons.poll_outlined), title: Text('Umfrage erstellen'), ), children: (sheetCtx) => [_PollCreateBody(token: token, onCreated: onCreated)], ); } class _PollCreateBody extends StatefulWidget { final String token; final VoidCallback onCreated; const _PollCreateBody({required this.token, required this.onCreated}); @override State<_PollCreateBody> createState() => _PollCreateBodyState(); } class _PollCreateBodyState extends State<_PollCreateBody> { final TextEditingController _question = TextEditingController(); final List _options = [ TextEditingController(), TextEditingController(), ]; final AsyncActionController _submitController = AsyncActionController(); bool _hideResults = false; bool _multipleChoice = false; String? _validationError; @override void dispose() { _question.dispose(); for (final controller in _options) { controller.dispose(); } _submitController.dispose(); super.dispose(); } void _addOption() { setState(() => _options.add(TextEditingController())); } void _removeOption(int index) { setState(() { _options.removeAt(index).dispose(); }); } Future _submit() async { if (guardDemoAction(context)) return; final question = _question.text.trim(); final options = _options .map((c) => c.text.trim()) .where((text) => text.isNotEmpty) .toList(); if (question.isEmpty) { setState(() => _validationError = 'Bitte gib eine Frage ein.'); return; } if (options.length < 2) { setState( () => _validationError = 'Bitte gib mindestens zwei Optionen an.', ); return; } setState(() => _validationError = null); await CreatePoll( token: widget.token, params: CreatePollParams( question: question, options: options, resultMode: _hideResults ? pollResultModeHidden : pollResultModePublic, maxVotes: _multipleChoice ? 0 : 1, ), ).run(); if (!mounted) return; Navigator.of(context).pop(); widget.onCreated(); } @override Widget build(BuildContext context) { final theme = Theme.of(context); return Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: TextField( controller: _question, textCapitalization: TextCapitalization.sentences, decoration: const InputDecoration( labelText: 'Frage', hintText: 'Worüber soll abgestimmt werden?', ), ), ), ...List.generate(_options.length, (index) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), child: Row( children: [ Expanded( child: TextField( controller: _options[index], textCapitalization: TextCapitalization.sentences, decoration: InputDecoration( labelText: 'Option ${index + 1}', ), ), ), IconButton( tooltip: 'Option entfernen', icon: const Icon(Icons.remove_circle_outline), onPressed: _options.length > 2 ? () => _removeOption(index) : null, ), ], ), ); }), Align( alignment: Alignment.centerLeft, child: TextButton.icon( onPressed: _addOption, icon: const Icon(Icons.add), label: const Text('Option hinzufügen'), ), ), SwitchListTile( value: _hideResults, onChanged: (value) => setState(() => _hideResults = value), title: const Text('Ergebnisse bis zum Schließen verbergen'), ), SwitchListTile( value: _multipleChoice, onChanged: (value) => setState(() => _multipleChoice = value), title: const Text('Mehrfachauswahl erlauben'), ), if (_validationError != null) Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), child: Text( _validationError!, style: TextStyle(color: theme.colorScheme.error), ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: AsyncActionButton( controller: _submitController, onPressed: _submit, child: const Text('Umfrage erstellen'), ), ), ], ); } }