Files
starr-philproperties/src/utils/planBundle.util.js
T
2026-08-05 04:32:29 +08:00

41 lines
1.9 KiB
JavaScript

import { BookOpen, Layers, FileText } from "lucide-react";
// A plan's bundle is single-type (Tier Plans v2) — resolve whichever of
// courses/units/lessons is actually populated instead of assuming courses.
const BUNDLE_META = {
course: { icon: BookOpen, idKey: "course_id", noun: "Course" },
unit: { icon: Layers, idKey: "unit_id", noun: "Unit" },
lesson: { icon: FileText, idKey: "lesson_id", noun: "Lesson" },
};
export function getBundleContent(plan) {
if (plan?.courses?.length) return { type: "course", items: plan.courses, ...BUNDLE_META.course };
if (plan?.units?.length) return { type: "unit", items: plan.units, ...BUNDLE_META.unit };
if (plan?.lessons?.length) return { type: "lesson", items: plan.lessons, ...BUNDLE_META.lesson };
return null;
}
// Item-specific "already covered" check (Tier Plans v2) — a plan is blocked
// from purchase if ANY of its bundle items overlap the user's existing
// granted items, even partially, regardless of tier slug.
export function overlapsExistingAccess(plan, myGrants) {
if (!myGrants) return false;
const overlaps = (planIds = [], grantedIds = []) => {
const granted = new Set((grantedIds ?? []).map(String));
return (planIds ?? []).some((id) => granted.has(String(id)));
};
return (
overlaps(plan?.course_ids, myGrants.course_ids) ||
overlaps(plan?.unit_ids, myGrants.unit_ids) ||
overlaps(plan?.lesson_ids, myGrants.lesson_ids)
);
}
// "Current" means the user actually purchased THIS exact plan (matched by
// plan_id) and it's still active — NOT just any plan sharing the same tier
// slug. Two different plans can be the same tier (e.g. two Premium bundles)
// and stay independently active (Tier Plans v2).
export function isPlanCurrent(plan, myTier) {
return (myTier?.active_tiers ?? []).some((t) => t.plan_id != null && String(t.plan_id) === String(plan?.plan_id));
}