forked from retoor/devplacepy
feat: add notification preference system with per-type per-channel toggles and admin defaults
Implement configurable notification preferences across in-app and push channels, including a new `notification_preferences` table with soft-delete support, per-user toggle endpoints, admin defaults management, and canonical type definitions. The change introduces `NOTIFICATION_TYPES` and `NOTIFICATION_CHANNELS` constants, `NotificationPrefForm`/`NotificationDefaultForm` models, `notification_enabled` resolution logic, and UI integration via the profile notifications tab and admin panel.
This commit is contained in:
@@ -613,3 +613,108 @@ a.profile-stat-value:hover {
|
||||
.ai-usage-table td {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.notif-prefs {
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
.notif-prefs-intro {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.notif-prefs-intro p {
|
||||
margin: 0 0 0.5rem;
|
||||
}
|
||||
|
||||
.notif-prefs-admin {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.notif-prefs-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.notif-prefs-table th,
|
||||
.notif-prefs-table td {
|
||||
padding: 0.75rem 0.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.notif-prefs-table th {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.8rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.notif-prefs-col {
|
||||
width: 5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.notif-prefs-label {
|
||||
display: block;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.notif-prefs-desc {
|
||||
display: block;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.notif-switch {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.notif-switch input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.notif-switch-track {
|
||||
position: relative;
|
||||
width: 2.4rem;
|
||||
height: 1.3rem;
|
||||
background: var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
transition: background 0.15s ease;
|
||||
}
|
||||
|
||||
.notif-switch-track::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
background: var(--bg-card);
|
||||
border-radius: 50%;
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
|
||||
.notif-switch input:checked + .notif-switch-track {
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
.notif-switch input:checked + .notif-switch-track::after {
|
||||
transform: translateX(1.1rem);
|
||||
}
|
||||
|
||||
.notif-switch input:disabled + .notif-switch-track {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.notif-prefs-actions {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user