Skip to content

Commit 6bc6040

Browse files
committed
add Namecard
1 parent 2e88b2a commit 6bc6040

File tree

7 files changed

+264
-6
lines changed

7 files changed

+264
-6
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<script setup lang="ts">
2+
import NamecardAvatar from './NamecardAvatar.vue'
3+
import type { NamecardUser } from '@vuejs-jp/model'
4+
import { useUserRole } from '@vuejs-jp/composable'
5+
6+
type NamecardProps = {
7+
user: NamecardUser
8+
isPlaceholder?: boolean
9+
}
10+
11+
defineProps<NamecardProps>()
12+
13+
const { backgroundColor } = useUserRole()
14+
</script>
15+
16+
<template>
17+
<div class="namecard-root">
18+
<NamecardAvatar :user="user" :is-placeholder="isPlaceholder" />
19+
<div class="role" :style="{ '--background-color-role': backgroundColor(user.role ?? 'staff') }">
20+
{{ user.role }}
21+
</div>
22+
<div class="sponsor">
23+
<img src="/namecard/support.svg" alt="Supported by Stockmark" />
24+
</div>
25+
</div>
26+
</template>
27+
28+
<style scoped>
29+
@import url('~/assets/media.css');
30+
31+
.namecard-root {
32+
width: 23.5rem;
33+
background-color: var(--color-white);
34+
border-radius: calc(var(--unit) * 1.25);
35+
overflow: hidden;
36+
box-shadow: 0px 8px 24px 0px hsla(0, 0%, 0%, 0.239);
37+
border: 1px solid #000;
38+
@media (--mobile) {
39+
width: 18rem;
40+
}
41+
}
42+
43+
.role {
44+
--background-color-role: color-mix(in srgb, var(--color-vue-blue), #000 20%);
45+
font-size: 1.3125rem;
46+
height: 2.0625rem;
47+
display: grid;
48+
place-items: center;
49+
font-weight: 700;
50+
text-transform: uppercase;
51+
color: var(--color-white);
52+
background-color: var(--background-color-role);
53+
}
54+
55+
.sponsor {
56+
display: grid;
57+
place-items: center;
58+
height: 3.75rem;
59+
img {
60+
width: 16.25rem;
61+
@media (--mobile) {
62+
width: 12.5rem;
63+
}
64+
}
65+
}
66+
</style>
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<script setup lang="ts">
2+
import type { NamecardUser } from '@vuejs-jp/model'
3+
4+
type NamecardAvatarProps = {
5+
user: NamecardUser
6+
isPlaceholder?: boolean
7+
}
8+
defineProps<NamecardAvatarProps>()
9+
10+
const COLOR_AVATAR_NAME = {
11+
DEFAULT: 'color-mix(in srgb, var(--color-vue-blue), #000 20%)',
12+
PLACEHOLDER: 'var(--color-gray100)',
13+
}
14+
</script>
15+
16+
<template>
17+
<div class="avatar">
18+
<span class="hook" aria-hidden="true" />
19+
<div class="vuefes-logo-wrapper">
20+
<img src="/namecard/vuefes_logo.svg" alt="vuefes logo" />
21+
</div>
22+
<div class="avatar-logo-wrapper">
23+
<img :alt="user.display_name" :src="user.avatar_url" class="avatar-logo" decoding="async" />
24+
</div>
25+
<div class="avatar-name-area">
26+
<h2
27+
class="avatar-name"
28+
:style="{
29+
'--color-avatar-name': isPlaceholder
30+
? COLOR_AVATAR_NAME.PLACEHOLDER
31+
: COLOR_AVATAR_NAME.DEFAULT,
32+
}"
33+
>
34+
{{ user.display_name }}
35+
</h2>
36+
</div>
37+
<div class="avatar-footer">Vue Fes Japan 2024</div>
38+
</div>
39+
</template>
40+
41+
<style scoped>
42+
@import url('~/assets/media.css');
43+
44+
.avatar {
45+
display: grid;
46+
47+
place-items: center;
48+
background: color-mix(in srgb, #4e5764, #000 20%) url('/namecard/bg_texture.png') no-repeat;
49+
background-size: cover;
50+
container: avatar / inline-size;
51+
box-shadow: var(--shadow-1);
52+
@media (--mobile) {
53+
background: #4e5764;
54+
position: relative;
55+
&::before {
56+
position: absolute;
57+
z-index: -1;
58+
left: 0;
59+
top: 0;
60+
opacity: 0.5;
61+
content: '';
62+
display: block;
63+
width: 100%;
64+
height: 100%;
65+
background-image: url('/namecard/bg_texture.png');
66+
background-size: cover;
67+
}
68+
}
69+
}
70+
71+
.hook {
72+
margin-top: 1.25rem;
73+
width: 25px;
74+
aspect-ratio: 1;
75+
background-color: #fff;
76+
border-radius: 50%;
77+
@media (--mobile) {
78+
margin-top: 0.9375rem;
79+
width: 20px;
80+
}
81+
}
82+
83+
.vuefes-logo-wrapper {
84+
position: absolute;
85+
top: 17.98px;
86+
right: 14.07px;
87+
width: 29.72px;
88+
img {
89+
width: 100%;
90+
}
91+
@media (--mobile) {
92+
top: 13.77px;
93+
right: 10.77px;
94+
width: 22.76px;
95+
}
96+
}
97+
98+
.avatar-logo-wrapper {
99+
width: 36.17cqi;
100+
aspect-ratio: 1;
101+
border-radius: 50%;
102+
margin-top: 2.5rem;
103+
@media (--mobile) {
104+
margin-top: 1.875rem;
105+
}
106+
}
107+
108+
.avatar-logo {
109+
width: 100%;
110+
height: 100%;
111+
border-radius: 50%;
112+
border: 4px solid var(--color-white);
113+
box-sizing: border-box;
114+
vertical-align: top;
115+
}
116+
117+
.avatar-name-area {
118+
width: 85cqi;
119+
background-color: var(--color-white);
120+
margin-top: 0.8125rem;
121+
display: grid;
122+
place-items: center;
123+
border-radius: calc(var(--unit) * 1.25);
124+
padding: 2.8125rem 1rem;
125+
@media (--mobile) {
126+
margin-top: 0.625rem;
127+
padding: 2.25rem 0.5rem;
128+
}
129+
}
130+
131+
.avatar-name {
132+
--color-avatar-name: color-mix(in srgb, var(--color-vue-blue), #000 20%);
133+
134+
font-size: 2.25rem;
135+
font-weight: 700;
136+
line-height: 1.1;
137+
color: var(--color-avatar-name);
138+
@media (--mobile) {
139+
font-size: 1.6875rem;
140+
}
141+
}
142+
143+
.avatar-footer {
144+
font-size: 1.0625rem;
145+
font-weight: 700;
146+
color: var(--color-white);
147+
margin-top: 2.875rem;
148+
margin-bottom: 0.75rem;
149+
line-height: 1;
150+
height: 0.75rem;
151+
@media (--mobile) {
152+
font-size: 0.8125rem;
153+
margin-top: 2.125rem;
154+
margin-bottom: 0.4rem;
155+
}
156+
}
157+
158+
.role {
159+
padding: calc(var(--unit) * 1) calc(var(--unit) * 3);
160+
border-radius: calc(var(--unit) * 6.25);
161+
font-size: 1.5rem;
162+
font-weight: 700;
163+
text-transform: uppercase;
164+
}
165+
</style>
83.8 KB
Loading
Lines changed: 24 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading

packages/composable/lib/useUserRole.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import { match } from 'ts-pattern'
44
export function useUserRole() {
55
const backgroundColor = (role: Role) =>
66
match(role)
7-
.with('staff', () => '#233445')
8-
.with('speaker', () => '#90B44B')
9-
.with('sponsor', () => '#FFC408')
10-
.with('attendee', () => '#F17C67')
11-
.with('attendee + party', () => '#33A6B8')
7+
.with('staff', () => 'color-mix(in srgb, var(--color-vue-blue), #000 20%)')
8+
.with('speaker', () => 'var(--color-hiwamoegi200)')
9+
.with('sponsor', () => 'var(--color-tohoh200)')
10+
.with('attendee', () => 'var(--color-sangosyo200)')
11+
.with('attendee + party', () => 'var(--color-asagi200)')
1212
.exhaustive()
1313

1414
const textColor = (role: Role) =>

packages/model/lib/attendee.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export type Attendee = {
2424
id?: string
2525
provider: string
2626
receipt_id: string
27-
role?: string
27+
role?: Role
2828
updated_at: string
2929
user_id: string
3030
}

0 commit comments

Comments
 (0)