Skip to content

Commit b4f7eba

Browse files
authored
Merge branch 'main' into feature/creation-namecard
2 parents 7a6456d + 2e88b2a commit b4f7eba

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+787
-93
lines changed

apps/web/.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ SUPABASE_URL=
66
SUPABASE_KEY=
77
SPEAKER_DATASOURCE= # local or supabase
88
SPONSOR_DATASOURCE= # local or supabase
9+
AVAILABLE_APPLY_SPEAKER=
910
AVAILABLE_APPLY_SPONSOR=
1011
ENABLE_INVITE_STAFF=
1112
ENABLE_OPERATE_ADMIN=
1213
ENABLE_SWITCH_LOCALE=
1314
ENABLE_REGISTER_TICKET=
1415
ENABLE_REGISTER_NAMECARD=
16+
SHOW_EVENT=
1517
SHOW_STORE=

apps/web/app/components/GlobalHeader.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ const toggleMenu = () => {
4242
<a
4343
href=""
4444
class="navigation-mobile-toggle"
45-
name="Menu"
45+
name="menu"
4646
:class="{ 'isOpened': showMenu }"
4747
@click.prevent="toggleMenu"
4848
>
4949
<span /><span /><span />
5050
</a>
51-
<!-- <VFIcon name="Menu" color="vue-blue" can-hover @click="toggleMenu" /> -->
51+
<!-- <VFIcon name="menu" color="vue-blue" can-hover @click="toggleMenu" /> -->
5252
</div>
5353
<!-- hamburger-menu -->
5454
<Transition name="slide-down">

apps/web/app/components/SpeakerPageSection.vue

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import { useFetch } from '#imports'
3+
import SpeakerCfp from '~/components/speaker/SpeakerCfp.vue'
34
import { useLocaleCurrent } from '@/composables/useLocaleCurrent'
45
import type { SpeakerCategory, SpeakerInfo } from '@vuejs-jp/model'
56
@@ -17,9 +18,9 @@ const { sessionSpeakers, lightningTalkSpeakers, sponsorSessionSpeakers } = data.
1718

1819
<template>
1920
<div class="speaker">
20-
<SpeakerCfp />
21+
<article class="speaker-body-wrapper">
22+
<SpeakerCfp />
2123

22-
<article class="speaker-body">
2324
<div class="speaker-text">
2425
<MarkDownText path="speaker" />
2526
</div>
@@ -108,12 +109,7 @@ const { sessionSpeakers, lightningTalkSpeakers, sponsorSessionSpeakers } = data.
108109
}
109110
}
110111
111-
.title {
112-
text-align: center;
113-
line-height: 1.2;
114-
}
115-
116-
.speaker-body {
112+
.speaker-body-wrapper {
117113
margin: 0 1.5%;
118114
max-width: calc(960px + 6%);
119115
isolation: isolate;
@@ -168,7 +164,7 @@ const { sessionSpeakers, lightningTalkSpeakers, sponsorSessionSpeakers } = data.
168164
--speaker-row-gap: 0px;
169165
}
170166
171-
.speaker-body {
167+
.speaker-body-wrapper {
172168
--speaker-body-padding: calc(var(--unit) * 4) 4.5% calc(var(--unit) * 6);
173169
}
174170

apps/web/app/components/SponsorPageSection.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const {
5959
silverSponsors,
6060
bronzeSponsors,
6161
specialNamingRightSponsors,
62+
namingRightSponsors,
6263
specialLunchSponsors,
6364
afterPartySponsors,
6465
nameCardSponsors,
@@ -146,6 +147,7 @@ const {
146147
<SponsorList v-bind="silverSponsors" />
147148
<SponsorList v-bind="bronzeSponsors" />
148149
<SponsorList v-bind="specialNamingRightSponsors" />
150+
<SponsorList v-bind="namingRightSponsors" />
149151
<div class="sponsor-list-layout-separate">
150152
<SponsorList v-bind="specialLunchSponsors" />
151153
<SponsorList v-bind="afterPartySponsors" />

apps/web/app/components/TopPageSection.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ const { locale } = useI18n()
2929
class="link-button"
3030
background-color="vue-green/200"
3131
color="white"
32-
icon-name="x22"
32+
icon-name="x"
3333
href="https://twitter.com/vuefes"
3434
>@vuefes</VFLinkButton
3535
>
3636
<VFLinkButton
3737
class="link-button"
3838
background-color="white"
3939
color="vue-blue"
40-
icon-name="note22"
40+
icon-name="note"
4141
href="https://note.com/vuejs_jp/m/mb35849fee631"
4242
>{{ $t('top_page.note') }}
4343
</VFLinkButton>
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<script setup lang="ts">
2+
import type { Job, Sponsor } from '@vuejs-jp/model'
3+
import { ref } from 'vue'
4+
import { useSupabase } from '~/composables/useSupabase'
5+
import { useSupabaseStorage } from '~/composables/useSupabaseStorage'
6+
7+
interface AddJobProps {
8+
job?: Job
9+
sponsors: Sponsor[]
10+
}
11+
const emit = defineEmits<{ close: [] }>()
12+
const props = defineProps<AddJobProps>()
13+
14+
const { upsertJob, uploadAvatar } = useSupabase()
15+
const { getFullAvatarUrl } = useSupabaseStorage()
16+
17+
const newJob = ref({
18+
...props.job?.id && { id: props.job?.id },
19+
sponsor_id: props.job?.sponsor_id ?? '',
20+
link_url: props.job?.link_url ?? '',
21+
image_url: props.job?.image_url ?? '',
22+
image_alt: props.job?.image_alt ?? '',
23+
display_order: props.job?.display_order ?? null,
24+
is_open: props.job?.is_open ?? true,
25+
})
26+
27+
const updateDisplayOrder = (e: any) => {
28+
newJob.value.display_order = e.target.value
29+
}
30+
const updateLinkUrl = (e: any) => {
31+
newJob.value.link_url = e.target.value
32+
}
33+
const checkFiles = (files: File[]) => {
34+
if (files.length === 0) return
35+
36+
const file = files[0]
37+
// const filename = file.name
38+
const fileExt = file.name.split('.').pop()
39+
const filePath = `/${Math.random()}.${fileExt}`
40+
41+
uploadAvatar(filePath, file)
42+
43+
newJob.value.image_url = getFullAvatarUrl(filePath)
44+
}
45+
const updateImageAlt = (e: any) => {
46+
newJob.value.image_alt = e.target.value
47+
}
48+
49+
const onSubmit = () => {
50+
upsertJob('jobs', newJob.value)
51+
}
52+
</script>
53+
54+
<template>
55+
<div class="container">
56+
<VFTitle class="title">Job</VFTitle>
57+
<div class="form">
58+
<form @submit="onSubmit">
59+
<VFDropdownField
60+
id="sponsor_id"
61+
v-model="newJob.sponsor_id"
62+
name="sponsor_id"
63+
label="スポンサー"
64+
:items="sponsors.map((s) => ({ value: s.id, text: s.name }))"
65+
/>
66+
<VFInputField
67+
id="link_url"
68+
v-model="newJob.link_url"
69+
name="link_url"
70+
label="回遊させたい URL"
71+
@input="updateLinkUrl"
72+
/>
73+
<VFDragDropArea file-name="profiledata" file-accept="image/*" @check-files="checkFiles">
74+
<div class="upload">
75+
<img
76+
v-if="newJob.image_url"
77+
alt=""
78+
:src="newJob.image_url"
79+
height="60"
80+
decoding="async"
81+
/>
82+
<p>Drag & drop a file</p>
83+
<p>または</p>
84+
<p>Select a file</p>
85+
</div>
86+
</VFDragDropArea>
87+
<VFInputField
88+
id="image_alt"
89+
v-model="newJob.image_alt"
90+
name="image_alt"
91+
label="掲載画像の ALT 属性"
92+
@input="updateImageAlt"
93+
/>
94+
<VFInputField
95+
id="display_order"
96+
v-model="newJob.display_order"
97+
name="display_order"
98+
label="表示順"
99+
@input="updateDisplayOrder"
100+
/>
101+
<VFDropdownField
102+
id="is_open"
103+
v-model="newJob.is_open"
104+
name="is_open"
105+
label="表示・非表示"
106+
:items="[
107+
{ value: 'false', text: '非表示' },
108+
{ value: 'true', text: '表示' },
109+
]"
110+
/>
111+
<div class="form-button">
112+
<VFSubmitButton>Save</VFSubmitButton>
113+
<VFLinkButton
114+
is="button"
115+
class="action"
116+
background-color="white"
117+
color="vue-blue"
118+
@click="emit('close')"
119+
>
120+
Close
121+
</VFLinkButton>
122+
</div>
123+
</form>
124+
</div>
125+
</div>
126+
</template>
127+
128+
<style scoped>
129+
.container {
130+
height: 600px;
131+
overflow-y: scroll;
132+
}
133+
.form {
134+
padding: 40px 20px;
135+
}
136+
form {
137+
display: grid;
138+
gap: 40px;
139+
width: 100%;
140+
}
141+
.action {
142+
--height-button: 66px;
143+
144+
margin-top: 40px;
145+
height: var(--height-button);
146+
}
147+
@media (--tablet) {
148+
.action {
149+
--height-button: 49px;
150+
}
151+
}
152+
</style>
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<script setup lang="ts">
2+
import { ref } from 'vue'
3+
4+
interface JobListProps {
5+
jobs: any
6+
}
7+
8+
const emit = defineEmits<{ edit: [id: string] }>()
9+
10+
const props = defineProps<JobListProps>()
11+
12+
const showDialog = ref(false)
13+
const jobId = ref('')
14+
const handleDialog = (id?: string) => {
15+
showDialog.value = !showDialog.value
16+
jobId.value = id ?? ''
17+
}
18+
</script>
19+
20+
<template>
21+
<table id="jobs">
22+
<tr>
23+
<th>link_url</th>
24+
<th>image_url</th>
25+
<th>image_alt</th>
26+
<th>is_open</th>
27+
<th style="min-width: 80px">action</th>
28+
</tr>
29+
<tr v-for="job in jobs" :key="job.id">
30+
<td>{{ job.link_url }}</td>
31+
<td>
32+
<img
33+
v-if="job.image_url"
34+
alt=""
35+
:src="job.image_url"
36+
height="60"
37+
decoding="async"
38+
/>
39+
<p v-if="!job.image_url">
40+
No image
41+
</p>
42+
</td>
43+
<td>{{ job.image_alt }}</td>
44+
<td>
45+
<p>{{ job.is_open ? '表示' : '非表示' }}</p>
46+
<p v-if="job.display_order">{{ `(${job.display_order})` }}</p>
47+
</td>
48+
<td>
49+
<VFLinkButton
50+
is="button"
51+
class="action"
52+
background-color="white"
53+
color="vue-blue"
54+
@click="() => handleDialog(job?.id)"
55+
>
56+
Edit
57+
</VFLinkButton>
58+
</td>
59+
</tr>
60+
</table>
61+
<VFDialog v-if="showDialog">
62+
<AdminJobItem
63+
:job="jobs.filter((s) => s.id === jobId)[0]"
64+
@close="handleDialog"
65+
/>
66+
</VFDialog>
67+
</template>
68+
69+
<style scoped>
70+
#jobs {
71+
border-collapse: collapse;
72+
width: 100%;
73+
}
74+
75+
#jobs td,
76+
#jobs th {
77+
border: 1px solid #ddd;
78+
padding: 8px;
79+
}
80+
81+
#jobs tr:nth-child(even){
82+
background-color: #f2f2f2;
83+
}
84+
85+
#jobs tr:hover {
86+
background-color: #ddd;
87+
}
88+
89+
#jobs th {
90+
padding: 12px auto;
91+
text-align: left;
92+
background-color: var(--color-vue-green200);
93+
color: #fff;
94+
}
95+
</style>

