diff --git a/app/assets/stylesheets/colors.css b/app/assets/stylesheets/colors.css
index 8c77bdc..b2cba83 100644
--- a/app/assets/stylesheets/colors.css
+++ b/app/assets/stylesheets/colors.css
@@ -12,4 +12,5 @@
--notice-text-color: #fff;
--invalid-alert: #d00;
+ --input-background: #fff;
}
diff --git a/app/assets/stylesheets/forms.css b/app/assets/stylesheets/forms.css
index 1eb719e..219fceb 100644
--- a/app/assets/stylesheets/forms.css
+++ b/app/assets/stylesheets/forms.css
@@ -1,4 +1,4 @@
-form {
+form, fieldset {
display: grid;
gap: 1rem;
grid-template-columns: 1fr 2fr;
@@ -31,4 +31,12 @@ form {
color: var(--invalid-alert);
font-size: .8em;
}
+
+ fieldset, p, trix-editor {
+ grid-column: 1/3;
+ }
+
+ trix-editor {
+ background-color: var(--input-background);
+ }
}
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index df1837a..c589672 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -2,14 +2,15 @@
class UsersController < ApplicationController
skip_before_action :authenticate, only: [ :new, :create ]
- before_action :set_user, only: [ :show ]
+ before_action :set_user, only: [ :show, :edit, :update ]
+ before_action :ensure_self, only: [ :edit, :update ]
def new
@user = User.new
end
def create
- @user = User.new(user_params)
+ @user = User.new(new_user_params)
if @user.save
token = @user.generate_token_for(:email_verification)
UserMailer.with(user: @user, token: token).email_verification.deliver_later
@@ -27,9 +28,21 @@ class UsersController < ApplicationController
end
end
+ def edit
+ end
+
+ def update
+ if @user.update(existing_user_params)
+ redirect_to @user, notice: t(".success")
+ else
+ flash.now[:alert] = t(".error")
+ render :edit, status: :unprocessable_entity
+ end
+ end
+
private
- def user_params
+ def new_user_params
params.require(:user).permit(
:username,
:password,
@@ -40,7 +53,22 @@ class UsersController < ApplicationController
)
end
+ def existing_user_params
+ params.require(:user).permit(
+ :password,
+ :password_confirmation,
+ :password_challenge,
+ :first_name,
+ :last_name,
+ :profile,
+ )
+ end
+
def set_user
@user = User.find_by(username: params[:id])
end
+
+ def ensure_self
+ head :forbidden unless @user == Current.user || Current.user.admin?
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 8c59498..69486c0 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -5,6 +5,7 @@ class User < ApplicationRecord
has_many :owned_tables, foreign_key: :owner_id, class_name: "Table"
has_many :players, dependent: :destroy
has_many :tables, through: :players
+ has_rich_text :profile
has_secure_password
generates_token_for :password_reset, expires_in: 4.hours do
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index a006677..80c3783 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -19,6 +19,7 @@
<% if logged_in? %>
- <%= link_to t(".tables"), tables_path %>
+ - <%= link_to t(".profile"), user_path(Current.user) %>
- <%= link_to t("log_out"), logout_path, data: {turbo_method: :delete} %>
<% if Current.user.admin? %>
- <%= link_to t("administration"), admin_index_path %>
diff --git a/app/views/users/_form.html.erb b/app/views/users/_form.html.erb
index fbc298e..f469edd 100644
--- a/app/views/users/_form.html.erb
+++ b/app/views/users/_form.html.erb
@@ -3,7 +3,7 @@
<%= form_with model: user do |f| %>
<%= f.label :username %>
- <%= f.text_field :username, required: true %>
+ <%= f.text_field :username, required: true, disabled: user.persisted? %>
<%= display_form_errors(user, :username) %>
<%= f.label :first_name %>
@@ -15,16 +15,34 @@
<%= display_form_errors(user, :last_name) %>
<%= f.label :email %>
- <%= f.text_field :email, required: true %>
+ <%= f.text_field :email, required: true, disabled: user.persisted? %>
<%= display_form_errors(user, :email) %>
- <%= f.label :password %>
- <%= f.password_field :password, required: true %>
- <%= display_form_errors(user, :password) %>
+
+
+ <% if user.persisted? %>
+ <%= f.label :profile %>
+ <%= f.rich_text_area :profile %>
+ <%= display_form_errors(user, :profile) %>
+ <% end %>
<%= f.submit button_text %>
<% end %>
diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb
new file mode 100644
index 0000000..dce3cfd
--- /dev/null
+++ b/app/views/users/edit.html.erb
@@ -0,0 +1,6 @@
+<% content_for :title, t(".edit_profile") %>
+
+<%= t(".edit_profile") %>
+
+<%= render partial: "users/form",
+ locals: { user: @user, button_text: t(".update_profile") } %>
diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb
index 313266b..467d4dd 100644
--- a/app/views/users/show.html.erb
+++ b/app/views/users/show.html.erb
@@ -2,6 +2,13 @@
<%= @user.username %>
-<% if @user == Current.user && @table_invites.any? %>
- <%= link_to t(".your_invites"), table_invites_path %>
-<% end %>
+
+
+<%= @user.profile %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 72f1cde..ce794e3 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -15,6 +15,7 @@ en:
game_systems: Game Systems
jobs: Jobs
application:
+ profile: Profile
tables: Tables
mailer:
greeting: "Hi %{name},"
@@ -130,6 +131,17 @@ en:
success: "Thanks for joining Tabletop Companion, %{name}! Please check your email to verify your address."
show:
your_invites: Your invites
+ edit_profile: Edit profile
+ edit:
+ edit_profile: Edit profile
+ update_profile: Update profile
+ form:
+ password: Password
+ password_hint: To keep your existing password, leave the below fields blank
+ current_password: Current password
+ update:
+ success: Your profile has been updated
+ error: Failed to update profile
user_mailer:
email_verified:
content: |-
diff --git a/config/routes.rb b/config/routes.rb
index cf59c74..1dc2a8c 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -8,7 +8,7 @@ Rails.application.routes.draw do
get "login" => "sessions#new", as: :login
delete "logout" => "sessions#destroy", as: :logout
- resources :users, only: [ :new, :create, :show ]
+ resources :users, only: [ :new, :create, :show, :edit, :update ]
resources :account_verifications, only: [ :show ]
resources :sessions, only: [ :new, :create, :destroy ]
diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb
index 9a71861..ebc3eed 100644
--- a/test/controllers/users_controller_test.rb
+++ b/test/controllers/users_controller_test.rb
@@ -34,6 +34,24 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
assert_response :unprocessable_entity
end
+ test "should get edit" do
+ sign_in users(:trevor)
+ get edit_user_url(users(:trevor))
+ assert_response :success
+ end
+
+ test "can only edit own user" do
+ sign_in users(:trevor)
+ get edit_user_url(users(:gimli))
+ assert_response :forbidden
+ end
+
+ test "should update user" do
+ sign_in users(:trevor)
+ patch user_url(users(:trevor)), params: { user: { profile: "All about me" } }
+ assert_redirected_to user_path(users(:trevor))
+ end
+
private
def user_params
diff --git a/test/fixtures/action_text/rich_texts.yml b/test/fixtures/action_text/rich_texts.yml
index 8b371ea..6ae16f0 100644
--- a/test/fixtures/action_text/rich_texts.yml
+++ b/test/fixtures/action_text/rich_texts.yml
@@ -1,4 +1,4 @@
-# one:
-# record: name_of_fixture (ClassOfFixture)
-# name: content
-# body: In a million stars!
+one:
+ record: trevor (User)
+ name: profile
+ body: I am just so awesome