diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..2f0f891
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,15 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "type": "dart",
+ "command": "dart",
+ "args": [
+ "pub",
+ "get"
+ ],
+ "problemMatcher": [],
+ "label": "dart: dart pub get"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/team_c_f/assets/images/google.svg b/team_c_f/assets/images/google.svg
deleted file mode 100644
index 0b0dfe3..0000000
--- a/team_c_f/assets/images/google.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/team_c_f/lib/components/createschedule.dart b/team_c_f/lib/components/createschedule.dart
new file mode 100644
index 0000000..8cf12c8
--- /dev/null
+++ b/team_c_f/lib/components/createschedule.dart
@@ -0,0 +1,80 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:team_c_f/servises/servises.dart';
+import 'package:team_c_f/storebloc/blocs/createschedule.dart';
+import 'package:provider/provider.dart';
+import 'package:team_c_f/storebloc/blocs/schedule.dart';
+
+class CreateScheduleView extends StatelessWidget {
+ const CreateScheduleView({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ CreateScheduleBloc bloc = context.watch();
+ return Container(
+ child: Card(
+ child: ListTile(
+ title: Container(
+ padding: const EdgeInsets.all(8.0),
+ child: Column(
+ children: [
+ Text(
+ showRegisterTeam(bloc.state.registTeam) +
+ ' ' +
+ showTeam(bloc.state.registTeam),
+ ),
+ SizedBox(height: 20),
+ Text(
+ showFullTeam(bloc.state.fullTeam) +
+ ' ' +
+ showTeam(bloc.state.fullTeam),
+ ),
+ SizedBox(height: 20),
+ Text('Укажите количество кругов в чемпионате'),
+ TextField(
+ textAlign: TextAlign.center,
+ keyboardType: TextInputType.number,
+ onChanged: (circle) {
+ circle.trim();
+ bloc.state.circle = circle != '' ? int.parse(circle) : 1;
+ bloc.add(CreateScheduleEvent.changeCircle);
+ },
+ inputFormatters: [
+ FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
+ ],
+ ),
+ SizedBox(height: 20),
+ Text(
+ 'Ожидается ' +
+ showMatches(
+ matches: bloc.state.matches,
+ ) +
+ ' в каждом туре',
+ ),
+ SizedBox(height: 20),
+ Text(
+ 'Ожидается ' +
+ showTours(
+ tours: bloc.state.tours,
+ ),
+ ),
+ SizedBox(height: 20),
+ ElevatedButton(
+ onPressed: () {
+ bloc.add(CreateScheduleEvent.createSchedule);
+ context
+ .read()
+ .add(ScheduleEvent(event: Event.createSuccessful));
+ },
+ child: Text(
+ 'Создать расписание',
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/components/login.dart b/team_c_f/lib/components/login.dart
new file mode 100644
index 0000000..24e7737
--- /dev/null
+++ b/team_c_f/lib/components/login.dart
@@ -0,0 +1,106 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+import 'package:provider/provider.dart';
+import 'package:team_c_f/components/reglament.dart';
+import 'package:team_c_f/components/selectteam.dart';
+import 'package:team_c_f/store/login/login.dart';
+
+class LoginView extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ final Login login = Provider.of(context);
+ return Container(
+ height: double.infinity,
+ width: double.infinity,
+ child: Column(
+ mainAxisSize: MainAxisSize.max,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Observer(
+ builder: (_) => ElevatedButton(
+ onPressed: () {
+ login.updatedLoginStatus
+ ? login.googleLogout()
+ : login.googleLogin();
+ },
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Text(
+ login.updatedLoginStatus ? 'Выйти' : 'Войти',
+ ),
+ SizedBox(width: 10),
+ Image(
+ image: AssetImage('assets/images/google.png'),
+ fit: BoxFit.fill,
+ height: 30,
+ ),
+ ],
+ ),
+ ),
+ ),
+ Observer(
+ builder: (_) => Text(
+ login.updatedLoginStatus
+ ? 'Вход выполнен, осталось совсем чуть чуть'
+ : 'Необходимо войти в аккаунт',
+ textAlign: TextAlign.center,
+ ),
+ ),
+ Observer(
+ builder: (_) => TextButton(
+ onPressed: () {
+ if (login.info != null)
+ Navigator.of(context)
+ .push(MaterialPageRoute(
+ builder: (_) => ReglamentView(info: login.info!)))
+ .then((value) => login.changeName(value!.toString()));
+ },
+ child: Text('Правила конкурса'),
+ ),
+ ),
+ Container(
+ padding: const EdgeInsets.all(8.0),
+ margin: const EdgeInsets.all(8.0),
+ decoration: BoxDecoration(
+ color: Colors.blue,
+ borderRadius: BorderRadius.circular(16.0),
+ ),
+ child: Column(
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Text(
+ 'Введите ваше имя и фамилию',
+ style: TextStyle(
+ color: Colors.white,
+ ),
+ ),
+ ),
+ TextField(
+ // Ввод имени участника
+ decoration: InputDecoration(
+ fillColor: Colors.white,
+ filled: true,
+ ),
+ onChanged: login.changeName,
+ textAlign: TextAlign.center,
+ ),
+ ],
+ ),
+ ),
+ Observer(
+ builder: (_) {
+ Provider.of(context)
+ .setDataToSelectTeam(buttonText: 'Зарегистрироваться');
+ return SelectTeamView(
+ selectTeam: context.read().selectTeam,
+ updateMyTeam: false,
+ );
+ },
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/components/meet.dart b/team_c_f/lib/components/meet.dart
new file mode 100644
index 0000000..dd9de58
--- /dev/null
+++ b/team_c_f/lib/components/meet.dart
@@ -0,0 +1,52 @@
+import 'package:flutter/material.dart';
+import 'package:team_c_f/models/meet.dart';
+import 'package:intl/intl.dart';
+
+class MeetView extends StatelessWidget {
+ final MeetData meetData;
+ const MeetView({Key? key, required this.meetData}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ DateTime date = DateFormat('yyyy-MM-dd HH:mm').parse(meetData.date);
+ String status = meetData.status == 'Не начат'
+ ? date.day == DateTime.now().day
+ ? DateFormat('HH:mm').format(date)
+ : DateFormat('dd.MM').format(date)
+ : meetData.status;
+ String score = meetData.started
+ ? '${meetData.score.first}:${meetData.score.last}'
+ : '-';
+ double width = MediaQuery.of(context).size.width;
+ return Padding(
+ padding: const EdgeInsets.all(2.0),
+ child: Container(
+ padding: const EdgeInsets.all(8.0),
+ color: meetData.started ? Colors.green[100] : Colors.yellow[300],
+ width: width - 15,
+ child: Column(
+ children: [
+ Table(
+ columnWidths: {
+ 0: FixedColumnWidth(width/6.5),
+ 1: FixedColumnWidth(width/3),
+ 2: FixedColumnWidth(width/10),
+ 3: FixedColumnWidth(width/3)
+ },
+ children: [
+ TableRow(
+ children: [
+ Text(status, textAlign: TextAlign.center),
+ Text(meetData.team.first, textAlign: TextAlign.right),
+ Text(score, textAlign: TextAlign.center),
+ Text(meetData.team.last),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/components/oneteam.dart b/team_c_f/lib/components/oneteam.dart
new file mode 100644
index 0000000..2897e59
--- /dev/null
+++ b/team_c_f/lib/components/oneteam.dart
@@ -0,0 +1,95 @@
+import 'package:flutter/material.dart';
+import 'package:team_c_f/storebloc/blocs/leaveforecast.dart';
+import 'package:team_c_f/storebloc/models/leaveforecast.dart';
+import 'package:provider/provider.dart';
+
+class OneTeamView extends StatelessWidget {
+ final LeaveForecastModel forecast;
+ OneTeamView({Key? key, required this.forecast}) : super(key: key);
+
+ final List numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ @override
+ Widget build(BuildContext context) {
+ LeaveForecastBloc bloc = context.read();
+ double size = MediaQuery.of(context).size.width;
+ return Card(
+ color: Colors.blue[400],
+ child: Table(
+ defaultVerticalAlignment: TableCellVerticalAlignment.middle,
+ columnWidths: {
+ 0: FixedColumnWidth(size / 7),
+ 1: FixedColumnWidth(size / 3),
+ 2: FixedColumnWidth(size / 11),
+ 3: FixedColumnWidth(size / 40),
+ 4: FixedColumnWidth(size / 11),
+ 5: FixedColumnWidth(size / 3),
+ },
+ children: [
+ TableRow(
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Text(forecast.date),
+ ),
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Text(
+ forecast.teams.first,
+ textAlign: TextAlign.right,
+ ),
+ ),
+ DropdownButton(
+ value: forecast.home,
+ onChanged: (i) {
+ bloc.add(
+ LeaveForecastEvent(
+ event: Event.changeValue,
+ position: true,
+ index: bloc.state.meets.indexOf(forecast),
+ newValue: i),
+ );
+ },
+ items: [
+ ...numbers.map>(
+ (int number) => DropdownMenuItem(
+ child: Text(number.toString()),
+ value: number,
+ ),
+ ),
+ ],
+ ),
+ Text(':'),
+ DropdownButton(
+ value: forecast.away,
+ onChanged: (i) {
+ bloc.add(
+ LeaveForecastEvent(
+ event: Event.changeValue,
+ position: false,
+ index: bloc.state.meets.indexOf(forecast),
+ newValue: i),
+ );
+ },
+ items: [
+ ...numbers.map>(
+ (int number) => DropdownMenuItem(
+ child: Text(number.toString()),
+ value: number,
+ ),
+ ),
+ ],
+ ),
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Text(
+ forecast.teams.last,
+ textAlign: TextAlign.left,
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/components/reglament.dart b/team_c_f/lib/components/reglament.dart
new file mode 100644
index 0000000..fa5f6db
--- /dev/null
+++ b/team_c_f/lib/components/reglament.dart
@@ -0,0 +1,43 @@
+import 'package:flutter/material.dart';
+import 'package:team_c_f/models/info.dart';
+
+class ReglamentView extends StatelessWidget {
+ final InfoData info;
+ ReglamentView({required this.info});
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ home: Scaffold(
+ appBar: AppBar(
+ title: Row(
+ children: [
+ InkWell(
+ child: Icon(Icons.arrow_back, size: 30),
+ onTap: () {
+ Navigator.of(context).pop(true);
+ },
+ ),
+ SizedBox(width: 20),
+ Text('Правила конкурса'),
+ ],
+ ),
+ ),
+ body: Container(
+ height: double.infinity,
+ width: double.infinity,
+ child: ListView(
+ padding: const EdgeInsets.all(8.0),
+ children: [
+ ...info.regulations.map(
+ (String item) => Padding(
+ padding: const EdgeInsets.all(2.0),
+ child: Text(item),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/components/selectteam.dart b/team_c_f/lib/components/selectteam.dart
new file mode 100644
index 0000000..3a2a447
--- /dev/null
+++ b/team_c_f/lib/components/selectteam.dart
@@ -0,0 +1,187 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+import 'package:provider/provider.dart';
+import 'package:team_c_f/data/data.dart';
+import 'package:team_c_f/storebloc/blocs/myteam.dart';
+import 'package:team_c_f/store/login/login.dart';
+import 'package:team_c_f/store/selectteam/selectteam.dart';
+
+class SelectTeamView extends StatelessWidget {
+ // Класс отображения выбора команды или регистрации новой
+ final SelectTeam selectTeam;
+ final bool updateMyTeam;
+
+ const SelectTeamView({
+ Key? key,
+ required this.selectTeam,
+ required this.updateMyTeam,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ children: [
+ Container(
+ padding: const EdgeInsets.all(8.0),
+ margin: const EdgeInsets.all(8.0),
+ decoration: BoxDecoration(
+ color: Colors.blue,
+ borderRadius: BorderRadius.circular(16.0),
+ ),
+ child: Column(
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Observer(
+ builder: (_) => Checkbox(
+ // Чекбокс для капитанов
+ value: selectTeam.capitan,
+ checkColor: Colors.blue,
+ activeColor: Colors.white,
+ onChanged: selectTeam.changeCapitan,
+ ),
+ ),
+ Text(
+ 'Я капитан команды',
+ style: TextStyle(
+ color: Colors.white,
+ ),
+ ),
+ ],
+ ),
+ Observer(
+ builder: (_) => Container(
+ child: Column(
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Text(
+ selectTeam.capitan
+ ? 'Введите название вашей команды'
+ : 'Выбери команду',
+ style: TextStyle(
+ color: Colors.white,
+ ),
+ ),
+ ),
+ selectTeam.capitan
+ ? Observer(
+ builder: (_) => TextField(
+ // Ввод названия команды для капитана
+ decoration: InputDecoration(
+ fillColor: Colors.white, filled: true),
+ onChanged: selectTeam.changeTeam,
+ controller: TextEditingController.fromValue(
+ TextEditingValue(
+ text: selectTeam.lastTeamName,
+ selection: TextSelection.collapsed(
+ offset: selectTeam.lastTeamName.length),
+ ),
+ ),
+ textAlign: TextAlign.center,
+ ),
+ )
+ : Observer(
+ builder: (_) => selectTeam.allTeamNames.isNotEmpty
+ ? DropdownButton(
+ value: selectTeam.selectedTeam,
+ onChanged: selectTeam.selestTeam,
+ items: [
+ ...selectTeam.allTeamNames
+ .map>(
+ (String team) => DropdownMenuItem(
+ child: Text(team),
+ value: team,
+ ),
+ )
+ .toList(),
+ ],
+ )
+ : Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Column(
+ children: [
+ Text(
+ 'Ни одной доступной команды нет',
+ style: TextStyle(
+ color: Colors.white,
+ ),
+ ),
+ Text(
+ 'Можешь создать команду сам \u261d',
+ style: TextStyle(
+ color: Colors.white,
+ ),
+ )
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ Observer(
+ builder: (_) => ElevatedButton(
+ // Кнопка регистрации
+ style: ButtonStyle(
+ backgroundColor: MaterialStateProperty.all(Colors.green),
+ ),
+ onPressed: selectTeam.uName.isNotEmpty
+ ? selectTeam.capitan
+ ? selectTeam.teamName.isNotEmpty
+ ? selectTeam.enableName
+ ? () {
+ selectTeam.registrateTeam().then(
+ (_) {
+ context.read().validateInApp();
+ context.read().refreshData();
+ if (updateMyTeam)
+ context
+ .read()
+ .add(MyTeamEvent.reset);
+ },
+ );
+ }
+ : null
+ : null
+ : selectTeam.selectedTeam != null
+ ? () {
+ selectTeam.assertTeam().then(
+ (_) {
+ context.read().validateInApp();
+ context.read().refreshData();
+ if (updateMyTeam)
+ context
+ .read()
+ .add(MyTeamEvent.reset);
+ },
+ );
+ }
+ : null
+ : null,
+ child: Observer(
+ builder: (_) => Text(selectTeam.uId.isNotEmpty
+ ? selectTeam.uName.isNotEmpty
+ ? selectTeam.capitan
+ ? selectTeam.teamName.isNotEmpty
+ ? selectTeam.enableName
+ ? 'Зарегистрировать команду'
+ : 'Данное название команды недоступно'
+ : 'Введите название команды'
+ : selectTeam.selectedTeam != null
+ ? selectTeam.regButtonText
+ : 'Выберите команду'
+ : 'Введите имя и фамилию'
+ : 'Необходимо войти в Google-аккаунт'),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/team_c_f/lib/components/unconfirmedplayer.dart b/team_c_f/lib/components/unconfirmedplayer.dart
new file mode 100644
index 0000000..01767c8
--- /dev/null
+++ b/team_c_f/lib/components/unconfirmedplayer.dart
@@ -0,0 +1,56 @@
+import 'package:flutter/material.dart';
+import 'package:fluttertoast/fluttertoast.dart';
+import 'package:team_c_f/storebloc/blocs/myteam.dart';
+import 'package:team_c_f/storebloc/models/unconfirmedplayer.dart';
+import 'package:provider/provider.dart';
+
+class UnconfirmedPlayerView extends StatelessWidget {
+ // Класс, для отображения неподтвержденных игроков
+ final UnconfirmedPlayerModel player; // Неподтвержденный игрок
+ UnconfirmedPlayerView({Key? key, required this.player}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ MyTeamBloc bloc = context.watch();
+ return Container(
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(10.0),
+ child: Text(player.name),
+ ),
+ IconButton(
+ icon: Icon(
+ Icons.check_box,
+ size: 30,
+ color: Colors.green,
+ ),
+ onPressed: () {
+ bloc.state.selectId = player.uid;
+ bloc.add(MyTeamEvent.confirmedPlayer);
+ Fluttertoast.showToast(
+ msg: '${player.name} добавлен в вашу команду',
+ );
+ },
+ ),
+ IconButton(
+ icon: Icon(
+ Icons.cancel,
+ size: 30,
+ color: Colors.red,
+ ),
+ onPressed: () {
+ bloc.state.selectId = player.uid;
+ bloc.add(MyTeamEvent.unconfirmedPlayer);
+ Fluttertoast.showToast(
+ msg: 'Заявка отклонена',
+ );
+ },
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/data/data.dart b/team_c_f/lib/data/data.dart
index a95623b..aad02b8 100644
--- a/team_c_f/lib/data/data.dart
+++ b/team_c_f/lib/data/data.dart
@@ -1,51 +1,117 @@
-import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
-import 'package:team_c_f/servise/auth.dart';
-import 'package:team_c_f/servise/operationdb.dart';
-
-class Account with ChangeNotifier {
- // Единый класс с информацией о Google-аккаунте и регистрации в приложении
- bool _signInGoogle = false;
- bool _registedInApp = false;
- String _userId = '';
-
- bool get signIn => _signInGoogle; // Выполнен вход в Google-аккаунт
- bool get registedInApp =>
- _registedInApp; // Выполнена ли регистрации в приложении
- String get userId => _userId; // Уникальный идентификатор Google-аккаунта
-
- Account() {
- // Конструктор
- calculateVariables();
+import 'package:team_c_f/models/currenttour.dart';
+import 'package:team_c_f/models/meets.dart';
+import 'package:team_c_f/models/player.dart';
+import 'package:team_c_f/models/team.dart';
+import 'package:team_c_f/models/tour.dart';
+import 'package:team_c_f/servises/data.dart';
+import 'package:team_c_f/servises/tour.dart';
+
+class Data with ChangeNotifier {
+ bool downloadSuccessful = false;
+
+ Data() {
+ initData();
+ }
+
+ void refreshData() {
+ downloadSuccessful = false;
+ notifyListeners();
+ initData();
}
- void calculateVariables() {
- // Вычисление переменных
- if (FirebaseAuth.instance.currentUser != null) {
- _userId = FirebaseAuth.instance.currentUser.uid;
- _signInGoogle = true;
- DatabaseService().userExists(userId: _userId).then((value) {
- _registedInApp = value;
- notifyListeners();
- });
- } else {
- _userId = '';
- _signInGoogle = false;
- _registedInApp = false;
+ void initData(){
+ DataService().initData().then((result) {
+ sortData();
+ downloadSuccessful = result;
notifyListeners();
- }
+ });
}
- Future changeSignIn() async {
- // Изменение статуса входа в Google-аккаунт
- _signInGoogle ? await signOutGoogle() : await signInWithGoogle();
- calculateVariables();
+ static late CurrentTourData currentTour;
+ static late List players;
+ static late List teams;
+ static late List tours;
+ static late List meets;
+ static late List names = [];
+
+ static void sortTour() {
+ tours.sort((TourData a, b) =>
+ a.round.compareTo(b.round)); // сортировка туров по порядку
}
- void registedUser() {
- // Регистрация пользователя в приложении
- _registedInApp = true;
+ static void sortData() {
+ sortTour();
+ sortPlayer(players: players);
+ players.forEach(
+ (PlayerData p) {
+ p.prevPosition = players.indexOf(p) + 1;
+ },
+ ); // указание текущей позиции игрока
- notifyListeners();
+ tours.forEach(
+ (TourData tour) {
+ int round = tours.indexOf(tour);
+ tour.team.forEach(
+ (List pair) {
+ TeamData home =
+ teams.where((TeamData team) => team.name == pair[0]).single;
+ TeamData away =
+ teams.where((TeamData team) => team.name == pair[1]).single;
+ if (home.goal.length > round) {
+ if (home.goal[round] == null && away.goal[round] == null) {
+ home.lose++;
+ away.lose++;
+ } else if (home.goal[round] == null) {
+ home.lose++;
+ away.win++;
+ home.missed += away.goal[round]!;
+ } else if (away.goal[round] == null) {
+ away.lose++;
+ home.win++;
+ away.missed += home.goal[round]!;
+ } else {
+ int goalHome = home.goal[round]!;
+ int goalAway = away.goal[round]!;
+ home.missed += goalAway;
+ away.missed += goalHome;
+ if (goalHome > goalAway) {
+ home.win++;
+ away.lose++;
+ } else if (goalAway > goalHome) {
+ away.win++;
+ home.lose++;
+ } else {
+ home.draw++;
+ away.draw++;
+ }
+ }
+ }
+ },
+ );
+ },
+ ); // определение wdl для команд и количества пропущенных
+ sortTeam(teams: teams);
+ teams.forEach(
+ (TeamData t) {
+ t.prevPosition = teams.indexOf(t) + 1;
+ },
+ ); // указание текущей позиции команды
+ }
+
+ static void sortTeam({required List teams}) {
+ teams.sort((TeamData a, b) => (b.goals - b.missed)
+ .compareTo(a.goals - a.missed)); // сортировка команд по разнице забитых
+ teams.sort((TeamData a, b) =>
+ b.win.compareTo(a.win)); // сортировка команд по количеству побед
+ teams.sort((TeamData a, b) =>
+ b.goals.compareTo(a.goals)); // сортировка команд по количеству забитых
+ teams.sort((TeamData a, b) =>
+ b.points.compareTo(a.points)); // сортировка команд по количеству очков
+ }
+
+ static void sortPlayer({required List players}) {
+ players.sort((PlayerData a, b) => b.goals
+ .compareTo(a.goals)); // сортировка участников по количеству забитых
}
}
diff --git a/team_c_f/lib/element/player.dart b/team_c_f/lib/element/player.dart
deleted file mode 100644
index 1f53206..0000000
--- a/team_c_f/lib/element/player.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:team_c_f/data/player.dart';
-import 'package:team_c_f/servise/make.dart';
-import 'package:adaptive_dialog/adaptive_dialog.dart';
-import 'package:provider/provider.dart';
-import 'package:team_c_f/data/tournament.dart';
-
-class ShowPlayer extends StatelessWidget {
- // Класс отображающий информацию об указанном игроке
- final Player player;
- ShowPlayer({Key key, @required this.player}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return Container(
- child: InkWell(
- onLongPress: () async {
- if (context.read().me.capitan) if (await showAlertDialog(
- context: context,
- title: 'Изменение состава',
- message: 'Удалить ${player.name}',
- actions: [
- AlertDialogAction(
- key: true,
- label: 'Да, удалить',
- isDefaultAction: true,
- ),
- AlertDialogAction(
- key: false,
- label: 'Отмена',
- isDestructiveAction: true,
- ),
- ],
- )) context.read().removePlayerFromMyTeam(uid: player.uid);
- },
- child: Card(
- child: ListTile(
- leading: CircleAvatar(
- child: Text(player.position.toString()),
- ),
- title: Text(player.name),
- trailing: Text(showPoints(player.points)),
- ),
- ),
- ),
- );
- }
-}
diff --git a/team_c_f/lib/main.dart b/team_c_f/lib/main.dart
index b5d443e..ec9dff9 100644
--- a/team_c_f/lib/main.dart
+++ b/team_c_f/lib/main.dart
@@ -1,13 +1,12 @@
-import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
-import 'package:provider/provider.dart';
-import 'package:team_c_f/data/data.dart';
-import 'package:team_c_f/data/shortmatch.dart';
-import 'package:team_c_f/data/tournament.dart';
-import 'package:team_c_f/page/home.dart';
-import 'package:team_c_f/page/sign.dart';
import 'package:firebase_core/firebase_core.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:onesignal_flutter/onesignal_flutter.dart';
+import 'package:provider/provider.dart';
+import 'package:team_c_f/data/data.dart';
+import 'package:team_c_f/pages/login.dart';
+import 'package:team_c_f/store/login/login.dart';
+import 'package:team_c_f/pages/home.dart';
Future main() async {
myApp();
@@ -17,307 +16,29 @@ myApp() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(); // Инициализация Firebase
- //OneSignal.shared.setLogLevel(OSLogLevel.verbose, OSLogLevel.none);
-
- OneSignal.shared.init('93b27d54-e442-4af5-86e4-a215faf20e3a', iOSSettings: {
- OSiOSSettings.autoPrompt: false,
- OSiOSSettings.inAppLaunchUrl: false
- });
- OneSignal.shared
- .setInFocusDisplayType(OSNotificationDisplayType.notification);
+ OneSignal.shared.setAppId('93b27d54-e442-4af5-86e4-a215faf20e3a');
runApp(
- MultiProvider(
- // Мультипровайдер, для упроощения взаимодействия с данными
- providers: [
- ChangeNotifierProvider(
- create: (context) => Account(),
- ), // Данные связанные с аутентификацией (гугл-вход и регистрация в приложении)
- ChangeNotifierProvider(
- create: (context) => Tournament(),
- ), // Данные полученные из Firebase
- ChangeNotifierProvider(
- create: (context) => DataMatch(),
- ),
- ],
- child: MaterialApp(
- // theme: ThemeData(
- // textTheme: TextTheme(
- // bodyText2: TextStyle(
- // color: Colors.black,
- // fontWeight: FontWeight.normal,
- // ),
- // bodyText1: TextStyle(
- // color: Colors.black,
- // decoration: TextDecoration.lineThrough,
- // fontWeight: FontWeight.normal,
- // ),
- // caption: TextStyle(
- // color: Colors.green,
- // fontWeight: FontWeight.w400,
- // ),
- // ),
- // ),
- home: SafeArea(
- child: Page(),
- ),
+ MaterialApp(
+ home: MultiProvider(
+ providers: [
+ Provider(create: (_) => Login()),
+ ChangeNotifierProvider(create: (_) => Data()),
+ ],
+ child: FirstPage(),
),
),
);
}
-class Page extends StatefulWidget {
- const Page({Key key}) : super(key: key);
-
- @override
- _PageState createState() => _PageState();
-}
+class FirstPage extends StatelessWidget {
+ const FirstPage({Key? key}) : super(key: key);
-class _PageState extends State {
@override
Widget build(BuildContext context) {
- return Container(
- child: context
- .watch()
- .registedInApp // Проверка зарегистрирован ли пользователь в приложении
- ? Homepage() // Домашняя страница приложения
- : Sign(), // Регистрация в приложении + вход в гугл
+ return Observer(
+ builder: (_) =>
+ context.read().registrateInApp ? HomePage() : LoginPage(),
);
}
}
-
-// class Prob extends StatelessWidget {
-// const Prob({Key key}) : super(key: key);
-
-// @override
-// Widget build(BuildContext context) {
-// return Container(
-// child: Text(
-// '1 - 1',
-// style: Theme.of(context).textTheme.bodyText2,
-// ),
-// );
-// }
-// }
-
-// class Content extends StatefulWidget {
-// const Content({Key key}) : super(key: key);
-
-// @override
-// _ContentState createState() => _ContentState();
-// }
-
-// class _ContentState extends State {
-// Tournament tournament;
-// String currentTour = 'start msg';
-// int matchNumber = 0;
-// Team home;
-// Team away;
-// bool dataDownload = false;
-
-// Tournament parseTournament(String responseBody) {
-// final parsed = json.decode(responseBody);
-
-// return Tournament.fromJson(parsed);
-// }
-
-// Future downloadInfo(http.Client client) async {
-// final response = await client
-// .get(Uri.parse('http://tcfserver.azurewebsites.net/info?tour=31'));
-
-// return parseTournament(response.body);
-// }
-
-// changeMatch(int index, CarouselPageChangedReason reason) {
-// setState(() {
-// matchNumber = index;
-// home = tournament.teams
-// .where((element) => element.name == tournament.pair[matchNumber * 2])
-// .first;
-// away = tournament.teams
-// .where(
-// (element) => element.name == tournament.pair[matchNumber * 2 + 1])
-// .first;
-// });
-// }
-
-// void download() async {
-// downloadInfo(http.Client()).then(
-// (all) => setState(() {
-// currentTour = 'Текущий тур ${all.currentTour}';
-// tournament = all;
-// home = all.teams
-// .where((element) => element.name == all.pair[matchNumber * 2])
-// .first;
-// away = all.teams
-// .where((element) => element.name == all.pair[matchNumber * 2 + 1])
-// .first;
-// dataDownload = true;
-// }),
-// );
-// setState(() {
-// currentTour = 'Загрузка данных';
-// });
-// }
-
-// Widget headerBuilder(int i) {
-// Team home = tournament.teams
-// .where((element) => element.name == tournament.pair[i * 2])
-// .first;
-// Team away = tournament.teams
-// .where((element) => element.name == tournament.pair[i * 2 + 1])
-// .first;
-// return Container(
-// decoration: BoxDecoration(
-// borderRadius: BorderRadius.circular(20),
-// color: Colors.blue[100],
-// ),
-// alignment: Alignment.center,
-// margin: const EdgeInsets.symmetric(
-// vertical: 8,
-// ),
-// child: Column(
-// mainAxisSize: MainAxisSize.max,
-// mainAxisAlignment: MainAxisAlignment.center,
-// children: [
-// Row(
-// mainAxisSize: MainAxisSize.max,
-// children: [
-// Expanded(
-// flex: 2,
-// child: Text(
-// '${home.countPerRound}',
-// textAlign: TextAlign.center,
-// style: TextStyle(
-// fontSize: 30,
-// ),
-// ),
-// ),
-// Expanded(
-// flex: 1,
-// child: Text(
-// '-',
-// textAlign: TextAlign.center,
-// style: TextStyle(
-// fontSize: 30,
-// ),
-// ),
-// ),
-// Expanded(
-// flex: 2,
-// child: Text(
-// '${away.countPerRound}',
-// textAlign: TextAlign.center,
-// style: TextStyle(
-// fontSize: 30,
-// ),
-// ),
-// ),
-// ],
-// ),
-// Expanded(
-// flex: 1,
-// child: Row(
-// children: [
-// Expanded(
-// flex: 1,
-// child: Text(
-// '${home.name.split("\"")[1]}',
-// textAlign: TextAlign.center,
-// style: TextStyle(
-// fontSize: 18,
-// ),
-// ),
-// ),
-// SizedBox(
-// width: 20,
-// ),
-// Expanded(
-// flex: 1,
-// child: Text(
-// '${away.name.split("\"")[1]}',
-// textAlign: TextAlign.center,
-// style: TextStyle(
-// fontSize: 18,
-// ),
-// ),
-// ),
-// ],
-// ),
-// ),
-// ],
-// ),
-// );
-// }
-
-// @override
-// Widget build(BuildContext context) {
-// Widget wrap() {
-// return Column(
-// children: [
-// Wrap(
-// spacing: 10,
-// runSpacing: 10,
-// alignment: WrapAlignment.center,
-// direction: Axis.horizontal,
-// children: [
-// for (int i = 0; i < 10; i++)
-// Meet(
-// number: i,
-// home: home,
-// away: away,
-// real: tournament.realResults,
-// rHome: tournament.names.team[i * 2],
-// rAway: tournament.names.team[i * 2 + 1],
-// info: tournament.names.info[i],
-// )
-// ],
-// ),
-// ],
-// );
-// }
-
-// Widget headers() {
-// return CarouselSlider(
-// items: [
-// for (int i = 0; i * 2 < tournament.pair.length; i++) headerBuilder(i)
-// ],
-// options: CarouselOptions(
-// autoPlay: false,
-// enlargeCenterPage: true,
-// onPageChanged: changeMatch,
-// aspectRatio: 4,
-// ),
-// );
-// }
-
-// return Container(
-// color: Colors.indigo,
-// alignment: Alignment.center,
-// width: double.infinity,
-// height: double.infinity,
-// padding: const EdgeInsets.all(10),
-// child: Column(
-// children: [
-// dataDownload ? headers() : SizedBox(height: 0),
-// Expanded(
-// child: Container(
-// child: ListView(
-// children: [
-// dataDownload ? wrap() : Text('Прогнозы ещё не загружены'),
-// ElevatedButton(
-// child: Text('Download'),
-// onPressed: download,
-// ),
-// Text(
-// currentTour,
-// ),
-// ],
-// ),
-// ),
-// ),
-// ],
-// ),
-// );
-// }
-// }
diff --git a/team_c_f/lib/models/choicemeet.dart b/team_c_f/lib/models/choicemeet.dart
new file mode 100644
index 0000000..62544a0
--- /dev/null
+++ b/team_c_f/lib/models/choicemeet.dart
@@ -0,0 +1,47 @@
+import 'package:html/dom.dart';
+import 'package:intl/intl.dart';
+
+class ChoiceMeetData {
+ final List team;
+ final DateTime date;
+ late bool selected;
+
+ ChoiceMeetData({
+ required this.team,
+ required this.date,
+ required this.selected,
+ });
+
+ factory ChoiceMeetData.fromHtml({
+ required String date,
+ required Element html,
+ }) {
+ List team = [
+ html.getElementsByClassName('owner-td').single.text.replaceAll(
+ '\n',
+ '',
+ ),
+ html.getElementsByClassName('guests-td').single.text.replaceAll(
+ '\n',
+ '',
+ ),
+ ];
+ String time = html.getElementsByClassName('alLeft gray-text').first.text;
+ time = date + ' ' + (time != '—' ? time : '00:00');
+ DateTime dateTime = DateFormat('yyyy-MM-dd HH:mm').parse(time);
+ bool selected = false;
+ return ChoiceMeetData(
+ team: team,
+ date: dateTime,
+ selected: selected,
+ );
+ }
+
+ ChoiceMeetData copyWith({required bool selected}) {
+ return ChoiceMeetData(
+ team: this.team,
+ date: this.date,
+ selected: selected,
+ );
+ }
+}
diff --git a/team_c_f/lib/models/currenttour.dart b/team_c_f/lib/models/currenttour.dart
new file mode 100644
index 0000000..585fba4
--- /dev/null
+++ b/team_c_f/lib/models/currenttour.dart
@@ -0,0 +1,17 @@
+class CurrentTourData {
+ late String docId;
+ int round;
+ CurrentTourData({required this.round});
+
+ Map toMap() {
+ return {
+ 'Round': round,
+ };
+ }
+
+ factory CurrentTourData.fromMap({required Map data, required String docId}){
+ CurrentTourData curr = CurrentTourData(round: data['Round']);
+ curr.docId = docId;
+ return curr;
+ }
+}
diff --git a/team_c_f/lib/models/forecast.dart b/team_c_f/lib/models/forecast.dart
new file mode 100644
index 0000000..71d62d5
--- /dev/null
+++ b/team_c_f/lib/models/forecast.dart
@@ -0,0 +1,37 @@
+class ForecastData {
+ late String docId;
+ final String uid;
+ final List rate;
+ final String? team;
+ final int round;
+ int result = 0;
+
+ ForecastData({
+ required this.uid,
+ required this.rate,
+ required this.team,
+ required this.round,
+ });
+
+ Map toMap() {
+ return {
+ 'UserId': uid,
+ 'Rate': rate,
+ 'Team': team,
+ 'Round': round,
+ 'Result': result,
+ };
+ }
+
+ factory ForecastData.fromMap({required Map data, required String docId}) {
+ ForecastData f = ForecastData(
+ uid: data['UserId'],
+ rate: data['Rate'].cast(),
+ team: data['Team'],
+ round: data['Round'],
+ );
+ f.result = data['Result'];
+ f.docId = docId;
+ return f;
+ }
+}
diff --git a/team_c_f/lib/models/info.dart b/team_c_f/lib/models/info.dart
new file mode 100644
index 0000000..d53112f
--- /dev/null
+++ b/team_c_f/lib/models/info.dart
@@ -0,0 +1,22 @@
+class InfoData {
+ final List regulations;
+ final String link;
+ InfoData({
+ required this.regulations,
+ required this.link,
+ });
+
+ factory InfoData.fromMap({required Map data}) {
+ return InfoData(
+ link: data['Link'],
+ regulations: [...data['Regulations']],
+ );
+ }
+
+ Map toMap(){
+ return {
+ 'Link': link,
+ 'Regulations': regulations,
+ };
+ }
+}
diff --git a/team_c_f/lib/models/meet.dart b/team_c_f/lib/models/meet.dart
new file mode 100644
index 0000000..17add45
--- /dev/null
+++ b/team_c_f/lib/models/meet.dart
@@ -0,0 +1,50 @@
+class MeetData {
+ final List team;
+ final String date;
+ late List score;
+ final bool started;
+ late String status;
+
+ MeetData({
+ required this.team,
+ required this.date,
+ required this.score,
+ required this.started,
+ required this.status,
+ });
+
+ factory MeetData.fromMap({required Map data}) {
+ return MeetData(
+ team: data['Team'].cast(),
+ date: data['Date'],
+ score: data['Score'].cast(),
+ started: data['Started'],
+ status: data['Status'],
+ );
+ }
+
+ Map toMap() {
+ return {
+ 'Team': team,
+ 'Date': date,
+ 'Score': score,
+ 'Started': started,
+ 'Status': status,
+ };
+ }
+
+ String toString() {
+ return '${team.first} - ${team.last}|$date|${score.first}:${score.last}|$started|$status';
+ }
+
+ factory MeetData.fromString({required String data}) {
+ List split = data.split('|');
+ return MeetData(
+ team: split[0].split(' - '),
+ date: split[1],
+ score: split[2].split(':').map((String goal) => int.parse(goal)).toList(),
+ started: bool.fromEnvironment(split[3]),
+ status: split[4],
+ );
+ }
+}
diff --git a/team_c_f/lib/models/meets.dart b/team_c_f/lib/models/meets.dart
new file mode 100644
index 0000000..d81b500
--- /dev/null
+++ b/team_c_f/lib/models/meets.dart
@@ -0,0 +1,48 @@
+import 'meet.dart';
+
+class MeetsData {
+ late String docId;
+ final int round;
+ final List meets;
+ final String deadline;
+ late bool started;
+
+ MeetsData({
+ required this.round,
+ required this.meets,
+ required this.deadline,
+ required this.started,
+ });
+
+ factory MeetsData.fromMap(
+ {required Map data, required String docId}) {
+ List a = [];
+ if (data['Meets'].isNotEmpty)
+ a.addAll(
+ [
+ ...data['Meets']
+ .map(
+ (meet) => MeetData.fromString(data: meet),
+ )
+ .toList(),
+ ],
+ );
+ MeetsData meets = MeetsData(
+ round: data['Round'],
+ meets: a,
+ deadline: data['Deadline'],
+ started: data['Started'],
+ );
+ meets.docId = docId;
+ return meets;
+ }
+
+ Map toMap() {
+ return {
+ 'Round': round,
+ 'Meets': meets.map((e) => e.toString()).toList(),
+ 'Deadline': deadline,
+ 'Started': started,
+ };
+ }
+}
diff --git a/team_c_f/lib/models/player.dart b/team_c_f/lib/models/player.dart
new file mode 100644
index 0000000..2baaceb
--- /dev/null
+++ b/team_c_f/lib/models/player.dart
@@ -0,0 +1,47 @@
+class PlayerData {
+ String? docId;
+ final String uid;
+ String name;
+ String? team;
+ late List points = [];
+
+ int get maxTour => points.fold(
+ 0,
+ (value, current) => current != null
+ ? current > value
+ ? current
+ : value
+ : value);
+ int get goals => points.fold(
+ 0,
+ (value, current) => value + (current != null ? current : 0),
+ );
+ late int prevPosition;
+
+ PlayerData({
+ required this.uid,
+ required this.name,
+ required this.team,
+ this.docId,
+ });
+
+ Map toMap() {
+ return {
+ 'UserId': uid,
+ 'Name': name,
+ 'Team': team,
+ 'Points': points,
+ };
+ }
+
+ factory PlayerData.fromMap({required Map data, required String docId}) {
+ PlayerData p = PlayerData(
+ name: data['Name'],
+ team: data['Team'],
+ uid: data['UserId'],
+ );
+ p.points = [...data['Points']];
+ p.docId = docId;
+ return p;
+ }
+}
diff --git a/team_c_f/lib/models/team.dart b/team_c_f/lib/models/team.dart
new file mode 100644
index 0000000..23bc927
--- /dev/null
+++ b/team_c_f/lib/models/team.dart
@@ -0,0 +1,49 @@
+class TeamData {
+ late String docId;
+ final String name;
+ final String uidCapitan;
+ List players = [];
+ List goal = [];
+
+ int get maxTour => goal.fold(
+ 0,
+ (value, current) => current != null
+ ? current > value
+ ? current
+ : value
+ : value);
+ int get goals => goal.fold(
+ 0,
+ (value, current) => value + (current != null ? current : 0),
+ );
+ int missed = 0;
+ int win = 0;
+ int draw = 0;
+ int lose = 0;
+ int get points => win * 3 + draw;
+ late int prevPosition;
+
+ TeamData({required this.name, required this.uidCapitan}) {
+ players.add(this.uidCapitan);
+ }
+
+ Map toMap() {
+ return {
+ 'Name': name,
+ 'Capitan': uidCapitan,
+ 'Players': players,
+ 'Goal': goal,
+ };
+ }
+
+ factory TeamData.fromMap({required Map data, required String docId}) {
+ TeamData t = TeamData(
+ name: data['Name'] as String,
+ uidCapitan: data['Capitan'],
+ );
+ t.players = [...data['Players']];
+ t.goal = [...data['Goal']];
+ t.docId = docId;
+ return t;
+ }
+}
diff --git a/team_c_f/lib/models/tour.dart b/team_c_f/lib/models/tour.dart
new file mode 100644
index 0000000..e7648c2
--- /dev/null
+++ b/team_c_f/lib/models/tour.dart
@@ -0,0 +1,28 @@
+class TourData {
+ final int round;
+ String? name;
+ late List> team;
+ TourData({required this.round, this.name});
+
+ String get stage => name?? round.toString();
+
+ TourData.all({
+ required this.round,
+ required this.team,
+ });
+
+ Map toMap() {
+ return {
+ 'Round': round,
+ 'Team': team.map((List match) => match.first + '><' + match.last).toList(),
+ 'Name': name ?? round.toString(),
+ };
+ }
+
+ factory TourData.fromMap({required Map data}) {
+ TourData t = TourData(round: data['Round'], name: data['Name']);
+ List match = data['Team'].cast();
+ t.team = match.map((String pair) => pair.split('><').toList()).toList();
+ return t;
+ }
+}
diff --git a/team_c_f/lib/data/currenttour.dart b/team_c_f/lib/old/data/currenttour.dart
similarity index 58%
rename from team_c_f/lib/data/currenttour.dart
rename to team_c_f/lib/old/data/currenttour.dart
index 3a01d59..f4801cd 100644
--- a/team_c_f/lib/data/currenttour.dart
+++ b/team_c_f/lib/old/data/currenttour.dart
@@ -1,17 +1,17 @@
import 'package:flutter/material.dart';
class CurrentTour { // Класс с данными о текущем туре
- final String tour; // Номер или стадия текущего тура
- final String tournament; // Название текущей стадии
+ final String? tour; // Номер или стадия текущего тура
+ final String? tournament; // Название текущей стадии
CurrentTour({ // Базовый конструктор
@required this.tour,
@required this.tournament,
});
- factory CurrentTour.fromJson({Map json}) { // Именованный конструктор, используется для десериализации
+ factory CurrentTour.fromJson({Map? json}) { // Именованный конструктор, используется для десериализации
return CurrentTour(
- tour: json['Tour'],
+ tour: json!['Tour'],
tournament: json['Tournament'],
);
}
diff --git a/team_c_f/lib/old/data/data.dart b/team_c_f/lib/old/data/data.dart
new file mode 100644
index 0000000..1110e25
--- /dev/null
+++ b/team_c_f/lib/old/data/data.dart
@@ -0,0 +1,51 @@
+import 'package:firebase_auth/firebase_auth.dart';
+import 'package:flutter/material.dart';
+import 'package:team_c_f/old/servise/auth.dart';
+import 'package:team_c_f/old/servise/operationdb.dart';
+
+class Account with ChangeNotifier {
+ // Единый класс с информацией о Google-аккаунте и регистрации в приложении
+ bool? _signInGoogle = false;
+ bool? _registedInApp = false;
+ String? _userId = '';
+
+ bool get signIn => _signInGoogle!; // Выполнен вход в Google-аккаунт
+ bool get registedInApp =>
+ _registedInApp!; // Выполнена ли регистрации в приложении
+ String get userId => _userId!; // Уникальный идентификатор Google-аккаунта
+
+ Account() {
+ // Конструктор
+ calculateVariables();
+ }
+
+ void calculateVariables() {
+ // Вычисление переменных
+ if (FirebaseAuth.instance.currentUser != null) {
+ _userId = FirebaseAuth.instance.currentUser!.uid;
+ _signInGoogle = true;
+ DatabaseService().userExists(userId: _userId!).then((value) {
+ _registedInApp = value;
+ notifyListeners();
+ });
+ } else {
+ _userId = '';
+ _signInGoogle = false;
+ _registedInApp = false;
+ notifyListeners();
+ }
+ }
+
+ Future changeSignIn() async {
+ // Изменение статуса входа в Google-аккаунт
+ _signInGoogle! ? await signOutGoogle() : await signInWithGoogle();
+ calculateVariables();
+ }
+
+ void registedUser() {
+ // Регистрация пользователя в приложении
+ _registedInApp = true;
+
+ notifyListeners();
+ }
+}
diff --git a/team_c_f/lib/data/forecast.dart b/team_c_f/lib/old/data/forecast.dart
similarity index 75%
rename from team_c_f/lib/data/forecast.dart
rename to team_c_f/lib/old/data/forecast.dart
index 40d9e6f..1d0c3fb 100644
--- a/team_c_f/lib/data/forecast.dart
+++ b/team_c_f/lib/old/data/forecast.dart
@@ -1,24 +1,23 @@
import 'dart:convert';
-import 'package:flutter/material.dart';
-import 'package:team_c_f/data/match.dart';
-import 'package:team_c_f/servise/make.dart';
+import 'package:team_c_f/old/data/match.dart';
+import 'package:team_c_f/old/servise/make.dart';
class Forecast {
// Информация о прогнозе
- String _docId; // Идентификатор документа с прогнозом
+ late String _docId; // Идентификатор документа с прогнозом
final String
userId; // Идентификатор Google-аккаунта участника оставившего прогноз
final String tour; // Номер тура
final List rate; // Список прогнозов
- int _points; // Количество набранных очков
+ late int _points; // Количество набранных очков
final String team;
Forecast({
// Конструктор
- @required this.userId,
- @required this.tour,
- @required this.rate,
- @required this.team,
+ required this.userId,
+ required this.tour,
+ required this.rate,
+ required this.team,
});
set docId(String docId) {
@@ -27,7 +26,7 @@ class Forecast {
int get points => _points;
- factory Forecast.fromJson({Map json, String docId}) {
+ factory Forecast.fromJson({required Map json, required String docId}) {
// Именованный конструктор для десериализации
Forecast f = Forecast(
userId: json['UserId'],
diff --git a/team_c_f/lib/data/match.dart b/team_c_f/lib/old/data/match.dart
similarity index 78%
rename from team_c_f/lib/data/match.dart
rename to team_c_f/lib/old/data/match.dart
index d506bac..cee18d0 100644
--- a/team_c_f/lib/data/match.dart
+++ b/team_c_f/lib/old/data/match.dart
@@ -1,5 +1,3 @@
-import 'package:flutter/material.dart';
-
class Match {
// Информация о матче
final String home; // Хозяева
@@ -11,15 +9,15 @@ class Match {
Match({
// Базовый конструктов
- @required this.home,
- @required this.away,
- @required this.time,
- @required this.date,
- @required this.score,
- @required this.started,
+ required this.home,
+ required this.away,
+ required this.time,
+ required this.date,
+ required this.score,
+ required this.started,
});
- factory Match.fromJson({Map json}) {
+ factory Match.fromJson({required Map json}) {
// Именованный конструктор, используемый при десериализации
return Match(
home: json['Home'],
diff --git a/team_c_f/lib/data/player.dart b/team_c_f/lib/old/data/player.dart
similarity index 74%
rename from team_c_f/lib/data/player.dart
rename to team_c_f/lib/old/data/player.dart
index fbb3d29..ef885e9 100644
--- a/team_c_f/lib/data/player.dart
+++ b/team_c_f/lib/old/data/player.dart
@@ -1,10 +1,8 @@
-import 'package:flutter/material.dart';
-
class Player {
// Информация об участнике
- String docId; // Идентификатор документа с информацией об участнике
+ late String docId; // Идентификатор документа с информацией об участнике
final String name; // Имя и фамилия участника
- String uid; // Идентификатор Google-аккаунта участника
+ late String uid; // Идентификатор Google-аккаунта участника
bool capitan; // Флаг капитана
bool confirmed; // Флаг подтверждения участия в команде
String team; // Название команды
@@ -13,18 +11,18 @@ class Player {
Player({
// Конструктор
- @required this.name,
- @required String uid,
- @required this.capitan,
- @required this.team,
- @required this.confirmed,
+ required this.name,
+ required String uid,
+ required this.capitan,
+ required this.team,
+ required this.confirmed,
this.points = 0,
this.position = 1,
}) {
this.uid = uid;
}
- factory Player.fromJson({Map json, String docId}) {
+ factory Player.fromJson({required Map json, required String docId}) {
// Именованный конструктор для десериализации
Player p = Player(
name: json['Name'],
diff --git a/team_c_f/lib/data/push.dart b/team_c_f/lib/old/data/push.dart
similarity index 75%
rename from team_c_f/lib/data/push.dart
rename to team_c_f/lib/old/data/push.dart
index 5bec592..fa2dd15 100644
--- a/team_c_f/lib/data/push.dart
+++ b/team_c_f/lib/old/data/push.dart
@@ -1,4 +1,3 @@
-import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class Push {
@@ -6,19 +5,19 @@ class Push {
final String ruTitle;
final String enContent;
final String ruContent;
- final DateTime date;
+ final DateTime? date;
Push({
- @required this.enTitle,
- @required this.ruTitle,
- @required this.enContent,
- @required this.ruContent,
+ required this.enTitle,
+ required this.ruTitle,
+ required this.enContent,
+ required this.ruContent,
this.date,
});
String toJson() {
String lateSend = (date != null)
- ? '"send_after": "${DateFormat('yyyy-MM-dd HH:mm:ss').format(date)}",'
+ ? '"send_after": "${DateFormat('yyyy-MM-dd HH:mm:ss').format(date!)}",'
: '';
return '{"app_id": "93b27d54-e442-4af5-86e4-a215faf20e3a",' +
'"headings" : {"en": "$enTitle", "ru": "$ruTitle"},' +
diff --git a/team_c_f/lib/data/schedule.dart b/team_c_f/lib/old/data/schedule.dart
similarity index 80%
rename from team_c_f/lib/data/schedule.dart
rename to team_c_f/lib/old/data/schedule.dart
index 71df023..ccf09fd 100644
--- a/team_c_f/lib/data/schedule.dart
+++ b/team_c_f/lib/old/data/schedule.dart
@@ -1,11 +1,10 @@
import 'dart:convert';
-import 'package:team_c_f/data/match.dart';
-import 'package:flutter/material.dart';
+import 'package:team_c_f/old/data/match.dart';
import 'package:intl/intl.dart';
class Tour {
// Информация о туре
- String docId; // Идентификатор документа с информацией о туре
+ late String docId; // Идентификатор документа с информацией о туре
final String tour; // Номер тура
final List pair; // Список участников тура
List matches = []; // Список матчей тура
@@ -16,22 +15,22 @@ class Tour {
Tour.basic({
// Именованный конструктор, используемый администраторами для создания расписания
- @required this.tour,
- @required this.pair,
+ required this.tour,
+ required this.pair,
});
Tour({
// Конструктор
- @required this.tour,
- @required this.pair,
- @required this.matches,
- @required this.deadline,
- @required this.ending,
+ required this.tour,
+ required this.pair,
+ required this.matches,
+ required this.deadline,
+ required this.ending,
});
bool get show => _show;
- factory Tour.fromJson({Map json, String docId}) {
+ factory Tour.fromJson({required Map json, required String docId}) {
// Именованный конструктор, используемый для десериализации
Tour t = Tour(
tour: json['Tour'],
diff --git a/team_c_f/lib/data/shortmatch.dart b/team_c_f/lib/old/data/shortmatch.dart
similarity index 81%
rename from team_c_f/lib/data/shortmatch.dart
rename to team_c_f/lib/old/data/shortmatch.dart
index 43e9ce0..f984565 100644
--- a/team_c_f/lib/data/shortmatch.dart
+++ b/team_c_f/lib/old/data/shortmatch.dart
@@ -1,16 +1,16 @@
import 'package:flutter/material.dart';
-import 'package:team_c_f/data/match.dart';
+import 'package:team_c_f/old/data/match.dart';
class ShortMatch extends Match {
// Основаная информация о матче, используется при выборе матчей
String tournament;
bool selected = false;
ShortMatch({
- String home,
- String away,
- String time,
- String date,
- @required this.tournament,
+ required String home,
+ required String away,
+ required String time,
+ required String date,
+ required this.tournament,
}) : super(
home: home,
away: away,
diff --git a/team_c_f/lib/data/team.dart b/team_c_f/lib/old/data/team.dart
similarity index 79%
rename from team_c_f/lib/data/team.dart
rename to team_c_f/lib/old/data/team.dart
index 6259ae1..b5b9b7f 100644
--- a/team_c_f/lib/data/team.dart
+++ b/team_c_f/lib/old/data/team.dart
@@ -1,10 +1,8 @@
import 'dart:convert';
-import 'package:flutter/material.dart';
-
class Team {
// Информация о команде
- String docId; // Идентификатор документа с командой на сервере
+ late String docId; // Идентификатор документа с командой на сервере
final String title; // Название команды
final List members; // Список участников
int points = 0; // Количество очков в чемпионате
@@ -12,13 +10,13 @@ class Team {
Team({
// Конструктор
- @required this.title,
- @required this.members,
+ required this.title,
+ required this.members,
this.points = 0,
this.position = 1,
});
- factory Team.fromJson({Map json, String docId}) {
+ factory Team.fromJson({required Map json, required String docId}) {
// Именованный конструктор, используемый при десериализации
Team t = Team(
title: json['Title'],
diff --git a/team_c_f/lib/data/tournament.dart b/team_c_f/lib/old/data/tournament.dart
similarity index 85%
rename from team_c_f/lib/data/tournament.dart
rename to team_c_f/lib/old/data/tournament.dart
index f7b5937..da5586e 100644
--- a/team_c_f/lib/data/tournament.dart
+++ b/team_c_f/lib/old/data/tournament.dart
@@ -1,26 +1,26 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
-import 'package:team_c_f/data/currenttour.dart';
-import 'package:team_c_f/data/forecast.dart';
-import 'package:team_c_f/data/player.dart';
-import 'package:team_c_f/data/push.dart';
-import 'package:team_c_f/data/schedule.dart';
-import 'package:team_c_f/data/shortmatch.dart';
-import 'package:team_c_f/data/team.dart';
-import 'package:team_c_f/servise/operationdb.dart';
+import 'package:team_c_f/old/data/currenttour.dart';
+import 'package:team_c_f/old/data/forecast.dart';
+import 'package:team_c_f/old/data/player.dart';
+import 'package:team_c_f/old/data/push.dart';
+import 'package:team_c_f/old/data/schedule.dart';
+import 'package:team_c_f/old/data/shortmatch.dart';
+import 'package:team_c_f/old/data/team.dart';
+import 'package:team_c_f/old/servise/operationdb.dart';
import 'package:intl/intl.dart';
import 'package:http/http.dart' as http;
class Tournament with ChangeNotifier {
// Класс хранящий актуальную информацию с сервера
- List allTeams = []; // Все команды
- CurrentTour current; // Информацию о текущем туре
- List schedule = []; // Расписание
- List currentForecasts = []; // Прогнозы на текущий тур
- List allPlayers = []; // Все игроки
- Player me; // Текущий игрок
- Team myTeam; // Моя команда
- String selectTour = ''; // Тур для просмотра
+ late List allTeams = []; // Все команды
+ late CurrentTour current; // Информацию о текущем туре
+ late List schedule = []; // Расписание
+ late List currentForecasts = []; // Прогнозы на текущий тур
+ late List allPlayers = []; // Все игроки
+ late Player me; // Текущий игрок
+ late Team? myTeam; // Моя команда
+ late String selectTour = ''; // Тур для просмотра
// bool leaveForecastForSelectedTour =
// false; // Оставлен ли прогноз на текущий тур
@@ -32,7 +32,7 @@ class Tournament with ChangeNotifier {
current = currentTour;
Stream> streamCurrentForecast =
- DatabaseService().getCurrentForecasts(stage: current.tour);
+ DatabaseService().getCurrentForecasts(stage: current.tour!);
streamCurrentForecast.listen(
(List forecasts) {
currentForecasts = forecasts;
@@ -79,13 +79,12 @@ class Tournament with ChangeNotifier {
curr.sort((a, b) => a.tour[6].compareTo(b.tour[6]));
schedule.addAll([...curr]);
- // schedule.sort((a, b) => a.tour.length.compareTo(b.tour.length));
notifyListeners();
},
);
}
- Future checkForecast({@required String stage}) async {
+ Future checkForecast({required String stage}) async {
return DatabaseService().checkForecast(uid: me.uid, stage: stage);
}
@@ -99,7 +98,7 @@ class Tournament with ChangeNotifier {
: [];
}
- void initMeAndMyTeam({@required String uid}) {
+ void initMeAndMyTeam({required String uid}) {
// Инициализация для более быстрой работы
if (allPlayers.isNotEmpty)
me = allPlayers.where((player) => player.uid == uid).single;
@@ -146,7 +145,7 @@ class Tournament with ChangeNotifier {
notifyListeners();
}
- void confirmPlayer({@required String uid, @required bool confirm}) {
+ void confirmPlayer({required String uid, required bool confirm}) {
// Подтверждение игрока и доабвление его в команду
Player p = allPlayers.where((player) => player.uid == uid).single;
Team t = allTeams.where((team) => team.title == p.team).single;
@@ -156,7 +155,7 @@ class Tournament with ChangeNotifier {
DatabaseService().updatePlayer(player: p);
}
- void removePlayerFromMyTeam({@required String uid}) {
+ void removePlayerFromMyTeam({required String uid}) {
// Удаление игрока из команды и обнуление команды у игрока
Player p = allPlayers.where((player) => player.uid == uid).first;
Team t = allTeams.where((team) => team.title == p.team).first;
@@ -167,7 +166,7 @@ class Tournament with ChangeNotifier {
DatabaseService().updatePlayer(player: p);
}
- void createSchedule({@required List tours}) {
+ void createSchedule({required List tours}) {
//Создание расписания
tours.forEach(
(tour) {
@@ -185,7 +184,7 @@ class Tournament with ChangeNotifier {
notifyListeners();
}
- Future getTour({@required String tour}) async {
+ Future getTour({required String tour}) async {
// Получение информации о туре
Tour t = await DatabaseService().getTour(stage: tour).first;
schedule.setAll(
@@ -193,19 +192,19 @@ class Tournament with ChangeNotifier {
return t;
}
- Future makeForecast({@required Forecast forecast}) {
+ Future makeForecast({required Forecast forecast}) {
return DatabaseService().makeForecast(forecast: forecast).then(
(response) => DatabaseService()
.checkForecast(uid: me.uid, stage: forecast.tour),
);
}
- Future getCurrentForecast({@required String stage}) {
+ Future getCurrentForecast({required String stage}) {
return DatabaseService().getForecast(uid: me.uid, tour: stage);
}
void createMatchesForTour(
- {@required List matches, String stage}) {
+ {required List matches, String? stage}) {
// Добавление матчей для прогнозирования на сервер
Tour t = schedule.where((tour) => tour.tour == stage).single;
matches.sort(
@@ -232,7 +231,7 @@ class Tournament with ChangeNotifier {
String notifyNow = Push(
enTitle: 'New tour',
enContent:
- 'You can leave a forecast for ${!stage.contains(' ') ? '$stage round' : stage}',
+ 'You can leave a forecast for ${!stage!.contains(' ') ? '$stage round' : stage}',
ruTitle: 'Новый тур',
ruContent:
'Можно оставить прогноз на ${!stage.contains(' ') ? '$stage тур' : '$stage'}',
diff --git a/team_c_f/lib/element/createschedule.dart b/team_c_f/lib/old/element/createschedule.dart
similarity index 95%
rename from team_c_f/lib/element/createschedule.dart
rename to team_c_f/lib/old/element/createschedule.dart
index 1e82b56..7a8ff20 100644
--- a/team_c_f/lib/element/createschedule.dart
+++ b/team_c_f/lib/old/element/createschedule.dart
@@ -1,13 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
-import 'package:team_c_f/data/schedule.dart';
-import 'package:team_c_f/data/tournament.dart';
-import 'package:team_c_f/servise/make.dart';
+import 'package:team_c_f/old/data/schedule.dart';
+import 'package:team_c_f/old/data/tournament.dart';
+import 'package:team_c_f/old/servise/make.dart';
class CreateSchedule extends StatefulWidget {
// Класс отображающий виджет для создания основы расписания
- const CreateSchedule({Key key}) : super(key: key);
+ const CreateSchedule({Key? key}) : super(key: key);
@override
_CreateScheduleState createState() => _CreateScheduleState();
diff --git a/team_c_f/lib/element/forecast.dart b/team_c_f/lib/old/element/forecast.dart
similarity index 94%
rename from team_c_f/lib/element/forecast.dart
rename to team_c_f/lib/old/element/forecast.dart
index 75e2bd8..170fa8d 100644
--- a/team_c_f/lib/element/forecast.dart
+++ b/team_c_f/lib/old/element/forecast.dart
@@ -1,14 +1,14 @@
import 'package:flutter/material.dart';
-import 'package:team_c_f/data/match.dart';
-import 'package:team_c_f/page/leaveforecast.dart';
+import 'package:team_c_f/old/data/match.dart';
+import 'package:team_c_f/old/page/leaveforecast.dart';
class ForecastView extends StatefulWidget {
final int index;
final Match match;
ForecastView({
- Key key,
- @required this.match,
- @required this.index,
+ Key? key,
+ required this.match,
+ required this.index,
}) : super(key: key);
@override
@@ -16,8 +16,8 @@ class ForecastView extends StatefulWidget {
}
class _ForecastViewState extends State {
- String home;
- String away;
+ String? home;
+ String? away;
List numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
int get index => widget.index;
@@ -62,7 +62,7 @@ class _ForecastViewState extends State {
setState(
() {
home = result;
- LeaveForecast.rate[index] = home +
+ LeaveForecast.rate[index] = home! +
'-' +
LeaveForecast.rate[index].split('-')[1];
},
@@ -95,7 +95,7 @@ class _ForecastViewState extends State {
LeaveForecast.rate[index] =
LeaveForecast.rate[index].split('-')[0] +
'-' +
- away;
+ away!;
},
);
},
diff --git a/team_c_f/lib/element/match.dart b/team_c_f/lib/old/element/match.dart
similarity index 95%
rename from team_c_f/lib/element/match.dart
rename to team_c_f/lib/old/element/match.dart
index 7f46934..8a04f90 100644
--- a/team_c_f/lib/element/match.dart
+++ b/team_c_f/lib/old/element/match.dart
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
-import 'package:team_c_f/data/match.dart';
+import 'package:team_c_f/old/data/match.dart';
import 'package:intl/intl.dart';
class MatchView extends StatelessWidget {
// Показ одного выбранного матча для прогнозирования
final Match match;
- const MatchView({Key key, this.match}) : super(key: key);
+ const MatchView({Key? key, required this.match}) : super(key: key);
@override
Widget build(BuildContext context) {
diff --git a/team_c_f/lib/element/meet.dart b/team_c_f/lib/old/element/meet.dart
similarity index 86%
rename from team_c_f/lib/element/meet.dart
rename to team_c_f/lib/old/element/meet.dart
index 182a82b..3a429fa 100644
--- a/team_c_f/lib/element/meet.dart
+++ b/team_c_f/lib/old/element/meet.dart
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
class MeetView extends StatelessWidget { // Показ одного выбранного матча для прогнозирования
final String match;
- const MeetView({Key key, this.match}) : super(key: key);
+ const MeetView({Key? key, required this.match}) : super(key: key);
@override
Widget build(BuildContext context) {
diff --git a/team_c_f/lib/element/notconfirmedplayer.dart b/team_c_f/lib/old/element/notconfirmedplayer.dart
similarity index 91%
rename from team_c_f/lib/element/notconfirmedplayer.dart
rename to team_c_f/lib/old/element/notconfirmedplayer.dart
index 36b1d10..958e80a 100644
--- a/team_c_f/lib/element/notconfirmedplayer.dart
+++ b/team_c_f/lib/old/element/notconfirmedplayer.dart
@@ -1,13 +1,13 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
-import 'package:team_c_f/data/player.dart';
-import 'package:team_c_f/data/tournament.dart';
+import 'package:team_c_f/old/data/player.dart';
+import 'package:team_c_f/old/data/tournament.dart';
import 'package:provider/provider.dart';
class PlayerToConfirm extends StatelessWidget {
// Класс, для отображения неподтвержденных игроков
final Player player; // Неподтвержденный игрок
- PlayerToConfirm({Key key, @required this.player}) : super(key: key);
+ PlayerToConfirm({Key? key, required this.player}) : super(key: key);
@override
Widget build(BuildContext context) {
diff --git a/team_c_f/lib/old/element/player.dart b/team_c_f/lib/old/element/player.dart
new file mode 100644
index 0000000..0d491f9
--- /dev/null
+++ b/team_c_f/lib/old/element/player.dart
@@ -0,0 +1,51 @@
+import 'package:flutter/material.dart';
+import 'package:team_c_f/old/data/player.dart';
+import 'package:team_c_f/old/servise/make.dart';
+import 'package:adaptive_dialog/adaptive_dialog.dart';
+import 'package:provider/provider.dart';
+import 'package:team_c_f/old/data/tournament.dart';
+
+class ShowPlayer extends StatelessWidget {
+ // Класс отображающий информацию об указанном игроке
+ final Player player;
+ ShowPlayer({Key? key, required this.player}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ child: InkWell(
+ onLongPress: () async {
+ if (context.read().me.capitan &&
+ (await showAlertDialog(
+ context: context,
+ title: 'Изменение состава',
+ message: 'Удалить ${player.name}',
+ actions: [
+ AlertDialogAction(
+ key: true,
+ label: 'Да, удалить',
+ isDefaultAction: true,
+ ),
+ AlertDialogAction(
+ key: false,
+ label: 'Отмена',
+ isDestructiveAction: true,
+ ),
+ ],
+ ))!) {
+ context.read().removePlayerFromMyTeam(uid: player.uid);
+ }
+ },
+ child: Card(
+ child: ListTile(
+ leading: CircleAvatar(
+ child: Text(player.position.toString()),
+ ),
+ title: Text(player.name),
+ trailing: Text(showPoints(player.points)),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/element/schedule.dart b/team_c_f/lib/old/element/schedule.dart
similarity index 87%
rename from team_c_f/lib/element/schedule.dart
rename to team_c_f/lib/old/element/schedule.dart
index e3e3218..d26d3b6 100644
--- a/team_c_f/lib/element/schedule.dart
+++ b/team_c_f/lib/old/element/schedule.dart
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
-import 'package:team_c_f/data/schedule.dart';
+import 'package:team_c_f/old/data/schedule.dart';
import 'package:provider/provider.dart';
-import 'package:team_c_f/data/tournament.dart';
+import 'package:team_c_f/old/data/tournament.dart';
class TourView extends StatelessWidget { // Элементы, отвечающие за вид туров при их выборе
final Tour tour;
- const TourView({Key key, @required this.tour}) : super(key: key);
+ const TourView({Key? key, required this.tour}) : super(key: key);
@override
Widget build(BuildContext context) {
@@ -19,7 +19,7 @@ class TourView extends StatelessWidget { // Элементы, отвечающи
: tour.tour.length != 12
? tour.tour.substring(4)
: tour.tour.substring(6);
- TextStyle styleTitle = tour.tour.length != 12
+ TextStyle? styleTitle = tour.tour.length != 12
? Theme.of(context).textTheme.headline5
: Theme.of(context).textTheme.headline6;
return Container(
diff --git a/team_c_f/lib/element/selectTeam.dart b/team_c_f/lib/old/element/selectTeam.dart
similarity index 96%
rename from team_c_f/lib/element/selectTeam.dart
rename to team_c_f/lib/old/element/selectTeam.dart
index 498dca2..2a62f78 100644
--- a/team_c_f/lib/element/selectTeam.dart
+++ b/team_c_f/lib/old/element/selectTeam.dart
@@ -1,15 +1,15 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
-import 'package:team_c_f/data/data.dart';
-import 'package:team_c_f/data/tournament.dart';
+import 'package:team_c_f/old/data/data.dart';
+import 'package:team_c_f/old/data/tournament.dart';
import 'package:provider/provider.dart';
-import 'package:team_c_f/servise/operationdb.dart';
+import 'package:team_c_f/old/servise/operationdb.dart';
class SelectTeam extends StatefulWidget {
// Класс отображения выбора команды или регистрации новой
final String message;
- final String name;
- SelectTeam({Key key, @required this.message, this.name}) : super(key: key);
+ final String? name;
+ SelectTeam({Key? key, required this.message, this.name}) : super(key: key);
@override
_SelectTeamState createState() => _SelectTeamState();
@@ -17,7 +17,7 @@ class SelectTeam extends StatefulWidget {
class _SelectTeamState extends State {
TextEditingController teamController = TextEditingController();
- String teamSelect;
+ String? teamSelect;
bool capitan = false;
@override
Widget build(BuildContext context) {
@@ -43,7 +43,7 @@ class _SelectTeamState extends State {
onChanged: (value) {
setState(
() {
- capitan = value;
+ capitan = value!;
},
);
},
diff --git a/team_c_f/lib/element/team.dart b/team_c_f/lib/old/element/team.dart
similarity index 84%
rename from team_c_f/lib/element/team.dart
rename to team_c_f/lib/old/element/team.dart
index 8006eab..27d8305 100644
--- a/team_c_f/lib/element/team.dart
+++ b/team_c_f/lib/old/element/team.dart
@@ -1,14 +1,14 @@
import 'package:flutter/material.dart';
-import 'package:team_c_f/data/team.dart';
-import 'package:team_c_f/data/tournament.dart';
-import 'package:team_c_f/element/player.dart';
+import 'package:team_c_f/old/data/team.dart';
+import 'package:team_c_f/old/data/tournament.dart';
+import 'package:team_c_f/old/element/player.dart';
import 'package:provider/provider.dart';
-import 'package:team_c_f/servise/make.dart';
+import 'package:team_c_f/old/servise/make.dart';
class ShowTeam extends StatelessWidget {
// Класс отображения информации об указанной команде
final Team team; // Команда
- ShowTeam({Key key, @required this.team}) : super(key: key);
+ ShowTeam({Key? key, required this.team}) : super(key: key);
@override
Widget build(BuildContext context) {
diff --git a/team_c_f/lib/element/tour.dart b/team_c_f/lib/old/element/tour.dart
similarity index 79%
rename from team_c_f/lib/element/tour.dart
rename to team_c_f/lib/old/element/tour.dart
index 974236d..a47a06f 100644
--- a/team_c_f/lib/element/tour.dart
+++ b/team_c_f/lib/old/element/tour.dart
@@ -1,25 +1,25 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
-import 'package:team_c_f/data/forecast.dart';
-import 'package:team_c_f/data/schedule.dart';
-import 'package:team_c_f/data/shortmatch.dart';
-import 'package:team_c_f/data/tournament.dart';
-import 'package:team_c_f/element/meet.dart';
-import 'package:team_c_f/element/match.dart';
-import 'package:team_c_f/page/leaveforecast.dart';
-import 'package:team_c_f/page/selectmatch.dart';
+import 'package:team_c_f/old/data/forecast.dart';
+import 'package:team_c_f/old/data/schedule.dart';
+import 'package:team_c_f/old/data/shortmatch.dart';
+import 'package:team_c_f/old/data/tournament.dart';
+import 'package:team_c_f/old/element/meet.dart';
+import 'package:team_c_f/old/element/match.dart';
+import 'package:team_c_f/old/page/leaveforecast.dart';
+import 'package:team_c_f/old/page/selectmatch.dart';
class ShowTour extends StatefulWidget {
// Класс, отображающий результаты выбранного тура тура
- final String tour;
- ShowTour({Key key, this.tour}) : super(key: key);
+ final String? tour;
+ ShowTour({Key? key, this.tour}) : super(key: key);
@override
_ShowTourState createState() => _ShowTourState();
}
class _ShowTourState extends State {
- Tour selectTour;
+ Tour? selectTour;
bool leaveForecast = false;
@override
@@ -28,11 +28,9 @@ class _ShowTourState extends State {
context
.read()
.getTour(
- tour: widget.tour == null
- ? context.read().selectTour == null
- ? '1'
- : context.read().selectTour
- : widget.tour)
+ tour: (widget.tour == null
+ ? context.read().selectTour
+ : widget.tour)!)
.then(
(value) {
setState(
@@ -40,12 +38,12 @@ class _ShowTourState extends State {
selectTour = value;
},
);
- context.read().checkForecast(stage: selectTour.tour).then(
- (response) {
+ context.read().checkForecast(stage: selectTour!.tour).then(
+ (bool response) async {
LeaveForecast.rate = response
- ? context
+ ? (await context
.read()
- .getCurrentForecast(stage: selectTour.tour)
+ .getCurrentForecast(stage: selectTour!.tour)).rate
: ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-'];
setState(() {
leaveForecast = response;
@@ -64,13 +62,13 @@ class _ShowTourState extends State {
Card(
color: Colors.yellow,
child: ListTile(
- leading: Text(selectTour.tour),
+ leading: Text(selectTour!.tour),
title: Text(
- '${selectTour.matches.where((element) => element.started).length}/10 матчей'),
+ '${selectTour!.matches.where((element) => element.started).length}/10 матчей'),
),
),
SizedBox(height: 20),
- selectTour.matches.length == 10
+ selectTour!.matches.length == 10
? Column(
children: [
Wrap(
@@ -79,11 +77,11 @@ class _ShowTourState extends State {
spacing: 10,
runSpacing: 10,
children: [
- ...selectTour.matches
+ ...selectTour!.matches
.map((match) => MatchView(match: match)),
],
),
- if (DateTime.now().isBefore(selectTour.deadline))
+ if (DateTime.now().isBefore(selectTour!.deadline))
Column(
children: [
SizedBox(height: 20),
@@ -94,12 +92,12 @@ class _ShowTourState extends State {
MaterialPageRoute>(
builder: (BuildContext context) {
return LeaveForecast(
- tour: selectTour,
+ tour: selectTour!,
);
},
),
).then(
- (List value) {
+ (List? value) {
//context.read()
//! отправка прогноза
if (value != null) {
@@ -134,7 +132,7 @@ class _ShowTourState extends State {
Navigator.of(context).push(
MaterialPageRoute>(
builder: (BuildContext context) {
- return SelectMatch(stage: selectTour.tour);
+ return SelectMatch(stage: selectTour!.tour);
},
),
).then(
@@ -153,7 +151,7 @@ class _ShowTourState extends State {
spacing: 10,
runSpacing: 10,
children: [
- ...selectTour.pair.map((pair) => MeetView(match: pair)),
+ ...selectTour!.pair.map((pair) => MeetView(match: pair)),
],
),
],
diff --git a/team_c_f/lib/old/oldmain.dart b/team_c_f/lib/old/oldmain.dart
new file mode 100644
index 0000000..3d9939e
--- /dev/null
+++ b/team_c_f/lib/old/oldmain.dart
@@ -0,0 +1,81 @@
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+// import 'package:team_c_f/data/data.dart';
+// import 'package:team_c_f/data/shortmatch.dart';
+// import 'package:team_c_f/data/tournament.dart';
+// import 'package:team_c_f/page/home.dart';
+// import 'package:team_c_f/page/sign.dart';
+import 'package:firebase_core/firebase_core.dart';
+// ignore: import_of_legacy_library_into_null_safe
+import 'package:onesignal_flutter/onesignal_flutter.dart';
+
+Future main() async {
+ myApp();
+}
+
+myApp() async {
+ WidgetsFlutterBinding.ensureInitialized();
+ await Firebase.initializeApp(); // Инициализация Firebase
+
+ OneSignal.shared.setAppId('93b27d54-e442-4af5-86e4-a215faf20e3a');
+
+ runApp(
+ MultiProvider(
+ // Мультипровайдер, для упроощения взаимодействия с данными
+ providers: [
+ // ChangeNotifierProvider(
+ // create: (context) => Account(),
+ // ), // Данные связанные с аутентификацией (гугл-вход и регистрация в приложении)
+ // ChangeNotifierProvider(
+ // create: (context) => Tournament(),
+ // ), // Данные полученные из Firebase
+ // ChangeNotifierProvider(
+ // create: (context) => DataMatch(),
+ // ),
+ ],
+ child: MaterialApp(
+ // theme: ThemeData(
+ // textTheme: TextTheme(
+ // bodyText2: TextStyle(
+ // color: Colors.black,
+ // fontWeight: FontWeight.normal,
+ // ),
+ // bodyText1: TextStyle(
+ // color: Colors.black,
+ // decoration: TextDecoration.lineThrough,
+ // fontWeight: FontWeight.normal,
+ // ),
+ // caption: TextStyle(
+ // color: Colors.green,
+ // fontWeight: FontWeight.w400,
+ // ),
+ // ),
+ // ),
+ home: SafeArea(
+ child: Page(),
+ ),
+ ),
+ ),
+ );
+}
+
+class Page extends StatefulWidget {
+ const Page({Key? key}) : super(key: key);
+
+ @override
+ _PageState createState() => _PageState();
+}
+
+class _PageState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ // child: context
+ // .watch()
+ // .registedInApp // Проверка зарегистрирован ли пользователь в приложении
+ // ? Homepage() // Домашняя страница приложения
+ // : Sign(), // Регистрация в приложении + вход в гугл
+ );
+ }
+}
\ No newline at end of file
diff --git a/team_c_f/lib/page/home.dart b/team_c_f/lib/old/page/home.dart
similarity index 86%
rename from team_c_f/lib/page/home.dart
rename to team_c_f/lib/old/page/home.dart
index f130359..2754ecf 100644
--- a/team_c_f/lib/page/home.dart
+++ b/team_c_f/lib/old/page/home.dart
@@ -1,19 +1,19 @@
import 'package:flutter/material.dart';
-import 'package:team_c_f/data/currenttour.dart';
-import 'package:team_c_f/element/tour.dart';
-import 'package:team_c_f/view/emptyschedule.dart';
-import 'package:team_c_f/view/scorers.dart';
-import 'package:team_c_f/view/table.dart';
-import 'package:team_c_f/view/team.dart';
+import 'package:team_c_f/old/data/currenttour.dart';
+import 'package:team_c_f/old/element/tour.dart';
+import 'package:team_c_f/old/view/emptyschedule.dart';
+import 'package:team_c_f/old/view/scorers.dart';
+import 'package:team_c_f/old/view/table.dart';
+import 'package:team_c_f/old/view/team.dart';
import 'package:custom_navigation_bar/custom_navigation_bar.dart';
import 'package:provider/provider.dart';
-import 'package:team_c_f/data/tournament.dart';
-import 'package:team_c_f/data/data.dart';
+import 'package:team_c_f/old/data/tournament.dart';
+import 'package:team_c_f/old/data/data.dart';
class Homepage extends StatefulWidget {
// Класс отображающий домашнюю страницу с баром снизу
- const Homepage({Key key}) : super(key: key);
+ const Homepage({Key? key}) : super(key: key);
@override
_HomepageState createState() => _HomepageState();
@@ -42,7 +42,7 @@ class _HomepageState extends State {
: ShowTable()
: selectedPage > 0
? selectedPage == 2
- ? ShowTour(tour: current != null ? current.tour : null)
+ ? ShowTour(tour: current.tour)
: ScheduleView()
: TeamView(),
bottomNavigationBar: CustomNavigationBar(
diff --git a/team_c_f/lib/page/leaveforecast.dart b/team_c_f/lib/old/page/leaveforecast.dart
similarity index 88%
rename from team_c_f/lib/page/leaveforecast.dart
rename to team_c_f/lib/old/page/leaveforecast.dart
index 1d64348..cd73740 100644
--- a/team_c_f/lib/page/leaveforecast.dart
+++ b/team_c_f/lib/old/page/leaveforecast.dart
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
-import 'package:team_c_f/data/schedule.dart';
-import 'package:team_c_f/element/forecast.dart';
-import 'package:team_c_f/data/match.dart';
+import 'package:team_c_f/old/data/schedule.dart';
+import 'package:team_c_f/old/element/forecast.dart';
+import 'package:team_c_f/old/data/match.dart';
class LeaveForecast extends StatefulWidget {
final Tour tour;
- const LeaveForecast({Key key, this.tour}) : super(key: key);
+ const LeaveForecast({Key? key, required this.tour}) : super(key: key);
static List rate = ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-'];
diff --git a/team_c_f/lib/page/selectmatch.dart b/team_c_f/lib/old/page/selectmatch.dart
similarity index 63%
rename from team_c_f/lib/page/selectmatch.dart
rename to team_c_f/lib/old/page/selectmatch.dart
index 0bc6239..d51e1ef 100644
--- a/team_c_f/lib/page/selectmatch.dart
+++ b/team_c_f/lib/old/page/selectmatch.dart
@@ -1,16 +1,14 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
-import 'package:team_c_f/data/shortmatch.dart';
-import 'package:team_c_f/servise/htmlparse.dart';
-import 'package:team_c_f/servise/make.dart';
-import 'package:intl/intl.dart';
-import 'package:date_range_picker/date_range_picker.dart' as DateRangePicker;
+import 'package:team_c_f/old/data/shortmatch.dart';
+import 'package:team_c_f/old/servise/htmlparse.dart';
+import 'package:team_c_f/old/servise/make.dart';
import 'package:http/http.dart' as http;
class SelectMatch extends StatefulWidget {
// Отображение выбора 10 матчей на тур
final String stage;
- SelectMatch({Key key, @required this.stage}) : super(key: key);
+ SelectMatch({Key? key, required this.stage}) : super(key: key);
@override
_SelectMatchState createState() => _SelectMatchState();
@@ -27,16 +25,18 @@ class _SelectMatchState extends State {
(date) {
http.Client()
.get(Uri.parse('https://www.sports.ru/football/match/$date/'))
- .then((value) {
- context.read().add(
- [
- ...getMatchs(
- body: value.body,
- date: '$date',
- )
- ],
- );
- });
+ .then(
+ (value) {
+ context.read().add(
+ [
+ ...getMatchs(
+ body: value.body,
+ date: '$date',
+ )
+ ],
+ );
+ },
+ );
},
);
}
@@ -58,24 +58,24 @@ class _SelectMatchState extends State {
ElevatedButton(
onPressed: () {
range.clear();
- DateRangePicker.showDatePicker(
- context: context,
- initialFirstDate: DateTime.now(),
- initialLastDate: DateTime.now(),
- firstDate: DateTime(2021),
- lastDate: DateTime(2040),
- ).then((value) {
- setState(() {
- period = value;
- for (DateTime i = value.first;
- i.isBefore(value.last.add(Duration(minutes: 1)));
- i = i.add(Duration(days: 1))) {
- range.add(DateFormat('yyyy-MM-dd').format(i));
- }
- });
- context.read().data.clear();
- download();
- });
+ // DateRangePicker.showDatePicker(
+ // context: context,
+ // initialFirstDate: DateTime.now(),
+ // initialLastDate: DateTime.now(),
+ // firstDate: DateTime(2021),
+ // lastDate: DateTime(2040),
+ // ).then((value) {
+ // setState(() {
+ // period = value;
+ // for (DateTime i = value.first;
+ // i.isBefore(value.last.add(Duration(minutes: 1)));
+ // i = i.add(Duration(days: 1))) {
+ // range.add(DateFormat('yyyy-MM-dd').format(i));
+ // }
+ // });
+ // context.read().data.clear();
+ // download();
+ // });
},
child: Text('Выбрать даты'),
),
diff --git a/team_c_f/lib/page/sign.dart b/team_c_f/lib/old/page/sign.dart
similarity index 95%
rename from team_c_f/lib/page/sign.dart
rename to team_c_f/lib/old/page/sign.dart
index d3ea08f..1a4b198 100644
--- a/team_c_f/lib/page/sign.dart
+++ b/team_c_f/lib/old/page/sign.dart
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
-import 'package:team_c_f/data/data.dart';
-import 'package:team_c_f/element/selectTeam.dart';
+import 'package:team_c_f/old/data/data.dart';
+import 'package:team_c_f/old/element/selectTeam.dart';
class Sign extends StatefulWidget {
// Класс отображения страницы входа в Google-аккаунт и регистрации в приложении
- Sign({Key key}) : super(key: key);
+ Sign({Key? key}) : super(key: key);
@override
_SignState createState() => _SignState();
diff --git a/team_c_f/lib/servise/auth.dart b/team_c_f/lib/old/servise/auth.dart
similarity index 74%
rename from team_c_f/lib/servise/auth.dart
rename to team_c_f/lib/old/servise/auth.dart
index 09f7b6d..8c6a4cf 100644
--- a/team_c_f/lib/servise/auth.dart
+++ b/team_c_f/lib/old/servise/auth.dart
@@ -4,16 +4,16 @@ import 'package:google_sign_in/google_sign_in.dart';
Future signInWithGoogle() async {
// Выполнение входа в Google-аккаунт
- final GoogleSignInAccount googleUser = await GoogleSignIn().signIn();
+ final GoogleSignInAccount googleUser = (await GoogleSignIn().signIn())!;
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
- final GoogleAuthCredential credential = GoogleAuthProvider.credential(
+ final OAuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
- return (await FirebaseAuth.instance.signInWithCredential(credential)).user;
+ return (await FirebaseAuth.instance.signInWithCredential(credential)).user!;
}
-Future signOutGoogle({BuildContext context}) async {
+Future signOutGoogle({BuildContext? context}) async {
// Выполнение выхода из Google-аккаунта
FirebaseAuth.instance.signOut();
return GoogleSignIn().signOut().then((value) => true);
diff --git a/team_c_f/lib/servise/htmlparse.dart b/team_c_f/lib/old/servise/htmlparse.dart
similarity index 90%
rename from team_c_f/lib/servise/htmlparse.dart
rename to team_c_f/lib/old/servise/htmlparse.dart
index 93ef346..8ae1bed 100644
--- a/team_c_f/lib/servise/htmlparse.dart
+++ b/team_c_f/lib/old/servise/htmlparse.dart
@@ -1,11 +1,10 @@
-import 'package:flutter/material.dart' as material;
import 'package:html/dom.dart';
import 'package:html/parser.dart' show parse;
-import 'package:team_c_f/data/shortmatch.dart';
+import 'package:team_c_f/old/data/shortmatch.dart';
List getMatchs({
- @material.required String body, // Html-текст страницы
- @material.required String date, // Дата
+ required String body, // Html-текст страницы
+ required String date, // Дата
}) {
List m = [];
Map> data = Map>();
diff --git a/team_c_f/lib/servise/make.dart b/team_c_f/lib/old/servise/make.dart
similarity index 86%
rename from team_c_f/lib/servise/make.dart
rename to team_c_f/lib/old/servise/make.dart
index 6af76e2..ace7bfd 100644
--- a/team_c_f/lib/servise/make.dart
+++ b/team_c_f/lib/old/servise/make.dart
@@ -1,10 +1,9 @@
-import 'package:flutter/widgets.dart';
-import 'package:team_c_f/data/shortmatch.dart';
+import 'package:team_c_f/old/data/shortmatch.dart';
import 'package:collection/collection.dart';
-import 'package:team_c_f/view/day.dart';
-import 'package:team_c_f/view/tournament.dart';
+import 'package:team_c_f/old/view/day.dart';
+import 'package:team_c_f/old/view/tournament.dart';
-List makeTournaments({List matches}) {
+List makeTournaments({required List matches}) {
// Функция группировки матчей по соревнованиям
Map> gr = groupBy(
matches, (obj) => obj.tournament); // Группировка матчей по соревнованиям
@@ -70,7 +69,7 @@ String showTeam(int points) {
: 'команд');
}
-String showMatches({@required int teams, @required int circles}) {
+String showMatches({required int teams, required int circles}) {
int matches = (teams * (teams - 1) / 2).round() * circles;
return matches.toString() +
' ' +
@@ -81,7 +80,7 @@ String showMatches({@required int teams, @required int circles}) {
: 'матчей');
}
-String showTours({@required int teams, @required int circles}) {
+String showTours({required int teams, required int circles}) {
int tours = circles * (teams.isEven ? teams - 1 : teams);
return tours.toString() +
' ' +
@@ -93,12 +92,12 @@ String showTours({@required int teams, @required int circles}) {
}
int calculatePointPerMatch({
- @required String result,
- @required String forecast,
+ required String result,
+ required String forecast,
}) {
// Фукнция подсчета очков за матч
- List res = result.split('-').map((e) => int.parse(e));
- List forec = forecast.split('-').map((e) => int.parse(e));
+ List res = result.split('-').map((e) => int.parse(e)).toList();
+ List forec = forecast.split('-').map((e) => int.parse(e)).toList();
return res[0] - res[1] == forec[0] - forec[1]
? res[0] == forec[0] && res[1] == forec[1]
? 3
diff --git a/team_c_f/lib/servise/operationdb.dart b/team_c_f/lib/old/servise/operationdb.dart
similarity index 84%
rename from team_c_f/lib/servise/operationdb.dart
rename to team_c_f/lib/old/servise/operationdb.dart
index 2ae8823..0394929 100644
--- a/team_c_f/lib/servise/operationdb.dart
+++ b/team_c_f/lib/old/servise/operationdb.dart
@@ -1,11 +1,10 @@
import 'package:cloud_firestore/cloud_firestore.dart';
-import 'package:flutter/material.dart';
-import 'package:team_c_f/data/currenttour.dart';
-import 'package:team_c_f/data/forecast.dart';
-import 'package:team_c_f/data/player.dart';
-import 'package:team_c_f/data/schedule.dart';
-import 'package:team_c_f/data/team.dart';
-import 'package:team_c_f/data/match.dart';
+import 'package:team_c_f/old/data/currenttour.dart';
+import 'package:team_c_f/old/data/forecast.dart';
+import 'package:team_c_f/old/data/player.dart';
+import 'package:team_c_f/old/data/schedule.dart';
+import 'package:team_c_f/old/data/team.dart';
+import 'package:team_c_f/old/data/match.dart';
class DatabaseService {
final CollectionReference currentCollection =
@@ -42,7 +41,7 @@ class DatabaseService {
);
}
- Stream> getCurrentForecasts({@required String stage}) {
+ Stream> getCurrentForecasts({required String stage}) {
// Получение всех прогнозов на текущий тур
return forecastsCollection
.where(
@@ -76,7 +75,7 @@ class DatabaseService {
);
}
- Stream getTour({@required String stage}) {
+ Stream getTour({required String stage}) {
// Получение информации о туре stage
return scheduleCollection
.where(
@@ -106,7 +105,7 @@ class DatabaseService {
);
}
- Future userExists({@required String userId}) {
+ Future userExists({required String userId}) {
// Проверка существует ли пользователь с указанным Google-аккаунтом
return playersCollection
.where('UserId', isEqualTo: userId)
@@ -114,21 +113,21 @@ class DatabaseService {
.then((value) => value.docs.length == 1);
}
- Future registrationPlayer({@required Player player}) {
+ Future registrationPlayer({required Player player}) {
// Регистрация игрока
return playersCollection
.add(player.toMap())
.then((response) => player.docId = response.id);
}
- Future registrationTeam({@required Team team}) {
+ Future registrationTeam({required Team team}) {
// Регистрация команды
return teamsCollection
.add(team.toMap())
.then((response) => team.docId = response.id);
}
- Future checkTeamName({@required String name}) {
+ Future checkTeamName({required String name}) {
// Проверка названия команды на уникальность
return teamsCollection
.where('Title', isEqualTo: name)
@@ -136,28 +135,28 @@ class DatabaseService {
.then((response) => response.docs.length == 0);
}
- void updatePlayer({@required Player player}) {
+ void updatePlayer({required Player player}) {
// Обновление информации об игроке
playersCollection.doc(player.docId).update(
player.toMap(),
);
}
- void updateTeam({@required Team team}) {
+ void updateTeam({required Team team}) {
// Обновление информации о команде
teamsCollection.doc(team.docId).update(
team.toMap(),
);
}
- void addTour({@required Tour tour}) {
+ void addTour({required Tour tour}) {
// Добавление тура на сервер
scheduleCollection
.add(tour.toMap())
.then((reaponse) => tour.docId = reaponse.id);
}
- void updateTour({@required Tour tour}) {
+ void updateTour({required Tour tour}) {
// Обновление тура на сервере
scheduleCollection.doc(tour.docId).update(
tour.toMap(),
@@ -172,8 +171,8 @@ class DatabaseService {
//! Выше используется и не требует изменений
Future checkForecast({
- @required String uid,
- @required String stage,
+ required String uid,
+ required String stage,
}) {
return forecastsCollection
.where(
@@ -185,7 +184,7 @@ class DatabaseService {
.then((QuerySnapshot response) => response.docs.length == 1);
}
- Future makeForecast({@required Forecast forecast}) async {
+ Future makeForecast({required Forecast forecast}) async {
// Создание прогноза
return forecastsCollection
.add(forecast.toMap())
@@ -193,8 +192,8 @@ class DatabaseService {
}
Future getForecast({
- @required String uid,
- @required String tour,
+ required String uid,
+ required String tour,
}) async {
// Получение прогноза указанного пользователя на указанный тур
Query query = forecastsCollection
@@ -204,7 +203,7 @@ class DatabaseService {
(QuerySnapshot value) => value.docs
.map(
(DocumentSnapshot doc) => Forecast.fromJson(
- json: doc.data(),
+ json: doc.data()!,
docId: doc.id,
),
)
@@ -212,14 +211,14 @@ class DatabaseService {
);
}
- Future> getForecasts({String tour}) async {
+ Future> getForecasts({required String tour}) async {
// Получение всех прогноз на указанный тур
Query query = forecastsCollection.where('Tour', isEqualTo: tour);
return query.get().then(
(QuerySnapshot value) => value.docs
.map(
(DocumentSnapshot doc) => Forecast.fromJson(
- json: doc.data(),
+ json: doc.data()!,
docId: doc.id,
),
)
@@ -228,7 +227,7 @@ class DatabaseService {
}
//! Использовать для обновления результатов с сервера
- Future> getResults({String tour}) {
+ Future> getResults({required String tour}) {
// Получение результатов матчей
return scheduleCollection
.where(
@@ -245,7 +244,7 @@ class DatabaseService {
}
//! Обновление результатов на сервера
- void updateResults({Tour tour}) {
+ void updateResults({required Tour tour}) {
// Обновление результатов матчей конкретного тура
scheduleCollection.doc(tour.docId).update(
tour.toMap(),
diff --git a/team_c_f/lib/view/day.dart b/team_c_f/lib/old/view/day.dart
similarity index 93%
rename from team_c_f/lib/view/day.dart
rename to team_c_f/lib/old/view/day.dart
index 033ea3b..304e0e0 100644
--- a/team_c_f/lib/view/day.dart
+++ b/team_c_f/lib/old/view/day.dart
@@ -1,15 +1,15 @@
import 'package:flutter/material.dart';
-import 'package:team_c_f/data/shortmatch.dart';
-import 'package:team_c_f/servise/make.dart';
+import 'package:team_c_f/old/data/shortmatch.dart';
+import 'package:team_c_f/old/servise/make.dart';
class DayView extends StatefulWidget {
// Класс, отобращающий все соревнования, в которых есть матчи, в текущий день
final String date; // Дата
final List matches; // Список матчей для отображения
const DayView({
- Key key,
- @required this.date,
- @required this.matches,
+ Key? key,
+ required this.date,
+ required this.matches,
}) : super(key: key);
@override
diff --git a/team_c_f/lib/view/emptyschedule.dart b/team_c_f/lib/old/view/emptyschedule.dart
similarity index 81%
rename from team_c_f/lib/view/emptyschedule.dart
rename to team_c_f/lib/old/view/emptyschedule.dart
index b9b61c8..31361f2 100644
--- a/team_c_f/lib/view/emptyschedule.dart
+++ b/team_c_f/lib/old/view/emptyschedule.dart
@@ -1,13 +1,13 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
-import 'package:team_c_f/data/tournament.dart';
-import 'package:team_c_f/element/createschedule.dart';
-import 'package:team_c_f/element/tour.dart';
-import 'package:team_c_f/view/schedule.dart';
+import 'package:team_c_f/old/data/tournament.dart';
+import 'package:team_c_f/old/element/createschedule.dart';
+import 'package:team_c_f/old/element/tour.dart';
+import 'package:team_c_f/old/view/schedule.dart';
class ScheduleView extends StatefulWidget {
// Если расписание отсутствует
- const ScheduleView({Key key}) : super(key: key);
+ const ScheduleView({Key? key}) : super(key: key);
@override
_ScheduleViewState createState() => _ScheduleViewState();
diff --git a/team_c_f/lib/view/forecast.dart b/team_c_f/lib/old/view/forecast.dart
similarity index 86%
rename from team_c_f/lib/view/forecast.dart
rename to team_c_f/lib/old/view/forecast.dart
index 2d33d45..4f2f69a 100644
--- a/team_c_f/lib/view/forecast.dart
+++ b/team_c_f/lib/old/view/forecast.dart
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
class MakeForecast extends StatelessWidget { // Класс, позволяющий сделать прогноз на следующий тур
- const MakeForecast({Key key}) : super(key: key);
+ const MakeForecast({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
diff --git a/team_c_f/lib/view/match.dart b/team_c_f/lib/old/view/match.dart
similarity index 87%
rename from team_c_f/lib/view/match.dart
rename to team_c_f/lib/old/view/match.dart
index d661277..0d977b5 100644
--- a/team_c_f/lib/view/match.dart
+++ b/team_c_f/lib/old/view/match.dart
@@ -1,13 +1,13 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
-import 'package:team_c_f/data/shortmatch.dart';
+import 'package:team_c_f/old/data/shortmatch.dart';
class MatchView extends StatefulWidget {
// Класс, отображащий информацию о матче, при выборе матчей
final ShortMatch match; // Краткая информация о матче
const MatchView({
- Key key,
- @required this.match,
+ Key? key,
+ required this.match,
}) : super(key: key);
@override
@@ -33,7 +33,7 @@ class _MatchViewState extends State {
value: selected,
title: Text('$time. $home - $away'),
onChanged: (a) {
- context.read().selectMatch(widget.match, a);
+ context.read().selectMatch(widget.match, a!);
},
),
);
diff --git a/team_c_f/lib/view/meet.dart b/team_c_f/lib/old/view/meet.dart
similarity index 100%
rename from team_c_f/lib/view/meet.dart
rename to team_c_f/lib/old/view/meet.dart
diff --git a/team_c_f/lib/view/schedule.dart b/team_c_f/lib/old/view/schedule.dart
similarity index 86%
rename from team_c_f/lib/view/schedule.dart
rename to team_c_f/lib/old/view/schedule.dart
index 221c04e..5f8e8f7 100644
--- a/team_c_f/lib/view/schedule.dart
+++ b/team_c_f/lib/old/view/schedule.dart
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
-import 'package:team_c_f/data/tournament.dart';
-import 'package:team_c_f/element/schedule.dart';
+import 'package:team_c_f/old/data/tournament.dart';
+import 'package:team_c_f/old/element/schedule.dart';
class ShowSchedules extends StatefulWidget {
// Класс, отображающий результаты тура, по умолчанию текущего
- const ShowSchedules({Key key}) : super(key: key);
+ const ShowSchedules({Key? key}) : super(key: key);
@override
_ShowSchedulesState createState() => _ShowSchedulesState();
diff --git a/team_c_f/lib/view/scorers.dart b/team_c_f/lib/old/view/scorers.dart
similarity index 85%
rename from team_c_f/lib/view/scorers.dart
rename to team_c_f/lib/old/view/scorers.dart
index bfd5387..ecbfef8 100644
--- a/team_c_f/lib/view/scorers.dart
+++ b/team_c_f/lib/old/view/scorers.dart
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
class ShowScorers extends StatelessWidget {
// Класс, отображающий список бомбардиров
- const ShowScorers({Key key}) : super(key: key);
+ const ShowScorers({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
diff --git a/team_c_f/lib/view/table.dart b/team_c_f/lib/old/view/table.dart
similarity index 91%
rename from team_c_f/lib/view/table.dart
rename to team_c_f/lib/old/view/table.dart
index 4dbfa6d..1794155 100644
--- a/team_c_f/lib/view/table.dart
+++ b/team_c_f/lib/old/view/table.dart
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
class ShowTable extends StatelessWidget {
// Класс, отображающий туры, с возможностью их выбора для просмотра
- const ShowTable({Key key}) : super(key: key);
+ const ShowTable({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
diff --git a/team_c_f/lib/view/team.dart b/team_c_f/lib/old/view/team.dart
similarity index 88%
rename from team_c_f/lib/view/team.dart
rename to team_c_f/lib/old/view/team.dart
index 6a83cc4..cb5e789 100644
--- a/team_c_f/lib/view/team.dart
+++ b/team_c_f/lib/old/view/team.dart
@@ -1,14 +1,14 @@
import 'package:flutter/material.dart';
-import 'package:team_c_f/data/data.dart';
-import 'package:team_c_f/data/tournament.dart';
+import 'package:team_c_f/old/data/data.dart';
+import 'package:team_c_f/old/data/tournament.dart';
import 'package:provider/provider.dart';
-import 'package:team_c_f/element/notconfirmedplayer.dart';
-import 'package:team_c_f/element/selectTeam.dart';
-import 'package:team_c_f/element/team.dart';
+import 'package:team_c_f/old/element/notconfirmedplayer.dart';
+import 'package:team_c_f/old/element/selectTeam.dart';
+import 'package:team_c_f/old/element/team.dart';
class TeamView extends StatefulWidget {
// Класс, отображающий информацию о команде участника
- const TeamView({Key key}) : super(key: key);
+ const TeamView({Key? key}) : super(key: key);
@override
_TeamViewState createState() => _TeamViewState();
@@ -17,7 +17,7 @@ class TeamView extends StatefulWidget {
class _TeamViewState extends State {
bool capitan = false;
TextEditingController teamController = TextEditingController();
- String teamSelect;
+ String? teamSelect;
@override
Widget build(BuildContext context) {
return Container(
@@ -75,7 +75,7 @@ class _TeamViewState extends State {
.watch()
.allPlayers
.where((player) => (!player.confirmed &&
- player.team == context.read().myTeam.title))
+ player.team == context.read().myTeam!.title))
.map(
(p) => PlayerToConfirm(player: p),
),
@@ -83,8 +83,8 @@ class _TeamViewState extends State {
if (context.read().myTeam != null)
ShowTeam(
// Показ информации о моей команде
- team: context.read().myTeam,
- )
+ team: context.read().myTeam!,
+ ),
],
),
);
diff --git a/team_c_f/lib/view/tournament.dart b/team_c_f/lib/old/view/tournament.dart
similarity index 92%
rename from team_c_f/lib/view/tournament.dart
rename to team_c_f/lib/old/view/tournament.dart
index a5aa59a..0bef1ed 100644
--- a/team_c_f/lib/view/tournament.dart
+++ b/team_c_f/lib/old/view/tournament.dart
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
-import 'package:team_c_f/data/shortmatch.dart';
-import 'package:team_c_f/view/match.dart';
+import 'package:team_c_f/old/data/shortmatch.dart';
+import 'package:team_c_f/old/view/match.dart';
class TournamentView extends StatefulWidget {
// Класс, отображения соревнований, в которых выбираются матчи
@@ -8,9 +8,9 @@ class TournamentView extends StatefulWidget {
final String tournament; // Название соревнования
const TournamentView({
// Конструктор
- Key key,
- @required this.tournament,
- @required this.matches,
+ Key? key,
+ required this.tournament,
+ required this.matches,
}) : super(key: key);
@override
diff --git a/team_c_f/lib/pages/home.dart b/team_c_f/lib/pages/home.dart
new file mode 100644
index 0000000..61ca13c
--- /dev/null
+++ b/team_c_f/lib/pages/home.dart
@@ -0,0 +1,115 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+import 'package:provider/provider.dart';
+import 'package:team_c_f/data/data.dart';
+import 'package:team_c_f/models/meets.dart';
+import 'package:team_c_f/pages/schedule.dart';
+import 'package:team_c_f/pages/team.dart';
+import 'package:team_c_f/pages/tour.dart';
+import 'package:team_c_f/storebloc/blocs/myteam.dart';
+import 'package:team_c_f/storebloc/blocs/schedule.dart';
+import 'package:team_c_f/storebloc/blocs/tour.dart';
+import 'package:team_c_f/storebloc/models/meet.dart';
+import 'package:team_c_f/storebloc/states/myteam.dart';
+import 'package:team_c_f/storebloc/states/schedule.dart';
+import 'package:team_c_f/store/home/home.dart';
+import 'package:team_c_f/store/login/login.dart';
+import 'package:bottom_navy_bar/bottom_navy_bar.dart';
+import 'package:team_c_f/storebloc/states/tour.dart';
+
+class HomePage extends StatelessWidget {
+ static Home state = Home();
+ @override
+ Widget build(BuildContext context) {
+ return SafeArea(
+ child: context.watch().downloadSuccessful
+ ? MultiBlocProvider(
+ providers: [
+ BlocProvider(
+ create: (BuildContext context) => MyTeamBloc(
+ MyTeamState(uid: context.read().userId),
+ ),
+ ),
+ BlocProvider(
+ create: (BuildContext context) => ScheduleBloc(
+ ScheduleState(),
+ ),
+ ),
+ BlocProvider(
+ create: (BuildContext context) => TourBloc(
+ TourState(
+ round: Data.currentTour.round,
+ uid: context.read().userId,
+ ),
+ ),
+ ),
+ ],
+ child: Scaffold(
+ body: Observer(
+ builder: (_) => SingleChildScrollView(
+ child: Column(
+ children: [
+ if (state.selectedIndex == 0)
+ TeamPage()
+ else if (state.selectedIndex == 1)
+ SchedulePage()
+ else if (state.selectedIndex == 2)
+ TourPage(back: false)
+ ],
+ ),
+ ),
+ ),
+ bottomNavigationBar: Observer(
+ builder: (_) => BottomNavyBar(
+ // Бар с вариантами выбора страниц
+ onItemSelected: state.selectIndex,
+ selectedIndex: state.selectedIndex,
+ iconSize: 20.0,
+ items: [
+ BottomNavyBarItem(
+ icon: Icon(Icons.people),
+ title: Text(
+ 'Моя команда',
+ style: Theme.of(context).textTheme.caption,
+ ),
+ ),
+ BottomNavyBarItem(
+ icon: Icon(Icons.calendar_today),
+ title: Text(
+ 'Календарь',
+ style: Theme.of(context).textTheme.caption,
+ ),
+ ),
+ BottomNavyBarItem(
+ icon: Icon(Icons.add_to_photos),
+ title: Text(
+ 'Текущий тур',
+ style: Theme.of(context).textTheme.caption,
+ ),
+ ),
+ BottomNavyBarItem(
+ icon: Icon(Icons.toc),
+ title: Text(
+ 'Таблица',
+ style: Theme.of(context).textTheme.caption,
+ ),
+ ),
+ BottomNavyBarItem(
+ icon: Icon(Icons.list_alt),
+ title: Text(
+ 'Бомбардиры',
+ style: Theme.of(context).textTheme.caption,
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ )
+ : Scaffold(
+ body: Text('DOWNLOADING'),
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/pages/leaveforecast.dart b/team_c_f/lib/pages/leaveforecast.dart
new file mode 100644
index 0000000..bf96ec3
--- /dev/null
+++ b/team_c_f/lib/pages/leaveforecast.dart
@@ -0,0 +1,72 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:team_c_f/components/oneteam.dart';
+import 'package:team_c_f/data/data.dart';
+import 'package:team_c_f/models/tour.dart';
+import 'package:team_c_f/storebloc/blocs/leaveforecast.dart';
+import 'package:team_c_f/storebloc/models/leaveforecast.dart';
+import 'package:team_c_f/storebloc/states/leaveforecast.dart';
+
+class LeaveForecastPage extends StatelessWidget {
+ //final MeetsData meetsData;
+ LeaveForecastPage({
+ Key? key,
+ //required this.meetsData,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return BlocBuilder(
+ bloc: context.watch(),
+ builder: (context, state) => SafeArea(
+ child: Scaffold(
+ appBar: AppBar(
+ title: Text(
+ 'Прогноз на ' +
+ Data.tours
+ .where((TourData t) => t.round == state.round)
+ .single
+ .name! +
+ ((Data.tours
+ .where((TourData t) => t.round == state.round)
+ .single
+ .name!
+ .length) <
+ 3
+ ? ' тур'
+ : ''),
+ ),
+ ),
+ body: Center(
+ child: Column(
+ children: [
+ Expanded(
+ child: ListView(
+ children: [
+ ...state.meets
+ .map(
+ (LeaveForecastModel forecast) => OneTeamView(
+ forecast: forecast,
+ ),
+ )
+ .toList(),
+ ],
+ ),
+ ),
+ ElevatedButton(
+ onPressed: () {
+ Navigator.pop(
+ context,
+ state,
+ );
+ },
+ child: Text('Оставить прогноз'),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/pages/login.dart b/team_c_f/lib/pages/login.dart
new file mode 100644
index 0000000..32184f2
--- /dev/null
+++ b/team_c_f/lib/pages/login.dart
@@ -0,0 +1,13 @@
+import 'package:flutter/material.dart';
+import 'package:team_c_f/components/login.dart';
+
+class LoginPage extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return SafeArea(
+ child: Scaffold(
+ body: LoginView(),
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/pages/schedule.dart b/team_c_f/lib/pages/schedule.dart
new file mode 100644
index 0000000..8c17be5
--- /dev/null
+++ b/team_c_f/lib/pages/schedule.dart
@@ -0,0 +1,45 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:team_c_f/components/createschedule.dart';
+import 'package:team_c_f/pages/tour.dart';
+import 'package:team_c_f/storebloc/blocs/createschedule.dart';
+import 'package:team_c_f/storebloc/blocs/schedule.dart';
+import 'package:team_c_f/storebloc/states/createschedule.dart';
+import 'package:team_c_f/storebloc/states/schedule.dart';
+import 'package:provider/provider.dart';
+import 'package:team_c_f/storebloc/models/tour.dart';
+import 'package:team_c_f/views/touravatar.dart';
+
+class SchedulePage extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ ScheduleBloc bloc = context.watch();
+ return BlocBuilder(
+ bloc: bloc,
+ builder: (context, state) => state.enableSchedule
+ ? state.tourSelected
+ ? TourPage(back: true)
+ : Container(
+ height: MediaQuery.of(context).size.height,
+ width: double.infinity,
+ child: Wrap(
+ alignment: WrapAlignment.spaceAround,
+ runAlignment: WrapAlignment.center,
+ spacing: 20,
+ runSpacing: 20,
+ children: [
+ ...bloc.state.tours.map(
+ (TourModel tour) => ShowTourAvatar(tour: tour),
+ ),
+ ],
+ ),
+ )
+ : BlocProvider(
+ create: (context) => CreateScheduleBloc(
+ CreateScheduleState(),
+ ),
+ child: CreateScheduleView(),
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/pages/selectmeets.dart b/team_c_f/lib/pages/selectmeets.dart
new file mode 100644
index 0000000..7afeba5
--- /dev/null
+++ b/team_c_f/lib/pages/selectmeets.dart
@@ -0,0 +1,217 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:team_c_f/models/choicemeet.dart';
+import 'package:team_c_f/models/meet.dart';
+import 'package:team_c_f/models/meets.dart';
+import 'package:team_c_f/servises/selectmeets.dart';
+import 'package:team_c_f/servises/servises.dart';
+import 'package:team_c_f/storebloc/blocs/selectmeets.dart';
+import 'package:team_c_f/storebloc/blocs/tour.dart' as tourBloc;
+import 'package:team_c_f/storebloc/states/selectmeets.dart';
+import 'package:flutter_date_pickers/flutter_date_pickers.dart';
+import 'package:intl/intl.dart';
+
+class SelectMeetsPage extends StatelessWidget {
+ final int round;
+ const SelectMeetsPage({Key? key, required this.round}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ SelectMeetsBloc bloc = SelectMeetsBloc(SelectMeetsState());
+ return BlocBuilder(
+ bloc: bloc,
+ builder: (context, state) => Container(
+ child: SafeArea(
+ child: Scaffold(
+ body: Center(
+ child: Column(
+ children: [
+ Expanded(
+ child: ListView(
+ children: [
+ RangePicker(
+ selectedPeriod: DatePeriod(
+ bloc.state.dateRange.isNotEmpty
+ ? bloc.state.dateRange.first
+ : DateTime.now().add(
+ Duration(days: 3),
+ ),
+ bloc.state.dateRange.isNotEmpty
+ ? bloc.state.dateRange.last
+ : DateTime.now().add(
+ Duration(days: 4),
+ ),
+ ),
+ firstDate: DateTime.now().add(
+ Duration(days: 2),
+ ),
+ lastDate: DateTime(2099),
+ onChanged: (DatePeriod period) {
+ bloc.add(
+ SelectMeetsEvent(
+ event: Event.changeRange,
+ range: [period.start, period.end],
+ ),
+ );
+ },
+ ),
+ ...bloc.state.allMeets.keys.map((String date) {
+ int countDate = bloc.state.allMeets[date]!.values
+ .map(
+ (list) => list
+ .where((element) => element.selected)
+ .length,
+ )
+ .reduce((value, element) => value + element);
+ return Column(
+ children: [
+ TextButton(
+ onPressed: () {
+ bloc.add(
+ SelectMeetsEvent(
+ event: Event.changeDateState,
+ key: date,
+ ),
+ );
+ },
+ child: Text(
+ date + showSelectIn(countDate),
+ ),
+ ),
+ if (bloc.state.openDate[date]!)
+ ...bloc.state.allMeets[date]!.keys.map(
+ (String tournament) {
+ int countTournament = bloc
+ .state.allMeets[date]![tournament]!
+ .where((element) => element.selected)
+ .length;
+ return Column(
+ children: [
+ TextButton(
+ onPressed: () {
+ bloc.add(
+ SelectMeetsEvent(
+ event:
+ Event.changeTournamentState,
+ key: date + tournament,
+ ),
+ );
+ },
+ child: Text(
+ tournament +
+ showSelectIn(
+ countTournament,
+ ),
+ ),
+ ),
+ if (bloc.state
+ .openTornament[date + tournament]!)
+ ...bloc.state
+ .allMeets[date]![tournament]!
+ .map(
+ (ChoiceMeetData meetData) {
+ return Card(
+ child: CheckboxListTile(
+ value: meetData.selected,
+ onChanged: (bool? a) {
+ bloc.add(
+ SelectMeetsEvent(
+ event: Event.selectMeet,
+ meet: meetData,
+ choice: a,
+ ),
+ );
+ },
+ title: Text(DateFormat(
+ 'HH:mm ')
+ .format(
+ meetData.date) +
+ meetData.team.first +
+ ' - ' +
+ meetData.team.last),
+ ),
+ );
+ },
+ ),
+ ],
+ );
+ },
+ ).toList(),
+ ],
+ );
+ }).toList(),
+ ],
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: TextButton(
+ onPressed: bloc.state.selectedMeets.length == 10
+ ? () {
+ bloc.state.selectedMeets
+ .sort((a, b) => a.date.compareTo(b.date));
+ List team = [];
+ bloc.state.selectedMeets.forEach(
+ (ChoiceMeetData meet) {
+ team.addAll(meet.team);
+ },
+ );
+ SelectMeetsService().cteateMeet(
+ meet: MeetsData(
+ round: round,
+ meets: bloc.state.selectedMeets
+ .map(
+ (ChoiceMeetData choiceMeetData) =>
+ MeetData(
+ date: DateFormat('yyyy-MM-dd HH:mm')
+ .format(choiceMeetData.date),
+ score: [0, 0],
+ started: false,
+ team: [
+ choiceMeetData.team.first,
+ choiceMeetData.team.last
+ ],
+ status: 'Не начат',
+ ),
+ )
+ .toList(),
+ deadline:
+ DateFormat('yyyy-MM-dd HH:mm').format(
+ bloc.state.selectedMeets[0].date.add(
+ Duration(hours: -1),
+ ),
+ ),
+ started: false,
+ ),
+ // MeetsData(
+ // round: round,
+ // team: team,
+ // date: DateFormat('yyyy-MM-dd HH:mm').format(
+ // bloc.state.selectedMeets[0].date.add(
+ // Duration(hours: -1),
+ // ),
+ // ),
+ // score: [],
+ // started: false,
+ // ),
+ );
+ Navigator.pop(
+ context,
+ tourBloc.TourEvent(
+ event: tourBloc.Event.selectMeets,
+ ),
+ );
+ }
+ : null,
+ child: Text('Выбрано ${bloc.state.selectedMeets.length}'),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/pages/team.dart b/team_c_f/lib/pages/team.dart
new file mode 100644
index 0000000..1f2725b
--- /dev/null
+++ b/team_c_f/lib/pages/team.dart
@@ -0,0 +1,93 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:team_c_f/components/unconfirmedplayer.dart';
+import 'package:team_c_f/components/selectteam.dart';
+import 'package:team_c_f/storebloc/blocs/myteam.dart';
+import 'package:team_c_f/storebloc/states/myteam.dart';
+import 'package:team_c_f/store/login/login.dart';
+import 'package:provider/provider.dart';
+import 'package:team_c_f/views/team.dart';
+
+class TeamPage extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ MyTeamBloc bloc = context.watch();
+ context.read().changeName(bloc.state.name);
+ context.read().setDataToSelectTeam(buttonText: 'Выбрать команду');
+ return BlocBuilder(
+ bloc: bloc,
+ builder: (context, state) => Column(
+ children: [
+ Container(
+ padding: const EdgeInsets.all(8.0),
+ margin: const EdgeInsets.all(8.0),
+ child: Column(
+ children: [
+ Card(
+ color: Colors.cyan[300],
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(10),
+ ),
+ child: ListTile(
+ leading: CircleAvatar(
+ // Показывает место в таблице бомбардиров
+ backgroundColor: Colors.blue[100],
+ child: Text(bloc.state.position),
+ ),
+ title: Row(
+ mainAxisSize: MainAxisSize.max,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(bloc.state.name), // Показывает имя участника
+ ],
+ ),
+ subtitle: bloc.state.team != 'Нет команды'
+ ? Row(
+ mainAxisSize: MainAxisSize.max,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Icon(Icons.done,
+ color: bloc.state.confirmed
+ ? Colors.green
+ : Colors.grey),
+ Text(bloc.state.team),
+ ],
+ )
+ : Text(
+ 'Нет команды',
+ textAlign: TextAlign.center,
+ ),
+ trailing: CircleAvatar(
+ backgroundColor: Colors.blue[100],
+ child: IconButton(
+ icon: Icon(Icons.exit_to_app),
+ onPressed: () {
+ context.read().googleLogout();
+ }),
+ ),
+ ),
+ ),
+ if (bloc.state.team == 'Нет команды')
+ SelectTeamView(
+ selectTeam: context.read().selectTeam,
+ updateMyTeam: true,
+ ),
+ ],
+ ),
+ ),
+ if (bloc.state.capitan &&
+ bloc.state.unconfirm
+ .isNotEmpty) // Отображение для капитана списка игроков, которые зарегистрировались, но ещё не получили подтверждение в его команде
+ ...bloc.state.unconfirm.map(
+ (p) => UnconfirmedPlayerView(player: p),
+ ),
+ if (bloc.state.teamData != null)
+ ShowTeam(
+ // Показ информации о моей команде
+ team: bloc.state.teamData!,
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/pages/tour.dart b/team_c_f/lib/pages/tour.dart
new file mode 100644
index 0000000..607481f
--- /dev/null
+++ b/team_c_f/lib/pages/tour.dart
@@ -0,0 +1,219 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:fluttertoast/fluttertoast.dart';
+import 'package:provider/provider.dart';
+import 'package:team_c_f/data/data.dart';
+import 'package:team_c_f/models/forecast.dart';
+import 'package:team_c_f/models/meets.dart';
+import 'package:team_c_f/models/player.dart';
+import 'package:team_c_f/pages/leaveforecast.dart';
+import 'package:team_c_f/pages/selectmeets.dart';
+import 'package:team_c_f/servises/tour.dart';
+import 'package:team_c_f/store/login/login.dart';
+import 'package:team_c_f/storebloc/blocs/leaveforecast.dart' as leave;
+import 'package:team_c_f/storebloc/blocs/schedule.dart' as schedule;
+import 'package:team_c_f/storebloc/blocs/tour.dart';
+import 'package:team_c_f/storebloc/models/leaveforecast.dart';
+import 'package:team_c_f/storebloc/states/leaveforecast.dart';
+import 'package:team_c_f/storebloc/states/tour.dart';
+import 'package:team_c_f/views/meets.dart';
+import 'package:team_c_f/views/tour.dart';
+
+class TourPage extends StatelessWidget {
+ final bool back;
+ const TourPage({Key? key, required this.back}) : super(key: key);
+ @override
+ Widget build(BuildContext context) {
+ TourBloc bloc = back
+ ? context.watch().state.tourBloc!
+ : context.watch();
+ return BlocBuilder(
+ bloc: bloc,
+ builder: (context, state) => SingleChildScrollView(
+ child: Center(
+ child: Column(
+ children: [
+ back
+ ? TextButton(
+ onPressed: () {
+ context.read().add(
+ schedule.ScheduleEvent(
+ event: schedule.Event.unselectTour),
+ );
+ },
+ child: Text(
+ 'Назад',
+ textAlign: TextAlign.center,
+ ),
+ )
+ : Card(
+ color: Colors.yellow[300],
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(20)),
+ child: Container(
+ width: MediaQuery.of(context).size.width - 20,
+ child: Column(
+ children: [
+ TextButton(
+ onPressed: () {
+ bloc.add(
+ TourEvent(event: Event.showListAbsense));
+ },
+ child: Container(
+ width: double.infinity,
+ padding: const EdgeInsets.all(8.0),
+ child: Text(
+ 'Список неявок',
+ textAlign: TextAlign.center,
+ ),
+ ),
+ ),
+ state.size
+ ? Container(
+ child: Column(
+ children: [
+ ...Data.players
+ .where(
+ (player) => player.team != '')
+ .where((player) => Data.names.every(
+ (leave) => leave != player.uid))
+ .map(
+ (player) => Padding(
+ padding:
+ const EdgeInsets.all(8.0),
+ child: Text(player.name),
+ ),
+ ),
+ ],
+ ),
+ )
+ : SizedBox(
+ height: 0,
+ ),
+ ],
+ ),
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Text(
+ 'Матчи ${state.tour.name} ${state.tour.name.length < 3 ? 'тура' : ''}'),
+ ),
+ state.meets.meets.isNotEmpty
+ ? Column(
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: ShowMeets(
+ meetsModel: state.meets,
+ ),
+ ),
+ if (!state.meets.started)
+ TextButton(
+ onPressed: () async {
+ ForecastData? oldForecast;
+ if (Data.names.isNotEmpty)
+ oldForecast = await TourService().getForecast(
+ uid: context.read().userId,
+ round: state.round,
+ );
+ await TourService()
+ .enableTour(round: state.tour.stage)
+ ? Navigator.of(context)
+ .push(
+ MaterialPageRoute(
+ builder: (context) => BlocProvider<
+ leave.LeaveForecastBloc>(
+ create: (_) =>
+ leave.LeaveForecastBloc(
+ LeaveForecastState(
+ meetsData: Data.meets
+ .where((MeetsData m) =>
+ m.round == state.round)
+ .single,
+ forecast: oldForecast,
+ ),
+ ),
+ child: LeaveForecastPage(),
+ ),
+ ),
+ )
+ .then(
+ (LeaveForecastState? result) {
+ if (result != null) {
+ List rate = [];
+ PlayerData me = Data.players
+ .where((PlayerData p) =>
+ p.uid ==
+ context
+ .read()
+ .userId)
+ .single;
+ ForecastData forecast =
+ ForecastData(
+ uid: me.uid,
+ team: me.team,
+ round: result.round,
+ rate: rate,
+ );
+ result.meets.forEach(
+ (LeaveForecastModel model) {
+ rate.addAll(
+ [model.home, model.away]);
+ },
+ );
+ if (oldForecast != null) {
+ forecast.docId =
+ oldForecast.docId;
+ TourService().updateForecast(
+ forecast: forecast,
+ );
+ } else
+ TourService().leaveForecast(
+ forecast: forecast,
+ );
+ bloc.add(
+ TourEvent(
+ event: Event.makeForecast,
+ ),
+ );
+ }
+ },
+ )
+ : Fluttertoast.showToast(
+ msg: 'Приём прогнозов закрыт');
+ },
+ child: Text('Мой прогноз')),
+ ],
+ )
+ : TextButton(
+ onPressed: () {
+ Navigator.of(context)
+ .push(
+ MaterialPageRoute(
+ builder: (context) =>
+ SelectMeetsPage(round: state.round),
+ ),
+ )
+ .then(
+ (TourEvent? event) {
+ if (event != null) bloc.add(event);
+ },
+ );
+ },
+ child: Text('Выбрать матчи'),
+ ),
+ ShowTour(tour: state.tour),
+ ElevatedButton(
+ onPressed: () {
+ bloc.add(TourEvent(event: Event.closeForecasting));
+ },
+ child: Text('Закрыть приём прогнозов'),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/servises/createschedule.dart b/team_c_f/lib/servises/createschedule.dart
new file mode 100644
index 0000000..582e90b
--- /dev/null
+++ b/team_c_f/lib/servises/createschedule.dart
@@ -0,0 +1,28 @@
+import 'package:cloud_firestore/cloud_firestore.dart';
+import 'package:team_c_f/data/data.dart';
+import 'package:team_c_f/models/meets.dart';
+import 'package:team_c_f/models/tour.dart';
+
+class CreateScheduleService {
+ final CollectionReference _scheduleCollection =
+ FirebaseFirestore.instance.collection('schedule');
+ final CollectionReference _meetsCollection =
+ FirebaseFirestore.instance.collection('meets');
+
+ void create() {
+ Data.tours.forEach(
+ (TourData tour) {
+ _scheduleCollection.add(
+ tour.toMap(),
+ );
+ },
+ );
+ Data.meets.forEach(
+ (MeetsData meets) {
+ _meetsCollection.add(
+ meets.toMap(),
+ );
+ },
+ );
+ }
+}
diff --git a/team_c_f/lib/servises/data.dart b/team_c_f/lib/servises/data.dart
new file mode 100644
index 0000000..ef8207a
--- /dev/null
+++ b/team_c_f/lib/servises/data.dart
@@ -0,0 +1,103 @@
+import 'package:cloud_firestore/cloud_firestore.dart';
+import 'package:team_c_f/models/currenttour.dart';
+import 'package:team_c_f/data/data.dart';
+import 'package:team_c_f/models/forecast.dart';
+import 'package:team_c_f/models/meets.dart';
+import 'package:team_c_f/models/player.dart';
+import 'package:team_c_f/models/team.dart';
+import 'package:team_c_f/models/tour.dart';
+
+class DataService {
+ final CollectionReference _playersCollection =
+ FirebaseFirestore.instance.collection('players');
+ final CollectionReference _teamsCollection =
+ FirebaseFirestore.instance.collection('teams');
+ final CollectionReference _currentTourCollection =
+ FirebaseFirestore.instance.collection('currentTour');
+ final CollectionReference _toursCollection =
+ FirebaseFirestore.instance.collection('schedule');
+ final CollectionReference _meetsCollection =
+ FirebaseFirestore.instance.collection('meets');
+ final CollectionReference _forecastsCollection =
+ FirebaseFirestore.instance.collection('forecasts');
+
+ Future initData() async {
+ Data.currentTour = await getCurrentTour();
+ Data.players = await getPlayers();
+ Data.teams = await getTeams();
+ Data.tours = await getTours();
+ Data.meets = await getMeets();
+ Data.names = await getUidLeftForecast();
+ return true;
+ }
+
+ Future> getUidLeftForecast() {
+ int round = Data.currentTour.round;
+ if (Data.meets.where((element) => element.round == round).single.started)
+ round++;
+ return _forecastsCollection.where('Round', isEqualTo: round).get().then(
+ (QuerySnapshot response) => response.docs
+ .map((QueryDocumentSnapshot doc) =>
+ ForecastData.fromMap(data: doc.data(), docId: doc.id).uid)
+ .toList(),
+ );
+ }
+
+ Future getCurrentTour() {
+ return _currentTourCollection.get().then(
+ (QuerySnapshot response) => CurrentTourData.fromMap(
+ data: response.docs.single.data(),
+ docId: response.docs.single.id,
+ ),
+ );
+ }
+
+ Future> getPlayers() {
+ return _playersCollection.get().then(
+ (QuerySnapshot response) => response.docs
+ .map(
+ (QueryDocumentSnapshot doc) => PlayerData.fromMap(
+ data: doc.data(),
+ docId: doc.id,
+ ),
+ )
+ .toList(),
+ );
+ }
+
+ Future> getTeams() {
+ return _teamsCollection.get().then(
+ (QuerySnapshot response) => response.docs
+ .map(
+ (QueryDocumentSnapshot doc) => TeamData.fromMap(
+ data: doc.data(),
+ docId: doc.id,
+ ),
+ )
+ .toList(),
+ );
+ }
+
+ Future> getTours() {
+ return _toursCollection.get().then(
+ (QuerySnapshot response) => response.docs
+ .map(
+ (QueryDocumentSnapshot doc) => TourData.fromMap(
+ data: doc.data(),
+ ),
+ )
+ .toList(),
+ );
+ }
+
+ Future> getMeets() {
+ return _meetsCollection.get().then(
+ (QuerySnapshot response) => response.docs
+ .map(
+ (QueryDocumentSnapshot doc) =>
+ MeetsData.fromMap(data: doc.data(), docId: doc.id),
+ )
+ .toList(),
+ );
+ }
+}
diff --git a/team_c_f/lib/servises/login.dart b/team_c_f/lib/servises/login.dart
new file mode 100644
index 0000000..eb61631
--- /dev/null
+++ b/team_c_f/lib/servises/login.dart
@@ -0,0 +1,27 @@
+import 'package:cloud_firestore/cloud_firestore.dart';
+import 'package:team_c_f/models/info.dart';
+
+class LoginService {
+ final CollectionReference _playersCollection =
+ FirebaseFirestore.instance.collection('players');
+ final CollectionReference _infoCollection =
+ FirebaseFirestore.instance.collection('information');
+
+ Future existPlayer({required String uid}) {
+ return _playersCollection
+ .where(
+ 'UserId',
+ isEqualTo: uid,
+ )
+ .get()
+ .then((QuerySnapshot response) => response.docs.isNotEmpty);
+ }
+
+ Future getInfo() {
+ return _infoCollection.get().then(
+ (QuerySnapshot response) => InfoData.fromMap(
+ data: response.docs.single.data(),
+ ),
+ );
+ }
+}
diff --git a/team_c_f/lib/servises/myteam.dart b/team_c_f/lib/servises/myteam.dart
new file mode 100644
index 0000000..b3bdcb0
--- /dev/null
+++ b/team_c_f/lib/servises/myteam.dart
@@ -0,0 +1,29 @@
+import 'package:cloud_firestore/cloud_firestore.dart';
+import 'package:team_c_f/data/data.dart';
+import 'package:team_c_f/models/player.dart';
+import 'package:team_c_f/models/team.dart';
+
+class MyTeamService {
+ final CollectionReference _playersCollection =
+ FirebaseFirestore.instance.collection('players');
+ final CollectionReference _teamsCollection =
+ FirebaseFirestore.instance.collection('teams');
+
+ void confirmedPlayer(bool confirmed, String uid) {
+ PlayerData player =
+ Data.players.where((PlayerData p) => p.uid == uid).single;
+ TeamData team =
+ Data.teams.where((TeamData t) => t.name == player.team).single;
+ if (confirmed) {
+ team.players.add(uid);
+ _teamsCollection.doc(team.docId).update(team.toMap());
+ } else {
+ player.team = null;
+ _playersCollection.doc(player.docId).update(player.toMap());
+ if (team.players.any((String playerUid) => playerUid == uid)) {
+ team.players.removeWhere((String playerId) => playerId == uid);
+ _teamsCollection.doc(team.docId).update(team.toMap());
+ }
+ }
+ }
+}
diff --git a/team_c_f/lib/servises/schedule.dart b/team_c_f/lib/servises/schedule.dart
new file mode 100644
index 0000000..1c08f76
--- /dev/null
+++ b/team_c_f/lib/servises/schedule.dart
@@ -0,0 +1,2 @@
+class ScheduleService {
+}
diff --git a/team_c_f/lib/servises/selectmeets.dart b/team_c_f/lib/servises/selectmeets.dart
new file mode 100644
index 0000000..cd21159
--- /dev/null
+++ b/team_c_f/lib/servises/selectmeets.dart
@@ -0,0 +1,16 @@
+import 'package:cloud_firestore/cloud_firestore.dart';
+import 'package:team_c_f/data/data.dart';
+import 'package:team_c_f/models/meets.dart';
+
+class SelectMeetsService {
+ final CollectionReference _meetsCollection =
+ FirebaseFirestore.instance.collection('meets');
+
+ void cteateMeet({required MeetsData meet}) {
+ MeetsData current = Data.meets.where((element) => element.round == meet.round).single;
+ meet.docId = current.docId;
+ Data.meets.remove(current);
+ Data.meets.add(meet);
+ _meetsCollection.doc(meet.docId).update(meet.toMap());
+ }
+}
diff --git a/team_c_f/lib/servises/selectteam.dart b/team_c_f/lib/servises/selectteam.dart
new file mode 100644
index 0000000..635c687
--- /dev/null
+++ b/team_c_f/lib/servises/selectteam.dart
@@ -0,0 +1,67 @@
+import 'package:cloud_firestore/cloud_firestore.dart';
+import 'package:team_c_f/models/team.dart';
+import 'package:team_c_f/models/player.dart';
+
+class SelectTeamService {
+ final CollectionReference _playersCollection =
+ FirebaseFirestore.instance.collection('players');
+ final CollectionReference _teamsCollection =
+ FirebaseFirestore.instance.collection('teams');
+
+ Future checkTeamName({required String name}) {
+ // Проверка названия команды на уникальность
+ return _teamsCollection
+ .where('Name', isEqualTo: name)
+ .get()
+ .then((response) => response.docs.length == 0);
+ }
+
+ Future registrateTeam({required TeamData team}) async {
+ // регистрация команды
+ await _teamsCollection.add(team.toMap());
+ }
+
+ Future existPlayer({required String uid}) {
+ return _playersCollection
+ .where(
+ 'UserId',
+ isEqualTo: uid,
+ )
+ .get()
+ .then((QuerySnapshot response) =>
+ response.docs.isNotEmpty ? response.docs.single.id : null);
+ }
+
+ Future?> allTeamNames() {
+ return _teamsCollection.get().then(
+ (QuerySnapshot response) => response.docs
+ .where((QueryDocumentSnapshot doc) =>
+ TeamData.fromMap(
+ data: doc.data(),
+ docId: doc.id,
+ ).players.length <
+ 3)
+ .map(
+ (QueryDocumentSnapshot doc) => TeamData.fromMap(
+ data: doc.data(),
+ docId: doc.id,
+ ).name,
+ )
+ .toList(),
+ );
+ }
+
+ Future registratePlayer({required PlayerData player}) async {
+ // регистрация игрока
+ await _playersCollection.add(player.toMap());
+ return true;
+ }
+
+ Future updatePlayer({required PlayerData player}) async {
+ // обновление игрока (добавление команды)
+ await _playersCollection.doc(player.docId).update(
+ player.toMap(),
+ );
+ return true;
+ }
+}
diff --git a/team_c_f/lib/servises/servises.dart b/team_c_f/lib/servises/servises.dart
new file mode 100644
index 0000000..63ef156
--- /dev/null
+++ b/team_c_f/lib/servises/servises.dart
@@ -0,0 +1,121 @@
+import 'package:team_c_f/data/data.dart';
+import 'package:team_c_f/models/team.dart';
+import 'package:team_c_f/models/tour.dart';
+
+String showSelectIn(int count) {
+ return count > 0
+ ? count == 1
+ ? ' (Выбран 1 матч)'
+ : count < 5
+ ? ' (Выбрано $count матча)'
+ : ' (Выбрано $count матчей)'
+ : '';
+}
+
+String showPoints(int points) {
+ // Функция изменения склонения слова "N очков"
+ return points.toString() +
+ ' ' +
+ ((points % 10 == 1 && points ~/ 10 != 1)
+ ? 'очко'
+ : ((points - 1) % 10 - 4 < 0 && points ~/ 10 != 1)
+ ? 'очка'
+ : 'очков');
+}
+
+String showGoals(int goals) {
+ // Функция изменения склонения слова "N забытых"
+ return goals.toString() +
+ ' ' +
+ ((goals % 10 == 1 && goals ~/ 10 != 1) ? 'забитый' : 'забитых');
+}
+
+String showRegisterTeam(int count) {
+ // Функция изменения склонения слова "Зарегистрировано"
+ return (count % 10 == 1 && count ~/ 10 != 1)
+ ? 'Зарегистрирована'
+ : 'Зарегистрировано';
+}
+
+String showFullTeam(int count) {
+ // Функция изменения склонения выражения "Готово к участию"
+ return (count % 10 == 1 && count ~/ 10 != 1)
+ ? 'Готова к участию'
+ : 'Готово к участию';
+}
+
+String showTeam(int points) {
+ // Функция изменения склонения слова "N команд"
+ return points.toString() +
+ ' ' +
+ ((points % 10 == 1 && points ~/ 10 != 1)
+ ? 'команда'
+ : ((points - 1) % 10 - 4 < 0 && points ~/ 10 != 1)
+ ? 'команды'
+ : 'команд');
+}
+
+String showMatches({required int matches}) {
+ return matches.toString() +
+ ' ' +
+ ((matches % 10 == 1 && matches ~/ 10 != 1)
+ ? 'матч'
+ : ((matches - 1) % 10 - 4 < 0 && matches ~/ 10 != 1)
+ ? 'матча'
+ : 'матчей');
+}
+
+String showTours({required int tours}) {
+ return tours.toString() +
+ ' ' +
+ ((tours % 10 == 1 && tours ~/ 10 != 1)
+ ? 'тур'
+ : ((tours - 1) % 10 - 4 < 0 && tours ~/ 10 != 1)
+ ? 'тура'
+ : 'туров');
+}
+
+List createSchedule(int circles) {
+ List registTeam =
+ Data.teams.where((TeamData team) => team.players.length == 3).toList();
+ List teams = ['1', '2', '3', '4', '5'];
+ // registTeam
+ // .map((TeamData team) => team.name)
+ // .toList(); //['1', '2', '3', '4', '5'];
+ List curr = [];
+ int count = 5; //registTeam.length;
+ int tour = (count.isEven ? count - 1 : count);
+ for (int q = 0; q < circles; q++) {
+ for (int i = 0; i < tour; i++) {
+ List> pair = [];
+ for (int j = 0; j < count ~/ 2; j++) {
+ List match = [];
+ int k = count.isEven ? j : j + 1;
+ int home = i.isOdd
+ ? k == 0
+ ? count - 1
+ : (count ~/ 2 + i ~/ 2 + k + (count.isEven ? 0 : 1)) %
+ (count.isOdd ? count : count - 1)
+ : k + i ~/ 2;
+ int away = i.isOdd
+ ? count ~/ 2 + i ~/ 2 - j
+ : k == 0
+ ? count - 1
+ : (count + i ~/ 2 - 1 - k + (count.isEven ? 0 : 1)) %
+ (count.isOdd ? count : count - 1);
+ if (q.isEven) {
+ match.add(teams[home]);
+ match.add(teams[away]);
+ } else {
+ match.add(teams[away]);
+ match.add(teams[home]);
+ }
+ pair.add(match);
+ }
+ curr.add(
+ TourData.all(round: (i + 1 + q * tour), team: pair),
+ );
+ }
+ }
+ return [...curr];
+}
diff --git a/team_c_f/lib/servises/tour.dart b/team_c_f/lib/servises/tour.dart
new file mode 100644
index 0000000..2158695
--- /dev/null
+++ b/team_c_f/lib/servises/tour.dart
@@ -0,0 +1,53 @@
+import 'package:cloud_firestore/cloud_firestore.dart';
+import 'package:team_c_f/models/forecast.dart';
+import 'package:team_c_f/models/meets.dart';
+
+class TourService {
+ final CollectionReference _forecastsCollection =
+ FirebaseFirestore.instance.collection('forecasts');
+ final CollectionReference _meetsCollection =
+ FirebaseFirestore.instance.collection('meets');
+
+ void leaveForecast({required ForecastData forecast}) {
+ _forecastsCollection.add(forecast.toMap());
+ }
+
+ void updateForecast({required ForecastData forecast}) {
+ _forecastsCollection.doc(forecast.docId).update(forecast.toMap());
+ }
+
+ Future getForecast({required String uid, required int round}) {
+ return _forecastsCollection
+ .where('Round', isEqualTo: round)
+ .where('UserId', isEqualTo: uid)
+ .get()
+ .then(
+ (QuerySnapshot response) => response.docs.length == 1
+ ? ForecastData.fromMap(
+ data: response.docs.single.data(),
+ docId: response.docs.single.id,
+ )
+ : null,
+ );
+ }
+
+ Future enableTour({required int round}) {
+ return _meetsCollection
+ .where('Round', isEqualTo: round)
+ .get()
+ .then((QuerySnapshot response) => !MeetsData.fromMap(
+ data: response.docs.single.data(),
+ docId: response.docs.single.id,
+ ).started);
+ }
+
+ Future closeForecasting({required int round}) async {
+ QueryDocumentSnapshot doc =
+ (await _meetsCollection.where('Round', isEqualTo: round).get())
+ .docs
+ .single;
+ MeetsData meets = MeetsData.fromMap(data: doc.data(), docId: doc.id);
+ meets.started = true;
+ _meetsCollection.doc(doc.id).update(meets.toMap());
+ }
+}
diff --git a/team_c_f/lib/store/home/home.dart b/team_c_f/lib/store/home/home.dart
new file mode 100644
index 0000000..a696e07
--- /dev/null
+++ b/team_c_f/lib/store/home/home.dart
@@ -0,0 +1,14 @@
+import 'package:mobx/mobx.dart';
+part 'home.g.dart';
+
+class Home = _HomeBase with _$Home;
+
+abstract class _HomeBase with Store {
+ @observable
+ int selectedIndex = 1;
+
+ @action
+ void selectIndex(int index){
+ selectedIndex = index;
+ }
+}
\ No newline at end of file
diff --git a/team_c_f/lib/store/home/home.g.dart b/team_c_f/lib/store/home/home.g.dart
new file mode 100644
index 0000000..9958a96
--- /dev/null
+++ b/team_c_f/lib/store/home/home.g.dart
@@ -0,0 +1,46 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'home.dart';
+
+// **************************************************************************
+// StoreGenerator
+// **************************************************************************
+
+// ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic
+
+mixin _$Home on _HomeBase, Store {
+ final _$selectedIndexAtom = Atom(name: '_HomeBase.selectedIndex');
+
+ @override
+ int get selectedIndex {
+ _$selectedIndexAtom.reportRead();
+ return super.selectedIndex;
+ }
+
+ @override
+ set selectedIndex(int value) {
+ _$selectedIndexAtom.reportWrite(value, super.selectedIndex, () {
+ super.selectedIndex = value;
+ });
+ }
+
+ final _$_HomeBaseActionController = ActionController(name: '_HomeBase');
+
+ @override
+ void selectIndex(int index) {
+ final _$actionInfo =
+ _$_HomeBaseActionController.startAction(name: '_HomeBase.selectIndex');
+ try {
+ return super.selectIndex(index);
+ } finally {
+ _$_HomeBaseActionController.endAction(_$actionInfo);
+ }
+ }
+
+ @override
+ String toString() {
+ return '''
+selectedIndex: ${selectedIndex}
+ ''';
+ }
+}
diff --git a/team_c_f/lib/store/login/login.dart b/team_c_f/lib/store/login/login.dart
new file mode 100644
index 0000000..d227d66
--- /dev/null
+++ b/team_c_f/lib/store/login/login.dart
@@ -0,0 +1,124 @@
+import 'package:firebase_auth/firebase_auth.dart';
+import 'package:google_sign_in/google_sign_in.dart';
+import 'package:mobx/mobx.dart';
+import 'package:team_c_f/models/info.dart';
+import 'package:team_c_f/servises/login.dart';
+import 'package:team_c_f/store/selectteam/selectteam.dart';
+
+part 'login.g.dart';
+
+final GoogleSignIn _googleSignIn = GoogleSignIn();
+final FirebaseAuth _auth = FirebaseAuth.instance;
+
+class Login = LoginBase with _$Login;
+
+abstract class LoginBase with Store {
+ LoginBase() {
+ googleLogin();
+ initInfo();
+ }
+ @observable
+ InfoData? info;
+
+ @action
+ void initInfo() {
+ LoginService().getInfo().then((InfoData value) => info = value);
+ }
+
+ String userId = '';
+
+ @observable
+ String userName = '';
+
+ @action
+ void changeName(String text) {
+ userName = text.trim();
+ }
+
+ final selectTeam = SelectTeam();
+
+ @observable
+ bool registrateInApp = false;
+
+ @observable
+ ObservableFuture loginStatus = ObservableFuture.value(false);
+
+ @action
+ void changeLoginStatus(dynamic status) {
+ loginStatus = status;
+ }
+
+ @computed
+ bool get updatedLoginStatus => loginStatus.value!;
+
+ @action
+ Future googleLogin() async {
+ GoogleSignInAccount gUser = await getGoogleUser();
+ GoogleSignInAuthentication googAuth = await gUser.authentication;
+ User? user;
+
+ final AuthCredential credential = GoogleAuthProvider.credential(
+ idToken: googAuth.idToken,
+ accessToken: googAuth.accessToken,
+ );
+ UserCredential userCredential =
+ await _auth.signInWithCredential(credential);
+
+ user = userCredential.user;
+
+ if (user != null) {
+ loginStatus = ObservableFuture.value(true);
+ userId = user.uid;
+ validateInApp();
+ } else {
+ loginStatus = ObservableFuture.value(false);
+ userId = '';
+ registrateInApp = false;
+ }
+ return Future.value(true);
+ }
+
+ @action
+ Future googleLogout() async {
+ _googleSignIn.signOut();
+ _auth.signOut();
+ loginStatus = ObservableFuture.value(false);
+ userId = '';
+ registrateInApp = false;
+ clearData();
+ return await Future.value(true);
+ }
+
+ @action
+ Future validateInApp() async {
+ registrateInApp = await LoginService().existPlayer(uid: userId);
+ }
+
+ Future getGoogleUser() async {
+ GoogleSignInAccount? googleUser = _googleSignIn.currentUser;
+ if (googleUser == null) {
+ googleUser = await _googleSignIn.signInSilently();
+ }
+ if (googleUser == null) {
+ googleUser = await _googleSignIn.signIn();
+ }
+ return googleUser;
+ }
+
+ @action
+ void clearData() {
+ userName = '';
+ selectTeam.lastTeamName = '';
+ selectTeam.teamName = '';
+ selectTeam.uName = '';
+ selectTeam.selectedTeam = null;
+ }
+
+ void setDataToSelectTeam({
+ required String buttonText,
+ }) {
+ selectTeam.uId = userId;
+ selectTeam.uName = userName;
+ selectTeam.regButtonText = buttonText;
+ }
+}
diff --git a/team_c_f/lib/store/login/login.g.dart b/team_c_f/lib/store/login/login.g.dart
new file mode 100644
index 0000000..7a254a6
--- /dev/null
+++ b/team_c_f/lib/store/login/login.g.dart
@@ -0,0 +1,157 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'login.dart';
+
+// **************************************************************************
+// StoreGenerator
+// **************************************************************************
+
+// ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic
+
+mixin _$Login on LoginBase, Store {
+ Computed? _$updatedLoginStatusComputed;
+
+ @override
+ bool get updatedLoginStatus => (_$updatedLoginStatusComputed ??=
+ Computed