@dcrackel/hematournamentui 1.0.699 → 1.0.702

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 (72) hide show
  1. package/AGENTS.md +3 -0
  2. package/dist/HemaTournamentUI-lib.es.js +10913 -10269
  3. package/dist/HemaTournamentUI-lib.umd.js +27 -27
  4. package/dist/hematournamentui-tailwind.css +23 -0
  5. package/dist/hematournamentui.css +1 -1
  6. package/package.json +8 -8
  7. package/src/stories/Molecules/Boxes/BoutBoxes/TimerBox/TimerBox.vue +1 -1
  8. package/src/stories/Molecules/Buttons/BaseButton/BaseButton.vue +1 -1
  9. package/src/stories/Molecules/Buttons/ButtonBar/ButtonBar.vue +1 -1
  10. package/src/stories/Molecules/Modals/DirectorModal/DirectorModal.vue +2 -2
  11. package/src/stories/Organisms/Cards/BoutCard/Variants/BoutCardActive/BoutCardActive.vue +25 -22
  12. package/src/stories/Organisms/Cards/BoutCard/Variants/BoutCardInactive/BoutCardInactive.vue +31 -29
  13. package/src/stories/Organisms/Cards/BoutCard/Variants/BoutCardWaiting/BoutCardWaiting.vue +2 -4
  14. package/src/stories/Organisms/Cards/KioskCard/KioskCard.vue +54 -35
  15. package/src/stories/Organisms/Cards/PenaltyCard/PenaltyCard.stories.js +6 -6
  16. package/src/stories/Organisms/Cards/PenaltyCard/PenaltyCard.vue +64 -53
  17. package/src/stories/Organisms/Cards/PenaltyFencerCard/PenaltyFencerCard.stories.js +6 -7
  18. package/src/stories/Organisms/Cards/PenaltyFencerCard/PenaltyFencerCard.vue +18 -10
  19. package/src/stories/Organisms/Cards/StaffCard/StaffCard.vue +4 -4
  20. package/src/stories/Organisms/Cards/WaitlistFencerCard/WaitlistFencerCard.vue +129 -0
  21. package/src/stories/Organisms/ComplexInputs/DatePicker/DatePicker.vue +64 -45
  22. package/src/stories/Organisms/Containers/KioskContainer/KioskContainer.vue +13 -9
  23. package/src/stories/Organisms/Containers/Pool/Pool.vue +1 -1
  24. package/src/stories/Organisms/Containers/PoolResults/PoolResultsTable.vue +35 -20
  25. package/src/stories/Organisms/Headers/AttendanceSummary/AttendanceSummary.vue +45 -19
  26. package/src/stories/Templates/Assignment/Assignment.stories.js +17 -15
  27. package/src/stories/Templates/Assignment/Assignment.vue +71 -40
  28. package/src/stories/Templates/ClubManagement/ClubBasic/ClubBasic.stories.js +49 -30
  29. package/src/stories/Templates/ClubManagement/ClubBasic/ClubBasic.vue +29 -28
  30. package/src/stories/Templates/ClubManagement/{ClubMangement.stories.js → ClubManagement.stories.js} +74 -59
  31. package/src/stories/Templates/ClubManagement/ClubManagement.vue +104 -92
  32. package/src/stories/Templates/EventManagement/Bracket/Bracket.vue +92 -97
  33. package/src/stories/Templates/EventManagement/EditEventInfo/EditEventInfo.stories.js +37 -33
  34. package/src/stories/Templates/EventManagement/EditEventInfo/EditEventInfo.vue +11 -14
  35. package/src/stories/Templates/EventManagement/EventAttendance/EventAttendance.stories.js +49 -14
  36. package/src/stories/Templates/EventManagement/EventAttendance/EventAttendance.vue +156 -62
  37. package/src/stories/Templates/EventManagement/EventFinalResults/EventFinalResults.stories.js +11 -10
  38. package/src/stories/Templates/EventManagement/EventFinalResults/EventFinalResults.vue +8 -8
  39. package/src/stories/Templates/EventManagement/KioskDisplay/KioskDisplay.stories.js +13 -16
  40. package/src/stories/Templates/EventManagement/KioskDisplay/KioskDisplay.vue +25 -25
  41. package/src/stories/Templates/EventManagement/Penalties/PenaltyReport.stories.js +25 -24
  42. package/src/stories/Templates/EventManagement/Penalties/PenaltyReport.vue +28 -34
  43. package/src/stories/Templates/EventManagement/PoolLive/PoolLive.stories.js +54 -19
  44. package/src/stories/Templates/EventManagement/PoolLive/PoolLive.vue +75 -68
  45. package/src/stories/Templates/EventManagement/PoolManagement/PoolManagement.stories.js +55 -45
  46. package/src/stories/Templates/EventManagement/PoolManagement/PoolManagement.vue +47 -55
  47. package/src/stories/Templates/EventManagement/PoolResults/PoolResults.stories.js +56 -55
  48. package/src/stories/Templates/EventManagement/PoolResults/PoolResults.vue +71 -73
  49. package/src/stories/Templates/EventManagement/StaffList/StaffList.stories.js +18 -16
  50. package/src/stories/Templates/EventManagement/StaffList/StaffList.vue +9 -6
  51. package/src/stories/Templates/Menus/Admin/AdminLeftMenu.stories.js +22 -19
  52. package/src/stories/Templates/Menus/Admin/AdminLeftMenu.vue +44 -36
  53. package/src/stories/Templates/Menus/EditEventsTopMenu/EditEventsTopMenu.stories.js +30 -23
  54. package/src/stories/Templates/Menus/EditEventsTopMenu/EditEventsTopMenu.vue +55 -58
  55. package/src/stories/Templates/PersonManagement/Admin/Administration/Administration.stories.js +67 -0
  56. package/src/stories/Templates/PersonManagement/Admin/{Administration.vue → Administration/Administration.vue} +94 -87
  57. package/src/stories/Templates/PersonManagement/Admin/FencerAdmin/FencerAdmin.stories.js +71 -0
  58. package/src/stories/Templates/PersonManagement/Admin/{FencerAdmin.vue → FencerAdmin/FencerAdmin.vue} +90 -77
  59. package/src/stories/Templates/PersonManagement/Admin/MergeAccounts/MergeAccounts.stories.js +86 -0
  60. package/src/stories/Templates/PersonManagement/Admin/{MergeAccounts.vue → MergeAccounts/MergeAccounts.vue} +258 -242
  61. package/src/stories/Templates/PersonManagement/Attendance/Attendance.vue +28 -28
  62. package/src/stories/Templates/PersonManagement/PersonManagement.vue +1 -1
  63. package/src/stories/Templates/TournamentManagement/ListEvents/ListEvents.stories.js +45 -28
  64. package/src/stories/Templates/TournamentManagement/ListEvents/ListEvents.vue +22 -16
  65. package/src/stories/Templates/TournamentManagement/{TournamentMangement.stories.js → TournamentManagement.stories.js} +68 -39
  66. package/src/stories/Templates/TournamentManagement/TournamentManagement.vue +199 -153
  67. package/src/stories/Templates/TournamentManagement/TournamentPageOne/TournamentPageOne.stories.js +113 -0
  68. package/src/stories/Templates/TournamentManagement/TournamentPageOne/TournamentPageOne.vue +123 -106
  69. package/src/stories/Templates/TournamentManagement/TournamentPageTwo/TournamentPageTwo.stories.js +76 -31
  70. package/src/stories/Templates/TournamentManagement/TournamentPageTwo/{TouranmentPageTwo.vue → TournamentPageTwo.vue} +63 -44
  71. package/src/stories/Templates/PersonManagement/Admin/FencerAdmin.stories.js +0 -48
  72. package/src/stories/Templates/TournamentManagement/TournamentPageOne/TouranmentPageOne.stories.js +0 -63
