From f208299f1b623d89977aba9c03a2273a22c0c9e0 Mon Sep 17 00:00:00 2001 From: Sabine Maennel <5292683+sabinem@users.noreply.github.com> Date: Wed, 2 Sep 2026 07:05:48 +0200 Subject: [PATCH] style(frontend): the organizer's participant page reads like the member's MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `participants/[participantId]` was set to be read in 648e77ee0b; this page was left in the shape that one had before it — every sentence 12px mono at the width of the window, two type sizes for the whole page, and each answer running its question into its value on one line, so a question and its answer read as a single sentence with no column to scan. The same treatment, deliberately identical rather than merely similar: capped column, a card per section, `text-section` headings, sentences in `.prose`, and the answers in a two-column grid with the question quieter beside the value. The two pages show one person and differ only in what they may say and do about them, so an organizer moving between them should be reading one page in two states rather than learning a second layout. Nothing an organizer acts on is changed: the email line, the Shared chips, Approve, Make owner, Remove owner, the two-step removal and its reset when the page swaps to another person, and the note explaining why an owner has no Remove button. Answers still render through `AnswerText`, and the value keeps `min-w-0 break-words` so a pasted address wraps rather than widening the column. --- .../lib/components/layout/AppFooter.svelte | 20 +++- .../frontend/src/lib/utils/imageUrl.test.ts | 2 +- .../manage/[participantId]/+page.svelte | 101 ++++++++++++------ 3 files changed, 84 insertions(+), 39 deletions(-) diff --git a/components/frontend/src/lib/components/layout/AppFooter.svelte b/components/frontend/src/lib/components/layout/AppFooter.svelte index 76deb9a2..88930ac8 100644 --- a/components/frontend/src/lib/components/layout/AppFooter.svelte +++ b/components/frontend/src/lib/components/layout/AppFooter.svelte @@ -125,9 +125,23 @@ canvas. Keep any replacement asset white-on-transparent. Heights differ because a shared box height is not a shared apparent - size. Measured against EPFL's cap height, PSI's lettering fills 48% + size. Measured against EPFL's cap height, PSI's lettering fills 50% of its asset and Biopôle's 55%, the rest being their graphic marks — - so h-5 for those two against h-4 for the two bare wordmarks. --> + so h-5 for those two against h-4 for the two bare wordmarks. + + PSI is the one that had to be vector rather than a PNG. Its mark is + a stipple — a cloud of separate dots — and a 91x40 bitmap of that + scaled down to 20px moirés into a mottled blob on any 1x display, + which is what "the logo looks brownish" turned out to be. Nothing + tinted it: every pixel of that PNG was neutral grey. It was the + dither collapsing. Vector dots stay dots at every DPI. + + Source: commons.wikimedia.org/wiki/File:Paul_Scherrer_Institute_Logo.svg + ({{PD-textlogo}} — simple shapes and text, below the threshold of + originality, so public domain; the trademark is PSI's and this is + nominative use, same as the three beside it). Recoloured white on + the root ; the file declares no other fill, which is why one + attribute is enough. -->
EPFL @@ -145,7 +159,7 @@ rel="noopener noreferrer" class={LOGO_LINK} > - PSI + PSI { it("rejects what is not a web address", () => { expect(adviseImageUrl("logo.png").problem).toMatch(/https:\/\//) - expect(adviseImageUrl("/images/logos/psi.png").problem).toMatch( + expect(adviseImageUrl("/images/logos/psi.svg").problem).toMatch( /https:\/\//, ) }) diff --git a/components/frontend/src/routes/(app)/my/hackathon/[id]/participants/manage/[participantId]/+page.svelte b/components/frontend/src/routes/(app)/my/hackathon/[id]/participants/manage/[participantId]/+page.svelte index b0edb419..f74429aa 100644 --- a/components/frontend/src/routes/(app)/my/hackathon/[id]/participants/manage/[participantId]/+page.svelte +++ b/components/frontend/src/routes/(app)/my/hackathon/[id]/participants/manage/[participantId]/+page.svelte @@ -70,8 +70,15 @@ This is also the only page that shows an organizer the *whole* registration form. `participants/[participantId]` stays the participant view and shows the shared answers only, to an organizer included. + + Set the same way as that page, deliberately: same capped column, same card per + section, same two-column answer grid, same type roles. The two show one person + and differ only in what they are allowed to say and do about them, so an + organizer moving between them should be reading the same page in two states + rather than learning a second layout. --> -
+
+
-

Registration answers

+
+

Registration answers

{#if data.answersFailed} -

+

Answers could not be loaded. Reload the page to try again.

{:else if data.questionCount === 0} -

+

This hackathon's registration form asks nothing yet.

{:else if data.answers.length === 0} -

+

{data.participant.name} has not answered the registration form.

{:else} @@ -142,59 +149,82 @@ here, including the ones the event keeps between the organizers and the applicant — the chip marks which of them the rest of the hackathon can also read. --> -
+
{#each data.answers as answer (answer.questionId)} -
-
{answer.label}
- -
+ +
+ {answer.label} +
+ +
+ -
+ {#if answer.publicAnswers} Shared {/if} -
+ {/each}
{/if}
-
-

Teams

+
+

Teams

{#if !data.teamsPublished} -

+

Team assignments have not been published in this hackathon yet.

{:else if data.teamsFailed} -

+

Teams could not be loaded. Reload the page to try again.

{:else if data.teams.length === 0} -

+

{data.participant.name} is not on a team in this hackathon yet.

{:else} - {#each data.teams as team (team.id)} -
- {team.name} - {#if team.projectTitle} - {team.projectTitle} - {/if} - - {/each} + + {/if}
-
-

Manage

+
+

Manage

{#if form?.message} @@ -209,7 +239,7 @@ project reject form takes the page over: nothing else here should be one mis-click away from a deletion. -->
-

+

{#if data.participant.isWaiting} Declining deletes {data.participant.name}'s application. There is no rejected state to come back to — they can ask to join again, and @@ -276,7 +306,7 @@ {#if data.isOwner} -

+

{#if data.isMe} You cannot remove your own owner role here — it is what this page runs on. Another owner can, on this page. @@ -288,4 +318,5 @@ {/if} {/if}

+