feat: улучшения формы и отображение case_taxonomy

- Добавлено отображение case_taxonomy вместо 'Разобрались' на странице кейса
- Улучшена интеграция iframe формы с обработкой событий
- Добавлен лог диалога по интеграции React формы
This commit is contained in:
Fedor
2025-12-16 11:40:31 +03:00
commit 4394550ff1
4 changed files with 727 additions and 0 deletions

View File

@@ -0,0 +1,170 @@
<?php
/**
* Template Name: Страница с формой
* Template Post Type: page
*
* Шаблон страницы с формой обратной связи
*
* @package Clientprav
*/
get_header();
?>
<div class="min-h-screen bg-gray-50 pt-24 pb-16">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<!-- Навигация назад -->
<a href="<?php echo esc_url(home_url('/')); ?>"
class="text-gray-600 hover:text-gray-900 mb-8 inline-flex items-center gap-2 transition-colors">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
</svg>
Назад на главную
</a>
<!-- Заголовок -->
<div class="mb-8">
<h1 class="text-5xl text-gray-900 mb-4">Получить помощь</h1>
<p class="text-xl text-gray-600">
Заполните форму, и мы поможем защитить ваши права бесплатно
</p>
</div>
<!-- Форма в iframe -->
<div class="bg-white rounded-2xl shadow-lg overflow-hidden">
<div class="form-iframe-wrapper">
<iframe
id="aiform-iframe"
src="https://aiform.clientright.ru/"
frameborder="0"
scrolling="yes"
allow="camera; microphone; geolocation"
class="w-full border-0"
style="min-height: 800px; height: 100vh; max-height: 1200px;">
</iframe>
</div>
</div>
</div>
</div>
<style>
/* Адаптивные стили для iframe */
.form-iframe-wrapper {
position: relative;
width: 100%;
min-height: 800px;
height: 100vh;
max-height: 1200px;
overflow: hidden;
}
#aiform-iframe {
width: 100%;
height: 100%;
border: none;
display: block;
}
/* Адаптация для мобильных устройств */
@media (max-width: 768px) {
.form-iframe-wrapper {
min-height: 600px;
max-height: 100vh;
}
#aiform-iframe {
min-height: 600px;
}
}
/* Для очень маленьких экранов */
@media (max-width: 480px) {
.form-iframe-wrapper {
min-height: 500px;
}
#aiform-iframe {
min-height: 500px;
}
}
</style>
<script>
// Улучшенная интеграция с формой через postMessage
window.addEventListener('message', function(event) {
// Проверяем источник сообщения
if (event.origin !== 'https://aiform.clientright.ru') {
return;
}
const iframe = document.getElementById('aiform-iframe');
const data = event.data;
// Автоматическая высота iframe
if (data && typeof data === 'object') {
// Изменение высоты
if (data.type === 'resize' && data.height) {
if (iframe) {
iframe.style.height = data.height + 'px';
}
}
// Форма отправлена успешно
if (data.type === 'form-submitted' || data.type === 'submit-success') {
console.log('Форма отправлена:', data);
// Можно отправить событие в Google Analytics, если нужно
if (typeof gtag !== 'undefined') {
gtag('event', 'form_submit', {
'event_category': 'Form',
'event_label': 'AI Form'
});
}
// Можно показать уведомление на странице WordPress
// showNotification('Спасибо! Ваша заявка отправлена.');
}
// Ошибка при отправке
if (data.type === 'form-error' || data.type === 'submit-error') {
console.error('Ошибка формы:', data);
}
// Прогресс заполнения формы
if (data.type === 'form-progress') {
// Можно показать прогресс-бар, если нужно
// updateProgressBar(data.progress);
}
}
});
// Улучшенная обработка загрузки iframe
document.addEventListener('DOMContentLoaded', function() {
const iframe = document.getElementById('aiform-iframe');
if (!iframe) return;
// Обработка загрузки iframe
iframe.addEventListener('load', function() {
// Пытаемся установить связь с формой
try {
// Запрашиваем начальную высоту
iframe.contentWindow.postMessage({
type: 'get-height'
}, 'https://aiform.clientright.ru');
} catch (e) {
// Игнорируем ошибки CORS
console.warn('Не удалось установить связь с формой:', e);
}
});
// Обработка ошибок загрузки
iframe.addEventListener('error', function() {
console.error('Ошибка загрузки формы');
});
});
</script>
<?php
get_footer();

View File

