diff --git a/app/assets/stylesheets/admin_timeline.css b/app/assets/stylesheets/admin_timeline.css index 76c44fa..1d5ddf0 100644 --- a/app/assets/stylesheets/admin_timeline.css +++ b/app/assets/stylesheets/admin_timeline.css @@ -136,4 +136,113 @@ background-color: #1F2937; /* Match page background to make it appear to "cut through" */ padding: 0 0.2rem; white-space: nowrap; -} \ No newline at end of file +} + +.user-trust-red { + background-color: rgba(239, 68, 68, 0.15) !important; + border-left: 3px solid rgb(239, 68, 68) !important; +} + +.user-trust-green { + background-color: rgba(16, 185, 129, 0.15) !important; + border-left: 3px solid rgb(16, 185, 129) !important; +} + +.user-trust-yellow { + background-color: rgba(245, 158, 11, 0.15) !important; + border-left: 3px solid rgb(245, 158, 11) !important; +} + +.user-trust-blue { + background-color: rgba(59, 130, 246, 0.1) !important; + border-left: 3px solid rgb(59, 130, 246) !important; +} + +.user-trust-indicator { + display: inline-block; + margin-left: 4px; + font-size: 0.875rem; +} + +.conviction-hammer { + cursor: pointer; + margin-left: 6px; + padding: 2px 4px; + border-radius: 4px; + transition: background-color 0.2s; +} + +.conviction-hammer:hover { + background-color: rgba(255, 255, 255, 0.1); +} + +.cm { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.cm-content { + background-color: #1F2937; + border-radius: 8px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + width: 90%; + max-width: 500px; +} + +.cm-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px; + border-bottom: 1px solid #374151; +} + +.cm-header h3 { + margin: 0; + color: #F3F4F6; + font-size: 1.25rem; +} + +.cm-close { + background: none; + border: none; + color: #9CA3AF; + font-size: 1.5rem; + cursor: pointer; +} + +.cm-body { + padding: 16px; + color: #D1D5DB; +} + +.cos { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 12px; + margin-top: 16px; +} + +.co { + background-color: #2D3748; + border: 1px solid #4B5563; + border-radius: 6px; + padding: 12px; + color: #E5E7EB; + font-size: 0.875rem; + cursor: pointer; + transition: background-color 0.2s; + text-align: center; +} + +.co:hover { + background-color: #374151; +} \ No newline at end of file diff --git a/app/javascript/controllers/user_conviction_controller.js b/app/javascript/controllers/user_conviction_controller.js index cf30891..7ec69ae 100644 --- a/app/javascript/controllers/user_conviction_controller.js +++ b/app/javascript/controllers/user_conviction_controller.js @@ -21,12 +21,15 @@ export default class extends Controller { - + @@ -68,12 +71,14 @@ export default class extends Controller { if (resp.ok) { const cell = document.querySelector(`.admin-timeline-user-header-cell[data-user-id="${userId}"]`); if (cell) { - cell.classList.remove('user-trust-red', 'user-trust-green'); + cell.classList.remove('user-trust-red', 'user-trust-green', 'user-trust-yellow'); if (level === 'red') { cell.classList.add('user-trust-red'); } else if (level === 'green') { cell.classList.add('user-trust-green'); + } else if (level === 'yellow') { + cell.classList.add('user-trust-yellow'); } const indicator = cell.querySelector('.user-trust-indicator'); @@ -84,8 +89,13 @@ export default class extends Controller { } else if (level === 'green') { indicator.textContent = '🟢'; indicator.title = 'Trusted'; + } else if (level === 'yellow') { + // For suspected users, show indicator only in admin UI + indicator.textContent = '🟡'; + indicator.title = 'Suspected (Hidden from user)'; } else { - indicator.textContent = ''; + // Blue/unscored + indicator.textContent = '🔵'; indicator.title = 'Unscored'; } } diff --git a/app/models/user.rb b/app/models/user.rb index 0a9875f..1ac07b6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -21,12 +21,11 @@ class User < ApplicationRecord end enum :trust_level, { - yellow: 0, - red: 1, - green: 2 + blue: 0, # unscored + red: 1, # convicted + green: 2, # trusted + yellow: 3 # suspected (invisible to user) } - # yellow is unscored, red being convicted while green being trusted - # labels make it easier for display :okay-1: def set_trust(level) update!(trust_level: level) @@ -422,10 +421,18 @@ class User < ApplicationRecord "https://github.com/#{github_username}" if github_username.present? end + # Returns users that are not convicted (red) + # For public APIs - includes blue, green, and yellow (suspected) users def self.not_convicted where.not(trust_level: User.trust_levels[:red]) end + # Returns only unscored (blue) and trusted (green) users + # Excludes suspected (yellow) and convicted (red) users + def self.not_suspect + where(trust_level: [ User.trust_levels[:blue], User.trust_levels[:green] ]) + end + private def invalidate_activity_graph_cache diff --git a/app/views/admin/timeline/show.html.erb b/app/views/admin/timeline/show.html.erb index 62cc49c..32b16e4 100644 --- a/app/views/admin/timeline/show.html.erb +++ b/app/views/admin/timeline/show.html.erb @@ -145,6 +145,8 @@ trust_level_class = "user-trust-red" when "green" trust_level_class = "user-trust-green" + when "yellow" + trust_level_class = "user-trust-yellow" end end %> @@ -170,9 +172,18 @@ style="font-size: 0.7rem; color: #9CA3AF; text-decoration: none;" title="Set trust level">🔨 <% end %> - <% if user.respond_to?(:trust_level) && user.trust_level != "yellow" %> + <% if user.respond_to?(:trust_level) %> - <%= user.trust_level == "red" ? "🔴" : "🟢" %> + <% case user.trust_level %> + <% when "red" %> + 🔴 + <% when "green" %> + 🟢 + <% when "yellow" %> + � + <% when "blue" %> + 🔵 + <% end %> <% else %> @@ -418,6 +429,11 @@ border-left: 3px solid #10B981; } + .user-trust-yellow { + background-color: rgba(245, 158, 11, 0.08); + border-left: 3px solid #F59E0B; + } + .user-trust-indicator { font-size: 0.75rem; margin-left: 0.25rem; diff --git a/docs/api/endpoints.md b/docs/api/endpoints.md index e9d0f7a..126a3fc 100644 --- a/docs/api/endpoints.md +++ b/docs/api/endpoints.md @@ -111,12 +111,6 @@ Get a user's trust factor. } ``` -Trust levels can be: - -- `yellow` (0): unscored -- `red` (1): convicted/untrusted -- `green` (2): trusted - ## Try These Examples ### See Your Recent Activity