@dcrackel/hematournamentui 1.0.98 → 1.0.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{HemaTouranmentUI-lib.es.js → HemaTournamentUI-lib.es.js} +1578 -1474
- package/dist/{HemaTouranmentUI-lib.umd.js → HemaTournamentUI-lib.umd.js} +4 -4
- package/package.json +3 -1
- package/src/assets/portrait1.png +0 -0
- package/src/config/boutScreenConfigurations.js +54 -0
- package/src/mocks/eventRules.js +31 -0
- package/src/mocks/getPoolsWithBouts.js +405 -0
- package/src/mocks/getPoolsWithBoutsByPoolId.js +921 -0
- package/src/mocks/getPoolsWithBoutsClubColors.js +6 -0
- package/src/mocks/getPoolsWithBoutsComplete.js +926 -0
- package/src/stories/Atoms/Icon/BaseIcon.vue +8 -4
- package/src/stories/Atoms/Text/BaseText.vue +8 -2
- package/src/stories/Molecules/Boxes/BoutBoxes/PassesBox/PassesBox.stories.js +60 -0
- package/src/stories/Molecules/Boxes/BoutBoxes/PassesBox/PassesBox.vue +94 -0
- package/src/stories/Molecules/Boxes/BoutBoxes/ScoreBox/ScoreBox.stories.js +113 -0
- package/src/stories/Molecules/Boxes/BoutBoxes/ScoreBox/ScoreBox.vue +110 -0
- package/src/stories/Molecules/Boxes/BoutBoxes/TimerBox/TimerBox.stories.js +39 -0
- package/src/stories/Molecules/Boxes/BoutBoxes/TimerBox/TimerBox.vue +112 -0
- package/src/stories/Molecules/Breadcrumb/Admin/Breadcrumb.test.js +0 -2
- package/src/stories/Molecules/Buttons/BaseButton/BaseButton.vue +6 -8
- package/src/stories/Molecules/Modals/BaseModal/BaseModal.vue +0 -5
- package/src/stories/Molecules/Modals/DirectorModal/DirectorModal.stories.js +52 -0
- package/src/stories/Molecules/Modals/DirectorModal/DirectorModal.vue +64 -0
- package/src/stories/Molecules/Modals/EditBoutModal/EditBoutModal.stories.js +56 -0
- package/src/stories/Molecules/Modals/EditBoutModal/EditBoutModal.vue +57 -0
- package/src/stories/Organisms/Cards/BoutCard/BoutCard.stories.js +81 -0
- package/src/stories/Organisms/Cards/BoutCard/BoutCard.vue +212 -0
- package/src/stories/Organisms/Cards/Director/DirectorCard.stories.js +34 -0
- package/src/stories/Organisms/Cards/Director/DirectorCard.vue +100 -0
- package/src/stories/Organisms/Cards/EditBout/EditBout.stories.js +53 -0
- package/src/stories/Organisms/Cards/EditBout/EditBout.vue +150 -0
- package/src/stories/Organisms/Cards/PoolBoutMatchCard/PoolBoutMatchCard.stories.js +202 -0
- package/src/stories/Organisms/Cards/PoolBoutMatchCard/PoolBoutMatchCard.vue +59 -0
- package/src/stories/Organisms/Cards/PoolFencerCard/PoolFencerCard.vue +30 -20
- package/src/stories/Organisms/ComplexInputs/FindLocation/FindLocation.vue +0 -2
- package/src/stories/Organisms/ComplexInputs/FindOrAddPerson/FindOrAddPerson.vue +0 -5
- package/src/stories/Organisms/Containers/Pool/Pool.vue +25 -5
- package/src/stories/Organisms/Containers/PoolGrid/PoolGrid.stories.js +30 -0
- package/src/stories/Organisms/Containers/PoolGrid/PoolGrid.vue +204 -0
- package/src/stories/Organisms/Headers/PoolSummary/PoolSummary.stories.js +42 -1
- package/src/stories/Organisms/Headers/PoolSummary/PoolSummary.vue +15 -4
- package/src/stories/Organisms/Headers/ToggleHeader/ToggleHeader.stories.js +52 -0
- package/src/stories/Organisms/Headers/{StaffSummary/StaffSummary.vue → ToggleHeader/ToggleHeader.vue} +20 -11
- package/src/stories/Templates/EventManagement/ListEvents/ListEvents.vue +0 -3
- package/src/stories/Templates/EventManagement/PoolLive/PoolLive.stories.js +32 -0
- package/src/stories/Templates/EventManagement/PoolLive/PoolLive.vue +206 -0
- package/src/stories/Templates/EventManagement/PoolManagement/PoolManagement.stories.js +1 -1
- package/src/stories/Templates/EventManagement/PoolManagement/PoolManagement.vue +1 -1
- package/src/stories/Templates/EventManagement/StaffList/StaffList.vue +3 -3
- package/src/stories/Templates/Menus/EditEventsTopMenu/EditEventsTopMenu.vue +0 -5
- package/src/stories/Templates/TournamentManagement/EditTournament/EditPageOne/EditTournamentPageOne.vue +0 -3
- package/tailwind.config.js +46 -3
- package/vite.config.js +9 -8
- package/src/stories/Organisms/Headers/StaffSummary/StaffSummary.stories.js +0 -35
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="pool-grid">
|
|
3
|
+
<table class="table-auto border-separate border-spacing-1">
|
|
4
|
+
<thead>
|
|
5
|
+
<tr>
|
|
6
|
+
<th class="bg-eventBoxBlue rounded-lg px-4 py-2"><BaseText text="Name" size="sm" weight="bold" color="quinary"/></th>
|
|
7
|
+
<th class="w-1"></th>
|
|
8
|
+
<th class="bg-gridBoxHeader rounded-lg px-4 py-2"></th>
|
|
9
|
+
<th v-for="(participant, index) in participants" :key="participant.PersonId"
|
|
10
|
+
class="bg-gridBoxHeader rounded-lg text-center align-middle">
|
|
11
|
+
<BaseText :text="index+1" size="sm" weight="bold" color="quinary"/>
|
|
12
|
+
</th>
|
|
13
|
+
<th class="w-1"></th>
|
|
14
|
+
<th class="bg-eventBoxBlue rounded-lg table-cell text-center align-middle h-10 w-10">
|
|
15
|
+
<BaseText text="W%" size="sm" weight="bold" color="quinary"/>
|
|
16
|
+
</th>
|
|
17
|
+
<th class="bg-eventBoxBlue rounded-lg table-cell text-center align-middle h-10 w-10">
|
|
18
|
+
<BaseText text="W" size="sm" weight="bold" color="quinary"/>
|
|
19
|
+
</th>
|
|
20
|
+
<th class="bg-eventBoxBlue rounded-lg table-cell text-center align-middle h-10 w-10">
|
|
21
|
+
<BaseText text="L" size="sm" weight="bold" color="quinary"/>
|
|
22
|
+
</th>
|
|
23
|
+
<th class="bg-eventBoxBlue rounded-lg table-cell text-center align-middle h-10 w-10">
|
|
24
|
+
<BaseText text="HS" size="sm" weight="bold" color="quinary"/>
|
|
25
|
+
</th>
|
|
26
|
+
<th class="bg-eventBoxBlue rounded-lg table-cell text-center align-middle h-10 w-10">
|
|
27
|
+
<BaseText text="HR" size="sm" weight="bold" color="quinary"/>
|
|
28
|
+
</th>
|
|
29
|
+
<th class="bg-eventBoxBlue rounded-lg able-cell text-center align-middle h-10 w-10">
|
|
30
|
+
<BaseText text="IND" size="sm" weight="bold" color="quinary"/>
|
|
31
|
+
</th>
|
|
32
|
+
</tr>
|
|
33
|
+
</thead>
|
|
34
|
+
<tbody>
|
|
35
|
+
<tr v-for="(participant, index) in participants" :key="participant.PersonId">
|
|
36
|
+
<td class="bg-eventBoxBlue rounded-lg text-right align-middle pr-4">
|
|
37
|
+
<BaseText :text="participant.DisplayName" size="sm" color="quinary"/>
|
|
38
|
+
</td>
|
|
39
|
+
<th class="w-1"></th>
|
|
40
|
+
<td class="bg-gridBoxHeader rounded-lg text-center align-middle h-10 w-10">
|
|
41
|
+
<BaseText :text="index + 1" size="sm" weight="bold" color="quinary"/>
|
|
42
|
+
</td>
|
|
43
|
+
|
|
44
|
+
<td v-for="opponent in participants" :key="opponent.PersonId"
|
|
45
|
+
:class="{'bg-gridBoxHeader rounded-lg ': participant.PersonId === opponent.PersonId, 'bg-eventBoxBlue rounded-lg': participant.PersonId !== opponent.PersonId}"
|
|
46
|
+
class="rounded-lg h-10 w-10">
|
|
47
|
+
<div v-if="participant.PersonId !== opponent.PersonId"
|
|
48
|
+
:class="getBoutClass(participant.PersonId, opponent.PersonId)"
|
|
49
|
+
class="rounded-lg text-center pt-2.5 h-10 w-10">
|
|
50
|
+
<BaseText :text="getScore(participant.PersonId, opponent.PersonId)" size="sm" color="neutral"/>
|
|
51
|
+
</div>
|
|
52
|
+
</td>
|
|
53
|
+
|
|
54
|
+
<td class="w-1"></td>
|
|
55
|
+
<td class="bg-eventBoxBlue rounded-lg table-cell text-center align-middle h-10 w-10">
|
|
56
|
+
<BaseText :text="getStats(participant).WP" size="sm" color="quinary"/>
|
|
57
|
+
</td>
|
|
58
|
+
<td class="bg-eventBoxBlue rounded-lg table-cell text-center align-middle h-10 w-10">
|
|
59
|
+
<BaseText :text="getStats(participant).W" size="sm" color="quinary"/>
|
|
60
|
+
</td>
|
|
61
|
+
<td class="bg-eventBoxBlue rounded-lg table-cell text-center align-middle h-10 w-10">
|
|
62
|
+
<BaseText :text="getStats(participant).L" size="sm" color="quinary"/>
|
|
63
|
+
</td>
|
|
64
|
+
<td class="bg-eventBoxBlue rounded-lg table-cell text-center align-middle h-10 w-10">
|
|
65
|
+
<BaseText :text="getStats(participant).HS" size="sm" color="quinary"/>
|
|
66
|
+
</td>
|
|
67
|
+
<td class="bg-eventBoxBlue rounded-lg table-cell text-center align-middle h-10 w-10">
|
|
68
|
+
<BaseText :text="getStats(participant).HR" size="sm" color="quinary"/>
|
|
69
|
+
</td>
|
|
70
|
+
<td class="bg-eventBoxBlue rounded-lg table-cell text-center align-middle h-10 w-10">
|
|
71
|
+
<BaseText :text="getStats(participant).IND" size="sm" color="quinary"/>
|
|
72
|
+
</td>
|
|
73
|
+
</tr>
|
|
74
|
+
</tbody>
|
|
75
|
+
</table>
|
|
76
|
+
|
|
77
|
+
</div>
|
|
78
|
+
</template>
|
|
79
|
+
|
|
80
|
+
<script>
|
|
81
|
+
import BaseText from "../../../Atoms/Text/BaseText.vue";
|
|
82
|
+
|
|
83
|
+
export default {
|
|
84
|
+
name: 'PoolGrid',
|
|
85
|
+
components: {BaseText},
|
|
86
|
+
props: {
|
|
87
|
+
bouts: {
|
|
88
|
+
type: Array,
|
|
89
|
+
required: true,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
data() {
|
|
93
|
+
return {};
|
|
94
|
+
},
|
|
95
|
+
computed: {
|
|
96
|
+
participants() {
|
|
97
|
+
const participantMap = {};
|
|
98
|
+
this.bouts.forEach((bout) => {
|
|
99
|
+
participantMap[bout.Person1Id] = bout.Person1;
|
|
100
|
+
participantMap[bout.Person2Id] = bout.Person2;
|
|
101
|
+
});
|
|
102
|
+
return Object.values(participantMap);
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
methods: {
|
|
106
|
+
getScore(rowPersonId, colPersonId) {
|
|
107
|
+
const bout = this.bouts.find(
|
|
108
|
+
(bout) =>
|
|
109
|
+
(bout.Person1Id === rowPersonId && bout.Person2Id === colPersonId) ||
|
|
110
|
+
(bout.Person1Id === colPersonId && bout.Person2Id === rowPersonId)
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
if (bout) {
|
|
114
|
+
if (bout.Status === 'Scheduled') return '';
|
|
115
|
+
|
|
116
|
+
const score1 = bout.Score1;
|
|
117
|
+
const score2 = bout.Score2;
|
|
118
|
+
|
|
119
|
+
if (bout.Status === 'Completed') {
|
|
120
|
+
if (score1 > score2) {
|
|
121
|
+
return bout.Person1Id === rowPersonId
|
|
122
|
+
? `W${score1}`
|
|
123
|
+
: `L${score2}`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (score2 > score1) {
|
|
127
|
+
return bout.Person1Id === rowPersonId
|
|
128
|
+
? `L${score1}`
|
|
129
|
+
: `W${score2}`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return `T${score1}`;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return bout.Person1Id === rowPersonId ? score1 : score2;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return '';
|
|
139
|
+
},
|
|
140
|
+
getBoutClass(person1Id, person2Id) {
|
|
141
|
+
const bout = this.bouts.find((bout) => (bout.Person1Id === person1Id && bout.Person2Id === person2Id) || (bout.Person1Id === person2Id && bout.Person2Id === person1Id));
|
|
142
|
+
|
|
143
|
+
if (bout) {
|
|
144
|
+
if (bout.Status === 'Completed') {
|
|
145
|
+
if (bout.Score1 > bout.Score2) {
|
|
146
|
+
return person1Id === bout.Person1Id ? 'bg-green' : 'bg-red';
|
|
147
|
+
}
|
|
148
|
+
if (bout.Score2 > bout.Score1) {
|
|
149
|
+
return person2Id === bout.Person2Id ? 'bg-red' : 'bg-green';
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (bout.Status === 'Active') {
|
|
154
|
+
return 'bg-blue';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return '';
|
|
158
|
+
},
|
|
159
|
+
getStats(participant) {
|
|
160
|
+
const completedBouts = this.bouts.filter((bout) =>
|
|
161
|
+
(bout.Person1Id === participant.PersonId || bout.Person2Id === participant.PersonId) &&
|
|
162
|
+
bout.Status === 'Completed');
|
|
163
|
+
|
|
164
|
+
const wins = completedBouts.filter((bout) =>
|
|
165
|
+
(bout.Person1Id === participant.PersonId && bout.Score1 > bout.Score2) ||
|
|
166
|
+
(bout.Person2Id === participant.PersonId && bout.Score2 > bout.Score1)).length;
|
|
167
|
+
|
|
168
|
+
const losses = completedBouts.filter((bout) =>
|
|
169
|
+
(bout.Person1Id === participant.PersonId && bout.Score1 < bout.Score2) ||
|
|
170
|
+
(bout.Person2Id === participant.PersonId && bout.Score2 < bout.Score1)).length;
|
|
171
|
+
|
|
172
|
+
const totalHitsScored = completedBouts.reduce((sum, bout) => sum + (bout.Person1Id === participant.PersonId ? bout.Score1 : bout.Score2), 0);
|
|
173
|
+
const totalHitsReceived = completedBouts.reduce((sum, bout) => sum + (bout.Person1Id === participant.PersonId ? bout.Score2 : bout.Score1), 0);
|
|
174
|
+
|
|
175
|
+
const indicator = totalHitsScored - totalHitsReceived;
|
|
176
|
+
const winPercent = completedBouts.length > 0 ? ((wins / completedBouts.length) * 100).toFixed(0) : '0.00';
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
WP: `${winPercent}%`,
|
|
180
|
+
HS: totalHitsScored,
|
|
181
|
+
HR: totalHitsReceived,
|
|
182
|
+
IND: indicator,
|
|
183
|
+
W: wins,
|
|
184
|
+
L: losses,
|
|
185
|
+
};
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
</script>
|
|
190
|
+
|
|
191
|
+
<style scoped>
|
|
192
|
+
.pool-grid {
|
|
193
|
+
margin: 20px;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.table-auto {
|
|
197
|
+
width: 100%;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.stats-panel {
|
|
201
|
+
border: 1px solid #ccc;
|
|
202
|
+
border-radius: 5px;
|
|
203
|
+
}
|
|
204
|
+
</style>
|
|
@@ -23,6 +23,47 @@ export const Default = {
|
|
|
23
23
|
Present: "0",
|
|
24
24
|
Absent: "20",
|
|
25
25
|
Removed: "1",
|
|
26
|
-
}
|
|
26
|
+
},
|
|
27
|
+
mode: 'planning'
|
|
27
28
|
}
|
|
28
29
|
}
|
|
30
|
+
|
|
31
|
+
export const preparingMode = {
|
|
32
|
+
args: {
|
|
33
|
+
event: {
|
|
34
|
+
EventId: 1,
|
|
35
|
+
TournamentId: 8,
|
|
36
|
+
EventName: "Longsword Event For Everyone",
|
|
37
|
+
Date: "2024-05-03",
|
|
38
|
+
StartTime: "12:00:16",
|
|
39
|
+
NumberOfRings: 3,
|
|
40
|
+
WeaponId: 1,
|
|
41
|
+
Status: "Active",
|
|
42
|
+
RuleSummary: "Pools -> DE -> 3rd Place Faceoff",
|
|
43
|
+
Present: "0",
|
|
44
|
+
Absent: "20",
|
|
45
|
+
Removed: "1",
|
|
46
|
+
},
|
|
47
|
+
mode: 'preparation'
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const liveMode = {
|
|
52
|
+
args: {
|
|
53
|
+
event: {
|
|
54
|
+
EventId: 1,
|
|
55
|
+
TournamentId: 8,
|
|
56
|
+
EventName: "Longsword Event For Everyone",
|
|
57
|
+
Date: "2024-05-03",
|
|
58
|
+
StartTime: "12:00:16",
|
|
59
|
+
NumberOfRings: 3,
|
|
60
|
+
WeaponId: 1,
|
|
61
|
+
Status: "Active",
|
|
62
|
+
RuleSummary: "Pools -> DE -> 3rd Place Faceoff",
|
|
63
|
+
Present: "0",
|
|
64
|
+
Absent: "20",
|
|
65
|
+
Removed: "1",
|
|
66
|
+
},
|
|
67
|
+
mode: 'live'
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -25,20 +25,31 @@
|
|
|
25
25
|
<BaseText text="Only present fencers will show. Make any/all final changes. Click 'Go Live' to start pools." size="xs" color="primaryHighlight" />
|
|
26
26
|
</span>
|
|
27
27
|
</section>
|
|
28
|
-
<section v-if="mode === 'live'" class="flex rounded-xl border border-dropdownSelect mt-2 px-4 pt-2 pb-4 bg-neutral w-
|
|
28
|
+
<section v-if="mode === 'live'" class="flex rounded-xl border border-dropdownSelect mt-2 px-4 pt-2 pb-4 bg-neutral w-2/3 shadow">
|
|
29
29
|
<div class="mt-1 w-10 mr-3">
|
|
30
30
|
<BaseIcon icon-name="fa-play" size="3xl" color="quaternary" class="" />
|
|
31
31
|
</div>
|
|
32
|
-
<
|
|
32
|
+
<div class="w-2/3">
|
|
33
33
|
<BaseText text="Pools are now live!" size="lg" color="quaternary" weight="bold" class="" />
|
|
34
34
|
<BaseText text="Pools can now be run" size="xs" color="primaryHighlight" />
|
|
35
|
-
</
|
|
35
|
+
</div>
|
|
36
|
+
<div class="w-1/3 flex flex-col">
|
|
37
|
+
<div class="flex justify-between items-center w-full">
|
|
38
|
+
<BaseText text="Bouts Left:" size="sm" color="quaternary" class="text-right mr-2 w-2/3" />
|
|
39
|
+
<BaseText text="20/20" size="sm" color="primaryHighlight" class="text-left mr-2 w-1/3" />
|
|
40
|
+
</div>
|
|
41
|
+
<div class="flex justify-between items-center w-full mt-0.5">
|
|
42
|
+
<BaseText text="Est. End Time:" size="sm" color="quaternary" class="text-right mr-2 w-2/3" />
|
|
43
|
+
<BaseText text="12:45" size="sm" color="primaryHighlight" class="text-left mr-2 w-1/3" />
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
36
46
|
</section>
|
|
37
47
|
|
|
38
|
-
<section class="flex flex-row w-1/3 justify-end">
|
|
48
|
+
<section v-if="mode === 'planning' || mode === 'preparation'" class="flex flex-row w-1/3 justify-end">
|
|
39
49
|
<CounterBox :recommended="7" :count="poolSize" label="Pool Size" :textColor="'quaternary'" @update:count="handlePoolSizeChange" />
|
|
40
50
|
<CounterBox :recommended="2" :count="numberOfRings" label="Num Rings" :textColor="'quaternary'" @update:count="handleNumOfRingsChange" />
|
|
41
51
|
</section>
|
|
52
|
+
|
|
42
53
|
</div>
|
|
43
54
|
</template>
|
|
44
55
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import ToggleHeader from './ToggleHeader.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Organisms/Headers/ToggleHeader',
|
|
5
|
+
component: ToggleHeader,
|
|
6
|
+
tags: ['autodocs'],
|
|
7
|
+
args: {
|
|
8
|
+
firstButtonLabel: 'Staff List',
|
|
9
|
+
secondButtonLabel: 'Staff Assignments',
|
|
10
|
+
currentSelection: 'Staff List'
|
|
11
|
+
},
|
|
12
|
+
argTypes: {
|
|
13
|
+
firstButtonLabel: {
|
|
14
|
+
control: 'text',
|
|
15
|
+
description: 'Label for the first button'
|
|
16
|
+
},
|
|
17
|
+
secondButtonLabel: {
|
|
18
|
+
control: 'text',
|
|
19
|
+
description: 'Label for the second button'
|
|
20
|
+
},
|
|
21
|
+
currentSelection: {
|
|
22
|
+
control: 'radio',
|
|
23
|
+
options: ['Staff List', 'Staff Assignments', 'Pool Grid', 'List View'],
|
|
24
|
+
description: 'Currently selected view'
|
|
25
|
+
},
|
|
26
|
+
'update:selection': { action: 'update:selection' }
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const Default = {
|
|
31
|
+
args: {
|
|
32
|
+
firstButtonLabel: 'Staff List',
|
|
33
|
+
secondButtonLabel: 'Staff Assignments',
|
|
34
|
+
currentSelection: 'Staff List'
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const StaffAssignmentsSelected = {
|
|
39
|
+
args: {
|
|
40
|
+
firstButtonLabel: 'Staff List',
|
|
41
|
+
secondButtonLabel: 'Staff Assignments',
|
|
42
|
+
currentSelection: 'Staff Assignments'
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const CustomLabels = {
|
|
47
|
+
args: {
|
|
48
|
+
firstButtonLabel: 'Pool Grid',
|
|
49
|
+
secondButtonLabel: 'List View',
|
|
50
|
+
currentSelection: 'Pool Grid'
|
|
51
|
+
}
|
|
52
|
+
};
|
|
@@ -2,37 +2,46 @@
|
|
|
2
2
|
<div class="bg-bannerBackground px-4 py-4 rounded-xl flex justify-center border border-dropdownSelect">
|
|
3
3
|
<section class="flex flex-row w-3/4 justify-center bg-poolBox rounded-lg p-0.5 border border-dropdownSelect">
|
|
4
4
|
<BaseButton
|
|
5
|
-
label="
|
|
6
|
-
:selected="view ===
|
|
5
|
+
:label="firstButtonLabel"
|
|
6
|
+
:selected="view === firstButtonLabel"
|
|
7
7
|
size="md"
|
|
8
8
|
type="whiteSecondary"
|
|
9
9
|
class="mx-2 w-1/2"
|
|
10
|
-
@click="handleSelection(
|
|
10
|
+
@click="handleSelection(firstButtonLabel)"
|
|
11
11
|
/>
|
|
12
12
|
<BaseButton
|
|
13
|
-
label="
|
|
14
|
-
:selected="view ===
|
|
13
|
+
:label="secondButtonLabel"
|
|
14
|
+
:selected="view === secondButtonLabel"
|
|
15
15
|
size="md"
|
|
16
16
|
type="liteGraySecondary"
|
|
17
17
|
class="mx-2 w-1/2"
|
|
18
|
-
@click="handleSelection(
|
|
18
|
+
@click="handleSelection(secondButtonLabel)"
|
|
19
19
|
/>
|
|
20
20
|
</section>
|
|
21
21
|
</div>
|
|
22
22
|
</template>
|
|
23
23
|
|
|
24
24
|
<script>
|
|
25
|
-
import BaseText from "../../../Atoms/Text/BaseText.vue";
|
|
26
25
|
import BaseButton from "../../../Molecules/Buttons/BaseButton/BaseButton.vue";
|
|
27
26
|
|
|
28
27
|
export default {
|
|
29
|
-
name: '
|
|
30
|
-
components: {
|
|
28
|
+
name: 'ToggleHeader',
|
|
29
|
+
components: { BaseButton },
|
|
31
30
|
props: {
|
|
31
|
+
firstButtonLabel: {
|
|
32
|
+
type: String,
|
|
33
|
+
required: true
|
|
34
|
+
},
|
|
35
|
+
secondButtonLabel: {
|
|
36
|
+
type: String,
|
|
37
|
+
required: true
|
|
38
|
+
},
|
|
32
39
|
currentSelection: {
|
|
33
40
|
type: String,
|
|
34
41
|
required: true,
|
|
35
|
-
validator
|
|
42
|
+
// validator(value) {
|
|
43
|
+
// return [this.firstButtonLabel, this.secondButtonLabel].includes(value);
|
|
44
|
+
// }
|
|
36
45
|
}
|
|
37
46
|
},
|
|
38
47
|
data() {
|
|
@@ -52,4 +61,4 @@ export default {
|
|
|
52
61
|
}
|
|
53
62
|
}
|
|
54
63
|
};
|
|
55
|
-
</script>
|
|
64
|
+
</script>
|
|
@@ -62,11 +62,9 @@ export default {
|
|
|
62
62
|
},
|
|
63
63
|
methods: {
|
|
64
64
|
handleAddEvent() {
|
|
65
|
-
console.log("handleAddEvent")
|
|
66
65
|
this.$emit('addEvent', this.tournamentId);
|
|
67
66
|
},
|
|
68
67
|
handleEdit(eventId) {
|
|
69
|
-
console.log("handleEdit")
|
|
70
68
|
this.$emit('editEvent', eventId);
|
|
71
69
|
},
|
|
72
70
|
handleManageEvent(eventId) {
|
|
@@ -74,7 +72,6 @@ export default {
|
|
|
74
72
|
this.$emit('manageEvent', eventId);
|
|
75
73
|
},
|
|
76
74
|
handleTabMenuClick(value) {
|
|
77
|
-
console.log(`----- handleTabMenuClick: ${value}`);
|
|
78
75
|
this.$emit('tab:menu-click', value);
|
|
79
76
|
}
|
|
80
77
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import PoolLive from './PoolLive.vue';
|
|
2
|
+
import getPoolsWithBoutsByPoolId from "../../../../mocks/getPoolsWithBoutsByPoolId.js";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Templates/EventManagement/PoolLive',
|
|
6
|
+
component: PoolLive,
|
|
7
|
+
tags: ['PoolLive'],
|
|
8
|
+
args: {
|
|
9
|
+
bouts: getPoolsWithBoutsByPoolId.pools[0].Bouts,
|
|
10
|
+
eventRules: getPoolsWithBoutsByPoolId.eventRules,
|
|
11
|
+
hostingClubColors: getPoolsWithBoutsByPoolId.hostingClubColors
|
|
12
|
+
},
|
|
13
|
+
argTypes: {
|
|
14
|
+
bouts: {
|
|
15
|
+
control: Object
|
|
16
|
+
},
|
|
17
|
+
eventRules: {
|
|
18
|
+
control: Object
|
|
19
|
+
},
|
|
20
|
+
hostingClubColors: {
|
|
21
|
+
control: Object
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const Default = {
|
|
27
|
+
args: {
|
|
28
|
+
bouts: getPoolsWithBoutsByPoolId.pools[0].Bouts,
|
|
29
|
+
eventRules: getPoolsWithBoutsByPoolId.eventRules,
|
|
30
|
+
hostingClubColors: getPoolsWithBoutsByPoolId.hostingClubColors
|
|
31
|
+
}
|
|
32
|
+
};
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section>
|
|
3
|
+
<EditEventsTopMenu :currentTab="'Pools'" :tabs="tabs" @tabMenuClick="handleTabMenuClick"/>
|
|
4
|
+
<ToggleHeader :currentSelection="viewName" @update:selection="handleViewChange" firstButtonLabel="List View"
|
|
5
|
+
secondButtonLabel="Pool Grid"/>
|
|
6
|
+
|
|
7
|
+
<!-- active bout -->
|
|
8
|
+
<section class="flex flex-row">
|
|
9
|
+
<div class="w-5 h-5 rounded-full border-2 mt-5 mr-2">
|
|
10
|
+
<div class="w-3 h-3 rounded-full mt-0.5 ml-0.5" :class="hasActiveBout ? 'bg-green' : 'bg-red'"></div>
|
|
11
|
+
</div>
|
|
12
|
+
<BaseText text="Active bout" size="md" color="primaryHighlight" class="mt-5" weight="bold"/>
|
|
13
|
+
</section>
|
|
14
|
+
<div class="border-b border-dropdownSelect mb-8"></div>
|
|
15
|
+
|
|
16
|
+
<section class="w-full flex flex-col items-center">
|
|
17
|
+
<div v-if="!hasActiveBout" class="w-3/4 my-4">
|
|
18
|
+
<BoutCard :hostingClubColors="hostingClubColors" :bout="{}" :isWaiting="true"/>
|
|
19
|
+
</div>
|
|
20
|
+
<div v-for="bout in activeBouts" :key="bout.BoutId" class="w-3/4 my-4">
|
|
21
|
+
<BoutCard :hostingClubColors="hostingClubColors" :bout="bout"/>
|
|
22
|
+
</div>
|
|
23
|
+
</section>
|
|
24
|
+
|
|
25
|
+
<!-- Upcoming -->
|
|
26
|
+
<section class="flex flex-row justify-between">
|
|
27
|
+
<BaseText text="Upcoming" size="md" color="primaryHighlight" class="mt-5" weight="bold"/>
|
|
28
|
+
<div class="flex mr-1">
|
|
29
|
+
<BaseText text="Remaining bouts:" size="md" color="primaryHighlight" class="mt-5 ml-5"/>
|
|
30
|
+
<BaseText :text="remainingBoutsCount" size="md" color="primaryHighlight" weight="bold" class="mt-5 ml-2"/>
|
|
31
|
+
</div>
|
|
32
|
+
</section>
|
|
33
|
+
<div class="border-b border-dropdownSelect mb-5"></div>
|
|
34
|
+
<section class="w-full flex flex-col items-center">
|
|
35
|
+
<div v-for="bout in markedUpcomingBouts" :key="bout.BoutId" class="w-3/4 my-4">
|
|
36
|
+
<BoutCard :hostingClubColors="hostingClubColors" :bout="bout" @action:startBout="directBout"/>
|
|
37
|
+
</div>
|
|
38
|
+
</section>
|
|
39
|
+
|
|
40
|
+
<!-- Completed -->
|
|
41
|
+
<section class="flex flex-row">
|
|
42
|
+
<BaseText text="Completed" size="md" color="primaryHighlight" class="mt-5" weight="bold"/>
|
|
43
|
+
</section>
|
|
44
|
+
<div class="border-b border-dropdownSelect mb-5"></div>
|
|
45
|
+
<section class="w-full flex flex-col items-center">
|
|
46
|
+
<div v-for="bout in completedBouts" :key="bout.BoutId" class="w-3/4 my-4">
|
|
47
|
+
<BoutCard :hostingClubColors="hostingClubColors" :bout="bout" @action:editBout="editBout" />
|
|
48
|
+
</div>
|
|
49
|
+
</section>
|
|
50
|
+
|
|
51
|
+
<DirectorModal ringName="RingName" :hostingClubColors="hostingClubColors" :eventRules="eventRules"
|
|
52
|
+
:bout="selectedBout" :show="showDirectorModal"
|
|
53
|
+
@update:closeModal="handleCloseModal"
|
|
54
|
+
@update:bout="handleUpdateBout"
|
|
55
|
+
@submit:bout="handleSubmitBout"/>
|
|
56
|
+
|
|
57
|
+
<EditBoutModal :hostingClubColors="hostingClubColors" :eventRules="eventRules" :bout="selectedBout" :show="showEditBoutModal"
|
|
58
|
+
@update:closeModal="handleCloseModal"
|
|
59
|
+
@submit:bout="handleSubmitBout"/>
|
|
60
|
+
|
|
61
|
+
</section>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
<script>
|
|
65
|
+
import EditEventsTopMenu from "../../Menus/EditEventsTopMenu/EditEventsTopMenu.vue";
|
|
66
|
+
import ToggleHeader from "../../../Organisms/Headers/ToggleHeader/ToggleHeader.vue";
|
|
67
|
+
import BaseText from "../../../Atoms/Text/BaseText.vue";
|
|
68
|
+
import BoutCard from "../../../Organisms/Cards/BoutCard/BoutCard.vue";
|
|
69
|
+
import DirectorModal from "../../../Molecules/Modals/DirectorModal/DirectorModal.vue";
|
|
70
|
+
import EditBoutModal from "../../../Molecules/Modals/EditBoutModal/EditBoutModal.vue";
|
|
71
|
+
|
|
72
|
+
export default {
|
|
73
|
+
components: {
|
|
74
|
+
EditBoutModal,
|
|
75
|
+
DirectorModal,
|
|
76
|
+
BoutCard,
|
|
77
|
+
BaseText,
|
|
78
|
+
ToggleHeader,
|
|
79
|
+
EditEventsTopMenu
|
|
80
|
+
},
|
|
81
|
+
props: {
|
|
82
|
+
bouts: {
|
|
83
|
+
type: Array,
|
|
84
|
+
required: true
|
|
85
|
+
},
|
|
86
|
+
eventRules: {
|
|
87
|
+
type: Object,
|
|
88
|
+
required: true
|
|
89
|
+
},
|
|
90
|
+
hostingClubColors: {
|
|
91
|
+
type: Object,
|
|
92
|
+
required: true
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
computed: {
|
|
96
|
+
upcomingBouts() {
|
|
97
|
+
return this.bouts.filter(bout => bout.Status === 'Scheduled');
|
|
98
|
+
},
|
|
99
|
+
completedBouts() {
|
|
100
|
+
return this.bouts.filter(bout => bout.Status === 'Completed');
|
|
101
|
+
},
|
|
102
|
+
activeBouts() {
|
|
103
|
+
return this.bouts.filter(bout => bout.Status === 'Active');
|
|
104
|
+
},
|
|
105
|
+
hasActiveBout() {
|
|
106
|
+
return this.activeBouts.length > 0;
|
|
107
|
+
},
|
|
108
|
+
remainingBoutsCount() {
|
|
109
|
+
return this.upcomingBouts.length;
|
|
110
|
+
},
|
|
111
|
+
markedUpcomingBouts() {
|
|
112
|
+
const statuses = ['On Deck', 'In The Hole', 'Preparing'];
|
|
113
|
+
return this.upcomingBouts.map((bout, index) => {
|
|
114
|
+
if (index < statuses.length) {
|
|
115
|
+
return {
|
|
116
|
+
...bout,
|
|
117
|
+
customStatus: statuses[index]
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return bout;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
data() {
|
|
125
|
+
return {
|
|
126
|
+
showDirectorModal: false,
|
|
127
|
+
showEditBoutModal: false,
|
|
128
|
+
selectedBout: {},
|
|
129
|
+
tabs: [
|
|
130
|
+
{id: 'Staff', label: 'Staff', color: 'primaryHighlight'},
|
|
131
|
+
{id: 'Checkin', label: 'Seeding & Checkin', color: 'primaryHighlight'},
|
|
132
|
+
{id: 'Pools', label: 'Pools', color: 'primaryHighlight'},
|
|
133
|
+
{id: 'Pool Results', label: 'Pool Results', color: 'primaryHighlight'},
|
|
134
|
+
{id: 'Bracket', label: 'Bracket', color: 'primaryHighlight'},
|
|
135
|
+
{id: 'Final', label: 'Final Results', color: 'primaryHighlight'}
|
|
136
|
+
],
|
|
137
|
+
viewName: "List View"
|
|
138
|
+
};
|
|
139
|
+
},
|
|
140
|
+
methods: {
|
|
141
|
+
handleCloseModal(bout) {
|
|
142
|
+
this.showDirectorModal = false;
|
|
143
|
+
this.showEditBoutModal = false;
|
|
144
|
+
|
|
145
|
+
if (bout.Status !== 'Completed') {
|
|
146
|
+
const updatedBout = this.bouts.find(b => b.BoutId === bout.BoutId);
|
|
147
|
+
if (updatedBout) {
|
|
148
|
+
updatedBout.Status = 'Scheduled';
|
|
149
|
+
updatedBout.Score1 = 0;
|
|
150
|
+
updatedBout.Score2 = 0;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
handleTabMenuClick() {
|
|
155
|
+
console.log('handleTabMenuClick')
|
|
156
|
+
this.$emit('tab:menu-click', value);
|
|
157
|
+
},
|
|
158
|
+
handleViewChange() {
|
|
159
|
+
console.log('handleViewChange')
|
|
160
|
+
},
|
|
161
|
+
handleUpdateBout(bout) {
|
|
162
|
+
if (!this.activeBouts || this.activeBouts.length === 0) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const updatedBout = this.activeBouts.find(b => b.BoutId === bout.BoutId);
|
|
167
|
+
|
|
168
|
+
if (!updatedBout) {
|
|
169
|
+
console.log('Bout not found in active bouts:', bout.BoutId);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
Object.assign(updatedBout, bout);
|
|
174
|
+
updatedBout.Status = 'Active';
|
|
175
|
+
},
|
|
176
|
+
handleSubmitBout(bout) {
|
|
177
|
+
this.showEditBoutModal = false;
|
|
178
|
+
this.showDirectorModal = false;
|
|
179
|
+
const updatedBout = this.bouts.find(b => b.BoutId === bout.BoutId);
|
|
180
|
+
|
|
181
|
+
if (updatedBout) {
|
|
182
|
+
Object.assign(updatedBout, bout);
|
|
183
|
+
updatedBout.Status = 'Completed';
|
|
184
|
+
updatedBout.Ended = new Date().toISOString();
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
this.$emit('submit:bout', updatedBout);
|
|
188
|
+
},
|
|
189
|
+
directBout(bout) {
|
|
190
|
+
const updatedBout = this.bouts.find(b => b.BoutId === bout.BoutId);
|
|
191
|
+
if (updatedBout) {
|
|
192
|
+
updatedBout.Status = 'Active';
|
|
193
|
+
this.showDirectorModal = true;
|
|
194
|
+
this.selectedBout = bout;
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
editBout(bout) {
|
|
198
|
+
const updatedBout = this.bouts.find(b => b.BoutId === bout.BoutId);
|
|
199
|
+
if (updatedBout) {
|
|
200
|
+
this.showEditBoutModal = true;
|
|
201
|
+
this.selectedBout = bout;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
</script>
|