This commit is contained in:
Professional 2025-05-26 00:38:09 +07:00
parent 2ec6c12403
commit 0b98b8a37d
2 changed files with 156 additions and 224 deletions

View File

@ -2,9 +2,6 @@
<div class="admin-dashboard"> <div class="admin-dashboard">
<div class="admin-header"> <div class="admin-header">
<div class="admin-header-left"> <div class="admin-header-left">
<button v-if="isMobile" @click="toggleSidebar" class="menu-toggle-btn">
<i class="bi-list"></i>
</button>
<h1>Панель управления</h1> <h1>Панель управления</h1>
</div> </div>
<div class="admin-user-info"> <div class="admin-user-info">
@ -32,35 +29,6 @@
</nav> </nav>
</div> </div>
<!-- Мобильное боковое меню -->
<div v-if="isMobile" class="admin-sidebar-mobile" :class="{ 'sidebar-open': sidebarOpen }">
<div class="sidebar-overlay" @click="toggleSidebar"></div>
<div class="sidebar-content">
<div class="sidebar-header">
<span>Меню администратора</span>
<button @click="toggleSidebar" class="close-sidebar-btn">
<i class="bi-x-lg"></i>
</button>
</div>
<nav>
<router-link :to="{ name: 'AdminUsers' }" active-class="active" @click="sidebarOpen = false">
<i class="bi-people"></i> Пользователи
</router-link>
<router-link :to="{ name: 'AdminConversations' }" active-class="active" @click="sidebarOpen = false">
<i class="bi-chat-dots"></i> Диалоги
</router-link>
<router-link :to="{ name: 'AdminStatistics' }" active-class="active" @click="sidebarOpen = false">
<i class="bi-graph-up"></i> Статистика
</router-link>
<div class="mobile-logout-container">
<button @click="logout" class="mobile-logout-btn">
<i class="bi-box-arrow-right"></i> Выйти
</button>
</div>
</nav>
</div>
</div>
<div class="admin-main-content"> <div class="admin-main-content">
<router-view></router-view> <router-view></router-view>
</div> </div>
@ -93,7 +61,7 @@
<script> <script>
import { useAuth } from '../../auth'; import { useAuth } from '../../auth';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { computed, ref, onMounted, onBeforeUnmount, watch } from 'vue'; import { computed, ref, onMounted, onBeforeUnmount } from 'vue';
export default { export default {
name: 'AdminDashboard', name: 'AdminDashboard',
@ -101,17 +69,9 @@ export default {
const { user, logout: authLogout } = useAuth(); const { user, logout: authLogout } = useAuth();
const router = useRouter(); const router = useRouter();
const isMobile = ref(window.innerWidth < 768); const isMobile = ref(window.innerWidth < 768);
const sidebarOpen = ref(false);
const handleResize = () => { const handleResize = () => {
isMobile.value = window.innerWidth < 768; isMobile.value = window.innerWidth < 768;
if (!isMobile.value) {
sidebarOpen.value = false;
}
};
const toggleSidebar = () => {
sidebarOpen.value = !sidebarOpen.value;
}; };
const logout = async () => { const logout = async () => {
@ -131,19 +91,10 @@ export default {
window.removeEventListener('resize', handleResize); window.removeEventListener('resize', handleResize);
}); });
// Закрываем боковое меню при изменении маршрута
watch(() => router.currentRoute.value.path, () => {
if (sidebarOpen.value) {
sidebarOpen.value = false;
}
});
return { return {
user: computed(() => user.value), user: computed(() => user.value),
logout, logout,
isMobile, isMobile
sidebarOpen,
toggleSidebar
}; };
} }
} }
@ -280,137 +231,6 @@ export default {
color: #ff3e68; color: #ff3e68;
} }
/* Стили для мобильной боковой панели */
.admin-sidebar-mobile {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
display: none;
}
.admin-sidebar-mobile.sidebar-open {
display: block;
}
.sidebar-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
z-index: 1;
backdrop-filter: blur(2px);
}
.sidebar-content {
position: absolute;
top: 0;
left: 0;
width: 80%;
max-width: 300px;
height: 100%;
background: white;
z-index: 2;
box-shadow: 2px 0 15px rgba(0,0,0,0.15);
display: flex;
flex-direction: column;
animation: slideIn 0.25s ease-out;
}
@keyframes slideIn {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
.sidebar-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1.2rem 1rem;
background: linear-gradient(135deg, #ff3e68 0%, #ff5252 100%);
color: white;
}
.close-sidebar-btn {
background: none;
border: none;
color: white;
font-size: 1.2rem;
padding: 0.3rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
width: 32px;
height: 32px;
}
.close-sidebar-btn:hover {
background-color: rgba(255, 255, 255, 0.2);
}
.admin-sidebar-mobile nav {
display: flex;
flex-direction: column;
flex: 1;
padding: 0.5rem 0;
}
.admin-sidebar-mobile a {
padding: 1rem 1.5rem;
color: #444;
text-decoration: none;
display: flex;
align-items: center;
gap: 0.75rem;
transition: all 0.2s ease;
}
.admin-sidebar-mobile a i {
font-size: 1.2rem;
}
.admin-sidebar-mobile a.active {
background-color: rgba(255, 62, 104, 0.1);
color: #ff3e68;
font-weight: 500;
}
.mobile-logout-container {
margin-top: auto;
padding: 1rem 1.5rem;
border-top: 1px solid rgba(0,0,0,0.05);
}
.mobile-logout-btn {
display: flex;
align-items: center;
gap: 0.75rem;
width: 100%;
padding: 0.85rem;
background-color: rgba(255, 62, 104, 0.08);
color: #ff3e68;
border: 1px solid rgba(255, 62, 104, 0.2);
border-radius: 8px;
font-weight: 500;
cursor: pointer;
text-align: left;
transition: all 0.2s ease;
}
.mobile-logout-btn:hover {
background-color: rgba(255, 62, 104, 0.12);
}
.admin-main-content { .admin-main-content {
flex: 1; flex: 1;
padding: 1.5rem; padding: 1.5rem;

View File

@ -319,63 +319,143 @@ h2::before {
font-size: 0.9rem; font-size: 0.9rem;
} }
/* Стили для блока распределения по полу */
.gender-distribution { .gender-distribution {
display: flex; margin-top: 2rem;
gap: 1rem; background-color: white;
flex-wrap: wrap; border-radius: 12px;
margin-top: 1rem; box-shadow: 0 2px 8px rgba(0,0,0,0.08);
padding: 1.5rem;
border: 1px solid #f1f3f5;
} }
.gender-card { .gender-distribution h4 {
flex: 1; margin: 0 0 1.5rem 0;
min-width: 150px; color: #333;
padding: 1rem; 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 {
display: flex;
flex-direction: column;
gap: 1rem;
}
/* Горизонтальная диаграмма-полоса */
.gender-bar {
display: flex;
height: 40px;
border-radius: 20px;
overflow: hidden;
background-color: #f8f9fa;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.05);
position: relative;
}
.gender-male,
.gender-female,
.gender-other {
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: 600;
font-size: 0.85rem;
text-shadow: 0 1px 2px rgba(0,0,0,0.3);
transition: all 0.3s ease;
min-width: 0;
position: relative;
}
.gender-male {
background: linear-gradient(135deg, #2196f3, #1976d2);
}
.gender-female {
background: linear-gradient(135deg, #e91e63, #c2185b);
}
.gender-other {
background: linear-gradient(135deg, #9c27b0, #7b1fa2);
}
.gender-male span,
.gender-female span,
.gender-other span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0 8px;
}
/* Анимация при наведении */
.gender-bar:hover .gender-male,
.gender-bar:hover .gender-female,
.gender-bar:hover .gender-other {
filter: brightness(1.1);
}
/* Легенда */
.gender-legend {
display: flex;
flex-wrap: wrap;
gap: 1rem;
margin-top: 1rem;
justify-content: center;
}
.legend-item {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 0.75rem;
background-color: #f8f9fa; background-color: #f8f9fa;
border-radius: 8px; border-radius: 8px;
text-align: center;
border-left: 3px solid transparent;
transition: all 0.2s ease; transition: all 0.2s ease;
border: 1px solid transparent;
} }
.gender-card:hover { .legend-item:hover {
background-color: white; background-color: white;
box-shadow: 0 2px 8px rgba(0,0,0,0.05); border-color: #e9ecef;
transform: translateY(-2px); box-shadow: 0 2px 4px rgba(0,0,0,0.05);
transform: translateY(-1px);
} }
.gender-card.male { .legend-color {
border-color: #2196f3; width: 16px;
height: 16px;
border-radius: 4px;
flex-shrink: 0;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
} }
.gender-card.female { .legend-color.male {
border-color: #e91e63; background: linear-gradient(135deg, #2196f3, #1976d2);
} }
.gender-card.other { .legend-color.female {
border-color: #9c27b0; background: linear-gradient(135deg, #e91e63, #c2185b);
} }
.gender-value { .legend-color.other {
font-size: 1.5rem; background: linear-gradient(135deg, #9c27b0, #7b1fa2);
font-weight: bold;
margin-bottom: 0.25rem;
} }
.gender-card.male .gender-value { .legend-label {
color: #2196f3;
}
.gender-card.female .gender-value {
color: #e91e63;
}
.gender-card.other .gender-value {
color: #9c27b0;
}
.gender-label {
color: #777;
font-size: 0.9rem; font-size: 0.9rem;
color: #555;
font-weight: 500;
white-space: nowrap;
} }
.averages-section { .averages-section {
@ -454,8 +534,22 @@ h2::before {
font-size: 1.8rem; font-size: 1.8rem;
} }
.gender-value { .gender-bar {
font-size: 1.3rem; height: 35px;
}
.gender-male,
.gender-female,
.gender-other {
font-size: 0.8rem;
}
.gender-distribution {
padding: 1rem;
}
.legend-label {
font-size: 0.85rem;
} }
h2 { h2 {
@ -490,11 +584,29 @@ h2::before {
} }
.gender-distribution { .gender-distribution {
flex-direction: column; padding: 1rem;
margin-top: 1.5rem;
} }
.gender-card { .gender-bar {
min-width: auto; height: 30px;
}
.gender-male,
.gender-female,
.gender-other {
font-size: 0.75rem;
}
.gender-legend {
flex-direction: column;
gap: 0.75rem;
align-items: center;
}
.legend-item {
justify-content: center;
min-width: 120px;
} }
h2 { h2 {