Skip to content

Commit

Permalink
Merge pull request #7272 from fjordllc/feature/list_upcoming_events_o…
Browse files Browse the repository at this point in the history
…n_special_and_regular_events_pages

 特別イベント一覧、定期イベント一覧に、直近(近日開催)のイベント一覧を表示する。
  • Loading branch information
komagata authored Jul 2, 2024
2 parents 2f8b194 + bdc7b96 commit c56eeef
Show file tree
Hide file tree
Showing 34 changed files with 520 additions and 376 deletions.
10 changes: 3 additions & 7 deletions app/controllers/events_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
class EventsController < ApplicationController
before_action :set_event, only: %i[edit update destroy]

def index; end
def index
@upcoming_events_groups = UpcomingEvent.upcoming_events_groups
end

def show
@event = Event.with_avatar.find(params[:id])
Expand Down Expand Up @@ -75,12 +77,6 @@ def set_wip
@event.wip = (params[:commit] == 'WIP')
end

def redirect_url(event)
return new_announcement_path(event_id: event.id) if publish_with_announcement?

event.wip? ? edit_event_url(event) : event_url(event)
end

def notice_message(event)
case params[:action]
when 'create'
Expand Down
7 changes: 1 addition & 6 deletions app/controllers/home_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,7 @@ def display_dashboard
end

def display_events_on_dashboard
@today_events = (Event.today_events + RegularEvent.today_events)
.sort_by { |e| e.start_at.strftime('%H:%M') }
@tomorrow_events = (Event.tomorrow_events + RegularEvent.tomorrow_events)
.sort_by { |e| e.start_at.strftime('%H:%M') }
@day_after_tomorrow_events = (Event.day_after_tomorrow_events + RegularEvent.day_after_tomorrow_events)
.sort_by { |e| e.start_at.strftime('%H:%M') }
@upcoming_events_groups = UpcomingEvent.upcoming_events_groups
end

def display_welcome_message_for_adviser
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/regular_events_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
class RegularEventsController < ApplicationController
before_action :set_regular_event, only: %i[edit update destroy]

def index; end
def index
@upcoming_events_groups = UpcomingEvent.upcoming_events_groups
end

def show
@regular_event = RegularEvent.find(params[:id])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def show
private

def notify_coming_soon_regular_events
today_events = RegularEvent.today_events
tomorrow_events = RegularEvent.tomorrow_events
today_events = RegularEvent.scheduled_on(Time.zone.today)
tomorrow_events = RegularEvent.scheduled_on(Time.zone.today + 1.day)
return if today_events.blank? && tomorrow_events.blank?

NotificationFacade.coming_soon_regular_events(today_events, tomorrow_events)
Expand Down
4 changes: 2 additions & 2 deletions app/decorators/regular_event_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ def holding_cycles
def next_holding_date
if finished
'開催終了'
elsif holding_today?
!hold_national_holiday && HolidayJp.holiday?(Time.zone.today) ? "次回の開催日は #{l next_event_date} です" : '本日開催'
elsif next_event_date == Time.zone.today
'本日開催'
else
"次回の開催日は #{l next_event_date} です"
end
Expand Down
30 changes: 30 additions & 0 deletions app/decorators/upcoming_event_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

module UpcomingEventDecorator
def label_style
case original_event
when Event
'is-special'
when RegularEvent
"is-#{original_event.category}"
end
end

def inner_title_style
case original_event
when Event
'card-list-item__label-inner.is-sm'
when RegularEvent
nil
end
end

