354 lines
16 KiB
Smarty
354 lines
16 KiB
Smarty
<style>
|
||
/* Глобальные шрифты */
|
||
.tableStatic, .tableStatic tbody td, .author-data-container,
|
||
.meta-sub-text, .comment-scroll-box, .cell-top-bar a,
|
||
.cell-top-bar span, .asset-name, #mass_action_select {
|
||
font-size: 13px !important;
|
||
}
|
||
|
||
/* Компактная строка */
|
||
.tableStatic tbody td { vertical-align: middle !important; padding: 4px 10px !important; }
|
||
|
||
/* АВАТАР */
|
||
.admin-avatar-box { width: 34px; height: 34px; flex-shrink: 0; }
|
||
.admin-avatar-box img { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; border: 1px solid #ddd; }
|
||
.mod_comment_avatar_letter { width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; color: #fff; text-transform: uppercase; font-size: 14px !important; }
|
||
|
||
/* Цвета для букв аватара */
|
||
.av-c1 { background-color: #6c5ce7; } .av-c2 { background-color: #2ecc71; }
|
||
.av-c3 { background-color: #e67e22; } .av-c4 { background-color: #e91e63; }
|
||
.av-c5 { background-color: #00cec9; } .av-c6 { background-color: #0984e3; }
|
||
.av-c7 { background-color: #d63031; } .av-c8 { background-color: #636e72; }
|
||
.av-c9 { background-color: #fdcb6e; } .av-c10 { background-color: #fd79a8; }
|
||
|
||
/* ЗВЕЗДЫ РЕЙТИНГА АВТОРА (справа от имени) */
|
||
.author-stars { color: #ff9800; font-size: 14px; letter-spacing: 0px; display: inline-block; margin-left: 8px; }
|
||
.star-grey { color: #ccc !important; }
|
||
|
||
.status-badge { font-size: 10px; padding: 1px 4px; border-radius: 3px; font-weight: bold; text-transform: uppercase; border: 1px solid; }
|
||
.bg-del-adm { background: #ffebee; color: #c62828; border-color: #ffcdd2; }
|
||
.bg-del-aut { background: #f5f5f5; color: #757575; border-color: #e0e0e0; font-style: italic; }
|
||
.row-hidden { background-color: #fff4f4 !important; }
|
||
|
||
/* Контейнер для веера */
|
||
.files-bundle {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 34px;
|
||
}
|
||
|
||
/* Базовый стиль для миниатюр в стопке */
|
||
.thumb-stack {
|
||
width: 28px;
|
||
height: 28px;
|
||
border: 2px solid #fff;
|
||
border-radius: 4px;
|
||
object-fit: cover;
|
||
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
|
||
margin-left: -15px; /* Наложение картинок друг на друга */
|
||
transition: all 0.2s ease;
|
||
cursor: pointer;
|
||
position: relative;
|
||
}
|
||
|
||
/* Первая картинка в стопке без отступа */
|
||
.thumb-stack:first-child { margin-left: 0; }
|
||
|
||
/* Эффект при наведении на конкретную картинку */
|
||
.thumb-stack:hover {
|
||
transform: scale(4.5);
|
||
z-index: 999;
|
||
margin: 0 40px; /* Раздвигаем соседей, чтобы не перекрывали зум */
|
||
box-shadow: 0 5px 15px rgba(0,0,0,0.5);
|
||
}
|
||
|
||
/* Иконка файла в стиле стопки */
|
||
.file-stack {
|
||
width: 28px; height: 28px; background: #f8f9fa;
|
||
display: flex; align-items: center; justify-content: center;
|
||
font-size: 8px; font-weight: bold; border: 2px solid #fff;
|
||
border-radius: 4px; color: #555; box-shadow: 0 1px 3px rgba(0,0,0,0.2);
|
||
margin-left: -15px; transition: all 0.2s ease;
|
||
}
|
||
.file-stack:hover { transform: scale(1.5); z-index: 100; }
|
||
|
||
/* Стиль индикатора статуса */
|
||
/* Базовый стиль кружка */
|
||
.status-dot {
|
||
width: 10px;
|
||
height: 10px;
|
||
border-radius: 50%;
|
||
display: inline-block;
|
||
}
|
||
|
||
/* Зеленый - просто светится */
|
||
.dot-active {
|
||
background-color: #2ecc71;
|
||
box-shadow: 0 0 6px #2ecc71;
|
||
}
|
||
|
||
/* Красный - ПУЛЬСИРУЕТ */
|
||
.dot-hidden {
|
||
background-color: #e74c3c;
|
||
animation: pulse-red 1.5s infinite;
|
||
}
|
||
|
||
/* Эффект пульсации */
|
||
@keyframes pulse-red {
|
||
0% {
|
||
transform: scale(0.95);
|
||
box-shadow: 0 0 0 0 rgba(231, 76, 60, 0.7);
|
||
}
|
||
70% {
|
||
transform: scale(1);
|
||
box-shadow: 0 0 0 10px rgba(231, 76, 60, 0);
|
||
}
|
||
100% {
|
||
transform: scale(0.95);
|
||
box-shadow: 0 0 0 0 rgba(231, 76, 60, 0);
|
||
}
|
||
}
|
||
|
||
/* Стиль для аватара удаленного пользователя */
|
||
.avatar-deleted {
|
||
background-color: #bdc3c7 !important; /* Серый цвет */
|
||
color: #fff !important;
|
||
font-size: 18px !important;
|
||
}
|
||
|
||
/* Плашки для текста удаленных комментариев */
|
||
.comment-deleted-info {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
padding: 4px 10px;
|
||
border-radius: 4px;
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
gap: 6px;
|
||
}
|
||
.del-adm { background: #fff5f5; color: #c0392b; border: 1px solid #fadbd8; }
|
||
.del-aut { background: #f8f9fa; color: #7f8c8d; border: 1px solid #e5e8e8; font-style: italic; }
|
||
|
||
</style>
|
||
|
||
<div class="title"><h5>{#COMMENT_MODULE_NAME#} (Всего: {$docs|count})</h5></div>
|
||
|
||
<div class="widget first">
|
||
<div class="head">
|
||
<h5 class="iFrames">{#COMMENT_MODULE_COMENTS#}</h5>
|
||
<div class="num"><a class="basicNum" href="index.php?do=modules&action=modedit&mod=comment&moduleaction=settings&cp={$sess}">{#COMMENT_MODULE_SETTINGS#}</a></div>
|
||
</div>
|
||
|
||
<table cellpadding="0" cellspacing="0" width="100%" class="tableStatic">
|
||
<thead>
|
||
<tr>
|
||
<td width="30"><input type="checkbox" id="selectAll" onclick="checkAll(this)" /></td>
|
||
<td width="40">ID</td>
|
||
<td width="30">Статус</td>
|
||
<td width="220">Автор и Рейтинг</td>
|
||
<td width="110">IP адрес</td>
|
||
<td width="130">Дата Создания / Редактирования</td>
|
||
<td>Текст комментария</td>
|
||
<td width="100">Файлы</td>
|
||
<td width="140" align="right">Действия</td>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{if $docs}
|
||
{foreach from=$docs item=row name=zebraloop}
|
||
{assign var="is_deleted" value=false}
|
||
{if $row.comment_author_name == '__DELETED__' || $row.comment_author_name == 'Удалено'}{assign var="is_deleted" value=true}{/if}
|
||
|
||
|
||
<tr class="{if $row.comment_status == '0'}row-hidden deleted-row{elseif $smarty.foreach.zebraloop.iteration % 2 == 0}row-even{else}row-odd{/if}">
|
||
<td align="center"><input class="row-checkbox" type="checkbox" value="{$row.CId}" /></td>
|
||
<td align="center"><strong>{$row.CId}</strong></td>
|
||
<td align="center">
|
||
{if $row.comment_status == '1'}
|
||
<span class="status-dot dot-active" title="Активен"></span>
|
||
{else}
|
||
<span class="status-dot dot-hidden" title="Скрыт"></span>
|
||
{/if}
|
||
</td>
|
||
|
||
<td>
|
||
<div style="display: flex; align-items: center; gap: 10px;">
|
||
<div class="admin-avatar-box">
|
||
{if $is_deleted}
|
||
<div class="mod_comment_avatar_letter avatar-deleted">?</div>
|
||
{else}
|
||
{if $row.avatar}<img src="{$row.avatar}">{else}
|
||
<div class="mod_comment_avatar_letter av-c{$row.avatar_color_index}">{$row.first_letter}</div>{/if}
|
||
{/if}
|
||
</div>
|
||
<div style="white-space: nowrap;">
|
||
<span style="font-weight:bold; color:{if $is_deleted}#95a5a6{else}#2c3e50{/if};">
|
||
{if $is_deleted}Пользователь удален{else}{$row.comment_author_name|escape}{/if}
|
||
</span>
|
||
{if !$is_deleted}
|
||
<span class="author-stars">
|
||
{section name=s start=1 loop=6}{if $smarty.section.s.index <= $row.user_rating}★{else}<span class="star-grey">★</span>{/if}{/section}
|
||
</span>
|
||
{/if}
|
||
</div>
|
||
</div>
|
||
</td>
|
||
<td align="center" style="color:#666; font-family:monospace;">
|
||
<div style="color:#999; font-size:11px; line-height:1.2; font-family:monospace;">{$row.comment_author_ip}</div>
|
||
</td>
|
||
<td>
|
||
<div style="font-size:11px; line-height:1.2;">
|
||
<div>{$row.date_pub}</div>
|
||
{if $row.date_edit}
|
||
<div style="color:#d35400;">ред. {$row.date_edit}</div>
|
||
{/if}
|
||
</div>
|
||
</td>
|
||
|
||
<td>
|
||
<div style="display: flex; flex-direction: column; gap: 4px;">
|
||
<div style="margin-bottom: 2px;">
|
||
<a href="index.php?id={$row.document_id}" target="_blank" style="color:#2980b9; font-weight:bold; text-decoration:none; border-bottom: 1px solid #d1d1d1; font-size: 12px;">
|
||
{$row.document_title|default:"Документ #`$row.document_id`"}
|
||
</a>
|
||
</div>
|
||
<div style="display: flex; align-items: center; gap: 8px;">
|
||
{if $row.parent_id > 0}
|
||
<span style="background:#e1f5fe; color:#0288d1; padding:1px 5px; border-radius:3px; font-weight:bold; font-size: 10px !important;">Ответ на комментарий #{$row.parent_id} »</span>
|
||
{/if}
|
||
<div class="comment-text-cell">
|
||
{if $row.comment_text == '__DEL_BY_ADM__'}
|
||
<div class="comment-deleted-info del-adm">
|
||
<span style="font-size:14px;">🚫</span> Комментарий удален администратором
|
||
</div>
|
||
{elseif $row.comment_text == '__DEL_BY_AUT__'}
|
||
<div class="comment-deleted-info del-aut">
|
||
<span style="font-size:14px;">🗑️</span> Автор удалил свой комментарий
|
||
</div>
|
||
{else}
|
||
{$row.comment_text|strip_tags|truncate:130}
|
||
{/if}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</td>
|
||
|
||
<td align="center">
|
||
<div class="files-bundle">
|
||
{if $row.images}
|
||
{foreach from=$row.images item=img name=img_loop}
|
||
{if $smarty.foreach.img_loop.iteration < 5} {* Показываем максимум 4 превью в стопке *}
|
||
<a href="{$ABS_PATH}uploads/comments/{$img.orig_name}" target="_blank" style="text-decoration:none;">
|
||
<img src="{$ABS_PATH}uploads/comments/{$img.orig_name}" class="thumb-stack" title="{$img.clean_name}">
|
||
</a>
|
||
{/if}
|
||
{/foreach}
|
||
{if $row.images|count >= 5}
|
||
<span style="font-size:10px; color:#999; margin-left:5px;">+{$row.images|count - 4}</span>
|
||
{/if}
|
||
{/if}
|
||
|
||
{if $row.files}
|
||
{foreach from=$row.files item=f}
|
||
<a href="{$ABS_PATH}uploads/comments/{$f.orig_name}" target="_blank" class="file-stack" title="{$f.clean_name}">
|
||
{$f.ext|upper}
|
||
</a>
|
||
{/foreach}
|
||
{/if}
|
||
</div>
|
||
</td>
|
||
|
||
<td align="right">
|
||
<div style="display: flex; justify-content: flex-end; gap: 6px;">
|
||
{if !$is_deleted}
|
||
{if $row.comment_status == '1'}
|
||
<a class="icon_sprite ico_unlock_no" title="Скрыть" href="index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=set_status_0&id={$row.CId}&cp={$sess}"></a>
|
||
{else}
|
||
<a class="icon_sprite ico_unlock" title="Одобрить" href="index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=set_status_1&id={$row.CId}&cp={$sess}"></a>
|
||
{/if}
|
||
<a class="icon_sprite ico_edit" title="Редактировать" href="javascript:void(0);" onClick="windowOpen('index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_edit&pop=1&docid={$row.document_id}&Id={$row.CId}','700','700','1');"></a>
|
||
{if $row.has_children}
|
||
<a class="icon_sprite ico_delete ConfirmDelete" title="Скрыть текст (сохранить ветку)"
|
||
href="index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_del&admin_action_type=soft&Id={$row.CId}&cp={$sess}"></a>
|
||
{/if}
|
||
{/if}
|
||
<a class="icon_sprite ico_delete ico_delete_all ConfirmDelete" title="УДАЛИТЬ ПОЛНОСТЬЮ"
|
||
href="index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_del&admin_action_type=full&Id={$row.CId}&cp={$sess}"></a>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
{/foreach}
|
||
{else}
|
||
<tr>
|
||
<td colspan="9">
|
||
<ul class="messages">
|
||
<li class="highlight yellow"><strong>Сообщение:</strong><br />Нет комментариев.</li>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
{/if}
|
||
</tbody>
|
||
</table>
|
||
|
||
<div class="tfoot">
|
||
<div class="left" style="padding:15px;">
|
||
<select id="mass_action_select">
|
||
<option value="">Выберите действие...</option>
|
||
<option value="set_status_1">Опубликовать</option>
|
||
<option value="set_status_0">Скрыть</option>
|
||
<option value="delete">Удалить выбранные</option>
|
||
</select>
|
||
<input type="button" value="ПРИМЕНИТЬ" class="blueBtn" onclick="runMassAction()" style="margin-left:10px;" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{if $page_nav}
|
||
<div class="pagination"><ul class="pages">{$page_nav}</ul></div>
|
||
{/if}
|
||
|
||
<script type="text/javascript">
|
||
function checkAll(master) {
|
||
var checkboxes = document.getElementsByClassName('row-checkbox');
|
||
for (var i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = master.checked; }
|
||
}
|
||
|
||
function runMassAction() {
|
||
var select = document.getElementById('mass_action_select');
|
||
var action = select.value;
|
||
|
||
// Красивое уведомление, если не выбрали действие
|
||
if (!action) {
|
||
jAlert('Выберите действие из списка!', 'Внимание');
|
||
return;
|
||
}
|
||
|
||
var checkboxes = document.getElementsByClassName('row-checkbox');
|
||
var ids = [];
|
||
for (var i = 0; i < checkboxes.length; i++) {
|
||
if (checkboxes[i].checked) ids.push(checkboxes[i].value);
|
||
}
|
||
|
||
// Красивое уведомление, если не выбрали чекбоксы
|
||
if (ids.length === 0) {
|
||
jAlert('Вы не выбрали ни одного комментария для обработки.', 'Ошибка');
|
||
return;
|
||
}
|
||
|
||
var cp = '{$sess}';
|
||
var url = '';
|
||
|
||
if (action === 'delete') {
|
||
var idParams = ids.map(function(id) { return 'id[]=' + id; }).join('&');
|
||
url = 'index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_del&' + idParams + '&cp=' + cp;
|
||
} else {
|
||
url = 'index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=' + action + '&ids=' + ids.join(',') + '&cp=' + cp;
|
||
}
|
||
|
||
// Красивое подтверждение
|
||
jConfirm('Выполнить выбранное действие для ' + ids.length + ' эл.?', 'Подтверждение', function(r) {
|
||
if(r) window.location.href = url;
|
||
});
|
||
}
|
||
</script> |