Files
customerTicket/templates/tickets/customer_new.html
T
2026-09-14 15:48:13 +03:30

147 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends 'base.html' %}{% load static %}
{% block title %}{{ page_title }}{% endblock %}
{% block content %}
<link rel="stylesheet" href="{% static 'css/ticket-composer.css' %}?v={{ static_asset_version }}">
<link rel="stylesheet" href="{% static 'css/ticket-composer-v2.css' %}?v={{ static_asset_version }}">
<link rel="stylesheet" href="{% static 'css/customer-ticket-wizard.css' %}?v={{ static_asset_version }}">
<div class="ticket-wizard-page">
<nav class="ticket-wizard-topbar" aria-label="مسیر صفحه">
<a class="ticket-wizard-back" href="{% url 'tickets:list' %}">→ بازگشت به درخواست‌ها</a>
<span class="ticket-wizard-save"><i></i> اطلاعات تا زمان خروج از صفحه حفظ می‌شود</span>
</nav>
<header class="ticket-wizard-intro">
<p class="page-kicker">ثبت درخواست جدید</p>
<h1>چطور می‌توانیم کمک کنیم؟</h1>
<p>قدم‌به‌قدم پیش می‌رویم؛ در هر مرحله فقط اطلاعات ضروری همان بخش را می‌بینید.</p>
</header>
<ol class="ticket-wizard-progress" data-wizard-progress aria-label="مراحل ثبت درخواست">
<li class="is-active" data-wizard-progress-item="1"><span>۱</span><div><b>موضوع</b><small>مسیر درخواست</small></div></li>
<li data-wizard-progress-item="2"><span>۲</span><div><b>موقعیت</b><small>اختیاری</small></div></li>
<li data-wizard-progress-item="3"><span>۳</span><div><b>کارشناس</b><small>انتخاب مسئول</small></div></li>
<li data-wizard-progress-item="4"><span>۴</span><div><b>جزئیات</b><small>متن و فایل</small></div></li>
<li data-wizard-progress-item="5"><span>۵</span><div><b>بازبینی</b><small>تأیید نهایی</small></div></li>
</ol>
<form class="ticket-wizard-card" method="post" enctype="multipart/form-data" novalidate
data-ticket-composer data-ticket-wizard
data-unit-options-url="{% url 'tickets:new_options' %}"
data-ticket-search-url="{% url 'tickets:new_search' %}"
data-chat-coach data-chat-coach-key="customer-new-{{ user.public_id }}">
{% csrf_token %}
<section class="ticket-wizard-step is-active" data-wizard-step="1" aria-labelledby="wizard-step-1-title">
<header class="ticket-wizard-step-head">
<span class="ticket-wizard-symbol" aria-hidden="true">⌕</span>
<div><small>مرحله ۱ از ۵</small><h2 id="wizard-step-1-title">موضوع درخواستتان چیست؟</h2><p>چند کلمه بنویسید تا مسیر مناسب پیشنهاد شود، یا واحد و دسته‌بندی را دستی انتخاب کنید.</p></div>
</header>
<label class="ticket-intent-search">
<span class="sr-only">جست‌وجوی موضوع درخواست</span><i aria-hidden="true">⌕</i>
<input type="search" data-ticket-search autocomplete="off" placeholder="مثلاً فیش واریزی، موجودی کالا یا ارسال بار...">
<kbd>جست‌وجو</kbd>
</label>
<div class="intent-results ticket-intent-results" data-ticket-search-results aria-live="polite"></div>
<details class="ticket-manual-routing manual-routing" {% if form.is_bound and form.errors %}open{% endif %}>
<summary><span>انتخاب دستی واحد و دسته‌بندی</span><small>در صورت تمایل مسیر درخواست را خودتان مشخص کنید</small></summary>
<div class="ticket-manual-body manual-routing-body">
<div class="ticket-routing-grid" data-routing-selectors>
<div class="field">{{ form.unit.label_tag }}{{ form.unit }}{{ form.unit.errors }}</div>
<div class="field">{{ form.category.label_tag }}{{ form.category }}{{ form.category.errors }}</div>
</div>
</div>
</details>
<div class="field ticket-subject-field">
<label for="{{ form.subject.id_for_label }}">موضوع دقیق درخواست <em>*</em></label>
{{ form.subject }}{{ form.subject.errors }}
<small>این عنوان فقط توسط شما نوشته می‌شود و با تغییر واحد یا دسته‌بندی عوض نخواهد شد.</small>
</div>
<p class="ticket-wizard-validation" data-wizard-error="1" role="alert"></p>
<footer class="ticket-wizard-actions"><span>حدود یک دقیقه تا پایان</span><button class="primary" type="button" data-wizard-next>ادامه <b>←</b></button></footer>
</section>
<section class="ticket-wizard-step" data-wizard-step="2" aria-labelledby="wizard-step-2-title">
<header class="ticket-wizard-step-head">
<span class="ticket-wizard-symbol" aria-hidden="true">⌖</span>
<div><small>مرحله ۲ از ۵ · اختیاری</small><h2 id="wizard-step-2-title">این درخواست مربوط به کجاست؟</h2><p>اگر موقعیت در پاسخ بهتر کارشناسان مؤثر است آن را انتخاب کنید؛ در غیر این صورت عبور کنید.</p></div>
</header>
<section class="ticket-location-fields" data-location-picker data-locations-url="{% static 'data/iran-locations.json' %}">
<div class="ticket-two-columns"><div class="field">{{ form.province.label_tag }}{{ form.province }}{{ form.province.errors }}</div><div class="field">{{ form.city.label_tag }}{{ form.city }}{{ form.city.errors }}</div></div>
<p class="location-hint" data-location-hint>نام استان را جست‌وجو و انتخاب کنید.</p>
</section>
<div class="ticket-soft-tip"><span>i</span><p><b>نیازی به انتخاب ندارید</b> این بخش کاملاً اختیاری است و می‌توانید مستقیماً ادامه دهید.</p></div>
<p class="ticket-wizard-validation" data-wizard-error="2" role="alert"></p>
<footer class="ticket-wizard-actions"><button class="secondary" type="button" data-wizard-prev>مرحله قبل</button><button class="primary" type="button" data-wizard-next>ادامه <b>←</b></button></footer>
</section>
<section class="ticket-wizard-step" data-wizard-step="3" aria-labelledby="wizard-step-3-title">
<header class="ticket-wizard-step-head">
<span class="ticket-wizard-symbol" aria-hidden="true">◎</span>
<div><small>مرحله ۳ از ۵ · اختیاری</small><h2 id="wizard-step-3-title">چه کسی درخواست را بررسی کند؟</h2><p>صف عمومی پیشنهاد ماست؛ درخواست به اولین کارشناس آزاد همان واحد می‌رسد.</p></div>
</header>
<fieldset class="expert-picker ticket-expert-picker" data-expert-picker>
<legend class="sr-only">کارشناس دلخواه</legend>
<label class="expert-card" data-general-queue data-unit-id="{{ selected_unit.pk|default:'' }}"><input type="radio" name="selected_expert" value="" {% if not form.selected_expert.value %}checked{% endif %}><span class="expert-avatar">⌁</span><strong>صف عمومی {{ selected_unit.name|default:'واحد' }}</strong><small>سریع‌ترین انتخاب · اولین کارشناس آزاد</small></label>
{% for expert in form.fields.selected_expert.queryset %}<label class="expert-card"><input type="radio" name="selected_expert" value="{{ expert.pk }}" {% if form.selected_expert.value|stringformat:'s' == expert.pk|stringformat:'s' %}checked{% endif %}><img src="{% url 'tickets:expert_avatar' expert.user.public_id %}?v={{ expert.updated_at|date:'U' }}" alt="تصویر {{ expert.display_name }}" width="56" height="56" loading="lazy"><strong>{{ expert.display_name }}</strong><small>{{ expert.job_title|default:'کارشناس واحد' }}</small></label>{% empty %}<p class="muted expert-empty">کارشناس قابل انتخابی ثبت نشده؛ درخواست به صف عمومی می‌رود.</p>{% endfor %}
</fieldset>
{{ form.selected_expert.errors }}
<p class="ticket-wizard-validation" data-wizard-error="3" role="alert"></p>
<footer class="ticket-wizard-actions"><button class="secondary" type="button" data-wizard-prev>مرحله قبل</button><button class="primary" type="button" data-wizard-next>ادامه <b>←</b></button></footer>
</section>
<section class="ticket-wizard-step" data-wizard-step="4" aria-labelledby="wizard-step-4-title">
<header class="ticket-wizard-step-head">
<span class="ticket-wizard-symbol" aria-hidden="true">≡</span>
<div><small>مرحله ۴ از ۵</small><h2 id="wizard-step-4-title">جزئیات را برای کارشناس بنویسید</h2><p>شرح متنی، فایل یا پیام صوتی اضافه کنید تا کارشناس مسئله را دقیق‌تر بررسی کند.</p></div>
</header>
<div class="field ticket-body-field">{{ form.body.label_tag }}{{ form.body }}{{ form.body.errors }}<small><span data-body-count>۰</span> نویسه</small></div>
<div class="upload-zone media-picker ticket-attachment-zone">
<header class="ticket-attachment-head"><span>+</span><div><b>عکس و فایل‌های مرتبط</b><small>تصاویر بزرگ پیش از ارسال روی دستگاه شما بهینه می‌شوند.</small></div></header>
<div class="media-picker-actions ticket-attachment-actions"><label class="media-picker-button gallery-button" for="ticket-gallery-input">▣ انتخاب عکس از گالری</label><label class="media-picker-button" for="ticket-file-input">+ انتخاب فایل</label></div>
<input id="ticket-gallery-input" type="file" accept="image/*" multiple data-gallery-input><input id="ticket-file-input" type="file" multiple data-document-input>
<span class="canonical-files">{{ form.files }}</span>{{ form.files.errors }}
<small class="compression-note" data-compression-status>فایل‌های انتخاب‌شده پیش از ثبت قابل مشاهده و حذف هستند.</small>
<div class="file-preview" data-file-preview aria-live="polite"></div>
</div>
<section class="ticket-voice-recorder" data-ticket-voice-recorder aria-labelledby="ticket-voice-title">
<header class="ticket-voice-head"><span class="ticket-voice-icon" aria-hidden="true">◉</span><div><b id="ticket-voice-title">پیام صوتی</b><small data-voice-status aria-live="polite">برای توضیح سریع‌تر، صدای خود را ضبط کنید.</small></div><span class="ticket-voice-timer" data-voice-timer>۰۰:۰۰</span></header>
<div class="ticket-voice-idle" data-voice-idle><button class="ticket-voice-start" type="button" data-voice-record><span>●</span> شروع ضبط صدا</button><small>پس از اجازه‌دادن به میکروفن، ضبط آغاز می‌شود.</small></div>
<div class="ticket-voice-live" data-voice-live hidden><div class="ticket-voice-wave" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div><div class="ticket-voice-controls"><button type="button" data-voice-pause>مکث</button><button class="ticket-voice-stop" type="button" data-voice-stop>■ توقف و ذخیره</button><button class="ticket-voice-cancel" type="button" data-voice-cancel>لغو</button></div></div>
<div class="ticket-voice-preview" data-voice-preview hidden><div class="ticket-voice-ready"><span>✓</span><p><b>پیام صوتی آماده است</b><small data-voice-meta>قابل پخش و بررسی پیش از ارسال</small></p></div><audio controls preload="metadata" data-voice-audio></audio><div class="ticket-voice-preview-actions"><button type="button" data-voice-rerecord>ضبط مجدد</button><button type="button" data-voice-delete>حذف پیام صوتی</button></div></div>
<p class="ticket-voice-note"><span>ⓘ</span> با رفتن به مرحله بعد، ضبط فعال به‌صورت خودکار متوقف و ذخیره می‌شود.</p>
<p class="ticket-voice-error" data-voice-error role="alert" hidden></p>
</section>
<div class="ticket-server-errors" data-step-server-errors>{% if form.non_field_errors %}{{ form.non_field_errors }}{% endif %}</div>
<p class="ticket-wizard-validation" data-wizard-error="4" role="alert"></p>
<footer class="ticket-wizard-actions"><button class="secondary" type="button" data-wizard-prev>مرحله قبل</button><button class="primary" type="button" data-wizard-next>مشاهده پیش‌نمایش <b>←</b></button></footer>
</section>
<section class="ticket-wizard-step ticket-review-step" data-wizard-step="5" aria-labelledby="wizard-step-5-title">
<header class="ticket-wizard-step-head"><span class="ticket-wizard-symbol is-success" aria-hidden="true">✓</span><div><small>مرحله ۵ از ۵</small><h2 id="wizard-step-5-title">همه‌چیز آماده ارسال است</h2><p>اطلاعات را یک‌بار مرور کنید؛ هر بخش را می‌توانید جداگانه ویرایش کنید.</p></div></header>
<div class="ticket-review-callout"><span>✓</span><div><b>یک مرور کوتاه پیش از ارسال</b><small>اگر موردی درست نیست، همان ردیف را ویرایش کنید؛ اطلاعات مراحل دیگر حفظ می‌شود.</small></div></div>
<div class="ticket-review-list">
<section class="ticket-review-row"><span class="ticket-review-icon">۱</span><div class="ticket-review-content"><small>موضوع و مسیر رسیدگی</small><h3 data-review-subject>—</h3><p><span data-review-unit>—</span><i>←</i><span data-review-category>—</span></p></div><button type="button" data-wizard-edit="1"><span>✎</span> ویرایش</button></section>
<section class="ticket-review-row"><span class="ticket-review-icon">۲</span><div class="ticket-review-content"><small>موقعیت</small><h3 data-review-location>ثبت نشده</h3><p>اختیاری</p></div><button type="button" data-wizard-edit="2"><span>✎</span> ویرایش</button></section>
<section class="ticket-review-row"><span class="ticket-review-icon">۳</span><div class="ticket-review-content"><small>نحوه ارجاع</small><h3 data-review-expert>صف عمومی</h3><p>در همان واحد سازمانی</p></div><button type="button" data-wizard-edit="3"><span>✎</span> ویرایش</button></section>
<section class="ticket-review-row ticket-review-details"><span class="ticket-review-icon">۴</span><div class="ticket-review-content"><small>شرح و پیوست‌ها</small><p class="ticket-review-body" data-review-body>—</p><div class="ticket-review-files" data-review-files></div><audio class="ticket-review-audio" controls hidden data-review-audio></audio></div><button type="button" data-wizard-edit="4"><span>✎</span> ویرایش</button></section>
</div>
<p class="ticket-wizard-validation" data-wizard-error="5" role="alert"></p>
<footer class="ticket-wizard-actions ticket-final-actions"><button class="secondary" type="button" data-wizard-prev>مرحله قبل</button><button class="primary" type="submit" data-final-submit>ثبت و ارسال نهایی <b>←</b></button></footer>
</section>
</form>
</div>
<script src="{% static 'vendor/compressor.min.js' %}?v={{ static_asset_version }}"></script>
<script src="{% static 'js/location-picker.js' %}?v={{ static_asset_version }}"></script>
<script src="{% static 'js/ticket-unit-options.js' %}?v={{ static_asset_version }}"></script>
<script src="{% static 'js/ticket-intent-search.js' %}?v={{ static_asset_version }}"></script>
<script src="{% static 'js/attachment-uploader.js' %}?v={{ static_asset_version }}"></script>
<script src="{% static 'js/customer-ticket-wizard.js' %}?v={{ static_asset_version }}"></script>
{% endblock %}