@@ -0,0 +1,381 @@
<?php
/**
* Шаблон одиночной записи
*
* @package Clientprav
*/
get_header();
?>
<div class="min-h-screen bg-gray-50 pt-24 pb-16">
<div class="max-w-6xl mx-auto px-4 sm:px-6">
<!-- Навигация назад -->
<?php
$categories = get_the_category();
$category_slug = !empty($categories) ? $categories[0]->slug : '';
if ($category_slug) :
?>
<a href="<?php echo esc_url(clientprav_get_category_link($category_slug)); ?>"
class="text-gray-600 hover:text-gray-900 mb-8 inline-flex items-center gap-2 transition-colors">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
</svg>
Назад к списку
</a>
<?php endif; ?>
<article id="post-<?php the_ID(); ?>" <?php post_class('max-w-4xl mx-auto'); ?>>
<header class="mb-8">
<!-- Категория Badge -->
<?php
$categories = get_the_category();
$category_name = !empty($categories) ? $categories[0]->name : '';
// Для кейсов используем case_taxonomy вместо названия категории
if (has_category('cases')) {
$case_taxonomy = clientprav_get_case_taxonomy(get_the_ID());
if (!empty($case_taxonomy)) {
$category_name = $case_taxonomy;
}
}
if (!empty($category_name)) :
?>
<div class="mb-4">
<span class="text-sm <?php echo has_category('cases') ? 'bg-blue-100 text-blue-700' : 'bg-blue-50 text-blue-600'; ?> px-4 py-1.5 rounded-full">
<?php echo esc_html($category_name); ?>
</span>
</div>
<?php endif; ?>
<h1 class="text-5xl text-gray-900 mb-6 leading-tight">
<?php the_title(); ?>
</h1>
<!-- Мета-информация -->
<?php if (has_category('news')) : ?>
<div class="flex items-center justify-between mb-8 pb-6 border-b border-gray-200">
<div class="flex items-center gap-6 text-gray-600">
<div class="flex items-center gap-2">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
<span><?php echo get_the_date('d F Y'); ?></span>
</div>
<div>Автор: <?php the_author(); ?></div>
<?php
$reading_time = get_post_meta(get_the_ID(), 'reading_time', true);
if (empty($reading_time)) {
$content = get_the_content();
$word_count = str_word_count(strip_tags($content));
$reading_time = max(1, round($word_count / 200)); // 200 слов в минуту
}
?>
<div><?php echo $reading_time; ?> мин чтения</div>
</div>
<!-- Кнопка "Поделиться" -->
<div class="relative">
<button id="share-btn" class="flex items-center gap-2 text-gray-600 hover:text-blue-600 transition-colors">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z"></path>
</svg>
Поделиться
</button>
<div id="share-menu" class="hidden absolute right-0 mt-2 bg-white border border-gray-200 rounded-xl shadow-lg p-2 min-w-[200px] z-10">
<a href="https://www.facebook.com/sharer/sharer.php?u=<?php echo urlencode(get_permalink()); ?>" target="_blank" class="w-full flex items-center gap-3 px-4 py-2 rounded-lg hover:bg-gray-50">
<svg class="w-5 h-5 text-blue-600" fill="currentColor" viewBox="0 0 24 24">
<path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>
</svg>
<span>Facebook</span>
</a>
<a href="https://twitter.com/intent/tweet?url=<?php echo urlencode(get_permalink()); ?>&text=<?php echo urlencode(get_the_title()); ?>" target="_blank" class="w-full flex items-center gap-3 px-4 py-2 rounded-lg hover:bg-gray-50">
<svg class="w-5 h-5 text-sky-500" fill="currentColor" viewBox="0 0 24 24">
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/>
</svg>
<span>Twitter</span>
</a>
<a href="mailto:?subject=<?php echo urlencode(get_the_title()); ?>&body=<?php echo urlencode(get_permalink()); ?>" class="w-full flex items-center gap-3 px-4 py-2 rounded-lg hover:bg-gray-50">
<svg class="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>
</svg>
<span>Email</span>
</a>
</div>
</div>
</div>
<?php elseif (has_category('cases')) : ?>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8 py-6 border-y border-gray-200">
<div class="flex items-center gap-2 text-gray-600">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
<span>Дата решения: <?php echo get_the_date('d F'); ?></span>
</div>
<?php
$duration = get_post_meta(get_the_ID(), 'case_duration_days', true);
if (empty($duration)) {
$duration = get_post_meta(get_the_ID(), 'duration_days', true);
}
if (!empty($duration)) :
?>
<div class="flex items-center gap-2 text-gray-600">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span>Срок: <?php echo esc_html($duration); ?> дней</span>
</div>
<?php endif; ?>
<?php
$result = clientprav_get_case_result(get_the_ID());
if (!empty($result)) :
?>
<div class="flex items-center gap-2 text-green-600">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"></path>
</svg>
<span class="font-semibold"><?php echo esc_html($result); ?></span>
</div>
<?php endif; ?>
</div>
<?php elseif (has_category('faq')) : ?>
<div class="flex items-center gap-6 mb-8 pb-6 border-b border-gray-200 text-gray-600">
<div>Юрист: <?php the_author(); ?></div>
<?php
$views = get_post_meta(get_the_ID(), 'faq_views_count', true);
if (empty($views)) {
$views = get_post_meta(get_the_ID(), 'views_count', true);
}
if (!empty($views)) :
?>
<div class="flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
</svg>
<span><?php echo number_format($views, 0, ',', ' '); ?> просмотра</span>
</div>
<?php endif; ?>
<div><?php echo get_the_date('d F Y'); ?></div>
</div>
<?php endif; ?>
<?php if (has_post_thumbnail()) : ?>
<div class="aspect-video rounded-2xl overflow-hidden bg-gray-200 mb-10">
<?php the_post_thumbnail('large', array('class' => 'w-full h-full object-cover')); ?>
</div>
<?php endif; ?>
</header>
<!-- Контент статьи -->
<div class="prose prose-lg max-w-none mb-12">
<?php
the_content();
wp_link_pages(array(
'before' => '<div class="page-links">' . __('Страницы:', 'clientprav'),
'after' => '</div>',
));
?>
</div>
<?php if (has_category('cases')) : ?>
<?php
$problem = clientprav_get_case_problem(get_the_ID());
$result = clientprav_get_case_result(get_the_ID());
?>
<!-- Ситуация -->
<?php if ($problem) : ?>
<section class="mb-12">
<h2 class="text-3xl text-gray-900 mb-6">Ситуация</h2>
<div class="prose prose-lg max-w-none">
<?php echo wpautop(esc_html($problem)); ?>
</div>
</section>
<?php endif; ?>
<!-- Решение (временная шкала) -->
<?php
$timeline = get_post_meta(get_the_ID(), 'case_timeline', true);
if (empty($timeline)) {
$timeline = get_post_meta(get_the_ID(), 'timeline', true);
}
if (!empty($timeline) || $problem) :
?>
<section class="mb-12 bg-gray-50 rounded-2xl p-8">
<h2 class="text-3xl text-gray-900 mb-6">Как мы решали</h2>
<?php if (!empty($timeline) && is_array($timeline)) : ?>
<div class="space-y-4">
<?php foreach ($timeline as $index => $item) : ?>
<div class="flex gap-4">
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-blue-600 rounded-full flex items-center justify-center">
<?php if ($index === count($timeline) - 1) : ?>
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
<?php else : ?>
<div class="w-2 h-2 bg-white rounded-full"></div>
<?php endif; ?>
</div>
<?php if ($index !== count($timeline) - 1) : ?>
<div class="w-0.5 h-full bg-blue-200 mt-2"></div>
<?php endif; ?>
</div>
<div class="flex-1 pb-6">
<div class="text-sm text-blue-600 mb-1"><?php echo esc_html($item['date'] ?? ''); ?></div>
<div class="text-gray-900"><?php echo esc_html($item['event'] ?? ''); ?></div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php else : ?>
<div class="prose prose-lg max-w-none">
<?php the_content(); ?>
</div>
<?php endif; ?>
</section>
<?php endif; ?>
<!-- Результат -->
<?php if ($result) : ?>
<section class="mb-12">
<h2 class="text-3xl text-gray-900 mb-6">Результат</h2>
<div class="prose prose-lg max-w-none">
<div class="bg-green-50 rounded-lg p-4 border-l-4 border-green-600">
<p class="text-green-700 font-semibold text-lg"><?php echo esc_html($result); ?></p>
</div>
</div>
</section>
<?php endif; ?>
<!-- Документы -->
<?php
$documents = get_post_meta(get_the_ID(), 'case_documents', true);
if (empty($documents)) {
$documents = get_post_meta(get_the_ID(), 'documents', true);
}
if (!empty($documents)) :
if (!is_array($documents)) {
$documents = explode("\n", $documents);
}
?>
<section class="mb-12 bg-blue-50 rounded-2xl p-8">
<div class="flex items-start gap-4 mb-6">
<svg class="w-6 h-6 text-blue-600 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
</svg>
<div>
<h3 class="text-xl text-gray-900 mb-2">Подготовленные документы</h3>
<p class="text-gray-600">Все эти документы мы подготовили бесплатно в рамках нашего сервиса</p>
</div>
</div>
<ul class="space-y-2">
<?php foreach ($documents as $doc) : ?>
<li class="flex items-center gap-3">
<svg class="w-5 h-5 text-green-600 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
<span class="text-gray-700"><?php echo esc_html(trim($doc)); ?></span>
</li>
<?php endforeach; ?>
</ul>
</section>
<?php endif; ?>
<!-- CTA блок для кейсов (градиент) -->
<div class="bg-gradient-to-r from-blue-600 to-blue-700 rounded-2xl p-10 mb-12 text-white text-center">
<svg class="w-12 h-12 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3"></path>
</svg>
<h3 class="text-3xl mb-4">Попали в похожую ситуацию?</h3>
<p class="text-xl mb-6 text-blue-100">Мы поможем защитить ваши права бесплатно. Расскажите о своей проблеме, и мы подготовим все необходимые документы.</p>
<a href="<?php echo esc_url(clientprav_get_form_url()); ?>"
class="inline-block bg-white text-blue-600 px-10 py-4 rounded-lg hover:bg-blue-50 transition-colors font-semibold">
Получить помощь
</a>
</div>
<?php endif; ?>
<?php if (has_category('faq')) : ?>
<?php
$short_answer = clientprav_get_faq_short_answer(get_the_ID());
if ($short_answer) :
?>
<!-- Краткий ответ -->
<div class="mb-10 bg-blue-50 border-l-4 border-blue-600 rounded-r-xl p-6">
<h3 class="text-xl text-gray-900 mb-3">Краткий ответ</h3>
<p class="text-gray-700 leading-relaxed"><?php echo esc_html($short_answer); ?></p>
</div>
<?php endif; ?>
<!-- CTA блок для FAQ -->
<div class="bg-blue-50 rounded-2xl p-8 mb-12">
<h3 class="text-2xl text-gray-900 mb-3">Нужна помощь с защитой прав потребителей?</h3>
<p class="text-gray-600 mb-6">Наш сервис бесплатно поможет составить претензию, жалобу или исковое заявление</p>
<a href="<?php echo esc_url(clientprav_get_form_url()); ?>"
class="inline-block bg-blue-600 text-white px-8 py-3 rounded-lg hover:bg-blue-700 transition-colors">
Получить консультацию
</a>
</div>
<?php endif; ?>
<?php if (has_category('news')) : ?>
<!-- CTA блок для новостей -->
<div class="bg-blue-50 rounded-2xl p-8 mb-12">
<h3 class="text-2xl text-gray-900 mb-3">Нужна помощь с защитой прав потребителей?</h3>
<p class="text-gray-600 mb-6">Наш сервис бесплатно поможет составить претензию, жалобу или исковое заявление</p>
<a href="<?php echo esc_url(clientprav_get_form_url()); ?>"
class="inline-block bg-blue-600 text-white px-8 py-3 rounded-lg hover:bg-blue-700 transition-colors">
Получить консультацию
</a>
</div>
<?php endif; ?>
<!-- Похожие материалы -->
<?php
$current_categories = wp_get_post_categories(get_the_ID());
$related_query = new WP_Query(array(
'post_type' => 'post',
'posts_per_page' => 3,
'post__not_in' => array(get_the_ID()),
'category__in' => $current_categories,
'orderby' => 'date',
'order' => 'DESC',
));
if ($related_query->have_posts()) :
?>
<div class="mt-12">
<h3 class="text-2xl text-gray-900 mb-6">
<?php echo has_category('cases') ? 'Другие кейсы' : (has_category('faq') ? 'Похожие вопросы' : 'Читайте также'); ?>
</h3>
<div class="space-y-4">
<?php while ($related_query->have_posts()) : $related_query->the_post(); ?>
<a href="<?php the_permalink(); ?>"
class="block bg-gray-50 rounded-xl p-5 hover:bg-gray-100 transition-colors group">
<div class="flex items-center justify-between">
<div>
<div class="text-sm text-gray-500 mb-2"><?php echo get_the_date(); ?></div>
<div class="text-lg text-gray-900 group-hover:text-blue-600 transition-colors">
<?php the_title(); ?>
</div>
</div>
<svg class="w-5 h-5 text-gray-400 group-hover:text-blue-600 transition-colors rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
</svg>
</div>
</a>
<?php endwhile; ?>
</div>
</div>
<?php wp_reset_postdata(); ?>
<?php endif; ?>
</article>
</div>
</div>
<?php
get_footer();