@@ -20,11 +20,11 @@
20
20
  </div>
21
21
  </TabBar>
22
22
  </section>
23
- <section v-if="activeDropdown" class="bg-eventBoxBlue rounded w-full -mt-4 grid grid-cols-4 gap-4 pt-3 pb-1">
24
- <div v-for="item in selectedDropdownItem" class="flex flex-col items-center justify-center mb-2 mr-2">
25
- <BaseIcon size="md" :iconName="item.icon" :color="item.color" class="w-6 mb-1 text-center"/>
26
- <BaseText size="xs" :color="item.color" :text="item.label" @click="handleButtonClick(item.id)" class="text-center"/>
27
- </div>
23
+ <section v-if="activeDropdown" class="bg-eventBoxBlue rounded w-full -mt-4 grid grid-cols-4 gap-4 pt-3 pb-1">
24
+ <div v-for="item in selectedDropdownItems" :key="item.id" class="flex flex-col items-center justify-center mb-2 mr-2">
25
+ <BaseIcon size="md" :iconName="item.icon" :color="item.color" class="w-6 mb-1 text-center"/>
26
+ <BaseText size="xs" :color="item.color" :text="item.label" @click="handleButtonClick(item.id)" class="text-center"/>
27
+ </div>
28
28
  </section>
29
29
  </div>
