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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@

# Ignore master key for decrypting credentials and more.
/config/master.key

/app/assets/builds/*
!/app/assets/builds/.keep
7 changes: 6 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -61,3 +62,7 @@ group :test do
gem "capybara"
gem "selenium-webdriver"
end

gem "devise", "~> 4.9"

gem "tailwindcss-rails", "~> 3.2"
30 changes: 28 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -360,7 +384,9 @@ DEPENDENCIES
solid_cable
solid_cache
solid_queue
sqlite3
stimulus-rails
tailwindcss-rails (~> 3.2)
thruster
turbo-rails
tzinfo-data
Expand Down
Empty file removed app/assets/images/.keep
Empty file.
10 changes: 0 additions & 10 deletions app/assets/stylesheets/application.css

This file was deleted.

20 changes: 14 additions & 6 deletions app/controllers/blog_posts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
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
@blog_post = BlogPost.new
end

def create
@blog_post = BlogPost.new(blog_post_params)
if @blog_post.save
redirect_to @blog_post
else
Expand All @@ -23,21 +22,30 @@ 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
render :edit, status: :unprocessable_entity
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
2 changes: 1 addition & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
@@ -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
4 changes: 3 additions & 1 deletion app/views/blog_posts/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<h1>Edit blog post</h1>

<%= render partial: "form", locals: {blog_post: @blog_post} %>
<%= render partial: "form", locals: {blog_post: @blog_post} %>

<%= button_to "Delete", @blog_post, method: :delete, data: {turbo_confirm: "Are you sure?"} %>
1 change: 1 addition & 0 deletions app/views/blog_posts/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
<%= link_to "Edit", edit_blog_post_path(@blog_post) if user_signed_in? %>
<h1><%= @blog_post.title %></h1>
<%= @blog_post.body %>
16 changes: 16 additions & 0 deletions app/views/devise/confirmations/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<h2>Resend confirmation instructions</h2>

<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
</div>

<div class="actions">
<%= f.submit "Resend confirmation instructions" %>
</div>
<% end %>

<%= render "devise/shared/links" %>
5 changes: 5 additions & 0 deletions app/views/devise/mailer/confirmation_instructions.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<p>Welcome <%= @email %>!</p>

<p>You can confirm your account email through the link below:</p>

<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>
7 changes: 7 additions & 0 deletions app/views/devise/mailer/email_changed.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<p>Hello <%= @email %>!</p>

<% if @resource.try(:unconfirmed_email?) %>
<p>We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.</p>
<% else %>
<p>We're contacting you to notify you that your email has been changed to <%= @resource.email %>.</p>
<% end %>
3 changes: 3 additions & 0 deletions app/views/devise/mailer/password_change.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<p>Hello <%= @resource.email %>!</p>

<p>We're contacting you to notify you that your password has been changed.</p>
8 changes: 8 additions & 0 deletions app/views/devise/mailer/reset_password_instructions.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<p>Hello <%= @resource.email %>!</p>

<p>Someone has requested a link to change your password. You can do this through the link below.</p>

<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>

<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>
7 changes: 7 additions & 0 deletions app/views/devise/mailer/unlock_instructions.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<p>Hello <%= @resource.email %>!</p>

<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>

<p>Click the link below to unlock your account:</p>

<p><%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %></p>
25 changes: 25 additions & 0 deletions app/views/devise/passwords/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<h2>Change your password</h2>

<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<%= f.hidden_field :reset_password_token %>

<div class="field">
<%= f.label :password, "New password" %><br />
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em><br />
<% end %>
<%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
</div>

<div class="field">
<%= f.label :password_confirmation, "Confirm new password" %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>

<div class="actions">
<%= f.submit "Change my password" %>
</div>
<% end %>

<%= render "devise/shared/links" %>
16 changes: 16 additions & 0 deletions app/views/devise/passwords/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<h2>Forgot your password?</h2>

<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>

<div class="actions">
<%= f.submit "Send me reset password instructions" %>
</div>
<% end %>

<%= render "devise/shared/links" %>
43 changes: 43 additions & 0 deletions app/views/devise/registrations/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<h2>Edit <%= resource_name.to_s.humanize %></h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>

<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>

<div class="field">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "new-password" %>
<% if @minimum_password_length %>
<br />
<em><%= @minimum_password_length %> characters minimum</em>
<% end %>
</div>

<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>

<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "current-password" %>
</div>

<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>

<h3>Cancel my account</h3>

<div>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?", turbo_confirm: "Are you sure?" }, method: :delete %></div>

<%= link_to "Back", :back %>
29 changes: 29 additions & 0 deletions app/views/devise/registrations/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email", class: "border" %>
</div>

<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "new-password", class: "border" %>
</div>

<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password", class: "border" %>
</div>

<div class="actions">
<%= f.submit "Sign up!", class: "bg-gray-100 px-4 py-1 rounded hover:bg-gray-200" %>
</div>
<% end %>

<%= render "devise/shared/links" %>
Loading
Loading