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,59 @@ export function ScmPlatformFeatures({onComplete}: StepProps) {
306321 }
307322 }
308323
309- function handleContinue ( ) {
324+ const existingProject = createdProjectSlug
325+ ? projects . find ( p => p . slug === createdProjectSlug )
326+ : undefined ;
327+
328+ async function handleContinue ( ) {
310329 // Persist derived defaults to context if user accepted them
311330 if ( currentPlatformKey && ! selectedPlatform ?. key ) {
312331 setPlatform ( currentPlatformKey ) ;
313332 }
314333 if ( ! selectedFeatures ) {
315334 setSelectedFeatures ( currentFeatures ) ;
316335 }
336+
337+ if ( ! hasProjectDetailsStep ) {
338+ // Auto-create project with defaults when SCM_PROJECT_DETAILS step is skipped
339+ const platform =
340+ selectedPlatform ??
341+ ( currentPlatformKey
342+ ? toSelectedSdk ( getPlatformInfo ( currentPlatformKey ) ! )
343+ : undefined ) ;
344+ if ( ! platform ) {
345+ return ;
346+ }
347+
348+ // If a project was already created for this platform (e.g. the user
349+ // went back after the project received its first event), reuse it.
350+ // If the platform changed, abandon the old project and create a new
351+ // one — matching legacy onboarding behavior.
352+ if ( existingProject ?. platform === platform . key ) {
353+ onComplete ( undefined , { product : currentFeatures } ) ;
354+ return ;
355+ }
356+
357+ const firstAdminTeam = teams . find ( ( team : Team ) =>
358+ team . access . includes ( 'team:admin' )
359+ ) ;
360+
361+ try {
362+ const project = await createProject . mutateAsync ( {
363+ name : platform . key ,
364+ platform,
365+ default_rules : true ,
366+ firstTeamSlug : firstAdminTeam ?. slug ,
367+ } ) ;
368+ setCreatedProjectSlug ( project . slug ) ;
369+ onComplete ( undefined , { product : currentFeatures } ) ;
370+ } catch ( error ) {
371+ addErrorMessage ( t ( 'Failed to create project' ) ) ;
372+ Sentry . captureException ( error ) ;
373+ }
374+ return ;
375+ }
376+
317377 onComplete ( ) ;
318378 }
319379
@@ -459,7 +519,12 @@ export function ScmPlatformFeatures({onComplete}: StepProps) {
459519 features : currentFeatures ,
460520 } }
461521 onClick = { handleContinue }
462- disabled = { ! currentPlatformKey }
522+ disabled = {
523+ ! currentPlatformKey ||
524+ createProject . isPending ||
525+ ( ! hasProjectDetailsStep && ( isLoadingTeams || ! projectsLoaded ) )
526+ }
527+ busy = { createProject . isPending }
463528 >
464529 { t ( 'Continue' ) }
465530 </ Button >
0 commit comments