feat(board): replace board/peer support with posts list on member profile

This commit is contained in:
Jennie Robinson Faber 2026-04-14 17:22:04 +01:00
parent 698f786951
commit f8bc5502ba

View file

@ -108,15 +108,10 @@
<div class="profile-bio" v-html="renderMarkdown(member.bio)"></div> <div class="profile-bio" v-html="renderMarkdown(member.bio)"></div>
</div> </div>
<!-- Two-column: Craft Tags + Board --> <!-- Craft Tags -->
<div <div v-if="craftTagsDisplay.length > 0" class="profile-section">
v-if="craftTagsDisplay.length > 0 || boardTopics.length > 0 || member.board?.details"
class="profile-two-col"
>
<!-- Left: What I Do -->
<div class="profile-section">
<div class="section-label">What I Do</div> <div class="section-label">What I Do</div>
<div v-if="craftTagsDisplay.length > 0" class="tag-list"> <div class="tag-list">
<span <span
v-for="tag in craftTagsDisplay" v-for="tag in craftTagsDisplay"
:key="tag" :key="tag"
@ -125,39 +120,27 @@
</div> </div>
</div> </div>
<!-- Right: Board --> <!-- Board Posts -->
<div class="profile-section"> <div class="profile-section">
<div class="section-label">Board</div> <div class="section-label">Board Posts</div>
<div v-if="boardTopics.length > 0" class="tag-list"> <p v-if="memberPosts.length === 0" class="profile-detail posts-empty">
No posts yet.
</p>
<ul v-else class="posts-list">
<li v-for="post in memberPosts" :key="post._id" class="post-item">
<NuxtLink to="/board" class="post-link">
<div class="post-title">{{ post.title }}</div>
<div class="post-excerpt">{{ postExcerpt(post) }}</div>
<div v-if="post.tags && post.tags.length" class="tag-list post-tags">
<span <span
v-for="topic in boardTopics" v-for="tag in post.tags"
:key="topic.tagSlug" :key="tag"
class="tag-pill connection-pill" class="tag-pill"
> >{{ tagLabel('cooperative', tag) }}</span>
<span v-if="topic.state" class="connection-state">{{ stateLabel(topic.state) }}</span>
{{ tagLabel('cooperative', topic.tagSlug) }}
</span>
</div>
<p v-if="member.board?.details" class="profile-detail connection-details">
{{ member.board.details }}
</p>
</div>
</div>
<!-- Peer Support -->
<div v-if="member.board?.offerPeerSupport" class="profile-section">
<div class="section-label">Peer Support</div>
<div class="dashed-box no-hover">
<p v-if="member.board?.personalMessage" class="profile-detail">
{{ member.board.personalMessage }}
</p>
<p v-if="member.board?.availability" class="profile-detail peer-availability">
{{ member.board.availability }}
</p>
<p v-if="member.board?.slackHandle" class="profile-detail peer-availability">
Reach out on Slack: <span class="slack-handle">@{{ member.board.slackHandle }}</span>
</p>
</div> </div>
</NuxtLink>
</li>
</ul>
</div> </div>
<!-- Recent Activity --> <!-- Recent Activity -->
@ -217,15 +200,6 @@ const circleLabels = {
practitioner: "Practitioner", practitioner: "Practitioner",
}; };
// State display text mapping
const stateLabels = {
help: "Can help",
interested: "Interested",
seeking: "Need help",
};
const stateLabel = (state) => stateLabels[state] || state || "";
const getInitials = (name) => { const getInitials = (name) => {
if (!name) return "?"; if (!name) return "?";
return name return name
@ -274,9 +248,19 @@ const tagLabel = (pool, slug) => {
const craftTagsDisplay = computed(() => member.value?.craftTags || []); const craftTagsDisplay = computed(() => member.value?.craftTags || []);
const boardTopics = computed( // Board posts authored by this member
() => member.value?.board?.topics || [], const memberPosts = ref([]);
); onMounted(async () => {
const { fetchPosts } = useBoardPosts();
const result = await fetchPosts({ author: id });
memberPosts.value = result || [];
});
const postExcerpt = (post) => {
const text = post.seeking || post.offering || "";
if (text.length <= 80) return text;
return text.slice(0, 80).trimEnd() + "...";
};
// Whether the member has any social links (for hero layout) // Whether the member has any social links (for hero layout)
const hasSocialLinks = computed(() => const hasSocialLinks = computed(() =>
@ -507,22 +491,6 @@ useHead({
color: var(--ember); color: var(--ember);
} }
/* ====================================================
TWO-COLUMN: Craft Tags + Board
==================================================== */
.profile-two-col {
display: grid;
grid-template-columns: 1fr 1fr;
border-bottom: 1px dashed var(--border);
}
.profile-two-col .profile-section {
border-bottom: none;
}
.profile-two-col .profile-section:first-child {
border-right: 1px dashed var(--border);
}
/* ==================================================== /* ====================================================
SHARED SECTION ELEMENTS SHARED SECTION ELEMENTS
==================================================== */ ==================================================== */
@ -533,9 +501,6 @@ useHead({
line-height: 1.6; line-height: 1.6;
margin: 0; margin: 0;
} }
.connection-details {
margin-top: 10px;
}
/* Tags */ /* Tags */
.tag-list { .tag-list {
@ -551,30 +516,47 @@ useHead({
border: 1px dashed var(--border); border: 1px dashed var(--border);
white-space: nowrap; white-space: nowrap;
} }
.connection-pill {
display: inline-flex;
align-items: center;
gap: 4px;
}
.connection-state {
font-size: 9px;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--text-faint);
}
/* ==================================================== /* ====================================================
PEER SUPPORT BOARD POSTS
==================================================== */ ==================================================== */
.peer-availability { .posts-empty {
margin-top: 12px; color: var(--text-faint);
padding-top: 12px; }
.posts-list {
list-style: none;
margin: 0;
padding: 0;
}
.post-item {
border-top: 1px dashed var(--border); border-top: 1px dashed var(--border);
} }
.slack-handle { .post-item:last-child {
font-family: "Commit Mono", monospace; border-bottom: 1px dashed var(--border);
color: var(--candle-dim); }
.post-link {
display: block;
padding: 10px 0;
text-decoration: none;
color: inherit;
}
.post-link:hover .post-title {
color: var(--candle);
}
.post-title {
font-size: 13px;
color: var(--text);
margin-bottom: 2px;
transition: color 0.15s;
}
.post-excerpt {
font-size: 11px;
color: var(--text-faint);
line-height: 1.4;
}
.post-tags {
margin-top: 6px;
} }
/* ==================================================== /* ====================================================
@ -666,17 +648,6 @@ useHead({
RESPONSIVE RESPONSIVE
==================================================== */ ==================================================== */
@media (max-width: 1024px) {
/* ColumnsLayout events-sidebar hides itself at ≤1024px */
.profile-two-col {
grid-template-columns: 1fr;
}
.profile-two-col .profile-section:first-child {
border-right: none;
border-bottom: 1px dashed var(--border);
}
}
@media (max-width: 768px) { @media (max-width: 768px) {
.profile-hero, .profile-hero,
.profile-hero--with-links { .profile-hero--with-links {