Skip to content

Commit 1394f67

Browse files
ryamakuchiinouetakuya
authored andcommitted
Contentful から Sponsor データを取得する (vuejs-jp#55)
* new file: src/components/TheSponsorListSection.vue * + test.todo('スポンサー情報が表示されている') * + test('スポンサー情報が表示されている', () => { ... } * wrapper が冗長だったのでリファクタリングした * + <TheSponsorListSection /> * スポンサー情報を asyncData でセットするようにした * Contentful からスポンサー情報を取得するようにした * fix: error TS2322: Type '{ ctfSpaceId: string | undefined; ctfCdaAccessToken: string | undefined; }' is not assignable to type 'NuxtConfigurationEnv'. * + CTF_CDA_ACCESS_TOKEN=PLEASE_SET_ME * nuxt 経由の env を使うように修正した * スポンサー情報の取得を src/plugins/contentful.ts に切り出した * + readonly sponsorList!: Entry<any>[] * new file: test/unit/__mocks__/sponsorListMock.ts * + import sponsorList from '../../__mocks__/sponsorListMock' * スポンサーの種類によって表示をまとめるようにした * スポンサーを publishedAt 順に表示する * SponsorListSection と SponsorSection とを統合した * new file: src/components/SponsorGroup.vue * + test('sponsorType がクラスに含まれる', () => { ... }) * SponsorGroup でバナー画像のリンクを表示させるようにした * interface を作るまでもない * Contentful の Sponsor 定義変更を反映させた * スポンサープランを追加した スポンサープランの表示を柔軟にできるようにした * fix testing * 複数のスポンサープランをまとめて表示させることもできるようにするため SponsorGroup コンポーネントを廃止した * スタイルの調整(モバイル) * スタイルの調整(デスクトップ) * fix: ネガティブマージンを短縮形で書いた * Update src/components/TheSponsorListSection.vue Co-Authored-By: INOUE Takuya <[email protected]> * fix: .sponsor-plan の md lg サイズのフォントを指定した * sm でもバナーがひとつしかない場合は中央配置になるように修正 * バナーサイズを修正 * ルーム A/B とルーム C スポンサーを統合した。ランチスポンサーも同様に統合した
1 parent f3b9cb7 commit 1394f67

21 files changed

+707
-174
lines changed

.env.example

+3-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
GA_TRACKING_ID=UA-XXXXXXX-X
1+
CTF_SPACE_ID=PLEASE_SET_CTF_SPACE_ID
2+
CTF_CDA_ACCESS_TOKEN=PLEASE_SET_CTF_CDA_ACCESS_TOKEN
3+
GA_TRACKING_ID=UA-XXXXXXX-X

.env.test

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CTF_SPACE_ID=secret
2+
CTF_CDA_ACCESS_TOKEN=secret
3+
GA_TRACKING_ID=UA-XXXXXXX-X

.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module.exports = {
2222
}
2323
}
2424
],
25+
'no-console': 'off',
2526
'no-unused-vars': 'off',
2627
'@typescript-eslint/no-unused-vars': 'error'
2728
}

