Skip to content

Commit e533740

Browse files
jeremylongshoreclaude
andcommitted
fix(ui): collapse secondary positions on add-athlete for mobile usability
Secondary positions grid (12 checkboxes) filled the entire iPhone screen, blocking users from scrolling to League/Team/Submit fields. Now collapsed behind a tap-to-expand button. Also increased touch targets to 44px min height with larger checkboxes (20px) and more padding for mobile. Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent e6dd80e commit e533740

1 file changed

Lines changed: 37 additions & 23 deletions

File tree

src/app/dashboard/add-athlete/page.tsx

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export default function AddAthlete() {
1414
const [photoPreview, setPhotoPreview] = useState<string | null>(null);
1515
const [errors, setErrors] = useState<Record<string, string>>({});
1616
const [generalError, setGeneralError] = useState<string | null>(null);
17+
const [showSecondaryPositions, setShowSecondaryPositions] = useState(false);
1718
const [formData, setFormData] = useState({
1819
name: '',
1920
birthday: '',
@@ -261,30 +262,43 @@ export default function AddAthlete() {
261262
{errors.primaryPosition && <p className="text-red-500 text-sm mt-1">{errors.primaryPosition}</p>}
262263
</div>
263264

264-
{/* Secondary Positions */}
265+
{/* Secondary Positions (collapsible) */}
265266
<div>
266-
<label className="block text-sm font-medium text-zinc-900 mb-2">
267-
Secondary Positions (Optional, max 3)
268-
</label>
269-
<div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
270-
{Object.entries(POSITION_LABELS)
271-
.filter(([code]) => code !== formData.primaryPosition)
272-
.map(([code, label]) => (
273-
<label key={code} className="flex items-center gap-2 cursor-pointer p-2 rounded border border-zinc-200 hover:bg-zinc-50">
274-
<input
275-
type="checkbox"
276-
checked={formData.secondaryPositions.includes(code as SoccerPositionCode)}
277-
onChange={() => handleSecondaryPositionToggle(code as SoccerPositionCode)}
278-
disabled={
279-
formData.secondaryPositions.length >= 3 &&
280-
!formData.secondaryPositions.includes(code as SoccerPositionCode)
281-
}
282-
className="w-4 h-4 text-zinc-900 focus:ring-zinc-900 rounded"
283-
/>
284-
<span className="text-sm text-zinc-700">{label}</span>
285-
</label>
286-
))}
287-
</div>
267+
<button
268+
type="button"
269+
onClick={() => setShowSecondaryPositions(!showSecondaryPositions)}
270+
className="flex items-center gap-2 text-sm font-medium text-zinc-900"
271+
>
272+
<span className={`transition-transform ${showSecondaryPositions ? 'rotate-90' : ''}`}>&#9654;</span>
273+
Secondary Positions
274+
<span className="font-normal text-zinc-500">(Optional, max 3)</span>
275+
{formData.secondaryPositions.length > 0 && (
276+
<span className="bg-zinc-900 text-white text-xs px-2 py-0.5 rounded-full">
277+
{formData.secondaryPositions.length}
278+
</span>
279+
)}
280+
</button>
281+
{showSecondaryPositions && (
282+
<div className="grid grid-cols-2 sm:grid-cols-3 gap-2 mt-3">
283+
{Object.entries(POSITION_LABELS)
284+
.filter(([code]) => code !== formData.primaryPosition)
285+
.map(([code, label]) => (
286+
<label key={code} className="flex items-center gap-3 cursor-pointer p-3 rounded-lg border border-zinc-200 hover:bg-zinc-50 active:bg-zinc-100 min-h-[44px]">
287+
<input
288+
type="checkbox"
289+
checked={formData.secondaryPositions.includes(code as SoccerPositionCode)}
290+
onChange={() => handleSecondaryPositionToggle(code as SoccerPositionCode)}
291+
disabled={
292+
formData.secondaryPositions.length >= 3 &&
293+
!formData.secondaryPositions.includes(code as SoccerPositionCode)
294+
}
295+
className="w-5 h-5 text-zinc-900 focus:ring-zinc-900 rounded flex-shrink-0"
296+
/>
297+
<span className="text-sm text-zinc-700">{label}</span>
298+
</label>
299+
))}
300+
</div>
301+
)}
288302
{errors.secondaryPositions && <p className="text-red-500 text-sm mt-1">{errors.secondaryPositions}</p>}
289303
</div>
290304

0 commit comments

Comments
 (0)