init
This commit is contained in:
111
jobs/desktop/DesktopJobsToolbar.js
Normal file
111
jobs/desktop/DesktopJobsToolbar.js
Normal file
@@ -0,0 +1,111 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user