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 const token = getCookie(event, "auth-token"); let isAuthenticated = false; let currentMemberId = null; if (token) { try { const decoded = jwt.verify(token, process.env.JWT_SECRET); currentMemberId = decoded.memberId; isAuthenticated = true; } catch (err) { // Invalid token, treat as public isAuthenticated = false; } } const query = getQuery(event); const search = query.search || ""; const circle = query.circle || ""; const skills = query.skills ? query.skills.split(",") : []; // Build query const dbQuery = { showInDirectory: true, status: "active", }; // Filter by circle if specified if (circle) { dbQuery.circle = circle; } // Search by name or bio if (search) { dbQuery.$or = [ { name: { $regex: search, $options: "i" } }, { bio: { $regex: search, $options: "i" } }, ]; } // Filter by skills if (skills.length > 0) { dbQuery.skills = { $in: skills }; } try { const members = await Member.find(dbQuery) .select( "name pronouns timeZone avatar studio bio skills location socialLinks offering lookingFor privacy circle createdAt" ) .sort({ createdAt: -1 }) .lean(); // Filter fields based on privacy settings const filteredMembers = members.map((member) => { const privacy = member.privacy || {}; const filtered = { _id: member._id, name: member.name, circle: member.circle, createdAt: member.createdAt, }; // Helper function to check if field should be visible const isVisible = (field) => { const privacySetting = privacy[field] || "members"; if (privacySetting === "public") return true; if (privacySetting === "members" && isAuthenticated) return true; if (privacySetting === "private") return false; return false; }; // Add fields based on privacy settings if (isVisible("avatar")) filtered.avatar = member.avatar; if (isVisible("pronouns")) filtered.pronouns = member.pronouns; if (isVisible("timeZone")) filtered.timeZone = member.timeZone; if (isVisible("studio")) filtered.studio = member.studio; if (isVisible("bio")) filtered.bio = member.bio; if (isVisible("skills")) filtered.skills = member.skills; if (isVisible("location")) filtered.location = member.location; if (isVisible("socialLinks")) filtered.socialLinks = member.socialLinks; if (isVisible("offering")) filtered.offering = member.offering; if (isVisible("lookingFor")) filtered.lookingFor = member.lookingFor; return filtered; }); // Get unique skills for filter options const allSkills = members .flatMap((m) => m.skills || []) .filter((skill, index, self) => self.indexOf(skill) === index) .sort(); return { members: filteredMembers, totalCount: filteredMembers.length, filters: { availableSkills: allSkills, }, }; } catch (error) { console.error("Directory fetch error:", error); throw createError({ statusCode: 500, message: "Failed to fetch member directory", }); } });