import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; import '../services/authentication_manager.dart'; import '../services/brandmeister_client.dart'; class AuthView extends StatefulWidget { const AuthView({super.key}); @override State createState() => _AuthViewState(); } class _AuthViewState extends State { final TextEditingController _tokenController = TextEditingController(); final FocusNode _focusNode = FocusNode(); bool _isLoading = false; String? _errorMessage; @override void initState() { super.initState(); _tokenController.addListener(() { setState(() { // Update button state when text changes }); }); WidgetsBinding.instance.addPostFrameCallback((_) { _focusNode.requestFocus(); }); } @override void dispose() { _tokenController.dispose(); _focusNode.dispose(); super.dispose(); } Future _verifyToken() async { setState(() { _isLoading = true; _errorMessage = null; }); try { final authManager = context.read(); await authManager.verifyAndSaveToken(_tokenController.text); } on BrandmeisterError catch (e) { setState(() { _errorMessage = e.message; _isLoading = false; }); } catch (e) { setState(() { _errorMessage = 'Authentication failed: ${e.toString()}'; _isLoading = false; }); } } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(24.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Center( child: Container( width: 100, height: 100, decoration: BoxDecoration( shape: BoxShape.circle, image: const DecorationImage( image: AssetImage('assets/icon/app_icon.png'), fit: BoxFit.cover, ), ), ), ), const SizedBox(height: 24), Text( 'BrandManager', style: Theme.of(context).textTheme.headlineLarge?.copyWith( fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, ), const SizedBox(height: 4), Text( 'Brandmeister Manager for Mobiles', style: Theme.of(context).textTheme.titleMedium?.copyWith( color: Theme.of(context).colorScheme.primary, fontWeight: FontWeight.w500, ), textAlign: TextAlign.center, ), const SizedBox(height: 24), Text( 'Please enter your BrandMeister API token', style: Theme.of(context).textTheme.bodyLarge?.copyWith( color: Colors.grey[600], ), textAlign: TextAlign.center, ), const SizedBox(height: 16), Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surfaceContainerHighest, borderRadius: BorderRadius.circular(12), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon( Icons.lock_outline, size: 20, color: Theme.of(context).colorScheme.onSurfaceVariant, ), const SizedBox(width: 12), Expanded( child: Text( 'Your API token is stored securely in encrypted storage on your device. It is never shared with anyone and is only used to authenticate with the BrandMeister network.', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), ), ], ), ), const SizedBox(height: 24), TextField( controller: _tokenController, focusNode: _focusNode, obscureText: true, enabled: !_isLoading, decoration: InputDecoration( labelText: 'API Token', hintText: 'Enter your BrandMeister API token', border: const OutlineInputBorder(), prefixIcon: const Icon(Icons.key), errorText: _errorMessage, ), onSubmitted: (_) { if (_tokenController.text.isNotEmpty && !_isLoading) { _verifyToken(); } }, ), const SizedBox(height: 16), ElevatedButton( onPressed: _tokenController.text.isEmpty || _isLoading ? null : _verifyToken, style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16), backgroundColor: Theme.of(context).colorScheme.primary, foregroundColor: Theme.of(context).colorScheme.onPrimary, ), child: _isLoading ? SizedBox( height: 20, width: 20, child: CircularProgressIndicator( strokeWidth: 2, color: Theme.of(context).colorScheme.onPrimary, ), ) : const Text('Sign In'), ), const SizedBox(height: 24), TextButton.icon( onPressed: () { final url = Uri.parse('https://brandmeister.network/?page=profile-api'); launchUrl(url, mode: LaunchMode.externalApplication); }, icon: const Icon(Icons.open_in_new), label: const Text('Get API Token from BrandMeister'), ), ], ), ), ), ), ); } }