ghostguild-org/app/composables/useMemberStatus.js
Jennie Robinson Faber 37a58cb0eb feat(member): pending_payment retains access, soften status copy
pending_payment now grants the same RSVP/peer-support capabilities as active,
and status banner/label copy is rewritten to be non-threatening ("Setting up
payment", "Paused", "Closed"). Aligns member-facing copy across the account
page with the capability model.
2026-04-18 17:06:22 +01:00

164 lines
4.3 KiB
JavaScript

/**
* Member Status Management Composable
* Handles member status constants, helpers, and UI state
*/
export const MEMBER_STATUSES = {
PENDING_PAYMENT: "pending_payment",
ACTIVE: "active",
SUSPENDED: "suspended",
CANCELLED: "cancelled",
};
export const MEMBER_STATUS_CONFIG = {
pending_payment: {
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: true,
canAccessMembers: true,
canPeerSupport: true,
},
active: {
label: "Active Member",
color: "green",
bgColor: "bg-green-500/10",
borderColor: "border-green-500/30",
textColor: "text-green-300",
icon: "heroicons:check-circle",
severity: "success",
canRSVP: true,
canAccessMembers: true,
canPeerSupport: true,
},
suspended: {
label: "Membership Suspended",
color: "red",
bgColor: "bg-red-500/10",
borderColor: "border-red-500/30",
textColor: "text-red-300",
icon: "heroicons:no-symbol",
severity: "error",
canRSVP: false,
canAccessMembers: false,
canPeerSupport: false,
},
cancelled: {
label: "Membership Cancelled",
color: "gray",
bgColor: "bg-gray-500/10",
borderColor: "border-gray-500/30",
textColor: "text-gray-300",
icon: "heroicons:x-circle",
severity: "error",
canRSVP: false,
canAccessMembers: false,
canPeerSupport: false,
},
};
export const useMemberStatus = () => {
const { memberData } = useAuth();
// Get current member status
const status = computed(
() => memberData.value?.status || MEMBER_STATUSES.PENDING_PAYMENT,
);
// Get status configuration
const statusConfig = computed(
() =>
MEMBER_STATUS_CONFIG[status.value] ||
MEMBER_STATUS_CONFIG.pending_payment,
);
// Helper methods
const isActive = computed(() => status.value === MEMBER_STATUSES.ACTIVE);
const isPendingPayment = computed(
() => status.value === MEMBER_STATUSES.PENDING_PAYMENT,
);
const isSuspended = computed(
() => status.value === MEMBER_STATUSES.SUSPENDED,
);
const isCancelled = computed(
() => status.value === MEMBER_STATUSES.CANCELLED,
);
const isInactive = computed(() => !isActive.value);
// Check if member can perform action
const canRSVP = computed(() => statusConfig.value.canRSVP);
const canAccessMembers = computed(() => statusConfig.value.canAccessMembers);
const canPeerSupport = computed(() => statusConfig.value.canPeerSupport);
// Get action button text and link based on status
const getNextAction = () => {
if (isPendingPayment.value) {
return {
label: "Complete Payment",
link: "/member/account",
icon: "heroicons:credit-card",
color: "orange",
};
}
if (isCancelled.value) {
return {
label: "Reactivate Membership",
link: "/member/account",
icon: "heroicons:arrow-path",
color: "blue",
};
}
if (isSuspended.value) {
return {
label: "Contact Support",
link: "mailto:support@ghostguild.org",
icon: "heroicons:envelope",
color: "gray",
};
}
return null;
};
// Get banner message based on status
const getBannerMessage = () => {
if (isPendingPayment.value) {
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 account is paused while we work through a community issue. We'll be in touch.";
}
if (isCancelled.value) {
return "Your account is closed. Reach out if you'd like to come back.";
}
return null;
};
// Get RSVP restriction message
const getRSVPMessage = () => {
if (isSuspended.value || isCancelled.value) {
return "Your account isn't active right now. Reach out if you have questions.";
}
return null;
};
return {
status,
statusConfig,
isActive,
isPendingPayment,
isSuspended,
isCancelled,
isInactive,
canRSVP,
canAccessMembers,
canPeerSupport,
getNextAction,
getBannerMessage,
getRSVPMessage,
MEMBER_STATUSES,
};
};