viewof filters = {
const defaultSeason = seasonOptions[1] || "All Seasons"
function getRoundRange(season) {
const src = gameLogs
if (!src) return { min: 0, max: 30 }
const allGames = season === "All Seasons" ? src : src.filter(d => String(d.season) === season)
let rMin = Infinity, rMax = -Infinity
for (const d of allGames) { if (d.round != null) { if (d.round < rMin) rMin = d.round; if (d.round > rMax) rMax = d.round } }
return { min: rMin === Infinity ? 0 : rMin, max: rMax === -Infinity ? 30 : rMax }
}
let roundBounds = getRoundRange(defaultSeason)
function makeSelect(options, defaultVal, label) {
const wrap = document.createElement("div")
wrap.className = "filter-select-wrap"
const lbl = document.createElement("span")
lbl.className = "filter-label"
lbl.textContent = label
const sel = document.createElement("select")
sel.className = "filter-select"
for (const opt of options) {
const o = document.createElement("option")
o.value = opt; o.textContent = opt
if (opt === defaultVal) o.selected = true
sel.appendChild(o)
}
wrap.appendChild(lbl); wrap.appendChild(sel)
return { wrap, sel }
}
const container = document.createElement("div")
container.className = "player-filter-bar"
const row = document.createElement("div")
row.className = "filter-row"
const season = makeSelect(seasonOptions, defaultSeason, "Season")
const team = makeSelect(teamOptions, "All Teams", "Team")
const opp = makeSelect(oppOptions, "All Opponents", "Vs")
const haSelect = makeSelect(["All", "Home", "Away"], "All", "H/A")
const seasonType = makeSelect(["All", "Regular", "Finals"], "All", "Type")
const venueSelect = makeSelect(venueOptions, "All Venues", "Venue")
const daySelect = makeSelect(dayOptions, "All Days", "Day")
row.appendChild(season.wrap)
row.appendChild(team.wrap)
row.appendChild(opp.wrap)
row.appendChild(haSelect.wrap)
row.appendChild(seasonType.wrap)
row.appendChild(venueSelect.wrap)
row.appendChild(daySelect.wrap)
// Round range
const roundWrap = document.createElement("div")
roundWrap.className = "filter-round-wrap"
const rLbl = document.createElement("span")
rLbl.className = "filter-label"
rLbl.textContent = "Rounds"
const rMin = document.createElement("input")
rMin.type = "number"; rMin.className = "round-input"
rMin.min = roundBounds.min; rMin.max = roundBounds.max; rMin.value = roundBounds.min
const rSep = document.createElement("span")
rSep.className = "round-sep"; rSep.textContent = "–"
const rMax = document.createElement("input")
rMax.type = "number"; rMax.className = "round-input"
rMax.min = roundBounds.min; rMax.max = roundBounds.max; rMax.value = roundBounds.max
roundWrap.appendChild(rLbl); roundWrap.appendChild(rMin); roundWrap.appendChild(rSep); roundWrap.appendChild(rMax)
row.appendChild(roundWrap)
container.appendChild(row)
container.value = {
season: defaultSeason,
team: "All Teams",
opponent: "All Opponents",
homeAway: "All",
seasonType: "All",
venue: "All Venues",
day: "All Days",
roundMin: +rMin.value,
roundMax: +rMax.value
}
function emit() { container.dispatchEvent(new Event("input", { bubbles: true })) }
season.sel.addEventListener("change", () => {
roundBounds = getRoundRange(season.sel.value)
rMin.min = roundBounds.min; rMin.max = roundBounds.max; rMin.value = roundBounds.min
rMax.min = roundBounds.min; rMax.max = roundBounds.max; rMax.value = roundBounds.max
container.value = { ...container.value, season: season.sel.value, roundMin: roundBounds.min, roundMax: roundBounds.max }
emit()
})
team.sel.addEventListener("change", () => { container.value = { ...container.value, team: team.sel.value }; emit() })
opp.sel.addEventListener("change", () => { container.value = { ...container.value, opponent: opp.sel.value }; emit() })
haSelect.sel.addEventListener("change", () => { container.value = { ...container.value, homeAway: haSelect.sel.value }; emit() })
seasonType.sel.addEventListener("change", () => { container.value = { ...container.value, seasonType: seasonType.sel.value }; emit() })
venueSelect.sel.addEventListener("change", () => { container.value = { ...container.value, venue: venueSelect.sel.value }; emit() })
daySelect.sel.addEventListener("change", () => { container.value = { ...container.value, day: daySelect.sel.value }; emit() })
let roundTimer
function clampRound(input) {
if (input.value === "") return
const v = +input.value
if (v < roundBounds.min) input.value = roundBounds.min
if (v > roundBounds.max) input.value = roundBounds.max
}
function updateRound() {
clearTimeout(roundTimer)
roundTimer = setTimeout(() => {
clampRound(rMin); clampRound(rMax)
container.value = { ...container.value, roundMin: rMin.value === "" ? null : +rMin.value, roundMax: rMax.value === "" ? null : +rMax.value }
emit()
}, 500)
}
rMin.addEventListener("input", updateRound); rMax.addEventListener("input", updateRound)
rMin.addEventListener("blur", () => { clampRound(rMin); updateRound() })
rMax.addEventListener("blur", () => { clampRound(rMax); updateRound() })
return container
}
seasonFilter = filters.season
teamFilter = filters.team
oppFilter = filters.opponent
homeAwayFilter = filters.homeAway
seasonTypeFilter = filters.seasonType
venueFilter = filters.venue
dayFilter = filters.day
roundRange = ({ min: filters.roundMin, max: filters.roundMax })