Skip to content
Merged
10 changes: 5 additions & 5 deletions packages/composable/lib/useUserRole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { match } from 'ts-pattern'
export function useUserRole() {
const backgroundColor = (role: Role) =>
match(role)
.with('staff', () => '#233445')
.with('speaker', () => '#90B44B')
.with('sponsor', () => '#FFC408')
.with('attendee', () => '#F17C67')
.with('attendee + party', () => '#33A6B8')
.with('staff', () => 'color-mix(in srgb, var(--color-vue-blue), #000 20%)')
.with('speaker', () => 'var(--color-hiwamoegi200)')
.with('sponsor', () => 'var(--color-tohoh200)')
.with('attendee', () => 'var(--color-sangosyo200)')
.with('attendee + party', () => 'var(--color-asagi200)')
.exhaustive()

const textColor = (role: Role) =>
Expand Down
2 changes: 1 addition & 1 deletion packages/model/lib/attendee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export type Attendee = {
id?: string
provider: string
receipt_id: string
role?: string
role?: Role
updated_at: string
user_id: string
}
Expand Down
Binary file added packages/ui/assets/namecard/bg_texture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions packages/ui/assets/namecard/support.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/ui/assets/namecard/vuefes_logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/ui/components/namecard/Namecard23.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import NamecardAvatar from './NamecardAvatar.vue'
import NamecardAvatar from './NamecardAvatar23.vue'
import type { NamecardUser } from '@vuejs-jp/model'
import { defineAsyncComponent } from 'vue'

Expand Down
53 changes: 53 additions & 0 deletions packages/ui/components/namecard/Namecard24.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import Namecard24 from './Namecard24.vue'
export default {
title: 'namecard/Namecard24',
component: Namecard24,
args: {
user: {
display_name: 'jiyuujin',
avatar_url: 'https://i.imgur.com/X0CcoU9.jpg',
role: 'attendee',
},
},
}

const Template: StoryFn<unknown> = (args, { argTypes }) => ({
Expand All @@ -16,3 +23,49 @@ const Template: StoryFn<unknown> = (args, { argTypes }) => ({
})

export const Default = Template.bind({})

export const WithParty = Template.bind({})
WithParty.args = {
user: {
display_name: 'jiyuujin',
avatar_url: 'https://i.imgur.com/X0CcoU9.jpg',
role: 'attendee + party',
},
}

export const Speaker = Template.bind({})
Speaker.args = {
user: {
display_name: 'jiyuujin',
avatar_url: 'https://i.imgur.com/X0CcoU9.jpg',
role: 'speaker',
},
}

export const Sponsor = Template.bind({})
Sponsor.args = {
user: {
display_name: 'jiyuujin',
avatar_url: 'https://i.imgur.com/X0CcoU9.jpg',
role: 'sponsor',
},
}

export const Staff = Template.bind({})
Staff.args = {
user: {
display_name: 'jiyuujin',
avatar_url: 'https://i.imgur.com/X0CcoU9.jpg',
role: 'staff',
},
}

export const NoAvatar = Template.bind({})
NoAvatar.args = {
user: {
display_name: '山田 太郎',
avatar_url: '',
role: 'attendee',
},
isPlaceholder: true,
}
78 changes: 77 additions & 1 deletion packages/ui/components/namecard/Namecard24.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,79 @@
<script setup lang="ts">
import NamecardAvatar from './NamecardAvatar24.vue'
import type { NamecardUser } from '@vuejs-jp/model'
import { useUserRole } from '@vuejs-jp/composable'
import { onMounted, ref } from 'vue'

type NamecardProps = {
user: NamecardUser
isPlaceholder?: boolean
}

defineProps<NamecardProps>()

const { backgroundColor } = useUserRole()
const sponsorImagePath = ref('')
onMounted(() => {
sponsorImagePath.value = new URL('../../assets/namecard/support.svg', import.meta.url).href
})
</script>

<template>
Namecard 2024
<div class="namecard-root">
<NamecardAvatar :user="user" :is-placeholder="isPlaceholder" />
<div
class="namecard-role"
:style="{ '--background-color-role': backgroundColor(user.role ?? 'staff') }"
>
{{ user.role }}
</div>
<div class="namecard-sponsor">
<img :src="sponsorImagePath" alt="Supported by Stockmark" />
</div>
</div>
</template>

<style scoped>
.namecard-root {
width: 23.5rem;
background-color: var(--color-white);
border-radius: calc(var(--unit) * 1.25);
overflow: hidden;
box-shadow: 0px 8px 24px 0px #0000003d;
border: 1px solid #000;
@media (width <= 480px) {
width: 18rem;
}
}

.namecard-role {
--background-color-role: color-mix(in srgb, var(--color-vue-blue), #000 20%);
font-size: 1.6875rem;
height: 2.625rem;
display: grid;
place-items: center;
font-weight: 700;
text-transform: uppercase;
color: var(--color-white);
background-color: var(--background-color-role);
@media (width <= 480px) {
font-size: 1.3125rem;
height: 2.0625rem;
}
}

.namecard-sponsor {
display: grid;
place-items: center;
height: 3.75rem;
img {
width: 16.25rem;
}
@media (width <= 480px) {
height: 2.8125rem;
img {
width: 12.5rem;
}
}
}
</style>
144 changes: 144 additions & 0 deletions packages/ui/components/namecard/NamecardAvatar24.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<script setup lang="ts">
import NamecardAvatarLogo from './NamecardAvatarLogo24.vue'
import type { NamecardUser } from '@vuejs-jp/model'
import { onMounted, ref } from 'vue'

type NamecardAvatarProps = {
user: NamecardUser
isPlaceholder?: boolean
}
defineProps<NamecardAvatarProps>()

const COLOR_AVATAR_NAME = {
DEFAULT: 'color-mix(in srgb, var(--color-vue-blue), #000 20%)',
PLACEHOLDER: 'var(--color-gray100)',
}
const vuefesLogoImagePath = ref('')
onMounted(() => {
vuefesLogoImagePath.value = new URL('../../assets/namecard/vuefes_logo.svg', import.meta.url).href
})
</script>

<template>
<div class="avatar">
<span class="avatar-hook" aria-hidden="true" />
<div class="vuefes-logo-wrapper">
<img :src="vuefesLogoImagePath" alt="vuefes logo" />
</div>
<div class="avatar-logo-wrapper">
<NamecardAvatarLogo :user="user" />
</div>
<div class="avatar-name-area">
<div
class="avatar-name"
:style="{
'--color-avatar-name': isPlaceholder
? COLOR_AVATAR_NAME.PLACEHOLDER
: COLOR_AVATAR_NAME.DEFAULT,
}"
>
{{ user.display_name }}
</div>
</div>
<small class="avatar-footer">Vue Fes Japan 2024</small>
</div>
</template>

<style scoped>
.avatar {
display: grid;
place-items: center;
background: color-mix(in srgb, var(--color-vue-blue), #000 20%)
url('../../assets/namecard/bg_texture.png') no-repeat;
background-size: cover;
container: avatar / inline-size;
}

.avatar-hook {
margin-top: 1.25rem;
width: 25px;
aspect-ratio: 1;
background-color: var(--color-white);
border-radius: 50%;
@media (width <= 480px) {
margin-top: 0.9375rem;
width: 20px;
}
}

.vuefes-logo-wrapper {
position: absolute;
top: 17.98px;
right: 14.07px;
width: 29.72px;
img {
width: 100%;
}
@media (width <= 480px) {
top: 13.77px;
right: 10.77px;
width: 22.76px;
}
}

.avatar-logo-wrapper {
width: 36.17cqi;
aspect-ratio: 1;
border-radius: 50%;
margin-top: 2.5rem;
background: var(--color-vue-green-gradation);
display: grid;
place-items: center;
border: 4px solid var(--color-white);
container: avatar-logo / inline-size;
@media (width <= 480px) {
border-width: 3px;
margin-top: 1.875rem;
}
}

.avatar-name-area {
width: 85cqi;
height: 8rem;
background-color: var(--color-white);
margin-top: 0.8125rem;
display: grid;
place-items: center;
border-radius: calc(var(--unit) * 1.25);
padding-inline: 1rem;
overflow-wrap: anywhere;
word-break: break-all;
overflow-y: hidden;
@media (width <= 480px) {
margin-top: 0.625rem;
height: 6.125rem;
}
}

.avatar-name {
--color-avatar-name: color-mix(in srgb, var(--color-vue-blue), #000 20%);

font-size: 2.25rem;
font-weight: 700;
line-height: 1.1;
color: var(--color-avatar-name);
@media (width <= 480px) {
font-size: 1.6875rem;
}
}

.avatar-footer {
font-size: 1.0625rem;
font-weight: 700;
color: var(--color-white);
margin-top: 2.875rem;
margin-bottom: 0.75rem;
line-height: 1;
height: 0.75rem;
@media (width <= 480px) {
font-size: 0.8125rem;
margin-top: 2.125rem;
margin-bottom: 0.4rem;
}
}
</style>
37 changes: 37 additions & 0 deletions packages/ui/components/namecard/NamecardAvatarLogo24.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script setup lang="ts">
import type { NamecardUser } from '@vuejs-jp/model'
import { onMounted, ref } from 'vue'

type NamecardAvatarLogoProps = {
user: NamecardUser
}

defineProps<NamecardAvatarLogoProps>()
const vuefesLogoImagePath = ref('')
onMounted(() => {
vuefesLogoImagePath.value = new URL('../../assets/namecard/vuefes_logo.svg', import.meta.url).href
})
</script>

<template>
<template v-if="user.avatar_url">
<img :alt="user.display_name" :src="user.avatar_url" class="avatar-logo" decoding="async" />
</template>
<template v-else>
<img alt="vuefes logo avatar sample" :src="vuefesLogoImagePath" class="sample-logo" />
</template>
</template>

<style scoped>
.avatar-logo {
width: 100%;
height: 100%;
border-radius: 50%;
}

.sample-logo {
width: 40cqi;
opacity: 0.5;
padding-bottom: 4cqi;
}
</style>
Loading
Loading