import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../api/endpoints/health.dart'; import '../theme/theme_extension.dart'; import 'auth_provider.dart'; class ServerUrlScreen extends ConsumerStatefulWidget { const ServerUrlScreen({super.key}); @override ConsumerState createState() => _ServerUrlScreenState(); } class _ServerUrlScreenState extends ConsumerState { final _ctrl = TextEditingController(); bool _busy = false; String? _error; Future _connect() async { final url = _ctrl.text.trim(); if (url.isEmpty) { setState(() => _error = 'Enter a server URL.'); return; } setState(() { _busy = true; _error = null; }); try { final dio = Dio(BaseOptions(baseUrl: url, connectTimeout: const Duration(seconds: 5))); final body = await HealthApi(dio).check(); if (body['status'] != 'ok') { throw StateError('unhealthy'); } await ref.read(authControllerProvider.notifier).setServerUrl(url); if (!mounted) return; context.go('/login'); } on DioException catch (_) { setState(() => _error = "Couldn't reach that server."); } catch (_) { setState(() => _error = "Couldn't reach that server."); } finally { if (mounted) setState(() => _busy = false); } } @override Widget build(BuildContext context) { final fs = Theme.of(context).extension()!; return Scaffold( body: SafeArea( child: Padding( padding: const EdgeInsets.all(24), child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const SizedBox(height: 48), Text('Connect to your Minstrel', style: TextStyle(fontFamily: fs.display.fontFamily, fontSize: 28)), const SizedBox(height: 24), TextField( controller: _ctrl, keyboardType: TextInputType.url, decoration: const InputDecoration(labelText: 'Server URL', hintText: 'https://music.example.com'), ), if (_error != null) Padding( padding: const EdgeInsets.only(top: 8), child: Text(_error!, style: TextStyle(color: fs.error)), ), const SizedBox(height: 16), FilledButton( onPressed: _busy ? null : _connect, child: _busy ? const SizedBox(width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 2)) : const Text('Connect'), ), ]), ), ), ); } }