import 'package:flutter/material.dart'; import '../../../../common/theme/theme.dart'; import '../../../../sample/community_sample_data.dart'; import '../../../../sample/sample_data.dart'; import '../../../components/button/button.dart'; import '../../../components/toast/flushbar.dart'; import '../community_ui.dart'; /// Bottom sheet untuk menulis postingan baru. Mengembalikan [CommunityPost] /// bila dikirim, `null` bila dibatalkan. class CommunityComposeSheet extends StatefulWidget { const CommunityComposeSheet({super.key, required this.groups}); /// Komunitas tujuan; hanya yang sudah diikuti. final List groups; static Future show( BuildContext context, { required List groups, }) { return showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (_) => CommunityComposeSheet(groups: groups), ); } @override State createState() => _CommunityComposeSheetState(); } class _CommunityComposeSheetState extends State { final _controller = TextEditingController(); late CommunityGroup _group = widget.groups.first; String? _merchantName; @override void initState() { super.initState(); _controller.addListener(() => setState(() {})); } @override void dispose() { _controller.dispose(); super.dispose(); } void _submit() { Navigator.of(context).pop( CommunityPost( id: 'local-${DateTime.now().millisecondsSinceEpoch}', author: currentMember, group: _group, content: _controller.text.trim(), merchantName: _merchantName, createdAt: DateTime.now(), ), ); } @override Widget build(BuildContext context) { final canSubmit = _controller.text.trim().isNotEmpty; return Padding( padding: EdgeInsets.only(bottom: MediaQuery.viewInsetsOf(context).bottom), child: Container( decoration: const BoxDecoration( color: AppColor.white, borderRadius: BorderRadius.vertical(top: Radius.circular(28)), ), child: SafeArea( top: false, child: SingleChildScrollView( padding: const EdgeInsets.fromLTRB(20, 12, 20, 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Center( child: Container( width: 40, height: 4, decoration: BoxDecoration( color: CommunityColor.divider, borderRadius: BorderRadius.circular(999), ), ), ), const SizedBox(height: 16), Row( children: [ Expanded( child: Text( 'Tulis Postingan', style: AppStyle.xl.copyWith( fontWeight: FontWeight.w700, ), ), ), IconButton( onPressed: () => Navigator.of(context).pop(), style: IconButton.styleFrom( backgroundColor: CommunityColor.background, ), icon: const Icon( Icons.close_rounded, size: 20, color: CommunityColor.muted, ), ), ], ), const SizedBox(height: 12), _Label('Posting ke'), SizedBox( height: 38, child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: widget.groups.length, separatorBuilder: (_, _) => const SizedBox(width: 8), itemBuilder: (context, index) { final group = widget.groups[index]; return _Chip( label: '${group.emoji} ${group.name}', selected: group.id == _group.id, onTap: () => setState(() => _group = group), ); }, ), ), const SizedBox(height: 16), TextField( controller: _controller, autofocus: true, minLines: 5, maxLines: 8, maxLength: 500, textCapitalization: TextCapitalization.sentences, style: AppStyle.md.copyWith( height: 1.5, fontWeight: FontWeight.w500, ), decoration: InputDecoration( hintText: 'Ceritakan pengalaman kulinermu hari ini...', filled: true, fillColor: CommunityColor.background, contentPadding: const EdgeInsets.all(16), border: OutlineInputBorder( borderRadius: BorderRadius.circular(18), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(18), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(18), borderSide: const BorderSide( color: CommunityColor.blushDeep, width: 1.5, ), ), ), ), const SizedBox(height: 8), _Label('Tandai merchant'), Wrap( spacing: 8, runSpacing: 8, children: merchants.map((merchant) { final selected = merchant.name == _merchantName; return _Chip( label: merchant.name, icon: Icons.storefront_rounded, selected: selected, onTap: () => setState( () => _merchantName = selected ? null : merchant.name, ), ); }).toList(), ), const SizedBox(height: 20), Row( children: [ _AttachButton( icon: Icons.photo_library_outlined, onTap: () => AppFlushbar.showSuccess( context, 'Unggah foto segera hadir', ), ), const SizedBox(width: 8), _AttachButton( icon: Icons.emoji_emotions_outlined, onTap: () { _controller.text = '${_controller.text}😋'; }, ), const SizedBox(width: 12), Expanded( child: AppElevatedButton( title: 'Posting', height: 48, onPressed: canSubmit ? _submit : null, ), ), ], ), ], ), ), ), ), ); } } class _Label extends StatelessWidget { const _Label(this.text); final String text; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.only(bottom: 8), child: Text( text, style: AppStyle.sm.copyWith( color: CommunityColor.muted, fontWeight: FontWeight.w600, ), ), ); } } class _Chip extends StatelessWidget { const _Chip({ required this.label, required this.selected, required this.onTap, this.icon, }); final String label; final bool selected; final VoidCallback onTap; final IconData? icon; @override Widget build(BuildContext context) { final color = selected ? AppColor.primary : AppColor.textPrimary; return GestureDetector( onTap: onTap, child: AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), decoration: BoxDecoration( color: selected ? CommunityColor.blush : CommunityColor.background, borderRadius: BorderRadius.circular(999), border: Border.all( color: selected ? CommunityColor.blushDeep : Colors.transparent, ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ if (icon != null) ...[ Icon(icon, size: 14, color: color), const SizedBox(width: 6), ], Text( label, style: AppStyle.sm.copyWith( color: color, fontWeight: FontWeight.w600, ), ), ], ), ), ); } } class _AttachButton extends StatelessWidget { const _AttachButton({required this.icon, required this.onTap}); final IconData icon; final VoidCallback onTap; @override Widget build(BuildContext context) { return Material( color: CommunityColor.background, borderRadius: BorderRadius.circular(14), child: InkWell( borderRadius: BorderRadius.circular(14), onTap: onTap, child: SizedBox( width: 48, height: 48, child: Icon(icon, color: CommunityColor.muted), ), ), ); } }