Skip to content
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
16 changes: 12 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ jobs:
command: |
bundle lock --add-platform ruby
- ruby/install-deps
- ruby/rubocop-check:
format: progress
label: Inspecting with Rubocop
- run:
name: Inspecting with Rubocop
command: bundle exec rubocop --format progress
- run:
name: Slim Lint
command: bundle exec slim-lint app/views -c config/slim_lint.yml
Expand Down Expand Up @@ -111,7 +111,15 @@ jobs:
psql -h localhost -U postgres -d ci_test -c "CREATE EXTENSION IF NOT EXISTS vector;"
- run:
name: Database setup
command: 'bundle exec rails db:prepare'
command: |
# pg_bigm未インストール環境でschema.rbのenable_extension/gin_bigm_opsが失敗するため除外
echo "=== Before sed ==="
grep -n "pg_bigm\|gin_bigm_ops" db/schema.rb || echo "No pg_bigm lines found"
sed -i '/pg_bigm/d' db/schema.rb
sed -i '/gin_bigm_ops/d' db/schema.rb
echo "=== After sed ==="
grep -n "pg_bigm\|gin_bigm_ops" db/schema.rb || echo "No pg_bigm lines found"
bundle exec rails db:migrate
- run:
name: Assets precompile
command: 'bundle exec rails assets:clean assets:precompile'
Expand Down
1 change: 1 addition & 0 deletions .cloudbuild/cloudbuild-review.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ steps:
- '--set-env-vars=RAILS_LOG_TO_STDOUT=true'
- '--set-env-vars=RAILS_ENV=production'
- '--set-env-vars=RACK_ENV=production'
- '--set-env-vars=REVIEW_APP=1'
- '--set-env-vars=APP_HOST_NAME=$_APP_HOST_NAME'
- '--set-env-vars=CLOUD_RUN_HOST_NAME=$_CLOUD_RUN_HOST_NAME'
- '--set-env-vars=RAILS_MASTER_KEY=$_RAILS_MASTER_KEY'
Expand Down
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ AllCops:
- db/data_schema.rb
- db/migrate/*
- db/schema.rb
- db/seeds/**/*
- storage/**/*
- tmp/**/*
- bin/**/*
1 change: 1 addition & 0 deletions app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
@import "./application/blocks/page-content/_page-content-header.css";
@import "./application/blocks/page-content/_page-content-members.css";
@import "./application/blocks/page-content/_page-content-prev-next.css";
@import "./application/blocks/textbook/_textbook-list.css";
@import "./application/blocks/pair-work/_pair-work-info.css";
@import "./application/blocks/pair-work/_pair-work-schedule-dates.css";
@import "./application/blocks/practice/_categories.css";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* 教科書共通 */

.textbook-summary {
margin-top: 0.75rem;
}

.textbook-summary__stats {
font-size: 0.8125rem;
color: var(--muted-text);
margin-bottom: 0.375rem;
}

.textbook-summary__action {
margin-top: 0.75rem;
}

.a-completed-check {
color: var(--success);
margin-right: 0.375rem;
}

.a-pending-check {
color: var(--disabled);
margin-right: 0.375rem;
font-size: 0.875em;
}

.textbook-breadcrumb {
font-size: 0.8125rem;
color: var(--muted-text);
margin-bottom: 1rem;
}

.textbook-breadcrumb a {
color: var(--link-text);
}

.textbook-breadcrumb a:hover {
text-decoration: underline;
}
1 change: 1 addition & 0 deletions app/assets/stylesheets/common-imports.css
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,4 @@
@import "./shared/blocks/form/_form-textarea.css";
@import "./shared/blocks/form/_form-table.css";
@import "./shared/blocks/_o-empty-message.css";
@import "./shared/blocks/_piyo-companion.css";
78 changes: 78 additions & 0 deletions app/assets/stylesheets/shared/blocks/_piyo-companion.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
.piyo-companion {
position: fixed;
bottom: 1rem;
right: 1rem;
z-index: 1000;
}

.piyo-companion__button {
background: none;
border: none;
cursor: pointer;
padding: 0;
position: relative;
transition: transform 0.15s;
}

.piyo-companion__button:hover {
transform: scale(1.1);
}

.piyo-companion__image {
width: 56px;
height: 56px;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.15));
}

