Skip to content

Commit 442fcea

Browse files
committed
feat: Add share reason
1 parent 04fee55 commit 442fcea

File tree

5 files changed

+51
-22
lines changed

5 files changed

+51
-22
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE votes ADD COLUMN reason TEXT NOT NULL;

src/lib/database.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ export class DatabaseService {
7272
const voteStatements = vote.participants.map((p) =>
7373
this.db
7474
.prepare(
75-
'INSERT INTO votes (session_id, voter_id, recipient_id, share) VALUES (?, ?, ?, ?)'
75+
'INSERT INTO votes (session_id, voter_id, recipient_id, share, reason) VALUES (?, ?, ?, ?, ?)'
7676
)
77-
.bind(sessionId, vote.voterId, p.id, p.share)
77+
.bind(sessionId, vote.voterId, p.id, p.share, p.reason)
7878
);
7979

8080
await this.db.batch(voteStatements);
@@ -111,14 +111,15 @@ export class DatabaseService {
111111

112112
async getParticipantShares(
113113
sessionId: number
114-
): Promise<Record<string, Array<number>>> {
114+
): Promise<Record<string, Array<{ share: number; reason: string }>>> {
115115
const { results } = await this.db
116116
.prepare(
117117
`
118118
SELECT
119119
p.name,
120120
p.description,
121-
v.share
121+
v.share,
122+
v.reason
122123
FROM participants p
123124
LEFT JOIN votes v
124125
ON p.id = v.recipient_id AND v.session_id = ?
@@ -129,16 +130,20 @@ export class DatabaseService {
129130
.all<{
130131
name: string;
131132
share: number;
133+
reason: string;
132134
}>();
133135

134-
const participantShares: Record<string, Array<number>> = {};
136+
const participantShares: Record<
137+
string,
138+
Array<{ share: number; reason: string }>
139+
> = {};
135140

136141
results.map((result) => {
137-
const { name, share } = result;
142+
const { name, share, reason } = result;
138143

139144
if (!participantShares[name]) participantShares[name] = [];
140145

141-
if (share != null) participantShares[name].push(share);
146+
if (share != null) participantShares[name].push({ share, reason });
142147
});
143148

144149
return participantShares;

src/lib/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export interface SubmitVoteRequest {
2727
participants: Array<{
2828
id: number;
2929
share: number;
30+
reason: string;
3031
}>;
3132
}
3233

src/routes/+page.svelte

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
name: string;
2424
description: string;
2525
share: number;
26+
reason: string;
27+
reasons: string[];
2628
}[];
2729
} | null = null;
2830
@@ -94,9 +96,10 @@
9496
},
9597
body: JSON.stringify({
9698
voterId,
97-
participants: session.participants.map(({ id, share }) => ({
99+
participants: session.participants.map(({ id, share, reason }) => ({
98100
id,
99-
share: share || 0
101+
share: share || 0,
102+
reason
100103
}))
101104
})
102105
});
@@ -331,8 +334,17 @@
331334
placeholder="Share"
332335
class="input"
333336
/>
337+
<textarea bind:value={participant.reason} placeholder="Reason"
338+
></textarea>
334339
{:else}
335340
<p><strong>Share:</strong> {participant.share || 0}</p>
341+
<strong>Reasons:</strong>
342+
343+
<ul>
344+
{#each participant.reasons as reason}
345+
<li>{reason}</li>
346+
{/each}
347+
</ul>
336348
{/if}
337349
{:else}
338350
<button on:click={() => selectParticipant(participant)}
@@ -377,7 +389,7 @@
377389
{/if}
378390
</div>
379391
{#if session}
380-
<button on:click={() => (session = null)}> Go back</button>
392+
<button on:click={() => (session = voterId = null)}> Go back</button>
381393
{/if}
382394
{/if}
383395
</main>

src/routes/api/[sessionKey]/+server.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const GET: RequestHandler = async ({ params, request, platform }) => {
2828

2929
const participantShares: Record<
3030
string,
31-
Array<number>
31+
Array<{ share: number; reason: string }>
3232
> = await db.getParticipantShares(sessionId);
3333

3434
const participantNames = Object.keys(participantShares);
@@ -50,9 +50,10 @@ export const GET: RequestHandler = async ({ params, request, platform }) => {
5050
}
5151

5252
const participants = Object.entries(participantShares).map(
53-
([name, shares]) => ({
53+
([name, vote]) => ({
5454
name,
55-
share: shares.reduce((sum, value) => sum + value, 0) / participantLength
55+
share: vote.reduce((sum, v) => sum + v.share, 0) / participantLength,
56+
reasons: vote.map((v) => v.reason)
5657
})
5758
);
5859

@@ -92,12 +93,30 @@ export const POST: RequestHandler = async ({ params, request, platform }) => {
9293
notFoundError();
9394
}
9495

96+
const allReasonsExist = vote.participants.every(
97+
(p) => p.reason && p.reason.trim().length > 0
98+
);
99+
if (!allReasonsExist) {
100+
badRequestError(
101+
'One or more participants in the vote do not have a share reason'
102+
);
103+
}
104+
95105
const participants = await db.getParticipants(session.id);
96106

97107
if (vote.participants.length !== participants.length - 1) {
98108
badRequestError('Invalid number of share participants.');
99109
}
100110

111+
const voterExists = participants.some((p) => p.id === voterId);
112+
if (!voterExists) {
113+
badRequestError('Voter is not a participant in this session');
114+
}
115+
116+
if (vote.participants.some((s) => s.id === voterId)) {
117+
badRequestError('You cannot vote for yourself');
118+
}
119+
101120
const totalShares = vote.participants.reduce((sum, s) => sum + s.share, 0);
102121
if (totalShares != session.stake) {
103122
badRequestError('Total shares must equal session stake');
@@ -110,15 +129,6 @@ export const POST: RequestHandler = async ({ params, request, platform }) => {
110129
badRequestError('You have already voted in this session');
111130
}
112131

113-
const voterExists = participants.some((p) => p.id === voterId);
114-
if (!voterExists) {
115-
badRequestError('Voter is not a participant in this session');
116-
}
117-
118-
if (vote.participants.some((s) => s.id === voterId)) {
119-
badRequestError('You cannot vote for yourself');
120-
}
121-
122132
const allShareParticipantsExist = vote.participants.every((s) =>
123133
participants.some((p) => p.id === s.id)
124134
);

0 commit comments

Comments
 (0)