Skip to content

Commit

Permalink
feat(client): GUI for organizations, divisions, favorites
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustl22 committed Mar 19, 2024
1 parent ace81ea commit ab30f8a
Show file tree
Hide file tree
Showing 14 changed files with 347 additions and 180 deletions.
2 changes: 2 additions & 0 deletions wrestling_scoreboard_client/lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"appName": "Ringerkampf-Anzeige",
"home": "Start",
"explore": "Erkunden",
"more": "Mehr",
"settings": "Einstellungen",
"general": "Allgemein",
Expand Down Expand Up @@ -52,6 +53,7 @@
"display": "Anzeige",
"name": "Name",
"description": "Beschreibung",
"abbreviation": "Abkürzung",
"position": "Position",
"noItems": "Keine Einträge vorhanden.",
"optional": "Optional",
Expand Down
2 changes: 2 additions & 0 deletions wrestling_scoreboard_client/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "The internationalized app name"
},
"home": "Home",
"explore": "Explore",
"more": "More",
"settings": "Settings",
"general": "General",
Expand Down Expand Up @@ -55,6 +56,7 @@
"display": "Display",
"name": "Name",
"description": "Description",
"abbreviation": "Abbreviation",
"position": "Position",
"noItems": "No items available.",
"optional": "Optional",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ final _leagueNational = League(
division: _adultDivision,
);

Club _homeClub = const Club(id: 1, name: 'Springfield Wrestlers');
Club _guestClub = const Club(id: 2, name: 'Quahog Hunters');
Club _homeClub = const Club(id: 1, name: 'Springfield Wrestlers', organization: _organization);
Club _guestClub = const Club(id: 2, name: 'Quahog Hunters', organization: _organization);

