@@ -270,7 +228,7 @@
@@ -324,11 +282,11 @@
- Peer support requests
+ Connection requests
When someone wants to connect
@@ -360,6 +318,9 @@
+
+
+
@@ -389,6 +350,20 @@ const availableGhosts = [
{ value: "wtf", label: "WTF", image: "/ghosties/Ghost-WTF.png" },
];
+// Fetch tags and split into pools
+const { data: tagsData } = await useFetch("/api/tags");
+
+const craftTags = computed(() =>
+ (tagsData.value?.tags || []).filter((t) => t.pool === "craft"),
+);
+const cooperativeTags = computed(() =>
+ (tagsData.value?.tags || []).filter((t) => t.pool === "cooperative"),
+);
+
+// Tag suggest modal state
+const showTagSuggestModal = ref(false);
+const tagSuggestPool = ref("");
+
// Form state
const formData = reactive({
name: "",
@@ -398,16 +373,18 @@ const formData = reactive({
studio: "",
bio: "",
location: "",
- offering: { text: "", tags: [] },
- lookingFor: { text: "", tags: [] },
showInDirectory: true,
- // Peer support
- peerSupportEnabled: false,
- peerSupportSkillTopics: [],
- peerSupportSupportTopics: [],
- peerSupportAvailability: "",
- peerSupportMessage: "",
- peerSupportSlackUsername: "",
+ // Craft tags
+ craftTags: [],
+ craftTagsPrivacy: "members",
+ // Community connections
+ communityConnectionsTopics: [],
+ communityConnectionsPrivacy: "members",
+ communityConnectionsDetails: "",
+ communityConnectionsOfferPeerSupport: false,
+ communityConnectionsAvailability: "",
+ communityConnectionsSlackHandle: "",
+ communityConnectionsPersonalMessage: "",
// Privacy
pronounsPrivacy: "members",
timeZonePrivacy: "members",
@@ -415,12 +392,10 @@ const formData = reactive({
studioPrivacy: "members",
bioPrivacy: "members",
locationPrivacy: "members",
- offeringPrivacy: "members",
- lookingForPrivacy: "members",
// Notifications
notifyEvents: true,
notifyUpdates: true,
- notifyPeerRequests: true,
+ notifyConnectionRequests: true,
});
const loading = ref(false);
@@ -429,47 +404,11 @@ const saveSuccess = ref(false);
const saveError = ref(null);
const initialData = ref(null);
-// Available conversational support topics
-const availableSupportTopics = [
- "Co-founder relationships",
- "Burnout prevention",
- "Impostor syndrome",
- "Work-life boundaries",
- "Conflict resolution",
- "General chat & support",
-];
-
// Computed
const hasChanges = computed(() => {
return JSON.stringify(formData) !== JSON.stringify(initialData.value);
});
-const suggestedSkillTopics = computed(() => {
- if (!formData.offering.tags?.length) return [];
- return formData.offering.tags.filter(
- (t) => !formData.peerSupportSkillTopics?.includes(t),
- );
-});
-
-// Toggle a support topic in/out of the selection
-const toggleSupportTopic = (topic) => {
- const idx = formData.peerSupportSupportTopics.indexOf(topic);
- if (idx >= 0) {
- formData.peerSupportSupportTopics.splice(idx, 1);
- } else {
- formData.peerSupportSupportTopics.push(topic);
- }
-};
-
-const addSuggestedSkillTopic = (tag) => {
- if (!Array.isArray(formData.peerSupportSkillTopics)) {
- formData.peerSupportSkillTopics = [];
- }
- if (!formData.peerSupportSkillTopics.includes(tag)) {
- formData.peerSupportSkillTopics.push(tag);
- }
-};
-
// Load member data into form
const loadProfile = () => {
if (memberData.value) {
@@ -481,66 +420,21 @@ const loadProfile = () => {
formData.bio = memberData.value.bio || "";
formData.location = memberData.value.location || "";
- // Load offering (handle both old string and new object format)
- if (typeof memberData.value.offering === "string") {
- formData.offering.text = memberData.value.offering;
- formData.offering.tags = [];
- } else if (memberData.value.offering) {
- formData.offering.text = memberData.value.offering?.text || "";
- formData.offering.tags = Array.isArray(memberData.value.offering?.tags)
- ? [...memberData.value.offering.tags]
- : [];
- } else {
- formData.offering.text = "";
- formData.offering.tags = [];
- }
-
- // Load lookingFor (handle both old string and new object format)
- if (typeof memberData.value.lookingFor === "string") {
- formData.lookingFor.text = memberData.value.lookingFor;
- formData.lookingFor.tags = [];
- } else if (memberData.value.lookingFor) {
- formData.lookingFor.text = memberData.value.lookingFor?.text || "";
- formData.lookingFor.tags = Array.isArray(
- memberData.value.lookingFor?.tags,
- )
- ? [...memberData.value.lookingFor.tags]
- : [];
- } else {
- formData.lookingFor.text = "";
- formData.lookingFor.tags = [];
- }
-
formData.showInDirectory = memberData.value.showInDirectory ?? true;
- // Load peer support data
- if (memberData.value.peerSupport) {
- formData.peerSupportEnabled =
- memberData.value.peerSupport.enabled || false;
- formData.peerSupportSkillTopics = Array.isArray(
- memberData.value.peerSupport.skillTopics,
- )
- ? [...memberData.value.peerSupport.skillTopics]
- : [];
- formData.peerSupportSupportTopics = Array.isArray(
- memberData.value.peerSupport.supportTopics,
- )
- ? [...memberData.value.peerSupport.supportTopics]
- : [];
- formData.peerSupportAvailability =
- memberData.value.peerSupport.availability || "";
- formData.peerSupportMessage =
- memberData.value.peerSupport.personalMessage || "";
- formData.peerSupportSlackUsername =
- memberData.value.peerSupport.slackUsername || "";
- } else {
- formData.peerSupportEnabled = false;
- formData.peerSupportSkillTopics = [];
- formData.peerSupportSupportTopics = [];
- formData.peerSupportAvailability = "";
- formData.peerSupportMessage = "";
- formData.peerSupportSlackUsername = "";
- }
+ // Load craft tags
+ formData.craftTags = Array.isArray(memberData.value.craftTags)
+ ? [...memberData.value.craftTags]
+ : [];
+
+ // Load community connections (with fallback to old peerSupport fields)
+ const cc = memberData.value.communityConnections || {};
+ formData.communityConnectionsTopics = Array.isArray(cc.topics) ? [...cc.topics] : [];
+ formData.communityConnectionsOfferPeerSupport = cc.offerPeerSupport ?? memberData.value.peerSupport?.enabled ?? false;
+ formData.communityConnectionsAvailability = cc.availability || memberData.value.peerSupport?.availability || "";
+ formData.communityConnectionsSlackHandle = cc.slackHandle || memberData.value.peerSupport?.slackUsername || "";
+ formData.communityConnectionsPersonalMessage = cc.personalMessage || memberData.value.peerSupport?.personalMessage || "";
+ formData.communityConnectionsDetails = cc.details || "";
// Load privacy settings (with defaults)
const privacy = memberData.value.privacy || {};
@@ -550,14 +444,14 @@ const loadProfile = () => {
formData.studioPrivacy = privacy.studio || "members";
formData.bioPrivacy = privacy.bio || "members";
formData.locationPrivacy = privacy.location || "members";
- formData.offeringPrivacy = privacy.offering || "members";
- formData.lookingForPrivacy = privacy.lookingFor || "members";
+ formData.craftTagsPrivacy = privacy.craftTags || "members";
+ formData.communityConnectionsPrivacy = privacy.communityConnections || "members";
// Load notification prefs
const notifs = memberData.value.notifications || {};
formData.notifyEvents = notifs.events ?? true;
formData.notifyUpdates = notifs.updates ?? true;
- formData.notifyPeerRequests = notifs.peerRequests ?? true;
+ formData.notifyConnectionRequests = notifs.connectionRequests ?? notifs.peerRequests ?? true;
// Store initial state for change detection
initialData.value = JSON.parse(JSON.stringify(formData));
@@ -571,29 +465,30 @@ const handleSubmit = async () => {
saveError.value = null;
try {
- // Save profile data
+ // Save profile data (includes craft tags + privacy + notifications)
await $fetch("/api/members/profile", {
method: "PATCH",
body: {
...formData,
+ craftTags: formData.craftTags,
notifications: {
events: formData.notifyEvents,
updates: formData.notifyUpdates,
- peerRequests: formData.notifyPeerRequests,
+ connectionRequests: formData.notifyConnectionRequests,
},
},
});
- // Save peer support data separately
- await $fetch("/api/members/me/peer-support", {
+ // Save community connections data
+ await $fetch("/api/members/me/community-connections", {
method: "PATCH",
body: {
- enabled: formData.peerSupportEnabled,
- skillTopics: formData.peerSupportSkillTopics,
- supportTopics: formData.peerSupportSupportTopics,
- availability: formData.peerSupportAvailability,
- personalMessage: formData.peerSupportMessage,
- slackUsername: formData.peerSupportSlackUsername,
+ topics: formData.communityConnectionsTopics,
+ offerPeerSupport: formData.communityConnectionsOfferPeerSupport,
+ availability: formData.communityConnectionsAvailability,
+ slackHandle: formData.communityConnectionsSlackHandle,
+ personalMessage: formData.communityConnectionsPersonalMessage,
+ details: formData.communityConnectionsDetails,
},
});
@@ -844,48 +739,8 @@ useHead({
margin-top: 1px;
}
-/* ---- CHECKBOX GRID ---- */
-.checkbox-grid {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 3px 12px;
-}
-
-.checkbox-item {
- display: flex;
- align-items: center;
- gap: 5px;
- font-size: 11px;
- color: var(--text-dim);
- cursor: pointer;
- padding: 2px 0;
- user-select: none;
-}
-
-.checkbox-item .cb {
- width: 13px;
- height: 13px;
- border: 1px dashed var(--border);
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 9px;
- color: transparent;
- flex-shrink: 0;
-}
-
-.checkbox-item.checked .cb {
- border-color: var(--candle);
- border-style: solid;
- color: var(--candle);
-}
-
-.checkbox-item:hover {
- color: var(--text);
-}
-
-/* ---- PEER SUPPORT PANEL ---- */
-.peer-panel {
+/* ---- CONNECTIONS PANEL ---- */
+.connections-panel {
border: 1px dashed var(--border);
padding: 12px 14px;
margin-top: 4px;
@@ -893,19 +748,6 @@ useHead({
background: var(--surface);
}
-.peer-panel .suggested {
- font-size: 10px;
- color: var(--text-faint);
- margin-top: 4px;
-}
-
-.peer-panel .suggested a {
- color: var(--candle);
- text-decoration: underline;
- cursor: pointer;
- margin-left: 4px;
-}
-
/* ---- DISABLED BUTTON ---- */
.btn:disabled {
opacity: 0.4;
@@ -962,10 +804,6 @@ useHead({
grid-template-columns: 1fr;
}
- .checkbox-grid {
- grid-template-columns: 1fr;
- }
-
.profile-col-left .profile-col-inset,
.profile-col-right .profile-col-inset {
padding-left: 16px;
diff --git a/app/pages/members/[id].vue b/app/pages/members/[id].vue
index 6b4e254..0b47108 100644
--- a/app/pages/members/[id].vue
+++ b/app/pages/members/[id].vue
@@ -60,40 +60,42 @@