@dcrackel/meyersquaredui 1.0.43 → 1.0.44

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 (73) hide show
  1. package/dist/meyersquaredui.es.js +615 -492
  2. package/dist/meyersquaredui.umd.js +1 -1
  3. package/package.json +4 -3
  4. package/src/index.js +1 -1
  5. package/src/mocks/getAllClubs.js +106 -0
  6. package/src/mocks/getClubById.js +130 -0
  7. package/src/mocks/getFencersByWeapon.js +2167 -0
  8. package/src/mocks/getTouranmentDetailsMock.js +92 -0
  9. package/src/stories/Atoms/BaseButton/BaseButton.vue +5 -3
  10. package/src/stories/Atoms/BaseText/BaseText.vue +1 -1
  11. package/src/stories/Atoms/Icon/Icon.vue +4 -2
  12. package/src/stories/Atoms/InputField/InputField.stories.js +28 -9
  13. package/src/stories/Atoms/InputField/InputField.vue +20 -2
  14. package/src/stories/Molecules/Calendar/Calendar.stories.js +39 -0
  15. package/src/stories/Molecules/Calendar/Calendar.vue +110 -0
  16. package/src/stories/Molecules/DropDowns/BasicDropDown.stories.js +31 -0
  17. package/src/stories/Molecules/DropDowns/BasicDropDown.vue +78 -0
  18. package/src/stories/Molecules/MapBox/MapBox.stories.js +30 -0
  19. package/src/stories/Molecules/MapBox/MapBox.vue +67 -0
  20. package/src/stories/Molecules/SearchBox/SearchBox.vue +2 -1
  21. package/src/stories/Molecules/SearchBox/Searchbox.stories.js +1 -1
  22. package/src/stories/Organisms/Cards/ArticleCard/ArticleCard.vue +8 -3
  23. package/src/stories/Organisms/Cards/ClubListCard/CLubListCard.stories.js +31 -0
  24. package/src/stories/Organisms/Cards/ClubListCard/ClubListCard.vue +72 -0
  25. package/src/stories/Organisms/Cards/ClubMember/ClubMember.stories.js +40 -0
  26. package/src/stories/Organisms/Cards/ClubMember/ClubMember.vue +56 -0
  27. package/src/stories/Organisms/Cards/EventListCard/EventListCard.stories.js +38 -0
  28. package/src/stories/Organisms/Cards/EventListCard/EventListCard.vue +64 -0
  29. package/src/stories/Organisms/Cards/FencerCard/FencerCard.vue +3 -5
  30. package/src/stories/Organisms/Cards/FencerListCard/FencerListCard.stories.js +30 -0
  31. package/src/stories/Organisms/Cards/FencerListCard/FencerListCard.vue +86 -0
  32. package/src/stories/Organisms/Cards/PhotoCard/PhotoCard.stories.js +28 -0
  33. package/src/stories/Organisms/Cards/PhotoCard/PhotoCard.vue +18 -0
  34. package/src/stories/Organisms/Cards/SocialMediaLinkCard/SocialMediaLinkCard.stories.js +40 -0
  35. package/src/stories/Organisms/Cards/SocialMediaLinkCard/SocialMediaLinkCard.vue +54 -0
  36. package/src/stories/Organisms/Cards/TournamentCard/TournamentCard.stories.js +1 -1
  37. package/src/stories/Organisms/Cards/TournamentCard/TournamentCard.vue +7 -2
  38. package/src/stories/Organisms/Cards/TournamentDetails/TournamentDetails.stories.js +35 -0
  39. package/src/stories/Organisms/Cards/TournamentDetails/TournamentDetails.vue +59 -0
  40. package/src/stories/Organisms/Cards/TournamentListCard/TournamentListCard.stories.js +26 -0
  41. package/src/stories/Organisms/Cards/TournamentListCard/TournamentListCard.vue +103 -0
  42. package/src/stories/Organisms/Column/HostColumn.stories.js +39 -0
  43. package/src/stories/Organisms/Column/HostColumn.vue +105 -0
  44. package/src/stories/Organisms/GridLayout/GridLayout.vue +28 -8
  45. package/src/stories/Organisms/Headers/ClubHeader/ClubHeader.stories.js +21 -0
  46. package/src/stories/Organisms/Headers/ClubHeader/ClubHeader.vue +58 -0
  47. package/src/stories/Organisms/Headers/LeaderboardHeader/LeaderboardHeader.stories.js +29 -0
  48. package/src/stories/Organisms/Headers/LeaderboardHeader/LeaderboardHeader.vue +59 -0
  49. package/src/stories/Organisms/Headers/{Header.stories.js → PageHeader/PageHeader.stories.js} +2 -2
  50. package/src/stories/Organisms/Headers/PageHeader/PageHeader.vue +101 -0
  51. package/src/stories/Organisms/Headers/TournamentHeader/TournamentHeader.stories.js +34 -0
  52. package/src/stories/Organisms/Headers/TournamentHeader/TournamentHeader.vue +73 -0
  53. package/src/stories/Organisms/HeroBanners/HomePage/HeroBanner.stories.js +3 -3
  54. package/src/stories/Organisms/HeroBanners/HomePage/HeroBanner.vue +1 -1
  55. package/src/stories/Organisms/HeroBanners/TournamentDetails/TournamentDetailsBanner.stories.js +39 -0
  56. package/src/stories/Organisms/HeroBanners/TournamentDetails/TournamentDetailsBanner.vue +129 -0
  57. package/src/stories/Organisms/HeroBanners/Tournaments/TournamentBanner.stories.js +25 -0
  58. package/src/stories/Organisms/HeroBanners/Tournaments/TournamentBanner.vue +79 -0
  59. package/src/stories/Organisms/SectionBanners/DoubleButtonBanner/DoubleButtonBanner.vue +4 -0
  60. package/src/stories/Organisms/SectionBanners/SingleButtonBanner/SingleButtonBanner.vue +1 -1
  61. package/src/stories/Templates/ClubDetailPage/ClubDetailPage.stories.js +43 -0
  62. package/src/stories/Templates/ClubDetailPage/ClubDetailPage.vue +127 -0
  63. package/src/stories/Templates/ClubListPage/ClubListPage.stories.js +43 -0
  64. package/src/stories/Templates/ClubListPage/ClubListPage.vue +84 -0
  65. package/src/stories/Templates/HomePage/HomePage.stories.js +6 -6
  66. package/src/stories/Templates/HomePage/HomePage.vue +20 -13
  67. package/src/stories/Templates/Leaderboard/Leaderboard.stories.js +43 -0
  68. package/src/stories/Templates/Leaderboard/Leaderboard.vue +93 -0
  69. package/src/stories/Templates/TournamentDetailPage/TournamentDetail.stories.js +32 -0
  70. package/src/stories/Templates/TournamentDetailPage/TournamentDetailPage.vue +121 -0
  71. package/src/stories/Templates/TournamentListPage/TournamentListPage.stories.js +41 -0
  72. package/src/stories/Templates/TournamentListPage/TournamentListPage.vue +91 -0
  73. package/src/stories/Organisms/Headers/Header.vue +0 -62
