Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c6ca819
new-userかどうかを判定するjoining_statusメソッドを追加
hirokiej May 26, 2025
44c89d0
動的にnew-userかstandard-userクラスを作成するjoining_status_classを追加
hirokiej May 26, 2025
4d602f7
spanにユーザーのjoining_statusクラスを追加
hirokiej May 26, 2025
d6d6e56
Slimファイルにjoining_statusクラスを追加
hirokiej May 26, 2025
4f07a06
joining_statusをフロントエンドでも利用できるようにした
hirokiej May 26, 2025
bdea2dc
ReactとVueファイルにjoining_statusを追加
hirokiej May 26, 2025
e9049b4
joining_statusに影響するクラスのテストを修正
hirokiej May 26, 2025
79fb9e0
joiningStatusClass の修正に加え、類似のミスも修正
hirokiej May 27, 2025
069cc67
APIユーザーのレスポンスのテストにjoining_statusを追加
hirokiej May 31, 2025
22932ee
入って一週間未満のユーザーのアイコンの装飾を実装
machida May 26, 2025
cdf163f
spanを共通化した、user_role_status_spanメソッドを作成
hirokiej Jun 11, 2025
09bcaf7
Slimファイルのspan部分をuser_role_status_spanに置き換えた
hirokiej Jun 11, 2025
14edaf5
work_component.html.slimにアイコンを表示させるため、同様のメソッドを追加
hirokiej Jun 12, 2025
7ec06d5
userのprimary_roleとjoining_statusをUserRoleStatusSpan.jsxで共通化
hirokiej Jun 16, 2025
eb2f260
UserRoleStatusSpan.jsxに共通化したためCommentUserIcon.jsxを削除
hirokiej Jun 16, 2025
d846f71
該当ファイルの処理をUserRoleStatusSpanに変更した
hirokiej Jun 16, 2025
4db6ea4
User.jsxでUserRoleStatusSpanとgetUserRoleStatusClassを使用
hirokiej Jun 16, 2025
7bee8c8
new-userでない場合、クラスを付与しないよう修正
hirokiej Jun 19, 2025
274d088
keyを再レンダリング最適化のためaタグに移動
hirokiej Jun 19, 2025
0bc2212
joining_statusで標準ユーザーにはクラスが付かないよう修正
hirokiej Jun 21, 2025
7100978
user_role_status_spanメソッドをuser_icon_frame_classに変更
hirokiej Jun 21, 2025
375960c
user_icon_frame_classをクラス名を返すだけに変更し、span生成を削除
hirokiej Jun 21, 2025
cf22f22
UserRoleStatusSpanをUserIconFrameClassに変更
hirokiej Jun 21, 2025
0b94e30
UserIconFrameClassをクラス名のみ返すだけの関数に変更
hirokiej Jun 22, 2025
935c081
ReactのUserRoleStatusSpanを UserIconFrameClassに書き換えた
hirokiej Jun 22, 2025
e71e47f
work_component.rbにUsersHelperをinclude
hirokiej Jun 22, 2025
51f2e0c
Slimのuser_role_status_spanをuser_icon_frame_classに変更
hirokiej Jun 22, 2025
a2d1567
product_componentにUsersHelperをinclude
hirokiej Jun 22, 2025
bb33199
product_componentでuser_icon_frame_classに書き換え
hirokiej Jun 22, 2025
c409183
user_icon_frame_classのテスト作成
hirokiej Jun 22, 2025
d958508
Vueファイルでnew-userでない場合、空文字を返すようにした
hirokiej Jun 23, 2025
52dcff2
user-icon.jsでnew-user以外はis-new-userクラスを付与しないように修正
hirokiej Jun 23, 2025
3691f52
UsersHelperのuser_icon_frame_classをusers_decorator.rbに移動
hirokiej Jul 4, 2025
5197fad
移動に伴いinclude UsersHelperを削除
hirokiej Jul 4, 2025
833978b
user_decorator.rbに合わせてSlimファイルを修正
hirokiej Jul 4, 2025
2fa81f6
user_icon_frame_classのテストをusers_helper_testからuser_decorator_testに移動
hirokiej Jul 4, 2025
625d78a
テスト名を'#user_icon_frame_class'に修正
hirokiej Jul 14, 2025
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
4 changes: 2 additions & 2 deletions app/components/products/product_component.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
- if @display_user_icon
.card-list-item__user
= link_to user_url(@product.user), class: "card-list-item__user-link" do
span class=["a-user-role", role_class]
span class=@product.user.user_icon_frame_class
= image_tag @product.user.avatar_url,
class: "card-list-item__user-icon a-user-icon",
title: @product.user.icon_title,
Expand Down Expand Up @@ -79,7 +79,7 @@
- @product.commented_users.distinct.each do |user|
a.card-list-item__user-icons-icon href=user_path(user)
= image_tag user.avatar_url,
class: "a-user-icon #{role_class}",
class: "a-user-icon #{role_class} #{joining_status_class}",
title: user.icon_title,
alt: user.icon_title

