Skip to content

Commit

Permalink
Back-end profile improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio-e committed Jul 22, 2024
1 parent 2025e60 commit f8bb1b4
Show file tree
Hide file tree
Showing 15 changed files with 120 additions and 103 deletions.
3 changes: 0 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ gem "tailwindcss-rails", "~> 2.6"
gem "stimulus-rails"
gem "turbo-rails"

# Authorization
gem "action_policy", "~> 0.7.0"

# Authentication
gem "bcrypt", "~> 3.1.20"

Expand Down
29 changes: 17 additions & 12 deletions app/controllers/profiles_controller.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
class ProfilesController < ApplicationController
def show
@profile = current_user.profile
@profile = current_profile
end

def edit
@profile = current_user.profile || Profile.new
@profile = current_profile
end

def update
if current_user.profile.nil?
current_user.profile = Profile.new(profile_params)
current_user.save!
@profile = current_profile
@profile.assign_attributes(profile_params)

if @profile.save
redirect_to profile_path, notice: t("controllers.profiles.update.success")
else
current_user.profile.update!(profile_params)
# TODO display errors
render :edit, status: :unprocessable_entity
end
current_user.update!(notifications_params)
redirect_to profile_path, notice: t("controllers.profiles.update.success")
end

private

def profile_params
params.permit(:name, :location, :bio, :is_public, :twitter_url, :linkedin_url, :github_url, :image)
def current_profile
current_user.profile || current_user.build_profile
end

def notifications_params
params.permit(:in_app_notifications_enabled, :mail_notifications_enabled)
def profile_params
params.require(:profile).permit(
:name, :location, :bio, :is_public, :image,
:twitter_url, :linkedin_url, :github_url,
:in_app_notifications, :mail_notifications
)
end
end
31 changes: 16 additions & 15 deletions app/models/profile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,30 @@
#
# Table name: profiles
#
# id :integer not null, primary key
# bio :string
# github_url :string
# is_public :boolean default(FALSE), not null
# linkedin_url :string
# location :string
# name :string
# profileable_type :string not null
# twitter_url :string
# created_at :datetime not null
# updated_at :datetime not null
# profileable_id :integer not null
# id :integer not null, primary key
# bio :text
# github_url :string
# in_app_notifications :boolean default(TRUE), not null
# is_public :boolean default(FALSE), not null
# linkedin_url :string
# location :string
# mail_notifications :boolean default(TRUE), not null
# name :string
# profileable_type :string not null
# twitter_url :string
# created_at :datetime not null
# updated_at :datetime not null
# profileable_id :integer not null
#
# Indexes
#
# index_profiles_on_profileable (profileable_type,profileable_id)
#
class Profile < ApplicationRecord
belongs_to :profileable, polymorphic: true
has_one_attached :image

has_one :self_ref, class_name: "Profile", foreign_key: :id, inverse_of: :self_ref, dependent: :destroy
has_one :user, through: :self_ref, source: :profileable, source_type: "User"
has_one :speaker, through: :self_ref, source: :profileable, source_type: "Speaker"

has_one_attached :image
belongs_to :profileable, polymorphic: true
end
22 changes: 11 additions & 11 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
#
# Table name: users
#
# id :integer not null, primary key
# email :string not null
# in_app_notifications_enabled :boolean default(TRUE), not null
# mail_notifications_enabled :boolean default(TRUE), not null
# password_digest :string not null
# role :string
# created_at :datetime not null
# updated_at :datetime not null
# id :integer not null, primary key
# email :string not null
# password_digest :string not null
# role :string
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
Expand All @@ -20,6 +18,10 @@ class User < ApplicationRecord

normalizes :email, with: ->(email) { email.strip.downcase }

generates_token_for :password_reset, expires_in: PASSWORD_RESET_EXPIRATION do
password_salt&.last(10)
end

has_secure_password

has_one :profile, as: :profileable, dependent: :destroy
Expand All @@ -30,7 +32,5 @@ class User < ApplicationRecord
validates :password_digest, presence: true
validates :password, length: {minimum: 8}, if: -> { password.present? }

generates_token_for :password_reset, expires_in: PASSWORD_RESET_EXPIRATION do
password_salt&.last(10)
end
after_create_commit { create_profile! }
end
1 change: 1 addition & 0 deletions app/views/main/index.html.erb
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<h1>Homepage</h1>
<%= link_to "Profile", profile_path %>
29 changes: 15 additions & 14 deletions app/views/profiles/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="bg-purple flex flex-col bg-slate-500 p-4 w-full bg-violet-800 border-t b-white">
<h1 class="text-4xl text-white mb-6 font-black w-full">Set up your account</h1>