@@ -0,0 +1,92 @@
1
+ const mockTournamentDetails =
2
+ {
3
+ "TournamentId": 9,
4
+ "Name": "Queen's Court",
5
+ "StartDate": "2024-07-20",
6
+ "EndDate": "2024-07-21",
7
+ "RegistrationCutOff": "2024-07-20",
8
+ "Description": "Queen City Sword GuildΓÇÖs first tournament, featuring steel longsword.",
9
+ "HostedOnM2": true,
10
+ "TotalParticipants": 77,
11
+ "Events": [
12
+ {
13
+ "EventId": 1,
14
+ "EventName": "Longsword Open",
15
+ "Date": "2024-05-03",
16
+ "StartTime": "12:00:16",
17
+ "ParticipantsCount": 13,
18
+ "Weapon": {
19
+ "Name": "Longsword"
20
+ }
21
+ },
22
+ {
23
+ "EventId": 8,
24
+ "EventName": "Longsword B",
25
+ "Date": "2024-07-20",
26
+ "StartTime": "09:00:00",
27
+ "ParticipantsCount": 26,
28
+ "Weapon": {
29
+ "Name": "Longsword"
30
+ }
31
+ },
32
+ {
33
+ "EventId": 9,
34
+ "EventName": "Longsword A",
35
+ "Date": "2024-07-20",
36
+ "StartTime": "13:00:00",
37
+ "ParticipantsCount": 15,
38
+ "Weapon": {
39
+ "Name": "Longsword"
40
+ }
41
+ },
42
+ {
43
+ "EventId": 10,
44
+ "EventName": "Messer",
45
+ "Date": "2024-07-21",
46
+ "StartTime": "09:00:00",
47
+ "ParticipantsCount": 23,
48
+ "Weapon": {
49
+ "Name": "Messer"
50
+ }
51
+ }
52
+ ],
53
+ "Club": {
54
+ "Name": "Queen City Sword Guild",
55
+ "ClubId": 23,
56
+ "Images": [
57
+ {
58
+ "ImageId": 34,
59
+ "URL": "https://meyersquared.com/images/Club12.png",
60
+ "AltText": "Queens City"
61
+ }
62
+ ]
63
+ },
64
+ "Address": {
65
+ "Name": "Test Location",
66
+ "City": "Delaware",
67
+ "State": "OH",
68
+ "Address1": "123 Anywhere",
69
+ "Zip": 43015,
70
+ "Coordinates": "40.2828592,-83.1118049"
71
+ },
72
+ "Images": [
73
+ {
74
+ "ImageId": 24,
75
+ "URL": "https://images.squarespace-cdn.com/content/v1/588e439e1b10e309aeed2280/1549377422004-9SSG2INBP1HGR5OK4DIN/FacebookMockup2.png?format=1000w",
76
+ "AltText": "Queen's Court"
77
+ }
78
+ ],
79
+ "PrimaryContact": {
80
+ "DisplayName": "Dwain Crackel",
81
+ "Images": [
82
+ {
83
+ "ImageId": 7,
84
+ "URL": "https://randomuser.me/api/portraits/men/22.jpg",
85
+ "AltText": null
86
+ }
87
+ ]
88
+ },
89
+ "TotalEvents": 4
90
+ }
91
+
92
+ export default mockTournamentDetails;
@@ -51,8 +51,10 @@ export default {
51
51
  },
