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
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '3.0.3'

gem "devise"
gem "faker"
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem 'rails', '~> 6.1.3', '>= 6.1.3.1'
# Use postgresql as the database for Active Record
Expand Down
19 changes: 17 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ GEM
ast (2.4.2)
awesome_print (1.9.2)
backport (1.2.0)
bcrypt (3.1.18)
benchmark (0.2.0)
better_errors (2.9.1)
coderay (>= 1.0.0)
Expand Down Expand Up @@ -111,10 +112,18 @@ GEM
concurrent-ruby (1.1.10)
crass (1.0.6)
debug_inspector (1.1.0)
devise (4.8.1)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
diff-lcs (1.5.0)
diffy (3.4.2)
e2mmap (0.1.0)
erubi (1.11.0)
faker (3.1.0)
i18n (>= 1.8.11, < 2)
ffi (1.15.5)
git (1.12.0)
addressable (~> 2.8)
Expand Down Expand Up @@ -153,8 +162,7 @@ GEM
nokogiri (1.13.9)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
nokogiri (1.13.9-x86_64-darwin)
racc (~> 1.4)
orm_adapter (0.5.0)
parallel (1.22.1)
parser (3.1.1.0)
ast (~> 2.4.1)
Expand Down Expand Up @@ -218,6 +226,9 @@ GEM
ffi (~> 1.0)
rchardet (1.8.0)
regexp_parser (2.2.1)
responders (3.0.1)
actionpack (>= 5.0)
railties (>= 5.0)
reverse_markdown (2.1.1)
nokogiri
rexml (3.2.5)
Expand Down Expand Up @@ -307,6 +318,8 @@ GEM
tzinfo (>= 1.0.0)
unicode-display_width (2.1.0)
uniform_notifier (1.16.0)
warden (1.2.9)
rack (>= 2.0.9)
web-console (4.2.0)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
Expand Down Expand Up @@ -344,6 +357,8 @@ DEPENDENCIES
bullet
byebug
capybara (>= 3.26)
devise
faker
htmlbeautifier
jbuilder (~> 2.7)
listen (~> 3.3)
Expand Down
1 change: 1 addition & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
class ApplicationController < ActionController::Base
before_action :authenticate_user!
end
90 changes: 90 additions & 0 deletions app/controllers/tasks_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
class TasksController < ApplicationController
before_action :set_task, only: %i[ show edit update destroy move]

def move
if @task.not_yet_started?
@task.in_progress!
elsif @task.in_progress?
@task.completed!
else
@task.in_progress!
end

respond_to do |format|
format.html { redirect_to tasks_url, notice: "Task updated" }
format.js
end
end

# GET /tasks or /tasks.json
def index
@tasks = Task.all
end

# GET /tasks/1 or /tasks/1.json
def show
end

# GET /tasks/new
def new
@task = Task.new
end

# GET /tasks/1/edit
def edit
end

# POST /tasks or /tasks.json
def create
@task = current_user.tasks.build(task_params)

respond_to do |format|
if @task.save
format.html { redirect_to task_url(@task), notice: "Task was successfully created." }
format.json { render :show, status: :created, location: @task }
format.js
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @task.errors, status: :unprocessable_entity }
format.js
end
end
end

# PATCH/PUT /tasks/1 or /tasks/1.json
def update
respond_to do |format|
if @task.update(task_params)
format.html { redirect_to task_url(@task), notice: "Task was successfully updated." }
format.json { render :show, status: :ok, location: @task }
format.js
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @task.errors, status: :unprocessable_entity }
format.js
end
end
end

# DELETE /tasks/1 or /tasks/1.json
def destroy
@task.destroy

respond_to do |format|
format.html { redirect_to tasks_url, notice: "Task was successfully destroyed." }
format.json { head :no_content }
format.js
end
end

private
# Use callbacks to share common setup or constraints between actions.
def set_task
@task = Task.find(params[:id])
end

# Only allow a list of trusted parameters through.
def task_params
params.require(:task).permit(:content, :status)
end
end
2 changes: 2 additions & 0 deletions app/helpers/tasks_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module TasksHelper
end
12 changes: 12 additions & 0 deletions app/models/task.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Task < ApplicationRecord
belongs_to :user

validates :content, presence: true

enum status: {
not_yet_started: "not_yet_started",
in_progress: "in_progress",
completed: "completed"
}

end
8 changes: 8 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable

has_many :tasks, dependent: :destroy
end
15 changes: 12 additions & 3 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<title>Vanilla Rails</title>
<meta charset="utf-8">
<title>Tasks</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>

<%= render "shared/cdn_assets" %>

<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>

<body>
<%= yield %>
<body class="mb-5">
<%= render "shared/navbar" %>

<div class = "container">
<%= render "shared/flash_messages" %>

