From ed33cbb9e715609e868c7e93e20cd1b20925a3e2 Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Sun, 5 Apr 2026 16:56:40 +0100 Subject: [PATCH] feat: add connections page, composable, nav badge, and peer-support redirect - useConnections composable wrapping all /api/connections endpoints - Connections page with suggestions, filters, and connection management - Pending connection count badge in sidebar navigation - peer-support.vue now redirects to /connections --- app/components/AppNavigation.vue | 36 +- app/composables/useConnections.js | 32 ++ app/pages/connections.vue | 834 ++++++++++++++++++++++++++++++ app/pages/peer-support.vue | 4 +- 4 files changed, 903 insertions(+), 3 deletions(-) create mode 100644 app/composables/useConnections.js create mode 100644 app/pages/connections.vue diff --git a/app/components/AppNavigation.vue b/app/components/AppNavigation.vue index 24c7da8..3095f8b 100644 --- a/app/components/AppNavigation.vue +++ b/app/components/AppNavigation.vue @@ -34,8 +34,13 @@ :to="item.path" :class="{ active: isActive(item.path) }" @click="handleNavigate" - >{{ item.label }} + {{ item.label }} + {{ pendingCount }} + @@ -129,7 +134,21 @@ const emit = defineEmits(["navigate"]); const route = useRoute(); const { isAuthenticated, logout } = useAuth(); +const { getPendingCount } = useConnections(); const isDev = import.meta.dev; +const pendingCount = ref(0); + +// Fetch pending connection count for authenticated users +onMounted(async () => { + if (isAuthenticated.value) { + try { + const data = await getPendingCount(); + pendingCount.value = data.count || 0; + } catch { + // Silently ignore — badge is non-critical + } + } +}); const handleNavigate = () => { if (props.isMobile) { @@ -279,4 +298,19 @@ const exploreItems = [ .sidebar-meta a { color: var(--candle-dim); } + +.nav-badge { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 16px; + height: 16px; + padding: 0 4px; + margin-left: 6px; + font-size: 10px; + line-height: 1; + color: var(--bg); + background: var(--candle); + border-radius: 0; +} diff --git a/app/composables/useConnections.js b/app/composables/useConnections.js new file mode 100644 index 0000000..6bf3833 --- /dev/null +++ b/app/composables/useConnections.js @@ -0,0 +1,32 @@ +export const useConnections = () => { + const getSuggestions = (params = {}) => + $fetch('/api/connections/suggestions', { params }) + + const getMyConnections = () => + $fetch('/api/connections') + + const requestConnection = (recipientId) => + $fetch('/api/connections', { method: 'POST', body: { recipientId } }) + + const confirmConnection = (id) => + $fetch(`/api/connections/${id}/confirm`, { method: 'POST' }) + + const hideConnection = (id) => + $fetch(`/api/connections/${id}/hide`, { method: 'POST' }) + + const withdrawConnection = (id) => + $fetch(`/api/connections/${id}/withdraw`, { method: 'POST' }) + + const getPendingCount = () => + $fetch('/api/connections/pending-count') + + return { + getSuggestions, + getMyConnections, + requestConnection, + confirmConnection, + hideConnection, + withdrawConnection, + getPendingCount, + } +} diff --git a/app/pages/connections.vue b/app/pages/connections.vue new file mode 100644 index 0000000..833c324 --- /dev/null +++ b/app/pages/connections.vue @@ -0,0 +1,834 @@ + + + + + diff --git a/app/pages/peer-support.vue b/app/pages/peer-support.vue index 682319d..1e26164 100644 --- a/app/pages/peer-support.vue +++ b/app/pages/peer-support.vue @@ -3,10 +3,10 @@