feat: make team section a floating sidebar on desktop
Add responsive 2-column layout for the encounters page: - Desktop (lg, ≥1024px): Encounters on left, team in sticky right sidebar - Mobile/tablet: Keep current stacked layout The sidebar scrolls independently when team exceeds viewport height. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -922,7 +922,7 @@ export function RunEncounters() {
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto p-8">
|
||||
<div className="max-w-4xl lg:max-w-6xl mx-auto p-8">
|
||||
{/* Header */}
|
||||
<div className="mb-6">
|
||||
<Link
|
||||
@@ -1246,9 +1246,12 @@ export function RunEncounters() {
|
||||
{/* Encounters Tab */}
|
||||
{activeTab === 'encounters' && (
|
||||
<>
|
||||
{/* Team Section */}
|
||||
<div className="lg:flex lg:gap-6">
|
||||
{/* Main content column */}
|
||||
<div className="flex-1 min-w-0">
|
||||
{/* Team Section - Mobile/Tablet only */}
|
||||
{(alive.length > 0 || dead.length > 0) && (
|
||||
<div className="mb-6">
|
||||
<div className="mb-6 lg:hidden">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<button
|
||||
type="button"
|
||||
@@ -1690,6 +1693,68 @@ export function RunEncounters() {
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Team Sidebar - Desktop only */}
|
||||
{(alive.length > 0 || dead.length > 0) && (
|
||||
<div className="hidden lg:block w-64 shrink-0">
|
||||
<div className="sticky top-20 max-h-[calc(100vh-6rem)] overflow-y-auto">
|
||||
<div className="bg-surface-1 border border-border-default rounded-lg p-4">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<h2 className="text-lg font-semibold text-text-primary">
|
||||
{isActive ? 'Team' : 'Final Team'}
|
||||
</h2>
|
||||
<span className="text-xs text-text-muted">
|
||||
{alive.length}/{alive.length + dead.length}
|
||||
</span>
|
||||
</div>
|
||||
{alive.length > 1 && (
|
||||
<select
|
||||
value={teamSort}
|
||||
onChange={(e) => setTeamSort(e.target.value as TeamSortKey)}
|
||||
className="w-full text-sm border border-border-default rounded-lg px-3 py-1.5 bg-surface-0 text-text-primary mb-3"
|
||||
>
|
||||
<option value="route">Route Order</option>
|
||||
<option value="level">Catch Level</option>
|
||||
<option value="species">Species Name</option>
|
||||
<option value="dex">National Dex</option>
|
||||
</select>
|
||||
)}
|
||||
{alive.length > 0 && (
|
||||
<div className="grid grid-cols-2 gap-2 mb-3">
|
||||
{alive.map((enc) => (
|
||||
<PokemonCard
|
||||
key={enc.id}
|
||||
encounter={enc}
|
||||
onClick={
|
||||
isActive && canEdit ? () => setSelectedTeamEncounter(enc) : undefined
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{dead.length > 0 && (
|
||||
<>
|
||||
<h3 className="text-sm font-medium text-text-tertiary mb-2">Graveyard</h3>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
{dead.map((enc) => (
|
||||
<PokemonCard
|
||||
key={enc.id}
|
||||
encounter={enc}
|
||||
showFaintLevel
|
||||
onClick={
|
||||
isActive && canEdit ? () => setSelectedTeamEncounter(enc) : undefined
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Encounter Modal */}
|
||||
{selectedRoute && (
|
||||
|
||||
Reference in New Issue
Block a user