def inner_title
case original_event
when Event
'特別<br>イベント'
when RegularEvent
I18n.translate("activerecord.enums.regular_event.category.#{original_event.category}")
end
end
end
56 changes: 24 additions & 32 deletions app/javascript/components/Events.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,33 @@ export default function Events() {

if (error) return <>エラーが発生しました。</>
if (!data) {
return (
<div className="page-body">
<div className="container is-md">
<LoadingListPlaceholder />
</div>
</div>
)
return <LoadingListPlaceholder />
}

return (
<div className="page-body">
<div className="container is-md">
{data.total_pages > 1 && (
<Pagination
sum={data.total_pages * per}
per={per}
page={page}
setPage={setPage}
/>
)}
<ul className="card-list a-card">
{data.events.map((event) => {
return <Event event={event} key={event.id} />
})}
</ul>
{data.total_pages > 1 && (
<Pagination
sum={data.total_pages * per}
per={per}
page={page}
setPage={setPage}
/>
)}
</div>
</div>
<>
{data.total_pages > 1 && (
<Pagination
sum={data.total_pages * per}
per={per}
page={page}
setPage={setPage}
/>
)}
<ul className="card-list a-card">
{data.events.map((event) => {
return <Event event={event} key={event.id} />
})}
</ul>
{data.total_pages > 1 && (
<Pagination
sum={data.total_pages * per}
per={per}
page={page}
setPage={setPage}
/>
)}
</>
)
}

Expand Down
2 changes: 1 addition & 1 deletion app/javascript/stylesheets/atoms/_a-side-nav.sass
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
padding-right: var(--side-nav-width)

.a-side-nav
background-color: var(--background)
background-color: var(--base)
+media-breakpoint-up(lg)
+position(absolute, right 0, top -1.5rem, bottom -1.5rem)
width: var(--side-nav-width)
Expand Down
12 changes: 1 addition & 11 deletions app/models/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ class Event < ApplicationRecord

scope :wip, -> { where(wip: true) }
scope :related_to, ->(user) { user.job_seeker ? all : where.not(job_hunting: true) }
scope :today_events, -> { where(start_at: Time.zone.today.midnight...Time.zone.tomorrow.midnight) }
scope :tomorrow_events, -> { where(start_at: Time.zone.tomorrow.midnight...(Time.zone.tomorrow + 1.day).midnight) }
scope :day_after_tomorrow_events, -> { where(start_at: (Time.zone.tomorrow + 1.day).midnight...(Time.zone.tomorrow + 2.days).midnight) }
scope :scheduled_on, ->(date) { where(start_at: date.midnight...(date + 1.day).midnight) }

def opening?
Time.current.between?(open_start_at, open_end_at)
Expand Down Expand Up @@ -104,14 +102,6 @@ def send_notification(receiver)
ActivityDelivery.with(receiver:, event: self).notify(:moved_up_event_waiting_user)
end

def holding_today?
start_at.to_date.today?
end

def holding_tomorrow?
start_at.to_date == Date.tomorrow
end

def watched_by?(user)
watches.exists?(user_id: user.id)
end
Expand Down
116 changes: 37 additions & 79 deletions app/models/regular_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,9 @@ class RegularEvent < ApplicationRecord # rubocop:disable Metrics/ClassLength
end

scope :holding, -> { where(finished: false) }
scope :today_events, -> { where(id: holding.select(&:holding_today?).map(&:id)) }
scope :tomorrow_events, -> { where(id: holding.select(&:holding_tomorrow?).map(&:id)) }
scope :day_after_tomorrow_events, -> { where(id: holding.select(&:holding_day_after_tomorrow?).map(&:id)) }
scope :participated_by, ->(user) { where(id: all.select { |e| e.participated_by?(user) }.map(&:id)) }
scope :participated_by, ->(user) { where(id: all.filter { |e| e.participated_by?(user) }.map(&:id)) }
scope :organizer_event, ->(user) { where(id: user.organizers.map(&:regular_event_id)) }
scope :scheduled_on, ->(date) { holding.filter { |event| event.scheduled_on?(date) } }

belongs_to :user
has_many :organizers, dependent: :destroy
Expand All @@ -73,87 +71,19 @@ class RegularEvent < ApplicationRecord # rubocop:disable Metrics/ClassLength

columns_for_keyword_search :title, :description

def organizers
users.with_attached_avatar.order('organizers.created_at')
end

def holding_today?
now = Time.current
event_day = regular_event_repeat_rules.map do |repeat_rule|
if repeat_rule.frequency.zero?
repeat_rule.day_of_the_week == now.wday
else
repeat_rule.day_of_the_week == now.wday && repeat_rule.frequency == convert_date_into_week(now.day)
end
end.include?(true)
event_start_time = Time.zone.local(now.year, now.month, now.day, start_at.hour, start_at.min, 0)