.piyo-companion__bubble {
position: absolute;
bottom: 64px;
right: 0;
background: var(--base, #fff);
border: 1px solid var(--border, #e0e0e0);
border-radius: 12px;
padding: 0.625rem 0.875rem;
max-width: 220px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
animation: piyo-bubble-in 0.2s ease-out;
}

.piyo-companion__bubble::after {
content: '';
position: absolute;
bottom: -7px;
right: 20px;
width: 0;
height: 0;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid var(--base, #fff);
}

.piyo-companion__message {
margin: 0;
font-size: 0.8125rem;
line-height: 1.5;
}

.piyo-companion__badge {
position: absolute;
top: -3px;
right: -3px;
width: 10px;
height: 10px;
background: var(--danger, #ef4444);
border-radius: 50%;
border: 2px solid var(--base, #fff);
}

@keyframes piyo-bubble-in {
from {
opacity: 0;
transform: translateY(4px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
35 changes: 35 additions & 0 deletions app/controllers/api/textbooks/reading_progresses_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

class API::Textbooks::ReadingProgressesController < API::BaseController
include TextbookFeatureGuard
before_action :require_textbook_enabled

def create
@reading_progress = current_user.reading_progresses.find_or_initialize_by(
textbook_section_id: reading_progress_params[:textbook_section_id]
)
@reading_progress.assign_attributes(reading_progress_params)
if @reading_progress.save
head(@reading_progress.previously_new_record? ? :created : :ok)
else
head :unprocessable_entity
end
rescue ActiveRecord::RecordNotUnique
retry
end

def update
@reading_progress = current_user.reading_progresses.find(params[:id])
if @reading_progress.update(reading_progress_params)
head :ok
else
head :unprocessable_entity
end
end

private

def reading_progress_params
params.require(:reading_progress).permit(:textbook_section_id, :read_ratio, :completed, :last_block_index, :last_read_at)
end
end
10 changes: 10 additions & 0 deletions app/controllers/api/textbooks/term_explanations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

class API::Textbooks::TermExplanationsController < API::BaseController
include TextbookFeatureGuard
before_action :require_textbook_enabled

def show
@term_explanation = TermExplanation.find(params[:id])
end
end
18 changes: 18 additions & 0 deletions app/controllers/concerns/textbook_feature_guard.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

# textbook機能のfeature flag制御
module TextbookFeatureGuard
extend ActiveSupport::Concern

private

def require_textbook_enabled
return if Switchlet.enabled?(:textbook) || Rails.env.local? || staging_or_review?

head :not_found
end

def staging_or_review?
ENV['REVIEW_APP'].present? || ENV['STAGING'].present?
end
end
51 changes: 51 additions & 0 deletions app/controllers/mentor/textbooks/chapters_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

class Mentor::Textbooks::ChaptersController < ApplicationController
include TextbookFeatureGuard
before_action :require_admin_or_mentor_login
before_action :require_textbook_enabled
before_action :set_textbook
before_action :set_chapter, only: %i[edit update destroy]

def new
@chapter = @textbook.chapters.build
end

def create
@chapter = @textbook.chapters.build(chapter_params)
if @chapter.save
redirect_to mentor_textbook_path(@textbook), notice: '章を作成しました。'
else
render :new, status: :unprocessable_entity
end
end

def edit; end

def update
if @chapter.update(chapter_params)
redirect_to mentor_textbook_path(@textbook), notice: '章を更新しました。'
else
render :edit, status: :unprocessable_entity
end
end

def destroy
@chapter.destroy!
redirect_to mentor_textbook_path(@textbook), notice: '章を削除しました。'
end

private

def set_textbook
@textbook = Textbook.find(params[:textbook_id])
end

def set_chapter
@chapter = @textbook.chapters.find(params[:id])
end

def chapter_params
params.require(:textbook_chapter).permit(:title, :position)
end
end
56 changes: 56 additions & 0 deletions app/controllers/mentor/textbooks/sections_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# frozen_string_literal: true

class Mentor::Textbooks::SectionsController < ApplicationController
include TextbookFeatureGuard
before_action :require_admin_or_mentor_login
before_action :require_textbook_enabled
before_action :set_textbook
before_action :set_chapter
before_action :set_section, only: %i[edit update destroy]

def new
@section = @chapter.sections.build
end

def create
@section = @chapter.sections.build(section_params)
if @section.save
redirect_to mentor_textbook_path(@textbook), notice: '節を作成しました。'
else
render :new, status: :unprocessable_entity
end
end

def edit; end

def update
if @section.update(section_params)
redirect_to mentor_textbook_path(@textbook), notice: '節を更新しました。'
else
render :edit, status: :unprocessable_entity
end
end

def destroy
@section.destroy!
redirect_to mentor_textbook_path(@textbook), notice: '節を削除しました。'
end

private

def set_textbook
@textbook = Textbook.find(params[:textbook_id])
end

def set_chapter
@chapter = @textbook.chapters.find(params[:chapter_id])
end

def set_section
@section = @chapter.sections.find(params[:id])
end

def section_params
params.require(:textbook_section).permit(:title, :body, :estimated_minutes, :position, goals: [], key_terms: [])
end
end
Loading
Loading