// plans.jsx — subscription tiers (space themed) + Profile plan card
const { useState: useStateP } = React;
const { Card, Chip, TopBar, IconBtn, DisplayHeading, Icon } = window.LAUNCH_SCREENS_1;
// Three tiers: free (browse only), basic ($9.99), vip ($19.99). Monthly,
// 30-day periods. Benefits map 1:1 to entitlements in user.jsx / subscriptions.sql.
const PLANS = [
{
id: 'free',
name: 'FREE',
price: 0,
priceDisplay: '0',
short: 'no plan',
tagline: 'Browse the community. Subscribe to join in.',
altitude: 'GROUND CONTROL',
coords: 'T-MINUS 10',
perks: [
'See the Feed, profiles & coaches',
'No posting, liking or comments',
'No chat or following',
'Upgrade anytime to unlock everything',
],
palette: ['#3A3F4A', '#0B0B0F'],
glow: '#9AA3B2',
},
{
id: 'basic',
name: 'BASIC',
price: 9.99,
priceDisplay: '9.99',
short: '$9.99 / mo',
tagline: 'Join the community + a free quick review every month.',
altitude: 'LOW EARTH ORBIT',
coords: '400 KM · ALTITUDE',
perks: [
'Full Feed access — post, like, comment, upload & rate',
'Earn & redeem community points',
'1 free Quick Score review ($11) every month',
],
palette: ['#5B6AC4', '#0B1030'],
glow: '#7AA8FF',
badge: 'POPULAR',
},
{
id: 'vip',
name: 'VIP',
price: 19.99,
priceDisplay: '19.99',
short: '$19.99 / mo',
tagline: 'Everything in Basic, plus pro reviews & a coach class.',
altitude: 'DEEP SPACE',
coords: 'ALL ACCESS',
perks: [
'Everything in Basic',
'2 free In-Depth reviews ($40 each) every month',
'1 free 20-min class with a coach every month',
],
palette: ['#C72820', '#7A1A0A'],
glow: '#FF7849',
badge: 'BEST VALUE',
},
];
// Format a plan expiry ISO date → 'JUN 30, 2026'.
function fmtPlanDate(iso) {
if (!iso) return '';
try {
return new Date(iso).toLocaleDateString('en-US', { month: 'short', day: '2-digit', year: 'numeric' }).toUpperCase();
} catch (e) { return ''; }
}
// SVG starfield + planet for plan cards
function PlanCelestial({ palette, glow, size = 110 }) {
const [c1, c2] = palette;
return (
);
}
// ─────────────────────────────────────────────────────────────
// Compact plan card for Profile
// ─────────────────────────────────────────────────────────────
function ProfilePlanCard({ theme, currentPlanId, expiresAt, active, onOpen }) {
const plan = PLANS.find(p => p.id === currentPlanId) || PLANS[0];
const isFree = plan.id === 'free' || !active;
const subline = isFree
? 'NO PLAN · TAP TO SUBSCRIBE'
: `$${plan.priceDisplay}/MO · RENEWS ${fmtPlanDate(expiresAt)}`;
return (
);
}
// ─────────────────────────────────────────────────────────────
// Full plans screen
// ─────────────────────────────────────────────────────────────
function PlansScreen({ theme, currentPlanId, onBack, onSubscribe }) {
const [selected, setSelected] = useStateP(currentPlanId === 'free' ? 'basic' : currentPlanId);
return (
{/* Starfield background */}
{/* Top bar */}
{/* Hero */}
★ CHOOSE YOUR ALTITUDE
HOW FAR
YOU GOING?
Three orbits. Cancel anytime. The further out you go, the more we put behind your launch.
{/* Plan cards */}
{PLANS.map((p, i) => {
const isCurrent = p.id === currentPlanId;
const isSelected = p.id === selected;
return (
);
})}
{/* FAQ-ish strip */}
★ THE FINE PRINT
Cancel or change orbit anytime. We pro-rate upgrades and refund downgrades. Stratosphere is invite-only — apply and we'll review within 7 days.
{/* Sticky CTA */}
SELECTED ALTITUDE
{PLANS.find(p => p.id === selected).name} · ${PLANS.find(p => p.id === selected).priceDisplay}/MO
);
}
window.LAUNCH_SCREENS_4 = { PlansScreen, ProfilePlanCard, PLANS };