From d3b1cd75a0f5eb0503598feb35982ec7403fccca Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Sun, 17 May 2026 15:25:34 +0300 Subject: [PATCH] =?UTF-8?q?feat(dashboard):=20teacher=20view=20polish=20?= =?UTF-8?q?=E2=80=94=20chips,=20bars,=20KPIs,=20groups,=20mobile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit P0 visual polish: - adm-actions: grouped layout (teaching/content/admin) with 3-col grid at wide, responsive - thick 8px colored progress bars (green ≥75 / amber 50-74 / pink <50) - session % rendered as colored chip (tinted bg + border) - hover state on .adm-sess-row and .asgn-row in admin-grid - empty states with Lucide icon + CTA button (inbox/users/clock) - class-name badge on assignment row (disambiguates duplicates) - relative timestamp on session rows via relativeAgo() - search input above assignment list (filterAdminAssignments()) - adm-act-icon bumped 16px → 20px; card hover: scale + shadow P1 header KPIs + urgency: - dh-kpi-row: classes / students / active-asgn / pending chips under greeting - isTeacherUrgent(): assignments within 48h get pink border + срочно badge - adm-act-badge: count badge on Мои классы and Работы cards - loadTeacherKPIs() fetches /api/classes + teacherAssignments() in parallel P2 grouping + mobile + micro: - chevron-right icons on Все/Все классы section links - mobile ≤640: single-column groups, KPI chips wrap, sess-rows wrap - mobile ≤480: adm-act-group single column - dark mode rules for new elements Co-Authored-By: Claude Sonnet 4.6 --- frontend/dashboard.html | 303 ++++++++++++++++++++++++++++++++++------ 1 file changed, 260 insertions(+), 43 deletions(-) diff --git a/frontend/dashboard.html b/frontend/dashboard.html index 0e81729..c90ac63 100644 --- a/frontend/dashboard.html +++ b/frontend/dashboard.html @@ -418,22 +418,31 @@ .admin-grid .widget { padding: 18px; border-radius: 16px; } .admin-grid .w-head { margin-bottom: 10px; } - /* Quick-action buttons grid */ - .adm-actions { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; } + /* Quick-action buttons grid — grouped layout */ + .adm-actions { display: grid; grid-template-columns: 2fr 2fr 1fr; gap: 16px; } + .adm-act-group { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; } + @media (max-width: 900px) { .adm-actions { grid-template-columns: 1fr 1fr; } } + @media (max-width: 640px) { .adm-actions { grid-template-columns: 1fr; } } .adm-act { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-radius: 12px; border: 1.5px solid rgba(15,23,42,0.07); background: #fff; font-family: 'Manrope', sans-serif; font-size: 0.8rem; font-weight: 700; - color: #0F172A; cursor: pointer; transition: all 0.15s; - text-decoration: none; + color: #0F172A; cursor: pointer; transition: all 0.18s; + text-decoration: none; position: relative; } - .adm-act:hover { border-color: rgba(155,93,229,0.25); transform: translateY(-1px); box-shadow: 0 4px 16px rgba(15,23,42,0.08); } + .adm-act:hover { border-color: rgba(155,93,229,0.25); transform: translateY(-2px) scale(1.01); box-shadow: 0 6px 20px rgba(15,23,42,0.10); } .adm-act-icon { - width: 32px; height: 32px; border-radius: 8px; + width: 36px; height: 36px; border-radius: 9px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; } - .adm-act-icon svg, .adm-act-icon i { width: 16px; height: 16px; stroke: #fff; stroke-width: 2; } + .adm-act-icon svg, .adm-act-icon i { width: 20px; height: 20px; stroke: #fff; stroke-width: 2; } + .adm-act-badge { + position: absolute; top: 6px; right: 8px; + background: #E0335E; color: #fff; font-size: 0.62rem; font-weight: 800; + padding: 1px 5px; border-radius: 999px; font-family: 'Unbounded', sans-serif; + line-height: 1.4; + } /* Compact stat chips row for admin header */ .adm-stat-chips { display: flex; gap: 10px; flex-shrink: 0; flex-wrap: wrap; } @@ -468,11 +477,67 @@ .adm-sess-name { flex: 1; font-weight: 600; color: #0F172A; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .adm-sess-subj { color: var(--text-3); font-weight: 600; min-width: 60px; } .adm-sess-pct { font-family: 'Unbounded', sans-serif; font-weight: 900; font-size: 0.74rem; min-width: 36px; text-align: right; } + /* Colored chip for session % */ + .adm-sess-chip { + display: inline-flex; padding: 3px 9px; border-radius: 999px; + font-size: 0.74rem; font-weight: 700; min-width: 42px; justify-content: center; + font-family: 'Unbounded', sans-serif; + } + .adm-sess-ago { color: var(--text-3); font-size: 0.7rem; flex-shrink: 0; } + /* Hover on rows in admin-grid */ + .admin-grid .adm-sess-row:hover, + .admin-grid .asgn-row:hover { + background: rgba(155,93,229,0.04); + cursor: pointer; + } + /* Thick colored progress bar */ + .admin-grid .ar-prog-bar { height: 8px !important; border-radius: 4px; overflow: hidden; background: rgba(15,23,42,0.06); } + .admin-grid .ar-prog-fill { height: 100%; border-radius: 4px; } + /* Empty states */ + .adm-empty { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 24px 12px; text-align: center; color: var(--text-3); } + .adm-empty i { display: block; } + .adm-empty-text { font-size: 0.82rem; } + .adm-empty-cta { + display: inline-flex; align-items: center; gap: 6px; + padding: 7px 16px; border-radius: 9px; font-size: 0.78rem; font-weight: 700; + background: var(--violet); color: #fff; text-decoration: none; + transition: opacity 0.15s; + } + .adm-empty-cta:hover { opacity: 0.85; } + /* Class badge on assignment row */ + .asgn-class-badge { + display: inline-flex; padding: 1px 6px; border-radius: 6px; + font-size: 0.68rem; font-weight: 700; + background: rgba(155,93,229,0.08); color: #7c3aed; + margin-left: 4px; vertical-align: middle; + } + /* Urgency highlight */ + .admin-grid .asgn-urgent { border-left: 3px solid var(--pink, #F15BB5); padding-left: 9px !important; } + .asgn-fire { + background: rgba(241,91,181,0.12); color: var(--pink, #F15BB5); + padding: 1px 7px; border-radius: 999px; font-size: 0.68rem; font-weight: 700; margin-left: 6px; + } + /* KPI row */ + .dh-kpi-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 6px; } + .dh-kpi { font-size: 0.84rem; color: var(--text-3); } + .dh-kpi strong { color: var(--text); font-weight: 700; } + .dh-kpi.warn strong { color: var(--amber, #F59E0B); } + /* Admin assignment search */ + .adm-asgn-search { + width: 100%; padding: 7px 10px; border: 1px solid var(--border); + border-radius: 8px; font: inherit; font-size: 0.82rem; + margin-bottom: 10px; background: var(--bg, #fff); color: var(--text); + box-sizing: border-box; + } + .adm-asgn-search:focus { outline: none; border-color: var(--violet); } /* Dark mode for admin */ .app-layout.dark .adm-act { background: #1A1D27; border-color: rgba(255,255,255,0.06); color: #E8ECF2; } .app-layout.dark .adm-stat-chip { background: rgba(255,255,255,0.04); border-color: rgba(255,255,255,0.06); } .app-layout.dark .adm-sess-name { color: #E8ECF2; } + .app-layout.dark .adm-asgn-search { background: #1A1D27; color: #E8ECF2; border-color: rgba(255,255,255,0.1); } + .app-layout.dark .adm-empty-text { color: var(--text-3); } + .app-layout.dark .asgn-class-badge { background: rgba(155,93,229,0.15); color: #b07de0; } /* C1: Teacher class summary widget */ .class-summary { display: flex; flex-direction: column; gap: 12px; } @@ -1079,7 +1144,15 @@ .main-grid { grid-template-columns: 1fr; } .action-cards { grid-template-columns: 1fr; } .admin-grid { grid-template-columns: 1fr; gap: 14px; } - .adm-actions { grid-template-columns: repeat(2, 1fr); } + .adm-actions { grid-template-columns: 1fr; gap: 10px; } + .adm-act-group { grid-template-columns: 1fr 1fr; } + /* KPI chips wrap to 2 cols */ + .dh-kpi-row { gap: 8px; } + /* Session rows: wrap on small screens */ + .adm-sess-row { flex-wrap: wrap; } + .adm-sess-subj { min-width: unset; } + /* Assignment title: allow wrapping */ + .admin-grid .ar-title { white-space: normal; } .theory-courses-grid { grid-template-columns: 1fr; } .subj-charts-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); } @@ -1152,8 +1225,9 @@ .stat-ring { min-width: 60px; } .dh-greeting { font-size: 0.82rem; } - /* Admin quick actions: stay 2 columns (narrow enough) */ + /* Admin quick actions: narrow */ .adm-actions { gap: 8px; } + .adm-act-group { grid-template-columns: 1fr; } .adm-act { padding: 10px 10px; font-size: 0.76rem; gap: 8px; } /* Assignment rows tighter */ @@ -1213,6 +1287,12 @@
Привет,
Выбери тест и начни
+