Team _homeTeam = Team(
id: 1,
Expand Down
11 changes: 9 additions & 2 deletions wrestling_scoreboard_client/lib/view/app_navigation.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:wrestling_scoreboard_client/view/screens/home/explore.dart';
import 'package:wrestling_scoreboard_client/view/screens/home/home.dart';
import 'package:wrestling_scoreboard_client/view/screens/home/more.dart';

Expand All @@ -16,6 +17,7 @@ class _AppNavigationState extends State<AppNavigation> {
int _selectedIndex = 0;
static final List<Widget> _widgetOptions = <Widget>[
const Home(),
const Explore(),
const MoreScreen(),
];

Expand All @@ -27,6 +29,7 @@ class _AppNavigationState extends State<AppNavigation> {

@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
return Scaffold(
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
Expand All @@ -36,11 +39,15 @@ class _AppNavigationState extends State<AppNavigation> {
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: const Icon(Icons.home),
label: AppLocalizations.of(context)!.home,
label: localizations.home,
),
BottomNavigationBarItem(
icon: const Icon(Icons.explore),
label: localizations.explore,
),
BottomNavigationBarItem(
icon: const Icon(Icons.more_horiz),
label: AppLocalizations.of(context)!.more,
label: localizations.more,
),
],
currentIndex: _selectedIndex,
Expand Down
41 changes: 38 additions & 3 deletions wrestling_scoreboard_client/lib/view/screens/edit/club_edit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,33 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:wrestling_scoreboard_client/provider/network_provider.dart';
import 'package:wrestling_scoreboard_client/view/widgets/dropdown.dart';
import 'package:wrestling_scoreboard_client/view/widgets/edit.dart';
import 'package:wrestling_scoreboard_common/common.dart';

class ClubEdit extends ConsumerStatefulWidget {
final Club? club;
final Organization? initialOrganization;

const ClubEdit({this.club, super.key});
const ClubEdit({this.club, this.initialOrganization, super.key});

@override
ConsumerState<ConsumerStatefulWidget> createState() => ClubEditState();
}

class ClubEditState extends ConsumerState<ClubEdit> {
final _formKey = GlobalKey<FormState>();
Iterable<Organization>? _availableOrganizations;

String? _name;
String? _no;
late Organization? _organization;

@override
void initState() {
_organization = widget.club?.organization ?? widget.initialOrganization;
super.initState();
}

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -54,6 +64,27 @@ class ClubEditState extends ConsumerState<ClubEdit> {
onSaved: (newValue) => _no = newValue,
),
),
ListTile(
title: getDropdown<Organization>(
icon: const Icon(Icons.corporate_fare),
selectedItem: _organization,
label: localizations.organization,
context: context,
onSaved: (Organization? value) => setState(() {
_organization = value;
}),
allowEmpty: false,
itemAsString: (u) => u.name,
onFind: (String? filter) async {
_availableOrganizations ??=
await (await ref.read(dataManagerNotifierProvider)).readMany<Organization, Null>();
return (filter == null
? _availableOrganizations!
: _availableOrganizations!.where((element) => element.name.contains(filter)))
.toList();
},
),
),
];

return Form(
Expand All @@ -70,8 +101,12 @@ class ClubEditState extends ConsumerState<ClubEdit> {
Future<void> handleSubmit(NavigatorState navigator) async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
await (await ref.read(dataManagerNotifierProvider))
.createOrUpdateSingle(Club(id: widget.club?.id, name: _name!, no: _no));
await (await ref.read(dataManagerNotifierProvider)).createOrUpdateSingle(Club(
id: widget.club?.id,
name: _name!,
no: _no,
organization: _organization!,
));
navigator.pop();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,33 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:wrestling_scoreboard_client/provider/network_provider.dart';
import 'package:wrestling_scoreboard_client/view/widgets/dropdown.dart';
import 'package:wrestling_scoreboard_client/view/widgets/edit.dart';
import 'package:wrestling_scoreboard_common/common.dart';

class OrganizationEdit extends ConsumerStatefulWidget {
final Organization? organization;
final Organization? initialParent;

const OrganizationEdit({this.organization, super.key});
const OrganizationEdit({this.organization, this.initialParent, super.key});

@override
ConsumerState<ConsumerStatefulWidget> createState() => _OrganizationEditState();
}

class _OrganizationEditState extends ConsumerState<OrganizationEdit> {
final _formKey = GlobalKey<FormState>();
Iterable<Organization>? _availableOrganizations;

String? _name;
String? _abbreviation;
Organization? _parent;

@override
void initState() {
_parent = widget.organization?.parent ?? widget.initialParent;
super.initState();
}

@override
Widget build(BuildContext context) {
Expand All @@ -42,6 +53,38 @@ class _OrganizationEditState extends ConsumerState<OrganizationEdit> {
onSaved: (newValue) => _name = newValue,
),
),
ListTile(
leading: const Icon(Icons.short_text),
title: TextFormField(
decoration: InputDecoration(
border: const UnderlineInputBorder(),
labelText: localizations.abbreviation,
),
initialValue: widget.organization?.abbreviation,
onSaved: (newValue) => _abbreviation = newValue,
),
),
ListTile(
title: getDropdown<Organization>(
icon: const Icon(Icons.corporate_fare),
selectedItem: _parent,
label: localizations.organization,
context: context,
onSaved: (Organization? value) => setState(() {
_parent = value;
}),
allowEmpty: false,
itemAsString: (u) => u.name,
onFind: (String? filter) async {
_availableOrganizations ??=
await (await ref.read(dataManagerNotifierProvider)).readMany<Organization, Null>();
return (filter == null
? _availableOrganizations!
: _availableOrganizations!.where((element) => element.name.contains(filter)))
.toList();
},
),
),
];

return Form(
Expand All @@ -58,8 +101,12 @@ class _OrganizationEditState extends ConsumerState<OrganizationEdit> {
Future<void> handleSubmit(NavigatorState navigator) async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
await (await ref.read(dataManagerNotifierProvider))
.createOrUpdateSingle(Organization(id: widget.organization?.id, name: _name!));
await (await ref.read(dataManagerNotifierProvider)).createOrUpdateSingle(Organization(
id: widget.organization?.id,
name: _name!,
abbreviation: _abbreviation,
parent: _parent,
));
navigator.pop();
}
}
Expand Down
50 changes: 0 additions & 50 deletions wrestling_scoreboard_client/lib/view/screens/home/clubs_view.dart

This file was deleted.

This file was deleted.

50 changes: 50 additions & 0 deletions wrestling_scoreboard_client/lib/view/screens/home/explore.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:wrestling_scoreboard_client/provider/network_provider.dart';
import 'package:wrestling_scoreboard_client/services/network/remote/web_socket.dart';
import 'package:wrestling_scoreboard_client/view/screens/home/organizations_view.dart';
import 'package:wrestling_scoreboard_client/view/widgets/dialogs.dart';

class Explore extends ConsumerStatefulWidget {
const Explore({super.key});

@override
ConsumerState<ConsumerStatefulWidget> createState() => OrganizationState();
}

class OrganizationState extends ConsumerState<Explore> {
@override
void initState() {
super.initState();
ref.read(dataManagerNotifierProvider).then((dataManager) {
void onRetry() {
Navigator.of(context).pop();
dataManager.webSocketManager.onWebSocketConnection.sink.add(WebSocketConnectionState.connecting);
}

WidgetsBinding.instance.addPostFrameCallback((_) {
dataManager.webSocketManager.onWebSocketConnection.stream.distinct().listen((connectionState) {
if (mounted && connectionState == WebSocketConnectionState.disconnected) {
final localizations = AppLocalizations.of(context)!;
showExceptionDialog(
context: context, exception: localizations.noWebSocketConnection, stackTrace: null, onRetry: onRetry);
}
}, onError: (e, [trace]) {
showExceptionDialog(exception: e, context: context, stackTrace: trace, onRetry: onRetry);
});
});
});
}

@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
return Scaffold(
appBar: AppBar(
title: Text(localizations.explore),
),
body: const OrganizationsView(),
);
}
}
Loading

0 comments on commit ab30f8a

Please sign in to comment.