diff --git a/frontend/src/assets/icons/alarm.svg b/frontend/src/assets/icons/alarm.svg
new file mode 100644
index 0000000..89f98f8
--- /dev/null
+++ b/frontend/src/assets/icons/alarm.svg
@@ -0,0 +1,22 @@
+
+
diff --git a/frontend/src/assets/icons/alert-triangle.svg b/frontend/src/assets/icons/alert-triangle.svg
new file mode 100644
index 0000000..8d9332e
--- /dev/null
+++ b/frontend/src/assets/icons/alert-triangle.svg
@@ -0,0 +1,21 @@
+
+
diff --git a/frontend/src/assets/icons/bell.svg b/frontend/src/assets/icons/bell.svg
new file mode 100644
index 0000000..fdf276b
--- /dev/null
+++ b/frontend/src/assets/icons/bell.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/frontend/src/assets/icons/book-2.svg b/frontend/src/assets/icons/book-2.svg
new file mode 100644
index 0000000..d3464f1
--- /dev/null
+++ b/frontend/src/assets/icons/book-2.svg
@@ -0,0 +1,21 @@
+
+
diff --git a/frontend/src/assets/icons/books.svg b/frontend/src/assets/icons/books.svg
new file mode 100644
index 0000000..13f40f8
--- /dev/null
+++ b/frontend/src/assets/icons/books.svg
@@ -0,0 +1,25 @@
+
+
diff --git a/frontend/src/assets/icons/building.svg b/frontend/src/assets/icons/building.svg
new file mode 100644
index 0000000..7f85a63
--- /dev/null
+++ b/frontend/src/assets/icons/building.svg
@@ -0,0 +1,26 @@
+
+
diff --git a/frontend/src/assets/icons/bulb.svg b/frontend/src/assets/icons/bulb.svg
new file mode 100644
index 0000000..b6577b3
--- /dev/null
+++ b/frontend/src/assets/icons/bulb.svg
@@ -0,0 +1,21 @@
+
+
diff --git a/frontend/src/assets/icons/calendar-event.svg b/frontend/src/assets/icons/calendar-event.svg
new file mode 100644
index 0000000..d3b85c2
--- /dev/null
+++ b/frontend/src/assets/icons/calendar-event.svg
@@ -0,0 +1,23 @@
+
+
diff --git a/frontend/src/assets/icons/calendar.svg b/frontend/src/assets/icons/calendar.svg
new file mode 100644
index 0000000..20d6753
--- /dev/null
+++ b/frontend/src/assets/icons/calendar.svg
@@ -0,0 +1,24 @@
+
+
diff --git a/frontend/src/assets/icons/chart-bar.svg b/frontend/src/assets/icons/chart-bar.svg
new file mode 100644
index 0000000..0e55695
--- /dev/null
+++ b/frontend/src/assets/icons/chart-bar.svg
@@ -0,0 +1,22 @@
+
+
diff --git a/frontend/src/assets/icons/chart-line.svg b/frontend/src/assets/icons/chart-line.svg
new file mode 100644
index 0000000..97a4c02
--- /dev/null
+++ b/frontend/src/assets/icons/chart-line.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/frontend/src/assets/icons/circle-check.svg b/frontend/src/assets/icons/circle-check.svg
new file mode 100644
index 0000000..73eb6ae
--- /dev/null
+++ b/frontend/src/assets/icons/circle-check.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/frontend/src/assets/icons/circle-x.svg b/frontend/src/assets/icons/circle-x.svg
new file mode 100644
index 0000000..c0bba84
--- /dev/null
+++ b/frontend/src/assets/icons/circle-x.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/frontend/src/assets/icons/clipboard-list.svg b/frontend/src/assets/icons/clipboard-list.svg
new file mode 100644
index 0000000..654a4c5
--- /dev/null
+++ b/frontend/src/assets/icons/clipboard-list.svg
@@ -0,0 +1,24 @@
+
+
diff --git a/frontend/src/assets/icons/clock.svg b/frontend/src/assets/icons/clock.svg
new file mode 100644
index 0000000..e4814fa
--- /dev/null
+++ b/frontend/src/assets/icons/clock.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/frontend/src/assets/icons/coin.svg b/frontend/src/assets/icons/coin.svg
new file mode 100644
index 0000000..b546a3b
--- /dev/null
+++ b/frontend/src/assets/icons/coin.svg
@@ -0,0 +1,21 @@
+
+
diff --git a/frontend/src/assets/icons/hand-stop.svg b/frontend/src/assets/icons/hand-stop.svg
new file mode 100644
index 0000000..2c46e10
--- /dev/null
+++ b/frontend/src/assets/icons/hand-stop.svg
@@ -0,0 +1,22 @@
+
+
diff --git a/frontend/src/assets/icons/home.svg b/frontend/src/assets/icons/home.svg
new file mode 100644
index 0000000..d5fa9e3
--- /dev/null
+++ b/frontend/src/assets/icons/home.svg
@@ -0,0 +1,21 @@
+
+
diff --git a/frontend/src/assets/icons/inbox.svg b/frontend/src/assets/icons/inbox.svg
new file mode 100644
index 0000000..9356470
--- /dev/null
+++ b/frontend/src/assets/icons/inbox.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/frontend/src/assets/icons/info-circle.svg b/frontend/src/assets/icons/info-circle.svg
new file mode 100644
index 0000000..c035ec3
--- /dev/null
+++ b/frontend/src/assets/icons/info-circle.svg
@@ -0,0 +1,21 @@
+
+
diff --git a/frontend/src/assets/icons/lock.svg b/frontend/src/assets/icons/lock.svg
new file mode 100644
index 0000000..984acce
--- /dev/null
+++ b/frontend/src/assets/icons/lock.svg
@@ -0,0 +1,21 @@
+
+
diff --git a/frontend/src/assets/icons/logout.svg b/frontend/src/assets/icons/logout.svg
new file mode 100644
index 0000000..50b5972
--- /dev/null
+++ b/frontend/src/assets/icons/logout.svg
@@ -0,0 +1,21 @@
+
+
diff --git a/frontend/src/assets/icons/map-pin.svg b/frontend/src/assets/icons/map-pin.svg
new file mode 100644
index 0000000..7501d8f
--- /dev/null
+++ b/frontend/src/assets/icons/map-pin.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/frontend/src/assets/icons/message-circle.svg b/frontend/src/assets/icons/message-circle.svg
new file mode 100644
index 0000000..e712c74
--- /dev/null
+++ b/frontend/src/assets/icons/message-circle.svg
@@ -0,0 +1,19 @@
+
+
diff --git a/frontend/src/assets/icons/mood-neutral.svg b/frontend/src/assets/icons/mood-neutral.svg
new file mode 100644
index 0000000..58cf5b8
--- /dev/null
+++ b/frontend/src/assets/icons/mood-neutral.svg
@@ -0,0 +1,21 @@
+
+
diff --git a/frontend/src/assets/icons/robot.svg b/frontend/src/assets/icons/robot.svg
new file mode 100644
index 0000000..cdbb7b7
--- /dev/null
+++ b/frontend/src/assets/icons/robot.svg
@@ -0,0 +1,27 @@
+
+
diff --git a/frontend/src/assets/icons/search.svg b/frontend/src/assets/icons/search.svg
new file mode 100644
index 0000000..3498a25
--- /dev/null
+++ b/frontend/src/assets/icons/search.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/frontend/src/assets/icons/shield.svg b/frontend/src/assets/icons/shield.svg
new file mode 100644
index 0000000..071513a
--- /dev/null
+++ b/frontend/src/assets/icons/shield.svg
@@ -0,0 +1,19 @@
+
+
diff --git a/frontend/src/assets/icons/sparkles.svg b/frontend/src/assets/icons/sparkles.svg
new file mode 100644
index 0000000..16d2cab
--- /dev/null
+++ b/frontend/src/assets/icons/sparkles.svg
@@ -0,0 +1,19 @@
+
+
diff --git a/frontend/src/assets/icons/star.svg b/frontend/src/assets/icons/star.svg
new file mode 100644
index 0000000..38eecdb
--- /dev/null
+++ b/frontend/src/assets/icons/star.svg
@@ -0,0 +1,19 @@
+
+
diff --git a/frontend/src/assets/icons/stopwatch.svg b/frontend/src/assets/icons/stopwatch.svg
new file mode 100644
index 0000000..9d85b90
--- /dev/null
+++ b/frontend/src/assets/icons/stopwatch.svg
@@ -0,0 +1,22 @@
+
+
diff --git a/frontend/src/assets/icons/thumb-down.svg b/frontend/src/assets/icons/thumb-down.svg
new file mode 100644
index 0000000..01a987d
--- /dev/null
+++ b/frontend/src/assets/icons/thumb-down.svg
@@ -0,0 +1,19 @@
+
+
diff --git a/frontend/src/assets/icons/thumb-up.svg b/frontend/src/assets/icons/thumb-up.svg
new file mode 100644
index 0000000..823b4eb
--- /dev/null
+++ b/frontend/src/assets/icons/thumb-up.svg
@@ -0,0 +1,19 @@
+
+
diff --git a/frontend/src/assets/icons/trophy.svg b/frontend/src/assets/icons/trophy.svg
new file mode 100644
index 0000000..6b7d40e
--- /dev/null
+++ b/frontend/src/assets/icons/trophy.svg
@@ -0,0 +1,24 @@
+
+
diff --git a/frontend/src/assets/icons/user.svg b/frontend/src/assets/icons/user.svg
new file mode 100644
index 0000000..52fc7ea
--- /dev/null
+++ b/frontend/src/assets/icons/user.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/frontend/src/assets/icons/users.svg b/frontend/src/assets/icons/users.svg
new file mode 100644
index 0000000..1eca1af
--- /dev/null
+++ b/frontend/src/assets/icons/users.svg
@@ -0,0 +1,22 @@
+
+
diff --git a/frontend/src/assets/icons/world.svg b/frontend/src/assets/icons/world.svg
new file mode 100644
index 0000000..9803590
--- /dev/null
+++ b/frontend/src/assets/icons/world.svg
@@ -0,0 +1,23 @@
+
+
diff --git a/frontend/src/components/layout/AppBottomNav.vue b/frontend/src/components/layout/AppBottomNav.vue
index 83fa441..f459b90 100644
--- a/frontend/src/components/layout/AppBottomNav.vue
+++ b/frontend/src/components/layout/AppBottomNav.vue
@@ -2,6 +2,7 @@
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
+import AppIcon from '@/components/ui/AppIcon.vue'
const auth = useAuthStore()
const route = useRoute()
@@ -9,22 +10,22 @@ const route = useRoute()
const navItems = computed(() => {
const role = auth.user?.role ?? 'student'
if (role === 'teacher') return [
- { label: 'Дашборд', icon: '📊', to: '/teacher' },
- { label: 'Лекции', icon: '📖', to: '/teacher/lectures' },
- { label: 'Аналитика',icon: '📈', to: '/teacher/analytics' },
- { label: 'Профиль', icon: '👤', to: '/profile' },
+ { label: 'Дашборд', icon: 'chart-bar', to: '/teacher' },
+ { label: 'Лекции', icon: 'book-2', to: '/teacher/lectures' },
+ { label: 'Аналитика', icon: 'chart-line', to: '/teacher/analytics' },
+ { label: 'Профиль', icon: 'user', to: '/profile' },
]
if (role === 'admin') return [
- { label: 'Дашборд', icon: '🛡️', to: '/admin' },
- { label: 'Юзеры', icon: '👥', to: '/admin/users' },
- { label: 'Лекции', icon: '📚', to: '/admin/lectures' },
- { label: 'ИИ', icon: '🤖', to: '/admin/llm-queue' },
+ { label: 'Дашборд', icon: 'shield', to: '/admin' },
+ { label: 'Юзеры', icon: 'users', to: '/admin/users' },
+ { label: 'Лекции', icon: 'books', to: '/admin/lectures' },
+ { label: 'ИИ', icon: 'robot', to: '/admin/llm-queue' },
]
return [
- { label: 'Главная', icon: '🏠', to: '/' },
- { label: 'Лекции', icon: '📚', to: '/catalog' },
- { label: 'Мои', icon: '📋', to: '/my-lectures' },
- { label: 'Профиль', icon: '👤', to: '/profile' },
+ { label: 'Главная', icon: 'home', to: '/' },
+ { label: 'Лекции', icon: 'books', to: '/catalog' },
+ { label: 'Мои', icon: 'clipboard-list', to: '/my-lectures' },
+ { label: 'Профиль', icon: 'user', to: '/profile' },
]
})
@@ -43,7 +44,7 @@ function isActive(to: string) {
class="bottom-nav-item"
:class="{ active: isActive(item.to) }"
>
- {{ item.icon }}
+
{{ item.label }}
@@ -78,7 +79,7 @@ function isActive(to: string) {
transition: color 0.2s;
}
.bottom-nav-item.active { color: var(--color-primary-dark); }
-.bottom-nav-icon { font-size: 20px; }
+.bottom-nav-icon { color: currentColor; }
.bottom-nav-label { font-size: 10px; font-weight: 600; }
@media (max-width: 768px) { .bottom-nav { display: flex; } }
diff --git a/frontend/src/components/layout/AppSidebar.vue b/frontend/src/components/layout/AppSidebar.vue
index d2ae79c..1a46111 100644
--- a/frontend/src/components/layout/AppSidebar.vue
+++ b/frontend/src/components/layout/AppSidebar.vue
@@ -2,6 +2,7 @@
import { computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
+import AppIcon from '@/components/ui/AppIcon.vue'
const auth = useAuthStore()
const router = useRouter()
@@ -10,22 +11,22 @@ const route = useRoute()
interface NavItem { label: string; icon: string; to: string; roles: string[] }
const navItems: NavItem[] = [
- { label: 'Главная', icon: '🏠', to: '/', roles: ['student'] },
- { label: 'Каталог', icon: '📚', to: '/catalog', roles: ['student'] },
- { label: 'Мои лекции', icon: '📋', to: '/my-lectures', roles: ['student'] },
- { label: 'Достижения', icon: '🏆', to: '/achievements', roles: ['student'] },
- { label: 'Уведомления', icon: '🔔', to: '/notifications', roles: ['student'] },
- { label: 'Профиль', icon: '👤', to: '/profile', roles: ['student'] },
+ { label: 'Главная', icon: 'home', to: '/', roles: ['student'] },
+ { label: 'Каталог', icon: 'books', to: '/catalog', roles: ['student'] },
+ { label: 'Мои лекции', icon: 'clipboard-list', to: '/my-lectures', roles: ['student'] },
+ { label: 'Достижения', icon: 'trophy', to: '/achievements', roles: ['student'] },
+ { label: 'Уведомления', icon: 'bell', to: '/notifications', roles: ['student'] },
+ { label: 'Профиль', icon: 'user', to: '/profile', roles: ['student'] },
// Teacher
- { label: 'Дашборд', icon: '📊', to: '/teacher', roles: ['teacher'] },
- { label: 'Лекции', icon: '📖', to: '/teacher/lectures',roles: ['teacher'] },
- { label: 'Аналитика', icon: '📈', to: '/teacher/analytics',roles: ['teacher'] },
- { label: 'Профиль', icon: '👤', to: '/profile', roles: ['teacher'] },
+ { label: 'Дашборд', icon: 'chart-bar', to: '/teacher', roles: ['teacher'] },
+ { label: 'Лекции', icon: 'book-2', to: '/teacher/lectures', roles: ['teacher'] },
+ { label: 'Аналитика', icon: 'chart-line', to: '/teacher/analytics', roles: ['teacher'] },
+ { label: 'Профиль', icon: 'user', to: '/profile', roles: ['teacher'] },
// Admin
- { label: 'Дашборд', icon: '🛡️', to: '/admin', roles: ['admin'] },
- { label: 'Пользователи',icon: '👥', to: '/admin/users', roles: ['admin'] },
- { label: 'Лекции', icon: '📚', to: '/admin/lectures', roles: ['admin'] },
- { label: 'ИИ очередь', icon: '🤖', to: '/admin/llm-queue', roles: ['admin'] },
+ { label: 'Дашборд', icon: 'shield', to: '/admin', roles: ['admin'] },
+ { label: 'Пользователи', icon: 'users', to: '/admin/users', roles: ['admin'] },
+ { label: 'Лекции', icon: 'books', to: '/admin/lectures', roles: ['admin'] },
+ { label: 'ИИ очередь', icon: 'robot', to: '/admin/llm-queue', roles: ['admin'] },
]
const visible = computed(() =>
@@ -44,18 +45,19 @@ function isActive(to: string) {
- {{ item.icon }}
+ :to="item.to"
+ class="nav-item"
+ :class="{ active: isActive(item.to) }"
+ >
+
{{ item.label }}
@@ -107,7 +109,7 @@ function isActive(to: string) {
font-weight: 700;
box-shadow: 0 2px 8px rgba(34,197,94,0.12);
}
-.nav-icon { font-size: 17px; flex-shrink: 0; }
+.nav-icon { flex-shrink: 0; color: currentColor; }
.sidebar-footer { padding: 10px 18px 8px; }
.logout-btn {
width: 100%;
@@ -124,6 +126,7 @@ function isActive(to: string) {
align-items: center;
gap: 6px;
}
+.logout-icon { color: currentColor; }
.logout-btn:hover { background: rgba(239,68,68,0.15); }
@media (max-width: 768px) { .sidebar { display: none; } }
diff --git a/frontend/src/components/layout/AppTopbar.vue b/frontend/src/components/layout/AppTopbar.vue
index 53af3d5..1b90ed8 100644
--- a/frontend/src/components/layout/AppTopbar.vue
+++ b/frontend/src/components/layout/AppTopbar.vue
@@ -5,6 +5,7 @@ import { useAuthStore } from '@/stores/auth'
import { useUserStore } from '@/stores/user'
import CoinChip from '@/components/ui/CoinChip.vue'
import SearchInput from '@/components/ui/SearchInput.vue'
+import AppIcon from '@/components/ui/AppIcon.vue'
import { formatUserName } from '@/utils/formatUserName'
const auth = useAuthStore()
@@ -35,7 +36,7 @@ function openProfile() {
@@ -51,7 +52,7 @@ function openProfile() {