Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
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: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"editor.formatOnSave": true
},
"[ruby]": {
"editor.defaultFormatter": "firstdraft.vscode-rufo",
"editor.defaultFormatter": "mbessey.vscode-rufo",
"editor.formatOnSave": true
},
"vscode-erb-beautify.keepBlankLines": 1,
Expand Down
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '3.0.3'

gem "grade_runner", github: "firstdraft/grade_runner"
gem 'devise'
gem 'faker'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem 'rails', '~> 6.1.3', '>= 6.1.3.1'
Expand Down
17 changes: 17 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,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 @@ -130,6 +131,12 @@ GEM
rexml
crass (1.0.6)
debug_inspector (1.1.0)
devise (4.9.2)
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)
Expand All @@ -139,6 +146,8 @@ GEM
factory_bot_rails (6.2.0)
factory_bot (~> 6.2.0)
railties (>= 5.0.0)
faker (3.2.0)
i18n (>= 1.8.11, < 2)
faraday (2.7.4)
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
Expand Down Expand Up @@ -193,6 +202,7 @@ GEM
faraday (>= 1, < 3)
sawyer (~> 0.9)
oj (3.10.18)
orm_adapter (0.5.0)
parallel (1.22.1)
parser (3.1.1.0)
ast (~> 2.4.1)
Expand Down Expand Up @@ -256,6 +266,9 @@ GEM
ffi (~> 1.0)
rchardet (1.8.0)
regexp_parser (2.2.1)
responders (3.1.0)
actionpack (>= 5.2)
railties (>= 5.2)
reverse_markdown (2.1.1)
nokogiri
rexml (3.2.5)
Expand Down Expand Up @@ -375,6 +388,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 @@ -417,7 +432,9 @@ DEPENDENCIES
byebug
capybara (>= 3.26)
carrierwave
devise
factory_bot_rails
faker
grade_runner!
htmlbeautifier
jbuilder (~> 2.7)
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
class ApplicationController < ActionController::Base
before_action :authenticate_user!

end
98 changes: 98 additions & 0 deletions app/controllers/tasks_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
class TasksController < ApplicationController
before_action :set_task, only: %i[ show edit update destroy move]

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


def move
if @task.not_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/1 or /tasks/1.json
def show
end

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

# GET /tasks/1/edit
def edit
respond_to do |format|
format.html
format.js
end
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_started: "not_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
end
12 changes: 10 additions & 2 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<title>Vanilla Rails</title>
<meta charset="utf-8">
<title>Tasks - UJS Practice</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 %>
<%= render "shared/navbar" %>
<div class="container">
<%= render "shared/flash" %>

<%= yield %>
</div>
</body>
</html>
5 changes: 5 additions & 0 deletions app/views/shared/_cdn_assets.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/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>
<link href="https://cdn.jsdelivr.net/npm/bootswatch@5.2.3/dist/lux/bootstrap.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
11 changes: 11 additions & 0 deletions app/views/shared/_flash.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<% if notice.present? %>
<div class="alert alert-dismissible alert-success">
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
<%= notice %>
</div>
<% end %>
<% if alert.present? %>
<div class="alert alert-warning" role="alert">
<%= alert %>
</div>
<% end %>
27 changes: 27 additions & 0 deletions app/views/shared/_navbar.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<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 ms-auto 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>
27 changes: 27 additions & 0 deletions app/views/tasks/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<li id="<%= dom_id task, :form %>" class="list-group-item">

<%= form_with(model: task, local: false) do |form| %>
<% if task.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(task.errors.count, "error") %> prohibited this task from being saved:</h2>

<ul>
<% task.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>

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

<div>
<div class="text-center">
<%= 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_started? %>
<i class="fa-sharp fa-solid fa-forward"></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), remote: true, class: "btn btn-link" 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, remote: true, class: "btn btn-link" 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, :created_at, :updated_at
json.url task_url(task, format: :json)
6 changes: 6 additions & 0 deletions app/views/tasks/create.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
var new_task = $("<%= j(render @task) %>");
new_task.hide();
$("#form_task").before(new_task);
new_task.slideDown();
$("#form_task").after(new_task);
$("#form_task #task_content").val("");
1 change: 1 addition & 0 deletions app/views/tasks/destroy.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$("#<%= dom_id @task %>").fadeOut();
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 "tasks/form", task: @task)%>");
Loading