Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add click through announcement feature #6821

Merged
merged 11 commits into from
Oct 24, 2023
74 changes: 43 additions & 31 deletions src/billing/components/PayAsYouGo/PayAsYouGo.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
// Libraries
import React, {FC} from 'react'
import {useSelector} from 'react-redux'

// Components
import {
AlignItems,
ComponentSize,
Expand All @@ -7,8 +11,6 @@ import {
Panel,
ResourceList,
} from '@influxdata/clockface'

// Components
import PlanTypePanel from 'src/billing/components/PayAsYouGo/PlanTypePanel'
import PaymentPanel from 'src/billing/components/PaymentInfo/PaymentPanel'
import BillingContactInfo from 'src/billing/components/BillingContactInfo'
Expand All @@ -17,35 +19,45 @@ import CancellationPanel from 'src/billing/components/PayAsYouGo/CancellationPan
import NotificationPanel from 'src/billing/components/PayAsYouGo/NotificationPanel'
import InvoiceLoadingWrapper from 'src/billing/components/AssetLoading/InvoiceWrapper'
import BillingInfoWrapper from 'src/billing/components/AssetLoading/BillingInfoWrapper'
import {PricingAlert} from 'src/billing/components/PayAsYouGo/PricingAlert'

// Utils
import {selectCurrentIdentity} from 'src/identity/selectors'

const BillingPayAsYouGo: FC = () => {
const {account} = useSelector(selectCurrentIdentity)
const directSignup = account.billingProvider === 'zuora'
mavarius marked this conversation as resolved.
Show resolved Hide resolved

const BillingPayAsYouGo: FC = () => (
<FlexBox
direction={FlexDirection.Column}
alignItems={AlignItems.Stretch}
margin={ComponentSize.Small}
>
<BillingInfoWrapper>
<>
<PlanTypePanel />
<Panel>
<Panel.Header testID="past-invoices--header">
<h4>Past Invoices</h4>
</Panel.Header>
<Panel.Body>
<ResourceList>
<InvoiceLoadingWrapper>
<InvoiceHistory />
</InvoiceLoadingWrapper>
</ResourceList>
</Panel.Body>
</Panel>
<PaymentPanel />
<BillingContactInfo />
</>
</BillingInfoWrapper>
<NotificationPanel />
<CancellationPanel />
</FlexBox>
)
return (
<FlexBox
direction={FlexDirection.Column}
alignItems={AlignItems.Stretch}
margin={ComponentSize.Small}
>
<BillingInfoWrapper>
<>
{directSignup && <PricingAlert />}
<PlanTypePanel />
<Panel>
<Panel.Header testID="past-invoices--header">
<h4>Past Invoices</h4>
</Panel.Header>
<Panel.Body>
<ResourceList>
<InvoiceLoadingWrapper>
<InvoiceHistory />
</InvoiceLoadingWrapper>
</ResourceList>
</Panel.Body>
</Panel>
<PaymentPanel />
<BillingContactInfo />
</>
</BillingInfoWrapper>
<NotificationPanel />
<CancellationPanel />
</FlexBox>
)
}

export default BillingPayAsYouGo
66 changes: 66 additions & 0 deletions src/billing/components/PayAsYouGo/PricingAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Libraries
import React, {useEffect} from 'react'
import {useSelector} from 'react-redux'

// Components
import {
Alert,
FlexBox,
IconFont,
ComponentColor,
ComponentSize,
} from '@influxdata/clockface'
import {SafeBlankLink} from 'src/utils/SafeBlankLink'

// Utils
import {event} from 'src/cloud/utils/reporting'

// Selectors
import {selectCurrentOrg, selectUser} from 'src/identity/selectors'

export const PricingAlert: React.FC = () => {
useEffect(() => {
event(`pricingAnnouncementBanner.displayed`)
}, [])

const org = useSelector(selectCurrentOrg)
const user = useSelector(selectUser)

const handleContactUsClick = () => {
event(`pricingAnnouncementBanner.contactUs.clicked`)
}

const handlePricingAnnouncementClick = () => {
event(`pricingAnnouncementBanner.details.clicked`)
}

return (
<Alert icon={IconFont.AlertTriangle} color={ComponentColor.Primary}>
<FlexBox margin={ComponentSize.Medium}>
<FlexBox.Child grow={1} shrink={0}>
Starting on <b>December 1, 2023</b> there will be an increase in to
your usage-based pricing. Please feel free to{' '}
<SafeBlankLink
href={`mailto:[email protected]?
&subject=PAYG%20price%20change%20inquiry
&body=User%20ID:%20${user.email}%0D%0AOrg%20ID:%20${org.id}%0D%0A%0D%0APlease%20describe%20your%20inquiry%20here.`}
onClick={handleContactUsClick}
mavarius marked this conversation as resolved.
Show resolved Hide resolved
>
contact us
</SafeBlankLink>{' '}
with questions or refer to our website for additional information.
</FlexBox.Child>
<FlexBox.Child grow={0} shrink={0}>
<SafeBlankLink
href="https://www.influxdata.com/influxdb-pricing"
onClick={handlePricingAnnouncementClick}
>
<div className="cf-button cf-button-xs cf-button-primary">
<span className="cf-button-label">View Pricing Changes</span>
</div>
</SafeBlankLink>
</FlexBox.Child>
</FlexBox>
</Alert>
)
}
67 changes: 67 additions & 0 deletions src/homepageExperience/ClickThroughAnnouncementHandler.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Libraries
import {FC, useEffect} from 'react'
import {useSelector, useDispatch} from 'react-redux'
import {useLocalStorageState} from 'use-local-storage-state'

// Selectors
import {selectCurrentIdentity} from 'src/identity/selectors'

// Utils
import {showOverlay, dismissOverlay} from 'src/overlays/actions/overlays'

// Constants
import {CLOUD} from 'src/shared/constants'

export const ClickThroughAnnouncementHandler: FC = () => {
const dispatch = useDispatch()
const {account} = useSelector(selectCurrentIdentity)

const [announcementState, setAnnouncementState] = useLocalStorageState(
'clickThroughAnnouncement',
{
announcementID: '',
display: true,
}
)
mavarius marked this conversation as resolved.
Show resolved Hide resolved

const setCurrentAnnouncement = (announcementID: string): void => {
if (announcementState['announcementID'] !== announcementID) {
setAnnouncementState({
announcementID: announcementID,
display: true,
})
}
}

const handleDismissAnnouncement = (): void => {
setAnnouncementState(prevState => ({
...prevState,
display: false,
}))
dismissOverlay()
}

useEffect(() => {
// Current Announcement: PAYG Pricing Increase
// Audience: Cloud, Pay As You Go, Direct Signups
const paygAccount = account.type === 'pay_as_you_go'
const directSignup = account.billingProvider === 'zuora'
const audience = CLOUD && paygAccount && directSignup
mavarius marked this conversation as resolved.
Show resolved Hide resolved

mavarius marked this conversation as resolved.
Show resolved Hide resolved
if (audience) {
setCurrentAnnouncement('payg-pricing-increase-announcement')

if (announcementState['display']) {
dispatch(
showOverlay(
'click-through-announcement',
null,
handleDismissAnnouncement
)
)
}
}
}, [announcementState])

return null
}
8 changes: 7 additions & 1 deletion src/homepageExperience/containers/HomepageContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {useSelector} from 'react-redux'
// Components
import {HomepageContents} from 'src/homepageExperience/containers/HomepageContents'
import {HomepageContentsTSM} from 'src/homepageExperience/containers/HomepageContentsTSM'
import {ClickThroughAnnouncementHandler} from 'src/homepageExperience/ClickThroughAnnouncementHandler'

// Utils
import {isOrgIOx} from 'src/organizations/selectors'
Expand All @@ -16,5 +17,10 @@ export const HomepageContainer: FC = () => {
<HomepageContentsTSM />
)

return <>{homepageContents}</>
return (
<>
{homepageContents}
<ClickThroughAnnouncementHandler />
</>
)
}
101 changes: 101 additions & 0 deletions src/me/components/ClickThroughAnnouncementOverlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Libraries
import React, {useEffect} from 'react'
import {useSelector} from 'react-redux'

