@dcrackel/hematournamentui 1.0.696 → 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.
Files changed (71) hide show
  1. package/AGENTS.md +85 -0
  2. package/README.md +22 -6
  3. package/dist/HemaTournamentUI-lib.es.js +43127 -44314
  4. package/dist/HemaTournamentUI-lib.umd.js +34 -38
  5. package/dist/hematournamentui-tailwind.css +3724 -0
  6. package/dist/hematournamentui.css +2 -9
  7. package/package.json +48 -43
  8. package/src/stories/Atoms/Input/BaseInput.vue +21 -18
  9. package/src/stories/Atoms/RadioGroup/BaseRadioGroup.vue +1 -0
  10. package/src/stories/Atoms/Tag/BaseTag.vue +17 -31
  11. package/src/stories/Atoms/Text/BaseText.vue +67 -144
  12. package/src/stories/Molecules/Boxes/BoutBoxes/PassesBox/PassesBox.vue +1 -0
  13. package/src/stories/Molecules/Boxes/BoutBoxes/TimerBox/TimerBox.vue +1 -0
  14. package/src/stories/Molecules/Boxes/CounterBox/CounterBox.vue +1 -0
  15. package/src/stories/Molecules/CombinationInputs/TitledInput/TitledInput.vue +1 -0
  16. package/src/stories/Molecules/Filters/FilterAndSortBar/FilterAndSortBar.vue +1 -0
  17. package/src/stories/Molecules/Filters/FilterUpcomingPast/FilterUpcomingPast.vue +1 -0
  18. package/src/stories/Molecules/Inputs/MultiSelect/MultiSelect.vue +1 -0
  19. package/src/stories/Molecules/Inputs/Toggle/Toggle.vue +1 -0
  20. package/src/stories/Molecules/Modals/AddDisplayModal/AddDisplayModal.vue +1 -0
  21. package/src/stories/Molecules/Modals/EditBoutModal/EditBoutModal.vue +1 -0
  22. package/src/stories/Molecules/Modals/EventWizardModal/EventWizardModal.vue +1 -0
  23. package/src/stories/Molecules/Reorder/ReorderableShell.vue +1 -0
  24. package/src/stories/Organisms/Cards/BoutCard/BoutCard.vue +3 -0
  25. package/src/stories/Organisms/Cards/BoutCard/Variants/BoutCardActive/BoutCardActive.vue +1 -0
  26. package/src/stories/Organisms/Cards/BoutCard/Variants/BoutCardInactive/BoutCardInactive.vue +1 -0
  27. package/src/stories/Organisms/Cards/FencerCard/FencerCard.vue +1 -0
  28. package/src/stories/Organisms/Cards/FencerPoolResultsCard/FencerPoolResultsCard.vue +1 -0
  29. package/src/stories/Organisms/Cards/ImportFencerCard/ImportFencerCard.vue +1 -0
  30. package/src/stories/Organisms/Cards/KioskCard/KioskCard.vue +30 -24
  31. package/src/stories/Organisms/Cards/PenaltyCard/PenaltyCard.vue +29 -39
  32. package/src/stories/Organisms/Cards/PoolFencerCard/PoolFencerCard.vue +1 -0
  33. package/src/stories/Organisms/Cards/StaffCard/StaffCard.vue +1 -0
  34. package/src/stories/Organisms/Cards/TableauBoutCard/TableauBoutCard.vue +1 -0
  35. package/src/stories/Organisms/Cards/TableauFencerCard/TableauFencerCard.vue +1 -0
  36. package/src/stories/Organisms/Cards/TournamentAdminCard/TournamentAdminCard.vue +17 -19
  37. package/src/stories/Organisms/ComplexInputs/AddressAutocomplete/AddressAutocomplete.vue +1 -0
  38. package/src/stories/Organisms/ComplexInputs/ClubColorPicker/ClubColorPicker.vue +1 -0
  39. package/src/stories/Organisms/ComplexInputs/DatePicker/DatePicker.vue +2 -1
  40. package/src/stories/Organisms/ComplexInputs/DropDown/DropDownMenu.vue +1 -0
  41. package/src/stories/Organisms/ComplexInputs/FindOrAddPerson/FindOrAddPerson.vue +1 -0
  42. package/src/stories/Organisms/ComplexInputs/FindPerson/FindPerson.vue +1 -0
  43. package/src/stories/Organisms/ComplexInputs/ImageCropper/ImageCropper.vue +1 -0
  44. package/src/stories/Organisms/Containers/PoolResults/PoolResultsTable.vue +1 -0
  45. package/src/stories/Organisms/Containers/TableauColumn/TableauColumn.vue +1 -0
  46. package/src/stories/Organisms/Form/AddDisplay/AddDisplay.vue +1 -0
  47. package/src/stories/Organisms/Form/AddNewPerson/AddNewPerson.vue +1 -0
  48. package/src/stories/Organisms/Grids/GridContainer.vue +113 -141
  49. package/src/stories/Organisms/Headers/EventFinalResultsHeader/EventFinalResultsHeader.vue +1 -0
  50. package/src/stories/Organisms/Headers/PoolResultsHeader/PoolResultsHeader.vue +1 -0
  51. package/src/stories/Organisms/Headers/PoolSummary/PoolSummary.vue +1 -0
  52. package/src/stories/Organisms/Headers/ToggleHeader/ToggleHeader.vue +1 -0
  53. package/src/stories/Organisms/Wizards/EditEventWizard/BasicEventInfo/BasicEventInfo.vue +1 -0
  54. package/src/stories/Organisms/Wizards/EditEventWizard/DirectEliminationPromotion/DirectEliminationPromotion.vue +21 -34
  55. package/src/stories/Organisms/Wizards/EditEventWizard/EditEventWizard.vue +77 -72
  56. package/src/stories/Organisms/Wizards/EditEventWizard/PoolConfiguration/PoolConfiguration.vue +1 -0
  57. package/src/stories/Templates/Assignment/Assignment.vue +56 -70
  58. package/src/stories/Templates/EventManagement/Bracket/Bracket.vue +1 -0
  59. package/src/stories/Templates/EventManagement/EditEventInfo/EditEventInfo.vue +1 -0
  60. package/src/stories/Templates/EventManagement/EventAttendance/EventAttendance.vue +26 -26
  61. package/src/stories/Templates/EventManagement/EventFinalResults/EventFinalResults.vue +1 -0
  62. package/src/stories/Templates/EventManagement/PoolLive/PoolLive.vue +0 -2
  63. package/src/stories/Templates/EventManagement/PoolManagement/PoolManagement.vue +2 -0
  64. package/src/stories/Templates/EventManagement/PoolResults/PoolResults.vue +1 -0
  65. package/src/stories/Templates/EventManagement/StaffList/StaffList.vue +1 -0
  66. package/src/stories/Templates/PersonManagement/Attendance/Attendance.vue +27 -33
  67. package/src/stories/Templates/TournamentManagement/TouranmentResultsImport/TournamentResultsImport.vue +0 -0
  68. package/src/stories/Templates/TournamentManagement/TournamentManagement.vue +1 -0
  69. package/src/stories/Templates/TournamentManagement/TournamentPageTwo/TouranmentPageTwo.vue +80 -4
  70. package/src/stories/Util/tabs.js +1 -0
  71. 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