<%= yield %>
</div>
</body>
</html>
7 changes: 7 additions & 0 deletions app/views/shared/_cdn_assets.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/js/all.min.js"></script>
10 changes: 10 additions & 0 deletions app/views/shared/_flash_messages.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<% if notice.present? %>
<div class="alert alert-success" role="alert">
<%= notice %>
</div>
<% end %>
<% if alert.present? %>
<div class="alert alert-warning" role="alert">
<%= alert %>
</div>
<% end %>
29 changes: 29 additions & 0 deletions app/views/shared/_navbar.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<nav class="navbar navbar-expand-lg bg-light mb-3">
<div class="container">
<a class="navbar-brand" href="/">Tasks</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
</ul>
<ul class="navbar-nav mb-2 mb-lg-0">
<% if user_signed_in? %>
<li class="nav-item">
<%= link_to 'Log out', destroy_user_session_path, method: :delete, class: "nav-link" %>
</li>
<li class="nav-item">
<%= link_to 'Edit profile', edit_user_registration_path, class: "nav-link" %>
</li>
<% else %>
<li class="nav-item">
<%= link_to 'Log in', new_user_session_path, method: :delete, class: "nav-link" %>
</li>
<li class="nav-item">
<%= link_to 'Sign up', new_user_registration_path, class: "nav-link" %>
</li>
<% end %>
</ul>
</div>
</div>
</nav>
15 changes: 15 additions & 0 deletions app/views/tasks/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<li id="<%= dom_id task, :form %>" class="list-group-item">
<%= form_with(model: task, local: false) do |form| %>

<div class="mb-2">
<%= form.label :content, class: "visually-hidden" %>
<%= form.text_field :content, class: "form-control" %>
</div>

<div>
<div class="d-grid">
<%= form.submit class: "btn btn-outline-primary" %>
</div>
</div>
<% end %>
</li>
38 changes: 38 additions & 0 deletions app/views/tasks/_task.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<li id="<%= dom_id(task) %>" class="list-group-item">
<div>
<%= task.content %>
</div>

<div class="row">
<div class="col-md-4">
<div class="d-grid gap-2">
<%= link_to move_task_path(task), class: "btn btn-link", method: :patch, remote: true do %>
<% if task.not_yet_started? %>
<i class="fa-sharp fa-solid fa-play"></i>
<% elsif task.in_progress? %>
<i class="fa-regular fa-circle-check"></i>
<% else %>
<i class="fa-sharp fa-solid fa-backward"></i>
<% end %>

<% end %>
</div>
</div>

<div class="col-md-4">
<div class="d-grid gap-2">
<%= link_to edit_task_path(task), class: "btn btn-link", remote: true do %>
<i class="fa-sharp fa-solid fa-pen-to-square"></i>
<% end %>
</div>
</div>

<div class="col-md-4">
<div class="d-grid gap-2">
<%= link_to task, method: :delete, class: "btn btn-link", remote: true do %>
<i class="fa-sharp fa-solid fa-trash-can"></i>
<% end %>
</div>
</div>
</div>
</li>
2 changes: 2 additions & 0 deletions app/views/tasks/_task.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
json.extract! task, :id, :content, :user_id, :status, :created_at, :updated_at
json.url task_url(task, format: :json)
9 changes: 9 additions & 0 deletions app/views/tasks/create.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
var new_task = $("<%= j(render @task) %>");

new_task.hide();

$("#form_task").after(new_task);

new_task.slideDown();

$("#form_task #task_content").val("");
3 changes: 3 additions & 0 deletions app/views/tasks/destroy.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
$("#<%= dom_id(@task) %>").slideUp(function(){
this.remove()
});
6 changes: 6 additions & 0 deletions app/views/tasks/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<h1>Editing Task</h1>

<%= render 'form', task: @task %>

<%= link_to 'Show', @task %> |
<%= link_to 'Back', tasks_path %>
1 change: 1 addition & 0 deletions app/views/tasks/edit.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$("#<%= dom_id(@task) %>").replaceWith("<%= j(render "form", task: @task)%>");
45 changes: 45 additions & 0 deletions app/views/tasks/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<div class="row">
<div class="col-md-4">
<div class="card">
<div class="card-header">
Not yet started
</div>

<ul id="not_yet_started_list" class="list-group list-group-flush">
<%= render "tasks/form", task: current_user.tasks.build %>

<% current_user.tasks.not_yet_started.each do |task| %>
<%= render "task", task: task %>
<% end %>

</ul>
</div>
</div>

<div class="col-md-4">
<div class="card">
<div class="card-header">
In progress
</div>
<ul id="in_progress_list" class="list-group list-group-flush">
<% current_user.tasks.in_progress.each do |task| %>
<%= render "task", task: task %>
<% end %>
</ul>
</div>
</div>

<div class="col-md-4">
<div class="card">
<div class="card-header">
Completed
</div>

<ul id="completed_list" class="list-group list-group-flush">
<% current_user.tasks.completed.each do |task| %>
<%= render "task", task: task %>
<% end %>
</ul>
</div>
</div>
</div>
Loading