+
+
+
+
![]()
+
{{ getInitials(member.name) }}
-
-
-
-
-
-
-
No members found
-
Try adjusting your search or filters
-
-
+
-
- Showing {{ members.length }} of {{ totalCount }} member{{ totalCount === 1 ? '' : 's' }}
-
-
-
-
-
-
-
-
Loading ecology...
+
+ Craft:
+ {{ craftTagLabel(tag) }}
+ +{{ member.craftTags.length - 5 }}
+
+
-
-
-
-
No topics yet
-
- Add topics to your profile to find connections.
-
-
-
-
-
-
-
-
-
![]()
-
{{ getInitials(suggestion.member.name) }}
-
-
-
-
- {{ suggestion.member.name }}
-
-
-
-
-
-
-
-
-
- {{ craftTagLabel(tag) }}
- +{{ suggestion.member.craftTags.length - 5 }}
-
-
-
-
- {{ ecologyTagLabel(match.tagSlug) }}
-
- You: {{ stateLabel(match.yourState) }}
- ·
- They: {{ stateLabel(match.theirState) }}
-
-
-
-
-
- @{{ suggestion.member.slackHandle }}
-
-
-
-
-
-
-
-
No matches yet
-
- Add cooperative topics to your
- profile
- to find members with shared interests.
-
-
-
-
-
-
-
-
-
+
+
No members found
+
Try adjusting your search or filters
+
+
+
+ Showing {{ members.length }} of {{ totalCount }} member{{ totalCount === 1 ? '' : 's' }}
+
@@ -289,18 +160,7 @@
definePageMeta({ middleware: ['members-auth'] })
const route = useRoute()
-const router = useRouter()
-const { memberData } = useAuth()
const { render: renderMarkdown } = useMarkdown()
-const { getSuggestions } = useEcology()
-const { trackGoal, isComplete } = useOnboarding()
-
-// ---- View mode (URL-driven) ----
-const viewMode = ref(route.query.view === 'ecology' ? 'ecology' : 'directory')
-
-watch(viewMode, (val) => {
- router.replace({ query: { ...route.query, view: val === 'ecology' ? 'ecology' : undefined } })
-})
// ---- Directory state ----
const members = ref([])
@@ -310,26 +170,11 @@ const searchQuery = ref('')
const selectedCircle = ref('all')
const peerSupportFilter = ref('all')
const directoryCraftTags = ref([])
-const directoryCraftTagOptions = ref([])
-const directoryConnectionTagOptions = ref([])
+const craftTagOptions = ref([])
const showAllTags = ref(false)
const showTagsDrawer = ref(false)
-// ---- Ecology state ----
-const suggestions = ref([])
-const ecologyLoading = ref(false)
-const ecologyTagOptions = ref([])
-const ecologyFilterTags = ref([])
-const copiedHandle = ref(null)
-
-// ---- Shared helpers ----
-const stateLabels = {
- help: 'Can help',
- interested: 'Interested',
- seeking: 'Need help',
-}
-const stateLabel = (state) => stateLabels[state] || state || ''
-
+// ---- Helpers ----
const circleOptions = [
{ label: 'All Circles', value: 'all' },
{ label: 'Community', value: 'community' },
@@ -344,18 +189,10 @@ const circleLabels = {
}
const craftTagLabel = (slug) => {
- const found = directoryCraftTagOptions.value.find((t) => t.slug === slug)
+ const found = craftTagOptions.value.find((t) => t.slug === slug)
return found ? found.label : slug
}
-const ecologyTagLabel = (slug) => {
- const found = ecologyTagOptions.value.find((t) => t.slug === slug)
- if (found) return found.label
- // Fallback to directory connection tags
- const fallback = directoryConnectionTagOptions.value.find((t) => t.slug === slug)
- return fallback ? fallback.label : slug
-}
-
const getInitials = (name) => {
if (!name) return '?'
return name
@@ -374,75 +211,22 @@ const capitalize = (str) => {
.join('-')
}
-// ---- Computed: tag options & active tags based on mode ----
-const currentTagOptions = computed(() =>
- viewMode.value === 'ecology' ? ecologyTagOptions.value : directoryCraftTagOptions.value
-)
-
-const currentActiveTags = computed(() =>
- viewMode.value === 'ecology' ? ecologyFilterTags.value : directoryCraftTags.value
-)
-
+// ---- Computed ----
const visibleTagOptions = computed(() =>
- showAllTags.value ? currentTagOptions.value : currentTagOptions.value.slice(0, 10)
+ showAllTags.value ? craftTagOptions.value : craftTagOptions.value.slice(0, 10)
)
-const hasNoTopics = computed(() => {
- if (!memberData.value) return false
- const topics = memberData.value?.communityEcology?.topics
- return !topics || topics.length === 0
-})
-
-const filteredSuggestions = computed(() => {
- if (ecologyFilterTags.value.length === 0) return suggestions.value
- return suggestions.value.filter((s) =>
- s.matchingTags.some((m) => ecologyFilterTags.value.includes(m.tagSlug))
- )
-})
-
const hasActiveFilters = computed(() =>
(selectedCircle.value && selectedCircle.value !== 'all') ||
peerSupportFilter.value === 'true' ||
directoryCraftTags.value.length > 0
)
-const pageSubtitle = computed(() => {
- if (viewMode.value === 'ecology') {
- const count = suggestions.value.length
- return `${count} connection${count === 1 ? '' : 's'}`
- }
- return `${totalCount.value} member${totalCount.value === 1 ? '' : 's'} across 3 circles`
-})
+const pageSubtitle = computed(() =>
+ `${totalCount.value} member${totalCount.value === 1 ? '' : 's'} across 3 circles`
+)
-// ---- View mode switching ----
-const setViewMode = (mode) => {
- if (viewMode.value === mode) return
- // Reset all filter state
- searchQuery.value = ''
- selectedCircle.value = 'all'
- peerSupportFilter.value = 'all'
- directoryCraftTags.value = []
- ecologyFilterTags.value = []
- showTagsDrawer.value = false
- showAllTags.value = false
-
- viewMode.value = mode
-
- if (mode === 'directory') {
- loadMembers()
- } else {
- loadEcology()
- }
-}
-
-// ---- Onboarding tracking ----
-watch(viewMode, (val) => {
- if (val === 'ecology' && !isComplete.value) {
- trackGoal('ecologyPageVisited')
- }
-})
-
-// ---- Directory: load members ----
+// ---- Load members ----
const loadMembers = async () => {
loading.value = true
try {
@@ -456,11 +240,8 @@ const loadMembers = async () => {
members.value = data.members || []
totalCount.value = data.totalCount || 0
- if (data.filters?.craftTags && directoryCraftTagOptions.value.length === 0) {
- directoryCraftTagOptions.value = data.filters.craftTags
- }
- if (data.filters?.cooperativeTags && directoryConnectionTagOptions.value.length === 0) {
- directoryConnectionTagOptions.value = data.filters.cooperativeTags
+ if (data.filters?.craftTags && craftTagOptions.value.length === 0) {
+ craftTagOptions.value = data.filters.craftTags
}
} catch (error) {
console.error('Failed to load members:', error)
@@ -471,43 +252,19 @@ const loadMembers = async () => {
}
}
-// ---- Directory: load tag options ----
+// ---- Load tag options ----
const loadTagOptions = async () => {
try {
const data = await $fetch('/api/tags')
const tags = data.tags || []
- directoryCraftTagOptions.value = tags
+ craftTagOptions.value = tags
.filter((t) => t.pool === 'craft')
.map((t) => ({ slug: t.slug, label: t.label }))
- directoryConnectionTagOptions.value = tags
- .filter((t) => t.pool === 'cooperative')
- .map((t) => ({ slug: t.slug, label: t.label }))
} catch (error) {
console.error('Failed to load tags:', error)
}
}
-// ---- Ecology: load suggestions ----
-const loadEcology = async () => {
- ecologyLoading.value = true
- try {
- const data = await getSuggestions()
- suggestions.value = data.suggestions || []
-
- // Build ecology tag options from user's own topics
- const allCoopTags = directoryConnectionTagOptions.value
- const myTopicSlugs = (memberData.value?.communityEcology?.topics || []).map((t) => t.tagSlug)
- ecologyTagOptions.value = myTopicSlugs.length
- ? allCoopTags.filter((t) => myTopicSlugs.includes(t.slug))
- : allCoopTags
- } catch (error) {
- console.error('Failed to load ecology:', error)
- suggestions.value = []
- } finally {
- ecologyLoading.value = false
- }
-}
-
// ---- Filter helpers ----
const togglePeerSupport = (e) => {
peerSupportFilter.value = e.target.checked ? 'true' : 'all'
@@ -522,19 +279,6 @@ const debouncedSearch = () => {
}, 300)
}
-const toggleTag = (slug) => {
- if (viewMode.value === 'ecology') {
- const idx = ecologyFilterTags.value.indexOf(slug)
- if (idx > -1) {
- ecologyFilterTags.value.splice(idx, 1)
- } else {
- ecologyFilterTags.value.push(slug)
- }
- } else {
- toggleDirectoryCraftTag(slug)
- }
-}
-
const toggleDirectoryCraftTag = (slug) => {
const idx = directoryCraftTags.value.indexOf(slug)
if (idx > -1) {
@@ -564,41 +308,20 @@ const clearAllFilters = () => {
loadMembers()
}
-// ---- Clipboard ----
-let copyTimer = null
-const copyHandle = async (handle) => {
- try {
- await navigator.clipboard.writeText(`@${handle}`)
- copiedHandle.value = handle
- if (copyTimer) clearTimeout(copyTimer)
- copyTimer = setTimeout(() => {
- copiedHandle.value = null
- copyTimer = null
- }, 1500)
- } catch (error) {
- console.error('Clipboard write failed:', error)
- }
-}
-
onBeforeUnmount(() => {
- if (copyTimer) clearTimeout(copyTimer)
clearTimeout(searchTimeout)
})
-// ---- useHead (reactive) ----
-useHead(computed(() => ({
- title: viewMode.value === 'ecology'
- ? 'Community Ecology - Ghost Guild'
- : 'Member Directory - Ghost Guild',
+// ---- useHead ----
+useHead({
+ title: 'Member Directory - Ghost Guild',
meta: [
{
name: 'description',
- content: viewMode.value === 'ecology'
- ? 'Find Ghost Guild members who share your cooperative interests and reach out on Slack.'
- : 'Connect with members of the Ghost Guild community - game developers, founders, and practitioners building solidarity economy studios.',
+ content: 'Connect with members of the Ghost Guild community - game developers, founders, and practitioners building solidarity economy studios.',
},
],
-})))
+})
// ---- Init ----
onMounted(async () => {
@@ -607,47 +330,11 @@ onMounted(async () => {
}
await loadTagOptions()
-
- if (viewMode.value === 'ecology') {
- await loadEcology()
- } else {
- await loadMembers()
- }
+ await loadMembers()
})