improve bazdid 4

This commit is contained in:
javad committed 2026-10-21 15:13:35 +03:30
1 parent f86d060e4d
commit 8fd881e0ea
10 files changed
+1752 -320

No files matched your search

@@ -239,6 +239,8 @@
{% block bodyPage %}
{% endblock %}
{# بستن <div class=""> که بالاتر باز شده بود؛ پیش‌تر بسته نمی‌شد و HTML نامعتبر می‌شد. #}
</div>
</body>
<script>
@@ -164,6 +164,8 @@
{% block bodyPage %}
{% endblock %}
{# بستن <div class=""> که بالاتر باز شده بود (همان باگ base.html). #}
</div>
</body>
<script>
+315 -149
View File
@@ -24,7 +24,7 @@
-webkit-overflow-scrolling: touch;
}
@media (min-width: 1024px) {
.ez-stats { grid-auto-flow: row; grid-template-columns: repeat(6, 1fr); overflow: visible; }
.ez-stats { grid-auto-flow: row; grid-template-columns: repeat(4, 1fr); overflow: visible; }
}
.ez-stat {
display: flex; flex-direction: column; gap: .18rem;
@@ -41,6 +41,7 @@
.ez-stat.warning { border-top-color: #d97706; }
.ez-stat.link { border-top-color: #0284c7; }
.ez-stat.violet { border-top-color: #7c3aed; }
.ez-stat.followup { border-top-color: #0e7490; }
.ez-stat-top {
display: flex; align-items: baseline; justify-content: space-between; gap: .4rem;
@@ -69,21 +70,84 @@
}
.ez-legend b { font-variant-numeric: tabular-nums; color: #334155; }
/* ---------- ابزارک‌ها ---------- */
.ez-toolbar {
display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: 0 0 .75rem;
/* ---------- نوار تاریخ (نمای «نیازمند پیگیری») ---------- */
.ez-datebar {
display: flex; flex-wrap: wrap; align-items: flex-end; gap: .4rem;
padding: .5rem .6rem; margin: .5rem 0 .4rem;
background: #f8fbfd; border: 1px solid #d9e8f0; border-radius: .5rem;
}
.ez-toolbar .button { margin: 0 !important; }
.ez-seg {
display: inline-flex; border: 1px solid #e2e8f0; border-radius: .5rem; overflow: hidden;
.ez-datebar .button { margin: 0 !important; }
.ez-dateform { margin: 0; }
.ez-datefield { display: flex; flex-direction: column; gap: .15rem; margin: 0; }
.ez-datefield-row { display: flex; gap: .25rem; align-items: center; }
.ez-datefield-row .input {
height: 2.1rem; font-size: .78rem; width: 8.5rem;
font-variant-numeric: tabular-nums; direction: ltr; text-align: center;
}
.ez-seg a {
padding: .3rem .6rem; font-size: .72rem; color: #475569; text-decoration: none;
background: #fff; border-inline-end: 1px solid #e2e8f0; white-space: nowrap;
.ez-datenote {
flex: 1 1 100%; font-size: .7rem; color: #64748b; line-height: 1.7;
}
.ez-seg a:last-child { border-inline-end: 0; }
.ez-seg a:hover { background: #f1f5f9; }
.ez-seg a.is-active { background: #33b5d3; color: #fff; font-weight: 700; }
.ez-datenote b { color: #334155; }
@media (min-width: 700px) {
.ez-datenote { flex: 1 1 auto; }
}
/* ---------- هشدار مینیمال «پیگیری‌های عقب‌افتاده» ---------- */
.ez-overdue-alert,
.ez-overdue-mode {
flex: 1 1 100%; display: inline-flex; align-items: center; gap: .35rem;
font-size: .72rem; line-height: 1.6; text-decoration: none;
}
.ez-overdue-alert { color: #b91c1c; font-weight: 600; }
.ez-overdue-alert:hover { color: #991b1b; text-decoration: underline; }
.ez-overdue-alert b { font-variant-numeric: tabular-nums; font-size: .8rem; }
.ez-overdue-dot {
width: .42rem; height: .42rem; border-radius: 50%;
background: #dc2626; flex: 0 0 auto;
}
.ez-overdue-mode {
color: #7f1d1d; background: #fef2f2;
border: 1px solid #fecaca; border-radius: .375rem; padding: .2rem .5rem;
}
.ez-overdue-mode b { font-variant-numeric: tabular-nums; }
.ez-overdue-mode a {
color: #b91c1c; font-weight: 700; text-decoration: none;
margin-inline-start: .35rem;
}
.ez-overdue-mode a:hover { text-decoration: underline; }
/* ---------- نوار فیلتر ---------- */
.ez-filters {
display: flex; flex-wrap: wrap; align-items: flex-end;
gap: .5rem; margin: .6rem 0 .4rem;
}
.ez-filter { display: flex; flex-direction: column; gap: .15rem; margin: 0; }
.ez-filter-grow { flex: 1 1 18rem; min-width: 14rem; }
.ez-filter-lbl { font-size: .68rem; color: #64748b; font-weight: 700; }
.ez-filters .select select { font-size: .76rem; height: 2.1rem; }
.ez-search { display: flex; gap: .25rem; align-items: center; }
.ez-search .input { height: 2.1rem; font-size: .76rem; }
.ez-search .button { margin: 0 !important; }
.ez-clear { margin: 0 !important; }
/* ---------- سرستون‌های مرتب‌شدنی ---------- */
.ez-th > a {
display: inline-flex; align-items: center; gap: .15rem;
color: #06323d; text-decoration: none; white-space: nowrap;
}
.ez-th > a:hover { text-decoration: underline; }
.ez-th.is-sorted > a { color: #0b4e60; }
.ez-arrow { font-size: .62rem; opacity: .55; }
.ez-th.is-sorted .ez-arrow { opacity: 1; }
/* ---------- تفکیک تأخیر (کلیک‌پذیر) ---------- */
.ez-legend a {
color: #64748b; text-decoration: none; padding: .05rem .35rem;
border-radius: .25rem; white-space: nowrap;
}
.ez-legend a:hover { background: #f1f5f9; }
.ez-legend a.is-active { background: #33b5d3; color: #fff; }
.ez-legend a.is-active b { color: #fff; }
/* ---------- جدول ---------- */
.ez-table { width: 100%; margin: 0; font-size: .82rem; border-collapse: collapse; }
@@ -196,134 +260,231 @@
<div class="ez-wrap">
<div class="columns m-0">
<div class="column is-12 p-0">
{# ===== نوار آمار: هر عدد لینک فیلتر ===== #}
{# ===== نوار آمار: چهار کارت، هر عدد لینک فیلتر ===== #}
<div class="ez-stats-head">
<p class="ez-stats-title">وضعیت مشتریانِ عقب‌افتاده</p>
<p class="ez-stats-title">وضعیت پیگیری مشتریان</p>
<p class="ez-stats-hint">
«عقب‌افتاده» یعنی از آخرین بازدید
<b>بیش از {{ counts.period_months }} ماه</b> گذشته باشد.
روی هر کارت بزنید تا فقط همان گروه نمایش داده شود؛
<b>کل = بدون قرار + با قرار</b>.
سه کارتِ آخر سه نوع قرارِ جدا هستند؛ یک مشتری می‌تواند بیش از
یکی داشته باشد، پس جمع آن‌ها ممکن است از «با قرار» بیشتر شود.
<b>کل = تعیین‌تکلیف‌نشده + تعیین‌تکلیف‌شده</b>.
</p>
</div>
<div class="ez-stats">
<a href="?view=all&sort={{ sort }}{% if searchVal %}&searchVal={{ searchVal }}&searchOn={{ searchOn }}{% endif %}"
class="ez-stat total {% if view == 'all' %}is-active{% endif %}"
title="همهٔ مشتریان عقب‌افتاده، با هر وضعیت قرار">
{# کارت «نیازمند پیگیری امروز» — مستقل از «عقب‌افتاده»؛ بازدیدها حذف می‌شوند. #}
<a href="{{ view_links.today }}"
class="ez-stat followup {% if view == followup_view %}is-active{% endif %}"
title="مشتریانی که موعد پیگیری/تماسشان امروز است و برایشان بازدید برنامه‌ریزی نشده">
<span class="ez-stat-top">
<span class="ez-lbl">کل عقب‌افتاده‌ها</span>
<span class="ez-num">{{ counts.total }}</span>
<span class="ez-lbl">نیازمند پیگیری امروز</span>
<span class="ez-num has-text-info">{{ counts.followup_today }}</span>
</span>
<span class="ez-desc">همه، فارغ از داشتن یا نداشتن قرار</span>
<span class="ez-desc">موعد تماسشان امروز است — بازدید ندارند</span>
</a>
<a href="?view=uncoordinated&sort={{ sort }}{% if searchVal %}&searchVal={{ searchVal }}&searchOn={{ searchOn }}{% endif %}"
class="ez-stat danger {% if view == 'uncoordinated' %}is-active{% endif %}"
title="مشتریانی که هنوز هیچ قرار بعدی برایشان ثبت نشده است">
<a href="{{ view_links.all }}"
class="ez-stat total {% if view == 'all' %}is-active{% endif %}"
title="همهٔ مشتریانی که بازدیدشان عقب افتاده، با هر وضعیت پیگیری">
<span class="ez-stat-top">
<span class="ez-lbl">بدون قرار</span>
<span class="ez-lbl">همهٔ مشتریان عقب‌افتاده</span>
<span class="ez-num">{{ counts.total }}</span>
</span>
<span class="ez-desc">با هر وضعیت پیگیری</span>
</a>
<a href="{{ view_links.uncoordinated }}"
class="ez-stat danger {% if view == 'uncoordinated' %}is-active{% endif %}"
title="مشتریانی که هنوز هیچ وقت بازدید/پیگیری برایشان تعیین نشده است">
<span class="ez-stat-top">
<span class="ez-lbl">تعیین تکلیف نشده</span>
<span class="ez-num has-text-danger">{{ counts.uncoordinated }}</span>
</span>
<span class="ez-desc">هنوز وقت بازدید تعیین نشده — نیاز به تماس</span>
</a>
<a href="?view=coordinated&sort={{ sort }}{% if searchVal %}&searchVal={{ searchVal }}&searchOn={{ searchOn }}{% endif %}"
<a href="{{ view_links.coordinated }}"
class="ez-stat success {% if view == 'coordinated' %}is-active{% endif %}"
title="مشتریانی که وقت بازدید بعدی برایشان مشخص شده است">
title="مشتریانی که وقت بازدید یا پیگیریِ بعدی برایشان تعیین شده است">
<span class="ez-stat-top">
<span class="ez-lbl">با قرار</span>
<span class="ez-lbl">تعیین تکلیف شده</span>
<span class="ez-num has-text-success">{{ counts.coordinated }}</span>
</span>
<span class="ez-desc">وقت بازدیدشان مشخص است (هر دو نوع قرار)</span>
</a>
<a href="?view=manual&sort={{ sort }}{% if searchVal %}&searchVal={{ searchVal }}&searchOn={{ searchOn }}{% endif %}"
class="ez-stat warning {% if view == 'manual' %}is-active{% endif %}"
title="قرار تعویق که از فرم «هماهنگی» ثبت شده است">
<span class="ez-stat-top">
<span class="ez-lbl">قرار هماهنگی</span>
<span class="ez-num has-text-warning-dark">{{ counts.manual }}</span>
</span>
<span class="ez-desc">تعویق دستی از فرم هماهنگی (مثلاً «ماه بعد زنگ بزنید»)</span>
</a>
<a href="?view=scheduled&sort={{ sort }}{% if searchVal %}&searchVal={{ searchVal }}&searchOn={{ searchOn }}{% endif %}"
class="ez-stat link {% if view == 'scheduled' %}is-active{% endif %}"
title="اقدام «بازدید» با تاریخ آینده">
<span class="ez-stat-top">
<span class="ez-lbl">بازدید برنامه‌ریزی‌شده</span>
<span class="ez-num has-text-link">{{ counts.scheduled }}</span>
</span>
<span class="ez-desc">اقدام «بازدید» با تاریخ آینده ثبت شده است</span>
</a>
<a href="?view=coordination&sort={{ sort }}{% if searchVal %}&searchVal={{ searchVal }}&searchOn={{ searchOn }}{% endif %}"
class="ez-stat violet {% if view == 'coordination' %}is-active{% endif %}"
title="اقدام «هماهنگی» با تاریخ پیگیری در آینده">
<span class="ez-stat-top">
<span class="ez-lbl">هماهنگی</span>
<span class="ez-num" style="color:#7c3aed">{{ counts.coordination }}</span>
</span>
<span class="ez-desc">تماس گرفته شده و پیگیری به آینده موکول شده است</span>
<span class="ez-desc">وقت بعدی‌شان مشخص است</span>
</a>
</div>
{# تفکیک مدت تأخیر در نمای جاری #}
<div class="ez-legend">
<span>میزان تأخیر در همین نما:</span>
<span><b>{{ counts.buckets.lt30 }}</b> تا ۳۰ روز</span>
<span><b>{{ counts.buckets.30to90 }}</b> ۳۰ تا ۹۰ روز</span>
<span><b>{{ counts.buckets.90to180 }}</b> ۹۰ تا ۱۸۰ روز</span>
<span><b>{{ counts.buckets.gt180 }}</b> بیش از ۶ ماه</span>
</div>
{# ===== نوار تاریخ در نمای «نیازمند پیگیری» ===== #}
{% if is_followup_view %}
<div class="ez-datebar">
<a href="{{ followup_nav.prev }}" class="button is-small is-light"
title="روز قبل">‹ روز قبل</a>
{# ===== ابزارک‌ها: جستجو و مرتب‌سازی ===== #}
<div class="ez-toolbar">
<a href="#" id="openSearchBox" class="button is-info is-outlined is-rounded is-small">
جستجو{% if searchVal %}: «{{ searchVal }}»{% endif %}
</a>
<form method="get" class="ez-dateform">
<input type="hidden" name="view" value="{{ followup_view }}">
{% if searchVal %}<input type="hidden" name="searchVal" value="{{ searchVal }}">{% endif %}
{% if searchVal %}<input type="hidden" name="searchOn" value="{{ searchOn }}">{% endif %}
<label class="ez-datefield">
<span class="ez-filter-lbl">تاریخ پیگیری (شمسی)</span>
<span class="ez-datefield-row">
<input type="text" name="fdate" id="followupDatePicker"
value="{{ followup_date_jalali }}" class="input is-small ss02"
placeholder="۱۴۰۵/۰۸/۲۹" autocomplete="off" inputmode="numeric">
<button type="submit" class="button is-info is-small">نمایش</button>
</span>
</label>
</form>
<span class="is-size-7 has-text-grey">مرتب‌سازی</span>
<span class="ez-seg">
<a href="?view={{ view }}&sort=oldest{% if searchVal %}&searchVal={{ searchVal }}&searchOn={{ searchOn }}{% endif %}"
class="{% if sort == 'oldest' %}is-active{% endif %}">قدیمی‌ترین</a>
<a href="?view={{ view }}&sort=overdue{% if searchVal %}&searchVal={{ searchVal }}&searchOn={{ searchOn }}{% endif %}"
class="{% if sort == 'overdue' %}is-active{% endif %}">بیشترین تأخیر</a>
<a href="?view={{ view }}&sort=newest{% if searchVal %}&searchVal={{ searchVal }}&searchOn={{ searchOn }}{% endif %}"
class="{% if sort == 'newest' %}is-active{% endif %}">جدیدترین</a>
<a href="{{ followup_nav.next }}" class="button is-small is-light"
title="روز بعد">روز بعد ›</a>
{% if not followup_nav.is_today %}
<a href="{{ followup_nav.today }}" class="button is-success is-light is-small">
بازگشت به امروز
</a>
{% endif %}
<span class="ez-datenote">
{% if followup_nav.is_today %}
فقط موعدهای <b>امروز</b> نمایش داده می‌شوند.
{% else %}
نمایش موعدهای <b>{{ followup_date_jalali }}</b> (نه امروز).
{% endif %}
مشتریانی که برایشان <b>بازدید</b> گذاشته شده در این فهرست نمی‌آیند.
</span>
{% if searchVal %}
<a href="?view={{ view }}&sort={{ sort }}" class="button is-small is-light">حذف جستجو</a>
{# هشدار مینیمال: موعدهایی که گذشته‌اند و هنوز تعیین تکلیف نشده‌اند. #}
{% if counts.followup_overdue and not show_missed %}
<a class="ez-overdue-alert"
href="{{ followup_overdue_link }}"
title="موعد پیگیری‌شان گذشته و هنوز تعیین تکلیف نشده‌اند — برای دیدن فهرستشان کلیک کنید">
<span class="ez-overdue-dot" aria-hidden="true"></span>
<b>{{ counts.followup_overdue }}</b> مورد نیازمند پیگیری از روزهای قبل باقی مانده
</a>
{% endif %}
{% if show_missed %}
<span class="ez-overdue-mode">
نمایش <b>{{ counts.followup_overdue }}</b> پیگیریِ عقب‌افتاده
<a href="{{ followup_ontime_link }}" title="بازگشت به فهرست امروز">✕ بازگشت به امروز</a>
</span>
{% endif %}
</div>
{% endif %}
{# ===== نوار فیلتر و جست‌وجو: یک ردیف، همهٔ کنترل‌ها ===== #}
<form class="ez-filters" method="get" action="">
{% if is_followup_view %}
<input type="hidden" name="fdate" value="{{ followup_date_jalali }}">
{% endif %}
{# حالت «فقط عقب‌افتاده‌ها» هنگام جست‌وجو/فیلتر حفظ شود. #}
{% if show_missed %}
<input type="hidden" name="missed" value="1">
{% endif %}
<label class="ez-filter">
<span class="ez-filter-lbl">نوع قرار</span>
<span class="select is-small">
<select name="view" class="ez-auto-submit">
<option value="today" {% if is_followup_view %}selected{% endif %}>نیازمند پیگیری (تاریخ انتخابی)</option>
<option value="all" {% if view == 'all' %}selected{% endif %}>همه (با و بدون قرار)</option>
<option value="uncoordinated" {% if view == 'uncoordinated' %}selected{% endif %}>تعیین تکلیف نشده</option>
<option value="coordinated" {% if view == 'coordinated' %}selected{% endif %}>تعیین تکلیف شده (همه)</option>
<option value="manual" {% if view == 'manual' %}selected{% endif %}>تعویق دستی</option>
<option value="scheduled" {% if view == 'scheduled' %}selected{% endif %}>بازدید برنامه‌ریزی‌شده</option>
<option value="coordination" {% if view == 'coordination' %}selected{% endif %}>پیگیری تلفنی</option>
</select>
</span>
</label>
{% if not is_followup_view %}
<label class="ez-filter">
<span class="ez-filter-lbl">میزان تأخیر</span>
<span class="select is-small">
<select name="delay" class="ez-auto-submit">
<option value="" {% if not delay %}selected{% endif %}>همه</option>
<option value="lt30" {% if delay == 'lt30' %}selected{% endif %}>تا ۳۰ روز ({{ counts.buckets.lt30 }})</option>
<option value="30to90" {% if delay == '30to90' %}selected{% endif %}>۳۰ تا ۹۰ روز ({{ counts.buckets.30to90 }})</option>
<option value="90to180" {% if delay == '90to180' %}selected{% endif %}>۹۰ تا ۱۸۰ روز ({{ counts.buckets.90to180 }})</option>
<option value="gt180" {% if delay == 'gt180' %}selected{% endif %}>بیش از ۶ ماه ({{ counts.buckets.gt180 }})</option>
</select>
</span>
</label>
{% endif %}
<label class="ez-filter">
<span class="ez-filter-lbl">مرتب‌سازی</span>
<span class="select is-small">
<select name="sort" class="ez-auto-submit">
<option value="last_visit" {% if sort == 'last_visit' and sort_dir == 'asc' %}selected{% endif %}>قدیمی‌ترین بازدید</option>
<option value="last_visit-desc" {% if sort == 'last_visit' and sort_dir == 'desc' %}selected{% endif %}>جدیدترین بازدید</option>
<option value="overdue" {% if sort == 'overdue' %}selected{% endif %}>بیشترین تأخیر</option>
<option value="name" {% if sort == 'name' %}selected{% endif %}>نام (الفبا)</option>
<option value="status" {% if sort == 'status' %}selected{% endif %}>وضعیت قرار</option>
<option value="coordination" {% if sort == 'coordination' %}selected{% endif %}>تاریخ پیگیری</option>
</select>
</span>
</label>
<label class="ez-filter ez-filter-grow">
<span class="ez-filter-lbl">جست‌وجو</span>
<span class="ez-search">
<input type="text" name="searchVal" value="{{ searchVal }}"
class="input is-small" placeholder="نام، تلفن، کد یا آدرس">
<span class="select is-small">
<select name="searchOn">
<option value="name" {% if searchOn == 'name' %}selected{% endif %}>نام</option>
<option value="phone" {% if searchOn == 'phone' %}selected{% endif %}>تلفن</option>
<option value="code" {% if searchOn == 'code' %}selected{% endif %}>کد</option>
<option value="address" {% if searchOn == 'address' %}selected{% endif %}>آدرس</option>
</select>
</span>
<button type="submit" class="button is-info is-small">جست‌وجو</button>
</span>
</label>
{% if has_filters %}
<a href="{{ clear_link }}" class="button is-light is-small ez-clear">✕ حذف فیلترها</a>
{% endif %}
</form>
{# تفکیک مدت تأخیر در نمای جاری (کلیک‌پذیر) #}
{% if not is_followup_view %}
<div class="ez-legend">
<span>میزان تأخیر در همین نما:</span>
<a href="{{ delay_links.ez_all }}" class="{% if not delay %}is-active{% endif %}">
<b>{{ counts.view_total }}</b> همه
</a>
<a href="{{ delay_links.lt30 }}" class="{% if delay == 'lt30' %}is-active{% endif %}">
<b>{{ counts.buckets.lt30 }}</b> تا ۳۰ روز
</a>
<a href="{{ delay_links.30to90 }}" class="{% if delay == '30to90' %}is-active{% endif %}">
<b>{{ counts.buckets.30to90 }}</b> ۳۰ تا ۹۰ روز
</a>
<a href="{{ delay_links.90to180 }}" class="{% if delay == '90to180' %}is-active{% endif %}">
<b>{{ counts.buckets.90to180 }}</b> ۹۰ تا ۱۸۰ روز
</a>
<a href="{{ delay_links.gt180 }}" class="{% if delay == 'gt180' %}is-active{% endif %}">
<b>{{ counts.buckets.gt180 }}</b> بیش از ۶ ماه
</a>
</div>
{% endif %}
<div class="table-container">
<table class="table ez-table">
<colgroup>
<col style="width: 21%">
<col style="width: 12%">
<col style="width: 10%">
<col style="width: 10%">
<col style="width: 10%">
<col style="width: 9%">
<col style="width: 8%">
<col style="width: 9%">
<col style="width: 11%">
{% for col in table_columns %}
<col style="width: {{ col.width }}%">
{% endfor %}
</colgroup>
<thead>
<tr>
<th>نام و نام خانوادگی</th>
<th>وضعیت قرار</th>
<th>قرار دستی</th>
<th>بازدید برنامه‌ریزی‌شده</th>
<th>هماهنگی</th>
<th>آخرین بازدید</th>
<th>تأخیر</th>
<th>تلفن</th>
<th>آدرس</th>
{% for col in sort_header %}
<th class="ez-th {% if col.active %}is-sorted{% endif %}">
<a href="{{ col.link }}" title="مرتب‌سازی بر اساس {{ col.label }}">
{{ col.label }}<span class="ez-arrow">{% if col.active %}{% if col.dir == 'asc' %}▲{% else %}▼{% endif %}{% else %}⇅{% endif %}</span>
</a>
</th>
{% endfor %}
</tr>
</thead>
<tbody>
@@ -364,6 +525,7 @@
<td data-label="آخرین بازدید" class="ez-num ez-nowrap lastView">
{% if appt.last_visit %}{{ appt.last_visit|toJalali }}{% else %}<span class="ez-muted">بدون بازدید</span>{% endif %}
</td>
{% if 'overdue' not in hidden_columns %}
<td data-label="تأخیر" class="ez-nowrap">
{% if appt.overdue_days >= 180 %}
<span class="ez-late lv3">{{ appt.overdue_days }} روز</span>
@@ -375,6 +537,7 @@
<span class="ez-late lv0">{{ appt.overdue_days }} روز</span>
{% endif %}
</td>
{% endif %}
{% endwith %}
<td data-label="تلفن" class="ez-nowrap">
@@ -397,8 +560,14 @@
</tr>
{% empty %}
<tr>
<td colspan="9" class="has-text-centered py-5">
<span class="has-text-grey">موردی در این نما پیدا نشد.</span>
<td colspan="{{ column_count }}" class="has-text-centered py-5">
<span class="has-text-grey">
{% if is_followup_view %}
برای تاریخ {{ followup_date_jalali }} موردی برای پیگیری نیست.
{% else %}
موردی در این نما پیدا نشد.
{% endif %}
</span>
</td>
</tr>
{% endfor %}
@@ -409,7 +578,7 @@
{# ===== صفحه‌بندی ===== #}
<div class="is-flex is-align-items-center is-justify-content-space-between mt-3 mb-5">
{% if customers.has_previous %}
<a class="button is-danger is-small" href="?view={{ view }}&sort={{ sort }}{% if searchVal %}&searchVal={{ searchVal }}&searchOn={{ searchOn }}{% endif %}&page={{ customers.previous_page_number }}">صفحه قبل</a>
<a class="button is-danger is-small" href="{{ page_prev }}">صفحه قبل</a>
{% else %}<span></span>{% endif %}
<span class="is-size-7 has-text-grey">
@@ -418,60 +587,57 @@
</span>
{% if customers.has_next %}
<a class="button is-danger is-small" href="?view={{ view }}&sort={{ sort }}{% if searchVal %}&searchVal={{ searchVal }}&searchOn={{ searchOn }}{% endif %}&page={{ customers.next_page_number }}">صفحه بعد</a>
<a class="button is-danger is-small" href="{{ page_next }}">صفحه بعد</a>
{% else %}<span></span>{% endif %}
</div>
</div>
</div>
</div>
<div class="modal SearchBox">
<div class="modal-background closeSearch"></div>
<div class="modal-content">
<form method="get" class="columns is-mobile is-multiline">
{# حفظ نما و ترتیب هنگام جست‌وجو #}
<input type="hidden" name="view" value="{{ view }}">
<input type="hidden" name="sort" value="{{ sort }}">
<div class="field column is-7-desktop is-12-mobile m-0">
<label class="label">جستجو کنید</label>
<div class="control">
<input name="searchVal" class="input search" type="text" value="{{ searchVal }}" placeholder="نام، تلفن، کد یا آدرس">
</div>
</div>
<div class="field column is-5-desktop is-12-mobile m-0">
<label class="label">فیلد</label>
<div class="select is-fullwidth">
<select name="searchOn">
<option value="name" {% if searchOn == 'name' %}selected{% endif %}>نام و نام خانوادگی</option>
<option value="phone" {% if searchOn == 'phone' %}selected{% endif %}>تلفن</option>
<option value="address" {% if searchOn == 'address' %}selected{% endif %}>آدرس</option>
<option value="code" {% if searchOn == 'code' %}selected{% endif %}>کد مشتری</option>
</select>
</div>
</div>
<div class="field column is-12-desktop is-12-mobile m-0">
<input class="button is-success is-fullwidth" id="searchbtn" value="جستجو مشتری" type="submit">
</div>
</form>
</div>
<button class="modal-close is-large closeSearch" aria-label="close"></button>
</div>
{% endblock %}
{% block jsEnd %}
<script>
$(document).ready(function() {
$("#openSearchBox").click(function(e) {
e.preventDefault();
$(".SearchBox").addClass("is-active");
});
$(".closeSearch").click(function() {
$(".SearchBox").removeClass("is-active");
// تغییر هر دراپ‌داون ⇒ ارسال خودکار فرم فیلترها.
$(".ez-auto-submit").on('change', function () {
$(this).closest('form').trigger('submit');
});
// مقدار «مرتب‌سازی» با علامتِ جهت ترکیب می‌شود (مثلاً last_visit-desc)
// تا یک دراپ‌داون بتواند هر دو جهت را پوشش دهد.
$(".ez-filters select[name=sort]").on('change', function () {
var value = $(this).val() || '';
var form = $(this).closest('form');
var dash = value.lastIndexOf('-');
if (dash > -1) {
form.find("input[name=sort]").val(value.slice(0, dash));
form.find("input[name=dir]").val(value.slice(dash + 1));
} else {
form.find("input[name=sort]").val(value);
form.find("input[name=dir]").val('');
}
});
// تقویم شمسی برای ناوبری روزهای نمای «نیازمند پیگیری».
// همان کامپوننت pDatepicker که در بقیهٔ صفحه‌ها استفاده شده است.
{% if is_followup_view %}
var $followupDate = $("#followupDatePicker");
if ($followupDate.length && typeof $followupDate.pDatepicker === 'function') {
$followupDate.pDatepicker({
initialValue: false,
initialValueType: 'persian',
format: 'YYYY/MM/DD',
autoClose: true,
calendar: {
persian: { locale: 'fa', leapYearMode: 'astronomical' }
},
onSelect: function () {
// انتخاب تاریخ ⇒ فوراً همان روز نمایش داده شود.
$followupDate.closest('form').trigger('submit');
}
});
}
{% endif %}
});
</script>
{% endblock %}