фикс стилей
This commit is contained in:
parent
c2791255ee
commit
04330f6c2d
@ -562,4 +562,183 @@ h3 {
|
|||||||
.pagination-info {
|
.pagination-info {
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Адаптивные стили для больших экранов (1200px+) */
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
.admin-conversation-detail {
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Адаптивные стили для средних экранов (992px - 1199px) */
|
||||||
|
@media (min-width: 992px) and (max-width: 1199px) {
|
||||||
|
.admin-conversation-detail {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Адаптивные стили для планшетов (768px - 991px) */
|
||||||
|
@media (min-width: 768px) and (max-width: 991px) {
|
||||||
|
.admin-conversation-detail {
|
||||||
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-grid {
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.participants-list {
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Адаптивные стили для малых планшетов (576px - 767px) */
|
||||||
|
@media (min-width: 576px) and (max-width: 767px) {
|
||||||
|
.admin-conversation-detail {
|
||||||
|
padding: 1rem;
|
||||||
|
/* Учитываем отступ внизу для нижней навигации на мобильных */
|
||||||
|
padding-bottom: calc(1rem + 56px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-item {
|
||||||
|
max-width: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.participants-list {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Адаптивные стили для мобильных устройств (до 575px) */
|
||||||
|
@media (max-width: 575px) {
|
||||||
|
.admin-conversation-detail {
|
||||||
|
padding: 0.75rem;
|
||||||
|
/* Учитываем отступ внизу для нижней навигации на мобильных */
|
||||||
|
padding-bottom: calc(0.75rem + 56px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conversation-info,
|
||||||
|
.participants-section,
|
||||||
|
.messages-section {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.participants-list {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.participant-card {
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.participant-photo {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-item {
|
||||||
|
max-width: 90%;
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-btn {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-info {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Специальные стили для очень маленьких экранов */
|
||||||
|
@media (max-width: 360px) {
|
||||||
|
.admin-conversation-detail {
|
||||||
|
padding: 0.5rem;
|
||||||
|
padding-bottom: calc(0.5rem + 56px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
|
||||||
|
.conversation-info,
|
||||||
|
.participants-section,
|
||||||
|
.messages-section {
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-time {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-sender {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-btn {
|
||||||
|
padding: 0.35rem 0.5rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ландшафтная ориентация на мобильных */
|
||||||
|
@media (max-height: 450px) and (orientation: landscape) {
|
||||||
|
.admin-conversation-detail {
|
||||||
|
padding: 0.75rem;
|
||||||
|
padding-bottom: calc(0.75rem + 50px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
|
||||||
|
.conversation-container {
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-controls {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conversation-info,
|
||||||
|
.participants-section,
|
||||||
|
.messages-section {
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
margin-top: 0.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -12,14 +12,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="loading" class="loading-indicator">
|
<div v-if="loading" class="loading-indicator">
|
||||||
Загрузка диалогов...
|
<div class="spinner"></div>
|
||||||
|
<p>Загрузка диалогов...</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="error" class="error-message">
|
<div v-if="error" class="error-message">
|
||||||
{{ error }}
|
{{ error }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!loading && !error" class="conversations-table-container">
|
<!-- Десктопная таблица (отображается только на больших экранах) -->
|
||||||
|
<div v-if="!loading && !error" class="desktop-table">
|
||||||
|
<div class="conversations-table-container">
|
||||||
<table class="conversations-table">
|
<table class="conversations-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -52,12 +55,51 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
<div v-if="conversations.length === 0" class="no-results">
|
|
||||||
Диалоги не найдены
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="pagination.pages > 1" class="pagination">
|
<!-- Мобильные карточки (отображаются только на малых экранах) -->
|
||||||
|
<div v-if="!loading && !error" class="mobile-cards">
|
||||||
|
<div
|
||||||
|
v-for="conversation in conversations"
|
||||||
|
:key="conversation._id"
|
||||||
|
class="conversation-card"
|
||||||
|
@click="viewConversation(conversation._id)"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="card-id">ID: {{ shortenId(conversation._id) }}</div>
|
||||||
|
<div class="card-date">{{ formatDate(conversation.updatedAt) }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="card-section">
|
||||||
|
<div class="section-title">Участники:</div>
|
||||||
|
<div class="section-content">
|
||||||
|
<div v-for="participant in conversation.participants" :key="participant._id" class="participant-item">
|
||||||
|
{{ participant.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-section">
|
||||||
|
<div class="section-title">Последнее сообщение:</div>
|
||||||
|
<div class="section-content message-preview">
|
||||||
|
{{ conversation.lastMessage ? truncateText(conversation.lastMessage.text, 50) : 'Нет сообщений' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<span>Просмотр диалога</span>
|
||||||
|
<i class="bi-arrow-right"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!loading && !error && conversations.length === 0" class="no-results">
|
||||||
|
<i class="bi-chat-dots"></i>
|
||||||
|
<h3>Диалоги не найдены</h3>
|
||||||
|
<p>Попробуйте изменить параметры поиска</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!loading && !error && pagination.pages > 1" class="pagination">
|
||||||
<button
|
<button
|
||||||
@click="changePage(currentPage - 1)"
|
@click="changePage(currentPage - 1)"
|
||||||
:disabled="currentPage === 1"
|
:disabled="currentPage === 1"
|
||||||
@ -79,7 +121,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -202,6 +243,7 @@ export default {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.admin-conversations {
|
.admin-conversations {
|
||||||
|
padding: 1.5rem;
|
||||||
padding-bottom: 2rem;
|
padding-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,6 +251,21 @@ h2 {
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
color: #333;
|
color: #333;
|
||||||
|
font-weight: 600;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 3px;
|
||||||
|
background: linear-gradient(to bottom, #ff3e68, #ff5252);
|
||||||
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-bar {
|
.search-bar {
|
||||||
@ -234,12 +291,35 @@ h2 {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-btn:hover {
|
||||||
|
background-color: #e9365e;
|
||||||
|
}
|
||||||
|
|
||||||
.loading-indicator {
|
.loading-indicator {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.spinner {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border: 4px solid rgba(255, 62, 104, 0.2);
|
||||||
|
border-left: 4px solid #ff3e68;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
.error-message {
|
.error-message {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
background-color: #ffebee;
|
background-color: #ffebee;
|
||||||
@ -248,8 +328,11 @@ h2 {
|
|||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Стили для десктопной таблицы */
|
||||||
.conversations-table-container {
|
.conversations-table-container {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.conversations-table {
|
.conversations-table {
|
||||||
@ -270,6 +353,10 @@ h2 {
|
|||||||
color: #444;
|
color: #444;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.conversations-table tr:hover {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
.participants-cell {
|
.participants-cell {
|
||||||
max-width: 300px;
|
max-width: 300px;
|
||||||
}
|
}
|
||||||
@ -300,12 +387,127 @@ h2 {
|
|||||||
color: #1976d2;
|
color: #1976d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.view-btn:hover {
|
||||||
|
background-color: #bbdefb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Стили для мобильных карточек */
|
||||||
|
.mobile-cards {
|
||||||
|
display: none;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conversation-card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
||||||
|
transition: transform 0.2s, box-shadow 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conversation-card:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0.75rem;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-id {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1976d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-date {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content {
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-section {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-section:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-content {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.participant-item {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-preview {
|
||||||
|
font-style: italic;
|
||||||
|
color: #495057;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.75rem;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1976d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-footer i {
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conversation-card:hover .card-footer i {
|
||||||
|
transform: translateX(2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Стили для пустого результата */
|
||||||
.no-results {
|
.no-results {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
color: #666;
|
color: #666;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-results i {
|
||||||
|
font-size: 3rem;
|
||||||
|
color: #ccc;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-results h3 {
|
||||||
|
margin: 0 0 0.5rem;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-results p {
|
||||||
|
margin: 0;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Стили для пагинации */
|
||||||
.pagination {
|
.pagination {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -320,6 +522,11 @@ h2 {
|
|||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-btn:hover:not(:disabled) {
|
||||||
|
background-color: #e9e9e9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination-btn:disabled {
|
.pagination-btn:disabled {
|
||||||
@ -330,4 +537,115 @@ h2 {
|
|||||||
.pagination-info {
|
.pagination-info {
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Адаптивные стили */
|
||||||
|
@media (max-width: 1199px) {
|
||||||
|
.admin-conversations {
|
||||||
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
/* На планшетах и меньше */
|
||||||
|
.desktop-table {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-cards {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-conversations {
|
||||||
|
padding: 1rem;
|
||||||
|
/* Добавляем отступ для нижней навигации */
|
||||||
|
padding-bottom: calc(1rem + 56px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
/* На десктопах */
|
||||||
|
.desktop-table {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-cards {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
/* Мобильные устройства */
|
||||||
|
h2 {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-btn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
/* Маленькие мобильные устройства */
|
||||||
|
.admin-conversations {
|
||||||
|
padding: 0.75rem;
|
||||||
|
padding-bottom: calc(0.75rem + 56px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar input {
|
||||||
|
padding: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-date {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.participant-item {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-btn {
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Очень маленькие экраны */
|
||||||
|
@media (max-width: 360px) {
|
||||||
|
.admin-conversations {
|
||||||
|
padding: 0.5rem;
|
||||||
|
padding-bottom: calc(0.5rem + 56px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content {
|
||||||
|
padding: 0.6rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ландшафтная ориентация на мобильных */
|
||||||
|
@media (max-height: 450px) and (orientation: landscape) {
|
||||||
|
.admin-conversations {
|
||||||
|
padding-bottom: calc(1rem + 50px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -3,10 +3,12 @@
|
|||||||
<h2>Статистика приложения</h2>
|
<h2>Статистика приложения</h2>
|
||||||
|
|
||||||
<div v-if="loading" class="loading-indicator">
|
<div v-if="loading" class="loading-indicator">
|
||||||
Загрузка статистики...
|
<div class="loading-spinner"></div>
|
||||||
|
<div>Загрузка статистики...</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="error" class="error-message">
|
<div v-if="error" class="error-message">
|
||||||
|
<i class="bi-exclamation-triangle"></i>
|
||||||
{{ error }}
|
{{ error }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -15,36 +17,34 @@
|
|||||||
<h3>Пользователи</h3>
|
<h3>Пользователи</h3>
|
||||||
|
|
||||||
<div class="stat-cards">
|
<div class="stat-cards">
|
||||||
<div class="stat-card">
|
<div class="stat-card users">
|
||||||
<div class="stat-value">{{ statistics.users.total }}</div>
|
<div class="stat-value">{{ statistics.users.total }}</div>
|
||||||
<div class="stat-label">Всего пользователей</div>
|
<div class="stat-label">Всего пользователей</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stat-card">
|
<div class="stat-card active">
|
||||||
<div class="stat-value">{{ statistics.users.active }}</div>
|
<div class="stat-value">{{ statistics.users.active }}</div>
|
||||||
<div class="stat-label">Активных пользователей</div>
|
<div class="stat-label">Активных</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stat-card">
|
<div class="stat-card blocked">
|
||||||
<div class="stat-value">{{ statistics.users.inactive }}</div>
|
<div class="stat-value">{{ statistics.users.inactive }}</div>
|
||||||
<div class="stat-label">Заблокированных</div>
|
<div class="stat-label">Заблокированных</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stat-card">
|
<div class="stat-card new">
|
||||||
<div class="stat-value">{{ statistics.users.newIn30Days }}</div>
|
<div class="stat-value">{{ statistics.users.newIn30Days }}</div>
|
||||||
<div class="stat-label">Новых за 30 дней</div>
|
<div class="stat-label">Новых за 30 дней</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gender-distribution">
|
<div class="gender-distribution">
|
||||||
<h4>Распределение по полу</h4>
|
<h4>Распределение пользователей по полу</h4>
|
||||||
<div class="gender-chart">
|
<div class="gender-chart">
|
||||||
<div class="gender-bar">
|
<div class="gender-bar">
|
||||||
<div
|
<div
|
||||||
class="gender-male"
|
class="gender-male"
|
||||||
:style="{
|
:style="{ width: calculateGenderPercentage('male') + '%' }"
|
||||||
width: calculateGenderPercentage('male') + '%'
|
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<span v-if="calculateGenderPercentage('male') > 10">
|
<span v-if="calculateGenderPercentage('male') > 10">
|
||||||
{{ statistics.users.genderDistribution.male }}
|
{{ statistics.users.genderDistribution.male }}
|
||||||
@ -52,9 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="gender-female"
|
class="gender-female"
|
||||||
:style="{
|
:style="{ width: calculateGenderPercentage('female') + '%' }"
|
||||||
width: calculateGenderPercentage('female') + '%'
|
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<span v-if="calculateGenderPercentage('female') > 10">
|
<span v-if="calculateGenderPercentage('female') > 10">
|
||||||
{{ statistics.users.genderDistribution.female }}
|
{{ statistics.users.genderDistribution.female }}
|
||||||
@ -62,9 +60,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="gender-other"
|
class="gender-other"
|
||||||
:style="{
|
:style="{ width: calculateGenderPercentage('other') + '%' }"
|
||||||
width: calculateGenderPercentage('other') + '%'
|
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<span v-if="calculateGenderPercentage('other') > 10">
|
<span v-if="calculateGenderPercentage('other') > 10">
|
||||||
{{ statistics.users.genderDistribution.other }}
|
{{ statistics.users.genderDistribution.other }}
|
||||||
@ -93,22 +89,23 @@
|
|||||||
<h3>Активность пользователей</h3>
|
<h3>Активность пользователей</h3>
|
||||||
|
|
||||||
<div class="stat-cards">
|
<div class="stat-cards">
|
||||||
<div class="stat-card">
|
<div class="stat-card messages">
|
||||||
<div class="stat-value">{{ statistics.activity.totalMessages }}</div>
|
<div class="stat-value">{{ statistics.activity.totalMessages }}</div>
|
||||||
<div class="stat-label">Всего сообщений</div>
|
<div class="stat-label">Всего сообщений</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stat-card">
|
<div class="stat-card conversations">
|
||||||
<div class="stat-value">{{ statistics.activity.totalConversations }}</div>
|
<div class="stat-value">{{ statistics.activity.totalConversations }}</div>
|
||||||
<div class="stat-label">Всего диалогов</div>
|
<div class="stat-label">Всего диалогов</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stat-card">
|
<div class="stat-card views">
|
||||||
<div class="stat-value">{{ statistics.activity.totalProfileViews }}</div>
|
<div class="stat-value">{{ statistics.activity.totalProfileViews }}</div>
|
||||||
<div class="stat-label">Просмотров профилей</div>
|
<div class="stat-label">Просмотров профилей</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="average-stats-container">
|
||||||
<h4>Средняя активность</h4>
|
<h4>Средняя активность</h4>
|
||||||
<div class="average-stats">
|
<div class="average-stats">
|
||||||
<div class="average-item">
|
<div class="average-item">
|
||||||
@ -123,6 +120,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -189,6 +187,7 @@ export default {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.admin-statistics {
|
.admin-statistics {
|
||||||
|
padding: 1.5rem;
|
||||||
padding-bottom: 2rem;
|
padding-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,12 +212,49 @@ h2::before {
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin: 1.5rem 0 1rem 0;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.loading-indicator {
|
.loading-indicator {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-spinner {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border: 4px solid rgba(255, 62, 104, 0.2);
|
||||||
|
border-left: 4px solid #ff3e68;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
.error-message {
|
.error-message {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
background-color: #ffebee;
|
background-color: #ffebee;
|
||||||
@ -226,6 +262,14 @@ h2::before {
|
|||||||
color: #d32f2f;
|
color: #d32f2f;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message i {
|
||||||
|
color: #d32f2f;
|
||||||
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.statistics-container {
|
.statistics-container {
|
||||||
@ -234,40 +278,67 @@ h2::before {
|
|||||||
gap: 2rem;
|
gap: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-container {
|
.stat-section {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border-radius: 8px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
overflow: hidden;
|
border: 1px solid #f1f3f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-title {
|
.stat-cards {
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats-section {
|
|
||||||
border-radius: 8px;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats-cards {
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card {
|
.stat-card {
|
||||||
background-color: white;
|
background-color: #f8f9fa;
|
||||||
border-radius: 8px;
|
border-radius: 10px;
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
border-top: 3px solid transparent;
|
border: 1px solid #f1f3f5;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 4px;
|
||||||
|
background: linear-gradient(to right, transparent, #ff3e68, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.users::before {
|
||||||
|
background: linear-gradient(to right, #ff3e68, #ff5252);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.active::before {
|
||||||
|
background: linear-gradient(to right, #4caf50, #8bc34a);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.blocked::before {
|
||||||
|
background: linear-gradient(to right, #f44336, #e91e63);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.new::before {
|
||||||
|
background: linear-gradient(to right, #ff9800, #ffc107);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.messages::before {
|
||||||
|
background: linear-gradient(to right, #2196f3, #03a9f4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.conversations::before {
|
||||||
|
background: linear-gradient(to right, #9c27b0, #673ab7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.views::before {
|
||||||
|
background: linear-gradient(to right, #009688, #4caf50);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card:hover {
|
.stat-card:hover {
|
||||||
@ -275,22 +346,6 @@ h2::before {
|
|||||||
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
|
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card.users {
|
|
||||||
border-color: #ff3e68;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card.messages {
|
|
||||||
border-color: #4caf50;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card.conversations {
|
|
||||||
border-color: #2196f3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card.views {
|
|
||||||
border-color: #ff9800;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-value {
|
.stat-value {
|
||||||
font-size: 2.2rem;
|
font-size: 2.2rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -302,48 +357,45 @@ h2::before {
|
|||||||
color: #ff3e68;
|
color: #ff3e68;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card.messages .stat-value {
|
.stat-card.active .stat-value {
|
||||||
color: #4caf50;
|
color: #4caf50;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card.conversations .stat-value {
|
.stat-card.blocked .stat-value {
|
||||||
|
color: #f44336;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.new .stat-value {
|
||||||
|
color: #ff9800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.messages .stat-value {
|
||||||
color: #2196f3;
|
color: #2196f3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stat-card.conversations .stat-value {
|
||||||
|
color: #9c27b0;
|
||||||
|
}
|
||||||
|
|
||||||
.stat-card.views .stat-value {
|
.stat-card.views .stat-value {
|
||||||
color: #ff9800;
|
color: #009688;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-label {
|
.stat-label {
|
||||||
color: #777;
|
color: #777;
|
||||||
font-size: 0.9rem;
|
font-size: 0.95rem;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Стили для блока распределения по полу */
|
/* Стили для блока распределения по полу */
|
||||||
.gender-distribution {
|
.gender-distribution {
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
background-color: white;
|
background-color: #f8f9fa;
|
||||||
border-radius: 12px;
|
border-radius: 10px;
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
border: 1px solid #f1f3f5;
|
border: 1px solid #f1f3f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gender-distribution h4 {
|
|
||||||
margin: 0 0 1.5rem 0;
|
|
||||||
color: #333;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gender-distribution h4::before {
|
|
||||||
content: '👥';
|
|
||||||
font-size: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gender-chart {
|
.gender-chart {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -356,7 +408,7 @@ h2::before {
|
|||||||
height: 40px;
|
height: 40px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #f8f9fa;
|
background-color: #f1f3f5;
|
||||||
box-shadow: inset 0 2px 4px rgba(0,0,0,0.05);
|
box-shadow: inset 0 2px 4px rgba(0,0,0,0.05);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@ -369,8 +421,8 @@ h2::before {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 0.85rem;
|
font-size: 0.9rem;
|
||||||
text-shadow: 0 1px 2px rgba(0,0,0,0.3);
|
text-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -408,7 +460,7 @@ h2::before {
|
|||||||
.gender-legend {
|
.gender-legend {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 1rem;
|
gap: 0.75rem;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
@ -418,16 +470,17 @@ h2::before {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.5rem 0.75rem;
|
||||||
background-color: #f8f9fa;
|
background-color: white;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
border: 1px solid transparent;
|
border: 1px solid #f1f3f5;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.legend-item:hover {
|
.legend-item:hover {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border-color: #e9ecef;
|
border-color: #e9ecef;
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,82 +511,108 @@ h2::before {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.averages-section {
|
/* Блок средних значений */
|
||||||
|
.average-stats-container {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border: 1px solid #f1f3f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.averages-title {
|
.average-stats {
|
||||||
margin-top: 0;
|
display: grid;
|
||||||
margin-bottom: 1rem;
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
font-weight: 500;
|
|
||||||
color: #333;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.averages-container {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.average-item {
|
.average-item {
|
||||||
background-color: #f8f9fa;
|
|
||||||
padding: 0.8rem 1.2rem;
|
|
||||||
border-radius: 8px;
|
|
||||||
flex: 1;
|
|
||||||
min-width: 200px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
background-color: white;
|
||||||
|
padding: 1rem 1.25rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
||||||
|
border: 1px solid #f1f3f5;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.average-item:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 3px 6px rgba(0,0,0,0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.average-label {
|
.average-label {
|
||||||
color: #555;
|
color: #555;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
font-size: 0.95rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.average-value {
|
.average-value {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ff3e68;
|
color: #ff3e68;
|
||||||
}
|
|
||||||
|
|
||||||
.donut-chart {
|
|
||||||
max-width: 300px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subcards {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
|
||||||
gap: 0.5rem;
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subcard {
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
padding: 0.8rem;
|
|
||||||
border-radius: 6px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subcard-value {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #ff3e68;
|
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subcard-label {
|
/* Адаптивное отображение */
|
||||||
font-size: 0.75rem;
|
@media (max-width: 1199px) {
|
||||||
color: #777;
|
.admin-statistics {
|
||||||
margin-top: 0.25rem;
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-cards {
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
.admin-statistics {
|
||||||
|
padding: 1rem;
|
||||||
|
/* Добавляем отступ для нижней навигации */
|
||||||
|
padding-bottom: calc(1rem + 56px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-cards {
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gender-distribution,
|
||||||
|
.average-stats-container {
|
||||||
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.average-stats {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Адаптивное отображение */
|
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
|
.stat-cards {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
.stat-value {
|
.stat-value {
|
||||||
font-size: 1.8rem;
|
font-size: 1.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-section {
|
||||||
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.gender-bar {
|
.gender-bar {
|
||||||
height: 35px;
|
height: 35px;
|
||||||
}
|
}
|
||||||
@ -544,25 +623,38 @@ h2::before {
|
|||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gender-distribution {
|
.gender-distribution,
|
||||||
padding: 1rem;
|
.average-stats-container {
|
||||||
|
padding: 1.25rem;
|
||||||
|
margin-top: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.legend-label {
|
.legend-item {
|
||||||
font-size: 0.85rem;
|
padding: 0.4rem 0.6rem;
|
||||||
|
flex: 1;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 1.4rem;
|
font-size: 1.3rem;
|
||||||
margin-bottom: 1.2rem;
|
margin-bottom: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-title {
|
h3 {
|
||||||
font-size: 1.1rem;
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-cards {
|
h4 {
|
||||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
font-size: 1rem;
|
||||||
|
margin: 0.75rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.average-item {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-statistics {
|
.admin-statistics {
|
||||||
@ -572,20 +664,31 @@ h2::before {
|
|||||||
|
|
||||||
@media (max-width: 576px) {
|
@media (max-width: 576px) {
|
||||||
.stat-card {
|
.stat-card {
|
||||||
padding: 1.2rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-value {
|
.stat-value {
|
||||||
font-size: 1.6rem;
|
font-size: 1.5rem;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-cards {
|
.stat-label {
|
||||||
grid-template-columns: repeat(2, 1fr);
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gender-distribution {
|
.admin-statistics {
|
||||||
|
padding: 0.75rem;
|
||||||
|
padding-bottom: calc(0.75rem + 56px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-section {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
margin-top: 1.5rem;
|
}
|
||||||
|
|
||||||
|
.gender-distribution,
|
||||||
|
.average-stats-container {
|
||||||
|
padding: 1rem;
|
||||||
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gender-bar {
|
.gender-bar {
|
||||||
@ -600,17 +703,72 @@ h2::before {
|
|||||||
|
|
||||||
.gender-legend {
|
.gender-legend {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.75rem;
|
gap: 0.5rem;
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.legend-item {
|
.legend-item {
|
||||||
justify-content: center;
|
width: 100%;
|
||||||
min-width: 120px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.stat-cards {
|
||||||
|
gap: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
margin-bottom: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.average-label {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.average-value {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 360px) {
|
||||||
|
.admin-statistics {
|
||||||
|
padding: 0.5rem;
|
||||||
|
padding-bottom: calc(0.5rem + 56px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-section,
|
||||||
|
.gender-distribution,
|
||||||
|
.average-stats-container {
|
||||||
|
padding: 0.75rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gender-bar {
|
||||||
|
height: 25px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,5 +784,29 @@ h2::before {
|
|||||||
.admin-statistics {
|
.admin-statistics {
|
||||||
padding-bottom: calc(50px + env(safe-area-inset-bottom, 0px));
|
padding-bottom: calc(50px + env(safe-area-inset-bottom, 0px));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stat-cards {
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gender-distribution {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gender-legend {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -26,14 +26,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="loading" class="loading-indicator">
|
<div v-if="loading" class="loading-indicator">
|
||||||
Загрузка пользователей...
|
<div class="loading-spinner"></div>
|
||||||
|
<span>Загрузка пользователей...</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="error" class="error-message">
|
<div v-if="error" class="error-message">
|
||||||
|
<i class="bi-exclamation-triangle"></i>
|
||||||
{{ error }}
|
{{ error }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!loading && !error" class="users-table-container">
|
<!-- Десктопная таблица (отображается только на больших экранах) -->
|
||||||
|
<div v-if="!loading && !error" class="desktop-table">
|
||||||
|
<div class="users-table-container">
|
||||||
<table class="users-table">
|
<table class="users-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -73,22 +77,75 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
<div v-if="users.length === 0" class="no-results">
|
|
||||||
Пользователи не найдены
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="pagination.pages > 1" class="pagination">
|
<!-- Мобильное карточное представление (отображается только на маленьких экранах) -->
|
||||||
|
<div v-if="!loading && !error" class="mobile-cards">
|
||||||
|
<div
|
||||||
|
v-for="user in users"
|
||||||
|
:key="user._id"
|
||||||
|
class="user-card"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="user-name">{{ user.name }}</div>
|
||||||
|
<span class="status-badge" :class="{ 'active': user.isActive, 'blocked': !user.isActive }">
|
||||||
|
{{ user.isActive ? 'Активен' : 'Заблокирован' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="info-row">
|
||||||
|
<div class="info-label">ID:</div>
|
||||||
|
<div class="info-value id-value">{{ shortenId(user._id) }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-row">
|
||||||
|
<div class="info-label">Email:</div>
|
||||||
|
<div class="info-value">{{ user.email }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-row">
|
||||||
|
<div class="info-label">Дата регистрации:</div>
|
||||||
|
<div class="info-value">{{ formatDate(user.createdAt) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-actions">
|
||||||
|
<button @click="viewUser(user._id)" class="card-btn view-btn">
|
||||||
|
<i class="bi-eye"></i>
|
||||||
|
<span>Просмотр</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="toggleUserStatus(user._id, user.isActive)"
|
||||||
|
class="card-btn"
|
||||||
|
:class="user.isActive ? 'block-btn' : 'unblock-btn'"
|
||||||
|
>
|
||||||
|
<i :class="user.isActive ? 'bi-lock-fill' : 'bi-unlock-fill'"></i>
|
||||||
|
<span>{{ user.isActive ? 'Заблокировать' : 'Разблокировать' }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!loading && !error && users.length === 0" class="no-results">
|
||||||
|
<i class="bi-person-slash"></i>
|
||||||
|
<h3>Пользователи не найдены</h3>
|
||||||
|
<p>Попробуйте изменить параметры поиска или фильтрации</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!loading && !error && pagination.pages > 1" class="pagination">
|
||||||
<button
|
<button
|
||||||
@click="changePage(currentPage - 1)"
|
@click="changePage(currentPage - 1)"
|
||||||
:disabled="currentPage === 1"
|
:disabled="currentPage === 1"
|
||||||
class="pagination-btn"
|
class="pagination-btn"
|
||||||
>
|
>
|
||||||
« Назад
|
<i class="bi-chevron-left"></i>
|
||||||
|
<span>Назад</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<span class="pagination-info">
|
<span class="pagination-info">
|
||||||
Страница {{ currentPage }} из {{ pagination.pages }}
|
{{ currentPage }} из {{ pagination.pages }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
@ -96,11 +153,11 @@
|
|||||||
:disabled="currentPage === pagination.pages"
|
:disabled="currentPage === pagination.pages"
|
||||||
class="pagination-btn"
|
class="pagination-btn"
|
||||||
>
|
>
|
||||||
Вперёд »
|
<span>Вперёд</span>
|
||||||
|
<i class="bi-chevron-right"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -264,6 +321,7 @@ export default {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.admin-users {
|
.admin-users {
|
||||||
|
padding: 1.5rem;
|
||||||
padding-bottom: 2rem;
|
padding-bottom: 2rem;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
@ -339,11 +397,30 @@ h2::before {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.loading-indicator {
|
.loading-indicator {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-spinner {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border: 4px solid rgba(255, 62, 104, 0.2);
|
||||||
|
border-left: 4px solid #ff3e68;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
.error-message {
|
.error-message {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
background-color: #ffebee;
|
background-color: #ffebee;
|
||||||
@ -351,11 +428,22 @@ h2::before {
|
|||||||
color: #d32f2f;
|
color: #d32f2f;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.error-message i {
|
||||||
|
color: #f44336;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Стили для десктопной таблицы */
|
||||||
.users-table-container {
|
.users-table-container {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.users-table {
|
.users-table {
|
||||||
@ -363,8 +451,6 @@ h2::before {
|
|||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
min-width: 800px;
|
min-width: 800px;
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.users-table th, .users-table td {
|
.users-table th, .users-table td {
|
||||||
@ -467,12 +553,116 @@ h2::before {
|
|||||||
background-color: rgba(46, 125, 50, 0.15);
|
background-color: rgba(46, 125, 50, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-results {
|
/* Стили для мобильных карточек */
|
||||||
padding: 2rem;
|
.mobile-cards {
|
||||||
text-align: center;
|
display: none;
|
||||||
color: #666;
|
flex-direction: column;
|
||||||
background-color: #f9f9f9;
|
gap: 1rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-card {
|
||||||
|
background: white;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||||
|
border: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-name {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-row {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-row:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-label {
|
||||||
|
flex: 0 0 40%;
|
||||||
|
color: #666;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-value {
|
||||||
|
flex: 1;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.id-value {
|
||||||
|
font-family: monospace;
|
||||||
|
color: #1976d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-actions {
|
||||||
|
display: flex;
|
||||||
|
padding: 0.75rem;
|
||||||
|
gap: 0.5rem;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-btn {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.6rem;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-btn:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-results {
|
||||||
|
text-align: center;
|
||||||
|
padding: 3rem 1rem;
|
||||||
|
color: #666;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-results i {
|
||||||
|
font-size: 3rem;
|
||||||
|
color: #ccc;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-results h3 {
|
||||||
|
margin: 0 0 0.5rem;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-results p {
|
||||||
|
margin: 0;
|
||||||
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination {
|
.pagination {
|
||||||
@ -493,6 +683,9 @@ h2::before {
|
|||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
color: #495057;
|
color: #495057;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination-btn:hover:not(:disabled) {
|
.pagination-btn:hover:not(:disabled) {
|
||||||
@ -507,122 +700,141 @@ h2::before {
|
|||||||
|
|
||||||
.pagination-info {
|
.pagination-info {
|
||||||
color: #6c757d;
|
color: #6c757d;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Адаптивные стили */
|
||||||
|
@media (max-width: 1199px) {
|
||||||
|
.admin-users {
|
||||||
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Адаптивное отображение */
|
|
||||||
@media (max-width: 991px) {
|
@media (max-width: 991px) {
|
||||||
.users-table {
|
/* На планшетах и меньше */
|
||||||
font-size: 0.9rem;
|
.desktop-table {
|
||||||
}
|
|
||||||
|
|
||||||
.users-table th, .users-table td {
|
|
||||||
padding: 0.6rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
padding: 0.3rem 0.6rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Планшеты и маленькие экраны */
|
|
||||||
@media (max-width: 767px) {
|
|
||||||
h2 {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Скрываем менее важные данные на мобильных */
|
|
||||||
.hide-sm {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.email-cell {
|
.mobile-cards {
|
||||||
max-width: 140px;
|
display: flex;
|
||||||
overflow: hidden;
|
}
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
.admin-users {
|
||||||
|
padding: 1rem;
|
||||||
|
/* Добавляем отступ для нижней навигации */
|
||||||
|
padding-bottom: calc(1rem + 56px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
/* На десктопах */
|
||||||
|
.desktop-table {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-cards {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
/* Мобильные устройства */
|
||||||
|
h2 {
|
||||||
|
font-size: 1.3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-options {
|
.filter-options {
|
||||||
justify-content: space-between;
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 0.5rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.users-table {
|
.filter-options label {
|
||||||
min-width: auto;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-badge {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
padding: 0.2rem 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
padding: 0.4rem;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
width: 100%;
|
||||||
|
font-size: 0.9rem;
|
||||||
.btn i {
|
padding: 0.5rem 0;
|
||||||
font-size: 1.1rem;
|
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination {
|
.pagination {
|
||||||
gap: 0.5rem;
|
gap: 0.75rem;
|
||||||
}
|
|
||||||
|
|
||||||
.pagination-btn {
|
|
||||||
padding: 0.4rem 0.7rem;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 1.3rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* На мобильных добавляем отступ снизу для нижней навигации */
|
|
||||||
.admin-users {
|
|
||||||
padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Мелкие мобильные устройства */
|
@media (max-width: 480px) {
|
||||||
@media (max-width: 420px) {
|
/* Маленькие мобильные устройства */
|
||||||
.users-table th, .users-table td {
|
.admin-users {
|
||||||
padding: 0.5rem 0.4rem;
|
padding: 0.75rem;
|
||||||
}
|
padding-bottom: calc(0.75rem + 56px + env(safe-area-inset-bottom, 0px));
|
||||||
|
|
||||||
.email-cell {
|
|
||||||
max-width: 80px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar input {
|
||||||
|
padding: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-options {
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-options label {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
padding: 0.5rem 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-actions {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-btn {
|
||||||
|
padding: 0.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Устройства с вырезом (notch) */
|
/* Очень маленькие экраны */
|
||||||
@supports (padding: env(safe-area-inset-bottom)) {
|
@media (max-width: 360px) {
|
||||||
.admin-users {
|
.admin-users {
|
||||||
padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px));
|
padding: 0.5rem;
|
||||||
|
padding-bottom: calc(0.5rem + 56px + env(safe-area-inset-bottom, 0px));
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-row {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-label {
|
||||||
|
flex: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ландшафтная ориентация на мобильных */
|
/* Ландшафтная ориентация на мобильных */
|
||||||
@media (max-height: 450px) and (orientation: landscape) {
|
@media (max-height: 450px) and (orientation: landscape) {
|
||||||
.users-table {
|
.admin-users {
|
||||||
font-size: 0.8rem;
|
padding-bottom: calc(1rem + 50px + env(safe-area-inset-bottom, 0px));
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-users {
|
.card-actions {
|
||||||
padding-bottom: calc(50px + env(safe-area-inset-bottom, 0px));
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
Loading…
x
Reference in New Issue
Block a user