metatroncubeswdev b59c2d0668 Plans page: show yearly prices and Plus extras
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 11:58:22 -04:00

58 lines
2.4 KiB
TypeScript

// Plans (brief §18). Prices live in the Partner Dashboard (managed pricing); limits are enforced here,
// server-side, when publishing and when compiling the function configuration.
export type PlanCode = "free" | "starter" | "growth" | "plus";
export interface PlanLimits {
name: string;
price: string;
runningOffers: number; // Infinity = unlimited (within config size)
types: string[];
scheduling: boolean;
homepage: boolean;
cartHints: boolean;
branding: boolean;
monthlyOrders: number;
templates: boolean;
analytics: boolean;
markets: boolean;
translations: boolean;
/** shown on the Plans page only */
yearly?: string;
extras?: string[];
}
const ALL_TYPES = ["fixed", "mix", "bxgy"];
export const PLANS: Record<PlanCode, PlanLimits> = {
free: {
name: "Free", price: "$0", runningOffers: 1, types: ["fixed"], scheduling: false, homepage: false,
cartHints: false, branding: true, monthlyOrders: 50, templates: false, analytics: false, markets: false, translations: false,
},
starter: {
name: "Starter", price: "$9.99/mo", yearly: "$99/yr", runningOffers: 5, types: ALL_TYPES, scheduling: true, homepage: true,
cartHints: true, branding: false, monthlyOrders: Infinity, templates: false, analytics: false, markets: false, translations: false,
},
growth: {
name: "Growth", price: "$24.99/mo", yearly: "$249/yr", runningOffers: Infinity, types: ALL_TYPES, scheduling: true, homepage: true,
cartHints: true, branding: false, monthlyOrders: Infinity, templates: true, analytics: true, markets: true, translations: true,
},
plus: {
name: "Plus", price: "$59.99/mo", yearly: "$599/yr", extras: ["priority support", "onboarding call", "custom styling help"], runningOffers: Infinity, types: ALL_TYPES, scheduling: true, homepage: true,
cartHints: true, branding: false, monthlyOrders: Infinity, templates: true, analytics: true, markets: true, translations: true,
},
};
export function planOf(code: string | null | undefined): PlanLimits {
return PLANS[(code as PlanCode) in PLANS ? (code as PlanCode) : "free"];
}
/** Maps a managed-pricing subscription name (Partner Dashboard plan name) to a plan code. */
export function planCodeFromSubscription(name: string | null | undefined): PlanCode {
const n = (name || "").toLowerCase();
if (n.includes("plus")) return "plus";
if (n.includes("growth")) return "growth";
if (n.includes("starter")) return "starter";
return "free";
}