Skip to content

Commit e9c7b6d

Browse files
authored
chore: eVoting fixes (#305)
1 parent 0420efc commit e9c7b6d

File tree

9 files changed

+1068
-895
lines changed

9 files changed

+1068
-895
lines changed

infrastructure/eid-wallet/src/routes/(app)/scan-qr/+page.svelte

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,86 +1171,6 @@
11711171
{signingData?.pollId ?? "Unknown"}
11721172
</p>
11731173
</div>
1174-
1175-
<div class="bg-gray rounded-2xl w-full p-4">
1176-
<h4 class="text-base text-black-700">Your Vote</h4>
1177-
<div class="text-black-700 font-normal">
1178-
{#if signingData?.voteData?.optionId !== undefined}
1179-
<!-- Normal voting mode -->
1180-
<p>
1181-
You selected: <strong
1182-
>Option {parseInt(signingData.voteData.optionId) +
1183-
1}</strong
1184-
>
1185-
</p>
1186-
<p class="text-sm text-gray-600 mt-1">
1187-
(This is the option number from the poll)
1188-
</p>
1189-
{:else if signingData?.voteData?.ranks}
1190-
<!-- Ranked voting mode -->
1191-
<p class="mb-2">Your ranking order:</p>
1192-
<div class="space-y-2">
1193-
{#each Object.entries(signingData.voteData.ranks).sort(([a], [b]) => parseInt(a) - parseInt(b)) as [rank, optionIndex]}
1194-
<div
1195-
class="flex items-center space-x-3 p-2 bg-blue-50 rounded-lg"
1196-
>
1197-
<span
1198-
class="text-sm bg-blue-500 text-white px-3 py-1 rounded-full font-medium"
1199-
>
1200-
{rank === "1"
1201-
? "1st"
1202-
: rank === "2"
1203-
? "2nd"
1204-
: rank === "3"
1205-
? "3rd"
1206-
: `${rank}th`}
1207-
</span>
1208-
<span class="font-medium"
1209-
>Option {parseInt(String(optionIndex)) +
1210-
1}</span
1211-
>
1212-
</div>
1213-
{/each}
1214-
</div>
1215-
<p class="text-sm text-gray-600 mt-2">
1216-
(1st = most preferred, 2nd = second choice, etc.)
1217-
</p>
1218-
{:else if signingData?.voteData?.points}
1219-
<!-- Points voting mode -->
1220-
<p class="mb-2">Your point distribution:</p>
1221-
<div class="space-y-2">
1222-
{#each Object.entries(signingData.voteData.points)
1223-
.filter(([_, points]) => (points as number) > 0)
1224-
.sort(([a], [b]) => parseInt(a) - parseInt(b)) as [optionIndex, points]}
1225-
<div
1226-
class="flex items-center space-x-3 p-2 bg-purple-50 rounded-lg"
1227-
>
1228-
<span
1229-
class="text-sm bg-purple-500 text-white px-3 py-1 rounded-full font-medium"
1230-
>
1231-
{points} pts
1232-
</span>
1233-
<span class="font-medium"
1234-
>Option {parseInt(String(optionIndex)) +
1235-
1}</span
1236-
>
1237-
</div>
1238-
{/each}
1239-
</div>
1240-
<p class="text-sm text-gray-600 mt-2">
1241-
(Total: {Object.values(
1242-
signingData.voteData.points,
1243-
).reduce(
1244-
(sum, points) =>
1245-
(sum as number) + ((points as number) || 0),
1246-
0,
1247-
)}/100 points)
1248-
</p>
1249-
{:else}
1250-
<p>Vote data not available</p>
1251-
{/if}
1252-
</div>
1253-
</div>
12541174
{:else if isBlindVotingRequest && signingData?.pollDetails}
12551175
<!-- Blind Voting UI -->
12561176
<div class="blind-voting-section">

platforms/eVoting/src/app/(app)/[id]/page.tsx

Lines changed: 530 additions & 505 deletions
Large diffs are not rendered by default.

platforms/eVoting/src/app/(app)/create/page.tsx

Lines changed: 63 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ const createPollSchema = z.object({
3535
.min(2, "At least 2 options required"),
3636
deadline: z
3737
.string()
38-
.optional()
38+
.min(1, "Deadline is required")
3939
.refine((val) => {
40-
if (!val) return true; // Allow empty deadline
4140
const date = new Date(val);
4241
return !Number.isNaN(date.getTime()) && date > new Date();
4342
}, "Deadline must be a valid future date"),
@@ -217,15 +216,16 @@ export default function CreatePoll() {
217216
{/* Vote Deadline */}
218217
<div>
219218
<Label className="text-sm font-semibold text-gray-700">
220-
Vote Deadline (Optional)
219+
Vote Deadline
221220
</Label>
222221
<Input
223222
{...register("deadline")}
224223
type="datetime-local"
225224
className="mt-2 focus:ring-(--crimson) focus:border-(--crimson)"
225+
required
226226
/>
227227
<p className="mt-1 text-sm text-gray-500">
228-
Leave empty for no deadline. Voting will be open indefinitely.
228+
Set a deadline for when voting will end.
229229
</p>
230230
{errors.deadline && (
231231
<p className="mt-1 text-sm text-red-600">
@@ -234,6 +234,59 @@ export default function CreatePoll() {
234234
)}
235235
</div>
236236

237+
{/* Vote Visibility */}
238+
<div>
239+
<Label className="text-sm font-semibold text-gray-700">
240+
Vote Visibility
241+
</Label>
242+
<div className="mt-2 space-y-3">
243+
<Label className={`flex items-center cursor-pointer p-4 border-2 rounded-lg transition-all duration-200 ${
244+
watchedVisibility === "public"
245+
? "border-(--crimson) bg-(--crimson) text-white"
246+
: "border-gray-300 hover:border-gray-400"
247+
}`}>
248+
<input
249+
type="radio"
250+
value="public"
251+
{...register("visibility")}
252+
className="sr-only"
253+
/>
254+
<div className="flex items-center">
255+
<Eye className="w-6 h-6 mr-3" />
256+
<div>
257+
<div className="font-semibold">Public</div>
258+
<div className="text-sm opacity-90">Voters are public</div>
259+
</div>
260+
</div>
261+
</Label>
262+
263+
<Label className={`flex items-center cursor-pointer p-4 border-2 rounded-lg transition-all duration-200 ${
264+
watchedVisibility === "private"
265+
? "border-(--crimson) bg-(--crimson) text-white"
266+
: "border-gray-300 hover:border-gray-400"
267+
}`}>
268+
<input
269+
type="radio"
270+
value="private"
271+
{...register("visibility")}
272+
className="sr-only"
273+
/>
274+
<div className="flex items-center">
275+
<UserX className="w-6 h-6 mr-3" />
276+
<div>
277+
<div className="font-semibold">Private</div>
278+
<div className="text-sm opacity-90">Voters are hidden</div>
279+
</div>
280+
</div>
281+
</Label>
282+
</div>
283+
{errors.visibility && (
284+
<p className="mt-1 text-sm text-red-600">
285+
{errors.visibility.message}
286+
</p>
287+
)}
288+
</div>
289+
237290
{/* Vote Type */}
238291
<div>
239292
<Label className="text-sm font-semibold text-gray-700">
@@ -263,13 +316,16 @@ export default function CreatePoll() {
263316
<Label className={`flex items-center cursor-pointer p-4 border-2 rounded-lg transition-all duration-200 ${
264317
watchedMode === "point"
265318
? "border-(--crimson) bg-(--crimson) text-white"
319+
: watchedVisibility === "private"
320+
? "border-gray-300 bg-gray-100 opacity-50 cursor-not-allowed"
266321
: "border-gray-300 hover:border-gray-400"
267322
}`}>
268323
<input
269324
type="radio"
270325
value="point"
271326
{...register("mode")}
272327
className="sr-only"
328+
disabled={watchedVisibility === "private"}
273329
/>
274330
<div className="flex items-center">
275331
<ChartLine className="w-6 h-6 mr-3" />
@@ -283,13 +339,16 @@ export default function CreatePoll() {
283339
<Label className={`flex items-center cursor-pointer p-4 border-2 rounded-lg transition-all duration-200 ${
284340
watchedMode === "rank"
285341
? "border-(--crimson) bg-(--crimson) text-white"
342+
: watchedVisibility === "private"
343+
? "border-gray-300 bg-gray-100 opacity-50 cursor-not-allowed"
286344
: "border-gray-300 hover:border-gray-400"
287345
}`}>
288346
<input
289347
type="radio"
290348
value="rank"
291349
{...register("mode")}
292350
className="sr-only"
351+
disabled={watchedVisibility === "private"}
293352
/>
294353
<div className="flex items-center">
295354
<ListOrdered className="w-6 h-6 mr-3" />
@@ -363,59 +422,6 @@ export default function CreatePoll() {
363422
<p className="mt-2 text-sm text-gray-500">Coming soon - currently disabled</p>
364423
</div>
365424

366-
{/* Vote Visibility */}
367-
<div>
368-
<Label className="text-sm font-semibold text-gray-700">
369-
Vote Visibility
370-
</Label>
371-
<div className="mt-2 space-y-3">
372-
<Label className={`flex items-center cursor-pointer p-4 border-2 rounded-lg transition-all duration-200 ${
373-
watchedVisibility === "public"
374-
? "border-(--crimson) bg-(--crimson) text-white"
375-
: "border-gray-300 hover:border-gray-400"
376-
}`}>
377-
<input
378-
type="radio"
379-
value="public"
380-
{...register("visibility")}
381-
className="sr-only"
382-
/>
383-
<div className="flex items-center">
384-
<Eye className="w-6 h-6 mr-3" />
385-
<div>
386-
<div className="font-semibold">Public</div>
387-
<div className="text-sm opacity-90">Voters are public</div>
388-
</div>
389-
</div>
390-
</Label>
391-
392-
<Label className={`flex items-center cursor-pointer p-4 border-2 rounded-lg transition-all duration-200 ${
393-
watchedVisibility === "private"
394-
? "border-(--crimson) bg-(--crimson) text-white"
395-
: "border-gray-300 hover:border-gray-400"
396-
}`}>
397-
<input
398-
type="radio"
399-
value="private"
400-
{...register("visibility")}
401-
className="sr-only"
402-
/>
403-
<div className="flex items-center">
404-
<UserX className="w-6 h-6 mr-3" />
405-
<div>
406-
<div className="font-semibold">Private</div>
407-
<div className="text-sm opacity-90">Voters are hidden</div>
408-
</div>
409-
</div>
410-
</Label>
411-
</div>
412-
{errors.visibility && (
413-
<p className="mt-1 text-sm text-red-600">
414-
{errors.visibility.message}
415-
</p>
416-
)}
417-
</div>
418-
419425
{/* Vote Options */}
420426
<div>
421427
<Label className="text-sm font-semibold text-gray-700">

0 commit comments

Comments
 (0)