Separate Providers
This commit is contained in:
@@ -3,7 +3,8 @@ import 'package:frontend_splatournament_manager/pages/home_page.dart';
|
||||
import 'package:frontend_splatournament_manager/pages/login_page.dart';
|
||||
import 'package:frontend_splatournament_manager/pages/settings_page.dart';
|
||||
import 'package:frontend_splatournament_manager/providers/auth_provider.dart';
|
||||
import 'package:frontend_splatournament_manager/state_provider.dart';
|
||||
import 'package:frontend_splatournament_manager/providers/theme_provider.dart';
|
||||
import 'package:frontend_splatournament_manager/providers/tournament_provider.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
@@ -11,7 +12,8 @@ void main() {
|
||||
runApp(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (_) => StateProvider()),
|
||||
ChangeNotifierProvider(create: (_) => ThemeProvider()),
|
||||
ChangeNotifierProvider(create: (_) => TournamentProvider()),
|
||||
ChangeNotifierProvider(create: (_) => AuthProvider()),
|
||||
],
|
||||
child: const SplatournamentApp(),
|
||||
@@ -23,11 +25,11 @@ class SplatournamentApp extends StatelessWidget {
|
||||
const SplatournamentApp({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final stateProvider = Provider.of<StateProvider>(context);
|
||||
final themeProvider = Provider.of<ThemeProvider>(context);
|
||||
return MaterialApp.router(
|
||||
title: 'Splatournament Manager',
|
||||
routerConfig: routes,
|
||||
themeMode: stateProvider.theme,
|
||||
themeMode: themeProvider.theme,
|
||||
theme: ThemeData(
|
||||
brightness: Brightness.light,
|
||||
primarySwatch: Colors.blue,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frontend_splatournament_manager/state_provider.dart';
|
||||
import 'package:frontend_splatournament_manager/providers/tournament_provider.dart';
|
||||
import 'package:frontend_splatournament_manager/widgets/available_tournament_list.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@@ -13,16 +13,20 @@ class HomePage extends StatelessWidget {
|
||||
appBar: AppBar(
|
||||
title: Text("Splatournament"),
|
||||
actions: [
|
||||
Consumer<StateProvider>(
|
||||
builder:
|
||||
(BuildContext context, StateProvider value, Widget? child) {
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
value.notifyState();
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
final tournamentProvider =
|
||||
Provider.of<TournamentProvider>(context, listen: false);
|
||||
try {
|
||||
await tournamentProvider.refreshAvailableTournaments();
|
||||
} catch (_) {
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Failed to refresh tournaments')),
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: Icon(Icons.refresh),
|
||||
);
|
||||
},
|
||||
),
|
||||
PopupMenuButton(
|
||||
onSelected: (value) {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ThemeProvider extends ChangeNotifier {
|
||||
ThemeMode _themeMode = ThemeMode.system;
|
||||
|
||||
ThemeMode get theme => _themeMode;
|
||||
|
||||
void setTheme(ThemeMode mode) {
|
||||
_themeMode = mode;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frontend_splatournament_manager/models/tournament.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class TournamentProvider extends ChangeNotifier {
|
||||
static const String baseUrl = "http://10.0.2.2:3000";
|
||||
|
||||
List<Tournament> _availableTournaments = [];
|
||||
Future<List<Tournament>>? _initialLoadFuture;
|
||||
|
||||
List<Tournament> get availableTournaments => _availableTournaments;
|
||||
|
||||
Future<List<Tournament>> _fetchTournaments() async {
|
||||
final response = await http.get(Uri.parse('$baseUrl/tournaments'));
|
||||
if (response.statusCode != HttpStatus.ok) {
|
||||
throw Exception('Failed to load tournaments (${response.statusCode})');
|
||||
}
|
||||
|
||||
final List<dynamic> list = json.decode(response.body);
|
||||
return list.map((json) => Tournament.fromJson(json)).toList();
|
||||
}
|
||||
|
||||
Future<List<Tournament>> fetchAvailableTournaments() async {
|
||||
_availableTournaments = await _fetchTournaments();
|
||||
notifyListeners();
|
||||
return _availableTournaments;
|
||||
}
|
||||
|
||||
Future<List<Tournament>> ensureTournamentsLoaded() {
|
||||
_initialLoadFuture ??= fetchAvailableTournaments();
|
||||
return _initialLoadFuture!;
|
||||
}
|
||||
|
||||
Future<List<Tournament>> refreshAvailableTournaments() {
|
||||
_initialLoadFuture = fetchAvailableTournaments();
|
||||
return _initialLoadFuture!;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frontend_splatournament_manager/models/tournament.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class StateProvider extends ChangeNotifier {
|
||||
static const String baseUrl = "http://10.0.2.2:3000";
|
||||
ThemeMode _themeMode = ThemeMode.system;
|
||||
|
||||
ThemeMode get theme => _themeMode;
|
||||
|
||||
void setTheme(ThemeMode mode) {
|
||||
_themeMode = mode;
|
||||
notifyListeners();
|
||||
}
|
||||
List<Tournament>? _availableTournaments;
|
||||
void notifyState(){
|
||||
notifyListeners();
|
||||
}
|
||||
Future<List<Tournament>> fetchAvailableTournaments() async {
|
||||
try {
|
||||
var response = await http.get(Uri.parse('$baseUrl/tournaments'));
|
||||
if (response.statusCode == 200) {
|
||||
final List<dynamic> list = json.decode(response.body);
|
||||
_availableTournaments = list.map((json) => Tournament.fromJson(json)).toList();
|
||||
return _availableTournaments!;
|
||||
}
|
||||
} catch (e) {
|
||||
_availableTournaments = null;
|
||||
return Future.error(e);
|
||||
}
|
||||
return[];
|
||||
}
|
||||
List<Tournament> get availableTournaments => _availableTournaments ?? [];
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frontend_splatournament_manager/models/tournament.dart';
|
||||
import 'package:frontend_splatournament_manager/pages/tournament_detail_page.dart';
|
||||
import 'package:frontend_splatournament_manager/state_provider.dart';
|
||||
import 'package:frontend_splatournament_manager/providers/tournament_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class AvailableTournamentList extends StatelessWidget {
|
||||
@@ -17,13 +17,10 @@ class AvailableTournamentList extends StatelessWidget {
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 350,
|
||||
child: Consumer<StateProvider>(
|
||||
builder:
|
||||
(
|
||||
BuildContext context,
|
||||
StateProvider provider,
|
||||
Widget? child,
|
||||
) => TournamentListFutureBuilder(provider: provider),
|
||||
child: Consumer<TournamentProvider>(
|
||||
builder: (context, provider, _) {
|
||||
return TournamentListFutureBuilder(provider: provider);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -33,22 +30,30 @@ class AvailableTournamentList extends StatelessWidget {
|
||||
}
|
||||
|
||||
class TournamentListFutureBuilder extends StatelessWidget {
|
||||
final StateProvider provider;
|
||||
final TournamentProvider provider;
|
||||
|
||||
const TournamentListFutureBuilder({super.key, required this.provider});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder(
|
||||
future: provider.fetchAvailableTournaments(),
|
||||
return FutureBuilder<List<Tournament>>(
|
||||
future: provider.ensureTournamentsLoaded(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasError) {
|
||||
return Center(child: Text('Error: ${snapshot.error}'));
|
||||
} else if (!snapshot.hasData ||
|
||||
snapshot.connectionState == ConnectionState.waiting) {
|
||||
final list = provider.availableTournaments;
|
||||
print(list);
|
||||
if (snapshot.connectionState == ConnectionState.waiting &&
|
||||
list.isEmpty) {
|
||||
return Center(child: CircularProgressIndicator());
|
||||
}
|
||||
var list = snapshot.data!;
|
||||
|
||||
if (snapshot.hasError && list.isEmpty) {
|
||||
return Center(child: Text('Error: ${snapshot.error}'));
|
||||
}
|
||||
|
||||
if (list.isEmpty) {
|
||||
return Center(child: Text('No tournaments found'));
|
||||
}
|
||||
|
||||
return ListView.builder(
|
||||
shrinkWrap: false,
|
||||
itemCount: list.length,
|
||||
@@ -85,4 +90,3 @@ class TournamentListItem extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../state_provider.dart';
|
||||
import '../providers/theme_provider.dart';
|
||||
|
||||
class ThemeSelectorWidget extends StatelessWidget {
|
||||
ThemeSelectorWidget({super.key});
|
||||
@@ -23,7 +23,7 @@ class ThemeSelectorWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final stateProvider = Provider.of<StateProvider>(context);
|
||||
final themeProvider = Provider.of<ThemeProvider>(context);
|
||||
return Container(
|
||||
decoration: BoxDecoration(color: Theme.of(context).hoverColor, borderRadius: BorderRadius.circular(8)),
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
@@ -37,10 +37,10 @@ class ThemeSelectorWidget extends StatelessWidget {
|
||||
child: DropdownButtonFormField(
|
||||
icon: Icon(Icons.color_lens),
|
||||
items: dropdownElements,
|
||||
initialValue: stateProvider.theme,
|
||||
initialValue: themeProvider.theme,
|
||||
onChanged: (value) {
|
||||
if (value == null) return;
|
||||
stateProvider.setTheme(value);
|
||||
themeProvider.setTheme(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user