- export default {
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
- switch (event.Role) {
96
- case "Director":
97
- return "fa-referee";
98
- case "List Table":
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
- switch (day % 10) {
141
- case 1: return 'st';
142
- case 2: return 'nd';
143
- case 3: return 'rd';
144
- default: return 'th';
145
- }
146
- },
147
- getStatusIcon(event) {
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,
@@ -21,6 +21,7 @@ import EditEventWizard from "../../../Organisms/Wizards/EditEventWizard/EditEven
21
21
  import { tabs } from '../../../Util/tabs.js';
22
22
 
23
23
  export default {
24
+ emits: ['tab:menu-click', 'update:submit'],
24
25
  components: {
25
26
  EditEventWizard,
26
27
  ToggleHeader,
@@ -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
- export default {
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
- switch (this.localSelectedItem.link) {
168
- case "Seed":
169
- return (a.Seed || 0) - (b.Seed || 0);
170
-
171
- case "FullName":
172
- return a.Person.DisplayName.localeCompare(b.Person.DisplayName);
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: {
@@ -420,8 +420,6 @@ export default {
420
420
  const updatedBout = this.localBouts.find(b => b.BoutId === bout.BoutId);
421
421
  if (updatedBout) {
422
422
  updatedBout.Status = 'Scheduled';
423
- updatedBout.Score1 = 0;
424
- updatedBout.Score2 = 0;
425
423
  }
426
424
  this.$emit('update:bout', updatedBout);
427
425
  }
@@ -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
- export default {
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
- switch (weapon) {
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
- switch (day % 10) {
105
- case 1: return 'st';
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>
@@ -21,6 +21,7 @@
21
21
  :tournament="localTournament"
22
22
  :isNewTournament="isNewTournament"
23
23
  @update:tournament="updateTournament"
24
+ @go:results-import="handleTab('ResultsImport')"
24
25
  />
25
26
 
26
27
  <div v-if="isNewTournament" class="flex flex-row justify-center h-12 mt-4">
@@ -33,7 +33,7 @@
33
33
  size="sm"
34
34
  type="square"
35
35
  :selected="!!tournament.HostedOnM2"
36
- @buttonClick="emitUpdate('HostedOnM2', true)"
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="emitUpdate('HostedOnM2', false)"
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 with a direct link to your tournament's webpage.\n\n`
186
- + `By selecting 'Yes', you'll gain access to our comprehensive MeyerSquared platform, allowing you to manage and conduct your tournament directly.`;
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>
@@ -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
  }
@@ -1,9 +1,8 @@
1
- @import 'tailwindcss/base';
2
- @import 'tailwindcss/components';
3
- @import 'tailwindcss/utilities';
4
- @import '@fontsource/inter/200.css';
5
- @import '@fontsource/inter/400.css';
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';