112 lines
4.0 KiB
JavaScript
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)
|