From 08f4654349b54a2b0fea18a6ee4cb0307aac54ed Mon Sep 17 00:00:00 2001 From: Chris Veleris Date: Fri, 17 Nov 2023 15:12:38 +0200 Subject: [PATCH 1/6] Scaffold notes structure --- app.rb | 2 + app/models/area.rb | 2 + app/models/note.rb | 6 ++ app/models/project.rb | 2 + app/models/tag.rb | 1 + app/models/task.rb | 2 + app/models/user.rb | 1 + app/routes/notes_routes.rb | 63 +++++++++++++++ app/views/notes/_edit_note_modal.erb | 13 +++ app/views/notes/_form.erb | 43 ++++++++++ app/views/notes/index.erb | 42 ++++++++++ app/views/sidebar.erb | 5 ++ app/views/tasks/_form.erb | 80 +++++++++---------- db/migrate/20231116112552_create_notes.rb | 10 +++ ...1116120633_create_join_table_notes_tags.rb | 8 ++ db/schema.rb | 18 ++++- public/js/app.js | 54 +++++++++---- 17 files changed, 296 insertions(+), 56 deletions(-) create mode 100644 app/models/note.rb create mode 100644 app/routes/notes_routes.rb create mode 100644 app/views/notes/_edit_note_modal.erb create mode 100644 app/views/notes/_form.erb create mode 100644 app/views/notes/index.erb create mode 100644 db/migrate/20231116112552_create_notes.rb create mode 100644 db/migrate/20231116120633_create_join_table_notes_tags.rb diff --git a/app.rb b/app.rb index e3e313b..d4722f9 100644 --- a/app.rb +++ b/app.rb @@ -7,6 +7,7 @@ require './app/models/area' require './app/models/project' require './app/models/task' require './app/models/tag' +require './app/models/note' require './app/helpers/authentication_helper' @@ -14,6 +15,7 @@ require './app/routes/authentication_routes' require './app/routes/tasks_routes' require './app/routes/projects_routes' require './app/routes/areas_routes' +require './app/routes/notes_routes' helpers AuthenticationHelper diff --git a/app/models/area.rb b/app/models/area.rb index a5cc3c8..ac3e13a 100644 --- a/app/models/area.rb +++ b/app/models/area.rb @@ -1,4 +1,6 @@ class Area < ActiveRecord::Base belongs_to :user has_many :projects, dependent: :destroy + + validates :name, presence: true end diff --git a/app/models/note.rb b/app/models/note.rb new file mode 100644 index 0000000..d2cf5e0 --- /dev/null +++ b/app/models/note.rb @@ -0,0 +1,6 @@ +class Note < ActiveRecord::Base + belongs_to :user, dependent: :destroy + has_and_belongs_to_many :tags + + validates :content, presence: true +end diff --git a/app/models/project.rb b/app/models/project.rb index df37298..b906943 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -5,4 +5,6 @@ class Project < ActiveRecord::Base scope :with_incomplete_tasks, -> { joins(:tasks).where(tasks: { completed: false }).distinct } scope :with_complete_tasks, -> { joins(:tasks).where(tasks: { completed: true }).distinct } + + validates :name, presence: true end diff --git a/app/models/tag.rb b/app/models/tag.rb index 920e262..ba58276 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -1,4 +1,5 @@ class Tag < ActiveRecord::Base belongs_to :user has_and_belongs_to_many :tasks + has_and_belongs_to_many :notes end diff --git a/app/models/task.rb b/app/models/task.rb index 47801ee..907bd8d 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -5,4 +5,6 @@ class Task < ActiveRecord::Base scope :complete, -> { where(completed: true) } scope :incomplete, -> { where(completed: false) } + + validates :name, presence: true end diff --git a/app/models/user.rb b/app/models/user.rb index d3b4b09..b81cc48 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,6 +5,7 @@ class User < ActiveRecord::Base has_many :projects has_many :tasks has_many :tags, dependent: :destroy + has_many :notes, dependent: :destroy validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }, uniqueness: true end diff --git a/app/routes/notes_routes.rb b/app/routes/notes_routes.rb new file mode 100644 index 0000000..9aa0039 --- /dev/null +++ b/app/routes/notes_routes.rb @@ -0,0 +1,63 @@ +class Sinatra::Application + def update_note_tags(note, tags_json) + return if tags_json.blank? + + begin + tag_names = JSON.parse(tags_json).map { |tag| tag['value'] }.uniq + tags = tag_names.map do |name| + current_user.tags.find_or_create_by(name: name) + end + note.tags = tags + rescue JSON::ParserError + puts "Failed to parse JSON for tags: #{tags_json}" + end + end + + get '/notes' do + @notes = current_user.notes.includes(:tags) + erb :'notes/index' + end + + post '/note/create' do + note_attributes = { + content: params[:content], + user_id: current_user.id + } + + note = current_user.notes.build(note_attributes) + + if note.save + update_note_tags(note, params[:tags]) + redirect request.referrer || '/' + else + halt 400, 'There was a problem creating the note.' + end + end + + patch '/note/:id' do + note = current_user.notes.find_by(id: params[:id]) + halt 404, 'Note not found.' unless note + + note_attributes = { + content: params[:content] + } + + if note.update(note_attributes) + update_note_tags(note, params[:tags]) + redirect request.referrer || '/' + else + halt 400, 'There was a problem updating the note.' + end + end + + delete '/note/:id' do + note = current_user.notes.find_by(id: params[:id]) + halt 404, 'Note not found.' unless note + + if note.destroy + redirect request.referrer || '/' + else + halt 400, 'There was a problem deleting the note.' + end + end +end diff --git a/app/views/notes/_edit_note_modal.erb b/app/views/notes/_edit_note_modal.erb new file mode 100644 index 0000000..cc417d2 --- /dev/null +++ b/app/views/notes/_edit_note_modal.erb @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/app/views/notes/_form.erb b/app/views/notes/_form.erb new file mode 100644 index 0000000..efb0658 --- /dev/null +++ b/app/views/notes/_form.erb @@ -0,0 +1,43 @@ +<% action_url = note.new_record? ? '/note/create' : "/note/#{note.id}" %> +<% method = note.new_record? ? 'post' : 'patch' %> +
+ <% unless note.new_record? %> + + <% end %> +
+
+
+ +
+
+
+
+ +
+
+
+ + <% unless note.new_record? %> + + <% end %> +
+
+
+ +<% if !note.new_record? %> +
+ +
+<% end %> + diff --git a/app/views/notes/index.erb b/app/views/notes/index.erb new file mode 100644 index 0000000..64e3d6a --- /dev/null +++ b/app/views/notes/index.erb @@ -0,0 +1,42 @@ +

