feat(voting): 5 votes per hackathon + redesigned results podium - #41

Merged
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium
Jun 23, 2026
Merged

feat(voting): 5 votes per hackathon + redesigned results podium#41
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium

Conversation

@agustinkassis

@agustinkassisagustinkassis commented Jun 23, 2026

Copy link
Copy Markdown
Member

What

Two voting-experience changes:

1. Vote budget: 1 → 5 votes per hackathon

A voter's budget is now VOTES_PER_HACKATHON (5) per distinct hackathon they participated in (was 1). This lets voters spread their votes across several different projects instead of being forced to back a single one.

  • Added the VOTES_PER_HACKATHON constant in lib/voting.ts and applied it in buildEligibleVoters (both the new-voter and the merge-dedupe branches).
  • /api/dev/soldiers and the DEV bar 🗳 count read the same function, so they update automatically.
  • Open/closed voting copy now reads "5 votos por hackatón…" via the same constant (no string drift).

2. Redesigned closed-results hero (VotingHero)

The published-results hero now showcases up to 6 winners with their prizes:

  • Top 3 on a podium — gold/silver/bronze cards, 1st centered and larger with a "Ganador" badge.
  • Positions 4–6 as a numbered list below.
  • Each entry shows its prize (from the program's 6-slot ladder: 400k/250k/150k/100k/60k/40k) and its vote count.
  • Removed the grid/checkerboard backdrop — kept the soft glow + top accent line for a cleaner look.

Why

  • 1 vote per hackathon made every ballot all-or-nothing; 5 votes enables meaningful preference spreading across projects.
  • The old closed hero was a small 3-item side list with no prizes; the podium reads as a proper results celebration and surfaces the prize ladder.

Reviewer notes

  • prizeForPosition/formatSats are reused from lib/hackathons.ts (the program's existing prize distribution) — no new prize source.
  • The closed hero gracefully handles fewer than 6 winners (shows whatever has votes) and a 0-winner edge case.
  • Scope: this PR contains only the shippable feature work. The e2e test scaffolding used this session (a throwaway local "E2E TEST" hackathon, a retargeted dev seeder, and scripts/e2e-*.mjs helpers) was intentionally excluded so nothing test-only reaches production.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Increased voting power: Users now receive 5 votes per hackathon participated in (previously 1).
    • Enhanced results display: Winner showcase now supports up to 6 winners with improved visual hierarchy—featuring a podium for the top 3 and a runners-up section for positions 4–6, including vote counts and prize amounts where applicable.

Vote budget is now VOTES_PER_HACKATHON (5) per distinct hackathon a voter
participated in, so voters can spread their votes across several projects
instead of backing a single one. Centralized as a constant in lib/voting.ts
(buildEligibleVoters) and reused in the open/closed voting copy.
Redesigned the closed-results hero (VotingHero):
- top 3 winners on a gold/silver/bronze podium (1st centered + "Ganador"
badge), positions 4-6 as a numbered list
- each winner shows its prize (from the program's 6-slot ladder) and votes
- removed the grid/checkerboard backdrop for a cleaner look
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
lacrypta-devReadyReadyPreview, CommentJun 23, 2026 9:02pm

Request Review

@coderabbitai

coderabbitaiBot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a8b5bc7e-acaa-40cd-bb2d-469238d87094

📥 Commits

Reviewing files that changed from the base of the PR and between 9347d17 and 227a2f4.

📒 Files selected for processing (3)
  • app/hackathons/[id]/VotingSection.tsx
  • components/voting/VotingHero.tsx
  • lib/voting.ts

📝 Walkthrough

Walkthrough

Introduces VOTES_PER_HACKATHON = 5 constant in lib/voting.ts and scales maxVotes by it in buildEligibleVoters. The open-state UI copy in VotingSection and VotingHero is updated to interpolate this constant. VotingHero's closed-state results view is replaced with a podium (top 3) and runners-up (positions 4–6) layout using new PodiumCard and RunnerRow components.

Changes

Vote Budget Constant and Results UI

Layer / File(s)Summary
Vote budget constant and maxVotes computation
lib/voting.ts
Exports VOTES_PER_HACKATHON = 5; updates VotingEligibleVoter.maxVotes docs and scales maxVotes as hackathons.size * VOTES_PER_HACKATHON in both the new-entry and merge paths of buildEligibleVoters.
Open-state UI copy updated to VOTES_PER_HACKATHON
app/hackathons/[id]/VotingSection.tsx, components/voting/VotingHero.tsx
Both components import VOTES_PER_HACKATHON and interpolate it into the open-voting explanatory message, removing hardcoded "1 voto" strings.
Closed-state podium and runners-up rendering
components/voting/VotingHero.tsx
Removes hero backdrop grid overlay; adds module-level MEDAL and RANK_TONE constants; refactors ClosedHero to split winners into podium (top 3) and runnersUp (4–6); renders via new PodiumCard and RunnerRow components with formatSats prize display and links to project pages.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Five votes per hackathon, hooray!
The podium gleams in gold array,
Runners-up proudly take their place,
No more hardcoded "1" to trace.
With VOTES_PER_HACKATHON in the lead,
This bunny's happy — vote indeed! 🏆

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.50% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately and concisely summarizes both main changes: the vote budget increase (5 per hackathon) and the redesigned results podium, directly matching the PR objectives and changeset.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/voting-budget-and-results-podium

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for freeto 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

@agustinkassis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(voting): 5 votes per hackathon + redesigned results podium - #41

Merged
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium
Jun 23, 2026
Merged

feat(voting): 5 votes per hackathon + redesigned results podium#41
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium

Conversation

@agustinkassis

@agustinkassisagustinkassis commented Jun 23, 2026

Copy link
Copy Markdown
Member

What

Two voting-experience changes:

1. Vote budget: 1 → 5 votes per hackathon

A voter's budget is now VOTES_PER_HACKATHON (5) per distinct hackathon they participated in (was 1). This lets voters spread their votes across several different projects instead of being forced to back a single one.

  • Added the VOTES_PER_HACKATHON constant in lib/voting.ts and applied it in buildEligibleVoters (both the new-voter and the merge-dedupe branches).
  • /api/dev/soldiers and the DEV bar 🗳 count read the same function, so they update automatically.
  • Open/closed voting copy now reads "5 votos por hackatón…" via the same constant (no string drift).

2. Redesigned closed-results hero (VotingHero)

The published-results hero now showcases up to 6 winners with their prizes:

  • Top 3 on a podium — gold/silver/bronze cards, 1st centered and larger with a "Ganador" badge.
  • Positions 4–6 as a numbered list below.
  • Each entry shows its prize (from the program's 6-slot ladder: 400k/250k/150k/100k/60k/40k) and its vote count.
  • Removed the grid/checkerboard backdrop — kept the soft glow + top accent line for a cleaner look.

Why

  • 1 vote per hackathon made every ballot all-or-nothing; 5 votes enables meaningful preference spreading across projects.
  • The old closed hero was a small 3-item side list with no prizes; the podium reads as a proper results celebration and surfaces the prize ladder.

Reviewer notes

  • prizeForPosition/formatSats are reused from lib/hackathons.ts (the program's existing prize distribution) — no new prize source.
  • The closed hero gracefully handles fewer than 6 winners (shows whatever has votes) and a 0-winner edge case.
  • Scope: this PR contains only the shippable feature work. The e2e test scaffolding used this session (a throwaway local "E2E TEST" hackathon, a retargeted dev seeder, and scripts/e2e-*.mjs helpers) was intentionally excluded so nothing test-only reaches production.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Increased voting power: Users now receive 5 votes per hackathon participated in (previously 1).
    • Enhanced results display: Winner showcase now supports up to 6 winners with improved visual hierarchy—featuring a podium for the top 3 and a runners-up section for positions 4–6, including vote counts and prize amounts where applicable.

Vote budget is now VOTES_PER_HACKATHON (5) per distinct hackathon a voter
participated in, so voters can spread their votes across several projects
instead of backing a single one. Centralized as a constant in lib/voting.ts
(buildEligibleVoters) and reused in the open/closed voting copy.
Redesigned the closed-results hero (VotingHero):
- top 3 winners on a gold/silver/bronze podium (1st centered + "Ganador"
badge), positions 4-6 as a numbered list
- each winner shows its prize (from the program's 6-slot ladder) and votes
- removed the grid/checkerboard backdrop for a cleaner look
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
lacrypta-devReadyReadyPreview, CommentJun 23, 2026 9:02pm

Request Review

@coderabbitai

coderabbitaiBot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a8b5bc7e-acaa-40cd-bb2d-469238d87094

📥 Commits

Reviewing files that changed from the base of the PR and between 9347d17 and 227a2f4.

📒 Files selected for processing (3)
  • app/hackathons/[id]/VotingSection.tsx
  • components/voting/VotingHero.tsx
  • lib/voting.ts

📝 Walkthrough

Walkthrough

Introduces VOTES_PER_HACKATHON = 5 constant in lib/voting.ts and scales maxVotes by it in buildEligibleVoters. The open-state UI copy in VotingSection and VotingHero is updated to interpolate this constant. VotingHero's closed-state results view is replaced with a podium (top 3) and runners-up (positions 4–6) layout using new PodiumCard and RunnerRow components.

Changes

Vote Budget Constant and Results UI

Layer / File(s)Summary
Vote budget constant and maxVotes computation
lib/voting.ts
Exports VOTES_PER_HACKATHON = 5; updates VotingEligibleVoter.maxVotes docs and scales maxVotes as hackathons.size * VOTES_PER_HACKATHON in both the new-entry and merge paths of buildEligibleVoters.
Open-state UI copy updated to VOTES_PER_HACKATHON
app/hackathons/[id]/VotingSection.tsx, components/voting/VotingHero.tsx
Both components import VOTES_PER_HACKATHON and interpolate it into the open-voting explanatory message, removing hardcoded "1 voto" strings.
Closed-state podium and runners-up rendering
components/voting/VotingHero.tsx
Removes hero backdrop grid overlay; adds module-level MEDAL and RANK_TONE constants; refactors ClosedHero to split winners into podium (top 3) and runnersUp (4–6); renders via new PodiumCard and RunnerRow components with formatSats prize display and links to project pages.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Five votes per hackathon, hooray!
The podium gleams in gold array,
Runners-up proudly take their place,
No more hardcoded "1" to trace.
With VOTES_PER_HACKATHON in the lead,
This bunny's happy — vote indeed! 🏆

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.50% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately and concisely summarizes both main changes: the vote budget increase (5 per hackathon) and the redesigned results podium, directly matching the PR objectives and changeset.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/voting-budget-and-results-podium

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for freeto 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

@agustinkassis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(voting): 5 votes per hackathon + redesigned results podium - #41

Merged
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium
Jun 23, 2026
Merged

feat(voting): 5 votes per hackathon + redesigned results podium#41
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium

Conversation

@agustinkassis

@agustinkassisagustinkassis commented Jun 23, 2026

Copy link
Copy Markdown
Member

What

Two voting-experience changes:

1. Vote budget: 1 → 5 votes per hackathon

A voter's budget is now VOTES_PER_HACKATHON (5) per distinct hackathon they participated in (was 1). This lets voters spread their votes across several different projects instead of being forced to back a single one.

  • Added the VOTES_PER_HACKATHON constant in lib/voting.ts and applied it in buildEligibleVoters (both the new-voter and the merge-dedupe branches).
  • /api/dev/soldiers and the DEV bar 🗳 count read the same function, so they update automatically.
  • Open/closed voting copy now reads "5 votos por hackatón…" via the same constant (no string drift).

2. Redesigned closed-results hero (VotingHero)

The published-results hero now showcases up to 6 winners with their prizes:

  • Top 3 on a podium — gold/silver/bronze cards, 1st centered and larger with a "Ganador" badge.
  • Positions 4–6 as a numbered list below.
  • Each entry shows its prize (from the program's 6-slot ladder: 400k/250k/150k/100k/60k/40k) and its vote count.
  • Removed the grid/checkerboard backdrop — kept the soft glow + top accent line for a cleaner look.

Why

  • 1 vote per hackathon made every ballot all-or-nothing; 5 votes enables meaningful preference spreading across projects.
  • The old closed hero was a small 3-item side list with no prizes; the podium reads as a proper results celebration and surfaces the prize ladder.

Reviewer notes

  • prizeForPosition/formatSats are reused from lib/hackathons.ts (the program's existing prize distribution) — no new prize source.
  • The closed hero gracefully handles fewer than 6 winners (shows whatever has votes) and a 0-winner edge case.
  • Scope: this PR contains only the shippable feature work. The e2e test scaffolding used this session (a throwaway local "E2E TEST" hackathon, a retargeted dev seeder, and scripts/e2e-*.mjs helpers) was intentionally excluded so nothing test-only reaches production.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Increased voting power: Users now receive 5 votes per hackathon participated in (previously 1).
    • Enhanced results display: Winner showcase now supports up to 6 winners with improved visual hierarchy—featuring a podium for the top 3 and a runners-up section for positions 4–6, including vote counts and prize amounts where applicable.

Vote budget is now VOTES_PER_HACKATHON (5) per distinct hackathon a voter
participated in, so voters can spread their votes across several projects
instead of backing a single one. Centralized as a constant in lib/voting.ts
(buildEligibleVoters) and reused in the open/closed voting copy.
Redesigned the closed-results hero (VotingHero):
- top 3 winners on a gold/silver/bronze podium (1st centered + "Ganador"
badge), positions 4-6 as a numbered list
- each winner shows its prize (from the program's 6-slot ladder) and votes
- removed the grid/checkerboard backdrop for a cleaner look
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
lacrypta-devReadyReadyPreview, CommentJun 23, 2026 9:02pm

Request Review

@coderabbitai

coderabbitaiBot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a8b5bc7e-acaa-40cd-bb2d-469238d87094

📥 Commits

Reviewing files that changed from the base of the PR and between 9347d17 and 227a2f4.

📒 Files selected for processing (3)
  • app/hackathons/[id]/VotingSection.tsx
  • components/voting/VotingHero.tsx
  • lib/voting.ts

📝 Walkthrough

Walkthrough

Introduces VOTES_PER_HACKATHON = 5 constant in lib/voting.ts and scales maxVotes by it in buildEligibleVoters. The open-state UI copy in VotingSection and VotingHero is updated to interpolate this constant. VotingHero's closed-state results view is replaced with a podium (top 3) and runners-up (positions 4–6) layout using new PodiumCard and RunnerRow components.

Changes

Vote Budget Constant and Results UI

Layer / File(s)Summary
Vote budget constant and maxVotes computation
lib/voting.ts
Exports VOTES_PER_HACKATHON = 5; updates VotingEligibleVoter.maxVotes docs and scales maxVotes as hackathons.size * VOTES_PER_HACKATHON in both the new-entry and merge paths of buildEligibleVoters.
Open-state UI copy updated to VOTES_PER_HACKATHON
app/hackathons/[id]/VotingSection.tsx, components/voting/VotingHero.tsx
Both components import VOTES_PER_HACKATHON and interpolate it into the open-voting explanatory message, removing hardcoded "1 voto" strings.
Closed-state podium and runners-up rendering
components/voting/VotingHero.tsx
Removes hero backdrop grid overlay; adds module-level MEDAL and RANK_TONE constants; refactors ClosedHero to split winners into podium (top 3) and runnersUp (4–6); renders via new PodiumCard and RunnerRow components with formatSats prize display and links to project pages.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Five votes per hackathon, hooray!
The podium gleams in gold array,
Runners-up proudly take their place,
No more hardcoded "1" to trace.
With VOTES_PER_HACKATHON in the lead,
This bunny's happy — vote indeed! 🏆

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.50% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately and concisely summarizes both main changes: the vote budget increase (5 per hackathon) and the redesigned results podium, directly matching the PR objectives and changeset.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/voting-budget-and-results-podium

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for freeto 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

@agustinkassis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(voting): 5 votes per hackathon + redesigned results podium - #41

Merged
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium
Jun 23, 2026
Merged

feat(voting): 5 votes per hackathon + redesigned results podium#41
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium

Conversation

@agustinkassis

@agustinkassisagustinkassis commented Jun 23, 2026

Copy link
Copy Markdown
Member

What

Two voting-experience changes:

1. Vote budget: 1 → 5 votes per hackathon

A voter's budget is now VOTES_PER_HACKATHON (5) per distinct hackathon they participated in (was 1). This lets voters spread their votes across several different projects instead of being forced to back a single one.

  • Added the VOTES_PER_HACKATHON constant in lib/voting.ts and applied it in buildEligibleVoters (both the new-voter and the merge-dedupe branches).
  • /api/dev/soldiers and the DEV bar 🗳 count read the same function, so they update automatically.
  • Open/closed voting copy now reads "5 votos por hackatón…" via the same constant (no string drift).

2. Redesigned closed-results hero (VotingHero)

The published-results hero now showcases up to 6 winners with their prizes:

  • Top 3 on a podium — gold/silver/bronze cards, 1st centered and larger with a "Ganador" badge.
  • Positions 4–6 as a numbered list below.
  • Each entry shows its prize (from the program's 6-slot ladder: 400k/250k/150k/100k/60k/40k) and its vote count.
  • Removed the grid/checkerboard backdrop — kept the soft glow + top accent line for a cleaner look.

Why

  • 1 vote per hackathon made every ballot all-or-nothing; 5 votes enables meaningful preference spreading across projects.
  • The old closed hero was a small 3-item side list with no prizes; the podium reads as a proper results celebration and surfaces the prize ladder.

Reviewer notes

  • prizeForPosition/formatSats are reused from lib/hackathons.ts (the program's existing prize distribution) — no new prize source.
  • The closed hero gracefully handles fewer than 6 winners (shows whatever has votes) and a 0-winner edge case.
  • Scope: this PR contains only the shippable feature work. The e2e test scaffolding used this session (a throwaway local "E2E TEST" hackathon, a retargeted dev seeder, and scripts/e2e-*.mjs helpers) was intentionally excluded so nothing test-only reaches production.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Increased voting power: Users now receive 5 votes per hackathon participated in (previously 1).
    • Enhanced results display: Winner showcase now supports up to 6 winners with improved visual hierarchy—featuring a podium for the top 3 and a runners-up section for positions 4–6, including vote counts and prize amounts where applicable.

Vote budget is now VOTES_PER_HACKATHON (5) per distinct hackathon a voter
participated in, so voters can spread their votes across several projects
instead of backing a single one. Centralized as a constant in lib/voting.ts
(buildEligibleVoters) and reused in the open/closed voting copy.
Redesigned the closed-results hero (VotingHero):
- top 3 winners on a gold/silver/bronze podium (1st centered + "Ganador"
badge), positions 4-6 as a numbered list
- each winner shows its prize (from the program's 6-slot ladder) and votes
- removed the grid/checkerboard backdrop for a cleaner look
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
lacrypta-devReadyReadyPreview, CommentJun 23, 2026 9:02pm

Request Review

@coderabbitai

coderabbitaiBot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a8b5bc7e-acaa-40cd-bb2d-469238d87094

📥 Commits

Reviewing files that changed from the base of the PR and between 9347d17 and 227a2f4.

📒 Files selected for processing (3)
  • app/hackathons/[id]/VotingSection.tsx
  • components/voting/VotingHero.tsx
  • lib/voting.ts

📝 Walkthrough

Walkthrough

Introduces VOTES_PER_HACKATHON = 5 constant in lib/voting.ts and scales maxVotes by it in buildEligibleVoters. The open-state UI copy in VotingSection and VotingHero is updated to interpolate this constant. VotingHero's closed-state results view is replaced with a podium (top 3) and runners-up (positions 4–6) layout using new PodiumCard and RunnerRow components.

Changes

Vote Budget Constant and Results UI

Layer / File(s)Summary
Vote budget constant and maxVotes computation
lib/voting.ts
Exports VOTES_PER_HACKATHON = 5; updates VotingEligibleVoter.maxVotes docs and scales maxVotes as hackathons.size * VOTES_PER_HACKATHON in both the new-entry and merge paths of buildEligibleVoters.
Open-state UI copy updated to VOTES_PER_HACKATHON
app/hackathons/[id]/VotingSection.tsx, components/voting/VotingHero.tsx
Both components import VOTES_PER_HACKATHON and interpolate it into the open-voting explanatory message, removing hardcoded "1 voto" strings.
Closed-state podium and runners-up rendering
components/voting/VotingHero.tsx
Removes hero backdrop grid overlay; adds module-level MEDAL and RANK_TONE constants; refactors ClosedHero to split winners into podium (top 3) and runnersUp (4–6); renders via new PodiumCard and RunnerRow components with formatSats prize display and links to project pages.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Five votes per hackathon, hooray!
The podium gleams in gold array,
Runners-up proudly take their place,
No more hardcoded "1" to trace.
With VOTES_PER_HACKATHON in the lead,
This bunny's happy — vote indeed! 🏆

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.50% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately and concisely summarizes both main changes: the vote budget increase (5 per hackathon) and the redesigned results podium, directly matching the PR objectives and changeset.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/voting-budget-and-results-podium

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for freeto 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

@agustinkassis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(voting): 5 votes per hackathon + redesigned results podium - #41

Merged
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium
Jun 23, 2026
Merged

feat(voting): 5 votes per hackathon + redesigned results podium#41
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium

Conversation

@agustinkassis

@agustinkassisagustinkassis commented Jun 23, 2026

Copy link
Copy Markdown
Member

What

Two voting-experience changes:

1. Vote budget: 1 → 5 votes per hackathon

A voter's budget is now VOTES_PER_HACKATHON (5) per distinct hackathon they participated in (was 1). This lets voters spread their votes across several different projects instead of being forced to back a single one.

  • Added the VOTES_PER_HACKATHON constant in lib/voting.ts and applied it in buildEligibleVoters (both the new-voter and the merge-dedupe branches).
  • /api/dev/soldiers and the DEV bar 🗳 count read the same function, so they update automatically.
  • Open/closed voting copy now reads "5 votos por hackatón…" via the same constant (no string drift).

2. Redesigned closed-results hero (VotingHero)

The published-results hero now showcases up to 6 winners with their prizes:

  • Top 3 on a podium — gold/silver/bronze cards, 1st centered and larger with a "Ganador" badge.
  • Positions 4–6 as a numbered list below.
  • Each entry shows its prize (from the program's 6-slot ladder: 400k/250k/150k/100k/60k/40k) and its vote count.
  • Removed the grid/checkerboard backdrop — kept the soft glow + top accent line for a cleaner look.

Why

  • 1 vote per hackathon made every ballot all-or-nothing; 5 votes enables meaningful preference spreading across projects.
  • The old closed hero was a small 3-item side list with no prizes; the podium reads as a proper results celebration and surfaces the prize ladder.

Reviewer notes

  • prizeForPosition/formatSats are reused from lib/hackathons.ts (the program's existing prize distribution) — no new prize source.
  • The closed hero gracefully handles fewer than 6 winners (shows whatever has votes) and a 0-winner edge case.
  • Scope: this PR contains only the shippable feature work. The e2e test scaffolding used this session (a throwaway local "E2E TEST" hackathon, a retargeted dev seeder, and scripts/e2e-*.mjs helpers) was intentionally excluded so nothing test-only reaches production.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Increased voting power: Users now receive 5 votes per hackathon participated in (previously 1).
    • Enhanced results display: Winner showcase now supports up to 6 winners with improved visual hierarchy—featuring a podium for the top 3 and a runners-up section for positions 4–6, including vote counts and prize amounts where applicable.

Vote budget is now VOTES_PER_HACKATHON (5) per distinct hackathon a voter
participated in, so voters can spread their votes across several projects
instead of backing a single one. Centralized as a constant in lib/voting.ts
(buildEligibleVoters) and reused in the open/closed voting copy.
Redesigned the closed-results hero (VotingHero):
- top 3 winners on a gold/silver/bronze podium (1st centered + "Ganador"
badge), positions 4-6 as a numbered list
- each winner shows its prize (from the program's 6-slot ladder) and votes
- removed the grid/checkerboard backdrop for a cleaner look
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
lacrypta-devReadyReadyPreview, CommentJun 23, 2026 9:02pm

Request Review

@coderabbitai

coderabbitaiBot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a8b5bc7e-acaa-40cd-bb2d-469238d87094

📥 Commits

Reviewing files that changed from the base of the PR and between 9347d17 and 227a2f4.

📒 Files selected for processing (3)
  • app/hackathons/[id]/VotingSection.tsx
  • components/voting/VotingHero.tsx
  • lib/voting.ts

📝 Walkthrough

Walkthrough

Introduces VOTES_PER_HACKATHON = 5 constant in lib/voting.ts and scales maxVotes by it in buildEligibleVoters. The open-state UI copy in VotingSection and VotingHero is updated to interpolate this constant. VotingHero's closed-state results view is replaced with a podium (top 3) and runners-up (positions 4–6) layout using new PodiumCard and RunnerRow components.

Changes

Vote Budget Constant and Results UI

Layer / File(s)Summary
Vote budget constant and maxVotes computation
lib/voting.ts
Exports VOTES_PER_HACKATHON = 5; updates VotingEligibleVoter.maxVotes docs and scales maxVotes as hackathons.size * VOTES_PER_HACKATHON in both the new-entry and merge paths of buildEligibleVoters.
Open-state UI copy updated to VOTES_PER_HACKATHON
app/hackathons/[id]/VotingSection.tsx, components/voting/VotingHero.tsx
Both components import VOTES_PER_HACKATHON and interpolate it into the open-voting explanatory message, removing hardcoded "1 voto" strings.
Closed-state podium and runners-up rendering
components/voting/VotingHero.tsx
Removes hero backdrop grid overlay; adds module-level MEDAL and RANK_TONE constants; refactors ClosedHero to split winners into podium (top 3) and runnersUp (4–6); renders via new PodiumCard and RunnerRow components with formatSats prize display and links to project pages.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Five votes per hackathon, hooray!
The podium gleams in gold array,
Runners-up proudly take their place,
No more hardcoded "1" to trace.
With VOTES_PER_HACKATHON in the lead,
This bunny's happy — vote indeed! 🏆

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.50% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately and concisely summarizes both main changes: the vote budget increase (5 per hackathon) and the redesigned results podium, directly matching the PR objectives and changeset.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/voting-budget-and-results-podium

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for freeto 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

@agustinkassis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(voting): 5 votes per hackathon + redesigned results podium - #41

Merged
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium
Jun 23, 2026
Merged

feat(voting): 5 votes per hackathon + redesigned results podium#41
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium

Conversation

@agustinkassis

@agustinkassisagustinkassis commented Jun 23, 2026

Copy link
Copy Markdown
Member

What

Two voting-experience changes:

1. Vote budget: 1 → 5 votes per hackathon

A voter's budget is now VOTES_PER_HACKATHON (5) per distinct hackathon they participated in (was 1). This lets voters spread their votes across several different projects instead of being forced to back a single one.

  • Added the VOTES_PER_HACKATHON constant in lib/voting.ts and applied it in buildEligibleVoters (both the new-voter and the merge-dedupe branches).
  • /api/dev/soldiers and the DEV bar 🗳 count read the same function, so they update automatically.
  • Open/closed voting copy now reads "5 votos por hackatón…" via the same constant (no string drift).

2. Redesigned closed-results hero (VotingHero)

The published-results hero now showcases up to 6 winners with their prizes:

  • Top 3 on a podium — gold/silver/bronze cards, 1st centered and larger with a "Ganador" badge.
  • Positions 4–6 as a numbered list below.
  • Each entry shows its prize (from the program's 6-slot ladder: 400k/250k/150k/100k/60k/40k) and its vote count.
  • Removed the grid/checkerboard backdrop — kept the soft glow + top accent line for a cleaner look.

Why

  • 1 vote per hackathon made every ballot all-or-nothing; 5 votes enables meaningful preference spreading across projects.
  • The old closed hero was a small 3-item side list with no prizes; the podium reads as a proper results celebration and surfaces the prize ladder.

Reviewer notes

  • prizeForPosition/formatSats are reused from lib/hackathons.ts (the program's existing prize distribution) — no new prize source.
  • The closed hero gracefully handles fewer than 6 winners (shows whatever has votes) and a 0-winner edge case.
  • Scope: this PR contains only the shippable feature work. The e2e test scaffolding used this session (a throwaway local "E2E TEST" hackathon, a retargeted dev seeder, and scripts/e2e-*.mjs helpers) was intentionally excluded so nothing test-only reaches production.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Increased voting power: Users now receive 5 votes per hackathon participated in (previously 1).
    • Enhanced results display: Winner showcase now supports up to 6 winners with improved visual hierarchy—featuring a podium for the top 3 and a runners-up section for positions 4–6, including vote counts and prize amounts where applicable.

Vote budget is now VOTES_PER_HACKATHON (5) per distinct hackathon a voter
participated in, so voters can spread their votes across several projects
instead of backing a single one. Centralized as a constant in lib/voting.ts
(buildEligibleVoters) and reused in the open/closed voting copy.
Redesigned the closed-results hero (VotingHero):
- top 3 winners on a gold/silver/bronze podium (1st centered + "Ganador"
badge), positions 4-6 as a numbered list
- each winner shows its prize (from the program's 6-slot ladder) and votes
- removed the grid/checkerboard backdrop for a cleaner look
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
lacrypta-devReadyReadyPreview, CommentJun 23, 2026 9:02pm

Request Review

@coderabbitai

coderabbitaiBot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a8b5bc7e-acaa-40cd-bb2d-469238d87094

📥 Commits

Reviewing files that changed from the base of the PR and between 9347d17 and 227a2f4.

📒 Files selected for processing (3)
  • app/hackathons/[id]/VotingSection.tsx
  • components/voting/VotingHero.tsx
  • lib/voting.ts

📝 Walkthrough

Walkthrough

Introduces VOTES_PER_HACKATHON = 5 constant in lib/voting.ts and scales maxVotes by it in buildEligibleVoters. The open-state UI copy in VotingSection and VotingHero is updated to interpolate this constant. VotingHero's closed-state results view is replaced with a podium (top 3) and runners-up (positions 4–6) layout using new PodiumCard and RunnerRow components.

Changes

Vote Budget Constant and Results UI

Layer / File(s)Summary
Vote budget constant and maxVotes computation
lib/voting.ts
Exports VOTES_PER_HACKATHON = 5; updates VotingEligibleVoter.maxVotes docs and scales maxVotes as hackathons.size * VOTES_PER_HACKATHON in both the new-entry and merge paths of buildEligibleVoters.
Open-state UI copy updated to VOTES_PER_HACKATHON
app/hackathons/[id]/VotingSection.tsx, components/voting/VotingHero.tsx
Both components import VOTES_PER_HACKATHON and interpolate it into the open-voting explanatory message, removing hardcoded "1 voto" strings.
Closed-state podium and runners-up rendering
components/voting/VotingHero.tsx
Removes hero backdrop grid overlay; adds module-level MEDAL and RANK_TONE constants; refactors ClosedHero to split winners into podium (top 3) and runnersUp (4–6); renders via new PodiumCard and RunnerRow components with formatSats prize display and links to project pages.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Five votes per hackathon, hooray!
The podium gleams in gold array,
Runners-up proudly take their place,
No more hardcoded "1" to trace.
With VOTES_PER_HACKATHON in the lead,
This bunny's happy — vote indeed! 🏆

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.50% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately and concisely summarizes both main changes: the vote budget increase (5 per hackathon) and the redesigned results podium, directly matching the PR objectives and changeset.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/voting-budget-and-results-podium

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for freeto 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

@agustinkassis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(voting): 5 votes per hackathon + redesigned results podium - #41

Merged
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium
Jun 23, 2026
Merged

feat(voting): 5 votes per hackathon + redesigned results podium#41
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium

Conversation

@agustinkassis

@agustinkassisagustinkassis commented Jun 23, 2026

Copy link
Copy Markdown
Member

What

Two voting-experience changes:

1. Vote budget: 1 → 5 votes per hackathon

A voter's budget is now VOTES_PER_HACKATHON (5) per distinct hackathon they participated in (was 1). This lets voters spread their votes across several different projects instead of being forced to back a single one.

  • Added the VOTES_PER_HACKATHON constant in lib/voting.ts and applied it in buildEligibleVoters (both the new-voter and the merge-dedupe branches).
  • /api/dev/soldiers and the DEV bar 🗳 count read the same function, so they update automatically.
  • Open/closed voting copy now reads "5 votos por hackatón…" via the same constant (no string drift).

2. Redesigned closed-results hero (VotingHero)

The published-results hero now showcases up to 6 winners with their prizes:

  • Top 3 on a podium — gold/silver/bronze cards, 1st centered and larger with a "Ganador" badge.
  • Positions 4–6 as a numbered list below.
  • Each entry shows its prize (from the program's 6-slot ladder: 400k/250k/150k/100k/60k/40k) and its vote count.
  • Removed the grid/checkerboard backdrop — kept the soft glow + top accent line for a cleaner look.

Why

  • 1 vote per hackathon made every ballot all-or-nothing; 5 votes enables meaningful preference spreading across projects.
  • The old closed hero was a small 3-item side list with no prizes; the podium reads as a proper results celebration and surfaces the prize ladder.

Reviewer notes

  • prizeForPosition/formatSats are reused from lib/hackathons.ts (the program's existing prize distribution) — no new prize source.
  • The closed hero gracefully handles fewer than 6 winners (shows whatever has votes) and a 0-winner edge case.
  • Scope: this PR contains only the shippable feature work. The e2e test scaffolding used this session (a throwaway local "E2E TEST" hackathon, a retargeted dev seeder, and scripts/e2e-*.mjs helpers) was intentionally excluded so nothing test-only reaches production.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Increased voting power: Users now receive 5 votes per hackathon participated in (previously 1).
    • Enhanced results display: Winner showcase now supports up to 6 winners with improved visual hierarchy—featuring a podium for the top 3 and a runners-up section for positions 4–6, including vote counts and prize amounts where applicable.

Vote budget is now VOTES_PER_HACKATHON (5) per distinct hackathon a voter
participated in, so voters can spread their votes across several projects
instead of backing a single one. Centralized as a constant in lib/voting.ts
(buildEligibleVoters) and reused in the open/closed voting copy.
Redesigned the closed-results hero (VotingHero):
- top 3 winners on a gold/silver/bronze podium (1st centered + "Ganador"
badge), positions 4-6 as a numbered list
- each winner shows its prize (from the program's 6-slot ladder) and votes
- removed the grid/checkerboard backdrop for a cleaner look
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
lacrypta-devReadyReadyPreview, CommentJun 23, 2026 9:02pm

Request Review

@coderabbitai

coderabbitaiBot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a8b5bc7e-acaa-40cd-bb2d-469238d87094

📥 Commits

Reviewing files that changed from the base of the PR and between 9347d17 and 227a2f4.

📒 Files selected for processing (3)
  • app/hackathons/[id]/VotingSection.tsx
  • components/voting/VotingHero.tsx
  • lib/voting.ts

📝 Walkthrough

Walkthrough

Introduces VOTES_PER_HACKATHON = 5 constant in lib/voting.ts and scales maxVotes by it in buildEligibleVoters. The open-state UI copy in VotingSection and VotingHero is updated to interpolate this constant. VotingHero's closed-state results view is replaced with a podium (top 3) and runners-up (positions 4–6) layout using new PodiumCard and RunnerRow components.

Changes

Vote Budget Constant and Results UI

Layer / File(s)Summary
Vote budget constant and maxVotes computation
lib/voting.ts
Exports VOTES_PER_HACKATHON = 5; updates VotingEligibleVoter.maxVotes docs and scales maxVotes as hackathons.size * VOTES_PER_HACKATHON in both the new-entry and merge paths of buildEligibleVoters.
Open-state UI copy updated to VOTES_PER_HACKATHON
app/hackathons/[id]/VotingSection.tsx, components/voting/VotingHero.tsx
Both components import VOTES_PER_HACKATHON and interpolate it into the open-voting explanatory message, removing hardcoded "1 voto" strings.
Closed-state podium and runners-up rendering
components/voting/VotingHero.tsx
Removes hero backdrop grid overlay; adds module-level MEDAL and RANK_TONE constants; refactors ClosedHero to split winners into podium (top 3) and runnersUp (4–6); renders via new PodiumCard and RunnerRow components with formatSats prize display and links to project pages.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Five votes per hackathon, hooray!
The podium gleams in gold array,
Runners-up proudly take their place,
No more hardcoded "1" to trace.
With VOTES_PER_HACKATHON in the lead,
This bunny's happy — vote indeed! 🏆

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.50% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately and concisely summarizes both main changes: the vote budget increase (5 per hackathon) and the redesigned results podium, directly matching the PR objectives and changeset.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/voting-budget-and-results-podium

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for freeto 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

@agustinkassis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(voting): 5 votes per hackathon + redesigned results podium - #41

Merged
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium
Jun 23, 2026
Merged

feat(voting): 5 votes per hackathon + redesigned results podium#41
agustinkassis merged 1 commit into
mainfrom
feat/voting-budget-and-results-podium

Conversation

@agustinkassis

@agustinkassisagustinkassis commented Jun 23, 2026

Copy link
Copy Markdown
Member

What

Two voting-experience changes:

1. Vote budget: 1 → 5 votes per hackathon

A voter's budget is now VOTES_PER_HACKATHON (5) per distinct hackathon they participated in (was 1). This lets voters spread their votes across several different projects instead of being forced to back a single one.

  • Added the VOTES_PER_HACKATHON constant in lib/voting.ts and applied it in buildEligibleVoters (both the new-voter and the merge-dedupe branches).
  • /api/dev/soldiers and the DEV bar 🗳 count read the same function, so they update automatically.
  • Open/closed voting copy now reads "5 votos por hackatón…" via the same constant (no string drift).

2. Redesigned closed-results hero (VotingHero)

The published-results hero now showcases up to 6 winners with their prizes:

  • Top 3 on a podium — gold/silver/bronze cards, 1st centered and larger with a "Ganador" badge.
  • Positions 4–6 as a numbered list below.
  • Each entry shows its prize (from the program's 6-slot ladder: 400k/250k/150k/100k/60k/40k) and its vote count.
  • Removed the grid/checkerboard backdrop — kept the soft glow + top accent line for a cleaner look.

Why

  • 1 vote per hackathon made every ballot all-or-nothing; 5 votes enables meaningful preference spreading across projects.
  • The old closed hero was a small 3-item side list with no prizes; the podium reads as a proper results celebration and surfaces the prize ladder.

Reviewer notes

  • prizeForPosition/formatSats are reused from lib/hackathons.ts (the program's existing prize distribution) — no new prize source.
  • The closed hero gracefully handles fewer than 6 winners (shows whatever has votes) and a 0-winner edge case.
  • Scope: this PR contains only the shippable feature work. The e2e test scaffolding used this session (a throwaway local "E2E TEST" hackathon, a retargeted dev seeder, and scripts/e2e-*.mjs helpers) was intentionally excluded so nothing test-only reaches production.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Increased voting power: Users now receive 5 votes per hackathon participated in (previously 1).
    • Enhanced results display: Winner showcase now supports up to 6 winners with improved visual hierarchy—featuring a podium for the top 3 and a runners-up section for positions 4–6, including vote counts and prize amounts where applicable.

Vote budget is now VOTES_PER_HACKATHON (5) per distinct hackathon a voter
participated in, so voters can spread their votes across several projects
instead of backing a single one. Centralized as a constant in lib/voting.ts
(buildEligibleVoters) and reused in the open/closed voting copy.
Redesigned the closed-results hero (VotingHero):
- top 3 winners on a gold/silver/bronze podium (1st centered + "Ganador"
badge), positions 4-6 as a numbered list
- each winner shows its prize (from the program's 6-slot ladder) and votes
- removed the grid/checkerboard backdrop for a cleaner look
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
lacrypta-devReadyReadyPreview, CommentJun 23, 2026 9:02pm

Request Review

@coderabbitai

coderabbitaiBot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a8b5bc7e-acaa-40cd-bb2d-469238d87094

📥 Commits

Reviewing files that changed from the base of the PR and between 9347d17 and 227a2f4.

📒 Files selected for processing (3)
  • app/hackathons/[id]/VotingSection.tsx
  • components/voting/VotingHero.tsx
  • lib/voting.ts

📝 Walkthrough

Walkthrough

Introduces VOTES_PER_HACKATHON = 5 constant in lib/voting.ts and scales maxVotes by it in buildEligibleVoters. The open-state UI copy in VotingSection and VotingHero is updated to interpolate this constant. VotingHero's closed-state results view is replaced with a podium (top 3) and runners-up (positions 4–6) layout using new PodiumCard and RunnerRow components.

Changes

Vote Budget Constant and Results UI

Layer / File(s)Summary
Vote budget constant and maxVotes computation
lib/voting.ts
Exports VOTES_PER_HACKATHON = 5; updates VotingEligibleVoter.maxVotes docs and scales maxVotes as hackathons.size * VOTES_PER_HACKATHON in both the new-entry and merge paths of buildEligibleVoters.
Open-state UI copy updated to VOTES_PER_HACKATHON
app/hackathons/[id]/VotingSection.tsx, components/voting/VotingHero.tsx
Both components import VOTES_PER_HACKATHON and interpolate it into the open-voting explanatory message, removing hardcoded "1 voto" strings.
Closed-state podium and runners-up rendering
components/voting/VotingHero.tsx
Removes hero backdrop grid overlay; adds module-level MEDAL and RANK_TONE constants; refactors ClosedHero to split winners into podium (top 3) and runnersUp (4–6); renders via new PodiumCard and RunnerRow components with formatSats prize display and links to project pages.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Five votes per hackathon, hooray!
The podium gleams in gold array,
Runners-up proudly take their place,
No more hardcoded "1" to trace.
With VOTES_PER_HACKATHON in the lead,
This bunny's happy — vote indeed! 🏆

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.50% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately and concisely summarizes both main changes: the vote budget increase (5 per hackathon) and the redesigned results podium, directly matching the PR objectives and changeset.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/voting-budget-and-results-podium

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for freeto 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

@agustinkassis