Yimaru-Admin/src/lib/teamInvitation.ts
Yared Yemane e75420e756 feat(admin): analytics user breakdowns, email templates, and team invites
Surface education, occupation, learning goals, and language challenges on the analytics page with normalized dashboard API parsing. Add email template management, accept-invite onboarding, and role-based team invitations.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 10:21:55 -07:00

45 lines
1.5 KiB
TypeScript

import type { VerifyInvitationData } from "../types/teamInvitation.types"
export function formatTeamRoleLabel(role: string | undefined): string {
if (!role) return "—"
return role.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())
}
export function formatInvitationExpiry(raw: string | undefined): string | null {
if (!raw) return null
const d = new Date(raw)
if (Number.isNaN(d.getTime())) return raw
return d.toLocaleString(undefined, { dateStyle: "medium", timeStyle: "short" })
}
/** User-facing title when verify returns valid: false. */
export function getInvalidInvitationTitle(data: VerifyInvitationData | null): string {
const status = data?.status?.toLowerCase() ?? ""
const message = (data?.message ?? "").toLowerCase()
if (status === "expired" || message.includes("expir")) {
return "This invitation has expired"
}
if (
status === "accepted" ||
message.includes("already") ||
message.includes("used") ||
message.includes("accepted")
) {
return "This invitation was already used"
}
if (status === "revoked" || message.includes("revok")) {
return "This invitation was revoked"
}
return "This invitation link is invalid"
}
export function getInvalidInvitationDescription(
data: VerifyInvitationData | null,
apiMessage?: string,
): string {
const specific = data?.message?.trim() || apiMessage?.trim()
if (specific) return specific
return "The link may be expired, invalid, or already used. Ask your administrator to send a new invitation."
}