[web] Remove SubscriptionFormatters, format subscription dates in the frontend (#36409)

* [web] Remove SubscriptionFormatters, format subscription dates in the frontend

Replace the server-formatted nextPaymentDueAt/nextPaymentDueDate/
trialEndsAtFormatted fields with the raw periodEnd date and format in
the React dashboard (same strings as before, English + UTC). Also
consolidate hand-rolled trial checks onto isInFreeTrial /
SubscriptionHelper.isInTrial.

* [web] Remove the now-unused dateformat dependency

* [web] Address review: payment-dates unit test, UTC dates in acceptance test

Add a dedicated unit test asserting the exact formatted strings from
formatPaymentDate/formatPaymentDateTime, and use explicit UTC timestamps
in the SubscriptionDashboard acceptance fixtures instead of
local-timezone Date constructors.

GitOrigin-RevId: 16ac4f1098b14ef9f1478d22cf39c1357ead7dea
This commit is contained in:
Antoine Clausse
2026-09-17 11:52:44 +00:00
committed by Copybot
parent d0399bd09f
commit ba4f024f34
26 changed files with 149 additions and 203 deletions
@@ -1,20 +0,0 @@
import dateformat from 'dateformat'
function formatDateTime(date) {
if (!date) {
return null
}
return dateformat(date, 'mmmm dS, yyyy h:MM TT Z', true)
}
function formatDate(date) {
if (!date) {
return null
}
return dateformat(date, 'mmmm dS, yyyy', true)
}
export default {
formatDateTime,
formatDate,
}
@@ -5,7 +5,6 @@ import PlansLocator from './PlansLocator.mjs'
import { getLocalizedPlanPricing } from './PriceVersions.mjs'
import { isStandaloneAiAddOnPlanCode } from './AiHelper.mjs'
import PaymentProviderEntities from './PaymentProviderEntities.mjs'
import SubscriptionFormatters from './SubscriptionFormatters.mjs'
import SubscriptionLocator from './SubscriptionLocator.mjs'
import InstitutionsGetter from '../Institutions/InstitutionsGetter.mjs'
import InstitutionsManager from '../Institutions/InstitutionsManager.mjs'
@@ -257,9 +256,9 @@ async function buildUsersSubscriptionViewModel(user, locale = 'en') {
}
})
const totalLicenses = (plan.membersLimit || 0) + additionalLicenses
const isInTrial =
paymentRecord.subscription.trialPeriodEnd &&
paymentRecord.subscription.trialPeriodEnd.getTime() > Date.now()
const isInTrial = SubscriptionHelper.isInTrial(
paymentRecord.subscription.trialPeriodEnd
)
let isEligibleForPause = false
const commonPauseConditions =
@@ -302,18 +301,10 @@ async function buildUsersSubscriptionViewModel(user, locale = 'en') {
additionalLicenses,
addOns,
totalLicenses,
nextPaymentDueAt: SubscriptionFormatters.formatDateTime(
paymentRecord.subscription.periodEnd
),
nextPaymentDueDate: SubscriptionFormatters.formatDate(
paymentRecord.subscription.periodEnd
),
periodEnd: paymentRecord.subscription.periodEnd,
currency: paymentRecord.subscription.currency,
planPrice: paymentRecord.subscription.planPrice,
state: paymentRecord.subscription.state,
trialEndsAtFormatted: SubscriptionFormatters.formatDateTime(
paymentRecord.subscription.trialPeriodEnd
),
trialEndsAt: paymentRecord.subscription.trialPeriodEnd,
activeCoupons,
accountEmail: paymentRecord.account.email,