Skip to content

Commit f980556

Browse files
authored
Merge pull request tgaeta#5 from tgaeta/add-empty-state
Add Empty State
2 parents d562af5 + 24c59b7 commit f980556

File tree

6 files changed

+103
-73
lines changed

6 files changed

+103
-73
lines changed

app/controllers/job_applications_controller.rb

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,21 @@ def destroy
7878
format.html { redirect_to root_path, success: "Job application was successfully deleted." }
7979
format.turbo_stream {
8080
flash.now[:success] = "Job application was successfully deleted."
81+
82+
# Reapply filters, sorting, and pagination
83+
@job_applications = filter_and_sort_job_applications
84+
@job_applications = @job_applications.paginate(page: params[:page], per_page: 10)
85+
86+
@pagination_info = {
87+
total_pages: @job_applications.total_pages,
88+
current_page: @job_applications.current_page,
89+
total_entries: @job_applications.total_entries
90+
}
91+
8192
render turbo_stream: [
82-
turbo_stream.remove(@job_application),
83-
turbo_stream.update("job_application_count", JobApplication.count),
84-
turbo_stream.update("flash_messages", partial: "flash_messages")
93+
turbo_stream.update("flash_messages", partial: "flash_messages"),
94+
turbo_stream.update("job_applications_content", partial: "empty_or_table"),
95+
turbo_stream.update("job_application_count", JobApplication.count)
8596
]
8697
}
8798
end
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<% if JobApplication.exists? %>
2+
<div class="mb-8 flex justify-end">
3+
<%= link_to 'New Job Application', new_job_application_path, class: 'text-sm bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded cursor-pointer', data: { turbo_frame: "_top" } %>
4+
</div>
5+
<%= form_with url: job_applications_path, method: :get, data: { controller: "job-filter", turbo_frame: "job_applications_table" } do |form| %>
6+
<div class="flex flex-wrap -mx-2 mb-4">
7+
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
8+
<%= form.label :search, "Search", class: "sr-only" %>
9+
<%= form.text_field :search, value: params[:search], class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline", placeholder: "Search", data: { action: "input->job-filter#submit" } %>
10+
</div>
11+
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
12+
<%= form.label :method_of_contact, "Contact Method", class: "sr-only" %>
13+
<%= form.select :method_of_contact,
14+
options_for_select([["All Contact Methods", ""]] + JobApplication.method_of_contacts.map { |k, v| [k.humanize, v] }, params[:method_of_contact]),
15+
{},
16+
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
17+
data: { action: "change->job-filter#submit" }
18+
%>
19+
</div>
20+
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
21+
<%= form.label :position_type, "Position Type", class: "sr-only" %>
22+
<%= form.select :position_type,
23+
options_for_select([["All Position Types", ""]] + JobApplication.position_types.map { |k, v| [display_position_type(k), v] }, params[:position_type]),
24+
{},
25+
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
26+
data: { action: "change->job-filter#submit" }
27+
%>
28+
</div>
29+
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
30+
<%= form.label :claimed_for_unemployment, "Unemployment Claim", class: "sr-only" %>
31+
<%= form.select :claimed_for_unemployment,
32+
options_for_select([["All Claims", ""], ["Claimed", "true"], ["Not Claimed", "false"]], params[:claimed_for_unemployment]),
33+
{},
34+
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
35+
data: { action: "change->job-filter#submit" }
36+
%>
37+
</div>
38+
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
39+
<%= form.label :status, "Application Status", class: "sr-only" %>
40+
<%= form.select :status,
41+
options_for_select([["All Statuses", ""]] + JobApplication.statuses.map { |k, v| [k.humanize, v] }, params[:status]),
42+
{},
43+
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
44+
data: { action: "change->job-filter#submit" }
45+
%>
46+
</div>
47+
<div class="w-full md:w-1/6 px-2 mt-4 md:mt-0">
48+
<%= form.button "Reset Filters", type: "button", class: "w-full bg-gray-600 hover:bg-gray-700 text-white font-bold py-2 px-4 rounded cursor-pointer", data: { action: "click->job-filter#reset" } %>
49+
</div>
50+
</div>
51+
<% end %>
52+
<%= turbo_frame_tag "job_applications_table" do %>
53+
<%= render partial: "job_applications_table", locals: { job_applications: @job_applications } %>
54+
<% if @job_applications.any? %>
55+
<div id="pagination" class="mt-4">
56+
<%= render partial: "pagination", locals: { job_applications: @job_applications, job_application_count: @job_applications.count } %>
57+
</div>
58+
<% end %>
59+
<% end %>
60+
<% else %>
61+
<%= render 'empty_state' %>
62+
<% end %>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<div class="text-center py-10 border-dashed border-2 border-gray-300 rounded-lg">
2+
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
3+
<path vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z" />
4+
</svg>
5+
<h2 class="mt-2 text-base font-semibold text-gray-900">No job applications</h2>
6+
<p class="mt-1 mb-8 text-sm text-gray-500">Get started by creating a new job application.</p>
7+
<%= link_to 'New Job Application', new_job_application_path, class: 'text-sm bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded cursor-pointer', data: { turbo_frame: "_top" } %>
8+
</div>

