Skip to content

Commit 672997e

Browse files
refactor(ui): replace radio buttons with Tabs in AddRepoDialog
- Replace native radio buttons with Radix UI Tabs component - Add mobile fullscreen support for dialog - Improve touch targets with consistent min-height on inputs - Simplify help text and branch descriptions - Reduce code complexity while maintaining functionality
1 parent 1e6f129 commit 672997e

1 file changed

Lines changed: 27 additions & 65 deletions

File tree

frontend/src/components/repo/AddRepoDialog.tsx

Lines changed: 27 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { createRepo, discoverRepos } from '@/api/repos'
44
import { Button } from '@/components/ui/button'
55
import { Input } from '@/components/ui/input'
66
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
7+
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'
78
import { Loader2 } from 'lucide-react'
89
import { showToast } from '@/lib/toast'
910
import type { DiscoverReposResponse } from '@opencode-manager/shared/types'
@@ -99,53 +100,22 @@ export function AddRepoDialog({ open, onOpenChange }: AddRepoDialogProps) {
99100

100101
return (
101102
<Dialog open={open} onOpenChange={onOpenChange}>
102-
<DialogContent className="sm:max-w-[500px] bg-[#141414] border-[#2a2a2a]">
103-
<DialogHeader>
103+
<DialogContent mobileFullscreen className="content-start gap-0 sm:max-w-[500px] sm:max-h-[80vh] sm:h-auto sm:top-[50%] sm:translate-y-[-50%] bg-[#141414] border-[#2a2a2a]">
104+
<DialogHeader className="px-4 sm:px-6 pt-2 sm:pt-6 pb-2 sm:pb-3 h-fit">
104105
<DialogTitle className="text-xl bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent">
105106
Add Repository
106107
</DialogTitle>
107108
</DialogHeader>
108-
<form onSubmit={handleSubmit} className="space-y-4 mt-4">
109+
<form onSubmit={handleSubmit} className="space-y-4 px-4 sm:px-6">
109110
<div className="space-y-2">
110111
<label className="text-sm text-zinc-400">Repository Type</label>
111-
<div className="flex gap-4">
112-
<label className="flex items-center space-x-2 cursor-pointer">
113-
<input
114-
type="radio"
115-
name="repoType"
116-
value="remote"
117-
checked={repoType === 'remote'}
118-
onChange={(e) => setRepoType(e.target.value as 'remote')}
119-
disabled={mutation.isPending}
120-
className="text-blue-600 bg-[#1a1a1a] border-[#2a2a2a]"
121-
/>
122-
<span className="text-sm text-white">Remote Repository</span>
123-
</label>
124-
<label className="flex items-center space-x-2 cursor-pointer">
125-
<input
126-
type="radio"
127-
name="repoType"
128-
value="local"
129-
checked={repoType === 'local'}
130-
onChange={(e) => setRepoType(e.target.value as 'local')}
131-
disabled={mutation.isPending}
132-
className="text-blue-600 bg-[#1a1a1a] border-[#2a2a2a]"
133-
/>
134-
<span className="text-sm text-white">Local Repository</span>
135-
</label>
136-
<label className="flex items-center space-x-2 cursor-pointer">
137-
<input
138-
type="radio"
139-
name="repoType"
140-
value="folder"
141-
checked={repoType === 'folder'}
142-
onChange={(e) => setRepoType(e.target.value as 'folder')}
143-
disabled={mutation.isPending}
144-
className="text-blue-600 bg-[#1a1a1a] border-[#2a2a2a]"
145-
/>
146-
<span className="text-sm text-white">Folder Discovery</span>
147-
</label>
148-
</div>
112+
<Tabs value={repoType} onValueChange={(value) => setRepoType(value as 'remote' | 'local' | 'folder')}>
113+
<TabsList className="grid w-full grid-cols-3 bg-[#1a1a1a]">
114+
<TabsTrigger value="remote">Remote</TabsTrigger>
115+
<TabsTrigger value="local">Local</TabsTrigger>
116+
<TabsTrigger value="folder">Folder</TabsTrigger>
117+
</TabsList>
118+
</Tabs>
149119
</div>
150120

151121
{repoType === 'remote' ? (
@@ -156,7 +126,7 @@ export function AddRepoDialog({ open, onOpenChange }: AddRepoDialogProps) {
156126
value={repoUrl}
157127
onChange={(e) => handleRepoUrlChange(e.target.value)}
158128
disabled={mutation.isPending}
159-
className="bg-[#1a1a1a] border-[#2a2a2a] text-white placeholder:text-zinc-500"
129+
className="bg-[#1a1a1a] border-[#2a2a2a] text-white placeholder:text-zinc-500 min-h-[44px] text-base"
160130
/>
161131
<p className="text-xs text-zinc-500">
162132
Full URL or shorthand format (owner/repo for GitHub)
@@ -170,10 +140,10 @@ export function AddRepoDialog({ open, onOpenChange }: AddRepoDialogProps) {
170140
value={localPath}
171141
onChange={(e) => setLocalPath(e.target.value)}
172142
disabled={mutation.isPending}
173-
className="bg-[#1a1a1a] border-[#2a2a2a] text-white placeholder:text-zinc-500"
143+
className="bg-[#1a1a1a] border-[#2a2a2a] text-white placeholder:text-zinc-500 min-h-[44px] text-base"
174144
/>
175145
<p className="text-xs text-zinc-500">
176-
Directory name for a new repo, or an absolute path to link an existing Git repo in place so its OpenCode sessions stay attached
146+
Directory name for a new repo, or an absolute path to link an existing Git repo
177147
</p>
178148
</div>
179149
) : (
@@ -184,57 +154,49 @@ export function AddRepoDialog({ open, onOpenChange }: AddRepoDialogProps) {
184154
value={folderPath}
185155
onChange={(e) => setFolderPath(e.target.value)}
186156
disabled={mutation.isPending}
187-
className="bg-[#1a1a1a] border-[#2a2a2a] text-white placeholder:text-zinc-500"
157+
className="bg-[#1a1a1a] border-[#2a2a2a] text-white placeholder:text-zinc-500 min-h-[44px] text-base"
188158
/>
189159
<p className="text-xs text-zinc-500">
190-
Scans the folder for nested Git repositories and links each one in place so existing OpenCode sessions show up immediately
160+
Scans the folder for nested Git repositories and links each one
191161
</p>
192162
</div>
193163
)}
194164

195165
<div className="space-y-2">
196-
<label className="text-sm text-zinc-400">Branch</label>
166+
<label className="text-sm text-zinc-400">Branch (optional)</label>
197167
<Input
198-
placeholder="Optional - uses default if empty"
168+
placeholder="Uses default if empty"
199169
value={branch}
200170
onChange={(e) => setBranch(e.target.value)}
201171
disabled={mutation.isPending || repoType === 'folder'}
202-
className="bg-[#1a1a1a] border-[#2a2a2a] text-white placeholder:text-zinc-500"
172+
className="bg-[#1a1a1a] border-[#2a2a2a] text-white placeholder:text-zinc-500 min-h-[44px] text-base"
203173
/>
204174
<p className="text-xs text-zinc-500">
205-
{repoType === 'folder'
206-
? 'Folder discovery links each repository on its current branch'
175+
{repoType === 'folder'
176+
? 'Links each repository on its current branch'
207177
: branch
208-
? repoType === 'remote'
209-
? `Clones repository directly to '${branch}' branch`
210-
: localPath?.startsWith('/')
211-
? `Links the repo in place and checks out '${branch}' branch`
212-
: `Initializes repository with '${branch}' branch`
213-
: repoType === 'remote'
214-
? "Clones repository to default branch"
215-
: localPath?.startsWith('/')
216-
? 'Links the repo in place and keeps its current branch'
217-
: "Initializes repository with 'main' branch"
178+
? `Uses '${branch}' branch`
179+
: 'Uses default branch'
218180
}
219181
</p>
220182
</div>
221183

222184
{showSkipSSHCheckbox && (
223-
<div className="flex items-start space-x-2">
185+
<div className="flex items-start space-x-3">
224186
<input
225187
type="checkbox"
226188
id="skip-ssh-verification"
227189
checked={skipSSHVerification}
228190
onChange={(e) => setSkipSSHVerification(e.target.checked)}
229191
disabled={mutation.isPending}
230-
className="mt-1 h-4 w-4 rounded border-[#2a2a2a] bg-[#1a1a1a] text-blue-600 focus:ring-blue-600"
192+
className="mt-1 h-5 w-5 rounded border-[#2a2a2a] bg-[#1a1a1a] text-blue-600 focus:ring-blue-600"
231193
/>
232194
<div className="flex-1">
233195
<label htmlFor="skip-ssh-verification" className="cursor-pointer text-sm text-white">
234196
Skip SSH host key verification
235197
</label>
236198
<p className="text-xs text-zinc-500">
237-
Auto-accept the SSH host key. Use for self-hosted or internal Git servers.
199+
Auto-accept the SSH host key for self-hosted or internal servers
238200
</p>
239201
</div>
240202
</div>
@@ -243,7 +205,7 @@ export function AddRepoDialog({ open, onOpenChange }: AddRepoDialogProps) {
243205
<Button
244206
type="submit"
245207
disabled={(!repoUrl && repoType === 'remote') || (!localPath && repoType === 'local') || (!folderPath && repoType === 'folder') || mutation.isPending}
246-
className="w-full bg-blue-600 hover:bg-blue-700 text-white"
208+
className="w-full min-h-[48px] bg-blue-600 hover:bg-blue-700 text-white text-base font-medium"
247209
>
248210
{mutation.isPending ? (
249211
<>

0 commit comments

Comments
 (0)