Profile page: Edit profile, Projects and Drops as one even group (closes #328) b951c58734e8
They sat on two rows, touching each other and the panel below. Now one
grid: Edit profile across the top, the two pages side by side, with
even gaps around.
Author Andy McCall @andymccall <[email protected] >
via ↳ agent agent:claude@andymccall <[email protected] > · keyless, under your grant for changes,refs,seal · key e003995a1df4
When 9 days ago · 2026-10-26 10:50 UTC
Signature ◈ sealed by agent:claude@andymccall
Hash b951c58734e86e85465b9f0ecc65ea5642d3dedcf5e3ef481ca32c9790c15dfe
Depends on 101740454617 166f6e9bf4f1 18e381ea88c2 89e89836cae7 d23464c0ac60
Depended on by nothing yet
In bookmarks api-unknown-fields diffusion-pin-bookmark main proposal-list-fast
In tags v0.9.11 v0.9.15 v0.9.16 v0.9.19 v0.9.20 v0.9.21 v0.9.22 v0.9.23 v0.9.24 v0.9.7 v0.9.8 v0.9.9
Edits 5 atoms, 0 tree operations, 3 files
Browse the tree at this change
crates/hub/tests/issues.rs templates/profile.html templates/style.css
modified
crates/hub/tests/issues.rs
+8 −2
…
606 unchanged lines
607
607
assert!(!page.body.contains("<b>oxy</b>"), "the bio is escaped");
608
608
assert!(!page.body.contains("[email protected] "), "the email stays private");
609
609
assert!(!page.body.contains("/andy/hidden"), "bob cannot see the private repository");
610
-
assert!(!page.body.contains("edit profile"), "only the owner gets the edit link");
611
-
assert!( get(app, "/andy", Some(&andy)).await.body.contains("/andy/hidden"), "andy sees his own private repository") ;
610
+
assert!(!page.body.contains("Edit profile"), "only the owner gets the edit link");
611
+
let own = get(app, "/andy", Some(&andy)).await.body;
612
+
assert!(own.contains("/andy/hidden"), "andy sees his own private repository");
613
+
// #328: his page's actions are one group, Edit profile across the top.
614
+
assert!(
615
+
own.contains(r#"<nav class="profile-actions""#) && own.contains(r#"class="go wide" href="/settings">Edit profile</a>"#),
616
+
"{own}"
617
+
);
612
618
613
619
let page = get(app, "/retro", Some(&bob)).await;
614
620
assert_eq!(page.status, StatusCode::OK);
…
585 unchanged lines
modified
templates/profile.html
+5 −2
…
14 unchanged lines
15
15
{% if !account.github.is_empty() %}<li class="social"><svg class="icon" viewBox="0 0 24 24" width="14" height="14" aria-hidden="true"><path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg> <a href="{{ crate::social::github_url(account.github) }}" rel="nofollow noopener me" title="GitHub">{{ account.github }}</a></li>{% endif %}
16
16
<li class="mute">joined <time title="{{ account.created_ms|when_i }}">{{ account.created_ms|ago_i }}</time></li>
17
17
</ul>
18
-
{% if is_me %}<a class="go small" href="/settings">edit profile</a>{% endif %}
19
-
<p><a class="go small" href="/projects/{ { account.username }}">Projects</a> <a class="go small " href="/{{ account.username }}/drops ">Drops </a></p>
18
+
<nav class="profile-actions" aria-label="{{ account.username }}'s pages">
19
+
{% if is_me %} <a class="go wide " href="/settings ">Edit profile </a>{% endif %}
20
+
<a class="go" href="/projects/{{ account.username }}">Projects</a>
21
+
<a class="go" href="/{{ account.username }}/drops">Drops</a>
22
+
</nav>
20
23
{% if !orgs.is_empty() %}
21
24
<section class="side-card"><h3>Organisations <span class="count-chip">{{ orgs.len() }}</span></h3><div class="body">
22
25
<ul class="plain">{% for (o, role) in orgs %}<li><img class="avatar xs" src="/avatar/{{ o.name }}" alt=""> <a href="/{{ o.name }}">{{ o.name }}</a>{% if role == "owner" %} <span class="small mute">owner</span>{% endif %}</li>{% endfor %}</ul>
…
18 unchanged lines
modified
templates/style.css
+4 −0
…
407 unchanged lines
408
408
.profile .who-card .bio { margin: 0 0 10px; }
409
409
.profile .who-card .facts-list li { padding: 2px 0; }
410
410
.profile .who-card .facts-list li.social .icon { vertical-align: -2px; }
411
+
/* Profile actions (#328): one even group, Edit profile across, the pages below. */
412
+
.profile-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 14px 0 18px; }
413
+
.profile-actions a.go { display: block; text-align: center; padding: 6px 10px; }
414
+
.profile-actions a.go.wide { grid-column: 1 / -1; }
411
415
.profile h2 { font-size: 15px; margin: 0 0 8px; }
412
416
.profile h2 ~ h2 { margin-top: 18px; }
413
417
.profile .keys li { margin-bottom: 6px; }
…
957 unchanged lines