├── .babelrc ├── .circleci └── config.yml ├── .editorconfig ├── .env.example ├── .env.test ├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .node-version ├── .prettierrc ├── README.md ├── bin ├── imagemin └── resize-images ├── jest.config.js ├── netlify.toml ├── nuxt.config.ts ├── package.json ├── scripts └── imagemin.js ├── src ├── assets │ ├── README.md │ ├── images │ │ ├── access.jpg │ │ ├── access@2x.jpg │ │ ├── event │ │ │ ├── badges.png │ │ │ ├── badges@2x.png │ │ │ ├── case.jpg │ │ │ ├── case@2x.jpg │ │ │ ├── cleaner.png │ │ │ ├── cleaner@2x.png │ │ │ ├── cushion.png │ │ │ ├── cushion@2x.png │ │ │ ├── information-table.jpg │ │ │ ├── information-table@2x.jpg │ │ │ ├── mobile-app.png │ │ │ ├── mobile-app@2x.png │ │ │ ├── mug.png │ │ │ ├── mug@2x.png │ │ │ ├── parka.png │ │ │ ├── parka@2x.png │ │ │ ├── party.jpg │ │ │ ├── party@2x.jpg │ │ │ ├── presents.jpg │ │ │ ├── refreshment.jpg │ │ │ ├── sponsor-booths.jpg │ │ │ ├── stickers.png │ │ │ ├── stickers@2x.png │ │ │ ├── t-shirt.png │ │ │ ├── t-shirt@2x.png │ │ │ ├── tattoo.jpg │ │ │ ├── tumbler.png │ │ │ └── tumbler@2x.png │ │ ├── header │ │ │ ├── image01.png │ │ │ ├── image02.png │ │ │ ├── image03.png │ │ │ ├── image04.png │ │ │ ├── image05.png │ │ │ └── image06.png │ │ ├── icon-exclamation.svg │ │ ├── icon-facebook.svg │ │ ├── icon-github.svg │ │ ├── icon-hatena-bookmark.svg │ │ ├── icon-note.svg │ │ ├── icon-translation.svg │ │ ├── icon-twitter-inside-btn.svg │ │ ├── icon-twitter.svg │ │ ├── logo-twitter.svg │ │ ├── logo-vuefes-invert.svg │ │ ├── logo-vuefes.svg │ │ ├── speakers │ │ │ ├── yyx990803.jpg │ │ │ └── yyx990803@2x.jpg │ │ ├── sponsors │ │ │ ├── image1.jpg │ │ │ ├── image1@2x.jpg │ │ │ ├── image2.jpg │ │ │ ├── image2@2x.jpg │ │ │ ├── image3.jpg │ │ │ └── image3@2x.jpg │ │ ├── staffs │ │ │ ├── 448jp.jpg │ │ │ ├── @2x │ │ │ │ ├── 448jp.jpg │ │ │ │ ├── KiaKing85.png │ │ │ │ ├── __syumai.png │ │ │ │ ├── andoshin11.jpg │ │ │ │ ├── aytdm251.jpg │ │ │ │ ├── c5meru.jpg │ │ │ │ ├── hashedrock.jpg │ │ │ │ ├── hisako135.jpg │ │ │ │ ├── inouetakuya.jpg │ │ │ │ ├── kawakami0717.png │ │ │ │ ├── kazu_pon.png │ │ │ │ ├── kazuyukimiyake.jpg │ │ │ │ ├── lenomick.png │ │ │ │ ├── massie.png │ │ │ │ ├── mtmtkzm.jpg │ │ │ │ ├── nahokomatsui.jpg │ │ │ │ ├── naokie.png │ │ │ │ ├── nicedchy.png │ │ │ │ ├── positiveflat.png │ │ │ │ ├── robjamdev.jpg │ │ │ │ ├── ryamakuchi.png │ │ │ │ ├── shika358.jpg │ │ │ │ ├── show60.png │ │ │ │ ├── takumisatojpn.png │ │ │ │ ├── treby006.png │ │ │ │ ├── tsuchikazu.png │ │ │ │ ├── umiremix.png │ │ │ │ ├── yakiniku040220.jpg │ │ │ │ ├── yinm.png │ │ │ │ └── yotaszk.png │ │ │ ├── KiaKing85.png │ │ │ ├── __syumai.png │ │ │ ├── andoshin11.jpg │ │ │ ├── aytdm251.jpg │ │ │ ├── c5meru.jpg │ │ │ ├── hashedrock.jpg │ │ │ ├── hisako135.jpg │ │ │ ├── inouetakuya.jpg │ │ │ ├── kawakami0717.png │ │ │ ├── kazu_pon.png │ │ │ ├── kazuyukimiyake.jpg │ │ │ ├── lenomick.png │ │ │ ├── massie.png │ │ │ ├── mtmtkzm.jpg │ │ │ ├── nahokomatsui.jpg │ │ │ ├── naokie.png │ │ │ ├── nicedchy.png │ │ │ ├── positiveflat.png │ │ │ ├── robjamdev.jpg │ │ │ ├── ryamakuchi.png │ │ │ ├── shika358.jpg │ │ │ ├── show60.png │ │ │ ├── takumisatojpn.png │ │ │ ├── treby006.png │ │ │ ├── tsuchikazu.png │ │ │ ├── umiremix.png │ │ │ ├── yakiniku040220.jpg │ │ │ ├── yinm.png │ │ │ └── yotaszk.png │ │ ├── store.png │ │ ├── store@2x.png │ │ ├── texture.png │ │ ├── ticket │ │ │ ├── image1.jpg │ │ │ ├── image1@2x.jpg │ │ │ ├── image2.jpg │ │ │ └── image2@2x.jpg │ │ └── volunteers │ │ │ ├── @2x │ │ │ ├── volunteer-1.jpg │ │ │ ├── volunteer-10.jpg │ │ │ ├── volunteer-11.jpg │ │ │ ├── volunteer-12.jpg │ │ │ ├── volunteer-13.jpg │ │ │ ├── volunteer-14.jpg │ │ │ ├── volunteer-15.jpg │ │ │ ├── volunteer-16.jpg │ │ │ ├── volunteer-17.jpg │ │ │ ├── volunteer-19.jpg │ │ │ ├── volunteer-2.jpg │ │ │ ├── volunteer-20.jpg │ │ │ ├── volunteer-21.jpg │ │ │ ├── volunteer-22.jpg │ │ │ ├── volunteer-23.jpg │ │ │ ├── volunteer-24.jpg │ │ │ ├── volunteer-25.jpg │ │ │ ├── volunteer-26.jpg │ │ │ ├── volunteer-27.jpg │ │ │ ├── volunteer-28.jpg │ │ │ ├── volunteer-3.jpg │ │ │ ├── volunteer-30.jpg │ │ │ ├── volunteer-31.jpg │ │ │ ├── volunteer-32.jpg │ │ │ ├── volunteer-33.jpg │ │ │ ├── volunteer-34.jpg │ │ │ ├── volunteer-35.jpg │ │ │ ├── volunteer-36.jpg │ │ │ ├── volunteer-37.jpg │ │ │ ├── volunteer-38.jpg │ │ │ ├── volunteer-4.jpg │ │ │ ├── volunteer-40.jpg │ │ │ ├── volunteer-41.jpg │ │ │ ├── volunteer-42.jpg │ │ │ ├── volunteer-43.jpg │ │ │ ├── volunteer-44.jpg │ │ │ ├── volunteer-45.jpg │ │ │ ├── volunteer-46.jpg │ │ │ ├── volunteer-47.jpg │ │ │ ├── volunteer-48.jpg │ │ │ ├── volunteer-5.jpg │ │ │ ├── volunteer-50.jpg │ │ │ ├── volunteer-51.jpg │ │ │ ├── volunteer-52.jpg │ │ │ ├── volunteer-53.jpg │ │ │ ├── volunteer-54.jpg │ │ │ ├── volunteer-55.jpg │ │ │ ├── volunteer-56.jpg │ │ │ ├── volunteer-57.jpg │ │ │ ├── volunteer-58.jpg │ │ │ ├── volunteer-59.jpg │ │ │ ├── volunteer-6.jpg │ │ │ ├── volunteer-60.jpg │ │ │ ├── volunteer-61.jpg │ │ │ ├── volunteer-62.jpg │ │ │ ├── volunteer-63.jpg │ │ │ ├── volunteer-64.jpg │ │ │ ├── volunteer-65.jpg │ │ │ ├── volunteer-66.jpg │ │ │ ├── volunteer-7.jpg │ │ │ └── volunteer-9.jpg │ │ │ ├── volunteer-1.jpg │ │ │ ├── volunteer-10.jpg │ │ │ ├── volunteer-11.jpg │ │ │ ├── volunteer-12.jpg │ │ │ ├── volunteer-13.jpg │ │ │ ├── volunteer-14.jpg │ │ │ ├── volunteer-15.jpg │ │ │ ├── volunteer-16.jpg │ │ │ ├── volunteer-17.jpg │ │ │ ├── volunteer-19.jpg │ │ │ ├── volunteer-2.jpg │ │ │ ├── volunteer-21.jpg │ │ │ ├── volunteer-22.jpg │ │ │ ├── volunteer-23.jpg │ │ │ ├── volunteer-24.jpg │ │ │ ├── volunteer-25.jpg │ │ │ ├── volunteer-26.jpg │ │ │ ├── volunteer-27.jpg │ │ │ ├── volunteer-28.jpg │ │ │ ├── volunteer-3.jpg │ │ │ ├── volunteer-31.jpg │ │ │ ├── volunteer-32.jpg │ │ │ ├── volunteer-33.jpg │ │ │ ├── volunteer-34.jpg │ │ │ ├── volunteer-35.jpg │ │ │ ├── volunteer-36.jpg │ │ │ ├── volunteer-37.jpg │ │ │ ├── volunteer-38.jpg │ │ │ ├── volunteer-4.jpg │ │ │ ├── volunteer-40.jpg │ │ │ ├── volunteer-41.jpg │ │ │ ├── volunteer-42.jpg │ │ │ ├── volunteer-43.jpg │ │ │ ├── volunteer-44.jpg │ │ │ ├── volunteer-45.jpg │ │ │ ├── volunteer-46.jpg │ │ │ ├── volunteer-47.jpg │ │ │ ├── volunteer-48.jpg │ │ │ ├── volunteer-5.jpg │ │ │ ├── volunteer-50.jpg │ │ │ ├── volunteer-51.jpg │ │ │ ├── volunteer-52.jpg │ │ │ ├── volunteer-53.jpg │ │ │ ├── volunteer-54.jpg │ │ │ ├── volunteer-55.jpg │ │ │ ├── volunteer-56.jpg │ │ │ ├── volunteer-57.jpg │ │ │ ├── volunteer-58.jpg │ │ │ ├── volunteer-59.jpg │ │ │ ├── volunteer-6.jpg │ │ │ ├── volunteer-60.jpg │ │ │ ├── volunteer-61.jpg │ │ │ ├── volunteer-62.jpg │ │ │ ├── volunteer-63.jpg │ │ │ ├── volunteer-64.jpg │ │ │ ├── volunteer-65.jpg │ │ │ ├── volunteer-66.jpg │ │ │ ├── volunteer-7.jpg │ │ │ └── volunteer-9.jpg │ └── stylesheets │ │ ├── foundation │ │ ├── colors.scss │ │ ├── reset.scss │ │ ├── typography.scss │ │ └── variables.scss │ │ ├── main.scss │ │ ├── media_queries.scss │ │ └── utilities.scss ├── components │ ├── BaseButton.vue │ ├── BaseMain.vue │ ├── BaseMainDescription.vue │ ├── BaseSection.vue │ ├── HeadCircle.vue │ ├── HeadCross.vue │ ├── HeadHorizontal.vue │ ├── HeadPhoto.vue │ ├── HeadSlash.vue │ ├── HeadSquare.vue │ ├── HeadTriangle.vue │ ├── LinkToTwitter.vue │ ├── README.md │ ├── TheAccessSection.vue │ ├── TheContactForm.vue │ ├── TheEventSection.vue │ ├── TheFooter.vue │ ├── TheHeadSection.vue │ ├── TheHeader.vue │ ├── TheSpeakerListSection.vue │ ├── TheSponsorListSection.vue │ ├── TheStaffListSection.vue │ ├── TheTicketSection.vue │ ├── TheTimeTableSection.vue │ └── TheTimeTableSection │ │ ├── Event.vue │ │ ├── EventContainer.vue │ │ ├── EventContent.vue │ │ ├── Keynote.vue │ │ ├── Room.vue │ │ └── Session.vue ├── hooks │ ├── index.js │ ├── render.js │ └── route-redirect-portal.js ├── layouts │ ├── README.md │ └── default.vue ├── middleware │ └── README.md ├── pages │ ├── README.md │ ├── code-of-conduct.vue │ ├── contact.vue │ ├── index.vue │ ├── privacy.vue │ ├── sessions │ │ └── _speakerId.vue │ └── sponsors.vue ├── plugins │ ├── README.md │ ├── contentful.ts │ ├── marked.ts │ ├── scroll-anchor-links.ts │ ├── typekit.ts │ ├── validateDictionary.ts │ ├── vee-validate.ts │ └── vue-lazyload.ts ├── static │ ├── README.md │ ├── apple-touch-icon.png │ ├── favicon.ico │ ├── opengraph.png │ └── session-og-images │ │ ├── Atinux.jpg │ │ ├── alexchopin.jpg │ │ ├── blackawa.jpg │ │ ├── chrisvfritz.jpg │ │ ├── default.png │ │ ├── jlooper.jpg │ │ ├── keimakai.jpg │ │ ├── keinuma.jpg │ │ ├── konu96.jpg │ │ ├── masaakikunsan.jpg │ │ ├── ninjinkun.jpg │ │ ├── octref.jpg │ │ ├── retty-y-takase.jpg │ │ ├── takefumi-yoshii.jpg │ │ ├── tejitak.jpg │ │ ├── ulivz.jpg │ │ ├── yamanoku.jpg │ │ └── yyx990803.jpg ├── store │ ├── README.md │ ├── eventContainerParts.ts │ ├── eventContainers.ts │ ├── index.ts │ ├── sessions.ts │ ├── speakers.ts │ ├── sponsors.ts │ └── timeTableSections.ts └── types │ ├── contentful.ts │ ├── event.ts │ ├── eventContainer.ts │ ├── eventContainerPart.ts │ ├── room.ts │ ├── session.ts │ ├── speaker.ts │ ├── sponsor.ts │ ├── sponsorPlan.ts │ ├── store.ts │ ├── timeTableSection.ts │ └── vue-shims.d.ts ├── stylelint.config.js ├── test ├── fixtures │ ├── assets │ │ └── images │ │ │ └── event │ │ │ ├── presents.jpg │ │ │ ├── refreshment.jpg │ │ │ ├── sponsor-booths.jpg │ │ │ └── tattoo.jpg │ └── contentful │ │ ├── asset.ts │ │ ├── eventContainerParts.ts │ │ ├── eventContainerWithEventsClosed.ts │ │ ├── eventContainerWithParts.ts │ │ ├── eventContainerWithSessionHavingTranslation.ts │ │ ├── eventContainerWithSessionNotHavingTranslation.ts │ │ ├── eventContainerWithoutParts.ts │ │ ├── eventContainers.ts │ │ ├── events.ts │ │ ├── keynote.ts │ │ ├── rooms.ts │ │ ├── sessions.ts │ │ ├── speakers.ts │ │ ├── sponsors.ts │ │ └── timeTableSections.ts └── unit │ ├── __mocks__ │ ├── fileMock.js │ └── styleMock.js │ └── specs │ ├── components │ ├── BaseButton.spec.ts │ ├── BaseMain.spec.ts │ ├── BaseMainDescription.spec.ts │ ├── BaseSection.spec.ts │ ├── LinkToTwitter.spec.ts │ ├── TheAccessSection.spec.ts │ ├── TheContactForm.spec.ts │ ├── TheEventSection.spec.ts │ ├── TheFooter.spec.ts │ ├── TheHeadSection.spec.ts │ ├── TheHeader.spec.ts │ ├── TheSpeakerListSection.spec.ts │ ├── TheSponsorListSection.spec.ts │ ├── TheStaffListSection.spec.ts │ ├── TheTicketSection.spec.ts │ ├── TheTimeTableSection.spec.ts │ └── TheTimeTableSection │ │ ├── Event.spec.ts │ │ ├── EventContainer.spec.ts │ │ ├── EventContent.spec.ts │ │ ├── Room.spec.ts │ │ └── Session.spec.ts │ ├── pages │ ├── code-of-conduct.spec.ts │ ├── contact.spec.ts │ ├── index.spec.ts │ ├── privacy.spec.ts │ ├── sessions │ │ └── _speakerId.spec.ts │ └── sponsors.spec.ts │ ├── store │ ├── eventContainerParts.spec.ts │ ├── eventContainers.spec.ts │ ├── sessions.spec.ts │ ├── speakers.spec.ts │ ├── sponsors.spec.ts │ └── timeTableSections.spec.ts │ └── utils │ └── createFullStore.ts ├── tsconfig.json └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "test": { 4 | "presets": [ 5 | [ 6 | "@babel/preset-env", 7 | { 8 | "targets": { 9 | "node": "current" 10 | } 11 | } 12 | ] 13 | ] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Javascript Node CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | docker: 9 | # specify the version you desire here 10 | - image: circleci/node:10.15.3-browsers 11 | 12 | # Specify service dependencies here if necessary 13 | # CircleCI maintains a library of pre-built images 14 | # documented at https://circleci.com/docs/2.0/circleci-images/ 15 | # - image: circleci/mongo:3.4.4 16 | 17 | working_directory: ~/repo 18 | 19 | steps: 20 | - checkout 21 | 22 | # Download and cache dependencies 23 | - restore_cache: 24 | keys: 25 | - v1-dependencies-{{ checksum "package.json" }} 26 | # fallback to using the latest cache if no exact match is found 27 | - v1-dependencies- 28 | 29 | - run: yarn install 30 | 31 | - save_cache: 32 | paths: 33 | - node_modules 34 | key: v1-dependencies-{{ checksum "package.json" }} 35 | 36 | - run: yarn lint 37 | - run: yarn test:ci 38 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 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 4 | GOOGLE_MAPS_API_KEY=PLEASE_SET_ME 5 | -------------------------------------------------------------------------------- /.env.test: -------------------------------------------------------------------------------- 1 | CTF_SPACE_ID=secret 2 | CTF_CDA_ACCESS_TOKEN=secret 3 | GA_TRACKING_ID=UA-XXXXXXX-X 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true 6 | }, 7 | parserOptions: { 8 | parser: '@typescript-eslint/parser' 9 | }, 10 | extends: [ 11 | '@nuxtjs', 12 | 'plugin:nuxt/recommended', 13 | 'plugin:prettier/recommended' 14 | ], 15 | plugins: ['@typescript-eslint', 'prettier'], 16 | rules: { 17 | 'vue/html-self-closing': [ 18 | 'error', 19 | { 20 | html: { 21 | void: 'always' 22 | } 23 | } 24 | ], 25 | 'no-console': 'off', 26 | 'no-unused-vars': 'off', 27 | '@typescript-eslint/no-unused-vars': 'error' 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## 解決したい問題 2 | 3 | 4 | ## 問題を解決するために 5 | 6 | 7 | ## この Issue の完了条件 8 | 9 | 10 | ## 参考 11 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | resolve 2 | 3 | ## TODO 4 | - [ ] 5 | 6 | ## レビューポイント 7 | - 8 | 9 | ## 参考 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE 81 | .idea 82 | 83 | # Service worker 84 | sw.* 85 | 86 | /tmp/ 87 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 10.15.3 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue Fes Japan 2019 2 | 3 | [![CircleCI](https://circleci.com/gh/vuejs-jp/vuefes-2019.svg?style=svg&circle-token=2e5a81f10b558c9aa99c38a2acc9bc862b20c860)](https://circleci.com/gh/vuejs-jp/vuefes-2019) 4 | 5 | このリポジトリは Vue Fes Japan 2019 の Web サイトのソースコードです。 6 | 7 | ## Setup 8 | 9 | ```shell 10 | yarn install 11 | ``` 12 | 13 | ## Development 14 | 15 | 下記コマンドを実行すると Web サーバーがホットリロードで起動して `http://localhost:3000/2019/` で確認できます。 16 | 17 | ```shell 18 | yarn dev --open 19 | ``` 20 | 21 | ### 画像の最適化 22 | 23 | 画像ファイルを追加または変更した場合には、コミット時に imagemin により自動で最適化されます。 24 | 25 | ただし Windows を使っている場合にエラーが発生するという報告を受けています。画像の最適化をスキップする場合はコミット時に `--no-verify` オプションを使ってください。 26 | 27 | ```shell 28 | git commit --no-verify 29 | ``` 30 | 31 | #### コアスタッフの画像のリサイズ 32 | 33 | 画像ファイルを追加または変更した場合には、コミット時に [sharp](https://github.com/lovell/sharp) により自動でリサイズされます。 34 | 35 | リサイズには、gawk を使っているためインストールが必要です。 36 | 37 | Mac で Homebrew を使っている場合は、以下のコマンドでインストールできます。 38 | 39 | ```shell 40 | brew install gawk 41 | ``` 42 | 43 | ## Testing 44 | 45 | ```shell 46 | yarn test 47 | ``` 48 | 49 | ## Generate 50 | 51 | 下記コマンドを実行すると、静的ファイルを `dist/2019/` 配下に生成できます。 52 | 53 | ```shell 54 | yarn generate 55 | ``` 56 | -------------------------------------------------------------------------------- /bin/imagemin: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Fail on unset variables and command errors 4 | set -ue -o pipefail 5 | 6 | # Prevent commands misbehaving due to locale differences 7 | export LC_ALL=C 8 | 9 | for file in `git diff --cached --name-status | \ 10 | awk '$1 ~ /[AM]/ && tolower($2) ~ /\.(jpe?g|png|gif|svg)$/ {print $2}'` 11 | do 12 | echo $file を最適化します 13 | 14 | cat $file | ./node_modules/.bin/imagemin \ 15 | --plugin=mozjpeg \ 16 | --plugin=gifsicle \ 17 | --plugin=pngquant \ 18 | --plugin=optipng \ 19 | --plugin=svgo > ${file}.new 20 | mv -f ${file}.new $file 21 | 22 | git add $file 23 | done 24 | -------------------------------------------------------------------------------- /bin/resize-images: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Fail on unset variables and command errors 4 | set -ue -o pipefail 5 | 6 | # Prevent commands misbehaving due to locale differences 7 | export LC_ALL=C 8 | 9 | # FIXME: 以下、\w+ の正規表現が awk(nawk)では使えないので、gawk にしている(awk にできるなら awk にしたい) 10 | for file in `git diff --cached --name-status | \ 11 | gawk '$1 ~ /[AM]/ && tolower($2) ~ /src\/assets\/images\/staffs\/\w+\.(jpe?g|png|gif|svg)$/ {print $2}'` 12 | do 13 | echo コアスタッフの $file をリサイズします 14 | cat $file | ./node_modules/.bin/sharp \ 15 | resize 155 155 > ${file}.new 16 | mv -f ${file}.new $file 17 | git add $file 18 | done 19 | 20 | for file in `git diff --cached --name-status | \ 21 | gawk '$1 ~ /[AM]/ && tolower($2) ~ /src\/assets\/images\/staffs\/@2x\/\w+\.(jpe?g|png|gif|svg)$/ {print $2}'` 22 | do 23 | echo コアスタッフ @2x の $file をリサイズします 24 | cat $file | ./node_modules/.bin/sharp \ 25 | resize 310 310 > ${file}.new 26 | mv -f ${file}.new $file 27 | git add $file 28 | done 29 | 30 | for file in `git diff --cached --name-status | \ 31 | gawk '$1 ~ /[AM]/ && tolower($2) ~ /src\/assets\/images\/volunteers\/\w+\.(jpe?g|png|gif|svg)$/ {print $2}'` 32 | do 33 | echo ボランティアスタッフの $file をリサイズします 34 | cat $file | ./node_modules/.bin/sharp \ 35 | resize 60 60 > ${file}.new 36 | mv -f ${file}.new $file 37 | git add $file 38 | done 39 | 40 | for file in `git diff --cached --name-status | \ 41 | gawk '$1 ~ /[AM]/ && tolower($2) ~ /src\/assets\/images\/volunteers\/@2x\/\w+\.(jpe?g|png|gif|svg)$/ {print $2}'` 42 | do 43 | echo ボランティアスタッフ @2x の $file をリサイズします 44 | cat $file | ./node_modules/.bin/sharp \ 45 | resize 120 120 > ${file}.new 46 | mv -f ${file}.new $file 47 | git add $file 48 | done 49 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config({ path: '.env.test' }) 2 | 3 | module.exports = { 4 | moduleNameMapper: { 5 | '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': 6 | '/test/unit/__mocks__/fileMock.js', 7 | '\\.(css|scss)$': '/test/unit/__mocks__/styleMock.js', 8 | '^@/(.*)$': '/src/$1', 9 | '^~/(.*)$': '/src/$1', 10 | '^test/(.*)$': '/test/$1', 11 | '^vue$': 'vue/dist/vue.common.js' 12 | }, 13 | moduleFileExtensions: ['js', 'ts', 'vue', 'json'], 14 | transform: { 15 | '^.+\\.js$': 'babel-jest', 16 | '^.+\\.ts$': 'ts-jest', 17 | '.*\\.(vue)$': 'vue-jest' 18 | }, 19 | collectCoverage: true, 20 | collectCoverageFrom: [ 21 | '/components/**/*.vue', 22 | '/pages/**/*.vue' 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [[redirects]] 2 | from = "/2018/*" 3 | to = "https://vuefes-2018.netlify.com/2018/:splat" 4 | status = 200 5 | 6 | [[redirects]] 7 | from = "/2019/*" 8 | to = "https://vuefes-2019.netlify.com/2019/:splat" 9 | status = 200 10 | 11 | [[redirects]] 12 | from = "/2020/*" 13 | to = "https://vuefes-2020.netlify.app/2020/:splat" 14 | status = 200 15 | 16 | [[redirects]] 17 | from = "/2022/*" 18 | to = "https://vuefes-2022.netlify.app/2022/:splat" 19 | status = 200 20 | 21 | [[redirects]] 22 | from = "/2023/*" 23 | to = "https://vuefes-2023.netlify.app/2023/:splat" 24 | status = 200 25 | 26 | [[redirects]] 27 | from = "/2024/*" 28 | to = "https://vuefes-2024.netlify.app/2024/:splat" 29 | status = 200 30 | 31 | [[redirects]] 32 | from = "/2025/*" 33 | to = "https://vuefes-2025.netlify.app/2025/:splat" 34 | status = 200 35 | 36 | [[redirects]] 37 | from = "/*" 38 | to = "/2025/:splat" 39 | status = 301 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuefes-2019", 3 | "version": "1.0.0", 4 | "description": "Vue Fes Japan 2019", 5 | "author": "INOUE Takuya ", 6 | "private": true, 7 | "scripts": { 8 | "dev": "nuxt", 9 | "build": "nuxt build", 10 | "start": "nuxt start", 11 | "generate": "nuxt generate", 12 | "imagemin": "imagemin --plugin=mozjpeg --plugin=gifsicle --plugin=pngquant --plugin=optipng --plugin=svgo", 13 | "lint": "yarn eslint && yarn stylelint", 14 | "lint:fix": "yarn eslint:fix && yarn stylelint:fix", 15 | "eslint": "eslint --ext .ts,.js,.vue --ignore-path .gitignore .", 16 | "eslint:fix": "yarn eslint --fix", 17 | "stylelint": "stylelint 'src/**/*.vue' 'src/**/*.scss'", 18 | "stylelint:fix": "yarn stylelint --fix", 19 | "test": "jest --verbose", 20 | "test:ci": "jest --ci --coverage --no-cache --maxWorkers=2" 21 | }, 22 | "husky": { 23 | "hooks": { 24 | "pre-commit": "yarn lint && ./bin/resize-images && ./bin/imagemin" 25 | } 26 | }, 27 | "dependencies": { 28 | "@fortawesome/free-brands-svg-icons": "^5.8.1", 29 | "@nuxtjs/dotenv": "^1.3.0", 30 | "@nuxtjs/google-analytics": "^2.2.0", 31 | "@nuxtjs/pwa": "^3.0.0-beta.12", 32 | "contentful": "^7.6.0", 33 | "cross-env": "^5.2.0", 34 | "dayjs": "^1.8.16", 35 | "lodash.clonedeep": "^4.5.0", 36 | "marked": "^0.8.0", 37 | "normalize.css": "^8.0.1", 38 | "nuxt": "^2.8.1", 39 | "nuxt-fontawesome": "^0.4.0", 40 | "nuxt-property-decorator": "^2.1.3", 41 | "ts-node": "^8.0.3", 42 | "vue-lazyload": "^1.2.6" 43 | }, 44 | "devDependencies": { 45 | "@nuxt/typescript": "^2.6.1", 46 | "@nuxtjs/eslint-config": "^1.0.1", 47 | "@nuxtjs/style-resources": "^0.1.2", 48 | "@types/gsap": "^1.20.2", 49 | "@types/jest": "^24.0.11", 50 | "@typescript-eslint/eslint-plugin": "^1.6.0", 51 | "@typescript-eslint/parser": "^1.12.0", 52 | "@vue/test-utils": "^1.0.0-beta.27", 53 | "babel-core": "7.0.0-bridge.0", 54 | "babel-eslint": "^10.0.2", 55 | "babel-jest": "^24.1.0", 56 | "eslint": "^6.0.1", 57 | "eslint-config-prettier": "^6.0.0", 58 | "eslint-config-standard": ">=12.0.0", 59 | "eslint-loader": "^2.0.0", 60 | "eslint-plugin-import": "^2.18.1", 61 | "eslint-plugin-jest": ">=21.24.1", 62 | "eslint-plugin-node": ">=7.0.1", 63 | "eslint-plugin-nuxt": ">=0.4.2", 64 | "eslint-plugin-prettier": "^3.1.0", 65 | "eslint-plugin-promise": ">=4.0.1", 66 | "eslint-plugin-standard": ">=4.0.0", 67 | "eslint-plugin-vue": "^5.0.0", 68 | "fetch-mock": "^7.3.3", 69 | "flush-promises": "^1.0.2", 70 | "gsap": "^3.6.0", 71 | "husky": "^3.0.1", 72 | "imagemin-cli": "^5.0.0", 73 | "imagemin-gifsicle": "^6.0.1", 74 | "imagemin-mozjpeg": "^8.0.0", 75 | "imagemin-optipng": "^7.0.0", 76 | "imagemin-pngquant": "^8.0.0", 77 | "imagemin-svgo": "^7.0.0", 78 | "jest": "^24.1.0", 79 | "node-sass": "^4.11.0", 80 | "nodemon": "^1.18.9", 81 | "prettier": "^1.18.2", 82 | "sass-loader": "^7.1.0", 83 | "sharp": "^0.23.0", 84 | "sharp-cli": "^1.10.0", 85 | "stylelint": "^10.1.0", 86 | "stylelint-config-standard": "^18.2.0", 87 | "stylelint-scss": "^3.5.4", 88 | "stylelint-webpack-plugin": "^0.10.5", 89 | "ts-jest": "^24.0.2", 90 | "vee-validate": "^2.2.5", 91 | "vue-jest": "^3.0.3" 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /scripts/imagemin.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | // imagemin にオプションを渡して画像を最適化するためのスクリプト 4 | // 5 | // 使い方: node scripts/imagemin.js で実行できる 6 | // スクリプト作成の経緯: https://github.com/kazupon/vuefes-2019/pull/171#issuecomment-530369690 7 | 8 | const imagemin = require('imagemin') 9 | const imageminMozjpeg = require('imagemin-mozjpeg') 10 | const imageminPngquant = require('imagemin-pngquant') 11 | 12 | ;(async () => { 13 | await imagemin( 14 | [ 15 | 'test/fixtures/assets/images/event/*.{jpg,png}' // 最適化したい画像 16 | ], 17 | { 18 | // 最適化した画像の出力先 19 | // NOTE: 例えば品質に応じてディレクトリ名を変えるなどしてください 20 | destination: 'tmp/dist/imagemin/event/80', 21 | 22 | plugins: [ 23 | imageminMozjpeg({ 24 | // 0 〜 100 の数字を入れる 25 | // 数字が大きいほど品質が高い 26 | // ソースを読んでもデフォルト値が分からなかった :sweat_smile: 27 | quality: 80 // NOTE: JPEG 画像の品質調整はココで行います 28 | }), 29 | imageminPngquant({ 30 | // [min, max] で いずれも 0 〜 1 の数字を入れる 31 | // 数字が大きいほど品質が高い 32 | // ソースを読んでもデフォルト値が分からなかった :sweat_smile: 33 | // 34 | // https://github.com/imagemin/imagemin-pngquant に下記のように書かれているが、理解できていない :sweat_smile: 35 | // Instructs pngquant to use the least amount of colors required to meet or exceed the max quality. If conversion results in quality below the min quality the image won't be saved. 36 | quality: [0.3, 0.5] // NOTE: PNG 画像の品質調整はココで行います 37 | }) 38 | ] 39 | } 40 | ) 41 | 42 | console.log('Images optimized') 43 | })() 44 | -------------------------------------------------------------------------------- /src/assets/README.md: -------------------------------------------------------------------------------- 1 | # ASSETS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your un-compiled assets such as LESS, SASS, or JavaScript. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked). 8 | -------------------------------------------------------------------------------- /src/assets/images/access.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/access.jpg -------------------------------------------------------------------------------- /src/assets/images/access@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/access@2x.jpg -------------------------------------------------------------------------------- /src/assets/images/event/badges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/badges.png -------------------------------------------------------------------------------- /src/assets/images/event/badges@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/badges@2x.png -------------------------------------------------------------------------------- /src/assets/images/event/case.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/case.jpg -------------------------------------------------------------------------------- /src/assets/images/event/case@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/case@2x.jpg -------------------------------------------------------------------------------- /src/assets/images/event/cleaner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/cleaner.png -------------------------------------------------------------------------------- /src/assets/images/event/cleaner@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/cleaner@2x.png -------------------------------------------------------------------------------- /src/assets/images/event/cushion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/cushion.png -------------------------------------------------------------------------------- /src/assets/images/event/cushion@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/cushion@2x.png -------------------------------------------------------------------------------- /src/assets/images/event/information-table.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/information-table.jpg -------------------------------------------------------------------------------- /src/assets/images/event/information-table@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/information-table@2x.jpg -------------------------------------------------------------------------------- /src/assets/images/event/mobile-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/mobile-app.png -------------------------------------------------------------------------------- /src/assets/images/event/mobile-app@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/mobile-app@2x.png -------------------------------------------------------------------------------- /src/assets/images/event/mug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/mug.png -------------------------------------------------------------------------------- /src/assets/images/event/mug@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/mug@2x.png -------------------------------------------------------------------------------- /src/assets/images/event/parka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/parka.png -------------------------------------------------------------------------------- /src/assets/images/event/parka@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/parka@2x.png -------------------------------------------------------------------------------- /src/assets/images/event/party.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/party.jpg -------------------------------------------------------------------------------- /src/assets/images/event/party@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/party@2x.jpg -------------------------------------------------------------------------------- /src/assets/images/event/presents.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/presents.jpg -------------------------------------------------------------------------------- /src/assets/images/event/refreshment.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/refreshment.jpg -------------------------------------------------------------------------------- /src/assets/images/event/sponsor-booths.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/sponsor-booths.jpg -------------------------------------------------------------------------------- /src/assets/images/event/stickers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/stickers.png -------------------------------------------------------------------------------- /src/assets/images/event/stickers@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/stickers@2x.png -------------------------------------------------------------------------------- /src/assets/images/event/t-shirt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/t-shirt.png -------------------------------------------------------------------------------- /src/assets/images/event/t-shirt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/t-shirt@2x.png -------------------------------------------------------------------------------- /src/assets/images/event/tattoo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/tattoo.jpg -------------------------------------------------------------------------------- /src/assets/images/event/tumbler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/tumbler.png -------------------------------------------------------------------------------- /src/assets/images/event/tumbler@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/event/tumbler@2x.png -------------------------------------------------------------------------------- /src/assets/images/header/image01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/header/image01.png -------------------------------------------------------------------------------- /src/assets/images/header/image02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/header/image02.png -------------------------------------------------------------------------------- /src/assets/images/header/image03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/header/image03.png -------------------------------------------------------------------------------- /src/assets/images/header/image04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/header/image04.png -------------------------------------------------------------------------------- /src/assets/images/header/image05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/header/image05.png -------------------------------------------------------------------------------- /src/assets/images/header/image06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/header/image06.png -------------------------------------------------------------------------------- /src/assets/images/icon-exclamation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/icon-facebook.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/icon-github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/icon-hatena-bookmark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/icon-note.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/icon-translation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/icon-twitter-inside-btn.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/icon-twitter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/logo-twitter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/speakers/yyx990803.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/speakers/yyx990803.jpg -------------------------------------------------------------------------------- /src/assets/images/speakers/yyx990803@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/speakers/yyx990803@2x.jpg -------------------------------------------------------------------------------- /src/assets/images/sponsors/image1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/sponsors/image1.jpg -------------------------------------------------------------------------------- /src/assets/images/sponsors/image1@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/sponsors/image1@2x.jpg -------------------------------------------------------------------------------- /src/assets/images/sponsors/image2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/sponsors/image2.jpg -------------------------------------------------------------------------------- /src/assets/images/sponsors/image2@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/sponsors/image2@2x.jpg -------------------------------------------------------------------------------- /src/assets/images/sponsors/image3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/sponsors/image3.jpg -------------------------------------------------------------------------------- /src/assets/images/sponsors/image3@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/sponsors/image3@2x.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/448jp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/448jp.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/448jp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/448jp.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/KiaKing85.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/KiaKing85.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/__syumai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/__syumai.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/andoshin11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/andoshin11.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/aytdm251.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/aytdm251.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/c5meru.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/c5meru.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/hashedrock.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/hashedrock.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/hisako135.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/hisako135.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/inouetakuya.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/inouetakuya.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/kawakami0717.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/kawakami0717.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/kazu_pon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/kazu_pon.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/kazuyukimiyake.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/kazuyukimiyake.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/lenomick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/lenomick.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/massie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/massie.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/mtmtkzm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/mtmtkzm.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/nahokomatsui.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/nahokomatsui.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/naokie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/naokie.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/nicedchy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/nicedchy.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/positiveflat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/positiveflat.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/robjamdev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/robjamdev.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/ryamakuchi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/ryamakuchi.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/shika358.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/shika358.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/show60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/show60.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/takumisatojpn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/takumisatojpn.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/treby006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/treby006.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/tsuchikazu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/tsuchikazu.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/umiremix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/umiremix.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/yakiniku040220.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/yakiniku040220.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/yinm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/yinm.png -------------------------------------------------------------------------------- /src/assets/images/staffs/@2x/yotaszk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/@2x/yotaszk.png -------------------------------------------------------------------------------- /src/assets/images/staffs/KiaKing85.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/KiaKing85.png -------------------------------------------------------------------------------- /src/assets/images/staffs/__syumai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/__syumai.png -------------------------------------------------------------------------------- /src/assets/images/staffs/andoshin11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/andoshin11.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/aytdm251.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/aytdm251.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/c5meru.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/c5meru.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/hashedrock.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/hashedrock.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/hisako135.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/hisako135.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/inouetakuya.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/inouetakuya.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/kawakami0717.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/kawakami0717.png -------------------------------------------------------------------------------- /src/assets/images/staffs/kazu_pon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/kazu_pon.png -------------------------------------------------------------------------------- /src/assets/images/staffs/kazuyukimiyake.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/kazuyukimiyake.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/lenomick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/lenomick.png -------------------------------------------------------------------------------- /src/assets/images/staffs/massie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/massie.png -------------------------------------------------------------------------------- /src/assets/images/staffs/mtmtkzm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/mtmtkzm.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/nahokomatsui.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/nahokomatsui.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/naokie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/naokie.png -------------------------------------------------------------------------------- /src/assets/images/staffs/nicedchy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/nicedchy.png -------------------------------------------------------------------------------- /src/assets/images/staffs/positiveflat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/positiveflat.png -------------------------------------------------------------------------------- /src/assets/images/staffs/robjamdev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/robjamdev.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/ryamakuchi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/ryamakuchi.png -------------------------------------------------------------------------------- /src/assets/images/staffs/shika358.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/shika358.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/show60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/show60.png -------------------------------------------------------------------------------- /src/assets/images/staffs/takumisatojpn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/takumisatojpn.png -------------------------------------------------------------------------------- /src/assets/images/staffs/treby006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/treby006.png -------------------------------------------------------------------------------- /src/assets/images/staffs/tsuchikazu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/tsuchikazu.png -------------------------------------------------------------------------------- /src/assets/images/staffs/umiremix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/umiremix.png -------------------------------------------------------------------------------- /src/assets/images/staffs/yakiniku040220.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/yakiniku040220.jpg -------------------------------------------------------------------------------- /src/assets/images/staffs/yinm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/yinm.png -------------------------------------------------------------------------------- /src/assets/images/staffs/yotaszk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/staffs/yotaszk.png -------------------------------------------------------------------------------- /src/assets/images/store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/store.png -------------------------------------------------------------------------------- /src/assets/images/store@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/store@2x.png -------------------------------------------------------------------------------- /src/assets/images/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/texture.png -------------------------------------------------------------------------------- /src/assets/images/ticket/image1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/ticket/image1.jpg -------------------------------------------------------------------------------- /src/assets/images/ticket/image1@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/ticket/image1@2x.jpg -------------------------------------------------------------------------------- /src/assets/images/ticket/image2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/ticket/image2.jpg -------------------------------------------------------------------------------- /src/assets/images/ticket/image2@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/ticket/image2@2x.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-1.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-10.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-11.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-12.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-13.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-14.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-15.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-16.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-17.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-19.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-2.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-20.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-21.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-22.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-23.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-24.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-25.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-26.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-27.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-28.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-3.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-30.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-31.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-32.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-33.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-34.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-34.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-35.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-36.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-36.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-37.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-38.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-38.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-4.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-40.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-40.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-41.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-41.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-42.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-42.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-43.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-43.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-44.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-44.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-45.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-45.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-46.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-46.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-47.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-47.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-48.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-48.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-5.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-50.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-50.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-51.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-51.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-52.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-52.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-53.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-53.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-54.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-54.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-55.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-55.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-56.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-56.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-57.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-57.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-58.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-58.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-59.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-59.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-6.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-60.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-60.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-61.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-61.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-62.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-62.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-63.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-63.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-64.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-65.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-65.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-66.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-66.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-7.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/@2x/volunteer-9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/@2x/volunteer-9.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-1.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-10.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-11.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-12.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-13.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-14.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-15.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-16.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-17.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-19.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-2.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-21.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-22.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-23.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-24.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-25.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-26.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-27.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-28.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-3.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-31.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-32.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-33.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-34.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-34.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-35.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-36.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-36.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-37.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-38.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-38.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-4.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-40.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-40.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-41.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-41.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-42.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-42.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-43.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-43.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-44.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-44.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-45.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-45.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-46.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-46.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-47.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-47.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-48.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-48.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-5.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-50.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-50.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-51.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-51.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-52.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-52.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-53.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-53.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-54.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-54.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-55.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-55.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-56.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-56.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-57.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-57.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-58.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-58.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-59.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-59.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-6.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-60.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-60.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-61.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-61.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-62.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-62.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-63.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-63.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-64.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-65.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-65.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-66.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-66.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-7.jpg -------------------------------------------------------------------------------- /src/assets/images/volunteers/volunteer-9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/assets/images/volunteers/volunteer-9.jpg -------------------------------------------------------------------------------- /src/assets/stylesheets/foundation/colors.scss: -------------------------------------------------------------------------------- 1 | $vue-dark-blue: #34495e; 2 | $vue-green: #42b983; 3 | 4 | $white: #fff; 5 | $gray: #bababa; 6 | $black: #000; 7 | 8 | $hiwamoegi: #90b44b; 9 | $tohoh: #ffc408; 10 | $sangosyu: #f17c67; 11 | $asagi: #33a6b8; 12 | 13 | // Primary color 14 | 15 | $primary-color: $vue-dark-blue; 16 | 17 | // Text color 18 | 19 | $primary-text-color: $vue-dark-blue; 20 | $primary-text-color--invert: $white; 21 | $haze-text-color: $gray; 22 | -------------------------------------------------------------------------------- /src/assets/stylesheets/foundation/reset.scss: -------------------------------------------------------------------------------- 1 | // normalize.css によってブラウザごとの差異を整えた後に、さらにリセットしたいブラウザのデフォルトのスタイル 2 | 3 | html, 4 | body { 5 | background-color: transparent; 6 | } 7 | 8 | body { 9 | padding: 0; 10 | } 11 | 12 | *, 13 | *::before, 14 | *::after { 15 | box-sizing: border-box; 16 | } 17 | 18 | *::before, 19 | *::after { 20 | margin: 0; 21 | } 22 | 23 | ol, 24 | ul { 25 | padding: 0; 26 | list-style: none; 27 | } 28 | 29 | h1, 30 | h2, 31 | h3, 32 | h4, 33 | h5, 34 | h6, 35 | p { 36 | margin: 0; 37 | font-weight: normal; 38 | } 39 | 40 | input::-ms-clear, 41 | input::-ms-reveal, 42 | select::-ms-expand { 43 | display: none; 44 | } 45 | 46 | button { 47 | padding: 0; 48 | border: none; 49 | 50 | &::-moz-focus-inner { 51 | border: 0; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/assets/stylesheets/foundation/typography.scss: -------------------------------------------------------------------------------- 1 | $font-size-default: 4vw; 2 | $font-size-default--is-small-up: 18px; 3 | 4 | html { 5 | // stylelint-disable 6 | // Unexpected missing generic font family / font-family-no-missing-generic-family-keyword 7 | font-family: 'din-2014', 游ゴシック Medium, sans-serif; 8 | // stylelint-enable 9 | font-size: 16px; 10 | line-height: 1.5; 11 | -ms-text-size-adjust: 100%; 12 | -webkit-text-size-adjust: 100%; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | color: $primary-text-color; 16 | } 17 | 18 | h1, 19 | h2, 20 | h3, 21 | h4, 22 | h5, 23 | h6, 24 | p { 25 | font-size: $font-size-default; 26 | line-height: 1.8; 27 | 28 | @media screen and (min-width: $layout-breakpoint--is-small-up) { 29 | font-size: $font-size-default--is-small-up; 30 | } 31 | } 32 | 33 | p + p { 34 | margin-top: 2em; 35 | } 36 | -------------------------------------------------------------------------------- /src/assets/stylesheets/foundation/variables.scss: -------------------------------------------------------------------------------- 1 | $layout-breakpoint--is-small: 768px !default; 2 | $layout-breakpoint--is-small-up: 769px !default; 3 | $layout-breakpoint--is-medium: 980px !default; 4 | $layout-breakpoint--is-medium-up: 981px !default; 5 | 6 | $layout-column-length--is-small: 4; 7 | $layout-gutter-width--is-small: 20px; 8 | $layout-column-width--is-small: calc( 9 | (100% - #{$layout-gutter-width--is-small} * (#{$layout-column-length--is-small} - 1)) / #{$layout-column-length--is-small} 10 | ); 11 | 12 | $layout-column-length--is-small-up: 20; 13 | $layout-gutter-width--is-small-up: 20px; 14 | $layout-column-width--is-small-up: calc( 15 | (100% - #{$layout-gutter-width--is-small-up} * (#{$layout-column-length--is-small-up} - 1)) / #{$layout-column-length--is-small-up} 16 | ); 17 | 18 | $section-container-horizontal-padding--is-small-up: 70px; 19 | $content-min-width--is-small-up: calc(#{$layout-breakpoint--is-small-up} - #{$section-container-horizontal-padding--is-small-up} * 2); 20 | 21 | $page-container-max-width: 1180px; 22 | 23 | // md サイズ以上のときのヘッダーの高さ 24 | // FIXME: アンカーがあるページ(sponsors など)で使っているため、ヘッダーの高さを変える場合はこの変数を調整する 25 | $header-logo-height: 100px; 26 | 27 | // transition のイージング 28 | $easeInOutCubic: cubic-bezier(0.215, 0.61, 0.355, 1); 29 | 30 | $easeOutExpo: cubic-bezier(0.19, 1, 0.22, 1); 31 | -------------------------------------------------------------------------------- /src/assets/stylesheets/main.scss: -------------------------------------------------------------------------------- 1 | @import "normalize.css/normalize.css"; 2 | @import "./foundation/variables"; 3 | @import "./foundation/colors"; 4 | @import "./foundation/reset"; 5 | @import "./foundation/typography"; 6 | @import "./media_queries"; 7 | @import "./utilities"; 8 | -------------------------------------------------------------------------------- /src/assets/stylesheets/media_queries.scss: -------------------------------------------------------------------------------- 1 | // メディアクエリによって要素を表示させるか否かを制御できるクラス。クラス名は下記を参考にした 2 | // * [Sass - Materialize](http://materializecss.com/sass.html) 3 | 4 | .hide-on-small { 5 | @media screen and (max-width: $layout-breakpoint--is-small) { 6 | display: none !important; 7 | } 8 | } 9 | 10 | .hide-on-medium { 11 | @media screen and (min-width: $layout-breakpoint--is-small-up) and (max-width: $layout-breakpoint--is-medium) { 12 | display: none !important; 13 | } 14 | } 15 | 16 | .hide-on-large { 17 | @media screen and (min-width: $layout-breakpoint--is-medium-up) { 18 | display: none !important; 19 | } 20 | } 21 | 22 | .hide-on-medium-and-up { 23 | @media screen and (min-width: $layout-breakpoint--is-small-up) { 24 | display: none !important; 25 | } 26 | } 27 | 28 | .hide-on-medium-and-down { 29 | @media screen and (max-width: $layout-breakpoint--is-medium) { 30 | display: none !important; 31 | } 32 | } 33 | 34 | .show-on-small { 35 | @extend .hide-on-medium-and-up; 36 | } 37 | 38 | .show-on-medium { 39 | @extend .hide-on-small; 40 | @extend .hide-on-large; 41 | } 42 | 43 | .show-on-large { 44 | @extend .hide-on-medium-and-down; 45 | } 46 | 47 | .show-on-medium-and-up { 48 | @extend .hide-on-small; 49 | } 50 | 51 | .show-on-medium-and-down { 52 | @extend .hide-on-large; 53 | } 54 | -------------------------------------------------------------------------------- /src/assets/stylesheets/utilities.scss: -------------------------------------------------------------------------------- 1 | .link { 2 | font-size: inherit; 3 | color: $primary-text-color; 4 | transition: 0.2s $easeInOutCubic; 5 | 6 | &:hover { 7 | opacity: 0.4; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/components/BaseButton.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 74 | -------------------------------------------------------------------------------- /src/components/BaseMain.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 19 | 20 | 54 | -------------------------------------------------------------------------------- /src/components/BaseMainDescription.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 17 | 18 | 41 | -------------------------------------------------------------------------------- /src/components/BaseSection.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 27 | 28 | 91 | -------------------------------------------------------------------------------- /src/components/HeadCircle.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 48 | 49 | 54 | -------------------------------------------------------------------------------- /src/components/HeadCross.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 92 | 93 | 98 | -------------------------------------------------------------------------------- /src/components/HeadHorizontal.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 60 | 61 | 66 | -------------------------------------------------------------------------------- /src/components/HeadSlash.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 59 | 60 | 65 | -------------------------------------------------------------------------------- /src/components/HeadSquare.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 48 | 49 | 54 | -------------------------------------------------------------------------------- /src/components/HeadTriangle.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 44 | 45 | 50 | -------------------------------------------------------------------------------- /src/components/LinkToTwitter.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 26 | 27 | 46 | -------------------------------------------------------------------------------- /src/components/README.md: -------------------------------------------------------------------------------- 1 | # COMPONENTS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | The components directory contains your Vue.js Components. 6 | 7 | _Nuxt.js doesn't supercharge these components._ 8 | -------------------------------------------------------------------------------- /src/components/TheTimeTableSection/Event.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 22 | 23 | 41 | -------------------------------------------------------------------------------- /src/components/TheTimeTableSection/EventContent.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 39 | -------------------------------------------------------------------------------- /src/components/TheTimeTableSection/Keynote.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 35 | 36 | 85 | -------------------------------------------------------------------------------- /src/components/TheTimeTableSection/Room.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 23 | 24 | 67 | -------------------------------------------------------------------------------- /src/components/TheTimeTableSection/Session.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 36 | 37 | 60 | -------------------------------------------------------------------------------- /src/hooks/index.js: -------------------------------------------------------------------------------- 1 | import render from './render' 2 | 3 | export default nuxtConfig => ({ 4 | render: render(nuxtConfig) 5 | }) 6 | -------------------------------------------------------------------------------- /src/hooks/render.js: -------------------------------------------------------------------------------- 1 | import redirectRootToPortal from './route-redirect-portal' 2 | 3 | export default nuxtConfig => { 4 | const router = Reflect.has(nuxtConfig, 'router') ? nuxtConfig.router : {} 5 | const base = Reflect.has(router, 'base') ? router.base : '/2019' 6 | 7 | return { 8 | /** 9 | * 'render:setupMiddleware' 10 | * {@link node_modules/nuxt/lib/core/renderer.js} 11 | */ 12 | setupMiddleware(app) { 13 | app.use('/', redirectRootToPortal(base)) 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/hooks/route-redirect-portal.js: -------------------------------------------------------------------------------- 1 | import parseurl from 'parseurl' 2 | 3 | export default desiredContextRoot => 4 | function projectHooksRouteRedirectPortal(req, res, next) { 5 | const desiredContextRootRegExp = new RegExp(`^${desiredContextRoot}`) 6 | const _parsedUrl = Reflect.has(req, '_parsedUrl') ? req._parsedUrl : null 7 | const url = _parsedUrl !== null ? _parsedUrl : parseurl(req) 8 | const startsWithDesired = desiredContextRootRegExp.test(url.pathname) 9 | const isNotProperContextRoot = desiredContextRoot !== url.pathname 10 | if (isNotProperContextRoot && startsWithDesired === false) { 11 | const pathname = url.pathname === null ? '' : url.pathname 12 | const search = url.search === null ? '' : url.search 13 | const Location = desiredContextRoot + pathname + search 14 | res.writeHead(302, { 15 | Location 16 | }) 17 | res.end() 18 | } 19 | next() 20 | } 21 | -------------------------------------------------------------------------------- /src/layouts/README.md: -------------------------------------------------------------------------------- 1 | # LAYOUTS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your Application Layouts. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts). 8 | -------------------------------------------------------------------------------- /src/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 22 | -------------------------------------------------------------------------------- /src/middleware/README.md: -------------------------------------------------------------------------------- 1 | # MIDDLEWARE 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your application middleware. 6 | Middleware let you define custom functions that can be run before rendering either a page or a group of pages. 7 | 8 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware). 9 | -------------------------------------------------------------------------------- /src/pages/README.md: -------------------------------------------------------------------------------- 1 | # PAGES 2 | 3 | This directory contains your Application Views and Routes. 4 | The framework reads all the `*.vue` files inside this directory and creates the router of your application. 5 | 6 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing). 7 | -------------------------------------------------------------------------------- /src/pages/contact.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 47 | -------------------------------------------------------------------------------- /src/pages/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 39 | -------------------------------------------------------------------------------- /src/plugins/README.md: -------------------------------------------------------------------------------- 1 | # PLUGINS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains Javascript plugins that you want to run before mounting the root Vue.js application. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins). 8 | -------------------------------------------------------------------------------- /src/plugins/contentful.ts: -------------------------------------------------------------------------------- 1 | import { ContentfulClientApi, Asset } from 'contentful/index' 2 | 3 | const contentful = require('contentful') 4 | 5 | const clientWithResolveLinks: ContentfulClientApi = contentful.createClient({ 6 | space: process.env.CTF_SPACE_ID, 7 | accessToken: process.env.CTF_CDA_ACCESS_TOKEN, 8 | resolveLinks: true 9 | }) 10 | 11 | const clientWithoutResolveLinks: ContentfulClientApi = contentful.createClient({ 12 | space: process.env.CTF_SPACE_ID, 13 | accessToken: process.env.CTF_CDA_ACCESS_TOKEN, 14 | resolveLinks: false 15 | }) 16 | 17 | export const getSpeakers = (): Promise => { 18 | return clientWithoutResolveLinks 19 | .getEntries({ 20 | content_type: 'speaker' 21 | }) 22 | .then(response => response.items) 23 | } 24 | 25 | export const getSessions = (): Promise => { 26 | return clientWithoutResolveLinks 27 | .getEntries({ 28 | content_type: 'session' 29 | }) 30 | .then(response => response.items) 31 | } 32 | 33 | // 実際には戻り値は Promise だが、型エラーが発生する 34 | // error: Type 'Promise[]>' is not assignable to type 'Promise => { 36 | return clientWithoutResolveLinks 37 | .getEntries({ 38 | content_type: 'timeTableSection', 39 | order: 'fields.startAt' 40 | }) 41 | .then(response => response.items) 42 | } 43 | 44 | export const getEventContainers = (): Promise => { 45 | return clientWithResolveLinks 46 | .getEntries({ 47 | content_type: 'eventContainer' 48 | }) 49 | .then(response => response.items) 50 | } 51 | 52 | export const getEventContainerParts = (): Promise => { 53 | return clientWithResolveLinks 54 | .getEntries({ 55 | content_type: 'eventContainerPart' 56 | }) 57 | .then(response => response.items) 58 | } 59 | 60 | export const getRooms = (): Promise => { 61 | return clientWithoutResolveLinks 62 | .getEntries({ 63 | content_type: 'room' 64 | }) 65 | .then(response => response.items) 66 | } 67 | 68 | export const getEvents = (): Promise => { 69 | return clientWithoutResolveLinks 70 | .getEntries({ 71 | content_type: 'event' 72 | }) 73 | .then(response => response.items) 74 | } 75 | 76 | export const getSponsors = (): Promise => { 77 | return clientWithResolveLinks 78 | .getEntries({ 79 | content_type: 'sponsor', 80 | order: 'fields.appliedAt' 81 | }) 82 | .then(response => response.items) 83 | } 84 | 85 | export const getAsset = (id: string): Promise => { 86 | return clientWithoutResolveLinks.getAsset(id) 87 | } 88 | -------------------------------------------------------------------------------- /src/plugins/marked.ts: -------------------------------------------------------------------------------- 1 | const marked = require('marked') 2 | 3 | // https://marked.js.org/#/USING_ADVANCED.md#options 4 | marked.setOptions({ 5 | renderer: new marked.Renderer(), 6 | highlight: null, 7 | pedantic: false, 8 | gfm: true, 9 | breaks: false, 10 | 11 | // Warning: This feature is deprecated and it should NOT be used as it cannot be considered secure. 12 | // Instead use a sanitize library, like DOMPurify (recommended), sanitize-html or insane on the output HTML! 13 | sanitize: false, 14 | 15 | smartLists: true, 16 | smartypants: false, 17 | xhtml: false 18 | }) 19 | 20 | export default marked 21 | -------------------------------------------------------------------------------- /src/plugins/scroll-anchor-links.ts: -------------------------------------------------------------------------------- 1 | export default async ({ app }) => { 2 | await app.router.afterEach(to => { 3 | if (to.hash) { 4 | const element = document.querySelector(to.hash) // 飛び先を取得 5 | 6 | if (element) { 7 | // 現在の位置から飛ぶ要素の位置までの距離を取得 8 | const rectTop = element.getBoundingClientRect().top 9 | // ページ上部から現在のスクロールの位置までの距離を取得 10 | const offsetTop = window.pageYOffset 11 | // スクロールする位置(ページ上部からの絶対値 + ヘッダーの高さ) 12 | const top = rectTop + offsetTop 13 | window.scroll({ 14 | top, 15 | behavior: 'smooth' 16 | }) 17 | } 18 | } 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /src/plugins/typekit.ts: -------------------------------------------------------------------------------- 1 | interface Window { 2 | Typekit: any 3 | } 4 | 5 | ;(function(d) { 6 | const config = { 7 | kitId: 'ecl1lua', 8 | scriptTimeout: 3000, 9 | async: true 10 | } 11 | 12 | const h: any = d.documentElement 13 | 14 | const t = setTimeout(function() { 15 | h.className = h.className.replace(/\bwf-loading\b/g, '') + ' wf-inactive' 16 | }, config.scriptTimeout) 17 | 18 | const tk: any = d.createElement('script') 19 | let f = false 20 | const s: any = d.getElementsByTagName('script')[0] 21 | let a 22 | 23 | h.className += ' wf-loading' 24 | tk.src = 'https://use.typekit.net/' + config.kitId + '.js' 25 | tk.async = true 26 | 27 | tk.onload = tk.onreadystatechange = function() { 28 | a = this.readyState 29 | 30 | if (f || (a && a !== 'complete' && a !== 'loaded')) { 31 | return 32 | } 33 | 34 | f = true 35 | clearTimeout(t) 36 | 37 | try { 38 | window.Typekit.load(config) 39 | } catch (e) {} 40 | } 41 | 42 | s.parentNode.insertBefore(tk, s) 43 | })(document) 44 | -------------------------------------------------------------------------------- /src/plugins/validateDictionary.ts: -------------------------------------------------------------------------------- 1 | const dictionary = { 2 | custom: { 3 | email: { 4 | required: 'メールアドレスを正しく入力してください', 5 | email: 'メールアドレスを正しく入力してください' 6 | }, 7 | name: { 8 | required: '名前を正しく入力してください' 9 | }, 10 | message: { 11 | required: '内容を正しく入力してください', 12 | max: '内容は 3,000 文字以内で入力してください' 13 | } 14 | } 15 | } 16 | 17 | export default dictionary 18 | -------------------------------------------------------------------------------- /src/plugins/vee-validate.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VeeValidate, { Validator } from 'vee-validate' 3 | import dictionary from './validateDictionary' 4 | 5 | Vue.use(VeeValidate, { inject: false }) 6 | Validator.localize('ja', dictionary) 7 | -------------------------------------------------------------------------------- /src/plugins/vue-lazyload.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueLazyload from 'vue-lazyload' 3 | 4 | Vue.use(VueLazyload, { 5 | throttleWait: 100, 6 | observer: true, 7 | observerOptions: { 8 | rootMargin: '2160px', 9 | threshold: 0 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /src/static/README.md: -------------------------------------------------------------------------------- 1 | # STATIC 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your static files. 6 | Each file inside this directory is mapped to `/`. 7 | Thus you'd want to delete this README.md before deploying to production. 8 | 9 | Example: `/static/robots.txt` is mapped as `/robots.txt`. 10 | 11 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static). 12 | -------------------------------------------------------------------------------- /src/static/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/apple-touch-icon.png -------------------------------------------------------------------------------- /src/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/favicon.ico -------------------------------------------------------------------------------- /src/static/opengraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/opengraph.png -------------------------------------------------------------------------------- /src/static/session-og-images/Atinux.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/Atinux.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/alexchopin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/alexchopin.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/blackawa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/blackawa.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/chrisvfritz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/chrisvfritz.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/default.png -------------------------------------------------------------------------------- /src/static/session-og-images/jlooper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/jlooper.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/keimakai.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/keimakai.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/keinuma.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/keinuma.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/konu96.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/konu96.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/masaakikunsan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/masaakikunsan.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/ninjinkun.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/ninjinkun.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/octref.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/octref.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/retty-y-takase.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/retty-y-takase.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/takefumi-yoshii.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/takefumi-yoshii.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/tejitak.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/tejitak.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/ulivz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/ulivz.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/yamanoku.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/yamanoku.jpg -------------------------------------------------------------------------------- /src/static/session-og-images/yyx990803.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/src/static/session-og-images/yyx990803.jpg -------------------------------------------------------------------------------- /src/store/README.md: -------------------------------------------------------------------------------- 1 | # STORE 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your Vuex Store files. 6 | Vuex Store option is implemented in the Nuxt.js framework. 7 | 8 | Creating a file in this directory automatically activates the option in the framework. 9 | 10 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store). 11 | -------------------------------------------------------------------------------- /src/store/eventContainerParts.ts: -------------------------------------------------------------------------------- 1 | import { Getters, Mutations, Actions } from '~/types/store' 2 | import EventContainerPart from '~/types/eventContainerPart' 3 | import { getEventContainerParts } from '~/plugins/contentful' 4 | 5 | namespace EventContainerParts { 6 | export type State = { 7 | eventContainerParts: EventContainerPart[] 8 | } 9 | 10 | export type Getters = { 11 | find: (id: string) => EventContainerPart | undefined 12 | } 13 | 14 | export type Mutations = { 15 | setEventContainerParts: EventContainerPart[] 16 | } 17 | 18 | export type Actions = { 19 | fetchEventContainerParts: void 20 | } 21 | } 22 | 23 | export const state = (): EventContainerParts.State => ({ 24 | eventContainerParts: [] 25 | }) 26 | 27 | export const getters: Getters< 28 | EventContainerParts.State, 29 | EventContainerParts.Getters 30 | > = { 31 | find: state => id => { 32 | return state.eventContainerParts.find( 33 | eventContainerPart => eventContainerPart.sys.id === id 34 | ) 35 | } 36 | } 37 | 38 | export const mutations: Mutations< 39 | EventContainerParts.State, 40 | EventContainerParts.Mutations 41 | > = { 42 | setEventContainerParts(state, payload) { 43 | state.eventContainerParts = payload 44 | } 45 | } 46 | 47 | export const actions: Actions< 48 | EventContainerParts.State, 49 | EventContainerParts.Actions, 50 | EventContainerParts.Getters, 51 | EventContainerParts.Mutations 52 | > = { 53 | async fetchEventContainerParts({ commit }) { 54 | const eventContainerParts: EventContainerPart[] = await getEventContainerParts() 55 | commit('setEventContainerParts', eventContainerParts) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/store/eventContainers.ts: -------------------------------------------------------------------------------- 1 | import { Getters, Mutations, Actions } from '~/types/store' 2 | import EventContainer from '~/types/eventContainer' 3 | import { getEventContainers } from '~/plugins/contentful' 4 | 5 | namespace EventContainers { 6 | export type State = { 7 | eventContainers: EventContainer[] 8 | } 9 | 10 | export type Getters = { 11 | find: (id: string) => EventContainer | undefined 12 | } 13 | 14 | export type Mutations = { 15 | setEventContainers: EventContainer[] 16 | } 17 | 18 | export type Actions = { 19 | fetchEventContainers: void 20 | } 21 | } 22 | 23 | export const state = (): EventContainers.State => ({ 24 | eventContainers: [] 25 | }) 26 | 27 | export const getters: Getters< 28 | EventContainers.State, 29 | EventContainers.Getters 30 | > = { 31 | find: state => id => { 32 | return state.eventContainers.find( 33 | eventContainer => eventContainer.sys.id === id 34 | ) 35 | } 36 | } 37 | 38 | export const mutations: Mutations< 39 | EventContainers.State, 40 | EventContainers.Mutations 41 | > = { 42 | setEventContainers(state, payload) { 43 | state.eventContainers = payload 44 | } 45 | } 46 | 47 | export const actions: Actions< 48 | EventContainers.State, 49 | EventContainers.Actions, 50 | EventContainers.Getters, 51 | EventContainers.Mutations 52 | > = { 53 | async fetchEventContainers({ commit }) { 54 | const eventContainers: EventContainer[] = await getEventContainers() 55 | commit('setEventContainers', eventContainers) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/store/index.ts: -------------------------------------------------------------------------------- 1 | export const actions = { 2 | async nuxtServerInit({ dispatch }) { 3 | await Promise.all([ 4 | dispatch('speakers/initialize'), 5 | dispatch('sessions/initialize'), 6 | dispatch('timeTableSections/fetchTimeTableSections'), 7 | dispatch('eventContainers/fetchEventContainers'), 8 | dispatch('eventContainerParts/fetchEventContainerParts'), 9 | dispatch('sponsors/fetchSponsors') 10 | ]).catch(error => console.error(error)) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/store/sessions.ts: -------------------------------------------------------------------------------- 1 | import cloneDeep from 'lodash.clonedeep' 2 | import { Getters, Mutations, Actions } from '~/types/store' 3 | import Session from '~/types/session' 4 | import { getAsset, getSessions } from '~/plugins/contentful' 5 | 6 | namespace Sessions { 7 | export type State = { 8 | sessions: Session[] 9 | } 10 | 11 | export type Getters = { 12 | all: Session[] 13 | find: (id: string) => Session | undefined 14 | } 15 | 16 | export type Mutations = { 17 | setSessions: Session[] 18 | updateSession: Session 19 | } 20 | 21 | export type Actions = { 22 | initialize: undefined 23 | fetchSessions: void 24 | fetchAsset: Session 25 | } 26 | } 27 | 28 | export const state = (): Sessions.State => ({ 29 | sessions: [] 30 | }) 31 | 32 | export const getters: Getters = { 33 | all: state => { 34 | return state.sessions 35 | }, 36 | find: state => id => { 37 | return state.sessions.find(session => session.sys.id === id) 38 | } 39 | } 40 | 41 | export const mutations: Mutations = { 42 | setSessions(state, payload) { 43 | state.sessions = payload 44 | }, 45 | 46 | updateSession(state, newSession) { 47 | state.sessions = state.sessions.map(session => 48 | session.sys.id === newSession.sys.id ? newSession : session 49 | ) 50 | } 51 | } 52 | 53 | export const actions: Actions< 54 | Sessions.State, 55 | Sessions.Actions, 56 | Sessions.Getters, 57 | Sessions.Mutations 58 | > = { 59 | async initialize({ getters, dispatch }) { 60 | await dispatch('fetchSessions') 61 | await Promise.all( 62 | getters.all.map(session => dispatch('fetchAsset', session)) 63 | ) 64 | }, 65 | 66 | async fetchSessions({ commit }) { 67 | const sessions: Session[] = await getSessions() 68 | commit('setSessions', sessions) 69 | }, 70 | 71 | async fetchAsset({ commit }, session) { 72 | const newSession = cloneDeep(session) 73 | 74 | // @ts-ignore error TS2532: Object is possibly 'undefined' 75 | newSession.fields.ogImage = await getAsset(session.fields.ogImage.sys.id) 76 | 77 | commit('updateSession', newSession) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/store/speakers.ts: -------------------------------------------------------------------------------- 1 | import cloneDeep from 'lodash.clonedeep' 2 | import { Getters, Mutations, Actions } from '~/types/store' 3 | import Speaker from '~/types/speaker' 4 | import { getAsset, getSpeakers } from '~/plugins/contentful' 5 | 6 | namespace Speakers { 7 | export type State = { 8 | speakers: Speaker[] 9 | } 10 | 11 | export type Getters = { 12 | all: Speaker[] 13 | find: (id: string) => Speaker | undefined 14 | findByGithub: (github: string) => Speaker | undefined 15 | } 16 | 17 | export type Mutations = { 18 | setSpeakers: Speaker[] 19 | updateSpeaker: Speaker 20 | } 21 | 22 | export type Actions = { 23 | initialize: undefined 24 | fetchSpeakers: undefined 25 | fetchAsset: Speaker 26 | } 27 | } 28 | 29 | export const state = (): Speakers.State => ({ 30 | speakers: [] 31 | }) 32 | 33 | export const getters: Getters = { 34 | all: state => { 35 | return state.speakers 36 | }, 37 | find: state => id => { 38 | return state.speakers.find(speaker => speaker.sys.id === id) 39 | }, 40 | findByGithub: state => github => { 41 | return state.speakers.find(speaker => speaker.fields.github === github) 42 | } 43 | } 44 | 45 | export const mutations: Mutations = { 46 | setSpeakers(state, speakers) { 47 | state.speakers = speakers 48 | }, 49 | 50 | updateSpeaker(state, newSpeaker) { 51 | state.speakers = state.speakers.map(speaker => 52 | speaker.sys.id === newSpeaker.sys.id ? newSpeaker : speaker 53 | ) 54 | } 55 | } 56 | 57 | export const actions: Actions< 58 | Speakers.State, 59 | Speakers.Actions, 60 | Speakers.Getters, 61 | Speakers.Mutations 62 | > = { 63 | async initialize({ getters, dispatch }) { 64 | await dispatch('fetchSpeakers') 65 | await Promise.all( 66 | getters.all.map(speaker => dispatch('fetchAsset', speaker)) 67 | ) 68 | }, 69 | 70 | async fetchSpeakers({ commit }) { 71 | const speakers: Speaker[] = await getSpeakers() 72 | commit('setSpeakers', speakers) 73 | }, 74 | 75 | async fetchAsset({ commit }, speaker) { 76 | const newSpeaker = cloneDeep(speaker) 77 | 78 | const [newAvatar, newAvatar2x] = await Promise.all([ 79 | // @ts-ignore error TS2532: Object is possibly 'undefined' 80 | getAsset(speaker.fields.avatar.sys.id), 81 | 82 | // @ts-ignore error TS2532: Object is possibly 'undefined' 83 | getAsset(speaker.fields.avatar2x.sys.id) 84 | ]) 85 | 86 | newSpeaker.fields.avatar = newAvatar 87 | newSpeaker.fields.avatar2x = newAvatar2x 88 | 89 | commit('updateSpeaker', newSpeaker) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/store/sponsors.ts: -------------------------------------------------------------------------------- 1 | import { Getters, Mutations, Actions } from '~/types/store' 2 | import Sponsor from '~/types/sponsor' 3 | import SponsorPlan from '~/types/sponsorPlan' 4 | import { getSponsors } from '~/plugins/contentful' 5 | 6 | namespace Sponsors { 7 | export type State = { 8 | sponsors: Sponsor[] 9 | sponsorPlans: SponsorPlan[] 10 | } 11 | 12 | export type Getters = { 13 | sponsorsByPlan: (plan: string) => Sponsor[] 14 | sponsorPlansHavingSponsors: SponsorPlan[] 15 | } 16 | 17 | export type Mutations = { 18 | setSponsors: Sponsor[] 19 | } 20 | 21 | export type Actions = { 22 | fetchSponsors: void 23 | } 24 | } 25 | 26 | export const state = (): Sponsors.State => ({ 27 | sponsors: [], 28 | sponsorPlans: [ 29 | { plan: 'platinum', name: 'PLATINUM' }, 30 | { plan: 'gold', name: 'GOLD' }, 31 | { plan: 'silver', name: 'SILVER' }, 32 | { plan: 'bronze', name: 'BRONZE' }, 33 | { plan: 'special', name: 'SPECIAL' }, 34 | { plan: 'room', name: 'ROOM' }, 35 | { plan: 'translation', name: '同時通訳' }, 36 | { plan: 'commercial', name: '幕間 CM' }, 37 | { plan: 'toast', name: 'カンパイ' }, 38 | { plan: 'lunch', name: 'LUNCH' }, 39 | { plan: 'refreshment', name: 'REFRESHMENT' }, 40 | { plan: 'video', name: 'VIDEO' }, 41 | { plan: 'media', name: 'MEDIA' } 42 | ] 43 | }) 44 | 45 | export const getters: Getters = { 46 | sponsorsByPlan: state => plan => { 47 | return state.sponsors.filter(sponsor => sponsor.fields.plan === plan) 48 | }, 49 | sponsorPlansHavingSponsors: (state, getters) => { 50 | return state.sponsorPlans.filter( 51 | // @ts-ignore error TS2532: Object is possibly 'undefined' 52 | // FIXME: getters?: Stores.Getters と定義していて、getters は引数として使わない場合があるので、これで正しいのでは? 53 | sponsorPlan => getters.sponsorsByPlan(sponsorPlan.plan).length > 0 54 | ) 55 | } 56 | } 57 | 58 | export const mutations: Mutations = { 59 | setSponsors(state, payload) { 60 | state.sponsors = payload 61 | } 62 | } 63 | 64 | export const actions: Actions< 65 | Sponsors.State, 66 | Sponsors.Actions, 67 | Sponsors.Getters, 68 | Sponsors.Mutations 69 | > = { 70 | async fetchSponsors({ commit }) { 71 | const sponsors: Sponsor[] = await getSponsors() 72 | commit('setSponsors', sponsors) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/store/timeTableSections.ts: -------------------------------------------------------------------------------- 1 | import { Getters, Mutations, Actions } from '~/types/store' 2 | import TimeTableSection from '~/types/timeTableSection' 3 | import { getTimeTableSections } from '~/plugins/contentful' 4 | 5 | namespace TimeTableSections { 6 | export type State = { 7 | timeTableSections: TimeTableSection[] 8 | } 9 | 10 | export type Getters = { 11 | all: TimeTableSection[] 12 | } 13 | 14 | export type Mutations = { 15 | setTimeTableSections: TimeTableSection[] 16 | } 17 | 18 | export type Actions = { 19 | fetchTimeTableSections: void 20 | } 21 | } 22 | 23 | export const state = (): TimeTableSections.State => ({ 24 | timeTableSections: [] 25 | }) 26 | 27 | export const getters: Getters< 28 | TimeTableSections.State, 29 | TimeTableSections.Getters 30 | > = { 31 | all: state => { 32 | return state.timeTableSections 33 | } 34 | } 35 | 36 | export const mutations: Mutations< 37 | TimeTableSections.State, 38 | TimeTableSections.Mutations 39 | > = { 40 | setTimeTableSections(state, payload) { 41 | state.timeTableSections = payload 42 | } 43 | } 44 | 45 | export const actions: Actions< 46 | TimeTableSections.State, 47 | TimeTableSections.Actions, 48 | TimeTableSections.Getters, 49 | TimeTableSections.Mutations 50 | > = { 51 | async fetchTimeTableSections({ commit }) { 52 | const timeTableSections: TimeTableSection[] = await getTimeTableSections() 53 | commit('setTimeTableSections', timeTableSections) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/types/contentful.ts: -------------------------------------------------------------------------------- 1 | export interface EntrySys { 2 | space: Object 3 | id: string 4 | type: 'Entry' 5 | createdAt: string 6 | updatedAt: string 7 | environment: Object 8 | revision: number 9 | contentType: { 10 | sys: { 11 | type: 'Link' 12 | linkType: 'ContentType' 13 | id: string 14 | } 15 | } 16 | locale: 'en-US' 17 | } 18 | 19 | export interface EntryLink { 20 | sys: { 21 | type: 'Link' 22 | linkType: 'Entry' 23 | id: string 24 | } 25 | } 26 | 27 | export interface AssetSys { 28 | space: Object 29 | id: string 30 | type: 'Asset' 31 | createdAt: string 32 | updatedAt: string 33 | environment: Object 34 | revision: number 35 | locale: 'en-US' 36 | } 37 | 38 | export interface Asset { 39 | sys: AssetSys 40 | fields: { 41 | title: string 42 | file: { 43 | url: string 44 | details: { 45 | size: number 46 | image: { 47 | width: number 48 | height: number 49 | } 50 | } 51 | fileName: string 52 | contentType: string 53 | } 54 | } 55 | } 56 | 57 | export interface AssetLink { 58 | sys: { 59 | type: 'Link' 60 | linkType: 'Asset' 61 | id: string 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/types/event.ts: -------------------------------------------------------------------------------- 1 | import { EntrySys } from '~/types/contentful' 2 | 3 | export default interface Event { 4 | sys: EntrySys 5 | fields: { 6 | title: string 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/types/eventContainer.ts: -------------------------------------------------------------------------------- 1 | import { EntrySys } from '~/types/contentful' 2 | import EventContainerPart from '~/types/eventContainerPart' 3 | import Session from '~/types/session' 4 | import Event from '~/types/event' 5 | import Room from '~/types/room' 6 | 7 | export default interface EventContainer { 8 | sys: EntrySys 9 | fields: { 10 | titleForContentful: string // Contentful での操作時にどうしても識別するタイトルが必要であるため 11 | 12 | // sys.contentType.sys.id によって 13 | // Event なのか Session なのか EventContainerPart なのかを判定する 14 | contents: (EventContainerPart | Session | Event)[] 15 | 16 | // Room が null のときは部屋がないという意味ではなく、 17 | // どこか 1つのルームに限定しないという意味。 18 | // 2つ以上のルームを合体させた場合など。 19 | room?: Room 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/types/eventContainerPart.ts: -------------------------------------------------------------------------------- 1 | import { EntrySys, EntryLink } from '~/types/contentful' 2 | import Session from '~/types/session' 3 | 4 | export default interface EventContainerPart { 5 | sys: EntrySys 6 | fields: { 7 | titleForContentful: string // Contentful での操作時にどうしても識別するタイトルが必要であるため 8 | startAt: string // タイムゾーン情報を持つ。例: '2019-10-12T09:30:00+09:00' 9 | endAt: string // タイムゾーン情報を持つ。例: '2019-10-12T09:30:00+09:00' 10 | 11 | // sys.contentType.sys.id によって Event なのか Session なのかを判定する 12 | content: Session | Event | EntryLink 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/types/room.ts: -------------------------------------------------------------------------------- 1 | import { EntrySys } from '~/types/contentful' 2 | 3 | export default interface Room { 4 | sys: EntrySys 5 | fields: { 6 | name: string 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/types/session.ts: -------------------------------------------------------------------------------- 1 | import { EntrySys, Asset, EntryLink, AssetLink } from '~/types/contentful' 2 | 3 | export default interface Session { 4 | sys: EntrySys 5 | fields: { 6 | title: string 7 | time: number 8 | description: string // Markdown 9 | ogImage: Asset | AssetLink // Contentful から初回取得時には AssetLink で、その後 Asset に置き換えられる 10 | speakers: EntryLink[] // ひとつのセッションに複数のスピーカーが入るものがある(例: Nuxt 11 | hasTranslation: boolean // 同時通訳の有無 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/types/speaker.ts: -------------------------------------------------------------------------------- 1 | import { EntrySys, EntryLink, Asset, AssetLink } from '~/types/contentful' 2 | 3 | export default interface Speaker { 4 | sys: EntrySys 5 | fields: { 6 | name: string 7 | title: string // 肩書き 8 | avatar: Asset | AssetLink // Contentful から初回取得時には AssetLink で、その後 Asset に置き換えられる 9 | avatar2x: Asset | AssetLink // Contentful から初回取得時には AssetLink で、その後 Asset に置き換えられる 10 | twitter: string | null 11 | github: string 12 | description: string // Markdown 13 | 14 | // Vue Fes Japan 2019 では 1人のスピーカーが複数のセッションを持つことはないが、 15 | // 理論上はありうるので一般的にしておく 16 | sessions: EntryLink[] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/types/sponsor.ts: -------------------------------------------------------------------------------- 1 | import { EntrySys, Asset } from '~/types/contentful' 2 | 3 | export default interface Sponsor { 4 | sys: EntrySys 5 | fields: { 6 | plan: string 7 | name: string 8 | url: string 9 | banner: Asset 10 | pr: string 11 | appliedAt: string 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/types/sponsorPlan.ts: -------------------------------------------------------------------------------- 1 | export default interface SponsorPlan { 2 | plan: string 3 | name: string 4 | } 5 | -------------------------------------------------------------------------------- /src/types/store.ts: -------------------------------------------------------------------------------- 1 | export type Getters = { 2 | [K in keyof G]: ( 3 | state: S, 4 | getters?: G, 5 | rootState?: RS, 6 | rootGetters?: RG 7 | ) => G[K] 8 | } 9 | 10 | export type Mutations = { 11 | [K in keyof M]: (state: S, payload: M[K]) => void 12 | } 13 | 14 | type Commit = (type: T, payload?: M[T]) => void 15 | type Dispatch = (type: T, payload?: A[T]) => any 16 | 17 | type Context = { 18 | commit: Commit 19 | dispatch: Dispatch 20 | state: S 21 | getters: G 22 | rootState: RS 23 | rootGetters: RG 24 | } 25 | 26 | export type Actions = { 27 | [K in keyof A]: (context: Context, payload?: A[K]) => any 28 | } 29 | -------------------------------------------------------------------------------- /src/types/timeTableSection.ts: -------------------------------------------------------------------------------- 1 | import { EntrySys, EntryLink } from '~/types/contentful' 2 | 3 | export default interface TimeTableSection { 4 | sys: EntrySys 5 | fields: { 6 | titleForContentful: string // Contentful での操作時にどうしても識別するタイトルが必要であるため 7 | startAt: string // タイムゾーン情報を持つ。例: '2019-10-12T09:30:00+09:00' 8 | endAt: string // タイムゾーン情報を持つ。例: '2019-10-12T09:30:00+09:00' 9 | eventContainers: EntryLink[] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/types/vue-shims.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import Vue from 'vue' 3 | export default Vue 4 | } 5 | -------------------------------------------------------------------------------- /stylelint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: ['stylelint-scss'], 3 | extends: 'stylelint-config-standard', 4 | rules: { 5 | 'declaration-colon-newline-after': null, 6 | 'value-list-comma-newline-after': null, // Prettier と競合するため 7 | 'at-rule-no-unknown': null, 8 | 'scss/at-rule-no-unknown': true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/assets/images/event/presents.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/test/fixtures/assets/images/event/presents.jpg -------------------------------------------------------------------------------- /test/fixtures/assets/images/event/refreshment.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/test/fixtures/assets/images/event/refreshment.jpg -------------------------------------------------------------------------------- /test/fixtures/assets/images/event/sponsor-booths.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/test/fixtures/assets/images/event/sponsor-booths.jpg -------------------------------------------------------------------------------- /test/fixtures/assets/images/event/tattoo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs-jp/vuefes-2019/49f5c598a21e4d7e46ae06efd6abf38a3008dca1/test/fixtures/assets/images/event/tattoo.jpg -------------------------------------------------------------------------------- /test/fixtures/contentful/asset.ts: -------------------------------------------------------------------------------- 1 | import { Asset } from '~/types/contentful' 2 | 3 | const asset: Asset = { 4 | sys: { 5 | space: { 6 | sys: { 7 | type: 'Link', 8 | linkType: 'Space', 9 | id: 'makqrw5hfm9d' 10 | } 11 | }, 12 | id: '1Bqb7VVTxdnL3zZIh8FNJD', 13 | type: 'Asset', 14 | createdAt: '2019-08-27T09:08:50.871Z', 15 | updatedAt: '2019-08-27T09:08:50.871Z', 16 | environment: { 17 | sys: { 18 | id: 'master', 19 | type: 'Link', 20 | linkType: 'Environment' 21 | } 22 | }, 23 | revision: 1, 24 | locale: 'en-US' 25 | }, 26 | fields: { 27 | title: 'jlooper', 28 | file: { 29 | url: 30 | '//images.ctfassets.net/makqrw5hfm9d/1Bqb7VVTxdnL3zZIh8FNJD/ba31d2b26ab370284345ebaf82196f7e/jlooper.jpg', 31 | details: { 32 | size: 21973, 33 | image: { 34 | width: 500, 35 | height: 500 36 | } 37 | }, 38 | fileName: 'jlooper.jpg', 39 | contentType: 'image/jpeg' 40 | } 41 | } 42 | } 43 | 44 | export default asset 45 | -------------------------------------------------------------------------------- /test/fixtures/contentful/eventContainerWithEventsClosed.ts: -------------------------------------------------------------------------------- 1 | import EventContainer from '~/types/eventContainer' 2 | 3 | const eventContainerWithEventsClosed: EventContainer = { 4 | sys: { 5 | space: { 6 | sys: { 7 | type: 'Link', 8 | linkType: 'Space', 9 | id: 'makqrw5hfm9d' 10 | } 11 | }, 12 | id: '6xarOqNqmbfdY7zNlXnkkv', 13 | type: 'Entry', 14 | createdAt: '2019-09-19T09:49:32.875Z', 15 | updatedAt: '2019-09-19T09:49:32.875Z', 16 | environment: { 17 | sys: { 18 | id: 'master', 19 | type: 'Link', 20 | linkType: 'Environment' 21 | } 22 | }, 23 | revision: 1, 24 | contentType: { 25 | sys: { 26 | type: 'Link', 27 | linkType: 'ContentType', 28 | id: 'eventContainer' 29 | } 30 | }, 31 | locale: 'en-US' 32 | }, 33 | fields: { 34 | titleForContentful: '11-ye', 35 | contents: [ 36 | { 37 | sys: { 38 | space: { 39 | sys: { 40 | type: 'Link', 41 | linkType: 'Space', 42 | id: 'makqrw5hfm9d' 43 | } 44 | }, 45 | id: '5NPCujTlHiEd7KcRmGp3hS', 46 | type: 'Entry', 47 | createdAt: '2019-09-19T09:48:38.666Z', 48 | updatedAt: '2019-09-19T09:48:38.666Z', 49 | environment: { 50 | sys: { 51 | id: 'master', 52 | type: 'Link', 53 | linkType: 'Environment' 54 | } 55 | }, 56 | revision: 1, 57 | contentType: { 58 | sys: { 59 | type: 'Link', 60 | linkType: 'ContentType', 61 | id: 'event' 62 | } 63 | }, 64 | locale: 'en-US' 65 | }, 66 | fields: { title: 'クローズ' } 67 | } 68 | ], 69 | room: { 70 | sys: { 71 | space: { 72 | sys: { 73 | type: 'Link', 74 | linkType: 'Space', 75 | id: 'makqrw5hfm9d' 76 | } 77 | }, 78 | id: '1rnDVEsknx6MhhPgMAS9Gj', 79 | type: 'Entry', 80 | createdAt: '2019-08-25T10:51:56.475Z', 81 | updatedAt: '2019-08-25T10:51:56.475Z', 82 | environment: { 83 | sys: { 84 | id: 'master', 85 | type: 'Link', 86 | linkType: 'Environment' 87 | } 88 | }, 89 | revision: 1, 90 | contentType: { 91 | sys: { 92 | type: 'Link', 93 | linkType: 'ContentType', 94 | id: 'room' 95 | } 96 | }, 97 | locale: 'en-US' 98 | }, 99 | fields: { name: 'イエソドルーム' } 100 | } 101 | } 102 | } 103 | 104 | export default eventContainerWithEventsClosed 105 | -------------------------------------------------------------------------------- /test/fixtures/contentful/keynote.ts: -------------------------------------------------------------------------------- 1 | import Session from '~/types/session' 2 | 3 | const keynote: Session = { 4 | sys: { 5 | space: { 6 | sys: { 7 | type: 'Link', 8 | linkType: 'Space', 9 | id: 'makqrw5hfm9d' 10 | } 11 | }, 12 | id: '7xvdef2fny01iVD0ra03Iz', 13 | type: 'Entry', 14 | createdAt: '2019-08-25T11:00:38.634Z', 15 | updatedAt: '2019-09-18T13:39:30.715Z', 16 | environment: { 17 | sys: { 18 | id: 'master', 19 | type: 'Link', 20 | linkType: 'Environment' 21 | } 22 | }, 23 | revision: 4, 24 | contentType: { 25 | sys: { 26 | type: 'Link', 27 | linkType: 'ContentType', 28 | id: 'session' 29 | } 30 | }, 31 | locale: 'en-US' 32 | }, 33 | fields: { 34 | title: 'Keynote', 35 | time: 50, 36 | description: 'Keynote', 37 | ogImage: { 38 | sys: { 39 | type: 'Link', 40 | linkType: 'Asset', 41 | id: '5MWxt8IHkH1VpMdh6HgFa6' 42 | } 43 | }, 44 | speakers: [ 45 | { 46 | sys: { 47 | type: 'Link', 48 | linkType: 'Entry', 49 | id: '7aHzCP1a1rYpR6KbWENRmB' 50 | } 51 | } 52 | ], 53 | hasTranslation: true 54 | } 55 | } 56 | 57 | export default keynote 58 | -------------------------------------------------------------------------------- /test/fixtures/contentful/rooms.ts: -------------------------------------------------------------------------------- 1 | import Room from '~/types/room' 2 | 3 | const rooms: Room[] = [ 4 | { 5 | sys: { 6 | space: { 7 | sys: { 8 | type: 'Link', 9 | linkType: 'Space', 10 | id: 'makqrw5hfm9d' 11 | } 12 | }, 13 | id: '4MMzyRoKhtw4BlxWnCHbW9', 14 | type: 'Entry', 15 | createdAt: '2019-08-25T10:51:28.574Z', 16 | updatedAt: '2019-08-25T10:51:28.574Z', 17 | environment: { 18 | sys: { 19 | id: 'master', 20 | type: 'Link', 21 | linkType: 'Environment' 22 | } 23 | }, 24 | revision: 1, 25 | contentType: { 26 | sys: { 27 | type: 'Link', 28 | linkType: 'ContentType', 29 | id: 'room' 30 | } 31 | }, 32 | locale: 'en-US' 33 | }, 34 | fields: { name: 'PLAID ルーム' } 35 | }, 36 | { 37 | sys: { 38 | space: { 39 | sys: { 40 | type: 'Link', 41 | linkType: 'Space', 42 | id: 'makqrw5hfm9d' 43 | } 44 | }, 45 | id: '1rnDVEsknx6MhhPgMAS9Gj', 46 | type: 'Entry', 47 | createdAt: '2019-08-25T10:51:56.475Z', 48 | updatedAt: '2019-08-25T10:51:56.475Z', 49 | environment: { 50 | sys: { 51 | id: 'master', 52 | type: 'Link', 53 | linkType: 'Environment' 54 | } 55 | }, 56 | revision: 1, 57 | contentType: { 58 | sys: { 59 | type: 'Link', 60 | linkType: 'ContentType', 61 | id: 'room' 62 | } 63 | }, 64 | locale: 'en-US' 65 | }, 66 | fields: { name: 'イエソドルーム' } 67 | }, 68 | { 69 | sys: { 70 | space: { 71 | sys: { 72 | type: 'Link', 73 | linkType: 'Space', 74 | id: 'makqrw5hfm9d' 75 | } 76 | }, 77 | id: '6DXe9VnLT91YWE9UkVgkep', 78 | type: 'Entry', 79 | createdAt: '2019-08-25T10:51:45.572Z', 80 | updatedAt: '2019-08-25T10:51:45.572Z', 81 | environment: { 82 | sys: { 83 | id: 'master', 84 | type: 'Link', 85 | linkType: 'Environment' 86 | } 87 | }, 88 | revision: 1, 89 | contentType: { 90 | sys: { 91 | type: 'Link', 92 | linkType: 'ContentType', 93 | id: 'room' 94 | } 95 | }, 96 | locale: 'en-US' 97 | }, 98 | fields: { name: 'YUMEMI ルーム' } 99 | } 100 | ] 101 | 102 | export default rooms 103 | -------------------------------------------------------------------------------- /test/unit/__mocks__/fileMock.js: -------------------------------------------------------------------------------- 1 | module.exports = 'test-file-stub' 2 | -------------------------------------------------------------------------------- /test/unit/__mocks__/styleMock.js: -------------------------------------------------------------------------------- 1 | module.exports = {} 2 | -------------------------------------------------------------------------------- /test/unit/specs/components/BaseButton.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, RouterLinkStub } from '@vue/test-utils' 2 | import BaseButton from '~/components/BaseButton.vue' 3 | 4 | describe('BaseButton', () => { 5 | describe('href 属性を持っているとき', () => { 6 | test('a タグが返ってくる', () => { 7 | const wrapper = mount(BaseButton, { 8 | propsData: { 9 | href: 'https://example.com/' 10 | } 11 | }) 12 | 13 | expect(wrapper.is('a')).toBeTruthy() 14 | }) 15 | }) 16 | 17 | describe('to プロパティを持っているとき', () => { 18 | test('nuxt-link タグが返ってくる', () => { 19 | const toProp = '/' 20 | const wrapper = mount(BaseButton, { 21 | propsData: { 22 | to: toProp 23 | }, 24 | stubs: { 25 | NuxtLink: RouterLinkStub 26 | } 27 | }) 28 | 29 | expect(wrapper.find('a').props().to).toEqual(toProp) 30 | }) 31 | }) 32 | 33 | describe('href 属性も to プロパティを持っていないとき', () => { 34 | test('button タグが返ってくる', () => { 35 | const wrapper = mount(BaseButton) 36 | expect(wrapper.is('button')).toBeTruthy() 37 | }) 38 | }) 39 | 40 | describe('クリックされたとき', () => { 41 | test('click イベントが emit される', () => { 42 | const wrapper = mount(BaseButton) 43 | wrapper.trigger('click') 44 | expect(wrapper.emitted().click).toBeTruthy() 45 | }) 46 | }) 47 | }) 48 | -------------------------------------------------------------------------------- /test/unit/specs/components/BaseMain.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import BaseMain from '~/components/BaseMain.vue' 3 | 4 | describe('BaseMain', () => { 5 | test('$slots.heading を表示できる', () => { 6 | const wrapper = mount(BaseMain, { 7 | slots: { 8 | default: 'My Default', 9 | heading: 'MY HEADING' 10 | } 11 | }) 12 | expect(wrapper.find('.heading').text()).toEqual('MY HEADING') 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /test/unit/specs/components/BaseMainDescription.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import BaseMainDescription from '~/components/BaseMainDescription.vue' 3 | 4 | describe('BaseMainDescription', () => { 5 | test('$slots.heading を表示できる', () => { 6 | const wrapper = mount(BaseMainDescription, { 7 | slots: { 8 | default: 'My Default', 9 | heading: 'MY HEADING' 10 | } 11 | }) 12 | expect(wrapper.find('.heading').text()).toEqual('MY HEADING') 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /test/unit/specs/components/BaseSection.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import BaseSection from '~/components/BaseSection.vue' 3 | 4 | describe('BaseSection', () => { 5 | test('$slots.heading を表示できる', () => { 6 | const wrapper = mount(BaseSection, { 7 | slots: { 8 | default: 'My Default', 9 | heading: 'MY HEADING' 10 | } 11 | }) 12 | expect(wrapper.find('.heading').text()).toEqual('MY HEADING') 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /test/unit/specs/components/LinkToTwitter.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import LinkToTwitter from '~/components/LinkToTwitter.vue' 3 | 4 | describe('LinkToTwitter', () => { 5 | test('https://twitter.com/vuefes へのリンクをレンダリングできる', () => { 6 | const wrapper = mount(LinkToTwitter) 7 | expect(wrapper.find('a').attributes('href')).toEqual( 8 | 'https://twitter.com/vuefes' 9 | ) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheAccessSection.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, createLocalVue } from '@vue/test-utils' 2 | import VueLazyLoad from 'vue-lazyload' 3 | import TheAccessSection from '~/components/TheAccessSection.vue' 4 | 5 | const localVue = createLocalVue() 6 | 7 | localVue.use(VueLazyLoad) 8 | 9 | describe('TheAccessSection', () => { 10 | test('レンダリングできる', () => { 11 | const wrapper = mount(TheAccessSection, { localVue }) 12 | expect(wrapper.find('.the-access-section').isVisible()).toBeTruthy() 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheEventSection.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, createLocalVue } from '@vue/test-utils' 2 | import VueLazyLoad from 'vue-lazyload' 3 | import TheEventSection from '~/components/TheEventSection.vue' 4 | 5 | const localVue = createLocalVue() 6 | 7 | localVue.use(VueLazyLoad) 8 | 9 | describe('TheEventSection', () => { 10 | test('レンダリングできる', () => { 11 | const wrapper = mount(TheEventSection, { localVue }) 12 | expect(wrapper.find('.the-event-section').isVisible()).toBeTruthy() 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheFooter.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, createLocalVue, RouterLinkStub, Wrapper } from '@vue/test-utils' 2 | import Vue from 'vue' 3 | import VueLazyLoad from 'vue-lazyload' 4 | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' 5 | import TheFooter from '~/components/TheFooter.vue' 6 | 7 | const localVue = createLocalVue() 8 | 9 | localVue.use(VueLazyLoad) 10 | 11 | describe('TheFooter', () => { 12 | let wrapper: Wrapper 13 | 14 | beforeEach(() => { 15 | wrapper = mount(TheFooter, { 16 | localVue, 17 | stubs: { 18 | NuxtLink: RouterLinkStub, 19 | Fa: FontAwesomeIcon 20 | } 21 | }) 22 | }) 23 | 24 | test('レンダリングできる', () => { 25 | expect(wrapper.find('.the-footer').isVisible()).toBeTruthy() 26 | }) 27 | 28 | test('NuxtLink がルートパス指定になっており、かつ Trailing Slash が入っている', () => { 29 | const nuxtLinks: Wrapper[] = wrapper.findAll(RouterLinkStub).wrappers 30 | 31 | for (const nuxtLink of nuxtLinks) { 32 | expect(nuxtLink.props().to).toEqual( 33 | expect.stringMatching(/^\/([\w-]+\/)?$/) 34 | ) 35 | } 36 | }) 37 | }) 38 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheHeadSection.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import TheHeadSection from '~/components/TheHeadSection.vue' 3 | 4 | describe('TheHeadSection', () => { 5 | test('レンダリングできる', () => { 6 | const wrapper = mount(TheHeadSection, { 7 | stubs: { 8 | 'no-ssr': '
' 9 | } 10 | }) 11 | expect(wrapper.find('.the-head-section').isVisible()).toBeTruthy() 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheHeader.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, createLocalVue, RouterLinkStub } from '@vue/test-utils' 2 | import VueLazyLoad from 'vue-lazyload' 3 | import TheHeader from '~/components/TheHeader.vue' 4 | 5 | const localVue = createLocalVue() 6 | 7 | localVue.use(VueLazyLoad) 8 | 9 | let wrapper 10 | const navigationLinks = [ 11 | '/#the-speaker-list-section', 12 | '/#the-time-table-section', 13 | '/#the-event-section', 14 | '/#the-ticket-section', 15 | '/#the-access-section', 16 | '/#the-sponsor-list-section', 17 | '/#the-staff-list-section' 18 | ] 19 | 20 | describe('TheHeader', () => { 21 | beforeEach(() => { 22 | wrapper = mount(TheHeader, { 23 | localVue, 24 | stubs: { 25 | NuxtLink: RouterLinkStub 26 | } 27 | }) 28 | }) 29 | 30 | test('トップページへのリンクをレンダリングできる', () => { 31 | expect(wrapper.find('a').props().to).toEqual('/') 32 | }) 33 | 34 | describe('ナビゲーションメニューのリンク', () => { 35 | test('メニューボタンを押した場合に、必要なリンクが含まれている', () => { 36 | const aTagWrappers = wrapper.findAll('.togglable-menu-contents a') 37 | .wrappers 38 | 39 | navigationLinks.forEach((link, linkIndex) => { 40 | expect(aTagWrappers[linkIndex].props().to).toEqual(link) 41 | }) 42 | }) 43 | 44 | test('直接表示している場合に、必要なリンクが含まれている', () => { 45 | const aTagWrappers = wrapper.findAll('.menu-contents a').wrappers 46 | 47 | navigationLinks.forEach((link, linkIndex) => { 48 | expect(aTagWrappers[linkIndex].props().to).toEqual(link) 49 | }) 50 | }) 51 | }) 52 | }) 53 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheSpeakerListSection.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, createLocalVue, RouterLinkStub } from '@vue/test-utils' 2 | import VueLazyLoad from 'vue-lazyload' 3 | import Vuex from 'vuex' 4 | import createFullStore from 'test/unit/specs/utils/createFullStore' 5 | import TheSpeakerListSection from '~/components/TheSpeakerListSection.vue' 6 | 7 | const localVue = createLocalVue() 8 | 9 | localVue.use(VueLazyLoad) 10 | localVue.use(Vuex) 11 | 12 | const store = createFullStore(Vuex) 13 | 14 | describe('TheSpeakerListSection', () => { 15 | let wrapper 16 | 17 | beforeEach(() => { 18 | wrapper = mount(TheSpeakerListSection, { 19 | localVue, 20 | store, 21 | stubs: { 22 | NuxtLink: RouterLinkStub 23 | } 24 | }) 25 | }) 26 | 27 | test('レンダリングできる', () => { 28 | expect(wrapper.find('.the-speaker-list-section').isVisible()).toBeTruthy() 29 | }) 30 | 31 | test('リンクに Trailing Slash が入っている', () => { 32 | expect(wrapper.find('.avatar-link').props().to).toBe('/sessions/jlooper/') 33 | expect(wrapper.find('.name-link').props().to).toBe('/sessions/jlooper/') 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheSponsorListSection.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, RouterLinkStub, createLocalVue } from '@vue/test-utils' 2 | import VueLazyLoad from 'vue-lazyload' 3 | import Vuex from 'vuex' 4 | import createFullStore from 'test/unit/specs/utils/createFullStore' 5 | import sponsors from 'test/fixtures/contentful/sponsors' 6 | import TheSponsorListSection from '~/components/TheSponsorListSection.vue' 7 | 8 | const localVue = createLocalVue() 9 | 10 | localVue.use(VueLazyLoad) 11 | localVue.use(Vuex) 12 | 13 | const store = createFullStore(Vuex) 14 | 15 | describe('TheSponsorListSection', () => { 16 | let wrapper 17 | 18 | beforeEach(() => { 19 | wrapper = mount(TheSponsorListSection, { 20 | localVue, 21 | store, 22 | stubs: { 23 | NuxtLink: RouterLinkStub 24 | } 25 | }) 26 | }) 27 | 28 | test('レンダリングできる', () => { 29 | expect(wrapper.find('.the-sponsor-list-section').isVisible()).toBeTruthy() 30 | }) 31 | 32 | describe('.sponsor-group', () => { 33 | test('スポンサープランがクラス名に付与される', () => { 34 | expect(wrapper.find('.sponsor-group').classes()).toEqual([ 35 | 'sponsor-group', 36 | 'platinum' 37 | ]) 38 | }) 39 | 40 | test('スポンサープランが表示される', () => { 41 | expect(wrapper.find('.sponsor-plan').text()).toBe('PLATINUM') 42 | }) 43 | }) 44 | 45 | describe('.sponsor', () => { 46 | test('スポンサーが表示される', () => { 47 | expect(wrapper.find('.sponsor').isVisible()).toBeTruthy() 48 | }) 49 | 50 | test('リンクがスポンサー一覧ページのアンカーになっている', () => { 51 | const platinumSponsorSysId: string = sponsors[2].sys.id 52 | expect( 53 | wrapper 54 | .find('.platinum') 55 | .find(RouterLinkStub) 56 | .props().to 57 | ).toBe(`/sponsors/#sponsor_${platinumSponsorSysId}`) 58 | }) 59 | }) 60 | }) 61 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheStaffListSection.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, createLocalVue, RouterLinkStub } from '@vue/test-utils' 2 | import VueLazyLoad from 'vue-lazyload' 3 | import TheStaffListSection from '~/components/TheStaffListSection.vue' 4 | 5 | const localVue = createLocalVue() 6 | 7 | localVue.use(VueLazyLoad) 8 | 9 | describe('TheStaffListSection', () => { 10 | let wrapper 11 | 12 | beforeEach(() => { 13 | wrapper = mount(TheStaffListSection, { 14 | localVue, 15 | stubs: { 16 | NuxtLink: RouterLinkStub 17 | } 18 | }) 19 | }) 20 | 21 | test('レンダリングできる', () => { 22 | expect(wrapper.find('.the-staff-list-section').isVisible()).toBeTruthy() 23 | }) 24 | 25 | describe('compareStaffNames', () => { 26 | test('英大文字・小文字を区別しない', () => { 27 | expect( 28 | wrapper.vm.compareStaffNames('KiaKing85', 'inouetakuya') > 0 29 | ).toBeTruthy() 30 | }) 31 | 32 | test('アンダースコア(_)は無視される', () => { 33 | expect( 34 | wrapper.vm.compareStaffNames('__syumai', 'inouetakuya') > 0 35 | ).toBeTruthy() 36 | }) 37 | 38 | test.todo('英字のほうが数字よりも先にソートされる') 39 | test.todo('数字のほうが記号よりも先にソートされる') 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheTicketSection.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, createLocalVue, RouterLinkStub } from '@vue/test-utils' 2 | import VueLazyLoad from 'vue-lazyload' 3 | import TheTicketSection from '~/components/TheTicketSection.vue' 4 | 5 | const localVue = createLocalVue() 6 | 7 | localVue.use(VueLazyLoad) 8 | 9 | describe('TheTicketSection', () => { 10 | test('レンダリングできる', () => { 11 | const wrapper = mount(TheTicketSection, { 12 | localVue, 13 | stubs: { 14 | NuxtLink: RouterLinkStub 15 | } 16 | }) 17 | 18 | expect(wrapper.find('.the-ticket-section').isVisible()).toBeTruthy() 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheTimeTableSection.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, RouterLinkStub, createLocalVue } from '@vue/test-utils' 2 | import VueLazyLoad from 'vue-lazyload' 3 | import Vuex from 'vuex' 4 | import createFullStore from 'test/unit/specs/utils/createFullStore' 5 | import TheTimeTableSection from '~/components/TheTimeTableSection.vue' 6 | 7 | const localVue = createLocalVue() 8 | 9 | localVue.use(VueLazyLoad) 10 | localVue.use(Vuex) 11 | 12 | const store = createFullStore(Vuex) 13 | 14 | describe('TheTimeTableSection', () => { 15 | test('レンダリングできる', () => { 16 | const wrapper = mount(TheTimeTableSection, { 17 | localVue, 18 | store, 19 | stubs: { 20 | NuxtLink: RouterLinkStub 21 | } 22 | }) 23 | expect(wrapper.find('.the-time-table-section').isVisible()).toBeTruthy() 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheTimeTableSection/Event.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import events from 'test/fixtures/contentful/events' 3 | import Event from '~/components/TheTimeTableSection/Event.vue' 4 | 5 | describe('Event', () => { 6 | test('event.fields.title を表示できる', () => { 7 | const wrapper = mount(Event, { 8 | propsData: { 9 | event: events[0] 10 | } 11 | }) 12 | expect(wrapper.find('.event').text()).toBe(events[0].fields.title) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheTimeTableSection/EventContent.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, RouterLinkStub, createLocalVue } from '@vue/test-utils' 2 | import VueLazyLoad from 'vue-lazyload' 3 | import Vuex from 'vuex' 4 | import createFullStore from 'test/unit/specs/utils/createFullStore' 5 | import keynote from 'test/fixtures/contentful/keynote' 6 | import sessions from 'test/fixtures/contentful/sessions' 7 | import events from 'test/fixtures/contentful/events' 8 | import EventContent from '~/components/TheTimeTableSection/EventContent.vue' 9 | 10 | const localVue = createLocalVue() 11 | 12 | localVue.use(VueLazyLoad) 13 | localVue.use(Vuex) 14 | 15 | const store = createFullStore(Vuex) 16 | 17 | const mountEventContent = content => { 18 | return mount(EventContent, { 19 | localVue, 20 | store, 21 | propsData: { 22 | content 23 | }, 24 | stubs: { 25 | NuxtLink: RouterLinkStub 26 | } 27 | }) 28 | } 29 | 30 | describe('EventContent', () => { 31 | let wrapper 32 | 33 | describe('content がキーノートのとき', () => { 34 | beforeEach(() => { 35 | wrapper = mountEventContent(keynote) 36 | }) 37 | 38 | test('Keynote を表示できる', () => { 39 | expect(wrapper.find('.keynote').isVisible()).toBeTruthy() 40 | }) 41 | }) 42 | 43 | describe('content が Session のとき', () => { 44 | beforeEach(() => { 45 | wrapper = mountEventContent(sessions[0]) 46 | }) 47 | 48 | test('Session を表示できる', () => { 49 | expect(wrapper.find('.session').isVisible()).toBeTruthy() 50 | }) 51 | }) 52 | 53 | describe('content が Event のとき', () => { 54 | beforeEach(() => { 55 | wrapper = mountEventContent(events[0]) 56 | }) 57 | 58 | test('Event を表示できる', () => { 59 | expect(wrapper.find('.event').isVisible()).toBeTruthy() 60 | }) 61 | }) 62 | }) 63 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheTimeTableSection/Room.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import rooms from 'test/fixtures/contentful/rooms' 3 | import Room from '~/components/TheTimeTableSection/Room.vue' 4 | 5 | describe('Room', () => { 6 | let wrapper 7 | 8 | beforeEach(() => { 9 | wrapper = mount(Room, { 10 | propsData: { 11 | room: rooms[0] 12 | } 13 | }) 14 | }) 15 | 16 | test('room.fields.name を表示できる', () => { 17 | expect(wrapper.find('.room').text()).toBe(rooms[0].fields.name) 18 | }) 19 | 20 | test('room.sys.id に基づいたクラスが追加される', () => { 21 | expect(wrapper.find('.room').classes()).toContain('room--is-plaid') 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /test/unit/specs/components/TheTimeTableSection/Session.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, RouterLinkStub, createLocalVue } from '@vue/test-utils' 2 | import Vuex from 'vuex' 3 | import createFullStore from 'test/unit/specs/utils/createFullStore' 4 | import sessions from 'test/fixtures/contentful/sessions' 5 | 6 | // @ts-ignore error TS2307: Cannot find module 7 | import Session from '~/components/TheTimeTableSection/Session.vue' 8 | 9 | const localVue = createLocalVue() 10 | 11 | localVue.use(Vuex) 12 | 13 | const store = createFullStore(Vuex) 14 | 15 | describe('Session', () => { 16 | let wrapper 17 | 18 | beforeEach(() => { 19 | wrapper = mount(Session, { 20 | localVue, 21 | store, 22 | propsData: { 23 | session: sessions[0] 24 | }, 25 | stubs: { 26 | NuxtLink: RouterLinkStub 27 | } 28 | }) 29 | }) 30 | 31 | test('Session 情報を表示できる', () => { 32 | expect(wrapper.find('.session').text()).toContain(sessions[0].fields.title) 33 | }) 34 | 35 | test('Speaker 情報を表示できる', () => { 36 | const speaker = store.getters['speakers/find']( 37 | sessions[0].fields.speakers[0].sys.id 38 | ) 39 | 40 | expect(wrapper.find('.speaker-name').text()).toContain(speaker.fields.name) 41 | }) 42 | 43 | describe('sessionIdAlias', () => { 44 | test('Speaker の github アカウント名を取得できる', () => { 45 | expect(wrapper.vm.sessionIdAlias).toBe('Atinux') 46 | }) 47 | }) 48 | }) 49 | -------------------------------------------------------------------------------- /test/unit/specs/pages/code-of-conduct.spec.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import { mount, RouterLinkStub, Wrapper } from '@vue/test-utils' 3 | import CodeOfConductPage from '~/pages/code-of-conduct.vue' 4 | 5 | describe('CodeOfConductPage', () => { 6 | let wrapper: Wrapper 7 | 8 | beforeEach(() => { 9 | wrapper = mount(CodeOfConductPage, { 10 | stubs: { 11 | NuxtLink: RouterLinkStub 12 | } 13 | }) 14 | }) 15 | 16 | test('レンダリングできる', () => { 17 | expect(wrapper.find('.code-of-conduct-page').isVisible()).toBeTruthy() 18 | }) 19 | 20 | test('NuxtLink がルートパス指定になっており、かつ Trailing Slash が入っている', () => { 21 | const nuxtLinks: Wrapper[] = wrapper.findAll(RouterLinkStub).wrappers 22 | 23 | for (const nuxtLink of nuxtLinks) { 24 | expect(nuxtLink.props().to).toEqual( 25 | expect.stringMatching(/^\/([\w-]+\/)?$/) 26 | ) 27 | } 28 | }) 29 | }) 30 | -------------------------------------------------------------------------------- /test/unit/specs/pages/contact.spec.ts: -------------------------------------------------------------------------------- 1 | import { shallowMount, RouterLinkStub } from '@vue/test-utils' 2 | import ContactPage from '~/pages/contact.vue' 3 | 4 | describe('ContactPage', () => { 5 | test('レンダリングできる', () => { 6 | const wrapper = shallowMount(ContactPage, { 7 | stubs: { 8 | NuxtLink: RouterLinkStub 9 | } 10 | }) 11 | expect(wrapper.find('.contact-page').isVisible()).toBeTruthy() 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /test/unit/specs/pages/index.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, RouterLinkStub, createLocalVue } from '@vue/test-utils' 2 | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' 3 | import VueLazyLoad from 'vue-lazyload' 4 | import Vuex from 'vuex' 5 | import createFullStore from 'test/unit/specs/utils/createFullStore' 6 | import HomePage from '~/pages/index.vue' 7 | 8 | const localVue = createLocalVue() 9 | 10 | localVue.use(VueLazyLoad) 11 | localVue.use(Vuex) 12 | 13 | const store = createFullStore(Vuex) 14 | 15 | describe('HomePage', () => { 16 | test('レンダリングできる', () => { 17 | const wrapper = mount(HomePage, { 18 | localVue, 19 | store, 20 | stubs: { 21 | NuxtLink: RouterLinkStub, 22 | Fa: FontAwesomeIcon, 23 | 'no-ssr': '
' 24 | } 25 | }) 26 | expect(wrapper.find('.home-page').isVisible()).toBeTruthy() 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /test/unit/specs/pages/privacy.spec.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import { mount, RouterLinkStub, Wrapper } from '@vue/test-utils' 3 | import PrivacyPage from '~/pages/privacy.vue' 4 | 5 | describe('PrivacyPage', () => { 6 | let wrapper: Wrapper 7 | 8 | beforeEach(() => { 9 | wrapper = mount(PrivacyPage, { 10 | stubs: { 11 | NuxtLink: RouterLinkStub 12 | } 13 | }) 14 | }) 15 | 16 | test('レンダリングできる', () => { 17 | expect(wrapper.find('.privacy-page').isVisible()).toBeTruthy() 18 | }) 19 | 20 | test('NuxtLink がルートパス指定になっており、かつ Trailing Slash が入っている', () => { 21 | expect(wrapper.find(RouterLinkStub).props().to).toBe('/') 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /test/unit/specs/pages/sessions/_speakerId.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, createLocalVue, RouterLinkStub } from '@vue/test-utils' 2 | import Vuex from 'vuex' 3 | import createFullStore from 'test/unit/specs/utils/createFullStore' 4 | import SessionPage from '~/pages/sessions/_speakerId.vue' 5 | 6 | const localVue = createLocalVue() 7 | 8 | localVue.use(Vuex) 9 | 10 | const store = createFullStore(Vuex) 11 | 12 | describe('SessionPage', () => { 13 | let wrapper 14 | 15 | beforeEach(() => { 16 | wrapper = mount(SessionPage, { 17 | localVue, 18 | store, 19 | stubs: { 20 | NuxtLink: RouterLinkStub 21 | } 22 | }) 23 | }) 24 | 25 | test('レンダリングできる', () => { 26 | const data = wrapper.vm.$options.asyncData({ 27 | params: { speakerId: 'yyx990803' }, 28 | route: { path: '/sessions/yyx990803/' } 29 | }) 30 | wrapper.setData(data) 31 | 32 | expect(wrapper.find('.session-page').isVisible()).toBeTruthy() 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /test/unit/specs/pages/sponsors.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount, RouterLinkStub, createLocalVue } from '@vue/test-utils' 2 | import Vuex from 'vuex' 3 | import sponsors from 'test/fixtures/contentful/sponsors' 4 | import createFullStore from 'test/unit/specs/utils/createFullStore' 5 | import SponsorsPage from '~/pages/sponsors.vue' 6 | 7 | const localVue = createLocalVue() 8 | 9 | localVue.use(Vuex) 10 | 11 | const store = createFullStore(Vuex) 12 | 13 | describe('SponsorsPage', () => { 14 | let wrapper 15 | 16 | beforeEach(() => { 17 | wrapper = mount(SponsorsPage, { 18 | localVue, 19 | store, 20 | stubs: { 21 | NuxtLink: RouterLinkStub 22 | } 23 | }) 24 | }) 25 | 26 | test('レンダリングできる', () => { 27 | expect(wrapper.find('.sponsors-page').isVisible()).toBeTruthy() 28 | }) 29 | 30 | describe('.index', () => { 31 | test('index にプランのアンカーがついている', () => { 32 | const indexLinkWrapper = wrapper.find('.index .link') 33 | expect(indexLinkWrapper.text()).toBe('PLATINUM') 34 | expect(indexLinkWrapper.props().to).toBe('/sponsors/#platinum') 35 | }) 36 | }) 37 | 38 | describe('.sponsor-group-list', () => { 39 | test('スポンサープランがクラス名に付与される', () => { 40 | expect(wrapper.find('.sponsor-group').classes()).toEqual([ 41 | 'sponsor-group', 42 | 'platinum' 43 | ]) 44 | }) 45 | 46 | test('スポンサープランの詳細が表示される', () => { 47 | const platinumSponsor = sponsors[2] 48 | const platinumSponsorWrapper = wrapper.find('.platinum') 49 | expect(platinumSponsorWrapper.find('.sponsor-plan').text()).toBe( 50 | 'PLATINUM' 51 | ) 52 | expect(platinumSponsorWrapper.find('.sponsor').attributes().id).toBe( 53 | `sponsor_${platinumSponsor.sys.id}` 54 | ) 55 | expect( 56 | platinumSponsorWrapper.find('.sponsor > li > a').attributes().href 57 | ).toBe(platinumSponsor.fields.url) 58 | expect( 59 | platinumSponsorWrapper.find('.sponsor-image').isVisible() 60 | ).toBeTruthy() 61 | expect(platinumSponsorWrapper.find('.sponsor-name').text()).toBe( 62 | platinumSponsor.fields.name 63 | ) 64 | expect(platinumSponsorWrapper.find('.sponsor-url').text()).toBe( 65 | platinumSponsor.fields.url 66 | ) 67 | expect(platinumSponsorWrapper.find('.sponsor-pr').text()).toBe( 68 | platinumSponsor.fields.pr 69 | ) 70 | }) 71 | }) 72 | }) 73 | -------------------------------------------------------------------------------- /test/unit/specs/store/eventContainerParts.spec.ts: -------------------------------------------------------------------------------- 1 | import eventContainerParts from 'test/fixtures/contentful/eventContainerParts' 2 | import * as contentful from '~/plugins/contentful' 3 | import { 4 | state as initialState, 5 | getters, 6 | mutations, 7 | actions 8 | } from '~/store/eventContainerParts' 9 | 10 | describe('eventContainerParts module', () => { 11 | let state 12 | 13 | beforeEach(() => { 14 | state = initialState() 15 | }) 16 | 17 | describe('getters', () => { 18 | describe('find', () => { 19 | beforeEach(() => { 20 | state.eventContainerParts = eventContainerParts 21 | }) 22 | 23 | test('id が一致する EventContainerPart を取得できる', () => { 24 | const id: string = eventContainerParts[0].sys.id 25 | expect(getters.find(state)(id)).toEqual(eventContainerParts[0]) 26 | }) 27 | }) 28 | }) 29 | 30 | describe('mutations', () => { 31 | describe('setEventContainerParts', () => { 32 | test('eventContainerParts をセットできる', () => { 33 | mutations.setEventContainerParts(state, eventContainerParts) 34 | expect(state.eventContainerParts).toEqual(eventContainerParts) 35 | }) 36 | }) 37 | }) 38 | 39 | describe('actions', () => { 40 | describe('fetchEventContainerParts', () => { 41 | beforeEach(() => { 42 | // @ts-ignore error TS2540: Cannot assign to 'getEventContainerParts' because it is a read-only property. 43 | contentful.getEventContainerParts = jest 44 | .fn() 45 | .mockResolvedValue(eventContainerParts) 46 | }) 47 | 48 | test('eventContainerParts を取得してセットする', async () => { 49 | const commit = jest.fn() 50 | 51 | // @ts-ignore error TS2345: Argument of type '{ commit: Mock; }' is not assignable to parameter of type 'Context'. 52 | // Type '{ commit: Mock; }' is missing the following properties from type 'Context': dispatch, state, getters, rootState, rootGetters 53 | await actions.fetchEventContainerParts({ commit }) 54 | 55 | expect(commit).toHaveBeenCalledWith( 56 | 'setEventContainerParts', 57 | eventContainerParts 58 | ) 59 | }) 60 | }) 61 | }) 62 | }) 63 | -------------------------------------------------------------------------------- /test/unit/specs/store/eventContainers.spec.ts: -------------------------------------------------------------------------------- 1 | import eventContainers from 'test/fixtures/contentful/eventContainers' 2 | import * as contentful from '~/plugins/contentful' 3 | import { 4 | state as initialState, 5 | getters, 6 | mutations, 7 | actions 8 | } from '~/store/eventContainers' 9 | 10 | describe('eventContainers module', () => { 11 | let state 12 | 13 | beforeEach(() => { 14 | state = initialState() 15 | }) 16 | 17 | describe('getters', () => { 18 | describe('find', () => { 19 | beforeEach(() => { 20 | state.eventContainers = eventContainers 21 | }) 22 | 23 | test('id が一致する EventContainer を取得できる', () => { 24 | const id: string = eventContainers[0].sys.id 25 | expect(getters.find(state)(id)).toEqual(eventContainers[0]) 26 | }) 27 | }) 28 | }) 29 | 30 | describe('mutations', () => { 31 | describe('setEventContainers', () => { 32 | test('eventContainers をセットできる', () => { 33 | mutations.setEventContainers(state, eventContainers) 34 | expect(state.eventContainers).toEqual(eventContainers) 35 | }) 36 | }) 37 | }) 38 | 39 | describe('actions', () => { 40 | describe('fetchEventContainers', () => { 41 | beforeEach(() => { 42 | // @ts-ignore error TS2540: Cannot assign to 'getEventContainers' because it is a read-only property. 43 | contentful.getEventContainers = jest 44 | .fn() 45 | .mockResolvedValue(eventContainers) 46 | }) 47 | 48 | test('eventContainers を取得してセットする', async () => { 49 | const commit = jest.fn() 50 | 51 | // @ts-ignore error TS2345: Argument of type '{ commit: Mock; }' is not assignable to parameter of type 'Context'. 52 | // Type '{ commit: Mock; }' is missing the following properties from type 'Context': dispatch, state, getters, rootState, rootGetters 53 | await actions.fetchEventContainers({ commit }) 54 | 55 | expect(commit).toHaveBeenCalledWith( 56 | 'setEventContainers', 57 | eventContainers 58 | ) 59 | }) 60 | }) 61 | }) 62 | }) 63 | -------------------------------------------------------------------------------- /test/unit/specs/store/sponsors.spec.ts: -------------------------------------------------------------------------------- 1 | import sponsors from 'test/fixtures/contentful/sponsors' 2 | import * as contentful from '~/plugins/contentful' 3 | import Sponsor from '~/types/sponsor' 4 | import { 5 | state as initialState, 6 | getters, 7 | mutations, 8 | actions 9 | } from '~/store/sponsors' 10 | 11 | describe('sponsors module', () => { 12 | let state 13 | 14 | beforeEach(() => { 15 | state = initialState() 16 | }) 17 | 18 | describe('getters', () => { 19 | describe('sponsorsByPlan', () => { 20 | beforeEach(() => { 21 | state.sponsors = sponsors 22 | }) 23 | 24 | test('plan と一致するスポンサー情報のみ取得できる', () => { 25 | const platinumSponsors: Sponsor[] = [sponsors[2]] 26 | expect(getters.sponsorsByPlan(state)('platinum')).toEqual( 27 | platinumSponsors 28 | ) 29 | }) 30 | }) 31 | 32 | describe('sponsorPlansHavingSponsors', () => { 33 | beforeEach(() => { 34 | state.sponsors = sponsors 35 | }) 36 | 37 | test('スポンサーを持っている sponsorPlan の一覧を取得できる', () => { 38 | expect( 39 | // Getters の型を備えたスタブを準備するのが大変でコストに見合わないため @ts-ignore 40 | // @ts-ignore error TS2339: Argument of type '{ sponsorsByPlan: (plan: string) => any; }' is not assignable to parameter of type 'Getters'. 41 | // Property 'sponsorPlansHavingSponsors' is missing in type '{ sponsorsByPlan: (plan: string) => any; }' but required in type 'Getters'. 42 | getters.sponsorPlansHavingSponsors(state, { 43 | sponsorsByPlan: getters.sponsorsByPlan(state) 44 | }) 45 | ).toEqual([ 46 | { name: 'PLATINUM', plan: 'platinum' }, 47 | { name: 'SILVER', plan: 'silver' } 48 | ]) 49 | }) 50 | }) 51 | }) 52 | 53 | describe('mutations', () => { 54 | describe('setSponsors', () => { 55 | test('SponsorList をセットできる', () => { 56 | mutations.setSponsors(state, sponsors) 57 | expect(state.sponsors).toEqual(sponsors) 58 | }) 59 | }) 60 | }) 61 | 62 | describe('actions', () => { 63 | describe('fetchSponsors', () => { 64 | beforeEach(() => { 65 | // @ts-ignore error TS2540: Cannot assign to 'getSponsors' because it is a read-only property. 66 | contentful.getSponsors = jest.fn().mockResolvedValue(sponsors) 67 | }) 68 | 69 | test('sponsorList を取得してセットする', async () => { 70 | const commit = jest.fn() 71 | 72 | // Context の型を備えたモックを準備するのが大変でコストに見合わないため @ts-ignore 73 | // @ts-ignore error TS2345: Argument of type '{ commit: Mock; }' is not assignable to parameter of type 'Context'. 74 | // Type '{ commit: Mock; }' is missing the following properties from type 'Context': dispatch, state, getters, rootState, rootGettersts 75 | await actions.fetchSponsors({ commit }) 76 | 77 | expect(commit).toHaveBeenCalledWith('setSponsors', sponsors) 78 | }) 79 | }) 80 | }) 81 | }) 82 | -------------------------------------------------------------------------------- /test/unit/specs/store/timeTableSections.spec.ts: -------------------------------------------------------------------------------- 1 | import timeTableSections from 'test/fixtures/contentful/timeTableSections' 2 | import * as contentful from '~/plugins/contentful' 3 | import { 4 | state as initialState, 5 | getters, 6 | mutations, 7 | actions 8 | } from '~/store/timeTableSections' 9 | 10 | describe('timeTableSections module', () => { 11 | let state 12 | 13 | beforeEach(() => { 14 | state = initialState() 15 | }) 16 | 17 | describe('getters', () => { 18 | describe('all', () => { 19 | beforeEach(() => { 20 | state.timeTableSections = timeTableSections 21 | }) 22 | 23 | test('すべての timeTableSections を取得できる', () => { 24 | expect(getters.all(state)).toEqual(timeTableSections) 25 | }) 26 | }) 27 | }) 28 | 29 | describe('mutations', () => { 30 | describe('setTimeTableSections', () => { 31 | test('timeTableSections をセットできる', () => { 32 | mutations.setTimeTableSections(state, timeTableSections) 33 | expect(state.timeTableSections).toEqual(timeTableSections) 34 | }) 35 | }) 36 | }) 37 | 38 | describe('actions', () => { 39 | describe('fetchTimeTableSections', () => { 40 | beforeEach(() => { 41 | // @ts-ignore error TS2540: Cannot assign to 'getTimeTableSections' because it is a read-only property. 42 | contentful.getTimeTableSections = jest 43 | .fn() 44 | .mockResolvedValue(timeTableSections) 45 | }) 46 | 47 | test('TimeTableSections を取得してセットする', async () => { 48 | const commit = jest.fn() 49 | 50 | // @ts-ignore error TS2345: Argument of type '{ commit: Mock; }' is not assignable to parameter of type 'Context'. 51 | // Type '{ commit: Mock; }' is missing the following properties from type 'Context': dispatch, state, getters, rootState, rootGetters 52 | await actions.fetchTimeTableSections({ commit }) 53 | 54 | expect(commit).toHaveBeenCalledWith( 55 | 'setTimeTableSections', 56 | timeTableSections 57 | ) 58 | }) 59 | }) 60 | }) 61 | }) 62 | -------------------------------------------------------------------------------- /test/unit/specs/utils/createFullStore.ts: -------------------------------------------------------------------------------- 1 | import cloneDeep from 'lodash.clonedeep' 2 | import speakersData from 'test/fixtures/contentful/speakers' 3 | import sessionsData from 'test/fixtures/contentful/sessions' 4 | import timeTableSectionsData from 'test/fixtures/contentful/timeTableSections' 5 | import eventContainersData from 'test/fixtures/contentful/eventContainers' 6 | import eventContainerPartsData from 'test/fixtures/contentful/eventContainerParts' 7 | import sponsorsData from 'test/fixtures/contentful/sponsors' 8 | import assetData from 'test/fixtures/contentful/asset' 9 | import * as speakers from '~/store/speakers' 10 | import * as sessions from '~/store/sessions' 11 | import * as timeTableSections from '~/store/timeTableSections' 12 | import * as eventContainers from '~/store/eventContainers' 13 | import * as eventContainerParts from '~/store/eventContainerParts' 14 | import * as sponsors from '~/store/sponsors' 15 | 16 | const speakersDataWithAssets = cloneDeep(speakersData).map(speaker => { 17 | speaker.fields.avatar = assetData 18 | speaker.fields.avatar2x = assetData 19 | return speaker 20 | }) 21 | 22 | const sessionsDataWithAssets = cloneDeep(sessionsData).map(session => { 23 | session.fields.ogImage = assetData 24 | return session 25 | }) 26 | 27 | export default Vuex => { 28 | const store = new Vuex.Store({ 29 | modules: { 30 | speakers: { 31 | namespaced: true, 32 | ...speakers 33 | }, 34 | sessions: { 35 | namespaced: true, 36 | ...sessions 37 | }, 38 | timeTableSections: { 39 | namespaced: true, 40 | ...timeTableSections 41 | }, 42 | eventContainers: { 43 | namespaced: true, 44 | ...eventContainers 45 | }, 46 | eventContainerParts: { 47 | namespaced: true, 48 | ...eventContainerParts 49 | }, 50 | sponsors: { 51 | namespaced: true, 52 | ...sponsors 53 | } 54 | } 55 | }) 56 | 57 | // nuxtServerInit と同様のことを行う 58 | store.commit('speakers/setSpeakers', speakersDataWithAssets) 59 | store.commit('sessions/setSessions', sessionsDataWithAssets) 60 | store.commit('timeTableSections/setTimeTableSections', timeTableSectionsData) 61 | store.commit('eventContainers/setEventContainers', eventContainersData) 62 | store.commit( 63 | 'eventContainerParts/setEventContainerParts', 64 | eventContainerPartsData 65 | ) 66 | store.commit('sponsors/setSponsors', sponsorsData) 67 | 68 | return store 69 | } 70 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "lib": [ 7 | "esnext", 8 | "esnext.asynciterable", 9 | "dom" 10 | ], 11 | "esModuleInterop": true, 12 | "experimentalDecorators": true, 13 | "allowJs": true, 14 | "sourceMap": true, 15 | "strict": true, 16 | "noImplicitAny": false, 17 | "noEmit": true, 18 | "baseUrl": ".", 19 | "paths": { 20 | "~/*": [ 21 | "./src/*" 22 | ], 23 | "@/*": [ 24 | "./src/*" 25 | ], 26 | "test/*": [ 27 | "./test/*" 28 | ] 29 | }, 30 | "types": [ 31 | "@types/node", 32 | "@types/jest", 33 | "@nuxt/vue-app" 34 | ] 35 | } 36 | } 37 | --------------------------------------------------------------------------------