app/views/job_applications/_job_applications_table.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
<path vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z" />
5353
</svg>
5454
<p class="mt-1 text-sm text-gray-500">
55-
<%= "No results match your search criteria." if params[:search].present? || params[:method_of_contact].present? || params[:position_type].present? %>
55+
No results match your search criteria.
5656
</p>
5757
</div>
5858
<% end %>
Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
<% if @pagination_info[:total_pages] > 1 %>
1+
<% if @pagination_info && @pagination_info[:total_pages] && @pagination_info[:total_pages] > 1 %>
22
<div class="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6 shadow appearance-none border rounded w-full text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
33
<div class="text-sm text-gray-700">
4+
Showing <%= @pagination_info[:current_page] %> of <%= @pagination_info[:total_pages] %> pages
45
</div>
56
<div>
67
<%= will_paginate @job_applications,
7-
renderer: CustomPaginationRenderer,
8-
previous_label: 'Previous',
9-
next_label: 'Next',
10-
inner_window: 0,
11-
outer_window: 0,
12-
class: 'pagination',
13-
previous_page_class: 'px-3 py-1 rounded-md text-sm font-medium text-gray-700 bg-white border border-gray-300 hover:bg-gray-50',
14-
next_page_class: 'px-3 py-1 rounded-md text-sm font-medium text-gray-700 bg-white border border-gray-300 hover:bg-gray-50' %>
8+
renderer: CustomPaginationRenderer,
9+
previous_label: 'Previous',
10+
next_label: 'Next',
11+
inner_window: 0,
12+
outer_window: 0,
13+
class: 'pagination',
14+
previous_page_class: 'px-3 py-1 rounded-md text-sm font-medium text-gray-700 bg-white border border-gray-300 hover:bg-gray-50',
15+
next_page_class: 'px-3 py-1 rounded-md text-sm font-medium text-gray-700 bg-white border border-gray-300 hover:bg-gray-50' %>
1516
</div>
1617
</div>
1718
<% end %>

app/views/job_applications/index.html.erb

Lines changed: 8 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,70 +6,18 @@
66
<div class="mb-8 flex justify-between items-center">
77
<div class="flex items-center">
88
<%= image_tag(asset_path('apple-touch-icon.png'),
9-
height: '32',
10-
width: '32',
11-
class: "rounded-full object-cover shadow-sm border-2 border-gray-200 mr-2",
12-
aria: { label: "Job Tracker logo" },
13-
title: "Job Tracker logo") %>
9+
height: '32',
10+
width: '32',
11+
class: "rounded-full object-cover shadow-sm border-2 border-gray-200 mr-2",
12+
aria: { label: "Job Tracker logo" },
13+
title: "Job Tracker logo") %>
1414
<h2 class="hidden md:block md:text-2xl font-semibold text-gray-700 shadow-2xl">
1515
Job Tracker
1616
</h2>
1717
</div>
18-
<%= link_to 'New Job Application', new_job_application_path, class: 'text-sm bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded cursor-pointer', data: { turbo_frame: "_top" } %>
1918
</div>
20-
<%= form_with url: job_applications_path, method: :get, data: { controller: "job-filter", turbo_frame: "job_applications_table" } do |form| %>
21-
<div class="flex flex-wrap -mx-2 mb-4">
22-
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
23-
<%= form.label :search, "Search", class: "sr-only" %>
24-
<%= form.text_field :search, value: params[:search], class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline", placeholder: "Search", data: { action: "input->job-filter#submit" } %>
25-
</div>
26-
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
27-
<%= form.label :method_of_contact, "Contact Method", class: "sr-only" %>
28-
<%= form.select :method_of_contact,
29-
options_for_select([["All Contact Methods", ""]] + JobApplication.method_of_contacts.map { |k, v| [k.humanize, v] }, params[:method_of_contact]),
30-
{},
31-
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
32-
data: { action: "change->job-filter#submit" }
33-
%>
34-
</div>
35-
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
36-
<%= form.label :position_type, "Position Type", class: "sr-only" %>
37-
<%= form.select :position_type,
38-
options_for_select([["All Position Types", ""]] + JobApplication.position_types.map { |k, v| [display_position_type(k), v] }, params[:position_type]),
39-
{},
40-
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
41-
data: { action: "change->job-filter#submit" }
42-
%>
43-
</div>
44-
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
45-
<%= form.label :claimed_for_unemployment, "Unemployment Claim", class: "sr-only" %>
46-
<%= form.select :claimed_for_unemployment,
47-
options_for_select([["All Claims", ""], ["Claimed", "true"], ["Not Claimed", "false"]], params[:claimed_for_unemployment]),
48-
{},
49-
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
50-
data: { action: "change->job-filter#submit" }
51-
%>
52-
</div>
53-
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
54-
<%= form.label :status, "Application Status", class: "sr-only" %>
55-
<%= form.select :status,
56-
options_for_select([["All Statuses", ""]] + JobApplication.statuses.map { |k, v| [k.humanize, v] }, params[:status]),
57-
{},
58-
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
59-
data: { action: "change->job-filter#submit" }
60-
%>
61-
</div>
62-
<div class="w-full md:w-1/6 px-2 mt-4 md:mt-0">
63-
<%= form.button "Reset Filters", type: "button", class: "w-full bg-gray-600 hover:bg-gray-700 text-white font-bold py-2 px-4 rounded cursor-pointer", data: { action: "click->job-filter#reset" } %>
64-
</div>
65-
</div>
66-
<% end %>
67-
<%= turbo_frame_tag "job_applications_table" do %>
68-
<%= render partial: "job_applications_table", locals: { job_applications: @job_applications } %>
69-
<div id="pagination" class="mt-4">
70-
<%= render partial: "pagination", locals: { job_applications: @job_applications, job_application_count: @job_application_count } %>
71-
</div>
72-
<% end %>
73-
<%= turbo_frame_tag "new_job_application" %>
19+
<div id="job_applications_content">
20+
<%= render 'empty_or_table' %>
21+
</div>
7422
</div>
7523
<% end %>

0 commit comments

Comments
 (0)