Expand Down
4 changes: 4 additions & 0 deletions app/components/products/product_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ def role_class
"is-#{@product.user.primary_role}"
end

def joining_status_class
@product.user.joining_status == 'new-user' ? 'is-new-user' : ''
end

def practice_title
"#{@product.practice.title}の提出物"
end
Expand Down
2 changes: 1 addition & 1 deletion app/components/works/work_component.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
.thumbnail-card__author
.thumbnail-card__icon
= link_to user_path(work.user) do
span class="a-user-role is-#{work.user.primary_role}"
span class=work.user.user_icon_frame_class
= creator_avatar
.thumbnail-card__user
= link_to work.user.name, user_path(work.user), class: 'a-user-name'
Expand Down
12 changes: 12 additions & 0 deletions app/decorators/user_decorator.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

module UserDecorator
NEW_USER_DAYS = 7

include Role
include Retire

Expand Down Expand Up @@ -91,4 +93,14 @@ def niconico_calendar(dates_and_reports)

[*blanks, *dates_and_reports].each_slice(7).to_a
end

def joining_status
elapsed_days <= NEW_USER_DAYS ? 'new-user' : ''
end

def user_icon_frame_class
classes = ['a-user-role', "is-#{primary_role}"]
classes << 'is-new-user' if joining_status == 'new-user'
classes.join(' ')
end
end
14 changes: 0 additions & 14 deletions app/javascript/components/CommentUserIcon.jsx

This file was deleted.

11 changes: 9 additions & 2 deletions app/javascript/components/ListComment.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import CommentUserIcon from './CommentUserIcon'
import { UserIconFrameClass } from './UserIconFrameClass'

