import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/connections/connection.dart'; import '../../../core/connections/connection_providers.dart'; /// Add/edit dialog for a saved [Connection]. Passing [existing] switches it /// to edit mode; omitting it creates a new connection and makes it active /// (the common "just point me at a node" first-run flow). Future showConnectionFormDialog( BuildContext context, { Connection? existing, }) { return showDialog( context: context, builder: (context) => _ConnectionFormDialog(existing: existing), ); } class _ConnectionFormDialog extends ConsumerStatefulWidget { const _ConnectionFormDialog({this.existing}); final Connection? existing; @override ConsumerState<_ConnectionFormDialog> createState() => _ConnectionFormDialogState(); } class _ConnectionFormDialogState extends ConsumerState<_ConnectionFormDialog> { final _formKey = GlobalKey(); late final _nameController = TextEditingController(text: widget.existing?.name); late final _urlController = TextEditingController(text: widget.existing?.baseUrl); bool _saving = false; @override void dispose() { _nameController.dispose(); _urlController.dispose(); super.dispose(); } String? _validateUrl(String? value) { final trimmed = value?.trim() ?? ''; if (trimmed.isEmpty) return 'Required.'; final uri = Uri.tryParse(trimmed); if (uri == null || !uri.hasScheme || !uri.hasAuthority) { return 'Enter a full URL, e.g. https://edge-01.local:8080'; } return null; } Future _save() async { if (!(_formKey.currentState?.validate() ?? false)) return; setState(() => _saving = true); final name = _nameController.text.trim(); var url = _urlController.text.trim(); if (url.endsWith('/')) url = url.substring(0, url.length - 1); final existing = widget.existing; if (existing != null) { await ref .read(savedConnectionsProvider.notifier) .update(existing.copyWith(name: name, baseUrl: url)); } else { final connection = Connection( id: 'conn_${DateTime.now().microsecondsSinceEpoch}', name: name, baseUrl: url, ); await ref.read(savedConnectionsProvider.notifier).add(connection); await ref.read(activeConnectionIdProvider.notifier).setActive(connection.id); } if (mounted) Navigator.of(context).pop(); } @override Widget build(BuildContext context) { return AlertDialog( title: Text(widget.existing == null ? 'Add connection' : 'Edit connection'), content: Form( key: _formKey, child: SizedBox( width: 380, child: Column( mainAxisSize: MainAxisSize.min, children: [ TextFormField( controller: _nameController, decoration: const InputDecoration(labelText: 'Name'), validator: (v) => (v == null || v.trim().isEmpty) ? 'Required.' : null, textInputAction: TextInputAction.next, ), const SizedBox(height: 14), TextFormField( controller: _urlController, decoration: const InputDecoration( labelText: 'Base URL', hintText: 'https://edge-01.local:8080', ), validator: _validateUrl, keyboardType: TextInputType.url, onFieldSubmitted: (_) => _save(), ), ], ), ), ), actions: [ TextButton( onPressed: _saving ? null : () => Navigator.of(context).pop(), child: const Text('Cancel'), ), FilledButton( onPressed: _saving ? null : _save, child: _saving ? const SizedBox( width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text('Save'), ), ], ); } }