@dcrackel/meyersquaredui 1.0.36 → 1.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/meyersquaredui.es.js +343 -219
- package/dist/meyersquaredui.umd.js +1 -0
- package/dist/style.css +1 -1
- package/package.json +8 -2
- package/src/assets/fonts/Raleway-Thin.ttf +0 -0
- package/src/assets/images/portrait1.png +0 -0
- package/src/mocks/getArticles.js +19 -0
- package/src/mocks/getTopFencers.js +157 -0
- package/src/mocks/getTournamentsMock.js +185 -0
- package/src/stories/Atoms/BaseButton/BaseButton.stories.js +35 -32
- package/src/stories/Atoms/BaseButton/BaseButton.vue +66 -4
- package/src/stories/Atoms/BaseText/BaseText.vue +25 -8
- package/src/stories/Atoms/Icon/Icon.vue +6 -1
- package/src/stories/Organisms/Cards/ArticleCard/ArticleCard.stories.js +25 -0
- package/src/stories/Organisms/Cards/ArticleCard/ArticleCard.vue +48 -0
- package/src/stories/Organisms/Cards/FencerCard/FencerCard.stories.js +48 -0
- package/src/stories/Organisms/Cards/FencerCard/FencerCard.vue +69 -0
- package/src/stories/Organisms/Cards/TournamentCard/TournamentCard.stories.js +24 -0
- package/src/stories/Organisms/Cards/TournamentCard/TournamentCard.vue +121 -0
- package/src/stories/Organisms/Footer/Foot.stories.js +11 -0
- package/src/stories/Organisms/Footer/Footer.vue +94 -0
- package/src/stories/Organisms/GridLayout/GridLayout.stories.js +148 -0
- package/src/stories/Organisms/GridLayout/GridLayout.vue +98 -0
- package/src/stories/Organisms/Headers/Header.stories.js +1 -1
- package/src/stories/Organisms/Headers/Header.vue +5 -6
- package/src/stories/Organisms/HeroBanners/HomePage/HeroBanner.vue +52 -25
- package/src/stories/Organisms/SectionBanners/DoubleButtonBanner/DoubleButtonBanner.stories.js +28 -0
- package/src/stories/Organisms/SectionBanners/DoubleButtonBanner/DoubleButtonBanner.vue +118 -0
- package/src/stories/Organisms/SectionBanners/SingleButtonBanner/SingleButtonBanner.stories.js +35 -0
- package/src/stories/Organisms/SectionBanners/SingleButtonBanner/SingleButtonBanner.vue +48 -0
- package/src/stories/Templates/HomePage/TestPage.stories.js +7 -2
- package/src/stories/Templates/HomePage/TestPage.vue +73 -1
- package/dist/meyersquaredui.cjs.js +0 -1
- package/src/components/HelloWorld.vue +0 -43
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button
|
|
3
3
|
:class="[
|
|
4
|
-
'
|
|
4
|
+
'rounded-md transition duration-300 ease-in-out',
|
|
5
|
+
paddingClass,
|
|
5
6
|
textColorClass,
|
|
6
7
|
backgroundClass,
|
|
7
8
|
borderClass,
|
|
@@ -10,13 +11,23 @@
|
|
|
10
11
|
:aria-label="altText || label"
|
|
11
12
|
@click="$emit('click')"
|
|
12
13
|
>
|
|
13
|
-
|
|
14
|
+
<div :class="['flex items-center', alignmentClass, 'space-x-2']">
|
|
15
|
+
<BaseText :color="color" :hoverColor="hoverColor" :size="size" :weight="weight">{{ label }}</BaseText>
|
|
16
|
+
<Icon :icon="iconName" :color="iconColor" :size="iconSize" :type="iconType"/>
|
|
17
|
+
</div>
|
|
14
18
|
</button>
|
|
15
19
|
</template>
|
|
16
20
|
|
|
17
21
|
<script>
|
|
22
|
+
import BaseText from "../BaseText/BaseText.vue";
|
|
23
|
+
import Icon from '../../Atoms/Icon/Icon.vue';
|
|
24
|
+
|
|
18
25
|
export default {
|
|
19
26
|
name: 'BaseButton',
|
|
27
|
+
components: {
|
|
28
|
+
BaseText,
|
|
29
|
+
Icon
|
|
30
|
+
},
|
|
20
31
|
props: {
|
|
21
32
|
label: {
|
|
22
33
|
type: String,
|
|
@@ -26,11 +37,24 @@ export default {
|
|
|
26
37
|
type: String,
|
|
27
38
|
default: null,
|
|
28
39
|
},
|
|
40
|
+
size: {
|
|
41
|
+
type: String,
|
|
42
|
+
default: 'md',
|
|
43
|
+
},
|
|
44
|
+
weight: {
|
|
45
|
+
type: String,
|
|
46
|
+
default: 'normal',
|
|
47
|
+
},
|
|
29
48
|
color: {
|
|
30
49
|
type: String,
|
|
31
50
|
default: 'primary',
|
|
32
51
|
validator: (value) => ['primary', 'secondary', 'accent'].includes(value),
|
|
33
52
|
},
|
|
53
|
+
hoverColor: {
|
|
54
|
+
type: String,
|
|
55
|
+
default: '',
|
|
56
|
+
validator: (value) => ['primary', 'secondary', 'accent'].includes(value),
|
|
57
|
+
},
|
|
34
58
|
backgroundColor: {
|
|
35
59
|
type: String,
|
|
36
60
|
default: 'primary',
|
|
@@ -42,8 +66,38 @@ export default {
|
|
|
42
66
|
validator: (value) =>
|
|
43
67
|
['none', 'primary', 'secondary', 'accent', 'gradient1', 'gradient2'].includes(value),
|
|
44
68
|
},
|
|
69
|
+
padding: {
|
|
70
|
+
type: String,
|
|
71
|
+
default: 'px-4 py-2',
|
|
72
|
+
},
|
|
73
|
+
iconName: {
|
|
74
|
+
type: String,
|
|
75
|
+
default: ''
|
|
76
|
+
},
|
|
77
|
+
iconColor: {
|
|
78
|
+
type: String,
|
|
79
|
+
default: 'primary',
|
|
80
|
+
validator: (value) => ['primary', 'secondary', 'accent'].includes(value),
|
|
81
|
+
},
|
|
82
|
+
iconSize: {
|
|
83
|
+
control: { type: 'select', options: ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl'] },
|
|
84
|
+
description: 'Icon size',
|
|
85
|
+
},
|
|
86
|
+
iconType: {
|
|
87
|
+
type: String,
|
|
88
|
+
default: 'fa-solid',
|
|
89
|
+
validator: (value) => ['fa-thin', 'fa-sharp'].includes(value),
|
|
90
|
+
},
|
|
91
|
+
align: {
|
|
92
|
+
type: String,
|
|
93
|
+
default: 'center',
|
|
94
|
+
validator: (value) => ['left', 'center', 'right', 'between'].includes(value),
|
|
95
|
+
},
|
|
45
96
|
},
|
|
46
97
|
computed: {
|
|
98
|
+
paddingClass() {
|
|
99
|
+
return this.padding;
|
|
100
|
+
},
|
|
47
101
|
textColorClass() {
|
|
48
102
|
const textColor = {
|
|
49
103
|
primary: 'text-primary',
|
|
@@ -55,7 +109,7 @@ export default {
|
|
|
55
109
|
backgroundClass() {
|
|
56
110
|
const colorMap = {
|
|
57
111
|
primary: 'bg-primary hover:bg-accent',
|
|
58
|
-
secondary: 'bg-secondary hover:bg-
|
|
112
|
+
secondary: 'bg-secondary hover:bg-primary',
|
|
59
113
|
accent: 'bg-accent hover:bg-accent',
|
|
60
114
|
};
|
|
61
115
|
return colorMap[this.backgroundColor] || 'bg-primary';
|
|
@@ -71,6 +125,15 @@ export default {
|
|
|
71
125
|
};
|
|
72
126
|
return borderMap[this.border] || '';
|
|
73
127
|
},
|
|
128
|
+
alignmentClass() {
|
|
129
|
+
const alignmentMap = {
|
|
130
|
+
left: 'justify-start',
|
|
131
|
+
center: 'justify-center',
|
|
132
|
+
right: 'justify-end',
|
|
133
|
+
between: 'justify-between', // New "between" option added
|
|
134
|
+
};
|
|
135
|
+
return alignmentMap[this.align] || 'justify-center';
|
|
136
|
+
},
|
|
74
137
|
},
|
|
75
138
|
};
|
|
76
139
|
</script>
|
|
@@ -106,5 +169,4 @@ export default {
|
|
|
106
169
|
background: linear-gradient(to right, #009DFF, #25E07C);
|
|
107
170
|
color: white; /* Optional: You can change the text color on hover as well */
|
|
108
171
|
}
|
|
109
|
-
|
|
110
172
|
</style>
|
|
@@ -16,20 +16,24 @@ export default {
|
|
|
16
16
|
size: {
|
|
17
17
|
type: String,
|
|
18
18
|
default: 'md',
|
|
19
|
-
validator: (value) => ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl'].includes(value),
|
|
20
19
|
},
|
|
21
20
|
color: {
|
|
22
21
|
type: String,
|
|
23
22
|
default: 'primary',
|
|
24
23
|
},
|
|
24
|
+
hoverColor: {
|
|
25
|
+
type: String,
|
|
26
|
+
default: '',
|
|
27
|
+
},
|
|
25
28
|
weight: {
|
|
26
29
|
type: String,
|
|
27
30
|
default: 'normal',
|
|
28
|
-
validator: (value) => ['light', 'normal',
|
|
31
|
+
validator: (value) => ['thin','light', 'normal','semibold','bold'].includes(value),
|
|
29
32
|
},
|
|
30
33
|
},
|
|
31
34
|
computed: {
|
|
32
35
|
textClasses() {
|
|
36
|
+
// Map for size classes
|
|
33
37
|
const sizeClasses = {
|
|
34
38
|
xs: 'text-xs',
|
|
35
39
|
sm: 'text-sm',
|
|
@@ -39,17 +43,30 @@ export default {
|
|
|
39
43
|
'2xl': 'text-2xl',
|
|
40
44
|
'3xl': 'text-3xl',
|
|
41
45
|
'4xl': 'text-4xl',
|
|
42
|
-
'5xl': 'text-5xl'
|
|
46
|
+
'5xl': 'text-5xl',
|
|
43
47
|
};
|
|
44
48
|
|
|
45
49
|
const weightClasses = {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
thin: 'font-thin font-[100]',
|
|
51
|
+
light: 'font-light font-[300]',
|
|
52
|
+
normal: 'font-normal font-[400]',
|
|
53
|
+
semibold: 'font-semibold font-[600]',
|
|
54
|
+
bold: 'font-bold font-[700]',
|
|
50
55
|
};
|
|
51
56
|
|
|
52
|
-
|
|
57
|
+
const hoverClass = this.hoverColor ? `hover:text-${this.hoverColor}` : '';
|
|
58
|
+
|
|
59
|
+
// Parse the size prop to allow responsive classes
|
|
60
|
+
const sizeClassList = this.size
|
|
61
|
+
.split(' ')
|
|
62
|
+
.map((size) => {
|
|
63
|
+
const [prefix, value] = size.includes(':') ? size.split(':') : [null, size];
|
|
64
|
+
return prefix ? `${prefix}:${sizeClasses[value]}` : sizeClasses[value];
|
|
65
|
+
})
|
|
66
|
+
.filter(Boolean)
|
|
67
|
+
.join(' ');
|
|
68
|
+
|
|
69
|
+
return `${sizeClassList} ${weightClasses[this.weight]} text-${this.color} ${hoverClass} font-raleway`;
|
|
53
70
|
},
|
|
54
71
|
},
|
|
55
72
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<i :class="[
|
|
2
|
+
<i :class="[ type, icon, colorClasses, sizeClasses ]" @click="$emit('click')" />
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
5
|
<script>
|
|
@@ -20,6 +20,11 @@ export default {
|
|
|
20
20
|
default: 'md',
|
|
21
21
|
validator: (value) => ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl'].includes(value),
|
|
22
22
|
},
|
|
23
|
+
type: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: 'fa-solid',
|
|
26
|
+
validator: (value) => ['fa-thin', 'fa-sharp'].includes(value),
|
|
27
|
+
}
|
|
23
28
|
},
|
|
24
29
|
computed: {
|
|
25
30
|
colorClasses() {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import ArticleCard from './ArticleCard.vue';
|
|
2
|
+
import mockArticles from "../../../../mocks/getArticles.js";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Organisms/Cards/ArticleCard',
|
|
6
|
+
component: ArticleCard,
|
|
7
|
+
argTypes: {
|
|
8
|
+
onReadMore: { action: 'read-more' }
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const Template = (args) => ({
|
|
13
|
+
components: { ArticleCard },
|
|
14
|
+
setup() {
|
|
15
|
+
return { args };
|
|
16
|
+
},
|
|
17
|
+
template: '<ArticleCard v-bind="args" @read-more="args.onReadMore" />',
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const Default = Template.bind({});
|
|
21
|
+
Default.args = {
|
|
22
|
+
image: 'https://via.placeholder.com/300x200',
|
|
23
|
+
articleTitle: 'Exciting News in HEMA',
|
|
24
|
+
description: 'Learn about the latest developments and events happening in the HEMA community. Stay informed and get the latest updates.',
|
|
25
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="w-72 p-4 bg-secondary rounded-lg flex flex-col items-start">
|
|
3
|
+
<img :src="image" alt="Article Image" class="w-full h-40 object-cover rounded-t-md mb-4" />
|
|
4
|
+
|
|
5
|
+
<BaseText tag="h3" size="xl" weight="semibold" class="mb-2">{{ articleTitle }}</BaseText>
|
|
6
|
+
<BaseText tag="p" size="sm" weight="normal" class="mb-4 h-20">{{ truncatedDescription }}</BaseText>
|
|
7
|
+
|
|
8
|
+
<a href="#" @click.prevent="onReadMore" class="w-full flex justify-end pr-2">
|
|
9
|
+
<BaseText tag="p" size="sm" weight="simibold" class="mb-4 border-b border-secondary hover:border-accent">Read More →</BaseText>
|
|
10
|
+
</a>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
import BaseText from "../../../Atoms/BaseText/BaseText.vue";
|
|
16
|
+
|
|
17
|
+
export default {
|
|
18
|
+
name: 'ArticleCard',
|
|
19
|
+
components: {
|
|
20
|
+
BaseText
|
|
21
|
+
},
|
|
22
|
+
props: {
|
|
23
|
+
data: {
|
|
24
|
+
type: Object,
|
|
25
|
+
required: true,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
computed: {
|
|
29
|
+
image() {
|
|
30
|
+
return this.data.image;
|
|
31
|
+
},
|
|
32
|
+
articleTitle() {
|
|
33
|
+
return this.data.articleTitle;
|
|
34
|
+
},
|
|
35
|
+
truncatedDescription() {
|
|
36
|
+
if (this.data.description.length > 120) {
|
|
37
|
+
return this.data.description.substring(0, 120) + ' ...';
|
|
38
|
+
}
|
|
39
|
+
return this.data.description;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
methods: {
|
|
43
|
+
onReadMore() {
|
|
44
|
+
this.$emit('read-more');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
</script>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import FencerCard from './FencerCard.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Organisms/Cards/FencerCard',
|
|
5
|
+
component: FencerCard,
|
|
6
|
+
argTypes: {
|
|
7
|
+
portrait: { control: 'text' },
|
|
8
|
+
displayName: { control: 'text' },
|
|
9
|
+
clubName: { control: 'text' },
|
|
10
|
+
m2Rating: { control: 'number' },
|
|
11
|
+
hrRating: { control: 'number' },
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const Template = (args) => ({
|
|
16
|
+
components: { FencerCard },
|
|
17
|
+
setup() {
|
|
18
|
+
return { args };
|
|
19
|
+
},
|
|
20
|
+
template: '<FencerCard v-bind="args" />',
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const Default = Template.bind({});
|
|
24
|
+
Default.args = {
|
|
25
|
+
portrait: 'https://randomuser.me/api/portraits/women/26.jpg',
|
|
26
|
+
displayName: 'John Doe',
|
|
27
|
+
clubName: 'Awesome Fencing Club',
|
|
28
|
+
m2Rating: 'A24',
|
|
29
|
+
hrRating: 1567,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const HighRating = Template.bind({});
|
|
33
|
+
HighRating.args = {
|
|
34
|
+
portrait: '',
|
|
35
|
+
displayName: 'Jane Smith',
|
|
36
|
+
clubName: 'Elite Fencing Academy',
|
|
37
|
+
m2Rating: 1500,
|
|
38
|
+
hrRating: 1300,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const NoRating = Template.bind({});
|
|
42
|
+
NoRating.args = {
|
|
43
|
+
portrait: '',
|
|
44
|
+
displayName: 'Unknown Fencer',
|
|
45
|
+
clubName: 'No Club',
|
|
46
|
+
m2Rating: null,
|
|
47
|
+
hrRating: null,
|
|
48
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section class="mr-4 md:mr-2 items-center">
|
|
3
|
+
<div class="flex flex-col m-auto justify-center mb-4 items-center w-[160px]">
|
|
4
|
+
<img :src="portrait" alt="Fencer Portrait" class="w-[120px] h-[120px] md:w-40 md:h-40 rounded-full object-cover z-1 flex-shrink-0" />
|
|
5
|
+
</div>
|
|
6
|
+
<!-- Ratings -->
|
|
7
|
+
<div class="flex flex-col md:flex-row justify-center md:justify-around -mt-2 border-b border-borderGray z-10 pb-2 mb-2">
|
|
8
|
+
<div class="flex items-center justify-center">
|
|
9
|
+
<BaseText tag="p" size="xs md:sm" weight="semibold" class="primary mr-1 block z-50">M2: </BaseText>
|
|
10
|
+
<BaseText tag="p" size="sm md:md" weight="bold" class="text-accent">{{ m2Rating }}</BaseText>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="hidden md:flex items-center justify-center">
|
|
13
|
+
<BaseText tag="p" size="md" weight="bold" class="text-accent">{{ hrRating }}</BaseText>
|
|
14
|
+
<BaseText tag="p" size="sm" weight="semibold" class="primary mr-1">:HR</BaseText>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
<BaseText tag="h3" size="sm md:xl" weight="semibold" class="text-center">{{ displayName }}</BaseText>
|
|
18
|
+
<BaseText tag="p" size="xs md:sm" weight="normal" class="text-center h-10">{{ clubName }}</BaseText>
|
|
19
|
+
</section>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script>
|
|
23
|
+
import BaseText from "../../../Atoms/BaseText/BaseText.vue";
|
|
24
|
+
import defaultPortrait from '../../../../assets/images/portrait1.png'
|
|
25
|
+
|
|
26
|
+
// :style="{ flexShrink: '0', minWidth: '160px', minHeight: '160px' }"
|
|
27
|
+
export default {
|
|
28
|
+
name: 'FencerCard',
|
|
29
|
+
components: {
|
|
30
|
+
BaseText,
|
|
31
|
+
defaultPortrait
|
|
32
|
+
},
|
|
33
|
+
props: {
|
|
34
|
+
data: {
|
|
35
|
+
type: Object,
|
|
36
|
+
required: true,
|
|
37
|
+
},
|
|
38
|
+
index: {
|
|
39
|
+
type: Number,
|
|
40
|
+
required: true,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
data() {
|
|
44
|
+
return {
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
computed: {
|
|
48
|
+
portrait() {
|
|
49
|
+
return this.data.ProfileImage && this.data.ProfileImage.URL
|
|
50
|
+
? this.data.ProfileImage.URL
|
|
51
|
+
: defaultPortrait;
|
|
52
|
+
},
|
|
53
|
+
displayName() {
|
|
54
|
+
return this.data.DisplayName;
|
|
55
|
+
},
|
|
56
|
+
clubName() {
|
|
57
|
+
return this.data.Club.Name;
|
|
58
|
+
},
|
|
59
|
+
m2Rating() {
|
|
60
|
+
const m2RatingForWeapon = this.data.M2Ratings.find(rating => rating.WeaponId === 1);
|
|
61
|
+
return m2RatingForWeapon ? m2RatingForWeapon.FormattedRating : 'U';
|
|
62
|
+
},
|
|
63
|
+
hrRating() {
|
|
64
|
+
return this.data.HEMARatings && this.data.HEMARatings[0] ? this.data.HEMARatings[0].Rating : 0;
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
</script>
|
|
69
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import TournamentCard from './TournamentCard.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Organisms/Cards/TournamentCard',
|
|
5
|
+
component: TournamentCard,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const Template = (args) => ({
|
|
9
|
+
components: { TournamentCard },
|
|
10
|
+
setup() {
|
|
11
|
+
return { args };
|
|
12
|
+
},
|
|
13
|
+
template: '<TournamentCard v-bind="args" />',
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export const Default = Template.bind({});
|
|
17
|
+
Default.args = {
|
|
18
|
+
image: 'https://assets.simpleviewinc.com/simpleview/image/upload/c_fill,f_avif,h_800,q_65,w_1920/v1/clients/wausauwi/download_5__d27db8e0-a64a-4db5-8126-17033dab6712.jpg',
|
|
19
|
+
title: 'National Fencing Tournament',
|
|
20
|
+
location: 'New York City, NY',
|
|
21
|
+
startDate: 'Jan 1, 2024',
|
|
22
|
+
endDate: 'Jan 3, 2024',
|
|
23
|
+
numberOfFencers: 120,
|
|
24
|
+
};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="md:w-full mb-8">
|
|
3
|
+
<!-- Desktop Version -->
|
|
4
|
+
<section class="hidden md:block">
|
|
5
|
+
<img
|
|
6
|
+
:src="image"
|
|
7
|
+
alt="Tournament Image"
|
|
8
|
+
class="w-full h-52 object-cover mb-2 rounded-md"
|
|
9
|
+
@error="imageError"
|
|
10
|
+
:style="fallbackStyle"
|
|
11
|
+
/>
|
|
12
|
+
<BaseText tag="h3" size="xl" weight="semibold" class="mb-1">{{ title }}</BaseText>
|
|
13
|
+
<BaseText tag="p" size="sm" weight="semibold" class="mb-2">{{ location }}</BaseText>
|
|
14
|
+
<div class="flex items-center mb-1">
|
|
15
|
+
<span class="flex w-6 justify-center">
|
|
16
|
+
<Icon icon="fa-calendar" color="accent" size="sm" class="mr-3 w-4"/>
|
|
17
|
+
</span>
|
|
18
|
+
<BaseText tag="p" size="sm" class="">{{ startDate }} to {{ endDate }}</BaseText>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="flex items-center">
|
|
21
|
+
<span class="flex w-6 justify-center">
|
|
22
|
+
<Icon icon="fa-user-friends" color="accent" size="sm" class="mr-3"/>
|
|
23
|
+
</span>
|
|
24
|
+
<BaseText tag="p" size="sm" class="">{{ numberOfFencers }} Registered Fencers</BaseText>
|
|
25
|
+
</div>
|
|
26
|
+
</section>
|
|
27
|
+
|
|
28
|
+
<!-- Mobile Version -->
|
|
29
|
+
<section class="md:hidden flex-col items-start gap-2 border-b border-borderGray">
|
|
30
|
+
|
|
31
|
+
<div class="flex flex-row">
|
|
32
|
+
<img :src="image"
|
|
33
|
+
alt="Tournament Image"
|
|
34
|
+
class="w-28 h-16 object-cover rounded-md"
|
|
35
|
+
@error="imageError"
|
|
36
|
+
:style="fallbackStyle"
|
|
37
|
+
/>
|
|
38
|
+
<div class="flex flex-col h-16 justify-center pl-2">
|
|
39
|
+
<BaseText tag="h3" size="lg" weight="semibold" class="mb-1">{{ title }}</BaseText>
|
|
40
|
+
<BaseText tag="p" size="xs" weight="semibold" class="mb-1">{{ location }}</BaseText>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="flex justify-between pt-4 pb-2">
|
|
44
|
+
<div class="flex justify-start w-5/12">
|
|
45
|
+
<Icon icon="fa-user-friends" color="accent" size="xs" class="mr-1" />
|
|
46
|
+
<BaseText tag="p" size="xs" class="">{{ numberOfFencers }} Registered</BaseText>
|
|
47
|
+
</div>
|
|
48
|
+
<div class="flex justify-start mb-1 w-7/12">
|
|
49
|
+
<Icon icon="fa-calendar" color="accent" size="xs" class="mr-1 w-4" />
|
|
50
|
+
<BaseText tag="p" size="xs" class="">{{ startDate }} to {{ endDate }}</BaseText>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</section>
|
|
54
|
+
</div>
|
|
55
|
+
</template>
|
|
56
|
+
|
|
57
|
+
<script>
|
|
58
|
+
import BaseText from "../../../Atoms/BaseText/BaseText.vue";
|
|
59
|
+
import Icon from "../../../Atoms/Icon/Icon.vue";
|
|
60
|
+
|
|
61
|
+
export default {
|
|
62
|
+
name: 'TournamentCard',
|
|
63
|
+
components: {
|
|
64
|
+
BaseText,
|
|
65
|
+
Icon
|
|
66
|
+
},
|
|
67
|
+
props: {
|
|
68
|
+
data: {
|
|
69
|
+
type: Object,
|
|
70
|
+
required: true,
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
data() {
|
|
74
|
+
return {
|
|
75
|
+
isImageError: false
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
mounted() {
|
|
79
|
+
console.log(this.data);
|
|
80
|
+
},
|
|
81
|
+
computed: {
|
|
82
|
+
image() {
|
|
83
|
+
return !this.isImageError && this.data.Images && this.data.Images.length > 0
|
|
84
|
+
? this.data.Images[0].URL
|
|
85
|
+
: 'https://via.placeholder.com/300x200';
|
|
86
|
+
},
|
|
87
|
+
fallbackStyle() {
|
|
88
|
+
return this.isImageError
|
|
89
|
+
? {backgroundColor: '#f5f5f5', display: 'flex', alignItems: 'center', justifyContent: 'center'}
|
|
90
|
+
: {};
|
|
91
|
+
},
|
|
92
|
+
title() {
|
|
93
|
+
return this.data && this.data.Name || '';
|
|
94
|
+
},
|
|
95
|
+
location() {
|
|
96
|
+
return this.data && this.data.Address ? `${this.data.Address.Name} • ${this.data.Address.City}, ${this.data.Address.State}` : 'Location Unavailable';
|
|
97
|
+
},
|
|
98
|
+
startDate() {
|
|
99
|
+
return this.data && this.formatDate(this.data.StartDate);
|
|
100
|
+
},
|
|
101
|
+
endDate() {
|
|
102
|
+
return this.data && this.formatDate(this.data.EndDate);
|
|
103
|
+
},
|
|
104
|
+
numberOfFencers() {
|
|
105
|
+
return this.data && this.data.NumberOfFencers ? this.data.NumberOfFencers : 0;
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
methods: {
|
|
109
|
+
formatDate(date) {
|
|
110
|
+
return new Date(date).toLocaleDateString('en-US', {
|
|
111
|
+
year: 'numeric',
|
|
112
|
+
month: 'short',
|
|
113
|
+
day: 'numeric',
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
imageError() {
|
|
117
|
+
this.isImageError = true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
</script>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section class="flex flex-col bg-primary">
|
|
3
|
+
<div class="h-20"></div>
|
|
4
|
+
|
|
5
|
+
<section class="w-full hidden md:flex">
|
|
6
|
+
<!-- logo -->
|
|
7
|
+
<div class="w-1/3">
|
|
8
|
+
<div class="items-center w-full flex justify-center">
|
|
9
|
+
<img :src="logo" alt="Logo" class="w-[71px] h-[56px]"/>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
<!-- middle -->
|
|
13
|
+
<div class="w-1/3 flex flex-col">
|
|
14
|
+
<div class="w-full flex justify-around">
|
|
15
|
+
<div class="flex w-1/3">
|
|
16
|
+
<BaseText color="secondary" size="md" tag="p" weight="normal" class="pb-2">Tournaments</BaseText>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="flex w-1/3">
|
|
19
|
+
<BaseText color="secondary" size="md" tag="p" weight="normal" class="pb-2">Clubs</BaseText>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="flex items-center w-1/3">
|
|
22
|
+
<BaseText color="secondary" size="md" tag="p" weight="normal" class="pb-2">Leaderboard</BaseText>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="w-full flex justify-around">
|
|
26
|
+
<div class="flex items-center w-1/3">
|
|
27
|
+
<BaseText color="secondary" size="sm" tag="p" weight="thin" class="pb-2">Upcoming</BaseText>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="flex items-center w-1/3">
|
|
30
|
+
<BaseText color="secondary" size="sm" tag="p" weight="thin" class="pb-2">Club List</BaseText>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="flex items-center w-1/3">
|
|
33
|
+
<BaseText color="secondary" size="sm" tag="p" weight="thin" class="pb-2">Top Fencers</BaseText>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="w-full flex justify-around">
|
|
37
|
+
<div class="flex items-center w-1/3">
|
|
38
|
+
<BaseText color="secondary" size="sm" tag="p" weight="thin" class="pb-2">Past</BaseText>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="flex items-center w-1/3">
|
|
41
|
+
<BaseText color="secondary" size="sm" tag="p" weight=thin class="pb-2">Local Clubs</BaseText>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="flex w-1/3">
|
|
44
|
+
<BaseText color="secondary" size="sm" tag="p" weight="thin" class="pb-2">By Weapon</BaseText>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
<!-- subscribe -->
|
|
49
|
+
<div class="w-1/3 flex flex-col">
|
|
50
|
+
<div class="w-full flex justify-end">
|
|
51
|
+
<div class="w-30 mr-16">
|
|
52
|
+
<BaseText color="secondary" size="md" tag="p" weight="thin" class="pb-4 ">Subscribe</BaseText>
|
|
53
|
+
<InputField placeholder="Email" type="email" class="w-52"/>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
<div class="w-full flex justify-end mt-12">
|
|
57
|
+
<div class="w-48 mr-16">
|
|
58
|
+
<BaseText color="secondary" size="md" tag="p" weight="thin" class="pb-2 ">Follow Us</BaseText>
|
|
59
|
+
<div>
|
|
60
|
+
<Icon type="fa-brands" icon="fa-facebook" color="secondary" size="lg" class="mr-4"/>
|
|
61
|
+
<Icon type="fa-brands" icon="fa-discord" color="secondary" size="lg" class="mr-4"/>
|
|
62
|
+
<Icon type="fa-brands" icon="fa-instagram" color="secondary" size="lg" class="mr-4"/>
|
|
63
|
+
<Icon type="fa-brands" icon="fa-youtube" color="secondary" size="lg" class="mr-4"/>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
</section>
|
|
70
|
+
|
|
71
|
+
<div class="h-32 border border-t mt-10 pb-10 border-lineGrey flex flex-col justify-center items-center">
|
|
72
|
+
<BaseText color="secondary" size="sm" tag="p" weight="normal" class="text-center pt-4">© Copyright Meyer Squared 2024. All rights reserved.</BaseText>
|
|
73
|
+
</div>
|
|
74
|
+
</section>
|
|
75
|
+
</template>
|
|
76
|
+
|
|
77
|
+
<script>
|
|
78
|
+
import BaseText from "../../Atoms/BaseText/BaseText.vue";
|
|
79
|
+
import BaseButton from "../../Atoms/BaseButton/BaseButton.vue";
|
|
80
|
+
import logo from "../../../assets/images/m2.png";
|
|
81
|
+
import InputField from "../../Atoms/InputField/InputField.vue";
|
|
82
|
+
import Icon from "../../Atoms/Icon/Icon.vue";
|
|
83
|
+
|
|
84
|
+
export default {
|
|
85
|
+
name: 'Footer',
|
|
86
|
+
components: {Icon, InputField, BaseButton, BaseText},
|
|
87
|
+
data() {
|
|
88
|
+
return {
|
|
89
|
+
logo: logo,
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
</script>
|
|
94
|
+
|