import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hl_lieferservice/bloc/app_bloc.dart'; import 'package:hl_lieferservice/bloc/app_events.dart'; import 'package:hl_lieferservice/bloc/app_states.dart'; import 'package:hl_lieferservice/data/network/backend_environment.dart'; /// Einstellungen vor dem Login: Auswahl der Server-Umgebung. /// /// Erreichbar über das Zahnrad im Login-Screen. Die Umgebungen stammen /// aus `assets/hl_server_config.json`; die Wahl persistiert der /// [AppBloc]. Nach dem Antippen einer anderen Umgebung schließt sich die /// Seite und die App baut sich gegen den neuen Server neu auf. class EnvironmentSettingsPage extends StatelessWidget { const EnvironmentSettingsPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Einstellungen')), body: BlocBuilder( builder: (context, state) { if (state is! AppConfigLoaded) { return const Center(child: CircularProgressIndicator()); } final catalog = state.catalog; return ListView( padding: const EdgeInsets.all(16), children: [ Text('Umgebung', style: Theme.of(context).textTheme.titleMedium), const SizedBox(height: 4), Text( 'Mit welchem Server sich die App verbindet.', style: Theme.of(context).textTheme.bodySmall, ), const SizedBox(height: 12), for (final env in catalog.environments) _EnvironmentCard( environment: env, selected: env.id == state.active.id, isDefault: env.id == catalog.defaultEnvironmentId, onTap: () => _select(context, state.active, env), ), ], ); }, ), ); } void _select( BuildContext context, BackendEnvironment active, BackendEnvironment picked, ) { final appBloc = context.read(); Navigator.of(context).pop(); if (picked.id != active.id) { appBloc.add(AppSwitchEnvironment(environmentId: picked.id)); } } } class _EnvironmentCard extends StatelessWidget { const _EnvironmentCard({ required this.environment, required this.selected, required this.isDefault, required this.onTap, }); final BackendEnvironment environment; final bool selected; final bool isDefault; final VoidCallback onTap; @override Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; return Card( margin: const EdgeInsets.only(bottom: 12), clipBehavior: Clip.antiAlias, elevation: selected ? 2 : 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), side: BorderSide( color: selected ? scheme.primary : scheme.outlineVariant, width: selected ? 2 : 1, ), ), child: InkWell( onTap: onTap, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), child: Row( children: [ Icon( Icons.dns_outlined, color: selected ? scheme.primary : scheme.onSurfaceVariant, ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Flexible( child: Text( environment.name, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), ), if (isDefault) ...[ const SizedBox(width: 8), Text( 'Standard', style: TextStyle( fontSize: 12, color: scheme.onSurfaceVariant, ), ), ], ], ), const SizedBox(height: 2), Text( environment.hostAndPort, style: TextStyle( fontFamily: 'monospace', color: scheme.onSurfaceVariant, ), ), ], ), ), if (selected) Icon(Icons.check_circle, color: scheme.primary), ], ), ), ), ); } }