Files
sst_site/views/admin/contacts/list.ejs
Andrey K. Choi 9477ff6de0 feat: Реализован полный CRUD для админ-панели и улучшена функциональность
- Portfolio CRUD: добавление, редактирование, удаление, переключение публикации
- Services CRUD: полное управление услугами с возможностью активации/деактивации
- Banner system: новая модель Banner с CRUD операциями и аналитикой кликов
- Telegram integration: расширенные настройки бота, обнаружение чатов, отправка сообщений
- Media management: улучшенная загрузка файлов с оптимизацией изображений и превью
- UI improvements: обновлённые админ-панели с rich-text редактором и drag&drop загрузкой
- Database: добавлена таблица banners с полями для баннеров и аналитики
2025-10-22 20:32:16 +09:00

117 lines
6.7 KiB
Plaintext
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.

<!-- Contacts List -->
<div class="bg-white shadow rounded-lg">
<div class="px-4 py-5 sm:px-6 border-b border-gray-200">
<div class="flex items-center justify-between">
<h3 class="text-lg leading-6 font-medium text-gray-900">
<i class="fas fa-envelope mr-2"></i>
Управление сообщениями
</h3>
<div class="flex items-center space-x-2">
<!-- Status Filter -->
<select id="statusFilter" class="border-gray-300 rounded-md shadow-sm text-sm">
<option value="all" <%= currentStatus === 'all' ? 'selected' : '' %>>Все статусы</option>
<option value="new" <%= currentStatus === 'new' ? 'selected' : '' %>>Новые</option>
<option value="in_progress" <%= currentStatus === 'in_progress' ? 'selected' : '' %>>В работе</option>
<option value="completed" <%= currentStatus === 'completed' ? 'selected' : '' %>>Завершенные</option>
</select>
</div>
</div>
</div>
<div class="bg-white shadow overflow-hidden sm:rounded-md">
<ul role="list" class="divide-y divide-gray-200">
<% if (contacts && contacts.length > 0) { %>
<% contacts.forEach(contact => { %>
<li>
<a href="/admin/contacts/<%= contact.id %>" class="block hover:bg-gray-50">
<div class="px-4 py-4 flex items-center justify-between">
<div class="flex items-center">
<div class="flex-shrink-0">
<% if (!contact.isRead) { %>
<div class="h-2 w-2 bg-blue-600 rounded-full"></div>
<% } else { %>
<div class="h-2 w-2"></div>
<% } %>
</div>
<div class="ml-4 min-w-0 flex-1">
<div class="flex items-center">
<p class="text-sm font-medium text-gray-900 truncate">
<%= contact.name %>
</p>
<% if (contact.serviceInterest) { %>
<span class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
<%= contact.serviceInterest %>
</span>
<% } %>
</div>
<div class="flex items-center mt-1">
<p class="text-sm text-gray-500 truncate">
<%= contact.email %>
</p>
<span class="mx-2 text-gray-300">•</span>
<p class="text-sm text-gray-500">
<%= new Date(contact.createdAt).toLocaleDateString('ru-RU') %>
</p>
</div>
<p class="text-sm text-gray-500 mt-1 truncate">
<%= contact.message.substring(0, 100) %>...
</p>
</div>
</div>
<div class="flex items-center space-x-2">
<!-- Status Badge -->
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
<%= contact.status === 'new' ? 'bg-green-100 text-green-800' :
contact.status === 'in_progress' ? 'bg-yellow-100 text-yellow-800' :
'bg-gray-100 text-gray-800' %>">
<%= contact.status === 'new' ? 'Новое' :
contact.status === 'in_progress' ? 'В работе' : 'Завершено' %>
</span>
<!-- Priority -->
<% if (contact.priority === 'high') { %>
<i class="fas fa-exclamation-triangle text-red-500"></i>
<% } %>
</div>
</div>
</a>
</li>
<% }) %>
<% } else { %>
<li>
<div class="px-4 py-8 text-center">
<i class="fas fa-envelope text-4xl text-gray-300 mb-4"></i>
<p class="text-gray-500">Сообщения не найдены</p>
</div>
</li>
<% } %>
</ul>
</div>
<!-- Pagination -->
<% if (pagination && pagination.total > 1) { %>
<div class="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6">
<div class="flex-1 flex justify-between sm:hidden">
<% if (pagination.hasPrev) { %>
<a href="?page=<%= pagination.current - 1 %>&status=<%= currentStatus %>" class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
Предыдущая
</a>
<% } %>
<% if (pagination.hasNext) { %>
<a href="?page=<%= pagination.current + 1 %>&status=<%= currentStatus %>" class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
Следующая
</a>
<% } %>
</div>
</div>
<% } %>
</div>
<script>
document.getElementById('statusFilter').addEventListener('change', function() {
const status = this.value;
const url = new URL(window.location);
url.searchParams.set('status', status);
url.searchParams.delete('page'); // Reset to first page
window.location.href = url.toString();
});
</script>