@@ -29,6 +29,8 @@ const formSchema = z.object({
29
29
baseCurrency : z . string ( ) ,
30
30
} ) ;
31
31
32
+ type FormValues = z . infer < typeof formSchema > ;
33
+
32
34
type Props = {
33
35
defaultCurrencyPromise : Promise < string > ;
34
36
defaultCountryCodePromise : Promise < string > ;
@@ -47,23 +49,80 @@ export function CreateTeamForm({
47
49
48
50
const createTeamMutation = useMutation (
49
51
trpc . team . create . mutationOptions ( {
50
- onSuccess : async ( ) => {
52
+ onSuccess : async ( teamId ) => {
53
+ const successId = `team_creation_success_${ Date . now ( ) } _${ Math . random ( ) . toString ( 36 ) . substr ( 2 , 9 ) } ` ;
54
+
55
+ console . log ( `[${ successId } ] Team creation mutation successful` , {
56
+ teamId,
57
+ timestamp : new Date ( ) . toISOString ( ) ,
58
+ url : window . location . href ,
59
+ } ) ;
60
+
51
61
// Lock the form permanently - never reset on success
52
62
setIsLoading ( true ) ;
53
63
isSubmittedRef . current = true ;
54
64
55
65
try {
56
66
// Invalidate all queries to ensure fresh data everywhere
67
+ console . log ( `[${ successId } ] Invalidating queries` ) ;
57
68
await queryClient . invalidateQueries ( ) ;
69
+
58
70
// Revalidate server-side paths and redirect
71
+ console . log ( `[${ successId } ] Revalidating server-side paths` ) ;
59
72
await revalidateAfterTeamChange ( ) ;
73
+
74
+ console . log (
75
+ `[${ successId } ] Team creation flow completed successfully` ,
76
+ ) ;
60
77
} catch ( error ) {
61
- // Even if redirect fails, keep the form locked to prevent duplicates
62
- console . error ( "Redirect failed, but keeping form locked:" , error ) ;
78
+ // Check if this is a Next.js redirect (expected behavior)
79
+ if ( error instanceof Error && error . message === "NEXT_REDIRECT" ) {
80
+ console . log (
81
+ `[${ successId } ] Team creation completed successfully - redirecting to home` ,
82
+ ) ;
83
+ // This is expected - Next.js redirects work by throwing this error
84
+ return ;
85
+ }
86
+
87
+ // Only log actual errors, not expected redirects
88
+ console . error ( `[${ successId } ] Team creation flow failed:` , {
89
+ error : error instanceof Error ? error . message : String ( error ) ,
90
+ stack : error instanceof Error ? error . stack : undefined ,
91
+ teamId,
92
+ } ) ;
63
93
}
64
94
// Note: We NEVER reset loading state on success - user should be redirected
65
95
} ,
66
- onError : ( ) => {
96
+ onError : ( error ) => {
97
+ const errorId = `team_creation_error_${ Date . now ( ) } _${ Math . random ( ) . toString ( 36 ) . substr ( 2 , 9 ) } ` ;
98
+
99
+ const errorContext = {
100
+ error : error instanceof Error ? error . message : String ( error ) ,
101
+ stack : error instanceof Error ? error . stack : undefined ,
102
+ timestamp : new Date ( ) . toISOString ( ) ,
103
+ url : window . location . href ,
104
+ userAgent : navigator . userAgent ,
105
+ } ;
106
+
107
+ console . error (
108
+ `[${ errorId } ] Team creation mutation failed` ,
109
+ errorContext ,
110
+ ) ;
111
+
112
+ // Capture error in Sentry for debugging
113
+ if ( error instanceof Error && process . env . NODE_ENV === "production" ) {
114
+ import ( "@sentry/nextjs" ) . then ( ( Sentry ) => {
115
+ Sentry . captureException ( error , {
116
+ extra : {
117
+ ...errorContext ,
118
+ errorId,
119
+ component : "CreateTeamForm" ,
120
+ action : "team_creation_mutation" ,
121
+ } ,
122
+ } ) ;
123
+ } ) ;
124
+ }
125
+
67
126
setIsLoading ( false ) ;
68
127
isSubmittedRef . current = false ; // Reset on error to allow retry
69
128
} ,
@@ -81,11 +140,28 @@ export function CreateTeamForm({
81
140
// Computed loading state that can never be reset unexpectedly
82
141
const isFormLocked = isLoading || isSubmittedRef . current ;
83
142
84
- function onSubmit ( values : z . infer < typeof formSchema > ) {
143
+ function onSubmit ( values : FormValues ) {
85
144
if ( isFormLocked ) {
145
+ console . warn ( "Team creation form submission blocked - form is locked" , {
146
+ isFormLocked,
147
+ isLoading,
148
+ isSubmittedRef : isSubmittedRef . current ,
149
+ formValues : values ,
150
+ } ) ;
86
151
return ;
87
152
}
88
153
154
+ const submissionId = `form_submission_${ Date . now ( ) } _${ Math . random ( ) . toString ( 36 ) . substr ( 2 , 9 ) } ` ;
155
+
156
+ console . log ( `[${ submissionId } ] Team creation form submission started` , {
157
+ teamName : values . name ,
158
+ baseCurrency : values . baseCurrency ,
159
+ countryCode : values . countryCode ,
160
+ timestamp : new Date ( ) . toISOString ( ) ,
161
+ userAgent : navigator . userAgent ,
162
+ url : window . location . href ,
163
+ } ) ;
164
+
89
165
setIsLoading ( true ) ;
90
166
isSubmittedRef . current = true ; // Permanent flag that survives re-renders
91
167
0 commit comments