pingql/apps/shared/plans.ts

73 lines
3.4 KiB
TypeScript

// ── Types ─────────────────────────────────────────────────────────
export type Plan = "free" | "pro" | "pro2x" | "pro4x" | "lifetime";
export interface PlanLimits {
maxMonitors: number;
minIntervalS: number;
maxRegions: number;
}
// ── Limits ────────────────────────────────────────────────────────
const PLAN_LIMITS: Record<Plan, PlanLimits> = {
free: { maxMonitors: 10, minIntervalS: 30, maxRegions: 1 },
pro: { maxMonitors: 200, minIntervalS: 5, maxRegions: 99 },
pro2x: { maxMonitors: 400, minIntervalS: 5, maxRegions: 99 },
pro4x: { maxMonitors: 800, minIntervalS: 5, maxRegions: 99 },
lifetime: { maxMonitors: 200, minIntervalS: 5, maxRegions: 99 },
};
export function getPlanLimits(plan: string): PlanLimits {
return PLAN_LIMITS[plan as Plan] || PLAN_LIMITS.free;
}
// ── Display ───────────────────────────────────────────────────────
export const PLAN_LABELS: Record<string, string> = {
free: "Free", pro: "Pro", pro2x: "Pro 2x", pro4x: "Pro 4x", lifetime: "Lifetime",
};
// ── Pricing ───────────────────────────────────────────────────────
export const PRO_MONTHLY_USD = 12;
export const LIFETIME_USD = 140;
export const PLAN_PRICING: Record<string, { label: string; monthlyUsd?: number; priceUsd?: number }> = {
pro: { label: "Pro", monthlyUsd: PRO_MONTHLY_USD },
pro2x: { label: "Pro 2x", monthlyUsd: PRO_MONTHLY_USD * 2 },
pro4x: { label: "Pro 4x", monthlyUsd: PRO_MONTHLY_USD * 4 },
lifetime: { label: "Lifetime", priceUsd: LIFETIME_USD },
};
export const COINS: Record<string, { label: string; ticker: string; confirmations: number; uri: string }> = {
btc: { label: "Bitcoin", ticker: "BTC", confirmations: 1, uri: "bitcoin" },
ltc: { label: "Litecoin", ticker: "LTC", confirmations: 1, uri: "litecoin" },
doge: { label: "Dogecoin", ticker: "DOGE", confirmations: 1, uri: "dogecoin" },
dash: { label: "Dash", ticker: "DASH", confirmations: 1, uri: "dash" },
bch: { label: "Bitcoin Cash", ticker: "BCH", confirmations: 0, uri: "bitcoincash" },
xec: { label: "eCash", ticker: "XEC", confirmations: 0, uri: "ecash" },
};
// ── Tier ranking (for plan stacking) ──────────────────────────────
const PLAN_RANK: Record<string, number> = {
free: 0, pro: 1, lifetime: 1, pro2x: 2, pro4x: 3,
};
export function planTier(plan: string): number {
return PLAN_RANK[plan] ?? 0;
}
// ── Regions ───────────────────────────────────────────────────────
export const REGION_COLORS: Record<string, string> = {
"eu-central": "#3b82f6",
"us-west": "#f59e0b",
"__none__": "#6b7280",
};
export const REGION_LABELS: Record<string, string> = {
"eu-central": "EU Central",
"us-west": "US West",
};
export const REGIONS: [string, string][] = [
["eu-central", "EU Central"],
["us-west", "US West"],
];