11import { useCallback , useEffect , useMemo , useState } from 'react' ;
2+ import * as Sentry from '@sentry/react' ;
23import { LayoutGroup , motion } from 'framer-motion' ;
34import { PlatformIcon } from 'platformicons' ;
45
@@ -7,6 +8,7 @@ import {Container, Flex, Grid, Stack} from '@sentry/scraps/layout';
78import { Select } from '@sentry/scraps/select' ;
89import { Heading } from '@sentry/scraps/text' ;
910
11+ import { addErrorMessage } from 'sentry/actionCreators/indicator' ;
1012import { closeModal , openConsoleModal , openModal } from 'sentry/actionCreators/modal' ;
1113import { LoadingIndicator } from 'sentry/components/loadingIndicator' ;
1214import { SupportedLanguages } from 'sentry/components/onboarding/frameworkSuggestionModal' ;
@@ -16,13 +18,17 @@ import {
1618 getDisabledProducts ,
1719 platformProductAvailability ,
1820} from 'sentry/components/onboarding/productSelection' ;
21+ import { useCreateProject } from 'sentry/components/onboarding/useCreateProject' ;
1922import { platforms } from 'sentry/data/platforms' ;
2023import { t } from 'sentry/locale' ;
2124import type { OnboardingSelectedSDK } from 'sentry/types/onboarding' ;
25+ import type { Team } from 'sentry/types/organization' ;
2226import type { PlatformIntegration , PlatformKey } from 'sentry/types/project' ;
2327import { trackAnalytics } from 'sentry/utils/analytics' ;
2428import { isDisabledGamingPlatform } from 'sentry/utils/platform' ;
2529import { useOrganization } from 'sentry/utils/useOrganization' ;
30+ import { useProjects } from 'sentry/utils/useProjects' ;
31+ import { useTeams } from 'sentry/utils/useTeams' ;
2632import { ScmFeatureSelectionCards } from 'sentry/views/onboarding/components/scmFeatureSelectionCards' ;
2733import { ScmPlatformCard } from 'sentry/views/onboarding/components/scmPlatformCard' ;
2834
@@ -84,8 +90,17 @@ export function ScmPlatformFeatures({onComplete}: StepProps) {
8490 setSelectedPlatform,
8591 selectedFeatures,
8692 setSelectedFeatures,
93+ createdProjectSlug,
94+ setCreatedProjectSlug,
8795 } = useOnboardingContext ( ) ;
8896
97+ const { teams, fetching : isLoadingTeams } = useTeams ( ) ;
98+ const { projects, initiallyLoaded : projectsLoaded } = useProjects ( ) ;
99+ const createProject = useCreateProject ( ) ;
100+ const hasProjectDetailsStep = organization . features . includes (
101+ 'onboarding-scm-project-details'
102+ ) ;
103+
89104 const [ showManualPicker , setShowManualPicker ] = useState ( false ) ;
90105
91106 useEffect ( ( ) => {
@@ -306,14 +321,54 @@ export function ScmPlatformFeatures({onComplete}: StepProps) {
306321 }
307322 }
308323
309- function handleContinue ( ) {
324+ async function handleContinue ( ) {
310325 // Persist derived defaults to context if user accepted them
311326 if ( currentPlatformKey && ! selectedPlatform ?. key ) {
312327 setPlatform ( currentPlatformKey ) ;
313328 }
314329 if ( ! selectedFeatures ) {
315330 setSelectedFeatures ( currentFeatures ) ;
316331 }
332+
333+ if ( ! hasProjectDetailsStep ) {
334+ // Auto-create project with defaults when SCM_PROJECT_DETAILS step is skipped
335+ const platform =
336+ selectedPlatform ??
337+ ( currentPlatformKey
338+ ? toSelectedSdk ( getPlatformInfo ( currentPlatformKey ) ! )
339+ : undefined ) ;
340+ if ( ! platform ) {
341+ return ;
342+ }
343+
344+ // If the onboarding context still holds a created project slug (e.g.
345+ // the user went back after the project received its first event),
346+ // reuse it instead of creating a duplicate.
347+ if ( createdProjectSlug && projects . some ( p => p . slug === createdProjectSlug ) ) {
348+ onComplete ( undefined , { product : currentFeatures } ) ;
349+ return ;
350+ }
351+
352+ const firstAdminTeam = teams . find ( ( team : Team ) =>
353+ team . access . includes ( 'team:admin' )
354+ ) ;
355+
356+ try {
357+ const project = await createProject . mutateAsync ( {
358+ name : platform . key ,
359+ platform,
360+ default_rules : true ,
361+ firstTeamSlug : firstAdminTeam ?. slug ,
362+ } ) ;
363+ setCreatedProjectSlug ( project . slug ) ;
364+ onComplete ( undefined , { product : currentFeatures } ) ;
365+ } catch ( error ) {
366+ addErrorMessage ( t ( 'Failed to create project' ) ) ;
367+ Sentry . captureException ( error ) ;
368+ }
369+ return ;
370+ }
371+
317372 onComplete ( ) ;
318373 }
319374
@@ -459,7 +514,12 @@ export function ScmPlatformFeatures({onComplete}: StepProps) {
459514 features : currentFeatures ,
460515 } }
461516 onClick = { handleContinue }
462- disabled = { ! currentPlatformKey }
517+ disabled = {
518+ ! currentPlatformKey ||
519+ createProject . isPending ||
520+ ( ! hasProjectDetailsStep && ( isLoadingTeams || ! projectsLoaded ) )
521+ }
522+ busy = { createProject . isPending }
463523 >
464524 { t ( 'Continue' ) }
465525 </ Button >
0 commit comments