// Components
import {Overlay, Button, ComponentColor} from '@influxdata/clockface'
import {SafeBlankLink} from 'src/utils/SafeBlankLink'

// Utils
import {event} from 'src/cloud/utils/reporting'

// Selectors
import {selectCurrentOrg, selectUser} from 'src/identity/selectors'

interface ClickThroughAnnouncementOverlayProps {
onClose: () => void
}

export const ClickThroughAnnouncementOverlay: React.FC<
ClickThroughAnnouncementOverlayProps
> = ({onClose}) => {
useEffect(() => {
event(`pricingClickThroughAnnouncement.displayed`)
}, [])

const org = useSelector(selectCurrentOrg)
const user = useSelector(selectUser)

const handlePricingAnnouncementClick = () => {
event(`pricingClickThroughAnnouncement.details.clicked`)
}

const handleContactUsClick = () => {
event(`pricingClickThroughAnnouncement.contactUs.clicked`)
}

const handleAcknowledgeClick = () => {
event(`pricingClickThroughAnnouncement.acknowledge.clicked`)
onClose()
}

return (
<Overlay visible={true}>
<Overlay.Container>
<Overlay.Header title="Notice: Your Plan Pricing is Changing" />
<Overlay.Body>
<p>
Starting on <strong>December 1, 2023</strong> there will be an
increase in to your usage-based pricing.
</p>
<p>
Your monthly charges will continue to be based on your actual
consumption of the four billable usage vectors: Data In, Query
Count, Storage and Data Out. This is unchanged. However, unit
pricing for two of these vectors will be increased beginning{' '}
<strong>December 1, 2023</strong>:
</p>
<ul>
<li>
Data In will increase from $0.002 to $0.0025 per MB ingested
</li>
<li>
Query Count will increase from $0.01 to $0.012 per 100 executed
</li>
</ul>
<p>
This increase to your total monthly charges will depend on the
specific distribution of your workload across the billable vectors.
Most customers will experience an increase between 14% - 24%.
</p>
<p>
Please feel free to{' '}
<SafeBlankLink
href={`mailto:[email protected]?
mavarius marked this conversation as resolved.
Show resolved Hide resolved
&subject=PAYG%20price%20change%20inquiry
&body=User%20ID:%20${user.email}%0D%0AOrg%20ID:%20${org.id}%0D%0A%0D%0APlease%20describe%20your%20inquiry%20here.`}
onClick={handleContactUsClick}
>
contact us
</SafeBlankLink>{' '}
with questions or refer to our website for{' '}
<SafeBlankLink
href="https://www.influxdata.com/influxdb-pricing"
onClick={handlePricingAnnouncementClick}
>
additional information
</SafeBlankLink>
.
</p>
</Overlay.Body>
<Overlay.Footer>
<Button
text="Acknowledge"
color={ComponentColor.Primary}
onClick={handleAcknowledgeClick}
/>
</Overlay.Footer>
</Overlay.Container>
</Overlay>
)
}
6 changes: 6 additions & 0 deletions src/overlays/components/OverlayController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import {MarketoAccountUpgradeOverlay} from 'src/identity/components/MarketoAccou
import {SuspendPaidOrgOverlay} from 'src/organizations/components/OrgProfileTab/SuspendPaidOrgOverlay'
import {ReplaceCertificateOverlay} from 'src/writeData/subscriptions/components/CertificateInput'
import {RemoveMemberOverlay} from 'src/users/components/RemoveMemberOverlay'
import {ClickThroughAnnouncementOverlay} from 'src/me/components/ClickThroughAnnouncementOverlay'

// Actions
import {dismissOverlay} from 'src/overlays/actions/overlays'
Expand Down Expand Up @@ -189,6 +190,11 @@ export const OverlayController: FunctionComponent = () => {
case 'remove-member':
activeOverlay.current = <RemoveMemberOverlay />
break
case 'click-through-announcement':
activeOverlay.current = (
<ClickThroughAnnouncementOverlay onClose={onClose} />
)
break
default:
activeOverlay.current = null
break
Expand Down
1 change: 1 addition & 0 deletions src/overlays/reducers/overlays.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export type OverlayID =
| 'marketo-upgrade-account-overlay'
| 'suspend-org-in-paid-account'
| 'remove-member'
| 'click-through-announcement'

export interface OverlayState {
id: OverlayID | null
Expand Down
Loading