import 'package:flutter/material.dart'; import '../data/share_service.dart'; import '../data/share.dart'; class ShareBottomSheet extends StatefulWidget { const ShareBottomSheet({ super.key, required this.igelId, required this.shareService, required this.accessRole, // AccessRole.owner/editor/viewer required this.token, }); final int igelId; final ShareService shareService; final String token; final AccessRole accessRole; @override State createState() => _ShareBottomSheetState(); } class _ShareBottomSheetState extends State { final _emailCtrl = TextEditingController(); String _role = 'viewer'; Future>? _future; final ScrollController _scrollCtrl = ScrollController(); @override void initState() { super.initState(); _future = widget.shareService .listShares(igelId: widget.igelId, token: widget.token); } Future _reload() async { setState(() { _future = widget.shareService .listShares(igelId: widget.igelId, token: widget.token); }); } Future _invite() async { final email = _emailCtrl.text.trim(); if (email.isEmpty) return; await widget.shareService.invite( igelId: widget.igelId, email: email, role: _role, token: widget.token, ); _emailCtrl.clear(); await _reload(); } Future _updateRole(Share s, String newRole) async { await widget.shareService .updateRole(shareId: s.id, role: newRole, token: widget.token); await _reload(); } Future _revoke(Share s) async { await widget.shareService.revoke(shareId: s.id, token: widget.token); await _reload(); } @override void dispose() { _scrollCtrl.dispose(); _emailCtrl.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final canInvite = widget.accessRole == AccessRole.owner; return SafeArea( child: Padding( padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, children: [ Row(children: [ const Icon(Icons.share), const SizedBox(width: 8), Text('Igel teilen', style: Theme.of(context).textTheme.titleLarge), const Spacer(), IconButton( icon: const Icon(Icons.close), onPressed: () => Navigator.pop(context), ), ]), const SizedBox(height: 12), // Einladen (nur Owner) if (canInvite) _InviteRow( emailCtrl: _emailCtrl, role: _role, onRoleChanged: (v) => setState(() => _role = v), onInvite: _invite, ), if (canInvite) const SizedBox(height: 16), // Liste der Freigaben Expanded( child: FutureBuilder>( future: _future, builder: (context, snap) { if (snap.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snap.hasError) { return Center(child: Text('Fehler: ${snap.error}')); } final items = snap.data ?? const []; if (items.isEmpty) { return const Center(child: Text('Keine Freigaben')); } return ScrollConfiguration( behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false), child: Scrollbar( controller: _scrollCtrl, child: ListView.separated( controller: _scrollCtrl, primary: false, itemCount: items.length, separatorBuilder: (_, __) => const Divider(height: 1), itemBuilder: (ctx, i) { final s = items[i]; // Priorität: pending -> invitedEmail, accepted -> targetEmail final label = (s.invitedEmail != null && s.invitedEmail!.isNotEmpty) ? s.invitedEmail! : ((s.targetEmail != null && s.targetEmail!.isNotEmpty) ? s.targetEmail! : 'Unbekannt'); return ListTile( leading: Icon( s.status == 'accepted' ? Icons.check_circle_outline : Icons.hourglass_bottom, ), title: Text(label), subtitle: Text('Rolle: ${s.role} · Status: ${s.status}'), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ if (canInvite && s.status == 'accepted') PopupMenuButton( onSelected: (v) => _updateRole(s, v), itemBuilder: (_) => const [ PopupMenuItem( value: 'viewer', child: Text('Viewer')), PopupMenuItem( value: 'editor', child: Text('Editor')), ], child: const Icon(Icons.admin_panel_settings), ), if (canInvite) IconButton( icon: const Icon(Icons.remove_circle_outline), tooltip: 'Zugriff entfernen', onPressed: () => _revoke(s), ), ], ), ); }, ), ), ); }, ), ), ], ), ), ); } } class _InviteRow extends StatelessWidget { const _InviteRow({ required this.emailCtrl, required this.role, required this.onRoleChanged, required this.onInvite, }); final TextEditingController emailCtrl; final String role; final ValueChanged onRoleChanged; final VoidCallback onInvite; @override Widget build(BuildContext context) { return Row(children: [ Expanded( child: TextField( controller: emailCtrl, decoration: const InputDecoration(labelText: 'E-Mail einladen'), keyboardType: TextInputType.emailAddress, ), ), const SizedBox(width: 8), DropdownButton( value: role, items: const [ DropdownMenuItem(value: 'viewer', child: Text('Viewer')), DropdownMenuItem(value: 'editor', child: Text('Editor')), ], onChanged: (v) { if (v != null) onRoleChanged(v); }, ), const SizedBox(width: 8), ElevatedButton.icon( onPressed: onInvite, icon: const Icon(Icons.send), label: const Text('Einladen'), ), ]); } }