@@ -106,7 +106,7 @@ interface PendingMember {
106106}
107107
108108export function TeamMembersSettings ( ) {
109- const { user, organization, addToast, getEffectiveRole, apiServerUrl } = usePDMStore ( )
109+ const { user, organization, setOrganization , addToast, getEffectiveRole, apiServerUrl } = usePDMStore ( )
110110
111111 const isAdmin = getEffectiveRole ( ) === 'admin'
112112
@@ -120,6 +120,7 @@ export function TeamMembersSettings() {
120120 const [ pendingMembers , setPendingMembers ] = useState < PendingMember [ ] > ( [ ] )
121121 const [ isLoading , setIsLoading ] = useState ( true )
122122 const [ searchQuery , setSearchQuery ] = useState ( '' )
123+ const [ isSavingDefaultTeam , setIsSavingDefaultTeam ] = useState ( false )
123124
124125 // Team dialogs
125126 const [ selectedTeam , setSelectedTeam ] = useState < TeamWithDetails | null > ( null )
@@ -754,6 +755,35 @@ export function TeamMembersSettings() {
754755 setCopyFromTeamId ( null )
755756 }
756757
758+ // Update the default team for new users (joining without invite or with invite but no teams)
759+ const handleSetDefaultTeam = async ( teamId : string | null ) => {
760+ if ( ! organization ?. id ) return
761+
762+ setIsSavingDefaultTeam ( true )
763+ try {
764+ const { error } = await supabase
765+ . from ( 'organizations' )
766+ . update ( { default_new_user_team_id : teamId } )
767+ . eq ( 'id' , organization . id )
768+
769+ if ( error ) throw error
770+
771+ // Update local organization state
772+ setOrganization ( {
773+ ...organization ,
774+ default_new_user_team_id : teamId
775+ } )
776+
777+ const teamName = teamId ? teams . find ( t => t . id === teamId ) ?. name : 'None'
778+ addToast ( 'success' , `Default team set to "${ teamName } "` )
779+ } catch ( err ) {
780+ console . error ( 'Failed to set default team:' , err )
781+ addToast ( 'error' , 'Failed to update default team' )
782+ } finally {
783+ setIsSavingDefaultTeam ( false )
784+ }
785+ }
786+
757787 const openEditTeamDialog = ( team : TeamWithDetails ) => {
758788 setSelectedTeam ( team )
759789 setTeamFormData ( {
@@ -1504,6 +1534,41 @@ export function TeamMembersSettings() {
15041534 { activeTab === 'teams' && (
15051535 < div className = "space-y-3" >
15061536
1537+ { /* Default Team for New Users Setting */ }
1538+ { isAdmin && teams . length > 0 && (
1539+ < div className = "p-4 bg-plm-bg rounded-lg border border-plm-border" >
1540+ < div className = "flex items-center justify-between gap-4" >
1541+ < div className = "flex items-center gap-3" >
1542+ < div className = "p-2 rounded-lg bg-plm-accent/10" >
1543+ < UserPlus size = { 18 } className = "text-plm-accent" />
1544+ </ div >
1545+ < div >
1546+ < h4 className = "text-sm font-medium text-plm-fg" > Default Team for New Users</ h4 >
1547+ < p className = "text-xs text-plm-fg-muted" >
1548+ Users joining via org code (or invited without specific teams) will be added here
1549+ </ p >
1550+ </ div >
1551+ </ div >
1552+ < div className = "flex items-center gap-2" >
1553+ < select
1554+ value = { ( organization as any ) ?. default_new_user_team_id || '' }
1555+ onChange = { ( e ) => handleSetDefaultTeam ( e . target . value || null ) }
1556+ disabled = { isSavingDefaultTeam }
1557+ className = "px-3 py-1.5 text-sm bg-plm-bg-secondary border border-plm-border rounded-lg text-plm-fg focus:outline-none focus:border-plm-accent disabled:opacity-50"
1558+ >
1559+ < option value = "" > No default (unassigned)</ option >
1560+ { teams . map ( team => (
1561+ < option key = { team . id } value = { team . id } > { team . name } </ option >
1562+ ) ) }
1563+ </ select >
1564+ { isSavingDefaultTeam && (
1565+ < Loader2 size = { 14 } className = "animate-spin text-plm-fg-muted" />
1566+ ) }
1567+ </ div >
1568+ </ div >
1569+ </ div >
1570+ ) }
1571+
15071572 { filteredTeams . length === 0 ? (
15081573 < div className = "text-center py-8 border border-dashed border-plm-border rounded-lg" >
15091574 < Users size = { 36 } className = "mx-auto text-plm-fg-muted mb-3 opacity-50" />
0 commit comments