diff --git a/packages/web/src/pages/chat-page/components/TargetedMessageModal.tsx b/packages/web/src/pages/chat-page/components/TargetedMessageModal.tsx index 764375aae89..85323dcb93d 100644 --- a/packages/web/src/pages/chat-page/components/TargetedMessageModal.tsx +++ b/packages/web/src/pages/chat-page/components/TargetedMessageModal.tsx @@ -1,3 +1,7 @@ +import { useMemo } from 'react' + +import { useGetCurrentUser, useGetUserTracksByHandle } from '@audius/common/api' +import { isContentUSDCPurchaseGated } from '@audius/common/models' import { useTargetedMessageModal } from '@audius/common/src/store/ui/modals/create-targeted-message-modal' import { Flex, @@ -11,40 +15,52 @@ import { RadioGroup, ModalFooter, IconCaretLeft, - ModalContent + ModalContent, + Select } from '@audius/harmony' import { Formik, FormikValues, useField } from 'formik' const messages = { title: 'Target Audience', back: 'Back', - continue: 'Continue' -} - -const targetAudienceOptions = [ - { + continue: 'Continue', + followers: { label: 'My Followers', - value: 'followers' + description: 'Send a bulk message to all of your followers.' }, - { + supporters: { label: 'Tip Supporters', - value: 'supporters' + description: 'Send a bulk message to everyone who has tipped you.' }, - { + purchasers: { label: 'Past Purchasers', - value: 'purchasers' + description: + 'Send a bulk message to everyone who has purchased content from you on Audius.', + placeholder: 'Premium Content' }, - { + remixCreators: { label: 'Remix Creators', - value: 'remix_creators' + description: + 'Send a bulk message to creators who have remixed your tracks.', + placeholder: 'Tracks with Remixes' } -] +} + +const TARGET_AUDIENCE_FIELD = 'target_audience' + +type TargetedMessageFormValues = { + target_audience: 'followers' | 'supporters' | 'purchasers' | 'remix_creators' + purchased_track_id?: string + remixed_track_id?: string +} export const TargetedMessageModal = () => { const { isOpen, onClose } = useTargetedMessageModal() - const initialValues = { - target_audience: undefined + const initialValues: TargetedMessageFormValues = { + target_audience: 'followers', + purchased_track_id: undefined, + remixed_track_id: undefined } const handleSubmit = (values: FormikValues) => { @@ -69,7 +85,10 @@ export const TargetedMessageModal = () => { return ( - + + initialValues={initialValues} + onSubmit={handleSubmit} + > {({ submitForm }) => ( <> @@ -109,20 +128,189 @@ export const TargetedMessageModal = () => { } const TargetedMessagesFields = () => { - const [field] = useField('target_audience') + const [field] = useField(TARGET_AUDIENCE_FIELD) return ( - {targetAudienceOptions.map(({ label, value }) => ( - - - - {label} + + + + + + + ) +} + +const FollowersMessageField = () => { + const { data: user } = useGetCurrentUser() + const { follower_count: followerCount } = user ?? {} + const [{ value }] = useField(TARGET_AUDIENCE_FIELD) + const selected = value === 'followers' + return ( + + + + + + {messages.followers.label} + + {selected ? ( + + ({followerCount ?? 0}) + + ) : null} + + {selected ? ( + {messages.followers.description} + ) : null} + + + ) +} + +const TipSupportersMessageField = () => { + const { data: user } = useGetCurrentUser() + const { supporter_count: supporterCount } = user ?? {} + const [{ value }] = useField(TARGET_AUDIENCE_FIELD) + const selected = value === 'supporters' + return ( + + + + + + {messages.supporters.label} + + {selected ? ( + + ({supporterCount ?? 0}) + ) : null} + + {selected ? ( + {messages.supporters.description} + ) : null} + + + ) +} + +const PastPurchasersMessageField = () => { + const { data: user } = useGetCurrentUser() + const { + // TODO: Need to add a new endpoint to get the list of past purchasers + supporter_count: supporterCount, + handle, + user_id: currentUserId + } = user ?? {} + const [{ value }] = useField(TARGET_AUDIENCE_FIELD) + const [purchasedTrackField, , { setValue: setPurchasedTrackId }] = useField({ + name: 'purchased_track_id', + type: 'select' + }) + + const isSelected = value === 'purchasers' + + const { data: tracks } = useGetUserTracksByHandle({ handle, currentUserId }) + const premiumTrackOptions = useMemo( + () => + (tracks ?? []) + .filter( + (track) => + isContentUSDCPurchaseGated(track.stream_conditions) || + isContentUSDCPurchaseGated(track.download_conditions) + ) + .map((track) => ({ + value: track.track_id.toString(), + label: track.title + })), + [tracks] + ) + + return ( + + + + + + {messages.purchasers.label} + + {isSelected ? ( + + ({supporterCount ?? 0}) + + ) : null} + + {isSelected ? ( + + {messages.purchasers.description} + + + ) : null} + + ) }