export default function ListComment({ report }) {
return (
Expand All @@ -17,7 +17,14 @@ export default function ListComment({ report }) {
<div className="card-list-item__user-icons">
{report.comments.map((comment) => {
return (
<CommentUserIcon comment={comment} key={comment.user_id} />
<a
className="card-list-item__user-icons-icon"
href={`/users/${comment.user_id}`}
key={comment.user_id}>
<span className={UserIconFrameClass(comment)}>
<img className="a-user-icon" src={comment.user_icon} />
</span>
</a>
)
})}
</div>
Expand Down
5 changes: 3 additions & 2 deletions app/javascript/components/NotificationsBell/Notifications.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react'
import LoadingListPlaceholder from '../LoadingListPlaceholder'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import { UserIconFrameClass } from '../UserIconFrameClass'
dayjs.extend(relativeTime)

export default function Notifications({ notifications, targetStatus }) {
Expand Down Expand Up @@ -56,9 +57,9 @@ function Notification({ notification }) {
href={notification.path}
className="header-dropdown__item-link unconfirmed_link">
<div className="header-notifications-item__body">
<span
className={`a-user-role header-notifications-item__user-icon is-${notification.sender.primary_role}`}>
<span className={UserIconFrameClass(notification.sender)}>
<img
spanClassName="header-notifications-item__user-icon"
src={notification.sender.avatar_url}
className="a-user-icon"
alt="User Icon"
Expand Down
5 changes: 2 additions & 3 deletions app/javascript/components/Report.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import ListComment from './ListComment'
import { UserIconFrameClass } from './UserIconFrameClass'

export default function Report({ report, currentUserId, displayUserIcon }) {
return (
Expand Down Expand Up @@ -66,12 +67,10 @@ export default function Report({ report, currentUserId, displayUserIcon }) {
}

const DisplayUserIcon = ({ report }) => {
const roleClass = `is-${report.user.primary_role}`

return (
<div className="card-list-item__user">
<a href={report.user.url} className="card-list-item__user-link">
<span className={`a-user-role ${roleClass}`}>
<span className={UserIconFrameClass(report.user)}>
<img
className="card-list-item__user-icon a-user-icon"
src={report.user.avatar_url}
Expand Down
9 changes: 4 additions & 5 deletions app/javascript/components/User.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import UserActivityCounts from './UserActivityCounts.jsx'
import UserSns from './UserSns.jsx'
import UserTags from './UserTags.jsx'
import UserPracticeProgress from './UserPracticeProgress.jsx'
import { UserIconFrameClass } from './UserIconFrameClass.jsx'

export default function User({ user, currentUser }) {
const userDescParagraphs = () => {
Expand All @@ -21,12 +22,10 @@ export default function User({ user, currentUser }) {
return paragraphs
}

const roleClass = () => `is-${user.primary_role}`

return (
<div className="col-xxxl-2 col-xxl-3 col-xl-4 col-lg-4 col-md-6 col-xs-12">
<div className="users-item is-react">
<div className={`users-item__inner a-card ${roleClass()}`}>
<div className={`users-item__inner a-card ${UserIconFrameClass(user)}`}>
{currentUser &&
(currentUser.mentor || currentUser.admin) &&
user.student_or_trainee && (
Expand Down Expand Up @@ -54,12 +53,12 @@ export default function User({ user, currentUser }) {
<div className="users-item__header-start">
<div className="users-item__icon">
<a href={user.url}>
<span className={`a-user-role ${roleClass()}`}>
<span className={UserIconFrameClass(user)}>
<img
className="users-item__user-icon-image a-user-icon"
src={user.avatar_url}
title={user.icon_title}
alt={user.icon_title}
src={user.avatar_url}
/>
</span>
</a>
Expand Down
5 changes: 5 additions & 0 deletions app/javascript/components/UserIconFrameClass.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function UserIconFrameClass(user) {
return `a-user-role is-${user.primary_role} ${
user.joining_status === 'new-user' ? 'is-new-user' : ''
}`
}
7 changes: 6 additions & 1 deletion app/javascript/components/question.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
.card-list-item__inner
.card-list-item__user
a.card-list-item__user-link(:href='question.user.url')
span(:class='["a-user-role", roleClass]')
span(:class='["a-user-role", roleClass, joiningStatusClass]')
img.card-list-item__user-icon.a-user-icon(
:title='question.user.icon_title',
:alt='question.user.icon_title',
Expand Down Expand Up @@ -84,6 +84,11 @@ export default {
roleClass() {
return `is-${this.question.user.primary_role}`
},
joiningStatusClass() {
return this.question.user.joining_status === 'new-user'
? 'is-new-user'
: ''
},
urgentClass() {
return {
'is-important': !this.hasAnswers
Expand Down
9 changes: 9 additions & 0 deletions app/javascript/stylesheets/config/mixins/_user-role.sass
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,12 @@
background-color: black
.a-user-icon
opacity: .7
body.is-mentor-mode &.is-new-user
.a-user-icon
box-shadow: 0 0 1px 2px var(--warning)
&.is-student
.a-user-icon
border: dashed 2px var(--danger)
&.is-trainee
.a-user-icon
border: dashed 2px var(--main)
3 changes: 3 additions & 0 deletions app/javascript/user-icon.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export default function userIcon({

const span = document.createElement('span')
span.classList.add('a-user-role', `is-${user.primary_role}`)
if (user.joining_status === 'new-user') {
span.classList.add('is-new-user')
}

const img = document.createElement('img')
img.src = user.avatar_url
Expand Down
2 changes: 1 addition & 1 deletion app/views/admin/users/_table.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
td.admin-table__item-value.text-left
= link_to user, class: 'admin-table__user', target: '_blank', rel: 'noopener' do
span.admin-table__user-icon
span(class="a-user-role is-#{user.primary_role}")
span class=user.user_icon_frame_class
= image_tag user.avatar_url, title: user.icon_title, class: 'admin-table__user-icon a-user-icon'
span.admin-table__user-login-name
= user.login_name
Expand Down
1 change: 1 addition & 0 deletions app/views/api/comments/_user_icons.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ if report.comments.present?
json.user_icon user.avatar_url
json.user_id user.id
json.primary_role user.primary_role
json.joining_status user.joining_status
end
end
end
1 change: 1 addition & 0 deletions app/views/api/courses/practices/index.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ json.categories @categories do |category|
json.icon_title user.icon_title
json.roles user.roles
json.primary_role user.primary_role
json.joining_status user.joining_status
end
end
end
Expand Down
1 change: 1 addition & 0 deletions app/views/api/generations/users/_user.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ json.avatar_url user.avatar_url
json.icon_title user.icon_title
json.login_name user.login_name
json.primary_role user.primary_role
json.joining_status user.joining_status
1 change: 1 addition & 0 deletions app/views/api/products/_product.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ json.comments do
json.url user_path(user)
json.icon_title user.icon_title
json.primary_role user.primary_role
json.joining_status user.joining_status
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions app/views/api/searchables/_searchable.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ if searchable.respond_to?(:user)
json.avatar_url searchable.user.avatar_url
json.icon_title searchable.user.icon_title
json.primary_role searchable.user.primary_role
json.joining_status searchable.user.joining_status
end
json.is_comment_or_answer comment_or_answer?(searchable)
if comment_or_answer?(searchable)
Expand All @@ -25,4 +26,5 @@ json.is_user user?(searchable)
if user?(searchable)
json.avatar_url searchable.avatar_url
json.primary_role searchable.primary_role
json.joining_status searchable.joining_status
end
2 changes: 1 addition & 1 deletion app/views/api/users/_list_user.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
user_course_practice = ActiveDecorator::Decorator.instance.decorate(UserCoursePractice.new(user))

json.(user, :id, :login_name, :name, :description, :github_account, :twitter_account, :facebook_url, :blog_url, :job_seeker, :job, :os, :experiences, :email, :roles, :primary_role, :icon_title, :graduated_on)
json.(user, :id, :login_name, :name, :description, :github_account, :twitter_account, :facebook_url, :blog_url, :job_seeker, :job, :os, :experiences, :email, :roles, :primary_role, :icon_title, :graduated_on, :joining_status)
json.tag_list user.tags.pluck(:name)
json.url user_url(user)
json.updated_at l(user.updated_at)
Expand Down
2 changes: 1 addition & 1 deletion app/views/api/users/_user.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
columns = %i(id login_name email long_name url roles primary_role icon_title)
columns = %i(id login_name email long_name url roles primary_role icon_title joining_status)
columns << :mentor_memo if admin_or_mentor_login?
json.(user, *columns)
json.avatar_url user.avatar_url
Expand Down
2 changes: 1 addition & 1 deletion app/views/application/_current_user.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
const user = <%= raw(current_user&.to_json(only: [:id, :login_name, :name], methods: [:avatar_url, :roles, :primary_role]) || '{}') %>;
const user = <%= raw(current_user&.to_json(only: [:id, :login_name, :name], methods: [:avatar_url, :roles, :primary_role, :joining_status]) || '{}') %>;

window.currentUser = user;
window.currentUserID = user.id || 0;
Expand Down
8 changes: 4 additions & 4 deletions app/views/coding_tests/coding_test_submissions/show.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ ruby:
= link_to cts.user,
itemprop: 'url',
class: 'page-content-header__user-link' do
span class="a-user-role is-#{cts.user.primary_role}"
= image_tag cts.user.avatar_url,
title: cts.user.icon_title,
class: 'page-content-header__user-icon-image a-user-icon'
span class=cts.user.user_icon_frame_class
= image_tag cts.user.avatar_url,
title: cts.user.icon_title,
class: 'page-content-header__user-icon-image a-user-icon'
.page-content-header__end
.page-content-header__row
.page-content-header__before-title
Expand Down
2 changes: 1 addition & 1 deletion app/views/companies/products/_product.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
title="#{user.icon_title}"
alt="#{user.icon_title}"
src="#{user.avatar_url}"
class="is-#{user.primary_role}")
class="is-#{user.primary_role} is-#{user.joining_status}")

- if product.self_last_commented_at && product.mentor_last_commented_at
.card-list-item-meta__item
Expand Down
2 changes: 1 addition & 1 deletion app/views/companies/users/_user.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
.users-item__header-start
.users-item__icon
= link_to user.url
span(:class='["a-user-role", roleClass]')
span(:class='["a-user-role", roleClass, joiningStatusClass]')
img.users-item__user-icon-image.a-user-icon(
title="#{user.login_name}(#{user.name})"
alt="#{user.login_name}(#{user.name})"
Expand Down
2 changes: 1 addition & 1 deletion app/views/courses/practices/_practice_user_icon.html.slim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.a-user-icons__item
a.a-user-icons__item-link(href="#{user_path(started_or_submitted_student)}")
span.a-user-role(class="a-user-role is-#{started_or_submitted_student.primary_role}")
span class=started_or_submitted_student.user_icon_frame_class
= image_tag started_or_submitted_student.avatar_url, title: started_or_submitted_student.icon_title, class: 'a-user-icons__item-icon a-user-icon'
2 changes: 1 addition & 1 deletion app/views/events/_event.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
- event.participants.each do |participant|
li.user-icons-item
= link_to participant do
span class="a-user-role is-#{participant.primary_role}"
span class=participant.user_icon_frame_class
= image_tag participant.avatar_url, title: participant.icon_title, class: "a-user-icon is-sm is-#{participant.login_name}", alt: participant.login_name
- else
.o-empty-message
Expand Down
2 changes: 1 addition & 1 deletion app/views/footprints/_footprint.html.slim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
li.user-icons__item
a.user-icons__item-link href=footprint.user.url
span.a-user-role class="is-#{footprint.user.primary_role}"
span class=footprint.user.user_icon_frame_class
img.a-user-icon.is-sm title=footprint.user.icon_title alt=footprint.user.icon_title src=footprint.user.avatar_url class="is-#{footprint.user.login_name}"
2 changes: 1 addition & 1 deletion app/views/generations/index.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ main.page-main
- ActiveDecorator::Decorator.instance.decorate(user)
.a-user-icons__item
= link_to user_path(user), class: 'a-user-icons__item-link' do
span class=["a-user-role", "is-#{user.primary_role}"]
span class=user.user_icon_frame_class
img.a-user-icons__item-icon.a-user-icon src=user.avatar_url title=user.icon_title data-login-name=user.login_name
= paginate @generations
2 changes: 1 addition & 1 deletion app/views/questions/_answer.html.slim
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.thread-comment.answer id="answer_#{answer.id}" data-question_id="#{question.id}" data-answer_id="#{answer.id}" data-answer_description="#{answer.description}"
.thread-comment__start
a.thread-comment__user-link href="#{answer.user.url}"
span class="a-user-role is-#{answer.user.primary_role}"
span class=answer.user.user_icon_frame_class
img.thread-comment__user-icon.a-user-icon src="#{answer.user.avatar_url}"
- if answer.user.company && (answer.user.adviser? || answer.user.trainee?)
a.thread-comment__company-link href="#{company_path(answer.user.company)}"
Expand Down
2 changes: 1 addition & 1 deletion app/views/questions/_new_answer.html.slim
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.thread-comment-form.new-answer data-question_id="#{question.id}"
.thread-comment__start
span class="a-user-role is-#{user.primary_role}"
span class=user.user_icon_frame_class
img.thread-comment__user-icon.a-user-icon src="#{user.avatar_url}" alt="#{current_user.icon_title}"
.thread-comment__end
.answer-editor
Expand Down
2 changes: 1 addition & 1 deletion app/views/regular_events/_regular_event.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
- regular_event.participants.each do |participant|
li.user-icons-item
= link_to participant do
span class="a-user-role is-#{participant.primary_role}"
span class=participant.user_icon_frame_class
= image_tag participant.avatar_url, title: participant.icon_title, class: "a-user-icon is-sm is-#{participant.login_name}", alt: participant.login_name
- if admin_login?
= link_to regular_event_participation_path(regular_event_id: regular_event, participant_id: participant),
Expand Down
2 changes: 1 addition & 1 deletion app/views/regular_events/_regular_event_meta.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
- regular_event.organizers.each do |organizer|
li.user-icons-item
= link_to organizer do
span class="a-user-role is-#{organizer.primary_role}"
span class=organizer.user_icon_frame_class
= image_tag organizer.avatar_url, title: organizer.icon_title, class: "a-user-icon is-sm is-#{organizer.login_name}", alt: organizer.login_name
.event-meta__item
dt.event-meta__item-label
Expand Down
Loading