import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../app/theme.dart'; import '../../providers/session_provider.dart'; import '../../shared/models/match.dart'; import '../../shared/api_client.dart'; import '../../shared/widgets/screen_insets.dart'; import 'step_match.dart'; import 'step_network_test.dart'; import 'step_roles.dart'; import 'step_transmission.dart'; class WizardShell extends ConsumerStatefulWidget { const WizardShell({ super.key, required this.matchId, required this.step, }); final String matchId; final int step; @override ConsumerState createState() => _WizardShellState(); } class _WizardShellState extends ConsumerState { MatchModel? _match; bool _loading = true; static const _stepTitles = [ '01 · Partita', '02 · Trasmissione', '03 · Ruoli', '04 · Test', ]; @override void initState() { super.initState(); _loadMatch(); } @override void didUpdateWidget(WizardShell oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.matchId != widget.matchId) { _loadMatch(); } } Future _loadMatch() async { setState(() => _loading = true); try { final client = ref.read(apiClientProvider); final match = await client.fetchMatch(widget.matchId); ref.read(sessionProvider.notifier).setMatch(match); if (mounted) { setState(() { _match = match; _loading = false; }); } } catch (_) { if (mounted) setState(() => _loading = false); } } void _goToStep(int step) { context.go('/setup/${widget.matchId}/$step'); } @override Widget build(BuildContext context) { final theme = Theme.of(context); final stepIndex = widget.step.clamp(1, 4) - 1; return Scaffold( appBar: AppBar( title: Text(_stepTitles[stepIndex]), leading: IconButton( icon: const Icon(Icons.close), onPressed: () => context.go('/matches'), ), ), body: _loading ? const Center( child: CircularProgressIndicator(color: AppTheme.primaryRed), ) : Column( children: [ _StepIndicator(current: widget.step), Expanded( child: AppSafeArea( top: false, child: _buildStep(stepIndex), ), ), ], ), ); } Widget _buildStep(int index) { final match = _match; if (match == null) { return Center( child: Text( 'Partita non trovata', style: Theme.of(context).textTheme.bodyMedium, ), ); } switch (index) { case 0: return StepMatch( match: match, onNext: () => _goToStep(2), ); case 1: return StepTransmission( match: match, onBack: () => _goToStep(1), onNext: () => _goToStep(3), ); case 2: return StepRoles( match: match, onBack: () => _goToStep(2), onNext: () => _goToStep(4), ); case 3: return StepNetworkTest( match: match, onBack: () => _goToStep(3), ); default: return const SizedBox.shrink(); } } } class _StepIndicator extends StatelessWidget { const _StepIndicator({required this.current}); final int current; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), child: Row( children: List.generate(4, (i) { final step = i + 1; final active = step <= current; return Expanded( child: Container( height: 4, margin: EdgeInsets.only(right: i < 3 ? 6 : 0), decoration: BoxDecoration( color: active ? AppTheme.primaryRed : AppTheme.surfaceElevated, borderRadius: BorderRadius.circular(2), ), ), ); }), ), ); } }