@dcrackel/hematournamentui 1.0.697 → 1.0.698
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/AGENTS.md +85 -0
- package/README.md +22 -6
- package/dist/HemaTournamentUI-lib.es.js +43127 -44314
- package/dist/HemaTournamentUI-lib.umd.js +34 -38
- package/dist/hematournamentui-tailwind.css +3724 -0
- package/dist/hematournamentui.css +2 -9
- package/package.json +48 -43
- package/src/stories/Atoms/Input/BaseInput.vue +21 -18
- package/src/stories/Atoms/RadioGroup/BaseRadioGroup.vue +1 -0
- package/src/stories/Atoms/Tag/BaseTag.vue +17 -31
- package/src/stories/Atoms/Text/BaseText.vue +67 -144
- package/src/stories/Molecules/Boxes/BoutBoxes/PassesBox/PassesBox.vue +1 -0
- package/src/stories/Molecules/Boxes/BoutBoxes/TimerBox/TimerBox.vue +1 -0
- package/src/stories/Molecules/Boxes/CounterBox/CounterBox.vue +1 -0
- package/src/stories/Molecules/CombinationInputs/TitledInput/TitledInput.vue +1 -0
- package/src/stories/Molecules/Filters/FilterAndSortBar/FilterAndSortBar.vue +1 -0
- package/src/stories/Molecules/Filters/FilterUpcomingPast/FilterUpcomingPast.vue +1 -0
- package/src/stories/Molecules/Inputs/MultiSelect/MultiSelect.vue +1 -0
- package/src/stories/Molecules/Inputs/Toggle/Toggle.vue +1 -0
- package/src/stories/Molecules/Modals/AddDisplayModal/AddDisplayModal.vue +1 -0
- package/src/stories/Molecules/Modals/EditBoutModal/EditBoutModal.vue +1 -0
- package/src/stories/Molecules/Modals/EventWizardModal/EventWizardModal.vue +1 -0
- package/src/stories/Molecules/Reorder/ReorderableShell.vue +1 -0
- package/src/stories/Organisms/Cards/BoutCard/BoutCard.vue +3 -0
- package/src/stories/Organisms/Cards/BoutCard/Variants/BoutCardActive/BoutCardActive.vue +1 -0
- package/src/stories/Organisms/Cards/BoutCard/Variants/BoutCardInactive/BoutCardInactive.vue +1 -0
- package/src/stories/Organisms/Cards/FencerCard/FencerCard.vue +1 -0
- package/src/stories/Organisms/Cards/FencerPoolResultsCard/FencerPoolResultsCard.vue +1 -0
- package/src/stories/Organisms/Cards/ImportFencerCard/ImportFencerCard.vue +1 -0
- package/src/stories/Organisms/Cards/KioskCard/KioskCard.vue +30 -24
- package/src/stories/Organisms/Cards/PenaltyCard/PenaltyCard.vue +29 -39
- package/src/stories/Organisms/Cards/PoolFencerCard/PoolFencerCard.vue +1 -0
- package/src/stories/Organisms/Cards/StaffCard/StaffCard.vue +1 -0
- package/src/stories/Organisms/Cards/TableauBoutCard/TableauBoutCard.vue +1 -0
- package/src/stories/Organisms/Cards/TableauFencerCard/TableauFencerCard.vue +1 -0
- package/src/stories/Organisms/Cards/TournamentAdminCard/TournamentAdminCard.vue +17 -19
- package/src/stories/Organisms/ComplexInputs/AddressAutocomplete/AddressAutocomplete.vue +1 -0
- package/src/stories/Organisms/ComplexInputs/ClubColorPicker/ClubColorPicker.vue +1 -0
- package/src/stories/Organisms/ComplexInputs/DatePicker/DatePicker.vue +2 -1
- package/src/stories/Organisms/ComplexInputs/DropDown/DropDownMenu.vue +1 -0
- package/src/stories/Organisms/ComplexInputs/FindOrAddPerson/FindOrAddPerson.vue +1 -0
- package/src/stories/Organisms/ComplexInputs/FindPerson/FindPerson.vue +1 -0
- package/src/stories/Organisms/ComplexInputs/ImageCropper/ImageCropper.vue +1 -0
- package/src/stories/Organisms/Containers/PoolResults/PoolResultsTable.vue +1 -0
- package/src/stories/Organisms/Containers/TableauColumn/TableauColumn.vue +1 -0
- package/src/stories/Organisms/Form/AddDisplay/AddDisplay.vue +1 -0
- package/src/stories/Organisms/Form/AddNewPerson/AddNewPerson.vue +1 -0
- package/src/stories/Organisms/Grids/GridContainer.vue +113 -141
- package/src/stories/Organisms/Headers/EventFinalResultsHeader/EventFinalResultsHeader.vue +1 -0
- package/src/stories/Organisms/Headers/PoolResultsHeader/PoolResultsHeader.vue +1 -0
- package/src/stories/Organisms/Headers/PoolSummary/PoolSummary.vue +1 -0
- package/src/stories/Organisms/Headers/ToggleHeader/ToggleHeader.vue +1 -0
- package/src/stories/Organisms/Wizards/EditEventWizard/BasicEventInfo/BasicEventInfo.vue +1 -0
- package/src/stories/Organisms/Wizards/EditEventWizard/DirectEliminationPromotion/DirectEliminationPromotion.vue +21 -34
- package/src/stories/Organisms/Wizards/EditEventWizard/EditEventWizard.vue +77 -72
- package/src/stories/Organisms/Wizards/EditEventWizard/PoolConfiguration/PoolConfiguration.vue +1 -0
- package/src/stories/Templates/Assignment/Assignment.vue +56 -70
- package/src/stories/Templates/EventManagement/Bracket/Bracket.vue +1 -0
- package/src/stories/Templates/EventManagement/EditEventInfo/EditEventInfo.vue +1 -0
- package/src/stories/Templates/EventManagement/EventAttendance/EventAttendance.vue +26 -26
- package/src/stories/Templates/EventManagement/EventFinalResults/EventFinalResults.vue +1 -0
- package/src/stories/Templates/EventManagement/PoolManagement/PoolManagement.vue +2 -0
- package/src/stories/Templates/EventManagement/PoolResults/PoolResults.vue +1 -0
- package/src/stories/Templates/EventManagement/StaffList/StaffList.vue +1 -0
- package/src/stories/Templates/PersonManagement/Attendance/Attendance.vue +27 -33
- package/src/stories/Templates/TournamentManagement/TouranmentResultsImport/TournamentResultsImport.vue +0 -0
- package/src/stories/Templates/TournamentManagement/TournamentManagement.vue +1 -0
- package/src/stories/Templates/TournamentManagement/TournamentPageTwo/TouranmentPageTwo.vue +80 -4
- package/src/stories/Util/tabs.js +1 -0
- package/tailwind/tailwind.css +5 -6
|
@@ -53,12 +53,47 @@
|
|
|
53
53
|
|
|
54
54
|
<script>
|
|
55
55
|
import BaseButton from "../../Molecules/Buttons/BaseButton/BaseButton.vue";
|
|
56
|
-
import BaseText from "../../Atoms/Text/BaseText.vue";
|
|
57
|
-
import defaultImage from "../../../assets/default-tournament_old.png"
|
|
58
|
-
import BaseIcon from "../../Atoms/Icon/BaseIcon.vue";
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
import BaseText from "../../Atoms/Text/BaseText.vue";
|
|
57
|
+
import defaultImage from "../../../assets/default-tournament_old.png"
|
|
58
|
+
import BaseIcon from "../../Atoms/Icon/BaseIcon.vue";
|
|
59
|
+
|
|
60
|
+
const roleIcons = {
|
|
61
|
+
Director: 'fa-referee',
|
|
62
|
+
'List Table': 'fa-laptop',
|
|
63
|
+
'Line Judge': 'fa-flag-pennant'
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const roleIconStyles = {
|
|
67
|
+
Director: 'fa-kit'
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const daySuffixes = {
|
|
71
|
+
1: 'st',
|
|
72
|
+
2: 'nd',
|
|
73
|
+
3: 'rd'
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const statusIcons = {
|
|
77
|
+
planning: 'fa-hourglass',
|
|
78
|
+
preparation: 'fa-hourglass-start',
|
|
79
|
+
live: 'fa-play',
|
|
80
|
+
results: 'fa-pause',
|
|
81
|
+
de: 'fa-circle-play',
|
|
82
|
+
completed: 'fa-trophy'
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const statusIconClasses = {
|
|
86
|
+
planning: 'mt-1 pl-1',
|
|
87
|
+
preparation: 'mt-1 pl-1',
|
|
88
|
+
live: 'mt-1 pl-0',
|
|
89
|
+
results: 'mt-1 pl-1',
|
|
90
|
+
de: 'mt-1 pl-0',
|
|
91
|
+
completed: 'mt-0.5'
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export default {
|
|
61
95
|
name: "TournamentAssignments",
|
|
96
|
+
emits: ['forwardToEvent', 'refreshAssignments'],
|
|
62
97
|
components: {BaseIcon, BaseText, BaseButton},
|
|
63
98
|
props: {
|
|
64
99
|
assignments: {
|
|
@@ -90,26 +125,12 @@ export default {
|
|
|
90
125
|
const eventDate = new Date(`${date}T${time}`);
|
|
91
126
|
const options = {weekday: 'long', hour: 'numeric', minute: '2-digit', hour12: true};
|
|
92
127
|
return eventDate.toLocaleDateString('en-US', options);
|
|
93
|
-
},
|
|
94
|
-
getRoleIcon(event) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return "fa-laptop";
|
|
100
|
-
case "Line Judge":
|
|
101
|
-
return "fa-flag-pennant";
|
|
102
|
-
default:
|
|
103
|
-
return "fa-circle-question";
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
getIconStyle(event) {
|
|
107
|
-
switch (event.Role) {
|
|
108
|
-
case "Director":
|
|
109
|
-
return "fa-kit";
|
|
110
|
-
default:
|
|
111
|
-
return "fa-solid";
|
|
112
|
-
}
|
|
128
|
+
},
|
|
129
|
+
getRoleIcon(event) {
|
|
130
|
+
return roleIcons[event.Role] || 'fa-circle-question';
|
|
131
|
+
},
|
|
132
|
+
getIconStyle(event) {
|
|
133
|
+
return roleIconStyles[event.Role] || 'fa-solid';
|
|
113
134
|
},
|
|
114
135
|
shouldShowButton(event) {
|
|
115
136
|
const eventStatus = event.Status.toLowerCase();
|
|
@@ -135,51 +156,16 @@ export default {
|
|
|
135
156
|
|
|
136
157
|
return `${formatDate(startDate, includeYear)} to ${formatDate(endDate, includeYear)}`;
|
|
137
158
|
},
|
|
138
|
-
getDaySuffix(day) {
|
|
139
|
-
if (day > 3 && day < 21) return 'th'; // General rule
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
switch (event.Status) {
|
|
149
|
-
case "planning":
|
|
150
|
-
return "fa-hourglass";
|
|
151
|
-
case "preparation":
|
|
152
|
-
return "fa-hourglass-start";
|
|
153
|
-
case "live":
|
|
154
|
-
return "fa-play";
|
|
155
|
-
case "results":
|
|
156
|
-
return "fa-pause";
|
|
157
|
-
case "de":
|
|
158
|
-
return "fa-circle-play";
|
|
159
|
-
case "completed":
|
|
160
|
-
return "fa-trophy";
|
|
161
|
-
default:
|
|
162
|
-
return "fa-circle-question";
|
|
163
|
-
}
|
|
164
|
-
},
|
|
165
|
-
getIconClass(event) {
|
|
166
|
-
switch (event.Status) {
|
|
167
|
-
case "planning":
|
|
168
|
-
return "mt-1 pl-1";
|
|
169
|
-
case "preparation":
|
|
170
|
-
return "mt-1 pl-1";
|
|
171
|
-
case "live":
|
|
172
|
-
return "mt-1 pl-0";
|
|
173
|
-
case "results":
|
|
174
|
-
return "mt-1 pl-1";
|
|
175
|
-
case "de":
|
|
176
|
-
return "mt-1 pl-0";
|
|
177
|
-
case "completed":
|
|
178
|
-
return "mt-0.5";
|
|
179
|
-
default:
|
|
180
|
-
return "";
|
|
181
|
-
}
|
|
182
|
-
},
|
|
159
|
+
getDaySuffix(day) {
|
|
160
|
+
if (day > 3 && day < 21) return 'th'; // General rule
|
|
161
|
+
return daySuffixes[day % 10] || 'th';
|
|
162
|
+
},
|
|
163
|
+
getStatusIcon(event) {
|
|
164
|
+
return statusIcons[event.Status] || 'fa-circle-question';
|
|
165
|
+
},
|
|
166
|
+
getIconClass(event) {
|
|
167
|
+
return statusIconClasses[event.Status] || '';
|
|
168
|
+
},
|
|
183
169
|
forwardToEvent(event) {
|
|
184
170
|
this.$emit('forwardToEvent', event);
|
|
185
171
|
},
|
|
@@ -81,6 +81,7 @@ import { tabs } from '../../../Util/tabs.js';
|
|
|
81
81
|
import AssignDirectorModal from "../../../Molecules/Modals/AssignDirectorModal/AssignDirectorModal.vue";
|
|
82
82
|
|
|
83
83
|
export default {
|
|
84
|
+
emits: ['penalty:add', 'penalty:remove', 'penalty:update', 'submit:bout', 'tab:menu-click', 'update:bout', 'update:directing-bout'],
|
|
84
85
|
components: {
|
|
85
86
|
AssignDirectorModal,
|
|
86
87
|
ServerConnected,
|
|
@@ -78,10 +78,26 @@ import DropDownMenu from "../../../Organisms/ComplexInputs/DropDown/DropDownMenu
|
|
|
78
78
|
import FindOrAddPerson from "../../../Organisms/ComplexInputs/FindOrAddPerson/FindOrAddPerson.vue";
|
|
79
79
|
import AttendanceSummary from "../../../Organisms/Headers/AttendanceSummary/AttendanceSummary.vue";
|
|
80
80
|
import FencerCardSkeleton from "../../../Organisms/Skeletons/FencerCard/FencerCardSkeleton.vue";
|
|
81
|
-
import BaseModal from "../../../Molecules/Modals/BaseModal/BaseModal.vue";
|
|
82
|
-
import { tabs } from '../../../Util/tabs.js';
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
import BaseModal from "../../../Molecules/Modals/BaseModal/BaseModal.vue";
|
|
82
|
+
import { tabs } from '../../../Util/tabs.js';
|
|
83
|
+
|
|
84
|
+
const personSorters = {
|
|
85
|
+
Seed: (a, b) => (a.Seed || 0) - (b.Seed || 0),
|
|
86
|
+
FullName: (a, b) => a.Person.DisplayName.localeCompare(b.Person.DisplayName),
|
|
87
|
+
HEMARating: (a, b) => {
|
|
88
|
+
const ratingA = a.Person.HEMARatings?.[0]?.Rating || 0;
|
|
89
|
+
const ratingB = b.Person.HEMARatings?.[0]?.Rating || 0;
|
|
90
|
+
return ratingB - ratingA;
|
|
91
|
+
},
|
|
92
|
+
M2Rating: (a, b) => {
|
|
93
|
+
const m2RatingA = a.Person.M2Ratings?.[0]?.Rating || 'U00';
|
|
94
|
+
const m2RatingB = b.Person.M2Ratings?.[0]?.Rating || 'U00';
|
|
95
|
+
return m2RatingA.localeCompare(m2RatingB);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export default {
|
|
100
|
+
emits: ['add:existing-person', 'add:person', 'forward:toProfile', 'remove:fencer', 'tab:menu-click', 'update:moveDown', 'update:moveUp', 'update:person', 'weaver:sign'],
|
|
85
101
|
components: {
|
|
86
102
|
FencerCardSkeleton,
|
|
87
103
|
AttendanceSummary,
|
|
@@ -164,28 +180,12 @@ export default {
|
|
|
164
180
|
return 0;
|
|
165
181
|
}
|
|
166
182
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
case "HEMARating":
|
|
175
|
-
const ratingA = a.Person.HEMARatings?.[0]?.Rating || 0; // Fix: Ensure safe access
|
|
176
|
-
const ratingB = b.Person.HEMARatings?.[0]?.Rating || 0;
|
|
177
|
-
return ratingB - ratingA; // Descending order (higher rating first)
|
|
178
|
-
|
|
179
|
-
case "M2Rating":
|
|
180
|
-
const m2RatingA = a.Person.M2Ratings?.[0]?.Rating || "U00"; // Fix: Handle missing data
|
|
181
|
-
const m2RatingB = b.Person.M2Ratings?.[0]?.Rating || "U00";
|
|
182
|
-
return m2RatingA.localeCompare(m2RatingB);
|
|
183
|
-
|
|
184
|
-
default:
|
|
185
|
-
console.warn("Unknown sorting key:", this.localSelectedItem.link);
|
|
186
|
-
return 0;
|
|
187
|
-
}
|
|
188
|
-
});
|
|
183
|
+
const sortPersons = personSorters[this.localSelectedItem.link];
|
|
184
|
+
if (sortPersons) return sortPersons(a, b);
|
|
185
|
+
|
|
186
|
+
console.warn("Unknown sorting key:", this.localSelectedItem.link);
|
|
187
|
+
return 0;
|
|
188
|
+
});
|
|
189
189
|
return sortedArray;
|
|
190
190
|
},
|
|
191
191
|
absent() {
|
|
@@ -26,6 +26,7 @@ import { tabs } from '../../../Util/tabs.js';
|
|
|
26
26
|
|
|
27
27
|
export default {
|
|
28
28
|
name: 'EventFinalResult',
|
|
29
|
+
emits: ['export:HemaRatings', 'tab:menu-click'],
|
|
29
30
|
components: {BaseText, EventFinalResultsHeader, FinalResultsTable, EditEventsTopMenu},
|
|
30
31
|
props: {
|
|
31
32
|
event: {
|
|
@@ -58,6 +58,7 @@ import { tabs } from '../../../Util/tabs.js';
|
|
|
58
58
|
|
|
59
59
|
export default {
|
|
60
60
|
name: 'PoolManagement',
|
|
61
|
+
emits: ['fencer:poolChanged', 'goLive:pool', 'remove:fencer', 'reset:pool', 'select:pool', 'start:pool', 'tab:menu-click', 'update:director', 'update:numberOfRings', 'update:poolSize', 'update:swapFencers'],
|
|
61
62
|
components: {
|
|
62
63
|
BaseText,
|
|
63
64
|
BaseButton,
|
|
@@ -127,6 +128,7 @@ export default {
|
|
|
127
128
|
return Array.from({ length: 2 }).map((_, index) => ({
|
|
128
129
|
PoolId: `skeleton-${index}`,
|
|
129
130
|
Name: 'Loading...',
|
|
131
|
+
emits: ['fencer:poolChanged', 'goLive:pool', 'remove:fencer', 'reset:pool', 'select:pool', 'start:pool', 'tab:menu-click', 'update:director', 'update:numberOfRings', 'update:poolSize', 'update:swapFencers'],
|
|
130
132
|
RingName: 'Loading...',
|
|
131
133
|
poolStrengthInd: 0,
|
|
132
134
|
BoutsLeft: 0,
|
|
@@ -52,6 +52,7 @@ import { tabs } from '../../../Util/tabs.js';
|
|
|
52
52
|
|
|
53
53
|
export default {
|
|
54
54
|
name: 'PoolResults',
|
|
55
|
+
emits: ['tab:menu-click', 'update:moveFencerDESeedDown', 'update:moveFencerDESeedUp', 'update:withdraw'],
|
|
55
56
|
components: {BaseModal, PoolResultsTable, PoolGrid, PoolResultsHeader, EditEventsTopMenu, PoolSummary},
|
|
56
57
|
props: {
|
|
57
58
|
event: {
|
|
@@ -60,6 +60,7 @@ import ToggleHeader from "../../../Organisms/Headers/ToggleHeader/ToggleHeader.v
|
|
|
60
60
|
import { tabs } from '../../../Util/tabs.js';
|
|
61
61
|
|
|
62
62
|
export default {
|
|
63
|
+
emits: ['add:existing-person', 'add:person', 'remove:staff', 'tab:menu-click', 'update:assignment'],
|
|
63
64
|
components: {
|
|
64
65
|
ToggleHeader,
|
|
65
66
|
FindOrAddPerson,
|
|
@@ -34,10 +34,26 @@
|
|
|
34
34
|
</template>
|
|
35
35
|
|
|
36
36
|
<script>
|
|
37
|
-
import BaseText from "../../../Atoms/Text/BaseText.vue";
|
|
38
|
-
import BaseIcon from "../../..//Atoms/Icon/BaseIcon.vue";
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
import BaseText from "../../../Atoms/Text/BaseText.vue";
|
|
38
|
+
import BaseIcon from "../../..//Atoms/Icon/BaseIcon.vue";
|
|
39
|
+
|
|
40
|
+
const weaponIcons = {
|
|
41
|
+
Longsword: 'fa-longsword',
|
|
42
|
+
'Military Saber': 'fa-saber',
|
|
43
|
+
'Rapier & Dagger': 'fa-rapier',
|
|
44
|
+
'Single Rapier': 'fa-rapier',
|
|
45
|
+
Messer: 'fa-messer',
|
|
46
|
+
'Sword & Buckler': 'fa-swordandbuckler',
|
|
47
|
+
Sidesword: 'fa-sidesword'
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const daySuffixes = {
|
|
51
|
+
1: 'st',
|
|
52
|
+
2: 'nd',
|
|
53
|
+
3: 'rd'
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default {
|
|
41
57
|
name: "Attendance",
|
|
42
58
|
components: {BaseIcon, BaseText },
|
|
43
59
|
props: {
|
|
@@ -53,26 +69,9 @@ export default {
|
|
|
53
69
|
},
|
|
54
70
|
computed: {
|
|
55
71
|
},
|
|
56
|
-
methods: {
|
|
57
|
-
getWeaponIcon(weapon){
|
|
58
|
-
|
|
59
|
-
case "Longsword":
|
|
60
|
-
return "fa-longsword";
|
|
61
|
-
case "Military Saber":
|
|
62
|
-
return "fa-saber";
|
|
63
|
-
case "Rapier & Dagger":
|
|
64
|
-
return "fa-rapier";
|
|
65
|
-
case "Single Rapier":
|
|
66
|
-
return "fa-rapier";
|
|
67
|
-
case "Messer":
|
|
68
|
-
return "fa-messer";
|
|
69
|
-
case "Sword & Buckler":
|
|
70
|
-
return "fa-swordandbuckler";
|
|
71
|
-
case "Sidesword":
|
|
72
|
-
return "fa-sidesword"
|
|
73
|
-
default:
|
|
74
|
-
return "fa-longsword";
|
|
75
|
-
}
|
|
72
|
+
methods: {
|
|
73
|
+
getWeaponIcon(weapon){
|
|
74
|
+
return weaponIcons[weapon] || 'fa-longsword';
|
|
76
75
|
},
|
|
77
76
|
formatEventDate(date, time) {
|
|
78
77
|
const eventDate = new Date(`${date}T${time}`);
|
|
@@ -99,15 +98,10 @@ export default {
|
|
|
99
98
|
|
|
100
99
|
return `${formatDate(startDate, includeYear)} to ${formatDate(endDate, includeYear)}`;
|
|
101
100
|
},
|
|
102
|
-
getDaySuffix(day) {
|
|
103
|
-
if (day > 3 && day < 21) return 'th';
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
case 2: return 'nd';
|
|
107
|
-
case 3: return 'rd';
|
|
108
|
-
default: return 'th';
|
|
109
|
-
}
|
|
110
|
-
},
|
|
101
|
+
getDaySuffix(day) {
|
|
102
|
+
if (day > 3 && day < 21) return 'th';
|
|
103
|
+
return daySuffixes[day % 10] || 'th';
|
|
104
|
+
},
|
|
111
105
|
}
|
|
112
106
|
};
|
|
113
107
|
</script>
|
|
File without changes
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
size="sm"
|
|
34
34
|
type="square"
|
|
35
35
|
:selected="!!tournament.HostedOnM2"
|
|
36
|
-
@buttonClick="
|
|
36
|
+
@buttonClick="handleHostedChoice(true)"
|
|
37
37
|
/>
|
|
38
38
|
<BaseButton
|
|
39
39
|
class="w-1/2 ml-1"
|
|
@@ -42,11 +42,75 @@
|
|
|
42
42
|
size="sm"
|
|
43
43
|
type="square"
|
|
44
44
|
:selected="!tournament.HostedOnM2"
|
|
45
|
-
@buttonClick="
|
|
45
|
+
@buttonClick="handleHostedChoice(false)"
|
|
46
46
|
/>
|
|
47
47
|
</div>
|
|
48
48
|
</section>
|
|
49
49
|
|
|
50
|
+
<!-- Results Import (only when NOT hosted) -->
|
|
51
|
+
<div v-if="!tournament.HostedOnM2" class="flex flex-col pb-4 mt-10">
|
|
52
|
+
<BaseText
|
|
53
|
+
:color="'primaryHighlight'"
|
|
54
|
+
:size="'xl'"
|
|
55
|
+
:text="'Publish final results on MeyerSquared?'"
|
|
56
|
+
:weight="'normal'"
|
|
57
|
+
class="mb-2 border-b border-dropdownSelect"
|
|
58
|
+
data-testid="text-results-publish"
|
|
59
|
+
/>
|
|
60
|
+
<BaseText
|
|
61
|
+
:color="'quaternary'"
|
|
62
|
+
:size="'sm'"
|
|
63
|
+
:text="resultsDescription"
|
|
64
|
+
:weight="'normal'"
|
|
65
|
+
data-testid="text-results-description"
|
|
66
|
+
/>
|
|
67
|
+
|
|
68
|
+
<section class="flex w-full justify-center mt-6">
|
|
69
|
+
<div class="flex flex-row justify-center w-3/4">
|
|
70
|
+
<BaseButton
|
|
71
|
+
class="w-1/2 mr-1"
|
|
72
|
+
color="neutral"
|
|
73
|
+
label="Not now"
|
|
74
|
+
size="sm"
|
|
75
|
+
type="square"
|
|
76
|
+
:selected="!tournament.ResultsEnabled"
|
|
77
|
+
@buttonClick="emitUpdate('ResultsEnabled', false)"
|
|
78
|
+
/>
|
|
79
|
+
<BaseButton
|
|
80
|
+
class="w-1/2 ml-1"
|
|
81
|
+
color="neutral"
|
|
82
|
+
label="Yes, I’ll upload results"
|
|
83
|
+
size="sm"
|
|
84
|
+
type="square"
|
|
85
|
+
:selected="!!tournament.ResultsEnabled"
|
|
86
|
+
@buttonClick="emitUpdate('ResultsEnabled', true)"
|
|
87
|
+
/>
|
|
88
|
+
</div>
|
|
89
|
+
</section>
|
|
90
|
+
|
|
91
|
+
<div v-if="tournament.ResultsEnabled" class="w-full flex flex-col items-center mt-6">
|
|
92
|
+
<BaseText
|
|
93
|
+
:color="'quaternary'"
|
|
94
|
+
:size="'sm'"
|
|
95
|
+
:text="'You can upload results any time from the tournament edit page (Results Import tab).'"
|
|
96
|
+
:weight="'normal'"
|
|
97
|
+
class="text-center mb-3"
|
|
98
|
+
data-testid="text-results-anytime"
|
|
99
|
+
/>
|
|
100
|
+
|
|
101
|
+
<!-- This does not navigate by itself; it just emits an intent.
|
|
102
|
+
Parent can switch to a "Results Import" tab/screen. -->
|
|
103
|
+
<BaseButton
|
|
104
|
+
class="w-3/4"
|
|
105
|
+
color="neutral"
|
|
106
|
+
label="Go to Results Import"
|
|
107
|
+
size="sm"
|
|
108
|
+
type="primary"
|
|
109
|
+
@buttonClick="$emit('go:results-import')"
|
|
110
|
+
/>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
|
|
50
114
|
<!-- Visibility (only when hosted) -->
|
|
51
115
|
<div v-if="tournament.HostedOnM2" class="flex flex-col pb-4 mt-10">
|
|
52
116
|
<BaseText
|
|
@@ -158,6 +222,7 @@ import BaseRadioGroup from "../../../Atoms/RadioGroup/BaseRadioGroup.vue";
|
|
|
158
222
|
export default {
|
|
159
223
|
name: 'TournamentPageTwo',
|
|
160
224
|
components: { BaseRadioGroup, BaseInput, BaseButton, BaseText },
|
|
225
|
+
emits: ['update:tournament', 'go:results-import'],
|
|
161
226
|
props: {
|
|
162
227
|
tournament: { type: Object, required: true },
|
|
163
228
|
isNewTournament: { type: Boolean, default: true }
|
|
@@ -182,14 +247,25 @@ export default {
|
|
|
182
247
|
},
|
|
183
248
|
computed: {
|
|
184
249
|
hostingDescription() {
|
|
185
|
-
return `If you select 'No', your tournament will be featured on our main calendar
|
|
186
|
-
+ `
|
|
250
|
+
return `If you select 'No', your tournament will be featured on our main calendar and you can link out to your registration page.\n\n`
|
|
251
|
+
+ `You can also publish final results on MeyerSquared later (any time) to support ratings and historical records.\n\n`
|
|
252
|
+
+ `By selecting 'Yes', you'll gain access to the full MeyerSquared platform to run pools, brackets, and live scoring.`;
|
|
253
|
+
},
|
|
254
|
+
resultsDescription() {
|
|
255
|
+
return `Choose 'Yes' if you want MeyerSquared to display final placements for your events.\n\n`
|
|
256
|
+
+ `You can upload results now, or come back after the tournament and upload them later.`;
|
|
187
257
|
}
|
|
188
258
|
},
|
|
189
259
|
methods: {
|
|
190
260
|
emitUpdate(field, value) {
|
|
191
261
|
this.$emit('update:tournament', { [field]: value });
|
|
192
262
|
},
|
|
263
|
+
handleHostedChoice(isHosted) {
|
|
264
|
+
this.emitUpdate('HostedOnM2', isHosted);
|
|
265
|
+
|
|
266
|
+
// If they switch to Hosted, results import doesn't apply. Clear it to avoid confusion.
|
|
267
|
+
if (isHosted) this.emitUpdate('ResultsEnabled', false);
|
|
268
|
+
}
|
|
193
269
|
}
|
|
194
270
|
};
|
|
195
271
|
</script>
|
package/src/stories/Util/tabs.js
CHANGED
|
@@ -80,5 +80,6 @@ export const tournamentTabs = () => {
|
|
|
80
80
|
{id: 'Basic', label: 'Basic', color: 'primaryHighlight', icon: 'fa-info-circle'},
|
|
81
81
|
{id: 'Hosting', label: 'Hosting', color: 'primaryHighlight', icon: 'fa-globe-pointer'},
|
|
82
82
|
{id: 'Events', label: 'Events', color: 'primaryHighlight', icon: 'fa-swords'},
|
|
83
|
+
{id: 'ResultsImport', label: 'Results', color: 'primaryHighlight', icon: 'fa-swords'},
|
|
83
84
|
]
|
|
84
85
|
}
|
package/tailwind/tailwind.css
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
@
|
|
2
|
-
@import 'tailwindcss
|
|
3
|
-
@import '
|
|
4
|
-
@import '@fontsource/inter/
|
|
5
|
-
@import '@fontsource/inter/
|
|
6
|
-
@import '@fontsource/inter/500.css';
|
|
1
|
+
@config '../tailwind.config.js';
|
|
2
|
+
@import 'tailwindcss';
|
|
3
|
+
@import '@fontsource/inter/200.css';
|
|
4
|
+
@import '@fontsource/inter/400.css';
|
|
5
|
+
@import '@fontsource/inter/500.css';
|
|
7
6
|
@import '@fontsource/inter/600.css';
|
|
8
7
|
@import '@fontsource/inter/700.css';
|
|
9
8
|
@import '@fontsource/roboto-mono/index.css';
|