feat: enhance HomePage and OrganizationSettings to display detailed subscription information and improve user interaction with invoice links

This commit is contained in:
Usman Baig
2026-02-20 18:05:59 +01:00
parent 6817f0c9fa
commit fa3982001d
3 changed files with 31 additions and 6 deletions

View File

@@ -390,7 +390,7 @@ export default function HomePage() {
return `${label} Plan` return `${label} Plan`
})()} })()}
</p> </p>
{(typeof subscription.sites_count === 'number' || (subscription.pageview_limit > 0 && typeof subscription.pageview_usage === 'number')) && ( {(typeof subscription.sites_count === 'number' || (subscription.pageview_limit > 0 && typeof subscription.pageview_usage === 'number') || (subscription.next_invoice_amount_due != null && subscription.next_invoice_currency && !subscription.cancel_at_period_end && (subscription.subscription_status === 'active' || subscription.subscription_status === 'trialing'))) && (
<p className="text-sm text-neutral-600 dark:text-neutral-400 mt-1"> <p className="text-sm text-neutral-600 dark:text-neutral-400 mt-1">
{typeof subscription.sites_count === 'number' && ( {typeof subscription.sites_count === 'number' && (
<span>Sites: {(() => { <span>Sites: {(() => {
@@ -398,10 +398,26 @@ export default function HomePage() {
return limit != null && typeof subscription.sites_count === 'number' ? `${subscription.sites_count}/${limit}` : subscription.sites_count return limit != null && typeof subscription.sites_count === 'number' ? `${subscription.sites_count}/${limit}` : subscription.sites_count
})()}</span> })()}</span>
)} )}
{typeof subscription.sites_count === 'number' && subscription.pageview_limit > 0 && typeof subscription.pageview_usage === 'number' && ' · '} {typeof subscription.sites_count === 'number' && (subscription.pageview_limit > 0 && typeof subscription.pageview_usage === 'number') && ' · '}
{subscription.pageview_limit > 0 && typeof subscription.pageview_usage === 'number' && ( {subscription.pageview_limit > 0 && typeof subscription.pageview_usage === 'number' && (
<span>Pageviews: {subscription.pageview_usage.toLocaleString()}/{subscription.pageview_limit.toLocaleString()}</span> <span>Pageviews: {subscription.pageview_usage.toLocaleString()}/{subscription.pageview_limit.toLocaleString()}</span>
)} )}
{subscription.next_invoice_amount_due != null && subscription.next_invoice_currency && !subscription.cancel_at_period_end && (subscription.subscription_status === 'active' || subscription.subscription_status === 'trialing') && (
<span className="block mt-1">
Renews {(() => {
const ts = subscription.next_invoice_period_end ?? subscription.current_period_end
const d = ts ? new Date(typeof ts === 'number' ? ts * 1000 : ts) : null
const dateStr = d && !Number.isNaN(d.getTime()) && d.getTime() !== 0
? d.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' })
: null
const amount = (subscription.next_invoice_amount_due / 100).toLocaleString('en-US', {
style: 'currency',
currency: subscription.next_invoice_currency.toUpperCase(),
})
return dateStr ? `${dateStr} for ${amount}` : amount
})()}
</span>
)}
</p> </p>
)} )}
<div className="mt-2 flex gap-2"> <div className="mt-2 flex gap-2">

View File

@@ -376,9 +376,12 @@ export default function PricingSection() {
</div> </div>
</div> </div>
<Button variant="secondary" className="w-full mb-8 border-neutral-200 dark:border-neutral-700 hover:bg-neutral-100 dark:hover:bg-neutral-800"> <a
href="mailto:business@ciphera.net?subject=Enterprise%20Plan%20Inquiry"
className="inline-flex items-center justify-center w-full mb-8 rounded-lg border border-neutral-200 dark:border-neutral-700 px-4 py-2 text-sm font-medium text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-colors focus:outline-none focus:ring-2 focus:ring-brand-orange"
>
Contact us Contact us
</Button> </a>
<ul className="space-y-4"> <ul className="space-y-4">
{[ {[

View File

@@ -312,6 +312,7 @@ export default function OrganizationSettings() {
const limit = getLimitForTierIndex(changePlanTierIndex) const limit = getLimitForTierIndex(changePlanTierIndex)
previewInvoice({ plan_id: changePlanId, interval, limit }) previewInvoice({ plan_id: changePlanId, interval, limit })
.then((res) => { if (!cancelled) setInvoicePreview(res ?? null) }) .then((res) => { if (!cancelled) setInvoicePreview(res ?? null) })
.catch(() => { if (!cancelled) { setInvoicePreview(null) } })
.finally(() => { if (!cancelled) setIsLoadingPreview(false) }) .finally(() => { if (!cancelled) setIsLoadingPreview(false) })
return () => { cancelled = true } return () => { cancelled = true }
}, [showChangePlanModal, hasActiveSubscription, changePlanId, changePlanTierIndex, changePlanYearly]) }, [showChangePlanModal, hasActiveSubscription, changePlanId, changePlanTierIndex, changePlanYearly])
@@ -1083,9 +1084,14 @@ export default function OrganizationSettings() {
)} )}
{invoice.hosted_invoice_url && ( {invoice.hosted_invoice_url && (
<a href={invoice.hosted_invoice_url} target="_blank" rel="noopener noreferrer" <a href={invoice.hosted_invoice_url} target="_blank" rel="noopener noreferrer"
className="inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-brand-orange" title="View invoice"> className={`inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-brand-orange ${
invoice.status === 'open'
? 'bg-brand-orange text-white hover:bg-brand-orange-hover'
: 'text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800'
}`}
title={invoice.status === 'open' ? 'Pay now' : 'View invoice'}>
<ExternalLinkIcon className="w-3.5 h-3.5" /> <ExternalLinkIcon className="w-3.5 h-3.5" />
View invoice {invoice.status === 'open' ? 'Pay now' : 'View invoice'}
</a> </a>
)} )}
</div> </div>