This repository has been archived by the owner on May 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 56
/
job.cljc
227 lines (201 loc) · 8.96 KB
/
job.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
(ns wh.components.job
(:require [clojure.string :as str]
[wh.common.job :as jobc]
[wh.common.subs]
[wh.components.cards :refer [match-circle]]
[wh.components.common :refer [wrap-img img]]
[wh.components.conversation-link.core :as conversation-link]
[wh.components.icons :refer [icon]]
[wh.components.tag :as tag]
[wh.re-frame.events :refer [dispatch]]
[wh.re-frame.subs :refer [<sub]]
[wh.routes :as routes]
[wh.slug :as slug]
[wh.util :as util]))
(defn state->candidate-status
[s]
(cond (or (= s :approved)
(= s :pending)) "Pending"
(= s :get_in_touch) "Interviewing \u2728"
(or (= s :pass)
(= s :rejected)) "Rejected \uD83D\uDE41"
(= s :hired) "Hired 🎉"))
(defn state-class
[s]
(cond (or (= s :approved)
(= s :pending)) "state state--pending"
(= s :get_in_touch) "state state--interviewing"
(or (= s :pass)
(= s :rejected)) "state state--rejected"
(= s :hired) "state state--hired"))
(defn save-button
[{:keys [id] :as job}
{:keys [on-close saved?]}]
[icon "bookmark"
:id (str "job-card__like-button_job-" id)
:class (util/merge-classes "job__icon" "like" (when saved? "selected"))
:on-click #(dispatch [:wh.events/toggle-job-like job on-close])
:data-test "job-save"])
(defn job-card--tag [tag]
(let [vertical-tags (<sub [:wh/vertical-tags-ids])
add-nofollow? (not (contains? vertical-tags (:id tag)))
href (routes/path :pre-set-search :params {:tag (slug/slug (:slug tag))})
tag (cond-> (-> tag
(assoc :href href)
(update :label str/lower-case))
add-nofollow? (assoc :rel "nofollow"))]
[tag/tag :a tag]))
(defn job-card--tags
[job-tags]
(into [:ul.tags.tags__job]
(map job-card--tag job-tags)))
(defn job-card--buttons
[{:keys [slug id state published] :as job}
{:keys [user-has-applied? user-is-owner? user-is-company?
applied? logged-in? small? liked? skeleton? on-close apply-source]}]
[:div.apply
[:div.buttons
[:a.button.button--inverted {:href (routes/path :job :params {:slug slug} :query-params {:interaction 1})}
(if user-is-owner? "View" "More Info")]
(let [apply-id (str "job-card__apply-button_job-" id)
button-opts (merge {:id apply-id}
(when (or applied?
(and user-is-company?
(not user-is-owner?)))
{:disabled true}))]
(if-not user-is-owner?
(when published
(let [job-page-path [:job
:params {:slug slug}
:query-params (merge {"apply" true
:interaction 1}
(when apply-source
{"apply_source" apply-source}))]]
[:a {:href (apply routes/path job-page-path)}
[:button.button button-opts
(cond applied?
"Applied"
user-has-applied?
"Instant Apply"
:else
"Apply")]]))
[:a {:href (routes/path :edit-job :params {:id id})}
[:button.button "Edit"]]))
(when (and logged-in? (not skeleton?) small?)
[save-button job {:on-close on-close
:saved? liked?}])]])
(defn card-perks [remote role-type sponsorship-offered score small?]
(cond-> [:div.card__perks]
score (conj [match-circle {:score score
:text? (not small?)
:percentage? small?}])
remote (conj [icon "globe"
:class "job__icon--small"]
[:span.card__perks__perk-name "Remote"])
(not= role-type "Full time") (conj [icon "contract"
:class "job__icon--small"]
[:span.card__perks__perk-name role-type])
sponsorship-offered (conj [icon "award"
:class "job__icon--small"]
[:span.card__perks__perk-name "Sponsorship"])))
(defn job-card--header
[{:keys [id slug logo title display-location salary published] :as job}
{company-logo :logo company-name :name}
{:keys [logged-in? skeleton? liked? small? on-close user-is-owner? perks?]}]
[:div.job-card__header
[:a {:href (when (or published user-is-owner?) (routes/path :job :params {:slug slug}))}
[:div
{:class (util/merge-classes "info" (when perks? "info--with-perks"))}
[:div.basic-info
[:div.job-title
{:data-test "job-title"}
title]
[:div.salary salary]
[:div.company-name
[icon "home"]
[:span company-name]]
[:div.location
[icon "location-round"]
[:span display-location]]]
[:div.logo
(if (or skeleton? (not company-logo))
[:div]
(wrap-img img company-logo {:alt (str company-name " logo") :w 48 :h 48 :fit "clip"}))]]]])
(def job-card-class
{:cards ""
:list "full-width"})
(defn create-skeleton-tags []
(map (fn [i]
{:label (apply str (repeat (+ 8 (rand-int 30)) " "))
:key i
:type :tech
:subtype :software
:slug ""})
(range 6)))
(defn job-card
[{:keys [company tagline tags published score user-score applied role-type
liked display-salary remuneration remote sponsorship-offered id]
:or {published true}
:as job}
{:keys [liked? applied? user-is-owner? small? view-type logged-in? on-close highlighted? conversation]
:or {liked? (or liked false) ;; old style job handlers added 'liked' bool to the job itself
applied? (or applied false) ;; old style job handlers added 'applied' bool to the job itself
user-is-owner? false
small? false
highlighted? false}
:as opts}]
(let [skeleton? (and job (empty? (dissoc job :id :slug)))
salary (or display-salary (jobc/format-job-remuneration remuneration))
job-tags (if skeleton? (create-skeleton-tags) tags)
score (or (:user-score job) score)
opts (assoc opts
:liked? liked?
:applied? applied?)
unpublished-label [:div.card__label.card__label--unpublished.card__label--job
"Unpublished"]
perks? (or remote (not= role-type "Full time") sponsorship-offered)
state (:state job)]
[:div {:class (util/merge-classes "card"
"card--job"
(when remote "card--job--remote")
(when small? "card--small")
(when skeleton? "job-card--skeleton")
(when highlighted? "job-card--highlighted")
(job-card-class view-type))
:data-test "job-card"}
[:div
{:class (util/merge-classes "card--job__control-bar"
(when state "card--job__control-bar--with-state"))}
(when state
[:div
{:class (state-class state)}
[:span.applied-state (state->candidate-status state)]])
(when (and logged-in? (not skeleton?) on-close)
[icon "close"
:id (str "job-card__blacklist-button_job-" id)
:class "job__icon blacklist"
:on-click #(dispatch [:wh.events/blacklist-job job on-close])])
(when (and logged-in? (not skeleton?) (not small?))
[save-button job {:on-close on-close
:saved? liked?}])]
[job-card--header (assoc job :salary salary) company (assoc opts :perks? perks?)]
[conversation-link/link
{:conversations-enabled? (<sub [:wh/conversations-enabled?])}
conversation]
[:div.tagline
(when-not small?
[:div.tagline-content tagline])]
[card-perks remote role-type sponsorship-offered score small?]
(if (and small? (not published))
unpublished-label
[job-card--tags job-tags])
[job-card--buttons job opts]
(when (and (not published) (not small?) user-is-owner?)
unpublished-label)]))
(defn highlight [{:keys [title icon-name children icon-class]}]
[:div.job__highlight
[:div.job__highlight_icon
(when (and title icon-name) [icon icon-name :class icon-class])]
[:div.job__highlight__content
[:h2.job__highlight__title title]
children]])