diff --git a/static/app/actionCreators/modal.tsx b/static/app/actionCreators/modal.tsx index 779ce59893865a..b960cb68ff9c9f 100644 --- a/static/app/actionCreators/modal.tsx +++ b/static/app/actionCreators/modal.tsx @@ -7,6 +7,7 @@ import type {SaveQueryModalProps} from 'sentry/components/modals/explore/saveQue import type {ImportDashboardFromFileModalProps} from 'sentry/components/modals/importDashboardFromFileModal'; import type {InsightChartModalOptions} from 'sentry/components/modals/insightChartModal'; import type {InviteRow} from 'sentry/components/modals/inviteMembersModal/types'; +import type {PrivateGamingSdkAccessModalProps} from 'sentry/components/modals/privateGamingSdkAccessModal'; import type {ReprocessEventModalOptions} from 'sentry/components/modals/reprocessEventModal'; import type {AddToDashboardModalProps} from 'sentry/components/modals/widgetBuilder/addToDashboardModal'; import type {OverwriteWidgetModalProps} from 'sentry/components/modals/widgetBuilder/overwriteWidgetModal'; @@ -447,3 +448,13 @@ export async function openTokenRegenerationConfirmationModal(options: ModalOptio openModal(deps => ); } + +export async function openPrivateGamingSdkAccessModal( + options: PrivateGamingSdkAccessModalProps +) { + const {PrivateGamingSdkAccessModal} = await import( + 'sentry/components/modals/privateGamingSdkAccessModal' + ); + + openModal(deps => ); +} diff --git a/static/app/components/modals/privateGamingSdkAccessModal.tsx b/static/app/components/modals/privateGamingSdkAccessModal.tsx new file mode 100644 index 00000000000000..094cbc50da4894 --- /dev/null +++ b/static/app/components/modals/privateGamingSdkAccessModal.tsx @@ -0,0 +1,174 @@ +import {Fragment, useState} from 'react'; +import {captureFeedback} from '@sentry/react'; + +import {addSuccessMessage} from 'sentry/actionCreators/indicator'; +import {type ModalRenderProps} from 'sentry/actionCreators/modal'; +import {Button} from 'sentry/components/core/button'; +import {ButtonBar} from 'sentry/components/core/button/buttonBar'; +import SelectField from 'sentry/components/forms/fields/selectField'; +import TextField from 'sentry/components/forms/fields/textField'; +import {t, tct} from 'sentry/locale'; +import type {Organization} from 'sentry/types/organization'; +import {useUser} from 'sentry/utils/useUser'; + +const PRIVATE_GAMING_SDK_OPTIONS = [ + {value: 'playstation', label: 'PlayStation'}, + {value: 'xbox', label: 'Xbox'}, + {value: 'nintendo-switch', label: 'Nintendo Switch'}, +] as const; + +type GamingPlatform = (typeof PRIVATE_GAMING_SDK_OPTIONS)[number]['value']; + +export interface PrivateGamingSdkAccessModalProps { + organization: Organization; + projectSlug: string; + sdkName: string; + gamingPlatform?: GamingPlatform; + onSubmit?: () => void; +} + +export function PrivateGamingSdkAccessModal({ + Header, + Body, + Footer, + closeModal, + organization, + projectSlug, + sdkName, + gamingPlatform, + onSubmit, +}: PrivateGamingSdkAccessModalProps & ModalRenderProps) { + const user = useUser(); + const [isSubmitting, setIsSubmitting] = useState(false); + const [githubProfile, setGithubProfile] = useState(''); + const [gamingPlatforms, setGamingPlatforms] = useState( + gamingPlatform ? [gamingPlatform] : [] + ); + + const isFormValid = !!githubProfile.trim() && gamingPlatforms.length > 0; + + function handleSubmit() { + if (!isFormValid) { + return; + } + + setIsSubmitting(true); + + onSubmit?.(); + + const messageBody = [ + `User: ${user.name}`, + `Email: ${user.email}`, + gamingPlatforms.length === 1 + ? `Platform: ${gamingPlatforms[0]}` + : `Platforms: ${gamingPlatforms + .map( + (platform: string) => + PRIVATE_GAMING_SDK_OPTIONS.find(option => option.value === platform) + ?.label || platform + ) + .join(', ')}`, + `Org Slug: ${organization.slug}`, + `Project: ${projectSlug}`, + `GitHub Profile: ${githubProfile}`, + ].join('\n'); + + const source = `${sdkName.toLowerCase()}-sdk-access`; + + // Use captureFeedback with proper user context instead of tags + captureFeedback( + { + message: messageBody, + name: user.name, + email: user.email, + source, + tags: { + feature: source, + }, + }, + { + captureContext: { + user: { + id: user.id, + email: user.email, + username: user.username, + name: user.name, + }, + }, + } + ); + + addSuccessMessage( + tct('Your [sdkName] SDK access request has been submitted.', { + sdkName, + }) + ); + setIsSubmitting(false); + closeModal(); + } + + return ( + +
+

+ {tct('Request [sdkName] SDK Access', { + sdkName, + })} +

+
+ +

+ {gamingPlatform + ? tct( + 'Request access to our [sdkName] SDK. Please provide your GitHub profile.', + { + sdkName, + } + ) + : tct( + 'Request access to our [sdkName] SDK. Please provide your GitHub profile and the gaming platforms you work with.', + { + sdkName, + } + )} +

+ + {!gamingPlatform && ( + + )} + + +
+ ); +}