Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

卒業証書のPDFファイルをアップロードできる機能を追加 #8190

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/controllers/admin/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def show
def edit; end

def update
@user.diploma_file = nil if params[:user][:remove_diploma] == '1'
if @user.update(user_params)
destroy_subscription(@user)
Newspaper.publish(:retirement_create, { user: @user }) if @user.saved_change_to_retired_on?
Expand Down Expand Up @@ -67,7 +68,7 @@ def user_params
:job_seeker, :github_collaborator,
:officekey_permission, :tag_list, :training_ends_on,
:auto_retire, :invoice_payment, :hide_mentor_profile,
:profile_image, :profile_name, :profile_job, :mentor,
:profile_image, :profile_name, :profile_job, :mentor, :diploma_file,
:profile_text, { authored_books_attributes: %i[id title url cover _destroy] },
:country_code, :subdivision_code, discord_profile_attributes: %i[account_name times_url times_id]
)
Expand Down
39 changes: 39 additions & 0 deletions app/javascript/fileinput.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,42 @@ document.addEventListener('DOMContentLoaded', () => {
}
initializeFileInput(document)
})

document.addEventListener('DOMContentLoaded', () => {
const removePdfButton = document.getElementById('js-remove-pdf-button')
const pdfUploadField = document.getElementById('js-pdf-upload-field')
const pdfFileLink = document.getElementById('js-pdf-file-link')
const removePdfFlag = document.getElementById('js-remove-pdf-flag')
const pdfFileNameDisplay = document.getElementById('js-pdf-name')

removePdfButton.addEventListener('click', () => {
if (pdfFileLink) pdfFileLink.style.display = 'none'
pdfUploadField.style.display = 'flex'
pdfUploadField.querySelector('input[type="file"]').value = ''
removePdfFlag.value = '1'

if (pdfFileNameDisplay) {
pdfFileNameDisplay.textContent = ''
pdfFileNameDisplay.style.display = 'none'
}
})

const fileInput = pdfUploadField.querySelector('input[type="file"]')
fileInput.addEventListener('change', () => {
if (fileInput.files && fileInput.files[0]) {
const fileName = fileInput.files[0].name

if (pdfFileNameDisplay) {
pdfFileNameDisplay.textContent = fileName
pdfFileNameDisplay.style.display = 'block'
}

removePdfFlag.value = '0'
} else {
if (pdfFileNameDisplay) {
pdfFileNameDisplay.textContent = ''
pdfFileNameDisplay.style.display = 'none'
}
}
})
})
1 change: 1 addition & 0 deletions app/javascript/stylesheets/_common-imports.sass
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
@import "atoms/a-elapsed-days"
@import "atoms/a-empty-message"
@import "atoms/a-file-input"
@import "atoms/a-pdf-input"
@import "atoms/a-form-frame"
@import "atoms/a-form-help"
@import "atoms/a-form-label"
Expand Down
85 changes: 43 additions & 42 deletions app/javascript/stylesheets/atoms/_a-file-input.sass
Original file line number Diff line number Diff line change
@@ -1,47 +1,48 @@
.a-file-input
label
height: 10rem
max-width: 100%
margin-inline: auto
border: solid 1px var(--input-border)
background-color: var(--base)
display: flex
align-items: center
justify-content: center
+position(relative)
overflow: hidden
cursor: pointer
border-radius: .25rem
padding: .5rem .5rem 2.75rem .5rem
&.is-thumbnail
label
height: 15rem
img
max-height: 100%
transition: all .2s ease-out
&:hover
opacity: .6
&.is-square img
+size(7rem)
object-fit: cover
&.is-book img
max-height: 100%
max-width: 100%
object-fit: contain
border: solid 1px var(--border-tint)
.a-pdf-input
display: flex
gap: .75rem
+media-breakpoint-down(sm)
flex-direction: column

.a-pdf-input__inner
flex: 1
background-color: var(--base)
display: flex
align-items: center
justify-content: center
+position(relative)
overflow: hidden
cursor: pointer
border-radius: .25rem
height: 2.25rem
input
overflow: hidden
+size(0)
+position(absolute, left 0, top 0)
opacity: 0
p
+size(100% 2.25rem)
background-color: var(--base)
+position(absolute, left 0, bottom 0, right 0)
+text-block(.8125rem 1, flex 600)
justify-content: center
align-items: center
border-top: solid 1px var(--input-border)
transition: all .2s ease-out
&:hover
background-color: #e8e8e8

a.a-pdf-input__inner
text-decoration: none
color: var(--default-text)

.a-pdf-input__file
padding: .5rem
flex: 1
border-radius: .25rem 0 0 .25rem
border: solid 1px var(--input-border)
border-right: none
height: 2.25rem

.a-pdf-input__file-name
font-size: .875rem
white-space: nowrap
overflow: hidden
text-overflow: ellipsis
display: block
+media-breakpoint-up(md)
max-width: 18rem
+media-breakpoint-down(sm)
max-width: 8rem

.a-pdf-input__upload.a-button
border-radius: 0 .25rem .25rem 0
48 changes: 48 additions & 0 deletions app/javascript/stylesheets/atoms/_a-pdf-input.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
.a-pdf-input
display: flex
gap: .75rem
+media-breakpoint-down(sm)
flex-direction: column