<%= form_with url: profile_path, class: "flex flex-col items-center", method: :put do |form| %>
<%= form_with url: profile_path, scope: :profile, class: "flex flex-col items-center", method: :put do |form| %>
<%= form.label :image, data: {controller: "image-previewer", }, class: "overflow-hidden relative font-bold text-white text-base w-32 h-32 bg-white cursor-pointer rounded-full flex flex-col items-center justify-center" do %>
<%= form.file_field :image, data: {image_previewer_target: "input"}, class: "text-white border-2 border-white bg-transparent rounded-sm hidden mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>
<% if @profile.image.present? %>
Expand All @@ -12,30 +12,31 @@
<%= image_tag "", data: {image_previewer_target: "image"}, class: "hidden absolute" %>
<% end %>
<div class="flex flex-col items-start w-full w-full">
<%= form.label :bio, class: "font-bold text-white text-base" %>
<%= form.text_area :bio, value: @profile.bio,class: "w-full text-white border-2 border-white bg-transparent rounded-sm mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>

<div class="flex flex-col items-start w-full w-full">
<%= form.label :name, class: "font-bold text-white text-base" %>
<%= form.text_field :name, value: @profile.name, class: "w-full text-white border-2 border-white bg-transparent rounded-sm mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>
<%= form.text_field :name, class: "w-full text-white border-2 border-white bg-transparent rounded-sm mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>
<%= form.label :bio, class: "font-bold text-white text-base" %>
<%= form.text_area :bio, class: "w-full text-white border-2 border-white bg-transparent rounded-sm mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>
<%= form.label :location, class: "font-bold text-white text-base" %>
<%= form.text_field :location, value: @profile.location, class: "w-full text-white border-2 border-white bg-transparent rounded-sm mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>
<%= form.text_field :location, class: "w-full text-white border-2 border-white bg-transparent rounded-sm mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>
<%= form.label :github_url, class: "font-bold text-white text-base" %>
<%= form.text_field :github_url, value: @profile.github_url, class: "w-full text-white border-2 border-white bg-transparent rounded-sm mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>
<%= form.text_field :github_url, class: "w-full text-white border-2 border-white bg-transparent rounded-sm mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>
<%= form.label :linkedin_url, class: "font-bold text-white text-base" %>
<%= form.text_field :linkedin_url, value: @profile.linkedin_url, class: "w-full text-white border-2 border-white bg-transparent rounded-sm mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>
<%= form.text_field :linkedin_url, class: "w-full text-white border-2 border-white bg-transparent rounded-sm mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>
<%= form.label :twitter_url, class: "font-bold text-white text-base" %>
<%= form.text_field :twitter_url, value: @profile.twitter_url, class: "w-full text-white border-2 border-white bg-transparent rounded-sm mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>
<%= form.text_field :twitter_url, class: "w-full text-white border-2 border-white bg-transparent rounded-sm mb-6 focus:outline-none focus:outline-0 focus:ring-0 focus:border-2 focus:border-white active:border-2 active:border-white" %>

<p class="text-white font-bold">Discoverability</p>
<div class="flex flex-row items-center bg-white justify-between rounded-md w-full p-4">
<%= form.label :is_public, "Public profile", class: "grow font-medium text-slate-900 text-base cursor-pointer mr-2" %>
<label class="inline-flex items-center cursor-pointer">
<%= form.check_box :is_public, checked: @profile.is_public || false, class: "sr-only peer" %>
<%= form.check_box :is_public, class: "sr-only peer" %>
<div class="relative w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-red-300 dark:peer-focus:ring-red-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-red-600"></div>
</label>
</div>
Expand All @@ -44,16 +45,16 @@
<p class="text-white font-bold">Notifications</p>
<div class="rounded-md w-full overflow-hidden mb-10">
<div class="flex flex-row items-center bg-white justify-between w-full p-4">
<%= form.label :mail_notifications_enabled, "Mail Notifications", class: "grow font-medium text-slate-900 text-base cursor-pointer mr-2" %>
<%= form.label :mail_notifications, "Mail", class: "grow font-medium text-slate-900 text-base cursor-pointer mr-2" %>
<label class="inline-flex items-center cursor-pointer">
<%= form.check_box :mail_notifications_enabled, checked: current_user.mail_notifications_enabled || false, class: "sr-only peer" %>
<%= form.check_box :mail_notifications, class: "sr-only peer" %>
<div class="relative w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-red-300 dark:peer-focus:ring-red-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-red-600"></div>
</label>
</div>
<div class="flex flex-row items-center bg-white justify-between w-full p-4">
<%= form.label :in_app_notifications_enabled, "In app Notifications", class: "grow font-medium text-slate-900 text-base cursor-pointer mr-2" %>
<%= form.label :in_app_notifications, "In app", class: "grow font-medium text-slate-900 text-base cursor-pointer mr-2" %>
<label class="inline-flex items-center cursor-pointer">
<%= form.check_box :in_app_notifications_enabled, checked: current_user.in_app_notifications_enabled || false, class: "sr-only peer" %>
<%= form.check_box :in_app_notifications, class: "sr-only peer" %>
<div class="relative w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-red-300 dark:peer-focus:ring-red-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-red-600"></div>
</label>
</div>
Expand Down
3 changes: 1 addition & 2 deletions app/views/profiles/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

