44 Cog6ToothIcon ,
55 ShieldCheckIcon ,
66 KeyIcon ,
7+ CodeBracketIcon ,
78} from "@heroicons/react/24/outline" ;
89import axios from "axios" ;
910import React , { useEffect , useMemo , useState } from "react" ;
@@ -12,6 +13,7 @@ import {Alert} from "~/components/ui/Alert";
1213import { Button } from "~/components/ui/Button" ;
1314import { Input } from "~/components/ui/Input" ;
1415import { Modal } from "~/components/ui/Modal" ;
16+ import { useBranchStore } from "~/stores/branchStore" ;
1517
1618interface RepoMetadata {
1719 title ?: string ;
@@ -77,6 +79,11 @@ export const RepoSettingsModal: React.FC<RepoSettingsModalProps> = ({
7779 const [ isDeleting , setIsDeleting ] = useState ( false ) ;
7880 const [ error , setError ] = useState < string | null > ( null ) ;
7981
82+ // Default branch
83+ const { branches, currentBranch, fetchBranches} = useBranchStore ( ) ;
84+ const [ selectedDefaultBranch , setSelectedDefaultBranch ] = useState ( "" ) ;
85+ const [ isSavingBranch , setIsSavingBranch ] = useState ( false ) ;
86+
8087 useEffect ( ( ) => {
8188 if ( ! isOpen ) return ;
8289
@@ -86,13 +93,14 @@ export const RepoSettingsModal: React.FC<RepoSettingsModalProps> = ({
8693 setTitle ( repoMetadata ?. title ?? "" ) ;
8794 setDescription ( repoMetadata ?. description ?? "" ) ;
8895 setNewRepoName ( repoNameWithoutGit ) ;
96+ setSelectedDefaultBranch ( currentBranch || "" ) ;
8997
9098 // reset inline confirmations
9199 setRenameConfirmText ( "" ) ;
92100 setArchiveConfirmChecked ( false ) ;
93101 setDeleteExpanded ( false ) ;
94102 setDeleteConfirmText ( "" ) ;
95- } , [ isOpen , repoMetadata , repoNameWithoutGit ] ) ;
103+ } , [ isOpen , repoMetadata , repoNameWithoutGit , currentBranch ] ) ;
96104
97105 const closeAndReset = ( ) => {
98106 setError ( null ) ;
@@ -137,6 +145,26 @@ export const RepoSettingsModal: React.FC<RepoSettingsModalProps> = ({
137145 }
138146 } ;
139147
148+ const handleSetDefaultBranch = async ( ) => {
149+ if ( ! selectedDefaultBranch || selectedDefaultBranch === currentBranch )
150+ return ;
151+
152+ setError ( null ) ;
153+ setIsSavingBranch ( true ) ;
154+ try {
155+ await axios . put (
156+ `/api/repos/${ encodeURIComponent ( repoNameWithGit ) } /default-branch` ,
157+ { branch : selectedDefaultBranch } ,
158+ ) ;
159+ // Refresh branches to reflect the change
160+ await fetchBranches ( repoName ) ;
161+ } catch ( err : any ) {
162+ setError ( err ?. response ?. data ?. error || "Failed to update default branch" ) ;
163+ } finally {
164+ setIsSavingBranch ( false ) ;
165+ }
166+ } ;
167+
140168 const handleRename = async ( ) => {
141169 const trimmed = newRepoName . trim ( ) ;
142170
@@ -222,7 +250,7 @@ export const RepoSettingsModal: React.FC<RepoSettingsModalProps> = ({
222250 ) => (
223251 < button
224252 onClick = { ( ) => setActiveTab ( key ) }
225- className = { `w-full flex items-center gap-3 px-4 py-3 text-sm font-medium transition-colors border-l-2 ${
253+ className = { `w-full flex items-center gap-2 px-3 py-2 text-sm font-medium transition-colors border-l-2 ${
226254 activeTab === key
227255 ? variant === "danger"
228256 ? "bg-error/10 text-error border-error"
@@ -254,29 +282,29 @@ export const RepoSettingsModal: React.FC<RepoSettingsModalProps> = ({
254282
255283 < div
256284 data-testid = "repo-settings-shell"
257- className = "flex flex-col md:flex-row h-full min-h-[500px ] border-t border-app-border -mx-6"
285+ className = "flex flex-col md:flex-row h-full min-h-[400px ] border-t border-app-border -mx-6"
258286 >
259287 { /* Left Sidebar */ }
260288 < nav
261289 data-testid = "repo-settings-nav"
262- className = "w-full md:w-64 bg-app-surface border-b md:border-b-0 md:border-r border-app-border flex-shrink-0"
290+ className = "w-full md:w-56 bg-app-surface border-b md:border-b-0 md:border-r border-app-border flex-shrink-0"
263291 >
264- < div className = "p-4 md:py-6 space-y-1 " >
292+ < div className = "p-3 md:py-4 space-y-0.5 " >
265293 { renderTabButton (
266294 "general" ,
267295 "General" ,
268- < Cog6ToothIcon className = "w-5 h-5 " /> ,
296+ < Cog6ToothIcon className = "w-4 h-4 " /> ,
269297 ) }
270298 { renderTabButton (
271299 "access" ,
272300 "Access" ,
273- < ShieldCheckIcon className = "w-5 h-5 " /> ,
301+ < ShieldCheckIcon className = "w-4 h-4 " /> ,
274302 ) }
275- < div className = "h-px bg-app-border my-2 mx-4 " />
303+ < div className = "h-px bg-app-border my-1.5 mx-3 " />
276304 { renderTabButton (
277305 "danger" ,
278306 "Danger Zone" ,
279- < ExclamationTriangleIcon className = "w-5 h-5 " /> ,
307+ < ExclamationTriangleIcon className = "w-4 h-4 " /> ,
280308 "danger" ,
281309 ) }
282310 </ div >
@@ -287,24 +315,24 @@ export const RepoSettingsModal: React.FC<RepoSettingsModalProps> = ({
287315 data-testid = "repo-settings-content"
288316 className = "flex-1 overflow-y-auto bg-app-surface"
289317 >
290- < div className = "p-6 max-w-3xl mx-auto" >
318+ < div className = "p-4 max-w-3xl mx-auto" >
291319 { activeTab === "general" && (
292- < div className = "space-y-8 " >
320+ < div className = "space-y-5 " >
293321 < div >
294- < h3 className = "text-xl font-semibold text-text-primary mb-1 " >
322+ < h3 className = "text-lg font-semibold text-text-primary mb-0.5 " >
295323 General Settings
296324 </ h3 >
297- < p className = "text-sm text-text-tertiary" >
325+ < p className = "text-xs text-text-tertiary" >
298326 Manage your repository's main configuration.
299327 </ p >
300328 </ div >
301329
302- < div className = "space-y-6 " >
330+ < div className = "space-y-4 " >
303331 { /* Metadata Section */ }
304- < section className = "bg-app-surface/30 border border-app-border rounded-lg p-5 space-y-5 " >
305- < div className = "flex items-center gap-2 pb-3 border-b border-app-border" >
306- < PencilIcon className = "w-5 h-5 text-app-accent" />
307- < h4 className = "font-medium text-text-primary" >
332+ < section className = "bg-app-surface/30 border border-app-border rounded-lg p-4 space-y-4 " >
333+ < div className = "flex items-center gap-2 pb-2 border-b border-app-border" >
334+ < PencilIcon className = "w-4 h-4 text-app-accent" />
335+ < h4 className = "text-sm font-medium text-text-primary" >
308336 Repository Details
309337 </ h4 >
310338 </ div >
@@ -354,10 +382,10 @@ export const RepoSettingsModal: React.FC<RepoSettingsModalProps> = ({
354382 </ section >
355383
356384 { /* Rename Section */ }
357- < section className = "bg-app-surface/30 border border-app-border rounded-lg p-5 space-y-5 " >
358- < div className = "flex items-center gap-2 pb-3 border-b border-app-border" >
359- < KeyIcon className = "w-5 h-5 text-text-primary" />
360- < h4 className = "font-medium text-text-primary" >
385+ < section className = "bg-app-surface/30 border border-app-border rounded-lg p-4 space-y-4 " >
386+ < div className = "flex items-center gap-2 pb-2 border-b border-app-border" >
387+ < KeyIcon className = "w-4 h-4 text-text-primary" />
388+ < h4 className = "text-sm font-medium text-text-primary" >
361389 Rename Repository
362390 </ h4 >
363391 </ div >
@@ -407,20 +435,72 @@ export const RepoSettingsModal: React.FC<RepoSettingsModalProps> = ({
407435 ) }
408436 </ div >
409437 </ section >
438+
439+ { /* Default Branch Section */ }
440+ < section className = "bg-app-surface/30 border border-app-border rounded-lg p-4 space-y-4" >
441+ < div className = "flex items-center gap-2 pb-2 border-b border-app-border" >
442+ < CodeBracketIcon className = "w-4 h-4 text-app-accent" />
443+ < h4 className = "text-sm font-medium text-text-primary" >
444+ Default Branch
445+ </ h4 >
446+ </ div >
447+
448+ < div className = "space-y-3" >
449+ < p className = "text-xs text-text-tertiary" >
450+ The default branch is used when viewing files and
451+ creating new branches.
452+ </ p >
453+
454+ < div >
455+ < label className = "block text-sm font-medium text-text-primary mb-1.5" >
456+ Default Branch
457+ </ label >
458+ < select
459+ value = { selectedDefaultBranch }
460+ onChange = { ( e ) =>
461+ setSelectedDefaultBranch ( e . target . value )
462+ }
463+ className = "w-full h-9 px-3 bg-app-surface border border-app-border rounded text-sm text-text-primary focus:outline-none focus:ring-1 focus:ring-app-accent focus:border-app-accent transition-colors"
464+ >
465+ { branches . map ( ( b : string ) => (
466+ < option key = { b } value = { b } >
467+ { b }
468+ { b === currentBranch ? " (current default)" : "" }
469+ </ option >
470+ ) ) }
471+ </ select >
472+ </ div >
473+
474+ < div className = "pt-2 flex justify-end" >
475+ < Button
476+ onClick = { handleSetDefaultBranch }
477+ disabled = {
478+ isSavingBranch ||
479+ ! selectedDefaultBranch ||
480+ selectedDefaultBranch === currentBranch
481+ }
482+ >
483+ { isSavingBranch
484+ ? "Updating..."
485+ : "Update Default Branch" }
486+ </ Button >
487+ </ div >
488+ </ div >
489+ </ section >
410490 </ div >
411491 </ div >
412492 ) }
413493
414494 { activeTab === "access" && (
415- < div className = "flex flex-col items-center justify-center h-full text-center py-12 space-y-4 " >
416- < div className = "w-16 h-16 rounded-full bg-app-surface flex items-center justify-center" >
417- < ShieldCheckIcon className = "w-8 h-8 text-text-tertiary" />
495+ < div className = "flex flex-col items-center justify-center h-full text-center py-8 space-y-3 " >
496+ < div className = "w-12 h-12 rounded-full bg-app-surface flex items-center justify-center" >
497+ < ShieldCheckIcon className = "w-6 h-6 text-text-tertiary" />
418498 </ div >
419499 < div >
420- < h3 className = "text-lg font-medium text-text-primary" >
500+ < h3 className = "text-base font-medium text-text-primary" >
421501 Access Control
422502 </ h3 >
423- < p className = "text-text-tertiary max-w-sm mt-2 " >
503+ < p className = "text-xs text-text- tertiary max-w-sm mt-1 " >
424504 Manage collaborators, teams, and deploy keys. This feature
425505 is currently under development.
426506 </ p >
@@ -429,19 +509,19 @@ export const RepoSettingsModal: React.FC<RepoSettingsModalProps> = ({
429509 ) }
430510
431511 { activeTab === "danger" && (
432- < div className = "space-y-8 " >
512+ < div className = "space-y-5 " >
433513 < div >
434- < h3 className = "text-xl font-semibold text-error mb-1 " >
514+ < h3 className = "text-lg font-semibold text-error mb-0.5 " >
435515 Danger Zone
436516 </ h3 >
437- < p className = "text-sm text-text-tertiary" >
517+ < p className = "text-xs text-text-tertiary" >
438518 Destructive actions that affect your repository.
439519 </ p >
440520 </ div >
441521
442522 < div className = "border border-error/30 rounded-lg overflow-hidden divide-y divide-error/30" >
443523 { /* Archive Row */ }
444- < div className = "p-5 bg-error/5 flex flex-col sm:flex-row sm:items-start justify-between gap-4 " >
524+ < div className = "p-4 bg-error/5 flex flex-col sm:flex-row sm:items-start justify-between gap-3 " >
445525 < div className = "space-y-1" >
446526 < h4 className = "text-sm font-medium text-text-primary" >
447527 { isArchived
@@ -486,7 +566,7 @@ export const RepoSettingsModal: React.FC<RepoSettingsModalProps> = ({
486566 </ div >
487567
488568 { /* Delete Row */ }
489- < div className = "p-5 bg-error/10 flex flex-col sm:flex-row sm:items-start justify-between gap-4 " >
569+ < div className = "p-4 bg-error/10 flex flex-col sm:flex-row sm:items-start justify-between gap-3 " >
490570 < div className = "space-y-1 flex-1" >
491571 < h4 className = "text-sm font-medium text-text-primary" >
492572 Delete this repository
0 commit comments