From 41cf8f94ba973d06200955b4f3adc5d17b2474a3 Mon Sep 17 00:00:00 2001 From: Mahal <12588690+ShiroUsagi-san@users.noreply.github.com> Date: Sun, 11 Feb 2024 23:28:26 +0100 Subject: [PATCH 01/18] adding models for tournament --- src/models/bracket.ts | 23 +++++++++++++++++++++++ src/models/group.ts | 7 +++++++ src/models/match.ts | 30 ++++++++++++++++++++++++++++++ src/models/swiss.ts | 20 ++++++++++++++++++++ src/models/tournament.ts | 10 +++++++++- 5 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 src/models/bracket.ts create mode 100644 src/models/group.ts create mode 100644 src/models/match.ts create mode 100644 src/models/swiss.ts diff --git a/src/models/bracket.ts b/src/models/bracket.ts new file mode 100644 index 0000000..b6bc2b5 --- /dev/null +++ b/src/models/bracket.ts @@ -0,0 +1,23 @@ + +export enum BracketType { + SINGLE = 'SINGLE', + DOUBLE = 'DOUBLE', +} + +export enum BracketSet { + WINNER = 'WINNER', + LOOSER = 'LOOSER', +} +export interface Bracket { + id: number; + name: string; + tournament: number; + bracket_type: BracketType; + team_count: number; + +} + +export interface KnockoutMatch { + bracket: Bracket; + bracket_set: BracketSet; +} diff --git a/src/models/group.ts b/src/models/group.ts new file mode 100644 index 0000000..5d63f33 --- /dev/null +++ b/src/models/group.ts @@ -0,0 +1,7 @@ +import type { Tournament } from '@/models/tournament' +export interface Group { + id: number; + name: string; + tournament: Tournament; + round_count: number; +} diff --git a/src/models/match.ts b/src/models/match.ts new file mode 100644 index 0000000..10fcc40 --- /dev/null +++ b/src/models/match.ts @@ -0,0 +1,30 @@ +import type { Team } from '@/models/team'; + +export enum MatchStatus { + SCHEDULED = 'SCHEDULED', + ONGOING = 'ONGOING', + COMPLETED = 'COMPLETED', +} + +export enum BestofType { + BO1 = 1, + BO3 = 3, + BO5 = 5, + BO7 = 7, + RANKING = 0, +} + +export interface Match { + teams: Team[]; + round_number: number; + index_in_round: number; + status: MatchStatus; + bo_type: BestofType; + times: number[]; +} + +export interface Score { + team: Team; + match: Match; + score: number; +} diff --git a/src/models/swiss.ts b/src/models/swiss.ts new file mode 100644 index 0000000..c4c4120 --- /dev/null +++ b/src/models/swiss.ts @@ -0,0 +1,20 @@ +import type { Team } from '@/models/team'; +import type { Match } from '@/models/Match'; + +export interface SwissRound { + id: number; + tournament: number; + min_score: number; + teams: Team[]; + matches: Match[]; +} + +export interface SwissSeeding { + swiss: SwissRound; + team: Team; + seeding: number; +} + +export interface SwissMatch { + swiss: SwissRound; +} diff --git a/src/models/tournament.ts b/src/models/tournament.ts index 71001e8..8d0e828 100644 --- a/src/models/tournament.ts +++ b/src/models/tournament.ts @@ -2,7 +2,9 @@ import type { Caster } from '@/models/caster'; import type { EventDeref } from '@/models/event'; import type { Game } from '@/models/game'; import type { Team } from '@/models/team'; - +import type { Group } from '@/models/group'; +import type { SwissRound } from '@/models/swiss'; +import type { Bracket } from '@/models/bracket'; interface BaseTournament { id: number; teams: Team[] | Team['id'][]; @@ -30,8 +32,14 @@ interface BaseTournament { export interface TournamentDeref extends BaseTournament { event: EventDeref; + groups: Group[]; + brackets: Bracket[]; + swissRounds: SwissRound[]; } export interface Tournament extends BaseTournament { event: number; + groups: number[]; + brackets: number[]; + swissRounds: number[]; } From 3070985843080d46424d0608ef5003518d764cd5 Mon Sep 17 00:00:00 2001 From: Mahal <12588690+ShiroUsagi-san@users.noreply.github.com> Date: Tue, 13 Feb 2024 11:08:43 +0100 Subject: [PATCH 02/18] adding frontend for tournament details matches/groups/bracket --- src/models/bracket.ts | 2 +- src/models/group.ts | 3 ++ src/models/match.ts | 1 + src/stores/tournament.store.ts | 2 +- src/views/TournamentDetail.vue | 68 +++++++++++++++++++++++++++++++--- tailwind.config.js | 5 +++ 6 files changed, 74 insertions(+), 7 deletions(-) diff --git a/src/models/bracket.ts b/src/models/bracket.ts index b6bc2b5..73b4665 100644 --- a/src/models/bracket.ts +++ b/src/models/bracket.ts @@ -14,7 +14,7 @@ export interface Bracket { tournament: number; bracket_type: BracketType; team_count: number; - + winner: number; } export interface KnockoutMatch { diff --git a/src/models/group.ts b/src/models/group.ts index 5d63f33..1cd5d85 100644 --- a/src/models/group.ts +++ b/src/models/group.ts @@ -1,7 +1,10 @@ import type { Tournament } from '@/models/tournament' +import type { Team } from '@/models/team'; export interface Group { id: number; name: string; tournament: Tournament; + teams: Team[]; round_count: number; + scores: { [id:string]: number }; } diff --git a/src/models/match.ts b/src/models/match.ts index 10fcc40..f26daf8 100644 --- a/src/models/match.ts +++ b/src/models/match.ts @@ -17,6 +17,7 @@ export enum BestofType { export interface Match { teams: Team[]; round_number: number; + score: Record; index_in_round: number; status: MatchStatus; bo_type: BestofType; diff --git a/src/stores/tournament.store.ts b/src/stores/tournament.store.ts index a736de3..96b5fc4 100755 --- a/src/stores/tournament.store.ts +++ b/src/stores/tournament.store.ts @@ -11,7 +11,7 @@ import { useUserStore } from './user.store'; const { get_csrf } = useUserStore(); const { csrf, inscriptions } = storeToRefs(useUserStore()); -function groupBy(items: T[], key: keyof T): Record { +export function groupBy(items: T[], key: keyof T): Record { return items.reduce((result, item) => ({ ...result, [item[key] as keyof T]: [ diff --git a/src/views/TournamentDetail.vue b/src/views/TournamentDetail.vue index 3a588e4..1fd5de0 100755 --- a/src/views/TournamentDetail.vue +++ b/src/views/TournamentDetail.vue @@ -9,8 +9,10 @@ import TeamCard from '@/components/TeamCard.vue'; import type { Game } from '@/models/game'; import type { Team } from '@/models/team'; import type { Tournament } from '@/models/tournament'; +import type { Bracket } from '@/models/bracket'; +import type { Match } from '@/models/match'; import { useContentStore } from '@/stores/content.store'; -import { useTournamentStore } from '@/stores/tournament.store'; +import { useTournamentStore, groupBy } from '@/stores/tournament.store'; const props = defineProps<{ id: number; @@ -31,7 +33,7 @@ const teams = computed>(() => (tournament.value?.teams as } return ret; }, { validated_teams: [] as Team[], non_validated_teams: [] as Team[] })); - +//const bracket_games = computed>() const open_drop = ref(false); const drop_label = ref('Informations'); const trans = ref('translateX(0vw)'); @@ -44,6 +46,10 @@ const sections = reactive>({ rules: [false, 5], }); +const get_validated_team_by_id = (id: number) => { + return teams.value?.validated_teams.find(team => team.id === id); +}; + const select_tag = (e: Event) => { const target = e.target as HTMLInputElement; open_drop.value = false; @@ -55,8 +61,21 @@ const select_tag = (e: Event) => { sections[target.id][0] = true; }; +const get_col_class = (bracket: Bracket) => { + return `grid-cols-${Math.ceil(Math.log2(bracket.team_count)) + 1}`; +}; + +const is_winning_team = (obj: {[key: number]: number}, team_id: number) => { + return parseInt(Object.keys(obj).reduce((a, b) => obj[a] > obj[b] ? a : b)) == team_id; +} +const get_matchs_per_round = (matchs: Match[]) => { + const reversed_rounds = groupBy(matchs, "round_number"); + return Object.values(reversed_rounds).reverse(); + +}; const router = useRouter(); onMounted(async () => { + try { await getTournamentFull(props.id); } catch (err: unknown) { @@ -301,10 +320,49 @@ onMounted(async () => { -
- -
+
+
+
+ + + + + + + + + + + + + + + + +
{{ group.name }}
EquipeScore
{{ + get_validated_team_by_id(team_id).name }}{{group.scores[team_id]}}
+
+
+
+
+
+

{{ bracket.name}}

+
+
+
+
+
{{ get_validated_team_by_id(team_id).name}}
{{ game.score[team_id] }}
+
+
+
+
+

Vainqueur

+

{{ get_validated_team_by_id(bracket.winner).name }}

+
+
+
+
Les plannings peuvent varier en fonction de l'avancement des tournois et sont donnés à titre indicatif. diff --git a/tailwind.config.js b/tailwind.config.js index 30314c9..3384464 100755 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -4,6 +4,11 @@ export default { './index.html', './src/**/*.{vue,ts,js,jsx,tsx}', ], + safelist: [ + { + pattern: /grid-cols-\d+/, + } + ], theme: { extend: { colors: { From 12787fe8994ad8de04ad48610fd0a86579c6b3a0 Mon Sep 17 00:00:00 2001 From: Mahal <12588690+ShiroUsagi-san@users.noreply.github.com> Date: Wed, 14 Feb 2024 11:24:59 +0100 Subject: [PATCH 03/18] adding brackets and group details --- src/components/GroupTable.vue | 32 ++++++++++++++ src/main.ts | 2 + src/models/group.ts | 4 +- src/stores/tournament.store.ts | 2 - src/views/TournamentDetail.vue | 76 +++++++++++++++++++++++----------- 5 files changed, 89 insertions(+), 27 deletions(-) create mode 100644 src/components/GroupTable.vue diff --git a/src/components/GroupTable.vue b/src/components/GroupTable.vue new file mode 100644 index 0000000..26e2132 --- /dev/null +++ b/src/components/GroupTable.vue @@ -0,0 +1,32 @@ + + \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 3aae3b2..8ba42a2 100755 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,6 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { + faArrowLeft, faArrowsRotate, faBolt, faChevronDown, faChevronUp, faCircle, faCircleCheck, faCirclePlus, faClock, faDownload, faEye, faEyeSlash, @@ -37,6 +38,7 @@ library.add( faMagnifyingGlass, faTrashCan, faBolt, + faArrowLeft, ); axios.defaults.baseURL = import.meta.env.VITE_API_URL; diff --git a/src/models/group.ts b/src/models/group.ts index 1cd5d85..db8b5be 100644 --- a/src/models/group.ts +++ b/src/models/group.ts @@ -1,10 +1,12 @@ import type { Tournament } from '@/models/tournament' import type { Team } from '@/models/team'; +import type { Match } from '@/models/match'; export interface Group { id: number; name: string; tournament: Tournament; - teams: Team[]; + matchs: Match[]; + teams: number; round_count: number; scores: { [id:string]: number }; } diff --git a/src/stores/tournament.store.ts b/src/stores/tournament.store.ts index 96b5fc4..44c6453 100755 --- a/src/stores/tournament.store.ts +++ b/src/stores/tournament.store.ts @@ -123,7 +123,6 @@ export const useTournamentStore = defineStore('tournament', () => { await fetchTournament(id); } } - async function getTournaments(ids: number[]) { const missing: number[] = []; ids.forEach((id) => { @@ -347,7 +346,6 @@ export const useTournamentStore = defineStore('tournament', () => { payRegistration, patch_registration, $reset, - groupBy, get_ticket_pdf, get_unpaid_registration, validate_registration, diff --git a/src/views/TournamentDetail.vue b/src/views/TournamentDetail.vue index 1fd5de0..4938d0b 100755 --- a/src/views/TournamentDetail.vue +++ b/src/views/TournamentDetail.vue @@ -6,14 +6,15 @@ import { import { useRouter } from 'vue-router'; import Content from '@/components/Content.vue'; import TeamCard from '@/components/TeamCard.vue'; +import GroupTable from '@/components/GroupTable.vue'; import type { Game } from '@/models/game'; import type { Team } from '@/models/team'; import type { Tournament } from '@/models/tournament'; import type { Bracket } from '@/models/bracket'; import type { Match } from '@/models/match'; +import type { Group } from '@/models/group'; import { useContentStore } from '@/stores/content.store'; import { useTournamentStore, groupBy } from '@/stores/tournament.store'; - const props = defineProps<{ id: number; section?: { s: string }; @@ -33,10 +34,10 @@ const teams = computed>(() => (tournament.value?.teams as } return ret; }, { validated_teams: [] as Team[], non_validated_teams: [] as Team[] })); -//const bracket_games = computed>() const open_drop = ref(false); const drop_label = ref('Informations'); const trans = ref('translateX(0vw)'); +const show_detail_group = ref(null); const sections = reactive>({ info: [false, 0], teams: [false, 1], @@ -73,6 +74,15 @@ const get_matchs_per_round = (matchs: Match[]) => { return Object.values(reversed_rounds).reverse(); }; +/** +const get_matchs_per_round_reverse = (matchs: Match[]) => { + return groupBy(matchs, "round_number"); + +}; +*/ +const get_group_by_id = (groups: Group[], id: number) => { + return groups.find(group => group.id === id); +}; const router = useRouter(); onMounted(async () => { @@ -320,33 +330,51 @@ onMounted(async () => {
-
-
-
- - - - - - - - - - - - - - - - -
{{ group.name }}
EquipeScore
{{ - get_validated_team_by_id(team_id).name }}{{group.scores[team_id]}}
+
+

+ Les poules ne sont pas disponibles. +

+
+
+
+ +
+ +
+ +
+
+

Round {{ match[0].round_number }}

+
+
+
+
{{ get_validated_team_by_id(game.teams[0]).name }}
+
{{ game.score[game.teams[0]] }}
+
+
+
{{ game.score[game.teams[1]] }}
+
{{ get_validated_team_by_id(game.teams[1]).name }}
+
+
+
+
+
+
+
+
-
+ +

+ Les arbres ne sont pas disponibles. +

+

{{ bracket.name}}

From 563dada8a0fd2c763d4dc2aaf02f841cacaaa240 Mon Sep 17 00:00:00 2001 From: Arthur Branchu-Harel Date: Wed, 14 Feb 2024 18:00:48 +0100 Subject: [PATCH 04/18] fix undefined return value of get_validated_team_by_id --- src/views/TournamentDetail.vue | 122 ++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 54 deletions(-) diff --git a/src/views/TournamentDetail.vue b/src/views/TournamentDetail.vue index 4938d0b..2c022e8 100755 --- a/src/views/TournamentDetail.vue +++ b/src/views/TournamentDetail.vue @@ -5,16 +5,17 @@ import { } from 'vue'; import { useRouter } from 'vue-router'; import Content from '@/components/Content.vue'; -import TeamCard from '@/components/TeamCard.vue'; import GroupTable from '@/components/GroupTable.vue'; +import TeamCard from '@/components/TeamCard.vue'; +import type { Bracket } from '@/models/bracket'; import type { Game } from '@/models/game'; +import type { Group } from '@/models/group'; +import type { Match } from '@/models/match'; import type { Team } from '@/models/team'; import type { Tournament } from '@/models/tournament'; -import type { Bracket } from '@/models/bracket'; -import type { Match } from '@/models/match'; -import type { Group } from '@/models/group'; import { useContentStore } from '@/stores/content.store'; -import { useTournamentStore, groupBy } from '@/stores/tournament.store'; +import { groupBy, useTournamentStore } from '@/stores/tournament.store'; + const props = defineProps<{ id: number; section?: { s: string }; @@ -47,9 +48,7 @@ const sections = reactive>({ rules: [false, 5], }); -const get_validated_team_by_id = (id: number) => { - return teams.value?.validated_teams.find(team => team.id === id); -}; +const get_validated_team_by_id = (id: number) => teams.value?.validated_teams.find((team) => team.id === id); const select_tag = (e: Event) => { const target = e.target as HTMLInputElement; @@ -62,30 +61,22 @@ const select_tag = (e: Event) => { sections[target.id][0] = true; }; -const get_col_class = (bracket: Bracket) => { - return `grid-cols-${Math.ceil(Math.log2(bracket.team_count)) + 1}`; -}; +const get_col_class = (bracket: Bracket) => `grid-cols-${Math.ceil(Math.log2(bracket.team_count)) + 1}`; -const is_winning_team = (obj: {[key: number]: number}, team_id: number) => { - return parseInt(Object.keys(obj).reduce((a, b) => obj[a] > obj[b] ? a : b)) == team_id; -} +const is_winning_team = (obj: { [key: number]: number }, team_id: number) => parseInt(Object.keys(obj).reduce((a, b) => (obj[a] > obj[b] ? a : b))) == team_id; const get_matchs_per_round = (matchs: Match[]) => { - const reversed_rounds = groupBy(matchs, "round_number"); + const reversed_rounds = groupBy(matchs, 'round_number'); return Object.values(reversed_rounds).reverse(); - }; -/** +/** const get_matchs_per_round_reverse = (matchs: Match[]) => { return groupBy(matchs, "round_number"); }; */ -const get_group_by_id = (groups: Group[], id: number) => { - return groups.find(group => group.id === id); -}; +const get_group_by_id = (groups: Group[], id: number) => groups.find((group) => group.id === id); const router = useRouter(); onMounted(async () => { - try { await getTournamentFull(props.id); } catch (err: unknown) { @@ -335,37 +326,50 @@ onMounted(async () => { Les poules ne sont pas disponibles.
-
- +
+
- -
-
From ac6d19643ff81f8b6539e543ae02a63dc3e0ce7d Mon Sep 17 00:00:00 2001 From: Mahal <12588690+ShiroUsagi-san@users.noreply.github.com> Date: Fri, 16 Feb 2024 01:22:01 +0100 Subject: [PATCH 05/18] WIP enter game score --- src/models/match.ts | 29 +++++++++++++++++++++++++---- src/views/TournamentDetail.vue | 2 +- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/models/match.ts b/src/models/match.ts index f26daf8..92b97ef 100644 --- a/src/models/match.ts +++ b/src/models/match.ts @@ -13,19 +13,40 @@ export enum BestofType { BO7 = 7, RANKING = 0, } +export enum MatchTypeEnum { + GROUP = "group", + BRACKET = "bracket", + SWISS = "swiss", +} -export interface Match { - teams: Team[]; +export interface BaseMatch { + id: number; round_number: number; score: Record; index_in_round: number; status: MatchStatus; bo_type: BestofType; - times: number[]; } +export interface MatchType { + id: number, + type: MatchTypeEnum +} + +export interface Match extends BaseMatch { + teams: Team[]; + times: number[]; +} +export interface ScorePatch { + score: {[id: number]: number}; + times: number[]; +} +export interface OngoingMatch extends BaseMatch { + teams: {id: number, name: string}[]; + match_type: MatchType +} export interface Score { team: Team; match: Match; score: number; -} +} \ No newline at end of file diff --git a/src/views/TournamentDetail.vue b/src/views/TournamentDetail.vue index 2c022e8..0c07d0f 100755 --- a/src/views/TournamentDetail.vue +++ b/src/views/TournamentDetail.vue @@ -325,7 +325,7 @@ onMounted(async () => {

Les poules ne sont pas disponibles.

-
+
From 9a807f1c35b5becd337387cc1eead6c02c90b751 Mon Sep 17 00:00:00 2001 From: Arthur Branchu-Harel Date: Thu, 15 Feb 2024 19:32:41 +0100 Subject: [PATCH 06/18] fix bracket display and some other type fixes --- src/models/bracket.ts | 7 +- src/models/game.ts | 1 + src/models/group.ts | 4 +- src/models/match.ts | 2 +- src/models/tournament.ts | 14 ++-- src/views/TournamentDetail.vue | 130 +++++++++++++++++++++++++++------ 6 files changed, 123 insertions(+), 35 deletions(-) diff --git a/src/models/bracket.ts b/src/models/bracket.ts index 73b4665..e28e937 100644 --- a/src/models/bracket.ts +++ b/src/models/bracket.ts @@ -1,3 +1,4 @@ +import type { Match } from '@/models/match'; export enum BracketType { SINGLE = 'SINGLE', @@ -13,11 +14,13 @@ export interface Bracket { name: string; tournament: number; bracket_type: BracketType; - team_count: number; + depth: number; winner: number; + teams: number[]; + matchs: KnockoutMatch[]; } -export interface KnockoutMatch { +export interface KnockoutMatch extends Match { bracket: Bracket; bracket_set: BracketSet; } diff --git a/src/models/game.ts b/src/models/game.ts index c8d9ed0..91d2c12 100644 --- a/src/models/game.ts +++ b/src/models/game.ts @@ -3,4 +3,5 @@ export interface Game { name: string; short_name?: string; players_per_team: number; + team_per_match: number; } diff --git a/src/models/group.ts b/src/models/group.ts index db8b5be..a1e451f 100644 --- a/src/models/group.ts +++ b/src/models/group.ts @@ -1,6 +1,6 @@ -import type { Tournament } from '@/models/tournament' -import type { Team } from '@/models/team'; import type { Match } from '@/models/match'; +import type { Tournament } from '@/models/tournament'; + export interface Group { id: number; name: string; diff --git a/src/models/match.ts b/src/models/match.ts index 92b97ef..a041bce 100644 --- a/src/models/match.ts +++ b/src/models/match.ts @@ -49,4 +49,4 @@ export interface Score { team: Team; match: Match; score: number; -} \ No newline at end of file +} diff --git a/src/models/tournament.ts b/src/models/tournament.ts index 8d0e828..bdc7bea 100644 --- a/src/models/tournament.ts +++ b/src/models/tournament.ts @@ -1,10 +1,11 @@ +import type { Bracket } from '@/models/bracket'; import type { Caster } from '@/models/caster'; import type { EventDeref } from '@/models/event'; import type { Game } from '@/models/game'; -import type { Team } from '@/models/team'; import type { Group } from '@/models/group'; import type { SwissRound } from '@/models/swiss'; -import type { Bracket } from '@/models/bracket'; +import type { Team } from '@/models/team'; + interface BaseTournament { id: number; teams: Team[] | Team['id'][]; @@ -19,7 +20,6 @@ interface BaseTournament { manager_price_online: string; manager_price_onsite: string; cashprizes: number[]; - game: Game | Game['id']; manager_online_product: number; player_online_product: number; substitute_online_product: number; @@ -32,6 +32,7 @@ interface BaseTournament { export interface TournamentDeref extends BaseTournament { event: EventDeref; + game: Game; groups: Group[]; brackets: Bracket[]; swissRounds: SwissRound[]; @@ -39,7 +40,8 @@ export interface TournamentDeref extends BaseTournament { export interface Tournament extends BaseTournament { event: number; - groups: number[]; - brackets: number[]; - swissRounds: number[]; + game: Game; + groups: Group[]; + brackets: Bracket[]; + swissRounds: SwissRound[]; } diff --git a/src/views/TournamentDetail.vue b/src/views/TournamentDetail.vue index 0c07d0f..f86a82d 100755 --- a/src/views/TournamentDetail.vue +++ b/src/views/TournamentDetail.vue @@ -7,10 +7,12 @@ import { useRouter } from 'vue-router'; import Content from '@/components/Content.vue'; import GroupTable from '@/components/GroupTable.vue'; import TeamCard from '@/components/TeamCard.vue'; -import type { Bracket } from '@/models/bracket'; +import { + type Bracket, BracketSet, BracketType, type KnockoutMatch, +} from '@/models/bracket'; import type { Game } from '@/models/game'; import type { Group } from '@/models/group'; -import type { Match } from '@/models/match'; +import { BestofType, type Match } from '@/models/match'; import type { Team } from '@/models/team'; import type { Tournament } from '@/models/tournament'; import { useContentStore } from '@/stores/content.store'; @@ -38,7 +40,7 @@ const teams = computed>(() => (tournament.value?.teams as const open_drop = ref(false); const drop_label = ref('Informations'); const trans = ref('translateX(0vw)'); -const show_detail_group = ref(null); +const show_detail_group = ref(NaN); const sections = reactive>({ info: [false, 0], teams: [false, 1], @@ -61,16 +63,39 @@ const select_tag = (e: Event) => { sections[target.id][0] = true; }; -const get_col_class = (bracket: Bracket) => `grid-cols-${Math.ceil(Math.log2(bracket.team_count)) + 1}`; +const get_bracket_cols_count = (bracket: Bracket) => { + if (bracket.bracket_type === BracketType.SINGLE) { + return bracket.depth + 1; + } + return 2 * (bracket.depth - 1) + 3; +}; +const get_col_class = (bracket: Bracket) => { + const nb_cols = get_bracket_cols_count(bracket); + return `grid-cols-${nb_cols}`; +}; + +const is_winning_team = (match: Match, team_id: number) => { + if (match.bo_type === BestofType.RANKING) { + return match.score[team_id] >= Object.keys(match.score).length; + } + + return match.score[team_id] >= Math.ceil(match.bo_type / 2); +}; -const is_winning_team = (obj: { [key: number]: number }, team_id: number) => parseInt(Object.keys(obj).reduce((a, b) => (obj[a] > obj[b] ? a : b))) == team_id; const get_matchs_per_round = (matchs: Match[]) => { const reversed_rounds = groupBy(matchs, 'round_number'); return Object.values(reversed_rounds).reverse(); }; -/** -const get_matchs_per_round_reverse = (matchs: Match[]) => { - return groupBy(matchs, "round_number"); +const get_winner_matchs_per_round = (matchs: KnockoutMatch[], round: number) => { + const winner_matchs = matchs.filter((match) => match.bracket_set === BracketSet.WINNER); + const round_matchs = groupBy(winner_matchs, 'round_number'); + return round_matchs[round]; +}; +const get_looser_matchs = (matchs: KnockoutMatch[]) => { + const looser_matchs = matchs.filter((match) => match.bracket_set === BracketSet.LOOSER); + const round_matchs = groupBy(looser_matchs, 'round_number'); + return Object.values(round_matchs).reverse(); +}; }; */ @@ -338,13 +363,13 @@ onMounted(async () => { Retour

- {{ get_group_by_id(tournament?.groups, show_detail_group).name }} + {{ get_group_by_id(tournament?.groups, show_detail_group)?.name }}

-
+

Round {{ match[0].round_number }}

@@ -378,33 +403,90 @@ onMounted(async () => {

Les arbres ne sont pas disponibles.

-
+

{{ bracket.name }}

-
-
+
+
-
+
- {{ get_validated_team_by_id(team_id)?.name }} -
- {{ game.score[team_id] }} + {{ get_validated_team_by_id(game.teams[idx - 1])?.name || "TBD" }} +
+
+ {{ game.score[game.teams[idx - 1]] }} +
+
+ 0
-
-

- Vainqueur -

-

- {{ get_validated_team_by_id(bracket.winner)?.name }} -

+
+
+
+
+
+
+
+ {{ get_validated_team_by_id(game.teams[idx - 1])?.name || "TBD" }} +
+
+ {{ game.score[game.teams[idx - 1]] }} +
+
+ 0 +
+
+
+
+
+
+
+
+
+ {{ get_validated_team_by_id(game.teams[idx - 1])?.name || "TBD" }} +
+
+ {{ game.score[game.teams[idx - 1]] }} +
+
+ 0 +
+
+
+
+
+
+

+ Vainqueur +

+

+ {{ get_validated_team_by_id(bracket.winner)?.name }} +

+
+
+
+
+
+
+
+
+ {{ get_validated_team_by_id(game.teams[idx - 1])?.name || "TBD" }} +
+
+ {{ game.score[game.teams[idx - 1]] || "0" }} +
+
+
+
+
+
Les plannings peuvent varier en fonction de l'avancement des tournois et sont donnés à titre indicatif. From c3cf57510a9314b3365f4776618b1747e69e0099 Mon Sep 17 00:00:00 2001 From: Arthur Branchu-Harel Date: Thu, 15 Feb 2024 21:48:46 +0100 Subject: [PATCH 07/18] component for Knockout matchs --- src/components/KnockoutMatchCard.vue | 22 +++++++ src/views/TournamentDetail.vue | 86 +++++++++++++--------------- 2 files changed, 61 insertions(+), 47 deletions(-) create mode 100644 src/components/KnockoutMatchCard.vue diff --git a/src/components/KnockoutMatchCard.vue b/src/components/KnockoutMatchCard.vue new file mode 100644 index 0000000..8025e16 --- /dev/null +++ b/src/components/KnockoutMatchCard.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/views/TournamentDetail.vue b/src/views/TournamentDetail.vue index f86a82d..fb4efdc 100755 --- a/src/views/TournamentDetail.vue +++ b/src/views/TournamentDetail.vue @@ -6,6 +6,7 @@ import { import { useRouter } from 'vue-router'; import Content from '@/components/Content.vue'; import GroupTable from '@/components/GroupTable.vue'; +import KnockoutMatchCard from '@/components/KnockoutMatchCard.vue'; import TeamCard from '@/components/TeamCard.vue'; import { type Bracket, BracketSet, BracketType, type KnockoutMatch, @@ -40,7 +41,7 @@ const teams = computed>(() => (tournament.value?.teams as const open_drop = ref(false); const drop_label = ref('Informations'); const trans = ref('translateX(0vw)'); -const show_detail_group = ref(NaN); +const show_detail_group = ref(0); const sections = reactive>({ info: [false, 0], teams: [false, 1], @@ -97,8 +98,19 @@ const get_looser_matchs = (matchs: KnockoutMatch[]) => { return Object.values(round_matchs).reverse(); }; +const knockout_match_results = (match: KnockoutMatch) => { + const match_results = [] as Record[]; + match.teams.forEach((team) => { + const data = {} as Record; + data.name = get_validated_team_by_id(team)?.name; + data.score = match.score[team]; + data.is_winner = is_winning_team(match, team); + match_results.push(data); + }); + + return match_results; }; -*/ + const get_group_by_id = (groups: Group[], id: number) => groups.find((group) => group.id === id); const router = useRouter(); onMounted(async () => { @@ -359,7 +371,7 @@ onMounted(async () => {
@@ -389,7 +352,7 @@ onMounted(async () => {
- +
@@ -413,9 +376,9 @@ onMounted(async () => {
- +
-
+

Round {{ matchs[0].round_number }}

From 8893af8110405231d3f0e39c65c7cd5b89401f05 Mon Sep 17 00:00:00 2001 From: Mahal <12588690+ShiroUsagi-san@users.noreply.github.com> Date: Fri, 16 Feb 2024 12:04:39 +0100 Subject: [PATCH 10/18] finishing score reporting --- src/stores/user.store.ts | 5 ++-- src/views/Me.vue | 45 +++++++++++++++++++--------------- src/views/TournamentDetail.vue | 13 +++++----- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/stores/user.store.ts b/src/stores/user.store.ts index 8ed037c..1894ea5 100755 --- a/src/stores/user.store.ts +++ b/src/stores/user.store.ts @@ -199,8 +199,7 @@ export const useUserStore = defineStore('user', () => { unpaid[registration.id] = true; } }); - - ongoing_match.value = registrations.data.ongoing_match; + ongoing_match.value = registrations.data.ongoing_match || {} as OngoingMatch; inscriptions.value = { ongoing, past, @@ -282,7 +281,7 @@ export const useUserStore = defineStore('user', () => { // TODO: catch error } } - ongoing_match.value = null; + ongoing_match.value = {} as OngoingMatch; } diff --git a/src/views/Me.vue b/src/views/Me.vue index d530307..4a4b6af 100755 --- a/src/views/Me.vue +++ b/src/views/Me.vue @@ -22,9 +22,7 @@ const { user, role, inscriptions, ongoing_match } = storeToRefs(userStore); const { fetch_user_inscription_full, patch_user, send_score } = userStore; const { patch_registration, payRegistration, get_ticket_pdf } = tournamentStore; -onMounted(async () => { - await fetch_user_inscription_full(); -}); +await fetch_user_inscription_full(); // Register form validation const data_name = reactive({ @@ -54,7 +52,7 @@ const rules_name_in_game = computed(() => ({ name_in_game: { required }, })); const rules_score = computed(() => ({ - times: { required, minValue: minValue(0),} + times: { required }, })) const v$_name_in_game = useVuelidate(rules_name_in_game, data_name_in_game); @@ -79,12 +77,11 @@ const modal_enter_score = ref(false); const modal_enter_times = ref(false); const invalid_score = ref(""); -//Object.keys(ongoing_match?.value.teams).forEach(id => data_score.score[parseInt(id)] = 0); const NextModalEnterScore = () => { if (ongoing_match.value.bo_type != 0) { const score_total = Object.values(data_score.score).reduce((a, b) => a + b, 0); - const winning_score = Math.ceil(ongoing_match.value.bo_type/2) - if (score_total > ongoing_match.value.bo_type || Object.keys(data_score.score).length === 0 || score_total !== winning_score){ + if (score_total > ongoing_match.value.bo_type || + Object.keys(data_score.score).length === 0 ){ invalid_score.value = "Le score que vous avez rentrés n'est pas valide!"; } else { invalid_score.value = ""; @@ -107,6 +104,7 @@ const NextModalEnterScore = () => { const PrevModalEnterScore = () => { modal_enter_times.value = false; modal_enter_score.value = true; + invalid_score.value = ""; } const showModalNameInGame = ref(false); @@ -119,11 +117,12 @@ const game_number = computed(() => { if (ongoing_match.value.bo_type === 0 ){ return 1; } else { - return 3; //teams_score.reduce((a, b) => a + b, 0); + return Object.values(data_score.score).reduce((a, b) => a + b, 0); } }) -const v$_score_game = useVuelidate(rules_score, data_score); +const v$_time_game = useVuelidate(rules_score, data_score, {$autoDirty: true}); + const closeModalNameInGame = () => { showModalNameInGame.value = false; }; @@ -162,8 +161,12 @@ const closeModal = () => { }; const sendScore = async () => { const scores = ({} as ScorePatch); - scores['times'] = data_score.times.filter((time) => time !== null ); - console.log(data_score); + const times = data_score.times.filter((time) => time !== null ) + if (times.length !== game_number.value){ + invalid_score.value = "Les temps ne peuvent pas être nuls"; + return + } + scores['times'] = times; scores['score'] = data_score.score; await send_score(ongoing_match.value, scores); data_score.score = {}; @@ -305,15 +308,15 @@ const openScoreModal = () => { Supprimer son compte
-
+

Partie en cours

-
-
-
- {{team}} +
+
+
+

{{team}}

- +
@@ -737,7 +740,8 @@ const openScoreModal = () => { @@ -752,20 +756,21 @@ const openScoreModal = () => { min="1" /> +

{{ invalid_score }}