diff --git a/static/css/style.css b/static/css/style.css index 6a0a1fde..0753abad 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3484,7 +3484,242 @@ html[dir='rtl'] .fa-sign-out-alt { } /* ============================================================================ - Upload Progress Toast + Notification Bell + ============================================================================ */ +.notif-wrapper { + position: relative; +} + +.notif-bell-btn { + background: none; + border: none; + cursor: pointer; + font-size: 18px; + color: #64748b; + width: 40px; + height: 40px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s ease; + position: relative; +} +.notif-bell-btn:hover { + background: rgba(255, 94, 58, 0.08); + color: #ff5e3a; +} +.notif-bell-btn.active { + color: #ff5e3a; + background: rgba(255, 94, 58, 0.1); +} + +/* Badge counter on bell */ +.notif-badge { + position: absolute; + top: 4px; + right: 4px; + min-width: 16px; + height: 16px; + line-height: 16px; + border-radius: 8px; + background: #ff3b30; + color: #fff; + font-size: 10px; + font-weight: 700; + text-align: center; + padding: 0 4px; + pointer-events: none; +} + +/* Animated wiggle for new notifications */ +@keyframes bellRing { + 0%, 100% { transform: rotate(0deg); } + 15% { transform: rotate(14deg); } + 30% { transform: rotate(-14deg); } + 45% { transform: rotate(8deg); } + 60% { transform: rotate(-8deg); } + 75% { transform: rotate(3deg); } +} +.notif-bell-btn.ring i { + animation: bellRing 0.6s ease; +} + +/* Dropdown panel */ +.notif-panel { + display: none; + position: absolute; + top: calc(100% + 10px); + right: -40px; + width: 380px; + max-height: 480px; + background: #fff; + border-radius: 16px; + box-shadow: 0 12px 40px rgba(0,0,0,0.15), 0 0 0 1px rgba(0,0,0,0.05); + z-index: 2000; + overflow: hidden; + animation: notifPanelIn 0.2s ease-out; +} +.notif-wrapper.open .notif-panel { + display: flex; + flex-direction: column; +} + +@keyframes notifPanelIn { + from { opacity: 0; transform: translateY(-8px) scale(0.97); } + to { opacity: 1; transform: translateY(0) scale(1); } +} + +.notif-panel-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 14px 16px; + border-bottom: 1px solid #f0f0f0; +} +.notif-panel-title { + font-weight: 600; + font-size: 15px; + color: #1e293b; +} +.notif-clear-btn { + background: none; + border: none; + cursor: pointer; + color: #94a3b8; + font-size: 14px; + padding: 4px 8px; + border-radius: 6px; + transition: all 0.15s; +} +.notif-clear-btn:hover { + color: #ff5e3a; + background: rgba(255, 94, 58, 0.08); +} + +.notif-panel-body { + flex: 1; + overflow-y: auto; + max-height: 400px; +} +.notif-empty { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 40px 20px; + color: #94a3b8; + gap: 8px; +} +.notif-empty i { + font-size: 28px; + opacity: 0.5; +} +.notif-empty span { + font-size: 14px; +} + +/* Individual notification items */ +.notif-item { + display: flex; + align-items: flex-start; + padding: 12px 16px; + gap: 12px; + border-bottom: 1px solid #f5f5f5; + transition: background 0.15s; + cursor: default; +} +.notif-item:last-child { + border-bottom: none; +} +.notif-item:hover { + background: #f8fafc; +} +.notif-item-icon { + width: 32px; + height: 32px; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + font-size: 14px; +} +.notif-item-icon.upload { + background: rgba(255, 94, 58, 0.1); + color: #ff5e3a; +} +.notif-item-icon.success { + background: rgba(52, 199, 89, 0.1); + color: #34c759; +} +.notif-item-icon.error { + background: rgba(255, 59, 48, 0.1); + color: #ff3b30; +} +.notif-item-body { + flex: 1; + min-width: 0; +} +.notif-item-title { + font-size: 13px; + font-weight: 600; + color: #1e293b; + margin-bottom: 2px; +} +.notif-item-text { + font-size: 12px; + color: #64748b; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.notif-item-time { + font-size: 11px; + color: #94a3b8; + margin-top: 3px; +} + +/* Upload progress inside notification */ +.notif-upload-progress { + margin-top: 6px; +} +.notif-upload-bar { + height: 3px; + background: #eee; + border-radius: 2px; + overflow: hidden; +} +.notif-upload-fill { + height: 100%; + background: #ff5e3a; + width: 0%; + transition: width 0.2s ease; + border-radius: 2px; +} +.notif-upload-fill.done { + background: #34c759; +} +.notif-upload-fill.error { + background: #ff3b30; +} +.notif-upload-detail { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 3px; +} +.notif-upload-pct { + font-size: 11px; + color: #94a3b8; +} +.notif-upload-stats { + font-size: 11px; + color: #94a3b8; +} + +/* ============================================================================ + Upload Progress Toast (legacy — hidden, kept for compat) ============================================================================ */ .upload-toast { position: fixed; @@ -4175,6 +4410,51 @@ html[dir='rtl'] .fa-sign-out-alt { border-top-color: #334155; } +/* Notification bell */ +[data-theme="dark"] .notif-bell-btn { + color: #94a3b8; +} +[data-theme="dark"] .notif-bell-btn:hover, +[data-theme="dark"] .notif-bell-btn.active { + color: #ff5e3a; + background: rgba(255, 94, 58, 0.15); +} +[data-theme="dark"] .notif-panel { + background: #1e293b; + box-shadow: 0 12px 40px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.06); +} +[data-theme="dark"] .notif-panel-header { + border-bottom-color: #334155; +} +[data-theme="dark"] .notif-panel-title { + color: #f1f5f9; +} +[data-theme="dark"] .notif-clear-btn { + color: #64748b; +} +[data-theme="dark"] .notif-clear-btn:hover { + color: #ff5e3a; + background: rgba(255, 94, 58, 0.12); +} +[data-theme="dark"] .notif-empty { + color: #64748b; +} +[data-theme="dark"] .notif-item { + border-bottom-color: #1a2536; +} +[data-theme="dark"] .notif-item:hover { + background: #162032; +} +[data-theme="dark"] .notif-item-title { + color: #e2e8f0; +} +[data-theme="dark"] .notif-item-text { + color: #94a3b8; +} +[data-theme="dark"] .notif-upload-bar { + background: #334155; +} + /* Dropzone */ [data-theme="dark"] .dropzone { border-color: #475569; diff --git a/static/index.html b/static/index.html index 389785a9..fe5430d2 100644 --- a/static/index.html +++ b/static/index.html @@ -19,6 +19,7 @@ + @@ -105,6 +106,29 @@