import 'dart:async'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:pshared/provider/account.dart'; import 'package:pweb/utils/snackbar.dart'; import 'package:pweb/widgets/error/snackbar.dart'; import 'package:pweb/widgets/vspacer.dart'; import 'package:pweb/generated/i18n/app_localizations.dart'; class SignupConfirmationCard extends StatefulWidget { final String? email; const SignupConfirmationCard({super.key, this.email}); @override State createState() => _SignupConfirmationCardState(); } class _SignupConfirmationCardState extends State { static const int _defaultCooldownSeconds = 60; Timer? _cooldownTimer; int _cooldownRemainingSeconds = 0; bool _isResending = false; @override void initState() { super.initState(); _startCooldown(_defaultCooldownSeconds); } @override void dispose() { _cooldownTimer?.cancel(); super.dispose(); } bool get _isCooldownActive => _cooldownRemainingSeconds > 0; void _startCooldown(int seconds) { _cooldownTimer?.cancel(); if (seconds <= 0) { setState(() => _cooldownRemainingSeconds = 0); return; } setState(() => _cooldownRemainingSeconds = seconds); _cooldownTimer = Timer.periodic(const Duration(seconds: 1), (timer) { if (!mounted) { timer.cancel(); return; } if (_cooldownRemainingSeconds <= 1) { timer.cancel(); setState(() => _cooldownRemainingSeconds = 0); return; } setState(() => _cooldownRemainingSeconds -= 1); }); } Future _resendVerificationEmail() async { final email = widget.email?.trim(); final locs = AppLocalizations.of(context)!; if (email == null || email.isEmpty) { notifyUser(context, locs.errorEmailMissing); return; } if (_isResending || _isCooldownActive) return; setState(() => _isResending = true); try { await context.read().resendVerificationEmail(email); if (!mounted) return; notifyUser(context, locs.signupConfirmationResent(email)); _startCooldown(_defaultCooldownSeconds); } catch (e) { if (!mounted) return; postNotifyUserOfErrorX( context: context, errorSituation: locs.signupConfirmationResendError, exception: e, ); } finally { if (mounted) { setState(() => _isResending = false); } } } String _formatCooldown(int seconds) { final minutes = seconds ~/ 60; final remainingSeconds = seconds % 60; if (minutes > 0) { return '$minutes:${remainingSeconds.toString().padLeft(2, '0')}'; } return remainingSeconds.toString(); } @override Widget build(BuildContext context) { final theme = Theme.of(context); final locs = AppLocalizations.of(context)!; final email = widget.email?.trim(); final description = (email != null && email.isNotEmpty) ? locs.signupConfirmationDescription(email) : locs.signupConfirmationDescriptionNoEmail; final canResend = !_isResending && !_isCooldownActive && email != null && email.isNotEmpty; final resendLabel = _isCooldownActive ? locs.signupConfirmationResendCooldown(_formatCooldown(_cooldownRemainingSeconds)) : locs.signupConfirmationResend; return Card( child: Padding( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( locs.signupConfirmationTitle, style: theme.textTheme.headlineSmall, ), const VSpacer(), Text(description, style: theme.textTheme.bodyMedium), if (email != null && email.isNotEmpty) ...[ const VSpacer(), SelectableText( email, style: theme.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w600, ), ), ], const VSpacer(multiplier: 1.5), Row( children: [ ElevatedButton.icon( onPressed: canResend ? _resendVerificationEmail : null, icon: _isResending ? SizedBox( width: 16, height: 16, child: CircularProgressIndicator( strokeWidth: 2, color: theme.colorScheme.onPrimary, ), ) : const Icon(Icons.mark_email_read_outlined), label: Text(resendLabel), ), ], ), ], ), ), ); } }