jest.config.js

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require('dotenv').config({ path: '.env.test' })
2+
13
module.exports = {
24
moduleNameMapper: {
35
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':

nuxt.config.ts

+5
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ const config: NuxtConfiguration = {
106106
}
107107
]
108108
],
109+
env: {
110+
CTF_SPACE_ID: process.env.CTF_SPACE_ID || 'PLEASE_SET_CTF_SPACE_ID',
111+
CTF_CDA_ACCESS_TOKEN:
112+
process.env.CTF_CDA_ACCESS_TOKEN || 'PLEASE_SET_CTF_CDA_ACCESS_TOKEN'
113+
},
109114
build: {
110115
extend(config, ctx) {
111116
if (ctx.isDev && ctx.isClient) {

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"@nuxtjs/dotenv": "^1.3.0",
3030
"@nuxtjs/google-analytics": "^2.2.0",
3131
"@nuxtjs/pwa": "^3.0.0-beta.12",
32+
"contentful": "^7.6.0",
3233
"cross-env": "^5.2.0",
3334
"normalize.css": "^8.0.1",
3435
"nuxt": "^2.6.1",
-17 Bytes
Loading
6 Bytes
Loading
-19 Bytes
Loading

src/assets/images/staffs/show60.png

-7 Bytes
Loading

src/assets/images/store.png

3 Bytes
Loading

src/assets/images/[email protected]

-78 Bytes
Loading
+316
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
<template>
2+
<BaseSection class="the-sponsor-list-section">
3+
<template slot="heading">
4+
SPONSORS
5+
</template>
6+
7+
<div class="content">
8+
<div class="description">
9+
<p>
10+
Vue.js に関わる人々が集まる Vue Fes Japan 2019 をよりよいイベントにするため、スポンサーを募集します。<a class="link" href="https://fortee.jp/vuefes-2019/sponsor/form" target="_blank" rel="noopener">こちらのフォーム</a> よりお申し込みください。応募締め切りは、2019年7月31日(水)です。
11+
</p>
12+
13+
<p>
14+
最新情報は <a class="link" href="https://twitter.com/vuefes" target="_blank" rel="noopener">Vue Fes Japan の Twitter</a> もしくは <a class="link" href="https://note.mu/vuejs_jp/m/mb35849fee631" target="_blank" rel="noopener">公式 note</a> でご確認ください。
15+
</p>
16+
17+
<p>
18+
資料は <a class="link" href="https://docs.google.com/presentation/d/1YSr_QVUUKZmkYMBICE3mIQl2Um9OXfeS2AKgiOHX4Ds/edit#slide=id.p" target="_blank" rel="noopener">こちら</a>
19+
</p>
20+
</div>
21+
22+
<LinkToTwitter class="link-to-twitter show-on-medium-and-up" />
23+
</div>
24+
25+
<div
26+
v-lazy-container="{ selector: 'img' }"
27+
class="image"
28+
>
29+
<img
30+
:data-srcset="`${imageOne}, ${imageOne2x} 2x`"
31+
:data-src="imageOne2x"
32+
alt=""
33+
/>
34+
35+
<img
36+
:data-srcset="`${imageTwo}, ${imageTwo2x} 2x`"
37+
:data-src="imageTwo2x"
38+
alt=""
39+
/>
40+
41+
<img
42+
:data-srcset="`${imageThree}, ${imageThree2x} 2x`"
43+
:data-src="imageThree2x"
44+
alt=""
45+
/>
46+
</div>
47+
48+
<LinkToTwitter class="show-on-small" />
49+
50+
<ul v-for="sponsorPlan in sponsorPlans" :key="sponsorPlan.plan">
51+
<li
52+
v-if="sponsorsByPlan(sponsorPlan.plan).length > 0"
53+
class="sponsor-group"
54+
:class="sponsorPlan.plan"
55+
>
56+
<h3 class="sponsor-plan">
57+
{{ sponsorPlan.name }}
58+
</h3>
59+
60+
<ul>
61+
<li
62+
v-for="sponsor in sortSponsors(sponsorsByPlan(sponsorPlan.plan))"
63+
:key="sponsor.sys.id"
64+
class="sponsor"
65+
>
66+
<a
67+
:href="sponsor.fields.url"
68+
target="_blank"
69+
rel="noopener"
70+
>
71+
<div v-lazy-container="{ selector: 'img' }">
72+
<img
73+
class="sponsor-image"
74+
:data-src="sponsor.fields.banner.fields.file.url"
75+
:alt="sponsor.fields.name"
76+
/>
77+
</div>
78+
</a>
79+
</li>
80+
</ul>
81+
</li>
82+
</ul>
83+
84+
<BaseButton
85+
class="link-to-sponsor-form"
86+
href="https://fortee.jp/vuefes-2019/sponsor/form"
87+
target="_blank"
88+
rel="noopener"
89+
>
90+
スポンサー申し込みフォーム
91+
</BaseButton>
92+
</BaseSection>
93+
</template>
94+
95+
<script lang="ts">
96+
import { Component, Prop, Vue } from 'nuxt-property-decorator'
97+
import { Entry } from 'contentful/index'
98+
import BaseButton from '~/components/BaseButton.vue'
99+
import BaseSection from '~/components/BaseSection.vue'
100+
import LinkToTwitter from '~/components/LinkToTwitter.vue'
101+
102+
@Component({
103+
components: {
104+
BaseButton,
105+
BaseSection,
106+
LinkToTwitter
107+
}
108+
})
109+
export default class TheSponsorListSection extends Vue {
110+
private imageOne = require('~/assets/images/sponsors/image1.jpg')
111+
private imageOne2x = require('~/assets/images/sponsors/[email protected]')
112+
113+
private imageTwo = require('~/assets/images/sponsors/image2.jpg')
114+
private imageTwo2x = require('~/assets/images/sponsors/[email protected]')
115+
116+
private imageThree = require('~/assets/images/sponsors/image3.jpg')
117+
private imageThree2x = require('~/assets/images/sponsors/[email protected]')
118+
119+
sponsorPlans: { plan: string; name: string }[] = [
120+
{ plan: 'platinum', name: 'PLATINUM' },
121+
{ plan: 'gold', name: 'GOLD' },
122+
{ plan: 'silver', name: 'SILVER' },
123+
{ plan: 'bronze', name: 'BRONZE' },
124+
{ plan: 'room', name: 'ROOM' },
125+
{ plan: 'translation', name: '同時通訳' },
126+
{ plan: 'commercial', name: '幕間 CM' },
127+
{ plan: 'toast', name: 'カンパイ' },
128+
{ plan: 'lunch', name: 'LUNCH' },
129+
{ plan: 'refreshment', name: 'REFRESHMENT' }
130+
]
131+
132+
@Prop()
133+
readonly sponsorList!: Entry<any>[]
134+
135+
sortSponsors(sponsors): Entry<any>[] {
136+
return sponsors.sort((a, b) => {
137+
if (a.fields.appliedAt < b.fields.appliedAt) return -1
138+
if (a.fields.appliedAt > b.fields.appliedAt) return 1
139+
140+
return 0
141+
})
142+
}
143+
144+
sponsorsByPlan(plan): Entry<any>[] {
145+
return this.sponsorList.filter(sponsor => sponsor.fields.plan === plan)
146+
}
147+
}
148+
</script>
149+
150+
<style lang="scss" scoped>
151+
ul {
152+
margin: 0; // このコンポーネントでは ul 要素に margin を持たせない
153+
}
154+
155+
.the-sponsor-list-section {
156+
background: linear-gradient(to right bottom, $tohoh, $sangosyu);
157+
}
158+
159+
.content {
160+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
161+
position: absolute;
162+
width: calc(100% - 140px);
163+
max-width: $page-container-max-width;
164+
}
165+
}
166+
167+
.description {
168+
background-color: $white;
169+
padding: 6.17%;
170+
margin-bottom: 5vw;
171+
172+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
173+
width: 70%;
174+
max-width: calc(#{$page-container-max-width} * 0.7);
175+
padding: 40px;
176+
margin-top: -30px;
177+
margin-bottom: 60px;
178+
z-index: 1;
179+
}
180+
}
181+
182+
.start-datetime {
183+
text-decoration: underline;
184+
}
185+
186+
.image {
187+
margin-bottom: 5vw;
188+
189+
img {
190+
display: block;
191+
width: 100%;
192+
}
193+
194+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
195+
width: 340px;
196+
margin: -125px 0 0 auto;
197+
}
198+
199+
@media screen and (min-width: $layout-breakpoint--is-medium-up) {
200+
margin: -125px 5% 0 auto;
201+
}
202+
}
203+
204+
.link-to-twitter {
205+
width: 100%;
206+
max-width: 100%;
207+
margin-top: 10vw;
208+
209+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
210+
width: 700px;
211+
margin: 0 auto 0 0;
212+
}
213+
}
214+
215+
// ここから下は Sponsor 一覧の CSS
216+
.sponsor-plan {
217+
font-size: 5vw;
218+
text-align: center;
219+
font-weight: bold;
220+
margin: calc(10vw - 20px) 0 1vw;
221+
222+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
223+
font-size: 30px;
224+
margin: 80px 0 20px;
225+
}
226+
}
227+
228+
.sponsor-group {
229+
ul {
230+
display: flex;
231+
flex-wrap: wrap;
232+
justify-content: center;
233+
width: calc(100% + 20px);
234+
margin: -10px;
235+
}
236+
237+
img {
238+
display: block;
239+
width: 100%;
240+
}
241+
242+
.sponsor {
243+
width: calc(50% - 20px);
244+
margin: 10px;
245+
246+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
247+
width: calc((100% / 5) - 20px); // 普通サイズの Sponsor バナーの横幅
248+
}
249+
}
250+
}
251+
252+
.sponsor-group.bronze {
253+
.sponsor {
254+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
255+
width: calc((100% / 6) - 20px);
256+
}
257+
}
258+
}
259+
260+
.sponsor-group.gold {
261+
.sponsor {
262+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
263+
width: calc((100% / 4) - 20px);
264+
}
265+
}
266+
}
267+
268+
.sponsor-group.platinum {
269+
ul {
270+
width: 100%;
271+
margin: 0;
272+
273+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
274+
width: calc(100% + 20px);
275+
margin: -10px;
276+
}
277+
}
278+
279+
.sponsor-plan {
280+
margin: 5vw 0 1vw;
281+
282+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
283+
margin: 40px 0 20px;
284+
}
285+
}
286+
287+
.sponsor {
288+
width: 100%;
289+
margin: 0 0 5vw;
290+
291+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
292+
width: calc(30% - 20px);
293+
margin: 10px;
294+
}
295+
296+
&:last-child {
297+
margin-bottom: 0;
298+
299+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
300+
margin-bottom: 10px;
301+
}
302+
}
303+
}
304+
}
305+
306+
.link-to-sponsor-form {
307+
width: 100%;
308+
max-width: 100%;
309+
margin: calc(10vw - 20px) auto 0;
310+
311+
@media screen and (min-width: $layout-breakpoint--is-small-up) {
312+
width: 700px;
313+
margin: 80px auto 0;
314+
}
315+
}
316+
</style>

0 commit comments

Comments
 (0)