diff --git a/app/assets/stylesheets/characters.css b/app/assets/stylesheets/characters.css index 23d2f9a..10dace6 100644 --- a/app/assets/stylesheets/characters.css +++ b/app/assets/stylesheets/characters.css @@ -50,14 +50,14 @@ } } -.stats { +.stats, .counters { display: flex; flex-wrap: wrap; gap: .2em; justify-content: center; } -.stat { +.stat, .counter { display: flex; flex-direction: column; border-radius: var(--border-radius); diff --git a/app/assets/stylesheets/forms.css b/app/assets/stylesheets/forms.css index d8b7dbc..ad08a17 100644 --- a/app/assets/stylesheets/forms.css +++ b/app/assets/stylesheets/forms.css @@ -41,7 +41,7 @@ form, fieldset { } } -form.stat-form { +form.stat-form, form.counter-form { display: flex; flex-direction: column; diff --git a/app/controllers/counters_controller.rb b/app/controllers/counters_controller.rb new file mode 100644 index 0000000..2f8cb73 --- /dev/null +++ b/app/controllers/counters_controller.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +class CountersController < ApplicationController + before_action :set_section, only: [ :new, :create ] + before_action :set_character, only: [ :new, :create ] + before_action :set_counter, only: [ :update, :destroy ] + + def new + @counter = @section.counters.new + end + + def create + @counter = @section.counters.new(counter_params) + unless @counter.save + render :new, status: :unprocessable_entity + end + end + + def update + @counter.update(counter_params) + end + + def destroy + @id = helpers.dom_id(@counter) + @counter.destroy + end + + private + def set_character + @character = @section.character + end + + def set_section + @section = Current.user.character_sheet_sections.find(params[:character_sheet_section_id]) + end + + def set_counter + @counter = Current.user.counters.find(params[:id]) + end + + def counter_params + params.require(:counter).permit( + :name, + :value, + :character_sheet_section_id, + ) + end +end diff --git a/app/javascript/controllers/stat_update_controller.js b/app/javascript/controllers/auto_update_controller.js similarity index 100% rename from app/javascript/controllers/stat_update_controller.js rename to app/javascript/controllers/auto_update_controller.js diff --git a/app/models/user.rb b/app/models/user.rb index 97a6154..fec6849 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -9,6 +9,7 @@ class User < ApplicationRecord has_many :character_sheet_sections, through: :characters has_many :owned_tables, foreign_key: :owner_id, class_name: "Table" has_many :players, dependent: :destroy + has_many :counters, through: :character_sheet_sections has_many :stats, through: :character_sheet_sections has_many :tables, through: :players has_rich_text :profile diff --git a/app/views/character_sheet_sections/_character_sheet_section.html.erb b/app/views/character_sheet_sections/_character_sheet_section.html.erb index f32486b..eb6e28c 100644 --- a/app/views/character_sheet_sections/_character_sheet_section.html.erb +++ b/app/views/character_sheet_sections/_character_sheet_section.html.erb @@ -7,6 +7,9 @@
<%= render character_sheet_section.stats %>
+
+ <%= render character_sheet_section.counters %> +
<%= render character_sheet_section.character_sheet_subsections %>
diff --git a/app/views/character_sheet_sections/_edit_links.html.erb b/app/views/character_sheet_sections/_edit_links.html.erb index 28eac2f..1d3b43a 100644 --- a/app/views/character_sheet_sections/_edit_links.html.erb +++ b/app/views/character_sheet_sections/_edit_links.html.erb @@ -5,6 +5,8 @@ <% if section.present? %> <%= link_to t(".add_stat"), new_character_sheet_section_stat_path(section), data: { turbo_stream: true }, class: "add-stat" %> + <%= link_to t(".add_counter"), + new_character_sheet_section_counter_path(section), data: { turbo_stream: true }, class: "add-counter" %> <% end %> <% unless id == "character_sheet_add_section" %> <%= link_to t(".delete_section", name: section.name), character_sheet_section_path(section), diff --git a/app/views/counters/_counter.html.erb b/app/views/counters/_counter.html.erb new file mode 100644 index 0000000..847980a --- /dev/null +++ b/app/views/counters/_counter.html.erb @@ -0,0 +1,11 @@ +
+ <% if @editable %> + <%= link_to(t(".delete"), counter, + data: { turbo_method: :delete, turbo_confirm: t(".confirm_delete", name: counter.name) }) %> + <% end %> +
<%= counter.name %>
+ <%= form_with model: counter, class: "counter-form", + data: { controller: "auto-update", auto_update_update_url_value: counter_path(counter) } do |f| %> + <%= f.number_field :value %> + <% end %> +
diff --git a/app/views/counters/_form.html.erb b/app/views/counters/_form.html.erb new file mode 100644 index 0000000..ddd1fd2 --- /dev/null +++ b/app/views/counters/_form.html.erb @@ -0,0 +1,11 @@ +
+ <%= form_with model: @counter, url: character_sheet_section_counters_path(@section) do |f| %> + <%= f.hidden_field :character_sheet_section_id, value: @section.id %> + + <%= f.label :name %> + <%= f.text_field :name %> + <%= display_form_errors(@section, :name) %> + + <%= f.submit button_text %> + <% end %> +
diff --git a/app/views/counters/create.turbo_stream.erb b/app/views/counters/create.turbo_stream.erb new file mode 100644 index 0000000..68cd0ea --- /dev/null +++ b/app/views/counters/create.turbo_stream.erb @@ -0,0 +1,11 @@ +<%= content_target = "#{dom_id(@section)}_counters" %> +<%= turbo_stream.append(content_target) do %> + <%= render @counter %> +<% end %> + +<%= form_target = "#{dom_id(@section)}_add_section" %> +<%= turbo_stream.replace(form_target) do %> +
+ <%= render partial: "character_sheet_sections/edit_links", locals: { section: @section, parent: @section.parent_section, id: nil} %> +
+<% end %> diff --git a/app/views/counters/destroy.turbo_stream.erb b/app/views/counters/destroy.turbo_stream.erb new file mode 100644 index 0000000..f50ff4a --- /dev/null +++ b/app/views/counters/destroy.turbo_stream.erb @@ -0,0 +1 @@ +<%= turbo_stream.remove @id %> diff --git a/app/views/counters/new.turbo_stream.erb b/app/views/counters/new.turbo_stream.erb new file mode 100644 index 0000000..c56aa03 --- /dev/null +++ b/app/views/counters/new.turbo_stream.erb @@ -0,0 +1,6 @@ +<% target = "#{dom_id(@counter.character_sheet_section)}_add_section" %> +<%= turbo_stream.replace(target) do %> +
+ <%= render partial: "form", locals: { button_text: t(".create_counter") } %> +
+<% end %> diff --git a/app/views/counters/update.turbo_stream.erb b/app/views/counters/update.turbo_stream.erb new file mode 100644 index 0000000..92a6c47 --- /dev/null +++ b/app/views/counters/update.turbo_stream.erb @@ -0,0 +1,3 @@ +<%= turbo_stream.replace dom_id(@counter) do %> + <%= render @counter %> +<% end %> diff --git a/app/views/stats/_stat.html.erb b/app/views/stats/_stat.html.erb index 6528816..507a78e 100644 --- a/app/views/stats/_stat.html.erb +++ b/app/views/stats/_stat.html.erb @@ -5,7 +5,7 @@ <% end %>
<%= stat.name %>
<%= form_with model: stat, class: "stat-form", - data: { controller: "stat-update", stat_update_update_url_value: stat_path(stat) } do |f| %> + data: { controller: "auto-update", auto_update_update_url_value: stat_path(stat) } do |f| %> <%= f.number_field :value, disabled: !@editable %> <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 6230b67..db67e7b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -61,6 +61,7 @@ en: delete_section: Delete %{name} confirm_delete: Are you sure you want to delete this section? add_stat: Add stat + add_counter: Add counter index: edit: Edit character sheet stop_editing: Stop editing @@ -97,6 +98,12 @@ en: destroy: success: Deleted “%{name}” error: Could not delete your character + counters: + counter: + delete: Delete counter + confirm_delete: Are you sure you want to delete %{name}? + new: + create_counter: Create counter password_resets: new: reset_password: Reset your password diff --git a/config/routes.rb b/config/routes.rb index 2caeadc..f0a1ba9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,11 +16,13 @@ Rails.application.routes.draw do resources :sessions, only: [ :new, :create, :destroy ] resources :character_sheet_sections, only: [ :destroy ] do + resources :counters, only: [ :new, :create ] resources :stats, only: [ :new, :create ] end resources :characters do resources :character_sheet_sections, only: [ :index, :new, :create ] end + resources :counters, only: [ :update, :destroy ] resources :stats, only: [ :update, :destroy ] resources :table_invites, only: [ :index, :edit, :update ] resources :tables do diff --git a/test/controllers/counters_controller_test.rb b/test/controllers/counters_controller_test.rb new file mode 100644 index 0000000..b994630 --- /dev/null +++ b/test/controllers/counters_controller_test.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require "test_helper" + +class CountersControllerTest < ActionDispatch::IntegrationTest + test "should render new turbo stream" do + sign_in users(:trevor) + get new_character_sheet_section_counter_url(character_sheet_sections(:counters)), as: :turbo_stream + assert_response :success + end + + test "should create counter" do + sign_in users(:trevor) + assert_difference "Counter.count", 1 do + post character_sheet_section_counters_url(character_sheet_sections(:counters)), + params: { counter: { name: "Ammo", character_sheet_section_id: character_sheet_sections(:counters).id } }, + as: :turbo_stream + end + end + + test "should delete counter" do + sign_in users(:trevor) + assert_difference "Counter.count", -1 do + delete counter_url(Counter.first), as: :turbo_stream + assert_response :success + end + end +end diff --git a/todo.md b/todo.md index c811f1c..cb8beba 100644 --- a/todo.md +++ b/todo.md @@ -7,3 +7,4 @@ - notifications - chat - maps +- show errors from invalid sheet bits