Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
2026-07-12 12:39:47 +08:00
parent 71f758fe0b
commit fa92d924f4
50 changed files with 2202 additions and 2623 deletions
+15
View File
@@ -22,3 +22,18 @@ export function tierBadgeClass(colorKey = 'green') {
export function tierPanelColors(colorKey = 'green') {
return getTierColor(colorKey).panel;
}
/**
* Picks the lowest-rank (cheapest) tier slug among several access paths —
* e.g. a Unit's own subscription plus every course that also unlocks it, or
* a Lesson's attached courses. Falls back to 'free' when none are gated.
*/
export function cheapestTierSlug(slugs = [], tierMap = {}) {
const gated = slugs.filter(Boolean);
if (!gated.length) return 'free';
return gated.reduce((cheapest, slug) => {
const rank = tierMap[slug]?.rank ?? 0;
const cheapestRank = tierMap[cheapest]?.rank ?? 0;
return rank < cheapestRank ? slug : cheapest;
}, gated[0]);
}
+26
View File
@@ -198,6 +198,32 @@ export const TIER_COLOR_OPTIONS = Object.entries(TIER_COLOR_MAP).map(([key, val]
swatch: val.swatch,
}));
/** Darkens (negative percent) or lightens (positive percent) a hex color. */
export function shadeColor(hex, percent) {
const num = parseInt(hex.replace("#", ""), 16);
const amt = Math.round(2.55 * percent);
const clamp = (v) => Math.max(0, Math.min(255, v));
const r = clamp((num >> 16) + amt);
const g = clamp(((num >> 8) & 0x00ff) + amt);
const b = clamp((num & 0x0000ff) + amt);
return "#" + (0x1000000 + r * 0x10000 + g * 0x100 + b).toString(16).slice(1);
}
// The perceived-brightness formula below underweights blue, so these read as
// "dark enough for white text" even though they're visually too light for it.
const FORCE_BLACK_TEXT = new Set(["sky", "blue", "cyan", "teal"]);
/** Returns "#000000" or "#ffffff", whichever reads better on top of the given hex color. */
export function getContrastText(hex, key) {
if (key && FORCE_BLACK_TEXT.has(key)) return "#000000";
const num = parseInt(hex.replace("#", ""), 16);
const r = (num >> 16) & 0xff;
const g = (num >> 8) & 0xff;
const b = num & 0xff;
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
return luminance > 0.6 ? "#000000" : "#ffffff";
}
/** Fallback when a stored color key is not in the map. */
const FALLBACK = TIER_COLOR_MAP.purple;