hesabixSite/templates/qa/ask_question.html.twig
Hesabix 06a2fb398d
Some checks are pending
PHP Composer / build (push) Waiting to run
progress in site customer part
2025-09-05 09:37:27 +03:30

470 lines
21 KiB
Twig

{% extends 'base.html.twig' %}
{% block title %}پرسیدن سوال جدید - پرسش و پاسخ{% endblock %}
{% block body %}
<div class="container my-4">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card">
<div class="card-header">
<h3 class="mb-0">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-2">
<circle cx="12" cy="12" r="10"></circle>
<path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
<line x1="12" y1="17" x2="12.01" y2="17"></line>
</svg>پرسیدن سوال جدید
</h3>
</div>
<div class="card-body">
{{ form_start(form, {'attr': {'novalidate': 'novalidate'}}) }}
<div class="mb-4">
{{ form_label(form.title) }}
{{ form_widget(form.title) }}
{{ form_errors(form.title) }}
<div class="form-text">
عنوان سوال باید واضح و مختصر باشد. سعی کنید مشکل خود را در یک جمله خلاصه کنید.
</div>
</div>
<div class="mb-4">
{{ form_label(form.content) }}
<div class="editor-toolbar mb-2">
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="formatText('bold')" title="پررنگ">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"></path>
<path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"></path>
</svg>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="formatText('italic')" title="کج">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="19" y1="4" x2="10" y2="4"></line>
<line x1="14" y1="20" x2="5" y2="20"></line>
<line x1="15" y1="4" x2="9" y2="20"></line>
</svg>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="formatText('code')" title="کد">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="16,18 22,12 16,6"></polyline>
<polyline points="8,6 2,12 8,18"></polyline>
</svg>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="insertList()" title="لیست">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="8" y1="6" x2="21" y2="6"></line>
<line x1="8" y1="12" x2="21" y2="12"></line>
<line x1="8" y1="18" x2="21" y2="18"></line>
<line x1="3" y1="6" x2="3.01" y2="6"></line>
<line x1="3" y1="12" x2="3.01" y2="12"></line>
<line x1="3" y1="18" x2="3.01" y2="18"></line>
</svg>
</button>
</div>
{{ form_widget(form.content, {'attr': {'class': 'form-control editor-textarea', 'rows': 10}}) }}
{{ form_errors(form.content) }}
<div class="form-text">
سوال خود را به تفصیل شرح دهید. هرچه جزئیات بیشتری ارائه دهید، پاسخ‌های بهتری دریافت خواهید کرد.
<br><small class="text-muted">می‌توانید از دکمه‌های بالا برای فرمت کردن متن استفاده کنید.</small>
</div>
</div>
<div class="mb-4">
<label class="form-label">تگ‌ها</label>
<div class="tags-container">
<div class="selected-tags mb-2" id="selected-tags"></div>
<div class="input-group">
<input type="text" class="form-control" id="tag-input" placeholder="تگ جدید را وارد کنید یا از لیست انتخاب کنید...">
<button class="btn btn-outline-primary" type="button" id="add-tag-btn">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="12" y1="5" x2="12" y2="19"></line>
<line x1="5" y1="12" x2="19" y2="12"></line>
</svg>
</button>
</div>
<div class="available-tags mt-2" id="available-tags">
<small class="text-muted">تگ‌های موجود:</small>
<div class="tag-suggestions mt-1">
{% for tag in availableTags %}
<span class="badge bg-light text-dark me-1 mb-1 tag-suggestion" data-tag-id="{{ tag.id }}" data-tag-name="{{ tag.name }}">
{{ tag.name }}
</span>
{% endfor %}
</div>
</div>
</div>
<div class="form-text">
تگ‌های مرتبط را انتخاب کنید تا دیگران راحت‌تر بتوانند سوال شما را پیدا کنند.
<br><small class="text-muted">می‌توانید تگ جدید ایجاد کنید یا از تگ‌های موجود انتخاب کنید.</small>
</div>
</div>
<div class="d-flex justify-content-between">
<a href="{{ path('qa_index') }}" class="btn btn-outline-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-2">
<path d="M19 12H5"></path>
<polyline points="12,19 5,12 12,5"></polyline>
</svg>انصراف
</a>
<button type="submit" class="btn btn-primary">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-2">
<line x1="22" y1="2" x2="11" y2="13"></line>
<polygon points="22,2 15,22 11,13 2,9 22,2"></polygon>
</svg>ارسال سوال
</button>
</div>
{{ form_end(form) }}
</div>
</div>
<!-- راهنمای پرسیدن سوال -->
<div class="card mt-4">
<div class="card-header">
<h5 class="mb-0">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-2">
<path d="M9 12l2 2 4-4"></path>
<path d="M21 12c.552 0 1-.448 1-1s-.448-1-1-1-1 .448-1 1 .448 1 1 1z"></path>
<path d="M3 12c.552 0 1-.448 1-1s-.448-1-1-1-1 .448-1 1 .448 1 1 1z"></path>
<path d="M12 3c.552 0 1-.448 1-1s-.448-1-1-1-1 .448-1 1 .448 1 1 1z"></path>
<path d="M12 21c.552 0 1-.448 1-1s-.448-1-1-1-1 .448-1 1 .448 1 1 1z"></path>
</svg>راهنمای پرسیدن سوال خوب
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6 class="text-success">✅ کارهای درست:</h6>
<ul class="list-unstyled">
<li><i class="fas fa-check text-success me-2"></i>عنوان واضح و مختصر</li>
<li><i class="fas fa-check text-success me-2"></i>شرح کامل مشکل</li>
<li><i class="fas fa-check text-success me-2"></i>انتخاب تگ‌های مناسب</li>
<li><i class="fas fa-check text-success me-2"></i>استفاده از کلمات کلیدی</li>
</ul>
</div>
<div class="col-md-6">
<h6 class="text-danger">❌ کارهای نادرست:</h6>
<ul class="list-unstyled">
<li><i class="fas fa-times text-danger me-2"></i>عنوان مبهم</li>
<li><i class="fas fa-times text-danger me-2"></i>شرح ناکافی</li>
<li><i class="fas fa-times text-danger me-2"></i>عدم انتخاب تگ</li>
<li><i class="fas fa-times text-danger me-2"></i>سوال تکراری</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<style>
.form-control:focus, .form-select:focus {
border-color: #0d6efd;
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25);
}
.card {
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
border: none;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
.form-text {
font-size: 0.9rem;
color: #6c757d;
}
.list-unstyled li {
margin-bottom: 0.5rem;
}
.editor-toolbar {
border: 1px solid #dee2e6;
border-bottom: none;
border-radius: 0.375rem 0.375rem 0 0;
padding: 0.5rem;
background-color: #f8f9fa;
}
.editor-textarea {
border-radius: 0 0 0.375rem 0.375rem;
border-top: none;
}
.tags-container {
border: 1px solid #dee2e6;
border-radius: 0.375rem;
padding: 1rem;
background-color: #f8f9fa;
}
.selected-tags {
min-height: 40px;
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: center;
}
.tag-item {
display: inline-flex;
align-items: center;
background-color: #0d6efd;
color: white;
padding: 0.25rem 0.5rem;
border-radius: 0.375rem;
font-size: 0.875rem;
}
.tag-remove {
background: none;
border: none;
color: white;
margin-left: 0.5rem;
cursor: pointer;
padding: 0;
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
}
.tag-suggestion {
cursor: pointer;
transition: all 0.3s ease;
}
.tag-suggestion:hover {
background-color: #0d6efd !important;
color: white !important;
}
.tag-suggestion.selected {
background-color: #0d6efd !important;
color: white !important;
}
</style>
<script>
let selectedTags = [];
function initializeQuestionForm() {
// ادیتور متن
const textarea = document.querySelector('.editor-textarea');
// سیستم تگ‌ها
const tagInput = document.getElementById('tag-input');
const addTagBtn = document.getElementById('add-tag-btn');
const selectedTagsContainer = document.getElementById('selected-tags');
const tagSuggestions = document.querySelectorAll('.tag-suggestion');
// اضافه کردن تگ
function addTag(tagId, tagName) {
if (selectedTags.find(tag => tag.id === tagId)) {
return;
}
selectedTags.push({ id: tagId, name: tagName });
renderSelectedTags();
updateHiddenInput();
console.log('Tag added:', { id: tagId, name: tagName });
}
// حذف تگ
window.removeTag = function(tagId) {
selectedTags = selectedTags.filter(tag => tag.id !== tagId);
renderSelectedTags();
updateHiddenInput();
}
// نمایش تگ‌های انتخاب شده
function renderSelectedTags() {
selectedTagsContainer.innerHTML = '';
selectedTags.forEach(tag => {
const tagElement = document.createElement('span');
tagElement.className = 'tag-item';
tagElement.innerHTML = `
${tag.name}
<button type="button" class="tag-remove" data-tag-id="${tag.id}">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</button>
`;
// اضافه کردن event listener برای دکمه حذف
const removeBtn = tagElement.querySelector('.tag-remove');
removeBtn.addEventListener('click', function() {
const tagId = this.dataset.tagId;
window.removeTag(tagId);
// حذف کلاس selected از تگ پیشنهادی
const suggestion = document.querySelector(`[data-tag-id="${tagId}"]`);
if (suggestion) {
suggestion.classList.remove('selected');
}
});
selectedTagsContainer.appendChild(tagElement);
});
}
// به‌روزرسانی input مخفی
function updateHiddenInput() {
// حذف تمام input های قبلی
const existingInputs = document.querySelectorAll('input[name="question[tags][]"]');
existingInputs.forEach(input => input.remove());
// اضافه کردن input های جدید
selectedTags.forEach(tag => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'question[tags][]';
input.value = tag.id;
document.querySelector('form').appendChild(input);
});
console.log('Selected tags:', selectedTags);
}
// کلیک روی تگ‌های پیشنهادی
tagSuggestions.forEach(suggestion => {
suggestion.addEventListener('click', function() {
const tagId = this.dataset.tagId;
const tagName = this.dataset.tagName;
if (selectedTags.find(tag => tag.id === tagId)) {
window.removeTag(tagId);
this.classList.remove('selected');
} else {
addTag(tagId, tagName);
this.classList.add('selected');
}
});
});
// اضافه کردن تگ جدید
addTagBtn.addEventListener('click', function() {
const tagName = tagInput.value.trim();
if (tagName) {
// بررسی وجود تگ
const existingTag = Array.from(tagSuggestions).find(suggestion =>
suggestion.dataset.tagName.toLowerCase() === tagName.toLowerCase()
);
if (existingTag) {
const tagId = existingTag.dataset.tagId;
const tagName = existingTag.dataset.tagName;
addTag(tagId, tagName);
existingTag.classList.add('selected');
} else {
// ایجاد تگ جدید
createNewTag(tagName);
}
tagInput.value = '';
}
});
// Enter برای اضافه کردن تگ
tagInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
addTagBtn.click();
}
});
// ایجاد تگ جدید
function createNewTag(tagName) {
fetch('/qa/tag/create', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest'
},
body: `name=${encodeURIComponent(tagName)}&_token={{ csrf_token('vote') }}`
})
.then(response => response.json())
.then(data => {
if (data.error) {
alert(data.error);
return;
}
// اضافه کردن تگ به لیست انتخاب شده
addTag(data.id, data.name);
// اضافه کردن تگ به لیست پیشنهادی
const suggestionElement = document.createElement('span');
suggestionElement.className = 'badge bg-light text-dark me-1 mb-1 tag-suggestion selected';
suggestionElement.dataset.tagId = data.id;
suggestionElement.dataset.tagName = data.name;
suggestionElement.textContent = data.name;
suggestionElement.addEventListener('click', function() {
if (selectedTags.find(tag => tag.id === data.id)) {
removeTag(data.id);
this.classList.remove('selected');
} else {
addTag(data.id, data.name);
this.classList.add('selected');
}
});
document.querySelector('.tag-suggestions').appendChild(suggestionElement);
})
.catch(error => {
console.error('Error:', error);
alert('خطا در ایجاد تگ جدید');
});
}
});
// توابع ادیتور متن
function formatText(command) {
const textarea = document.querySelector('.editor-textarea');
const start = textarea.selectionStart;
const end = textarea.selectionEnd;
const selectedText = textarea.value.substring(start, end);
let formattedText = '';
switch(command) {
case 'bold':
formattedText = `**${selectedText}**`;
break;
case 'italic':
formattedText = `*${selectedText}*`;
break;
case 'code':
formattedText = `\`${selectedText}\``;
break;
}
textarea.value = textarea.value.substring(0, start) + formattedText + textarea.value.substring(end);
textarea.focus();
textarea.setSelectionRange(start + formattedText.length, start + formattedText.length);
}
function insertList() {
const textarea = document.querySelector('.editor-textarea');
const start = textarea.selectionStart;
const end = textarea.selectionEnd;
const selectedText = textarea.value.substring(start, end);
const listText = selectedText.split('\n').map(line => `- ${line}`).join('\n');
textarea.value = textarea.value.substring(0, start) + listText + textarea.value.substring(end);
textarea.focus();
}
// اجرا در هر دو حالت
document.addEventListener('DOMContentLoaded', initializeQuestionForm);
document.addEventListener('turbo:load', initializeQuestionForm);
</script>
{% endblock %}