Notes

+ +
+
+ <%= partial :'notes/_form', locals: { note: Note.new } %> +
+
+
+ + + + + + + + + + <% @notes.each do |note| %> +
+ <%= partial :'notes/_form', locals: { note: note } %> +
+ + + + + + <% end %> + +
ContentTagsActions
+
+ <%= note.content %> +
+
+ <% note.tags.each do |tag| %> + <%= tag.name %> + <% end %> + +
+
+<%= partial :'notes/_edit_note_modal' %> diff --git a/app/views/sidebar.erb b/app/views/sidebar.erb index b2622b4..133be88 100644 --- a/app/views/sidebar.erb +++ b/app/views/sidebar.erb @@ -33,6 +33,11 @@ Completed +
  • + + Notes + +
  • diff --git a/app/views/tasks/_form.erb b/app/views/tasks/_form.erb index 38a6720..d498b66 100644 --- a/app/views/tasks/_form.erb +++ b/app/views/tasks/_form.erb @@ -8,60 +8,60 @@
    - +
    - <% current_user.projects.each do |project| %> <% end %> - -
    -
    - - +
    +
    + +
    - -
    -
    -
    -
    - -
    -
    -
    - - <% unless task.new_record? %> - + +
    +
    +
    +
    + +
    +
    +
    + + <% unless task.new_record? %> + + <% end %> +
    + + + <% if !task.new_record? %> +
    + +
    <% end %> - - - -<% if !task.new_record? %> -
    - -
    -<% end %> - + diff --git a/db/migrate/20231116112552_create_notes.rb b/db/migrate/20231116112552_create_notes.rb new file mode 100644 index 0000000..c127ea6 --- /dev/null +++ b/db/migrate/20231116112552_create_notes.rb @@ -0,0 +1,10 @@ +class CreateNotes < ActiveRecord::Migration[7.1] + def change + create_table :notes do |t| + t.text :content + t.references :user, null: false, foreign_key: { on_delete: :cascade } + + t.timestamps + end + end +end diff --git a/db/migrate/20231116120633_create_join_table_notes_tags.rb b/db/migrate/20231116120633_create_join_table_notes_tags.rb new file mode 100644 index 0000000..2c605ca --- /dev/null +++ b/db/migrate/20231116120633_create_join_table_notes_tags.rb @@ -0,0 +1,8 @@ +class CreateJoinTableNotesTags < ActiveRecord::Migration[7.1] + def change + create_join_table :notes, :tags do |t| + t.index :note_id + t.index :tag_id + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 3065cfc..6103f10 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2023_11_15_092055) do +ActiveRecord::Schema[7.1].define(version: 2023_11_16_120633) do create_table "areas", force: :cascade do |t| t.string "name" t.integer "user_id", null: false @@ -19,6 +19,21 @@ ActiveRecord::Schema[7.1].define(version: 2023_11_15_092055) do t.index ["user_id"], name: "index_areas_on_user_id" end + create_table "notes", force: :cascade do |t| + t.text "content" + t.integer "user_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_notes_on_user_id" + end + + create_table "notes_tags", id: false, force: :cascade do |t| + t.integer "note_id", null: false + t.integer "tag_id", null: false + t.index ["note_id"], name: "index_notes_tags_on_note_id" + t.index ["tag_id"], name: "index_notes_tags_on_tag_id" + end + create_table "projects", force: :cascade do |t| t.string "name" t.integer "user_id", null: false @@ -69,6 +84,7 @@ ActiveRecord::Schema[7.1].define(version: 2023_11_15_092055) do end add_foreign_key "areas", "users" + add_foreign_key "notes", "users", on_delete: :cascade add_foreign_key "projects", "areas", on_delete: :cascade add_foreign_key "projects", "users" add_foreign_key "tags", "users", on_delete: :cascade diff --git a/public/js/app.js b/public/js/app.js index 6b307c1..fac0a9b 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1,6 +1,11 @@ document.addEventListener("DOMContentLoaded", function () { attachEventListeners(); - new Tagify(document.getElementById('task_tags')); + if (document.getElementById('task_tags_')) { + new Tagify(document.getElementById('task_tags_')); + } + if (document.getElementById('note_tags_')) { + new Tagify(document.getElementById('note_tags_')); + } }); function attachEventListeners() { @@ -8,6 +13,7 @@ function attachEventListeners() { attachTaskClickListeners(); attachProjectModalListeners(); attachAreaModalListeners(); + attachNoteClickListeners(); } function attachCollapseListeners() { @@ -47,18 +53,40 @@ function openEditTaskModal(taskId) { const editTaskFormContainer = document.getElementById('editTaskFormContainer'); editTaskFormContainer.innerHTML = formHtml; - new Tagify(editTaskFormContainer.querySelector('#task_tags')); + new Tagify(editTaskFormContainer.querySelector('#task_tags_' + taskId)); new bootstrap.Modal(document.getElementById('editTaskModal')).show(); } - function attachProjectModalListeners() { document.querySelectorAll('[data-bs-toggle="modal"][data-project-id]').forEach(button => { button.addEventListener('click', () => openProjectModalForEdit(button.getAttribute('data-project-id'))); }); } +function attachNoteClickListeners() { + document.querySelectorAll('.note-item').forEach(noteElement => { + noteElement.addEventListener('click', event => { + openEditNoteModal(noteElement.dataset.noteId); + }); + }); +} + +function openEditNoteModal(noteId) { + const formContainer = document.getElementById('edit_note_form_' + noteId); + if (!formContainer) { + console.error('Edit form not found for note: ' + noteId); + return; + } + const formHtml = formContainer.innerHTML; + const editNoteFormContainer = document.getElementById('editNoteFormContainer'); + editNoteFormContainer.innerHTML = formHtml; + + new Tagify(editNoteFormContainer.querySelector('#note_tags_' + noteId)); + + new bootstrap.Modal(document.getElementById('editNoteModal')).show(); +} + function openProjectModalForEdit(projectId) { fetch('/project/' + projectId) .then(response => { @@ -141,15 +169,15 @@ function toggleTaskCompletion(event, taskId) { event.stopPropagation(); fetch('/task/' + taskId + '/toggle_completion', { method: 'PATCH', - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({_method: 'patch'}) + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ _method: 'patch' }) }) - .then(response => { - if (!response.ok) throw new Error('Network response was not ok'); - return response.json(); - }) - .then(data => updateTaskCompletionStatus(taskId, data)) - .catch(error => console.error('There has been a problem with your fetch operation:', error)); + .then(response => { + if (!response.ok) throw new Error('Network response was not ok'); + return response.json(); + }) + .then(data => updateTaskCompletionStatus(taskId, data)) + .catch(error => console.error('There has been a problem with your fetch operation:', error)); } function updateTaskCompletionStatus(taskId, data) { @@ -171,7 +199,6 @@ function updateTaskCompletionStatus(taskId, data) { setTimeout(() => taskDiv.remove(), 200); } - function applyPriorityColor(taskIcon, priority) { taskIcon.classList.remove('text-warning', 'text-danger', 'text-secondary'); switch (priority) { @@ -185,6 +212,3 @@ function applyPriorityColor(taskIcon, priority) { taskIcon.classList.add('text-secondary'); } } - - - From 86493b56c756bcd58a6fc9cfc6ebc46f34070acd Mon Sep 17 00:00:00 2001 From: Chris Veleris Date: Fri, 17 Nov 2023 17:12:29 +0200 Subject: [PATCH 2/6] Fix td issue and tags --- app/views/notes/index.erb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/notes/index.erb b/app/views/notes/index.erb index 64e3d6a..a3c8cd0 100644 --- a/app/views/notes/index.erb +++ b/app/views/notes/index.erb @@ -17,15 +17,15 @@ - <% @notes.each do |note| %> -
    - <%= partial :'notes/_form', locals: { note: note } %> -
    + <% current_user.notes.each do |note| %>
    <%= note.content %>
    +
    + <%= partial :'notes/_form', locals: { note: note } %> +
    <% note.tags.each do |tag| %> From 65e8f9296f39b9eae8a9b4c3c3405aa5f7305b50 Mon Sep 17 00:00:00 2001 From: Chris Veleris Date: Fri, 17 Nov 2023 19:37:57 +0200 Subject: [PATCH 3/6] Add title to notes --- app/models/note.rb | 2 +- app/routes/notes_routes.rb | 6 +- app/views/notes/_form.erb | 10 ++- app/views/notes/index.erb | 11 ++- app/views/tasks/_form.erb | 74 +++++++++---------- ...dd_cascade_delete_to_projects_and_tasks.rb | 4 - .../20231117170940_add_title_to_notes.rb | 5 ++ db/schema.rb | 3 +- public/css/app.css | 9 ++- 9 files changed, 71 insertions(+), 53 deletions(-) create mode 100644 db/migrate/20231117170940_add_title_to_notes.rb diff --git a/app/models/note.rb b/app/models/note.rb index d2cf5e0..770a220 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -1,5 +1,5 @@ class Note < ActiveRecord::Base - belongs_to :user, dependent: :destroy + belongs_to :user has_and_belongs_to_many :tags validates :content, presence: true diff --git a/app/routes/notes_routes.rb b/app/routes/notes_routes.rb index 9aa0039..2032b4e 100644 --- a/app/routes/notes_routes.rb +++ b/app/routes/notes_routes.rb @@ -20,6 +20,7 @@ class Sinatra::Application post '/note/create' do note_attributes = { + title: params[:title], content: params[:content], user_id: current_user.id } @@ -39,6 +40,7 @@ class Sinatra::Application halt 404, 'Note not found.' unless note note_attributes = { + title: params[:title], content: params[:content] } @@ -54,8 +56,8 @@ class Sinatra::Application note = current_user.notes.find_by(id: params[:id]) halt 404, 'Note not found.' unless note - if note.destroy - redirect request.referrer || '/' + if note.destroy! + redirect '/notes' else halt 400, 'There was a problem deleting the note.' end diff --git a/app/views/notes/_form.erb b/app/views/notes/_form.erb index efb0658..e287d6c 100644 --- a/app/views/notes/_form.erb +++ b/app/views/notes/_form.erb @@ -7,7 +7,14 @@
    - +
    + +
    +
    +
    +
    +
    +
    @@ -36,6 +43,7 @@ +
    +
    + +<% if !task.new_record? %> +
    + +
    +<% end %> + diff --git a/db/migrate/20231110163101_add_cascade_delete_to_projects_and_tasks.rb b/db/migrate/20231110163101_add_cascade_delete_to_projects_and_tasks.rb index 098cdd4..822d9a7 100644 --- a/db/migrate/20231110163101_add_cascade_delete_to_projects_and_tasks.rb +++ b/db/migrate/20231110163101_add_cascade_delete_to_projects_and_tasks.rb @@ -1,13 +1,9 @@ class AddCascadeDeleteToProjectsAndTasks < ActiveRecord::Migration[7.1] def change - # Remove the existing foreign key from projects to areas remove_foreign_key :projects, :areas - # Add the new foreign key with on_delete: :cascade add_foreign_key :projects, :areas, on_delete: :cascade - # Remove the existing foreign key from tasks to projects remove_foreign_key :tasks, :projects - # Add the new foreign key with on_delete: :cascade add_foreign_key :tasks, :projects, on_delete: :cascade end end diff --git a/db/migrate/20231117170940_add_title_to_notes.rb b/db/migrate/20231117170940_add_title_to_notes.rb new file mode 100644 index 0000000..3bae3a8 --- /dev/null +++ b/db/migrate/20231117170940_add_title_to_notes.rb @@ -0,0 +1,5 @@ +class AddTitleToNotes < ActiveRecord::Migration[7.1] + def change + add_column :notes, :title, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 6103f10..5ecd67e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2023_11_16_120633) do +ActiveRecord::Schema[7.1].define(version: 2023_11_17_170940) do create_table "areas", force: :cascade do |t| t.string "name" t.integer "user_id", null: false @@ -24,6 +24,7 @@ ActiveRecord::Schema[7.1].define(version: 2023_11_16_120633) do t.integer "user_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "title" t.index ["user_id"], name: "index_notes_on_user_id" end diff --git a/public/css/app.css b/public/css/app.css index 7d7301d..8f3ab74 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -84,4 +84,11 @@ h6 { #task_name::placeholder { color: #ccc; opacity: 1; /* Firefox */ -} \ No newline at end of file +} + +/* note form */ + +.no-focus-outline textarea:focus, +.no-focus-outline textarea:-moz-focusring { + outline: none !important; +} From 95181c062bb7b84e9de073a169e0559795321dc0 Mon Sep 17 00:00:00 2001 From: Chris Veleris Date: Fri, 17 Nov 2023 22:19:01 +0200 Subject: [PATCH 4/6] Add more notes partials --- app/models/note.rb | 1 + app/models/project.rb | 1 + app/routes/notes_routes.rb | 16 ++++- app/views/notes/_form.erb | 12 +++- app/views/notes/_notes_table.erb | 31 +++++++++ app/views/notes/index.erb | 30 +-------- app/views/projects/show.erb | 63 ++++++++++++------- app/views/sidebar.erb | 4 +- .../20231117174412_add_project_to_notes.rb | 5 ++ db/schema.rb | 5 +- public/js/app.js | 39 ++++++++++++ 11 files changed, 151 insertions(+), 56 deletions(-) create mode 100644 app/views/notes/_notes_table.erb create mode 100644 db/migrate/20231117174412_add_project_to_notes.rb diff --git a/app/models/note.rb b/app/models/note.rb index 770a220..b7acfc9 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -1,5 +1,6 @@ class Note < ActiveRecord::Base belongs_to :user + belongs_to :project, optional: true has_and_belongs_to_many :tags validates :content, presence: true diff --git a/app/models/project.rb b/app/models/project.rb index b906943..f928894 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -2,6 +2,7 @@ class Project < ActiveRecord::Base belongs_to :user belongs_to :area, optional: true has_many :tasks, dependent: :destroy + has_many :notes, dependent: :destroy scope :with_incomplete_tasks, -> { joins(:tasks).where(tasks: { completed: false }).distinct } scope :with_complete_tasks, -> { joins(:tasks).where(tasks: { completed: true }).distinct } diff --git a/app/routes/notes_routes.rb b/app/routes/notes_routes.rb index 2032b4e..ec8be13 100644 --- a/app/routes/notes_routes.rb +++ b/app/routes/notes_routes.rb @@ -25,7 +25,13 @@ class Sinatra::Application user_id: current_user.id } - note = current_user.notes.build(note_attributes) + if params[:project_id].empty? + note = current_user.notes.build(note_attributes) + else + project = current_user.projects.find_by(id: params[:project_id]) + halt 400, 'Invalid project.' unless project + note = project.notes.build(note_attributes) + end if note.save update_note_tags(note, params[:tags]) @@ -44,6 +50,14 @@ class Sinatra::Application content: params[:content] } + if params[:project_id] && !params[:project_id].empty? + project = current_user.projects.find_by(id: params[:project_id]) + halt 400, 'Invalid project.' unless project + note.project = project + else + note.project = nil + end + if note.update(note_attributes) update_note_tags(note, params[:tags]) redirect request.referrer || '/' diff --git a/app/views/notes/_form.erb b/app/views/notes/_form.erb index e287d6c..4f6fe90 100644 --- a/app/views/notes/_form.erb +++ b/app/views/notes/_form.erb @@ -12,6 +12,17 @@ +
    +
    + + +
    +
    @@ -34,7 +45,6 @@
    - <% if !note.new_record? %>
    diff --git a/app/views/notes/_notes_table.erb b/app/views/notes/_notes_table.erb new file mode 100644 index 0000000..18d7160 --- /dev/null +++ b/app/views/notes/_notes_table.erb @@ -0,0 +1,31 @@ +
    + + + + + + + + + <% notes.each do |note| %> + + + + + <% end %> + +
    ContentTags
    + +
    + <%= partial :'notes/_form', locals: { note: note } %> +
    +
    + <% note.tags.each do |tag| %> + <%= tag.name %> + <% end %> +
    +
    \ No newline at end of file diff --git a/app/views/notes/index.erb b/app/views/notes/index.erb index ede1691..2729f24 100644 --- a/app/views/notes/index.erb +++ b/app/views/notes/index.erb @@ -8,34 +8,6 @@
    - - - - - - - - - <% current_user.notes.each do |note| %> - - - - - <% end %> - -
    ContentTags
    - -
    - <%= partial :'notes/_form', locals: { note: note } %> -
    -
    - <% note.tags.each do |tag| %> - <%= tag.name %> - <% end %> -
    + <%= partial :'notes/_notes_table', locals: {notes: @notes} %>
    <%= partial :'notes/_edit_note_modal' %> diff --git a/app/views/projects/show.erb b/app/views/projects/show.erb index cf62be7..859cbb3 100644 --- a/app/views/projects/show.erb +++ b/app/views/projects/show.erb @@ -1,37 +1,40 @@

    <%= @project.name.upcase %> -

    + + <% unless @project.description.blank? %>
    <%= @project.description %>
    <% end %> -