52
52
  hoverColor: {
53
53
  type: String,
54
- default: '',
55
- validator: (value) => ['primary', 'secondary', 'accent'].includes(value),
54
+ default: null,
55
+ validator: (value) => {
56
+ return value === null || ['primary', 'secondary', 'accent'].includes(value);
57
+ },
56
58
  },
57
59
  backgroundColor: {
58
60
  type: String,
@@ -85,7 +87,7 @@ export default {
85
87
  iconType: {
86
88
  type: String,
87
89
  default: 'fa-solid',
88
- validator: (value) => ['fa-thin', 'fa-sharp'].includes(value),
90
+ validator: (value) => ['fa-brands','fa-solid','fa-thin', 'fa-sharp'].includes(value),
89
91
  },
90
92
  align: {
91
93
  type: String,
@@ -23,7 +23,7 @@ export default {
23
23
  },
24
24
  hoverColor: {
25
25
  type: String,
26
- default: '',
26
+ default: null,
27
27
  },
28
28
  weight: {
29
29
  type: String,
@@ -18,12 +18,12 @@ export default {
18
18
  size: {
19
19
  type: String,
20
20
  default: 'md',
21
- validator: (value) => ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl'].includes(value),
21
+ validator: (value) => ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl'].includes(value),
22
22
  },
23
23
  type: {
24
24
  type: String,
25
25
  default: 'fa-solid',
26
- validator: (value) => ['fa-thin', 'fa-sharp'].includes(value),
26
+ validator: (value) => ['fa-thin', 'fa-sharp', 'fa-kit', 'fa-brands', 'fa-solid','fa-regular'].includes(value),
27
27
  }
28
28
  },
29
29
  computed: {
@@ -44,6 +44,8 @@ export default {
44
44
  xl: 'text-xl',
45
45
  '2xl': 'text-2xl',
46
46
  '3xl': 'text-3xl',
47
+ '4xl': 'text-5xl',
48
+ '5xl': 'text-5xl'
47
49
  };
48
50
  return sizeMap[this.size] || 'text-base';
49
51
  },
@@ -3,15 +3,24 @@ import InputField from './InputField.vue';
3
3
  export default {
4
4
  title: 'Atoms/InputField',
5
5
  component: InputField,
6
- args: {
7
- type: 'text',
8
- placeholder: 'Search',
9
- modelValue: '',
10
- },
11
6
  argTypes: {
12
- type: { control: 'text' },
13
- placeholder: { control: 'text' },
14
- modelValue: { control: 'text' },
7
+ type: {
8
+ control: { type: 'text' },
9
+ defaultValue: 'text',
10
+ },
11
+ placeholder: {
12
+ control: { type: 'text' },
13
+ defaultValue: 'Search',
14
+ },
15
+ modelValue: {
16
+ control: { type: 'text' },
17
+ defaultValue: '',
18
+ },
19
+ color: {
20
+ control: { type: 'radio' },
21
+ options: ['primary', 'secondary'],
22
+ defaultValue: 'primary',
23
+ },
15
24
  },
16
25
  };
17
26
 
@@ -23,4 +32,14 @@ const Template = (args) => ({
23
32
  template: '<InputField v-bind="args" />',
24
33
  });
25
34
 
26
- export const Default = Template.bind({});
35
+ export const Primary = Template.bind({});
36
+ Primary.args = {
37
+ color: 'primary',
38
+ placeholder: 'Search in Primary Mode',
39
+ };
40
+
41
+ export const Secondary = Template.bind({});
42
+ Secondary.args = {
43
+ color: 'secondary',
44
+ placeholder: 'Search in Secondary Mode',
45
+ };
@@ -2,8 +2,13 @@
2
2
  <input
3
3
  :type="type"
4
4
  :placeholder="placeholder"
5
- v-bind="$attrs"
6
- class="bg-black text-secondary border-b-2 border-secondary focus:outline-none focus:border-accent w-full placeholder-secondary px-2 hover:border-accent duration-300 ease-in-out"
5
+ :value="modelValue"
6
+ :class="[
7
+ color === 'primary'
8
+ ? 'bg-primary text-secondary border-b-2 border-secondary focus:outline-none focus:border-accent w-full placeholder-secondary px-2 hover:border-accent duration-300 ease-in-out'
9
+ : 'text-primary bg-white border-b-2 border-secondary focus:outline-none focus:border-accent w-full placeholder-primary px-2 hover:border-accent duration-300 ease-in-out'
10
+ ,
11
+ ]"
7
12
  @input="$emit('update:modelValue', $event.target.value)"
8
13
  />
9
14
  </template>
@@ -24,6 +29,19 @@ export default {
24
29
  type: String,
25
30
  default: '',
26
31
  },
32
+ color: {
33
+ type: String,
34
+ default: 'primary',
35
+ validator: (value) => ['primary', 'secondary'].includes(value),
36
+ }
27
37
  },
38
+ computed: {
39
+ bgClass() {
40
+ return this.mode === 'primary' ? 'bg-primary text-secondary border-b-2 border-secondary focus:outline-none focus:border-accent w-full placeholder-secondary px-2 hover:border-accent duration-300 ease-in-out' : 'bg-secondary';
41
+ },
42
+ textClass() {
43
+ return this.mode === 'primary' ? 'text-primary' : 'text-primary';
44
+ }
45
+ }
28
46
  };
29
47
  </script>
@@ -0,0 +1,39 @@
1
+ import Calendar from './Calendar.vue';
2
+
3
+ export default {
4
+ title: 'Molecules/Calendar/Calendar',
5
+ component: Calendar,
6
+ argTypes: {
7
+ 'date-select': { action: 'date-select' },
8
+ tournaments: { control: 'array', description: 'List of tournaments with dates to highlight on the calendar' },
9
+ },
10
+ };
11
+
12
+ const Template = (args, { argTypes }) => ({
13
+ props: Object.keys(argTypes),
14
+ components: { Calendar },
15
+ template: '<Calendar v-bind="$props" @date-select="date-select" />',
16
+ });
17
+
18
+ export const Default = Template.bind({});
19
+ Default.args = {
20
+ tournaments: [
21
+ { id: 1, name: 'Tournament 1', date: '2024-09-15' },
22
+ { id: 2, name: 'Tournament 2', date: '2024-09-20' },
23
+ { id: 3, name: 'Tournament 3', date: '2024-09-25' },
24
+ ],
25
+ };
26
+
27
+ export const NoTournaments = Template.bind({});
28
+ NoTournaments.args = {
29
+ tournaments: [],
30
+ };
31
+
32
+ export const DifferentMonth = Template.bind({});
33
+ DifferentMonth.args = {
34
+ tournaments: [
35
+ { id: 1, name: 'Tournament A', date: '2024-10-05' },
36
+ { id: 2, name: 'Tournament B', date: '2024-10-12' },
37
+ { id: 3, name: 'Tournament C', date: '2024-10-20' },
38
+ ],
39
+ };
@@ -0,0 +1,110 @@
1
+ <template>
2
+ <div class="w-80 h-80 p-6 bg-primary rounded-lg shadow-md">
3
+ <!-- Header with Month and Navigation -->
4
+ <div class="flex justify-between items-center mb-4">
5
+ <BaseText tag="h2" size="sm" weight="normal" color="secondary">{{ monthYear }}</BaseText>
6
+
7
+ <div>
8
+ <button @click="prevMonth" class="text-secondary hover:text-accent mr-4">
9
+ &lt; <!-- Previous Month Button -->
10
+ </button>
11
+ <button @click="nextMonth" class="text-secondary hover:text-accent">
12
+ &gt; <!-- Next Month Button -->
13
+ </button>
14
+ </div>
15
+ </div>
16
+
17
+ <!-- Weekday Headers -->
18
+ <div class="grid grid-cols-7 gap-1 text-center font-bold text-sm text-gray-600 mb-2">
19
+ <div v-for="day in weekdays" :key="day">
20
+ <BaseText tag="p" size="xs" weight="bold" color="secondary">{{ day }}</BaseText>
21
+ </div>
22
+ </div>
23
+
24
+ <!-- Days Grid -->
25
+ <div class="grid grid-cols-7 gap-1 text-center">
26
+ <!-- Empty Cells for Days of the Previous Month -->
27
+ <div v-for="n in startDay" :key="'empty-' + n"></div>
28
+
29
+ <!-- Calendar Days -->
30
+ <div
31
+ v-for="(day, index) in daysInMonth"
32
+ :key="'day-' + day"
33
+ @click="dayClicked(day)"
34
+ class="flex justify-center items-center cursor-pointer p-2 rounded-full"
35
+ :class="{
36
+ 'bg-accent text-white': hasTournament(day),
37
+ 'hover:bg-gray-200': hasTournament(day),
38
+ 'text-gray-400': !hasTournament(day)
39
+ }"
40
+ >
41
+ <BaseText tag="p" size="xs" weight="thin" color="secondary">{{ day }}</BaseText>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </template>
46
+
47
+ <script>
48
+ import BaseText from "../../Atoms/BaseText/BaseText.vue";
49
+
50
+ export default {
51
+ name: 'Calendar',
52
+ components: {BaseText},
53
+ props: {
54
+ tournaments: {
55
+ type: Array,
56
+ default: () => []
57
+ },
58
+ },
59
+ data() {
60
+ return {
61
+ currentMonth: new Date().getMonth(),
62
+ currentYear: new Date().getFullYear(),
63
+ weekdays: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
64
+ };
65
+ },
66
+ computed: {
67
+ daysInMonth() {
68
+ const days = new Date(this.currentYear, this.currentMonth + 1, 0).getDate();
69
+ return Array.from({ length: days }, (_, i) => i + 1);
70
+ },
71
+ startDay() {
72
+ // Calculate the day of the week the month starts on (0=Sunday, 6=Saturday)
73
+ const start = new Date(this.currentYear, this.currentMonth, 1).getDay();
74
+ return start === 0 ? 6 : start - 1; // Adjust for Monday start
75
+ },
76
+ monthYear() {
77
+ return new Date(this.currentYear, this.currentMonth).toLocaleString('default', { month: 'long', year: 'numeric' });
78
+ }
79
+ },
80
+ methods: {
81
+ hasTournament(day) {
82
+ // Check if the day has any tournaments
83
+ const date = `${this.currentYear}-${String(this.currentMonth + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
84
+ return this.tournaments.some(tournament => tournament.date === date);
85
+ },
86
+ dayClicked(day) {
87
+ if (this.hasTournament(day)) {
88
+ const selectedDate = `${this.currentYear}-${String(this.currentMonth + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
89
+ this.$emit('date-select', selectedDate);
90
+ }
91
+ },
92
+ prevMonth() {
93
+ if (this.currentMonth === 0) {
94
+ this.currentMonth = 11;
95
+ this.currentYear--;
96
+ } else {
97
+ this.currentMonth--;
98
+ }
99
+ },
100
+ nextMonth() {
101
+ if (this.currentMonth === 11) {
102
+ this.currentMonth = 0;
103
+ this.currentYear++;
104
+ } else {
105
+ this.currentMonth++;
106
+ }
107
+ }
108
+ }
109
+ };
110
+ </script>
@@ -0,0 +1,31 @@
1
+ import BasicDropDown from './BasicDropDown.vue';
2
+
3
+ export default {
4
+ title: 'Molecules/DropDowns/BasicDropDown',
5
+ component: BasicDropDown,
6
+ argTypes: {
7
+ items: {
8
+ control: { type: 'array' },
9
+ defaultValue: ['All Weapons', 'Longsword', 'Saber', 'Rapier', 'Smallsword', 'Sword and Buckler']
10
+ },
11
+ selectedItem: {
12
+ control: { type: 'text' },
13
+ defaultValue: 'Longsword'
14
+ },
15
+ 'item-select': { action: 'item-select' },
16
+ },
17
+ };
18
+
19
+ const Template = (args) => ({
20
+ components: { BasicDropDown },
21
+ setup() {
22
+ return { args };
23
+ },
24
+ template: '<BasicDropDown v-bind="args" @item-select="args[\'item-select\']" />',
25
+ });
26
+
27
+ export const Default = Template.bind({});
28
+ Default.args = {
29
+ items: ['All Weapons', 'Longsword', 'Saber', 'Rapier', 'Smallsword', 'Sword and Buckler'],
30
+ defaultSelectedItem: 'Longsword',
31
+ };
@@ -0,0 +1,78 @@
1
+ <template>
2
+ <div class="relative w-48" ref="dropdownContainer">
3
+ <div @click="toggleDropdown" class="flex items-center cursor-pointer">
4
+ <BaseText
5
+ class="border-b-2 border-transparent hover:border-accent pb-1 duration-300 ease-in-out"
6
+ color="primary"
7
+ size="xs md"
8
+ tag="p"
9
+ weight="normal"
10
+ >
11
+ {{ selectedItem }}
12
+ </BaseText>
13
+ <Icon icon="fa-chevron-down" size="sm" color="primary" class="ml-4" />
14
+ </div>
15
+
16
+ <!-- Dropdown Menu -->
17
+ <div v-if="dropdownOpen" class="absolute top-full mt-1 w-48 bg-secondary border rounded-lg border-lineGrey shadow-xl z-20">
18
+ <ul>
19
+ <li v-for="item in items"
20
+ :key="item"
21
+ @click="selectWeapon(item)"
22
+ class="px-4 py-2 cursor-pointer hover:bg-hoverColor">
23
+ <BaseText color="primary" size="xs sm" tag="p" weight="bold">{{ item }}</BaseText>
24
+ </li>
25
+ </ul>
26
+ </div>
27
+ </div>
28
+ </template>
29
+
30
+ <script>
31
+ import BaseText from '../../Atoms/BaseText/BaseText.vue';
32
+ import Icon from '../../Atoms/Icon/Icon.vue';
33
+
34
+ export default {
35
+ name: 'BasicDropDown',
36
+ components: {
37
+ BaseText,
38
+ Icon
39
+ },
40
+ props: {
41
+ items: {
42
+ type: Array,
43
+ default: () => ['All Weapons', 'Longsword', 'Saber', 'Rapier', 'Smallsword', 'Sword and Buckler']
44
+ },
45
+ defaultSelectedItem: {
46
+ type: String,
47
+ default: ''
48
+ }
49
+ },
50
+ data() {
51
+ return {
52
+ selectedItem: this.defaultSelectedItem,
53
+ dropdownOpen: false
54
+ };
55
+ },
56
+ mounted() {
57
+ document.addEventListener('click', this.handleClickOutside);
58
+ },
59
+ beforeUnmount() {
60
+ document.removeEventListener('click', this.handleClickOutside);
61
+ },
62
+ methods: {
63
+ toggleDropdown() {
64
+ this.dropdownOpen = !this.dropdownOpen;
65
+ },
66
+ selectWeapon(weapon) {
67
+ this.$emit('item-select', weapon);
68
+ this.selectedItem = weapon;
69
+ this.dropdownOpen = false;
70
+ },
71
+ handleClickOutside(event) {
72
+ if (this.dropdownOpen && !this.$refs.dropdownContainer.contains(event.target)) {
73
+ this.dropdownOpen = false;
74
+ }
75
+ }
76
+ }
77
+ };
78
+ </script>
@@ -0,0 +1,30 @@
1
+ import Mapbox from './Mapbox.vue';
2
+
3
+ export default {
4
+ title: 'Molecules/Mapbox',
5
+ component: Mapbox,
6
+ };
7
+
8
+ const Template = (args) => ({
9
+ components: { Mapbox },
10
+ setup() {
11
+ return { args };
12
+ },
13
+ template: '<Mapbox v-bind="args" />',
14
+ });
15
+
16
+ export const Default = Template.bind({});
17
+ Default.args = {
18
+ apiKey: 'AIzaSyC5kuJeMLopgjHDqsQPjRZ6Fkg3PFydw9Q',
19
+ coordinates: { lat: 40.7128, lng: -74.006 },
20
+ zoom: 10,
21
+ isFullWidth: false,
22
+ };
23
+
24
+ export const FullWidth = Template.bind({});
25
+ FullWidth.args = {
26
+ apiKey: 'AIzaSyC5kuJeMLopgjHDqsQPjRZ6Fkg3PFydw9Q',
27
+ coordinates: { lat: 40.7128, lng: -74.006 },
28
+ zoom: 10,
29
+ isFullWidth: true,
30
+ };
@@ -0,0 +1,67 @@
1
+ <template>
2
+ <div>
3
+ <GoogleMap
4
+ :api-key="apiKey"
5
+ :class="mapClasses"
6
+ mapId="M2-Map1"
7
+ :center="center"
8
+ :zoom="zoom"
9
+ :clickable-icons="false"
10
+ :streetViewControl="false"
11
+ :fullscreenControl="false"
12
+ :mapTypeControl="false"
13
+ :disable-default-ui="false"
14
+ @click="openMap()"
15
+ >
16
+ <AdvancedMarker :options="{ position: center }" />
17
+ </GoogleMap>
18
+ </div>
19
+ </template>
20
+
21
+ <script>
22
+ import { GoogleMap, AdvancedMarker } from 'vue3-google-map';
23
+
24
+ export default {
25
+ name: "Mapbox",
26
+ components: {
27
+ GoogleMap,
28
+ AdvancedMarker,
29
+ },
30
+ props: {
31
+ apiKey: {
32
+ type: String,
33
+ required: true,
34
+ },
35
+ coordinates: {
36
+ type: Object,
37
+ default: () => ({ lat: 39.9533483, lng: -82.8270003 }),
38
+ },
39
+ zoom: {
40
+ type: Number,
41
+ default: 13,
42
+ },
43
+ isFullWidth: {
44
+ type: Boolean,
45
+ default: false,
46
+ },
47
+ },
48
+ data() {
49
+ return {
50
+ center: this.coordinates,
51
+ };
52
+ },
53
+ computed: {
54
+ mapClasses() {
55
+ return this.isFullWidth ? 'w-full h-80 mx-auto' : 'w-72 h-80 mx-auto';
56
+ },
57
+ },
58
+ methods: {
59
+ openMap() {
60
+ window.open(
61
+ `https://www.google.com/maps/search/?api=1&query=${this.center.lat},${this.center.lng}`,
62
+ '_blank'
63
+ );
64
+ },
65
+ },
66
+ };
67
+ </script>
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="relative flex items-center w-full max-w-md">
3
- <InputField v-model="searchQuery" placeholder="Search" />
3
+ <InputField v-model="searchQuery" placeholder="Search" color="primary"/>
4
4
  <Icon icon="fa-search" color="secondary" size="sm" class="absolute right-2" @click="onSearch" />
5
5
  </div>
6
6
  </template>
@@ -23,6 +23,7 @@ export default {
23
23
  methods: {
24
24
  onSearch() {
25
25
  console.log('Search Query:', this.searchQuery);
26
+ this.$emit('search', this.searchQuery);
26
27
  },
27
28
  },
28
29
  };
@@ -1,7 +1,7 @@
1
1
  import SearchBox from './SearchBox.vue';
2
2
 
3
3
  export default {
4
- title: 'Molecules/SearchBox',
4
+ title: 'Molecules/SearchBox/SearchBox',
5
5
  component: SearchBox,
6
6
  tags: ['autodocs'],
7
7
  argTypes: {
@@ -5,11 +5,11 @@
5
5
  <div v-if="!isLoading" class="min-w-72 p-4 bg-secondary rounded-lg flex flex-col items-start">
6
6
  <img :src="image" alt="Article Image" class="w-full h-40 object-cover rounded-t-md mb-4" />
7
7
 
8
- <BaseText tag="h3" size="xl" weight="semibold" class="mb-2">{{ articleTitle }}</BaseText>
8
+ <BaseText tag="h3" size="xl" weight="bold" class="mb-2">{{ articleTitle }}</BaseText>
9
9
  <BaseText tag="p" size="sm" weight="normal" class="mb-4 h-20">{{ truncatedDescription }}</BaseText>
10
10
 
11
11
  <a href="#" @click.prevent="onReadMore" class="w-full flex justify-end pr-2">
12
- <BaseText tag="p" size="sm" weight="simibold" class="mb-4 border-b border-secondary hover:border-accent">Read More &rarr;</BaseText>
12
+ <BaseText tag="p" size="sm" weight="bold" class="mb-4 border-b border-secondary hover:border-accent">Read More &rarr;</BaseText>
13
13
  </a>
14
14
  </div>
15
15
  </template>
@@ -29,11 +29,16 @@ export default {
29
29
  type: Object,
30
30
  required: true,
31
31
  },
32
+ index: {
33
+ type: Number,
34
+ required: true,
35
+ },
32
36
  isLoading: {
33
37
  type: Boolean,
34
38
  default: false,
35
39
  }
36
40
  },
41
+ emits: ['grid-card-click'],
37
42
  computed: {
38
43
  image() {
39
44
  return this.data.image;
@@ -50,7 +55,7 @@ export default {
50
55
  },
51
56
  methods: {
52
57
  onReadMore() {
53
- this.$emit('card-click', this.data);
58
+ this.$emit('grid-card-click', this.data);
54
59
  }
55
60
  }
56
61
  };