event_day && (now < event_start_time)
end

def convert_date_into_week(date)
(date / 7.0).ceil
def scheduled_on?(date)
all_scheduled_dates.include?(date)
end

def next_event_date
today = Time.zone.today
this_month_first_day = Date.new(today.year, today.mon, 1)
next_month_first_day = this_month_first_day.next_month

possible_dates = regular_event_repeat_rules.map do |repeat_rule|
[
possible_next_event_date(this_month_first_day, repeat_rule),
possible_next_event_date(next_month_first_day, repeat_rule)
]
end.flatten
possible_dates.compact.select { |possible_date| possible_date > Time.zone.today }.min
end

def possible_next_event_date(first_day, repeat_rule)
return next_specific_day_of_the_week(repeat_rule) if repeat_rule.frequency.zero?

possible_date = calculate_date_of_specific_nth_day_of_the_week(repeat_rule, first_day, DAYS_OF_THE_WEEK_COUNT)

return possible_date if hold_national_holiday

while possible_date.mon == first_day.mon && HolidayJp.holiday?(possible_date)
first_day = first_day.next_month
possible_date = calculate_date_of_specific_nth_day_of_the_week(repeat_rule, first_day, DAYS_OF_THE_WEEK_COUNT)
end
possible_date
end

def next_specific_day_of_the_week(repeat_rule)
day_of_the_week_symbol = DateAndTime::Calculations::DAYS_INTO_WEEK.key(repeat_rule.day_of_the_week)
possible_date = 0.days.ago.next_occurring(day_of_the_week_symbol).to_date
possible_date = possible_date.next_occurring(day_of_the_week_symbol) while !hold_national_holiday && HolidayJp.holiday?(possible_date)
possible_date
end

def calculate_date_of_specific_nth_day_of_the_week(repeat_rule, first_day, days_of_the_week_count)
# 次の第n X曜日の日付を計算する
specific_date = (repeat_rule.frequency - 1) * days_of_the_week_count + repeat_rule.day_of_the_week - first_day.wday + 1
specific_date += days_of_the_week_count if repeat_rule.day_of_the_week < first_day.wday
Date.new(first_day.year, first_day.mon, specific_date)
end

def holding_tomorrow?
holding_next_day?(1)
end
event_dates =
hold_national_holiday ? feature_scheduled_dates : feature_scheduled_dates.reject { |d| HolidayJp.holiday?(d) }

def holding_day_after_tomorrow?
holding_next_day?(2)
event_dates.min
end

def holding_next_day?(days = 1)
next_day = Time.current.next_day(days)
regular_event_repeat_rules.map do |repeat_rule|
if repeat_rule.frequency.zero?
repeat_rule.day_of_the_week == next_day.wday
else
repeat_rule.day_of_the_week == next_day.wday && repeat_rule.frequency == convert_date_into_week(next_day.day)
end
end.include?(true)
def organizers
users.with_attached_avatar.order('organizers.created_at')
end

def cancel_participation(user)
Expand Down Expand Up @@ -184,4 +114,32 @@ def end_at_be_greater_than_start_at

errors.add(:end_at, ': イベント終了時刻はイベント開始時刻よりも後の時刻にしてください。')
end

def all_scheduled_dates(
from: Date.new(Time.current.year, 1, 1),
to: Date.new(Time.current.year, 12, 31)
)
(from..to).filter { |d| date_match_the_rules?(d, regular_event_repeat_rules) }
end

def feature_scheduled_dates
# 時刻が過ぎたイベントを排除するためだけに、一時的にstart_timeを与える。後でDate型に戻す。
event_dates_with_start_time = all_scheduled_dates.map { |d| d.in_time_zone.change(hour: start_at.hour, min: start_at.min) }

event_dates_with_start_time.reject { |d| d < Time.zone.now }.map(&:to_date)
end

def date_match_the_rules?(date, rules)
rules.any? do |rule|
if rule.frequency.zero?
rule.day_of_the_week == date.wday
else
rule.frequency == nth_wday(date) && rule.day_of_the_week == date.wday
end
end
end

def nth_wday(date)
(date.day + 6) / 7
end
end
Loading

0 comments on commit c56eeef

Please sign in to comment.