feat(tiers): add display-name layer, push.frequency entitlement, and rename pricing cards
Reconciles tier docs with `PlanSeeder` reality (basic has price_threshold and score_alerts; schema is stripe_price_id_monthly + stripe_price_id_annual) and introduces the display-name layer from pricing-plan.md v2. - PlanTier::label() + Plan::displayName() + PlanFeatures::displayName() expose user-facing names (Free/Daily/Smart/Pro); backend identifiers stay basic/plus/pro so every call site, Stripe mapping, and test keeps working. - push.frequency key added to features JSON (none/daily/triggered), mirroring email.frequency so Daily's daily push is distinguishable from Smart/Pro's triggered push. Seeder, factory, free-tier stubs, and Filament form updated. - Homepage pricing cards renamed: Basic→Daily, Plus→Smart; badge "Most Popular"→"Most pick this"; CTAs refreshed. - docs/tiers.md change log records the full diff. Fleet tier, 14-day trial copy, and Smart dark-card treatment deferred. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -259,10 +259,10 @@
|
||||
<a :href="ctaHref('free')" class="w-full py-3 px-4 border border-zinc-300 rounded-xl text-center font-bold hover:bg-zinc-100 transition-colors">{{ ctaLabel('free') }}</a>
|
||||
</div>
|
||||
|
||||
<!-- Basic -->
|
||||
<!-- Daily (backend: basic) -->
|
||||
<div class="bg-white border border-zinc-300 p-8 rounded-3xl flex flex-col h-full">
|
||||
<div class="mb-8">
|
||||
<h4 class="text-xl font-bold font-display mb-2">Basic</h4>
|
||||
<h4 class="text-xl font-bold font-display mb-2">Daily</h4>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="text-4xl font-black">{{ PRICES[cadence].basic }}</span>
|
||||
<span class="text-zinc-500 text-sm">{{ PRICE_SUFFIX[cadence] }}</span>
|
||||
@@ -276,11 +276,11 @@
|
||||
<a :href="ctaHref('basic')" class="w-full py-3 px-4 border border-zinc-300 rounded-xl text-center font-bold hover:bg-zinc-100 transition-colors">{{ ctaLabel('basic') }}</a>
|
||||
</div>
|
||||
|
||||
<!-- Plus -->
|
||||
<!-- Smart (backend: plus) -->
|
||||
<div class="bg-white border-2 border-accent p-8 rounded-3xl flex flex-col h-full relative">
|
||||
<div class="absolute -top-4 left-1/2 -translate-x-1/2 bg-accent text-white px-4 py-1 rounded-full text-[10px] font-black uppercase tracking-widest whitespace-nowrap">Most Popular</div>
|
||||
<div class="absolute -top-4 left-1/2 -translate-x-1/2 bg-accent text-white px-4 py-1 rounded-full text-[10px] font-black uppercase tracking-widest whitespace-nowrap">Most pick this</div>
|
||||
<div class="mb-8">
|
||||
<h4 class="text-xl font-bold font-display mb-2">Plus</h4>
|
||||
<h4 class="text-xl font-bold font-display mb-2">Smart</h4>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="text-4xl font-black text-accent">{{ PRICES[cadence].plus }}</span>
|
||||
<span class="text-zinc-500 text-sm">{{ PRICE_SUFFIX[cadence] }}</span>
|
||||
@@ -454,15 +454,15 @@ function ctaHref(tier) {
|
||||
|
||||
function ctaLabel(tier) {
|
||||
if (tier === 'free') {
|
||||
return isAuthenticated.value ? 'Go to dashboard' : 'Get started'
|
||||
return isAuthenticated.value ? 'Go to dashboard' : 'Start free'
|
||||
}
|
||||
if (isAuthenticated.value && userTier.value === tier) {
|
||||
return 'Manage subscription'
|
||||
}
|
||||
return {
|
||||
basic: 'Select Basic',
|
||||
plus: 'Join Plus',
|
||||
pro: 'Go Pro',
|
||||
basic: 'Choose Daily',
|
||||
plus: 'Choose Smart',
|
||||
pro: 'Choose Pro',
|
||||
}[tier]
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user