Allow multiple games per region in Custom genlocke
All checks were successful
CI / backend-tests (push) Successful in 25s
CI / frontend-tests (push) Successful in 27s

In custom mode, the region picker no longer filters out already-used
regions, letting users add multiple legs from the same region (e.g.
Black + Black 2 in Unova). Preset modes keep the one-per-region
behavior. Already-used regions show a subtle dot indicator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Julian Tabel
2026-03-17 13:32:34 +01:00
parent 7d1c091432
commit 535154a056
2 changed files with 48 additions and 16 deletions

View File

@@ -0,0 +1,11 @@
---
# nuzlocke-tracker-na3s
title: Allow multiple games per region in Custom genlocke
status: completed
type: feature
priority: normal
created_at: 2026-03-17T12:29:57Z
updated_at: 2026-03-17T12:32:05Z
---
Users want to run multiple games from the same region in a genlocke (e.g., Black + Black 2 in Unova). Change availableRegions computation so custom mode shows all regions, and add a subtle indicator for already-used regions in AddLegDropdown.

View File

@@ -111,8 +111,14 @@ export function NewGenlocke() {
const enabledRuleCount = RULE_DEFINITIONS.filter((r) => nuzlockeRules[r.key]).length const enabledRuleCount = RULE_DEFINITIONS.filter((r) => nuzlockeRules[r.key]).length
const totalRuleCount = RULE_DEFINITIONS.length const totalRuleCount = RULE_DEFINITIONS.length
// Regions not yet used in legs (for "add leg" picker) // In custom mode, show all regions (allow multiple legs per region).
const availableRegions = regions?.filter((r) => !legs.some((l) => l.region === r.name)) ?? [] // In preset modes, filter out regions already used.
const availableRegions =
preset === 'custom'
? regions ?? []
: regions?.filter((r) => !legs.some((l) => l.region === r.name)) ?? []
const usedRegionNames = new Set(legs.map((l) => l.region))
return ( return (
<div className="max-w-4xl mx-auto p-8"> <div className="max-w-4xl mx-auto p-8">
@@ -225,7 +231,11 @@ export function NewGenlocke() {
{/* Add leg button */} {/* Add leg button */}
{preset === 'custom' && availableRegions.length > 0 && ( {preset === 'custom' && availableRegions.length > 0 && (
<div className="mt-4"> <div className="mt-4">
<AddLegDropdown regions={availableRegions} onAdd={handleAddLeg} /> <AddLegDropdown
regions={availableRegions}
usedRegionNames={usedRegionNames}
onAdd={handleAddLeg}
/>
</div> </div>
)} )}
@@ -551,9 +561,11 @@ function LegRow({
function AddLegDropdown({ function AddLegDropdown({
regions, regions,
usedRegionNames,
onAdd, onAdd,
}: { }: {
regions: Region[] regions: Region[]
usedRegionNames?: Set<string>
onAdd: (region: Region) => void onAdd: (region: Region) => void
}) { }) {
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
@@ -583,7 +595,9 @@ function AddLegDropdown({
<div className="bg-surface-1 rounded-lg shadow p-3"> <div className="bg-surface-1 rounded-lg shadow p-3">
<div className="text-sm font-medium text-text-secondary mb-2">Select a region to add</div> <div className="text-sm font-medium text-text-secondary mb-2">Select a region to add</div>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
{regions.map((region) => ( {regions.map((region) => {
const alreadyUsed = usedRegionNames?.has(region.name)
return (
<button <button
key={region.name} key={region.name}
type="button" type="button"
@@ -591,11 +605,18 @@ function AddLegDropdown({
onAdd(region) onAdd(region)
setOpen(false) setOpen(false)
}} }}
className="px-3 py-1.5 rounded-md text-sm bg-surface-2 text-text-primary hover:bg-surface-3 transition-colors" className="px-3 py-1.5 rounded-md text-sm bg-surface-2 text-text-primary hover:bg-surface-3 transition-colors flex items-center gap-1.5"
> >
{region.name.charAt(0).toUpperCase() + region.name.slice(1)} {region.name.charAt(0).toUpperCase() + region.name.slice(1)}
{alreadyUsed && (
<span
className="w-1.5 h-1.5 rounded-full bg-accent-400 inline-block"
title="Already added"
/>
)}
</button> </button>
))} )
})}
<button <button
type="button" type="button"
onClick={() => setOpen(false)} onClick={() => setOpen(false)}