import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:island/models/poll.dart'; import 'package:island/models/publisher.dart'; import 'package:island/screens/creators/poll/poll_list.dart'; import 'package:island/widgets/content/sheet.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:riverpod_paging_utils/riverpod_paging_utils.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:island/widgets/post/publishers_modal.dart'; /// Bottom sheet for selecting or creating a poll. Returns SnPoll via Navigator.pop. class ComposePollSheet extends HookConsumerWidget { /// Optional publisher name to filter polls and prefill creation. final String? pubName; const ComposePollSheet({super.key, this.pubName}); @override Widget build(BuildContext context, WidgetRef ref) { final selectedPublisher = useState(pubName); final isPushing = useState(false); final errorText = useState(null); return SheetScaffold( heightFactor: 0.6, titleText: 'poll'.tr(), child: DefaultTabController( length: 2, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TabBar( tabs: [ Tab(text: 'pollsRecent'.tr()), Tab(text: 'pollCreateNew'.tr()), ], ), Expanded( child: TabBarView( children: [ // Link/Select existing poll list PagingHelperView( provider: pollListNotifierProvider(pubName), futureRefreshable: pollListNotifierProvider(pubName).future, notifierRefreshable: pollListNotifierProvider(pubName).notifier, contentBuilder: (data, widgetCount, endItemView) => ListView.builder( padding: EdgeInsets.zero, itemCount: widgetCount, itemBuilder: (context, index) { if (index == widgetCount - 1) { return endItemView; } final poll = data.items[index]; return ListTile( leading: const Icon(Symbols.how_to_vote, fill: 1), title: Text(poll.title ?? 'untitled'.tr()), subtitle: _buildPollSubtitle(poll), onTap: () { Navigator.of(context).pop(poll); }, ); }, ), ), // Create new poll and return it SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'pollCreateNewHint', ).tr().fontSize(13).opacity(0.85).padding(bottom: 8), ListTile( title: Text( selectedPublisher.value == null ? 'publisher'.tr() : '@${selectedPublisher.value}', ), subtitle: Text( selectedPublisher.value == null ? 'publisherHint'.tr() : 'selected'.tr(), ), leading: const Icon(Symbols.account_circle), trailing: const Icon(Symbols.chevron_right), onTap: () async { final picked = await showModalBottomSheet( context: context, isScrollControlled: true, builder: (context) => const PublisherModal(), ); if (picked != null) { try { final name = picked.name; if (name.isNotEmpty) { selectedPublisher.value = name; errorText.value = null; } } catch (_) { // ignore } } }, ), if (errorText.value != null) Padding( padding: const EdgeInsets.only( left: 16, right: 16, top: 4, ), child: Text( errorText.value!, style: TextStyle(color: Colors.red[700]), ), ), const Gap(16), Align( alignment: Alignment.centerRight, child: FilledButton.icon( icon: isPushing.value ? const SizedBox( width: 18, height: 18, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white, ), ) : const Icon(Symbols.add_circle), label: Text('create'.tr()), onPressed: isPushing.value ? null : () async { final pub = selectedPublisher.value ?? ''; if (pub.isEmpty) { errorText.value = 'publisherCannotBeEmpty'.tr(); return; } errorText.value = null; isPushing.value = true; // Push to creatorPollNew route and await result final result = await GoRouter.of( context, ).push( '/creators/$pub/polls/new', ); if (result == null) { isPushing.value = false; return; } if (!context.mounted) return; // Return created poll to caller of this bottom sheet Navigator.of(context).pop(result); }, ), ), ], ).padding(horizontal: 24, vertical: 24), ), ], ), ), ], ), ), ); } Widget? _buildPollSubtitle(SnPoll poll) { try { final SnPoll dyn = poll; final List options = dyn.questions; if (options.isEmpty) return null; final preview = options.take(3).map((e) => e.title).join(' ยท '); if (preview.trim().isEmpty) return null; return Text(preview); } catch (_) { return null; } } }