diff --git a/Gemfile.lock b/Gemfile.lock
index ac898c77c..66613187f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -233,6 +233,8 @@ GEM
railties (>= 6.0.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
+ tzinfo-data (1.2023.4)
+ tzinfo (>= 1.0.0)
web-console (4.2.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb
new file mode 100644
index 000000000..c95e8a79d
--- /dev/null
+++ b/app/controllers/articles_controller.rb
@@ -0,0 +1,108 @@
+class ArticlesController < ApplicationController
+ before_action :set_article, only: %i[ show edit update destroy ]
+
+ # GET /articles or /articles.json
+ def index
+ @articles = Article.all
+
+ # Default values
+ sort_column = params[:sort] || 'title'
+ sort_order = params[:order] || 'asc'
+
+ # Toggle the order if sorting on the same column
+ sort_order = toggle_order(sort_order) if sort_column == params[:sort]
+
+ # Sorting logic based on sort_column and sort_order
+ case sort_column
+ when 'title'
+ @articles = @articles.order(title: sort_order)
+ when 'author'
+ @articles = @articles.order(author: sort_order)
+ when 'date'
+ @articles = @articles.order(date: sort_order)
+ end
+ end
+
+ # GET /articles/search
+ def search
+ @query = params[:query]
+ @results = Article.search(@query)
+
+ if @query.present?
+ if @results&.any?
+ @articles = @results
+ else
+ @articles = []
+ end
+ else
+ @articles = Article.all
+ end
+ end
+
+ # GET /articles/1 or /articles/1.json
+ def show
+ end
+
+ # GET /articles/new
+ def new
+ @article = Article.new
+ end
+
+ # GET /articles/1/edit
+ def edit
+ end
+
+ # POST /articles or /articles.json
+ def create
+ @article = Article.new(article_params)
+
+ respond_to do |format|
+ if @article.save
+ format.html { redirect_to article_url(@article), notice: "Article was successfully created." }
+ format.json { render :show, status: :created, location: @article }
+ else
+ format.html { render :new, status: :unprocessable_entity }
+ format.json { render json: @article.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # PATCH/PUT /articles/1 or /articles/1.json
+ def update
+ respond_to do |format|
+ if @article.update(article_params)
+ format.html { redirect_to article_url(@article), notice: "Article was successfully updated." }
+ format.json { render :show, status: :ok, location: @article }
+ else
+ format.html { render :edit, status: :unprocessable_entity }
+ format.json { render json: @article.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /articles/1 or /articles/1.json
+ def destroy
+ @article.destroy!
+
+ respond_to do |format|
+ format.html { redirect_to articles_url, notice: "Article was successfully destroyed." }
+ format.json { head :no_content }
+ end
+ end
+
+ private
+ # Use callbacks to share common setup or constraints between actions.
+ def set_article
+ @article = Article.find(params[:id])
+ end
+
+ # Toggle between ascending order and descending order
+ def toggle_order(order)
+ order == 'asc' ? 'desc' : 'asc'
+ end
+
+ # Only allow a list of trusted parameters through.
+ def article_params
+ params.require(:article).permit(: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..f5680a0c3
--- /dev/null
+++ b/app/controllers/pages_controller.rb
@@ -0,0 +1,7 @@
+class PagesController < ApplicationController
+ def home
+ end
+
+ def about
+ 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..df77f7c2c
--- /dev/null
+++ b/app/models/article.rb
@@ -0,0 +1,9 @@
+class Article < ApplicationRecord
+ validates :title, presence: true
+ validates :content, presence: true
+
+ # perform case-insentitive search on title or content of articles
+ def self.search(query)
+ where("title LIKE ? OR content LIKE ?", "%#{query}%", "%#{query}%")
+ end
+end
diff --git a/app/views/articles/_article.html.erb b/app/views/articles/_article.html.erb
new file mode 100644
index 000000000..15f315457
--- /dev/null
+++ b/app/views/articles/_article.html.erb
@@ -0,0 +1,16 @@
+
+
+
+
+
+
<%= article.title %>
+
<%= article.content %>
+
+
+ <%= article.date %>
+
+
+
+
diff --git a/app/views/articles/_article.json.jbuilder b/app/views/articles/_article.json.jbuilder
new file mode 100644
index 000000000..2e17e23ea
--- /dev/null
+++ b/app/views/articles/_article.json.jbuilder
@@ -0,0 +1,2 @@
+json.extract! article, :id, :title, :content, :author, :date, :created_at, :updated_at
+json.url article_url(article, format: :json)
diff --git a/app/views/articles/_form.html.erb b/app/views/articles/_form.html.erb
new file mode 100644
index 000000000..e41f060c2
--- /dev/null
+++ b/app/views/articles/_form.html.erb
@@ -0,0 +1,38 @@
+<%= 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.text_field :author, class:"form-control", placeholder:"Author" %>
+
+
+
+ <%= form.text_field :title, class:"form-control", placeholder:"Title" %>
+
+
+
+ <%= form.text_area :content, class:"form-control", placeholder:"Fill with your content" %>
+
+
+
+ <%= form.date_field :date, id: :article_date, class:"form-control", value:Date.today, type: :hidden %>
+
+
+ <%# %>
+ <%# <%= form.text_field :user_id, id: :article_user_id, class:"form-control", value:current_user.id, type: :hidden %>
+ <%# %>
+ <%#
%>
+
+
+ <%= form.submit "Save", class:"btn btn-primary" %>
+
+<% end %>
diff --git a/app/views/articles/_table.html.erb b/app/views/articles/_table.html.erb
new file mode 100644
index 000000000..1d29a1d73
--- /dev/null
+++ b/app/views/articles/_table.html.erb
@@ -0,0 +1,24 @@
+
+
+
+ <%= link_to "Title", articles_path(sort: 'title') %>
+ <%= link_to "Author", articles_path(sort: 'author') %>
+ <%= link_to "Date Posted", articles_path(sort: 'date') %>
+
+
+
+ <% if @articles.present? %>
+ <% @articles.each do |article| %>
+
+ <%= link_to "#{article.title}", article %>
+ <%=article.author %>
+ <%=article.date %>
+
+ <% end %>
+ <% else %>
+
+ No articles found.
+
+ <% end %>
+
+
\ No newline at end of file
diff --git a/app/views/articles/edit.html.erb b/app/views/articles/edit.html.erb
new file mode 100644
index 000000000..fd7c7391e
--- /dev/null
+++ b/app/views/articles/edit.html.erb
@@ -0,0 +1,10 @@
+Editing article
+
+<%= render "form", article: @article %>
+
+
+
+
+ <%= link_to "Details...", @article, class:"btn btn-primary" %>
+ <%= link_to "Back", articles_path, class:"btn btn-dark" %>
+
diff --git a/app/views/articles/index.html.erb b/app/views/articles/index.html.erb
new file mode 100644
index 000000000..638fccbc6
--- /dev/null
+++ b/app/views/articles/index.html.erb
@@ -0,0 +1,5 @@
+Articles
+
+<%= render "table" %>
+
+<%= link_to "New article", new_article_path, class:"btn btn-secondary" %>
diff --git a/app/views/articles/index.json.jbuilder b/app/views/articles/index.json.jbuilder
new file mode 100644
index 000000000..09a21f390
--- /dev/null
+++ b/app/views/articles/index.json.jbuilder
@@ -0,0 +1 @@
+json.array! @articles, partial: "articles/article", as: :article
diff --git a/app/views/articles/new.html.erb b/app/views/articles/new.html.erb
new file mode 100644
index 000000000..f63a2ce2f
--- /dev/null
+++ b/app/views/articles/new.html.erb
@@ -0,0 +1,9 @@
+New article
+
+<%= render "form", article: @article %>
+
+
+
+
+ <%= link_to "Back", articles_path, class:"btn btn-dark" %>
+
diff --git a/app/views/articles/search.html.erb b/app/views/articles/search.html.erb
new file mode 100644
index 000000000..638fccbc6
--- /dev/null
+++ b/app/views/articles/search.html.erb
@@ -0,0 +1,5 @@
+Articles
+
+<%= render "table" %>
+
+<%= link_to "New article", new_article_path, class:"btn btn-secondary" %>
diff --git a/app/views/articles/show.html.erb b/app/views/articles/show.html.erb
new file mode 100644
index 000000000..69b5f09a4
--- /dev/null
+++ b/app/views/articles/show.html.erb
@@ -0,0 +1,8 @@
+<%= render @article %>
+
+
+ <%= link_to "Edit", edit_article_path(@article) , class:"btn btn-secondary" %>
+ <%= link_to "Back", articles_path, class:"btn btn-dark" %>
+
+ <%= button_to "Delete", @article, method: :delete, class:"btn btn-danger" %>
+
diff --git a/app/views/articles/show.json.jbuilder b/app/views/articles/show.json.jbuilder
new file mode 100644
index 000000000..dd1fbb4c4
--- /dev/null
+++ b/app/views/articles/show.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "articles/article", article: @article
diff --git a/app/views/layouts/_navbar.html.erb b/app/views/layouts/_navbar.html.erb
new file mode 100644
index 000000000..0ae180270
--- /dev/null
+++ b/app/views/layouts/_navbar.html.erb
@@ -0,0 +1,26 @@
+
+
+ <%= link_to "Shopify Encyclopedia", root_path, class:"nav-link" %>
+
+
+
+
+
+
+ <%= link_to "About Us", about_path, class:"nav-link" %>
+
+
+
+ <%= link_to "Articles", articles_path, class:"nav-link" %>
+
+
+ <%= link_to "Add Article", new_article_path, class:"nav-link" %>
+
+
+
+ <%= render 'layouts/searchForm' %>
+
+
+
+
+
diff --git a/app/views/layouts/_searchForm.html.erb b/app/views/layouts/_searchForm.html.erb
new file mode 100644
index 000000000..2106a1087
--- /dev/null
+++ b/app/views/layouts/_searchForm.html.erb
@@ -0,0 +1,4 @@
+<%= form_tag(article_search_path, method: 'get', class: "d-flex") do %>
+ <%= text_field_tag(:query, params[:query], class: "form-control me-2", placeholder: 'Search articles...') %>
+ <%= submit_tag('Search', class: "btn btn-outline-success") %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 812bfb90f..b3c008c12 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -8,9 +8,12 @@
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
+
+ <%= render 'layouts/navbar' %>
<%= yield %>
+