30
30
  </template>
@@ -32,71 +32,68 @@
32
32
 
33
33
  <script>
34
34
  import TabBar from "../../../Molecules/Menus/TabBar/TabBar.vue";
35
- import BaseButton from "../../../Molecules/Buttons/BaseButton/BaseButton.vue";
36
- import BaseText from "../../../Atoms/Text/BaseText.vue";
37
- import BaseIcon from "../../../Atoms/Icon/BaseIcon.vue";
38
- import DropDownMenu from "../../../Organisms/ComplexInputs/DropDown/DropDownMenu.vue";
39
-
40
- export default {
41
- components: {
42
- DropDownMenu,
43
- BaseIcon,
44
- BaseText,
45
- TabBar,
35
+ import BaseButton from "../../../Molecules/Buttons/BaseButton/BaseButton.vue";
36
+ import BaseText from "../../../Atoms/Text/BaseText.vue";
37
+ import BaseIcon from "../../../Atoms/Icon/BaseIcon.vue";
38
+
39
+ export default {
40
+ components: {
41
+ BaseIcon,
42
+ BaseText,
43
+ TabBar,
46
44
  BaseButton
47
45
  },
48
46
  emits: ['tabMenuClick'],
49
47
  props: {
50
- currentTab: {
51
- type: String,
52
- required: true,
53
- default: ''
54
- },
55
- tabs: {
56
- type: Array,
57
- required: true,
58
- default: () => []
59
- }
60
- },
61
- data() {
62
- return {
63
- windowWidth: window.innerWidth,
64
- activeDropdown: null,
65
- selectedDropdownItem: []
66
- };
67
- },
68
- computed: {
69
- isMobile() {
70
- return this.windowWidth <= 748;
71
- },
72
- },
73
- mounted() {
74
- window.addEventListener('resize', this.handleResize);
75
- },
48
+ currentTab: {
49
+ type: String,
50
+ default: ''
51
+ },
52
+ tabs: {
53
+ type: Array,
54
+ default: () => []
55
+ }
56
+ },
57
+ data() {
58
+ return {
59
+ windowWidth: 1024,
60
+ activeDropdown: null,
61
+ };
62
+ },
63
+ computed: {
64
+ isMobile() {
65
+ return this.windowWidth <= 748;
66
+ },
67
+ selectedDropdownItems() {
68
+ return this.tabs.find((tab) => tab.id === this.activeDropdown)?.children || [];
69
+ },
70
+ },
71
+ mounted() {
72
+ this.handleResize();
73
+ window.addEventListener('resize', this.handleResize);
74
+ },
76
75
  beforeUnmount() {
77
76
  window.removeEventListener('resize', this.handleResize);
78
77
  },
79
78
  methods: {
80
79
  handleButtonClick(buttonId) {
81
80
  const selectedTab = this.tabs.find((tab) => tab.id === buttonId);
82
- if (selectedTab && selectedTab.children && this.isMobile) {
83
- this.activeDropdown = this.activeDropdown === buttonId ? null : buttonId;
84
- this.selectedDropdownItem = this.activeDropdown ? selectedTab.children : [];
85
- return
86
- }
87
-
88
- this.activeDropdown = null;
89
- this.selectedDropdownItem = [];
90
-
91
- this.$emit('tabMenuClick', buttonId);
81
+ if (selectedTab && selectedTab.children && this.isMobile) {
82
+ this.activeDropdown = this.activeDropdown === buttonId ? null : buttonId;
83
+ return
84
+ }
85
+
86
+ this.activeDropdown = null;
87
+
88
+ this.$emit('tabMenuClick', buttonId);
92
89
  },
93
90
  getIconName(tab) {
94
91
  if (this.isMobile) return tab.icon;
95
92
  return '';
96
- },
97
- handleResize() {
98
- this.windowWidth = window.innerWidth;
99
- }
100
- }
101
- }
93
+ },
94
+ handleResize() {
95
+ this.windowWidth = window?.innerWidth || 1024;
96
+ }
97
+ }
98
+ }
102
99
  </script>
