From e6bc1e93da094ade916812656946180ea5f05853 Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Tue, 10 Dec 2024 18:21:10 -0500 Subject: [PATCH] Convert PurchasesList to TS --- .../purchases-list/{index.jsx => index.tsx} | 51 +++++++++++++------ client/me/purchases/purchases-site/index.tsx | 2 +- .../get-available-concierge-sessions.ts | 2 +- .../get-concierge-next-appointment.js | 5 -- .../get-concierge-next-appointment.ts | 11 ++++ 5 files changed, 48 insertions(+), 23 deletions(-) rename client/me/purchases/purchases-list/{index.jsx => index.tsx} (81%) delete mode 100644 client/state/selectors/get-concierge-next-appointment.js create mode 100644 client/state/selectors/get-concierge-next-appointment.ts diff --git a/client/me/purchases/purchases-list/index.jsx b/client/me/purchases/purchases-list/index.tsx similarity index 81% rename from client/me/purchases/purchases-list/index.jsx rename to client/me/purchases/purchases-list/index.tsx index 4007193a8aec5..660d16aed03d9 100644 --- a/client/me/purchases/purchases-list/index.jsx +++ b/client/me/purchases/purchases-list/index.tsx @@ -1,7 +1,8 @@ import { recordTracksEvent } from '@automattic/calypso-analytics'; import { CompactCard } from '@automattic/components'; -import { localize } from 'i18n-calypso'; -import PropTypes from 'prop-types'; +import { SiteDetails } from '@automattic/data-stores'; +import { isValueTruthy } from '@automattic/wpcom-checkout'; +import { LocalizeProps, localize } from 'i18n-calypso'; import { Component } from 'react'; import { connect } from 'react-redux'; import noSitesIllustration from 'calypso/assets/images/illustrations/illustration-nosites.svg'; @@ -16,10 +17,14 @@ import NavigationHeader from 'calypso/components/navigation-header'; import PageViewTracker from 'calypso/lib/analytics/page-view-tracker'; import TrackComponentView from 'calypso/lib/analytics/track-component-view'; import { getPurchasesBySite, getSubscriptionsBySite } from 'calypso/lib/purchases'; +import { MembershipSubscription, Purchase } from 'calypso/lib/purchases/types'; import { PurchaseListConciergeBanner } from 'calypso/me/purchases/purchases-list/purchase-list-concierge-banner'; import PurchasesNavigation from 'calypso/me/purchases/purchases-navigation'; import titles from 'calypso/me/purchases/titles'; -import { withStoredPaymentMethods } from 'calypso/my-sites/checkout/src/hooks/use-stored-payment-methods'; +import { + WithStoredPaymentMethodsProps, + withStoredPaymentMethods, +} from 'calypso/my-sites/checkout/src/hooks/use-stored-payment-methods'; import { getAllSubscriptions } from 'calypso/state/memberships/subscriptions/selectors'; import { getUserPurchases, @@ -27,15 +32,36 @@ import { isFetchingUserPurchases, } from 'calypso/state/purchases/selectors'; import getAvailableConciergeSessions from 'calypso/state/selectors/get-available-concierge-sessions'; -import getConciergeNextAppointment from 'calypso/state/selectors/get-concierge-next-appointment'; +import getConciergeNextAppointment, { + NextAppointment, +} from 'calypso/state/selectors/get-concierge-next-appointment'; import getConciergeUserBlocked from 'calypso/state/selectors/get-concierge-user-blocked'; import getSites from 'calypso/state/selectors/get-sites'; import { getSiteId } from 'calypso/state/sites/selectors'; +import { AppState } from 'calypso/types'; import MembershipSite from '../membership-site'; import PurchasesSite from '../purchases-site'; import PurchasesListHeader from './purchases-list-header'; -class PurchasesList extends Component { +export interface PurchasesListProps { + noticeType?: string | undefined; +} + +export interface PurchasesListConnectedProps { + hasLoadedUserPurchasesFromServer: boolean; + isFetchingUserPurchases: boolean; + purchases: Purchase[] | null; + subscriptions: MembershipSubscription[]; + sites: SiteDetails[]; + nextAppointment: NextAppointment | null; + isUserBlocked: boolean; + availableSessions: number[]; + siteId: number | null; +} + +class PurchasesList extends Component< + PurchasesListProps & PurchasesListConnectedProps & WithStoredPaymentMethodsProps & LocalizeProps +> { isDataLoading() { if ( this.props.isFetchingUserPurchases && ! this.props.hasLoadedUserPurchasesFromServer ) { return true; @@ -48,7 +74,7 @@ class PurchasesList extends Component { const { nextAppointment, availableSessions, isUserBlocked } = this.props; return ( @@ -164,21 +190,14 @@ class PurchasesList extends Component { } } -PurchasesList.propTypes = { - noticeType: PropTypes.string, - purchases: PropTypes.array, - subscriptions: PropTypes.array, - sites: PropTypes.array, -}; - -export default connect( ( state ) => ( { +export default connect( ( state: AppState ) => ( { hasLoadedUserPurchasesFromServer: hasLoadedUserPurchasesFromServer( state ), isFetchingUserPurchases: isFetchingUserPurchases( state ), purchases: getUserPurchases( state ), subscriptions: getAllSubscriptions( state ), - sites: getSites( state ), + sites: getSites( state ).filter( isValueTruthy ), nextAppointment: getConciergeNextAppointment( state ), isUserBlocked: getConciergeUserBlocked( state ), availableSessions: getAvailableConciergeSessions( state ), - siteId: getSiteId( state ), + siteId: getSiteId( state, null ), } ) )( withStoredPaymentMethods( localize( PurchasesList ), { type: 'card', expired: true } ) ); diff --git a/client/me/purchases/purchases-site/index.tsx b/client/me/purchases/purchases-site/index.tsx index f36e4ac453131..287304d235e33 100644 --- a/client/me/purchases/purchases-site/index.tsx +++ b/client/me/purchases/purchases-site/index.tsx @@ -22,7 +22,7 @@ export default function PurchasesSite( siteId?: number; } | { - getManagePurchaseUrlFor: ( slug: string, purchaseId: number ) => string; + getManagePurchaseUrlFor?: ( slug: string, purchaseId: number ) => string; isPlaceholder?: false; siteId: number; purchases: Purchase[]; diff --git a/client/state/selectors/get-available-concierge-sessions.ts b/client/state/selectors/get-available-concierge-sessions.ts index c50308afd5b5e..622399ee66619 100644 --- a/client/state/selectors/get-available-concierge-sessions.ts +++ b/client/state/selectors/get-available-concierge-sessions.ts @@ -1,4 +1,4 @@ import 'calypso/state/concierge/init'; import type { AppState } from 'calypso/types'; -export default ( state: AppState ) => state?.concierge?.availableSessions || []; +export default ( state: AppState ): number[] => state?.concierge?.availableSessions || []; diff --git a/client/state/selectors/get-concierge-next-appointment.js b/client/state/selectors/get-concierge-next-appointment.js deleted file mode 100644 index 27bb568b19e4b..0000000000000 --- a/client/state/selectors/get-concierge-next-appointment.js +++ /dev/null @@ -1,5 +0,0 @@ -import { get } from 'lodash'; - -import 'calypso/state/concierge/init'; - -export default ( state ) => get( state, 'concierge.nextAppointment', null ); diff --git a/client/state/selectors/get-concierge-next-appointment.ts b/client/state/selectors/get-concierge-next-appointment.ts new file mode 100644 index 0000000000000..117dcbe5b4202 --- /dev/null +++ b/client/state/selectors/get-concierge-next-appointment.ts @@ -0,0 +1,11 @@ +import 'calypso/state/concierge/init'; +import { AppState } from 'calypso/types'; + +export interface NextAppointment { + id: number; + siteId: number; + scheduleId: number; +} + +export default ( state: AppState ): NextAppointment | null => + state.concierge?.nextAppointment ?? null;