.a-pdf-input__inner
flex: 1
background-color: var(--base)
display: flex
align-items: center
justify-content: center
+position(relative)
overflow: hidden
cursor: pointer
border-radius: .25rem
height: 2.25rem
input
overflow: hidden
+size(0)
+position(absolute, left 0, top 0)
opacity: 0

a.a-pdf-input__inner
text-decoration: none
color: var(--default-text)

.a-pdf-input__file
padding: .5rem
flex: 1
border-radius: .25rem 0 0 .25rem
border: solid 1px var(--input-border)
border-right: none
height: 2.25rem

.a-pdf-input__file-name
font-size: .875rem
white-space: nowrap
overflow: hidden
text-overflow: ellipsis
display: block
+media-breakpoint-up(md)
max-width: 18rem
+media-breakpoint-down(sm)
max-width: 8rem

.a-pdf-input__upload.a-button
border-radius: 0 .25rem .25rem 0
2 changes: 2 additions & 0 deletions app/javascript/stylesheets/config/mixins/_button.sass
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@
background-color: $color
color: $text-color
border-color: $border-color
&.is-secondary
border-color: var(--input-border)
&:focus,
&:active
box-shadow: 0 0 0 .1875rem rgba($color, .25)
Expand Down
3 changes: 3 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ class User < ApplicationRecord

has_one_attached :avatar
has_one_attached :profile_image
has_one_attached :diploma_file

after_create UserCallbacks.new

Expand Down Expand Up @@ -207,6 +208,8 @@ class User < ApplicationRecord
message: 'はPNG, JPG, GIF, HEIC, HEIF形式にしてください'
}

validates :diploma_file, content_type: { in: ['application/pdf'], message: 'はPDF形式にしてください' }

validates :country_code, inclusion: { in: ISO3166::Country.codes }, allow_blank: true

validates :subdivision_code, inclusion: { in: ->(user) { user.subdivision_codes } }, allow_blank: true, if: -> { country_code.present? }
Expand Down
22 changes: 22 additions & 0 deletions app/views/users/_form.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,28 @@
.form-item-block__item
= render 'users/form/graduate', f: f

.form-item
// 卒業証書
= f.hidden_field :remove_diploma, value: '0', id: 'js-remove-pdf-flag'
= f.label :diploma_file, class: 'a-form-label'
.a-pdf-input
- if @user.diploma_file.attached?
= link_to url_for(@user.diploma_file), class: 'a-pdf-input__inner', id: 'js-pdf-file-link', target: '_blank', rel: 'noopener' do
.a-pdf-input__file
span.a-pdf-input__file-name
= @user.diploma_file.filename
.a-pdf-input__upload.a-button.is-md.is-secondary
| PDFを確認
- display = @user.diploma_file.attached? ? 'display: none' : 'display: flex'
label.a-pdf-input__inner#js-pdf-upload-field(style="#{display}")
= f.file_field :diploma_file
.a-pdf-input__file
span.a-pdf-input__file-name#js-pdf-name
.a-pdf-input__upload.a-button.is-md.is-secondary
| PDFを選択
button.a-button.is-md.is-secondary(type='button' id='js-remove-pdf-button')
| 削除

.form-item-block
.form-item-block__inner
header.form-item-block__header
Expand Down
1 change: 1 addition & 0 deletions config/locales/ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ ja:
other_editor: その他のエディタ
hide_mentor_profile: プロフィール非公開
invoice_payment: 「請求書払い」
diploma_file: 卒業証書PDF
discord_profile:
account_name: Discord アカウント
times_url: 分報URL
Expand Down
11 changes: 11 additions & 0 deletions test/fixtures/files/users/diplomas/diploma.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>卒業証書</title>
</head>
<body>
<h1>卒業証書</h1>
</body>
</html>
Binary file added test/fixtures/files/users/diplomas/diploma.pdf
Binary file not shown.
35 changes: 35 additions & 0 deletions test/system/admin/users_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -352,4 +352,39 @@ class Admin::UsersTest < ApplicationSystemTestCase
visit_with_auth "/admin/users/#{user.id}/edit", 'komagata'
assert has_checked_field?('user_hide_mentor_profile', visible: false)
end

test 'shows diploma link on edit page after upload' do
user = users(:kimura)
visit_with_auth edit_admin_user_path(user), 'komagata'
attach_file 'user[diploma_file]', file_fixture('users/diplomas/diploma.pdf'), visible: false
click_on '更新する'
assert_text 'ユーザー情報を更新しました'
assert user.reload.diploma_file.attached?
visit edit_admin_user_path(user)
assert_link 'diploma.pdf'
end

test 'admin can delete diploma file' do
user = users(:kimura)
visit_with_auth edit_admin_user_path(user), 'komagata'
attach_file 'user[diploma_file]', file_fixture('users/diplomas/diploma.pdf'), visible: false
click_button '更新する'
assert_text 'ユーザー情報を更新しました'
assert user.reload.diploma_file.attached?
visit edit_admin_user_path(user)
click_on '削除'
click_on '更新する'
assert_text 'ユーザー情報を更新しました'
assert_not user.reload.diploma_file.attached?
visit edit_admin_user_path(user)
assert_no_link 'diploma.pdf'
end

test 'rejects diploma upload if not PDF format' do
user = users(:kimura)
visit_with_auth edit_admin_user_path(user), 'komagata'
attach_file 'user[diploma_file]', file_fixture('users/diplomas/diploma.html'), visible: false
click_on '更新する'
assert_text '卒業証書PDFはPDF形式にしてください'
end
end