diff --git a/app/assets/images/completion/completion_background.svg b/app/assets/images/completion/completion_background.svg new file mode 100644 index 00000000000..79ec092303c --- /dev/null +++ b/app/assets/images/completion/completion_background.svg @@ -0,0 +1,1522 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/assets/images/completion/completion_default.png b/app/assets/images/completion/completion_default.png new file mode 100644 index 00000000000..2f9cc5605c9 Binary files /dev/null and b/app/assets/images/completion/completion_default.png differ diff --git a/app/assets/stylesheets/atoms/_a-completion-message.sass b/app/assets/stylesheets/atoms/_a-completion-message.sass new file mode 100644 index 00000000000..acde9251485 --- /dev/null +++ b/app/assets/stylesheets/atoms/_a-completion-message.sass @@ -0,0 +1,29 @@ +.a-completion-message + background-color: $info + +padding(vertical, .75rem) + &:not(:last-child) + margin-bottom: 1.25rem + +.a-completion-message__inner + +media-breakpoint-up(md) + display: flex + justify-content: center + align-items: center + +.a-completion-message__title + +text-block(1em 1.45, center $reversal-text 600) + +media-breakpoint-up(md) + font-size: 1rem + +media-breakpoint-down(sm) + font-size: .8125rem + +.a-completion-message__actions-item + +media-breakpoint-up(md) + width: 10rem + +media-breakpoint-down(sm) + +.a-completion-message__inner-end + +media-breakpoint-up(md) + margin-left: 1rem + +media-breakpoint-down(sm) + margin-top: .75rem diff --git a/app/assets/stylesheets/blocks/card/_congrats-card-body.sass b/app/assets/stylesheets/blocks/card/_congrats-card-body.sass new file mode 100644 index 00000000000..83edf604e9d --- /dev/null +++ b/app/assets/stylesheets/blocks/card/_congrats-card-body.sass @@ -0,0 +1,22 @@ +.congrats-card-body__title + +text-block(1.5rem 1.5, 700) + +media-breakpoint-up(md) + font-size: 1.5rem + +media-breakpoint-down(sm) + font-size: 1rem + +.congrats-card-body__image-container + margin-top: 1.25rem + +.congrats-card-body__image-container + width: 100% + max-width: 28rem + +margin(horizontal, auto) + +.congrats-card-body__image + border-radius: .75rem + border: solid .5rem $background + +.congrats-card-body + .card-main-actions + margin-top: 1.25rem diff --git a/app/assets/stylesheets/blocks/page/_page-body.sass b/app/assets/stylesheets/blocks/page/_page-body.sass index 909f529b80d..e55e8121594 100644 --- a/app/assets/stylesheets/blocks/page/_page-body.sass +++ b/app/assets/stylesheets/blocks/page/_page-body.sass @@ -2,19 +2,21 @@ +padding(vertical, 1.5rem) +media-breakpoint-down(sm) +padding(vertical, 1.125rem) + .page-header + & + border-top: solid 1px $border-shade .page-body__inner position: relative .page-optional-header +padding(vertical, .875rem) - border-bottom: solid 1px $border-shade + border-bottom: solid 1px $border-more-shade .page-optional-header__title - +text-block(1em 1.4, center flex) + +text-block(1em 1.4, center 600 flex) align-items: center +media-breakpoint-up(md) - font-size: 1.25rem + font-size: 1.125rem +media-breakpoint-down(sm) font-size: 1rem diff --git a/app/assets/stylesheets/blocks/page/_page-tabs.sass b/app/assets/stylesheets/blocks/page/_page-tabs.sass index e0663a070bd..e2a1c3c4fd0 100644 --- a/app/assets/stylesheets/blocks/page/_page-tabs.sass +++ b/app/assets/stylesheets/blocks/page/_page-tabs.sass @@ -8,6 +8,11 @@ +media-breakpoint-down(sm) >.container +padding(horizontal, 0) + .page-header + & + border-top: solid 1px $border-more-shade + .page-tools &:last-child + border-bottom: none + .page-tabs__items display: flex diff --git a/app/assets/stylesheets/blocks/page/_page-tools.sass b/app/assets/stylesheets/blocks/page/_page-tools.sass new file mode 100644 index 00000000000..e8dd44c93dc --- /dev/null +++ b/app/assets/stylesheets/blocks/page/_page-tools.sass @@ -0,0 +1,5 @@ +.page-tools + .page-header + & + border-top: solid 1px $border-more-shade + & + .page-body + border-top: solid 1px $border-more-shade diff --git a/app/assets/stylesheets/blocks/practice/_completion-massage.sass b/app/assets/stylesheets/blocks/practice/_completion-massage.sass new file mode 100644 index 00000000000..fdf729b13f9 --- /dev/null +++ b/app/assets/stylesheets/blocks/practice/_completion-massage.sass @@ -0,0 +1,2 @@ +.completion-massage + background-color: $success diff --git a/app/assets/stylesheets/blocks/practice/_sticky-message.sass b/app/assets/stylesheets/blocks/practice/_sticky-message.sass index 342b4bf251e..c208fd1d952 100644 --- a/app/assets/stylesheets/blocks/practice/_sticky-message.sass +++ b/app/assets/stylesheets/blocks/practice/_sticky-message.sass @@ -4,7 +4,7 @@ width: 100% +position(sticky, left 0, bottom 0, 1) +padding(vertical, .5rem) - +text-block(1rem 1.4, center $reversal-text) + +text-block(.875rem 1.4, center $reversal-text) a +hover-link-reversal color: $reversal-text diff --git a/app/assets/stylesheets/blocks/shared/_modal.sass b/app/assets/stylesheets/blocks/shared/_modal.sass index 26edd77bde7..ee108a78b1a 100644 --- a/app/assets/stylesheets/blocks/shared/_modal.sass +++ b/app/assets/stylesheets/blocks/shared/_modal.sass @@ -14,11 +14,14 @@ font-size: .875rem .modal-header - padding: .25rem 1rem display: flex align-items: center justify-content: space-between border-bottom: solid 1px $background + +media-breakpoint-up(md) + padding: .25rem 1.5rem + +media-breakpoint-down(sm) + padding: .25rem 1rem .modal-header__close display: flex @@ -26,15 +29,18 @@ justify-content: center +size(2.75rem) cursor: pointer - margin-right: -.75rem - opacity: .7 + opacity: .4 transition: all .2s ease-out position: relative + +media-breakpoint-up(md) + margin-right: -1.5rem + +media-breakpoint-down(sm) + margin-right: -1rem &::before, &::after content: "" display: block - +size(50% 2px) + +size(40% 2px) background-color: $default-text +position(absolute, left 50%, top 50%) border-radius: 2px @@ -60,12 +66,21 @@ .modal-body max-height: calc(100vh - 11.5rem) overflow: auto - padding: 1rem border-bottom: solid 1px $background + +media-breakpoint-up(md) + padding: 1rem 1.5rem + +media-breakpoint-down(sm) + padding: 1rem .modal-title - font-size: 1.25rem font-weight: 600 + +media-breakpoint-up(md) + font-size: 1.25rem + +media-breakpoint-down(sm) + font-size: 1rem .modal-footer - padding: .25rem 1rem + +media-breakpoint-up(md) + padding: .25rem 1.5rem + +media-breakpoint-down(sm) + padding: .25rem 1rem diff --git a/app/assets/stylesheets/blocks/shared/_sort-nav.sass b/app/assets/stylesheets/blocks/shared/_sort-nav.sass index 2ce78d2e2cc..6bdb4e19220 100644 --- a/app/assets/stylesheets/blocks/shared/_sort-nav.sass +++ b/app/assets/stylesheets/blocks/shared/_sort-nav.sass @@ -12,7 +12,7 @@ flex-direction: column .sort-nav__label - +text-block(.8125rem 1.45) + +text-block(.75rem 1.4) margin-right: .5rem white-space: nowrap +media-breakpoint-down(sm) diff --git a/app/assets/stylesheets/blocks/thread/_thread-list-item-meta.sass b/app/assets/stylesheets/blocks/thread/_thread-list-item-meta.sass index b205355d1cf..f915a0b9a9c 100644 --- a/app/assets/stylesheets/blocks/thread/_thread-list-item-meta.sass +++ b/app/assets/stylesheets/blocks/thread/_thread-list-item-meta.sass @@ -2,6 +2,8 @@ .a-user-name, .a-meta font-size: .75rem + .thread-list-item-title + & + margin-top: .25em .thread-list-item-meta__items +text-block(.75rem 1.4) diff --git a/app/assets/stylesheets/completion.sass b/app/assets/stylesheets/completion.sass new file mode 100644 index 00000000000..0ec9f86a5bd --- /dev/null +++ b/app/assets/stylesheets/completion.sass @@ -0,0 +1,4 @@ +@import common-imports +@import blocks/shared/flash +@import blocks/shared/modal +@import completion/**/* diff --git a/app/assets/stylesheets/completion/_completion-base.sass b/app/assets/stylesheets/completion/_completion-base.sass new file mode 100644 index 00000000000..6ed3f62a0a4 --- /dev/null +++ b/app/assets/stylesheets/completion/_completion-base.sass @@ -0,0 +1,80 @@ +$completion: #00a0dd + +body.is-completion + background-color: $completion + +.completion-wrapper + min-height: 100vh + display: flex + flex-direction: column + &::before + content: '' + background-image: image_url('completion/completion_background.svg') + background-repeat: repeat + +position(fixed, left 0, top 0, right 0, bottom 0, 1) + +size(100%) + opacity: .075 + +media-breakpoint-up(md) + background-size: 16rem auto + +.completion-wrapper__start + flex: 1 + +position(relative, 2) + +.completion-wrapper__end + +position(relative, 2) + +.complestion + +padding(vertical, 4rem 2rem) + +.complestion__title + +text-block(2rem 1.5, 800 center $reversal-text) + font-family: YakuHanJP_Narrow,Hiragino Sans,Hiragino Kaku Gothic ProN,BIZ UDPGothic,Meiryo,sans-serif + +.complestion__body + margin-top: 3rem + +.complestion__image + border-radius: 1rem + border: solid .75rem shade($completion, 30%) + +.welcome-footer + +media-breakpoint-up(md) + +padding(vertical, 3rem) + +media-breakpoint-down(sm) + padding-bottom: 1.5rem + body.welcome & .container + +padding(horizontal, 0) + +.welcome-footer__nav + margin-bottom: 1.5rem + +.welcome-footer__nav-items + +media-breakpoint-up(md) + display: flex + justify-content: center + +.welcome-footer__nav-item + +media-breakpoint-up(md) + +padding(horizontal, .5rem) + +.welcome-footer__nav-item-link + +text-block(.875rem 1, $reversal-text) + +media-breakpoint-up(md) + +hover-link + +media-breakpoint-down(sm) + text-decoration: none + display: flex + align-items: center + +padding(horizontal, 1rem) + border-bottom: solid 1px $border + +size(100% 2.75rem) + +.welcome-footer-copyright + justify-content: center + align-items: center + +text-block(.875rem 1.45, flex $reversal-text) + +.welcome-footer-copyright__author + display: block + +margin(horizontal, .1em .5em) diff --git a/app/controllers/api/practices/learning/completion_message_controller.rb b/app/controllers/api/practices/learning/completion_message_controller.rb new file mode 100644 index 00000000000..b4313a6fe00 --- /dev/null +++ b/app/controllers/api/practices/learning/completion_message_controller.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class API::Practices::Learning::CompletionMessageController < API::BaseController + def update + learning = current_user.learnings.find_by(practice_id: params[:practice_id]) + if learning.update(completion_message_displayed: true) + head :ok + else + head :bad_request + end + end +end diff --git a/app/controllers/practices/completion_controller.rb b/app/controllers/practices/completion_controller.rb new file mode 100644 index 00000000000..602074192ef --- /dev/null +++ b/app/controllers/practices/completion_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class Practices::CompletionController < ApplicationController + layout 'completion' + + def show + @practice = Practice.find(params[:practice_id]) + end +end diff --git a/app/controllers/practices_controller.rb b/app/controllers/practices_controller.rb index d537ea0110f..2d3744e7f54 100644 --- a/app/controllers/practices_controller.rb +++ b/app/controllers/practices_controller.rb @@ -9,6 +9,7 @@ class PracticesController < ApplicationController def show @categories = @practice.categories + @tweet_url = @practice.tweet_url(practice_completion_url(@practice.id)) end def new @@ -47,6 +48,7 @@ def practice_params :submission, :open_product, :include_progress, + :ogp_image, :memo, category_ids: [], reference_books_attributes: %i[id title price page_url must_read cover description _destroy] diff --git a/app/controllers/products_controller.rb b/app/controllers/products_controller.rb index 575e10a760e..320cb2b3249 100644 --- a/app/controllers/products_controller.rb +++ b/app/controllers/products_controller.rb @@ -16,7 +16,9 @@ def show .includes(:comments, :checks) .order(reported_on: :DESC) @practice = find_practice + @learning = @product.learning # decoratorメソッド用にcontrollerでインスタンス変数化 @footprints = find_footprints + @tweet_url = @practice.tweet_url(practice_completion_url(@practice.id)) footprint! respond_to do |format| format.html diff --git a/app/decorators/learning_decorator.rb b/app/decorators/learning_decorator.rb new file mode 100644 index 00000000000..8a443ab5e7b --- /dev/null +++ b/app/decorators/learning_decorator.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module LearningDecorator + def should_display_message_automatically?(current_user:) + user == current_user && complete? && !completion_message_displayed? + end +end diff --git a/app/javascript/learning-completion-message.js b/app/javascript/learning-completion-message.js new file mode 100644 index 00000000000..417c3dade34 --- /dev/null +++ b/app/javascript/learning-completion-message.js @@ -0,0 +1,35 @@ +document.addEventListener('DOMContentLoaded', () => { + const modal = document.querySelector('#modal-learning_completion') + if (!modal) { + return null + } + + const datasetNode = document.querySelector('#modal-learning_completion-data') + + if (datasetNode.dataset.shouldDisplayMessageAutomatically === 'true') { + modal.checked = true + } + + modal.addEventListener('change', () => { + if (!modal.checked) { + const practiceId = datasetNode.dataset.practiceId + fetch(`/api/practices/${practiceId}/learning/completion_message`, { + method: 'PATCH', + headers: { + 'Content-Type': 'application/json; charset=utf-8', + 'X-Requested-With': 'XMLHttpRequest', + 'X-CSRF-Token': token() + }, + credentials: 'same-origin', + redirect: 'manual' + }).catch((error) => { + console.warn('Failed to parsing', error) + }) + } + }) + + function token() { + const meta = document.querySelector('meta[name="csrf-token"]') + return meta ? meta.getAttribute('content') : '' + } +}) diff --git a/app/javascript/learning.vue b/app/javascript/learning.vue index 81dec462e19..1a8aba44371 100644 --- a/app/javascript/learning.vue +++ b/app/javascript/learning.vue @@ -10,8 +10,9 @@ i.fas.fa-check | 完了しています li.card-main-actions__item(v-else) - button#js-complete.a-button.is-md.is-warning.is-block( - @click='pushComplete' + label#js-complete.a-button.is-md.is-warning.is-block( + @click='pushComplete', + for='modal-learning_completion' ) i.fas.fa-check | 完了 diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 98d2ae9c213..02d0d2b20ad 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -67,3 +67,4 @@ import '../talks.js' import '../admin_companies.js' import '../company-users.js' import '../generation-users.js' +import '../learning-completion-message.js' diff --git a/app/models/practice.rb b/app/models/practice.rb index 9869746d1c4..e962ed0861f 100644 --- a/app/models/practice.rb +++ b/app/models/practice.rb @@ -35,6 +35,7 @@ class Practice < ApplicationRecord has_many :categories_practices, dependent: :destroy has_many :categories, through: :categories_practices has_many :reference_books, inverse_of: :practice, dependent: :destroy + has_one_attached :ogp_image accepts_nested_attributes_for :reference_books, reject_if: :all_blank, allow_destroy: true validates :title, presence: true @@ -149,6 +150,13 @@ def category(course) Category.category(practice: self, course: course) || categories.first || Category.first end + def tweet_url(practice_completion_url) + completion_text = "プラクティス「#{title}」を修了しました🎉" + # ref: https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/guides/web-intent + tweet_param = URI.encode_www_form(text: completion_text, url: practice_completion_url, hashtags: 'fjordbootcamp') + "https://twitter.com/intent/tweet?#{tweet_param}" + end + private def total_learning_minute(report) diff --git a/app/models/product.rb b/app/models/product.rb index 71134c713fe..a2b10f2dbe5 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -142,6 +142,14 @@ def change_learning_status(status) learning.update(status: status) end + # nilの場合あり + def learning + Learning.find_by( + user_id: user.id, + practice_id: practice.id + ) + end + def last_commented_user Rails.cache.fetch "/model/product/#{id}/last_commented_user" do commented_users.last diff --git a/app/views/application/_header.html.slim b/app/views/application/_header.html.slim index e27e134480a..ad7d1724209 100644 --- a/app/views/application/_header.html.slim +++ b/app/views/application/_header.html.slim @@ -31,7 +31,7 @@ header.header #js-notifications-mobile -= render '/shared/modal', id: 'modal-mentor-mode', title: 'メンターモードとは?' += render '/shared/modal', id: 'modal-mentor-mode', modal_title: 'メンターモードとは?' .modal__description.is-md .a-short-text p diff --git a/app/views/application/_header_links.html.slim b/app/views/application/_header_links.html.slim index 4d90b295a8d..78ab9030847 100644 --- a/app/views/application/_header_links.html.slim +++ b/app/views/application/_header_links.html.slim @@ -33,6 +33,6 @@ .header-links__link-label Menu #js-notifications-bell -= render '/shared/modal', id: 'header-search', title: '検索' += render '/shared/modal', id: 'header-search', modal_title: '検索' .modal__description.is-md = render 'header_search', select_id: 'header-search-select-modal', text_field_id: 'header-search-word-modal', submit_id: 'test-search-modal' diff --git a/app/views/courses/practices/index.html.slim b/app/views/courses/practices/index.html.slim index 76a25c3eebd..3f7722c1894 100644 --- a/app/views/courses/practices/index.html.slim +++ b/app/views/courses/practices/index.html.slim @@ -1,6 +1,6 @@ - title "#{@course.title}コース" -= render '/shared/modal', id: 'modal-progress', title: 'みんなの進捗とは?' += render '/shared/modal', id: 'modal-progress', modal_title: 'みんなの進捗とは?' .modal__description.is-md .a-short-text p diff --git a/app/views/current_user/reports/index.html.slim b/app/views/current_user/reports/index.html.slim index 378ab0476f1..68461513b4a 100644 --- a/app/views/current_user/reports/index.html.slim +++ b/app/views/current_user/reports/index.html.slim @@ -11,7 +11,8 @@ header.page-header i.fas.fa-plus | 日報作成 -= render 'home/page_tabs', user: @user +.page-tools + = render 'home/page_tabs', user: @user .page-body .container.is-md diff --git a/app/views/current_user/watches/index.html.slim b/app/views/current_user/watches/index.html.slim index c63157235ea..4ceedb44c3b 100644 --- a/app/views/current_user/watches/index.html.slim +++ b/app/views/current_user/watches/index.html.slim @@ -5,7 +5,8 @@ header.page-header h2.page-header__title | ダッシュボード -= render 'home/page_tabs', user: @user +.page-tools + = render 'home/page_tabs', user: @user .page-body - if @watches.present? diff --git a/app/views/home/index.html.slim b/app/views/home/index.html.slim index 2524be89099..2d9ae5e2306 100644 --- a/app/views/home/index.html.slim +++ b/app/views/home/index.html.slim @@ -15,7 +15,8 @@ header.page-header i.fas.fa-plus | 日報作成 -= render 'page_tabs', user: current_user +.page-tools + = render 'page_tabs', user: current_user .page-body - if @events_coming_soon.present? && current_user.job_seeker diff --git a/app/views/layouts/completion.html.slim b/app/views/layouts/completion.html.slim new file mode 100644 index 00000000000..ba3364c4bca --- /dev/null +++ b/app/views/layouts/completion.html.slim @@ -0,0 +1,28 @@ +doctype html +html.is-application lang='ja' + head + = render 'google_tag_manager_head' + meta content='IE=edge' http-equiv='X-UA-Compatible' + meta name='robots' content='noindex' + = display_meta_tags default_meta_tags + = javascript_include_tag 'application' + = javascript_pack_tag 'application' + = csrf_meta_tags + = render 'pwa' + = render 'favicons' + = render 'rollbar' if Rails.env.production? + link(rel='manifest' href='/manifest.json') + = stylesheet_link_tag 'completion', media: 'all' + link(rel='canonical' href='https://bootcamp.fjord.jp/') + = stylesheet_link_tag 'https://cdn.jsdelivr.net/npm/yakuhanjp@3.2.0/dist/css/yakuhanjp-narrow.min.css', media: 'all' + = render '/head/fontawsome' + = content_for(:head_last) if content_for?(:head_last) + body.is-completion + = render 'google_tag_manager_body' + = render 'flash' + .completion-wrapper + .completion-wrapper__start + .welcome-page + = yield + .completion-wrapper__end + = render 'welcome/welcome_footer' diff --git a/app/views/practices/_form.html.slim b/app/views/practices/_form.html.slim index f8046022505..05b6c808d98 100644 --- a/app/views/practices/_form.html.slim +++ b/app/views/practices/_form.html.slim @@ -73,6 +73,21 @@ label = f.check_box :include_progress | 進捗の計算に含むようにする場合はチェック + .form-item + .row.js-markdown-parent + .col-md-6.col-xs-12 + = f.label '完了おめでとう画像', class: 'a-form-label' + .form-item-file-input.js-file-input.a-file-input + label.js-file-input__preview(for='practice_ogp_image') + - if f.object.ogp_image.attached? + = image_tag f.object.ogp_image.variant(resize: '100x100') + p 画像を変更 + - else + p 画像を選択 + = f.file_field :ogp_image + .a-form-help + | 画像サイズ: 1200px × 630xp + .form-actions ul.form-actions__items li.form-actions__item.is-main diff --git a/app/views/practices/_page_header.html.slim b/app/views/practices/_page_header.html.slim new file mode 100644 index 00000000000..190e250390a --- /dev/null +++ b/app/views/practices/_page_header.html.slim @@ -0,0 +1,16 @@ +header.page-header + .container + .page-header__inner + h2.page-header__title + = title + .page-header-actions + ul.page-header-actions__items + - if current_user.admin? + li.page-header-actions__item.is-hidden-sm-down.is-only-mentor + = link_to new_practice_path, class: 'a-button is-md is-secondary is-block' do + i.fas.fa-plus + | プラクティス作成 + li.page-header-actions__item + = link_to course_practices_path(current_user.course, anchor: "category-#{category.id}"), + class: 'a-button is-md is-secondary is-block is-back' do + | プラクティス一覧 diff --git a/app/views/practices/_practice_content_notice.html.slim b/app/views/practices/_practice_content_notice.html.slim new file mode 100644 index 00000000000..57f247ebd56 --- /dev/null +++ b/app/views/practices/_practice_content_notice.html.slim @@ -0,0 +1,6 @@ +.practice-content__body-notice + p + | このプラクティスは、OKをもらっていなくても他の人の提出物を閲覧できます。 + = link_to practice_products_path(@practice) do + | 他の人の提出物 + | も参考にしてください。 diff --git a/app/views/practices/completion/show.html.slim b/app/views/practices/completion/show.html.slim new file mode 100644 index 00000000000..1ae006852e3 --- /dev/null +++ b/app/views/practices/completion/show.html.slim @@ -0,0 +1,24 @@ +- title @practice.title +- if @practice.ogp_image.attached? + - set_meta_tags(og: { image: polymorphic_url(@practice.ogp_image), url: request.url }) + - set_meta_tags(twitter: { image: polymorphic_url(@practice.ogp_image), url: request.url }) +- else + - set_meta_tags(og: { image: image_url('completion/completion_default.png'), url: request.url }) + - set_meta_tags(twitter: { image: image_url('completion/completion_default.png'), url: request.url }) + +.page-body + .complestion + .complestion__header + .container + h1.complestion__title + | おめでとうございます!! + br + | 「#{@practice.title}」を + br + | 修了しました🎉 + .complestion__body + .container.is-md + - if @practice.ogp_image.attached? + = image_tag @practice.ogp_image, class: 'complestion__image', alt: "#{@practice.title}修了おめでとうカード" + - else + = image_tag('completion/completion_default.png', class: 'complestion__image', alt: "#{@practice.title}修了おめでとうカード") diff --git a/app/views/practices/pages/index.html.slim b/app/views/practices/pages/index.html.slim index 7722fb6a31c..607e49e827d 100644 --- a/app/views/practices/pages/index.html.slim +++ b/app/views/practices/pages/index.html.slim @@ -1,18 +1,7 @@ - title @practice.title - category = @practice.category(current_user.course) -header.page-header - .container - .page-header__inner - h1.page-header__title - = title - .page-header-actions - ul.page-header-actions__items - li.page-header-actions__item - = link_to course_practices_path(current_user.course, anchor: "category-#{category.id}"), - class: 'a-button is-md is-secondary is-block is-back' do - | プラクティス一覧 - += render '/practices/page_header', title: title, category: category = render 'page_tabs', resource: @practice .page-body diff --git a/app/views/practices/products/index.html.slim b/app/views/practices/products/index.html.slim index c35232d531f..d21ecbc1311 100644 --- a/app/views/practices/products/index.html.slim +++ b/app/views/practices/products/index.html.slim @@ -1,26 +1,21 @@ - title @practice.title - category = @practice.category(current_user.course) -header.page-header - .container - .page-header__inner - h2.page-header__title - = title - .page-header-actions - ul.page-header-actions__items - li.page-header-actions__item - = link_to course_practices_path(current_user.course, anchor: "category-#{category.id}"), - class: 'a-button is-md is-secondary is-block is-back' do - | プラクティス一覧 - += render '/practices/page_header', title: title, category: category = render 'page_tabs', resource: @practice .page-body - - if current_user.student_or_trainee? && !@practice.open_product? && (@my_product.nil? || @my_product.checks.empty?) - .a-page-notice - .container - .a-page-notice__inner - p プラクティスを完了するまで他の人の提出物は見れません。 + - if current_user.student_or_trainee? + - if @practice.open_product? + .a-page-notice + .container + .a-page-notice__inner + p このプラクティスは、OKをもらっていなくても他の人の提出物を閲覧できます。 + - elsif @my_product.nil? || @my_product.checks.empty? + .a-page-notice + .container + .a-page-notice__inner + p プラクティスを完了するまで他の人の提出物は見れません。 .container.is-md = paginate @products - if @products.present? diff --git a/app/views/practices/questions/index.html.slim b/app/views/practices/questions/index.html.slim index 5e33857ed9b..c2aba9832f6 100644 --- a/app/views/practices/questions/index.html.slim +++ b/app/views/practices/questions/index.html.slim @@ -1,18 +1,7 @@ - title @practice.title - category = @practice.category(current_user.course) -header.page-header - .container - .page-header__inner - h2.page-header__title - = title - .page-header-actions - ul.page-header-actions__items - li.page-header-actions__item - = link_to course_practices_path(current_user.course, anchor: "category-#{category.id}"), - class: 'a-button is-md is-secondary is-block is-back' do - | プラクティス一覧 - += render '/practices/page_header', title: title, category: category = render 'page_tabs', resource: @practice nav.tab-nav diff --git a/app/views/practices/reports/index.html.slim b/app/views/practices/reports/index.html.slim index 50da1d23f4e..8502e574396 100644 --- a/app/views/practices/reports/index.html.slim +++ b/app/views/practices/reports/index.html.slim @@ -1,18 +1,7 @@ - title @practice.title - category = @practice.category(current_user.course) -header.page-header - .container - .page-header__inner - h2.page-header__title - = title - .page-header-actions - ul.page-header-actions__items - li.page-header-actions__item - = link_to course_practices_path(current_user.course, anchor: "category-#{category.id}"), - class: 'a-button is-md is-secondary is-block is-back' do - | プラクティス一覧 - += render '/practices/page_header', title: title, category: category = render 'page_tabs', resource: @practice .page-body diff --git a/app/views/practices/show.html.slim b/app/views/practices/show.html.slim index c3cc6c979f1..f1bad103314 100644 --- a/app/views/practices/show.html.slim +++ b/app/views/practices/show.html.slim @@ -1,21 +1,15 @@ - title @practice.title - category = @practice.category(current_user.course) -header.page-header - .container - .page-header__inner - .page-header__title - = @practice.title - .page-header-actions - ul.page-header-actions__items - li.page-header-actions__item - = link_to course_practices_path(current_user.course, anchor: "category-#{category.id}"), - class: 'a-button is-md is-secondary is-block is-back' do - | プラクティス一覧 - += render '/shared/modal_learning_completion', practice: @practice, tweet_url: @tweet_url, should_display_message_automatically: false += render '/practices/page_header', title: title, category: category = render 'page_tabs', resource: @practice .page-body + // + [TODO]完了Tweetの正式リリース後にコメントを外す + - if @practice.learning(current_user)&.complete? + = render '/products/completion_message', practice: @practice .container.is-xl .practice-contents .practice-contents__inner @@ -119,12 +113,7 @@ header.page-header .js-markdown-view.js-target-blank.is-long-text = @practice.goal - if !current_user.adviser? && @practice.open_product? - .practice-content__body-notice - p - | このプラクティスは、OKをもらっていなくても他の人の提出物を閲覧できます。 - = link_to practice_products_path(@practice) do - | 他の人の提出物 - | も参考にしてください。 + = render '/practices/practice_content_notice' footer.card-footer #js-learning(data-practice-id="#{@practice.id}") - if @practice.submission diff --git a/app/views/products/_completion_message.html.slim b/app/views/products/_completion_message.html.slim new file mode 100644 index 00000000000..f2096dfe191 --- /dev/null +++ b/app/views/products/_completion_message.html.slim @@ -0,0 +1,14 @@ +.a-completion-message + .container + .a-completion-message__inner + .a-completion-message__inner-start + h2.a-completion-message__title + | 「#{practice.title}」を + br + | 修了しました🎉 + .a-completion-message__inner-end + .a-completion-message__actions + .a-completion-message__actions-items + .a-completion-message__actions-item + label.a-button.is-sm.is-secondary.is-block.is-tweet(for='modal-learning_completion') + | 完了 Tweet する diff --git a/app/views/products/show.html.slim b/app/views/products/show.html.slim index 19d308c9a9e..d9fdd8cba63 100644 --- a/app/views/products/show.html.slim +++ b/app/views/products/show.html.slim @@ -1,11 +1,16 @@ - title "#{@product.practice.title}の提出物" - category = @product.category(current_user.course) += render '/shared/modal_learning_completion', + practice: @product.practice, + tweet_url: @tweet_url, + should_display_message_automatically: @learning&.should_display_message_automatically?(current_user: current_user) + header.page-header .container .page-header__inner h1.page-header__title - = "#{@product.user.login_name}の提出物" + = title .page-header-actions ul.page-header-actions__items li.page-header-actions__item @@ -20,12 +25,6 @@ header.page-header = render 'page_tabs', resource: @product.practice .page-body - - if !current_user.adviser? && @product.practice.open_product? - .a-page-notice.page-notice - .container - .a-page-notice__inner - p - | このプラクティスは、OKをもらっていなくても他の人の提出物を閲覧できます。 - if @product.user == current_user && !@product.wip? && !@product.checked? && @product.commented_users.mentor.empty? .a-page-alert .container.is-md @@ -35,6 +34,11 @@ header.page-header | 7日以内にメンターがレビューしますので、次のプラクティスにお進みください。 br | もし、7日以上経ってもレビューされない場合は、メンターにお問い合わせください。 + // + [TODO]完了Tweetの正式リリース後にコメントを外す + - if @product.user == current_user && @learning&.complete? + = render 'completion_message', practice: @product.practice + .container.is-xxxl div(class="#{current_user.mentor? || current_user.admin? ? 'row is-jc:c' : ''}") div(class="#{current_user.mentor? || current_user.admin? ? 'col-xl-7 col-xs-12' : ''}") @@ -110,6 +114,7 @@ header.page-header .thread__description.js-target-blank.is-long-text.js-markdown-view(data-taskable-id="#{@product.id}" data-taskable-type='Product' data-taskable="#{@product.taskable?(current_user).to_s}") = @product.body = render 'reactions/reactions', reactionable: @product + - if @product.user == current_user || admin_or_mentor_login? .card-footer .card-main-actions @@ -188,3 +193,9 @@ header.page-header = render 'users/user_secret_attributes', user: @product.user = render 'users/metas', user: @product.user #js-user-mentor-memo(data-user-id="#{@product.user.id}" data-products-mode="#{true}") + +- if !current_user.adviser? && @product.practice.open_product? + .sticky-message + .container + p + | このプラクティスは、OKをもらっていなくても他の人の提出物を閲覧できます。 diff --git a/app/views/questions/index.html.slim b/app/views/questions/index.html.slim index b2d6cb50599..be363f22f02 100644 --- a/app/views/questions/index.html.slim +++ b/app/views/questions/index.html.slim @@ -14,7 +14,7 @@ header.page-header nav.sort-nav .container.is-md .sort-nav__inner - = label_tag :practice_id, 'プラクティスで絞り込む:', class: 'sort-nav__label' + = label_tag :practice_id, 'プラクティスで絞り込む', class: 'sort-nav__label' .sort-nav__select #js-practice-select data-solved=params[:solved] data-current-user-id=current_user.id = render 'questions/tabs' diff --git a/app/views/reports/_form.html.slim b/app/views/reports/_form.html.slim index 91f47ec5178..73abb325ba0 100644 --- a/app/views/reports/_form.html.slim +++ b/app/views/reports/_form.html.slim @@ -100,7 +100,7 @@ - when 'edit', 'update' = link_to 'キャンセル', report_path, class: 'a-button is-md is-secondary is-block' -= render '/shared/modal', id: 'modal-progress', title: '学習時間は無しとは?' += render '/shared/modal', id: 'modal-progress', modal_title: '学習時間は無しとは?' .modal__description.is-md .a-short-text p @@ -111,7 +111,7 @@ | 日報を書くということも文章を書くこと、アウトプットに慣れるための大事な学習です。 | なので、今この日報を書いている時間も学習時間に含めてしまって問題ないですよ。 -= render '/shared/modal', id: 'modal-wip', title: 'WIPとは?' += render '/shared/modal', id: 'modal-wip', modal_title: 'WIPとは?' .modal__description.is-md .a-short-text p diff --git a/app/views/reports/index.html.slim b/app/views/reports/index.html.slim index 9ed4ba22a08..b6336f1f155 100644 --- a/app/views/reports/index.html.slim +++ b/app/views/reports/index.html.slim @@ -12,7 +12,7 @@ header.page-header = form_tag reports_url, method: 'get' do .container.is-md .sort-nav__inner - = label_tag :practice_id, 'プラクティスで絞り込む:', class: 'sort-nav__label' + = label_tag :practice_id, 'プラクティスで絞り込む', class: 'sort-nav__label' .sort-nav__select = select_tag :practice_id, options_from_collection_for_select(current_user.practices, :id, :title, selected: params[:practice_id]), include_blank: '全ての日報を表示', onchange: 'this.form.submit()', class: 'js-select2' diff --git a/app/views/shared/_modal.html.slim b/app/views/shared/_modal.html.slim index dfde696d7cd..c0da8c4b489 100644 --- a/app/views/shared/_modal.html.slim +++ b/app/views/shared/_modal.html.slim @@ -2,9 +2,10 @@ input.a-toggle-checkbox(id="#{id}" type="checkbox") .modal label.modal__overlay(for="#{id}") .modal-content - .modal-header - h2.modal-title - = title - label.modal-header__close(for="#{id}") + - if defined?(modal_title) + .modal-header + h2.modal-title + = modal_title + label.modal-header__close(for="#{id}") .modal-body = yield diff --git a/app/views/shared/_modal_learning_completion.html.slim b/app/views/shared/_modal_learning_completion.html.slim new file mode 100644 index 00000000000..b4cdd68174b --- /dev/null +++ b/app/views/shared/_modal_learning_completion.html.slim @@ -0,0 +1,18 @@ +- id = 'modal-learning_completion' += render '/shared/modal', id: id + #modal-learning_completion-data(data-practice-id="#{practice.id}" data-should-display-message-automatically="#{should_display_message_automatically}") + .congrats-card-body + h2.congrats-card-body__title + | プラクティス「#{practice.title}」を修了しました🎉 + .congrats-card-body__image-container + - if practice.ogp_image.attached? + = image_tag @practice.ogp_image, class: 'congrats-card-body__image', alt: "#{practice.title}修了おめでとうカード" + - else + = image_tag('completion/completion_default.png', class: 'congrats-card-body__image', alt: "#{practice.title}修了おめでとうカード") + .card-main-actions + ul.card-main-actions__items + li.card-main-actions__item + = link_to '喜びを Tweet する!', tweet_url, class: 'a-button is-md is-primary is-block', target: '_blank', rel: 'noopener' + li.card-main-actions__item.is-sub + label.card-main-actions__delete(for="#{id}") + | 閉じる diff --git a/app/views/users/form/_os.html.slim b/app/views/users/form/_os.html.slim index a29141a1aa3..b75632b7698 100644 --- a/app/views/users/form/_os.html.slim +++ b/app/views/users/form/_os.html.slim @@ -42,7 +42,7 @@ | できない場合がありますのでご注意ください。 = render '/shared/modal', id: 'modal-mac', - title: '🍏 M1 Mac or Intel Mac? の調べ方' + modal_title: '🍏 M1 Mac or Intel Mac? の調べ方' .modal__description.is-md .a-short-text p @@ -62,7 +62,7 @@ alt: 'この Mac についてのポップアップウインドウのキャプチャ' = render '/shared/modal', id: 'modal-win', - title: 'Hyper-V対応の調べ方' + modal_title: 'Hyper-V対応の調べ方' .modal__description.is-md .a-short-text p スタートボタンの右にある検索欄に「タスクマネージャー」を入力してタスクマネージャーを立ち上げます。 diff --git a/app/views/users/form/_sns.html.slim b/app/views/users/form/_sns.html.slim index 1c4bcf4a15f..cae6fc23d60 100644 --- a/app/views/users/form/_sns.html.slim +++ b/app/views/users/form/_sns.html.slim @@ -52,7 +52,7 @@ .a-form-help p URL を入力。 -= render '/shared/modal', id: 'modal-discord-account', title: 'Discord のアカウントの調べ方' += render '/shared/modal', id: 'modal-discord-account', modal_title: 'Discord のアカウントの調べ方' .modal__description.is-md .a-short-text p @@ -60,7 +60,7 @@ p = image_tag('help/discord-account.jpg', alt: 'Discord のアカウントの調べ方') -= render '/shared/modal', id: 'modal-times-url', title: '分報チャンネルの URL の調べ方' += render '/shared/modal', id: 'modal-times-url', modal_title: '分報チャンネルの URL の調べ方' .modal__description.is-md .a-short-text p diff --git a/app/views/users/form/_tags.html.slim b/app/views/users/form/_tags.html.slim index 51c296a736e..245e1e2e314 100644 --- a/app/views/users/form/_tags.html.slim +++ b/app/views/users/form/_tags.html.slim @@ -13,7 +13,7 @@ span.a-help i.fas.fa-question -= render '/shared/modal', id: 'modal-user-tag', title: '🔖 タグとは?' += render '/shared/modal', id: 'modal-user-tag', modal_title: '🔖 タグとは?' .modal__description.is-md .a-short-text p diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index d25af6a6543..782bc60cb8d 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -12,7 +12,7 @@ # application.js, application.css, and all non-JS/CSS in the app/assets # folder are already added. # Rails.application.config.assets.precompile += %w( admin.js admin.css ) -Rails.application.config.assets.precompile += %w( application.css welcome.css qrcodes.css ) +Rails.application.config.assets.precompile += %w( application.css welcome.css completion.css ) # Rubyが落ちるエラーがあり、原因としてSprocketsの関係で、assetsが並列でコンパイルされていることが考えられる。 # ソースは以下。 diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 16132048400..98dc29a6136 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -95,6 +95,7 @@ ja: target: ターゲット submission: 提出物 progress: 進捗の計算 + ogp_image: OGP画像 categories: カテゴリー memo: メンター向けメモ practice/reference_books: diff --git a/config/routes.rb b/config/routes.rb index 98fa00e6a0b..1330b2db0ec 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -44,6 +44,7 @@ resources :questions, only: %i(index), controller: "practices/questions" resources :products, only: %i(index), controller: "practices/products" resources :pages, only: %i(index), controller: "practices/pages" + resource :completion, only: %i(show), controller: "practices/completion" end resources :pages, param: :slug_or_id resources :notifications, only: %i(index show) do diff --git a/config/routes/api.rb b/config/routes/api.rb index faf3502c41d..dc335018c9b 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -34,7 +34,9 @@ resources :user_icon_urls, only: %i(index) get "users/tags/:tag", to: "users#index", as: :users_tag, tag: /.+/ resources :practices, only: %i(index show update) do - resource :learning, only: %i(show update), controller: "practices/learning" + resource :learning, only: %i(show update), controller: "practices/learning" do + resource :completion_message, only: %i(update), controller: "practices/learning/completion_message" + end end resources :reports, only: %i(index) namespace "reports" do diff --git a/db/data/20210927124918_add_completion_message_displayed_to_learnings.rb b/db/data/20210927124918_add_completion_message_displayed_to_learnings.rb new file mode 100644 index 00000000000..2d4711325b0 --- /dev/null +++ b/db/data/20210927124918_add_completion_message_displayed_to_learnings.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class AddCompletionMessageDisplayedToLearnings < ActiveRecord::Migration[6.1] + def up + Learning.complete.update_all(completion_message_displayed: true) # rubocop:disable Rails/SkipsModelValidations + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/fixtures/learnings.yml b/db/fixtures/learnings.yml index 9bfaddd1a38..80b9b9e6305 100644 --- a/db/fixtures/learnings.yml +++ b/db/fixtures/learnings.yml @@ -3,41 +3,49 @@ learning1: user: komagata practice: practice1 status: "started" + completion_message_displayed: false learning2: user: komagata practice: practice2 status: "complete" + completion_message_displayed: true learning3: user: komagata practice: practice3 status: "unstarted" + completion_message_displayed: false learning4: user: machida practice: practice2 status: "complete" + completion_message_displayed: true learning5: user: sotugyou practice: practice2 status: "complete" + completion_message_displayed: true learning6: user: kimura practice: practice1 status: "complete" + completion_message_displayed: true learning7: user: komagata practice: practice4 status: "submitted" + completion_message_displayed: false learning8: user: machida practice: practice5 status: "complete" + completion_message_displayed: true created_at: "2020-04-12 14:05:53.782503" updated_at: "2020-04-12 14:05:53.782503" @@ -47,6 +55,7 @@ learning9: status: "complete" created_at: "2020-04-10 14:05:53.782503" updated_at: "2020-04-10 14:05:53.782503" + completion_message_displayed: true learning10: user: machida @@ -54,6 +63,7 @@ learning10: status: "complete" created_at: "2020-04-19 14:05:53.782503" updated_at: "2020-04-19 14:05:53.782503" + completion_message_displayed: true learning11: user: machida @@ -61,29 +71,46 @@ learning11: status: "complete" created_at: "2020-04-22 14:05:53.782503" updated_at: "2020-04-22 14:05:53.782503" + completion_message_displayed: true learning12: user: hajime practice: practice1 status: "started" + completion_message_displayed: false learning13: user: kananashi practice: practice3 status: "started" + completion_message_displayed: false learning14: user: hajime practice: practice27 status: "complete" + completion_message_displayed: true learning15: user: hajime practice: practice48 status: "complete" + completion_message_displayed: true + +learning16: + user: kimura + practice: practice6 + status: "complete" + completion_message_displayed: false + +learning17: + user: sotugyou + practice: practice3 + status: "submitted" + completion_message_displayed: false <% (0..4).each do |i| %> -learning<%= i + 16 %>: +learning<%= i + 18 %>: user: <%= [:akiyosi, :fujiyasu, :jobseeker, :muryou, :nippounashi][i] %> practice: practice1 status: "complete" diff --git a/db/fixtures/products.yml b/db/fixtures/products.yml index 5af7e9c9316..8e4cb3c9bda 100644 --- a/db/fixtures/products.yml +++ b/db/fixtures/products.yml @@ -119,3 +119,8 @@ product62: user: take8 body: テストの提出物62です。 published_at: <%= (now - 60 * 60 * 24 * 10).to_s(:db) %> + +product63: + practice: practice6 + user: kimura + body: プラクティス完了メッセージ未表示の提出物です。 diff --git a/db/migrate/20210922124824_add_completion_message_displayed_to_learnings.rb b/db/migrate/20210922124824_add_completion_message_displayed_to_learnings.rb new file mode 100644 index 00000000000..1322ee97fbb --- /dev/null +++ b/db/migrate/20210922124824_add_completion_message_displayed_to_learnings.rb @@ -0,0 +1,5 @@ +class AddCompletionMessageDisplayedToLearnings < ActiveRecord::Migration[6.1] + def change + add_column :learnings, :completion_message_displayed, :boolean, null: false, default: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 51778a560cf..f6c0351673f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -242,6 +242,7 @@ t.integer "status", default: 0, null: false t.datetime "created_at" t.datetime "updated_at" + t.boolean "completion_message_displayed", default: false, null: false t.index ["user_id", "practice_id"], name: "index_learnings_on_user_id_and_practice_id", unique: true t.index ["user_id", "status"], name: "index_learnings_on_user_id_and_status" end diff --git a/test/fixtures/files/practices/ogp_images/1.jpg b/test/fixtures/files/practices/ogp_images/1.jpg new file mode 100644 index 00000000000..ee2f8a23192 Binary files /dev/null and b/test/fixtures/files/practices/ogp_images/1.jpg differ diff --git a/test/fixtures/learnings.yml b/test/fixtures/learnings.yml index 90601c82ca5..c28a6875ef5 100644 --- a/test/fixtures/learnings.yml +++ b/test/fixtures/learnings.yml @@ -3,41 +3,49 @@ learning1: user: komagata practice: practice1 status: "started" + completion_message_displayed: false learning2: user: komagata practice: practice2 status: "complete" + completion_message_displayed: true learning3: user: komagata practice: practice3 status: "unstarted" + completion_message_displayed: false learning4: user: machida practice: practice2 status: "complete" + completion_message_displayed: true learning5: user: sotugyou practice: practice2 status: "complete" + completion_message_displayed: true learning6: user: kimura practice: practice1 status: "complete" + completion_message_displayed: true learning7: user: komagata practice: practice4 status: "submitted" + completion_message_displayed: false learning8: user: machida practice: practice5 status: "complete" + completion_message_displayed: true created_at: "2020-04-12 14:05:53.782503" updated_at: "2020-04-12 14:05:53.782503" @@ -45,6 +53,7 @@ learning9: user: machida practice: practice6 status: "complete" + completion_message_displayed: true created_at: "2020-04-10 14:05:53.782503" updated_at: "2020-04-10 14:05:53.782503" @@ -52,6 +61,7 @@ learning10: user: machida practice: practice7 status: "complete" + completion_message_displayed: true created_at: "2020-04-19 14:05:53.782503" updated_at: "2020-04-19 14:05:53.782503" @@ -59,6 +69,7 @@ learning11: user: machida practice: practice8 status: "complete" + completion_message_displayed: true created_at: "2020-04-22 14:05:53.782503" updated_at: "2020-04-22 14:05:53.782503" @@ -66,24 +77,40 @@ learning12: user: hajime practice: practice1 status: "started" + completion_message_displayed: false learning13: user: kananashi practice: practice3 status: "started" + completion_message_displayed: false learning14: user: hajime practice: practice27 status: "complete" + completion_message_displayed: true learning15: user: hajime practice: practice48 status: "complete" + completion_message_displayed: true + +learning16: + user: kimura + practice: practice6 + status: "complete" + completion_message_displayed: false + +learning17: + user: sotugyou + practice: practice3 + status: "submitted" + completion_message_displayed: false <% (0..1).each do |i| %> -learning<%= i + 16 %>: +learning<%= i + 18 %>: user: <%= [:jobseeker, :muryou][i] %> practice: practice1 status: "complete" diff --git a/test/fixtures/products.yml b/test/fixtures/products.yml index 56d7e60c9ed..a39417eda64 100644 --- a/test/fixtures/products.yml +++ b/test/fixtures/products.yml @@ -370,3 +370,8 @@ product64: user: kimura body: 担当者のいる提出物です。 checker_id: "<%= ActiveRecord::FixtureSet.identify(:machida) %>" + +product65: + practice: practice6 + user: kimura + body: プラクティス完了メッセージ未表示の提出物です。 diff --git a/test/system/practice/completion_test.rb b/test/system/practice/completion_test.rb new file mode 100644 index 00000000000..c0c035b914a --- /dev/null +++ b/test/system/practice/completion_test.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'application_system_test_case' + +class Practice::CompletionTest < ApplicationSystemTestCase + test 'not logging-in user can access show' do + visit "/practices/#{practices(:practice1).id}/completion" + assert_text '「OS X Mountain Lionをクリーンインストールする」' + end + + test 'ogp image is displayed' do + practice = practices(:practice1) + visit_with_auth "/practices/#{practice.id}/edit", 'komagata' + attach_file 'practice[ogp_image]', 'test/fixtures/files/practices/ogp_images/1.jpg', make_visible: true + click_button '更新する' + + visit "/practices/#{practice.id}/completion" + assert_selector 'img' + end +end diff --git a/test/system/practices_test.rb b/test/system/practices_test.rb index 862473e02ac..8044dea4e40 100644 --- a/test/system/practices_test.rb +++ b/test/system/practices_test.rb @@ -34,6 +34,29 @@ class PracticesTest < ApplicationSystemTestCase assert_no_link '提出物を作る' end + # [TODO]完了Tweetの正式リリース後にコメントを外す + # test 'complete and tweet' do + # visit_with_auth "/practices/#{practices(:practice2).id}", 'kimura' + # find('#js-complete').click + # assert_text '喜びを Tweet する!' + + # click_link '喜びを Tweet する!' + # switch_to_window(windows.last) + # assert_includes current_url, 'https://twitter.com/intent/tweet' + # end + # + # test 'can see tweet button when current_user has completed a practice' do + # visit_with_auth "/practices/#{practices(:practice1).id}", 'kimura' + # assert_text '完了 Tweet する' + + # find(:label, '完了 Tweet する').click + # assert_text '喜びを Tweet する!' + + # click_link '喜びを Tweet する!' + # switch_to_window(windows.last) + # assert_includes current_url, 'https://twitter.com/intent/tweet' + # end + test "only show when user isn't admin " do visit_with_auth "/practices/#{practices(:practice1).id}/edit", 'yamada' assert_not_equal 'プラクティス編集', title @@ -130,6 +153,18 @@ class PracticesTest < ApplicationSystemTestCase click_button '更新する' end + test 'add ogp image' do + practice = practices(:practice1) + visit_with_auth "/practices/#{practice.id}/edit", 'komagata' + attach_file 'practice[ogp_image]', 'test/fixtures/files/practices/ogp_images/1.jpg', make_visible: true + click_button '更新する' + + visit_with_auth "/practices/#{practice.id}/edit", 'komagata' + within('form[name=practice]') do + assert_selector 'img' + end + end + test 'show setting for completed percentage' do visit_with_auth '/practices/new', 'komagata' assert_text '進捗の計算' diff --git a/test/system/product/unchecked_test.rb b/test/system/product/unchecked_test.rb index 76969c22caa..a3cd0865a40 100644 --- a/test/system/product/unchecked_test.rb +++ b/test/system/product/unchecked_test.rb @@ -86,6 +86,7 @@ class Product::UncheckedTest < ApplicationSystemTestCase click_button 'コメントする' visit_with_auth '/products/unchecked', 'komagata' wait_for_vuejs + click_link '自分の担当' assert_text product.practice.title end @@ -122,6 +123,7 @@ class Product::UncheckedTest < ApplicationSystemTestCase click_button 'コメントする' visit_with_auth '/products/unchecked?target=unchecked_all', 'komagata' wait_for_vuejs + click_link '自分の担当' assert_text product.practice.title end diff --git a/test/system/products_test.rb b/test/system/products_test.rb index 7201e52356f..abfc5a4fd3b 100644 --- a/test/system/products_test.rb +++ b/test/system/products_test.rb @@ -39,6 +39,46 @@ class ProductsTest < ApplicationSystemTestCase assert_text 'プラクティスを完了するまで他の人の提出物は見れません。' end + # [TODO]完了Tweetの正式リリース後にコメントを外す + # test 'can not see tweet button when current_user does not complete a practice' do + # visit_with_auth "/products/#{products(:product1).id}", 'yamada' + # assert_no_text '完了 Tweet する' + # end + + # test 'display learning completion message when a user of the completed product visits show first time' do + # visit_with_auth "/products/#{products(:product65).id}", 'kimura' + # assert_text '喜びを Tweet する!' + # end + + # test 'not display learning completion message when a user of the completed product visits after the second time' do + # visit_with_auth "/products/#{products(:product65).id}", 'kimura' + # find('label.card-main-actions__delete').click + # visit current_path + # assert_no_text '喜びを Tweet する!' + # end + + # test 'not display learning completion message when a user whom the product does not belongs to visits show' do + # visit_with_auth "/products/#{products(:product65).id}", 'yamada' + # assert_no_text '喜びを Tweet する!' + # end + + # test 'not display learning completion message when a user of the non-completed product visits show' do + # visit_with_auth "/products/#{products(:product6).id}", 'sotugyou' + # assert_no_text '喜びを Tweet する!' + # end + + # test 'can see tweet button when current_user has completed a practice' do + # visit_with_auth "/products/#{products(:product2).id}", 'kimura' + # assert_text '完了 Tweet する' + + # find('.a-button.is-tweet').click + # assert_text '喜びを Tweet する!' + + # click_link '喜びを Tweet する!' + # switch_to_window(windows.last) + # assert_includes current_url, 'https://twitter.com/intent/tweet' + # end + test 'create product' do visit_with_auth "/products/new?practice_id=#{practices(:practice6).id}", 'yamada' within('#new_product') do