Skip to content

Comments

[WIP] Add AGM view for users#1671

Draft
Drewbi wants to merge 7 commits intov4from
add-meeting-user-view
Draft

[WIP] Add AGM view for users#1671
Drewbi wants to merge 7 commits intov4from
add-meeting-user-view

Conversation

@Drewbi
Copy link
Contributor

@Drewbi Drewbi commented Feb 22, 2026

image image image image image

@vercel
Copy link

vercel bot commented Feb 22, 2026

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

Project Deployment Actions Updated (UTC)
website Error Error Feb 22, 2026 3:56pm

Request Review

Comment on lines +57 to +59
CLAUDE.md
.CLAUDE
.llms No newline at end of file
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shout out to my homies


export const positionsInGeneralMeetingsRouter = createTRPCRouter({
get: getPositions,
getWithCounts: getPositionsWithCounts,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can probably just be calculated from the returned candidates for a position

Comment on lines +17 to +25
.select({
...getTableColumns(positions),
nomineeCount: count(nominations.candidateId),
})
.from(positions)
.leftJoin(nominations, eq(nominations.positionId, positions.id))
.where(eq(positions.meetingId, input.meetingId))
.groupBy(positions.id)
.orderBy(asc(positions.priority))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You reckon there would be a way to do this with query instead of select? Will probably delete this endpoint anyway

if (!position) throw new TRPCError({ code: "NOT_FOUND", message: "Position not found" })

const positionNominations = await ctx.db
.select()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change to query

questions: meetingQuestions,
candidates: candidateRows.map((candidate) => ({
...candidate,
answers: allAnswers.filter((a) => a.candidateId === candidate.id),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is BAD. Should really just include questions and answers in candidate query

const getNominations = publicRatedProcedure()
.input(z.object({ positionId: z.uuidv7() }))
.query(async ({ ctx, input }) => {
return ctx.db.select().from(nominations).where(eq(nominations.positionId, input.positionId))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

query

const getNominationsByCandidate = publicRatedProcedure()
.input(z.object({ candidateId: z.uuidv7() }))
.query(async ({ ctx, input }) => {
return ctx.db.select().from(nominations).where(eq(nominations.candidateId, input.candidateId))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

query

const getCandidates = publicRatedProcedure()
.input(z.object({ meetingId: z.uuidv7() }))
.query(async ({ ctx, input }) => {
return ctx.db.select().from(candidates).where(eq(candidates.meetingId, input.meetingId))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

query

Comment on lines +10 to +14
const [candidate] = await ctx.db
.select()
.from(candidates)
.where(and(eq(candidates.meetingId, input.meetingId), eq(candidates.userId, ctx.session.user.id)))
return candidate ?? null
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

query

const sameDay = meeting.end && meeting.start.toDateString() === meeting.end.toDateString()

return (
<main className="container mx-auto px-4 py-12">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs extra styles to work in light mode

<h1 className="scroll-m-20 font-mono text-4xl tracking-tight text-balance">{meeting.title}</h1>
<div className="flex flex-col gap-1.5 font-mono text-sm text-neutral-500 dark:text-neutral-400">
<div className="flex items-center gap-2">
<span className="material-symbols-sharp text-base! leading-none!">schedule</span>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of important usage here, not really sure why

</section>
)}

{(meeting.status === "upcoming" || meeting.status === "ongoing") && (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows them to access nominations page even when meeting is open. I think this is desired behaviour

</section>
)}

{meeting.status === "ongoing" && (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might need an else here to tell them to hang tight if the meeting hasn't opened yet

Comment on lines +7 to +9
<Header />
{children}
<Footer />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could probably put some of the general layout styles in this top level layout

</ul>
)}

<p className="text-sm text-neutral-500 dark:text-neutral-400">Voting coming soon.</p>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how we want to handle which position is open for voting. Might need to add a property to the positions table

Comment on lines +11 to +12
const key = `cfc-stars-${positionId}`
const [starred, setStarred] = React.useState<Set<string>>(new Set())
Copy link
Contributor Author

@Drewbi Drewbi Feb 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a non-essential feature but is kinda useful for remembering your favs before voting has opened

Comment on lines +17 to +23
type Question = {
id: string
text: string
type: "short" | "long" | "checkbox" | null
required: boolean | null
order: number
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this stuff be coming from tRPC?

{ enabled: !!myCandidate },
)

const [isEditing, setIsEditing] = React.useState(false)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really gotta preface React. all the time?

Comment on lines +155 to +159
await Promise.all([
...[...selectedPositions].map((positionId) =>
createNomination.mutateAsync({ meetingId: meeting.id, positionId, candidateId: candidate.id }),
),
...questions
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks hella jank, lmk if theres a better way

{btnText}
</motion.span>
</AnimatePresence>
{loading && <Spinner className="absolute right-4" />}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loading spinner is inside the text every time, gotta fix

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably has huge conflicts with your changes @JeremiahPinto, m'pologies

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