Files
customerTicket/templates/tickets/staff_detail.html
T
2026-09-10 11:34:19 +03:30

38 lines
11 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 jalali %}
{% block title %}{{ page_title }}{% endblock %}
{% block content %}
<div class="ticket-workspace staff-ticket-workspace" data-conversation-workspace data-poll-url="{% url 'staff_tickets:poll' ticket.public_id %}" data-poll-version="{{ poll_version }}" data-poll-cursor="{{ poll_cursor }}" data-draft-key="ticket-{{ ticket.public_id }}-staff" data-reply-result="{{ request.GET.reply_result|default:'' }}">
<header class="ticket-workspace-head">
<div class="ticket-title"><a class="workspace-back" href="{% url 'staff_tickets:list' %}" aria-label="بازگشت">→</a><div><span class="ticket-number" dir="ltr">{{ ticket.ticket_number }}</span><h1>{{ ticket.subject }}</h1></div></div>
<div class="ticket-head-actions"><span class="badge" data-ticket-status>{{ ticket.get_status_display }}</span>{% if can_claim %}<form method="post" action="{% url 'staff_tickets:claim' ticket.public_id %}">{% csrf_token %}<button type="submit">اختصاص به من</button></form>{% endif %}<button type="button" class="icon-button" data-toggle-panel="ticket-actions" aria-label="عملیات تیکت">⚙</button><button type="button" class="icon-button" data-toggle-panel="customer-info" aria-label="اطلاعات مشتری">◉</button></div>
</header>
<div class="workspace-grid staff-conversation-grid">
<aside class="workspace-side actions-side" id="ticket-actions" data-workspace-panel>
<button type="button" class="panel-close" data-close-panel>×</button>
<section class="info-card"><p class="panel-index">وضعیت تیکت</p><div class="info-list"><div class="info-row"><span>وضعیت</span><b>{{ ticket.get_status_display }}</b></div><div class="info-row"><span>اولویت</span><b>{{ ticket.get_priority_display }}</b></div><div class="info-row"><span>دسته</span><b>{{ ticket.category }}</b></div><div class="info-row"><span>مالک</span><b>{{ ticket.assigned_expert_name }}</b></div>{% if ticket.first_response_due_at %}<div class="info-row"><span>مهلت پاسخ</span><b>{{ ticket.first_response_due_at|jalali_datetime }}</b></div>{% endif %}</div></section>
<section class="info-card ticket-operations"><h3>عملیات تیکت</h3>{% if perms.tickets.change_ticket %}<form method="post" action="{% url 'staff_tickets:status' ticket.public_id %}">{% csrf_token %}<label>وضعیت<select name="status">{% for value,label in statuses %}<option value="{{ value }}" {% if ticket.status == value %}selected{% endif %}>{{ label }}</option>{% endfor %}</select></label><button>ثبت وضعیت</button></form>{% endif %}{% if perms.tickets.change_ticket_priority %}<form method="post" action="{% url 'staff_tickets:priority' ticket.public_id %}">{% csrf_token %}<label>اولویت<select name="priority">{% for value,label in priorities %}<option value="{{ value }}" {% if ticket.priority == value %}selected{% endif %}>{{ label }}</option>{% endfor %}</select></label><button class="secondary">ثبت اولویت</button></form>{% endif %}{% if can_transfer %}<details><summary>انتقال تیکت</summary><form method="post" action="{% url 'staff_tickets:transfer' ticket.public_id %}">{% csrf_token %}{{ transfer_form.as_p }}<button>انتقال</button></form></details>{% endif %}{% if can_share %}<details><summary>اشتراک با کارشناس</summary><form method="post" action="{% url 'staff_tickets:share' ticket.public_id %}">{% csrf_token %}{{ share_form.as_p }}<button>ایجاد دسترسی</button></form>{% for grant in grants %}<div class="grant"><span>{{ grant.user.staff_profile.display_name }}</span><form method="post" action="{% url 'staff_tickets:revoke' ticket.public_id grant.user.public_id %}">{% csrf_token %}<button class="danger-button">لغو</button></form></div>{% endfor %}</details>{% endif %}</section>
{% if can_delete %}<section class="info-card danger-zone"><h3>حذف کامل تیکت</h3><p class="muted">تمام پیام‌ها، فایل‌ها و سوابق تیکت برای همیشه حذف می‌شوند.</p><form method="post" action="{% url 'staff_tickets:delete' ticket.public_id %}" onsubmit="return confirm('آیا از حذف کامل و غیرقابل‌بازگشت این تیکت مطمئن هستید؟')">{% csrf_token %}<button type="submit" class="danger-button">حذف کامل تیکت</button></form></section>{% endif %}
</aside>
<main class="conversation-pane correspondence-pane">
<section class="conversation-toolbar"><div><b>سوابق رسیدگی و مکاتبات</b></div><small><span data-conversation-count>{{ conversation|length }}</span> مکاتبه</small></section>
<section class="conversation" data-conversation role="log" aria-live="polite">{% if has_older %}<button class="load-older" type="button" data-load-older hx-get="{% url 'staff_tickets:messages' ticket.public_id %}?before={{ older_cursor }}" hx-target="this" hx-swap="outerHTML">↑ نمایش مکاتبات قدیمی‌تر</button>{% endif %}{% include 'tickets/_messages.html' %}<div class="conversation-end" data-conversation-end aria-hidden="true"></div></section>
<button class="new-message-jump" type="button" data-jump-latest hidden>↓ رفتن به آخرین مکاتبه</button>
<section class="composer staff-composer {% if request.GET.reply_result != 'error' %}is-collapsed{% endif %}" x-data="{mode:'reply'}" :class="mode==='note'&&'note-mode'" data-composer-shell>
<button type="button" class="composer-launch" data-composer-toggle aria-expanded="false"><span class="composer-launch-icon">+</span><span><b>ثبت اقدام جدید در تیکت</b><small>پاسخ رسمی یا یادداشت کارشناسی ثبت کنید</small></span><span class="composer-launch-arrow">↑</span></button>
<div class="mode" role="tablist"><button type="button" role="tab" data-composer-mode="reply" @click="mode='reply'" :class="mode==='reply'&&'active'">پاسخ رسمی به مشتری</button>{% if perms.messaging.add_internal_note %}<button type="button" role="tab" data-composer-mode="note" @click="mode='note'" :class="mode==='note'&&'active note-button'">🔒 یادداشت کارشناسی</button>{% endif %}</div>
<form method="post" enctype="multipart/form-data" data-ticket-composer data-chat-coach data-chat-coach-key="ticket-{{ ticket.public_id }}-staff-{{ user.public_id }}" :action="mode==='note'?'{% url 'staff_tickets:note' ticket.public_id %}':'{% url 'staff_tickets:reply' ticket.public_id %}'">{% csrf_token %}
<div class="composer-context"><div><b x-text="mode==='note'?'ثبت یادداشت کارشناسی در پرونده':'ثبت پاسخ رسمی در تیکت'"></b><small x-text="mode==='note'?'این یادداشت فقط برای تیم کارشناسی قابل مشاهده است.':'پاسخ را کامل و یک‌جا بنویسید؛ این متن برای مشتری ارسال و اعلان می‌شود.'"></small></div><div class="composer-context-actions"><span data-draft-status></span><span class="composer-send-icon" role="button" tabindex="0" data-scroll-to-submit aria-label="رفتن به دکمه ثبت پاسخ" title="رفتن به دکمه ثبت پاسخ"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 20.5 21 12 3 3.5v6.6l12 1.9-12 1.9z"/></svg></span></div></div>
{{ form.body }}{{ form.body.errors }}<div class="reply-media-picker"><div class="media-picker-actions"><label class="media-picker-button gallery-button" for="staff-reply-gallery">▣ انتخاب عکس از گالری</label><label class="media-picker-button" for="staff-reply-file">+ انتخاب فایل</label></div><input id="staff-reply-gallery" type="file" accept="image/*" multiple data-gallery-input><input id="staff-reply-file" 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><div class="file-preview" data-file-preview></div>
<div class="composer-extra" hidden data-composer-extra>{{ form.mentioned_experts.label_tag }}{{ form.mentioned_experts }}</div>
<div class="voice-recorder compact-recorder" data-voice-recorder hidden><div class="voice-head"><b>افزودن توضیح صوتی</b><span class="badge" data-timer>00:00</span></div><div class="voice-actions"><button type="button" data-record>● شروع ضبط</button><button type="button" data-pause disabled>مکث</button><button type="button" data-stop disabled>توقف</button><button type="button" class="ghost" data-delete hidden>حذف</button></div><audio controls hidden></audio></div>
<div class="composer-bar"><div class="composer-tools"><button class="tool-button" type="button" data-toggle-recorder>●<span>توضیح صوتی</span></button><button class="tool-button" type="button" data-toggle-extra>@<span>اطلاع به کارشناس</span></button><button class="tool-button composer-close" type="button" data-composer-close>بستن</button></div><small class="composer-hint">پیش از ثبت، متن و پیوست‌ها را بازبینی کنید.</small><button class="send-button" type="submit" data-primary-submit><span x-text="mode==='note'?'ثبت یادداشت در پرونده':'ثبت پاسخ در تیکت'"></span> ←</button></div>
</form>
</section>
</main>
<aside class="workspace-side customer-side" id="customer-info" data-workspace-panel><button type="button" class="panel-close" data-close-panel>×</button><section class="info-card"><p class="panel-index">مشتری</p><h3>{{ ticket.customer.customer_profile|default:'بدون نام' }}</h3><p class="mt-1 text-sm font-bold" dir="ltr">{{ ticket.customer.mobile }}</p><div class="info-list"><div class="info-row"><span>نوع مشتری</span><b>{{ ticket.customer.customer_profile.get_customer_type_display|default:'ثبت نشده' }}</b></div><div class="info-row"><span>موقعیت تیکت</span><b>{% if ticket.city %}{{ ticket.city }}، {{ ticket.province }}{% elif ticket.province %}{{ ticket.province }}{% else %}ثبت نشده{% endif %}</b></div><div class="info-row"><span>تعداد تیکت</span><b>{{ ticket.customer.customer_tickets.count }}</b></div></div></section><section class="info-card"><h3>سابقه اخیر</h3>{% for old in customer_history %}<div class="history-item"><b>{{ old.subject }}</b><span class="ticket-number">{{ old.ticket_number }}</span>{% if perms.tickets.view_all_tickets or old.owner == user or old.selected_expert == user %}<a class="back-link" href="{% url 'staff_tickets:detail' old.public_id %}">مشاهده ←</a>{% else %}<small class="muted">محتوای خصوصی</small>{% endif %}</div>{% empty %}<p class="muted mt-3">تیکت دیگری ثبت نشده است.</p>{% endfor %}</section></aside>
</div>
</div>
{% include 'tickets/_image_viewer.html' %}
<script src="{% static 'vendor/compressor.min.js' %}?v={{ static_asset_version }}"></script><script src="{% static 'js/attachment-uploader.js' %}?v={{ static_asset_version }}"></script><script src="{% static 'js/image-viewer.js' %}?v={{ static_asset_version }}"></script><script src="{% static 'js/conversation.js' %}?v={{ static_asset_version }}"></script>
{% endblock %}