diff --git a/Gemfile b/Gemfile
index 7abd44d7a..3f73b8103 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,6 +1,11 @@
source "https://rubygems.org"
-ruby "3.2.3"
+# Temporary fix: Could not instal ruby 3.2.3
+# Using ruby 3.3.0
+ruby ">=3.2.3"
+
+# Added devise for User model and authentication
+gem 'devise'
# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.1.2"
diff --git a/Gemfile.lock b/Gemfile.lock
index ac898c77c..d21ebe4aa 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -78,6 +78,7 @@ GEM
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
base64 (0.2.0)
+ bcrypt (3.1.20)
bigdecimal (3.1.6)
bindex (0.8.1)
bootsnap (1.17.1)
@@ -99,6 +100,12 @@ GEM
debug (1.9.1)
irb (~> 1.10)
reline (>= 0.3.8)
+ devise (4.9.3)
+ bcrypt (~> 3.0)
+ orm_adapter (~> 0.1)
+ railties (>= 4.1.0)
+ responders
+ warden (~> 1.2.3)
drb (2.2.0)
ruby2_keywords
erubi (1.12.0)
@@ -153,6 +160,7 @@ GEM
racc (~> 1.4)
nokogiri (1.16.0-x86_64-linux)
racc (~> 1.4)
+ orm_adapter (0.5.0)
psych (5.1.2)
stringio
public_suffix (5.0.4)
@@ -202,6 +210,9 @@ GEM
regexp_parser (2.9.0)
reline (0.4.2)
io-console (~> 0.5)
+ responders (3.1.1)
+ actionpack (>= 5.2)
+ railties (>= 5.2)
rexml (3.2.6)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
@@ -233,6 +244,8 @@ GEM
railties (>= 6.0.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
+ warden (1.2.9)
+ rack (>= 2.0.9)
web-console (4.2.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
@@ -262,6 +275,7 @@ DEPENDENCIES
bootsnap
capybara
debug
+ devise
importmap-rails
jbuilder
puma (>= 5.0)
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index 288b9ab71..573ff04b9 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -13,3 +13,31 @@
*= require_tree .
*= require_self
*/
+
+ nav {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ height: 1in;
+ padding: 0 20px; /* Add padding for better spacing, adjust as needed */
+
+ /* Optional: If you want a background color for the nav bar */
+ background-color: #f0f0f0; /* Adjust color as needed */
+ }
+
+ #hiddenLink {
+ /* Styling for the Article Encyclopedia link */
+ text-decoration: none;
+ }
+
+ .nav-button {
+ /* Styling for all other nav buttons */
+ margin: 0 10px; /* Add margin for better spacing, adjust as needed */
+ text-decoration: none;
+ }
+
+ .larger-button {
+ /* Styling for the larger Article Encyclopedia link */
+ font-size: 1.2em; /* Adjust font size as needed */
+ text-decoration: none;
+ }
\ No newline at end of file
diff --git a/app/assets/stylesheets/article_search.css b/app/assets/stylesheets/article_search.css
new file mode 100644
index 000000000..05543f0ca
--- /dev/null
+++ b/app/assets/stylesheets/article_search.css
@@ -0,0 +1,59 @@
+body {
+ font-family: 'Arial', sans-serif;
+ background-color: #f8f8f8; /* Set background color */
+ color: #333; /* Set text color */
+ margin: 0;
+ padding: 20px;
+ }
+
+ h1 {
+ font-size: 24px;
+ margin-bottom: 20px;
+ }
+
+ form {
+ margin-bottom: 20px;
+ }
+
+ input[type="text"] {
+ width: 100%;
+ padding: 10px;
+ font-size: 16px;
+ margin-bottom: 10px;
+ box-sizing: border-box;
+ }
+
+ input[type="submit"] {
+ background-color: #007bff; /* Set button background color */
+ color: #fff; /* Set button text color */
+ padding: 10px 20px;
+ font-size: 16px;
+ cursor: pointer;
+ border: none;
+ }
+
+ input[type="submit"]:hover {
+ background-color: #0056b3; /* Change button color on hover */
+ }
+
+ #search-results {
+ margin-top: 20px;
+ }
+
+ #search-results p {
+ margin-bottom: 10px;
+ }
+
+ #search-results a {
+ color: #007bff; /* Set link color */
+ text-decoration: none;
+ }
+
+ #search-results a:hover {
+ text-decoration: underline;
+ }
+
+ #no-articles-found {
+ color: #888; /* Set color for the message when no articles are found */
+ }
+
\ No newline at end of file
diff --git a/app/assets/stylesheets/home.css b/app/assets/stylesheets/home.css
new file mode 100644
index 000000000..9403c4403
--- /dev/null
+++ b/app/assets/stylesheets/home.css
@@ -0,0 +1,29 @@
+body {
+ font-family: 'Arial', sans-serif;
+ background-color: #f8f8f8; /* Set background color */
+ color: #333; /* Set text color */
+ margin: 0;
+ padding: 20px;
+ }
+
+ h1 {
+ font-size: 36px;
+ color: #007bff; /* Set heading color */
+ margin-bottom: 20px;
+ }
+
+ p {
+ font-size: 18px;
+ line-height: 1.6;
+ margin-bottom: 20px;
+ }
+
+ a {
+ color: #007bff; /* Set link color */
+ text-decoration: none;
+ }
+
+ a:hover {
+ text-decoration: underline;
+ }
+
\ No newline at end of file
diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb
new file mode 100644
index 000000000..fa20badd5
--- /dev/null
+++ b/app/controllers/articles_controller.rb
@@ -0,0 +1,63 @@
+class ArticlesController < ApplicationController
+ before_action :authenticate_user!, only: [:article_repository]
+
+ def index
+ @articles = Article.all
+ end
+
+ def show
+ @article = Article.find(params[:id])
+ end
+
+ def new
+ @article = Article.new
+ end
+
+ def edit
+ @article = Article.find(params[:id])
+ end
+
+ def create
+ @article = Article.new(article_params)
+ if @article.save
+ redirect_to @article, notice: 'Article was successfully created.'
+ else
+ render :new, status: :unprocessable_entity
+ end
+ end
+
+ def update
+ @article = Article.find(params[:id])
+ if @article.update(article_params)
+ redirect_to article_url(@article), notice: "Article was successfully updated."
+ else
+ render :edit, status: :unprocessable_entity
+ end
+ end
+
+ def destroy
+ @article = Article.find(params[:id])
+ @article.destroy!
+ redirect_to article_repository_path, notice: "Article was successfully destroyed."
+ end
+
+ def article_repository
+ @user_articles = current_user.articles
+ end
+
+ def article_search
+ @search_query = params[:query]
+ begin
+ @search_results = Article.search(@search_query)
+ rescue ActiveRecord::RecordNotFound
+ flash[:alert] = "No articles found"
+ @search_results = []
+ end
+ end
+
+ private
+ # Only allow a list of trusted parameters through.
+ def article_params
+ params.require(:article).permit(:user_id, :title, :content, :author, :date)
+ end
+end
diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb
new file mode 100644
index 000000000..45f463e4c
--- /dev/null
+++ b/app/controllers/pages_controller.rb
@@ -0,0 +1,4 @@
+class PagesController < ApplicationController
+ def home
+ end
+end
diff --git a/app/helpers/articles_helper.rb b/app/helpers/articles_helper.rb
new file mode 100644
index 000000000..296827759
--- /dev/null
+++ b/app/helpers/articles_helper.rb
@@ -0,0 +1,2 @@
+module ArticlesHelper
+end
diff --git a/app/helpers/pages_helper.rb b/app/helpers/pages_helper.rb
new file mode 100644
index 000000000..2c057fd05
--- /dev/null
+++ b/app/helpers/pages_helper.rb
@@ -0,0 +1,2 @@
+module PagesHelper
+end
diff --git a/app/models/article.rb b/app/models/article.rb
new file mode 100644
index 000000000..82e300f02
--- /dev/null
+++ b/app/models/article.rb
@@ -0,0 +1,8 @@
+class Article < ApplicationRecord
+ belongs_to :user
+
+ def self.search(query)
+ where("title LIKE ? OR content LIKE ? OR author LIKE ? OR date LIKE ?",
+ "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%")
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
new file mode 100644
index 000000000..2331adacd
--- /dev/null
+++ b/app/models/user.rb
@@ -0,0 +1,7 @@
+class User < ApplicationRecord
+ has_many :articles
+ # Include default devise modules. Others available are:
+ # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
+ devise :database_authenticatable, :registerable,
+ :recoverable, :rememberable, :validatable
+end
diff --git a/app/views/articles/_article.html.erb b/app/views/articles/_article.html.erb
new file mode 100644
index 000000000..8a86dbbed
--- /dev/null
+++ b/app/views/articles/_article.html.erb
@@ -0,0 +1,23 @@
+
+
+
+ Title:
+ <%= article.title %>
+
+
+
+ Content:
+ <%= article.content %>
+
+
+
+ Author:
+ <%= article.author %>
+
+
+
+ Date:
+ <%= article.date %>
+
+
+
diff --git a/app/views/articles/_form.html.erb b/app/views/articles/_form.html.erb
new file mode 100644
index 000000000..fae374ffe
--- /dev/null
+++ b/app/views/articles/_form.html.erb
@@ -0,0 +1,39 @@
+<%= form_with(model: article) do |form| %>
+ <% if article.errors.any? %>
+
+
<%= pluralize(article.errors.count, "error") %> prohibited this article from being saved:
+
+
+ <% article.errors.each do |error| %>
+ <%= error.full_message %>
+ <% end %>
+
+
+ <% end %>
+
+ <%= form.hidden_field :user_id, value: current_user.id %>
+
+
+ <%= form.label :title, style: "display: block" %>
+ <%= form.text_field :title %>
+
+
+
+ <%= form.label :content, style: "display: block" %>
+ <%= form.text_area :content %>
+
+
+
+ <%= form.label :author, style: "display: block" %>
+ <%= form.text_field :author %>
+
+
+
+ <%= form.label :date, style: "display: block" %>
+ <%= form.date_field :date %>
+
+
+
+ <%= form.submit %>
+
+<% end %>
diff --git a/app/views/articles/article_repository.html.erb b/app/views/articles/article_repository.html.erb
new file mode 100644
index 000000000..504d5b388
--- /dev/null
+++ b/app/views/articles/article_repository.html.erb
@@ -0,0 +1,23 @@
+My Articles
+
+<% if @user_articles.any? %>
+
+ <% @user_articles.each do |article| %>
+
+ Title:
+ <%= article.title %>
+
+
+
+ Content:
+ <%= article.content %>
+
+
+
+ <%= link_to "Show this article", article %>
+
+ <% end %>
+
+<% else %>
+ Article repository is empty. No previous articles written.
+<% end %>
diff --git a/app/views/articles/article_search.html.erb b/app/views/articles/article_search.html.erb
new file mode 100644
index 000000000..8c4f2f8e7
--- /dev/null
+++ b/app/views/articles/article_search.html.erb
@@ -0,0 +1,25 @@
+Article Search
+
+<%= form_with(url: article_search_path, method: :get) do |form| %>
+ <%= form.text_field :query, placeholder: 'Search articles...' %>
+ <%= form.submit 'Search' %>
+<% end %>
+
+<%= form_with(url: article_search_path, method: :get) do |form| %>
+ <%= form.submit 'Clear Search', name: 'clear_search' %>
+<% end %>
+
+<% if params[:query].present? %>
+
+ <% if @search_results.any? %>
+ <% @search_results.each do |article| %>
+ <%= render article %>
+
+ <%= link_to "Show this article", article %>
+
+ <% end %>
+ <% else %>
+
No articles found.
+ <% end %>
+
+<% end %>
diff --git a/app/views/articles/edit.html.erb b/app/views/articles/edit.html.erb
new file mode 100644
index 000000000..4252d7a0e
--- /dev/null
+++ b/app/views/articles/edit.html.erb
@@ -0,0 +1,10 @@
+Editing article
+
+<%= render "form", article: @article %>
+
+
+
+
+ <%= link_to "Show this article", @article %> |
+ <%= link_to "Back to articles", articles_path %>
+
diff --git a/app/views/articles/index.html.erb b/app/views/articles/index.html.erb
new file mode 100644
index 000000000..54b0d0dcf
--- /dev/null
+++ b/app/views/articles/index.html.erb
@@ -0,0 +1,14 @@
+<%= notice %>
+
+Articles
+
+
+ <% @articles.each do |article| %>
+ <%= render article %>
+
+ <%= link_to "Show this article", article %>
+
+ <% end %>
+
+
+<%= link_to "New article", new_article_path %>
diff --git a/app/views/articles/new.html.erb b/app/views/articles/new.html.erb
new file mode 100644
index 000000000..dacaabc37
--- /dev/null
+++ b/app/views/articles/new.html.erb
@@ -0,0 +1,9 @@
+New article
+
+<%= render "form", article: @article %>
+
+
+
+
+ <%= link_to "Back to articles", article_repository_path %>
+
diff --git a/app/views/articles/show.html.erb b/app/views/articles/show.html.erb
new file mode 100644
index 000000000..1c7a64757
--- /dev/null
+++ b/app/views/articles/show.html.erb
@@ -0,0 +1,10 @@
+<%= notice %>
+
+<%= render @article %>
+
+
+ <%= link_to "Edit this article", edit_article_path(@article) %> |
+ <%= link_to "Back to articles", articles_path %>
+
+ <%= button_to "Destroy this article", @article, method: :delete %>
+
diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb
new file mode 100644
index 000000000..b12dd0cbe
--- /dev/null
+++ b/app/views/devise/confirmations/new.html.erb
@@ -0,0 +1,16 @@
+Resend confirmation instructions
+
+<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
+ <%= render "devise/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
+
+
+
+ <%= f.submit "Resend confirmation instructions" %>
+
+<% end %>
+
+<%= render "devise/shared/links" %>
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 000000000..dc55f64f6
--- /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) %>
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 000000000..32f4ba803
--- /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 %>
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 000000000..b41daf476
--- /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.
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 000000000..f667dc12f
--- /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.
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 000000000..41e148bf2
--- /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) %>
diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb
new file mode 100644
index 000000000..5fbb9ff0a
--- /dev/null
+++ b/app/views/devise/passwords/edit.html.erb
@@ -0,0 +1,25 @@
+Change your password
+
+<%= 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 %>
+
+
+ <%= f.label :password, "New password" %>
+ <% if @minimum_password_length %>
+ (<%= @minimum_password_length %> characters minimum)
+ <% end %>
+ <%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
+
+
+
+ <%= f.label :password_confirmation, "Confirm new password" %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
+
+
+
+ <%= f.submit "Change my password" %>
+
+<% end %>
+
+<%= render "devise/shared/links" %>
diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb
new file mode 100644
index 000000000..9b486b81b
--- /dev/null
+++ b/app/views/devise/passwords/new.html.erb
@@ -0,0 +1,16 @@
+Forgot your password?
+
+<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
+ <%= render "devise/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+
+ <%= f.submit "Send me reset password instructions" %>
+
+<% end %>
+
+<%= render "devise/shared/links" %>
diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb
new file mode 100644
index 000000000..b82e3365a
--- /dev/null
+++ b/app/views/devise/registrations/edit.html.erb
@@ -0,0 +1,43 @@
+Edit <%= resource_name.to_s.humanize %>
+
+<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
+ <%= render "devise/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+ <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
+ Currently waiting confirmation for: <%= resource.unconfirmed_email %>
+ <% end %>
+
+
+ <%= f.label :password %> (leave blank if you don't want to change it)
+ <%= f.password_field :password, autocomplete: "new-password" %>
+ <% if @minimum_password_length %>
+
+ <%= @minimum_password_length %> characters minimum
+ <% end %>
+
+
+
+ <%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
+
+
+
+ <%= 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 %>
diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb
new file mode 100644
index 000000000..d655b66f6
--- /dev/null
+++ b/app/views/devise/registrations/new.html.erb
@@ -0,0 +1,29 @@
+Sign up
+
+<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
+ <%= render "devise/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+
+ <%= f.label :password %>
+ <% if @minimum_password_length %>
+ (<%= @minimum_password_length %> characters minimum)
+ <% end %>
+ <%= f.password_field :password, autocomplete: "new-password" %>
+
+
+
+ <%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
+
+
+
+ <%= f.submit "Sign up" %>
+
+<% end %>
+
+<%= render "devise/shared/links" %>
diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb
new file mode 100644
index 000000000..5ede96489
--- /dev/null
+++ b/app/views/devise/sessions/new.html.erb
@@ -0,0 +1,26 @@
+Log in
+
+<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+
+ <%= f.label :password %>
+ <%= f.password_field :password, autocomplete: "current-password" %>
+
+
+ <% if devise_mapping.rememberable? %>
+
+ <%= f.check_box :remember_me %>
+ <%= f.label :remember_me %>
+
+ <% end %>
+
+
+ <%= f.submit "Log in" %>
+
+<% end %>
+
+<%= render "devise/shared/links" %>
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 000000000..cabfe307e
--- /dev/null
+++ b/app/views/devise/shared/_error_messages.html.erb
@@ -0,0 +1,15 @@
+<% if resource.errors.any? %>
+
+
+ <%= I18n.t("errors.messages.not_saved",
+ count: resource.errors.count,
+ resource: resource.class.model_name.human.downcase)
+ %>
+
+
+ <% resource.errors.full_messages.each do |message| %>
+ <%= message %>
+ <% end %>
+
+
+<% end %>
diff --git a/app/views/devise/shared/_links.html.erb b/app/views/devise/shared/_links.html.erb
new file mode 100644
index 000000000..7a75304ba
--- /dev/null
+++ b/app/views/devise/shared/_links.html.erb
@@ -0,0 +1,25 @@
+<%- if controller_name != 'sessions' %>
+ <%= link_to "Log in", new_session_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
+ <%= link_to "Sign up", new_registration_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
+ <%= link_to "Forgot your password?", new_password_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
+ <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
+ <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.omniauthable? %>
+ <%- resource_class.omniauth_providers.each do |provider| %>
+ <%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), data: { turbo: false } %>
+ <% end %>
+<% end %>
diff --git a/app/views/devise/unlocks/new.html.erb b/app/views/devise/unlocks/new.html.erb
new file mode 100644
index 000000000..ffc34de8d
--- /dev/null
+++ b/app/views/devise/unlocks/new.html.erb
@@ -0,0 +1,16 @@
+Resend unlock instructions
+
+<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
+ <%= render "devise/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+
+ <%= f.submit "Resend unlock instructions" %>
+
+<% end %>
+
+<%= render "devise/shared/links" %>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 812bfb90f..5bd0f9fae 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -8,9 +8,27 @@
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
+ <%= javascript_include_tag 'application' %>
+
+
+ <%= link_to("Article Encyclopedia", root_path, id: "hiddenLink", class: "larger-button") %>
+
+ <% unless user_signed_in? %>
+ <%= link_to("Search", article_search_path, class: "nav-button") %>
+ <%= link_to("Sign Up", new_user_registration_path, class: "nav-button") %>
+ <%= link_to("Login", signin_path, class: "nav-button") %>
+ <% end %>
+
+ <% if user_signed_in? %>
+ <%= link_to("Search", article_search_path, class: "nav-button") %>
+ <%= link_to("Create Article", create_article_path, class: "nav-button") %>
+ <%= link_to("My Articles", article_repository_path, class: "nav-button")%>
+ <%= link_to("Sign Out", destroy_user_session_path, :method => :delete, class: "nav-button")%>
+ <% end %>
+
<%= yield %>