apps/web/app/components/admin/Page.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@ interface ListProps {
1414
const selectedRole = ref<Role>('attendee')
1515
1616
const { fetchData, fetchAttendeeData } = useSupabase()
17-
const { exportSpeaker, exportSponsor, exportAttendee, exportStaff } = useSupabaseCsv()
17+
const { exportSpeaker, exportSponsor, exportJob, exportAttendee, exportStaff } = useSupabaseCsv()
1818
const { write } = useCsv()
1919
const { data: speakers } = await useAsyncData('speakers', async () => {
2020
return await fetchData('speakers')
2121
})
2222
const { data: sponsors } = await useAsyncData('sponsors', async () => {
2323
return await fetchData('sponsors')
2424
})
25+
const { data: jobs } = await useAsyncData('jobs', async () => {
26+
return await fetchData('jobs')
27+
})
2528
const { data: attendees } = await useAsyncData('attendees', async () => {
2629
return await fetchAttendeeData('attendees', selectedRole.value)
2730
})
@@ -41,6 +44,7 @@ const handleCsv = async () => {
4144
const res = await match(props.page)
4245
.with('speaker', () => exportSpeaker('speakers'))
4346
.with('sponsor', () => exportSponsor('sponsors'))
47+
.with('job', () => exportJob('jobs'))
4448
.with('adminUser', () => exportStaff('staffs'))
4549
.with('namecard', () => exportAttendee('attendees'))
4650
.exhaustive()
@@ -91,6 +95,7 @@ const pageText = props.page.replace(/^[a-z]/g, function (val) {
9195
</div>
9296
<AdminSpeakerList v-if="page === 'speaker'" :speakers="speakers?.data" />
9397
<AdminSponsorList v-if="page === 'sponsor'" :sponsors="sponsors?.data" :speakers="speakers?.data" />
98+
<AdminJobList v-if="page === 'job'" :jobs="jobs?.data" :sponsors="sponsors?.data" />
9499
<div v-if="page === 'namecard'" class="tab-content-attendee">
95100
<VFDropdownField
96101
id="selected_role"
@@ -108,6 +113,7 @@ const pageText = props.page.replace(/^[a-z]/g, function (val) {
108113
<VFDialog v-if="showDialog">
109114
<AdminSpeakerItem v-if="page === 'speaker'" @close="handleDialog" />
110115
<AdminSponsorItem v-if="page === 'sponsor'" :speakers="speakers?.data" @close="handleDialog" />
116+
<AdminJobItem v-if="page === 'job'" :sponsors="sponsors?.data" @close="handleDialog" />
111117
<AdminStaffItem v-if="page === 'adminUser'" @close="handleDialog" />
112118
</VFDialog>
113119
</div>

0 commit comments

Comments
 (0)