Rename communityEcology → board across frontend, add Board nav, update redirects
- Add Board to exploreItems in AppNavigation - Update ecology.vue + connections.vue redirects to /board - Rename all communityEcology refs to board in member profiles, dashboard, admin, onboarding - Update API path /api/members/me/community-ecology → /api/members/me/board
This commit is contained in:
parent
3e5cedb1a6
commit
cdef868256
9 changed files with 75 additions and 76 deletions
|
|
@ -210,6 +210,7 @@ const youItems = [
|
|||
const exploreItems = [
|
||||
{ label: "Events", path: "/events" },
|
||||
{ label: "Members", path: "/members" },
|
||||
{ label: "Board", path: "/board" },
|
||||
{ label: "Wiki", path: "https://wiki.ghostguild.org", external: true },
|
||||
{ label: "About", path: "/about" },
|
||||
];
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ const { goals, isComplete, currentSuggestion, trackGoal, loading } = useOnboardi
|
|||
|
||||
const completedCount = computed(() => {
|
||||
const g = goals.value
|
||||
return [g.hasProfileTags, g.hasVisitedEvent, g.hasEngagedEcology, g.hasClickedWiki]
|
||||
return [g.hasProfileTags, g.hasVisitedEvent, g.hasEngagedBoard, g.hasClickedWiki]
|
||||
.filter(Boolean).length
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export function useOnboarding(options = {}) {
|
|||
const goals = useState('onboarding.goals', () => ({
|
||||
hasProfileTags: false,
|
||||
hasVisitedEvent: false,
|
||||
hasEngagedEcology: false,
|
||||
hasEngagedBoard: false,
|
||||
hasClickedWiki: false,
|
||||
}))
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ export function useOnboarding(options = {}) {
|
|||
const loading = useState('onboarding.loading', () => false)
|
||||
const recommendations = useState('onboarding.recommendations', () => ({
|
||||
events: [],
|
||||
ecology: [],
|
||||
board: [],
|
||||
wiki: [],
|
||||
}))
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ export function useOnboarding(options = {}) {
|
|||
!!completedAt.value ||
|
||||
(goals.value.hasProfileTags &&
|
||||
goals.value.hasVisitedEvent &&
|
||||
goals.value.hasEngagedEcology &&
|
||||
goals.value.hasEngagedBoard &&
|
||||
goals.value.hasClickedWiki)
|
||||
)
|
||||
|
||||
|
|
@ -52,12 +52,12 @@ export function useOnboarding(options = {}) {
|
|||
actionText: 'Browse events',
|
||||
}
|
||||
}
|
||||
if (!goals.value.hasEngagedEcology) {
|
||||
if (!goals.value.hasEngagedBoard) {
|
||||
return {
|
||||
key: 'ecology',
|
||||
text: 'Explore the community ecology to find collaborators',
|
||||
action: '/ecology',
|
||||
actionText: 'Explore ecology',
|
||||
key: 'board',
|
||||
text: 'Explore the board to find collaborators',
|
||||
action: '/board',
|
||||
actionText: 'Explore board',
|
||||
}
|
||||
}
|
||||
if (!goals.value.hasClickedWiki) {
|
||||
|
|
@ -72,7 +72,7 @@ export function useOnboarding(options = {}) {
|
|||
}
|
||||
|
||||
// Graduated — suggestion mode
|
||||
const cats = ['events', 'ecology', 'wiki'].filter(
|
||||
const cats = ['events', 'board', 'wiki'].filter(
|
||||
(c) => recommendations.value[c]?.length > 0
|
||||
)
|
||||
|
||||
|
|
@ -99,12 +99,12 @@ export function useOnboarding(options = {}) {
|
|||
actionText: 'View event',
|
||||
}
|
||||
}
|
||||
if (category === 'ecology') {
|
||||
if (category === 'board') {
|
||||
return {
|
||||
key: 'ecology',
|
||||
text: `Connect with ${item.name || 'a member'} in the ecology`,
|
||||
action: '/ecology',
|
||||
actionText: 'Explore ecology',
|
||||
key: 'board',
|
||||
text: `Connect with ${item.name || 'a member'} on the board`,
|
||||
action: '/board',
|
||||
actionText: 'Explore board',
|
||||
}
|
||||
}
|
||||
if (category === 'wiki') {
|
||||
|
|
@ -144,14 +144,14 @@ export function useOnboarding(options = {}) {
|
|||
}
|
||||
|
||||
async function fetchRecommendations() {
|
||||
const [events, ecology, wiki] = await Promise.allSettled([
|
||||
const [events, board, wiki] = await Promise.allSettled([
|
||||
$fetch('/api/events/recommended'),
|
||||
$fetch('/api/ecology/suggestions'),
|
||||
$fetch('/api/board/suggestions'),
|
||||
$fetch('/api/wiki/recommended'),
|
||||
])
|
||||
recommendations.value = {
|
||||
events: events.status === 'fulfilled' ? (events.value || []) : [],
|
||||
ecology: ecology.status === 'fulfilled' ? (ecology.value?.suggestions || []) : [],
|
||||
board: board.status === 'fulfilled' ? (board.value?.suggestions || []) : [],
|
||||
wiki: wiki.status === 'fulfilled' ? (wiki.value || []) : [],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -351,13 +351,13 @@ function statusClass(status) {
|
|||
const hasProfileTags = computed(() => {
|
||||
const m = member.value
|
||||
if (!m) return false
|
||||
return m.craftTags?.length > 0 && m.communityEcology?.topics?.length > 0
|
||||
return m.craftTags?.length > 0 && m.board?.topics?.length > 0
|
||||
})
|
||||
|
||||
const hasEcologyEngaged = computed(() => {
|
||||
const m = member.value
|
||||
if (!m) return false
|
||||
return m.onboarding?.ecologyPageVisited && m.communityEcology?.topics?.some(
|
||||
return m.onboarding?.boardPageVisited && m.board?.topics?.some(
|
||||
t => ['help', 'interested', 'seeking'].includes(t.state)
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
<script setup>
|
||||
definePageMeta({ middleware: "auth" });
|
||||
await navigateTo("/members?view=ecology", { replace: true });
|
||||
await navigateTo("/board", { replace: true });
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
<script setup>
|
||||
definePageMeta({ middleware: "auth" });
|
||||
await navigateTo("/members?view=ecology", { replace: true });
|
||||
await navigateTo("/board", { replace: true });
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -120,16 +120,16 @@
|
|||
<div class="content-block">
|
||||
<div class="section-label">Quick Actions</div>
|
||||
<NuxtLink
|
||||
to="/ecology"
|
||||
to="/board"
|
||||
class="quick-action"
|
||||
:class="{ disabled: !canPeerSupport }"
|
||||
:title="
|
||||
!canPeerSupport
|
||||
? 'Complete your membership to access community ecology'
|
||||
? 'Complete your membership to access the board'
|
||||
: ''
|
||||
"
|
||||
>
|
||||
Community ecology<span class="arrow">→</span>
|
||||
Board<span class="arrow">→</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/member/profile" class="quick-action">
|
||||
Update your profile<span class="arrow">→</span>
|
||||
|
|
@ -198,8 +198,8 @@
|
|||
Connect with other members through shared interests and
|
||||
cooperative topics.
|
||||
</p>
|
||||
<NuxtLink to="/ecology" class="section-link">
|
||||
Browse community ecology →
|
||||
<NuxtLink to="/board" class="section-link">
|
||||
Browse the board →
|
||||
</NuxtLink>
|
||||
</DashedBox>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -162,34 +162,34 @@
|
|||
|
||||
<template #right>
|
||||
<PageSection>
|
||||
<div class="section-label">Community Ecology</div>
|
||||
<div class="section-label">Board</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Topics</label>
|
||||
<CooperativeTagSelector
|
||||
v-model="formData.communityEcologyTopics"
|
||||
v-model="formData.boardTopics"
|
||||
:tags="cooperativeTags"
|
||||
@suggest="openTagSuggest('cooperative')"
|
||||
/>
|
||||
<PrivacyToggle v-model="formData.communityEcologyPrivacy" />
|
||||
<PrivacyToggle v-model="formData.boardPrivacy" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Details</label>
|
||||
<textarea
|
||||
v-model="formData.communityEcologyDetails"
|
||||
v-model="formData.boardDetails"
|
||||
rows="3"
|
||||
placeholder="What are you hoping to connect about?"
|
||||
maxlength="300"
|
||||
></textarea>
|
||||
<div class="char-count">
|
||||
{{ formData.communityEcologyDetails?.length || 0 }} / 300
|
||||
{{ formData.boardDetails?.length || 0 }} / 300
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toggle-field">
|
||||
<USwitch
|
||||
v-model="formData.communityEcologyOfferPeerSupport"
|
||||
v-model="formData.boardOfferPeerSupport"
|
||||
aria-label="Offer Peer Support"
|
||||
/>
|
||||
<div class="toggle-label">
|
||||
|
|
@ -200,11 +200,11 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="formData.communityEcologyOfferPeerSupport" class="connections-panel">
|
||||
<div v-if="formData.boardOfferPeerSupport" class="connections-panel">
|
||||
<div class="field">
|
||||
<label>Availability</label>
|
||||
<textarea
|
||||
v-model="formData.communityEcologyAvailability"
|
||||
v-model="formData.boardAvailability"
|
||||
rows="3"
|
||||
placeholder="e.g. Weekday afternoons ET"
|
||||
></textarea>
|
||||
|
|
@ -213,7 +213,7 @@
|
|||
<div class="field">
|
||||
<label>Slack Handle</label>
|
||||
<input
|
||||
v-model="formData.communityEcologySlackHandle"
|
||||
v-model="formData.boardSlackHandle"
|
||||
type="text"
|
||||
placeholder="@yourslackname"
|
||||
/>
|
||||
|
|
@ -222,13 +222,13 @@
|
|||
<div class="field">
|
||||
<label>Personal Message</label>
|
||||
<textarea
|
||||
v-model="formData.communityEcologyPersonalMessage"
|
||||
v-model="formData.boardPersonalMessage"
|
||||
rows="3"
|
||||
maxlength="200"
|
||||
placeholder="Brief note shown alongside your Slack handle"
|
||||
></textarea>
|
||||
<div class="char-count">
|
||||
{{ formData.communityEcologyPersonalMessage?.length || 0 }} / 200
|
||||
{{ formData.boardPersonalMessage?.length || 0 }} / 200
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -339,13 +339,13 @@ const formData = reactive({
|
|||
showInDirectory: true,
|
||||
craftTags: [],
|
||||
craftTagsPrivacy: "members",
|
||||
communityEcologyTopics: [],
|
||||
communityEcologyPrivacy: "members",
|
||||
communityEcologyDetails: "",
|
||||
communityEcologyOfferPeerSupport: false,
|
||||
communityEcologyAvailability: "",
|
||||
communityEcologySlackHandle: "",
|
||||
communityEcologyPersonalMessage: "",
|
||||
boardTopics: [],
|
||||
boardPrivacy: "members",
|
||||
boardDetails: "",
|
||||
boardOfferPeerSupport: false,
|
||||
boardAvailability: "",
|
||||
boardSlackHandle: "",
|
||||
boardPersonalMessage: "",
|
||||
pronounsPrivacy: "members",
|
||||
timeZonePrivacy: "members",
|
||||
avatarPrivacy: "members",
|
||||
|
|
@ -387,13 +387,13 @@ const loadProfile = () => {
|
|||
? [...memberData.value.craftTags]
|
||||
: [];
|
||||
|
||||
const ecology = memberData.value.communityEcology || {};
|
||||
formData.communityEcologyTopics = Array.isArray(ecology.topics) ? [...ecology.topics] : [];
|
||||
formData.communityEcologyOfferPeerSupport = ecology.offerPeerSupport ?? false;
|
||||
formData.communityEcologyAvailability = ecology.availability || "";
|
||||
formData.communityEcologySlackHandle = ecology.slackHandle || "";
|
||||
formData.communityEcologyPersonalMessage = ecology.personalMessage || "";
|
||||
formData.communityEcologyDetails = ecology.details || "";
|
||||
const board = memberData.value.board || {};
|
||||
formData.boardTopics = Array.isArray(board.topics) ? [...board.topics] : [];
|
||||
formData.boardOfferPeerSupport = board.offerPeerSupport ?? false;
|
||||
formData.boardAvailability = board.availability || "";
|
||||
formData.boardSlackHandle = board.slackHandle || "";
|
||||
formData.boardPersonalMessage = board.personalMessage || "";
|
||||
formData.boardDetails = board.details || "";
|
||||
|
||||
const privacy = memberData.value.privacy || {};
|
||||
formData.pronounsPrivacy = privacy.pronouns || "members";
|
||||
|
|
@ -403,7 +403,7 @@ const loadProfile = () => {
|
|||
formData.bioPrivacy = privacy.bio || "members";
|
||||
formData.locationPrivacy = privacy.location || "members";
|
||||
formData.craftTagsPrivacy = privacy.craftTags || "members";
|
||||
formData.communityEcologyPrivacy = privacy.communityEcology || "members";
|
||||
formData.boardPrivacy = privacy.board || "members";
|
||||
|
||||
const notifs = memberData.value.notifications || {};
|
||||
formData.notifications.events = notifs.events ?? true;
|
||||
|
|
@ -423,15 +423,15 @@ const handleSubmit = async () => {
|
|||
method: "PATCH",
|
||||
body: { ...formData },
|
||||
}),
|
||||
$fetch("/api/members/me/community-ecology", {
|
||||
$fetch("/api/members/me/board", {
|
||||
method: "PATCH",
|
||||
body: {
|
||||
topics: formData.communityEcologyTopics,
|
||||
offerPeerSupport: formData.communityEcologyOfferPeerSupport,
|
||||
availability: formData.communityEcologyAvailability,
|
||||
slackHandle: formData.communityEcologySlackHandle,
|
||||
personalMessage: formData.communityEcologyPersonalMessage,
|
||||
details: formData.communityEcologyDetails,
|
||||
topics: formData.boardTopics,
|
||||
offerPeerSupport: formData.boardOfferPeerSupport,
|
||||
availability: formData.boardAvailability,
|
||||
slackHandle: formData.boardSlackHandle,
|
||||
personalMessage: formData.boardPersonalMessage,
|
||||
details: formData.boardDetails,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -108,9 +108,9 @@
|
|||
<div class="profile-bio" v-html="renderMarkdown(member.bio)"></div>
|
||||
</div>
|
||||
|
||||
<!-- Two-column: Craft Tags + Community Ecology -->
|
||||
<!-- Two-column: Craft Tags + Board -->
|
||||
<div
|
||||
v-if="craftTagsDisplay.length > 0 || ecologyTopics.length > 0 || member.communityEcology?.details"
|
||||
v-if="craftTagsDisplay.length > 0 || ecologyTopics.length > 0 || member.board?.details"
|
||||
class="profile-two-col"
|
||||
>
|
||||
<!-- Left: What I Do -->
|
||||
|
|
@ -125,9 +125,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right: Community Ecology -->
|
||||
<!-- Right: Board -->
|
||||
<div class="profile-section">
|
||||
<div class="section-label">Community Ecology</div>
|
||||
<div class="section-label">Board</div>
|
||||
<div v-if="ecologyTopics.length > 0" class="tag-list">
|
||||
<span
|
||||
v-for="topic in ecologyTopics"
|
||||
|
|
@ -138,24 +138,24 @@
|
|||
{{ tagLabel('cooperative', topic.tagSlug) }}
|
||||
</span>
|
||||
</div>
|
||||
<p v-if="member.communityEcology?.details" class="profile-detail connection-details">
|
||||
{{ member.communityEcology.details }}
|
||||
<p v-if="member.board?.details" class="profile-detail connection-details">
|
||||
{{ member.board.details }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Peer Support -->
|
||||
<div v-if="member.communityEcology?.offerPeerSupport" class="profile-section">
|
||||
<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.communityEcology?.personalMessage" class="profile-detail">
|
||||
{{ member.communityEcology.personalMessage }}
|
||||
<p v-if="member.board?.personalMessage" class="profile-detail">
|
||||
{{ member.board.personalMessage }}
|
||||
</p>
|
||||
<p v-if="member.communityEcology?.availability" class="profile-detail peer-availability">
|
||||
{{ member.communityEcology.availability }}
|
||||
<p v-if="member.board?.availability" class="profile-detail peer-availability">
|
||||
{{ member.board.availability }}
|
||||
</p>
|
||||
<p v-if="member.communityEcology?.slackHandle" class="profile-detail peer-availability">
|
||||
Reach out on Slack: <span class="slack-handle">@{{ member.communityEcology.slackHandle }}</span>
|
||||
<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>
|
||||
|
|
@ -275,7 +275,7 @@ const tagLabel = (pool, slug) => {
|
|||
const craftTagsDisplay = computed(() => member.value?.craftTags || []);
|
||||
|
||||
const ecologyTopics = computed(
|
||||
() => member.value?.communityEcology?.topics || [],
|
||||
() => member.value?.board?.topics || [],
|
||||
);
|
||||
|
||||
// Whether the member has any social links (for hero layout)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue