Add peer support functionality and UI

This commit is contained in:
Jennie Robinson Faber 2025-10-06 11:29:47 +01:00
parent 2b55ca4104
commit 1b8dacf92a
11 changed files with 1159 additions and 35 deletions

View file

@ -48,6 +48,8 @@ export default defineEventHandler(async (event) => {
lookingFor: member.lookingFor,
showInDirectory: member.showInDirectory,
privacy: member.privacy,
// Peer support
peerSupport: member.peerSupport,
};
} catch (err) {
console.error("Token verification error:", err);

View file

@ -0,0 +1,119 @@
import jwt from "jsonwebtoken";
import Member from "../../../models/member.js";
import { connectDB } from "../../../utils/mongoose.js";
export default defineEventHandler(async (event) => {
await connectDB();
const token = getCookie(event, "auth-token");
if (!token) {
throw createError({
statusCode: 401,
statusMessage: "Not authenticated",
});
}
let memberId;
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
memberId = decoded.memberId;
} catch (err) {
throw createError({
statusCode: 401,
statusMessage: "Invalid or expired token",
});
}
const body = await readBody(event);
// Build update object for peer support settings
const updateData = {
"peerSupport.enabled": body.enabled || false,
"peerSupport.topics": body.topics || [],
"peerSupport.availability": body.availability || "",
"peerSupport.personalMessage": body.personalMessage || "",
"peerSupport.slackUsername": body.slackUsername || "",
};
// If Slack username provided and peer support enabled, try to fetch Slack user ID
if (body.enabled && body.slackUsername) {
try {
console.log(
`[Peer Support] Attempting to fetch Slack user ID for: ${body.slackUsername}`,
);
// Dynamically import the Slack service
const { getSlackService } = await import("../../../utils/slack.ts");
const slackService = getSlackService();
if (slackService) {
console.log(
"[Peer Support] Slack service initialized, looking up user...",
);
const slackUserId = await slackService.findUserIdByUsername(
body.slackUsername,
);
if (slackUserId) {
updateData["slackUserId"] = slackUserId;
console.log(
`[Peer Support] ✓ Found Slack user ID for ${body.slackUsername}: ${slackUserId}`,
);
// Now get/create the DM channel
console.log("[Peer Support] Opening DM channel...");
const dmChannelId = await slackService.openDMChannel(slackUserId);
if (dmChannelId) {
updateData["peerSupport.slackDMChannelId"] = dmChannelId;
console.log(`[Peer Support] ✓ Got DM channel ID: ${dmChannelId}`);
} else {
console.warn("[Peer Support] Could not get DM channel ID");
}
} else {
console.warn(
`[Peer Support] Could not find Slack user ID for username: ${body.slackUsername}`,
);
}
} else {
console.log(
"[Peer Support] Slack service not configured, skipping user ID lookup",
);
}
} catch (error) {
console.error(
"[Peer Support] Error fetching Slack user ID:",
error.message,
);
console.error("[Peer Support] Stack trace:", error.stack);
// Continue anyway - we'll still save the username
}
}
try {
const member = await Member.findByIdAndUpdate(
memberId,
{ $set: updateData },
{ new: true, runValidators: true },
);
if (!member) {
throw createError({
statusCode: 404,
statusMessage: "Member not found",
});
}
return {
success: true,
peerSupport: member.peerSupport,
};
} catch (error) {
console.error("Peer support update error:", error);
throw createError({
statusCode: 500,
statusMessage: "Failed to update peer support settings",
});
}
});

View file

@ -0,0 +1,63 @@
import jwt from "jsonwebtoken";
import Member from "../models/member.js";
import { connectDB } from "../utils/mongoose.js";
export default defineEventHandler(async (event) => {
await connectDB();
// Check if user is authenticated (optional for this endpoint)
const token = getCookie(event, "auth-token");
let isAuthenticated = false;
if (token) {
try {
jwt.verify(token, process.env.JWT_SECRET);
isAuthenticated = true;
} catch (err) {
isAuthenticated = false;
}
}
const query = getQuery(event);
const topic = query.topic;
// Build query for peer supporters
const dbQuery = {
"peerSupport.enabled": true,
status: "active",
};
// Filter by topic if specified
if (topic) {
dbQuery["peerSupport.topics"] = topic;
}
try {
const supporters = await Member.find(dbQuery)
.select(
"name avatar circle peerSupport slackUserId createdAt"
)
.sort({ createdAt: -1 })
.lean();
// Get unique topics for filter options
const allTopics = supporters
.flatMap((supporter) => supporter.peerSupport?.topics || [])
.filter((topic, index, self) => self.indexOf(topic) === index)
.sort();
return {
supporters,
totalCount: supporters.length,
filters: {
availableTopics: allTopics,
},
};
} catch (error) {
console.error("Peer support fetch error:", error);
throw createError({
statusCode: 500,
statusMessage: "Failed to fetch peer supporters",
});
}
});

View file

@ -0,0 +1,28 @@
import jwt from "jsonwebtoken";
import Member from "../../models/member.js";
import { connectDB } from "../../utils/mongoose.js";
export default defineEventHandler(async (event) => {
await connectDB();
const token = getCookie(event, "auth-token");
if (!token) {
throw createError({ statusCode: 401, statusMessage: "Not authenticated" });
}
let memberId;
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
memberId = decoded.memberId;
} catch (err) {
throw createError({ statusCode: 401, statusMessage: "Invalid token" });
}
const member = await Member.findById(memberId).select("name peerSupport slackUserId");
return {
name: member.name,
peerSupport: member.peerSupport,
slackUserId: member.slackUserId,
};
});