diff --git a/app/controllers/api/regular_events_controller.rb b/app/controllers/api/regular_events_controller.rb
deleted file mode 100644
index cd7256b850a..00000000000
--- a/app/controllers/api/regular_events_controller.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class API::RegularEventsController < API::BaseController
- before_action :require_active_user_login
-
- def index
- regular_events =
- case params[:target]
- when 'not_finished'
- RegularEvent.not_finished
- else
- RegularEvent.all
- end
- @regular_events = regular_events.with_avatar
- .includes(:comments, :users)
- .order(created_at: :desc)
- .page(params[:page])
- end
-end
diff --git a/app/controllers/regular_events_controller.rb b/app/controllers/regular_events_controller.rb
index 7c8f8788567..6cd99906e59 100644
--- a/app/controllers/regular_events_controller.rb
+++ b/app/controllers/regular_events_controller.rb
@@ -1,9 +1,13 @@
# frozen_string_literal: true
-class RegularEventsController < ApplicationController
+class RegularEventsController < ApplicationController # rubocop:disable Metrics/ClassLength
before_action :set_regular_event, only: %i[edit update destroy]
def index
+ @regular_events = RegularEvent.list
+ .fetch_target_events(params[:target])
+ .page(params[:page])
+
@upcoming_events_groups = UpcomingEvent.upcoming_events_groups
end
diff --git a/app/javascript/components/RegularEvent.jsx b/app/javascript/components/RegularEvent.jsx
deleted file mode 100644
index 73b1b61c9b2..00000000000
--- a/app/javascript/components/RegularEvent.jsx
+++ /dev/null
@@ -1,136 +0,0 @@
-import React, { useEffect, useRef } from 'react'
-import userIcon from '../user-icon.js'
-
-const RegularEvent = ({ regularEvent }) => {
- const categoryClass =
- regularEvent.category_class === 'reading_circle'
- ? 'is-reading-circle'
- : `is-${regularEvent.category_class}`
-
- return (
-
-
-
- {regularEvent.category}
-
-
-
-
- )
-}
-
-const EventStatus = ({ event }) => {
- return (
- <>
- {event.wip ? (
-
- WIP
-
- ) : (
- event.finished && (
-
- 終了
-
- )
- )}
- >
- )
-}
-
-const EventTitle = ({ event }) => {
- return (
-
- )
-}
-
-const EventOrganizers = ({ event }) => {
- // userIconの非React化により、useRef,useEffectを導入している。
- const userIconRef = useRef(null)
- useEffect(() => {
- const linkClass = 'card-list-item__user-link'
- const imgClasses = ['card-list-item__user-icon', 'a-user-icon']
-
- const userIconElements = event.organizers.map((organizer) => {
- return userIcon({
- user: organizer,
- linkClass,
- imgClasses
- })
- })
-
- if (userIconRef.current) {
- userIconRef.current.innerHTML = ''
- userIconElements.forEach((element) => {
- userIconRef.current.appendChild(element)
- })
- }
- }, [event.organizers])
-
- return (
- <>
- {event.organizers.length > 0 && (
-
- )}
- >
- )
-}
-
-const EventDatetime = ({ event }) => {
- return (
-
-
-
- )
-}
-
-const Comments = ({ event }) => {
- return (
- <>
- {event.comments_count > 0 && (
-
-
コメント({event.comments_count})
-
- )}
- >
- )
-}
-
-export default RegularEvent
diff --git a/app/javascript/components/RegularEvents.jsx b/app/javascript/components/RegularEvents.jsx
deleted file mode 100644
index 2e2f310f8dc..00000000000
--- a/app/javascript/components/RegularEvents.jsx
+++ /dev/null
@@ -1,135 +0,0 @@
-import React, { useState, useEffect } from 'react'
-import useSWR from 'swr'
-import { get } from '@rails/request.js'
-import queryString from 'query-string'
-import Pagination from './Pagination'
-import LoadingListPlaceholder from './LoadingListPlaceholder'
-import RegularEvent from './RegularEvent'
-import usePage from './hooks/usePage'
-const fetcher = (url) =>
- get(url, { responseKind: 'json' }).then((res) => res.json)
-
-const RegularEvents = () => {
- const getTargetQueryParam = () => {
- return queryString.parse(location.search).target || ''
- }
- const [target, setTarget] = useState(getTargetQueryParam())
- const { page, setPage } = usePage()
-
- useEffect(() => {
- const handlePopState = () => {
- setTarget(getTargetQueryParam())
- }
- window.addEventListener('popstate', handlePopState)
- return () => {
- window.removeEventListener('popstate', handlePopState)
- }
- }, [])
-
- const handleNotFinishedClick = () => {
- setTarget('not_finished')
- setPage(1)
- window.history.pushState(null, null, '/regular_events?target=not_finished')
- }
-
- const handleAllClick = () => {
- setTarget('')
- setPage(1)
- window.history.pushState(null, null, '/regular_events')
- }
-
- return (
- <>
-
-
- >
- )
-}
-
-const Navigation = ({ target, handleNotFinishedClick, handleAllClick }) => {
- return (
-
- )
-}
-
-const EventList = ({ target, page, setPage }) => {
- const per = 20
-
- const { data, error } = useSWR(
- `/api/regular_events?${buildParams(target, page)}`,
- fetcher
- )
-
- if (error) console.warn(error)
-
- if (!data) {
- return (
-
- )
- }
-
- return (
-
- {data.total_pages > 1 && (
-
- )}
-
- {data.regular_events.map((regularEvent) => (
-
- ))}
-
- {data.total_pages > 1 && (
-
- )}
-
- )
-}
-
-const buildParams = (targetParam, pageParam) => {
- const params = {
- ...(targetParam === 'not_finished' && { target: 'not_finished' }),
- page: pageParam
- }
- return new URLSearchParams(params).toString()
-}
-
-export default RegularEvents
diff --git a/app/models/regular_event.rb b/app/models/regular_event.rb
index ee83e3201c2..f1bcb3031b4 100644
--- a/app/models/regular_event.rb
+++ b/app/models/regular_event.rb
@@ -53,6 +53,21 @@ class RegularEvent < ApplicationRecord # rubocop:disable Metrics/ClassLength
scope :scheduled_on, ->(date) { holding.filter { |event| event.scheduled_on?(date) } }
scope :scheduled_on_without_ended, ->(date) { holding.filter { |event| event.scheduled_on?(date) && !event.ended?(date) } }
+ scope :fetch_target_events, lambda { |target|
+ case target
+ when 'not_finished'
+ not_finished
+ else
+ all
+ end
+ }
+
+ scope :list, lambda {
+ with_avatar
+ .includes(:comments, :users, :regular_event_repeat_rules)
+ .order(created_at: :desc)
+ }
+
belongs_to :user
has_many :organizers, dependent: :destroy
has_many :users, through: :organizers
diff --git a/app/views/api/regular_events/_regular_event.json.jbuilder b/app/views/api/regular_events/_regular_event.json.jbuilder
deleted file mode 100644
index f2e8c879a58..00000000000
--- a/app/views/api/regular_events/_regular_event.json.jbuilder
+++ /dev/null
@@ -1,11 +0,0 @@
-json.(regular_event, :id, :title, :wip, :start_at, :end_at, :finished)
-json.title regular_event.title
-json.start_at_localized l regular_event.start_at, format: :time_only
-json.end_at_localized l regular_event.end_at, format: :time_only
-json.finished regular_event.finished
-json.category t("activerecord.enums.regular_event.category.#{regular_event.category}")
-json.category_class regular_event.category
-json.comments_count regular_event.comments.size
-json.url regular_event_url(regular_event)
-json.organizers regular_event.organizers, partial: "api/users/user", as: :user
-json.holding_cycles regular_event.holding_cycles
diff --git a/app/views/api/regular_events/index.json.jbuilder b/app/views/api/regular_events/index.json.jbuilder
deleted file mode 100644
index 16756d1fd23..00000000000
--- a/app/views/api/regular_events/index.json.jbuilder
+++ /dev/null
@@ -1,2 +0,0 @@
-json.regular_events @regular_events, partial: "api/regular_events/regular_event", as: :regular_event
-json.total_pages @regular_events.total_pages
diff --git a/app/views/regular_events/_regular_events.html.slim b/app/views/regular_events/_regular_events.html.slim
new file mode 100644
index 00000000000..c539a13fc86
--- /dev/null
+++ b/app/views/regular_events/_regular_events.html.slim
@@ -0,0 +1,55 @@
+nav.pill-nav.mb-8
+ .pill-nav__items
+ .pill-nav__item
+ = link_to regular_events_path(target: :not_finished), class: "pill-nav__item-link#{params[:target] == 'not_finished' ? ' is-active' : ''}" do
+ | 開催中
+ .pill-nav__item
+ = link_to regular_events_path, class: "pill-nav__item-link#{params[:target].nil? ? ' is-active' : ''}" do
+ | 全て
+
+= paginate @regular_events
+ul.card-list.a-card
+ - @regular_events.each do |event|
+ li.card-list-item
+ .card-list-item__inner
+ .card-list-item__label class="#{event.category}"
+ = t("activerecord.enums.regular_event.category.#{event.category}")
+ .card-list-item__user
+ = render 'users/icon', user: event.user, link_class: 'card-list-item__user-link', image_class: 'card-list-item__user-icon'
+ .card-list-item__rows
+ .card-list-item__row
+ .card-list-item-title
+ - if event.wip
+ .a-list-item-badge.is-wip
+ span WIP
+ - elsif event.finished?
+ .a-list-item-badge.is-ended
+ span 終了
+ h2.card-list-item-title__title(itemprop='name')
+ = link_to event, itemprop: 'url', class: 'card-list-item-title__link a-text-link' do
+ = event.title
+ .card-list-item__row
+ .card-list-item-meta
+ .card-list-item-meta__items
+ .card-list-item-meta__item
+ .a-meta
+ .a-meta__label 主催
+ .a-meta__value
+ .card-list-item__user-icons
+ - event.users.each do |user|
+ .card-list-item__user-link
+ = render 'users/icon',
+ user: user,
+ link_class: 'card-list-item__user-link',
+ image_class: 'card-list-item__user-icon a-user-icon'
+
+ .card-list-item-meta__item
+ time.a-meta(datetime=event.start_at.iso8601)
+ span.a-meta__label 開催日時
+ span.a-meta__value = "#{event.holding_cycles} #{l event.start_at, format: :time_only} ~ #{l event.end_at, format: :time_only}"
+ .card-list-item-meta__item
+ - if event.comments.size.positive?
+ .card-list-item-meta__item
+ .a-meta
+ | コメント(#{event.comments.size})
+= paginate @regular_events
diff --git a/app/views/regular_events/index.html.slim b/app/views/regular_events/index.html.slim
index f52ada2e424..5071bb109c5 100644
--- a/app/views/regular_events/index.html.slim
+++ b/app/views/regular_events/index.html.slim
@@ -23,5 +23,12 @@
.page-body
.page-body__inner.has-side-nav
.container.is-md
- = react_component 'RegularEvents'
+ - if @regular_events.empty?
+ .o-empty-message
+ .o-empty-message__icon
+ i.fa-regular.fa-sad-tear
+ p.o-empty-message__text
+ | 登録されている定期イベントはありません。
+ - else
+ = render 'regular_events/regular_events'
= render 'events/upcoming_events_groups', upcoming_events_groups: @upcoming_events_groups
diff --git a/config/routes/api.rb b/config/routes/api.rb
index 53616f6b163..ab92d0700c2 100644
--- a/config/routes/api.rb
+++ b/config/routes/api.rb
@@ -76,7 +76,6 @@
resources :action_uncompleted, only: %i(index)
end
resources :talks, only: %i(index update)
- resources :regular_events, only: %i(index)
resources :books, only: %i(index)
resources :survey_question_listings, only: %i() do
resource :position, only: %i(update), controller: "survey_question_listings/position"
diff --git a/test/integration/api/regular_events_test.rb b/test/integration/api/regular_events_test.rb
deleted file mode 100644
index a9f54c39213..00000000000
--- a/test/integration/api/regular_events_test.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-require 'test_helper'
-
-class API::RegularEventsTest < ActionDispatch::IntegrationTest
- test 'GET /api/regular_events.json' do
- get api_regular_events_path(format: :json)
- assert_response :unauthorized
-
- token = create_token('hatsuno', 'testtest')
- get api_regular_events_path(format: :json),
- headers: { 'Authorization' => "Bearer #{token}" }
- assert_response :ok
- end
-end
diff --git a/test/system/regular_events_test.rb b/test/system/regular_events_test.rb
index fe45f788da0..0b0b07baccc 100644
--- a/test/system/regular_events_test.rb
+++ b/test/system/regular_events_test.rb
@@ -47,7 +47,7 @@ class RegularEventsTest < ApplicationSystemTestCase
visit_with_auth regular_events_path, 'kimura'
assert_selector '.card-list.a-card .card-list-item', count: 25
visit regular_events_path(page: 2)
- assert_selector '.card-list.a-card .card-list-item', count: 8
+ assert_selector '.card-list.a-card .card-list-item', count: 16
end
test 'using file uploading by file selection dialogue in textarea' do