import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; import 'package:provider/provider.dart'; import 'package:pshared/models/resources.dart'; import 'package:pshared/provider/account.dart'; import 'package:pshared/provider/invitations.dart'; import 'package:pshared/provider/permissions.dart'; import 'package:pweb/pages/invitations/widgets/header.dart'; import 'package:pweb/pages/invitations/widgets/form/form.dart'; import 'package:pweb/pages/invitations/widgets/list/list.dart'; import 'package:pweb/pages/loader.dart'; import 'package:pweb/widgets/error/snackbar.dart'; import 'package:pweb/generated/i18n/app_localizations.dart'; class InvitationsPage extends StatefulWidget { const InvitationsPage({super.key}); @override State createState() => _InvitationsPageState(); } class _InvitationsPageState extends State { final GlobalKey _formKey = GlobalKey(); final TextEditingController _emailController = TextEditingController(); final TextEditingController _nameController = TextEditingController(); final TextEditingController _messageController = TextEditingController(); String? _selectedRoleRef; int _expiryDays = 7; @override void didChangeDependencies() { super.didChangeDependencies(); _bootstrapRoleSelection(); } void _bootstrapRoleSelection() { final roles = context.read().roleDescriptions; if (_selectedRoleRef == null && roles.isNotEmpty) { _selectedRoleRef = roles.first.storable.id; } } @override void dispose() { _emailController.dispose(); _nameController.dispose(); _messageController.dispose(); super.dispose(); } Future _sendInvitation() async { final form = _formKey.currentState; if (form == null || !form.validate()) return; final account = context.read().account; if (account == null) return; final permissions = context.read(); final roleRef = _selectedRoleRef ?? permissions.roleDescriptions.firstOrNull?.storable.id; if (roleRef == null) return; final invitations = context.read(); final loc = AppLocalizations.of(context)!; await executeActionWithNotification( context: context, action: () => invitations.sendInvitation( email: _emailController.text.trim(), name: _nameController.text.trim(), comment: _messageController.text.trim(), roleRef: roleRef, inviterRef: account.id, expiresAt: DateTime.now().toUtc().add(Duration(days: _expiryDays)), ), successMessage: loc.invitationCreatedSuccess, errorMessage: loc.errorCreatingInvitation, ); _emailController.clear(); _nameController.clear(); _messageController.clear(); } @override Widget build(BuildContext context) { final loc = AppLocalizations.of(context)!; final permissions = context.watch(); if (!permissions.canRead(ResourceType.invitations)) { return PageViewLoader( child: Center(child: Text(loc.errorAccessDenied)), ); } return PageViewLoader( child: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ InvitationsHeader(loc: loc), const SizedBox(height: 16), InvitationsForm( formKey: _formKey, emailController: _emailController, nameController: _nameController, messageController: _messageController, expiryDays: _expiryDays, onExpiryChanged: (value) => setState(() => _expiryDays = value), selectedRoleRef: _selectedRoleRef, onRoleChanged: (role) => setState(() => _selectedRoleRef = role), canCreate: permissions.canCreate(ResourceType.invitations), onSubmit: _sendInvitation, ), const SizedBox(height: 24), const InvitationsList(), ], ), ), ), ); } }