<div class="flex flex-col items-start bg-indigo-300 relative min-h-screen justify-between ">
<div class="bg-cover bg-bottom bg-no-repeat h-[430px] w-full pt-6 px-5 pb-12" style="background-image: url(<%= asset_path 'background_design.svg' %>)">
<div class="flex flex-col items-start z-10">
Expand Down Expand Up @@ -30,6 +29,6 @@
</div>
</div>
<div class="p-4 flex flex-col items-center gap-4 w-full">
<%= link_to 'EDIT PROFILE', edit_profile_path, class: "w-full bg-white text-red-500 font-bold rounded-sm p-4 rounded-lg grow flex flex-row items-center justify-center" %>
<%= link_to 'EDIT PROFILE', edit_profile_path, class: "w-full bg-white text-red-500 font-bold rounded-sm p-4 rounded-lg grow flex flex-row items-center justify-center" %>
</div>
</div>
4 changes: 3 additions & 1 deletion db/migrate/20240628210301_create_profiles.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ class CreateProfiles < ActiveRecord::Migration[7.1]
def change
create_table :profiles do |t|
t.string :name
t.string :bio
t.text :bio
t.string :location
t.string :github_url
t.string :linkedin_url
t.string :twitter_url
t.boolean :mail_notifications, default: true, null: false
t.boolean :in_app_notifications, default: true, null: false
t.boolean :is_public, default: false, null: false
t.references :profileable, polymorphic: true, null: false

Expand Down
2 changes: 0 additions & 2 deletions db/migrate/20240628211820_create_users.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ def change
create_table :users do |t|
t.string :email, null: false
t.string :role
t.boolean :mail_notifications_enabled, default: true, null: false
t.boolean :in_app_notifications_enabled, default: true, null: false
t.string :password_digest, null: false

t.timestamps
Expand Down
6 changes: 3 additions & 3 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

# Users
user = User.create!(email: "dev@example.com", password: "foobar2024", password_confirmation: "foobar2024")
User.create!(email: "dev+1@example.com", password: "foobar2024", password_confirmation: "foobar2024")

# Profiles
user.create_profile!(
name: "John Doe",
bio: "I'm a Ruby on Rails developer.",
is_public: true,
mail_notifications: true,
in_app_notifications: true,
github_url: "https://github.com/TelosLabs",
twitter_url: "https://x.com/teloslabs",
linkedin_url: "https://www.linkedin.com/company/telos-labs"
)

# Tags
Tag.create!(name: "Hotwire")
Expand Down
26 changes: 14 additions & 12 deletions spec/factories/profiles.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@
#
# Table name: profiles
#
# id :integer not null, primary key
# bio :string
# github_url :string
# is_public :boolean default(FALSE), not null
# linkedin_url :string
# location :string
# name :string
# profileable_type :string not null
# twitter_url :string
# created_at :datetime not null
# updated_at :datetime not null
# profileable_id :integer not null
# id :integer not null, primary key
# bio :text
# github_url :string
# in_app_notifications :boolean default(TRUE), not null
# is_public :boolean default(FALSE), not null
# linkedin_url :string
# location :string
# mail_notifications :boolean default(TRUE), not null
# name :string
# profileable_type :string not null
# twitter_url :string
# created_at :datetime not null
# updated_at :datetime not null
# profileable_id :integer not null
#
# Indexes
#
Expand Down
14 changes: 6 additions & 8 deletions spec/factories/users.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
#
# Table name: users
#
# id :integer not null, primary key
# email :string not null
# in_app_notifications_enabled :boolean default(TRUE), not null
# mail_notifications_enabled :boolean default(TRUE), not null
# password_digest :string not null
# role :string
# created_at :datetime not null
# updated_at :datetime not null
# id :integer not null, primary key
# email :string not null
# password_digest :string not null
# role :string
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
Expand Down
26 changes: 14 additions & 12 deletions spec/models/profile_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@
#
# Table name: profiles
#
# id :integer not null, primary key
# bio :string
# github_url :string
# is_public :boolean default(FALSE), not null
# linkedin_url :string
# location :string
# name :string
# profileable_type :string not null
# twitter_url :string
# created_at :datetime not null
# updated_at :datetime not null
# profileable_id :integer not null
# id :integer not null, primary key
# bio :text
# github_url :string
# in_app_notifications :boolean default(TRUE), not null
# is_public :boolean default(FALSE), not null
# linkedin_url :string
# location :string
# mail_notifications :boolean default(TRUE), not null
# name :string
# profileable_type :string not null
# twitter_url :string
# created_at :datetime not null
# updated_at :datetime not null
# profileable_id :integer not null
#
# Indexes
#
Expand Down
Loading

0 comments on commit f8bb1b4

Please sign in to comment.