import 'dart:async'; import 'package:flutter/material.dart'; import 'package:listenmeister/main.dart'; import 'package:listenmeister/models/models.dart'; import 'package:listenmeister/pages/layout_detail.dart'; class LayoutsPage extends StatefulWidget { const LayoutsPage({super.key}); @override State createState() => _LayoutsPageState(); } class _LayoutsPageState extends State { late Future> _layoutsFuture; StreamSubscription? _layoutsSubscription; @override void initState() { super.initState(); _loadLayouts(); _layoutsSubscription = apiService.watchStoreLayouts().listen((_) { _loadLayouts(); }); } @override void dispose() { _layoutsSubscription?.cancel(); super.dispose(); } void _loadLayouts() { _layoutsFuture = apiService.getStoreLayouts(); setState(() {}); } Future _createLayout() async { final TextEditingController nameCtl = TextEditingController(); final TextEditingController addressCtl = TextEditingController(); final TextEditingController latCtl = TextEditingController(); final TextEditingController lonCtl = TextEditingController(); bool isPublic = false; final bool? ok = await showDialog( context: context, builder: (context) { return StatefulBuilder( builder: (context, setDialogState) { return AlertDialog( title: const Text('Neues Ladenlayout'), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ TextField( controller: nameCtl, decoration: const InputDecoration(labelText: 'Name'), autofocus: true, ), TextField( controller: addressCtl, decoration: const InputDecoration( labelText: 'Adresse (optional)', ), ), TextField( controller: latCtl, decoration: const InputDecoration( labelText: 'Breitengrad (optional)', ), keyboardType: const TextInputType.numberWithOptions( decimal: true, signed: true, ), ), TextField( controller: lonCtl, decoration: const InputDecoration( labelText: 'Längengrad (optional)', ), keyboardType: const TextInputType.numberWithOptions( decimal: true, signed: true, ), ), SwitchListTile.adaptive( value: isPublic, onChanged: (value) { setDialogState(() => isPublic = value); }, title: const Text('Für andere sichtbar'), contentPadding: EdgeInsets.zero, ), ], ), ), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: const Text('Abbrechen'), ), TextButton( onPressed: () => Navigator.pop(context, true), child: const Text('Erstellen'), ), ], ); }, ); }, ); if (ok != true) return; final String name = nameCtl.text.trim(); if (name.isEmpty) return; double? latitude; double? longitude; final String latText = latCtl.text.trim(); final String lonText = lonCtl.text.trim(); if (latText.isNotEmpty) { latitude = double.tryParse(latText.replaceAll(',', '.')); if (latitude == null) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Ungültiger Breitengrad.')), ); } return; } } if (lonText.isNotEmpty) { longitude = double.tryParse(lonText.replaceAll(',', '.')); if (longitude == null) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Ungültiger Längengrad.')), ); } return; } } try { await apiService.createStoreLayout( name: name, latitude: latitude, longitude: longitude, address: addressCtl.text.trim().isEmpty ? null : addressCtl.text.trim(), isPublic: isPublic, ); _loadLayouts(); } catch (e) { if (mounted) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text('Fehler: $e'))); } } } Future _openLayout(StoreLayout layout) async { await Navigator.of(context).push( MaterialPageRoute(builder: (_) => LayoutDetailPage(layout: layout)), ); if (mounted) { _loadLayouts(); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Ladenlayouts')), body: FutureBuilder>( future: _layoutsFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snapshot.hasError) { return Center(child: Text('Fehler: ${snapshot.error}')); } final layouts = snapshot.data ?? []; if (layouts.isEmpty) { return const Center(child: Text('Noch keine Layouts vorhanden.')); } return ListView.builder( itemCount: layouts.length, itemBuilder: (context, index) { final layout = layouts[index]; return ListTile( title: Text(layout.name), subtitle: layout.address != null && layout.address!.isNotEmpty ? Text(layout.address!) : null, leading: Icon( layout.owner == apiService.userId ? Icons.store_mall_directory : Icons.share, ), trailing: layout.isPublic ? const Icon(Icons.public, size: 20) : null, onTap: () => _openLayout(layout), ); }, ); }, ), floatingActionButton: FloatingActionButton( onPressed: _createLayout, child: const Icon(Icons.add), ), ); } }