restrict members page to authenticated users only, remove public access
This commit is contained in:
parent
1d469c3617
commit
fc7ec52574
1 changed files with 6 additions and 101 deletions
|
|
@ -18,14 +18,8 @@
|
||||||
type="button"
|
type="button"
|
||||||
class="toggle-btn"
|
class="toggle-btn"
|
||||||
:class="{ active: viewMode === 'ecology' }"
|
:class="{ active: viewMode === 'ecology' }"
|
||||||
@click="handleEcologyToggle"
|
@click="setViewMode('ecology')"
|
||||||
>
|
>
|
||||||
<template v-if="!isAuthenticated">
|
|
||||||
<svg width="10" height="12" viewBox="0 0 10 12" fill="none" aria-label="Members only" class="lock-icon">
|
|
||||||
<rect x="0.5" y="5" width="9" height="6.5" rx="0" stroke="currentColor" stroke-width="1"/>
|
|
||||||
<path d="M2.5 5V3.5a2.5 2.5 0 015 0V5" stroke="currentColor" stroke-width="1" fill="none"/>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
Ecology
|
Ecology
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -125,12 +119,6 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Public CTA (unauthenticated) -->
|
|
||||||
<div v-if="!isAuthenticated" class="public-cta">
|
|
||||||
<p>Join Ghost Guild to see the full directory and find collaborators</p>
|
|
||||||
<NuxtLink to="/join" class="btn btn-primary">Join Ghost Guild</NuxtLink>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- DIRECTORY MODE -->
|
<!-- DIRECTORY MODE -->
|
||||||
<template v-if="viewMode === 'directory'">
|
<template v-if="viewMode === 'directory'">
|
||||||
<div v-if="loading && !members.length" class="loading-state">
|
<div v-if="loading && !members.length" class="loading-state">
|
||||||
|
|
@ -294,31 +282,15 @@
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- Auth notice (unauthenticated, has results) -->
|
|
||||||
<div v-if="!isAuthenticated && members.length > 0" class="auth-notice">
|
|
||||||
<p>Some member information is visible to members only.</p>
|
|
||||||
<div class="auth-actions">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn"
|
|
||||||
@click="openLoginModal({
|
|
||||||
title: 'Sign in to see more',
|
|
||||||
description: 'Log in to view full member profiles',
|
|
||||||
})"
|
|
||||||
>
|
|
||||||
Log In
|
|
||||||
</button>
|
|
||||||
<NuxtLink to="/join" class="btn btn-primary">Join Ghost Guild</NuxtLink>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</PageShell>
|
</PageShell>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
definePageMeta({ middleware: ['members-auth'] })
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { isAuthenticated, memberData } = useAuth()
|
const { memberData } = useAuth()
|
||||||
const { openLoginModal } = useLoginModal()
|
|
||||||
const { render: renderMarkdown } = useMarkdown()
|
const { render: renderMarkdown } = useMarkdown()
|
||||||
const { getSuggestions } = useEcology()
|
const { getSuggestions } = useEcology()
|
||||||
const { trackGoal, isComplete } = useOnboarding()
|
const { trackGoal, isComplete } = useOnboarding()
|
||||||
|
|
@ -443,18 +415,6 @@ const pageSubtitle = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// ---- View mode switching ----
|
// ---- View mode switching ----
|
||||||
const handleEcologyToggle = () => {
|
|
||||||
if (!isAuthenticated.value) {
|
|
||||||
openLoginModal({
|
|
||||||
title: 'Sign in to explore ecology',
|
|
||||||
description: 'Log in to find members who share your cooperative interests',
|
|
||||||
redirectTo: '/members?view=ecology',
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
setViewMode('ecology')
|
|
||||||
}
|
|
||||||
|
|
||||||
const setViewMode = (mode) => {
|
const setViewMode = (mode) => {
|
||||||
if (viewMode.value === mode) return
|
if (viewMode.value === mode) return
|
||||||
// Reset all filter state
|
// Reset all filter state
|
||||||
|
|
@ -541,17 +501,7 @@ const loadEcology = async () => {
|
||||||
? allCoopTags.filter((t) => myTopicSlugs.includes(t.slug))
|
? allCoopTags.filter((t) => myTopicSlugs.includes(t.slug))
|
||||||
: allCoopTags
|
: allCoopTags
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error?.statusCode === 401 || error?.status === 401) {
|
console.error('Failed to load ecology:', error)
|
||||||
viewMode.value = 'directory'
|
|
||||||
loadMembers()
|
|
||||||
openLoginModal({
|
|
||||||
title: 'Session expired',
|
|
||||||
description: 'Please sign in again to view ecology',
|
|
||||||
redirectTo: '/members?view=ecology',
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
console.error('Failed to load ecology:', error)
|
|
||||||
}
|
|
||||||
suggestions.value = []
|
suggestions.value = []
|
||||||
} finally {
|
} finally {
|
||||||
ecologyLoading.value = false
|
ecologyLoading.value = false
|
||||||
|
|
@ -658,12 +608,9 @@ onMounted(async () => {
|
||||||
|
|
||||||
await loadTagOptions()
|
await loadTagOptions()
|
||||||
|
|
||||||
if (viewMode.value === 'ecology' && isAuthenticated.value) {
|
if (viewMode.value === 'ecology') {
|
||||||
await loadEcology()
|
await loadEcology()
|
||||||
} else {
|
} else {
|
||||||
if (viewMode.value === 'ecology' && !isAuthenticated.value) {
|
|
||||||
viewMode.value = 'directory'
|
|
||||||
}
|
|
||||||
await loadMembers()
|
await loadMembers()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -701,12 +648,6 @@ onMounted(async () => {
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.lock-icon {
|
|
||||||
width: 10px;
|
|
||||||
height: 12px;
|
|
||||||
color: var(--text-faint);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- FILTER BAR ---- */
|
/* ---- FILTER BAR ---- */
|
||||||
.filter-bar {
|
.filter-bar {
|
||||||
padding: 16px 24px;
|
padding: 16px 24px;
|
||||||
|
|
@ -916,18 +857,6 @@ onMounted(async () => {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- PUBLIC CTA ---- */
|
|
||||||
.public-cta {
|
|
||||||
padding: 24px;
|
|
||||||
border-bottom: 1px dashed var(--border);
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.public-cta p {
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- LOADING ---- */
|
/* ---- LOADING ---- */
|
||||||
.loading-state {
|
.loading-state {
|
||||||
padding: 60px 24px;
|
padding: 60px 24px;
|
||||||
|
|
@ -1198,24 +1127,6 @@ onMounted(async () => {
|
||||||
color: var(--candle);
|
color: var(--candle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- AUTH NOTICE ---- */
|
|
||||||
.auth-notice {
|
|
||||||
padding: 24px;
|
|
||||||
margin: 20px 24px;
|
|
||||||
border: 1px dashed var(--candle-faint);
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.auth-notice p {
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--text-dim);
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
.auth-actions {
|
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- RESPONSIVE ---- */
|
/* ---- RESPONSIVE ---- */
|
||||||
@media (max-width: 1024px) {
|
@media (max-width: 1024px) {
|
||||||
.member-grid {
|
.member-grid {
|
||||||
|
|
@ -1247,12 +1158,6 @@ onMounted(async () => {
|
||||||
.member-card {
|
.member-card {
|
||||||
padding: 14px 16px;
|
padding: 14px 16px;
|
||||||
}
|
}
|
||||||
.auth-notice {
|
|
||||||
margin: 16px;
|
|
||||||
}
|
|
||||||
.public-cta {
|
|
||||||
padding: 20px 16px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 375px) {
|
@media (max-width: 375px) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue