142 lines
7.6 KiB
HTML
142 lines
7.6 KiB
HTML
{% extends 'base.html' %}
|
|
{% load i18n static humanize %}
|
|
{% load custom_filters %}
|
|
{% block title %}
|
|
{{ _("Opportunities") }}
|
|
{% endblock title %}
|
|
{% block content %}
|
|
{% if opportunities or request.GET.q %}
|
|
<div class="row g-3 mt-4">
|
|
<div class="row g-3 justify-content-between mb-4">
|
|
<div class="col-auto">
|
|
<div class="d-md-flex justify-content-between">
|
|
<h2 class="mb-3">
|
|
{{ _("Opportunities") }}
|
|
<li class="fas fas fa-rocket text-primary ms-2"></li>
|
|
</h2>
|
|
</div>
|
|
</div>
|
|
<div class="col-auto">
|
|
{% if perms.inventory.add_opportunity %}
|
|
<div class="d-flex justify-content-between">
|
|
<a class="btn btn-phoenix-primary btn-sm"
|
|
href="{% url 'opportunity_create' request.dealer.slug %}">
|
|
<span class="fas fa-plus me-2"></span>{{ _("Add Opportunity") }}
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="d-flex flex-column flex-md-row justify-content-between align-items-md-center gap-3 mb-4">
|
|
<!-- Filter Controls -->
|
|
<div class="d-flex flex-column flex-lg-row align-items-start align-items-lg-center gap-3 w-100"
|
|
id="filter-container">
|
|
<!-- Search Input - Wider and properly aligned -->
|
|
<div class="search-box position-relative flex-grow-1 me-2"
|
|
style="min-width: 200px">
|
|
<form class="position-relative show"
|
|
id="search-form"
|
|
hx-get=""
|
|
hx-boost="false"
|
|
hx-trigger="keyup changed delay:500ms, search">
|
|
<input name="q"
|
|
id="search-input"
|
|
class="form-control form-control-sm search-input search"
|
|
type="search"
|
|
aria-label="Search"
|
|
placeholder="{{ _("Search") }}..."
|
|
value="{{ request.GET.q }}" />
|
|
<span class="fa fa-magnifying-glass search-box-icon"></span>
|
|
{% if request.GET.q %}
|
|
<button type="button"
|
|
class="btn-close position-absolute end-0 top-50 translate-middle cursor-pointer shadow-none"
|
|
id="clear-search"
|
|
aria-label="Clear Search"></button>
|
|
{% endif %}
|
|
</form>
|
|
</div>
|
|
<!-- Filter Dropdowns - Aligned in a row -->
|
|
<div class="d-flex flex-column flex-sm-row gap-3 w-100"
|
|
style="max-width: 400px">
|
|
<!-- Stage Filter -->
|
|
<!-- Stage Filter -->
|
|
<div class="flex-grow-1">
|
|
<select class="form-select"
|
|
name="stage"
|
|
hx-get="{% url 'opportunity_list' request.dealer.slug %}"
|
|
hx-trigger="change"
|
|
hx-target="#opportunities-grid"
|
|
hx-select="#opportunities-grid"
|
|
hx-swap="outerHTML"
|
|
hx-include="#filter-container input, #filter-container select">
|
|
<option value="">{% trans "All Stages" %}</option>
|
|
{% for value, label in stage_choices %}
|
|
<option value="{{ value }}"
|
|
{% if request.GET.stage == value %}selected{% endif %}>
|
|
{{ label }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<!-- Sort Filter -->
|
|
<div class="flex-grow-1">
|
|
<select class="form-select"
|
|
name="sort"
|
|
hx-get="{% url 'opportunity_list' request.dealer.slug %}"
|
|
hx-trigger="change"
|
|
hx-target="#opportunities-grid"
|
|
hx-select="#opportunities-grid"
|
|
hx-swap="outerHTML"
|
|
hx-include="#filter-container input, #filter-container select">
|
|
<option value="newest"
|
|
{% if request.GET.sort == 'newest' %}selected{% endif %}>
|
|
{% trans "Newest First" %}
|
|
</option>
|
|
<option value="highest"
|
|
{% if request.GET.sort == 'highest' %}selected{% endif %}>
|
|
{% trans "Highest Value" %}
|
|
</option>
|
|
<option value="closing"
|
|
{% if request.GET.sort == 'closing' %}selected{% endif %}>
|
|
{% trans "Earliest Close Date" %}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="opportunities-grid" class="row g-4 px-2 px-lg-4 mt-1 mb-4">
|
|
{% include 'crm/opportunities/partials/opportunity_grid.html' %}
|
|
</div>
|
|
{% if page_obj.paginator.num_pages > 1 %}
|
|
<div class="d-flex justify-content-end mt-3">
|
|
<div class="d-flex">{% include 'partials/pagination.html' %}</div>
|
|
</div>
|
|
{% endif %}
|
|
{% else %}
|
|
{% url 'opportunity_create' request.dealer.slug as create_opportunity_url %}
|
|
{% include "empty-illustration-page.html" with value=empty_state_value url=create_opportunity_url %}
|
|
{% endif %}
|
|
{% block customJS %}
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
const searchInput = document.getElementById("search-input");
|
|
const clearButton = document.getElementById("clear-search");
|
|
const searchForm = document.getElementById("search-form");
|
|
|
|
if (clearButton) {
|
|
clearButton.addEventListener("click", function() {
|
|
searchInput.value = "";
|
|
// This clears the search and triggers the htmx search
|
|
// by submitting the form with an empty query.
|
|
searchForm.submit();
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
{% endblock %}
|