@@ -0,0 +1,67 @@
1
+ import Administration from './Administration.vue';
2
+ import personsMock from "../../../../../mocks/personsMock.js";
3
+
4
+ export default {
5
+ title: 'Templates/PersonManagement/Admin/Administration',
6
+ component: Administration,
7
+ tags: ['autodocs'],
8
+ args: {
9
+ person: personsMock[1],
10
+ userLevel: 'Club'
11
+ },
12
+ argTypes: {
13
+ person: { control: { type: 'object' } },
14
+ userLevel: {
15
+ control: { type: 'select' },
16
+ options: ['User', 'Director', 'Club', 'Admin']
17
+ },
18
+ 'update:person': { action: 'update:person' }
19
+ }
20
+ };
21
+
22
+ export const Default = {
23
+ args: {
24
+ person: personsMock[1],
25
+ userLevel: 'Club'
26
+ }
27
+ };
28
+
29
+ export const AdminCanSelectAdminAccess = {
30
+ args: {
31
+ person: {
32
+ ...personsMock[1],
33
+ AccessLevel: 'Admin'
34
+ },
35
+ userLevel: 'Admin'
36
+ }
37
+ };
38
+
39
+ export const AdminEditingUserAccess = {
40
+ args: {
41
+ person: {
42
+ ...personsMock[1],
43
+ AccessLevel: 'User'
44
+ },
45
+ userLevel: 'Admin'
46
+ }
47
+ };
48
+
49
+ export const WithoutHemaRating = {
50
+ args: {
51
+ person: {
52
+ ...personsMock[1],
53
+ HemaRatingsId: ''
54
+ },
55
+ userLevel: 'Club'
56
+ }
57
+ };
58
+
59
+ export const EmptyAccessLevel = {
60
+ args: {
61
+ person: {
62
+ ...personsMock[1],
63
+ AccessLevel: ''
64
+ },
65
+ userLevel: 'Club'
66
+ }
67
+ };
@@ -1,87 +1,94 @@
1
- <template>
2
- <section class="mt-2">
3
- <div class="flex flex-col mb-4">
4
- <TitledInput
5
- :inputValue="personId"
6
- :inputType="'number'"
7
- placeholder="Meyer Squared ID"
8
- title="Meyer Squared ID"
9
- :disabled="true"
10
- aria-disabled="true"
11
- />
12
- </div>
13
-
14
- <div class="flex flex-col mb-4">
15
- <TitledInput
16
- :inputValue="hemaRatingId"
17
- :inputType="'number'"
18
- placeholder="HEMA Rating ID"
19
- title="HEMA Rating ID"
20
- @update:value="emitUpdate('HemaRatingsId', $event)"
21
- />
22
- </div>
23
-
24
- <div class="flex flex-col mb-4">
25
- <BaseText text="Access Level" size="sm" color="quaternary"/>
26
- <DropDownMenu
27
- :label="getAccessLevelLabel"
28
- :items="accessLevels"
29
- class="pb-2"
30
- :selectedItem="getSelectedAccessLevel"
31
- @update:selectedItem="emitUpdate('AccessLevel', $event.text)"
32
- width="w-full"
33
- dropDownWidth="w-full"
34
- />
35
- </div>
36
- </section>
37
- </template>
38
-
39
- <script>
40
- import TitledInput from "../../../Molecules/CombinationInputs/TitledInput/TitledInput.vue";
41
- import BaseText from "../../../Atoms/Text/BaseText.vue";
42
- import DropDownMenu from "../../../Organisms/ComplexInputs/DropDown/DropDownMenu.vue";
43
-
44
- export default {
45
- name: "Administration",
46
- emits: ["update:person"],
47
- components: { TitledInput, BaseText, DropDownMenu },
48
- props: {
49
- person: { type: Object, required: true },
50
- userLevel: { type: String, required: true },
51
- },
52
- computed: {
53
- personId() {
54
- return this.person?.PersonId ?? "";
55
- },
56
- hemaRatingId() {
57
- return this.person?.HEMARatings?.[0]?.HemaRatingId ?? "";
58
- },
59
- accessLevels() {
60
- if (this.userLevel === "Admin") {
61
- return [
62
- { text: "User", link: "User" },
63
- { text: "Director", link: "Director" },
64
- { text: "Club", link: "Club" },
65
- { text: "Admin", link: "Admin" },
66
- ];
67
- }
68
- return [
69
- { text: "User", link: "User" },
70
- { text: "Director", link: "Director" },
71
- { text: "Club", link: "Club" },
72
- ];
73
- },
74
- getSelectedAccessLevel() {
75
- return { text: this.person.AccessLevel, link: this.person.AccessLevel };
76
- },
77
- getAccessLevelLabel() {
78
- return this.person.AccessLevel ? "" : "Select Access Level";
79
- },
80
- },
81
- methods: {
82
- emitUpdate(field, value) {
83
- this.$emit("update:person", { field, value });
84
- },
85
- },
86
- };
87
- </script>
1
+ <template>
2
+ <section class="mt-2">
3
+ <div class="flex flex-col mb-4">
4
+ <TitledInput
5
+ :inputValue="personId"
6
+ :inputType="'number'"
7
+ placeholder="Meyer Squared ID"
8
+ title="Meyer Squared ID"
9
+ :disabled="true"
10
+ aria-disabled="true"
11
+ />
12
+ </div>
13
+
14
+ <div class="flex flex-col mb-4">
15
+ <TitledInput
16
+ :inputValue="hemaRatingId"
17
+ :inputType="'number'"
18
+ placeholder="HEMA Rating ID"
19
+ title="HEMA Rating ID"
20
+ @update:value="emitUpdate('HemaRatingsId', $event)"
21
+ />
22
+ </div>
23
+
24
+ <div class="flex flex-col mb-4">
25
+ <BaseText text="Access Level" size="sm" color="quaternary"/>
26
+ <DropDownMenu
27
+ :key="accessLevelDropdownKey"
28
+ :label="accessLevelLabel"
29
+ :items="accessLevels"
30
+ class="pb-2"
31
+ :selectedItem="selectedAccessLevel"
32
+ @update:selectedItem="emitUpdate('AccessLevel', $event.text)"
33
+ width="w-full"
34
+ dropDownWidth="w-full"
35
+ />
36
+ </div>
37
+ </section>
38
+ </template>
39
+
40
+ <script>
41
+ import TitledInput from "../../../../Molecules/CombinationInputs/TitledInput/TitledInput.vue";
42
+ import BaseText from "../../../../Atoms/Text/BaseText.vue";
43
+ import DropDownMenu from "../../../../Organisms/ComplexInputs/DropDown/DropDownMenu.vue";
44
+
45
+ const STANDARD_ACCESS_LEVELS = [
46
+ { text: "User", link: "User" },
47
+ { text: "Director", link: "Director" },
48
+ { text: "Club", link: "Club" },
49
+ ];
50
+
51
+ const ADMIN_ACCESS_LEVELS = [
52
+ ...STANDARD_ACCESS_LEVELS,
53
+ { text: "Admin", link: "Admin" },
54
+ ];
55
+
56
+ export default {
57
+ name: "Administration",
58
+ emits: ["update:person"],
59
+ components: { TitledInput, BaseText, DropDownMenu },
60
+ props: {
61
+ person: { type: Object, required: true },
62
+ userLevel: { type: String, required: true },
63
+ },
64
+ computed: {
65
+ personId() {
66
+ return this.person?.PersonId ?? "";
67
+ },
68
+ hemaRatingId() {
69
+ return this.person?.HemaRatingsId ?? this.person?.HEMARatings?.[0]?.HemaRatingId ?? "";
70
+ },
71
+ accessLevels() {
72
+ if (this.userLevel === "Admin") {
73
+ return ADMIN_ACCESS_LEVELS;
74
+ }
75
+
76
+ return STANDARD_ACCESS_LEVELS;
77
+ },
78
+ selectedAccessLevel() {
79
+ return { text: this.person.AccessLevel, link: this.person.AccessLevel };
80
+ },
81
+ accessLevelLabel() {
82
+ return this.person.AccessLevel ? "" : "Select Access Level";
83
+ },
84
+ accessLevelDropdownKey() {
85
+ return `${this.userLevel}-${this.person.AccessLevel || "none"}`;
86
+ },
87
+ },
88
+ methods: {
89
+ emitUpdate(field, value) {
90
+ this.$emit("update:person", { field, value });
91
+ },
92
+ },
93
+ };
94
+ </script>
@@ -0,0 +1,71 @@
1
+ import FencerAdmin from './FencerAdmin.vue';
2
+ import personsMock from "../../../../../mocks/personsMock.js";
3
+ import peopleMock from "../../../../../mocks/personGetAllMock.js";
4
+
5
+ export default {
6
+ title: 'Templates/PersonManagement/Admin/FencerAdmin',
7
+ component: FencerAdmin,
8
+ tags: ['autodocs'],
9
+ args: {
10
+ person: personsMock[1],
11
+ people: peopleMock,
12
+ userLevel: 'Club',
13
+ canMergeAccounts: null
14
+ },
15
+ argTypes: {
16
+ person: { control: { type: 'object' } },
17
+ people: { control: { type: 'object' } },
18
+ userLevel: {
19
+ control: { type: 'select' },
20
+ options: ['User', 'Director', 'Club', 'Admin']
21
+ },
22
+ canMergeAccounts: { control: { type: 'boolean' } },
23
+ 'update:person': { action: 'update:person' },
24
+ 'merge:merge': { action: 'merge:merge' }
25
+ }
26
+ };
27
+
28
+ export const ClubUser = {
29
+ args: {
30
+ person: {
31
+ ...personsMock[1],
32
+ AccessLevel: 'Club'
33
+ },
34
+ people: peopleMock,
35
+ userLevel: 'Club'
36
+ }
37
+ };
38
+
39
+ export const AdminViewingUser = {
40
+ args: {
41
+ person: {
42
+ ...personsMock[1],
43
+ AccessLevel: 'User'
44
+ },
45
+ people: peopleMock,
46
+ userLevel: 'Admin'
47
+ }
48
+ };
49
+
50
+ export const AdminViewingAdmin = {
51
+ args: {
52
+ person: {
53
+ ...personsMock[1],
54
+ AccessLevel: 'Admin'
55
+ },
56
+ people: peopleMock,
57
+ userLevel: 'Admin'
58
+ }
59
+ };
60
+
61
+ export const MergeDisabledByParent = {
62
+ args: {
63
+ person: {
64
+ ...personsMock[1],
65
+ AccessLevel: 'User'
66
+ },
67
+ people: peopleMock,
68
+ userLevel: 'Admin',
69
+ canMergeAccounts: false
70
+ }
71
+ };
@@ -1,77 +1,90 @@
1
- <template>
2
- <section class="mt-2 min-h-80">
3
- <!-- Administration section -->
4
- <div class="pb-6">
5
- <BaseText text="Administration" size="lg" color="primary" />
6
- <div class="mt-3">
7
- <Administration
8
- :person="person"
9
- :userLevel="userLevel"
10
- @update:person="$emit('update:person', $event)"
11
- />
12
- </div>
13
- </div>
14
-
15
- <!-- Merge Accounts section (collapsible) -->
16
- <div v-if="userLevel === 'Admin'" class="pt-6 border-t border-dropdownSelect">
17
- <button
18
- type="button"
19
- class="w-full flex items-center justify-between text-left"
20
- @click="toggleMergeOpen"
21
- >
22
- <div>
23
- <BaseText text="Merge Accounts" size="lg" color="primary" />
24
- <BaseText
25
- class="mt-1"
26
- text="Merge other fencer accounts into this one. This will move all references and delete the duplicate accounts."
27
- size="sm"
28
- color="quaternary"
29
- />
30
- </div>
31
-
32
- <!-- Optional caret (swap for your icon system if preferred) -->
33
- <span
34
- class="ml-4 text-quaternary transition-transform duration-200"
35
- :class="mergeOpen ? 'rotate-180' : 'rotate-0'"
36
- aria-hidden="true"
37
- >
38
-
39
- </span>
40
- </button>
41
-
42
- <div v-if="mergeOpen" class="mt-4">
43
- <MergeAccounts :person="person" :people="people" @merge:merge="doMerge" />
44
- </div>
45
- </div>
46
- </section>
47
- </template>
48
-
49
- <script>
50
- import BaseText from "../../../Atoms/Text/BaseText.vue";
51
- import Administration from "./Administration.vue";
52
- import MergeAccounts from "./MergeAccounts.vue";
53
-
54
- export default {
55
- name: "FencerAdmin",
56
- emits: ["update:person", "merge:merge"],
57
- components: { BaseText, Administration, MergeAccounts },
58
- props: {
59
- person: { type: Object, required: true },
60
- people: { type: Array, required: true },
61
- userLevel: { type: String, required: true },
62
- },
63
- data() {
64
- return {
65
- mergeOpen: false, // collapsed by default
66
- };
67
- },
68
- methods: {
69
- toggleMergeOpen() {
70
- this.mergeOpen = !this.mergeOpen;
71
- },
72
- doMerge(data) {
73
- this.$emit("merge:merge", data);
74
- }
75
- },
76
- };
77
- </script>
1
+ <template>
2
+ <section class="mt-2 min-h-80">
3
+ <div class="pb-6">
4
+ <BaseText text="Administration" size="lg" color="primary" />
5
+ <div class="mt-3">
6
+ <Administration
7
+ :person="person"
8
+ :userLevel="userLevel"
9
+ @update:person="$emit('update:person', $event)"
10
+ />
11
+ </div>
12
+ </div>
13
+
14
+ <div v-if="showMergeAccounts" class="pt-6 border-t border-dropdownSelect">
15
+ <button
16
+ :id="mergeAccountsToggleId"
17
+ type="button"
18
+ class="w-full flex items-center justify-between text-left"
19
+ :aria-expanded="mergeOpen"
20
+ :aria-controls="mergeAccountsPanelId"
21
+ @click="toggleMergeOpen"
22
+ >
23
+ <div>
24
+ <BaseText text="Merge Accounts" size="lg" color="primary" />
25
+ <BaseText
26
+ class="mt-1"
27
+ text="Merge other fencer accounts into this one. This will move all references and delete the duplicate accounts."
28
+ size="sm"
29
+ color="quaternary"
30
+ />
31
+ </div>
32
+
33
+ <span
34
+ class="fa-solid fa-chevron-down ml-4 text-quaternary transition-transform duration-200"
35
+ :class="mergeOpen ? 'rotate-180' : 'rotate-0'"
36
+ aria-hidden="true"
37
+ />
38
+ </button>
39
+
40
+ <div v-if="mergeOpen" :id="mergeAccountsPanelId" class="mt-4">
41
+ <MergeAccounts :person="person" :people="people" @merge:merge="emitMergeAccounts" />
42
+ </div>
43
+ </div>
44
+ </section>
45
+ </template>
46
+
47
+ <script>
48
+ import BaseText from "../../../../Atoms/Text/BaseText.vue";
49
+ import Administration from "../Administration/Administration.vue";
50
+ import MergeAccounts from "../MergeAccounts/MergeAccounts.vue";
51
+
52
+ export default {
53
+ name: "FencerAdmin",
54
+ emits: ["update:person", "merge:merge"],
55
+ components: { BaseText, Administration, MergeAccounts },
56
+ props: {
57
+ person: { type: Object, required: true },
58
+ people: { type: Array, required: true },
59
+ userLevel: { type: String, required: true },
60
+ canMergeAccounts: { type: Boolean, default: null },
61
+ },
62
+ data() {
63
+ return {
64
+ mergeOpen: false,
65
+ };
66
+ },
67
+ computed: {
68
+ showMergeAccounts() {
69
+ return this.canMergeAccounts ?? this.userLevel === "Admin";
70
+ },
71
+ personIdForDom() {
72
+ return this.person?.PersonId ?? "unknown";
73
+ },
74
+ mergeAccountsToggleId() {
75
+ return `merge-accounts-toggle-${this.personIdForDom}`;
76
+ },
77
+ mergeAccountsPanelId() {
78
+ return `merge-accounts-panel-${this.personIdForDom}`;
79
+ },
80
+ },
81
+ methods: {
82
+ toggleMergeOpen() {
83
+ this.mergeOpen = !this.mergeOpen;
84
+ },
85
+ emitMergeAccounts(data) {
86
+ this.$emit("merge:merge", data);
87
+ },
88
+ },
89
+ };
90
+ </script>