diff --git a/.gitignore b/.gitignore
index f92525c..1303e39 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,6 @@
# Ignore master key for decrypting credentials and more.
/config/master.key
+
+/app/assets/builds/*
+!/app/assets/builds/.keep
diff --git a/Gemfile b/Gemfile
index a4ada41..8f5fd92 100644
--- a/Gemfile
+++ b/Gemfile
@@ -5,7 +5,8 @@ gem "rails", "~> 8.0.1"
# The modern asset pipeline for Rails [https://github.com/rails/propshaft]
gem "propshaft"
# Use postgresql as the database for Active Record
-gem "pg", "~> 1.1"
+# gem "pg", "~> 1.1"
+gem "sqlite3"
# Use the Puma web server [https://github.com/puma/puma]
gem "puma", ">= 5.0"
# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails]
@@ -61,3 +62,7 @@ group :test do
gem "capybara"
gem "selenium-webdriver"
end
+
+gem "devise", "~> 4.9"
+
+gem "tailwindcss-rails", "~> 3.2"
diff --git a/Gemfile.lock b/Gemfile.lock
index f36d8ab..9197ce6 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -76,6 +76,7 @@ GEM
public_suffix (>= 2.0.2, < 7.0)
ast (2.4.2)
base64 (0.2.0)
+ bcrypt (3.1.20)
bcrypt_pbkdf (1.1.1)
benchmark (0.4.0)
bigdecimal (3.1.9)
@@ -101,6 +102,12 @@ GEM
debug (1.10.0)
irb (~> 1.10)
reline (>= 0.3.8)
+ devise (4.9.4)
+ bcrypt (~> 3.0)
+ orm_adapter (~> 0.1)
+ railties (>= 4.1.0)
+ responders
+ warden (~> 1.2.3)
dotenv (3.1.7)
drb (2.2.1)
ed25519 (1.3.0)
@@ -178,12 +185,12 @@ GEM
racc (~> 1.4)
nokogiri (1.18.1-x86_64-linux-musl)
racc (~> 1.4)
+ orm_adapter (0.5.0)
ostruct (0.6.1)
parallel (1.26.3)
parser (3.3.6.0)
ast (~> 2.4.1)
racc
- pg (1.5.9)
propshaft (1.1.0)
actionpack (>= 7.0.0)
activesupport (>= 7.0.0)
@@ -241,6 +248,9 @@ GEM
regexp_parser (2.10.0)
reline (0.6.0)
io-console (~> 0.5)
+ responders (3.1.1)
+ actionpack (>= 5.2)
+ railties (>= 5.2)
rexml (3.4.0)
rubocop (1.69.2)
json (~> 2.3)
@@ -295,6 +305,12 @@ GEM
fugit (~> 1.11.0)
railties (>= 7.1)
thor (~> 1.3.1)
+ sqlite3 (2.5.0-aarch64-linux-gnu)
+ sqlite3 (2.5.0-aarch64-linux-musl)
+ sqlite3 (2.5.0-arm-linux-gnu)
+ sqlite3 (2.5.0-arm-linux-musl)
+ sqlite3 (2.5.0-x86_64-linux-gnu)
+ sqlite3 (2.5.0-x86_64-linux-musl)
sshkit (1.23.2)
base64
net-scp (>= 1.1.2)
@@ -304,6 +320,12 @@ GEM
stimulus-rails (1.3.4)
railties (>= 6.0.0)
stringio (3.1.2)
+ tailwindcss-rails (3.2.0)
+ railties (>= 7.0.0)
+ tailwindcss-ruby
+ tailwindcss-ruby (3.4.17-aarch64-linux)
+ tailwindcss-ruby (3.4.17-arm-linux)
+ tailwindcss-ruby (3.4.17-x86_64-linux)
thor (1.3.2)
thruster (0.1.10)
thruster (0.1.10-aarch64-linux)
@@ -319,6 +341,8 @@ GEM
unicode-emoji (4.0.4)
uri (1.0.2)
useragent (0.16.11)
+ warden (1.2.9)
+ rack (>= 2.0.9)
web-console (4.2.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
@@ -348,10 +372,10 @@ DEPENDENCIES
brakeman
capybara
debug
+ devise (~> 4.9)
importmap-rails
jbuilder
kamal
- pg (~> 1.1)
propshaft
puma (>= 5.0)
rails (~> 8.0.1)
@@ -360,7 +384,9 @@ DEPENDENCIES
solid_cable
solid_cache
solid_queue
+ sqlite3
stimulus-rails
+ tailwindcss-rails (~> 3.2)
thruster
turbo-rails
tzinfo-data
diff --git a/app/assets/images/.keep b/app/assets/images/.keep
deleted file mode 100644
index e69de29..0000000
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
deleted file mode 100644
index fe93333..0000000
--- a/app/assets/stylesheets/application.css
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * This is a manifest file that'll be compiled into application.css.
- *
- * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
- * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
- * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
- * depending on specificity.
- *
- * Consider organizing styles into separate files for maintainability.
- */
diff --git a/app/controllers/blog_posts_controller.rb b/app/controllers/blog_posts_controller.rb
index 8a0990b..de3dcab 100644
--- a/app/controllers/blog_posts_controller.rb
+++ b/app/controllers/blog_posts_controller.rb
@@ -1,12 +1,12 @@
class BlogPostsController < ApplicationController
+ before_action :authenticate_user!, except: [ :index, :show ]
+ before_action :set_blog_post, except: [ :index, :new, :create ] # only: [ :show, :edit, :update, :destroy ]
+
def index
@blog_posts = BlogPost.all
end
def show
- @blog_post = BlogPost.find(params[:id])
- rescue ActiveRecord::RecordNotFound
- redirect_to root_path
end
def new
@@ -14,7 +14,6 @@ def new
end
def create
- @blog_post = BlogPost.new(blog_post_params)
if @blog_post.save
redirect_to @blog_post
else
@@ -23,11 +22,9 @@ def create
end
def edit
- @blog_post = BlogPost.find(params[:id])
end
def update
- @blog_post = BlogPost.find(params[:id])
if @blog_post.update(blog_post_params)
redirect_to @blog_post
else
@@ -35,9 +32,20 @@ def update
end
end
+ def destroy
+ @blog_post.destroy
+ redirect_to root_path
+ end
+
private
def blog_post_params
params.require(:blog_post).permit(:title, :body)
end
+
+ def set_blog_post
+ @blog_post = BlogPost.find(params[:id])
+ rescue ActiveRecord::RecordNotFound
+ redirect_to root_path
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 4756799..e50fa94 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,6 +1,6 @@
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
- devise :database_authenticatable, :registerable,
+ devise :database_authenticatable,
:recoverable, :rememberable, :validatable
end
diff --git a/app/views/blog_posts/edit.html.erb b/app/views/blog_posts/edit.html.erb
index 9eaadc6..3aa9507 100644
--- a/app/views/blog_posts/edit.html.erb
+++ b/app/views/blog_posts/edit.html.erb
@@ -1,3 +1,5 @@
Edit blog post
-<%= render partial: "form", locals: {blog_post: @blog_post} %>
\ No newline at end of file
+<%= render partial: "form", locals: {blog_post: @blog_post} %>
+
+<%= button_to "Delete", @blog_post, method: :delete, data: {turbo_confirm: "Are you sure?"} %>
\ No newline at end of file
diff --git a/app/views/blog_posts/show.html.erb b/app/views/blog_posts/show.html.erb
index 3ca57ef..2b17d13 100644
--- a/app/views/blog_posts/show.html.erb
+++ b/app/views/blog_posts/show.html.erb
@@ -1,2 +1,3 @@
+<%= link_to "Edit", edit_blog_post_path(@blog_post) if user_signed_in? %>
<%= @blog_post.title %>
<%= @blog_post.body %>
\ No newline at end of file
diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb
new file mode 100644
index 0000000..0da540e
--- /dev/null
+++ b/app/views/devise/confirmations/new.html.erb
@@ -0,0 +1,16 @@
+
+<% end %>
+
+<%= render "devise/shared/links" %>
\ No newline at end of file
diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb
new file mode 100644
index 0000000..c2b058f
--- /dev/null
+++ b/app/views/devise/mailer/confirmation_instructions.html.erb
@@ -0,0 +1,5 @@
+
Welcome <%= @email %>!
+
+
You can confirm your account email through the link below:
+
+
<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>
\ No newline at end of file
diff --git a/app/views/devise/mailer/email_changed.html.erb b/app/views/devise/mailer/email_changed.html.erb
new file mode 100644
index 0000000..268be2d
--- /dev/null
+++ b/app/views/devise/mailer/email_changed.html.erb
@@ -0,0 +1,7 @@
+
Hello <%= @email %>!
+
+<% if @resource.try(:unconfirmed_email?) %>
+
We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.
+<% else %>
+
We're contacting you to notify you that your email has been changed to <%= @resource.email %>.
+<% end %>
\ No newline at end of file
diff --git a/app/views/devise/mailer/password_change.html.erb b/app/views/devise/mailer/password_change.html.erb
new file mode 100644
index 0000000..1070cff
--- /dev/null
+++ b/app/views/devise/mailer/password_change.html.erb
@@ -0,0 +1,3 @@
+
Hello <%= @resource.email %>!
+
+
We're contacting you to notify you that your password has been changed.
\ No newline at end of file
diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb
new file mode 100644
index 0000000..7bc3a70
--- /dev/null
+++ b/app/views/devise/mailer/reset_password_instructions.html.erb
@@ -0,0 +1,8 @@
+
Hello <%= @resource.email %>!
+
+
Someone has requested a link to change your password. You can do this through the link below.
+
+
<%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>
+
+
If you didn't request this, please ignore this email.
+
Your password won't change until you access the link above and create a new one.
\ No newline at end of file
diff --git a/app/views/devise/mailer/unlock_instructions.html.erb b/app/views/devise/mailer/unlock_instructions.html.erb
new file mode 100644
index 0000000..5aefc91
--- /dev/null
+++ b/app/views/devise/mailer/unlock_instructions.html.erb
@@ -0,0 +1,7 @@
+
Hello <%= @resource.email %>!
+
+
Your account has been locked due to an excessive number of unsuccessful sign in attempts.
+
+
Click the link below to unlock your account:
+
+
<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>
\ No newline at end of file
diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb
new file mode 100644
index 0000000..729772f
--- /dev/null
+++ b/app/views/devise/passwords/edit.html.erb
@@ -0,0 +1,25 @@
+
+<% end %>
+
+<%= render "devise/shared/links" %>
\ No newline at end of file
diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb
new file mode 100644
index 0000000..2b136d8
--- /dev/null
+++ b/app/views/devise/passwords/new.html.erb
@@ -0,0 +1,16 @@
+
+ <%= f.submit "Send me reset password instructions" %>
+
+<% end %>
+
+<%= render "devise/shared/links" %>
\ No newline at end of file
diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb
new file mode 100644
index 0000000..5a61a2d
--- /dev/null
+++ b/app/views/devise/registrations/edit.html.erb
@@ -0,0 +1,43 @@
+
+ <%= f.label :current_password %> (we need your current password to confirm your changes)
+ <%= f.password_field :current_password, autocomplete: "current-password" %>
+
+
+
+ <%= f.submit "Update" %>
+
+<% end %>
+
+
Cancel my account
+
+
Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?", turbo_confirm: "Are you sure?" }, method: :delete %>
+
+<%= link_to "Back", :back %>
\ No newline at end of file
diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb
new file mode 100644
index 0000000..e6bd5a7
--- /dev/null
+++ b/app/views/devise/registrations/new.html.erb
@@ -0,0 +1,29 @@
+
+<% end %>
+
+<%= render "devise/shared/links" %>
\ No newline at end of file
diff --git a/app/views/devise/shared/_error_messages.html.erb b/app/views/devise/shared/_error_messages.html.erb
new file mode 100644
index 0000000..db8dba6
--- /dev/null
+++ b/app/views/devise/shared/_error_messages.html.erb
@@ -0,0 +1,15 @@
+<% if resource.errors.any? %>
+