Skip to content

Vote Rewards: 2-col tab layout + dedup (supersedes #52)#53

Merged
AdaInTheLab merged 2 commits into
mainfrom
fix/vote-rewards-layout
Apr 30, 2026
Merged

Vote Rewards: 2-col tab layout + dedup (supersedes #52)#53
AdaInTheLab merged 2 commits into
mainfrom
fix/vote-rewards-layout

Conversation

@AdaInTheLab
Copy link
Copy Markdown
Collaborator

Summary

Two changes bundled. Supersedes #52 — close that one, merge this instead.

1. 2-col tab layout (the new bit)

Vote Rewards tab was rendering everything in a single column on the left half of the screen, leaving a huge empty area on the right. Mirrored the Discord tab pattern:

  • Left col (3fr): master toggle card + provider config card + Save Settings button
  • Right col (2fr): audit feed

Picked 3:2 instead of 1:1 because the provider config card has more density (its own 2-col grid inside) and the audit table is naturally narrower. Collapses to single col at <=1100px (earlier than the 768px tablet breakpoint) since the split gets cramped on smaller laptops before mobile.

2. Dedupe provider list on load (carried from #52)

PR #50 prevented new duplicates forming, but admins whose state was already poisoned still carry the doubled list in their persisted JSON. `EnsureDefaultProviders` now dedups by Key with a configured-priority tiebreaker (`enabled+apiKey > enabled > apiKey > anything`). Logs once when it dropped any rows. Self-heals on the next boot. The Vue `:key` is also `${provider.key}-${idx}` now as defense in depth.

(Already verified working on Ada's WSL test box — boot log:
`VoteRewards: deduped 1 duplicate provider entry/entries on load.`)

Files

File What
`Features/VoteRewardsFeature.cs` dedup logic in `EnsureDefaultProviders`
`frontend/src/views/SettingsView.vue` tab grid, `:key=${provider.key}-${idx}`, `.vote-rewards-grid` CSS

Test plan

  • Pull, build, deploy
  • Hard-refresh panel
  • Vote Rewards tab: configuration on the left, audit feed on the right
  • Resize the window narrower → at ~1100px the audit drops below the config
  • One provider block visible (not two)
  • Server log shows `providers configured=1, enabled=1`
  • `/vote` chat command prints exactly one provider line

🤖 Generated with Claude Code

AdaInTheLab and others added 2 commits April 30, 2026 12:48
PR #50 prevented new duplicates forming (the Newtonsoft-append bug),
but admins whose state was poisoned while that bug was active still
carry the doubled list in their persisted JSON. Symptoms after loading:

- /vote prints "<key>: provider disabled" + "<displayname>: granted ..."
  side by side because the foreach iterates both entries
- Settings tab shows two provider blocks; Vue's v-for warns about
  duplicate :key values and the diffing reconciles unpredictably

Two-part fix:

1. EnsureDefaultProviders now deduplicates by Key on every load. The
   entry with the strongest "configured" signal wins (enabled+apiKey >
   enabled > apiKey > anything else), so a real config never gets
   displaced by an empty stub. Logs a one-line note when it dropped
   any rows so admins can see it ran.

2. SettingsView.vue's v-for key is now `${provider.key}-${idx}` so
   duplicate provider keys can't collide in Vue's diffing. Defense in
   depth — the backend dedup means duplicates shouldn't reach the UI
   anymore, but the v-for shouldn't be the thing that breaks if they do.

Self-heals existing poisoned state on the next server boot.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Vote Rewards tab was rendering everything in a single column inside
the left half of the available width — large empty space sat to the
right. Mirrors the Discord tab pattern: a 2-col grid at the tab level,
with the configuration cards (master toggle, providers, save) on the
left and the audit feed on the right.

Grid is 3fr / 2fr because the provider config card is wider than the
audit table needs. Collapses to single column at <=1100px (earlier than
the 768px tablet breakpoint) since the 3:2 split gets cramped on
narrow-desktop screens before mobile.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@AdaInTheLab AdaInTheLab merged commit 0f7a863 into main Apr 30, 2026
2 checks passed
@AdaInTheLab AdaInTheLab deleted the fix/vote-rewards-layout branch April 30, 2026 16:58
@AdaInTheLab AdaInTheLab mentioned this pull request Apr 30, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant