diff --git a/app/composables/useMemberStatus.js b/app/composables/useMemberStatus.js index 6c4acb9..48ec762 100644 --- a/app/composables/useMemberStatus.js +++ b/app/composables/useMemberStatus.js @@ -12,16 +12,16 @@ export const MEMBER_STATUSES = { export const MEMBER_STATUS_CONFIG = { pending_payment: { - label: "Payment Pending", + label: "Setting up payment", color: "orange", bgColor: "bg-orange-500/10", borderColor: "border-orange-500/30", textColor: "text-orange-300", icon: "heroicons:exclamation-triangle", severity: "warning", - canRSVP: false, + canRSVP: true, canAccessMembers: true, - canPeerSupport: false, + canPeerSupport: true, }, active: { label: "Active Member", @@ -126,24 +126,21 @@ export const useMemberStatus = () => { // Get banner message based on status const getBannerMessage = () => { if (isPendingPayment.value) { - return "Your membership is pending payment. Please complete your payment to unlock full features."; + return "Your payment setup isn't finished yet. Your membership and access aren't affected — finish whenever you're ready, or reach out if there's a snag."; } if (isSuspended.value) { - return "Your membership has been suspended. Please contact support to reactivate your account."; + return "Your account is paused while we work through a community issue. We'll be in touch."; } if (isCancelled.value) { - return "Your membership has been cancelled. Would you like to reactivate?"; + return "Your account is closed. Reach out if you'd like to come back."; } return null; }; // Get RSVP restriction message const getRSVPMessage = () => { - if (isPendingPayment.value) { - return "Complete your payment to register for events"; - } if (isSuspended.value || isCancelled.value) { - return "Your membership status prevents RSVP. Please reactivate your account."; + return "Your account isn't active right now. Reach out if you have questions."; } return null; }; diff --git a/app/pages/member/account.vue b/app/pages/member/account.vue index c69f561..da9f1fd 100644 --- a/app/pages/member/account.vue +++ b/app/pages/member/account.vue @@ -34,7 +34,7 @@ + /> {{ formatStatus(memberData.status || "active") }} @@ -93,26 +93,26 @@
+ >
@@ -128,9 +128,12 @@
Danger Zone

- Cancelling your membership will immediately revoke access to - member-only resources, events, and the Slack workspace. - This action cannot be easily undone. + Cancelling closes your account and ends access to member-only + spaces, including Slack. If you're cancelling because of a + money issue, the + Solidarity Fund + and the $0 tier are always available — reach out before you + go.

@@ -139,8 +142,8 @@

@@ -152,8 +155,8 @@ @@ -172,11 +175,11 @@
@@ -192,8 +195,8 @@ /> @@ -254,9 +257,9 @@ const circleOptions = [ const STATUS_LABELS = { active: "Active", - pending_payment: "Pending", - suspended: "Suspended", - cancelled: "Cancelled", + pending_payment: "Setting up payment", + suspended: "Paused", + cancelled: "Closed", }; const formatStatus = (s) => STATUS_LABELS[s] || s; diff --git a/tests/client/composables/useMemberStatus.test.js b/tests/client/composables/useMemberStatus.test.js index 5bd1094..3e8b228 100644 --- a/tests/client/composables/useMemberStatus.test.js +++ b/tests/client/composables/useMemberStatus.test.js @@ -61,11 +61,11 @@ describe("MEMBER_STATUS_CONFIG", () => { expect(cfg.canPeerSupport).toBe(true); }); - it("pending_payment can access members but not RSVP or peer support", () => { + it("pending_payment has full permissions (payment is decoupled from access)", () => { const cfg = MEMBER_STATUS_CONFIG.pending_payment; - expect(cfg.canRSVP).toBe(false); + expect(cfg.canRSVP).toBe(true); expect(cfg.canAccessMembers).toBe(true); - expect(cfg.canPeerSupport).toBe(false); + expect(cfg.canPeerSupport).toBe(true); }); it("suspended has all permissions false", () => { @@ -122,10 +122,10 @@ describe("useMemberStatus composable", () => { expect(canRSVP.value).toBe(true); }); - it("canRSVP is false when pending_payment", () => { + it("canRSVP is true when pending_payment (decoupled from payment)", () => { memberData.value = { status: "pending_payment" }; const { canRSVP } = useMemberStatus(); - expect(canRSVP.value).toBe(false); + expect(canRSVP.value).toBe(true); }); it("canAccessMembers is true for active and pending_payment", () => { @@ -182,22 +182,22 @@ describe("useMemberStatus composable", () => { }); describe("getBannerMessage", () => { - it("returns payment message for pending_payment", () => { + it("returns payment-setup message for pending_payment", () => { memberData.value = { status: "pending_payment" }; const { getBannerMessage } = useMemberStatus(); - expect(getBannerMessage()).toContain("pending payment"); + expect(getBannerMessage()).toContain("payment setup"); }); - it("returns suspended message for suspended", () => { + it("returns paused message for suspended", () => { memberData.value = { status: "suspended" }; const { getBannerMessage } = useMemberStatus(); - expect(getBannerMessage()).toContain("suspended"); + expect(getBannerMessage()).toContain("paused"); }); - it("returns cancelled message for cancelled", () => { + it("returns closed message for cancelled", () => { memberData.value = { status: "cancelled" }; const { getBannerMessage } = useMemberStatus(); - expect(getBannerMessage()).toContain("cancelled"); + expect(getBannerMessage()).toContain("closed"); }); it("returns null for active", () => { @@ -208,22 +208,22 @@ describe("useMemberStatus composable", () => { }); describe("getRSVPMessage", () => { - it("returns payment message for pending_payment", () => { + it("returns null for pending_payment (decoupled from RSVP)", () => { memberData.value = { status: "pending_payment" }; const { getRSVPMessage } = useMemberStatus(); - expect(getRSVPMessage()).toContain("payment"); + expect(getRSVPMessage()).toBeNull(); }); - it("returns restriction message for suspended", () => { + it("returns inactive-account message for suspended", () => { memberData.value = { status: "suspended" }; const { getRSVPMessage } = useMemberStatus(); - expect(getRSVPMessage()).toContain("reactivate"); + expect(getRSVPMessage()).toContain("isn't active"); }); - it("returns restriction message for cancelled", () => { + it("returns inactive-account message for cancelled", () => { memberData.value = { status: "cancelled" }; const { getRSVPMessage } = useMemberStatus(); - expect(getRSVPMessage()).toContain("reactivate"); + expect(getRSVPMessage()).toContain("isn't active"); }); it("returns null for active", () => {