Files
apps/jobs/desktop/DesktopJobsToolbar.js
metacryst 0d6c7683ff init
2026-04-28 20:05:00 -05:00

112 lines
4.0 KiB
JavaScript

class DesktopJobsToolbar extends Shadow {
constructor(filters, onFiltersChange) {
super()
this.filters = filters
this.onFiltersChange = onFiltersChange
}
render() {
HStack(() => {
// Keyword search
HStack(() => {
p("🔍")
.margin(0)
.fontSize(0.85, em)
.opacity(0.45)
.flexShrink(0)
input()
.attr({ type: "text", placeholder: "Search jobs, titles, companies…", value: this.filters.keyword })
.flex(1)
.border("none")
.outline("none")
.background("transparent")
.color("var(--headertext)")
.fontSize(0.9, em)
.onInput((e) => this.onFiltersChange({ ...this.filters, keyword: e.target.value }))
})
.gap(0.55, em)
.paddingHorizontal(0.9, em)
.paddingVertical(0.6, em)
.background("var(--darkaccent)")
.border("1px solid var(--divider)")
.borderRadius(0.5, em)
.alignItems("center")
.flex(1)
// Location
HStack(() => {
p("📍")
.margin(0)
.fontSize(0.85, em)
.opacity(0.45)
.flexShrink(0)
input()
.attr({ type: "text", placeholder: "Location", value: this.filters.location })
.flex(1)
.border("none")
.outline("none")
.background("transparent")
.color("var(--headertext)")
.fontSize(0.9, em)
.onInput((e) => this.onFiltersChange({ ...this.filters, location: e.target.value }))
})
.gap(0.55, em)
.paddingHorizontal(0.9, em)
.paddingVertical(0.6, em)
.background("var(--darkaccent)")
.border("1px solid var(--divider)")
.borderRadius(0.5, em)
.alignItems("center")
.width(200, px)
.flexShrink(0)
// Job type filter
this.filterSelect("Type", [
{ label: "All Types", value: "" },
{ label: "Full-time", value: "full-time" },
{ label: "Part-time", value: "part-time" },
{ label: "Contract", value: "contract" },
{ label: "Internship", value: "internship" },
], this.filters.type, (v) => this.onFiltersChange({ ...this.filters, type: v }))
// Experience level
this.filterSelect("Level", [
{ label: "All Levels", value: "" },
{ label: "Entry", value: "entry" },
{ label: "Mid", value: "mid" },
{ label: "Senior", value: "senior" },
], this.filters.level, (v) => this.onFiltersChange({ ...this.filters, level: v }))
})
.gap(0.65, em)
.paddingHorizontal(1.5, em)
.paddingVertical(0.85, em)
.borderBottom("1px solid var(--divider)")
.alignItems("center")
.width(100, pct)
.boxSizing("border-box")
.flexShrink(0)
}
filterSelect(placeholder, options, value, onChange) {
select(() => {
options.forEach(opt => {
option(opt.label)
.attr({ value: opt.value, selected: opt.value === value ? "" : null })
})
})
.paddingVertical(0.55, em)
.paddingHorizontal(0.75, em)
.background("var(--darkaccent)")
.border("1px solid var(--divider)")
.borderRadius(0.5, em)
.color("var(--headertext)")
.fontSize(0.85, em)
.outline("none")
.cursor("pointer")
.flexShrink(0)
.onEvent("change", (e) => onChange(e.target.value))
}
}
register(DesktopJobsToolbar)