Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,6 @@ packages/db/scripts/seed.ts
packages/db/scripts/seed2.ts
scripts/seed-stripe.ts
packages/db/scripts/seed-judges.ts
packages/db/scripts/seed-projects.ts
packages/db/scripts/seed-projects.ts
packages/db/final_judge_assignments.csv
packages/db/scripts/seed-2026.ts
2 changes: 1 addition & 1 deletion packages/db/src/schemas/hackathons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export const hackathonProjects = pgTable("hackathon_project", {
name: text("name").notNull(),
description: text("description").notNull(),
technologies: text("technologies").array(),
tracks: text("tracks").array(), // Enum: GEN-AI, SPORTS, FINANCE, HEALTH, CYBER, NONE
tracks: text("tracks").array(), // Enum: Sports, Entertainment, Imagination, Finance, Healthcare, databricks, sphinx, growth factor, figma, actian, safety kit, GEN-AI, CYBER, NONE
challenges: text("challenges").array(), // Enum: AGG, ASSURANT, AWS, CAPONE, GROWTH, MLH_MONGODB, MLH_STREAMLIT, MLH_TECH, MLH_CLOUDFLARE, MLH_REACH_CAPITAL
isCreateX: boolean("is_create_x").default(false),
teamMembers: text("team_members").array(), // Store names/emails if not fully linked
Expand Down
2 changes: 1 addition & 1 deletion packages/db/src/schemas/judge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const judgingProjects = pgTable("judging_project", {
teamMembers: text("team_members"), // comma-separated or JSON string
projectUrl: text("project_url"),
repoUrl: text("repo_url"),
tracks: text("tracks").array(), // Enum: GEN-AI, SPORTS, FINANCE, HEALTH, CYBER, NONE
tracks: text("tracks").array(), // Enum: Sports, Entertainment, Imagination, Finance, Healthcare, databricks, sphinx, growth factor, figma, actian, safety kit, GEN-AI, CYBER, NONE
challenges: text("challenges").array(), // Enum: AGG, ASSURANT, AWS, CAPONE, GROWTH, MLH_MONGODB, MLH_STREAMLIT, MLH_TECH, MLH_CLOUDFLARE, MLH_REACH_CAPITAL
isCreateX: boolean("is_create_x").default(false),
createdAt: timestamp("created_at").defaultNow().notNull(),
Expand Down
81 changes: 81 additions & 0 deletions sites/mainweb/app/(portal)/admin-judging/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ export default function AdminResultsPage() {
{ enabled: !!selectedHackathon }
);

// Get judges
const { data: judges } = trpc.judge.list.useQuery(undefined, {
enabled: !!session && !!adminStatus?.isAdmin,
});

useEffect(() => {
setMounted(true);
}, []);
Expand Down Expand Up @@ -525,6 +530,82 @@ export default function AdminResultsPage() {
)}
</div>

{/* Judge Roster Section */}
<div className="mt-16 space-y-6">
<div className="flex justify-between items-end mb-4">
<div>
<p className="text-xs text-gray-600 uppercase tracking-[0.4em] mb-2 font-mono">Operations Personnel</p>
<h2 className="text-3xl font-black text-white italic uppercase tracking-tighter">
Judge <span className="text-[#00A8A8]">Roster</span>
</h2>
</div>
<div className="px-4 py-2 bg-white/5 border border-white/5 rounded-lg text-[10px] font-mono uppercase tracking-widest text-[#00A8A8]">
Active: {judges?.filter(j => j.isActive).length || 0} Nodes
</div>
</div>

<LiquidGlass className="rounded-lg overflow-hidden shadow-[0_20px_50px_rgba(0,0,0,0.5)]">
<div className="overflow-x-auto">
<table className="w-full text-left border-collapse">
<thead>
<tr className="border-b border-white/5 bg-white/[0.02]">
<th className="px-8 py-6 text-[10px] font-mono text-gray-500 uppercase tracking-[0.2em]">Judge</th>
<th className="px-8 py-6 text-[10px] font-mono text-gray-500 uppercase tracking-[0.2em]">Contact</th>
<th className="px-8 py-6 text-[10px] font-mono text-gray-500 uppercase tracking-[0.2em]">Assigned Tracks</th>
<th className="px-8 py-6 text-[10px] font-mono text-gray-500 uppercase tracking-[0.2em] text-right">Status</th>
</tr>
</thead>
<tbody className="divide-y divide-white/5">
{judges?.map((j) => (
<tr key={j.id} className="hover:bg-black/40 transition-colors duration-300">
<td className="px-8 py-6">
<div className="flex items-center gap-4">
<img
src={j.user?.image || `https://ui-avatars.com/api/?name=${encodeURIComponent(j.name || 'J')}`}
alt={j.name || ''}
className="w-10 h-10 rounded-full border border-white/10 ring-1 ring-[#00A8A8]/20"
/>
<div>
<p className="text-sm font-bold text-white uppercase tracking-tight">{j.name}</p>
<p className="text-[10px] text-gray-600 font-mono tracking-widest uppercase">{j.specialty || 'Generalist'}</p>
</div>
</div>
</td>
<td className="px-8 py-6">
<p className="text-xs text-gray-400 font-mono">{j.user?.email}</p>
</td>
<td className="px-8 py-6">
<div className="flex flex-wrap gap-2">
{j.assignments
.filter(a => a.hackathonId === selectedHackathon)
.map((a, i) => (
<span key={i} className="px-3 py-1 rounded bg-white/5 border border-white/10 text-[9px] font-mono text-[#00A8A8] uppercase tracking-widest">
{a.track || 'Unassigned'}
</span>
))}
</div>
</td>
<td className="px-8 py-6 text-right">
<span className={`px-3 py-1 rounded-full text-[8px] font-black uppercase tracking-widest ${j.isActive ? 'bg-green-500/10 text-green-500 border border-green-500/20' : 'bg-red-500/10 text-red-500 border border-red-500/20'
}`}>
{j.isActive ? 'Active' : 'Offline'}
</span>
</td>
</tr>
))}
{!judges?.length && (
<tr>
<td colSpan={4} className="px-8 py-12 text-center text-gray-500 font-mono uppercase tracking-widest text-xs">
No judges registered in the central database.
</td>
</tr>
)}
</tbody>
</table>
</div>
</LiquidGlass>
</div>

{/* Global Stats */}
{rankings && rankings.rankings.length > 0 && (
<div className="mt-12 grid grid-cols-1 md:grid-cols-3 gap-6">
Expand Down
Loading