Skip to content

Commit

Permalink
Merge pull request #191 from vuejs-jp/enhance/update-detail-page
Browse files Browse the repository at this point in the history
update detail page (speaker, sponsor)
  • Loading branch information
jiyuujin authored Jul 12, 2024
2 parents edcd72c + 0edd71f commit 16ff39c
Show file tree
Hide file tree
Showing 9 changed files with 705 additions and 4 deletions.
16 changes: 16 additions & 0 deletions apps/web/app/composables/useSponsor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { SponsorType, OptionSponsorType } from '@vuejs-jp/model'
import { match } from 'ts-pattern'

export function useSponsor() {
function color(tag: SponsorType | OptionSponsorType) {
return match(tag)
.with('platinum', () => '#93AF5E')
.with('gold', () => '#FFC408')
.with('silver', () => '#ADBFD4')
.with('bronze', () => '#F17C67')
.with('option', 'option-separate', 'name-card', 'special-naming-rights', 'after-party', 'simultaneous-interpretation', 'special-lunch', 'media', 'tool', () => '#546F89')
.exhaustive()
}

return { color }
}
8 changes: 7 additions & 1 deletion apps/web/app/composables/useSupabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import type { FormSpeaker, FormSponsor, FormAttendee, FormStaff } from '~/types/
export function useSupabase() {
const client = useSupabaseClient<Database>()

async function fetchData(table: Table) {
async function fetchData(table: Table, options?: { id?: string; detailPageId?: string }) {
if (options?.id) {
return await client.from(table).select().eq('id', options.id)
}
if (options?.detailPageId) {
return await client.from(table).select().eq('detail_page_id', options.detailPageId)
}
return await client.from(table).select()
}

Expand Down
264 changes: 264 additions & 0 deletions apps/web/app/pages/sessions/[id]/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
<script setup lang="ts">
import { createError, useAsyncData, useHead, useRoute } from '#imports'
import type { Speaker } from '@vuejs-jp/model'
import { useLocaleCurrent } from '~/composables/useLocaleCurrent'
import { useSupabase } from '~/composables/useSupabase'
import { conferenceTitle, linkUrl, ogSpeakerDescription } from '~/utils/constants'
import { generalOg, twitterOg } from '~/utils/og.constants'
const route = useRoute()
const id = route.params.id as string
const { fetchData } = useSupabase()
const { data: speakers } = await useAsyncData('speakers', async () => {
return await fetchData('speakers', { detailPageId: id })
})
const speakerData = speakers.value?.data as Speaker[]
if (!speakerData) {
throw createError({ statusCode: 404, statusMessage: 'Speaker not found' })
}
if (!speakerData[0].detail_page_id) {
throw createError({ statusCode: 404, statusMessage: 'Speaker not found' })
}
const currentLocale = useLocaleCurrent().locale
useHead({
titleTemplate: (titleChunk) => `${speakerData[0].session_title_ja} | ${conferenceTitle}`,
meta: [
...generalOg({
title: `${speakerData[0].session_title_ja} | ${conferenceTitle}`,
description: ogSpeakerDescription,
url: `${linkUrl}sessions/${id}`,
}),
...twitterOg({
title: `${speakerData[0].session_title_ja} | ${conferenceTitle}`,
description: ogSpeakerDescription,
url: `${linkUrl}sessions/${id}`,
}),
],
})
</script>

<template>
<VFPageHeading>{{ $t('speaker.title') }}</VFPageHeading>
<div class="session-detail">
<div class="session-detail-body">
<VFTitle id="sponsor-detail" class="detailbody-title">
{{ currentLocale === 'ja' ? (speakerData[0].session_title_ja ?? 'TBD') : (speakerData[0].session_title_en ?? 'TBD') }}
</VFTitle>

<div class="detailbody-explain">
{{ currentLocale === 'ja' ? (speakerData[0].session_description_ja ?? 'TBD') : (speakerData[0].session_description_en ?? 'TBD') }}
</div>

<div class="detailbody-persons">
<VFSpeaker
:image="speakerData[0].image_url"
:company="currentLocale === 'en' ? speakerData[0].caption_en : speakerData[0].caption_ja"
:division="currentLocale === 'en' ? speakerData[0].description_en : speakerData[0].description_ja"
:name="currentLocale === 'en' ? speakerData[0].name_en : speakerData[0].name_ja"
:github-id="speakerData[0].github_id"
:x-id="speakerData[0].x_id"
/>
<div class="person-info">
{{ currentLocale === 'ja' ? speakerData[0].description_ja : speakerData[0].description_en }}
</div>
</div>

<div class="back">
<VFLinkButton
class="back-action"
background-color="white"
color="vue-blue"
target=""
:href="currentLocale === 'ja' ? '/' : `${currentLocale}/`"
>
{{ $t('back_to_top') }}
</VFLinkButton>
</div>
</div>
</div>
</template>

<style scoped>
@import url('../../../assets/base.css');
@import url('../../../assets/media.css');
.session-detail {
margin: 0;
padding: 0 1.5%;
background-image: linear-gradient(#fff, #ebf0f5);
position: relative;
z-index: 0;
overflow: hidden;
@media (--tablet) {
padding: 0 6%;
}
&:before {
content: "";
position: absolute;
display: block;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('/form-bg.png');
background-size: auto;
background-repeat: repeat;
background-position: bottom left;
opacity: 0.8;
mix-blend-mode: overlay;
z-index: -1;
}
}
.session-detail-body {
--head-img-width: 475px;
margin: 0 auto;
padding: 60px 0 120px;
width: 100%;
max-width: 1280px;
display: grid;
gap: calc(var(--unit) * 8);
@media (--tablet) {
padding: 20px 0 60px;
max-width: 100%
}
.detailbody-title {
text-align: left;
font-size: 32px;
font-weight: 700;
margin-bottom: calc(var(--unit) * 3);
}
.detailbody-explain {
/* margin: 0 auto calc(var(--unit) * 8); */
}
.detailbody-explain ul {
list-style-type: square;
margin-left: calc(var(--unit) * 4);
margin-bottom: calc(var(--unit) * 2);
}
.detailbody-explain p {
color: var(--color-vue-blue);
font-weight: 500;
font-size: 18px;
line-height: 1.8;
}
.detailbody-explain p a {
color: var(--color-vue-green);
text-decoration: underline;
}
.detailbody-explain p a:hover {
transition: 0.2s;
}
.detailbody-persons {
font-size: 18px;
display: grid;
grid-template-columns: auto 1fr;
gap: calc(var(--unit) * 4);
}
.detailbody-persons ::v-deep(img) {
width: var(--head-img-width);
}
.person-info ::v-deep(ul) {
list-style-type: square;
margin-left: calc(var(--unit) * 4);
margin-bottom: calc(var(--unit) * 2);
}
.person-info ::v-deep(p) {
color: var(--color-vue-blue);
font-weight: 500;
font-size: 18px;
line-height: 1.8;
}
.person-info ::v-deep(p a) {
color: var(--color-vue-green);
text-decoration: underline;
}
.person-info ::v-deep(p a:hover) {
transition: 0.2s;
}
.back {
margin: 40px auto 0;
width: 100%;
max-width: 260px;
}
.back-action {
--height-button: 66px;
height: var(--height-button);
border-radius: var(--height-button);
display: flex;
}
@media (--tablet) {
--head-img-width: 368px;
.back-action {
--height-button: 58px;
}
}
@media (--mobile) {
--head-img-width: 100%;
.detailbody {
display: block;
}
.detailbody-title {
font-size: 24px;
}
.detailbody-explain ::v-deep(p) {
font-size: 16px;
}
.detailbody-persons {
grid-template-columns: 1fr;
place-items: center;
}
.person-info ::v-deep(p) {
font-size: 16px;
}
.back {
width: 100%;
padding: 0 23.5px;
margin-top: 30px;
margin-bottom: 60px;
}
.back-action {
--height-button: 58px;
}
}
a {
border-radius: 12px;
overflow: hidden;
display: block;
}
}
</style>
Loading

0 comments on commit 16ff39c

Please sign in to comment.