import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:onsolgo/core/constants.dart'; /// Bottom sheet: list comments under [parent] (`parent.collection('comments')`). class CommentsSheet extends StatefulWidget { final DocumentReference parent; final String title; const CommentsSheet({ super.key, required this.parent, this.title = 'Comments', }); static Future show(BuildContext context, {required DocumentReference parent, String title = 'Comments'}) { return showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.grey[900], shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(16))), builder: (ctx) => CommentsSheet(parent: parent, title: title), ); } @override State createState() => _CommentsSheetState(); } class _CommentsSheetState extends State { final _textC = TextEditingController(); bool _sending = false; @override void dispose() { _textC.dispose(); super.dispose(); } Future _send() async { final uid = FirebaseAuth.instance.currentUser?.uid; if (uid == null) { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Sign in to comment'))); return; } final text = _textC.text.trim(); if (text.isEmpty) return; setState(() => _sending = true); try { final uSnap = await FirebaseFirestore.instance.collection('users').doc(uid).get(); final name = (uSnap.data()?['username'] as String?)?.trim() ?? 'Citizen'; await widget.parent.collection('comments').add({ 'uid': uid, 'authorName': name, 'text': text, 'timestamp': FieldValue.serverTimestamp(), }); _textC.clear(); if (mounted) FocusScope.of(context).unfocus(); } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Could not post: $e'))); } } finally { if (mounted) setState(() => _sending = false); } } @override Widget build(BuildContext context) { final uid = FirebaseAuth.instance.currentUser?.uid ?? ''; final padBottom = MediaQuery.of(context).viewInsets.bottom; return Padding( padding: EdgeInsets.only(bottom: padBottom), child: SizedBox( height: MediaQuery.of(context).size.height * 0.55, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Padding( padding: const EdgeInsets.fromLTRB(16, 12, 8, 8), child: Row( children: [ Text(widget.title, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16)), const Spacer(), IconButton(icon: const Icon(Icons.close, color: Colors.white54), onPressed: () => Navigator.pop(context)), ], ), ), Expanded( child: StreamBuilder( stream: widget.parent.collection('comments').orderBy('timestamp', descending: false).snapshots(), builder: (context, snap) { if (snap.hasError) { return Center(child: Text('Error: ${snap.error}', style: const TextStyle(color: Colors.redAccent))); } if (!snap.hasData) return const Center(child: CircularProgressIndicator(color: kOnsolGold)); final docs = snap.data!.docs; if (docs.isEmpty) { return Center(child: Text('No comments yet.', style: TextStyle(color: Colors.grey[500]))); } return ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 12), itemCount: docs.length, itemBuilder: (context, i) { final c = docs[i].data() as Map; final author = c['authorName'] ?? 'Citizen'; final text = c['text'] ?? ''; final own = c['uid'] == uid; return Card( color: Colors.black54, margin: const EdgeInsets.only(bottom: 8), child: ListTile( dense: true, title: Text(author, style: const TextStyle(color: kOnsolGold, fontSize: 12, fontWeight: FontWeight.bold)), subtitle: Text(text, style: const TextStyle(color: Colors.white70, fontSize: 14)), trailing: own ? IconButton( icon: const Icon(Icons.delete_outline, color: Colors.redAccent, size: 20), onPressed: () async { try { await docs[i].reference.delete(); } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('$e'))); } } }, ) : null, ), ); }, ); }, ), ), Padding( padding: const EdgeInsets.fromLTRB(12, 8, 12, 12), child: Row( children: [ Expanded( child: TextField( controller: _textC, style: const TextStyle(color: Colors.white), minLines: 1, maxLines: 3, decoration: InputDecoration( hintText: 'Add a comment…', hintStyle: TextStyle(color: Colors.grey[600]), filled: true, fillColor: Colors.black38, border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)), ), onSubmitted: (_) => _send(), ), ), const SizedBox(width: 8), _sending ? const Padding(padding: EdgeInsets.all(12), child: SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2))) : IconButton.filled( style: IconButton.styleFrom(backgroundColor: kOnsolGold, foregroundColor: Colors.black), onPressed: _send, icon: const Icon(Icons.send), ), ], ), ), ], ), ), ); } }