Skip to content
Merged
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
17 changes: 14 additions & 3 deletions app/controllers/job_applications_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,21 @@ def destroy
format.html { redirect_to root_path, success: "Job application was successfully deleted." }
format.turbo_stream {
flash.now[:success] = "Job application was successfully deleted."

# Reapply filters, sorting, and pagination
@job_applications = filter_and_sort_job_applications
@job_applications = @job_applications.paginate(page: params[:page], per_page: 10)

@pagination_info = {
total_pages: @job_applications.total_pages,
current_page: @job_applications.current_page,
total_entries: @job_applications.total_entries
}

render turbo_stream: [
turbo_stream.remove(@job_application),
turbo_stream.update("job_application_count", JobApplication.count),
turbo_stream.update("flash_messages", partial: "flash_messages")
turbo_stream.update("flash_messages", partial: "flash_messages"),
turbo_stream.update("job_applications_content", partial: "empty_or_table"),
turbo_stream.update("job_application_count", JobApplication.count)
]
}
end
Expand Down
62 changes: 62 additions & 0 deletions app/views/job_applications/_empty_or_table.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<% if JobApplication.exists? %>
<div class="mb-8 flex justify-end">
<%= 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" } %>
</div>
<%= form_with url: job_applications_path, method: :get, data: { controller: "job-filter", turbo_frame: "job_applications_table" } do |form| %>
<div class="flex flex-wrap -mx-2 mb-4">
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
<%= form.label :search, "Search", class: "sr-only" %>
<%= 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" } %>
</div>
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
<%= form.label :method_of_contact, "Contact Method", class: "sr-only" %>
<%= form.select :method_of_contact,
options_for_select([["All Contact Methods", ""]] + JobApplication.method_of_contacts.map { |k, v| [k.humanize, v] }, params[:method_of_contact]),
{},
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
data: { action: "change->job-filter#submit" }
%>
</div>
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
<%= form.label :position_type, "Position Type", class: "sr-only" %>
<%= form.select :position_type,
options_for_select([["All Position Types", ""]] + JobApplication.position_types.map { |k, v| [display_position_type(k), v] }, params[:position_type]),
{},
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
data: { action: "change->job-filter#submit" }
%>
</div>
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
<%= form.label :claimed_for_unemployment, "Unemployment Claim", class: "sr-only" %>
<%= form.select :claimed_for_unemployment,
options_for_select([["All Claims", ""], ["Claimed", "true"], ["Not Claimed", "false"]], params[:claimed_for_unemployment]),
{},
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
data: { action: "change->job-filter#submit" }
%>
</div>
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
<%= form.label :status, "Application Status", class: "sr-only" %>
<%= form.select :status,
options_for_select([["All Statuses", ""]] + JobApplication.statuses.map { |k, v| [k.humanize, v] }, params[:status]),
{},
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
data: { action: "change->job-filter#submit" }
%>
</div>
<div class="w-full md:w-1/6 px-2 mt-4 md:mt-0">
<%= 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" } %>
</div>
</div>
<% end %>
<%= turbo_frame_tag "job_applications_table" do %>
<%= render partial: "job_applications_table", locals: { job_applications: @job_applications } %>
<% if @job_applications.any? %>
<div id="pagination" class="mt-4">
<%= render partial: "pagination", locals: { job_applications: @job_applications, job_application_count: @job_applications.count } %>
</div>
<% end %>
<% end %>
<% else %>
<%= render 'empty_state' %>
<% end %>
8 changes: 8 additions & 0 deletions app/views/job_applications/_empty_state.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="text-center py-10 border-dashed border-2 border-gray-300 rounded-lg">
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<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" />
</svg>
<h2 class="mt-2 text-base font-semibold text-gray-900">No job applications</h2>
<p class="mt-1 mb-8 text-sm text-gray-500">Get started by creating a new job application.</p>
<%= 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" } %>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
<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" />
</svg>
<p class="mt-1 text-sm text-gray-500">
<%= "No results match your search criteria." if params[:search].present? || params[:method_of_contact].present? || params[:position_type].present? %>
No results match your search criteria.
</p>
</div>
<% end %>
Expand Down
19 changes: 10 additions & 9 deletions app/views/job_applications/_pagination.html.erb
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
<% if @pagination_info[:total_pages] > 1 %>
<% if @pagination_info && @pagination_info[:total_pages] && @pagination_info[:total_pages] > 1 %>
<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">
<div class="text-sm text-gray-700">
Showing <%= @pagination_info[:current_page] %> of <%= @pagination_info[:total_pages] %> pages
</div>
<div>
<%= will_paginate @job_applications,
renderer: CustomPaginationRenderer,
previous_label: 'Previous',
next_label: 'Next',
inner_window: 0,
outer_window: 0,
class: 'pagination',
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',
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' %>
renderer: CustomPaginationRenderer,
previous_label: 'Previous',
next_label: 'Next',
inner_window: 0,
outer_window: 0,
class: 'pagination',
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',
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' %>
</div>
</div>
<% end %>
68 changes: 8 additions & 60 deletions app/views/job_applications/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,70 +6,18 @@
<div class="mb-8 flex justify-between items-center">
<div class="flex items-center">
<%= image_tag(asset_path('apple-touch-icon.png'),
height: '32',
width: '32',
class: "rounded-full object-cover shadow-sm border-2 border-gray-200 mr-2",
aria: { label: "Job Tracker logo" },
title: "Job Tracker logo") %>
height: '32',
width: '32',
class: "rounded-full object-cover shadow-sm border-2 border-gray-200 mr-2",
aria: { label: "Job Tracker logo" },
title: "Job Tracker logo") %>
<h2 class="hidden md:block md:text-2xl font-semibold text-gray-700 shadow-2xl">
Job Tracker
</h2>
</div>
<%= 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" } %>
</div>
<%= form_with url: job_applications_path, method: :get, data: { controller: "job-filter", turbo_frame: "job_applications_table" } do |form| %>
<div class="flex flex-wrap -mx-2 mb-4">
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
<%= form.label :search, "Search", class: "sr-only" %>
<%= 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" } %>
</div>
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
<%= form.label :method_of_contact, "Contact Method", class: "sr-only" %>
<%= form.select :method_of_contact,
options_for_select([["All Contact Methods", ""]] + JobApplication.method_of_contacts.map { |k, v| [k.humanize, v] }, params[:method_of_contact]),
{},
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
data: { action: "change->job-filter#submit" }
%>
</div>
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
<%= form.label :position_type, "Position Type", class: "sr-only" %>
<%= form.select :position_type,
options_for_select([["All Position Types", ""]] + JobApplication.position_types.map { |k, v| [display_position_type(k), v] }, params[:position_type]),
{},
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
data: { action: "change->job-filter#submit" }
%>
</div>
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
<%= form.label :claimed_for_unemployment, "Unemployment Claim", class: "sr-only" %>
<%= form.select :claimed_for_unemployment,
options_for_select([["All Claims", ""], ["Claimed", "true"], ["Not Claimed", "false"]], params[:claimed_for_unemployment]),
{},
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
data: { action: "change->job-filter#submit" }
%>
</div>
<div class="w-full md:w-1/6 px-2 mb-4 md:mb-0">
<%= form.label :status, "Application Status", class: "sr-only" %>
<%= form.select :status,
options_for_select([["All Statuses", ""]] + JobApplication.statuses.map { |k, v| [k.humanize, v] }, params[:status]),
{},
class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
data: { action: "change->job-filter#submit" }
%>
</div>
<div class="w-full md:w-1/6 px-2 mt-4 md:mt-0">
<%= 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" } %>
</div>
</div>
<% end %>
<%= turbo_frame_tag "job_applications_table" do %>
<%= render partial: "job_applications_table", locals: { job_applications: @job_applications } %>
<div id="pagination" class="mt-4">
<%= render partial: "pagination", locals: { job_applications: @job_applications, job_application_count: @job_application_count } %>
</div>
<% end %>
<%= turbo_frame_tag "new_job_application" %>
<div id="job_applications_content">
<%= render 'empty_or_table' %>
</div>
</div>
<% end %>